]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #8038 from imzyxwvu/same-attr
[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 "prefix.h"
27 #include "linklist.h"
28 #include "memory.h"
29 #include "command.h"
30 #include "stream.h"
31 #include "filter.h"
32 #include "log.h"
33 #include "routemap.h"
34 #include "buffer.h"
35 #include "sockunion.h"
36 #include "plist.h"
37 #include "thread.h"
38 #include "workqueue.h"
39 #include "queue.h"
40 #include "memory.h"
41 #include "srv6.h"
42 #include "lib/json.h"
43 #include "lib_errors.h"
44 #include "zclient.h"
45 #include "bgpd/bgpd.h"
46 #include "bgpd/bgp_table.h"
47 #include "bgpd/bgp_route.h"
48 #include "bgpd/bgp_attr.h"
49 #include "bgpd/bgp_debug.h"
50 #include "bgpd/bgp_errors.h"
51 #include "bgpd/bgp_aspath.h"
52 #include "bgpd/bgp_regex.h"
53 #include "bgpd/bgp_community.h"
54 #include "bgpd/bgp_ecommunity.h"
55 #include "bgpd/bgp_lcommunity.h"
56 #include "bgpd/bgp_clist.h"
57 #include "bgpd/bgp_packet.h"
58 #include "bgpd/bgp_filter.h"
59 #include "bgpd/bgp_fsm.h"
60 #include "bgpd/bgp_mplsvpn.h"
61 #include "bgpd/bgp_nexthop.h"
62 #include "bgpd/bgp_damp.h"
63 #include "bgpd/bgp_advertise.h"
64 #include "bgpd/bgp_zebra.h"
65 #include "bgpd/bgp_vty.h"
66 #include "bgpd/bgp_mpath.h"
67 #include "bgpd/bgp_nht.h"
68 #include "bgpd/bgp_updgrp.h"
69 #include "bgpd/bgp_label.h"
70 #include "bgpd/bgp_addpath.h"
71 #include "bgpd/bgp_mac.h"
72 #include "bgpd/bgp_network.h"
73 #include "bgpd/bgp_trace.h"
74
75 #ifdef ENABLE_BGP_VNC
76 #include "bgpd/rfapi/rfapi_backend.h"
77 #include "bgpd/rfapi/vnc_import_bgp.h"
78 #include "bgpd/rfapi/vnc_export_bgp.h"
79 #endif
80 #include "bgpd/bgp_encap_types.h"
81 #include "bgpd/bgp_encap_tlv.h"
82 #include "bgpd/bgp_evpn.h"
83 #include "bgpd/bgp_evpn_mh.h"
84 #include "bgpd/bgp_evpn_vty.h"
85 #include "bgpd/bgp_flowspec.h"
86 #include "bgpd/bgp_flowspec_util.h"
87 #include "bgpd/bgp_pbr.h"
88 #include "northbound.h"
89 #include "northbound_cli.h"
90 #include "bgpd/bgp_nb.h"
91
92 #ifndef VTYSH_EXTRACT_PL
93 #include "bgpd/bgp_route_clippy.c"
94 #endif
95
96 /* Extern from bgp_dump.c */
97 extern const char *bgp_origin_str[];
98 extern const char *bgp_origin_long_str[];
99
100 /* PMSI strings. */
101 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
102 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
103 static const struct message bgp_pmsi_tnltype_str[] = {
104 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
105 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
106 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
107 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
108 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
109 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
110 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
111 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
112 {0}
113 };
114
115 #define VRFID_NONE_STR "-"
116
117 DEFINE_HOOK(bgp_process,
118 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
119 struct peer *peer, bool withdraw),
120 (bgp, afi, safi, bn, peer, withdraw))
121
122 /** Test if path is suppressed. */
123 static bool bgp_path_suppressed(struct bgp_path_info *pi)
124 {
125 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
126 return false;
127
128 return listcount(pi->extra->aggr_suppressors) > 0;
129 }
130
131 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
132 safi_t safi, const struct prefix *p,
133 struct prefix_rd *prd)
134 {
135 struct bgp_dest *dest;
136 struct bgp_dest *pdest = NULL;
137
138 assert(table);
139
140 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
141 || (safi == SAFI_EVPN)) {
142 pdest = bgp_node_get(table, (struct prefix *)prd);
143
144 if (!bgp_dest_has_bgp_path_info_data(pdest))
145 bgp_dest_set_bgp_table_info(
146 pdest, bgp_table_init(table->bgp, afi, safi));
147 else
148 bgp_dest_unlock_node(pdest);
149 table = bgp_dest_get_bgp_table_info(pdest);
150 }
151
152 dest = bgp_node_get(table, p);
153
154 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
155 || (safi == SAFI_EVPN))
156 dest->pdest = pdest;
157
158 return dest;
159 }
160
161 struct bgp_dest *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
162 safi_t safi, const struct prefix *p,
163 struct prefix_rd *prd)
164 {
165 struct bgp_dest *dest;
166 struct bgp_dest *pdest = NULL;
167
168 if (!table)
169 return NULL;
170
171 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
172 || (safi == SAFI_EVPN)) {
173 pdest = bgp_node_lookup(table, (struct prefix *)prd);
174 if (!pdest)
175 return NULL;
176
177 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
178 bgp_dest_unlock_node(pdest);
179 return NULL;
180 }
181
182 table = bgp_dest_get_bgp_table_info(pdest);
183 }
184
185 dest = bgp_node_lookup(table, p);
186
187 return dest;
188 }
189
190 /* Allocate bgp_path_info_extra */
191 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
192 {
193 struct bgp_path_info_extra *new;
194 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
195 sizeof(struct bgp_path_info_extra));
196 new->label[0] = MPLS_INVALID_LABEL;
197 new->num_labels = 0;
198 new->bgp_fs_pbr = NULL;
199 new->bgp_fs_iprule = NULL;
200 return new;
201 }
202
203 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
204 {
205 struct bgp_path_info_extra *e;
206
207 if (!extra || !*extra)
208 return;
209
210 e = *extra;
211
212 e->damp_info = NULL;
213 if (e->parent) {
214 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
215
216 if (bpi->net) {
217 /* FIXME: since multiple e may have the same e->parent
218 * and e->parent->net is holding a refcount for each
219 * of them, we need to do some fudging here.
220 *
221 * WARNING: if bpi->net->lock drops to 0, bpi may be
222 * freed as well (because bpi->net was holding the
223 * last reference to bpi) => write after free!
224 */
225 unsigned refcount;
226
227 bpi = bgp_path_info_lock(bpi);
228 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
229 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
230 if (!refcount)
231 bpi->net = NULL;
232 bgp_path_info_unlock(bpi);
233 }
234 bgp_path_info_unlock(e->parent);
235 e->parent = NULL;
236 }
237
238 if (e->bgp_orig)
239 bgp_unlock(e->bgp_orig);
240
241 if (e->aggr_suppressors)
242 list_delete(&e->aggr_suppressors);
243
244 if (e->es_info)
245 bgp_evpn_path_es_info_free(e->es_info);
246
247 if ((*extra)->bgp_fs_iprule)
248 list_delete(&((*extra)->bgp_fs_iprule));
249 if ((*extra)->bgp_fs_pbr)
250 list_delete(&((*extra)->bgp_fs_pbr));
251 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
252 }
253
254 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
255 * allocated if required.
256 */
257 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
258 {
259 if (!pi->extra)
260 pi->extra = bgp_path_info_extra_new();
261 return pi->extra;
262 }
263
264 /* Free bgp route information. */
265 static void bgp_path_info_free(struct bgp_path_info *path)
266 {
267 bgp_attr_unintern(&path->attr);
268
269 bgp_unlink_nexthop(path);
270 bgp_path_info_extra_free(&path->extra);
271 bgp_path_info_mpath_free(&path->mpath);
272 if (path->net)
273 bgp_addpath_free_info_data(&path->tx_addpath,
274 &path->net->tx_addpath);
275
276 peer_unlock(path->peer); /* bgp_path_info peer reference */
277
278 XFREE(MTYPE_BGP_ROUTE, path);
279 }
280
281 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
282 {
283 path->lock++;
284 return path;
285 }
286
287 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
288 {
289 assert(path && path->lock > 0);
290 path->lock--;
291
292 if (path->lock == 0) {
293 #if 0
294 zlog_debug ("%s: unlocked and freeing", __func__);
295 zlog_backtrace (LOG_DEBUG);
296 #endif
297 bgp_path_info_free(path);
298 return NULL;
299 }
300
301 #if 0
302 if (path->lock == 1)
303 {
304 zlog_debug ("%s: unlocked to 1", __func__);
305 zlog_backtrace (LOG_DEBUG);
306 }
307 #endif
308
309 return path;
310 }
311
312 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
313 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
314 {
315 struct peer *peer;
316 struct bgp_path_info *old_pi, *nextpi;
317 bool set_flag = false;
318 struct bgp *bgp = NULL;
319 struct bgp_table *table = NULL;
320 afi_t afi = 0;
321 safi_t safi = 0;
322
323 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
324 * then the route selection is deferred
325 */
326 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
327 return 0;
328
329 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
330 if (BGP_DEBUG(update, UPDATE_OUT))
331 zlog_debug(
332 "Route %pBD is in workqueue and being processed, not deferred.",
333 dest);
334
335 return 0;
336 }
337
338 table = bgp_dest_table(dest);
339 if (table) {
340 bgp = table->bgp;
341 afi = table->afi;
342 safi = table->safi;
343 }
344
345 for (old_pi = bgp_dest_get_bgp_path_info(dest);
346 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
347 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
348 continue;
349
350 /* Route selection is deferred if there is a stale path which
351 * which indicates peer is in restart mode
352 */
353 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
354 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
355 set_flag = true;
356 } else {
357 /* If the peer is graceful restart capable and peer is
358 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
359 */
360 peer = old_pi->peer;
361 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
362 && BGP_PEER_RESTARTING_MODE(peer)
363 && (old_pi
364 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
365 set_flag = true;
366 }
367 }
368 if (set_flag)
369 break;
370 }
371
372 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
373 * is active
374 */
375 if (set_flag && table) {
376 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
377 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
378 bgp->gr_info[afi][safi].gr_deferred++;
379 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
380 if (BGP_DEBUG(update, UPDATE_OUT))
381 zlog_debug("DEFER route %pBD, dest %p", dest,
382 dest);
383 return 0;
384 }
385 }
386 return -1;
387 }
388
389 void bgp_path_info_add(struct bgp_dest *dest, struct bgp_path_info *pi)
390 {
391 struct bgp_path_info *top;
392
393 top = bgp_dest_get_bgp_path_info(dest);
394
395 pi->next = top;
396 pi->prev = NULL;
397 if (top)
398 top->prev = pi;
399 bgp_dest_set_bgp_path_info(dest, pi);
400
401 bgp_path_info_lock(pi);
402 bgp_dest_lock_node(dest);
403 peer_lock(pi->peer); /* bgp_path_info peer reference */
404 bgp_dest_set_defer_flag(dest, false);
405 }
406
407 /* Do the actual removal of info from RIB, for use by bgp_process
408 completion callback *only* */
409 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
410 {
411 if (pi->next)
412 pi->next->prev = pi->prev;
413 if (pi->prev)
414 pi->prev->next = pi->next;
415 else
416 bgp_dest_set_bgp_path_info(dest, pi->next);
417
418 bgp_path_info_mpath_dequeue(pi);
419 bgp_path_info_unlock(pi);
420 bgp_dest_unlock_node(dest);
421 }
422
423 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
424 {
425 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
426 /* set of previous already took care of pcount */
427 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
428 }
429
430 /* undo the effects of a previous call to bgp_path_info_delete; typically
431 called when a route is deleted and then quickly re-added before the
432 deletion has been processed */
433 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
434 {
435 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
436 /* unset of previous already took care of pcount */
437 SET_FLAG(pi->flags, BGP_PATH_VALID);
438 }
439
440 /* Adjust pcount as required */
441 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
442 {
443 struct bgp_table *table;
444
445 assert(dest && bgp_dest_table(dest));
446 assert(pi && pi->peer && pi->peer->bgp);
447
448 table = bgp_dest_table(dest);
449
450 if (pi->peer == pi->peer->bgp->peer_self)
451 return;
452
453 if (!BGP_PATH_COUNTABLE(pi)
454 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
455
456 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
457
458 /* slight hack, but more robust against errors. */
459 if (pi->peer->pcount[table->afi][table->safi])
460 pi->peer->pcount[table->afi][table->safi]--;
461 else
462 flog_err(EC_LIB_DEVELOPMENT,
463 "Asked to decrement 0 prefix count for peer");
464 } else if (BGP_PATH_COUNTABLE(pi)
465 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
466 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
467 pi->peer->pcount[table->afi][table->safi]++;
468 }
469 }
470
471 static int bgp_label_index_differs(struct bgp_path_info *pi1,
472 struct bgp_path_info *pi2)
473 {
474 return (!(pi1->attr->label_index == pi2->attr->label_index));
475 }
476
477 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
478 * This is here primarily to keep prefix-count in check.
479 */
480 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
481 uint32_t flag)
482 {
483 SET_FLAG(pi->flags, flag);
484
485 /* early bath if we know it's not a flag that changes countability state
486 */
487 if (!CHECK_FLAG(flag,
488 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
489 return;
490
491 bgp_pcount_adjust(dest, pi);
492 }
493
494 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
495 uint32_t flag)
496 {
497 UNSET_FLAG(pi->flags, flag);
498
499 /* early bath if we know it's not a flag that changes countability state
500 */
501 if (!CHECK_FLAG(flag,
502 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
503 return;
504
505 bgp_pcount_adjust(dest, pi);
506 }
507
508 /* Get MED value. If MED value is missing and "bgp bestpath
509 missing-as-worst" is specified, treat it as the worst value. */
510 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
511 {
512 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
513 return attr->med;
514 else {
515 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
516 return BGP_MED_MAX;
517 else
518 return 0;
519 }
520 }
521
522 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf)
523 {
524 if (pi->addpath_rx_id)
525 sprintf(buf, "path %s (addpath rxid %d)", pi->peer->host,
526 pi->addpath_rx_id);
527 else
528 sprintf(buf, "path %s", pi->peer->host);
529 }
530
531 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
532 */
533 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
534 struct bgp_path_info *exist, int *paths_eq,
535 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
536 char *pfx_buf, afi_t afi, safi_t safi,
537 enum bgp_path_selection_reason *reason)
538 {
539 struct attr *newattr, *existattr;
540 bgp_peer_sort_t new_sort;
541 bgp_peer_sort_t exist_sort;
542 uint32_t new_pref;
543 uint32_t exist_pref;
544 uint32_t new_med;
545 uint32_t exist_med;
546 uint32_t new_weight;
547 uint32_t exist_weight;
548 uint32_t newm, existm;
549 struct in_addr new_id;
550 struct in_addr exist_id;
551 int new_cluster;
552 int exist_cluster;
553 int internal_as_route;
554 int confed_as_route;
555 int ret = 0;
556 char new_buf[PATH_ADDPATH_STR_BUFFER];
557 char exist_buf[PATH_ADDPATH_STR_BUFFER];
558 uint32_t new_mm_seq;
559 uint32_t exist_mm_seq;
560 int nh_cmp;
561 esi_t *exist_esi;
562 esi_t *new_esi;
563 bool same_esi;
564 bool old_proxy;
565 bool new_proxy;
566 bool new_origin, exist_origin;
567
568 *paths_eq = 0;
569
570 /* 0. Null check. */
571 if (new == NULL) {
572 *reason = bgp_path_selection_none;
573 if (debug)
574 zlog_debug("%s: new is NULL", pfx_buf);
575 return 0;
576 }
577
578 if (debug)
579 bgp_path_info_path_with_addpath_rx_str(new, new_buf);
580
581 if (exist == NULL) {
582 *reason = bgp_path_selection_first;
583 if (debug)
584 zlog_debug("%s: %s is the initial bestpath", pfx_buf,
585 new_buf);
586 return 1;
587 }
588
589 if (debug) {
590 bgp_path_info_path_with_addpath_rx_str(exist, exist_buf);
591 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
592 pfx_buf, new_buf, new->flags, exist_buf,
593 exist->flags);
594 }
595
596 newattr = new->attr;
597 existattr = exist->attr;
598
599 /* For EVPN routes, we cannot just go by local vs remote, we have to
600 * look at the MAC mobility sequence number, if present.
601 */
602 if (safi == SAFI_EVPN) {
603 /* This is an error condition described in RFC 7432 Section
604 * 15.2. The RFC
605 * states that in this scenario "the PE MUST alert the operator"
606 * but it
607 * does not state what other action to take. In order to provide
608 * some
609 * consistency in this scenario we are going to prefer the path
610 * with the
611 * sticky flag.
612 */
613 if (newattr->sticky != existattr->sticky) {
614 if (!debug) {
615 prefix2str(
616 bgp_dest_get_prefix(new->net), pfx_buf,
617 sizeof(*pfx_buf) * PREFIX2STR_BUFFER);
618 bgp_path_info_path_with_addpath_rx_str(new,
619 new_buf);
620 bgp_path_info_path_with_addpath_rx_str(
621 exist, exist_buf);
622 }
623
624 if (newattr->sticky && !existattr->sticky) {
625 *reason = bgp_path_selection_evpn_sticky_mac;
626 if (debug)
627 zlog_debug(
628 "%s: %s wins over %s due to sticky MAC flag",
629 pfx_buf, new_buf, exist_buf);
630 return 1;
631 }
632
633 if (!newattr->sticky && existattr->sticky) {
634 *reason = bgp_path_selection_evpn_sticky_mac;
635 if (debug)
636 zlog_debug(
637 "%s: %s loses to %s due to sticky MAC flag",
638 pfx_buf, new_buf, exist_buf);
639 return 0;
640 }
641 }
642
643 new_esi = bgp_evpn_attr_get_esi(newattr);
644 exist_esi = bgp_evpn_attr_get_esi(existattr);
645 if (bgp_evpn_is_esi_valid(new_esi) &&
646 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
647 same_esi = true;
648 } else {
649 same_esi = false;
650 }
651
652 /* If both paths have the same non-zero ES and
653 * one path is local it wins.
654 * PS: Note the local path wins even if the remote
655 * has the higher MM seq. The local path's
656 * MM seq will be fixed up to match the highest
657 * rem seq, subsequently.
658 */
659 if (same_esi) {
660 char esi_buf[ESI_STR_LEN];
661
662 if (bgp_evpn_is_path_local(bgp, new)) {
663 *reason = bgp_path_selection_evpn_local_path;
664 if (debug)
665 zlog_debug(
666 "%s: %s wins over %s as ES %s is same and local",
667 pfx_buf, new_buf, exist_buf,
668 esi_to_str(new_esi, esi_buf,
669 sizeof(esi_buf)));
670 return 1;
671 }
672 if (bgp_evpn_is_path_local(bgp, exist)) {
673 *reason = bgp_path_selection_evpn_local_path;
674 if (debug)
675 zlog_debug(
676 "%s: %s loses to %s as ES %s is same and local",
677 pfx_buf, new_buf, exist_buf,
678 esi_to_str(new_esi, esi_buf,
679 sizeof(esi_buf)));
680 return 0;
681 }
682 }
683
684 new_mm_seq = mac_mobility_seqnum(newattr);
685 exist_mm_seq = mac_mobility_seqnum(existattr);
686
687 if (new_mm_seq > exist_mm_seq) {
688 *reason = bgp_path_selection_evpn_seq;
689 if (debug)
690 zlog_debug(
691 "%s: %s wins over %s due to MM seq %u > %u",
692 pfx_buf, new_buf, exist_buf, new_mm_seq,
693 exist_mm_seq);
694 return 1;
695 }
696
697 if (new_mm_seq < exist_mm_seq) {
698 *reason = bgp_path_selection_evpn_seq;
699 if (debug)
700 zlog_debug(
701 "%s: %s loses to %s due to MM seq %u < %u",
702 pfx_buf, new_buf, exist_buf, new_mm_seq,
703 exist_mm_seq);
704 return 0;
705 }
706
707 /* if the sequence numbers and ESI are the same and one path
708 * is non-proxy it wins (over proxy)
709 */
710 new_proxy = bgp_evpn_attr_is_proxy(newattr);
711 old_proxy = bgp_evpn_attr_is_proxy(existattr);
712 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
713 old_proxy != new_proxy) {
714 if (!new_proxy) {
715 *reason = bgp_path_selection_evpn_non_proxy;
716 if (debug)
717 zlog_debug(
718 "%s: %s wins over %s, same seq/es and non-proxy",
719 pfx_buf, new_buf, exist_buf);
720 return 1;
721 }
722
723 *reason = bgp_path_selection_evpn_non_proxy;
724 if (debug)
725 zlog_debug(
726 "%s: %s loses to %s, same seq/es and non-proxy",
727 pfx_buf, new_buf, exist_buf);
728 return 0;
729 }
730
731 /*
732 * if sequence numbers are the same path with the lowest IP
733 * wins
734 */
735 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
736 if (nh_cmp < 0) {
737 *reason = bgp_path_selection_evpn_lower_ip;
738 if (debug)
739 zlog_debug(
740 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
741 pfx_buf, new_buf, exist_buf, new_mm_seq,
742 &new->attr->nexthop);
743 return 1;
744 }
745 if (nh_cmp > 0) {
746 *reason = bgp_path_selection_evpn_lower_ip;
747 if (debug)
748 zlog_debug(
749 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
750 pfx_buf, new_buf, exist_buf, new_mm_seq,
751 &new->attr->nexthop);
752 return 0;
753 }
754 }
755
756 /* 1. Weight check. */
757 new_weight = newattr->weight;
758 exist_weight = existattr->weight;
759
760 if (new_weight > exist_weight) {
761 *reason = bgp_path_selection_weight;
762 if (debug)
763 zlog_debug("%s: %s wins over %s due to weight %d > %d",
764 pfx_buf, new_buf, exist_buf, new_weight,
765 exist_weight);
766 return 1;
767 }
768
769 if (new_weight < exist_weight) {
770 *reason = bgp_path_selection_weight;
771 if (debug)
772 zlog_debug("%s: %s loses to %s due to weight %d < %d",
773 pfx_buf, new_buf, exist_buf, new_weight,
774 exist_weight);
775 return 0;
776 }
777
778 /* 2. Local preference check. */
779 new_pref = exist_pref = bgp->default_local_pref;
780
781 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
782 new_pref = newattr->local_pref;
783 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
784 exist_pref = existattr->local_pref;
785
786 if (new_pref > exist_pref) {
787 *reason = bgp_path_selection_local_pref;
788 if (debug)
789 zlog_debug(
790 "%s: %s wins over %s due to localpref %d > %d",
791 pfx_buf, new_buf, exist_buf, new_pref,
792 exist_pref);
793 return 1;
794 }
795
796 if (new_pref < exist_pref) {
797 *reason = bgp_path_selection_local_pref;
798 if (debug)
799 zlog_debug(
800 "%s: %s loses to %s due to localpref %d < %d",
801 pfx_buf, new_buf, exist_buf, new_pref,
802 exist_pref);
803 return 0;
804 }
805
806 /* 3. Local route check. We prefer:
807 * - BGP_ROUTE_STATIC
808 * - BGP_ROUTE_AGGREGATE
809 * - BGP_ROUTE_REDISTRIBUTE
810 */
811 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
812 new->sub_type == BGP_ROUTE_IMPORTED);
813 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
814 exist->sub_type == BGP_ROUTE_IMPORTED);
815
816 if (new_origin && !exist_origin) {
817 *reason = bgp_path_selection_local_route;
818 if (debug)
819 zlog_debug(
820 "%s: %s wins over %s due to preferred BGP_ROUTE type",
821 pfx_buf, new_buf, exist_buf);
822 return 1;
823 }
824
825 if (!new_origin && exist_origin) {
826 *reason = bgp_path_selection_local_route;
827 if (debug)
828 zlog_debug(
829 "%s: %s loses to %s due to preferred BGP_ROUTE type",
830 pfx_buf, new_buf, exist_buf);
831 return 0;
832 }
833
834 /* 4. AS path length check. */
835 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
836 int exist_hops = aspath_count_hops(existattr->aspath);
837 int exist_confeds = aspath_count_confeds(existattr->aspath);
838
839 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
840 int aspath_hops;
841
842 aspath_hops = aspath_count_hops(newattr->aspath);
843 aspath_hops += aspath_count_confeds(newattr->aspath);
844
845 if (aspath_hops < (exist_hops + exist_confeds)) {
846 *reason = bgp_path_selection_confed_as_path;
847 if (debug)
848 zlog_debug(
849 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
850 pfx_buf, new_buf, exist_buf,
851 aspath_hops,
852 (exist_hops + exist_confeds));
853 return 1;
854 }
855
856 if (aspath_hops > (exist_hops + exist_confeds)) {
857 *reason = bgp_path_selection_confed_as_path;
858 if (debug)
859 zlog_debug(
860 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
861 pfx_buf, new_buf, exist_buf,
862 aspath_hops,
863 (exist_hops + exist_confeds));
864 return 0;
865 }
866 } else {
867 int newhops = aspath_count_hops(newattr->aspath);
868
869 if (newhops < exist_hops) {
870 *reason = bgp_path_selection_as_path;
871 if (debug)
872 zlog_debug(
873 "%s: %s wins over %s due to aspath hopcount %d < %d",
874 pfx_buf, new_buf, exist_buf,
875 newhops, exist_hops);
876 return 1;
877 }
878
879 if (newhops > exist_hops) {
880 *reason = bgp_path_selection_as_path;
881 if (debug)
882 zlog_debug(
883 "%s: %s loses to %s due to aspath hopcount %d > %d",
884 pfx_buf, new_buf, exist_buf,
885 newhops, exist_hops);
886 return 0;
887 }
888 }
889 }
890
891 /* 5. Origin check. */
892 if (newattr->origin < existattr->origin) {
893 *reason = bgp_path_selection_origin;
894 if (debug)
895 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
896 pfx_buf, new_buf, exist_buf,
897 bgp_origin_long_str[newattr->origin],
898 bgp_origin_long_str[existattr->origin]);
899 return 1;
900 }
901
902 if (newattr->origin > existattr->origin) {
903 *reason = bgp_path_selection_origin;
904 if (debug)
905 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
906 pfx_buf, new_buf, exist_buf,
907 bgp_origin_long_str[newattr->origin],
908 bgp_origin_long_str[existattr->origin]);
909 return 0;
910 }
911
912 /* 6. MED check. */
913 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
914 && aspath_count_hops(existattr->aspath) == 0);
915 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
916 && aspath_count_confeds(existattr->aspath) > 0
917 && aspath_count_hops(newattr->aspath) == 0
918 && aspath_count_hops(existattr->aspath) == 0);
919
920 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
921 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
922 || aspath_cmp_left(newattr->aspath, existattr->aspath)
923 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
924 || internal_as_route) {
925 new_med = bgp_med_value(new->attr, bgp);
926 exist_med = bgp_med_value(exist->attr, bgp);
927
928 if (new_med < exist_med) {
929 *reason = bgp_path_selection_med;
930 if (debug)
931 zlog_debug(
932 "%s: %s wins over %s due to MED %d < %d",
933 pfx_buf, new_buf, exist_buf, new_med,
934 exist_med);
935 return 1;
936 }
937
938 if (new_med > exist_med) {
939 *reason = bgp_path_selection_med;
940 if (debug)
941 zlog_debug(
942 "%s: %s loses to %s due to MED %d > %d",
943 pfx_buf, new_buf, exist_buf, new_med,
944 exist_med);
945 return 0;
946 }
947 }
948
949 /* 7. Peer type check. */
950 new_sort = new->peer->sort;
951 exist_sort = exist->peer->sort;
952
953 if (new_sort == BGP_PEER_EBGP
954 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
955 *reason = bgp_path_selection_peer;
956 if (debug)
957 zlog_debug(
958 "%s: %s wins over %s due to eBGP peer > iBGP peer",
959 pfx_buf, new_buf, exist_buf);
960 return 1;
961 }
962
963 if (exist_sort == BGP_PEER_EBGP
964 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
965 *reason = bgp_path_selection_peer;
966 if (debug)
967 zlog_debug(
968 "%s: %s loses to %s due to iBGP peer < eBGP peer",
969 pfx_buf, new_buf, exist_buf);
970 return 0;
971 }
972
973 /* 8. IGP metric check. */
974 newm = existm = 0;
975
976 if (new->extra)
977 newm = new->extra->igpmetric;
978 if (exist->extra)
979 existm = exist->extra->igpmetric;
980
981 if (newm < existm) {
982 if (debug)
983 zlog_debug(
984 "%s: %s wins over %s due to IGP metric %d < %d",
985 pfx_buf, new_buf, exist_buf, newm, existm);
986 ret = 1;
987 }
988
989 if (newm > existm) {
990 if (debug)
991 zlog_debug(
992 "%s: %s loses to %s due to IGP metric %d > %d",
993 pfx_buf, new_buf, exist_buf, newm, existm);
994 ret = 0;
995 }
996
997 /* 9. Same IGP metric. Compare the cluster list length as
998 representative of IGP hops metric. Rewrite the metric value
999 pair (newm, existm) with the cluster list length. Prefer the
1000 path with smaller cluster list length. */
1001 if (newm == existm) {
1002 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP
1003 && peer_sort_lookup(exist->peer) == BGP_PEER_IBGP
1004 && (mpath_cfg == NULL
1005 || CHECK_FLAG(
1006 mpath_cfg->ibgp_flags,
1007 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN))) {
1008 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1009 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1010
1011 if (newm < existm) {
1012 if (debug)
1013 zlog_debug(
1014 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1015 pfx_buf, new_buf, exist_buf,
1016 newm, existm);
1017 ret = 1;
1018 }
1019
1020 if (newm > existm) {
1021 if (debug)
1022 zlog_debug(
1023 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1024 pfx_buf, new_buf, exist_buf,
1025 newm, existm);
1026 ret = 0;
1027 }
1028 }
1029 }
1030
1031 /* 10. confed-external vs. confed-internal */
1032 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1033 if (new_sort == BGP_PEER_CONFED
1034 && exist_sort == BGP_PEER_IBGP) {
1035 *reason = bgp_path_selection_confed;
1036 if (debug)
1037 zlog_debug(
1038 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1039 pfx_buf, new_buf, exist_buf);
1040 return 1;
1041 }
1042
1043 if (exist_sort == BGP_PEER_CONFED
1044 && new_sort == BGP_PEER_IBGP) {
1045 *reason = bgp_path_selection_confed;
1046 if (debug)
1047 zlog_debug(
1048 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1049 pfx_buf, new_buf, exist_buf);
1050 return 0;
1051 }
1052 }
1053
1054 /* 11. Maximum path check. */
1055 if (newm == existm) {
1056 /* If one path has a label but the other does not, do not treat
1057 * them as equals for multipath
1058 */
1059 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1060 != (exist->extra
1061 && bgp_is_valid_label(&exist->extra->label[0]))) {
1062 if (debug)
1063 zlog_debug(
1064 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1065 pfx_buf, new_buf, exist_buf);
1066 } else if (CHECK_FLAG(bgp->flags,
1067 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1068
1069 /*
1070 * For the two paths, all comparison steps till IGP
1071 * metric
1072 * have succeeded - including AS_PATH hop count. Since
1073 * 'bgp
1074 * bestpath as-path multipath-relax' knob is on, we
1075 * don't need
1076 * an exact match of AS_PATH. Thus, mark the paths are
1077 * equal.
1078 * That will trigger both these paths to get into the
1079 * multipath
1080 * array.
1081 */
1082 *paths_eq = 1;
1083
1084 if (debug)
1085 zlog_debug(
1086 "%s: %s and %s are equal via multipath-relax",
1087 pfx_buf, new_buf, exist_buf);
1088 } else if (new->peer->sort == BGP_PEER_IBGP) {
1089 if (aspath_cmp(new->attr->aspath,
1090 exist->attr->aspath)) {
1091 *paths_eq = 1;
1092
1093 if (debug)
1094 zlog_debug(
1095 "%s: %s and %s are equal via matching aspaths",
1096 pfx_buf, new_buf, exist_buf);
1097 }
1098 } else if (new->peer->as == exist->peer->as) {
1099 *paths_eq = 1;
1100
1101 if (debug)
1102 zlog_debug(
1103 "%s: %s and %s are equal via same remote-as",
1104 pfx_buf, new_buf, exist_buf);
1105 }
1106 } else {
1107 /*
1108 * TODO: If unequal cost ibgp multipath is enabled we can
1109 * mark the paths as equal here instead of returning
1110 */
1111 if (debug) {
1112 if (ret == 1)
1113 zlog_debug(
1114 "%s: %s wins over %s after IGP metric comparison",
1115 pfx_buf, new_buf, exist_buf);
1116 else
1117 zlog_debug(
1118 "%s: %s loses to %s after IGP metric comparison",
1119 pfx_buf, new_buf, exist_buf);
1120 }
1121 *reason = bgp_path_selection_igp_metric;
1122 return ret;
1123 }
1124
1125 /* 12. If both paths are external, prefer the path that was received
1126 first (the oldest one). This step minimizes route-flap, since a
1127 newer path won't displace an older one, even if it was the
1128 preferred route based on the additional decision criteria below. */
1129 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1130 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1131 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1132 *reason = bgp_path_selection_older;
1133 if (debug)
1134 zlog_debug(
1135 "%s: %s wins over %s due to oldest external",
1136 pfx_buf, new_buf, exist_buf);
1137 return 1;
1138 }
1139
1140 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1141 *reason = bgp_path_selection_older;
1142 if (debug)
1143 zlog_debug(
1144 "%s: %s loses to %s due to oldest external",
1145 pfx_buf, new_buf, exist_buf);
1146 return 0;
1147 }
1148 }
1149
1150 /* 13. Router-ID comparision. */
1151 /* If one of the paths is "stale", the corresponding peer router-id will
1152 * be 0 and would always win over the other path. If originator id is
1153 * used for the comparision, it will decide which path is better.
1154 */
1155 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1156 new_id.s_addr = newattr->originator_id.s_addr;
1157 else
1158 new_id.s_addr = new->peer->remote_id.s_addr;
1159 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1160 exist_id.s_addr = existattr->originator_id.s_addr;
1161 else
1162 exist_id.s_addr = exist->peer->remote_id.s_addr;
1163
1164 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1165 *reason = bgp_path_selection_router_id;
1166 if (debug)
1167 zlog_debug(
1168 "%s: %s wins over %s due to Router-ID comparison",
1169 pfx_buf, new_buf, exist_buf);
1170 return 1;
1171 }
1172
1173 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1174 *reason = bgp_path_selection_router_id;
1175 if (debug)
1176 zlog_debug(
1177 "%s: %s loses to %s due to Router-ID comparison",
1178 pfx_buf, new_buf, exist_buf);
1179 return 0;
1180 }
1181
1182 /* 14. Cluster length comparision. */
1183 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1184 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1185
1186 if (new_cluster < exist_cluster) {
1187 *reason = bgp_path_selection_cluster_length;
1188 if (debug)
1189 zlog_debug(
1190 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1191 pfx_buf, new_buf, exist_buf, new_cluster,
1192 exist_cluster);
1193 return 1;
1194 }
1195
1196 if (new_cluster > exist_cluster) {
1197 *reason = bgp_path_selection_cluster_length;
1198 if (debug)
1199 zlog_debug(
1200 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1201 pfx_buf, new_buf, exist_buf, new_cluster,
1202 exist_cluster);
1203 return 0;
1204 }
1205
1206 /* 15. Neighbor address comparision. */
1207 /* Do this only if neither path is "stale" as stale paths do not have
1208 * valid peer information (as the connection may or may not be up).
1209 */
1210 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1211 *reason = bgp_path_selection_stale;
1212 if (debug)
1213 zlog_debug(
1214 "%s: %s wins over %s due to latter path being STALE",
1215 pfx_buf, new_buf, exist_buf);
1216 return 1;
1217 }
1218
1219 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1220 *reason = bgp_path_selection_stale;
1221 if (debug)
1222 zlog_debug(
1223 "%s: %s loses to %s due to former path being STALE",
1224 pfx_buf, new_buf, exist_buf);
1225 return 0;
1226 }
1227
1228 /* locally configured routes to advertise do not have su_remote */
1229 if (new->peer->su_remote == NULL) {
1230 *reason = bgp_path_selection_local_configured;
1231 return 0;
1232 }
1233 if (exist->peer->su_remote == NULL) {
1234 *reason = bgp_path_selection_local_configured;
1235 return 1;
1236 }
1237
1238 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1239
1240 if (ret == 1) {
1241 *reason = bgp_path_selection_neighbor_ip;
1242 if (debug)
1243 zlog_debug(
1244 "%s: %s loses to %s due to Neighor IP comparison",
1245 pfx_buf, new_buf, exist_buf);
1246 return 0;
1247 }
1248
1249 if (ret == -1) {
1250 *reason = bgp_path_selection_neighbor_ip;
1251 if (debug)
1252 zlog_debug(
1253 "%s: %s wins over %s due to Neighor IP comparison",
1254 pfx_buf, new_buf, exist_buf);
1255 return 1;
1256 }
1257
1258 *reason = bgp_path_selection_default;
1259 if (debug)
1260 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1261 pfx_buf, new_buf, exist_buf);
1262
1263 return 1;
1264 }
1265
1266
1267 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1268 struct bgp_path_info *exist, int *paths_eq)
1269 {
1270 enum bgp_path_selection_reason reason;
1271 char pfx_buf[PREFIX2STR_BUFFER];
1272
1273 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1274 AFI_L2VPN, SAFI_EVPN, &reason);
1275 }
1276
1277 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1278 * is preferred, or 0 if they are the same (usually will only occur if
1279 * multipath is enabled
1280 * This version is compatible with */
1281 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1282 struct bgp_path_info *exist, char *pfx_buf,
1283 afi_t afi, safi_t safi,
1284 enum bgp_path_selection_reason *reason)
1285 {
1286 int paths_eq;
1287 int ret;
1288 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1289 afi, safi, reason);
1290
1291 if (paths_eq)
1292 ret = 0;
1293 else {
1294 if (ret == 1)
1295 ret = -1;
1296 else
1297 ret = 1;
1298 }
1299 return ret;
1300 }
1301
1302 static enum filter_type bgp_input_filter(struct peer *peer,
1303 const struct prefix *p,
1304 struct attr *attr, afi_t afi,
1305 safi_t safi)
1306 {
1307 struct bgp_filter *filter;
1308 enum filter_type ret = FILTER_PERMIT;
1309
1310 filter = &peer->filter[afi][safi];
1311
1312 #define FILTER_EXIST_WARN(F, f, filter) \
1313 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1314 zlog_debug("%s: Could not find configured input %s-list %s!", \
1315 peer->host, #f, F##_IN_NAME(filter));
1316
1317 if (DISTRIBUTE_IN_NAME(filter)) {
1318 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1319
1320 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1321 == FILTER_DENY) {
1322 ret = FILTER_DENY;
1323 goto done;
1324 }
1325 }
1326
1327 if (PREFIX_LIST_IN_NAME(filter)) {
1328 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1329
1330 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1331 == PREFIX_DENY) {
1332 ret = FILTER_DENY;
1333 goto done;
1334 }
1335 }
1336
1337 if (FILTER_LIST_IN_NAME(filter)) {
1338 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1339
1340 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1341 == AS_FILTER_DENY) {
1342 ret = FILTER_DENY;
1343 goto done;
1344 }
1345 }
1346
1347 done:
1348 if (frrtrace_enabled(frr_bgp, input_filter)) {
1349 char pfxprint[PREFIX2STR_BUFFER];
1350
1351 prefix2str(p, pfxprint, sizeof(pfxprint));
1352 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1353 ret == FILTER_PERMIT ? "permit" : "deny");
1354 }
1355
1356 return ret;
1357 #undef FILTER_EXIST_WARN
1358 }
1359
1360 static enum filter_type bgp_output_filter(struct peer *peer,
1361 const struct prefix *p,
1362 struct attr *attr, afi_t afi,
1363 safi_t safi)
1364 {
1365 struct bgp_filter *filter;
1366 enum filter_type ret = FILTER_PERMIT;
1367
1368 filter = &peer->filter[afi][safi];
1369
1370 #define FILTER_EXIST_WARN(F, f, filter) \
1371 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1372 zlog_debug("%s: Could not find configured output %s-list %s!", \
1373 peer->host, #f, F##_OUT_NAME(filter));
1374
1375 if (DISTRIBUTE_OUT_NAME(filter)) {
1376 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1377
1378 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1379 == FILTER_DENY) {
1380 ret = FILTER_DENY;
1381 goto done;
1382 }
1383 }
1384
1385 if (PREFIX_LIST_OUT_NAME(filter)) {
1386 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1387
1388 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1389 == PREFIX_DENY) {
1390 ret = FILTER_DENY;
1391 goto done;
1392 }
1393 }
1394
1395 if (FILTER_LIST_OUT_NAME(filter)) {
1396 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1397
1398 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1399 == AS_FILTER_DENY) {
1400 ret = FILTER_DENY;
1401 goto done;
1402 }
1403 }
1404
1405 if (frrtrace_enabled(frr_bgp, output_filter)) {
1406 char pfxprint[PREFIX2STR_BUFFER];
1407
1408 prefix2str(p, pfxprint, sizeof(pfxprint));
1409 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1410 ret == FILTER_PERMIT ? "permit" : "deny");
1411 }
1412
1413 done:
1414 return ret;
1415 #undef FILTER_EXIST_WARN
1416 }
1417
1418 /* If community attribute includes no_export then return 1. */
1419 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1420 {
1421 if (attr->community) {
1422 /* NO_ADVERTISE check. */
1423 if (community_include(attr->community, COMMUNITY_NO_ADVERTISE))
1424 return true;
1425
1426 /* NO_EXPORT check. */
1427 if (peer->sort == BGP_PEER_EBGP
1428 && community_include(attr->community, COMMUNITY_NO_EXPORT))
1429 return true;
1430
1431 /* NO_EXPORT_SUBCONFED check. */
1432 if (peer->sort == BGP_PEER_EBGP
1433 || peer->sort == BGP_PEER_CONFED)
1434 if (community_include(attr->community,
1435 COMMUNITY_NO_EXPORT_SUBCONFED))
1436 return true;
1437 }
1438 return false;
1439 }
1440
1441 /* Route reflection loop check. */
1442 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1443 {
1444 struct in_addr cluster_id;
1445 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1446
1447 if (cluster) {
1448 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1449 cluster_id = peer->bgp->cluster_id;
1450 else
1451 cluster_id = peer->bgp->router_id;
1452
1453 if (cluster_loop_check(cluster, cluster_id))
1454 return true;
1455 }
1456 return false;
1457 }
1458
1459 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1460 struct attr *attr, afi_t afi, safi_t safi,
1461 const char *rmap_name, mpls_label_t *label,
1462 uint32_t num_labels, struct bgp_dest *dest)
1463 {
1464 struct bgp_filter *filter;
1465 struct bgp_path_info rmap_path = { 0 };
1466 struct bgp_path_info_extra extra = { 0 };
1467 route_map_result_t ret;
1468 struct route_map *rmap = NULL;
1469
1470 filter = &peer->filter[afi][safi];
1471
1472 /* Apply default weight value. */
1473 if (peer->weight[afi][safi])
1474 attr->weight = peer->weight[afi][safi];
1475
1476 if (rmap_name) {
1477 rmap = route_map_lookup_by_name(rmap_name);
1478
1479 if (rmap == NULL)
1480 return RMAP_DENY;
1481 } else {
1482 if (ROUTE_MAP_IN_NAME(filter)) {
1483 rmap = ROUTE_MAP_IN(filter);
1484
1485 if (rmap == NULL)
1486 return RMAP_DENY;
1487 }
1488 }
1489
1490 /* Route map apply. */
1491 if (rmap) {
1492 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1493 /* Duplicate current value to new strucutre for modification. */
1494 rmap_path.peer = peer;
1495 rmap_path.attr = attr;
1496 rmap_path.extra = &extra;
1497 rmap_path.net = dest;
1498
1499 extra.num_labels = num_labels;
1500 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1501 memcpy(extra.label, label,
1502 num_labels * sizeof(mpls_label_t));
1503
1504 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1505
1506 /* Apply BGP route map to the attribute. */
1507 ret = route_map_apply(rmap, p, &rmap_path);
1508
1509 peer->rmap_type = 0;
1510
1511 if (ret == RMAP_DENYMATCH)
1512 return RMAP_DENY;
1513 }
1514 return RMAP_PERMIT;
1515 }
1516
1517 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1518 struct attr *attr, afi_t afi, safi_t safi,
1519 const char *rmap_name)
1520 {
1521 struct bgp_path_info rmap_path;
1522 route_map_result_t ret;
1523 struct route_map *rmap = NULL;
1524 uint8_t rmap_type;
1525
1526 /*
1527 * So if we get to this point and have no rmap_name
1528 * we want to just show the output as it currently
1529 * exists.
1530 */
1531 if (!rmap_name)
1532 return RMAP_PERMIT;
1533
1534 /* Apply default weight value. */
1535 if (peer->weight[afi][safi])
1536 attr->weight = peer->weight[afi][safi];
1537
1538 rmap = route_map_lookup_by_name(rmap_name);
1539
1540 /*
1541 * If we have a route map name and we do not find
1542 * the routemap that means we have an implicit
1543 * deny.
1544 */
1545 if (rmap == NULL)
1546 return RMAP_DENY;
1547
1548 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1549 /* Route map apply. */
1550 /* Duplicate current value to new strucutre for modification. */
1551 rmap_path.peer = peer;
1552 rmap_path.attr = attr;
1553
1554 rmap_type = peer->rmap_type;
1555 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1556
1557 /* Apply BGP route map to the attribute. */
1558 ret = route_map_apply(rmap, p, &rmap_path);
1559
1560 peer->rmap_type = rmap_type;
1561
1562 if (ret == RMAP_DENYMATCH)
1563 /*
1564 * caller has multiple error paths with bgp_attr_flush()
1565 */
1566 return RMAP_DENY;
1567
1568 return RMAP_PERMIT;
1569 }
1570
1571 /* If this is an EBGP peer with remove-private-AS */
1572 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1573 struct peer *peer, struct attr *attr)
1574 {
1575 if (peer->sort == BGP_PEER_EBGP
1576 && (peer_af_flag_check(peer, afi, safi,
1577 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1578 || peer_af_flag_check(peer, afi, safi,
1579 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1580 || peer_af_flag_check(peer, afi, safi,
1581 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1582 || peer_af_flag_check(peer, afi, safi,
1583 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1584 // Take action on the entire aspath
1585 if (peer_af_flag_check(peer, afi, safi,
1586 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1587 || peer_af_flag_check(peer, afi, safi,
1588 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1589 if (peer_af_flag_check(
1590 peer, afi, safi,
1591 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1592 attr->aspath = aspath_replace_private_asns(
1593 attr->aspath, bgp->as, peer->as);
1594
1595 // The entire aspath consists of private ASNs so create
1596 // an empty aspath
1597 else if (aspath_private_as_check(attr->aspath))
1598 attr->aspath = aspath_empty_get();
1599
1600 // There are some public and some private ASNs, remove
1601 // the private ASNs
1602 else
1603 attr->aspath = aspath_remove_private_asns(
1604 attr->aspath, peer->as);
1605 }
1606
1607 // 'all' was not specified so the entire aspath must be private
1608 // ASNs
1609 // for us to do anything
1610 else if (aspath_private_as_check(attr->aspath)) {
1611 if (peer_af_flag_check(
1612 peer, afi, safi,
1613 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1614 attr->aspath = aspath_replace_private_asns(
1615 attr->aspath, bgp->as, peer->as);
1616 else
1617 attr->aspath = aspath_empty_get();
1618 }
1619 }
1620 }
1621
1622 /* If this is an EBGP peer with as-override */
1623 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1624 struct peer *peer, struct attr *attr)
1625 {
1626 if (peer->sort == BGP_PEER_EBGP
1627 && peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1628 if (aspath_single_asn_check(attr->aspath, peer->as))
1629 attr->aspath = aspath_replace_specific_asn(
1630 attr->aspath, peer->as, bgp->as);
1631 }
1632 }
1633
1634 void bgp_attr_add_gshut_community(struct attr *attr)
1635 {
1636 struct community *old;
1637 struct community *new;
1638 struct community *merge;
1639 struct community *gshut;
1640
1641 old = attr->community;
1642 gshut = community_str2com("graceful-shutdown");
1643
1644 assert(gshut);
1645
1646 if (old) {
1647 merge = community_merge(community_dup(old), gshut);
1648
1649 if (old->refcnt == 0)
1650 community_free(&old);
1651
1652 new = community_uniq_sort(merge);
1653 community_free(&merge);
1654 } else {
1655 new = community_dup(gshut);
1656 }
1657
1658 community_free(&gshut);
1659 attr->community = new;
1660 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
1661
1662 /* When we add the graceful-shutdown community we must also
1663 * lower the local-preference */
1664 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1665 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1666 }
1667
1668
1669 /* Notify BGP Conditional advertisement scanner process. */
1670 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1671 {
1672 struct peer *temp_peer;
1673 struct peer *peer = SUBGRP_PEER(subgrp);
1674 struct listnode *temp_node, *temp_nnode = NULL;
1675 afi_t afi = SUBGRP_AFI(subgrp);
1676 safi_t safi = SUBGRP_SAFI(subgrp);
1677 struct bgp *bgp = SUBGRP_INST(subgrp);
1678 struct bgp_filter *filter = &peer->filter[afi][safi];
1679
1680 if (!ADVERTISE_MAP_NAME(filter))
1681 return;
1682
1683 for (ALL_LIST_ELEMENTS(bgp->peer, temp_node, temp_nnode, temp_peer)) {
1684 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1685 continue;
1686
1687 if (peer != temp_peer)
1688 continue;
1689
1690 temp_peer->advmap_table_change = true;
1691 break;
1692 }
1693 }
1694
1695
1696 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1697 {
1698 if (family == AF_INET) {
1699 attr->nexthop.s_addr = INADDR_ANY;
1700 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1701 }
1702 if (family == AF_INET6)
1703 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1704 if (family == AF_EVPN)
1705 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1706 }
1707
1708 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1709 struct update_subgroup *subgrp,
1710 const struct prefix *p, struct attr *attr,
1711 bool skip_rmap_check)
1712 {
1713 struct bgp_filter *filter;
1714 struct peer *from;
1715 struct peer *peer;
1716 struct peer *onlypeer;
1717 struct bgp *bgp;
1718 struct attr *piattr;
1719 route_map_result_t ret;
1720 int transparent;
1721 int reflect;
1722 afi_t afi;
1723 safi_t safi;
1724 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1725 bool nh_reset = false;
1726 uint64_t cum_bw;
1727
1728 if (DISABLE_BGP_ANNOUNCE)
1729 return false;
1730
1731 afi = SUBGRP_AFI(subgrp);
1732 safi = SUBGRP_SAFI(subgrp);
1733 peer = SUBGRP_PEER(subgrp);
1734 onlypeer = NULL;
1735 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1736 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1737
1738 from = pi->peer;
1739 filter = &peer->filter[afi][safi];
1740 bgp = SUBGRP_INST(subgrp);
1741 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
1742 : pi->attr;
1743
1744 #ifdef ENABLE_BGP_VNC
1745 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
1746 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
1747 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
1748
1749 /*
1750 * direct and direct_ext type routes originate internally even
1751 * though they can have peer pointers that reference other
1752 * systems
1753 */
1754 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
1755 __func__, p);
1756 samepeer_safe = 1;
1757 }
1758 #endif
1759
1760 if (((afi == AFI_IP) || (afi == AFI_IP6))
1761 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
1762 && (pi->type == ZEBRA_ROUTE_BGP)
1763 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
1764
1765 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1766
1767 samepeer_safe = 1;
1768 }
1769
1770 /* With addpath we may be asked to TX all kinds of paths so make sure
1771 * pi is valid */
1772 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
1773 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
1774 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
1775 return false;
1776 }
1777
1778 /* If this is not the bestpath then check to see if there is an enabled
1779 * addpath
1780 * feature that requires us to advertise it */
1781 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
1782 if (!bgp_addpath_tx_path(peer->addpath_type[afi][safi], pi)) {
1783 return false;
1784 }
1785 }
1786
1787 /* Aggregate-address suppress check. */
1788 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
1789 return false;
1790
1791 /*
1792 * If we are doing VRF 2 VRF leaking via the import
1793 * statement, we want to prevent the route going
1794 * off box as that the RT and RD created are localy
1795 * significant and globaly useless.
1796 */
1797 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
1798 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
1799 return false;
1800
1801 /* If it's labeled safi, make sure the route has a valid label. */
1802 if (safi == SAFI_LABELED_UNICAST) {
1803 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
1804 if (!bgp_is_valid_label(&label)) {
1805 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1806 zlog_debug("u%" PRIu64 ":s%" PRIu64
1807 " %pFX is filtered - no label (%p)",
1808 subgrp->update_group->id, subgrp->id,
1809 p, &label);
1810 return false;
1811 }
1812 }
1813
1814 /* Do not send back route to sender. */
1815 if (onlypeer && from == onlypeer) {
1816 return false;
1817 }
1818
1819 /* Do not send the default route in the BGP table if the neighbor is
1820 * configured for default-originate */
1821 if (CHECK_FLAG(peer->af_flags[afi][safi],
1822 PEER_FLAG_DEFAULT_ORIGINATE)) {
1823 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
1824 return false;
1825 else if (p->family == AF_INET6 && p->prefixlen == 0)
1826 return false;
1827 }
1828
1829 /* Transparency check. */
1830 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
1831 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1832 transparent = 1;
1833 else
1834 transparent = 0;
1835
1836 /* If community is not disabled check the no-export and local. */
1837 if (!transparent && bgp_community_filter(peer, piattr)) {
1838 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1839 zlog_debug("%s: community filter check fail for %pFX",
1840 __func__, p);
1841 return false;
1842 }
1843
1844 /* If the attribute has originator-id and it is same as remote
1845 peer's id. */
1846 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
1847 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
1848 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1849 zlog_debug(
1850 "%s [Update:SEND] %pFX originator-id is same as remote router-id",
1851 onlypeer->host, p);
1852 return false;
1853 }
1854
1855 /* ORF prefix-list filter check */
1856 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
1857 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
1858 || CHECK_FLAG(peer->af_cap[afi][safi],
1859 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
1860 if (peer->orf_plist[afi][safi]) {
1861 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
1862 == PREFIX_DENY) {
1863 if (bgp_debug_update(NULL, p,
1864 subgrp->update_group, 0))
1865 zlog_debug(
1866 "%s [Update:SEND] %pFX is filtered via ORF",
1867 peer->host, p);
1868 return false;
1869 }
1870 }
1871
1872 /* Output filter check. */
1873 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
1874 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1875 zlog_debug("%s [Update:SEND] %pFX is filtered",
1876 peer->host, p);
1877 return false;
1878 }
1879
1880 /* AS path loop check. */
1881 if (onlypeer && onlypeer->as_path_loop_detection
1882 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
1883 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1884 zlog_debug(
1885 "%s [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
1886 onlypeer->host, onlypeer->as);
1887 return false;
1888 }
1889
1890 /* If we're a CONFED we need to loop check the CONFED ID too */
1891 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1892 if (aspath_loop_check(piattr->aspath, bgp->confed_id)) {
1893 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1894 zlog_debug(
1895 "%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
1896 peer->host, bgp->confed_id);
1897 return false;
1898 }
1899 }
1900
1901 /* Route-Reflect check. */
1902 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
1903 reflect = 1;
1904 else
1905 reflect = 0;
1906
1907 /* IBGP reflection check. */
1908 if (reflect && !samepeer_safe) {
1909 /* A route from a Client peer. */
1910 if (CHECK_FLAG(from->af_flags[afi][safi],
1911 PEER_FLAG_REFLECTOR_CLIENT)) {
1912 /* Reflect to all the Non-Client peers and also to the
1913 Client peers other than the originator. Originator
1914 check
1915 is already done. So there is noting to do. */
1916 /* no bgp client-to-client reflection check. */
1917 if (CHECK_FLAG(bgp->flags,
1918 BGP_FLAG_NO_CLIENT_TO_CLIENT))
1919 if (CHECK_FLAG(peer->af_flags[afi][safi],
1920 PEER_FLAG_REFLECTOR_CLIENT))
1921 return false;
1922 } else {
1923 /* A route from a Non-client peer. Reflect to all other
1924 clients. */
1925 if (!CHECK_FLAG(peer->af_flags[afi][safi],
1926 PEER_FLAG_REFLECTOR_CLIENT))
1927 return false;
1928 }
1929 }
1930
1931 /* For modify attribute, copy it to temporary structure. */
1932 *attr = *piattr;
1933
1934 /* If local-preference is not set. */
1935 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
1936 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
1937 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1938 attr->local_pref = bgp->default_local_pref;
1939 }
1940
1941 /* If originator-id is not set and the route is to be reflected,
1942 set the originator id */
1943 if (reflect
1944 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
1945 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
1946 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
1947 }
1948
1949 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
1950 */
1951 if (peer->sort == BGP_PEER_EBGP
1952 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
1953 if (from != bgp->peer_self && !transparent
1954 && !CHECK_FLAG(peer->af_flags[afi][safi],
1955 PEER_FLAG_MED_UNCHANGED))
1956 attr->flag &=
1957 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
1958 }
1959
1960 /* Since the nexthop attribute can vary per peer, it is not explicitly
1961 * set
1962 * in announce check, only certain flags and length (or number of
1963 * nexthops
1964 * -- for IPv6/MP_REACH) are set here in order to guide the update
1965 * formation
1966 * code in setting the nexthop(s) on a per peer basis in
1967 * reformat_peer().
1968 * Typically, the source nexthop in the attribute is preserved but in
1969 * the
1970 * scenarios where we know it will always be overwritten, we reset the
1971 * nexthop to "0" in an attempt to achieve better Update packing. An
1972 * example of this is when a prefix from each of 2 IBGP peers needs to
1973 * be
1974 * announced to an EBGP peer (and they have the same attributes barring
1975 * their nexthop).
1976 */
1977 if (reflect)
1978 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
1979
1980 #define NEXTHOP_IS_V6 \
1981 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
1982 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
1983 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
1984 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1985
1986 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
1987 * if
1988 * the peer (group) is configured to receive link-local nexthop
1989 * unchanged
1990 * and it is available in the prefix OR we're not reflecting the route,
1991 * link-local nexthop address is valid and
1992 * the peer (group) to whom we're going to announce is on a shared
1993 * network
1994 * and this is either a self-originated route or the peer is EBGP.
1995 * By checking if nexthop LL address is valid we are sure that
1996 * we do not announce LL address as `::`.
1997 */
1998 if (NEXTHOP_IS_V6) {
1999 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2000 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2001 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2002 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2003 || (!reflect
2004 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2005 && peer->shared_network
2006 && (from == bgp->peer_self
2007 || peer->sort == BGP_PEER_EBGP))) {
2008 attr->mp_nexthop_len =
2009 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2010 }
2011
2012 /* Clear off link-local nexthop in source, whenever it is not
2013 * needed to
2014 * ensure more prefixes share the same attribute for
2015 * announcement.
2016 */
2017 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2018 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2019 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2020 }
2021
2022 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2023 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2024
2025 /* Route map & unsuppress-map apply. */
2026 if (!skip_rmap_check
2027 && (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2028 struct bgp_path_info rmap_path = {0};
2029 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2030 struct attr dummy_attr = {0};
2031
2032 /* Fill temp path_info */
2033 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2034 pi, peer, attr);
2035
2036 /* don't confuse inbound and outbound setting */
2037 RESET_FLAG(attr->rmap_change_flags);
2038
2039 /*
2040 * The route reflector is not allowed to modify the attributes
2041 * of the reflected IBGP routes unless explicitly allowed.
2042 */
2043 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2044 && !CHECK_FLAG(bgp->flags,
2045 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2046 dummy_attr = *attr;
2047 rmap_path.attr = &dummy_attr;
2048 }
2049
2050 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2051
2052 if (bgp_path_suppressed(pi))
2053 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2054 &rmap_path);
2055 else
2056 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2057 &rmap_path);
2058
2059 peer->rmap_type = 0;
2060
2061 if (ret == RMAP_DENYMATCH) {
2062 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2063 zlog_debug(
2064 "%s [Update:SEND] %pFX is filtered by route-map",
2065 peer->host, p);
2066
2067 bgp_attr_flush(attr);
2068 return false;
2069 }
2070 }
2071
2072 /* RFC 8212 to prevent route leaks.
2073 * This specification intends to improve this situation by requiring the
2074 * explicit configuration of both BGP Import and Export Policies for any
2075 * External BGP (EBGP) session such as customers, peers, or
2076 * confederation boundaries for all enabled address families. Through
2077 * codification of the aforementioned requirement, operators will
2078 * benefit from consistent behavior across different BGP
2079 * implementations.
2080 */
2081 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2082 if (!bgp_outbound_policy_exists(peer, filter))
2083 return false;
2084
2085 /* draft-ietf-idr-deprecate-as-set-confed-set
2086 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2087 * Eventually, This document (if approved) updates RFC 4271
2088 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2089 * and obsoletes RFC 6472.
2090 */
2091 if (peer->bgp->reject_as_sets)
2092 if (aspath_check_as_sets(attr->aspath))
2093 return false;
2094
2095 /* Codification of AS 0 Processing */
2096 if (aspath_check_as_zero(attr->aspath))
2097 return false;
2098
2099 if (bgp_in_graceful_shutdown(bgp)) {
2100 if (peer->sort == BGP_PEER_IBGP
2101 || peer->sort == BGP_PEER_CONFED) {
2102 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2103 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2104 } else {
2105 bgp_attr_add_gshut_community(attr);
2106 }
2107 }
2108
2109 /* After route-map has been applied, we check to see if the nexthop to
2110 * be carried in the attribute (that is used for the announcement) can
2111 * be cleared off or not. We do this in all cases where we would be
2112 * setting the nexthop to "ourselves". For IPv6, we only need to
2113 * consider
2114 * the global nexthop here; the link-local nexthop would have been
2115 * cleared
2116 * already, and if not, it is required by the update formation code.
2117 * Also see earlier comments in this function.
2118 */
2119 /*
2120 * If route-map has performed some operation on the nexthop or the peer
2121 * configuration says to pass it unchanged, we cannot reset the nexthop
2122 * here, so only attempt to do it if these aren't true. Note that the
2123 * route-map handler itself might have cleared the nexthop, if for
2124 * example,
2125 * it is configured as 'peer-address'.
2126 */
2127 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2128 piattr->rmap_change_flags)
2129 && !transparent
2130 && !CHECK_FLAG(peer->af_flags[afi][safi],
2131 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2132 /* We can reset the nexthop, if setting (or forcing) it to
2133 * 'self' */
2134 if (CHECK_FLAG(peer->af_flags[afi][safi],
2135 PEER_FLAG_NEXTHOP_SELF)
2136 || CHECK_FLAG(peer->af_flags[afi][safi],
2137 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2138 if (!reflect
2139 || CHECK_FLAG(peer->af_flags[afi][safi],
2140 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2141 subgroup_announce_reset_nhop(
2142 (peer_cap_enhe(peer, afi, safi)
2143 ? AF_INET6
2144 : p->family),
2145 attr);
2146 nh_reset = true;
2147 }
2148 } else if (peer->sort == BGP_PEER_EBGP) {
2149 /* Can also reset the nexthop if announcing to EBGP, but
2150 * only if
2151 * no peer in the subgroup is on a shared subnet.
2152 * Note: 3rd party nexthop currently implemented for
2153 * IPv4 only.
2154 */
2155 if ((p->family == AF_INET) &&
2156 (!bgp_subgrp_multiaccess_check_v4(
2157 piattr->nexthop,
2158 subgrp, from))) {
2159 subgroup_announce_reset_nhop(
2160 (peer_cap_enhe(peer, afi, safi)
2161 ? AF_INET6
2162 : p->family),
2163 attr);
2164 nh_reset = true;
2165 }
2166
2167 if ((p->family == AF_INET6) &&
2168 (!bgp_subgrp_multiaccess_check_v6(
2169 piattr->mp_nexthop_global,
2170 subgrp, from))) {
2171 subgroup_announce_reset_nhop(
2172 (peer_cap_enhe(peer, afi, safi)
2173 ? AF_INET6
2174 : p->family),
2175 attr);
2176 nh_reset = true;
2177 }
2178
2179
2180
2181 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2182 /*
2183 * This flag is used for leaked vpn-vrf routes
2184 */
2185 int family = p->family;
2186
2187 if (peer_cap_enhe(peer, afi, safi))
2188 family = AF_INET6;
2189
2190 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2191 zlog_debug(
2192 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
2193 __func__, family2str(family));
2194 subgroup_announce_reset_nhop(family, attr);
2195 nh_reset = true;
2196 }
2197 }
2198
2199 /* If IPv6/MP and nexthop does not have any override and happens
2200 * to
2201 * be a link-local address, reset it so that we don't pass along
2202 * the
2203 * source's link-local IPv6 address to recipients who may not be
2204 * on
2205 * the same interface.
2206 */
2207 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2208 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2209 subgroup_announce_reset_nhop(AF_INET6, attr);
2210 nh_reset = true;
2211 }
2212 }
2213
2214 /*
2215 * When the next hop is set to ourselves, if all multipaths have
2216 * link-bandwidth announce the cumulative bandwidth as that makes
2217 * the most sense. However, don't modify if the link-bandwidth has
2218 * been explicitly set by user policy.
2219 */
2220 if (nh_reset &&
2221 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2222 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2223 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2224 attr->ecommunity = ecommunity_replace_linkbw(
2225 bgp->as, attr->ecommunity, cum_bw);
2226
2227 return true;
2228 }
2229
2230 static int bgp_route_select_timer_expire(struct thread *thread)
2231 {
2232 struct afi_safi_info *info;
2233 afi_t afi;
2234 safi_t safi;
2235 struct bgp *bgp;
2236
2237 info = THREAD_ARG(thread);
2238 afi = info->afi;
2239 safi = info->safi;
2240 bgp = info->bgp;
2241
2242 if (BGP_DEBUG(update, UPDATE_OUT))
2243 zlog_debug("afi %d, safi %d : route select timer expired", afi,
2244 safi);
2245
2246 bgp->gr_info[afi][safi].t_route_select = NULL;
2247
2248 XFREE(MTYPE_TMP, info);
2249
2250 /* Best path selection */
2251 return bgp_best_path_select_defer(bgp, afi, safi);
2252 }
2253
2254 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2255 struct bgp_maxpaths_cfg *mpath_cfg,
2256 struct bgp_path_info_pair *result, afi_t afi,
2257 safi_t safi)
2258 {
2259 struct bgp_path_info *new_select;
2260 struct bgp_path_info *old_select;
2261 struct bgp_path_info *pi;
2262 struct bgp_path_info *pi1;
2263 struct bgp_path_info *pi2;
2264 struct bgp_path_info *nextpi = NULL;
2265 int paths_eq, do_mpath, debug;
2266 struct list mp_list;
2267 char pfx_buf[PREFIX2STR_BUFFER];
2268 char path_buf[PATH_ADDPATH_STR_BUFFER];
2269
2270 bgp_mp_list_init(&mp_list);
2271 do_mpath =
2272 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2273
2274 debug = bgp_debug_bestpath(dest);
2275
2276 if (debug)
2277 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2278
2279 dest->reason = bgp_path_selection_none;
2280 /* bgp deterministic-med */
2281 new_select = NULL;
2282 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2283
2284 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2285 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2286 pi1 = pi1->next)
2287 bgp_path_info_unset_flag(dest, pi1,
2288 BGP_PATH_DMED_SELECTED);
2289
2290 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2291 pi1 = pi1->next) {
2292 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2293 continue;
2294 if (BGP_PATH_HOLDDOWN(pi1))
2295 continue;
2296 if (pi1->peer != bgp->peer_self)
2297 if (pi1->peer->status != Established)
2298 continue;
2299
2300 new_select = pi1;
2301 if (pi1->next) {
2302 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2303 if (CHECK_FLAG(pi2->flags,
2304 BGP_PATH_DMED_CHECK))
2305 continue;
2306 if (BGP_PATH_HOLDDOWN(pi2))
2307 continue;
2308 if (pi2->peer != bgp->peer_self
2309 && !CHECK_FLAG(
2310 pi2->peer->sflags,
2311 PEER_STATUS_NSF_WAIT))
2312 if (pi2->peer->status
2313 != Established)
2314 continue;
2315
2316 if (!aspath_cmp_left(pi1->attr->aspath,
2317 pi2->attr->aspath)
2318 && !aspath_cmp_left_confed(
2319 pi1->attr->aspath,
2320 pi2->attr->aspath))
2321 continue;
2322
2323 if (bgp_path_info_cmp(
2324 bgp, pi2, new_select,
2325 &paths_eq, mpath_cfg, debug,
2326 pfx_buf, afi, safi,
2327 &dest->reason)) {
2328 bgp_path_info_unset_flag(
2329 dest, new_select,
2330 BGP_PATH_DMED_SELECTED);
2331 new_select = pi2;
2332 }
2333
2334 bgp_path_info_set_flag(
2335 dest, pi2, BGP_PATH_DMED_CHECK);
2336 }
2337 }
2338 bgp_path_info_set_flag(dest, new_select,
2339 BGP_PATH_DMED_CHECK);
2340 bgp_path_info_set_flag(dest, new_select,
2341 BGP_PATH_DMED_SELECTED);
2342
2343 if (debug) {
2344 bgp_path_info_path_with_addpath_rx_str(
2345 new_select, path_buf);
2346 zlog_debug(
2347 "%pBD: %s is the bestpath from AS %u",
2348 dest, path_buf,
2349 aspath_get_first_as(
2350 new_select->attr->aspath));
2351 }
2352 }
2353 }
2354
2355 /* Check old selected route and new selected route. */
2356 old_select = NULL;
2357 new_select = NULL;
2358 for (pi = bgp_dest_get_bgp_path_info(dest);
2359 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2360 enum bgp_path_selection_reason reason;
2361
2362 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2363 old_select = pi;
2364
2365 if (BGP_PATH_HOLDDOWN(pi)) {
2366 /* reap REMOVED routes, if needs be
2367 * selected route must stay for a while longer though
2368 */
2369 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2370 && (pi != old_select))
2371 bgp_path_info_reap(dest, pi);
2372
2373 if (debug)
2374 zlog_debug("%s: pi %p in holddown", __func__,
2375 pi);
2376
2377 continue;
2378 }
2379
2380 if (pi->peer && pi->peer != bgp->peer_self
2381 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2382 if (pi->peer->status != Established) {
2383
2384 if (debug)
2385 zlog_debug(
2386 "%s: pi %p non self peer %s not estab state",
2387 __func__, pi, pi->peer->host);
2388
2389 continue;
2390 }
2391
2392 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2393 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2394 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2395 if (debug)
2396 zlog_debug("%s: pi %p dmed", __func__, pi);
2397 continue;
2398 }
2399
2400 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2401
2402 reason = dest->reason;
2403 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2404 debug, pfx_buf, afi, safi,
2405 &dest->reason)) {
2406 if (new_select == NULL &&
2407 reason != bgp_path_selection_none)
2408 dest->reason = reason;
2409 new_select = pi;
2410 }
2411 }
2412
2413 /* Now that we know which path is the bestpath see if any of the other
2414 * paths
2415 * qualify as multipaths
2416 */
2417 if (debug) {
2418 if (new_select)
2419 bgp_path_info_path_with_addpath_rx_str(new_select,
2420 path_buf);
2421 else
2422 snprintf(path_buf, sizeof(path_buf), "NONE");
2423 zlog_debug(
2424 "%pBD: After path selection, newbest is %s oldbest was %s",
2425 dest, path_buf,
2426 old_select ? old_select->peer->host : "NONE");
2427 }
2428
2429 if (do_mpath && new_select) {
2430 for (pi = bgp_dest_get_bgp_path_info(dest);
2431 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2432
2433 if (debug)
2434 bgp_path_info_path_with_addpath_rx_str(
2435 pi, path_buf);
2436
2437 if (pi == new_select) {
2438 if (debug)
2439 zlog_debug(
2440 "%pBD: %s is the bestpath, add to the multipath list",
2441 dest, path_buf);
2442 bgp_mp_list_add(&mp_list, pi);
2443 continue;
2444 }
2445
2446 if (BGP_PATH_HOLDDOWN(pi))
2447 continue;
2448
2449 if (pi->peer && pi->peer != bgp->peer_self
2450 && !CHECK_FLAG(pi->peer->sflags,
2451 PEER_STATUS_NSF_WAIT))
2452 if (pi->peer->status != Established)
2453 continue;
2454
2455 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2456 if (debug)
2457 zlog_debug(
2458 "%pBD: %s has the same nexthop as the bestpath, skip it",
2459 dest, path_buf);
2460 continue;
2461 }
2462
2463 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2464 mpath_cfg, debug, pfx_buf, afi, safi,
2465 &dest->reason);
2466
2467 if (paths_eq) {
2468 if (debug)
2469 zlog_debug(
2470 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2471 dest, path_buf);
2472 bgp_mp_list_add(&mp_list, pi);
2473 }
2474 }
2475 }
2476
2477 bgp_path_info_mpath_update(dest, new_select, old_select, &mp_list,
2478 mpath_cfg);
2479 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2480 bgp_mp_list_clear(&mp_list);
2481
2482 bgp_addpath_update_ids(bgp, dest, afi, safi);
2483
2484 result->old = old_select;
2485 result->new = new_select;
2486
2487 return;
2488 }
2489
2490 /*
2491 * A new route/change in bestpath of an existing route. Evaluate the path
2492 * for advertisement to the subgroup.
2493 */
2494 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2495 struct bgp_path_info *selected,
2496 struct bgp_dest *dest,
2497 uint32_t addpath_tx_id)
2498 {
2499 const struct prefix *p;
2500 struct peer *onlypeer;
2501 struct attr attr;
2502 afi_t afi;
2503 safi_t safi;
2504 struct bgp *bgp;
2505 bool advertise;
2506
2507 p = bgp_dest_get_prefix(dest);
2508 afi = SUBGRP_AFI(subgrp);
2509 safi = SUBGRP_SAFI(subgrp);
2510 bgp = SUBGRP_INST(subgrp);
2511 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2512 : NULL);
2513
2514 if (BGP_DEBUG(update, UPDATE_OUT))
2515 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2516
2517 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2518 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2519 PEER_STATUS_ORF_WAIT_REFRESH))
2520 return;
2521
2522 memset(&attr, 0, sizeof(struct attr));
2523 /* It's initialized in bgp_announce_check() */
2524
2525 /* Announcement to the subgroup. If the route is filtered withdraw it.
2526 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2527 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2528 * route
2529 */
2530 advertise = bgp_check_advertise(bgp, dest);
2531
2532 if (selected) {
2533 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2534 false)) {
2535 /* Route is selected, if the route is already installed
2536 * in FIB, then it is advertised
2537 */
2538 if (advertise)
2539 bgp_adj_out_set_subgroup(dest, subgrp, &attr,
2540 selected);
2541 } else
2542 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2543 addpath_tx_id);
2544 }
2545
2546 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2547 else {
2548 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2549 }
2550 }
2551
2552 /*
2553 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2554 * This is called at the end of route processing.
2555 */
2556 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2557 {
2558 struct bgp_path_info *pi;
2559
2560 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2561 if (BGP_PATH_HOLDDOWN(pi))
2562 continue;
2563 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2564 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2565 }
2566 }
2567
2568 /*
2569 * Has the route changed from the RIB's perspective? This is invoked only
2570 * if the route selection returns the same best route as earlier - to
2571 * determine if we need to update zebra or not.
2572 */
2573 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2574 {
2575 struct bgp_path_info *mpinfo;
2576
2577 /* If this is multipath, check all selected paths for any nexthop
2578 * change or attribute change. Some attribute changes (e.g., community)
2579 * aren't of relevance to the RIB, but we'll update zebra to ensure
2580 * we handle the case of BGP nexthop change. This is the behavior
2581 * when the best path has an attribute change anyway.
2582 */
2583 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2584 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2585 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2586 return true;
2587
2588 /*
2589 * If this is multipath, check all selected paths for any nexthop change
2590 */
2591 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2592 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2593 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2594 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2595 return true;
2596 }
2597
2598 /* Nothing has changed from the RIB's perspective. */
2599 return false;
2600 }
2601
2602 struct bgp_process_queue {
2603 struct bgp *bgp;
2604 STAILQ_HEAD(, bgp_dest) pqueue;
2605 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2606 unsigned int flags;
2607 unsigned int queued;
2608 };
2609
2610 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
2611 safi_t safi, struct bgp_dest *dest,
2612 struct bgp_path_info *new_select,
2613 struct bgp_path_info *old_select)
2614 {
2615 const struct prefix *p = bgp_dest_get_prefix(dest);
2616
2617 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
2618 return;
2619
2620 if (advertise_type5_routes(bgp, afi) && new_select
2621 && is_route_injectable_into_evpn(new_select)) {
2622
2623 /* apply the route-map */
2624 if (bgp->adv_cmd_rmap[afi][safi].map) {
2625 route_map_result_t ret;
2626 struct bgp_path_info rmap_path;
2627 struct bgp_path_info_extra rmap_path_extra;
2628 struct attr dummy_attr;
2629
2630 dummy_attr = *new_select->attr;
2631
2632 /* Fill temp path_info */
2633 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
2634 new_select, new_select->peer,
2635 &dummy_attr);
2636
2637 RESET_FLAG(dummy_attr.rmap_change_flags);
2638
2639 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
2640 p, &rmap_path);
2641
2642 if (ret == RMAP_DENYMATCH) {
2643 bgp_attr_flush(&dummy_attr);
2644 bgp_evpn_withdraw_type5_route(bgp, p, afi,
2645 safi);
2646 } else
2647 bgp_evpn_advertise_type5_route(
2648 bgp, p, &dummy_attr, afi, safi);
2649 } else {
2650 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
2651 afi, safi);
2652 }
2653 } else if (advertise_type5_routes(bgp, afi) && old_select
2654 && is_route_injectable_into_evpn(old_select))
2655 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
2656 }
2657
2658 /*
2659 * old_select = The old best path
2660 * new_select = the new best path
2661 *
2662 * if (!old_select && new_select)
2663 * We are sending new information on.
2664 *
2665 * if (old_select && new_select) {
2666 * if (new_select != old_select)
2667 * We have a new best path send a change
2668 * else
2669 * We've received a update with new attributes that needs
2670 * to be passed on.
2671 * }
2672 *
2673 * if (old_select && !new_select)
2674 * We have no eligible route that we can announce or the rn
2675 * is being removed.
2676 */
2677 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
2678 afi_t afi, safi_t safi)
2679 {
2680 struct bgp_path_info *new_select;
2681 struct bgp_path_info *old_select;
2682 struct bgp_path_info_pair old_and_new;
2683 int debug = 0;
2684
2685 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
2686 if (dest)
2687 debug = bgp_debug_bestpath(dest);
2688 if (debug)
2689 zlog_debug(
2690 "%s: bgp delete in progress, ignoring event, p=%pBD",
2691 __func__, dest);
2692 return;
2693 }
2694 /* Is it end of initial update? (after startup) */
2695 if (!dest) {
2696 quagga_timestamp(3, bgp->update_delay_zebra_resume_time,
2697 sizeof(bgp->update_delay_zebra_resume_time));
2698
2699 bgp->main_zebra_update_hold = 0;
2700 FOREACH_AFI_SAFI (afi, safi) {
2701 if (bgp_fibupd_safi(safi))
2702 bgp_zebra_announce_table(bgp, afi, safi);
2703 }
2704 bgp->main_peers_update_hold = 0;
2705
2706 bgp_start_routeadv(bgp);
2707 return;
2708 }
2709
2710 const struct prefix *p = bgp_dest_get_prefix(dest);
2711
2712 debug = bgp_debug_bestpath(dest);
2713 if (debug)
2714 zlog_debug("%s: p=%pBD afi=%s, safi=%s start", __func__, dest,
2715 afi2str(afi), safi2str(safi));
2716
2717 /* The best path calculation for the route is deferred if
2718 * BGP_NODE_SELECT_DEFER is set
2719 */
2720 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
2721 if (BGP_DEBUG(update, UPDATE_OUT))
2722 zlog_debug("SELECT_DEFER flag set for route %p", dest);
2723 return;
2724 }
2725
2726 /* Best path selection. */
2727 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
2728 afi, safi);
2729 old_select = old_and_new.old;
2730 new_select = old_and_new.new;
2731
2732 /* Do we need to allocate or free labels?
2733 * Right now, since we only deal with per-prefix labels, it is not
2734 * necessary to do this upon changes to best path. Exceptions:
2735 * - label index has changed -> recalculate resulting label
2736 * - path_info sub_type changed -> switch to/from implicit-null
2737 * - no valid label (due to removed static label binding) -> get new one
2738 */
2739 if (bgp->allocate_mpls_labels[afi][safi]) {
2740 if (new_select) {
2741 if (!old_select
2742 || bgp_label_index_differs(new_select, old_select)
2743 || new_select->sub_type != old_select->sub_type
2744 || !bgp_is_valid_label(&dest->local_label)) {
2745 /* Enforced penultimate hop popping:
2746 * implicit-null for local routes, aggregate
2747 * and redistributed routes
2748 */
2749 if (new_select->sub_type == BGP_ROUTE_STATIC
2750 || new_select->sub_type
2751 == BGP_ROUTE_AGGREGATE
2752 || new_select->sub_type
2753 == BGP_ROUTE_REDISTRIBUTE) {
2754 if (CHECK_FLAG(
2755 dest->flags,
2756 BGP_NODE_REGISTERED_FOR_LABEL)
2757 || CHECK_FLAG(
2758 dest->flags,
2759 BGP_NODE_LABEL_REQUESTED))
2760 bgp_unregister_for_label(dest);
2761 label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1,
2762 &dest->local_label);
2763 bgp_set_valid_label(&dest->local_label);
2764 } else
2765 bgp_register_for_label(dest,
2766 new_select);
2767 }
2768 } else if (CHECK_FLAG(dest->flags,
2769 BGP_NODE_REGISTERED_FOR_LABEL)
2770 || CHECK_FLAG(dest->flags,
2771 BGP_NODE_LABEL_REQUESTED)) {
2772 bgp_unregister_for_label(dest);
2773 }
2774 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
2775 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
2776 bgp_unregister_for_label(dest);
2777 }
2778
2779 if (debug)
2780 zlog_debug(
2781 "%s: p=%pBD afi=%s, safi=%s, old_select=%p, new_select=%p",
2782 __func__, dest, afi2str(afi), safi2str(safi),
2783 old_select, new_select);
2784
2785 /* If best route remains the same and this is not due to user-initiated
2786 * clear, see exactly what needs to be done.
2787 */
2788 if (old_select && old_select == new_select
2789 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
2790 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2791 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
2792 if (bgp_zebra_has_route_changed(old_select)) {
2793 #ifdef ENABLE_BGP_VNC
2794 vnc_import_bgp_add_route(bgp, p, old_select);
2795 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
2796 #endif
2797 if (bgp_fibupd_safi(safi)
2798 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2799
2800 if (new_select->type == ZEBRA_ROUTE_BGP
2801 && (new_select->sub_type == BGP_ROUTE_NORMAL
2802 || new_select->sub_type
2803 == BGP_ROUTE_IMPORTED))
2804
2805 bgp_zebra_announce(dest, p, old_select,
2806 bgp, afi, safi);
2807 }
2808 }
2809
2810 /* If there is a change of interest to peers, reannounce the
2811 * route. */
2812 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2813 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
2814 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
2815 group_announce_route(bgp, afi, safi, dest, new_select);
2816
2817 /* unicast routes must also be annouced to
2818 * labeled-unicast update-groups */
2819 if (safi == SAFI_UNICAST)
2820 group_announce_route(bgp, afi,
2821 SAFI_LABELED_UNICAST, dest,
2822 new_select);
2823
2824 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
2825 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
2826 }
2827
2828 /* advertise/withdraw type-5 routes */
2829 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
2830 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
2831 bgp_process_evpn_route_injection(
2832 bgp, afi, safi, dest, old_select, old_select);
2833
2834 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
2835 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
2836 bgp_zebra_clear_route_change_flags(dest);
2837 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
2838 return;
2839 }
2840
2841 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2842 */
2843 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
2844
2845 /* bestpath has changed; bump version */
2846 if (old_select || new_select) {
2847 bgp_bump_version(dest);
2848
2849 if (!bgp->t_rmap_def_originate_eval) {
2850 bgp_lock(bgp);
2851 thread_add_timer(
2852 bm->master,
2853 update_group_refresh_default_originate_route_map,
2854 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
2855 &bgp->t_rmap_def_originate_eval);
2856 }
2857 }
2858
2859 if (old_select)
2860 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
2861 if (new_select) {
2862 if (debug)
2863 zlog_debug("%s: setting SELECTED flag", __func__);
2864 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
2865 bgp_path_info_unset_flag(dest, new_select,
2866 BGP_PATH_ATTR_CHANGED);
2867 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
2868 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
2869 }
2870
2871 #ifdef ENABLE_BGP_VNC
2872 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
2873 if (old_select != new_select) {
2874 if (old_select) {
2875 vnc_import_bgp_exterior_del_route(bgp, p,
2876 old_select);
2877 vnc_import_bgp_del_route(bgp, p, old_select);
2878 }
2879 if (new_select) {
2880 vnc_import_bgp_exterior_add_route(bgp, p,
2881 new_select);
2882 vnc_import_bgp_add_route(bgp, p, new_select);
2883 }
2884 }
2885 }
2886 #endif
2887
2888 group_announce_route(bgp, afi, safi, dest, new_select);
2889
2890 /* unicast routes must also be annouced to labeled-unicast update-groups
2891 */
2892 if (safi == SAFI_UNICAST)
2893 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
2894 new_select);
2895
2896 /* FIB update. */
2897 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
2898 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2899 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
2900 && (new_select->sub_type == BGP_ROUTE_NORMAL
2901 || new_select->sub_type == BGP_ROUTE_AGGREGATE
2902 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
2903
2904 /* if this is an evpn imported type-5 prefix,
2905 * we need to withdraw the route first to clear
2906 * the nh neigh and the RMAC entry.
2907 */
2908 if (old_select &&
2909 is_route_parent_evpn(old_select))
2910 bgp_zebra_withdraw(p, old_select, bgp, safi);
2911
2912 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
2913 } else {
2914 /* Withdraw the route from the kernel. */
2915 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
2916 && (old_select->sub_type == BGP_ROUTE_NORMAL
2917 || old_select->sub_type == BGP_ROUTE_AGGREGATE
2918 || old_select->sub_type == BGP_ROUTE_IMPORTED))
2919
2920 bgp_zebra_withdraw(p, old_select, bgp, safi);
2921 }
2922 }
2923
2924 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
2925 old_select);
2926
2927 /* Clear any route change flags. */
2928 bgp_zebra_clear_route_change_flags(dest);
2929
2930 /* Reap old select bgp_path_info, if it has been removed */
2931 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
2932 bgp_path_info_reap(dest, old_select);
2933
2934 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
2935 return;
2936 }
2937
2938 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
2939 int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
2940 {
2941 struct bgp_dest *dest;
2942 int cnt = 0;
2943 struct afi_safi_info *thread_info;
2944
2945 if (bgp->gr_info[afi][safi].t_route_select) {
2946 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
2947
2948 thread_info = THREAD_ARG(t);
2949 XFREE(MTYPE_TMP, thread_info);
2950 BGP_TIMER_OFF(bgp->gr_info[afi][safi].t_route_select);
2951 }
2952
2953 if (BGP_DEBUG(update, UPDATE_OUT)) {
2954 zlog_debug("%s: processing route for %s : cnt %d", __func__,
2955 get_afi_safi_str(afi, safi, false),
2956 bgp->gr_info[afi][safi].gr_deferred);
2957 }
2958
2959 /* Process the route list */
2960 for (dest = bgp_table_top(bgp->rib[afi][safi]);
2961 dest && bgp->gr_info[afi][safi].gr_deferred != 0;
2962 dest = bgp_route_next(dest)) {
2963 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
2964 continue;
2965
2966 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
2967 bgp->gr_info[afi][safi].gr_deferred--;
2968 bgp_process_main_one(bgp, dest, afi, safi);
2969 cnt++;
2970 if (cnt >= BGP_MAX_BEST_ROUTE_SELECT) {
2971 bgp_dest_unlock_node(dest);
2972 break;
2973 }
2974 }
2975
2976 /* Send EOR message when all routes are processed */
2977 if (!bgp->gr_info[afi][safi].gr_deferred) {
2978 bgp_send_delayed_eor(bgp);
2979 /* Send route processing complete message to RIB */
2980 bgp_zebra_update(afi, safi, bgp->vrf_id,
2981 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
2982 return 0;
2983 }
2984
2985 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
2986
2987 thread_info->afi = afi;
2988 thread_info->safi = safi;
2989 thread_info->bgp = bgp;
2990
2991 /* If there are more routes to be processed, start the
2992 * selection timer
2993 */
2994 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
2995 BGP_ROUTE_SELECT_DELAY,
2996 &bgp->gr_info[afi][safi].t_route_select);
2997 return 0;
2998 }
2999
3000 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3001 {
3002 struct bgp_process_queue *pqnode = data;
3003 struct bgp *bgp = pqnode->bgp;
3004 struct bgp_table *table;
3005 struct bgp_dest *dest;
3006
3007 /* eoiu marker */
3008 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3009 bgp_process_main_one(bgp, NULL, 0, 0);
3010 /* should always have dedicated wq call */
3011 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3012 return WQ_SUCCESS;
3013 }
3014
3015 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3016 dest = STAILQ_FIRST(&pqnode->pqueue);
3017 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3018 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3019 table = bgp_dest_table(dest);
3020 /* note, new DESTs may be added as part of processing */
3021 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3022
3023 bgp_dest_unlock_node(dest);
3024 bgp_table_unlock(table);
3025 }
3026
3027 return WQ_SUCCESS;
3028 }
3029
3030 static void bgp_processq_del(struct work_queue *wq, void *data)
3031 {
3032 struct bgp_process_queue *pqnode = data;
3033
3034 bgp_unlock(pqnode->bgp);
3035
3036 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3037 }
3038
3039 void bgp_process_queue_init(struct bgp *bgp)
3040 {
3041 if (!bgp->process_queue) {
3042 char name[BUFSIZ];
3043
3044 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3045 bgp->process_queue = work_queue_new(bm->master, name);
3046 }
3047
3048 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3049 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3050 bgp->process_queue->spec.max_retries = 0;
3051 bgp->process_queue->spec.hold = 50;
3052 /* Use a higher yield value of 50ms for main queue processing */
3053 bgp->process_queue->spec.yield = 50 * 1000L;
3054 }
3055
3056 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3057 {
3058 struct bgp_process_queue *pqnode;
3059
3060 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3061 sizeof(struct bgp_process_queue));
3062
3063 /* unlocked in bgp_processq_del */
3064 pqnode->bgp = bgp_lock(bgp);
3065 STAILQ_INIT(&pqnode->pqueue);
3066
3067 return pqnode;
3068 }
3069
3070 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3071 {
3072 #define ARBITRARY_PROCESS_QLEN 10000
3073 struct work_queue *wq = bgp->process_queue;
3074 struct bgp_process_queue *pqnode;
3075 int pqnode_reuse = 0;
3076
3077 /* already scheduled for processing? */
3078 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3079 return;
3080
3081 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3082 * the workqueue
3083 */
3084 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3085 if (BGP_DEBUG(update, UPDATE_OUT))
3086 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3087 dest);
3088 return;
3089 }
3090
3091 if (wq == NULL)
3092 return;
3093
3094 /* Add route nodes to an existing work queue item until reaching the
3095 limit only if is from the same BGP view and it's not an EOIU marker
3096 */
3097 if (work_queue_item_count(wq)) {
3098 struct work_queue_item *item = work_queue_last_item(wq);
3099 pqnode = item->data;
3100
3101 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3102 || pqnode->bgp != bgp
3103 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3104 pqnode = bgp_processq_alloc(bgp);
3105 else
3106 pqnode_reuse = 1;
3107 } else
3108 pqnode = bgp_processq_alloc(bgp);
3109 /* all unlocked in bgp_process_wq */
3110 bgp_table_lock(bgp_dest_table(dest));
3111
3112 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3113 bgp_dest_lock_node(dest);
3114
3115 /* can't be enqueued twice */
3116 assert(STAILQ_NEXT(dest, pq) == NULL);
3117 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3118 pqnode->queued++;
3119
3120 if (!pqnode_reuse)
3121 work_queue_add(wq, pqnode);
3122
3123 return;
3124 }
3125
3126 void bgp_add_eoiu_mark(struct bgp *bgp)
3127 {
3128 struct bgp_process_queue *pqnode;
3129
3130 if (bgp->process_queue == NULL)
3131 return;
3132
3133 pqnode = bgp_processq_alloc(bgp);
3134
3135 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3136 work_queue_add(bgp->process_queue, pqnode);
3137 }
3138
3139 static int bgp_maximum_prefix_restart_timer(struct thread *thread)
3140 {
3141 struct peer *peer;
3142
3143 peer = THREAD_ARG(thread);
3144 peer->t_pmax_restart = NULL;
3145
3146 if (bgp_debug_neighbor_events(peer))
3147 zlog_debug(
3148 "%s Maximum-prefix restart timer expired, restore peering",
3149 peer->host);
3150
3151 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3152 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3153
3154 return 0;
3155 }
3156
3157 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3158 safi_t safi)
3159 {
3160 uint32_t count = 0;
3161 bool filtered = false;
3162 struct bgp_dest *dest;
3163 struct bgp_adj_in *ain;
3164 struct attr attr = {};
3165 struct bgp_table *table = peer->bgp->rib[afi][safi];
3166
3167 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3168 for (ain = dest->adj_in; ain; ain = ain->next) {
3169 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3170
3171 attr = *ain->attr;
3172
3173 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3174 == FILTER_DENY)
3175 filtered = true;
3176
3177 if (bgp_input_modifier(
3178 peer, rn_p, &attr, afi, safi,
3179 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3180 NULL, 0, NULL)
3181 == RMAP_DENY)
3182 filtered = true;
3183
3184 if (filtered)
3185 count++;
3186
3187 bgp_attr_undup(&attr, ain->attr);
3188 }
3189 }
3190
3191 return count;
3192 }
3193
3194 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3195 int always)
3196 {
3197 iana_afi_t pkt_afi;
3198 iana_safi_t pkt_safi;
3199 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3200 PEER_FLAG_MAX_PREFIX_FORCE))
3201 ? bgp_filtered_routes_count(peer, afi, safi)
3202 + peer->pcount[afi][safi]
3203 : peer->pcount[afi][safi];
3204
3205 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3206 return false;
3207
3208 if (pcount > peer->pmax[afi][safi]) {
3209 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3210 PEER_STATUS_PREFIX_LIMIT)
3211 && !always)
3212 return false;
3213
3214 zlog_info(
3215 "%%MAXPFXEXCEED: No. of %s prefix received from %s %u exceed, limit %u",
3216 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3217 peer->pmax[afi][safi]);
3218 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3219
3220 if (CHECK_FLAG(peer->af_flags[afi][safi],
3221 PEER_FLAG_MAX_PREFIX_WARNING))
3222 return false;
3223
3224 /* Convert AFI, SAFI to values for packet. */
3225 pkt_afi = afi_int2iana(afi);
3226 pkt_safi = safi_int2iana(safi);
3227 {
3228 uint8_t ndata[7];
3229
3230 ndata[0] = (pkt_afi >> 8);
3231 ndata[1] = pkt_afi;
3232 ndata[2] = pkt_safi;
3233 ndata[3] = (peer->pmax[afi][safi] >> 24);
3234 ndata[4] = (peer->pmax[afi][safi] >> 16);
3235 ndata[5] = (peer->pmax[afi][safi] >> 8);
3236 ndata[6] = (peer->pmax[afi][safi]);
3237
3238 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3239 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3240 BGP_NOTIFY_CEASE_MAX_PREFIX,
3241 ndata, 7);
3242 }
3243
3244 /* Dynamic peers will just close their connection. */
3245 if (peer_dynamic_neighbor(peer))
3246 return true;
3247
3248 /* restart timer start */
3249 if (peer->pmax_restart[afi][safi]) {
3250 peer->v_pmax_restart =
3251 peer->pmax_restart[afi][safi] * 60;
3252
3253 if (bgp_debug_neighbor_events(peer))
3254 zlog_debug(
3255 "%s Maximum-prefix restart timer started for %d secs",
3256 peer->host, peer->v_pmax_restart);
3257
3258 BGP_TIMER_ON(peer->t_pmax_restart,
3259 bgp_maximum_prefix_restart_timer,
3260 peer->v_pmax_restart);
3261 }
3262
3263 return true;
3264 } else
3265 UNSET_FLAG(peer->af_sflags[afi][safi],
3266 PEER_STATUS_PREFIX_LIMIT);
3267
3268 if (pcount
3269 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3270 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3271 PEER_STATUS_PREFIX_THRESHOLD)
3272 && !always)
3273 return false;
3274
3275 zlog_info(
3276 "%%MAXPFX: No. of %s prefix received from %s reaches %u, max %u",
3277 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3278 peer->pmax[afi][safi]);
3279 SET_FLAG(peer->af_sflags[afi][safi],
3280 PEER_STATUS_PREFIX_THRESHOLD);
3281 } else
3282 UNSET_FLAG(peer->af_sflags[afi][safi],
3283 PEER_STATUS_PREFIX_THRESHOLD);
3284 return false;
3285 }
3286
3287 /* Unconditionally remove the route from the RIB, without taking
3288 * damping into consideration (eg, because the session went down)
3289 */
3290 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3291 struct peer *peer, afi_t afi, safi_t safi)
3292 {
3293
3294 struct bgp *bgp = NULL;
3295 bool delete_route = false;
3296
3297 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3298 safi);
3299
3300 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3301 bgp_path_info_delete(dest, pi); /* keep historical info */
3302
3303 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3304 * flag
3305 */
3306 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3307 delete_route = true;
3308 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3309 delete_route = true;
3310 if (delete_route) {
3311 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3312 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3313 bgp = pi->peer->bgp;
3314 bgp->gr_info[afi][safi].gr_deferred--;
3315 }
3316 }
3317 }
3318
3319 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3320 bgp_process(peer->bgp, dest, afi, safi);
3321 }
3322
3323 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3324 struct peer *peer, afi_t afi, safi_t safi,
3325 struct prefix_rd *prd)
3326 {
3327 const struct prefix *p = bgp_dest_get_prefix(dest);
3328
3329 /* apply dampening, if result is suppressed, we'll be retaining
3330 * the bgp_path_info in the RIB for historical reference.
3331 */
3332 if (peer->sort == BGP_PEER_EBGP) {
3333 if (get_active_bdc_from_pi(pi, afi, safi)) {
3334 if (bgp_damp_withdraw(pi, dest, afi, safi, 0)
3335 == BGP_DAMP_SUPPRESSED) {
3336 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3337 safi);
3338 return;
3339 }
3340 }
3341 }
3342
3343 #ifdef ENABLE_BGP_VNC
3344 if (safi == SAFI_MPLS_VPN) {
3345 struct bgp_dest *pdest = NULL;
3346 struct bgp_table *table = NULL;
3347
3348 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3349 (struct prefix *)prd);
3350 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3351 table = bgp_dest_get_bgp_table_info(pdest);
3352
3353 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3354 peer->bgp, prd, table, p, pi);
3355 }
3356 bgp_dest_unlock_node(pdest);
3357 }
3358 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3359 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3360
3361 vnc_import_bgp_del_route(peer->bgp, p, pi);
3362 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3363 }
3364 }
3365 #endif
3366
3367 /* If this is an EVPN route, process for un-import. */
3368 if (safi == SAFI_EVPN)
3369 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3370
3371 bgp_rib_remove(dest, pi, peer, afi, safi);
3372 }
3373
3374 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3375 struct peer *peer, struct attr *attr,
3376 struct bgp_dest *dest)
3377 {
3378 struct bgp_path_info *new;
3379
3380 /* Make new BGP info. */
3381 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3382 new->type = type;
3383 new->instance = instance;
3384 new->sub_type = sub_type;
3385 new->peer = peer;
3386 new->attr = attr;
3387 new->uptime = bgp_clock();
3388 new->net = dest;
3389 return new;
3390 }
3391
3392 static void overlay_index_update(struct attr *attr,
3393 union gw_addr *gw_ip)
3394 {
3395 if (!attr)
3396 return;
3397 if (gw_ip == NULL) {
3398 struct bgp_route_evpn eo;
3399
3400 memset(&eo, 0, sizeof(eo));
3401 bgp_attr_set_evpn_overlay(attr, &eo);
3402 } else {
3403 struct bgp_route_evpn eo = {.gw_ip = *gw_ip};
3404
3405 bgp_attr_set_evpn_overlay(attr, &eo);
3406 }
3407 }
3408
3409 static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path,
3410 union gw_addr *gw_ip)
3411 {
3412 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(path->attr);
3413 union gw_addr path_gw_ip, *path_gw_ip_remote;
3414 union {
3415 esi_t esi;
3416 union gw_addr ip;
3417 } temp;
3418
3419 if (afi != AFI_L2VPN)
3420 return true;
3421
3422 path_gw_ip = eo->gw_ip;
3423
3424 if (gw_ip == NULL) {
3425 memset(&temp, 0, sizeof(temp));
3426 path_gw_ip_remote = &temp.ip;
3427 } else
3428 path_gw_ip_remote = gw_ip;
3429
3430 return !!memcmp(&path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr));
3431 }
3432
3433 /* Check if received nexthop is valid or not. */
3434 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3435 uint8_t type, uint8_t stype, struct attr *attr,
3436 struct bgp_dest *dest)
3437 {
3438 bool ret = false;
3439 bool is_bgp_static_route =
3440 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3441 : false;
3442
3443 /*
3444 * Only validated for unicast and multicast currently.
3445 * Also valid for EVPN where the nexthop is an IP address.
3446 * If we are a bgp static route being checked then there is
3447 * no need to check to see if the nexthop is martian as
3448 * that it should be ok.
3449 */
3450 if (is_bgp_static_route ||
3451 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3452 return false;
3453
3454 /* If NEXT_HOP is present, validate it. */
3455 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3456 if (attr->nexthop.s_addr == INADDR_ANY
3457 || IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr))
3458 || bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3459 return true;
3460 }
3461
3462 /* If MP_NEXTHOP is present, validate it. */
3463 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3464 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3465 * it is not an IPv6 link-local address.
3466 *
3467 * If we receive an UPDATE with nexthop length set to 32 bytes
3468 * we shouldn't discard an UPDATE if it's set to (::).
3469 * The link-local (2st) is validated along the code path later.
3470 */
3471 if (attr->mp_nexthop_len) {
3472 switch (attr->mp_nexthop_len) {
3473 case BGP_ATTR_NHLEN_IPV4:
3474 case BGP_ATTR_NHLEN_VPNV4:
3475 ret = (attr->mp_nexthop_global_in.s_addr == INADDR_ANY
3476 || IPV4_CLASS_DE(
3477 ntohl(attr->mp_nexthop_global_in.s_addr))
3478 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3479 dest));
3480 break;
3481
3482 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3483 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3484 ret = (IN6_IS_ADDR_UNSPECIFIED(
3485 &attr->mp_nexthop_global)
3486 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3487 || IN6_IS_ADDR_MULTICAST(
3488 &attr->mp_nexthop_global)
3489 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3490 dest));
3491 break;
3492 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3493 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3494 || IN6_IS_ADDR_MULTICAST(
3495 &attr->mp_nexthop_global)
3496 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3497 dest));
3498 break;
3499
3500 default:
3501 ret = true;
3502 break;
3503 }
3504 }
3505
3506 return ret;
3507 }
3508
3509 static void bgp_attr_add_no_export_community(struct attr *attr)
3510 {
3511 struct community *old;
3512 struct community *new;
3513 struct community *merge;
3514 struct community *no_export;
3515
3516 old = attr->community;
3517 no_export = community_str2com("no-export");
3518
3519 assert(no_export);
3520
3521 if (old) {
3522 merge = community_merge(community_dup(old), no_export);
3523
3524 if (!old->refcnt)
3525 community_free(&old);
3526
3527 new = community_uniq_sort(merge);
3528 community_free(&merge);
3529 } else {
3530 new = community_dup(no_export);
3531 }
3532
3533 community_free(&no_export);
3534
3535 attr->community = new;
3536 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
3537 }
3538
3539 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3540 struct attr *attr, afi_t afi, safi_t safi, int type,
3541 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3542 uint32_t num_labels, int soft_reconfig,
3543 struct bgp_route_evpn *evpn)
3544 {
3545 int ret;
3546 int aspath_loop_count = 0;
3547 struct bgp_dest *dest;
3548 struct bgp *bgp;
3549 struct attr new_attr;
3550 struct attr *attr_new;
3551 struct bgp_path_info *pi;
3552 struct bgp_path_info *new;
3553 struct bgp_path_info_extra *extra;
3554 const char *reason;
3555 char pfx_buf[BGP_PRD_PATH_STRLEN];
3556 int connected = 0;
3557 int do_loop_check = 1;
3558 int has_valid_label = 0;
3559 afi_t nh_afi;
3560 uint8_t pi_type = 0;
3561 uint8_t pi_sub_type = 0;
3562
3563 if (frrtrace_enabled(frr_bgp, process_update)) {
3564 char pfxprint[PREFIX2STR_BUFFER];
3565
3566 prefix2str(p, pfxprint, sizeof(pfxprint));
3567 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
3568 afi, safi, attr);
3569 }
3570
3571 #ifdef ENABLE_BGP_VNC
3572 int vnc_implicit_withdraw = 0;
3573 #endif
3574 int same_attr = 0;
3575
3576 memset(&new_attr, 0, sizeof(struct attr));
3577 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
3578 new_attr.label = MPLS_INVALID_LABEL;
3579
3580 bgp = peer->bgp;
3581 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3582 /* TODO: Check to see if we can get rid of "is_valid_label" */
3583 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3584 has_valid_label = (num_labels > 0) ? 1 : 0;
3585 else
3586 has_valid_label = bgp_is_valid_label(label);
3587
3588 if (has_valid_label)
3589 assert(label != NULL);
3590
3591 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
3592 * condition :
3593 * Suppress fib is enabled
3594 * BGP_OPT_NO_FIB is not enabled
3595 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
3596 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
3597 */
3598 if (BGP_SUPPRESS_FIB_ENABLED(bgp) &&
3599 (sub_type == BGP_ROUTE_NORMAL) &&
3600 (!bgp_option_check(BGP_OPT_NO_FIB)) &&
3601 (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
3602 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
3603
3604 /* When peer's soft reconfiguration enabled. Record input packet in
3605 Adj-RIBs-In. */
3606 if (!soft_reconfig
3607 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3608 && peer != bgp->peer_self)
3609 bgp_adj_in_set(dest, peer, attr, addpath_id);
3610
3611 /* Check previously received route. */
3612 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
3613 if (pi->peer == peer && pi->type == type
3614 && pi->sub_type == sub_type
3615 && pi->addpath_rx_id == addpath_id)
3616 break;
3617
3618 /* AS path local-as loop check. */
3619 if (peer->change_local_as) {
3620 if (peer->allowas_in[afi][safi])
3621 aspath_loop_count = peer->allowas_in[afi][safi];
3622 else if (!CHECK_FLAG(peer->flags,
3623 PEER_FLAG_LOCAL_AS_NO_PREPEND))
3624 aspath_loop_count = 1;
3625
3626 if (aspath_loop_check(attr->aspath, peer->change_local_as)
3627 > aspath_loop_count) {
3628 peer->stat_pfx_aspath_loop++;
3629 reason = "as-path contains our own AS A;";
3630 goto filtered;
3631 }
3632 }
3633
3634 /* If the peer is configured for "allowas-in origin" and the last ASN in
3635 * the
3636 * as-path is our ASN then we do not need to call aspath_loop_check
3637 */
3638 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
3639 if (aspath_get_last_as(attr->aspath) == bgp->as)
3640 do_loop_check = 0;
3641
3642 /* AS path loop check. */
3643 if (do_loop_check) {
3644 if (aspath_loop_check(attr->aspath, bgp->as)
3645 > peer->allowas_in[afi][safi]
3646 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
3647 && aspath_loop_check(attr->aspath, bgp->confed_id)
3648 > peer->allowas_in[afi][safi])) {
3649 peer->stat_pfx_aspath_loop++;
3650 reason = "as-path contains our own AS;";
3651 goto filtered;
3652 }
3653 }
3654
3655 /* Route reflector originator ID check. */
3656 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
3657 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
3658 peer->stat_pfx_originator_loop++;
3659 reason = "originator is us;";
3660 goto filtered;
3661 }
3662
3663 /* Route reflector cluster ID check. */
3664 if (bgp_cluster_filter(peer, attr)) {
3665 peer->stat_pfx_cluster_loop++;
3666 reason = "reflected from the same cluster;";
3667 goto filtered;
3668 }
3669
3670 /* Apply incoming filter. */
3671 if (bgp_input_filter(peer, p, attr, afi, safi) == FILTER_DENY) {
3672 peer->stat_pfx_filter++;
3673 reason = "filter;";
3674 goto filtered;
3675 }
3676
3677 /* RFC 8212 to prevent route leaks.
3678 * This specification intends to improve this situation by requiring the
3679 * explicit configuration of both BGP Import and Export Policies for any
3680 * External BGP (EBGP) session such as customers, peers, or
3681 * confederation boundaries for all enabled address families. Through
3682 * codification of the aforementioned requirement, operators will
3683 * benefit from consistent behavior across different BGP
3684 * implementations.
3685 */
3686 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
3687 if (!bgp_inbound_policy_exists(peer,
3688 &peer->filter[afi][safi])) {
3689 reason = "inbound policy missing";
3690 goto filtered;
3691 }
3692
3693 /* draft-ietf-idr-deprecate-as-set-confed-set
3694 * Filter routes having AS_SET or AS_CONFED_SET in the path.
3695 * Eventually, This document (if approved) updates RFC 4271
3696 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
3697 * and obsoletes RFC 6472.
3698 */
3699 if (peer->bgp->reject_as_sets)
3700 if (aspath_check_as_sets(attr->aspath)) {
3701 reason =
3702 "as-path contains AS_SET or AS_CONFED_SET type;";
3703 goto filtered;
3704 }
3705
3706 new_attr = *attr;
3707
3708 /* Apply incoming route-map.
3709 * NB: new_attr may now contain newly allocated values from route-map
3710 * "set"
3711 * commands, so we need bgp_attr_flush in the error paths, until we
3712 * intern
3713 * the attr (which takes over the memory references) */
3714 if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL, label,
3715 num_labels, dest)
3716 == RMAP_DENY) {
3717 peer->stat_pfx_filter++;
3718 reason = "route-map;";
3719 bgp_attr_flush(&new_attr);
3720 goto filtered;
3721 }
3722
3723 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
3724 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3725 /* remove from RIB previous entry */
3726 bgp_zebra_withdraw(p, pi, bgp, safi);
3727 }
3728
3729 if (peer->sort == BGP_PEER_EBGP) {
3730
3731 /* rfc7999:
3732 * A BGP speaker receiving an announcement tagged with the
3733 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
3734 * NO_EXPORT community as defined in RFC1997, or a
3735 * similar community, to prevent propagation of the
3736 * prefix outside the local AS. The community to prevent
3737 * propagation SHOULD be chosen according to the operator's
3738 * routing policy.
3739 */
3740 if (new_attr.community
3741 && community_include(new_attr.community,
3742 COMMUNITY_BLACKHOLE))
3743 bgp_attr_add_no_export_community(&new_attr);
3744
3745 /* If we receive the graceful-shutdown community from an eBGP
3746 * peer we must lower local-preference */
3747 if (new_attr.community
3748 && community_include(new_attr.community, COMMUNITY_GSHUT)) {
3749 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
3750 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
3751
3752 /* If graceful-shutdown is configured then add the GSHUT
3753 * community to all paths received from eBGP peers */
3754 } else if (bgp_in_graceful_shutdown(peer->bgp))
3755 bgp_attr_add_gshut_community(&new_attr);
3756 }
3757
3758 if (pi) {
3759 pi_type = pi->type;
3760 pi_sub_type = pi->sub_type;
3761 }
3762
3763 /* next hop check. */
3764 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
3765 && bgp_update_martian_nexthop(bgp, afi, safi, pi_type, pi_sub_type,
3766 &new_attr, dest)) {
3767 peer->stat_pfx_nh_invalid++;
3768 reason = "martian or self next-hop;";
3769 bgp_attr_flush(&new_attr);
3770 goto filtered;
3771 }
3772
3773 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
3774 peer->stat_pfx_nh_invalid++;
3775 reason = "self mac;";
3776 goto filtered;
3777 }
3778
3779 /* Update Overlay Index */
3780 if (afi == AFI_L2VPN) {
3781 overlay_index_update(&new_attr,
3782 evpn == NULL ? NULL : &evpn->gw_ip);
3783 }
3784
3785 attr_new = bgp_attr_intern(&new_attr);
3786
3787 /* If maximum prefix count is configured and current prefix
3788 * count exeed it.
3789 */
3790 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0))
3791 return -1;
3792
3793 /* If the update is implicit withdraw. */
3794 if (pi) {
3795 pi->uptime = bgp_clock();
3796 same_attr = attrhash_cmp(pi->attr, attr_new);
3797
3798 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
3799
3800 /* Same attribute comes in. */
3801 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
3802 && same_attr
3803 && (!has_valid_label
3804 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
3805 num_labels * sizeof(mpls_label_t))
3806 == 0)
3807 && (overlay_index_equal(
3808 afi, pi,
3809 evpn == NULL ? NULL : &evpn->gw_ip))) {
3810 if (get_active_bdc_from_pi(pi, afi, safi)
3811 && peer->sort == BGP_PEER_EBGP
3812 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3813 if (bgp_debug_update(peer, p, NULL, 1)) {
3814 bgp_debug_rdpfxpath2str(
3815 afi, safi, prd, p, label,
3816 num_labels, addpath_id ? 1 : 0,
3817 addpath_id, pfx_buf,
3818 sizeof(pfx_buf));
3819 zlog_debug("%s rcvd %s", peer->host,
3820 pfx_buf);
3821 }
3822
3823 if (bgp_damp_update(pi, dest, afi, safi)
3824 != BGP_DAMP_SUPPRESSED) {
3825 bgp_aggregate_increment(bgp, p, pi, afi,
3826 safi);
3827 bgp_process(bgp, dest, afi, safi);
3828 }
3829 } else /* Duplicate - odd */
3830 {
3831 if (bgp_debug_update(peer, p, NULL, 1)) {
3832 if (!peer->rcvd_attr_printed) {
3833 zlog_debug(
3834 "%s rcvd UPDATE w/ attr: %s",
3835 peer->host,
3836 peer->rcvd_attr_str);
3837 peer->rcvd_attr_printed = 1;
3838 }
3839
3840 bgp_debug_rdpfxpath2str(
3841 afi, safi, prd, p, label,
3842 num_labels, addpath_id ? 1 : 0,
3843 addpath_id, pfx_buf,
3844 sizeof(pfx_buf));
3845 zlog_debug(
3846 "%s rcvd %s...duplicate ignored",
3847 peer->host, pfx_buf);
3848 }
3849
3850 /* graceful restart STALE flag unset. */
3851 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3852 bgp_path_info_unset_flag(
3853 dest, pi, BGP_PATH_STALE);
3854 bgp_dest_set_defer_flag(dest, false);
3855 bgp_process(bgp, dest, afi, safi);
3856 }
3857 }
3858
3859 bgp_dest_unlock_node(dest);
3860 bgp_attr_unintern(&attr_new);
3861
3862 return 0;
3863 }
3864
3865 /* Withdraw/Announce before we fully processed the withdraw */
3866 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
3867 if (bgp_debug_update(peer, p, NULL, 1)) {
3868 bgp_debug_rdpfxpath2str(
3869 afi, safi, prd, p, label, num_labels,
3870 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3871 sizeof(pfx_buf));
3872 zlog_debug(
3873 "%s rcvd %s, flapped quicker than processing",
3874 peer->host, pfx_buf);
3875 }
3876
3877 bgp_path_info_restore(dest, pi);
3878 }
3879
3880 /* Received Logging. */
3881 if (bgp_debug_update(peer, p, NULL, 1)) {
3882 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
3883 num_labels, addpath_id ? 1 : 0,
3884 addpath_id, pfx_buf,
3885 sizeof(pfx_buf));
3886 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3887 }
3888
3889 /* graceful restart STALE flag unset. */
3890 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3891 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
3892 bgp_dest_set_defer_flag(dest, false);
3893 }
3894
3895 /* The attribute is changed. */
3896 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
3897
3898 /* implicit withdraw, decrement aggregate and pcount here.
3899 * only if update is accepted, they'll increment below.
3900 */
3901 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
3902
3903 /* Update bgp route dampening information. */
3904 if (get_active_bdc_from_pi(pi, afi, safi)
3905 && peer->sort == BGP_PEER_EBGP) {
3906 /* This is implicit withdraw so we should update
3907 * dampening information.
3908 */
3909 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
3910 bgp_damp_withdraw(pi, dest, afi, safi, 1);
3911 }
3912 #ifdef ENABLE_BGP_VNC
3913 if (safi == SAFI_MPLS_VPN) {
3914 struct bgp_dest *pdest = NULL;
3915 struct bgp_table *table = NULL;
3916
3917 pdest = bgp_node_get(bgp->rib[afi][safi],
3918 (struct prefix *)prd);
3919 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3920 table = bgp_dest_get_bgp_table_info(pdest);
3921
3922 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3923 bgp, prd, table, p, pi);
3924 }
3925 bgp_dest_unlock_node(pdest);
3926 }
3927 if ((afi == AFI_IP || afi == AFI_IP6)
3928 && (safi == SAFI_UNICAST)) {
3929 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3930 /*
3931 * Implicit withdraw case.
3932 */
3933 ++vnc_implicit_withdraw;
3934 vnc_import_bgp_del_route(bgp, p, pi);
3935 vnc_import_bgp_exterior_del_route(bgp, p, pi);
3936 }
3937 }
3938 #endif
3939
3940 /* Special handling for EVPN update of an existing route. If the
3941 * extended community attribute has changed, we need to
3942 * un-import
3943 * the route using its existing extended community. It will be
3944 * subsequently processed for import with the new extended
3945 * community.
3946 */
3947 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
3948 && !same_attr) {
3949 if ((pi->attr->flag
3950 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
3951 && (attr_new->flag
3952 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
3953 int cmp;
3954
3955 cmp = ecommunity_cmp(pi->attr->ecommunity,
3956 attr_new->ecommunity);
3957 if (!cmp) {
3958 if (bgp_debug_update(peer, p, NULL, 1))
3959 zlog_debug(
3960 "Change in EXT-COMM, existing %s new %s",
3961 ecommunity_str(
3962 pi->attr->ecommunity),
3963 ecommunity_str(
3964 attr_new->ecommunity));
3965 if (safi == SAFI_EVPN)
3966 bgp_evpn_unimport_route(
3967 bgp, afi, safi, p, pi);
3968 else /* SAFI_MPLS_VPN */
3969 vpn_leak_to_vrf_withdraw(bgp,
3970 pi);
3971 }
3972 }
3973 }
3974
3975 /* Update to new attribute. */
3976 bgp_attr_unintern(&pi->attr);
3977 pi->attr = attr_new;
3978
3979 /* Update MPLS label */
3980 if (has_valid_label) {
3981 extra = bgp_path_info_extra_get(pi);
3982 if (extra->label != label) {
3983 memcpy(&extra->label, label,
3984 num_labels * sizeof(mpls_label_t));
3985 extra->num_labels = num_labels;
3986 }
3987 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
3988 bgp_set_valid_label(&extra->label[0]);
3989 }
3990
3991 /* Update SRv6 SID */
3992 if (attr->srv6_l3vpn) {
3993 extra = bgp_path_info_extra_get(pi);
3994 if (sid_diff(&extra->sid[0], &attr->srv6_l3vpn->sid)) {
3995 sid_copy(&extra->sid[0],
3996 &attr->srv6_l3vpn->sid);
3997 extra->num_sids = 1;
3998 }
3999 } else if (attr->srv6_vpn) {
4000 extra = bgp_path_info_extra_get(pi);
4001 if (sid_diff(&extra->sid[0], &attr->srv6_vpn->sid)) {
4002 sid_copy(&extra->sid[0], &attr->srv6_vpn->sid);
4003 extra->num_sids = 1;
4004 }
4005 }
4006
4007 #ifdef ENABLE_BGP_VNC
4008 if ((afi == AFI_IP || afi == AFI_IP6)
4009 && (safi == SAFI_UNICAST)) {
4010 if (vnc_implicit_withdraw) {
4011 /*
4012 * Add back the route with its new attributes
4013 * (e.g., nexthop).
4014 * The route is still selected, until the route
4015 * selection
4016 * queued by bgp_process actually runs. We have
4017 * to make this
4018 * update to the VNC side immediately to avoid
4019 * racing against
4020 * configuration changes (e.g., route-map
4021 * changes) which
4022 * trigger re-importation of the entire RIB.
4023 */
4024 vnc_import_bgp_add_route(bgp, p, pi);
4025 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4026 }
4027 }
4028 #endif
4029
4030 /* Update bgp route dampening information. */
4031 if (get_active_bdc_from_pi(pi, afi, safi)
4032 && peer->sort == BGP_PEER_EBGP) {
4033 /* Now we do normal update dampening. */
4034 ret = bgp_damp_update(pi, dest, afi, safi);
4035 if (ret == BGP_DAMP_SUPPRESSED) {
4036 bgp_dest_unlock_node(dest);
4037 return 0;
4038 }
4039 }
4040
4041 /* Nexthop reachability check - for unicast and
4042 * labeled-unicast.. */
4043 if (((afi == AFI_IP || afi == AFI_IP6)
4044 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4045 || (safi == SAFI_EVPN &&
4046 bgp_evpn_is_prefix_nht_supported(p))) {
4047 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4048 && peer->ttl == BGP_DEFAULT_TTL
4049 && !CHECK_FLAG(peer->flags,
4050 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4051 && !CHECK_FLAG(bgp->flags,
4052 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4053 connected = 1;
4054 else
4055 connected = 0;
4056
4057 struct bgp *bgp_nexthop = bgp;
4058
4059 if (pi->extra && pi->extra->bgp_orig)
4060 bgp_nexthop = pi->extra->bgp_orig;
4061
4062 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4063
4064 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4065 safi, pi, NULL, connected)
4066 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4067 bgp_path_info_set_flag(dest, pi,
4068 BGP_PATH_VALID);
4069 else {
4070 if (BGP_DEBUG(nht, NHT)) {
4071 zlog_debug("%s(%pI4): NH unresolved",
4072 __func__,
4073 (in_addr_t *)&attr_new->nexthop);
4074 }
4075 bgp_path_info_unset_flag(dest, pi,
4076 BGP_PATH_VALID);
4077 }
4078 } else
4079 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4080
4081 #ifdef ENABLE_BGP_VNC
4082 if (safi == SAFI_MPLS_VPN) {
4083 struct bgp_dest *pdest = NULL;
4084 struct bgp_table *table = NULL;
4085
4086 pdest = bgp_node_get(bgp->rib[afi][safi],
4087 (struct prefix *)prd);
4088 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4089 table = bgp_dest_get_bgp_table_info(pdest);
4090
4091 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4092 bgp, prd, table, p, pi);
4093 }
4094 bgp_dest_unlock_node(pdest);
4095 }
4096 #endif
4097
4098 /* If this is an EVPN route and some attribute has changed,
4099 * process
4100 * route for import. If the extended community has changed, we
4101 * would
4102 * have done the un-import earlier and the import would result
4103 * in the
4104 * route getting injected into appropriate L2 VNIs. If it is
4105 * just
4106 * some other attribute change, the import will result in
4107 * updating
4108 * the attributes for the route in the VNI(s).
4109 */
4110 if (safi == SAFI_EVPN && !same_attr &&
4111 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4112 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4113
4114 /* Process change. */
4115 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4116
4117 bgp_process(bgp, dest, afi, safi);
4118 bgp_dest_unlock_node(dest);
4119
4120 if (SAFI_UNICAST == safi
4121 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4122 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4123
4124 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4125 }
4126 if ((SAFI_MPLS_VPN == safi)
4127 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4128
4129 vpn_leak_to_vrf_update(bgp, pi);
4130 }
4131
4132 #ifdef ENABLE_BGP_VNC
4133 if (SAFI_MPLS_VPN == safi) {
4134 mpls_label_t label_decoded = decode_label(label);
4135
4136 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4137 type, sub_type, &label_decoded);
4138 }
4139 if (SAFI_ENCAP == safi) {
4140 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4141 type, sub_type, NULL);
4142 }
4143 #endif
4144
4145 return 0;
4146 } // End of implicit withdraw
4147
4148 /* Received Logging. */
4149 if (bgp_debug_update(peer, p, NULL, 1)) {
4150 if (!peer->rcvd_attr_printed) {
4151 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
4152 peer->rcvd_attr_str);
4153 peer->rcvd_attr_printed = 1;
4154 }
4155
4156 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4157 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4158 sizeof(pfx_buf));
4159 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
4160 }
4161
4162 /* Make new BGP info. */
4163 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4164
4165 /* Update MPLS label */
4166 if (has_valid_label) {
4167 extra = bgp_path_info_extra_get(new);
4168 if (extra->label != label) {
4169 memcpy(&extra->label, label,
4170 num_labels * sizeof(mpls_label_t));
4171 extra->num_labels = num_labels;
4172 }
4173 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4174 bgp_set_valid_label(&extra->label[0]);
4175 }
4176
4177 /* Update SRv6 SID */
4178 if (safi == SAFI_MPLS_VPN) {
4179 extra = bgp_path_info_extra_get(new);
4180 if (attr->srv6_l3vpn) {
4181 sid_copy(&extra->sid[0], &attr->srv6_l3vpn->sid);
4182 extra->num_sids = 1;
4183 } else if (attr->srv6_vpn) {
4184 sid_copy(&extra->sid[0], &attr->srv6_vpn->sid);
4185 extra->num_sids = 1;
4186 }
4187 }
4188
4189 /* Update Overlay Index */
4190 if (afi == AFI_L2VPN) {
4191 overlay_index_update(new->attr,
4192 evpn == NULL ? NULL : &evpn->gw_ip);
4193 }
4194 /* Nexthop reachability check. */
4195 if (((afi == AFI_IP || afi == AFI_IP6)
4196 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4197 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4198 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4199 && peer->ttl == BGP_DEFAULT_TTL
4200 && !CHECK_FLAG(peer->flags,
4201 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4202 && !CHECK_FLAG(bgp->flags,
4203 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4204 connected = 1;
4205 else
4206 connected = 0;
4207
4208 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4209
4210 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4211 connected)
4212 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4213 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4214 else {
4215 if (BGP_DEBUG(nht, NHT)) {
4216 char buf1[INET6_ADDRSTRLEN];
4217 inet_ntop(AF_INET,
4218 (const void *)&attr_new->nexthop,
4219 buf1, INET6_ADDRSTRLEN);
4220 zlog_debug("%s(%s): NH unresolved", __func__,
4221 buf1);
4222 }
4223 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4224 }
4225 } else
4226 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4227
4228 /* Addpath ID */
4229 new->addpath_rx_id = addpath_id;
4230
4231 /* Increment prefix */
4232 bgp_aggregate_increment(bgp, p, new, afi, safi);
4233
4234 /* Register new BGP information. */
4235 bgp_path_info_add(dest, new);
4236
4237 /* route_node_get lock */
4238 bgp_dest_unlock_node(dest);
4239
4240 #ifdef ENABLE_BGP_VNC
4241 if (safi == SAFI_MPLS_VPN) {
4242 struct bgp_dest *pdest = NULL;
4243 struct bgp_table *table = NULL;
4244
4245 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4246 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4247 table = bgp_dest_get_bgp_table_info(pdest);
4248
4249 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4250 bgp, prd, table, p, new);
4251 }
4252 bgp_dest_unlock_node(pdest);
4253 }
4254 #endif
4255
4256 /* If this is an EVPN route, process for import. */
4257 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4258 bgp_evpn_import_route(bgp, afi, safi, p, new);
4259
4260 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4261
4262 /* Process change. */
4263 bgp_process(bgp, dest, afi, safi);
4264
4265 if (SAFI_UNICAST == safi
4266 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4267 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4268 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4269 }
4270 if ((SAFI_MPLS_VPN == safi)
4271 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4272
4273 vpn_leak_to_vrf_update(bgp, new);
4274 }
4275 #ifdef ENABLE_BGP_VNC
4276 if (SAFI_MPLS_VPN == safi) {
4277 mpls_label_t label_decoded = decode_label(label);
4278
4279 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4280 sub_type, &label_decoded);
4281 }
4282 if (SAFI_ENCAP == safi) {
4283 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4284 sub_type, NULL);
4285 }
4286 #endif
4287
4288 return 0;
4289
4290 /* This BGP update is filtered. Log the reason then update BGP
4291 entry. */
4292 filtered:
4293 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4294
4295 if (bgp_debug_update(peer, p, NULL, 1)) {
4296 if (!peer->rcvd_attr_printed) {
4297 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
4298 peer->rcvd_attr_str);
4299 peer->rcvd_attr_printed = 1;
4300 }
4301
4302 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4303 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4304 sizeof(pfx_buf));
4305 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
4306 peer->host, pfx_buf, reason);
4307 }
4308
4309 if (pi) {
4310 /* If this is an EVPN route, un-import it as it is now filtered.
4311 */
4312 if (safi == SAFI_EVPN)
4313 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4314
4315 if (SAFI_UNICAST == safi
4316 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4317 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4318
4319 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4320 }
4321 if ((SAFI_MPLS_VPN == safi)
4322 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4323
4324 vpn_leak_to_vrf_withdraw(bgp, pi);
4325 }
4326
4327 bgp_rib_remove(dest, pi, peer, afi, safi);
4328 }
4329
4330 bgp_dest_unlock_node(dest);
4331
4332 #ifdef ENABLE_BGP_VNC
4333 /*
4334 * Filtered update is treated as an implicit withdrawal (see
4335 * bgp_rib_remove()
4336 * a few lines above)
4337 */
4338 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4339 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4340 0);
4341 }
4342 #endif
4343
4344 return 0;
4345 }
4346
4347 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4348 struct attr *attr, afi_t afi, safi_t safi, int type,
4349 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4350 uint32_t num_labels, struct bgp_route_evpn *evpn)
4351 {
4352 struct bgp *bgp;
4353 char pfx_buf[BGP_PRD_PATH_STRLEN];
4354 struct bgp_dest *dest;
4355 struct bgp_path_info *pi;
4356
4357 #ifdef ENABLE_BGP_VNC
4358 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4359 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4360 0);
4361 }
4362 #endif
4363
4364 bgp = peer->bgp;
4365
4366 /* Lookup node. */
4367 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4368
4369 /* If peer is soft reconfiguration enabled. Record input packet for
4370 * further calculation.
4371 *
4372 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4373 * routes that are filtered. This tanks out Quagga RS pretty badly due
4374 * to
4375 * the iteration over all RS clients.
4376 * Since we need to remove the entry from adj_in anyway, do that first
4377 * and
4378 * if there was no entry, we don't need to do anything more.
4379 */
4380 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4381 && peer != bgp->peer_self)
4382 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4383 peer->stat_pfx_dup_withdraw++;
4384
4385 if (bgp_debug_update(peer, p, NULL, 1)) {
4386 bgp_debug_rdpfxpath2str(
4387 afi, safi, prd, p, label, num_labels,
4388 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4389 sizeof(pfx_buf));
4390 zlog_debug(
4391 "%s withdrawing route %s not in adj-in",
4392 peer->host, pfx_buf);
4393 }
4394 bgp_dest_unlock_node(dest);
4395 return 0;
4396 }
4397
4398 /* Lookup withdrawn route. */
4399 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4400 if (pi->peer == peer && pi->type == type
4401 && pi->sub_type == sub_type
4402 && pi->addpath_rx_id == addpath_id)
4403 break;
4404
4405 /* Logging. */
4406 if (bgp_debug_update(peer, p, NULL, 1)) {
4407 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4408 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4409 sizeof(pfx_buf));
4410 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
4411 pfx_buf);
4412 }
4413
4414 /* Withdraw specified route from routing table. */
4415 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4416 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4417 if (SAFI_UNICAST == safi
4418 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4419 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4420 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4421 }
4422 if ((SAFI_MPLS_VPN == safi)
4423 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4424
4425 vpn_leak_to_vrf_withdraw(bgp, pi);
4426 }
4427 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4428 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4429 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4430 sizeof(pfx_buf));
4431 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4432 }
4433
4434 /* Unlock bgp_node_get() lock. */
4435 bgp_dest_unlock_node(dest);
4436
4437 return 0;
4438 }
4439
4440 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4441 int withdraw)
4442 {
4443 struct update_subgroup *subgrp;
4444 subgrp = peer_subgroup(peer, afi, safi);
4445 subgroup_default_originate(subgrp, withdraw);
4446 }
4447
4448
4449 /*
4450 * bgp_stop_announce_route_timer
4451 */
4452 void bgp_stop_announce_route_timer(struct peer_af *paf)
4453 {
4454 if (!paf->t_announce_route)
4455 return;
4456
4457 thread_cancel(&paf->t_announce_route);
4458 }
4459
4460 /*
4461 * bgp_announce_route_timer_expired
4462 *
4463 * Callback that is invoked when the route announcement timer for a
4464 * peer_af expires.
4465 */
4466 static int bgp_announce_route_timer_expired(struct thread *t)
4467 {
4468 struct peer_af *paf;
4469 struct peer *peer;
4470
4471 paf = THREAD_ARG(t);
4472 peer = paf->peer;
4473
4474 if (peer->status != Established)
4475 return 0;
4476
4477 if (!peer->afc_nego[paf->afi][paf->safi])
4478 return 0;
4479
4480 peer_af_announce_route(paf, 1);
4481
4482 /* Notify BGP conditional advertisement scanner percess */
4483 peer->advmap_config_change[paf->afi][paf->safi] = true;
4484
4485 return 0;
4486 }
4487
4488 /*
4489 * bgp_announce_route
4490 *
4491 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
4492 */
4493 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi)
4494 {
4495 struct peer_af *paf;
4496 struct update_subgroup *subgrp;
4497
4498 paf = peer_af_find(peer, afi, safi);
4499 if (!paf)
4500 return;
4501 subgrp = PAF_SUBGRP(paf);
4502
4503 /*
4504 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
4505 * or a refresh has already been triggered.
4506 */
4507 if (!subgrp || paf->t_announce_route)
4508 return;
4509
4510 /*
4511 * Start a timer to stagger/delay the announce. This serves
4512 * two purposes - announcement can potentially be combined for
4513 * multiple peers and the announcement doesn't happen in the
4514 * vty context.
4515 */
4516 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
4517 (subgrp->peer_count == 1)
4518 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
4519 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
4520 &paf->t_announce_route);
4521 }
4522
4523 /*
4524 * Announce routes from all AF tables to a peer.
4525 *
4526 * This should ONLY be called when there is a need to refresh the
4527 * routes to the peer based on a policy change for this peer alone
4528 * or a route refresh request received from the peer.
4529 * The operation will result in splitting the peer from its existing
4530 * subgroups and putting it in new subgroups.
4531 */
4532 void bgp_announce_route_all(struct peer *peer)
4533 {
4534 afi_t afi;
4535 safi_t safi;
4536
4537 FOREACH_AFI_SAFI (afi, safi)
4538 bgp_announce_route(peer, afi, safi);
4539 }
4540
4541 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
4542 struct bgp_table *table,
4543 struct prefix_rd *prd)
4544 {
4545 int ret;
4546 struct bgp_dest *dest;
4547 struct bgp_adj_in *ain;
4548
4549 if (!table)
4550 table = peer->bgp->rib[afi][safi];
4551
4552 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
4553 for (ain = dest->adj_in; ain; ain = ain->next) {
4554 if (ain->peer != peer)
4555 continue;
4556
4557 struct bgp_path_info *pi;
4558 uint32_t num_labels = 0;
4559 mpls_label_t *label_pnt = NULL;
4560 struct bgp_route_evpn evpn;
4561
4562 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
4563 pi = pi->next)
4564 if (pi->peer == peer)
4565 break;
4566
4567 if (pi && pi->extra)
4568 num_labels = pi->extra->num_labels;
4569 if (num_labels)
4570 label_pnt = &pi->extra->label[0];
4571 if (pi)
4572 memcpy(&evpn,
4573 bgp_attr_get_evpn_overlay(pi->attr),
4574 sizeof(evpn));
4575 else
4576 memset(&evpn, 0, sizeof(evpn));
4577
4578 ret = bgp_update(peer, bgp_dest_get_prefix(dest),
4579 ain->addpath_rx_id, ain->attr, afi,
4580 safi, ZEBRA_ROUTE_BGP,
4581 BGP_ROUTE_NORMAL, prd, label_pnt,
4582 num_labels, 1, &evpn);
4583
4584 if (ret < 0) {
4585 bgp_dest_unlock_node(dest);
4586 return;
4587 }
4588 }
4589 }
4590
4591 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
4592 {
4593 struct bgp_dest *dest;
4594 struct bgp_table *table;
4595
4596 if (peer->status != Established)
4597 return;
4598
4599 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
4600 && (safi != SAFI_EVPN))
4601 bgp_soft_reconfig_table(peer, afi, safi, NULL, NULL);
4602 else
4603 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4604 dest = bgp_route_next(dest)) {
4605 table = bgp_dest_get_bgp_table_info(dest);
4606
4607 if (table == NULL)
4608 continue;
4609
4610 const struct prefix *p = bgp_dest_get_prefix(dest);
4611 struct prefix_rd prd;
4612
4613 prd.family = AF_UNSPEC;
4614 prd.prefixlen = 64;
4615 memcpy(&prd.val, p->u.val, 8);
4616
4617 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
4618 }
4619 }
4620
4621
4622 struct bgp_clear_node_queue {
4623 struct bgp_dest *dest;
4624 };
4625
4626 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
4627 {
4628 struct bgp_clear_node_queue *cnq = data;
4629 struct bgp_dest *dest = cnq->dest;
4630 struct peer *peer = wq->spec.data;
4631 struct bgp_path_info *pi;
4632 struct bgp *bgp;
4633 afi_t afi = bgp_dest_table(dest)->afi;
4634 safi_t safi = bgp_dest_table(dest)->safi;
4635
4636 assert(dest && peer);
4637 bgp = peer->bgp;
4638
4639 /* It is possible that we have multiple paths for a prefix from a peer
4640 * if that peer is using AddPath.
4641 */
4642 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
4643 if (pi->peer != peer)
4644 continue;
4645
4646 /* graceful restart STALE flag set. */
4647 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
4648 && peer->nsf[afi][safi])
4649 || CHECK_FLAG(peer->af_sflags[afi][safi],
4650 PEER_STATUS_ENHANCED_REFRESH))
4651 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
4652 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
4653 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
4654 else {
4655 /* If this is an EVPN route, process for
4656 * un-import. */
4657 if (safi == SAFI_EVPN)
4658 bgp_evpn_unimport_route(
4659 bgp, afi, safi,
4660 bgp_dest_get_prefix(dest), pi);
4661 /* Handle withdraw for VRF route-leaking and L3VPN */
4662 if (SAFI_UNICAST == safi
4663 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
4664 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4665 vpn_leak_from_vrf_withdraw(bgp_get_default(),
4666 bgp, pi);
4667 }
4668 if (SAFI_MPLS_VPN == safi &&
4669 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4670 vpn_leak_to_vrf_withdraw(bgp, pi);
4671 }
4672
4673 bgp_rib_remove(dest, pi, peer, afi, safi);
4674 }
4675 }
4676 return WQ_SUCCESS;
4677 }
4678
4679 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
4680 {
4681 struct bgp_clear_node_queue *cnq = data;
4682 struct bgp_dest *dest = cnq->dest;
4683 struct bgp_table *table = bgp_dest_table(dest);
4684
4685 bgp_dest_unlock_node(dest);
4686 bgp_table_unlock(table);
4687 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
4688 }
4689
4690 static void bgp_clear_node_complete(struct work_queue *wq)
4691 {
4692 struct peer *peer = wq->spec.data;
4693
4694 /* Tickle FSM to start moving again */
4695 BGP_EVENT_ADD(peer, Clearing_Completed);
4696
4697 peer_unlock(peer); /* bgp_clear_route */
4698 }
4699
4700 static void bgp_clear_node_queue_init(struct peer *peer)
4701 {
4702 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
4703
4704 snprintf(wname, sizeof(wname), "clear %s", peer->host);
4705 #undef CLEAR_QUEUE_NAME_LEN
4706
4707 peer->clear_node_queue = work_queue_new(bm->master, wname);
4708 peer->clear_node_queue->spec.hold = 10;
4709 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
4710 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
4711 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
4712 peer->clear_node_queue->spec.max_retries = 0;
4713
4714 /* we only 'lock' this peer reference when the queue is actually active
4715 */
4716 peer->clear_node_queue->spec.data = peer;
4717 }
4718
4719 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
4720 struct bgp_table *table)
4721 {
4722 struct bgp_dest *dest;
4723 int force = peer->bgp->process_queue ? 0 : 1;
4724
4725 if (!table)
4726 table = peer->bgp->rib[afi][safi];
4727
4728 /* If still no table => afi/safi isn't configured at all or smth. */
4729 if (!table)
4730 return;
4731
4732 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4733 struct bgp_path_info *pi, *next;
4734 struct bgp_adj_in *ain;
4735 struct bgp_adj_in *ain_next;
4736
4737 /* XXX:TODO: This is suboptimal, every non-empty route_node is
4738 * queued for every clearing peer, regardless of whether it is
4739 * relevant to the peer at hand.
4740 *
4741 * Overview: There are 3 different indices which need to be
4742 * scrubbed, potentially, when a peer is removed:
4743 *
4744 * 1 peer's routes visible via the RIB (ie accepted routes)
4745 * 2 peer's routes visible by the (optional) peer's adj-in index
4746 * 3 other routes visible by the peer's adj-out index
4747 *
4748 * 3 there is no hurry in scrubbing, once the struct peer is
4749 * removed from bgp->peer, we could just GC such deleted peer's
4750 * adj-outs at our leisure.
4751 *
4752 * 1 and 2 must be 'scrubbed' in some way, at least made
4753 * invisible via RIB index before peer session is allowed to be
4754 * brought back up. So one needs to know when such a 'search' is
4755 * complete.
4756 *
4757 * Ideally:
4758 *
4759 * - there'd be a single global queue or a single RIB walker
4760 * - rather than tracking which route_nodes still need to be
4761 * examined on a peer basis, we'd track which peers still
4762 * aren't cleared
4763 *
4764 * Given that our per-peer prefix-counts now should be reliable,
4765 * this may actually be achievable. It doesn't seem to be a huge
4766 * problem at this time,
4767 *
4768 * It is possible that we have multiple paths for a prefix from
4769 * a peer
4770 * if that peer is using AddPath.
4771 */
4772 ain = dest->adj_in;
4773 while (ain) {
4774 ain_next = ain->next;
4775
4776 if (ain->peer == peer) {
4777 bgp_adj_in_remove(dest, ain);
4778 bgp_dest_unlock_node(dest);
4779 }
4780
4781 ain = ain_next;
4782 }
4783
4784 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
4785 next = pi->next;
4786 if (pi->peer != peer)
4787 continue;
4788
4789 if (force)
4790 bgp_path_info_reap(dest, pi);
4791 else {
4792 struct bgp_clear_node_queue *cnq;
4793
4794 /* both unlocked in bgp_clear_node_queue_del */
4795 bgp_table_lock(bgp_dest_table(dest));
4796 bgp_dest_lock_node(dest);
4797 cnq = XCALLOC(
4798 MTYPE_BGP_CLEAR_NODE_QUEUE,
4799 sizeof(struct bgp_clear_node_queue));
4800 cnq->dest = dest;
4801 work_queue_add(peer->clear_node_queue, cnq);
4802 break;
4803 }
4804 }
4805 }
4806 return;
4807 }
4808
4809 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
4810 {
4811 struct bgp_dest *dest;
4812 struct bgp_table *table;
4813
4814 if (peer->clear_node_queue == NULL)
4815 bgp_clear_node_queue_init(peer);
4816
4817 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
4818 * Idle until it receives a Clearing_Completed event. This protects
4819 * against peers which flap faster than we can we clear, which could
4820 * lead to:
4821 *
4822 * a) race with routes from the new session being installed before
4823 * clear_route_node visits the node (to delete the route of that
4824 * peer)
4825 * b) resource exhaustion, clear_route_node likely leads to an entry
4826 * on the process_main queue. Fast-flapping could cause that queue
4827 * to grow and grow.
4828 */
4829
4830 /* lock peer in assumption that clear-node-queue will get nodes; if so,
4831 * the unlock will happen upon work-queue completion; other wise, the
4832 * unlock happens at the end of this function.
4833 */
4834 if (!peer->clear_node_queue->thread)
4835 peer_lock(peer);
4836
4837 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
4838 bgp_clear_route_table(peer, afi, safi, NULL);
4839 else
4840 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4841 dest = bgp_route_next(dest)) {
4842 table = bgp_dest_get_bgp_table_info(dest);
4843 if (!table)
4844 continue;
4845
4846 bgp_clear_route_table(peer, afi, safi, table);
4847 }
4848
4849 /* unlock if no nodes got added to the clear-node-queue. */
4850 if (!peer->clear_node_queue->thread)
4851 peer_unlock(peer);
4852 }
4853
4854 void bgp_clear_route_all(struct peer *peer)
4855 {
4856 afi_t afi;
4857 safi_t safi;
4858
4859 FOREACH_AFI_SAFI (afi, safi)
4860 bgp_clear_route(peer, afi, safi);
4861
4862 #ifdef ENABLE_BGP_VNC
4863 rfapiProcessPeerDown(peer);
4864 #endif
4865 }
4866
4867 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
4868 {
4869 struct bgp_table *table;
4870 struct bgp_dest *dest;
4871 struct bgp_adj_in *ain;
4872 struct bgp_adj_in *ain_next;
4873
4874 table = peer->bgp->rib[afi][safi];
4875
4876 /* It is possible that we have multiple paths for a prefix from a peer
4877 * if that peer is using AddPath.
4878 */
4879 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4880 ain = dest->adj_in;
4881
4882 while (ain) {
4883 ain_next = ain->next;
4884
4885 if (ain->peer == peer) {
4886 bgp_adj_in_remove(dest, ain);
4887 bgp_dest_unlock_node(dest);
4888 }
4889
4890 ain = ain_next;
4891 }
4892 }
4893 }
4894
4895 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
4896 {
4897 struct bgp_dest *dest;
4898 struct bgp_path_info *pi;
4899 struct bgp_table *table;
4900
4901 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
4902 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4903 dest = bgp_route_next(dest)) {
4904 struct bgp_dest *rm;
4905
4906 /* look for neighbor in tables */
4907 table = bgp_dest_get_bgp_table_info(dest);
4908 if (!table)
4909 continue;
4910
4911 for (rm = bgp_table_top(table); rm;
4912 rm = bgp_route_next(rm))
4913 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
4914 pi = pi->next) {
4915 if (pi->peer != peer)
4916 continue;
4917 if (!CHECK_FLAG(pi->flags,
4918 BGP_PATH_STALE))
4919 break;
4920
4921 bgp_rib_remove(rm, pi, peer, afi, safi);
4922 break;
4923 }
4924 }
4925 } else {
4926 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4927 dest = bgp_route_next(dest))
4928 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
4929 pi = pi->next) {
4930 if (pi->peer != peer)
4931 continue;
4932 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
4933 break;
4934 bgp_rib_remove(dest, pi, peer, afi, safi);
4935 break;
4936 }
4937 }
4938 }
4939
4940 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
4941 {
4942 struct bgp_dest *dest, *ndest;
4943 struct bgp_path_info *pi;
4944 struct bgp_table *table;
4945
4946 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
4947 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4948 dest = bgp_route_next(dest)) {
4949 table = bgp_dest_get_bgp_table_info(dest);
4950 if (!table)
4951 continue;
4952
4953 for (ndest = bgp_table_top(table); ndest;
4954 ndest = bgp_route_next(ndest)) {
4955 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
4956 pi = pi->next) {
4957 if (pi->peer != peer)
4958 continue;
4959
4960 if ((CHECK_FLAG(
4961 peer->af_sflags[afi][safi],
4962 PEER_STATUS_ENHANCED_REFRESH))
4963 && !CHECK_FLAG(pi->flags,
4964 BGP_PATH_STALE)
4965 && !CHECK_FLAG(
4966 pi->flags,
4967 BGP_PATH_UNUSEABLE)) {
4968 if (bgp_debug_neighbor_events(
4969 peer))
4970 zlog_debug(
4971 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
4972 peer->host,
4973 afi2str(afi),
4974 safi2str(safi),
4975 bgp_dest_get_prefix(
4976 ndest));
4977
4978 bgp_path_info_set_flag(
4979 ndest, pi,
4980 BGP_PATH_STALE);
4981 }
4982 }
4983 }
4984 }
4985 } else {
4986 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4987 dest = bgp_route_next(dest)) {
4988 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
4989 pi = pi->next) {
4990 if (pi->peer != peer)
4991 continue;
4992
4993 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
4994 PEER_STATUS_ENHANCED_REFRESH))
4995 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
4996 && !CHECK_FLAG(pi->flags,
4997 BGP_PATH_UNUSEABLE)) {
4998 if (bgp_debug_neighbor_events(peer))
4999 zlog_debug(
5000 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
5001 peer->host,
5002 afi2str(afi),
5003 safi2str(safi),
5004 bgp_dest_get_prefix(
5005 dest));
5006
5007 bgp_path_info_set_flag(dest, pi,
5008 BGP_PATH_STALE);
5009 }
5010 }
5011 }
5012 }
5013 }
5014
5015 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5016 {
5017 if (peer->sort == BGP_PEER_IBGP)
5018 return true;
5019
5020 if (peer->sort == BGP_PEER_EBGP
5021 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5022 || FILTER_LIST_OUT_NAME(filter)
5023 || DISTRIBUTE_OUT_NAME(filter)))
5024 return true;
5025 return false;
5026 }
5027
5028 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5029 {
5030 if (peer->sort == BGP_PEER_IBGP)
5031 return true;
5032
5033 if (peer->sort == BGP_PEER_EBGP
5034 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5035 || FILTER_LIST_IN_NAME(filter)
5036 || DISTRIBUTE_IN_NAME(filter)))
5037 return true;
5038 return false;
5039 }
5040
5041 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5042 safi_t safi)
5043 {
5044 struct bgp_dest *dest;
5045 struct bgp_path_info *pi;
5046 struct bgp_path_info *next;
5047
5048 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5049 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5050 const struct prefix *p = bgp_dest_get_prefix(dest);
5051
5052 next = pi->next;
5053
5054 /* Unimport EVPN routes from VRFs */
5055 if (safi == SAFI_EVPN)
5056 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5057 SAFI_EVPN, p, pi);
5058
5059 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5060 && pi->type == ZEBRA_ROUTE_BGP
5061 && (pi->sub_type == BGP_ROUTE_NORMAL
5062 || pi->sub_type == BGP_ROUTE_AGGREGATE
5063 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5064
5065 if (bgp_fibupd_safi(safi))
5066 bgp_zebra_withdraw(p, pi, bgp, safi);
5067 }
5068
5069 bgp_path_info_reap(dest, pi);
5070 }
5071 }
5072
5073 /* Delete all kernel routes. */
5074 void bgp_cleanup_routes(struct bgp *bgp)
5075 {
5076 afi_t afi;
5077 struct bgp_dest *dest;
5078 struct bgp_table *table;
5079
5080 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5081 if (afi == AFI_L2VPN)
5082 continue;
5083 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5084 SAFI_UNICAST);
5085 /*
5086 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5087 */
5088 if (afi != AFI_L2VPN) {
5089 safi_t safi;
5090 safi = SAFI_MPLS_VPN;
5091 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5092 dest = bgp_route_next(dest)) {
5093 table = bgp_dest_get_bgp_table_info(dest);
5094 if (table != NULL) {
5095 bgp_cleanup_table(bgp, table, safi);
5096 bgp_table_finish(&table);
5097 bgp_dest_set_bgp_table_info(dest, NULL);
5098 bgp_dest_unlock_node(dest);
5099 }
5100 }
5101 safi = SAFI_ENCAP;
5102 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5103 dest = bgp_route_next(dest)) {
5104 table = bgp_dest_get_bgp_table_info(dest);
5105 if (table != NULL) {
5106 bgp_cleanup_table(bgp, table, safi);
5107 bgp_table_finish(&table);
5108 bgp_dest_set_bgp_table_info(dest, NULL);
5109 bgp_dest_unlock_node(dest);
5110 }
5111 }
5112 }
5113 }
5114 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5115 dest = bgp_route_next(dest)) {
5116 table = bgp_dest_get_bgp_table_info(dest);
5117 if (table != NULL) {
5118 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5119 bgp_table_finish(&table);
5120 bgp_dest_set_bgp_table_info(dest, NULL);
5121 bgp_dest_unlock_node(dest);
5122 }
5123 }
5124 }
5125
5126 void bgp_reset(void)
5127 {
5128 vty_reset();
5129 bgp_zclient_reset();
5130 access_list_reset();
5131 prefix_list_reset();
5132 }
5133
5134 static int bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5135 {
5136 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5137 && CHECK_FLAG(peer->af_cap[afi][safi],
5138 PEER_CAP_ADDPATH_AF_TX_RCV));
5139 }
5140
5141 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5142 value. */
5143 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5144 struct bgp_nlri *packet)
5145 {
5146 uint8_t *pnt;
5147 uint8_t *lim;
5148 struct prefix p;
5149 int psize;
5150 int ret;
5151 afi_t afi;
5152 safi_t safi;
5153 int addpath_encoded;
5154 uint32_t addpath_id;
5155
5156 pnt = packet->nlri;
5157 lim = pnt + packet->length;
5158 afi = packet->afi;
5159 safi = packet->safi;
5160 addpath_id = 0;
5161 addpath_encoded = bgp_addpath_encode_rx(peer, afi, safi);
5162
5163 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5164 syntactic validity. If the field is syntactically incorrect,
5165 then the Error Subcode is set to Invalid Network Field. */
5166 for (; pnt < lim; pnt += psize) {
5167 /* Clear prefix structure. */
5168 memset(&p, 0, sizeof(struct prefix));
5169
5170 if (addpath_encoded) {
5171
5172 /* When packet overflow occurs return immediately. */
5173 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5174 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5175
5176 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5177 addpath_id = ntohl(addpath_id);
5178 pnt += BGP_ADDPATH_ID_LEN;
5179 }
5180
5181 /* Fetch prefix length. */
5182 p.prefixlen = *pnt++;
5183 /* afi/safi validity already verified by caller,
5184 * bgp_update_receive */
5185 p.family = afi2family(afi);
5186
5187 /* Prefix length check. */
5188 if (p.prefixlen > prefix_blen(&p) * 8) {
5189 flog_err(
5190 EC_BGP_UPDATE_RCV,
5191 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
5192 peer->host, p.prefixlen, packet->afi);
5193 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
5194 }
5195
5196 /* Packet size overflow check. */
5197 psize = PSIZE(p.prefixlen);
5198
5199 /* When packet overflow occur return immediately. */
5200 if (pnt + psize > lim) {
5201 flog_err(
5202 EC_BGP_UPDATE_RCV,
5203 "%s [Error] Update packet error (prefix length %d overflows packet)",
5204 peer->host, p.prefixlen);
5205 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5206 }
5207
5208 /* Defensive coding, double-check the psize fits in a struct
5209 * prefix */
5210 if (psize > (ssize_t)sizeof(p.u)) {
5211 flog_err(
5212 EC_BGP_UPDATE_RCV,
5213 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
5214 peer->host, p.prefixlen, sizeof(p.u));
5215 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5216 }
5217
5218 /* Fetch prefix from NLRI packet. */
5219 memcpy(p.u.val, pnt, psize);
5220
5221 /* Check address. */
5222 if (afi == AFI_IP && safi == SAFI_UNICAST) {
5223 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
5224 /* From RFC4271 Section 6.3:
5225 *
5226 * If a prefix in the NLRI field is semantically
5227 * incorrect
5228 * (e.g., an unexpected multicast IP address),
5229 * an error SHOULD
5230 * be logged locally, and the prefix SHOULD be
5231 * ignored.
5232 */
5233 flog_err(
5234 EC_BGP_UPDATE_RCV,
5235 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
5236 peer->host, &p.u.prefix4);
5237 continue;
5238 }
5239 }
5240
5241 /* Check address. */
5242 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
5243 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
5244 char buf[BUFSIZ];
5245
5246 flog_err(
5247 EC_BGP_UPDATE_RCV,
5248 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
5249 peer->host,
5250 inet_ntop(AF_INET6, &p.u.prefix6, buf,
5251 BUFSIZ));
5252
5253 continue;
5254 }
5255 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
5256 char buf[BUFSIZ];
5257
5258 flog_err(
5259 EC_BGP_UPDATE_RCV,
5260 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
5261 peer->host,
5262 inet_ntop(AF_INET6, &p.u.prefix6, buf,
5263 BUFSIZ));
5264
5265 continue;
5266 }
5267 }
5268
5269 /* Normal process. */
5270 if (attr)
5271 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
5272 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
5273 NULL, NULL, 0, 0, NULL);
5274 else
5275 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
5276 safi, ZEBRA_ROUTE_BGP,
5277 BGP_ROUTE_NORMAL, NULL, NULL, 0,
5278 NULL);
5279
5280 /* Do not send BGP notification twice when maximum-prefix count
5281 * overflow. */
5282 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
5283 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
5284
5285 /* Address family configuration mismatch. */
5286 if (ret < 0)
5287 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
5288 }
5289
5290 /* Packet length consistency check. */
5291 if (pnt != lim) {
5292 flog_err(
5293 EC_BGP_UPDATE_RCV,
5294 "%s [Error] Update packet error (prefix length mismatch with total length)",
5295 peer->host);
5296 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5297 }
5298
5299 return BGP_NLRI_PARSE_OK;
5300 }
5301
5302 static struct bgp_static *bgp_static_new(void)
5303 {
5304 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
5305 }
5306
5307 static void bgp_static_free(struct bgp_static *bgp_static)
5308 {
5309 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5310 route_map_counter_decrement(bgp_static->rmap.map);
5311
5312 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
5313 XFREE(MTYPE_BGP_STATIC, bgp_static);
5314 }
5315
5316 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
5317 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
5318 {
5319 struct bgp_dest *dest;
5320 struct bgp_path_info *pi;
5321 struct bgp_path_info *new;
5322 struct bgp_path_info rmap_path;
5323 struct attr attr;
5324 struct attr *attr_new;
5325 route_map_result_t ret;
5326 #ifdef ENABLE_BGP_VNC
5327 int vnc_implicit_withdraw = 0;
5328 #endif
5329
5330 assert(bgp_static);
5331
5332 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5333
5334 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5335
5336 attr.nexthop = bgp_static->igpnexthop;
5337 attr.med = bgp_static->igpmetric;
5338 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5339
5340 if (bgp_static->atomic)
5341 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
5342
5343 /* Store label index, if required. */
5344 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
5345 attr.label_index = bgp_static->label_index;
5346 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
5347 }
5348
5349 /* Apply route-map. */
5350 if (bgp_static->rmap.name) {
5351 struct attr attr_tmp = attr;
5352
5353 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
5354 rmap_path.peer = bgp->peer_self;
5355 rmap_path.attr = &attr_tmp;
5356
5357 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5358
5359 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
5360
5361 bgp->peer_self->rmap_type = 0;
5362
5363 if (ret == RMAP_DENYMATCH) {
5364 /* Free uninterned attribute. */
5365 bgp_attr_flush(&attr_tmp);
5366
5367 /* Unintern original. */
5368 aspath_unintern(&attr.aspath);
5369 bgp_static_withdraw(bgp, p, afi, safi);
5370 return;
5371 }
5372
5373 if (bgp_in_graceful_shutdown(bgp))
5374 bgp_attr_add_gshut_community(&attr_tmp);
5375
5376 attr_new = bgp_attr_intern(&attr_tmp);
5377 } else {
5378
5379 if (bgp_in_graceful_shutdown(bgp))
5380 bgp_attr_add_gshut_community(&attr);
5381
5382 attr_new = bgp_attr_intern(&attr);
5383 }
5384
5385 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5386 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5387 && pi->sub_type == BGP_ROUTE_STATIC)
5388 break;
5389
5390 if (pi) {
5391 if (attrhash_cmp(pi->attr, attr_new)
5392 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
5393 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
5394 bgp_dest_unlock_node(dest);
5395 bgp_attr_unintern(&attr_new);
5396 aspath_unintern(&attr.aspath);
5397 return;
5398 } else {
5399 /* The attribute is changed. */
5400 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5401
5402 /* Rewrite BGP route information. */
5403 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5404 bgp_path_info_restore(dest, pi);
5405 else
5406 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5407 #ifdef ENABLE_BGP_VNC
5408 if ((afi == AFI_IP || afi == AFI_IP6)
5409 && (safi == SAFI_UNICAST)) {
5410 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
5411 /*
5412 * Implicit withdraw case.
5413 * We have to do this before pi is
5414 * changed
5415 */
5416 ++vnc_implicit_withdraw;
5417 vnc_import_bgp_del_route(bgp, p, pi);
5418 vnc_import_bgp_exterior_del_route(
5419 bgp, p, pi);
5420 }
5421 }
5422 #endif
5423 bgp_attr_unintern(&pi->attr);
5424 pi->attr = attr_new;
5425 pi->uptime = bgp_clock();
5426 #ifdef ENABLE_BGP_VNC
5427 if ((afi == AFI_IP || afi == AFI_IP6)
5428 && (safi == SAFI_UNICAST)) {
5429 if (vnc_implicit_withdraw) {
5430 vnc_import_bgp_add_route(bgp, p, pi);
5431 vnc_import_bgp_exterior_add_route(
5432 bgp, p, pi);
5433 }
5434 }
5435 #endif
5436
5437 /* Nexthop reachability check. */
5438 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5439 && (safi == SAFI_UNICAST
5440 || safi == SAFI_LABELED_UNICAST)) {
5441
5442 struct bgp *bgp_nexthop = bgp;
5443
5444 if (pi->extra && pi->extra->bgp_orig)
5445 bgp_nexthop = pi->extra->bgp_orig;
5446
5447 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
5448 afi, safi, pi, NULL,
5449 0))
5450 bgp_path_info_set_flag(dest, pi,
5451 BGP_PATH_VALID);
5452 else {
5453 if (BGP_DEBUG(nht, NHT)) {
5454 char buf1[INET6_ADDRSTRLEN];
5455 inet_ntop(p->family,
5456 &p->u.prefix, buf1,
5457 INET6_ADDRSTRLEN);
5458 zlog_debug(
5459 "%s(%s): Route not in table, not advertising",
5460 __func__, buf1);
5461 }
5462 bgp_path_info_unset_flag(
5463 dest, pi, BGP_PATH_VALID);
5464 }
5465 } else {
5466 /* Delete the NHT structure if any, if we're
5467 * toggling between
5468 * enabling/disabling import check. We
5469 * deregister the route
5470 * from NHT to avoid overloading NHT and the
5471 * process interaction
5472 */
5473 bgp_unlink_nexthop(pi);
5474 bgp_path_info_set_flag(dest, pi,
5475 BGP_PATH_VALID);
5476 }
5477 /* Process change. */
5478 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5479 bgp_process(bgp, dest, afi, safi);
5480
5481 if (SAFI_UNICAST == safi
5482 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5483 || bgp->inst_type
5484 == BGP_INSTANCE_TYPE_DEFAULT)) {
5485 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
5486 pi);
5487 }
5488
5489 bgp_dest_unlock_node(dest);
5490 aspath_unintern(&attr.aspath);
5491 return;
5492 }
5493 }
5494
5495 /* Make new BGP info. */
5496 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5497 attr_new, dest);
5498 /* Nexthop reachability check. */
5499 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5500 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
5501 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0))
5502 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5503 else {
5504 if (BGP_DEBUG(nht, NHT)) {
5505 char buf1[INET6_ADDRSTRLEN];
5506 inet_ntop(p->family, &p->u.prefix, buf1,
5507 INET6_ADDRSTRLEN);
5508 zlog_debug(
5509 "%s(%s): Route not in table, not advertising",
5510 __func__, buf1);
5511 }
5512 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
5513 }
5514 } else {
5515 /* Delete the NHT structure if any, if we're toggling between
5516 * enabling/disabling import check. We deregister the route
5517 * from NHT to avoid overloading NHT and the process interaction
5518 */
5519 bgp_unlink_nexthop(new);
5520
5521 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5522 }
5523
5524 /* Aggregate address increment. */
5525 bgp_aggregate_increment(bgp, p, new, afi, safi);
5526
5527 /* Register new BGP information. */
5528 bgp_path_info_add(dest, new);
5529
5530 /* route_node_get lock */
5531 bgp_dest_unlock_node(dest);
5532
5533 /* Process change. */
5534 bgp_process(bgp, dest, afi, safi);
5535
5536 if (SAFI_UNICAST == safi
5537 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5538 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5539 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
5540 }
5541
5542 /* Unintern original. */
5543 aspath_unintern(&attr.aspath);
5544 }
5545
5546 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
5547 safi_t safi)
5548 {
5549 struct bgp_dest *dest;
5550 struct bgp_path_info *pi;
5551
5552 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5553
5554 /* Check selected route and self inserted route. */
5555 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5556 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5557 && pi->sub_type == BGP_ROUTE_STATIC)
5558 break;
5559
5560 /* Withdraw static BGP route from routing table. */
5561 if (pi) {
5562 if (SAFI_UNICAST == safi
5563 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5564 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5565 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5566 }
5567 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5568 bgp_unlink_nexthop(pi);
5569 bgp_path_info_delete(dest, pi);
5570 bgp_process(bgp, dest, afi, safi);
5571 }
5572
5573 /* Unlock bgp_node_lookup. */
5574 bgp_dest_unlock_node(dest);
5575 }
5576
5577 /*
5578 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
5579 */
5580 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
5581 afi_t afi, safi_t safi,
5582 struct prefix_rd *prd)
5583 {
5584 struct bgp_dest *dest;
5585 struct bgp_path_info *pi;
5586
5587 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
5588
5589 /* Check selected route and self inserted route. */
5590 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5591 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5592 && pi->sub_type == BGP_ROUTE_STATIC)
5593 break;
5594
5595 /* Withdraw static BGP route from routing table. */
5596 if (pi) {
5597 #ifdef ENABLE_BGP_VNC
5598 rfapiProcessWithdraw(
5599 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
5600 1); /* Kill, since it is an administrative change */
5601 #endif
5602 if (SAFI_MPLS_VPN == safi
5603 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5604 vpn_leak_to_vrf_withdraw(bgp, pi);
5605 }
5606 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5607 bgp_path_info_delete(dest, pi);
5608 bgp_process(bgp, dest, afi, safi);
5609 }
5610
5611 /* Unlock bgp_node_lookup. */
5612 bgp_dest_unlock_node(dest);
5613 }
5614
5615 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
5616 struct bgp_static *bgp_static, afi_t afi,
5617 safi_t safi)
5618 {
5619 struct bgp_dest *dest;
5620 struct bgp_path_info *new;
5621 struct attr *attr_new;
5622 struct attr attr = {0};
5623 struct bgp_path_info *pi;
5624 #ifdef ENABLE_BGP_VNC
5625 mpls_label_t label = 0;
5626 #endif
5627 uint32_t num_labels = 0;
5628 union gw_addr add;
5629
5630 assert(bgp_static);
5631
5632 if (bgp_static->label != MPLS_INVALID_LABEL)
5633 num_labels = 1;
5634 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
5635 &bgp_static->prd);
5636
5637 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5638
5639 attr.nexthop = bgp_static->igpnexthop;
5640 attr.med = bgp_static->igpmetric;
5641 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5642
5643 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
5644 || (safi == SAFI_ENCAP)) {
5645 if (afi == AFI_IP) {
5646 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
5647 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
5648 }
5649 }
5650 if (afi == AFI_L2VPN) {
5651 if (bgp_static->gatewayIp.family == AF_INET)
5652 add.ipv4.s_addr =
5653 bgp_static->gatewayIp.u.prefix4.s_addr;
5654 else if (bgp_static->gatewayIp.family == AF_INET6)
5655 memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
5656 sizeof(struct in6_addr));
5657 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
5658 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
5659 struct bgp_encap_type_vxlan bet;
5660 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
5661 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
5662 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
5663 }
5664 if (bgp_static->router_mac) {
5665 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
5666 }
5667 }
5668 /* Apply route-map. */
5669 if (bgp_static->rmap.name) {
5670 struct attr attr_tmp = attr;
5671 struct bgp_path_info rmap_path;
5672 route_map_result_t ret;
5673
5674 rmap_path.peer = bgp->peer_self;
5675 rmap_path.attr = &attr_tmp;
5676
5677 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5678
5679 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
5680
5681 bgp->peer_self->rmap_type = 0;
5682
5683 if (ret == RMAP_DENYMATCH) {
5684 /* Free uninterned attribute. */
5685 bgp_attr_flush(&attr_tmp);
5686
5687 /* Unintern original. */
5688 aspath_unintern(&attr.aspath);
5689 bgp_static_withdraw_safi(bgp, p, afi, safi,
5690 &bgp_static->prd);
5691 return;
5692 }
5693
5694 attr_new = bgp_attr_intern(&attr_tmp);
5695 } else {
5696 attr_new = bgp_attr_intern(&attr);
5697 }
5698
5699 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5700 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5701 && pi->sub_type == BGP_ROUTE_STATIC)
5702 break;
5703
5704 if (pi) {
5705 memset(&add, 0, sizeof(union gw_addr));
5706 if (attrhash_cmp(pi->attr, attr_new)
5707 && overlay_index_equal(afi, pi, &add)
5708 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
5709 bgp_dest_unlock_node(dest);
5710 bgp_attr_unintern(&attr_new);
5711 aspath_unintern(&attr.aspath);
5712 return;
5713 } else {
5714 /* The attribute is changed. */
5715 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5716
5717 /* Rewrite BGP route information. */
5718 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5719 bgp_path_info_restore(dest, pi);
5720 else
5721 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5722 bgp_attr_unintern(&pi->attr);
5723 pi->attr = attr_new;
5724 pi->uptime = bgp_clock();
5725 #ifdef ENABLE_BGP_VNC
5726 if (pi->extra)
5727 label = decode_label(&pi->extra->label[0]);
5728 #endif
5729
5730 /* Process change. */
5731 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5732 bgp_process(bgp, dest, afi, safi);
5733
5734 if (SAFI_MPLS_VPN == safi
5735 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5736 vpn_leak_to_vrf_update(bgp, pi);
5737 }
5738 #ifdef ENABLE_BGP_VNC
5739 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
5740 pi->attr, afi, safi, pi->type,
5741 pi->sub_type, &label);
5742 #endif
5743 bgp_dest_unlock_node(dest);
5744 aspath_unintern(&attr.aspath);
5745 return;
5746 }
5747 }
5748
5749
5750 /* Make new BGP info. */
5751 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5752 attr_new, dest);
5753 SET_FLAG(new->flags, BGP_PATH_VALID);
5754 new->extra = bgp_path_info_extra_new();
5755 if (num_labels) {
5756 new->extra->label[0] = bgp_static->label;
5757 new->extra->num_labels = num_labels;
5758 }
5759 #ifdef ENABLE_BGP_VNC
5760 label = decode_label(&bgp_static->label);
5761 #endif
5762
5763 /* Aggregate address increment. */
5764 bgp_aggregate_increment(bgp, p, new, afi, safi);
5765
5766 /* Register new BGP information. */
5767 bgp_path_info_add(dest, new);
5768 /* route_node_get lock */
5769 bgp_dest_unlock_node(dest);
5770
5771 /* Process change. */
5772 bgp_process(bgp, dest, afi, safi);
5773
5774 if (SAFI_MPLS_VPN == safi
5775 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5776 vpn_leak_to_vrf_update(bgp, new);
5777 }
5778 #ifdef ENABLE_BGP_VNC
5779 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
5780 safi, new->type, new->sub_type, &label);
5781 #endif
5782
5783 /* Unintern original. */
5784 aspath_unintern(&attr.aspath);
5785 }
5786
5787 /* Configure static BGP network. When user don't run zebra, static
5788 route should be installed as valid. */
5789 int bgp_static_set(struct bgp *bgp, const char *negate, struct prefix *pfx,
5790 afi_t afi, safi_t safi, const char *rmap, int backdoor,
5791 uint32_t label_index, char *errmsg, size_t errmsg_len)
5792 {
5793 struct prefix p;
5794 struct bgp_static *bgp_static;
5795 struct bgp_dest *dest;
5796 uint8_t need_update = 0;
5797
5798 prefix_copy(&p, pfx);
5799 apply_mask(&p);
5800
5801 if (negate) {
5802
5803 /* Set BGP static route configuration. */
5804 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
5805
5806 if (!dest) {
5807 snprintf(errmsg, errmsg_len,
5808 "Can't find static route specified\n");
5809 return -1;
5810 }
5811
5812 bgp_static = bgp_dest_get_bgp_static_info(dest);
5813
5814 if ((label_index != BGP_INVALID_LABEL_INDEX)
5815 && (label_index != bgp_static->label_index)) {
5816 snprintf(errmsg, errmsg_len,
5817 "label-index doesn't match static route\n");
5818 return -1;
5819 }
5820
5821 if ((rmap && bgp_static->rmap.name)
5822 && strcmp(rmap, bgp_static->rmap.name)) {
5823 snprintf(errmsg, errmsg_len,
5824 "route-map name doesn't match static route\n");
5825 return -1;
5826 }
5827
5828 /* Update BGP RIB. */
5829 if (!bgp_static->backdoor)
5830 bgp_static_withdraw(bgp, &p, afi, safi);
5831
5832 /* Clear configuration. */
5833 bgp_static_free(bgp_static);
5834 bgp_dest_set_bgp_static_info(dest, NULL);
5835 bgp_dest_unlock_node(dest);
5836 bgp_dest_unlock_node(dest);
5837 } else {
5838
5839 /* Set BGP static route configuration. */
5840 dest = bgp_node_get(bgp->route[afi][safi], &p);
5841 bgp_static = bgp_dest_get_bgp_static_info(dest);
5842 if (bgp_static) {
5843 /* Configuration change. */
5844 /* Label index cannot be changed. */
5845 if (bgp_static->label_index != label_index) {
5846 snprintf(errmsg, errmsg_len,
5847 "cannot change label-index\n");
5848 return -1;
5849 }
5850
5851 /* Check previous routes are installed into BGP. */
5852 if (bgp_static->valid
5853 && bgp_static->backdoor != backdoor)
5854 need_update = 1;
5855
5856 bgp_static->backdoor = backdoor;
5857
5858 if (rmap) {
5859 XFREE(MTYPE_ROUTE_MAP_NAME,
5860 bgp_static->rmap.name);
5861 route_map_counter_decrement(
5862 bgp_static->rmap.map);
5863 bgp_static->rmap.name =
5864 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5865 bgp_static->rmap.map =
5866 route_map_lookup_by_name(rmap);
5867 route_map_counter_increment(
5868 bgp_static->rmap.map);
5869 } else {
5870 XFREE(MTYPE_ROUTE_MAP_NAME,
5871 bgp_static->rmap.name);
5872 route_map_counter_decrement(
5873 bgp_static->rmap.map);
5874 bgp_static->rmap.map = NULL;
5875 bgp_static->valid = 0;
5876 }
5877 bgp_dest_unlock_node(dest);
5878 } else {
5879 /* New configuration. */
5880 bgp_static = bgp_static_new();
5881 bgp_static->backdoor = backdoor;
5882 bgp_static->valid = 0;
5883 bgp_static->igpmetric = 0;
5884 bgp_static->igpnexthop.s_addr = INADDR_ANY;
5885 bgp_static->label_index = label_index;
5886
5887 if (rmap) {
5888 XFREE(MTYPE_ROUTE_MAP_NAME,
5889 bgp_static->rmap.name);
5890 route_map_counter_decrement(
5891 bgp_static->rmap.map);
5892 bgp_static->rmap.name =
5893 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5894 bgp_static->rmap.map =
5895 route_map_lookup_by_name(rmap);
5896 route_map_counter_increment(
5897 bgp_static->rmap.map);
5898 }
5899 bgp_dest_set_bgp_static_info(dest, bgp_static);
5900 }
5901
5902 bgp_static->valid = 1;
5903 if (need_update)
5904 bgp_static_withdraw(bgp, &p, afi, safi);
5905
5906 if (!bgp_static->backdoor)
5907 bgp_static_update(bgp, &p, bgp_static, afi, safi);
5908 }
5909
5910 return 0;
5911 }
5912
5913 void bgp_static_add(struct bgp *bgp)
5914 {
5915 afi_t afi;
5916 safi_t safi;
5917 struct bgp_dest *dest;
5918 struct bgp_dest *rm;
5919 struct bgp_table *table;
5920 struct bgp_static *bgp_static;
5921
5922 FOREACH_AFI_SAFI (afi, safi)
5923 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
5924 dest = bgp_route_next(dest)) {
5925 if (!bgp_dest_has_bgp_path_info_data(dest))
5926 continue;
5927
5928 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5929 || (safi == SAFI_EVPN)) {
5930 table = bgp_dest_get_bgp_table_info(dest);
5931
5932 for (rm = bgp_table_top(table); rm;
5933 rm = bgp_route_next(rm)) {
5934 bgp_static =
5935 bgp_dest_get_bgp_static_info(
5936 rm);
5937 bgp_static_update_safi(
5938 bgp, bgp_dest_get_prefix(rm),
5939 bgp_static, afi, safi);
5940 }
5941 } else {
5942 bgp_static_update(
5943 bgp, bgp_dest_get_prefix(dest),
5944 bgp_dest_get_bgp_static_info(dest), afi,
5945 safi);
5946 }
5947 }
5948 }
5949
5950 /* Called from bgp_delete(). Delete all static routes from the BGP
5951 instance. */
5952 void bgp_static_delete(struct bgp *bgp)
5953 {
5954 afi_t afi;
5955 safi_t safi;
5956 struct bgp_dest *dest;
5957 struct bgp_dest *rm;
5958 struct bgp_table *table;
5959 struct bgp_static *bgp_static;
5960
5961 FOREACH_AFI_SAFI (afi, safi)
5962 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
5963 dest = bgp_route_next(dest)) {
5964 if (!bgp_dest_has_bgp_path_info_data(dest))
5965 continue;
5966
5967 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5968 || (safi == SAFI_EVPN)) {
5969 table = bgp_dest_get_bgp_table_info(dest);
5970
5971 for (rm = bgp_table_top(table); rm;
5972 rm = bgp_route_next(rm)) {
5973 bgp_static =
5974 bgp_dest_get_bgp_static_info(
5975 rm);
5976 if (!bgp_static)
5977 continue;
5978
5979 bgp_static_withdraw_safi(
5980 bgp, bgp_dest_get_prefix(rm),
5981 AFI_IP, safi,
5982 (struct prefix_rd *)
5983 bgp_dest_get_prefix(
5984 dest));
5985 bgp_static_free(bgp_static);
5986 bgp_dest_set_bgp_static_info(rm,
5987 NULL);
5988 bgp_dest_unlock_node(rm);
5989 }
5990 } else {
5991 bgp_static = bgp_dest_get_bgp_static_info(dest);
5992 bgp_static_withdraw(bgp,
5993 bgp_dest_get_prefix(dest),
5994 afi, safi);
5995 bgp_static_free(bgp_static);
5996 bgp_dest_set_bgp_static_info(dest, NULL);
5997 bgp_dest_unlock_node(dest);
5998 }
5999 }
6000 }
6001
6002 void bgp_static_redo_import_check(struct bgp *bgp)
6003 {
6004 afi_t afi;
6005 safi_t safi;
6006 struct bgp_dest *dest;
6007 struct bgp_dest *rm;
6008 struct bgp_table *table;
6009 struct bgp_static *bgp_static;
6010
6011 /* Use this flag to force reprocessing of the route */
6012 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6013 FOREACH_AFI_SAFI (afi, safi) {
6014 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6015 dest = bgp_route_next(dest)) {
6016 if (!bgp_dest_has_bgp_path_info_data(dest))
6017 continue;
6018
6019 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6020 || (safi == SAFI_EVPN)) {
6021 table = bgp_dest_get_bgp_table_info(dest);
6022
6023 for (rm = bgp_table_top(table); rm;
6024 rm = bgp_route_next(rm)) {
6025 bgp_static =
6026 bgp_dest_get_bgp_static_info(
6027 rm);
6028 bgp_static_update_safi(
6029 bgp, bgp_dest_get_prefix(rm),
6030 bgp_static, afi, safi);
6031 }
6032 } else {
6033 bgp_static = bgp_dest_get_bgp_static_info(dest);
6034 bgp_static_update(bgp,
6035 bgp_dest_get_prefix(dest),
6036 bgp_static, afi, safi);
6037 }
6038 }
6039 }
6040 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6041 }
6042
6043 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6044 safi_t safi)
6045 {
6046 struct bgp_table *table;
6047 struct bgp_dest *dest;
6048 struct bgp_path_info *pi;
6049
6050 /* Do not install the aggregate route if BGP is in the
6051 * process of termination.
6052 */
6053 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6054 || (bgp->peer_self == NULL))
6055 return;
6056
6057 table = bgp->rib[afi][safi];
6058 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6059 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6060 if (pi->peer == bgp->peer_self
6061 && ((pi->type == ZEBRA_ROUTE_BGP
6062 && pi->sub_type == BGP_ROUTE_STATIC)
6063 || (pi->type != ZEBRA_ROUTE_BGP
6064 && pi->sub_type
6065 == BGP_ROUTE_REDISTRIBUTE))) {
6066 bgp_aggregate_decrement(
6067 bgp, bgp_dest_get_prefix(dest), pi, afi,
6068 safi);
6069 bgp_unlink_nexthop(pi);
6070 bgp_path_info_delete(dest, pi);
6071 bgp_process(bgp, dest, afi, safi);
6072 }
6073 }
6074 }
6075 }
6076
6077 /*
6078 * Purge all networks and redistributed routes from routing table.
6079 * Invoked upon the instance going down.
6080 */
6081 void bgp_purge_static_redist_routes(struct bgp *bgp)
6082 {
6083 afi_t afi;
6084 safi_t safi;
6085
6086 FOREACH_AFI_SAFI (afi, safi)
6087 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6088 }
6089
6090 /*
6091 * gpz 110624
6092 * Currently this is used to set static routes for VPN and ENCAP.
6093 * I think it can probably be factored with bgp_static_set.
6094 */
6095 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6096 const char *ip_str, const char *rd_str,
6097 const char *label_str, const char *rmap_str,
6098 int evpn_type, const char *esi, const char *gwip,
6099 const char *ethtag, const char *routermac)
6100 {
6101 VTY_DECLVAR_CONTEXT(bgp, bgp);
6102 int ret;
6103 struct prefix p;
6104 struct prefix_rd prd;
6105 struct bgp_dest *pdest;
6106 struct bgp_dest *dest;
6107 struct bgp_table *table;
6108 struct bgp_static *bgp_static;
6109 mpls_label_t label = MPLS_INVALID_LABEL;
6110 struct prefix gw_ip;
6111
6112 /* validate ip prefix */
6113 ret = str2prefix(ip_str, &p);
6114 if (!ret) {
6115 vty_out(vty, "%% Malformed prefix\n");
6116 return CMD_WARNING_CONFIG_FAILED;
6117 }
6118 apply_mask(&p);
6119 if ((afi == AFI_L2VPN)
6120 && (bgp_build_evpn_prefix(evpn_type,
6121 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6122 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6123 return CMD_WARNING_CONFIG_FAILED;
6124 }
6125
6126 ret = str2prefix_rd(rd_str, &prd);
6127 if (!ret) {
6128 vty_out(vty, "%% Malformed rd\n");
6129 return CMD_WARNING_CONFIG_FAILED;
6130 }
6131
6132 if (label_str) {
6133 unsigned long label_val;
6134 label_val = strtoul(label_str, NULL, 10);
6135 encode_label(label_val, &label);
6136 }
6137
6138 if (safi == SAFI_EVPN) {
6139 if (esi && str2esi(esi, NULL) == 0) {
6140 vty_out(vty, "%% Malformed ESI\n");
6141 return CMD_WARNING_CONFIG_FAILED;
6142 }
6143 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6144 vty_out(vty, "%% Malformed Router MAC\n");
6145 return CMD_WARNING_CONFIG_FAILED;
6146 }
6147 if (gwip) {
6148 memset(&gw_ip, 0, sizeof(struct prefix));
6149 ret = str2prefix(gwip, &gw_ip);
6150 if (!ret) {
6151 vty_out(vty, "%% Malformed GatewayIp\n");
6152 return CMD_WARNING_CONFIG_FAILED;
6153 }
6154 if ((gw_ip.family == AF_INET
6155 && is_evpn_prefix_ipaddr_v6(
6156 (struct prefix_evpn *)&p))
6157 || (gw_ip.family == AF_INET6
6158 && is_evpn_prefix_ipaddr_v4(
6159 (struct prefix_evpn *)&p))) {
6160 vty_out(vty,
6161 "%% GatewayIp family differs with IP prefix\n");
6162 return CMD_WARNING_CONFIG_FAILED;
6163 }
6164 }
6165 }
6166 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6167 if (!bgp_dest_has_bgp_path_info_data(pdest))
6168 bgp_dest_set_bgp_table_info(pdest,
6169 bgp_table_init(bgp, afi, safi));
6170 table = bgp_dest_get_bgp_table_info(pdest);
6171
6172 dest = bgp_node_get(table, &p);
6173
6174 if (bgp_dest_has_bgp_path_info_data(dest)) {
6175 vty_out(vty, "%% Same network configuration exists\n");
6176 bgp_dest_unlock_node(dest);
6177 } else {
6178 /* New configuration. */
6179 bgp_static = bgp_static_new();
6180 bgp_static->backdoor = 0;
6181 bgp_static->valid = 0;
6182 bgp_static->igpmetric = 0;
6183 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6184 bgp_static->label = label;
6185 bgp_static->prd = prd;
6186
6187 if (rmap_str) {
6188 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6189 route_map_counter_decrement(bgp_static->rmap.map);
6190 bgp_static->rmap.name =
6191 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
6192 bgp_static->rmap.map =
6193 route_map_lookup_by_name(rmap_str);
6194 route_map_counter_increment(bgp_static->rmap.map);
6195 }
6196
6197 if (safi == SAFI_EVPN) {
6198 if (esi) {
6199 bgp_static->eth_s_id =
6200 XCALLOC(MTYPE_ATTR,
6201 sizeof(esi_t));
6202 str2esi(esi, bgp_static->eth_s_id);
6203 }
6204 if (routermac) {
6205 bgp_static->router_mac =
6206 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
6207 (void)prefix_str2mac(routermac,
6208 bgp_static->router_mac);
6209 }
6210 if (gwip)
6211 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
6212 }
6213 bgp_dest_set_bgp_static_info(dest, bgp_static);
6214
6215 bgp_static->valid = 1;
6216 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
6217 }
6218
6219 return CMD_SUCCESS;
6220 }
6221
6222 /* Configure static BGP network. */
6223 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
6224 const char *ip_str, const char *rd_str,
6225 const char *label_str, int evpn_type, const char *esi,
6226 const char *gwip, const char *ethtag)
6227 {
6228 VTY_DECLVAR_CONTEXT(bgp, bgp);
6229 int ret;
6230 struct prefix p;
6231 struct prefix_rd prd;
6232 struct bgp_dest *pdest;
6233 struct bgp_dest *dest;
6234 struct bgp_table *table;
6235 struct bgp_static *bgp_static;
6236 mpls_label_t label = MPLS_INVALID_LABEL;
6237
6238 /* Convert IP prefix string to struct prefix. */
6239 ret = str2prefix(ip_str, &p);
6240 if (!ret) {
6241 vty_out(vty, "%% Malformed prefix\n");
6242 return CMD_WARNING_CONFIG_FAILED;
6243 }
6244 apply_mask(&p);
6245 if ((afi == AFI_L2VPN)
6246 && (bgp_build_evpn_prefix(evpn_type,
6247 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6248 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6249 return CMD_WARNING_CONFIG_FAILED;
6250 }
6251 ret = str2prefix_rd(rd_str, &prd);
6252 if (!ret) {
6253 vty_out(vty, "%% Malformed rd\n");
6254 return CMD_WARNING_CONFIG_FAILED;
6255 }
6256
6257 if (label_str) {
6258 unsigned long label_val;
6259 label_val = strtoul(label_str, NULL, 10);
6260 encode_label(label_val, &label);
6261 }
6262
6263 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6264 if (!bgp_dest_has_bgp_path_info_data(pdest))
6265 bgp_dest_set_bgp_table_info(pdest,
6266 bgp_table_init(bgp, afi, safi));
6267 else
6268 bgp_dest_unlock_node(pdest);
6269 table = bgp_dest_get_bgp_table_info(pdest);
6270
6271 dest = bgp_node_lookup(table, &p);
6272
6273 if (dest) {
6274 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
6275
6276 bgp_static = bgp_dest_get_bgp_static_info(dest);
6277 bgp_static_free(bgp_static);
6278 bgp_dest_set_bgp_static_info(dest, NULL);
6279 bgp_dest_unlock_node(dest);
6280 bgp_dest_unlock_node(dest);
6281 } else
6282 vty_out(vty, "%% Can't find the route\n");
6283
6284 return CMD_SUCCESS;
6285 }
6286
6287 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
6288 const char *rmap_name)
6289 {
6290 VTY_DECLVAR_CONTEXT(bgp, bgp);
6291 struct bgp_rmap *rmap;
6292
6293 rmap = &bgp->table_map[afi][safi];
6294 if (rmap_name) {
6295 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6296 route_map_counter_decrement(rmap->map);
6297 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
6298 rmap->map = route_map_lookup_by_name(rmap_name);
6299 route_map_counter_increment(rmap->map);
6300 } else {
6301 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6302 route_map_counter_decrement(rmap->map);
6303 rmap->map = NULL;
6304 }
6305
6306 if (bgp_fibupd_safi(safi))
6307 bgp_zebra_announce_table(bgp, afi, safi);
6308
6309 return CMD_SUCCESS;
6310 }
6311
6312 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
6313 const char *rmap_name)
6314 {
6315 VTY_DECLVAR_CONTEXT(bgp, bgp);
6316 struct bgp_rmap *rmap;
6317
6318 rmap = &bgp->table_map[afi][safi];
6319 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6320 route_map_counter_decrement(rmap->map);
6321 rmap->map = NULL;
6322
6323 if (bgp_fibupd_safi(safi))
6324 bgp_zebra_announce_table(bgp, afi, safi);
6325
6326 return CMD_SUCCESS;
6327 }
6328
6329 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
6330 safi_t safi)
6331 {
6332 if (bgp->table_map[afi][safi].name) {
6333 vty_out(vty, " table-map %s\n",
6334 bgp->table_map[afi][safi].name);
6335 }
6336 }
6337
6338 DEFUN (bgp_table_map,
6339 bgp_table_map_cmd,
6340 "table-map WORD",
6341 "BGP table to RIB route download filter\n"
6342 "Name of the route map\n")
6343 {
6344 int idx_word = 1;
6345 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6346 argv[idx_word]->arg);
6347 }
6348 DEFUN (no_bgp_table_map,
6349 no_bgp_table_map_cmd,
6350 "no table-map WORD",
6351 NO_STR
6352 "BGP table to RIB route download filter\n"
6353 "Name of the route map\n")
6354 {
6355 int idx_word = 2;
6356 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6357 argv[idx_word]->arg);
6358 }
6359
6360 DEFPY_YANG (bgp_network, bgp_network_cmd,
6361 "[no] network \
6362 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
6363 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
6364 backdoor$backdoor}]",
6365 NO_STR
6366 "Specify a network to announce via BGP\n"
6367 "IPv4 prefix\n"
6368 "Network number\n"
6369 "Network mask\n"
6370 "Network mask\n"
6371 "Route-map to modify the attributes\n"
6372 "Name of the route map\n"
6373 "Label index to associate with the prefix\n"
6374 "Label index value\n"
6375 "Specify a BGP backdoor route\n")
6376 {
6377 char addr_prefix_str[PREFIX_STRLEN];
6378 char base_xpath[XPATH_MAXLEN];
6379 afi_t afi;
6380 safi_t safi;
6381
6382 if (address_str) {
6383 int ret;
6384
6385 ret = netmask_str2prefix_str(address_str, netmask_str,
6386 addr_prefix_str);
6387 if (!ret) {
6388 vty_out(vty, "%% Inconsistent address and mask\n");
6389 return CMD_WARNING_CONFIG_FAILED;
6390 }
6391 }
6392
6393 afi = bgp_node_afi(vty);
6394 safi = bgp_node_safi(vty);
6395
6396 if (no) {
6397 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
6398 } else {
6399 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
6400
6401 if (map_name)
6402 nb_cli_enqueue_change(vty, "./rmap-policy-export",
6403 NB_OP_CREATE, map_name);
6404 else
6405 nb_cli_enqueue_change(vty, "./rmap-policy-export",
6406 NB_OP_DESTROY, NULL);
6407
6408 if (label_index_str)
6409 nb_cli_enqueue_change(vty, "./label-index",
6410 NB_OP_MODIFY, label_index_str);
6411
6412 nb_cli_enqueue_change(vty, "./backdoor", NB_OP_MODIFY,
6413 backdoor ? "true" : "false");
6414 }
6415
6416 snprintf(
6417 base_xpath, sizeof(base_xpath),
6418 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/network-config[prefix='%s']",
6419 yang_afi_safi_value2identity(afi, safi),
6420 bgp_afi_safi_get_container_str(afi, safi),
6421 address_str ? addr_prefix_str : prefix_str);
6422
6423 return nb_cli_apply_changes(vty, base_xpath);
6424 }
6425
6426 DEFPY_YANG (ipv6_bgp_network,
6427 ipv6_bgp_network_cmd,
6428 "[no] network X:X::X:X/M$prefix \
6429 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
6430 NO_STR
6431 "Specify a network to announce via BGP\n"
6432 "IPv6 prefix\n"
6433 "Route-map to modify the attributes\n"
6434 "Name of the route map\n"
6435 "Label index to associate with the prefix\n"
6436 "Label index value\n")
6437 {
6438 char base_xpath[XPATH_MAXLEN];
6439 afi_t afi;
6440 safi_t safi;
6441
6442 afi = bgp_node_afi(vty);
6443 safi = bgp_node_safi(vty);
6444
6445 if (no) {
6446 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
6447 } else {
6448 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
6449
6450 if (map_name)
6451 nb_cli_enqueue_change(vty, "./rmap-policy-export",
6452 NB_OP_MODIFY, map_name);
6453 else
6454 nb_cli_enqueue_change(vty, "./rmap-policy-export",
6455 NB_OP_DESTROY, NULL);
6456
6457 if (label_index_str)
6458 nb_cli_enqueue_change(vty, "./label-index",
6459 NB_OP_MODIFY, label_index_str);
6460 }
6461
6462 snprintf(
6463 base_xpath, sizeof(base_xpath),
6464 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/network-config[prefix='%s']",
6465 yang_afi_safi_value2identity(afi, safi),
6466 bgp_afi_safi_get_container_str(afi, safi), prefix_str);
6467
6468 return nb_cli_apply_changes(vty, base_xpath);
6469 }
6470
6471 void cli_show_bgp_global_afi_safi_network_config(struct vty *vty,
6472 struct lyd_node *dnode,
6473 bool show_defaults)
6474 {
6475 vty_out(vty, " network %s", yang_dnode_get_string(dnode, "./prefix"));
6476
6477 if (yang_dnode_exists(dnode, "./label-index"))
6478 vty_out(vty, " label-index %s",
6479 yang_dnode_get_string(dnode, "./label-index"));
6480
6481 if (yang_dnode_exists(dnode, "./rmap-policy-export"))
6482 vty_out(vty, " route-map %s",
6483 yang_dnode_get_string(dnode, "./rmap-policy-export"));
6484
6485 if (yang_dnode_get_bool(dnode, "./backdoor"))
6486 vty_out(vty, " backdoor");
6487
6488 vty_out(vty, "\n");
6489 }
6490
6491 static struct bgp_aggregate *bgp_aggregate_new(void)
6492 {
6493 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
6494 }
6495
6496 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
6497 {
6498 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
6499 route_map_counter_decrement(aggregate->suppress_map);
6500 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
6501 route_map_counter_decrement(aggregate->rmap.map);
6502 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
6503 }
6504
6505 /**
6506 * Helper function to avoid repeated code: prepare variables for a
6507 * `route_map_apply` call.
6508 *
6509 * \returns `true` on route map match, otherwise `false`.
6510 */
6511 static bool aggr_suppress_map_test(struct bgp *bgp,
6512 struct bgp_aggregate *aggregate,
6513 struct bgp_path_info *pi)
6514 {
6515 const struct prefix *p = bgp_dest_get_prefix(pi->net);
6516 route_map_result_t rmr = RMAP_DENYMATCH;
6517 struct bgp_path_info rmap_path = {};
6518 struct attr attr = {};
6519
6520 /* No route map entries created, just don't match. */
6521 if (aggregate->suppress_map == NULL)
6522 return false;
6523
6524 /* Call route map matching and return result. */
6525 attr.aspath = aspath_empty();
6526 rmap_path.peer = bgp->peer_self;
6527 rmap_path.attr = &attr;
6528
6529 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
6530 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
6531 bgp->peer_self->rmap_type = 0;
6532
6533 bgp_attr_flush(&attr);
6534
6535 return rmr == RMAP_PERMITMATCH;
6536 }
6537
6538 /** Test whether the aggregation has suppressed this path or not. */
6539 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
6540 struct bgp_path_info *pi)
6541 {
6542 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
6543 return false;
6544
6545 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
6546 }
6547
6548 /**
6549 * Suppress this path and keep the reference.
6550 *
6551 * \returns `true` if needs processing otherwise `false`.
6552 */
6553 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
6554 struct bgp_path_info *pi)
6555 {
6556 struct bgp_path_info_extra *pie;
6557
6558 /* Path is already suppressed by this aggregation. */
6559 if (aggr_suppress_exists(aggregate, pi))
6560 return false;
6561
6562 pie = bgp_path_info_extra_get(pi);
6563
6564 /* This is the first suppression, allocate memory and list it. */
6565 if (pie->aggr_suppressors == NULL)
6566 pie->aggr_suppressors = list_new();
6567
6568 listnode_add(pie->aggr_suppressors, aggregate);
6569
6570 /* Only mark for processing if suppressed. */
6571 if (listcount(pie->aggr_suppressors) == 1) {
6572 if (BGP_DEBUG(update, UPDATE_OUT))
6573 zlog_debug("aggregate-address suppressing: %pFX",
6574 bgp_dest_get_prefix(pi->net));
6575
6576 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
6577 return true;
6578 }
6579
6580 return false;
6581 }
6582
6583 /**
6584 * Unsuppress this path and remove the reference.
6585 *
6586 * \returns `true` if needs processing otherwise `false`.
6587 */
6588 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
6589 struct bgp_path_info *pi)
6590 {
6591 /* Path wasn't suppressed. */
6592 if (!aggr_suppress_exists(aggregate, pi))
6593 return false;
6594
6595 listnode_delete(pi->extra->aggr_suppressors, aggregate);
6596
6597 /* Unsuppress and free extra memory if last item. */
6598 if (listcount(pi->extra->aggr_suppressors) == 0) {
6599 if (BGP_DEBUG(update, UPDATE_OUT))
6600 zlog_debug("aggregate-address unsuppressing: %pFX",
6601 bgp_dest_get_prefix(pi->net));
6602
6603 list_delete(&pi->extra->aggr_suppressors);
6604 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
6605 return true;
6606 }
6607
6608 return false;
6609 }
6610
6611 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
6612 struct aspath *aspath,
6613 struct community *comm,
6614 struct ecommunity *ecomm,
6615 struct lcommunity *lcomm)
6616 {
6617 static struct aspath *ae = NULL;
6618
6619 if (!ae)
6620 ae = aspath_empty();
6621
6622 if (!pi)
6623 return false;
6624
6625 if (origin != pi->attr->origin)
6626 return false;
6627
6628 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
6629 return false;
6630
6631 if (!community_cmp(pi->attr->community, comm))
6632 return false;
6633
6634 if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
6635 return false;
6636
6637 if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
6638 return false;
6639
6640 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
6641 return false;
6642
6643 return true;
6644 }
6645
6646 static void bgp_aggregate_install(
6647 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
6648 uint8_t origin, struct aspath *aspath, struct community *community,
6649 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
6650 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
6651 {
6652 struct bgp_dest *dest;
6653 struct bgp_table *table;
6654 struct bgp_path_info *pi, *orig, *new;
6655 struct attr *attr;
6656
6657 table = bgp->rib[afi][safi];
6658
6659 dest = bgp_node_get(table, p);
6660
6661 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6662 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6663 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6664 break;
6665
6666 /*
6667 * If we have paths with different MEDs, then don't install
6668 * (or uninstall) the aggregate route.
6669 */
6670 if (aggregate->match_med && aggregate->med_mismatched)
6671 goto uninstall_aggregate_route;
6672
6673 if (aggregate->count > 0) {
6674 /*
6675 * If the aggregate information has not changed
6676 * no need to re-install it again.
6677 */
6678 if (bgp_aggregate_info_same(orig, origin, aspath, community,
6679 ecommunity, lcommunity)) {
6680 bgp_dest_unlock_node(dest);
6681
6682 if (aspath)
6683 aspath_free(aspath);
6684 if (community)
6685 community_free(&community);
6686 if (ecommunity)
6687 ecommunity_free(&ecommunity);
6688 if (lcommunity)
6689 lcommunity_free(&lcommunity);
6690
6691 return;
6692 }
6693
6694 /*
6695 * Mark the old as unusable
6696 */
6697 if (pi)
6698 bgp_path_info_delete(dest, pi);
6699
6700 attr = bgp_attr_aggregate_intern(
6701 bgp, origin, aspath, community, ecommunity, lcommunity,
6702 aggregate, atomic_aggregate, p);
6703
6704 if (!attr) {
6705 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
6706 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
6707 zlog_debug("%s: %pFX null attribute", __func__,
6708 p);
6709 return;
6710 }
6711
6712 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
6713 bgp->peer_self, attr, dest);
6714
6715 SET_FLAG(new->flags, BGP_PATH_VALID);
6716
6717 bgp_path_info_add(dest, new);
6718 bgp_process(bgp, dest, afi, safi);
6719 } else {
6720 uninstall_aggregate_route:
6721 for (pi = orig; pi; pi = pi->next)
6722 if (pi->peer == bgp->peer_self
6723 && pi->type == ZEBRA_ROUTE_BGP
6724 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6725 break;
6726
6727 /* Withdraw static BGP route from routing table. */
6728 if (pi) {
6729 bgp_path_info_delete(dest, pi);
6730 bgp_process(bgp, dest, afi, safi);
6731 }
6732 }
6733
6734 bgp_dest_unlock_node(dest);
6735 }
6736
6737 /**
6738 * Check if the current path has different MED than other known paths.
6739 *
6740 * \returns `true` if the MED matched the others else `false`.
6741 */
6742 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
6743 struct bgp *bgp, struct bgp_path_info *pi)
6744 {
6745 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
6746
6747 /* This is the first route being analyzed. */
6748 if (!aggregate->med_initialized) {
6749 aggregate->med_initialized = true;
6750 aggregate->med_mismatched = false;
6751 aggregate->med_matched_value = cur_med;
6752 } else {
6753 /* Check if routes with different MED showed up. */
6754 if (cur_med != aggregate->med_matched_value)
6755 aggregate->med_mismatched = true;
6756 }
6757
6758 return !aggregate->med_mismatched;
6759 }
6760
6761 /**
6762 * Initializes and tests all routes in the aggregate address path for MED
6763 * values.
6764 *
6765 * \returns `true` if all MEDs are the same otherwise `false`.
6766 */
6767 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
6768 struct bgp *bgp, const struct prefix *p,
6769 afi_t afi, safi_t safi)
6770 {
6771 struct bgp_table *table = bgp->rib[afi][safi];
6772 const struct prefix *dest_p;
6773 struct bgp_dest *dest, *top;
6774 struct bgp_path_info *pi;
6775 bool med_matched = true;
6776
6777 aggregate->med_initialized = false;
6778
6779 top = bgp_node_get(table, p);
6780 for (dest = bgp_node_get(table, p); dest;
6781 dest = bgp_route_next_until(dest, top)) {
6782 dest_p = bgp_dest_get_prefix(dest);
6783 if (dest_p->prefixlen <= p->prefixlen)
6784 continue;
6785
6786 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6787 if (BGP_PATH_HOLDDOWN(pi))
6788 continue;
6789 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6790 continue;
6791 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
6792 med_matched = false;
6793 break;
6794 }
6795 }
6796 if (!med_matched)
6797 break;
6798 }
6799 bgp_dest_unlock_node(top);
6800
6801 return med_matched;
6802 }
6803
6804 /**
6805 * Toggles the route suppression status for this aggregate address
6806 * configuration.
6807 */
6808 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
6809 struct bgp *bgp, const struct prefix *p,
6810 afi_t afi, safi_t safi, bool suppress)
6811 {
6812 struct bgp_table *table = bgp->rib[afi][safi];
6813 const struct prefix *dest_p;
6814 struct bgp_dest *dest, *top;
6815 struct bgp_path_info *pi;
6816 bool toggle_suppression;
6817
6818 /* We've found a different MED we must revert any suppressed routes. */
6819 top = bgp_node_get(table, p);
6820 for (dest = bgp_node_get(table, p); dest;
6821 dest = bgp_route_next_until(dest, top)) {
6822 dest_p = bgp_dest_get_prefix(dest);
6823 if (dest_p->prefixlen <= p->prefixlen)
6824 continue;
6825
6826 toggle_suppression = false;
6827 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6828 if (BGP_PATH_HOLDDOWN(pi))
6829 continue;
6830 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6831 continue;
6832
6833 /* We are toggling suppression back. */
6834 if (suppress) {
6835 /* Suppress route if not suppressed already. */
6836 if (aggr_suppress_path(aggregate, pi))
6837 toggle_suppression = true;
6838 continue;
6839 }
6840
6841 /* Install route if there is no more suppression. */
6842 if (aggr_unsuppress_path(aggregate, pi))
6843 toggle_suppression = true;
6844 }
6845
6846 if (toggle_suppression)
6847 bgp_process(bgp, dest, afi, safi);
6848 }
6849 bgp_dest_unlock_node(top);
6850 }
6851
6852 /**
6853 * Aggregate address MED matching incremental test: this function is called
6854 * when the initial aggregation occurred and we are only testing a single
6855 * new path.
6856 *
6857 * In addition to testing and setting the MED validity it also installs back
6858 * suppressed routes (if summary is configured).
6859 *
6860 * Must not be called in `bgp_aggregate_route`.
6861 */
6862 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
6863 struct bgp *bgp, const struct prefix *p,
6864 afi_t afi, safi_t safi,
6865 struct bgp_path_info *pi, bool is_adding)
6866 {
6867 /* MED matching disabled. */
6868 if (!aggregate->match_med)
6869 return;
6870
6871 /* Aggregation with different MED, nothing to do. */
6872 if (aggregate->med_mismatched)
6873 return;
6874
6875 /*
6876 * Test the current entry:
6877 *
6878 * is_adding == true: if the new entry doesn't match then we must
6879 * install all suppressed routes.
6880 *
6881 * is_adding == false: if the entry being removed was the last
6882 * unmatching entry then we can suppress all routes.
6883 */
6884 if (!is_adding) {
6885 if (bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi)
6886 && aggregate->summary_only)
6887 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi,
6888 safi, true);
6889 } else
6890 bgp_aggregate_med_match(aggregate, bgp, pi);
6891
6892 /* No mismatches, just quit. */
6893 if (!aggregate->med_mismatched)
6894 return;
6895
6896 /* Route summarization is disabled. */
6897 if (!aggregate->summary_only)
6898 return;
6899
6900 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
6901 }
6902
6903 /* Update an aggregate as routes are added/removed from the BGP table */
6904 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
6905 safi_t safi, struct bgp_aggregate *aggregate)
6906 {
6907 struct bgp_table *table;
6908 struct bgp_dest *top;
6909 struct bgp_dest *dest;
6910 uint8_t origin;
6911 struct aspath *aspath = NULL;
6912 struct community *community = NULL;
6913 struct ecommunity *ecommunity = NULL;
6914 struct lcommunity *lcommunity = NULL;
6915 struct bgp_path_info *pi;
6916 unsigned long match = 0;
6917 uint8_t atomic_aggregate = 0;
6918
6919 /* If the bgp instance is being deleted or self peer is deleted
6920 * then do not create aggregate route
6921 */
6922 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6923 || (bgp->peer_self == NULL))
6924 return;
6925
6926 /* Initialize and test routes for MED difference. */
6927 if (aggregate->match_med)
6928 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
6929
6930 /*
6931 * Reset aggregate count: we might've been called from route map
6932 * update so in that case we must retest all more specific routes.
6933 *
6934 * \see `bgp_route_map_process_update`.
6935 */
6936 aggregate->count = 0;
6937 aggregate->incomplete_origin_count = 0;
6938 aggregate->incomplete_origin_count = 0;
6939 aggregate->egp_origin_count = 0;
6940
6941 /* ORIGIN attribute: If at least one route among routes that are
6942 aggregated has ORIGIN with the value INCOMPLETE, then the
6943 aggregated route must have the ORIGIN attribute with the value
6944 INCOMPLETE. Otherwise, if at least one route among routes that
6945 are aggregated has ORIGIN with the value EGP, then the aggregated
6946 route must have the origin attribute with the value EGP. In all
6947 other case the value of the ORIGIN attribute of the aggregated
6948 route is INTERNAL. */
6949 origin = BGP_ORIGIN_IGP;
6950
6951 table = bgp->rib[afi][safi];
6952
6953 top = bgp_node_get(table, p);
6954 for (dest = bgp_node_get(table, p); dest;
6955 dest = bgp_route_next_until(dest, top)) {
6956 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
6957
6958 if (dest_p->prefixlen <= p->prefixlen)
6959 continue;
6960
6961 /* If suppress fib is enabled and route not installed
6962 * in FIB, skip the route
6963 */
6964 if (!bgp_check_advertise(bgp, dest))
6965 continue;
6966
6967 match = 0;
6968
6969 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6970 if (BGP_PATH_HOLDDOWN(pi))
6971 continue;
6972
6973 if (pi->attr->flag
6974 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
6975 atomic_aggregate = 1;
6976
6977 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6978 continue;
6979
6980 /*
6981 * summary-only aggregate route suppress
6982 * aggregated route announcements.
6983 *
6984 * MED matching:
6985 * Don't create summaries if MED didn't match
6986 * otherwise neither the specific routes and the
6987 * aggregation will be announced.
6988 */
6989 if (aggregate->summary_only
6990 && AGGREGATE_MED_VALID(aggregate)) {
6991 if (aggr_suppress_path(aggregate, pi))
6992 match++;
6993 }
6994
6995 /*
6996 * Suppress more specific routes that match the route
6997 * map results.
6998 *
6999 * MED matching:
7000 * Don't suppress routes if MED matching is enabled and
7001 * it mismatched otherwise we might end up with no
7002 * routes for this path.
7003 */
7004 if (aggregate->suppress_map_name
7005 && AGGREGATE_MED_VALID(aggregate)
7006 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7007 if (aggr_suppress_path(aggregate, pi))
7008 match++;
7009 }
7010
7011 aggregate->count++;
7012
7013 /*
7014 * If at least one route among routes that are
7015 * aggregated has ORIGIN with the value INCOMPLETE,
7016 * then the aggregated route MUST have the ORIGIN
7017 * attribute with the value INCOMPLETE. Otherwise, if
7018 * at least one route among routes that are aggregated
7019 * has ORIGIN with the value EGP, then the aggregated
7020 * route MUST have the ORIGIN attribute with the value
7021 * EGP.
7022 */
7023 switch (pi->attr->origin) {
7024 case BGP_ORIGIN_INCOMPLETE:
7025 aggregate->incomplete_origin_count++;
7026 break;
7027 case BGP_ORIGIN_EGP:
7028 aggregate->egp_origin_count++;
7029 break;
7030 default:
7031 /*Do nothing.
7032 */
7033 break;
7034 }
7035
7036 if (!aggregate->as_set)
7037 continue;
7038
7039 /*
7040 * as-set aggregate route generate origin, as path,
7041 * and community aggregation.
7042 */
7043 /* Compute aggregate route's as-path.
7044 */
7045 bgp_compute_aggregate_aspath_hash(aggregate,
7046 pi->attr->aspath);
7047
7048 /* Compute aggregate route's community.
7049 */
7050 if (pi->attr->community)
7051 bgp_compute_aggregate_community_hash(
7052 aggregate,
7053 pi->attr->community);
7054
7055 /* Compute aggregate route's extended community.
7056 */
7057 if (pi->attr->ecommunity)
7058 bgp_compute_aggregate_ecommunity_hash(
7059 aggregate,
7060 pi->attr->ecommunity);
7061
7062 /* Compute aggregate route's large community.
7063 */
7064 if (pi->attr->lcommunity)
7065 bgp_compute_aggregate_lcommunity_hash(
7066 aggregate,
7067 pi->attr->lcommunity);
7068 }
7069 if (match)
7070 bgp_process(bgp, dest, afi, safi);
7071 }
7072 if (aggregate->as_set) {
7073 bgp_compute_aggregate_aspath_val(aggregate);
7074 bgp_compute_aggregate_community_val(aggregate);
7075 bgp_compute_aggregate_ecommunity_val(aggregate);
7076 bgp_compute_aggregate_lcommunity_val(aggregate);
7077 }
7078
7079
7080 bgp_dest_unlock_node(top);
7081
7082
7083 if (aggregate->incomplete_origin_count > 0)
7084 origin = BGP_ORIGIN_INCOMPLETE;
7085 else if (aggregate->egp_origin_count > 0)
7086 origin = BGP_ORIGIN_EGP;
7087
7088 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7089 origin = aggregate->origin;
7090
7091 if (aggregate->as_set) {
7092 if (aggregate->aspath)
7093 /* Retrieve aggregate route's as-path.
7094 */
7095 aspath = aspath_dup(aggregate->aspath);
7096
7097 if (aggregate->community)
7098 /* Retrieve aggregate route's community.
7099 */
7100 community = community_dup(aggregate->community);
7101
7102 if (aggregate->ecommunity)
7103 /* Retrieve aggregate route's ecommunity.
7104 */
7105 ecommunity = ecommunity_dup(aggregate->ecommunity);
7106
7107 if (aggregate->lcommunity)
7108 /* Retrieve aggregate route's lcommunity.
7109 */
7110 lcommunity = lcommunity_dup(aggregate->lcommunity);
7111 }
7112
7113 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7114 ecommunity, lcommunity, atomic_aggregate,
7115 aggregate);
7116 }
7117
7118 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7119 safi_t safi, struct bgp_aggregate *aggregate)
7120 {
7121 struct bgp_table *table;
7122 struct bgp_dest *top;
7123 struct bgp_dest *dest;
7124 struct bgp_path_info *pi;
7125 unsigned long match;
7126
7127 table = bgp->rib[afi][safi];
7128
7129 /* If routes exists below this node, generate aggregate routes. */
7130 top = bgp_node_get(table, p);
7131 for (dest = bgp_node_get(table, p); dest;
7132 dest = bgp_route_next_until(dest, top)) {
7133 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7134
7135 if (dest_p->prefixlen <= p->prefixlen)
7136 continue;
7137 match = 0;
7138
7139 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7140 if (BGP_PATH_HOLDDOWN(pi))
7141 continue;
7142
7143 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7144 continue;
7145
7146 if (aggregate->summary_only && pi->extra
7147 && AGGREGATE_MED_VALID(aggregate)) {
7148 if (aggr_unsuppress_path(aggregate, pi))
7149 match++;
7150 }
7151
7152 if (aggregate->suppress_map_name
7153 && AGGREGATE_MED_VALID(aggregate)
7154 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7155 if (aggr_unsuppress_path(aggregate, pi))
7156 match++;
7157 }
7158
7159 aggregate->count--;
7160
7161 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7162 aggregate->incomplete_origin_count--;
7163 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7164 aggregate->egp_origin_count--;
7165
7166 if (aggregate->as_set) {
7167 /* Remove as-path from aggregate.
7168 */
7169 bgp_remove_aspath_from_aggregate_hash(
7170 aggregate,
7171 pi->attr->aspath);
7172
7173 if (pi->attr->community)
7174 /* Remove community from aggregate.
7175 */
7176 bgp_remove_comm_from_aggregate_hash(
7177 aggregate,
7178 pi->attr->community);
7179
7180 if (pi->attr->ecommunity)
7181 /* Remove ecommunity from aggregate.
7182 */
7183 bgp_remove_ecomm_from_aggregate_hash(
7184 aggregate,
7185 pi->attr->ecommunity);
7186
7187 if (pi->attr->lcommunity)
7188 /* Remove lcommunity from aggregate.
7189 */
7190 bgp_remove_lcomm_from_aggregate_hash(
7191 aggregate,
7192 pi->attr->lcommunity);
7193 }
7194 }
7195
7196 /* If this node was suppressed, process the change. */
7197 if (match)
7198 bgp_process(bgp, dest, afi, safi);
7199 }
7200 if (aggregate->as_set) {
7201 aspath_free(aggregate->aspath);
7202 aggregate->aspath = NULL;
7203 if (aggregate->community)
7204 community_free(&aggregate->community);
7205 if (aggregate->ecommunity)
7206 ecommunity_free(&aggregate->ecommunity);
7207 if (aggregate->lcommunity)
7208 lcommunity_free(&aggregate->lcommunity);
7209 }
7210
7211 bgp_dest_unlock_node(top);
7212 }
7213
7214 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7215 const struct prefix *aggr_p,
7216 struct bgp_path_info *pinew, afi_t afi,
7217 safi_t safi,
7218 struct bgp_aggregate *aggregate)
7219 {
7220 uint8_t origin;
7221 struct aspath *aspath = NULL;
7222 uint8_t atomic_aggregate = 0;
7223 struct community *community = NULL;
7224 struct ecommunity *ecommunity = NULL;
7225 struct lcommunity *lcommunity = NULL;
7226
7227 /* If the bgp instance is being deleted or self peer is deleted
7228 * then do not create aggregate route
7229 */
7230 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7231 || (bgp->peer_self == NULL))
7232 return;
7233
7234 /* ORIGIN attribute: If at least one route among routes that are
7235 * aggregated has ORIGIN with the value INCOMPLETE, then the
7236 * aggregated route must have the ORIGIN attribute with the value
7237 * INCOMPLETE. Otherwise, if at least one route among routes that
7238 * are aggregated has ORIGIN with the value EGP, then the aggregated
7239 * route must have the origin attribute with the value EGP. In all
7240 * other case the value of the ORIGIN attribute of the aggregated
7241 * route is INTERNAL.
7242 */
7243 origin = BGP_ORIGIN_IGP;
7244
7245 aggregate->count++;
7246
7247 /*
7248 * This must be called before `summary` check to avoid
7249 * "suppressing" twice.
7250 */
7251 if (aggregate->match_med)
7252 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
7253 pinew, true);
7254
7255 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7256 aggr_suppress_path(aggregate, pinew);
7257
7258 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7259 && aggr_suppress_map_test(bgp, aggregate, pinew))
7260 aggr_suppress_path(aggregate, pinew);
7261
7262 switch (pinew->attr->origin) {
7263 case BGP_ORIGIN_INCOMPLETE:
7264 aggregate->incomplete_origin_count++;
7265 break;
7266 case BGP_ORIGIN_EGP:
7267 aggregate->egp_origin_count++;
7268 break;
7269 default:
7270 /* Do nothing.
7271 */
7272 break;
7273 }
7274
7275 if (aggregate->incomplete_origin_count > 0)
7276 origin = BGP_ORIGIN_INCOMPLETE;
7277 else if (aggregate->egp_origin_count > 0)
7278 origin = BGP_ORIGIN_EGP;
7279
7280 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7281 origin = aggregate->origin;
7282
7283 if (aggregate->as_set) {
7284 /* Compute aggregate route's as-path.
7285 */
7286 bgp_compute_aggregate_aspath(aggregate,
7287 pinew->attr->aspath);
7288
7289 /* Compute aggregate route's community.
7290 */
7291 if (pinew->attr->community)
7292 bgp_compute_aggregate_community(
7293 aggregate,
7294 pinew->attr->community);
7295
7296 /* Compute aggregate route's extended community.
7297 */
7298 if (pinew->attr->ecommunity)
7299 bgp_compute_aggregate_ecommunity(
7300 aggregate,
7301 pinew->attr->ecommunity);
7302
7303 /* Compute aggregate route's large community.
7304 */
7305 if (pinew->attr->lcommunity)
7306 bgp_compute_aggregate_lcommunity(
7307 aggregate,
7308 pinew->attr->lcommunity);
7309
7310 /* Retrieve aggregate route's as-path.
7311 */
7312 if (aggregate->aspath)
7313 aspath = aspath_dup(aggregate->aspath);
7314
7315 /* Retrieve aggregate route's community.
7316 */
7317 if (aggregate->community)
7318 community = community_dup(aggregate->community);
7319
7320 /* Retrieve aggregate route's ecommunity.
7321 */
7322 if (aggregate->ecommunity)
7323 ecommunity = ecommunity_dup(aggregate->ecommunity);
7324
7325 /* Retrieve aggregate route's lcommunity.
7326 */
7327 if (aggregate->lcommunity)
7328 lcommunity = lcommunity_dup(aggregate->lcommunity);
7329 }
7330
7331 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
7332 aspath, community, ecommunity,
7333 lcommunity, atomic_aggregate, aggregate);
7334 }
7335
7336 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
7337 safi_t safi,
7338 struct bgp_path_info *pi,
7339 struct bgp_aggregate *aggregate,
7340 const struct prefix *aggr_p)
7341 {
7342 uint8_t origin;
7343 struct aspath *aspath = NULL;
7344 uint8_t atomic_aggregate = 0;
7345 struct community *community = NULL;
7346 struct ecommunity *ecommunity = NULL;
7347 struct lcommunity *lcommunity = NULL;
7348 unsigned long match = 0;
7349
7350 /* If the bgp instance is being deleted or self peer is deleted
7351 * then do not create aggregate route
7352 */
7353 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7354 || (bgp->peer_self == NULL))
7355 return;
7356
7357 if (BGP_PATH_HOLDDOWN(pi))
7358 return;
7359
7360 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7361 return;
7362
7363 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7364 if (aggr_unsuppress_path(aggregate, pi))
7365 match++;
7366
7367 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7368 && aggr_suppress_map_test(bgp, aggregate, pi))
7369 if (aggr_unsuppress_path(aggregate, pi))
7370 match++;
7371
7372 /*
7373 * This must be called after `summary`, `suppress-map` check to avoid
7374 * "unsuppressing" twice.
7375 */
7376 if (aggregate->match_med)
7377 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi,
7378 true);
7379
7380 if (aggregate->count > 0)
7381 aggregate->count--;
7382
7383 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7384 aggregate->incomplete_origin_count--;
7385 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7386 aggregate->egp_origin_count--;
7387
7388 if (aggregate->as_set) {
7389 /* Remove as-path from aggregate.
7390 */
7391 bgp_remove_aspath_from_aggregate(aggregate,
7392 pi->attr->aspath);
7393
7394 if (pi->attr->community)
7395 /* Remove community from aggregate.
7396 */
7397 bgp_remove_community_from_aggregate(
7398 aggregate,
7399 pi->attr->community);
7400
7401 if (pi->attr->ecommunity)
7402 /* Remove ecommunity from aggregate.
7403 */
7404 bgp_remove_ecommunity_from_aggregate(
7405 aggregate,
7406 pi->attr->ecommunity);
7407
7408 if (pi->attr->lcommunity)
7409 /* Remove lcommunity from aggregate.
7410 */
7411 bgp_remove_lcommunity_from_aggregate(
7412 aggregate,
7413 pi->attr->lcommunity);
7414 }
7415
7416 /* If this node was suppressed, process the change. */
7417 if (match)
7418 bgp_process(bgp, pi->net, afi, safi);
7419
7420 origin = BGP_ORIGIN_IGP;
7421 if (aggregate->incomplete_origin_count > 0)
7422 origin = BGP_ORIGIN_INCOMPLETE;
7423 else if (aggregate->egp_origin_count > 0)
7424 origin = BGP_ORIGIN_EGP;
7425
7426 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7427 origin = aggregate->origin;
7428
7429 if (aggregate->as_set) {
7430 /* Retrieve aggregate route's as-path.
7431 */
7432 if (aggregate->aspath)
7433 aspath = aspath_dup(aggregate->aspath);
7434
7435 /* Retrieve aggregate route's community.
7436 */
7437 if (aggregate->community)
7438 community = community_dup(aggregate->community);
7439
7440 /* Retrieve aggregate route's ecommunity.
7441 */
7442 if (aggregate->ecommunity)
7443 ecommunity = ecommunity_dup(aggregate->ecommunity);
7444
7445 /* Retrieve aggregate route's lcommunity.
7446 */
7447 if (aggregate->lcommunity)
7448 lcommunity = lcommunity_dup(aggregate->lcommunity);
7449 }
7450
7451 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
7452 aspath, community, ecommunity,
7453 lcommunity, atomic_aggregate, aggregate);
7454 }
7455
7456 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
7457 struct bgp_path_info *pi, afi_t afi, safi_t safi)
7458 {
7459 struct bgp_dest *child;
7460 struct bgp_dest *dest;
7461 struct bgp_aggregate *aggregate;
7462 struct bgp_table *table;
7463
7464 table = bgp->aggregate[afi][safi];
7465
7466 /* No aggregates configured. */
7467 if (bgp_table_top_nolock(table) == NULL)
7468 return;
7469
7470 if (p->prefixlen == 0)
7471 return;
7472
7473 if (BGP_PATH_HOLDDOWN(pi))
7474 return;
7475
7476 /* If suppress fib is enabled and route not installed
7477 * in FIB, do not update the aggregate route
7478 */
7479 if (!bgp_check_advertise(bgp, pi->net))
7480 return;
7481
7482 child = bgp_node_get(table, p);
7483
7484 /* Aggregate address configuration check. */
7485 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
7486 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7487
7488 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7489 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
7490 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
7491 aggregate);
7492 }
7493 }
7494 bgp_dest_unlock_node(child);
7495 }
7496
7497 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
7498 struct bgp_path_info *del, afi_t afi, safi_t safi)
7499 {
7500 struct bgp_dest *child;
7501 struct bgp_dest *dest;
7502 struct bgp_aggregate *aggregate;
7503 struct bgp_table *table;
7504
7505 table = bgp->aggregate[afi][safi];
7506
7507 /* No aggregates configured. */
7508 if (bgp_table_top_nolock(table) == NULL)
7509 return;
7510
7511 if (p->prefixlen == 0)
7512 return;
7513
7514 child = bgp_node_get(table, p);
7515
7516 /* Aggregate address configuration check. */
7517 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
7518 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7519
7520 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7521 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
7522 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
7523 aggregate, dest_p);
7524 }
7525 }
7526 bgp_dest_unlock_node(child);
7527 }
7528
7529 /* Aggregate route attribute. */
7530 #define AGGREGATE_SUMMARY_ONLY 1
7531 #define AGGREGATE_AS_SET 1
7532 #define AGGREGATE_AS_UNSET 0
7533
7534 static const char *bgp_origin2str(uint8_t origin)
7535 {
7536 switch (origin) {
7537 case BGP_ORIGIN_IGP:
7538 return "igp";
7539 case BGP_ORIGIN_EGP:
7540 return "egp";
7541 case BGP_ORIGIN_INCOMPLETE:
7542 return "incomplete";
7543 }
7544 return "n/a";
7545 }
7546
7547 int bgp_aggregate_unset(struct bgp *bgp, struct prefix *prefix, afi_t afi,
7548 safi_t safi, char *errmsg, size_t errmsg_len)
7549 {
7550 struct bgp_dest *dest;
7551 struct bgp_aggregate *aggregate;
7552
7553 /* If the bgp instance is being deleted or self peer is deleted
7554 * then do not create aggregate route
7555 */
7556 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7557 || (bgp->peer_self == NULL))
7558 return 0;
7559
7560 apply_mask(prefix);
7561 /* Old configuration check. */
7562 dest = bgp_node_lookup(bgp->aggregate[afi][safi], prefix);
7563 if (!dest) {
7564 snprintf(errmsg, errmsg_len,
7565 "There is no aggregate-address configuration.\n");
7566 return -1;
7567 }
7568
7569 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7570 bgp_aggregate_delete(bgp, prefix, afi, safi, aggregate);
7571 bgp_aggregate_install(bgp, afi, safi, prefix, 0, NULL, NULL, NULL, NULL,
7572 0, aggregate);
7573
7574 /* Unlock aggregate address configuration. */
7575 bgp_dest_set_bgp_aggregate_info(dest, NULL);
7576
7577 if (aggregate->community)
7578 community_free(&aggregate->community);
7579
7580 if (aggregate->community_hash) {
7581 /* Delete all communities in the hash.
7582 */
7583 hash_clean(aggregate->community_hash,
7584 bgp_aggr_community_remove);
7585 /* Free up the community_hash.
7586 */
7587 hash_free(aggregate->community_hash);
7588 }
7589
7590 if (aggregate->ecommunity)
7591 ecommunity_free(&aggregate->ecommunity);
7592
7593 if (aggregate->ecommunity_hash) {
7594 /* Delete all ecommunities in the hash.
7595 */
7596 hash_clean(aggregate->ecommunity_hash,
7597 bgp_aggr_ecommunity_remove);
7598 /* Free up the ecommunity_hash.
7599 */
7600 hash_free(aggregate->ecommunity_hash);
7601 }
7602
7603 if (aggregate->lcommunity)
7604 lcommunity_free(&aggregate->lcommunity);
7605
7606 if (aggregate->lcommunity_hash) {
7607 /* Delete all lcommunities in the hash.
7608 */
7609 hash_clean(aggregate->lcommunity_hash,
7610 bgp_aggr_lcommunity_remove);
7611 /* Free up the lcommunity_hash.
7612 */
7613 hash_free(aggregate->lcommunity_hash);
7614 }
7615
7616 if (aggregate->aspath)
7617 aspath_free(aggregate->aspath);
7618
7619 if (aggregate->aspath_hash) {
7620 /* Delete all as-paths in the hash.
7621 */
7622 hash_clean(aggregate->aspath_hash,
7623 bgp_aggr_aspath_remove);
7624 /* Free up the aspath_hash.
7625 */
7626 hash_free(aggregate->aspath_hash);
7627 }
7628
7629 bgp_aggregate_free(aggregate);
7630 bgp_dest_unlock_node(dest);
7631 bgp_dest_unlock_node(dest);
7632
7633 return 0;
7634 }
7635
7636 int bgp_aggregate_set(struct bgp *bgp, struct prefix *prefix, afi_t afi,
7637 safi_t safi, const char *rmap, uint8_t summary_only,
7638 uint8_t as_set, uint8_t origin, bool match_med,
7639 const char *suppress_map,
7640 char *errmsg, size_t errmsg_len)
7641 {
7642 int ret;
7643 struct bgp_dest *dest;
7644 struct bgp_aggregate *aggregate;
7645 uint8_t as_set_new = as_set;
7646 char buf[PREFIX2STR_BUFFER];
7647
7648 if (suppress_map && summary_only) {
7649 snprintf(errmsg, errmsg_len,
7650 "'summary-only' and 'suppress-map' can't be used at the same time\n");
7651 return -1;
7652 }
7653
7654 apply_mask(prefix);
7655
7656 if ((afi == AFI_IP && prefix->prefixlen == IPV4_MAX_BITLEN)
7657 || (afi == AFI_IP6 && prefix->prefixlen == IPV6_MAX_BITLEN)) {
7658 snprintf(
7659 errmsg, errmsg_len,
7660 "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
7661 prefix2str(prefix, buf, PREFIX_STRLEN));
7662 return -1;
7663 }
7664
7665 /* Old configuration check. */
7666 dest = bgp_node_get(bgp->aggregate[afi][safi], prefix);
7667 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7668
7669 if (aggregate) {
7670 snprintf(errmsg, errmsg_len,
7671 "There is already same aggregate network.\n");
7672 /* try to remove the old entry */
7673 ret = bgp_aggregate_unset(bgp, prefix, afi, safi, errmsg,
7674 errmsg_len);
7675 if (ret) {
7676 snprintf(errmsg, errmsg_len,
7677 "Error deleting aggregate.\n");
7678 bgp_dest_unlock_node(dest);
7679 return -1;
7680 }
7681 }
7682
7683 /* Make aggregate address structure. */
7684 aggregate = bgp_aggregate_new();
7685 aggregate->summary_only = summary_only;
7686 aggregate->match_med = match_med;
7687
7688 /* Network operators MUST NOT locally generate any new
7689 * announcements containing AS_SET or AS_CONFED_SET. If they have
7690 * announced routes with AS_SET or AS_CONFED_SET in them, then they
7691 * SHOULD withdraw those routes and re-announce routes for the
7692 * aggregate or component prefixes (i.e., the more-specific routes
7693 * subsumed by the previously aggregated route) without AS_SET
7694 * or AS_CONFED_SET in the updates.
7695 */
7696 if (bgp->reject_as_sets) {
7697 if (as_set == AGGREGATE_AS_SET) {
7698 as_set_new = AGGREGATE_AS_UNSET;
7699 zlog_warn(
7700 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
7701 __func__);
7702 snprintf(
7703 errmsg, errmsg_len,
7704 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
7705 }
7706 }
7707
7708 aggregate->as_set = as_set_new;
7709 aggregate->safi = safi;
7710 /* Override ORIGIN attribute if defined.
7711 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
7712 * to IGP which is not what rfc4271 says.
7713 * This enables the same behavior, optionally.
7714 */
7715 aggregate->origin = origin;
7716
7717 if (rmap) {
7718 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7719 route_map_counter_decrement(aggregate->rmap.map);
7720 aggregate->rmap.name =
7721 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
7722 aggregate->rmap.map = route_map_lookup_by_name(rmap);
7723 route_map_counter_increment(aggregate->rmap.map);
7724 }
7725
7726 if (suppress_map) {
7727 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7728 route_map_counter_decrement(aggregate->suppress_map);
7729
7730 aggregate->suppress_map_name =
7731 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
7732 aggregate->suppress_map =
7733 route_map_lookup_by_name(aggregate->suppress_map_name);
7734 route_map_counter_increment(aggregate->suppress_map);
7735 }
7736
7737 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
7738
7739 /* Aggregate address insert into BGP routing table. */
7740 bgp_aggregate_route(bgp, prefix, afi, safi, aggregate);
7741
7742 return 0;
7743 }
7744
7745 DEFPY_YANG(
7746 aggregate_addressv4, aggregate_addressv4_cmd,
7747 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> {"
7748 "as-set$as_set_s"
7749 "|summary-only$summary_only"
7750 "|route-map WORD$rmap_name"
7751 "|origin <egp|igp|incomplete>$origin_s"
7752 "|matching-MED-only$match_med"
7753 "|suppress-map WORD$suppress_map"
7754 "}",
7755 NO_STR
7756 "Configure BGP aggregate entries\n"
7757 "Aggregate prefix\n"
7758 "Aggregate address\n"
7759 "Aggregate mask\n"
7760 "Generate AS set path information\n"
7761 "Filter more specific routes from updates\n"
7762 "Apply route map to aggregate network\n"
7763 "Route map name\n"
7764 "BGP origin code\n"
7765 "Remote EGP\n"
7766 "Local IGP\n"
7767 "Unknown heritage\n"
7768 "Only aggregate routes with matching MED\n"
7769 "Suppress the selected more specific routes\n"
7770 "Route map with the route selectors\n")
7771 {
7772 char base_xpath[XPATH_MAXLEN];
7773 safi_t safi = bgp_node_safi(vty);
7774 char prefix_buf[PREFIX2STR_BUFFER];
7775
7776 if (addr_str) {
7777 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf)
7778 == 0) {
7779 vty_out(vty, "%% Inconsistent address and mask\n");
7780 return CMD_WARNING_CONFIG_FAILED;
7781 }
7782 } else {
7783 strlcpy(prefix_buf, prefix_str, sizeof(prefix_buf));
7784 }
7785
7786 if (!no && origin_s)
7787 nb_cli_enqueue_change(vty, "./origin", NB_OP_MODIFY, origin_s);
7788
7789 if (!no && as_set_s)
7790 nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "true");
7791 else
7792 nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "false");
7793
7794 if (!no && summary_only)
7795 nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
7796 "true");
7797 else
7798 nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
7799 "false");
7800
7801 if (!no && match_med)
7802 nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, "true");
7803 else
7804 nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY,
7805 "false");
7806
7807 if (rmap_name)
7808 nb_cli_enqueue_change(vty, "./rmap-policy-export", NB_OP_MODIFY,
7809 rmap_name);
7810 else
7811 nb_cli_enqueue_change(vty, "./rmap-policy-export",
7812 NB_OP_DESTROY, NULL);
7813
7814 if (suppress_map)
7815 nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_MODIFY,
7816 suppress_map);
7817 else
7818 nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_DESTROY,
7819 NULL);
7820
7821 snprintf(
7822 base_xpath, sizeof(base_xpath),
7823 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/aggregate-route[prefix='%s']",
7824 yang_afi_safi_value2identity(AFI_IP, safi),
7825 bgp_afi_safi_get_container_str(AFI_IP, safi), prefix_buf);
7826
7827 if (no)
7828 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
7829 else
7830 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
7831
7832 return nb_cli_apply_changes(vty, base_xpath);
7833 }
7834
7835 DEFPY_YANG(aggregate_addressv6, aggregate_addressv6_cmd,
7836 "[no] aggregate-address X:X::X:X/M$prefix {"
7837 "as-set$as_set_s"
7838 "|summary-only$summary_only"
7839 "|route-map WORD$rmap_name"
7840 "|origin <egp|igp|incomplete>$origin_s"
7841 "|matching-MED-only$match_med"
7842 "|suppress-map WORD$suppress_map"
7843 "}",
7844 NO_STR
7845 "Configure BGP aggregate entries\n"
7846 "Aggregate prefix\n"
7847 "Generate AS set path information\n"
7848 "Filter more specific routes from updates\n"
7849 "Apply route map to aggregate network\n"
7850 "Route map name\n"
7851 "BGP origin code\n"
7852 "Remote EGP\n"
7853 "Local IGP\n"
7854 "Unknown heritage\n"
7855 "Only aggregate routes with matching MED\n"
7856 "Suppress the selected more specific routes\n"
7857 "Route map with the route selectors\n")
7858 {
7859 char base_xpath[XPATH_MAXLEN];
7860 safi_t safi = bgp_node_safi(vty);
7861
7862 if (!no && origin_s)
7863 nb_cli_enqueue_change(vty, "./origin", NB_OP_MODIFY, origin_s);
7864
7865 if (!no && as_set_s)
7866 nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "true");
7867 else
7868 nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "false");
7869
7870 if (!no && summary_only)
7871 nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
7872 "true");
7873 else
7874 nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
7875 "false");
7876
7877 if (!no && match_med)
7878 nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, "true");
7879 else
7880 nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY,
7881 "false");
7882
7883 if (rmap_name)
7884 nb_cli_enqueue_change(vty, "./rmap-policy-export", NB_OP_MODIFY,
7885 rmap_name);
7886
7887 if (suppress_map)
7888 nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_MODIFY,
7889 suppress_map);
7890 else
7891 nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_DESTROY,
7892 NULL);
7893
7894 snprintf(
7895 base_xpath, sizeof(base_xpath),
7896 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/aggregate-route[prefix='%s']",
7897 yang_afi_safi_value2identity(AFI_IP6, safi),
7898 bgp_afi_safi_get_container_str(AFI_IP6, safi), prefix_str);
7899
7900 if (no)
7901 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
7902 else
7903 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
7904
7905 return nb_cli_apply_changes(vty, base_xpath);
7906 }
7907
7908 void cli_show_bgp_global_afi_safi_unicast_aggregate_route(
7909 struct vty *vty, struct lyd_node *dnode, bool show_defaults)
7910 {
7911 uint8_t origin;
7912
7913 vty_out(vty, " aggregate-address %s",
7914 yang_dnode_get_string(dnode, "./prefix"));
7915
7916 if (yang_dnode_get_bool(dnode, "./as-set"))
7917 vty_out(vty, " as-set");
7918
7919 if (yang_dnode_get_bool(dnode, "./summary-only"))
7920 vty_out(vty, " summary-only");
7921
7922 if (yang_dnode_exists(dnode, "./rmap-policy-export"))
7923 vty_out(vty, " route-map %s",
7924 yang_dnode_get_string(dnode, "./rmap-policy-export"));
7925
7926 origin = yang_dnode_get_enum(dnode, "./origin");
7927 if (origin != BGP_ORIGIN_UNSPECIFIED)
7928 vty_out(vty, " origin %s", bgp_origin2str(origin));
7929
7930 if (yang_dnode_get_bool(dnode, "./match-med"))
7931 vty_out(vty, " matching-MED-only");
7932
7933 vty_out(vty, "\n");
7934 }
7935
7936 /* Redistribute route treatment. */
7937 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
7938 const union g_addr *nexthop, ifindex_t ifindex,
7939 enum nexthop_types_t nhtype, uint32_t metric,
7940 uint8_t type, unsigned short instance,
7941 route_tag_t tag)
7942 {
7943 struct bgp_path_info *new;
7944 struct bgp_path_info *bpi;
7945 struct bgp_path_info rmap_path;
7946 struct bgp_dest *bn;
7947 struct attr attr;
7948 struct attr *new_attr;
7949 afi_t afi;
7950 route_map_result_t ret;
7951 struct bgp_redist *red;
7952
7953 /* Make default attribute. */
7954 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
7955 /*
7956 * This must not be NULL to satisfy Coverity SA
7957 */
7958 assert(attr.aspath);
7959
7960 switch (nhtype) {
7961 case NEXTHOP_TYPE_IFINDEX:
7962 break;
7963 case NEXTHOP_TYPE_IPV4:
7964 case NEXTHOP_TYPE_IPV4_IFINDEX:
7965 attr.nexthop = nexthop->ipv4;
7966 break;
7967 case NEXTHOP_TYPE_IPV6:
7968 case NEXTHOP_TYPE_IPV6_IFINDEX:
7969 attr.mp_nexthop_global = nexthop->ipv6;
7970 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
7971 break;
7972 case NEXTHOP_TYPE_BLACKHOLE:
7973 switch (p->family) {
7974 case AF_INET:
7975 attr.nexthop.s_addr = INADDR_ANY;
7976 break;
7977 case AF_INET6:
7978 memset(&attr.mp_nexthop_global, 0,
7979 sizeof(attr.mp_nexthop_global));
7980 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
7981 break;
7982 }
7983 break;
7984 }
7985 attr.nh_ifindex = ifindex;
7986
7987 attr.med = metric;
7988 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
7989 attr.tag = tag;
7990
7991 afi = family2afi(p->family);
7992
7993 red = bgp_redist_lookup(bgp, afi, type, instance);
7994 if (red) {
7995 struct attr attr_new;
7996
7997 /* Copy attribute for modification. */
7998 attr_new = attr;
7999
8000 if (red->redist_metric_flag)
8001 attr_new.med = red->redist_metric;
8002
8003 /* Apply route-map. */
8004 if (red->rmap.name) {
8005 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
8006 rmap_path.peer = bgp->peer_self;
8007 rmap_path.attr = &attr_new;
8008
8009 SET_FLAG(bgp->peer_self->rmap_type,
8010 PEER_RMAP_TYPE_REDISTRIBUTE);
8011
8012 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8013
8014 bgp->peer_self->rmap_type = 0;
8015
8016 if (ret == RMAP_DENYMATCH) {
8017 /* Free uninterned attribute. */
8018 bgp_attr_flush(&attr_new);
8019
8020 /* Unintern original. */
8021 aspath_unintern(&attr.aspath);
8022 bgp_redistribute_delete(bgp, p, type, instance);
8023 return;
8024 }
8025 }
8026
8027 if (bgp_in_graceful_shutdown(bgp))
8028 bgp_attr_add_gshut_community(&attr_new);
8029
8030 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8031 SAFI_UNICAST, p, NULL);
8032
8033 new_attr = bgp_attr_intern(&attr_new);
8034
8035 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8036 if (bpi->peer == bgp->peer_self
8037 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8038 break;
8039
8040 if (bpi) {
8041 /* Ensure the (source route) type is updated. */
8042 bpi->type = type;
8043 if (attrhash_cmp(bpi->attr, new_attr)
8044 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8045 bgp_attr_unintern(&new_attr);
8046 aspath_unintern(&attr.aspath);
8047 bgp_dest_unlock_node(bn);
8048 return;
8049 } else {
8050 /* The attribute is changed. */
8051 bgp_path_info_set_flag(bn, bpi,
8052 BGP_PATH_ATTR_CHANGED);
8053
8054 /* Rewrite BGP route information. */
8055 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8056 bgp_path_info_restore(bn, bpi);
8057 else
8058 bgp_aggregate_decrement(
8059 bgp, p, bpi, afi, SAFI_UNICAST);
8060 bgp_attr_unintern(&bpi->attr);
8061 bpi->attr = new_attr;
8062 bpi->uptime = bgp_clock();
8063
8064 /* Process change. */
8065 bgp_aggregate_increment(bgp, p, bpi, afi,
8066 SAFI_UNICAST);
8067 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8068 bgp_dest_unlock_node(bn);
8069 aspath_unintern(&attr.aspath);
8070
8071 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8072 || (bgp->inst_type
8073 == BGP_INSTANCE_TYPE_DEFAULT)) {
8074
8075 vpn_leak_from_vrf_update(
8076 bgp_get_default(), bgp, bpi);
8077 }
8078 return;
8079 }
8080 }
8081
8082 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8083 bgp->peer_self, new_attr, bn);
8084 SET_FLAG(new->flags, BGP_PATH_VALID);
8085
8086 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8087 bgp_path_info_add(bn, new);
8088 bgp_dest_unlock_node(bn);
8089 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8090
8091 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8092 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8093
8094 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8095 }
8096 }
8097
8098 /* Unintern original. */
8099 aspath_unintern(&attr.aspath);
8100 }
8101
8102 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8103 unsigned short instance)
8104 {
8105 afi_t afi;
8106 struct bgp_dest *dest;
8107 struct bgp_path_info *pi;
8108 struct bgp_redist *red;
8109
8110 afi = family2afi(p->family);
8111
8112 red = bgp_redist_lookup(bgp, afi, type, instance);
8113 if (red) {
8114 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8115 SAFI_UNICAST, p, NULL);
8116
8117 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8118 if (pi->peer == bgp->peer_self && pi->type == type)
8119 break;
8120
8121 if (pi) {
8122 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8123 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8124
8125 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8126 bgp, pi);
8127 }
8128 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8129 bgp_path_info_delete(dest, pi);
8130 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8131 }
8132 bgp_dest_unlock_node(dest);
8133 }
8134 }
8135
8136 /* Withdraw specified route type's route. */
8137 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8138 unsigned short instance)
8139 {
8140 struct bgp_dest *dest;
8141 struct bgp_path_info *pi;
8142 struct bgp_table *table;
8143
8144 table = bgp->rib[afi][SAFI_UNICAST];
8145
8146 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8147 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8148 if (pi->peer == bgp->peer_self && pi->type == type
8149 && pi->instance == instance)
8150 break;
8151
8152 if (pi) {
8153 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8154 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8155
8156 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8157 bgp, pi);
8158 }
8159 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8160 pi, afi, SAFI_UNICAST);
8161 bgp_path_info_delete(dest, pi);
8162 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8163 }
8164 }
8165 }
8166
8167 /* Static function to display route. */
8168 static void route_vty_out_route(const struct prefix *p, struct vty *vty,
8169 json_object *json, bool wide)
8170 {
8171 int len = 0;
8172 char buf[BUFSIZ];
8173 char buf2[BUFSIZ];
8174
8175 if (p->family == AF_INET) {
8176 if (!json) {
8177 len = vty_out(vty, "%pFX", p);
8178 } else {
8179 json_object_string_add(json, "prefix",
8180 inet_ntop(p->family,
8181 &p->u.prefix, buf,
8182 BUFSIZ));
8183 json_object_int_add(json, "prefixLen", p->prefixlen);
8184 prefix2str(p, buf2, PREFIX_STRLEN);
8185 json_object_string_add(json, "network", buf2);
8186 }
8187 } else if (p->family == AF_ETHERNET) {
8188 len = vty_out(vty, "%pFX", p);
8189 } else if (p->family == AF_EVPN) {
8190 if (!json)
8191 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8192 else
8193 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8194 } else if (p->family == AF_FLOWSPEC) {
8195 route_vty_out_flowspec(vty, p, NULL,
8196 json ?
8197 NLRI_STRING_FORMAT_JSON_SIMPLE :
8198 NLRI_STRING_FORMAT_MIN, json);
8199 } else {
8200 if (!json)
8201 len = vty_out(vty, "%pFX", p);
8202 else {
8203 json_object_string_add(json, "prefix",
8204 inet_ntop(p->family,
8205 &p->u.prefix, buf,
8206 BUFSIZ));
8207 json_object_int_add(json, "prefixLen", p->prefixlen);
8208 prefix2str(p, buf2, PREFIX_STRLEN);
8209 json_object_string_add(json, "network", buf2);
8210 }
8211 }
8212
8213 if (!json) {
8214 len = wide ? (45 - len) : (17 - len);
8215 if (len < 1)
8216 vty_out(vty, "\n%*s", 20, " ");
8217 else
8218 vty_out(vty, "%*s", len, " ");
8219 }
8220 }
8221
8222 enum bgp_display_type {
8223 normal_list,
8224 };
8225
8226 static const char *
8227 bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8228 {
8229 switch (reason) {
8230 case bgp_path_selection_none:
8231 return "Nothing to Select";
8232 case bgp_path_selection_first:
8233 return "First path received";
8234 case bgp_path_selection_evpn_sticky_mac:
8235 return "EVPN Sticky Mac";
8236 case bgp_path_selection_evpn_seq:
8237 return "EVPN sequence number";
8238 case bgp_path_selection_evpn_lower_ip:
8239 return "EVPN lower IP";
8240 case bgp_path_selection_evpn_local_path:
8241 return "EVPN local ES path";
8242 case bgp_path_selection_evpn_non_proxy:
8243 return "EVPN non proxy";
8244 case bgp_path_selection_weight:
8245 return "Weight";
8246 case bgp_path_selection_local_pref:
8247 return "Local Pref";
8248 case bgp_path_selection_local_route:
8249 return "Local Route";
8250 case bgp_path_selection_confed_as_path:
8251 return "Confederation based AS Path";
8252 case bgp_path_selection_as_path:
8253 return "AS Path";
8254 case bgp_path_selection_origin:
8255 return "Origin";
8256 case bgp_path_selection_med:
8257 return "MED";
8258 case bgp_path_selection_peer:
8259 return "Peer Type";
8260 case bgp_path_selection_confed:
8261 return "Confed Peer Type";
8262 case bgp_path_selection_igp_metric:
8263 return "IGP Metric";
8264 case bgp_path_selection_older:
8265 return "Older Path";
8266 case bgp_path_selection_router_id:
8267 return "Router ID";
8268 case bgp_path_selection_cluster_length:
8269 return "Cluser length";
8270 case bgp_path_selection_stale:
8271 return "Path Staleness";
8272 case bgp_path_selection_local_configured:
8273 return "Locally configured route";
8274 case bgp_path_selection_neighbor_ip:
8275 return "Neighbor IP";
8276 case bgp_path_selection_default:
8277 return "Nothing left to compare";
8278 }
8279 return "Invalid (internal error)";
8280 }
8281
8282 /* Print the short form route status for a bgp_path_info */
8283 static void route_vty_short_status_out(struct vty *vty,
8284 struct bgp_path_info *path,
8285 json_object *json_path)
8286 {
8287 if (json_path) {
8288
8289 /* Route status display. */
8290 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8291 json_object_boolean_true_add(json_path, "removed");
8292
8293 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8294 json_object_boolean_true_add(json_path, "stale");
8295
8296 if (path->extra && bgp_path_suppressed(path))
8297 json_object_boolean_true_add(json_path, "suppressed");
8298
8299 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8300 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8301 json_object_boolean_true_add(json_path, "valid");
8302
8303 /* Selected */
8304 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8305 json_object_boolean_true_add(json_path, "history");
8306
8307 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8308 json_object_boolean_true_add(json_path, "damped");
8309
8310 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
8311 json_object_boolean_true_add(json_path, "bestpath");
8312 json_object_string_add(json_path, "selectionReason",
8313 bgp_path_selection_reason2str(
8314 path->net->reason));
8315 }
8316
8317 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8318 json_object_boolean_true_add(json_path, "multipath");
8319
8320 /* Internal route. */
8321 if ((path->peer->as)
8322 && (path->peer->as == path->peer->local_as))
8323 json_object_string_add(json_path, "pathFrom",
8324 "internal");
8325 else
8326 json_object_string_add(json_path, "pathFrom",
8327 "external");
8328
8329 return;
8330 }
8331
8332 /* Route status display. */
8333 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8334 vty_out(vty, "R");
8335 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8336 vty_out(vty, "S");
8337 else if (bgp_path_suppressed(path))
8338 vty_out(vty, "s");
8339 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8340 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8341 vty_out(vty, "*");
8342 else
8343 vty_out(vty, " ");
8344
8345 /* Selected */
8346 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8347 vty_out(vty, "h");
8348 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8349 vty_out(vty, "d");
8350 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
8351 vty_out(vty, ">");
8352 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8353 vty_out(vty, "=");
8354 else
8355 vty_out(vty, " ");
8356
8357 /* Internal route. */
8358 if (path->peer && (path->peer->as)
8359 && (path->peer->as == path->peer->local_as))
8360 vty_out(vty, "i");
8361 else
8362 vty_out(vty, " ");
8363 }
8364
8365 static char *bgp_nexthop_hostname(struct peer *peer,
8366 struct bgp_nexthop_cache *bnc)
8367 {
8368 if (peer->hostname
8369 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
8370 return peer->hostname;
8371 return NULL;
8372 }
8373
8374 /* called from terminal list command */
8375 void route_vty_out(struct vty *vty, const struct prefix *p,
8376 struct bgp_path_info *path, int display, safi_t safi,
8377 json_object *json_paths, bool wide)
8378 {
8379 int len;
8380 struct attr *attr = path->attr;
8381 json_object *json_path = NULL;
8382 json_object *json_nexthops = NULL;
8383 json_object *json_nexthop_global = NULL;
8384 json_object *json_nexthop_ll = NULL;
8385 json_object *json_ext_community = NULL;
8386 char vrf_id_str[VRF_NAMSIZ] = {0};
8387 bool nexthop_self =
8388 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8389 bool nexthop_othervrf = false;
8390 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
8391 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
8392 char *nexthop_hostname =
8393 bgp_nexthop_hostname(path->peer, path->nexthop);
8394 char esi_buf[ESI_STR_LEN];
8395
8396 if (json_paths)
8397 json_path = json_object_new_object();
8398
8399 /* short status lead text */
8400 route_vty_short_status_out(vty, path, json_path);
8401
8402 if (!json_paths) {
8403 /* print prefix and mask */
8404 if (!display)
8405 route_vty_out_route(p, vty, json_path, wide);
8406 else
8407 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
8408 } else {
8409 route_vty_out_route(p, vty, json_path, wide);
8410 }
8411
8412 /*
8413 * If vrf id of nexthop is different from that of prefix,
8414 * set up printable string to append
8415 */
8416 if (path->extra && path->extra->bgp_orig) {
8417 const char *self = "";
8418
8419 if (nexthop_self)
8420 self = "<";
8421
8422 nexthop_othervrf = true;
8423 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
8424
8425 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
8426 snprintf(vrf_id_str, sizeof(vrf_id_str),
8427 "@%s%s", VRFID_NONE_STR, self);
8428 else
8429 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
8430 path->extra->bgp_orig->vrf_id, self);
8431
8432 if (path->extra->bgp_orig->inst_type
8433 != BGP_INSTANCE_TYPE_DEFAULT)
8434
8435 nexthop_vrfname = path->extra->bgp_orig->name;
8436 } else {
8437 const char *self = "";
8438
8439 if (nexthop_self)
8440 self = "<";
8441
8442 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
8443 }
8444
8445 /*
8446 * For ENCAP and EVPN routes, nexthop address family is not
8447 * neccessarily the same as the prefix address family.
8448 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
8449 * EVPN routes are also exchanged with a MP nexthop. Currently,
8450 * this
8451 * is only IPv4, the value will be present in either
8452 * attr->nexthop or
8453 * attr->mp_nexthop_global_in
8454 */
8455 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
8456 char buf[BUFSIZ];
8457 char nexthop[128];
8458 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
8459
8460 switch (af) {
8461 case AF_INET:
8462 snprintf(nexthop, sizeof(nexthop), "%s",
8463 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
8464 BUFSIZ));
8465 break;
8466 case AF_INET6:
8467 snprintf(nexthop, sizeof(nexthop), "%s",
8468 inet_ntop(af, &attr->mp_nexthop_global, buf,
8469 BUFSIZ));
8470 break;
8471 default:
8472 snprintf(nexthop, sizeof(nexthop), "?");
8473 break;
8474 }
8475
8476 if (json_paths) {
8477 json_nexthop_global = json_object_new_object();
8478
8479 json_object_string_add(json_nexthop_global, "ip",
8480 nexthop);
8481
8482 if (path->peer->hostname)
8483 json_object_string_add(json_nexthop_global,
8484 "hostname",
8485 path->peer->hostname);
8486
8487 json_object_string_add(json_nexthop_global, "afi",
8488 (af == AF_INET) ? "ipv4"
8489 : "ipv6");
8490 json_object_boolean_true_add(json_nexthop_global,
8491 "used");
8492 } else {
8493 if (nexthop_hostname)
8494 len = vty_out(vty, "%s(%s)%s", nexthop,
8495 nexthop_hostname, vrf_id_str);
8496 else
8497 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
8498
8499 len = wide ? (41 - len) : (16 - len);
8500 if (len < 1)
8501 vty_out(vty, "\n%*s", 36, " ");
8502 else
8503 vty_out(vty, "%*s", len, " ");
8504 }
8505 } else if (safi == SAFI_EVPN) {
8506 if (json_paths) {
8507 char buf[BUFSIZ] = {0};
8508
8509 json_nexthop_global = json_object_new_object();
8510
8511 json_object_string_add(json_nexthop_global, "ip",
8512 inet_ntop(AF_INET,
8513 &attr->nexthop, buf,
8514 sizeof(buf)));
8515
8516 if (path->peer->hostname)
8517 json_object_string_add(json_nexthop_global,
8518 "hostname",
8519 path->peer->hostname);
8520
8521 json_object_string_add(json_nexthop_global, "afi",
8522 "ipv4");
8523 json_object_boolean_true_add(json_nexthop_global,
8524 "used");
8525 } else {
8526 if (nexthop_hostname)
8527 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
8528 nexthop_hostname, vrf_id_str);
8529 else
8530 len = vty_out(vty, "%pI4%s", &attr->nexthop,
8531 vrf_id_str);
8532
8533 len = wide ? (41 - len) : (16 - len);
8534 if (len < 1)
8535 vty_out(vty, "\n%*s", 36, " ");
8536 else
8537 vty_out(vty, "%*s", len, " ");
8538 }
8539 } else if (safi == SAFI_FLOWSPEC) {
8540 if (attr->nexthop.s_addr != INADDR_ANY) {
8541 if (json_paths) {
8542 char buf[BUFSIZ] = {0};
8543
8544 json_nexthop_global = json_object_new_object();
8545
8546 json_object_string_add(json_nexthop_global,
8547 "afi", "ipv4");
8548 json_object_string_add(
8549 json_nexthop_global, "ip",
8550 inet_ntop(AF_INET, &attr->nexthop, buf,
8551 sizeof(buf)));
8552
8553 if (path->peer->hostname)
8554 json_object_string_add(
8555 json_nexthop_global, "hostname",
8556 path->peer->hostname);
8557
8558 json_object_boolean_true_add(
8559 json_nexthop_global,
8560 "used");
8561 } else {
8562 if (nexthop_hostname)
8563 len = vty_out(vty, "%pI4(%s)%s",
8564 &attr->nexthop,
8565 nexthop_hostname,
8566 vrf_id_str);
8567 else
8568 len = vty_out(vty, "%pI4%s",
8569 &attr->nexthop,
8570 vrf_id_str);
8571
8572 len = wide ? (41 - len) : (16 - len);
8573 if (len < 1)
8574 vty_out(vty, "\n%*s", 36, " ");
8575 else
8576 vty_out(vty, "%*s", len, " ");
8577 }
8578 }
8579 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8580 if (json_paths) {
8581 char buf[BUFSIZ] = {0};
8582
8583 json_nexthop_global = json_object_new_object();
8584
8585 json_object_string_add(json_nexthop_global, "ip",
8586 inet_ntop(AF_INET,
8587 &attr->nexthop, buf,
8588 sizeof(buf)));
8589
8590 if (path->peer->hostname)
8591 json_object_string_add(json_nexthop_global,
8592 "hostname",
8593 path->peer->hostname);
8594
8595 json_object_string_add(json_nexthop_global, "afi",
8596 "ipv4");
8597 json_object_boolean_true_add(json_nexthop_global,
8598 "used");
8599 } else {
8600 if (nexthop_hostname)
8601 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
8602 nexthop_hostname, vrf_id_str);
8603 else
8604 len = vty_out(vty, "%pI4%s", &attr->nexthop,
8605 vrf_id_str);
8606
8607 len = wide ? (41 - len) : (16 - len);
8608 if (len < 1)
8609 vty_out(vty, "\n%*s", 36, " ");
8610 else
8611 vty_out(vty, "%*s", len, " ");
8612 }
8613 }
8614
8615 /* IPv6 Next Hop */
8616 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8617 char buf[BUFSIZ];
8618
8619 if (json_paths) {
8620 json_nexthop_global = json_object_new_object();
8621 json_object_string_add(
8622 json_nexthop_global, "ip",
8623 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
8624 buf, BUFSIZ));
8625
8626 if (path->peer->hostname)
8627 json_object_string_add(json_nexthop_global,
8628 "hostname",
8629 path->peer->hostname);
8630
8631 json_object_string_add(json_nexthop_global, "afi",
8632 "ipv6");
8633 json_object_string_add(json_nexthop_global, "scope",
8634 "global");
8635
8636 /* We display both LL & GL if both have been
8637 * received */
8638 if ((attr->mp_nexthop_len
8639 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
8640 || (path->peer->conf_if)) {
8641 json_nexthop_ll = json_object_new_object();
8642 json_object_string_add(
8643 json_nexthop_ll, "ip",
8644 inet_ntop(AF_INET6,
8645 &attr->mp_nexthop_local, buf,
8646 BUFSIZ));
8647
8648 if (path->peer->hostname)
8649 json_object_string_add(
8650 json_nexthop_ll, "hostname",
8651 path->peer->hostname);
8652
8653 json_object_string_add(json_nexthop_ll, "afi",
8654 "ipv6");
8655 json_object_string_add(json_nexthop_ll, "scope",
8656 "link-local");
8657
8658 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
8659 &attr->mp_nexthop_local)
8660 != 0)
8661 && !attr->mp_nexthop_prefer_global)
8662 json_object_boolean_true_add(
8663 json_nexthop_ll, "used");
8664 else
8665 json_object_boolean_true_add(
8666 json_nexthop_global, "used");
8667 } else
8668 json_object_boolean_true_add(
8669 json_nexthop_global, "used");
8670 } else {
8671 /* Display LL if LL/Global both in table unless
8672 * prefer-global is set */
8673 if (((attr->mp_nexthop_len
8674 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
8675 && !attr->mp_nexthop_prefer_global)
8676 || (path->peer->conf_if)) {
8677 if (path->peer->conf_if) {
8678 len = vty_out(vty, "%s",
8679 path->peer->conf_if);
8680 /* len of IPv6 addr + max len of def
8681 * ifname */
8682 len = wide ? (41 - len) : (16 - len);
8683
8684 if (len < 1)
8685 vty_out(vty, "\n%*s", 36, " ");
8686 else
8687 vty_out(vty, "%*s", len, " ");
8688 } else {
8689 if (nexthop_hostname)
8690 len = vty_out(
8691 vty, "%pI6(%s)%s",
8692 &attr->mp_nexthop_local,
8693 nexthop_hostname,
8694 vrf_id_str);
8695 else
8696 len = vty_out(
8697 vty, "%pI6%s",
8698 &attr->mp_nexthop_local,
8699 vrf_id_str);
8700
8701 len = wide ? (41 - len) : (16 - len);
8702
8703 if (len < 1)
8704 vty_out(vty, "\n%*s", 36, " ");
8705 else
8706 vty_out(vty, "%*s", len, " ");
8707 }
8708 } else {
8709 if (nexthop_hostname)
8710 len = vty_out(vty, "%pI6(%s)%s",
8711 &attr->mp_nexthop_global,
8712 nexthop_hostname,
8713 vrf_id_str);
8714 else
8715 len = vty_out(vty, "%pI6%s",
8716 &attr->mp_nexthop_global,
8717 vrf_id_str);
8718
8719 len = wide ? (41 - len) : (16 - len);
8720
8721 if (len < 1)
8722 vty_out(vty, "\n%*s", 36, " ");
8723 else
8724 vty_out(vty, "%*s", len, " ");
8725 }
8726 }
8727 }
8728
8729 /* MED/Metric */
8730 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
8731 if (json_paths)
8732 json_object_int_add(json_path, "metric", attr->med);
8733 else if (wide)
8734 vty_out(vty, "%7u", attr->med);
8735 else
8736 vty_out(vty, "%10u", attr->med);
8737 else if (!json_paths) {
8738 if (wide)
8739 vty_out(vty, "%*s", 7, " ");
8740 else
8741 vty_out(vty, "%*s", 10, " ");
8742 }
8743
8744 /* Local Pref */
8745 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
8746 if (json_paths)
8747 json_object_int_add(json_path, "locPrf",
8748 attr->local_pref);
8749 else
8750 vty_out(vty, "%7u", attr->local_pref);
8751 else if (!json_paths)
8752 vty_out(vty, " ");
8753
8754 if (json_paths)
8755 json_object_int_add(json_path, "weight", attr->weight);
8756 else
8757 vty_out(vty, "%7u ", attr->weight);
8758
8759 if (json_paths) {
8760 char buf[BUFSIZ];
8761 json_object_string_add(
8762 json_path, "peerId",
8763 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
8764 }
8765
8766 /* Print aspath */
8767 if (attr->aspath) {
8768 if (json_paths)
8769 json_object_string_add(json_path, "path",
8770 attr->aspath->str);
8771 else
8772 aspath_print_vty(vty, "%s", attr->aspath, " ");
8773 }
8774
8775 /* Print origin */
8776 if (json_paths)
8777 json_object_string_add(json_path, "origin",
8778 bgp_origin_long_str[attr->origin]);
8779 else
8780 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8781
8782 if (json_paths) {
8783 if (bgp_evpn_is_esi_valid(&attr->esi)) {
8784 json_object_string_add(json_path, "esi",
8785 esi_to_str(&attr->esi,
8786 esi_buf, sizeof(esi_buf)));
8787 }
8788 if (safi == SAFI_EVPN &&
8789 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8790 json_ext_community = json_object_new_object();
8791 json_object_string_add(json_ext_community,
8792 "string",
8793 attr->ecommunity->str);
8794 json_object_object_add(json_path,
8795 "extendedCommunity",
8796 json_ext_community);
8797 }
8798
8799 if (nexthop_self)
8800 json_object_boolean_true_add(json_path,
8801 "announceNexthopSelf");
8802 if (nexthop_othervrf) {
8803 json_object_string_add(json_path, "nhVrfName",
8804 nexthop_vrfname);
8805
8806 json_object_int_add(json_path, "nhVrfId",
8807 ((nexthop_vrfid == VRF_UNKNOWN)
8808 ? -1
8809 : (int)nexthop_vrfid));
8810 }
8811 }
8812
8813 if (json_paths) {
8814 if (json_nexthop_global || json_nexthop_ll) {
8815 json_nexthops = json_object_new_array();
8816
8817 if (json_nexthop_global)
8818 json_object_array_add(json_nexthops,
8819 json_nexthop_global);
8820
8821 if (json_nexthop_ll)
8822 json_object_array_add(json_nexthops,
8823 json_nexthop_ll);
8824
8825 json_object_object_add(json_path, "nexthops",
8826 json_nexthops);
8827 }
8828
8829 json_object_array_add(json_paths, json_path);
8830 } else {
8831 vty_out(vty, "\n");
8832
8833 if (safi == SAFI_EVPN) {
8834 struct bgp_path_es_info *path_es_info = NULL;
8835
8836 if (path->extra)
8837 path_es_info = path->extra->es_info;
8838
8839 if (bgp_evpn_is_esi_valid(&attr->esi)) {
8840 /* XXX - add these params to the json out */
8841 vty_out(vty, "%*s", 20, " ");
8842 vty_out(vty, "ESI:%s",
8843 esi_to_str(&attr->esi, esi_buf,
8844 sizeof(esi_buf)));
8845 if (path_es_info && path_es_info->es)
8846 vty_out(vty, " VNI: %u",
8847 path_es_info->vni);
8848 vty_out(vty, "\n");
8849 }
8850 if (attr->flag &
8851 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8852 vty_out(vty, "%*s", 20, " ");
8853 vty_out(vty, "%s\n", attr->ecommunity->str);
8854 }
8855 }
8856
8857 #ifdef ENABLE_BGP_VNC
8858 /* prints an additional line, indented, with VNC info, if
8859 * present */
8860 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
8861 rfapi_vty_out_vncinfo(vty, p, path, safi);
8862 #endif
8863 }
8864 }
8865
8866 /* called from terminal list command */
8867 void route_vty_out_tmp(struct vty *vty, const struct prefix *p,
8868 struct attr *attr, safi_t safi, bool use_json,
8869 json_object *json_ar, bool wide)
8870 {
8871 json_object *json_status = NULL;
8872 json_object *json_net = NULL;
8873 int len;
8874 char buff[BUFSIZ];
8875
8876 /* Route status display. */
8877 if (use_json) {
8878 json_status = json_object_new_object();
8879 json_net = json_object_new_object();
8880 } else {
8881 vty_out(vty, "*");
8882 vty_out(vty, ">");
8883 vty_out(vty, " ");
8884 }
8885
8886 /* print prefix and mask */
8887 if (use_json) {
8888 if (safi == SAFI_EVPN)
8889 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
8890 else if (p->family == AF_INET || p->family == AF_INET6) {
8891 json_object_string_add(
8892 json_net, "addrPrefix",
8893 inet_ntop(p->family, &p->u.prefix, buff,
8894 BUFSIZ));
8895 json_object_int_add(json_net, "prefixLen",
8896 p->prefixlen);
8897 prefix2str(p, buff, PREFIX_STRLEN);
8898 json_object_string_add(json_net, "network", buff);
8899 }
8900 } else
8901 route_vty_out_route(p, vty, NULL, wide);
8902
8903 /* Print attribute */
8904 if (attr) {
8905 if (use_json) {
8906 char buf[BUFSIZ] = {0};
8907
8908 if (p->family == AF_INET
8909 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8910 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8911 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
8912 json_object_string_add(
8913 json_net, "nextHop",
8914 inet_ntop(
8915 AF_INET,
8916 &attr->mp_nexthop_global_in,
8917 buf, sizeof(buf)));
8918 else
8919 json_object_string_add(
8920 json_net, "nextHop",
8921 inet_ntop(AF_INET,
8922 &attr->nexthop, buf,
8923 sizeof(buf)));
8924 } else if (p->family == AF_INET6
8925 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8926 char buf[BUFSIZ];
8927
8928 json_object_string_add(
8929 json_net, "nextHopGlobal",
8930 inet_ntop(AF_INET6,
8931 &attr->mp_nexthop_global, buf,
8932 BUFSIZ));
8933 } else if (p->family == AF_EVPN
8934 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8935 char buf[BUFSIZ] = {0};
8936
8937 json_object_string_add(
8938 json_net, "nextHop",
8939 inet_ntop(AF_INET,
8940 &attr->mp_nexthop_global_in,
8941 buf, sizeof(buf)));
8942 }
8943
8944 if (attr->flag
8945 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
8946 json_object_int_add(json_net, "metric",
8947 attr->med);
8948
8949 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
8950 json_object_int_add(json_net, "locPrf",
8951 attr->local_pref);
8952
8953 json_object_int_add(json_net, "weight", attr->weight);
8954
8955 /* Print aspath */
8956 if (attr->aspath)
8957 json_object_string_add(json_net, "path",
8958 attr->aspath->str);
8959
8960 /* Print origin */
8961 json_object_string_add(json_net, "bgpOriginCode",
8962 bgp_origin_str[attr->origin]);
8963 } else {
8964 if (p->family == AF_INET
8965 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8966 || safi == SAFI_EVPN
8967 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8968 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8969 || safi == SAFI_EVPN)
8970 vty_out(vty, "%-16pI4",
8971 &attr->mp_nexthop_global_in);
8972 else if (wide)
8973 vty_out(vty, "%-41pI4", &attr->nexthop);
8974 else
8975 vty_out(vty, "%-16pI4", &attr->nexthop);
8976 } else if (p->family == AF_INET6
8977 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8978 char buf[BUFSIZ];
8979
8980 len = vty_out(
8981 vty, "%s",
8982 inet_ntop(AF_INET6,
8983 &attr->mp_nexthop_global, buf,
8984 BUFSIZ));
8985 len = wide ? (41 - len) : (16 - len);
8986 if (len < 1)
8987 vty_out(vty, "\n%*s", 36, " ");
8988 else
8989 vty_out(vty, "%*s", len, " ");
8990 }
8991 if (attr->flag
8992 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
8993 if (wide)
8994 vty_out(vty, "%7u", attr->med);
8995 else
8996 vty_out(vty, "%10u", attr->med);
8997 else if (wide)
8998 vty_out(vty, " ");
8999 else
9000 vty_out(vty, " ");
9001
9002 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9003 vty_out(vty, "%7u", attr->local_pref);
9004 else
9005 vty_out(vty, " ");
9006
9007 vty_out(vty, "%7u ", attr->weight);
9008
9009 /* Print aspath */
9010 if (attr->aspath)
9011 aspath_print_vty(vty, "%s", attr->aspath, " ");
9012
9013 /* Print origin */
9014 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9015 }
9016 }
9017 if (use_json) {
9018 json_object_boolean_true_add(json_status, "*");
9019 json_object_boolean_true_add(json_status, ">");
9020 json_object_object_add(json_net, "appliedStatusSymbols",
9021 json_status);
9022
9023 prefix2str(p, buff, PREFIX_STRLEN);
9024 json_object_object_add(json_ar, buff, json_net);
9025 } else
9026 vty_out(vty, "\n");
9027 }
9028
9029 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9030 struct bgp_path_info *path, int display, safi_t safi,
9031 json_object *json)
9032 {
9033 json_object *json_out = NULL;
9034 struct attr *attr;
9035 mpls_label_t label = MPLS_INVALID_LABEL;
9036
9037 if (!path->extra)
9038 return;
9039
9040 if (json)
9041 json_out = json_object_new_object();
9042
9043 /* short status lead text */
9044 route_vty_short_status_out(vty, path, json_out);
9045
9046 /* print prefix and mask */
9047 if (json == NULL) {
9048 if (!display)
9049 route_vty_out_route(p, vty, NULL, false);
9050 else
9051 vty_out(vty, "%*s", 17, " ");
9052 }
9053
9054 /* Print attribute */
9055 attr = path->attr;
9056 if (((p->family == AF_INET)
9057 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
9058 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
9059 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9060 char buf[BUFSIZ] = {0};
9061
9062 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9063 || safi == SAFI_EVPN) {
9064 if (json)
9065 json_object_string_add(
9066 json_out, "mpNexthopGlobalIn",
9067 inet_ntop(AF_INET,
9068 &attr->mp_nexthop_global_in,
9069 buf, sizeof(buf)));
9070 else
9071 vty_out(vty, "%-16pI4",
9072 &attr->mp_nexthop_global_in);
9073 } else {
9074 if (json)
9075 json_object_string_add(
9076 json_out, "nexthop",
9077 inet_ntop(AF_INET, &attr->nexthop, buf,
9078 sizeof(buf)));
9079 else
9080 vty_out(vty, "%-16pI4", &attr->nexthop);
9081 }
9082 } else if (((p->family == AF_INET6)
9083 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
9084 || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
9085 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9086 char buf_a[512];
9087
9088 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9089 if (json)
9090 json_object_string_add(
9091 json_out, "mpNexthopGlobalIn",
9092 inet_ntop(AF_INET6,
9093 &attr->mp_nexthop_global,
9094 buf_a, sizeof(buf_a)));
9095 else
9096 vty_out(vty, "%s",
9097 inet_ntop(AF_INET6,
9098 &attr->mp_nexthop_global,
9099 buf_a, sizeof(buf_a)));
9100 } else if (attr->mp_nexthop_len
9101 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9102 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9103 &attr->mp_nexthop_global,
9104 &attr->mp_nexthop_local);
9105 if (json)
9106 json_object_string_add(json_out,
9107 "mpNexthopGlobalLocal",
9108 buf_a);
9109 else
9110 vty_out(vty, "%s", buf_a);
9111 }
9112 }
9113
9114 label = decode_label(&path->extra->label[0]);
9115
9116 if (bgp_is_valid_label(&label)) {
9117 if (json) {
9118 json_object_int_add(json_out, "notag", label);
9119 json_object_array_add(json, json_out);
9120 } else {
9121 vty_out(vty, "notag/%d", label);
9122 vty_out(vty, "\n");
9123 }
9124 }
9125 }
9126
9127 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9128 struct bgp_path_info *path, int display,
9129 json_object *json_paths)
9130 {
9131 struct attr *attr;
9132 char buf[BUFSIZ] = {0};
9133 json_object *json_path = NULL;
9134 json_object *json_nexthop = NULL;
9135 json_object *json_overlay = NULL;
9136
9137 if (!path->extra)
9138 return;
9139
9140 if (json_paths) {
9141 json_path = json_object_new_object();
9142 json_overlay = json_object_new_object();
9143 json_nexthop = json_object_new_object();
9144 }
9145
9146 /* short status lead text */
9147 route_vty_short_status_out(vty, path, json_path);
9148
9149 /* print prefix and mask */
9150 if (!display)
9151 route_vty_out_route(p, vty, json_path, false);
9152 else
9153 vty_out(vty, "%*s", 17, " ");
9154
9155 /* Print attribute */
9156 attr = path->attr;
9157 char buf1[BUFSIZ];
9158 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9159
9160 switch (af) {
9161 case AF_INET:
9162 inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ);
9163 if (!json_path) {
9164 vty_out(vty, "%-16s", buf);
9165 } else {
9166 json_object_string_add(json_nexthop, "ip", buf);
9167
9168 json_object_string_add(json_nexthop, "afi", "ipv4");
9169
9170 json_object_object_add(json_path, "nexthop",
9171 json_nexthop);
9172 }
9173 break;
9174 case AF_INET6:
9175 inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ);
9176 inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ);
9177 if (!json_path) {
9178 vty_out(vty, "%s(%s)", buf, buf1);
9179 } else {
9180 json_object_string_add(json_nexthop, "ipv6Global", buf);
9181
9182 json_object_string_add(json_nexthop, "ipv6LinkLocal",
9183 buf1);
9184
9185 json_object_string_add(json_nexthop, "afi", "ipv6");
9186
9187 json_object_object_add(json_path, "nexthop",
9188 json_nexthop);
9189 }
9190 break;
9191 default:
9192 if (!json_path) {
9193 vty_out(vty, "?");
9194 } else {
9195 json_object_string_add(json_nexthop, "Error",
9196 "Unsupported address-family");
9197 }
9198 }
9199
9200 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9201
9202 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p))
9203 inet_ntop(AF_INET, &eo->gw_ip.ipv4, buf, BUFSIZ);
9204 else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p))
9205 inet_ntop(AF_INET6, &eo->gw_ip.ipv6, buf, BUFSIZ);
9206
9207 if (!json_path)
9208 vty_out(vty, "/%s", buf);
9209 else
9210 json_object_string_add(json_overlay, "gw", buf);
9211
9212 if (attr->ecommunity) {
9213 char *mac = NULL;
9214 struct ecommunity_val *routermac = ecommunity_lookup(
9215 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
9216 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9217
9218 if (routermac)
9219 mac = ecom_mac2str((char *)routermac->val);
9220 if (mac) {
9221 if (!json_path) {
9222 vty_out(vty, "/%s", mac);
9223 } else {
9224 json_object_string_add(json_overlay, "rmac",
9225 mac);
9226 }
9227 XFREE(MTYPE_TMP, mac);
9228 }
9229 }
9230
9231 if (!json_path) {
9232 vty_out(vty, "\n");
9233 } else {
9234 json_object_object_add(json_path, "overlay", json_overlay);
9235
9236 json_object_array_add(json_paths, json_path);
9237 }
9238 }
9239
9240 /* dampening route */
9241 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9242 struct bgp_path_info *path, int display,
9243 afi_t afi, safi_t safi, bool use_json,
9244 json_object *json)
9245 {
9246 struct attr *attr;
9247 int len;
9248 char timebuf[BGP_UPTIME_LEN];
9249
9250 /* short status lead text */
9251 route_vty_short_status_out(vty, path, json);
9252
9253 /* print prefix and mask */
9254 if (!use_json) {
9255 if (!display)
9256 route_vty_out_route(p, vty, NULL, false);
9257 else
9258 vty_out(vty, "%*s", 17, " ");
9259 }
9260
9261 len = vty_out(vty, "%s", path->peer->host);
9262 len = 17 - len;
9263 if (len < 1) {
9264 if (!use_json)
9265 vty_out(vty, "\n%*s", 34, " ");
9266 } else {
9267 if (use_json)
9268 json_object_int_add(json, "peerHost", len);
9269 else
9270 vty_out(vty, "%*s", len, " ");
9271 }
9272
9273 if (use_json)
9274 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9275 safi, use_json, json);
9276 else
9277 vty_out(vty, "%s ",
9278 bgp_damp_reuse_time_vty(vty, path, timebuf,
9279 BGP_UPTIME_LEN, afi, safi,
9280 use_json, json));
9281
9282 /* Print attribute */
9283 attr = path->attr;
9284
9285 /* Print aspath */
9286 if (attr->aspath) {
9287 if (use_json)
9288 json_object_string_add(json, "asPath",
9289 attr->aspath->str);
9290 else
9291 aspath_print_vty(vty, "%s", attr->aspath, " ");
9292 }
9293
9294 /* Print origin */
9295 if (use_json)
9296 json_object_string_add(json, "origin",
9297 bgp_origin_str[attr->origin]);
9298 else
9299 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9300
9301 if (!use_json)
9302 vty_out(vty, "\n");
9303 }
9304
9305 /* flap route */
9306 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9307 struct bgp_path_info *path, int display,
9308 afi_t afi, safi_t safi, bool use_json,
9309 json_object *json)
9310 {
9311 struct attr *attr;
9312 struct bgp_damp_info *bdi;
9313 char timebuf[BGP_UPTIME_LEN];
9314 int len;
9315
9316 if (!path->extra)
9317 return;
9318
9319 bdi = path->extra->damp_info;
9320
9321 /* short status lead text */
9322 route_vty_short_status_out(vty, path, json);
9323
9324 /* print prefix and mask */
9325 if (!use_json) {
9326 if (!display)
9327 route_vty_out_route(p, vty, NULL, false);
9328 else
9329 vty_out(vty, "%*s", 17, " ");
9330 }
9331
9332 len = vty_out(vty, "%s", path->peer->host);
9333 len = 16 - len;
9334 if (len < 1) {
9335 if (!use_json)
9336 vty_out(vty, "\n%*s", 33, " ");
9337 } else {
9338 if (use_json)
9339 json_object_int_add(json, "peerHost", len);
9340 else
9341 vty_out(vty, "%*s", len, " ");
9342 }
9343
9344 len = vty_out(vty, "%d", bdi->flap);
9345 len = 5 - len;
9346 if (len < 1) {
9347 if (!use_json)
9348 vty_out(vty, " ");
9349 } else {
9350 if (use_json)
9351 json_object_int_add(json, "bdiFlap", len);
9352 else
9353 vty_out(vty, "%*s", len, " ");
9354 }
9355
9356 if (use_json)
9357 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
9358 json);
9359 else
9360 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
9361 BGP_UPTIME_LEN, 0, NULL));
9362
9363 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9364 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
9365 if (use_json)
9366 bgp_damp_reuse_time_vty(vty, path, timebuf,
9367 BGP_UPTIME_LEN, afi, safi,
9368 use_json, json);
9369 else
9370 vty_out(vty, "%s ",
9371 bgp_damp_reuse_time_vty(vty, path, timebuf,
9372 BGP_UPTIME_LEN, afi,
9373 safi, use_json, json));
9374 } else {
9375 if (!use_json)
9376 vty_out(vty, "%*s ", 8, " ");
9377 }
9378
9379 /* Print attribute */
9380 attr = path->attr;
9381
9382 /* Print aspath */
9383 if (attr->aspath) {
9384 if (use_json)
9385 json_object_string_add(json, "asPath",
9386 attr->aspath->str);
9387 else
9388 aspath_print_vty(vty, "%s", attr->aspath, " ");
9389 }
9390
9391 /* Print origin */
9392 if (use_json)
9393 json_object_string_add(json, "origin",
9394 bgp_origin_str[attr->origin]);
9395 else
9396 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9397
9398 if (!use_json)
9399 vty_out(vty, "\n");
9400 }
9401
9402 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
9403 int *first, const char *header,
9404 json_object *json_adv_to)
9405 {
9406 char buf1[INET6_ADDRSTRLEN];
9407 json_object *json_peer = NULL;
9408
9409 if (json_adv_to) {
9410 /* 'advertised-to' is a dictionary of peers we have advertised
9411 * this
9412 * prefix too. The key is the peer's IP or swpX, the value is
9413 * the
9414 * hostname if we know it and "" if not.
9415 */
9416 json_peer = json_object_new_object();
9417
9418 if (peer->hostname)
9419 json_object_string_add(json_peer, "hostname",
9420 peer->hostname);
9421
9422 if (peer->conf_if)
9423 json_object_object_add(json_adv_to, peer->conf_if,
9424 json_peer);
9425 else
9426 json_object_object_add(
9427 json_adv_to,
9428 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
9429 json_peer);
9430 } else {
9431 if (*first) {
9432 vty_out(vty, "%s", header);
9433 *first = 0;
9434 }
9435
9436 if (peer->hostname
9437 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
9438 if (peer->conf_if)
9439 vty_out(vty, " %s(%s)", peer->hostname,
9440 peer->conf_if);
9441 else
9442 vty_out(vty, " %s(%s)", peer->hostname,
9443 sockunion2str(&peer->su, buf1,
9444 SU_ADDRSTRLEN));
9445 } else {
9446 if (peer->conf_if)
9447 vty_out(vty, " %s", peer->conf_if);
9448 else
9449 vty_out(vty, " %s",
9450 sockunion2str(&peer->su, buf1,
9451 SU_ADDRSTRLEN));
9452 }
9453 }
9454 }
9455
9456 static void route_vty_out_tx_ids(struct vty *vty,
9457 struct bgp_addpath_info_data *d)
9458 {
9459 int i;
9460
9461 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9462 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
9463 d->addpath_tx_id[i],
9464 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
9465 }
9466 }
9467
9468 static void route_vty_out_detail_es_info(struct vty *vty,
9469 struct bgp_path_info *pi,
9470 struct attr *attr,
9471 json_object *json_path)
9472 {
9473 char esi_buf[ESI_STR_LEN];
9474 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
9475 bool peer_router = !!CHECK_FLAG(attr->es_flags,
9476 ATTR_ES_PEER_ROUTER);
9477 bool peer_active = !!CHECK_FLAG(attr->es_flags,
9478 ATTR_ES_PEER_ACTIVE);
9479 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
9480 ATTR_ES_PEER_PROXY);
9481 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
9482 if (json_path) {
9483 json_object *json_es_info = NULL;
9484
9485 json_object_string_add(
9486 json_path, "esi",
9487 esi_buf);
9488 if (es_local || bgp_evpn_attr_is_sync(attr)) {
9489 json_es_info = json_object_new_object();
9490 if (es_local)
9491 json_object_boolean_true_add(
9492 json_es_info, "localEs");
9493 if (peer_active)
9494 json_object_boolean_true_add(
9495 json_es_info, "peerActive");
9496 if (peer_proxy)
9497 json_object_boolean_true_add(
9498 json_es_info, "peerProxy");
9499 if (peer_router)
9500 json_object_boolean_true_add(
9501 json_es_info, "peerRouter");
9502 if (attr->mm_sync_seqnum)
9503 json_object_int_add(
9504 json_es_info, "peerSeq",
9505 attr->mm_sync_seqnum);
9506 json_object_object_add(
9507 json_path, "es_info",
9508 json_es_info);
9509 }
9510 } else {
9511 if (bgp_evpn_attr_is_sync(attr))
9512 vty_out(vty,
9513 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
9514 esi_buf,
9515 es_local ? "local-es":"",
9516 peer_proxy ? "proxy " : "",
9517 peer_active ? "active ":"",
9518 peer_router ? "router ":"",
9519 attr->mm_sync_seqnum);
9520 else
9521 vty_out(vty, " ESI %s %s\n",
9522 esi_buf,
9523 es_local ? "local-es":"");
9524 }
9525 }
9526
9527 void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
9528 struct bgp_dest *bn, struct bgp_path_info *path,
9529 afi_t afi, safi_t safi, json_object *json_paths)
9530 {
9531 char buf[INET6_ADDRSTRLEN];
9532 char buf1[BUFSIZ];
9533 struct attr *attr = path->attr;
9534 int sockunion_vty_out(struct vty *, union sockunion *);
9535 time_t tbuf;
9536 json_object *json_bestpath = NULL;
9537 json_object *json_cluster_list = NULL;
9538 json_object *json_cluster_list_list = NULL;
9539 json_object *json_ext_community = NULL;
9540 json_object *json_last_update = NULL;
9541 json_object *json_pmsi = NULL;
9542 json_object *json_nexthop_global = NULL;
9543 json_object *json_nexthop_ll = NULL;
9544 json_object *json_nexthops = NULL;
9545 json_object *json_path = NULL;
9546 json_object *json_peer = NULL;
9547 json_object *json_string = NULL;
9548 json_object *json_adv_to = NULL;
9549 int first = 0;
9550 struct listnode *node, *nnode;
9551 struct peer *peer;
9552 int addpath_capable;
9553 int has_adj;
9554 unsigned int first_as;
9555 bool nexthop_self =
9556 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9557 int i;
9558 char *nexthop_hostname =
9559 bgp_nexthop_hostname(path->peer, path->nexthop);
9560
9561 if (json_paths) {
9562 json_path = json_object_new_object();
9563 json_peer = json_object_new_object();
9564 json_nexthop_global = json_object_new_object();
9565 }
9566
9567 if (path->extra) {
9568 char tag_buf[30];
9569
9570 tag_buf[0] = '\0';
9571 if (path->extra && path->extra->num_labels) {
9572 bgp_evpn_label2str(path->extra->label,
9573 path->extra->num_labels, tag_buf,
9574 sizeof(tag_buf));
9575 }
9576 if (safi == SAFI_EVPN) {
9577 if (!json_paths) {
9578 vty_out(vty, " Route %pFX",
9579 (struct prefix_evpn *)
9580 bgp_dest_get_prefix(bn));
9581 if (tag_buf[0] != '\0')
9582 vty_out(vty, " VNI %s", tag_buf);
9583 vty_out(vty, "\n");
9584 } else {
9585 if (tag_buf[0])
9586 json_object_string_add(json_path, "VNI",
9587 tag_buf);
9588 }
9589 }
9590
9591 if (path->extra && path->extra->parent && !json_paths) {
9592 struct bgp_path_info *parent_ri;
9593 struct bgp_dest *dest, *pdest;
9594
9595 parent_ri = (struct bgp_path_info *)path->extra->parent;
9596 dest = parent_ri->net;
9597 if (dest && dest->pdest) {
9598 pdest = dest->pdest;
9599 prefix_rd2str(
9600 (struct prefix_rd *)bgp_dest_get_prefix(
9601 pdest),
9602 buf1, sizeof(buf1));
9603 if (is_pi_family_evpn(parent_ri)) {
9604 vty_out(vty,
9605 " Imported from %s:%pFX, VNI %s\n",
9606 buf1,
9607 (struct prefix_evpn *)
9608 bgp_dest_get_prefix(
9609 dest),
9610 tag_buf);
9611 } else
9612 vty_out(vty,
9613 " Imported from %s:%pFX\n",
9614 buf1,
9615 (struct prefix_evpn *)
9616 bgp_dest_get_prefix(
9617 dest));
9618 }
9619 }
9620 }
9621
9622 /* Line1 display AS-path, Aggregator */
9623 if (attr->aspath) {
9624 if (json_paths) {
9625 if (!attr->aspath->json)
9626 aspath_str_update(attr->aspath, true);
9627 json_object_lock(attr->aspath->json);
9628 json_object_object_add(json_path, "aspath",
9629 attr->aspath->json);
9630 } else {
9631 if (attr->aspath->segments)
9632 aspath_print_vty(vty, " %s", attr->aspath, "");
9633 else
9634 vty_out(vty, " Local");
9635 }
9636 }
9637
9638 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
9639 if (json_paths)
9640 json_object_boolean_true_add(json_path, "removed");
9641 else
9642 vty_out(vty, ", (removed)");
9643 }
9644
9645 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
9646 if (json_paths)
9647 json_object_boolean_true_add(json_path, "stale");
9648 else
9649 vty_out(vty, ", (stale)");
9650 }
9651
9652 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
9653 if (json_paths) {
9654 char buf[BUFSIZ] = {0};
9655
9656 json_object_int_add(json_path, "aggregatorAs",
9657 attr->aggregator_as);
9658 json_object_string_add(json_path, "aggregatorId",
9659 inet_ntop(AF_INET,
9660 &attr->aggregator_addr,
9661 buf, sizeof(buf)));
9662 if (attr->aggregator_as == BGP_AS_ZERO)
9663 json_object_boolean_true_add(
9664 json_path, "aggregatorAsMalformed");
9665 else
9666 json_object_boolean_false_add(
9667 json_path, "aggregatorAsMalformed");
9668 } else {
9669 if (attr->aggregator_as == BGP_AS_ZERO)
9670 vty_out(vty,
9671 ", (aggregated by %u(malformed) %pI4)",
9672 attr->aggregator_as,
9673 &attr->aggregator_addr);
9674 else
9675 vty_out(vty, ", (aggregated by %u %pI4)",
9676 attr->aggregator_as,
9677 &attr->aggregator_addr);
9678 }
9679 }
9680
9681 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
9682 PEER_FLAG_REFLECTOR_CLIENT)) {
9683 if (json_paths)
9684 json_object_boolean_true_add(json_path,
9685 "rxedFromRrClient");
9686 else
9687 vty_out(vty, ", (Received from a RR-client)");
9688 }
9689
9690 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
9691 PEER_FLAG_RSERVER_CLIENT)) {
9692 if (json_paths)
9693 json_object_boolean_true_add(json_path,
9694 "rxedFromRsClient");
9695 else
9696 vty_out(vty, ", (Received from a RS-client)");
9697 }
9698
9699 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
9700 if (json_paths)
9701 json_object_boolean_true_add(json_path,
9702 "dampeningHistoryEntry");
9703 else
9704 vty_out(vty, ", (history entry)");
9705 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
9706 if (json_paths)
9707 json_object_boolean_true_add(json_path,
9708 "dampeningSuppressed");
9709 else
9710 vty_out(vty, ", (suppressed due to dampening)");
9711 }
9712
9713 if (!json_paths)
9714 vty_out(vty, "\n");
9715
9716 /* Line2 display Next-hop, Neighbor, Router-id */
9717 /* Display the nexthop */
9718 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
9719
9720 if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET
9721 || bn_p->family == AF_EVPN)
9722 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
9723 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9724 char buf[BUFSIZ] = {0};
9725
9726 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9727 || safi == SAFI_EVPN) {
9728 if (json_paths) {
9729 json_object_string_add(
9730 json_nexthop_global, "ip",
9731 inet_ntop(AF_INET,
9732 &attr->mp_nexthop_global_in,
9733 buf, sizeof(buf)));
9734
9735 if (path->peer->hostname)
9736 json_object_string_add(
9737 json_nexthop_global, "hostname",
9738 path->peer->hostname);
9739 } else {
9740 if (nexthop_hostname)
9741 vty_out(vty, " %pI4(%s)",
9742 &attr->mp_nexthop_global_in,
9743 nexthop_hostname);
9744 else
9745 vty_out(vty, " %pI4",
9746 &attr->mp_nexthop_global_in);
9747 }
9748 } else {
9749 if (json_paths) {
9750 json_object_string_add(
9751 json_nexthop_global, "ip",
9752 inet_ntop(AF_INET, &attr->nexthop, buf,
9753 sizeof(buf)));
9754
9755 if (path->peer->hostname)
9756 json_object_string_add(
9757 json_nexthop_global, "hostname",
9758 path->peer->hostname);
9759 } else {
9760 if (nexthop_hostname)
9761 vty_out(vty, " %pI4(%s)",
9762 &attr->nexthop,
9763 nexthop_hostname);
9764 else
9765 vty_out(vty, " %pI4",
9766 &attr->nexthop);
9767 }
9768 }
9769
9770 if (json_paths)
9771 json_object_string_add(json_nexthop_global, "afi",
9772 "ipv4");
9773 } else {
9774 if (json_paths) {
9775 json_object_string_add(
9776 json_nexthop_global, "ip",
9777 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
9778 buf, INET6_ADDRSTRLEN));
9779
9780 if (path->peer->hostname)
9781 json_object_string_add(json_nexthop_global,
9782 "hostname",
9783 path->peer->hostname);
9784
9785 json_object_string_add(json_nexthop_global, "afi",
9786 "ipv6");
9787 json_object_string_add(json_nexthop_global, "scope",
9788 "global");
9789 } else {
9790 if (nexthop_hostname)
9791 vty_out(vty, " %pI6(%s)",
9792 &attr->mp_nexthop_global,
9793 nexthop_hostname);
9794 else
9795 vty_out(vty, " %pI6",
9796 &attr->mp_nexthop_global);
9797 }
9798 }
9799
9800 /* Display the IGP cost or 'inaccessible' */
9801 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
9802 if (json_paths)
9803 json_object_boolean_false_add(json_nexthop_global,
9804 "accessible");
9805 else
9806 vty_out(vty, " (inaccessible)");
9807 } else {
9808 if (path->extra && path->extra->igpmetric) {
9809 if (json_paths)
9810 json_object_int_add(json_nexthop_global,
9811 "metric",
9812 path->extra->igpmetric);
9813 else
9814 vty_out(vty, " (metric %u)",
9815 path->extra->igpmetric);
9816 }
9817
9818 /* IGP cost is 0, display this only for json */
9819 else {
9820 if (json_paths)
9821 json_object_int_add(json_nexthop_global,
9822 "metric", 0);
9823 }
9824
9825 if (json_paths)
9826 json_object_boolean_true_add(json_nexthop_global,
9827 "accessible");
9828 }
9829
9830 /* Display peer "from" output */
9831 /* This path was originated locally */
9832 if (path->peer == bgp->peer_self) {
9833
9834 if (safi == SAFI_EVPN
9835 || (bn_p->family == AF_INET
9836 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9837 if (json_paths)
9838 json_object_string_add(json_peer, "peerId",
9839 "0.0.0.0");
9840 else
9841 vty_out(vty, " from 0.0.0.0 ");
9842 } else {
9843 if (json_paths)
9844 json_object_string_add(json_peer, "peerId",
9845 "::");
9846 else
9847 vty_out(vty, " from :: ");
9848 }
9849
9850 if (json_paths) {
9851 char buf[BUFSIZ] = {0};
9852
9853 json_object_string_add(json_peer, "routerId",
9854 inet_ntop(AF_INET,
9855 &bgp->router_id, buf,
9856 sizeof(buf)));
9857 } else {
9858 vty_out(vty, "(%pI4)", &bgp->router_id);
9859 }
9860 }
9861
9862 /* We RXed this path from one of our peers */
9863 else {
9864
9865 if (json_paths) {
9866 json_object_string_add(json_peer, "peerId",
9867 sockunion2str(&path->peer->su,
9868 buf,
9869 SU_ADDRSTRLEN));
9870 json_object_string_add(json_peer, "routerId",
9871 inet_ntop(AF_INET,
9872 &path->peer->remote_id,
9873 buf1, sizeof(buf1)));
9874
9875 if (path->peer->hostname)
9876 json_object_string_add(json_peer, "hostname",
9877 path->peer->hostname);
9878
9879 if (path->peer->domainname)
9880 json_object_string_add(json_peer, "domainname",
9881 path->peer->domainname);
9882
9883 if (path->peer->conf_if)
9884 json_object_string_add(json_peer, "interface",
9885 path->peer->conf_if);
9886 } else {
9887 if (path->peer->conf_if) {
9888 if (path->peer->hostname
9889 && CHECK_FLAG(path->peer->bgp->flags,
9890 BGP_FLAG_SHOW_HOSTNAME))
9891 vty_out(vty, " from %s(%s)",
9892 path->peer->hostname,
9893 path->peer->conf_if);
9894 else
9895 vty_out(vty, " from %s",
9896 path->peer->conf_if);
9897 } else {
9898 if (path->peer->hostname
9899 && CHECK_FLAG(path->peer->bgp->flags,
9900 BGP_FLAG_SHOW_HOSTNAME))
9901 vty_out(vty, " from %s(%s)",
9902 path->peer->hostname,
9903 path->peer->host);
9904 else
9905 vty_out(vty, " from %s",
9906 sockunion2str(&path->peer->su,
9907 buf,
9908 SU_ADDRSTRLEN));
9909 }
9910
9911 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
9912 vty_out(vty, " (%pI4)", &attr->originator_id);
9913 else
9914 vty_out(vty, " (%s)",
9915 inet_ntop(AF_INET,
9916 &path->peer->remote_id, buf1,
9917 sizeof(buf1)));
9918 }
9919 }
9920
9921 /*
9922 * Note when vrfid of nexthop is different from that of prefix
9923 */
9924 if (path->extra && path->extra->bgp_orig) {
9925 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9926
9927 if (json_paths) {
9928 const char *vn;
9929
9930 if (path->extra->bgp_orig->inst_type
9931 == BGP_INSTANCE_TYPE_DEFAULT)
9932 vn = VRF_DEFAULT_NAME;
9933 else
9934 vn = path->extra->bgp_orig->name;
9935
9936 json_object_string_add(json_path, "nhVrfName", vn);
9937
9938 if (nexthop_vrfid == VRF_UNKNOWN) {
9939 json_object_int_add(json_path, "nhVrfId", -1);
9940 } else {
9941 json_object_int_add(json_path, "nhVrfId",
9942 (int)nexthop_vrfid);
9943 }
9944 } else {
9945 if (nexthop_vrfid == VRF_UNKNOWN)
9946 vty_out(vty, " vrf ?");
9947 else {
9948 struct vrf *vrf;
9949
9950 vrf = vrf_lookup_by_id(nexthop_vrfid);
9951 vty_out(vty, " vrf %s(%u)",
9952 VRF_LOGNAME(vrf), nexthop_vrfid);
9953 }
9954 }
9955 }
9956
9957 if (nexthop_self) {
9958 if (json_paths) {
9959 json_object_boolean_true_add(json_path,
9960 "announceNexthopSelf");
9961 } else {
9962 vty_out(vty, " announce-nh-self");
9963 }
9964 }
9965
9966 if (!json_paths)
9967 vty_out(vty, "\n");
9968
9969 /* display the link-local nexthop */
9970 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9971 if (json_paths) {
9972 json_nexthop_ll = json_object_new_object();
9973 json_object_string_add(
9974 json_nexthop_ll, "ip",
9975 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
9976 buf, INET6_ADDRSTRLEN));
9977
9978 if (path->peer->hostname)
9979 json_object_string_add(json_nexthop_ll,
9980 "hostname",
9981 path->peer->hostname);
9982
9983 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
9984 json_object_string_add(json_nexthop_ll, "scope",
9985 "link-local");
9986
9987 json_object_boolean_true_add(json_nexthop_ll,
9988 "accessible");
9989
9990 if (!attr->mp_nexthop_prefer_global)
9991 json_object_boolean_true_add(json_nexthop_ll,
9992 "used");
9993 else
9994 json_object_boolean_true_add(
9995 json_nexthop_global, "used");
9996 } else {
9997 vty_out(vty, " (%s) %s\n",
9998 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
9999 buf, INET6_ADDRSTRLEN),
10000 attr->mp_nexthop_prefer_global
10001 ? "(prefer-global)"
10002 : "(used)");
10003 }
10004 }
10005 /* If we do not have a link-local nexthop then we must flag the
10006 global as "used" */
10007 else {
10008 if (json_paths)
10009 json_object_boolean_true_add(json_nexthop_global,
10010 "used");
10011 }
10012
10013 if (safi == SAFI_EVPN &&
10014 bgp_evpn_is_esi_valid(&attr->esi)) {
10015 route_vty_out_detail_es_info(vty, path, attr, json_path);
10016 }
10017
10018 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10019 * Int/Ext/Local, Atomic, best */
10020 if (json_paths)
10021 json_object_string_add(json_path, "origin",
10022 bgp_origin_long_str[attr->origin]);
10023 else
10024 vty_out(vty, " Origin %s",
10025 bgp_origin_long_str[attr->origin]);
10026
10027 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10028 if (json_paths)
10029 json_object_int_add(json_path, "metric", attr->med);
10030 else
10031 vty_out(vty, ", metric %u", attr->med);
10032 }
10033
10034 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10035 if (json_paths)
10036 json_object_int_add(json_path, "locPrf",
10037 attr->local_pref);
10038 else
10039 vty_out(vty, ", localpref %u", attr->local_pref);
10040 }
10041
10042 if (attr->weight != 0) {
10043 if (json_paths)
10044 json_object_int_add(json_path, "weight", attr->weight);
10045 else
10046 vty_out(vty, ", weight %u", attr->weight);
10047 }
10048
10049 if (attr->tag != 0) {
10050 if (json_paths)
10051 json_object_int_add(json_path, "tag", attr->tag);
10052 else
10053 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10054 }
10055
10056 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10057 if (json_paths)
10058 json_object_boolean_false_add(json_path, "valid");
10059 else
10060 vty_out(vty, ", invalid");
10061 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10062 if (json_paths)
10063 json_object_boolean_true_add(json_path, "valid");
10064 else
10065 vty_out(vty, ", valid");
10066 }
10067
10068 if (path->peer != bgp->peer_self) {
10069 if (path->peer->as == path->peer->local_as) {
10070 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10071 if (json_paths)
10072 json_object_string_add(
10073 json_peer, "type",
10074 "confed-internal");
10075 else
10076 vty_out(vty, ", confed-internal");
10077 } else {
10078 if (json_paths)
10079 json_object_string_add(
10080 json_peer, "type", "internal");
10081 else
10082 vty_out(vty, ", internal");
10083 }
10084 } else {
10085 if (bgp_confederation_peers_check(bgp,
10086 path->peer->as)) {
10087 if (json_paths)
10088 json_object_string_add(
10089 json_peer, "type",
10090 "confed-external");
10091 else
10092 vty_out(vty, ", confed-external");
10093 } else {
10094 if (json_paths)
10095 json_object_string_add(
10096 json_peer, "type", "external");
10097 else
10098 vty_out(vty, ", external");
10099 }
10100 }
10101 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10102 if (json_paths) {
10103 json_object_boolean_true_add(json_path, "aggregated");
10104 json_object_boolean_true_add(json_path, "local");
10105 } else {
10106 vty_out(vty, ", aggregated, local");
10107 }
10108 } else if (path->type != ZEBRA_ROUTE_BGP) {
10109 if (json_paths)
10110 json_object_boolean_true_add(json_path, "sourced");
10111 else
10112 vty_out(vty, ", sourced");
10113 } else {
10114 if (json_paths) {
10115 json_object_boolean_true_add(json_path, "sourced");
10116 json_object_boolean_true_add(json_path, "local");
10117 } else {
10118 vty_out(vty, ", sourced, local");
10119 }
10120 }
10121
10122 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10123 if (json_paths)
10124 json_object_boolean_true_add(json_path,
10125 "atomicAggregate");
10126 else
10127 vty_out(vty, ", atomic-aggregate");
10128 }
10129
10130 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10131 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10132 && bgp_path_info_mpath_count(path))) {
10133 if (json_paths)
10134 json_object_boolean_true_add(json_path, "multipath");
10135 else
10136 vty_out(vty, ", multipath");
10137 }
10138
10139 // Mark the bestpath(s)
10140 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10141 first_as = aspath_get_first_as(attr->aspath);
10142
10143 if (json_paths) {
10144 if (!json_bestpath)
10145 json_bestpath = json_object_new_object();
10146 json_object_int_add(json_bestpath, "bestpathFromAs",
10147 first_as);
10148 } else {
10149 if (first_as)
10150 vty_out(vty, ", bestpath-from-AS %u", first_as);
10151 else
10152 vty_out(vty, ", bestpath-from-AS Local");
10153 }
10154 }
10155
10156 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10157 if (json_paths) {
10158 if (!json_bestpath)
10159 json_bestpath = json_object_new_object();
10160 json_object_boolean_true_add(json_bestpath, "overall");
10161 json_object_string_add(
10162 json_bestpath, "selectionReason",
10163 bgp_path_selection_reason2str(bn->reason));
10164 } else {
10165 vty_out(vty, ", best");
10166 vty_out(vty, " (%s)",
10167 bgp_path_selection_reason2str(bn->reason));
10168 }
10169 }
10170
10171 if (json_bestpath)
10172 json_object_object_add(json_path, "bestpath", json_bestpath);
10173
10174 if (!json_paths)
10175 vty_out(vty, "\n");
10176
10177 /* Line 4 display Community */
10178 if (attr->community) {
10179 if (json_paths) {
10180 if (!attr->community->json)
10181 community_str(attr->community, true);
10182 json_object_lock(attr->community->json);
10183 json_object_object_add(json_path, "community",
10184 attr->community->json);
10185 } else {
10186 vty_out(vty, " Community: %s\n",
10187 attr->community->str);
10188 }
10189 }
10190
10191 /* Line 5 display Extended-community */
10192 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10193 if (json_paths) {
10194 json_ext_community = json_object_new_object();
10195 json_object_string_add(json_ext_community, "string",
10196 attr->ecommunity->str);
10197 json_object_object_add(json_path, "extendedCommunity",
10198 json_ext_community);
10199 } else {
10200 vty_out(vty, " Extended Community: %s\n",
10201 attr->ecommunity->str);
10202 }
10203 }
10204
10205 /* Line 6 display Large community */
10206 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10207 if (json_paths) {
10208 if (!attr->lcommunity->json)
10209 lcommunity_str(attr->lcommunity, true);
10210 json_object_lock(attr->lcommunity->json);
10211 json_object_object_add(json_path, "largeCommunity",
10212 attr->lcommunity->json);
10213 } else {
10214 vty_out(vty, " Large Community: %s\n",
10215 attr->lcommunity->str);
10216 }
10217 }
10218
10219 /* Line 7 display Originator, Cluster-id */
10220 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10221 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10222 char buf[BUFSIZ] = {0};
10223
10224 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10225 if (json_paths)
10226 json_object_string_add(
10227 json_path, "originatorId",
10228 inet_ntop(AF_INET, &attr->originator_id,
10229 buf, sizeof(buf)));
10230 else
10231 vty_out(vty, " Originator: %pI4",
10232 &attr->originator_id);
10233 }
10234
10235 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10236 struct cluster_list *cluster =
10237 bgp_attr_get_cluster(attr);
10238 int i;
10239
10240 if (json_paths) {
10241 json_cluster_list = json_object_new_object();
10242 json_cluster_list_list =
10243 json_object_new_array();
10244
10245 for (i = 0; i < cluster->length / 4; i++) {
10246 json_string = json_object_new_string(
10247 inet_ntop(AF_INET,
10248 &cluster->list[i],
10249 buf, sizeof(buf)));
10250 json_object_array_add(
10251 json_cluster_list_list,
10252 json_string);
10253 }
10254
10255 /*
10256 * struct cluster_list does not have
10257 * "str" variable like aspath and community
10258 * do. Add this someday if someone asks
10259 * for it.
10260 * json_object_string_add(json_cluster_list,
10261 * "string", cluster->str);
10262 */
10263 json_object_object_add(json_cluster_list,
10264 "list",
10265 json_cluster_list_list);
10266 json_object_object_add(json_path, "clusterList",
10267 json_cluster_list);
10268 } else {
10269 vty_out(vty, ", Cluster list: ");
10270
10271 for (i = 0; i < cluster->length / 4; i++) {
10272 vty_out(vty, "%pI4 ",
10273 &cluster->list[i]);
10274 }
10275 }
10276 }
10277
10278 if (!json_paths)
10279 vty_out(vty, "\n");
10280 }
10281
10282 if (path->extra && path->extra->damp_info)
10283 bgp_damp_info_vty(vty, bgp, path, afi, safi, json_path);
10284
10285 /* Remote Label */
10286 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10287 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10288 mpls_label_t label = label_pton(&path->extra->label[0]);
10289
10290 if (json_paths)
10291 json_object_int_add(json_path, "remoteLabel", label);
10292 else
10293 vty_out(vty, " Remote label: %d\n", label);
10294 }
10295
10296 /* Remote SID */
10297 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10298 inet_ntop(AF_INET6, &path->extra->sid, buf, sizeof(buf));
10299 if (json_paths)
10300 json_object_string_add(json_path, "remoteSid", buf);
10301 else
10302 vty_out(vty, " Remote SID: %s\n", buf);
10303 }
10304
10305 /* Label Index */
10306 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10307 if (json_paths)
10308 json_object_int_add(json_path, "labelIndex",
10309 attr->label_index);
10310 else
10311 vty_out(vty, " Label Index: %d\n",
10312 attr->label_index);
10313 }
10314
10315 /* Line 8 display Addpath IDs */
10316 if (path->addpath_rx_id
10317 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
10318 if (json_paths) {
10319 json_object_int_add(json_path, "addpathRxId",
10320 path->addpath_rx_id);
10321
10322 /* Keep backwards compatibility with the old API
10323 * by putting TX All's ID in the old field
10324 */
10325 json_object_int_add(
10326 json_path, "addpathTxId",
10327 path->tx_addpath
10328 .addpath_tx_id[BGP_ADDPATH_ALL]);
10329
10330 /* ... but create a specific field for each
10331 * strategy
10332 */
10333 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10334 json_object_int_add(
10335 json_path,
10336 bgp_addpath_names(i)->id_json_name,
10337 path->tx_addpath.addpath_tx_id[i]);
10338 }
10339 } else {
10340 vty_out(vty, " AddPath ID: RX %u, ",
10341 path->addpath_rx_id);
10342
10343 route_vty_out_tx_ids(vty, &path->tx_addpath);
10344 }
10345 }
10346
10347 /* If we used addpath to TX a non-bestpath we need to display
10348 * "Advertised to" on a path-by-path basis
10349 */
10350 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
10351 first = 1;
10352
10353 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
10354 addpath_capable =
10355 bgp_addpath_encode_tx(peer, afi, safi);
10356 has_adj = bgp_adj_out_lookup(
10357 peer, path->net,
10358 bgp_addpath_id_for_peer(peer, afi, safi,
10359 &path->tx_addpath));
10360
10361 if ((addpath_capable && has_adj)
10362 || (!addpath_capable && has_adj
10363 && CHECK_FLAG(path->flags,
10364 BGP_PATH_SELECTED))) {
10365 if (json_path && !json_adv_to)
10366 json_adv_to = json_object_new_object();
10367
10368 route_vty_out_advertised_to(
10369 vty, peer, &first,
10370 " Advertised to:", json_adv_to);
10371 }
10372 }
10373
10374 if (json_path) {
10375 if (json_adv_to) {
10376 json_object_object_add(
10377 json_path, "advertisedTo", json_adv_to);
10378 }
10379 } else {
10380 if (!first) {
10381 vty_out(vty, "\n");
10382 }
10383 }
10384 }
10385
10386 /* Line 9 display Uptime */
10387 tbuf = time(NULL) - (bgp_clock() - path->uptime);
10388 if (json_paths) {
10389 json_last_update = json_object_new_object();
10390 json_object_int_add(json_last_update, "epoch", tbuf);
10391 json_object_string_add(json_last_update, "string",
10392 ctime(&tbuf));
10393 json_object_object_add(json_path, "lastUpdate",
10394 json_last_update);
10395 } else
10396 vty_out(vty, " Last update: %s", ctime(&tbuf));
10397
10398 /* Line 10 display PMSI tunnel attribute, if present */
10399 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
10400 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
10401 bgp_attr_get_pmsi_tnl_type(attr),
10402 PMSI_TNLTYPE_STR_DEFAULT);
10403
10404 if (json_paths) {
10405 json_pmsi = json_object_new_object();
10406 json_object_string_add(json_pmsi, "tunnelType", str);
10407 json_object_int_add(json_pmsi, "label",
10408 label2vni(&attr->label));
10409 json_object_object_add(json_path, "pmsi", json_pmsi);
10410 } else
10411 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
10412 str, label2vni(&attr->label));
10413 }
10414
10415 /* Output some debug about internal state of the dest flags */
10416 if (json_paths) {
10417 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
10418 json_object_boolean_true_add(json_path, "processScheduled");
10419 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
10420 json_object_boolean_true_add(json_path, "userCleared");
10421 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
10422 json_object_boolean_true_add(json_path, "labelChanged");
10423 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
10424 json_object_boolean_true_add(json_path, "registeredForLabel");
10425 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
10426 json_object_boolean_true_add(json_path, "selectDefered");
10427 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
10428 json_object_boolean_true_add(json_path, "fibInstalled");
10429 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
10430 json_object_boolean_true_add(json_path, "fibPending");
10431 }
10432
10433 /* We've constructed the json object for this path, add it to the json
10434 * array of paths
10435 */
10436 if (json_paths) {
10437 if (json_nexthop_global || json_nexthop_ll) {
10438 json_nexthops = json_object_new_array();
10439
10440 if (json_nexthop_global)
10441 json_object_array_add(json_nexthops,
10442 json_nexthop_global);
10443
10444 if (json_nexthop_ll)
10445 json_object_array_add(json_nexthops,
10446 json_nexthop_ll);
10447
10448 json_object_object_add(json_path, "nexthops",
10449 json_nexthops);
10450 }
10451
10452 json_object_object_add(json_path, "peer", json_peer);
10453 json_object_array_add(json_paths, json_path);
10454 }
10455 }
10456
10457 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
10458 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
10459 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
10460
10461 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
10462 const char *prefix_list_str, afi_t afi,
10463 safi_t safi, enum bgp_show_type type);
10464 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
10465 const char *filter, afi_t afi, safi_t safi,
10466 enum bgp_show_type type);
10467 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
10468 const char *rmap_str, afi_t afi, safi_t safi,
10469 enum bgp_show_type type);
10470 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
10471 const char *com, int exact, afi_t afi,
10472 safi_t safi);
10473 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
10474 const char *prefix, afi_t afi, safi_t safi,
10475 enum bgp_show_type type);
10476 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
10477 afi_t afi, safi_t safi, enum bgp_show_type type,
10478 bool use_json);
10479 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
10480 const char *comstr, int exact, afi_t afi,
10481 safi_t safi, uint8_t show_flags);
10482
10483
10484 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
10485 struct bgp_table *table, enum bgp_show_type type,
10486 void *output_arg, char *rd, int is_last,
10487 unsigned long *output_cum, unsigned long *total_cum,
10488 unsigned long *json_header_depth, uint8_t show_flags)
10489 {
10490 struct bgp_path_info *pi;
10491 struct bgp_dest *dest;
10492 int header = 1;
10493 int display;
10494 unsigned long output_count = 0;
10495 unsigned long total_count = 0;
10496 struct prefix *p;
10497 json_object *json_paths = NULL;
10498 int first = 1;
10499 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10500 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
10501 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
10502
10503 if (output_cum && *output_cum != 0)
10504 header = 0;
10505
10506 if (use_json && !*json_header_depth) {
10507 if (all)
10508 *json_header_depth = 1;
10509 else {
10510 vty_out(vty, "{\n");
10511 *json_header_depth = 2;
10512 }
10513
10514 vty_out(vty,
10515 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
10516 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
10517 " \"localAS\": %u,\n \"routes\": { ",
10518 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
10519 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
10520 ? VRF_DEFAULT_NAME
10521 : bgp->name,
10522 table->version, &bgp->router_id,
10523 bgp->default_local_pref, bgp->as);
10524 if (rd) {
10525 vty_out(vty, " \"routeDistinguishers\" : {");
10526 ++*json_header_depth;
10527 }
10528 }
10529
10530 if (use_json && rd) {
10531 vty_out(vty, " \"%s\" : { ", rd);
10532 }
10533
10534 /* Start processing of routes. */
10535 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
10536 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10537
10538 pi = bgp_dest_get_bgp_path_info(dest);
10539 if (pi == NULL)
10540 continue;
10541
10542 display = 0;
10543 if (use_json)
10544 json_paths = json_object_new_array();
10545 else
10546 json_paths = NULL;
10547
10548 for (; pi; pi = pi->next) {
10549 total_count++;
10550 if (type == bgp_show_type_flap_statistics
10551 || type == bgp_show_type_flap_neighbor
10552 || type == bgp_show_type_dampend_paths
10553 || type == bgp_show_type_damp_neighbor) {
10554 if (!(pi->extra && pi->extra->damp_info))
10555 continue;
10556 }
10557 if (type == bgp_show_type_regexp) {
10558 regex_t *regex = output_arg;
10559
10560 if (bgp_regexec(regex, pi->attr->aspath)
10561 == REG_NOMATCH)
10562 continue;
10563 }
10564 if (type == bgp_show_type_prefix_list) {
10565 struct prefix_list *plist = output_arg;
10566
10567 if (prefix_list_apply(plist, dest_p)
10568 != PREFIX_PERMIT)
10569 continue;
10570 }
10571 if (type == bgp_show_type_filter_list) {
10572 struct as_list *as_list = output_arg;
10573
10574 if (as_list_apply(as_list, pi->attr->aspath)
10575 != AS_FILTER_PERMIT)
10576 continue;
10577 }
10578 if (type == bgp_show_type_route_map) {
10579 struct route_map *rmap = output_arg;
10580 struct bgp_path_info path;
10581 struct attr dummy_attr;
10582 route_map_result_t ret;
10583
10584 dummy_attr = *pi->attr;
10585
10586 path.peer = pi->peer;
10587 path.attr = &dummy_attr;
10588
10589 ret = route_map_apply(rmap, dest_p, &path);
10590 if (ret == RMAP_DENYMATCH)
10591 continue;
10592 }
10593 if (type == bgp_show_type_neighbor
10594 || type == bgp_show_type_flap_neighbor
10595 || type == bgp_show_type_damp_neighbor) {
10596 union sockunion *su = output_arg;
10597
10598 if (pi->peer == NULL
10599 || pi->peer->su_remote == NULL
10600 || !sockunion_same(pi->peer->su_remote, su))
10601 continue;
10602 }
10603 if (type == bgp_show_type_cidr_only) {
10604 uint32_t destination;
10605
10606 destination = ntohl(dest_p->u.prefix4.s_addr);
10607 if (IN_CLASSC(destination)
10608 && dest_p->prefixlen == 24)
10609 continue;
10610 if (IN_CLASSB(destination)
10611 && dest_p->prefixlen == 16)
10612 continue;
10613 if (IN_CLASSA(destination)
10614 && dest_p->prefixlen == 8)
10615 continue;
10616 }
10617 if (type == bgp_show_type_prefix_longer) {
10618 p = output_arg;
10619 if (!prefix_match(p, dest_p))
10620 continue;
10621 }
10622 if (type == bgp_show_type_community_all) {
10623 if (!pi->attr->community)
10624 continue;
10625 }
10626 if (type == bgp_show_type_community) {
10627 struct community *com = output_arg;
10628
10629 if (!pi->attr->community
10630 || !community_match(pi->attr->community,
10631 com))
10632 continue;
10633 }
10634 if (type == bgp_show_type_community_exact) {
10635 struct community *com = output_arg;
10636
10637 if (!pi->attr->community
10638 || !community_cmp(pi->attr->community, com))
10639 continue;
10640 }
10641 if (type == bgp_show_type_community_list) {
10642 struct community_list *list = output_arg;
10643
10644 if (!community_list_match(pi->attr->community,
10645 list))
10646 continue;
10647 }
10648 if (type == bgp_show_type_community_list_exact) {
10649 struct community_list *list = output_arg;
10650
10651 if (!community_list_exact_match(
10652 pi->attr->community, list))
10653 continue;
10654 }
10655 if (type == bgp_show_type_lcommunity) {
10656 struct lcommunity *lcom = output_arg;
10657
10658 if (!pi->attr->lcommunity
10659 || !lcommunity_match(pi->attr->lcommunity,
10660 lcom))
10661 continue;
10662 }
10663
10664 if (type == bgp_show_type_lcommunity_exact) {
10665 struct lcommunity *lcom = output_arg;
10666
10667 if (!pi->attr->lcommunity
10668 || !lcommunity_cmp(pi->attr->lcommunity,
10669 lcom))
10670 continue;
10671 }
10672 if (type == bgp_show_type_lcommunity_list) {
10673 struct community_list *list = output_arg;
10674
10675 if (!lcommunity_list_match(pi->attr->lcommunity,
10676 list))
10677 continue;
10678 }
10679 if (type
10680 == bgp_show_type_lcommunity_list_exact) {
10681 struct community_list *list = output_arg;
10682
10683 if (!lcommunity_list_exact_match(
10684 pi->attr->lcommunity, list))
10685 continue;
10686 }
10687 if (type == bgp_show_type_lcommunity_all) {
10688 if (!pi->attr->lcommunity)
10689 continue;
10690 }
10691 if (type == bgp_show_type_dampend_paths
10692 || type == bgp_show_type_damp_neighbor) {
10693 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
10694 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
10695 continue;
10696 }
10697
10698 if (!use_json && header) {
10699 vty_out(vty,
10700 "BGP table version is %" PRIu64
10701 ", local router ID is %pI4, vrf id ",
10702 table->version, &bgp->router_id);
10703 if (bgp->vrf_id == VRF_UNKNOWN)
10704 vty_out(vty, "%s", VRFID_NONE_STR);
10705 else
10706 vty_out(vty, "%u", bgp->vrf_id);
10707 vty_out(vty, "\n");
10708 vty_out(vty, "Default local pref %u, ",
10709 bgp->default_local_pref);
10710 vty_out(vty, "local AS %u\n", bgp->as);
10711 vty_out(vty, BGP_SHOW_SCODE_HEADER);
10712 vty_out(vty, BGP_SHOW_NCODE_HEADER);
10713 vty_out(vty, BGP_SHOW_OCODE_HEADER);
10714 if (type == bgp_show_type_dampend_paths
10715 || type == bgp_show_type_damp_neighbor)
10716 vty_out(vty, BGP_SHOW_DAMP_HEADER);
10717 else if (type == bgp_show_type_flap_statistics
10718 || type == bgp_show_type_flap_neighbor)
10719 vty_out(vty, BGP_SHOW_FLAP_HEADER);
10720 else
10721 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
10722 : BGP_SHOW_HEADER));
10723 header = 0;
10724 }
10725 if (rd != NULL && !display && !output_count) {
10726 if (!use_json)
10727 vty_out(vty,
10728 "Route Distinguisher: %s\n",
10729 rd);
10730 }
10731 if (type == bgp_show_type_dampend_paths
10732 || type == bgp_show_type_damp_neighbor)
10733 damp_route_vty_out(vty, dest_p, pi, display,
10734 AFI_IP, safi, use_json,
10735 json_paths);
10736 else if (type == bgp_show_type_flap_statistics
10737 || type == bgp_show_type_flap_neighbor)
10738 flap_route_vty_out(vty, dest_p, pi, display,
10739 AFI_IP, safi, use_json,
10740 json_paths);
10741 else
10742 route_vty_out(vty, dest_p, pi, display, safi,
10743 json_paths, wide);
10744 display++;
10745 }
10746
10747 if (display) {
10748 output_count++;
10749 if (!use_json)
10750 continue;
10751
10752 /* encode prefix */
10753 if (dest_p->family == AF_FLOWSPEC) {
10754 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
10755
10756
10757 bgp_fs_nlri_get_string(
10758 (unsigned char *)
10759 dest_p->u.prefix_flowspec.ptr,
10760 dest_p->u.prefix_flowspec.prefixlen,
10761 retstr, NLRI_STRING_FORMAT_MIN, NULL,
10762 family2afi(dest_p->u
10763 .prefix_flowspec.family));
10764 if (first)
10765 vty_out(vty, "\"%s/%d\": ", retstr,
10766 dest_p->u.prefix_flowspec
10767 .prefixlen);
10768 else
10769 vty_out(vty, ",\"%s/%d\": ", retstr,
10770 dest_p->u.prefix_flowspec
10771 .prefixlen);
10772 } else {
10773 if (first)
10774 vty_out(vty, "\"%pFX\": ", dest_p);
10775 else
10776 vty_out(vty, ",\"%pFX\": ", dest_p);
10777 }
10778 vty_out(vty, "%s",
10779 json_object_to_json_string_ext(
10780 json_paths, JSON_C_TO_STRING_PRETTY));
10781 json_object_free(json_paths);
10782 json_paths = NULL;
10783 first = 0;
10784 } else
10785 json_object_free(json_paths);
10786 }
10787
10788 if (output_cum) {
10789 output_count += *output_cum;
10790 *output_cum = output_count;
10791 }
10792 if (total_cum) {
10793 total_count += *total_cum;
10794 *total_cum = total_count;
10795 }
10796 if (use_json) {
10797 if (rd) {
10798 vty_out(vty, " }%s ", (is_last ? "" : ","));
10799 }
10800 if (is_last) {
10801 unsigned long i;
10802 for (i = 0; i < *json_header_depth; ++i)
10803 vty_out(vty, " } ");
10804 if (!all)
10805 vty_out(vty, "\n");
10806 }
10807 } else {
10808 if (is_last) {
10809 /* No route is displayed */
10810 if (output_count == 0) {
10811 if (type == bgp_show_type_normal)
10812 vty_out(vty,
10813 "No BGP prefixes displayed, %ld exist\n",
10814 total_count);
10815 } else
10816 vty_out(vty,
10817 "\nDisplayed %ld routes and %ld total paths\n",
10818 output_count, total_count);
10819 }
10820 }
10821
10822 return CMD_SUCCESS;
10823 }
10824
10825 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
10826 struct bgp_table *table, struct prefix_rd *prd_match,
10827 enum bgp_show_type type, void *output_arg, bool use_json)
10828 {
10829 struct bgp_dest *dest, *next;
10830 unsigned long output_cum = 0;
10831 unsigned long total_cum = 0;
10832 unsigned long json_header_depth = 0;
10833 struct bgp_table *itable;
10834 bool show_msg;
10835 uint8_t show_flags = 0;
10836
10837 show_msg = (!use_json && type == bgp_show_type_normal);
10838
10839 if (use_json)
10840 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10841
10842 for (dest = bgp_table_top(table); dest; dest = next) {
10843 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10844
10845 next = bgp_route_next(dest);
10846 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
10847 continue;
10848
10849 itable = bgp_dest_get_bgp_table_info(dest);
10850 if (itable != NULL) {
10851 struct prefix_rd prd;
10852 char rd[RD_ADDRSTRLEN];
10853
10854 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
10855 prefix_rd2str(&prd, rd, sizeof(rd));
10856 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
10857 rd, next == NULL, &output_cum,
10858 &total_cum, &json_header_depth,
10859 show_flags);
10860 if (next == NULL)
10861 show_msg = false;
10862 }
10863 }
10864 if (show_msg) {
10865 if (output_cum == 0)
10866 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
10867 total_cum);
10868 else
10869 vty_out(vty,
10870 "\nDisplayed %ld routes and %ld total paths\n",
10871 output_cum, total_cum);
10872 }
10873 return CMD_SUCCESS;
10874 }
10875 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
10876 enum bgp_show_type type, void *output_arg,
10877 uint8_t show_flags)
10878 {
10879 struct bgp_table *table;
10880 unsigned long json_header_depth = 0;
10881 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10882
10883 if (bgp == NULL) {
10884 bgp = bgp_get_default();
10885 }
10886
10887 if (bgp == NULL) {
10888 if (!use_json)
10889 vty_out(vty, "No BGP process is configured\n");
10890 else
10891 vty_out(vty, "{}\n");
10892 return CMD_WARNING;
10893 }
10894
10895 table = bgp->rib[afi][safi];
10896 /* use MPLS and ENCAP specific shows until they are merged */
10897 if (safi == SAFI_MPLS_VPN) {
10898 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
10899 output_arg, use_json);
10900 }
10901
10902 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
10903 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
10904 output_arg, use_json,
10905 1, NULL, NULL);
10906 }
10907 /* labeled-unicast routes live in the unicast table */
10908 else if (safi == SAFI_LABELED_UNICAST)
10909 safi = SAFI_UNICAST;
10910
10911 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
10912 NULL, NULL, &json_header_depth, show_flags);
10913 }
10914
10915 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
10916 safi_t safi, uint8_t show_flags)
10917 {
10918 struct listnode *node, *nnode;
10919 struct bgp *bgp;
10920 int is_first = 1;
10921 bool route_output = false;
10922 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10923
10924 if (use_json)
10925 vty_out(vty, "{\n");
10926
10927 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
10928 route_output = true;
10929 if (use_json) {
10930 if (!is_first)
10931 vty_out(vty, ",\n");
10932 else
10933 is_first = 0;
10934
10935 vty_out(vty, "\"%s\":",
10936 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
10937 ? VRF_DEFAULT_NAME
10938 : bgp->name);
10939 } else {
10940 vty_out(vty, "\nInstance %s:\n",
10941 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
10942 ? VRF_DEFAULT_NAME
10943 : bgp->name);
10944 }
10945 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
10946 show_flags);
10947 }
10948
10949 if (use_json)
10950 vty_out(vty, "}\n");
10951 else if (!route_output)
10952 vty_out(vty, "%% BGP instance not found\n");
10953 }
10954
10955 /* Header of detailed BGP route information */
10956 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
10957 struct bgp_dest *dest, struct prefix_rd *prd,
10958 afi_t afi, safi_t safi, json_object *json)
10959 {
10960 struct bgp_path_info *pi;
10961 const struct prefix *p;
10962 struct peer *peer;
10963 struct listnode *node, *nnode;
10964 char buf1[RD_ADDRSTRLEN];
10965 char prefix_str[BUFSIZ];
10966 int count = 0;
10967 int best = 0;
10968 int suppress = 0;
10969 int accept_own = 0;
10970 int route_filter_translated_v4 = 0;
10971 int route_filter_v4 = 0;
10972 int route_filter_translated_v6 = 0;
10973 int route_filter_v6 = 0;
10974 int llgr_stale = 0;
10975 int no_llgr = 0;
10976 int accept_own_nexthop = 0;
10977 int blackhole = 0;
10978 int no_export = 0;
10979 int no_advertise = 0;
10980 int local_as = 0;
10981 int no_peer = 0;
10982 int first = 1;
10983 int has_valid_label = 0;
10984 mpls_label_t label = 0;
10985 json_object *json_adv_to = NULL;
10986
10987 p = bgp_dest_get_prefix(dest);
10988 has_valid_label = bgp_is_valid_label(&dest->local_label);
10989
10990 if (has_valid_label)
10991 label = label_pton(&dest->local_label);
10992
10993 if (safi == SAFI_EVPN) {
10994
10995 if (!json) {
10996 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
10997 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
10998 : "",
10999 prd ? ":" : "", (struct prefix_evpn *)p);
11000 } else {
11001 json_object_string_add(json, "rd",
11002 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11003 "");
11004 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11005 }
11006 } else {
11007 if (!json) {
11008 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11009 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11010 ? prefix_rd2str(prd, buf1,
11011 sizeof(buf1))
11012 : ""),
11013 safi == SAFI_MPLS_VPN ? ":" : "", p);
11014
11015 } else
11016 json_object_string_add(json, "prefix",
11017 prefix2str(p, prefix_str, sizeof(prefix_str)));
11018 }
11019
11020 if (has_valid_label) {
11021 if (json)
11022 json_object_int_add(json, "localLabel", label);
11023 else
11024 vty_out(vty, "Local label: %d\n", label);
11025 }
11026
11027 if (!json)
11028 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11029 vty_out(vty, "not allocated\n");
11030
11031 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11032 count++;
11033 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11034 best = count;
11035 if (bgp_path_suppressed(pi))
11036 suppress = 1;
11037
11038 if (pi->attr->community == NULL)
11039 continue;
11040
11041 no_advertise += community_include(
11042 pi->attr->community, COMMUNITY_NO_ADVERTISE);
11043 no_export += community_include(pi->attr->community,
11044 COMMUNITY_NO_EXPORT);
11045 local_as += community_include(pi->attr->community,
11046 COMMUNITY_LOCAL_AS);
11047 accept_own += community_include(pi->attr->community,
11048 COMMUNITY_ACCEPT_OWN);
11049 route_filter_translated_v4 += community_include(
11050 pi->attr->community,
11051 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11052 route_filter_translated_v6 += community_include(
11053 pi->attr->community,
11054 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11055 route_filter_v4 += community_include(
11056 pi->attr->community, COMMUNITY_ROUTE_FILTER_v4);
11057 route_filter_v6 += community_include(
11058 pi->attr->community, COMMUNITY_ROUTE_FILTER_v6);
11059 llgr_stale += community_include(pi->attr->community,
11060 COMMUNITY_LLGR_STALE);
11061 no_llgr += community_include(pi->attr->community,
11062 COMMUNITY_NO_LLGR);
11063 accept_own_nexthop +=
11064 community_include(pi->attr->community,
11065 COMMUNITY_ACCEPT_OWN_NEXTHOP);
11066 blackhole += community_include(pi->attr->community,
11067 COMMUNITY_BLACKHOLE);
11068 no_peer += community_include(pi->attr->community,
11069 COMMUNITY_NO_PEER);
11070 }
11071 }
11072
11073 if (!json) {
11074 vty_out(vty, "Paths: (%d available", count);
11075 if (best) {
11076 vty_out(vty, ", best #%d", best);
11077 if (safi == SAFI_UNICAST) {
11078 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11079 vty_out(vty, ", table %s",
11080 VRF_DEFAULT_NAME);
11081 else
11082 vty_out(vty, ", vrf %s",
11083 bgp->name);
11084 }
11085 } else
11086 vty_out(vty, ", no best path");
11087
11088 if (accept_own)
11089 vty_out(vty,
11090 ", accept own local route exported and imported in different VRF");
11091 else if (route_filter_translated_v4)
11092 vty_out(vty,
11093 ", mark translated RTs for VPNv4 route filtering");
11094 else if (route_filter_v4)
11095 vty_out(vty,
11096 ", attach RT as-is for VPNv4 route filtering");
11097 else if (route_filter_translated_v6)
11098 vty_out(vty,
11099 ", mark translated RTs for VPNv6 route filtering");
11100 else if (route_filter_v6)
11101 vty_out(vty,
11102 ", attach RT as-is for VPNv6 route filtering");
11103 else if (llgr_stale)
11104 vty_out(vty,
11105 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
11106 else if (no_llgr)
11107 vty_out(vty,
11108 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11109 else if (accept_own_nexthop)
11110 vty_out(vty,
11111 ", accept local nexthop");
11112 else if (blackhole)
11113 vty_out(vty, ", inform peer to blackhole prefix");
11114 else if (no_export)
11115 vty_out(vty, ", not advertised to EBGP peer");
11116 else if (no_advertise)
11117 vty_out(vty, ", not advertised to any peer");
11118 else if (local_as)
11119 vty_out(vty, ", not advertised outside local AS");
11120 else if (no_peer)
11121 vty_out(vty,
11122 ", inform EBGP peer not to advertise to their EBGP peers");
11123
11124 if (suppress)
11125 vty_out(vty,
11126 ", Advertisements suppressed by an aggregate.");
11127 vty_out(vty, ")\n");
11128 }
11129
11130 /* If we are not using addpath then we can display Advertised to and
11131 * that will
11132 * show what peers we advertised the bestpath to. If we are using
11133 * addpath
11134 * though then we must display Advertised to on a path-by-path basis. */
11135 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11136 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11137 if (bgp_adj_out_lookup(peer, dest, 0)) {
11138 if (json && !json_adv_to)
11139 json_adv_to = json_object_new_object();
11140
11141 route_vty_out_advertised_to(
11142 vty, peer, &first,
11143 " Advertised to non peer-group peers:\n ",
11144 json_adv_to);
11145 }
11146 }
11147
11148 if (json) {
11149 if (json_adv_to) {
11150 json_object_object_add(json, "advertisedTo",
11151 json_adv_to);
11152 }
11153 } else {
11154 if (first)
11155 vty_out(vty, " Not advertised to any peer");
11156 vty_out(vty, "\n");
11157 }
11158 }
11159 }
11160
11161 static void bgp_show_path_info(struct prefix_rd *pfx_rd,
11162 struct bgp_dest *bgp_node, struct vty *vty,
11163 struct bgp *bgp, afi_t afi, safi_t safi,
11164 json_object *json, enum bgp_path_type pathtype,
11165 int *display)
11166 {
11167 struct bgp_path_info *pi;
11168 int header = 1;
11169 char rdbuf[RD_ADDRSTRLEN];
11170 json_object *json_header = NULL;
11171 json_object *json_paths = NULL;
11172
11173 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
11174
11175 if (json && !json_paths) {
11176 /* Instantiate json_paths only if path is valid */
11177 json_paths = json_object_new_array();
11178 if (pfx_rd) {
11179 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
11180 json_header = json_object_new_object();
11181 } else
11182 json_header = json;
11183 }
11184
11185 if (header) {
11186 route_vty_out_detail_header(
11187 vty, bgp, bgp_node, pfx_rd,
11188 AFI_IP, safi, json_header);
11189 header = 0;
11190 }
11191 (*display)++;
11192
11193 if (pathtype == BGP_PATH_SHOW_ALL
11194 || (pathtype == BGP_PATH_SHOW_BESTPATH
11195 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
11196 || (pathtype == BGP_PATH_SHOW_MULTIPATH
11197 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
11198 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
11199 route_vty_out_detail(vty, bgp, bgp_node,
11200 pi, AFI_IP, safi,
11201 json_paths);
11202 }
11203
11204 if (json && json_paths) {
11205 json_object_object_add(json_header, "paths", json_paths);
11206
11207 if (pfx_rd)
11208 json_object_object_add(json, rdbuf, json_header);
11209 }
11210 }
11211
11212 /* Display specified route of BGP table. */
11213 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
11214 struct bgp_table *rib, const char *ip_str,
11215 afi_t afi, safi_t safi,
11216 struct prefix_rd *prd, int prefix_check,
11217 enum bgp_path_type pathtype, bool use_json)
11218 {
11219 int ret;
11220 int display = 0;
11221 struct prefix match;
11222 struct bgp_dest *dest;
11223 struct bgp_dest *rm;
11224 struct bgp_table *table;
11225 json_object *json = NULL;
11226 json_object *json_paths = NULL;
11227
11228 /* Check IP address argument. */
11229 ret = str2prefix(ip_str, &match);
11230 if (!ret) {
11231 vty_out(vty, "address is malformed\n");
11232 return CMD_WARNING;
11233 }
11234
11235 match.family = afi2family(afi);
11236
11237 if (use_json)
11238 json = json_object_new_object();
11239
11240 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
11241 for (dest = bgp_table_top(rib); dest;
11242 dest = bgp_route_next(dest)) {
11243 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11244
11245 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
11246 continue;
11247 table = bgp_dest_get_bgp_table_info(dest);
11248 if (!table)
11249 continue;
11250
11251 if ((rm = bgp_node_match(table, &match)) == NULL)
11252 continue;
11253
11254 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
11255 if (prefix_check
11256 && rm_p->prefixlen != match.prefixlen) {
11257 bgp_dest_unlock_node(rm);
11258 continue;
11259 }
11260
11261 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11262 bgp, afi, safi, json, pathtype,
11263 &display);
11264
11265 bgp_dest_unlock_node(rm);
11266 }
11267 } else if (safi == SAFI_EVPN) {
11268 struct bgp_dest *longest_pfx;
11269 bool is_exact_pfxlen_match = false;
11270
11271 for (dest = bgp_table_top(rib); dest;
11272 dest = bgp_route_next(dest)) {
11273 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11274
11275 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
11276 continue;
11277 table = bgp_dest_get_bgp_table_info(dest);
11278 if (!table)
11279 continue;
11280
11281 longest_pfx = NULL;
11282 is_exact_pfxlen_match = false;
11283 /*
11284 * Search through all the prefixes for a match. The
11285 * pfx's are enumerated in ascending order of pfxlens.
11286 * So, the last pfx match is the longest match. Set
11287 * is_exact_pfxlen_match when we get exact pfxlen match
11288 */
11289 for (rm = bgp_table_top(table); rm;
11290 rm = bgp_route_next(rm)) {
11291 const struct prefix *rm_p =
11292 bgp_dest_get_prefix(rm);
11293 /*
11294 * Get prefixlen of the ip-prefix within type5
11295 * evpn route
11296 */
11297 if (evpn_type5_prefix_match(rm_p, &match)
11298 && rm->info) {
11299 longest_pfx = rm;
11300 int type5_pfxlen =
11301 bgp_evpn_get_type5_prefixlen(
11302 rm_p);
11303 if (type5_pfxlen == match.prefixlen) {
11304 is_exact_pfxlen_match = true;
11305 bgp_dest_unlock_node(rm);
11306 break;
11307 }
11308 }
11309 }
11310
11311 if (!longest_pfx)
11312 continue;
11313
11314 if (prefix_check && !is_exact_pfxlen_match)
11315 continue;
11316
11317 rm = longest_pfx;
11318 bgp_dest_lock_node(rm);
11319
11320 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11321 bgp, afi, safi, json, pathtype,
11322 &display);
11323
11324 bgp_dest_unlock_node(rm);
11325 }
11326 } else if (safi == SAFI_FLOWSPEC) {
11327 if (use_json)
11328 json_paths = json_object_new_array();
11329
11330 display = bgp_flowspec_display_match_per_ip(afi, rib,
11331 &match, prefix_check,
11332 vty,
11333 use_json,
11334 json_paths);
11335 if (use_json) {
11336 if (display)
11337 json_object_object_add(json, "paths",
11338 json_paths);
11339 else
11340 json_object_free(json_paths);
11341 }
11342 } else {
11343 if ((dest = bgp_node_match(rib, &match)) != NULL) {
11344 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11345 if (!prefix_check
11346 || dest_p->prefixlen == match.prefixlen) {
11347 bgp_show_path_info(NULL, dest, vty, bgp, afi,
11348 safi, json, pathtype,
11349 &display);
11350 }
11351
11352 bgp_dest_unlock_node(dest);
11353 }
11354 }
11355
11356 if (use_json) {
11357 vty_out(vty, "%s\n", json_object_to_json_string_ext(
11358 json, JSON_C_TO_STRING_PRETTY |
11359 JSON_C_TO_STRING_NOSLASHESCAPE));
11360 json_object_free(json);
11361 } else {
11362 if (!display) {
11363 vty_out(vty, "%% Network not in table\n");
11364 return CMD_WARNING;
11365 }
11366 }
11367
11368 return CMD_SUCCESS;
11369 }
11370
11371 /* Display specified route of Main RIB */
11372 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
11373 afi_t afi, safi_t safi, struct prefix_rd *prd,
11374 int prefix_check, enum bgp_path_type pathtype,
11375 bool use_json)
11376 {
11377 if (!bgp) {
11378 bgp = bgp_get_default();
11379 if (!bgp) {
11380 if (!use_json)
11381 vty_out(vty, "No BGP process is configured\n");
11382 else
11383 vty_out(vty, "{}\n");
11384 return CMD_WARNING;
11385 }
11386 }
11387
11388 /* labeled-unicast routes live in the unicast table */
11389 if (safi == SAFI_LABELED_UNICAST)
11390 safi = SAFI_UNICAST;
11391
11392 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
11393 afi, safi, prd, prefix_check, pathtype,
11394 use_json);
11395 }
11396
11397 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
11398 struct cmd_token **argv, bool exact, afi_t afi,
11399 safi_t safi, bool uj)
11400 {
11401 struct lcommunity *lcom;
11402 struct buffer *b;
11403 int i;
11404 char *str;
11405 int first = 0;
11406 uint8_t show_flags = 0;
11407 int ret;
11408
11409 if (uj)
11410 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11411
11412 b = buffer_new(1024);
11413 for (i = 0; i < argc; i++) {
11414 if (first)
11415 buffer_putc(b, ' ');
11416 else {
11417 if (strmatch(argv[i]->text, "AA:BB:CC")) {
11418 first = 1;
11419 buffer_putstr(b, argv[i]->arg);
11420 }
11421 }
11422 }
11423 buffer_putc(b, '\0');
11424
11425 str = buffer_getstr(b);
11426 buffer_free(b);
11427
11428 lcom = lcommunity_str2com(str);
11429 XFREE(MTYPE_TMP, str);
11430 if (!lcom) {
11431 vty_out(vty, "%% Large-community malformed\n");
11432 return CMD_WARNING;
11433 }
11434
11435 ret = bgp_show(vty, bgp, afi, safi,
11436 (exact ? bgp_show_type_lcommunity_exact
11437 : bgp_show_type_lcommunity),
11438 lcom, show_flags);
11439
11440 lcommunity_free(&lcom);
11441 return ret;
11442 }
11443
11444 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
11445 const char *lcom, bool exact, afi_t afi,
11446 safi_t safi, bool uj)
11447 {
11448 struct community_list *list;
11449 uint8_t show_flags = 0;
11450
11451 if (uj)
11452 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11453
11454
11455 list = community_list_lookup(bgp_clist, lcom, 0,
11456 LARGE_COMMUNITY_LIST_MASTER);
11457 if (list == NULL) {
11458 vty_out(vty, "%% %s is not a valid large-community-list name\n",
11459 lcom);
11460 return CMD_WARNING;
11461 }
11462
11463 return bgp_show(vty, bgp, afi, safi,
11464 (exact ? bgp_show_type_lcommunity_list_exact
11465 : bgp_show_type_lcommunity_list),
11466 list, show_flags);
11467 }
11468
11469 DEFUN (show_ip_bgp_large_community_list,
11470 show_ip_bgp_large_community_list_cmd,
11471 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community-list <(1-500)|WORD> [exact-match] [json]",
11472 SHOW_STR
11473 IP_STR
11474 BGP_STR
11475 BGP_INSTANCE_HELP_STR
11476 BGP_AFI_HELP_STR
11477 BGP_SAFI_WITH_LABEL_HELP_STR
11478 "Display routes matching the large-community-list\n"
11479 "large-community-list number\n"
11480 "large-community-list name\n"
11481 "Exact match of the large-communities\n"
11482 JSON_STR)
11483 {
11484 afi_t afi = AFI_IP6;
11485 safi_t safi = SAFI_UNICAST;
11486 int idx = 0;
11487 bool exact_match = 0;
11488 struct bgp *bgp = NULL;
11489 bool uj = use_json(argc, argv);
11490
11491 if (uj)
11492 argc--;
11493
11494 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11495 &bgp, uj);
11496 if (!idx)
11497 return CMD_WARNING;
11498
11499 argv_find(argv, argc, "large-community-list", &idx);
11500
11501 const char *clist_number_or_name = argv[++idx]->arg;
11502
11503 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
11504 exact_match = 1;
11505
11506 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
11507 exact_match, afi, safi, uj);
11508 }
11509 DEFUN (show_ip_bgp_large_community,
11510 show_ip_bgp_large_community_cmd,
11511 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
11512 SHOW_STR
11513 IP_STR
11514 BGP_STR
11515 BGP_INSTANCE_HELP_STR
11516 BGP_AFI_HELP_STR
11517 BGP_SAFI_WITH_LABEL_HELP_STR
11518 "Display routes matching the large-communities\n"
11519 "List of large-community numbers\n"
11520 "Exact match of the large-communities\n"
11521 JSON_STR)
11522 {
11523 afi_t afi = AFI_IP6;
11524 safi_t safi = SAFI_UNICAST;
11525 int idx = 0;
11526 bool exact_match = 0;
11527 struct bgp *bgp = NULL;
11528 bool uj = use_json(argc, argv);
11529 uint8_t show_flags = 0;
11530
11531 if (uj) {
11532 argc--;
11533 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11534 }
11535
11536 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11537 &bgp, uj);
11538 if (!idx)
11539 return CMD_WARNING;
11540
11541 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
11542 if (argv_find(argv, argc, "exact-match", &idx))
11543 exact_match = 1;
11544 return bgp_show_lcommunity(vty, bgp, argc, argv,
11545 exact_match, afi, safi, uj);
11546 } else
11547 return bgp_show(vty, bgp, afi, safi,
11548 bgp_show_type_lcommunity_all, NULL, show_flags);
11549 }
11550
11551 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
11552 safi_t safi, struct json_object *json_array);
11553 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
11554 safi_t safi, struct json_object *json);
11555
11556
11557 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
11558 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
11559 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
11560 "Display number of prefixes for all afi/safi\n" JSON_STR)
11561 {
11562 bool uj = use_json(argc, argv);
11563 struct bgp *bgp = NULL;
11564 safi_t safi = SAFI_UNICAST;
11565 afi_t afi = AFI_IP6;
11566 int idx = 0;
11567 struct json_object *json_all = NULL;
11568 struct json_object *json_afi_safi = NULL;
11569
11570 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11571 &bgp, false);
11572 if (!idx)
11573 return CMD_WARNING;
11574
11575 if (uj)
11576 json_all = json_object_new_object();
11577
11578 FOREACH_AFI_SAFI (afi, safi) {
11579 /*
11580 * So limit output to those afi/safi pairs that
11581 * actually have something interesting in them
11582 */
11583 if (strmatch(get_afi_safi_str(afi, safi, true),
11584 "Unknown")) {
11585 continue;
11586 }
11587 if (uj) {
11588 json_afi_safi = json_object_new_array();
11589 json_object_object_add(
11590 json_all,
11591 get_afi_safi_str(afi, safi, true),
11592 json_afi_safi);
11593 } else {
11594 json_afi_safi = NULL;
11595 }
11596
11597 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
11598 }
11599
11600 if (uj) {
11601 vty_out(vty, "%s",
11602 json_object_to_json_string_ext(
11603 json_all, JSON_C_TO_STRING_PRETTY));
11604 json_object_free(json_all);
11605 }
11606
11607 return CMD_SUCCESS;
11608 }
11609
11610 /* BGP route print out function without JSON */
11611 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
11612 show_ip_bgp_l2vpn_evpn_statistics_cmd,
11613 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
11614 SHOW_STR
11615 IP_STR
11616 BGP_STR
11617 BGP_INSTANCE_HELP_STR
11618 L2VPN_HELP_STR
11619 EVPN_HELP_STR
11620 "BGP RIB advertisement statistics\n"
11621 JSON_STR)
11622 {
11623 afi_t afi = AFI_IP6;
11624 safi_t safi = SAFI_UNICAST;
11625 struct bgp *bgp = NULL;
11626 int idx = 0, ret;
11627 bool uj = use_json(argc, argv);
11628 struct json_object *json_afi_safi = NULL, *json = NULL;
11629
11630 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11631 &bgp, false);
11632 if (!idx)
11633 return CMD_WARNING;
11634
11635 if (uj)
11636 json_afi_safi = json_object_new_array();
11637 else
11638 json_afi_safi = NULL;
11639
11640 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
11641
11642 if (uj) {
11643 json = json_object_new_object();
11644 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
11645 json_afi_safi);
11646 vty_out(vty, "%s", json_object_to_json_string_ext(
11647 json, JSON_C_TO_STRING_PRETTY));
11648 json_object_free(json);
11649 }
11650 return ret;
11651 }
11652
11653 /* BGP route print out function without JSON */
11654 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
11655 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
11656 " [" BGP_SAFI_WITH_LABEL_CMD_STR
11657 "]]\
11658 statistics [json]",
11659 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
11660 BGP_SAFI_WITH_LABEL_HELP_STR
11661 "BGP RIB advertisement statistics\n" JSON_STR)
11662 {
11663 afi_t afi = AFI_IP6;
11664 safi_t safi = SAFI_UNICAST;
11665 struct bgp *bgp = NULL;
11666 int idx = 0, ret;
11667 bool uj = use_json(argc, argv);
11668 struct json_object *json_afi_safi = NULL, *json = NULL;
11669
11670 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11671 &bgp, false);
11672 if (!idx)
11673 return CMD_WARNING;
11674
11675 if (uj)
11676 json_afi_safi = json_object_new_array();
11677 else
11678 json_afi_safi = NULL;
11679
11680 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
11681
11682 if (uj) {
11683 json = json_object_new_object();
11684 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
11685 json_afi_safi);
11686 vty_out(vty, "%s",
11687 json_object_to_json_string_ext(
11688 json, JSON_C_TO_STRING_PRETTY));
11689 json_object_free(json);
11690 }
11691 return ret;
11692 }
11693
11694 /* BGP route print out function without JSON */
11695 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
11696 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
11697 " [" BGP_SAFI_WITH_LABEL_CMD_STR
11698 "]]\
11699 <[all$all] dampening <parameters>\
11700 |route-map WORD\
11701 |prefix-list WORD\
11702 |filter-list WORD\
11703 |community-list <(1-500)|WORD> [exact-match]\
11704 |A.B.C.D/M longer-prefixes\
11705 |X:X::X:X/M longer-prefixes\
11706 >",
11707 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
11708 BGP_SAFI_WITH_LABEL_HELP_STR
11709 "Display the entries for all address families\n"
11710 "Display detailed information about dampening\n"
11711 "Display detail of configured dampening parameters\n"
11712 "Display routes matching the route-map\n"
11713 "A route-map to match on\n"
11714 "Display routes conforming to the prefix-list\n"
11715 "Prefix-list name\n"
11716 "Display routes conforming to the filter-list\n"
11717 "Regular expression access list name\n"
11718 "Display routes matching the community-list\n"
11719 "community-list number\n"
11720 "community-list name\n"
11721 "Exact match of the communities\n"
11722 "IPv4 prefix\n"
11723 "Display route and more specific routes\n"
11724 "IPv6 prefix\n"
11725 "Display route and more specific routes\n")
11726 {
11727 afi_t afi = AFI_IP6;
11728 safi_t safi = SAFI_UNICAST;
11729 int exact_match = 0;
11730 struct bgp *bgp = NULL;
11731 int idx = 0;
11732 uint8_t show_flags = 0;
11733
11734 /* [<ipv4|ipv6> [all]] */
11735 if (all) {
11736 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11737 if (argv_find(argv, argc, "ipv4", &idx))
11738 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
11739
11740 if (argv_find(argv, argc, "ipv6", &idx))
11741 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
11742 }
11743
11744 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11745 &bgp, false);
11746 if (!idx)
11747 return CMD_WARNING;
11748
11749 if (argv_find(argv, argc, "dampening", &idx)) {
11750 if (argv_find(argv, argc, "parameters", &idx))
11751 return bgp_show_dampening_parameters(vty, afi, safi,
11752 show_flags);
11753 }
11754
11755 if (argv_find(argv, argc, "prefix-list", &idx))
11756 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
11757 safi, bgp_show_type_prefix_list);
11758
11759 if (argv_find(argv, argc, "filter-list", &idx))
11760 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
11761 safi, bgp_show_type_filter_list);
11762
11763 if (argv_find(argv, argc, "route-map", &idx))
11764 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
11765 safi, bgp_show_type_route_map);
11766
11767 if (argv_find(argv, argc, "community-list", &idx)) {
11768 const char *clist_number_or_name = argv[++idx]->arg;
11769 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
11770 exact_match = 1;
11771 return bgp_show_community_list(vty, bgp, clist_number_or_name,
11772 exact_match, afi, safi);
11773 }
11774 /* prefix-longer */
11775 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
11776 || argv_find(argv, argc, "X:X::X:X/M", &idx))
11777 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
11778 safi,
11779 bgp_show_type_prefix_longer);
11780
11781 return CMD_WARNING;
11782 }
11783
11784 /* BGP route print out function with JSON */
11785 DEFPY (show_ip_bgp_json,
11786 show_ip_bgp_json_cmd,
11787 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
11788 [all$all]\
11789 [cidr-only\
11790 |dampening <flap-statistics|dampened-paths>\
11791 |community [AA:NN|local-AS|no-advertise|no-export\
11792 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
11793 |accept-own|accept-own-nexthop|route-filter-v6\
11794 |route-filter-v4|route-filter-translated-v6\
11795 |route-filter-translated-v4] [exact-match]\
11796 ] [json$uj | wide$wide]",
11797 SHOW_STR
11798 IP_STR
11799 BGP_STR
11800 BGP_INSTANCE_HELP_STR
11801 BGP_AFI_HELP_STR
11802 BGP_SAFI_WITH_LABEL_HELP_STR
11803 "Display the entries for all address families\n"
11804 "Display only routes with non-natural netmasks\n"
11805 "Display detailed information about dampening\n"
11806 "Display flap statistics of routes\n"
11807 "Display paths suppressed due to dampening\n"
11808 "Display routes matching the communities\n"
11809 COMMUNITY_AANN_STR
11810 "Do not send outside local AS (well-known community)\n"
11811 "Do not advertise to any peer (well-known community)\n"
11812 "Do not export to next AS (well-known community)\n"
11813 "Graceful shutdown (well-known community)\n"
11814 "Do not export to any peer (well-known community)\n"
11815 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
11816 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
11817 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
11818 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
11819 "Should accept VPN route with local nexthop (well-known community)\n"
11820 "RT VPNv6 route filtering (well-known community)\n"
11821 "RT VPNv4 route filtering (well-known community)\n"
11822 "RT translated VPNv6 route filtering (well-known community)\n"
11823 "RT translated VPNv4 route filtering (well-known community)\n"
11824 "Exact match of the communities\n"
11825 JSON_STR
11826 "Increase table width for longer prefixes\n")
11827 {
11828 afi_t afi = AFI_IP6;
11829 safi_t safi = SAFI_UNICAST;
11830 enum bgp_show_type sh_type = bgp_show_type_normal;
11831 struct bgp *bgp = NULL;
11832 int idx = 0;
11833 int exact_match = 0;
11834 char *community = NULL;
11835 bool first = true;
11836 uint8_t show_flags = 0;
11837
11838
11839 if (uj) {
11840 argc--;
11841 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11842 }
11843
11844 /* [<ipv4|ipv6> [all]] */
11845 if (all) {
11846 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11847
11848 if (argv_find(argv, argc, "ipv4", &idx))
11849 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
11850
11851 if (argv_find(argv, argc, "ipv6", &idx))
11852 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
11853 }
11854
11855 if (wide)
11856 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11857
11858 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11859 &bgp, uj);
11860 if (!idx)
11861 return CMD_WARNING;
11862
11863 if (argv_find(argv, argc, "cidr-only", &idx))
11864 sh_type = bgp_show_type_cidr_only;
11865
11866 if (argv_find(argv, argc, "dampening", &idx)) {
11867 if (argv_find(argv, argc, "dampened-paths", &idx))
11868 sh_type = bgp_show_type_dampend_paths;
11869 else if (argv_find(argv, argc, "flap-statistics", &idx))
11870 sh_type = bgp_show_type_flap_statistics;
11871 }
11872
11873 if (argv_find(argv, argc, "community", &idx)) {
11874 char *maybecomm = NULL;
11875
11876 if (idx + 1 < argc) {
11877 if (argv[idx + 1]->type == VARIABLE_TKN)
11878 maybecomm = argv[idx + 1]->arg;
11879 else
11880 maybecomm = argv[idx + 1]->text;
11881 }
11882
11883 if (maybecomm && !strmatch(maybecomm, "json")
11884 && !strmatch(maybecomm, "exact-match"))
11885 community = maybecomm;
11886
11887 if (argv_find(argv, argc, "exact-match", &idx))
11888 exact_match = 1;
11889
11890 if (!community)
11891 sh_type = bgp_show_type_community_all;
11892 }
11893
11894 if (!all) {
11895 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
11896 if (community)
11897 return bgp_show_community(vty, bgp, community,
11898 exact_match, afi, safi,
11899 show_flags);
11900 else
11901 return bgp_show(vty, bgp, afi, safi, sh_type, NULL,
11902 show_flags);
11903 } else {
11904 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
11905 * AFI_IP6 */
11906
11907 if (uj)
11908 vty_out(vty, "{\n");
11909
11910 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
11911 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
11912 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
11913 ? AFI_IP
11914 : AFI_IP6;
11915 FOREACH_SAFI (safi) {
11916 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
11917 continue;
11918
11919 if (uj) {
11920 if (first)
11921 first = false;
11922 else
11923 vty_out(vty, ",\n");
11924 vty_out(vty, "\"%s\":{\n",
11925 get_afi_safi_str(afi, safi,
11926 true));
11927 } else
11928 vty_out(vty,
11929 "\nFor address family: %s\n",
11930 get_afi_safi_str(afi, safi,
11931 false));
11932
11933 if (community)
11934 bgp_show_community(vty, bgp, community,
11935 exact_match, afi,
11936 safi, show_flags);
11937 else
11938 bgp_show(vty, bgp, afi, safi, sh_type,
11939 NULL, show_flags);
11940 if (uj)
11941 vty_out(vty, "}\n");
11942 }
11943 } else {
11944 /* show <ip> bgp all: for each AFI and SAFI*/
11945 FOREACH_AFI_SAFI (afi, safi) {
11946 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
11947 continue;
11948
11949 if (uj) {
11950 if (first)
11951 first = false;
11952 else
11953 vty_out(vty, ",\n");
11954
11955 vty_out(vty, "\"%s\":{\n",
11956 get_afi_safi_str(afi, safi,
11957 true));
11958 } else
11959 vty_out(vty,
11960 "\nFor address family: %s\n",
11961 get_afi_safi_str(afi, safi,
11962 false));
11963
11964 if (community)
11965 bgp_show_community(vty, bgp, community,
11966 exact_match, afi,
11967 safi, show_flags);
11968 else
11969 bgp_show(vty, bgp, afi, safi, sh_type,
11970 NULL, show_flags);
11971 if (uj)
11972 vty_out(vty, "}\n");
11973 }
11974 }
11975 if (uj)
11976 vty_out(vty, "}\n");
11977 }
11978 return CMD_SUCCESS;
11979 }
11980
11981 DEFUN (show_ip_bgp_route,
11982 show_ip_bgp_route_cmd,
11983 "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>] [json]",
11984 SHOW_STR
11985 IP_STR
11986 BGP_STR
11987 BGP_INSTANCE_HELP_STR
11988 BGP_AFI_HELP_STR
11989 BGP_SAFI_WITH_LABEL_HELP_STR
11990 "Network in the BGP routing table to display\n"
11991 "IPv4 prefix\n"
11992 "Network in the BGP routing table to display\n"
11993 "IPv6 prefix\n"
11994 "Display only the bestpath\n"
11995 "Display only multipaths\n"
11996 JSON_STR)
11997 {
11998 int prefix_check = 0;
11999
12000 afi_t afi = AFI_IP6;
12001 safi_t safi = SAFI_UNICAST;
12002 char *prefix = NULL;
12003 struct bgp *bgp = NULL;
12004 enum bgp_path_type path_type;
12005 bool uj = use_json(argc, argv);
12006
12007 int idx = 0;
12008
12009 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12010 &bgp, uj);
12011 if (!idx)
12012 return CMD_WARNING;
12013
12014 if (!bgp) {
12015 vty_out(vty,
12016 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
12017 return CMD_WARNING;
12018 }
12019
12020 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
12021 if (argv_find(argv, argc, "A.B.C.D", &idx)
12022 || argv_find(argv, argc, "X:X::X:X", &idx))
12023 prefix_check = 0;
12024 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12025 || argv_find(argv, argc, "X:X::X:X/M", &idx))
12026 prefix_check = 1;
12027
12028 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
12029 && afi != AFI_IP6) {
12030 vty_out(vty,
12031 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
12032 return CMD_WARNING;
12033 }
12034 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
12035 && afi != AFI_IP) {
12036 vty_out(vty,
12037 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
12038 return CMD_WARNING;
12039 }
12040
12041 prefix = argv[idx]->arg;
12042
12043 /* [<bestpath|multipath>] */
12044 if (argv_find(argv, argc, "bestpath", &idx))
12045 path_type = BGP_PATH_SHOW_BESTPATH;
12046 else if (argv_find(argv, argc, "multipath", &idx))
12047 path_type = BGP_PATH_SHOW_MULTIPATH;
12048 else
12049 path_type = BGP_PATH_SHOW_ALL;
12050
12051 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
12052 path_type, uj);
12053 }
12054
12055 DEFUN (show_ip_bgp_regexp,
12056 show_ip_bgp_regexp_cmd,
12057 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
12058 SHOW_STR
12059 IP_STR
12060 BGP_STR
12061 BGP_INSTANCE_HELP_STR
12062 BGP_AFI_HELP_STR
12063 BGP_SAFI_WITH_LABEL_HELP_STR
12064 "Display routes matching the AS path regular expression\n"
12065 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
12066 JSON_STR)
12067 {
12068 afi_t afi = AFI_IP6;
12069 safi_t safi = SAFI_UNICAST;
12070 struct bgp *bgp = NULL;
12071 bool uj = use_json(argc, argv);
12072 char *regstr = NULL;
12073
12074 int idx = 0;
12075 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12076 &bgp, false);
12077 if (!idx)
12078 return CMD_WARNING;
12079
12080 // get index of regex
12081 if (argv_find(argv, argc, "REGEX", &idx))
12082 regstr = argv[idx]->arg;
12083
12084 assert(regstr);
12085 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
12086 bgp_show_type_regexp, uj);
12087 }
12088
12089 DEFPY (show_ip_bgp_instance_all,
12090 show_ip_bgp_instance_all_cmd,
12091 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
12092 SHOW_STR
12093 IP_STR
12094 BGP_STR
12095 BGP_INSTANCE_ALL_HELP_STR
12096 BGP_AFI_HELP_STR
12097 BGP_SAFI_WITH_LABEL_HELP_STR
12098 JSON_STR
12099 "Increase table width for longer prefixes\n")
12100 {
12101 afi_t afi = AFI_IP;
12102 safi_t safi = SAFI_UNICAST;
12103 struct bgp *bgp = NULL;
12104 int idx = 0;
12105 uint8_t show_flags = 0;
12106
12107 if (uj) {
12108 argc--;
12109 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12110 }
12111
12112 if (wide)
12113 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12114
12115 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12116 &bgp, uj);
12117 if (!idx)
12118 return CMD_WARNING;
12119
12120 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
12121 return CMD_SUCCESS;
12122 }
12123
12124 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
12125 afi_t afi, safi_t safi, enum bgp_show_type type,
12126 bool use_json)
12127 {
12128 regex_t *regex;
12129 int rc;
12130 uint8_t show_flags = 0;
12131
12132 if (use_json)
12133 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12134
12135 if (!config_bgp_aspath_validate(regstr)) {
12136 vty_out(vty, "Invalid character in REGEX %s\n",
12137 regstr);
12138 return CMD_WARNING_CONFIG_FAILED;
12139 }
12140
12141 regex = bgp_regcomp(regstr);
12142 if (!regex) {
12143 vty_out(vty, "Can't compile regexp %s\n", regstr);
12144 return CMD_WARNING;
12145 }
12146
12147 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags);
12148 bgp_regex_free(regex);
12149 return rc;
12150 }
12151
12152 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
12153 const char *prefix_list_str, afi_t afi,
12154 safi_t safi, enum bgp_show_type type)
12155 {
12156 struct prefix_list *plist;
12157 uint8_t show_flags = 0;
12158
12159 plist = prefix_list_lookup(afi, prefix_list_str);
12160 if (plist == NULL) {
12161 vty_out(vty, "%% %s is not a valid prefix-list name\n",
12162 prefix_list_str);
12163 return CMD_WARNING;
12164 }
12165
12166 return bgp_show(vty, bgp, afi, safi, type, plist, show_flags);
12167 }
12168
12169 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
12170 const char *filter, afi_t afi, safi_t safi,
12171 enum bgp_show_type type)
12172 {
12173 struct as_list *as_list;
12174 uint8_t show_flags = 0;
12175
12176 as_list = as_list_lookup(filter);
12177 if (as_list == NULL) {
12178 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
12179 filter);
12180 return CMD_WARNING;
12181 }
12182
12183 return bgp_show(vty, bgp, afi, safi, type, as_list, show_flags);
12184 }
12185
12186 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
12187 const char *rmap_str, afi_t afi, safi_t safi,
12188 enum bgp_show_type type)
12189 {
12190 struct route_map *rmap;
12191 uint8_t show_flags = 0;
12192
12193 rmap = route_map_lookup_by_name(rmap_str);
12194 if (!rmap) {
12195 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
12196 return CMD_WARNING;
12197 }
12198
12199 return bgp_show(vty, bgp, afi, safi, type, rmap, show_flags);
12200 }
12201
12202 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
12203 const char *comstr, int exact, afi_t afi,
12204 safi_t safi, uint8_t show_flags)
12205 {
12206 struct community *com;
12207 int ret = 0;
12208
12209 com = community_str2com(comstr);
12210 if (!com) {
12211 vty_out(vty, "%% Community malformed: %s\n", comstr);
12212 return CMD_WARNING;
12213 }
12214
12215 ret = bgp_show(vty, bgp, afi, safi,
12216 (exact ? bgp_show_type_community_exact
12217 : bgp_show_type_community),
12218 com, show_flags);
12219 community_free(&com);
12220
12221 return ret;
12222 }
12223
12224 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
12225 const char *com, int exact, afi_t afi,
12226 safi_t safi)
12227 {
12228 struct community_list *list;
12229 uint8_t show_flags = 0;
12230
12231 list = community_list_lookup(bgp_clist, com, 0, COMMUNITY_LIST_MASTER);
12232 if (list == NULL) {
12233 vty_out(vty, "%% %s is not a valid community-list name\n", com);
12234 return CMD_WARNING;
12235 }
12236
12237 return bgp_show(vty, bgp, afi, safi,
12238 (exact ? bgp_show_type_community_list_exact
12239 : bgp_show_type_community_list),
12240 list, show_flags);
12241 }
12242
12243 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
12244 const char *prefix, afi_t afi, safi_t safi,
12245 enum bgp_show_type type)
12246 {
12247 int ret;
12248 struct prefix *p;
12249 uint8_t show_flags = 0;
12250
12251 p = prefix_new();
12252
12253 ret = str2prefix(prefix, p);
12254 if (!ret) {
12255 vty_out(vty, "%% Malformed Prefix\n");
12256 return CMD_WARNING;
12257 }
12258
12259 ret = bgp_show(vty, bgp, afi, safi, type, p, show_flags);
12260 prefix_free(&p);
12261 return ret;
12262 }
12263
12264 enum bgp_stats {
12265 BGP_STATS_MAXBITLEN = 0,
12266 BGP_STATS_RIB,
12267 BGP_STATS_PREFIXES,
12268 BGP_STATS_TOTPLEN,
12269 BGP_STATS_UNAGGREGATEABLE,
12270 BGP_STATS_MAX_AGGREGATEABLE,
12271 BGP_STATS_AGGREGATES,
12272 BGP_STATS_SPACE,
12273 BGP_STATS_ASPATH_COUNT,
12274 BGP_STATS_ASPATH_MAXHOPS,
12275 BGP_STATS_ASPATH_TOTHOPS,
12276 BGP_STATS_ASPATH_MAXSIZE,
12277 BGP_STATS_ASPATH_TOTSIZE,
12278 BGP_STATS_ASN_HIGHEST,
12279 BGP_STATS_MAX,
12280 };
12281
12282 #define TABLE_STATS_IDX_VTY 0
12283 #define TABLE_STATS_IDX_JSON 1
12284
12285 static const char *table_stats_strs[][2] = {
12286 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
12287 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
12288 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
12289 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
12290 "unaggregateablePrefixes"},
12291 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
12292 "maximumAggregateablePrefixes"},
12293 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
12294 "bgpAggregateAdvertisements"},
12295 [BGP_STATS_SPACE] = {"Address space advertised",
12296 "addressSpaceAdvertised"},
12297 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
12298 "advertisementsWithPaths"},
12299 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
12300 "longestAsPath"},
12301 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
12302 "largestAsPath"},
12303 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
12304 "averageAsPathLengthHops"},
12305 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
12306 "averageAsPathSizeBytes"},
12307 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
12308 [BGP_STATS_MAX] = {NULL, NULL}
12309 };
12310
12311 struct bgp_table_stats {
12312 struct bgp_table *table;
12313 unsigned long long counts[BGP_STATS_MAX];
12314 double total_space;
12315 };
12316
12317 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
12318 struct bgp_table_stats *ts, unsigned int space)
12319 {
12320 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
12321 struct bgp_path_info *pi;
12322 const struct prefix *rn_p;
12323
12324 if (!bgp_dest_has_bgp_path_info_data(dest))
12325 return;
12326
12327 rn_p = bgp_dest_get_prefix(dest);
12328 ts->counts[BGP_STATS_PREFIXES]++;
12329 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
12330
12331 /* check if the prefix is included by any other announcements */
12332 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
12333 pdest = bgp_dest_parent_nolock(pdest);
12334
12335 if (pdest == NULL || pdest == top) {
12336 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
12337 /* announced address space */
12338 if (space)
12339 ts->total_space += pow(2.0, space - rn_p->prefixlen);
12340 } else if (bgp_dest_has_bgp_path_info_data(pdest))
12341 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
12342
12343
12344 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
12345 ts->counts[BGP_STATS_RIB]++;
12346
12347 if (CHECK_FLAG(pi->attr->flag,
12348 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
12349 ts->counts[BGP_STATS_AGGREGATES]++;
12350
12351 /* as-path stats */
12352 if (pi->attr->aspath) {
12353 unsigned int hops = aspath_count_hops(pi->attr->aspath);
12354 unsigned int size = aspath_size(pi->attr->aspath);
12355 as_t highest = aspath_highest(pi->attr->aspath);
12356
12357 ts->counts[BGP_STATS_ASPATH_COUNT]++;
12358
12359 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
12360 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
12361
12362 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
12363 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
12364
12365 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
12366 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
12367 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
12368 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
12369 }
12370 }
12371 }
12372
12373 static int bgp_table_stats_walker(struct thread *t)
12374 {
12375 struct bgp_dest *dest, *ndest;
12376 struct bgp_dest *top;
12377 struct bgp_table_stats *ts = THREAD_ARG(t);
12378 unsigned int space = 0;
12379
12380 if (!(top = bgp_table_top(ts->table)))
12381 return 0;
12382
12383 switch (ts->table->afi) {
12384 case AFI_IP:
12385 space = IPV4_MAX_BITLEN;
12386 break;
12387 case AFI_IP6:
12388 space = IPV6_MAX_BITLEN;
12389 break;
12390 default:
12391 return 0;
12392 }
12393
12394 ts->counts[BGP_STATS_MAXBITLEN] = space;
12395
12396 for (dest = top; dest; dest = bgp_route_next(dest)) {
12397 if (ts->table->safi == SAFI_MPLS_VPN
12398 || ts->table->safi == SAFI_ENCAP
12399 || ts->table->safi == SAFI_EVPN) {
12400 struct bgp_table *table;
12401
12402 table = bgp_dest_get_bgp_table_info(dest);
12403 if (!table)
12404 continue;
12405
12406 top = bgp_table_top(table);
12407 for (ndest = bgp_table_top(table); ndest;
12408 ndest = bgp_route_next(ndest))
12409 bgp_table_stats_rn(ndest, top, ts, space);
12410 } else {
12411 bgp_table_stats_rn(dest, top, ts, space);
12412 }
12413 }
12414
12415 return 0;
12416 }
12417
12418 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
12419 struct json_object *json_array)
12420 {
12421 struct listnode *node, *nnode;
12422 struct bgp *bgp;
12423
12424 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
12425 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
12426 }
12427
12428 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12429 safi_t safi, struct json_object *json_array)
12430 {
12431 struct bgp_table_stats ts;
12432 unsigned int i;
12433 int ret = CMD_SUCCESS;
12434 char temp_buf[20];
12435 struct json_object *json = NULL;
12436
12437 if (json_array)
12438 json = json_object_new_object();
12439
12440 if (!bgp->rib[afi][safi]) {
12441 char warning_msg[50];
12442
12443 snprintf(warning_msg, sizeof(warning_msg),
12444 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
12445 safi);
12446
12447 if (!json)
12448 vty_out(vty, "%s\n", warning_msg);
12449 else
12450 json_object_string_add(json, "warning", warning_msg);
12451
12452 ret = CMD_WARNING;
12453 goto end_table_stats;
12454 }
12455
12456 if (!json)
12457 vty_out(vty, "BGP %s RIB statistics (%s)\n",
12458 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
12459 else
12460 json_object_string_add(json, "instance", bgp->name_pretty);
12461
12462 /* labeled-unicast routes live in the unicast table */
12463 if (safi == SAFI_LABELED_UNICAST)
12464 safi = SAFI_UNICAST;
12465
12466 memset(&ts, 0, sizeof(ts));
12467 ts.table = bgp->rib[afi][safi];
12468 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
12469
12470 for (i = 0; i < BGP_STATS_MAX; i++) {
12471 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
12472 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
12473 continue;
12474
12475 switch (i) {
12476 case BGP_STATS_ASPATH_TOTHOPS:
12477 case BGP_STATS_ASPATH_TOTSIZE:
12478 if (!json) {
12479 snprintf(
12480 temp_buf, sizeof(temp_buf), "%12.2f",
12481 ts.counts[i]
12482 ? (float)ts.counts[i]
12483 / (float)ts.counts
12484 [BGP_STATS_ASPATH_COUNT]
12485 : 0);
12486 vty_out(vty, "%-30s: %s",
12487 table_stats_strs[i]
12488 [TABLE_STATS_IDX_VTY],
12489 temp_buf);
12490 } else {
12491 json_object_double_add(
12492 json,
12493 table_stats_strs[i]
12494 [TABLE_STATS_IDX_JSON],
12495 ts.counts[i]
12496 ? (double)ts.counts[i]
12497 / (double)ts.counts
12498 [BGP_STATS_ASPATH_COUNT]
12499 : 0);
12500 }
12501 break;
12502 case BGP_STATS_TOTPLEN:
12503 if (!json) {
12504 snprintf(
12505 temp_buf, sizeof(temp_buf), "%12.2f",
12506 ts.counts[i]
12507 ? (float)ts.counts[i]
12508 / (float)ts.counts
12509 [BGP_STATS_PREFIXES]
12510 : 0);
12511 vty_out(vty, "%-30s: %s",
12512 table_stats_strs[i]
12513 [TABLE_STATS_IDX_VTY],
12514 temp_buf);
12515 } else {
12516 json_object_double_add(
12517 json,
12518 table_stats_strs[i]
12519 [TABLE_STATS_IDX_JSON],
12520 ts.counts[i]
12521 ? (double)ts.counts[i]
12522 / (double)ts.counts
12523 [BGP_STATS_PREFIXES]
12524 : 0);
12525 }
12526 break;
12527 case BGP_STATS_SPACE:
12528 if (!json) {
12529 snprintf(temp_buf, sizeof(temp_buf), "%12g",
12530 ts.total_space);
12531 vty_out(vty, "%-30s: %s\n",
12532 table_stats_strs[i]
12533 [TABLE_STATS_IDX_VTY],
12534 temp_buf);
12535 } else {
12536 json_object_double_add(
12537 json,
12538 table_stats_strs[i]
12539 [TABLE_STATS_IDX_JSON],
12540 (double)ts.total_space);
12541 }
12542 if (afi == AFI_IP6) {
12543 if (!json) {
12544 snprintf(temp_buf, sizeof(temp_buf),
12545 "%12g",
12546 ts.total_space
12547 * pow(2.0, -128 + 32));
12548 vty_out(vty, "%30s: %s\n",
12549 "/32 equivalent %s\n",
12550 temp_buf);
12551 } else {
12552 json_object_double_add(
12553 json, "/32equivalent",
12554 (double)(ts.total_space
12555 * pow(2.0,
12556 -128 + 32)));
12557 }
12558 if (!json) {
12559 snprintf(temp_buf, sizeof(temp_buf),
12560 "%12g",
12561 ts.total_space
12562 * pow(2.0, -128 + 48));
12563 vty_out(vty, "%30s: %s\n",
12564 "/48 equivalent %s\n",
12565 temp_buf);
12566 } else {
12567 json_object_double_add(
12568 json, "/48equivalent",
12569 (double)(ts.total_space
12570 * pow(2.0,
12571 -128 + 48)));
12572 }
12573 } else {
12574 if (!json) {
12575 snprintf(temp_buf, sizeof(temp_buf),
12576 "%12.2f",
12577 ts.total_space * 100.
12578 * pow(2.0, -32));
12579 vty_out(vty, "%30s: %s\n",
12580 "% announced ", temp_buf);
12581 } else {
12582 json_object_double_add(
12583 json, "%announced",
12584 (double)(ts.total_space * 100.
12585 * pow(2.0, -32)));
12586 }
12587 if (!json) {
12588 snprintf(temp_buf, sizeof(temp_buf),
12589 "%12.2f",
12590 ts.total_space
12591 * pow(2.0, -32 + 8));
12592 vty_out(vty, "%30s: %s\n",
12593 "/8 equivalent ", temp_buf);
12594 } else {
12595 json_object_double_add(
12596 json, "/8equivalent",
12597 (double)(ts.total_space
12598 * pow(2.0, -32 + 8)));
12599 }
12600 if (!json) {
12601 snprintf(temp_buf, sizeof(temp_buf),
12602 "%12.2f",
12603 ts.total_space
12604 * pow(2.0, -32 + 24));
12605 vty_out(vty, "%30s: %s\n",
12606 "/24 equivalent ", temp_buf);
12607 } else {
12608 json_object_double_add(
12609 json, "/24equivalent",
12610 (double)(ts.total_space
12611 * pow(2.0, -32 + 24)));
12612 }
12613 }
12614 break;
12615 default:
12616 if (!json) {
12617 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
12618 ts.counts[i]);
12619 vty_out(vty, "%-30s: %s",
12620 table_stats_strs[i]
12621 [TABLE_STATS_IDX_VTY],
12622 temp_buf);
12623 } else {
12624 json_object_int_add(
12625 json,
12626 table_stats_strs[i]
12627 [TABLE_STATS_IDX_JSON],
12628 ts.counts[i]);
12629 }
12630 }
12631 if (!json)
12632 vty_out(vty, "\n");
12633 }
12634 end_table_stats:
12635 if (json)
12636 json_object_array_add(json_array, json);
12637 return ret;
12638 }
12639
12640 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12641 safi_t safi, struct json_object *json_array)
12642 {
12643 if (!bgp) {
12644 bgp_table_stats_all(vty, afi, safi, json_array);
12645 return CMD_SUCCESS;
12646 }
12647
12648 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
12649 }
12650
12651 enum bgp_pcounts {
12652 PCOUNT_ADJ_IN = 0,
12653 PCOUNT_DAMPED,
12654 PCOUNT_REMOVED,
12655 PCOUNT_HISTORY,
12656 PCOUNT_STALE,
12657 PCOUNT_VALID,
12658 PCOUNT_ALL,
12659 PCOUNT_COUNTED,
12660 PCOUNT_BPATH_SELECTED,
12661 PCOUNT_PFCNT, /* the figure we display to users */
12662 PCOUNT_MAX,
12663 };
12664
12665 static const char *const pcount_strs[] = {
12666 [PCOUNT_ADJ_IN] = "Adj-in",
12667 [PCOUNT_DAMPED] = "Damped",
12668 [PCOUNT_REMOVED] = "Removed",
12669 [PCOUNT_HISTORY] = "History",
12670 [PCOUNT_STALE] = "Stale",
12671 [PCOUNT_VALID] = "Valid",
12672 [PCOUNT_ALL] = "All RIB",
12673 [PCOUNT_COUNTED] = "PfxCt counted",
12674 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
12675 [PCOUNT_PFCNT] = "Useable",
12676 [PCOUNT_MAX] = NULL,
12677 };
12678
12679 struct peer_pcounts {
12680 unsigned int count[PCOUNT_MAX];
12681 const struct peer *peer;
12682 const struct bgp_table *table;
12683 safi_t safi;
12684 };
12685
12686 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
12687 {
12688 const struct bgp_adj_in *ain;
12689 const struct bgp_path_info *pi;
12690 const struct peer *peer = pc->peer;
12691
12692 for (ain = rn->adj_in; ain; ain = ain->next)
12693 if (ain->peer == peer)
12694 pc->count[PCOUNT_ADJ_IN]++;
12695
12696 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
12697
12698 if (pi->peer != peer)
12699 continue;
12700
12701 pc->count[PCOUNT_ALL]++;
12702
12703 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
12704 pc->count[PCOUNT_DAMPED]++;
12705 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
12706 pc->count[PCOUNT_HISTORY]++;
12707 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
12708 pc->count[PCOUNT_REMOVED]++;
12709 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
12710 pc->count[PCOUNT_STALE]++;
12711 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
12712 pc->count[PCOUNT_VALID]++;
12713 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
12714 pc->count[PCOUNT_PFCNT]++;
12715 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12716 pc->count[PCOUNT_BPATH_SELECTED]++;
12717
12718 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
12719 pc->count[PCOUNT_COUNTED]++;
12720 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
12721 flog_err(
12722 EC_LIB_DEVELOPMENT,
12723 "Attempting to count but flags say it is unusable");
12724 } else {
12725 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
12726 flog_err(
12727 EC_LIB_DEVELOPMENT,
12728 "Not counted but flags say we should");
12729 }
12730 }
12731 }
12732
12733 static int bgp_peer_count_walker(struct thread *t)
12734 {
12735 struct bgp_dest *rn, *rm;
12736 const struct bgp_table *table;
12737 struct peer_pcounts *pc = THREAD_ARG(t);
12738
12739 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
12740 || pc->safi == SAFI_EVPN) {
12741 /* Special handling for 2-level routing tables. */
12742 for (rn = bgp_table_top(pc->table); rn;
12743 rn = bgp_route_next(rn)) {
12744 table = bgp_dest_get_bgp_table_info(rn);
12745 if (table != NULL)
12746 for (rm = bgp_table_top(table); rm;
12747 rm = bgp_route_next(rm))
12748 bgp_peer_count_proc(rm, pc);
12749 }
12750 } else
12751 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
12752 bgp_peer_count_proc(rn, pc);
12753
12754 return 0;
12755 }
12756
12757 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
12758 safi_t safi, bool use_json)
12759 {
12760 struct peer_pcounts pcounts = {.peer = peer};
12761 unsigned int i;
12762 json_object *json = NULL;
12763 json_object *json_loop = NULL;
12764
12765 if (use_json) {
12766 json = json_object_new_object();
12767 json_loop = json_object_new_object();
12768 }
12769
12770 if (!peer || !peer->bgp || !peer->afc[afi][safi]
12771 || !peer->bgp->rib[afi][safi]) {
12772 if (use_json) {
12773 json_object_string_add(
12774 json, "warning",
12775 "No such neighbor or address family");
12776 vty_out(vty, "%s\n", json_object_to_json_string(json));
12777 json_object_free(json);
12778 json_object_free(json_loop);
12779 } else
12780 vty_out(vty, "%% No such neighbor or address family\n");
12781
12782 return CMD_WARNING;
12783 }
12784
12785 memset(&pcounts, 0, sizeof(pcounts));
12786 pcounts.peer = peer;
12787 pcounts.table = peer->bgp->rib[afi][safi];
12788 pcounts.safi = safi;
12789
12790 /* in-place call via thread subsystem so as to record execution time
12791 * stats for the thread-walk (i.e. ensure this can't be blamed on
12792 * on just vty_read()).
12793 */
12794 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
12795
12796 if (use_json) {
12797 json_object_string_add(json, "prefixCountsFor", peer->host);
12798 json_object_string_add(json, "multiProtocol",
12799 get_afi_safi_str(afi, safi, true));
12800 json_object_int_add(json, "pfxCounter",
12801 peer->pcount[afi][safi]);
12802
12803 for (i = 0; i < PCOUNT_MAX; i++)
12804 json_object_int_add(json_loop, pcount_strs[i],
12805 pcounts.count[i]);
12806
12807 json_object_object_add(json, "ribTableWalkCounters", json_loop);
12808
12809 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
12810 json_object_string_add(json, "pfxctDriftFor",
12811 peer->host);
12812 json_object_string_add(
12813 json, "recommended",
12814 "Please report this bug, with the above command output");
12815 }
12816 vty_out(vty, "%s\n", json_object_to_json_string_ext(
12817 json, JSON_C_TO_STRING_PRETTY));
12818 json_object_free(json);
12819 } else {
12820
12821 if (peer->hostname
12822 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
12823 vty_out(vty, "Prefix counts for %s/%s, %s\n",
12824 peer->hostname, peer->host,
12825 get_afi_safi_str(afi, safi, false));
12826 } else {
12827 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
12828 get_afi_safi_str(afi, safi, false));
12829 }
12830
12831 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
12832 vty_out(vty, "\nCounts from RIB table walk:\n\n");
12833
12834 for (i = 0; i < PCOUNT_MAX; i++)
12835 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
12836 pcounts.count[i]);
12837
12838 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
12839 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
12840 vty_out(vty,
12841 "Please report this bug, with the above command output\n");
12842 }
12843 }
12844
12845 return CMD_SUCCESS;
12846 }
12847
12848 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
12849 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
12850 "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]",
12851 SHOW_STR
12852 IP_STR
12853 BGP_STR
12854 BGP_INSTANCE_HELP_STR
12855 BGP_AFI_HELP_STR
12856 BGP_SAFI_HELP_STR
12857 "Detailed information on TCP and BGP neighbor connections\n"
12858 "Neighbor to display information about\n"
12859 "Neighbor to display information about\n"
12860 "Neighbor on BGP configured interface\n"
12861 "Display detailed prefix count information\n"
12862 JSON_STR)
12863 {
12864 afi_t afi = AFI_IP6;
12865 safi_t safi = SAFI_UNICAST;
12866 struct peer *peer;
12867 int idx = 0;
12868 struct bgp *bgp = NULL;
12869 bool uj = use_json(argc, argv);
12870
12871 if (uj)
12872 argc--;
12873
12874 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12875 &bgp, uj);
12876 if (!idx)
12877 return CMD_WARNING;
12878
12879 argv_find(argv, argc, "neighbors", &idx);
12880 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
12881 if (!peer)
12882 return CMD_WARNING;
12883
12884 return bgp_peer_counts(vty, peer, afi, safi, uj);
12885 }
12886
12887 #ifdef KEEP_OLD_VPN_COMMANDS
12888 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
12889 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
12890 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
12891 SHOW_STR
12892 IP_STR
12893 BGP_STR
12894 BGP_VPNVX_HELP_STR
12895 "Display information about all VPNv4 NLRIs\n"
12896 "Detailed information on TCP and BGP neighbor connections\n"
12897 "Neighbor to display information about\n"
12898 "Neighbor to display information about\n"
12899 "Neighbor on BGP configured interface\n"
12900 "Display detailed prefix count information\n"
12901 JSON_STR)
12902 {
12903 int idx_peer = 6;
12904 struct peer *peer;
12905 bool uj = use_json(argc, argv);
12906
12907 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
12908 if (!peer)
12909 return CMD_WARNING;
12910
12911 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
12912 }
12913
12914 DEFUN (show_ip_bgp_vpn_all_route_prefix,
12915 show_ip_bgp_vpn_all_route_prefix_cmd,
12916 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
12917 SHOW_STR
12918 IP_STR
12919 BGP_STR
12920 BGP_VPNVX_HELP_STR
12921 "Display information about all VPNv4 NLRIs\n"
12922 "Network in the BGP routing table to display\n"
12923 "Network in the BGP routing table to display\n"
12924 JSON_STR)
12925 {
12926 int idx = 0;
12927 char *network = NULL;
12928 struct bgp *bgp = bgp_get_default();
12929 if (!bgp) {
12930 vty_out(vty, "Can't find default instance\n");
12931 return CMD_WARNING;
12932 }
12933
12934 if (argv_find(argv, argc, "A.B.C.D", &idx))
12935 network = argv[idx]->arg;
12936 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
12937 network = argv[idx]->arg;
12938 else {
12939 vty_out(vty, "Unable to figure out Network\n");
12940 return CMD_WARNING;
12941 }
12942
12943 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
12944 BGP_PATH_SHOW_ALL, use_json(argc, argv));
12945 }
12946 #endif /* KEEP_OLD_VPN_COMMANDS */
12947
12948 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
12949 show_bgp_l2vpn_evpn_route_prefix_cmd,
12950 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
12951 SHOW_STR
12952 BGP_STR
12953 L2VPN_HELP_STR
12954 EVPN_HELP_STR
12955 "Network in the BGP routing table to display\n"
12956 "Network in the BGP routing table to display\n"
12957 "Network in the BGP routing table to display\n"
12958 "Network in the BGP routing table to display\n"
12959 JSON_STR)
12960 {
12961 int idx = 0;
12962 char *network = NULL;
12963 int prefix_check = 0;
12964
12965 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
12966 argv_find(argv, argc, "X:X::X:X", &idx))
12967 network = argv[idx]->arg;
12968 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
12969 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12970 network = argv[idx]->arg;
12971 prefix_check = 1;
12972 } else {
12973 vty_out(vty, "Unable to figure out Network\n");
12974 return CMD_WARNING;
12975 }
12976 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
12977 prefix_check, BGP_PATH_SHOW_ALL,
12978 use_json(argc, argv));
12979 }
12980
12981 static void show_adj_route_header(struct vty *vty, struct bgp *bgp,
12982 struct bgp_table *table, int *header1,
12983 int *header2, json_object *json,
12984 json_object *json_scode,
12985 json_object *json_ocode, bool wide)
12986 {
12987 uint64_t version = table ? table->version : 0;
12988 char buf[BUFSIZ] = {0};
12989
12990 if (*header1) {
12991 if (json) {
12992 json_object_int_add(json, "bgpTableVersion", version);
12993 json_object_string_add(json, "bgpLocalRouterId",
12994 inet_ntop(AF_INET,
12995 &bgp->router_id, buf,
12996 sizeof(buf)));
12997 json_object_int_add(json, "defaultLocPrf",
12998 bgp->default_local_pref);
12999 json_object_int_add(json, "localAS", bgp->as);
13000 json_object_object_add(json, "bgpStatusCodes",
13001 json_scode);
13002 json_object_object_add(json, "bgpOriginCodes",
13003 json_ocode);
13004 } else {
13005 vty_out(vty,
13006 "BGP table version is %" PRIu64
13007 ", local router ID is %pI4, vrf id ",
13008 version, &bgp->router_id);
13009 if (bgp->vrf_id == VRF_UNKNOWN)
13010 vty_out(vty, "%s", VRFID_NONE_STR);
13011 else
13012 vty_out(vty, "%u", bgp->vrf_id);
13013 vty_out(vty, "\n");
13014 vty_out(vty, "Default local pref %u, ",
13015 bgp->default_local_pref);
13016 vty_out(vty, "local AS %u\n", bgp->as);
13017 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13018 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13019 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13020 }
13021 *header1 = 0;
13022 }
13023 if (*header2) {
13024 if (!json)
13025 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
13026 : BGP_SHOW_HEADER));
13027 *header2 = 0;
13028 }
13029 }
13030
13031 static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
13032 safi_t safi, enum bgp_show_adj_route_type type,
13033 const char *rmap_name, json_object *json,
13034 uint8_t show_flags)
13035 {
13036 struct bgp_table *table;
13037 struct bgp_adj_in *ain;
13038 struct bgp_adj_out *adj;
13039 unsigned long output_count = 0;
13040 unsigned long filtered_count = 0;
13041 struct bgp_dest *dest;
13042 int header1 = 1;
13043 struct bgp *bgp;
13044 int header2 = 1;
13045 struct attr attr;
13046 int ret;
13047 struct update_subgroup *subgrp;
13048 json_object *json_scode = NULL;
13049 json_object *json_ocode = NULL;
13050 json_object *json_ar = NULL;
13051 struct peer_af *paf;
13052 bool route_filtered;
13053 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13054 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13055
13056 if (use_json) {
13057 json_scode = json_object_new_object();
13058 json_ocode = json_object_new_object();
13059 json_ar = json_object_new_object();
13060
13061 json_object_string_add(json_scode, "suppressed", "s");
13062 json_object_string_add(json_scode, "damped", "d");
13063 json_object_string_add(json_scode, "history", "h");
13064 json_object_string_add(json_scode, "valid", "*");
13065 json_object_string_add(json_scode, "best", ">");
13066 json_object_string_add(json_scode, "multipath", "=");
13067 json_object_string_add(json_scode, "internal", "i");
13068 json_object_string_add(json_scode, "ribFailure", "r");
13069 json_object_string_add(json_scode, "stale", "S");
13070 json_object_string_add(json_scode, "removed", "R");
13071
13072 json_object_string_add(json_ocode, "igp", "i");
13073 json_object_string_add(json_ocode, "egp", "e");
13074 json_object_string_add(json_ocode, "incomplete", "?");
13075 }
13076
13077 bgp = peer->bgp;
13078
13079 if (!bgp) {
13080 if (use_json) {
13081 json_object_string_add(json, "alert", "no BGP");
13082 vty_out(vty, "%s\n", json_object_to_json_string(json));
13083 json_object_free(json);
13084 } else
13085 vty_out(vty, "%% No bgp\n");
13086 return;
13087 }
13088
13089 /* labeled-unicast routes live in the unicast table */
13090 if (safi == SAFI_LABELED_UNICAST)
13091 table = bgp->rib[afi][SAFI_UNICAST];
13092 else
13093 table = bgp->rib[afi][safi];
13094
13095 output_count = filtered_count = 0;
13096 subgrp = peer_subgroup(peer, afi, safi);
13097
13098 if (type == bgp_show_adj_route_advertised && subgrp
13099 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
13100 char buf[BUFSIZ] = {0};
13101
13102 if (use_json) {
13103 json_object_int_add(json, "bgpTableVersion",
13104 table->version);
13105 json_object_string_add(json, "bgpLocalRouterId",
13106 inet_ntop(AF_INET,
13107 &bgp->router_id, buf,
13108 sizeof(buf)));
13109 json_object_int_add(json, "defaultLocPrf",
13110 bgp->default_local_pref);
13111 json_object_int_add(json, "localAS", bgp->as);
13112 json_object_object_add(json, "bgpStatusCodes",
13113 json_scode);
13114 json_object_object_add(json, "bgpOriginCodes",
13115 json_ocode);
13116 json_object_string_add(
13117 json, "bgpOriginatingDefaultNetwork",
13118 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13119 } else {
13120 vty_out(vty,
13121 "BGP table version is %" PRIu64
13122 ", local router ID is %pI4, vrf id ",
13123 table->version, &bgp->router_id);
13124 if (bgp->vrf_id == VRF_UNKNOWN)
13125 vty_out(vty, "%s", VRFID_NONE_STR);
13126 else
13127 vty_out(vty, "%u", bgp->vrf_id);
13128 vty_out(vty, "\n");
13129 vty_out(vty, "Default local pref %u, ",
13130 bgp->default_local_pref);
13131 vty_out(vty, "local AS %u\n", bgp->as);
13132 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13133 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13134 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13135
13136 vty_out(vty, "Originating default network %s\n\n",
13137 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13138 }
13139 header1 = 0;
13140 }
13141
13142 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
13143 if (type == bgp_show_adj_route_received
13144 || type == bgp_show_adj_route_filtered) {
13145 for (ain = dest->adj_in; ain; ain = ain->next) {
13146 if (ain->peer != peer)
13147 continue;
13148
13149 show_adj_route_header(
13150 vty, bgp, table, &header1, &header2,
13151 json, json_scode, json_ocode, wide);
13152
13153 attr = *ain->attr;
13154 route_filtered = false;
13155
13156 /* Filter prefix using distribute list,
13157 * filter list or prefix list
13158 */
13159 const struct prefix *rn_p =
13160 bgp_dest_get_prefix(dest);
13161 if ((bgp_input_filter(peer, rn_p, &attr, afi,
13162 safi))
13163 == FILTER_DENY)
13164 route_filtered = true;
13165
13166 /* Filter prefix using route-map */
13167 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
13168 safi, rmap_name, NULL,
13169 0, NULL);
13170
13171 if (type == bgp_show_adj_route_filtered &&
13172 !route_filtered && ret != RMAP_DENY) {
13173 bgp_attr_undup(&attr, ain->attr);
13174 continue;
13175 }
13176
13177 if (type == bgp_show_adj_route_received &&
13178 (route_filtered || ret == RMAP_DENY))
13179 filtered_count++;
13180
13181 route_vty_out_tmp(vty, rn_p, &attr, safi,
13182 use_json, json_ar, wide);
13183 bgp_attr_undup(&attr, ain->attr);
13184 output_count++;
13185 }
13186 } else if (type == bgp_show_adj_route_advertised) {
13187 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
13188 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
13189 if (paf->peer != peer || !adj->attr)
13190 continue;
13191
13192 show_adj_route_header(
13193 vty, bgp, table, &header1,
13194 &header2, json, json_scode,
13195 json_ocode, wide);
13196
13197 const struct prefix *rn_p =
13198 bgp_dest_get_prefix(dest);
13199
13200 attr = *adj->attr;
13201 ret = bgp_output_modifier(
13202 peer, rn_p, &attr, afi, safi,
13203 rmap_name);
13204
13205 if (ret != RMAP_DENY) {
13206 route_vty_out_tmp(
13207 vty, rn_p, &attr, safi,
13208 use_json, json_ar,
13209 wide);
13210 output_count++;
13211 } else {
13212 filtered_count++;
13213 }
13214
13215 bgp_attr_undup(&attr, adj->attr);
13216 }
13217 } else if (type == bgp_show_adj_route_bestpath) {
13218 struct bgp_path_info *pi;
13219
13220 show_adj_route_header(vty, bgp, table, &header1,
13221 &header2, json, json_scode,
13222 json_ocode, wide);
13223
13224 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
13225 pi = pi->next) {
13226 if (pi->peer != peer)
13227 continue;
13228
13229 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13230 continue;
13231
13232 route_vty_out_tmp(vty,
13233 bgp_dest_get_prefix(dest),
13234 pi->attr, safi, use_json,
13235 json_ar, wide);
13236 output_count++;
13237 }
13238 }
13239 }
13240
13241 if (use_json) {
13242 json_object_object_add(json, "advertisedRoutes", json_ar);
13243 json_object_int_add(json, "totalPrefixCounter", output_count);
13244 json_object_int_add(json, "filteredPrefixCounter",
13245 filtered_count);
13246
13247 vty_out(vty, "%s\n", json_object_to_json_string_ext(
13248 json, JSON_C_TO_STRING_PRETTY));
13249
13250 if (!output_count && !filtered_count) {
13251 json_object_free(json_scode);
13252 json_object_free(json_ocode);
13253 }
13254
13255 json_object_free(json);
13256 } else if (output_count > 0) {
13257 if (filtered_count > 0)
13258 vty_out(vty,
13259 "\nTotal number of prefixes %ld (%ld filtered)\n",
13260 output_count, filtered_count);
13261 else
13262 vty_out(vty, "\nTotal number of prefixes %ld\n",
13263 output_count);
13264 }
13265 }
13266
13267 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
13268 safi_t safi, enum bgp_show_adj_route_type type,
13269 const char *rmap_name, uint8_t show_flags)
13270 {
13271 json_object *json = NULL;
13272 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13273
13274 if (use_json)
13275 json = json_object_new_object();
13276
13277 if (!peer || !peer->afc[afi][safi]) {
13278 if (use_json) {
13279 json_object_string_add(
13280 json, "warning",
13281 "No such neighbor or address family");
13282 vty_out(vty, "%s\n", json_object_to_json_string(json));
13283 json_object_free(json);
13284 } else
13285 vty_out(vty, "%% No such neighbor or address family\n");
13286
13287 return CMD_WARNING;
13288 }
13289
13290 if ((type == bgp_show_adj_route_received
13291 || type == bgp_show_adj_route_filtered)
13292 && !CHECK_FLAG(peer->af_flags[afi][safi],
13293 PEER_FLAG_SOFT_RECONFIG)) {
13294 if (use_json) {
13295 json_object_string_add(
13296 json, "warning",
13297 "Inbound soft reconfiguration not enabled");
13298 vty_out(vty, "%s\n", json_object_to_json_string(json));
13299 json_object_free(json);
13300 } else
13301 vty_out(vty,
13302 "%% Inbound soft reconfiguration not enabled\n");
13303
13304 return CMD_WARNING;
13305 }
13306
13307 show_adj_route(vty, peer, afi, safi, type, rmap_name, json, show_flags);
13308
13309 return CMD_SUCCESS;
13310 }
13311
13312 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
13313 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
13314 "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]",
13315 SHOW_STR
13316 IP_STR
13317 BGP_STR
13318 BGP_INSTANCE_HELP_STR
13319 BGP_AFI_HELP_STR
13320 BGP_SAFI_WITH_LABEL_HELP_STR
13321 "Detailed information on TCP and BGP neighbor connections\n"
13322 "Neighbor to display information about\n"
13323 "Neighbor to display information about\n"
13324 "Neighbor on BGP configured interface\n"
13325 "Display the routes selected by best path\n"
13326 JSON_STR
13327 "Increase table width for longer prefixes\n")
13328 {
13329 afi_t afi = AFI_IP6;
13330 safi_t safi = SAFI_UNICAST;
13331 char *rmap_name = NULL;
13332 char *peerstr = NULL;
13333 struct bgp *bgp = NULL;
13334 struct peer *peer;
13335 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
13336 int idx = 0;
13337 uint8_t show_flags = 0;
13338
13339 if (uj)
13340 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13341
13342 if (wide)
13343 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13344
13345 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13346 &bgp, uj);
13347
13348 if (!idx)
13349 return CMD_WARNING;
13350
13351 argv_find(argv, argc, "neighbors", &idx);
13352 peerstr = argv[++idx]->arg;
13353
13354 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13355 if (!peer)
13356 return CMD_WARNING;
13357
13358 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13359 show_flags);
13360 }
13361
13362 DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
13363 show_ip_bgp_instance_neighbor_advertised_route_cmd,
13364 "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]",
13365 SHOW_STR
13366 IP_STR
13367 BGP_STR
13368 BGP_INSTANCE_HELP_STR
13369 BGP_AFI_HELP_STR
13370 BGP_SAFI_WITH_LABEL_HELP_STR
13371 "Display the entries for all address families\n"
13372 "Detailed information on TCP and BGP neighbor connections\n"
13373 "Neighbor to display information about\n"
13374 "Neighbor to display information about\n"
13375 "Neighbor on BGP configured interface\n"
13376 "Display the routes advertised to a BGP neighbor\n"
13377 "Display the received routes from neighbor\n"
13378 "Display the filtered routes received from neighbor\n"
13379 "Route-map to modify the attributes\n"
13380 "Name of the route map\n"
13381 JSON_STR
13382 "Increase table width for longer prefixes\n")
13383 {
13384 afi_t afi = AFI_IP6;
13385 safi_t safi = SAFI_UNICAST;
13386 char *rmap_name = NULL;
13387 char *peerstr = NULL;
13388 struct bgp *bgp = NULL;
13389 struct peer *peer;
13390 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
13391 int idx = 0;
13392 bool first = true;
13393 uint8_t show_flags = 0;
13394
13395 if (uj) {
13396 argc--;
13397 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13398 }
13399
13400 if (all) {
13401 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
13402 if (argv_find(argv, argc, "ipv4", &idx))
13403 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
13404
13405 if (argv_find(argv, argc, "ipv6", &idx))
13406 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
13407 }
13408
13409 if (wide)
13410 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13411
13412 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13413 &bgp, uj);
13414 if (!idx)
13415 return CMD_WARNING;
13416
13417 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
13418 argv_find(argv, argc, "neighbors", &idx);
13419 peerstr = argv[++idx]->arg;
13420
13421 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13422 if (!peer)
13423 return CMD_WARNING;
13424
13425 if (argv_find(argv, argc, "advertised-routes", &idx))
13426 type = bgp_show_adj_route_advertised;
13427 else if (argv_find(argv, argc, "received-routes", &idx))
13428 type = bgp_show_adj_route_received;
13429 else if (argv_find(argv, argc, "filtered-routes", &idx))
13430 type = bgp_show_adj_route_filtered;
13431
13432 if (argv_find(argv, argc, "route-map", &idx))
13433 rmap_name = argv[++idx]->arg;
13434
13435 if (!all)
13436 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13437 show_flags);
13438 if (uj)
13439 vty_out(vty, "{\n");
13440
13441 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
13442 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
13443 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
13444 : AFI_IP6;
13445 FOREACH_SAFI (safi) {
13446 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
13447 continue;
13448
13449 if (uj) {
13450 if (first)
13451 first = false;
13452 else
13453 vty_out(vty, ",\n");
13454 vty_out(vty, "\"%s\":",
13455 get_afi_safi_str(afi, safi, true));
13456 } else
13457 vty_out(vty, "\nFor address family: %s\n",
13458 get_afi_safi_str(afi, safi, false));
13459
13460 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13461 show_flags);
13462 }
13463 } else {
13464 FOREACH_AFI_SAFI (afi, safi) {
13465 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
13466 continue;
13467
13468 if (uj) {
13469 if (first)
13470 first = false;
13471 else
13472 vty_out(vty, ",\n");
13473 vty_out(vty, "\"%s\":",
13474 get_afi_safi_str(afi, safi, true));
13475 } else
13476 vty_out(vty, "\nFor address family: %s\n",
13477 get_afi_safi_str(afi, safi, false));
13478
13479 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13480 show_flags);
13481 }
13482 }
13483 if (uj)
13484 vty_out(vty, "}\n");
13485
13486 return CMD_SUCCESS;
13487 }
13488
13489 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
13490 show_ip_bgp_neighbor_received_prefix_filter_cmd,
13491 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
13492 SHOW_STR
13493 IP_STR
13494 BGP_STR
13495 "Address Family\n"
13496 "Address Family\n"
13497 "Address Family modifier\n"
13498 "Detailed information on TCP and BGP neighbor connections\n"
13499 "Neighbor to display information about\n"
13500 "Neighbor to display information about\n"
13501 "Neighbor on BGP configured interface\n"
13502 "Display information received from a BGP neighbor\n"
13503 "Display the prefixlist filter\n"
13504 JSON_STR)
13505 {
13506 afi_t afi = AFI_IP6;
13507 safi_t safi = SAFI_UNICAST;
13508 char *peerstr = NULL;
13509
13510 char name[BUFSIZ];
13511 union sockunion su;
13512 struct peer *peer;
13513 int count, ret;
13514
13515 int idx = 0;
13516
13517 /* show [ip] bgp */
13518 if (argv_find(argv, argc, "ip", &idx))
13519 afi = AFI_IP;
13520 /* [<ipv4|ipv6> [unicast]] */
13521 if (argv_find(argv, argc, "ipv4", &idx))
13522 afi = AFI_IP;
13523 if (argv_find(argv, argc, "ipv6", &idx))
13524 afi = AFI_IP6;
13525 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
13526 argv_find(argv, argc, "neighbors", &idx);
13527 peerstr = argv[++idx]->arg;
13528
13529 bool uj = use_json(argc, argv);
13530
13531 ret = str2sockunion(peerstr, &su);
13532 if (ret < 0) {
13533 peer = peer_lookup_by_conf_if(NULL, peerstr);
13534 if (!peer) {
13535 if (uj)
13536 vty_out(vty, "{}\n");
13537 else
13538 vty_out(vty,
13539 "%% Malformed address or name: %s\n",
13540 peerstr);
13541 return CMD_WARNING;
13542 }
13543 } else {
13544 peer = peer_lookup(NULL, &su);
13545 if (!peer) {
13546 if (uj)
13547 vty_out(vty, "{}\n");
13548 else
13549 vty_out(vty, "No peer\n");
13550 return CMD_WARNING;
13551 }
13552 }
13553
13554 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
13555 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
13556 if (count) {
13557 if (!uj)
13558 vty_out(vty, "Address Family: %s\n",
13559 get_afi_safi_str(afi, safi, false));
13560 prefix_bgp_show_prefix_list(vty, afi, name, uj);
13561 } else {
13562 if (uj)
13563 vty_out(vty, "{}\n");
13564 else
13565 vty_out(vty, "No functional output\n");
13566 }
13567
13568 return CMD_SUCCESS;
13569 }
13570
13571 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
13572 afi_t afi, safi_t safi,
13573 enum bgp_show_type type, bool use_json)
13574 {
13575 uint8_t show_flags = 0;
13576
13577 if (use_json)
13578 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13579
13580 if (!peer || !peer->afc[afi][safi]) {
13581 if (use_json) {
13582 json_object *json_no = NULL;
13583 json_no = json_object_new_object();
13584 json_object_string_add(
13585 json_no, "warning",
13586 "No such neighbor or address family");
13587 vty_out(vty, "%s\n",
13588 json_object_to_json_string(json_no));
13589 json_object_free(json_no);
13590 } else
13591 vty_out(vty, "%% No such neighbor or address family\n");
13592 return CMD_WARNING;
13593 }
13594
13595 /* labeled-unicast routes live in the unicast table */
13596 if (safi == SAFI_LABELED_UNICAST)
13597 safi = SAFI_UNICAST;
13598
13599 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags);
13600 }
13601
13602 DEFUN (show_ip_bgp_flowspec_routes_detailed,
13603 show_ip_bgp_flowspec_routes_detailed_cmd,
13604 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
13605 SHOW_STR
13606 IP_STR
13607 BGP_STR
13608 BGP_INSTANCE_HELP_STR
13609 BGP_AFI_HELP_STR
13610 "SAFI Flowspec\n"
13611 "Detailed information on flowspec entries\n"
13612 JSON_STR)
13613 {
13614 afi_t afi = AFI_IP;
13615 safi_t safi = SAFI_UNICAST;
13616 struct bgp *bgp = NULL;
13617 int idx = 0;
13618 bool uj = use_json(argc, argv);
13619 uint8_t show_flags = 0;
13620
13621 if (uj) {
13622 argc--;
13623 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13624 }
13625
13626 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13627 &bgp, uj);
13628 if (!idx)
13629 return CMD_WARNING;
13630
13631 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
13632 show_flags);
13633 }
13634
13635 DEFUN (show_ip_bgp_neighbor_routes,
13636 show_ip_bgp_neighbor_routes_cmd,
13637 "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]",
13638 SHOW_STR
13639 IP_STR
13640 BGP_STR
13641 BGP_INSTANCE_HELP_STR
13642 BGP_AFI_HELP_STR
13643 BGP_SAFI_WITH_LABEL_HELP_STR
13644 "Detailed information on TCP and BGP neighbor connections\n"
13645 "Neighbor to display information about\n"
13646 "Neighbor to display information about\n"
13647 "Neighbor on BGP configured interface\n"
13648 "Display flap statistics of the routes learned from neighbor\n"
13649 "Display the dampened routes received from neighbor\n"
13650 "Display routes learned from neighbor\n"
13651 JSON_STR)
13652 {
13653 char *peerstr = NULL;
13654 struct bgp *bgp = NULL;
13655 afi_t afi = AFI_IP6;
13656 safi_t safi = SAFI_UNICAST;
13657 struct peer *peer;
13658 enum bgp_show_type sh_type = bgp_show_type_neighbor;
13659 int idx = 0;
13660 bool uj = use_json(argc, argv);
13661
13662 if (uj)
13663 argc--;
13664
13665 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13666 &bgp, uj);
13667 if (!idx)
13668 return CMD_WARNING;
13669
13670 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
13671 argv_find(argv, argc, "neighbors", &idx);
13672 peerstr = argv[++idx]->arg;
13673
13674 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13675 if (!peer)
13676 return CMD_WARNING;
13677
13678 if (argv_find(argv, argc, "flap-statistics", &idx))
13679 sh_type = bgp_show_type_flap_neighbor;
13680 else if (argv_find(argv, argc, "dampened-routes", &idx))
13681 sh_type = bgp_show_type_damp_neighbor;
13682 else if (argv_find(argv, argc, "routes", &idx))
13683 sh_type = bgp_show_type_neighbor;
13684
13685 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
13686 }
13687
13688 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
13689
13690 struct bgp_distance {
13691 /* Distance value for the IP source prefix. */
13692 uint8_t distance;
13693
13694 /* Name of the access-list to be matched. */
13695 char *access_list;
13696 };
13697
13698 DEFUN (show_bgp_afi_vpn_rd_route,
13699 show_bgp_afi_vpn_rd_route_cmd,
13700 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN <A.B.C.D/M|X:X::X:X/M> [json]",
13701 SHOW_STR
13702 BGP_STR
13703 BGP_AFI_HELP_STR
13704 "Address Family modifier\n"
13705 "Display information for a route distinguisher\n"
13706 "Route Distinguisher\n"
13707 "Network in the BGP routing table to display\n"
13708 "Network in the BGP routing table to display\n"
13709 JSON_STR)
13710 {
13711 int ret;
13712 struct prefix_rd prd;
13713 afi_t afi = AFI_MAX;
13714 int idx = 0;
13715
13716 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
13717 vty_out(vty, "%% Malformed Address Family\n");
13718 return CMD_WARNING;
13719 }
13720
13721 ret = str2prefix_rd(argv[5]->arg, &prd);
13722 if (!ret) {
13723 vty_out(vty, "%% Malformed Route Distinguisher\n");
13724 return CMD_WARNING;
13725 }
13726
13727 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
13728 0, BGP_PATH_SHOW_ALL, use_json(argc, argv));
13729 }
13730
13731 static struct bgp_distance *bgp_distance_new(void)
13732 {
13733 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
13734 }
13735
13736 static void bgp_distance_free(struct bgp_distance *bdistance)
13737 {
13738 XFREE(MTYPE_BGP_DISTANCE, bdistance);
13739 }
13740
13741 int bgp_distance_set(uint8_t distance, const char *ip_str,
13742 const char *access_list_str, afi_t afi, safi_t safi,
13743 char *errmsg, size_t errmsg_len)
13744 {
13745 int ret;
13746 struct prefix p;
13747 struct bgp_dest *dest;
13748 struct bgp_distance *bdistance;
13749
13750 ret = str2prefix(ip_str, &p);
13751 if (ret == 0) {
13752 snprintf(errmsg, errmsg_len, "Malformed prefix\n");
13753 return CMD_WARNING_CONFIG_FAILED;
13754 }
13755
13756 /* Get BGP distance node. */
13757 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
13758 bdistance = bgp_dest_get_bgp_distance_info(dest);
13759 if (bdistance)
13760 bgp_dest_unlock_node(dest);
13761 else {
13762 bdistance = bgp_distance_new();
13763 bgp_dest_set_bgp_distance_info(dest, bdistance);
13764 }
13765
13766 /* Set distance value. */
13767 bdistance->distance = distance;
13768
13769 /* Reset access-list configuration. */
13770 XFREE(MTYPE_AS_LIST, bdistance->access_list);
13771 if (access_list_str)
13772 bdistance->access_list =
13773 XSTRDUP(MTYPE_AS_LIST, access_list_str);
13774
13775 return CMD_SUCCESS;
13776 }
13777
13778 int bgp_distance_unset(uint8_t distance, const char *ip_str,
13779 const char *access_list_str, afi_t afi, safi_t safi,
13780 char *errmsg, size_t errmsg_len)
13781 {
13782 int ret;
13783 struct prefix p;
13784 struct bgp_dest *dest;
13785 struct bgp_distance *bdistance;
13786
13787 ret = str2prefix(ip_str, &p);
13788 if (ret == 0) {
13789 snprintf(errmsg, errmsg_len, "Malformed prefix\n");
13790 return CMD_WARNING_CONFIG_FAILED;
13791 }
13792
13793 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
13794 if (!dest) {
13795 snprintf(errmsg, errmsg_len, "Can't find specified prefix\n");
13796 return CMD_WARNING_CONFIG_FAILED;
13797 }
13798
13799 bdistance = bgp_dest_get_bgp_distance_info(dest);
13800
13801 if (bdistance->distance != distance) {
13802 snprintf(errmsg, errmsg_len,
13803 "Distance does not match configured\n");
13804 return CMD_WARNING_CONFIG_FAILED;
13805 }
13806
13807 XFREE(MTYPE_AS_LIST, bdistance->access_list);
13808 bgp_distance_free(bdistance);
13809
13810 bgp_dest_set_bgp_path_info(dest, NULL);
13811 bgp_dest_unlock_node(dest);
13812 bgp_dest_unlock_node(dest);
13813
13814 return CMD_SUCCESS;
13815 }
13816
13817 /* Apply BGP information to distance method. */
13818 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
13819 afi_t afi, safi_t safi, struct bgp *bgp)
13820 {
13821 struct bgp_dest *dest;
13822 struct prefix q = {0};
13823 struct peer *peer;
13824 struct bgp_distance *bdistance;
13825 struct access_list *alist;
13826 struct bgp_static *bgp_static;
13827
13828 if (!bgp)
13829 return 0;
13830
13831 peer = pinfo->peer;
13832
13833 if (pinfo->attr->distance)
13834 return pinfo->attr->distance;
13835
13836 /* Check source address.
13837 * Note: for aggregate route, peer can have unspec af type.
13838 */
13839 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
13840 && !sockunion2hostprefix(&peer->su, &q))
13841 return 0;
13842
13843 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
13844 if (dest) {
13845 bdistance = bgp_dest_get_bgp_distance_info(dest);
13846 bgp_dest_unlock_node(dest);
13847
13848 if (bdistance->access_list) {
13849 alist = access_list_lookup(afi, bdistance->access_list);
13850 if (alist
13851 && access_list_apply(alist, p) == FILTER_PERMIT)
13852 return bdistance->distance;
13853 } else
13854 return bdistance->distance;
13855 }
13856
13857 /* Backdoor check. */
13858 dest = bgp_node_lookup(bgp->route[afi][safi], p);
13859 if (dest) {
13860 bgp_static = bgp_dest_get_bgp_static_info(dest);
13861 bgp_dest_unlock_node(dest);
13862
13863 if (bgp_static->backdoor) {
13864 if (bgp->distance_local[afi][safi])
13865 return bgp->distance_local[afi][safi];
13866 else
13867 return ZEBRA_IBGP_DISTANCE_DEFAULT;
13868 }
13869 }
13870
13871 if (peer->sort == BGP_PEER_EBGP) {
13872 if (bgp->distance_ebgp[afi][safi])
13873 return bgp->distance_ebgp[afi][safi];
13874 return ZEBRA_EBGP_DISTANCE_DEFAULT;
13875 } else if (peer->sort == BGP_PEER_IBGP) {
13876 if (bgp->distance_ibgp[afi][safi])
13877 return bgp->distance_ibgp[afi][safi];
13878 return ZEBRA_IBGP_DISTANCE_DEFAULT;
13879 } else {
13880 if (bgp->distance_local[afi][safi])
13881 return bgp->distance_local[afi][safi];
13882 return ZEBRA_IBGP_DISTANCE_DEFAULT;
13883 }
13884 }
13885
13886 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
13887 * we should tell ZEBRA update the routes for a specific
13888 * AFI/SAFI to reflect changes in RIB.
13889 */
13890 void bgp_announce_routes_distance_update(struct bgp *bgp, afi_t update_afi,
13891 safi_t update_safi)
13892 {
13893 afi_t afi;
13894 safi_t safi;
13895
13896 FOREACH_AFI_SAFI (afi, safi) {
13897 if (!bgp_fibupd_safi(safi))
13898 continue;
13899
13900 if (afi != update_afi && safi != update_safi)
13901 continue;
13902
13903 if (BGP_DEBUG(zebra, ZEBRA))
13904 zlog_debug(
13905 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
13906 __func__, afi, safi);
13907 bgp_zebra_announce_table(bgp, afi, safi);
13908 }
13909 }
13910
13911 DEFUN_YANG(bgp_distance, bgp_distance_cmd,
13912 "distance bgp (1-255) (1-255) (1-255)",
13913 "Define an administrative distance\n"
13914 "BGP distance\n"
13915 "Distance for routes external to the AS\n"
13916 "Distance for routes internal to the AS\n"
13917 "Distance for local routes\n")
13918 {
13919 int idx_number = 2;
13920 int idx_number_2 = 3;
13921 int idx_number_3 = 4;
13922 afi_t afi;
13923 safi_t safi;
13924 char xpath[XPATH_MAXLEN];
13925
13926 afi = bgp_node_afi(vty);
13927 safi = bgp_node_safi(vty);
13928
13929 snprintf(
13930 xpath, sizeof(xpath),
13931 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/external",
13932 yang_afi_safi_value2identity(afi, safi),
13933 bgp_afi_safi_get_container_str(afi, safi));
13934 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, argv[idx_number]->arg);
13935 snprintf(
13936 xpath, sizeof(xpath),
13937 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/internal",
13938 yang_afi_safi_value2identity(afi, safi),
13939 bgp_afi_safi_get_container_str(afi, safi));
13940 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
13941 argv[idx_number_2]->arg);
13942 snprintf(
13943 xpath, sizeof(xpath),
13944 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/local",
13945 yang_afi_safi_value2identity(afi, safi),
13946 bgp_afi_safi_get_container_str(afi, safi));
13947
13948 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
13949 argv[idx_number_3]->arg);
13950
13951 return nb_cli_apply_changes(vty, NULL);
13952 }
13953
13954 DEFUN_YANG(no_bgp_distance, no_bgp_distance_cmd,
13955 "no distance bgp [(1-255) (1-255) (1-255)]",
13956 NO_STR
13957 "Define an administrative distance\n"
13958 "BGP distance\n"
13959 "Distance for routes external to the AS\n"
13960 "Distance for routes internal to the AS\n"
13961 "Distance for local routes\n")
13962 {
13963 afi_t afi;
13964 safi_t safi;
13965 char xpath[XPATH_MAXLEN];
13966
13967 afi = bgp_node_afi(vty);
13968 safi = bgp_node_safi(vty);
13969
13970 snprintf(
13971 xpath, sizeof(xpath),
13972 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/external",
13973 yang_afi_safi_value2identity(afi, safi),
13974 bgp_afi_safi_get_container_str(afi, safi));
13975 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL);
13976 snprintf(
13977 xpath, sizeof(xpath),
13978 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/internal",
13979 yang_afi_safi_value2identity(afi, safi),
13980 bgp_afi_safi_get_container_str(afi, safi));
13981 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL);
13982 snprintf(
13983 xpath, sizeof(xpath),
13984 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/local",
13985 yang_afi_safi_value2identity(afi, safi),
13986 bgp_afi_safi_get_container_str(afi, safi));
13987
13988 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL);
13989
13990 return nb_cli_apply_changes(vty, NULL);
13991 }
13992
13993 void cli_show_bgp_global_afi_safi_admin_distance_config(struct vty *vty,
13994 struct lyd_node *dnode,
13995 bool show_defaults)
13996 {
13997 uint8_t distance_ebgp, distance_ibgp, distance_local;
13998
13999 distance_ebgp = yang_dnode_get_uint8(dnode, "./external");
14000 distance_ibgp = yang_dnode_get_uint8(dnode, "./internal");
14001 distance_local = yang_dnode_get_uint8(dnode, "./local");
14002
14003 vty_out(vty, " distance bgp %d %d %d\n", distance_ebgp, distance_ibgp,
14004 distance_local);
14005 }
14006
14007 DEFPY_YANG(bgp_distance_source,
14008 bgp_distance_source_cmd,
14009 "[no] distance (1-255) <A.B.C.D/M | X:X::X:X/M>$prefix [WORD$acl]",
14010 NO_STR
14011 "Define an administrative distance\n"
14012 "Distance value\n"
14013 "IPv4 source prefix\n"
14014 "IPv6 source prefix\n"
14015 "Access list name\n")
14016 {
14017 afi_t afi;
14018 safi_t safi;
14019 char xpath[XPATH_MAXLEN];
14020
14021 afi = bgp_node_afi(vty);
14022 safi = bgp_node_safi(vty);
14023
14024 if (!no) {
14025 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
14026 nb_cli_enqueue_change(vty, "./distance", NB_OP_MODIFY,
14027 distance_str);
14028 if (acl)
14029 nb_cli_enqueue_change(vty,
14030 "./access-list-policy-export",
14031 NB_OP_CREATE, acl);
14032 else
14033 nb_cli_enqueue_change(vty,
14034 "./access-list-policy-export",
14035 NB_OP_DESTROY, NULL);
14036 } else {
14037 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
14038 }
14039
14040 snprintf(
14041 xpath, sizeof(xpath),
14042 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance-route[prefix='%s']",
14043 yang_afi_safi_value2identity(afi, safi),
14044 bgp_afi_safi_get_container_str(afi, safi), prefix_str);
14045
14046 return nb_cli_apply_changes(vty, xpath);
14047 }
14048
14049 void cli_show_bgp_global_afi_safi_unicast_admin_distance_route(
14050 struct vty *vty, struct lyd_node *dnode, bool show_defaults)
14051 {
14052 vty_out(vty, " distance %d %s %s\n",
14053 yang_dnode_get_uint8(dnode, "./distance"),
14054 yang_dnode_get_string(dnode, "./prefix"),
14055 (yang_dnode_exists(dnode, "./access-list-policy-export"))
14056 ? yang_dnode_get_string(dnode,
14057 "./access-list-policy-export")
14058 : "");
14059 }
14060
14061 DEFPY_YANG(
14062 bgp_dampening, bgp_dampening_cmd,
14063 "[no] bgp dampening [(1-45)$halflife [(1-20000)$reuse (1-20000)$suppress (1-255)$max_suppress]]",
14064 NO_STR
14065 "BGP Specific commands\n"
14066 "Enable route-flap dampening\n"
14067 "Half-life time for the penalty\n"
14068 "Value to start reusing a route\n"
14069 "Value to start suppressing a route\n"
14070 "Maximum duration to suppress a stable route\n")
14071 {
14072 afi_t afi;
14073 safi_t safi;
14074 char xpath[XPATH_MAXLEN];
14075
14076 afi = bgp_node_afi(vty);
14077 safi = bgp_node_safi(vty);
14078
14079 if (!no) {
14080 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "true");
14081 if (argc == 6) {
14082 nb_cli_enqueue_change(vty, "./reach-decay",
14083 NB_OP_MODIFY, halflife_str);
14084 nb_cli_enqueue_change(vty, "./reuse-above",
14085 NB_OP_MODIFY, reuse_str);
14086 nb_cli_enqueue_change(vty, "./suppress-above",
14087 NB_OP_MODIFY, suppress_str);
14088 nb_cli_enqueue_change(vty, "./unreach-decay",
14089 NB_OP_MODIFY, max_suppress_str);
14090 } if (argc == 3) {
14091 nb_cli_enqueue_change(vty, "./reach-decay",
14092 NB_OP_MODIFY, halflife_str);
14093 }
14094 } else {
14095 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "false");
14096 }
14097
14098 snprintf(
14099 xpath, sizeof(xpath),
14100 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/route-flap-dampening",
14101 yang_afi_safi_value2identity(afi, safi),
14102 bgp_afi_safi_get_container_str(afi, safi));
14103
14104 return nb_cli_apply_changes(vty, xpath);
14105 }
14106
14107 void cli_show_bgp_global_afi_safi_route_flap_dampening(struct vty *vty,
14108 struct lyd_node *dnode,
14109 bool show_defaults)
14110 {
14111 if (!yang_dnode_get_bool(dnode, "./enable"))
14112 return;
14113
14114 int half = DEFAULT_HALF_LIFE * 60;
14115 int reuse = DEFAULT_REUSE;
14116 int suppress = DEFAULT_SUPPRESS;
14117 int max;
14118
14119 half = yang_dnode_get_uint8(dnode, "../reach-decay");
14120 reuse = yang_dnode_get_uint16(dnode, "../reuse-above");
14121 suppress = yang_dnode_get_uint16(dnode, "../suppress-above");
14122 max = yang_dnode_get_uint8(dnode, "../unreach-decay");
14123
14124 if (half == DEFAULT_HALF_LIFE * 60 && reuse == DEFAULT_REUSE
14125 && suppress == DEFAULT_SUPPRESS && max == half * 4)
14126 vty_out(vty, " bgp dampening\n");
14127 else if (half != DEFAULT_HALF_LIFE * 60 && reuse == DEFAULT_REUSE
14128 && suppress == DEFAULT_SUPPRESS && max == half * 4)
14129 vty_out(vty, " bgp dampening %u\n", half);
14130 else
14131 vty_out(vty, " bgp dampening %u %d %d %d\n", half, reuse,
14132 suppress, max);
14133 }
14134
14135 /* Display specified route of BGP table. */
14136 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
14137 const char *ip_str, afi_t afi, safi_t safi,
14138 struct prefix_rd *prd, int prefix_check)
14139 {
14140 int ret;
14141 struct prefix match;
14142 struct bgp_dest *dest;
14143 struct bgp_dest *rm;
14144 struct bgp_path_info *pi;
14145 struct bgp_path_info *pi_temp;
14146 struct bgp *bgp;
14147 struct bgp_table *table;
14148
14149 /* BGP structure lookup. */
14150 if (view_name) {
14151 bgp = bgp_lookup_by_name(view_name);
14152 if (bgp == NULL) {
14153 vty_out(vty, "%% Can't find BGP instance %s\n",
14154 view_name);
14155 return CMD_WARNING;
14156 }
14157 } else {
14158 bgp = bgp_get_default();
14159 if (bgp == NULL) {
14160 vty_out(vty, "%% No BGP process is configured\n");
14161 return CMD_WARNING;
14162 }
14163 }
14164
14165 /* Check IP address argument. */
14166 ret = str2prefix(ip_str, &match);
14167 if (!ret) {
14168 vty_out(vty, "%% address is malformed\n");
14169 return CMD_WARNING;
14170 }
14171
14172 match.family = afi2family(afi);
14173
14174 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14175 || (safi == SAFI_EVPN)) {
14176 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
14177 dest = bgp_route_next(dest)) {
14178 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14179
14180 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
14181 continue;
14182 table = bgp_dest_get_bgp_table_info(dest);
14183 if (!table)
14184 continue;
14185 if ((rm = bgp_node_match(table, &match)) == NULL)
14186 continue;
14187
14188 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
14189
14190 if (!prefix_check
14191 || rm_p->prefixlen == match.prefixlen) {
14192 pi = bgp_dest_get_bgp_path_info(rm);
14193 while (pi) {
14194 if (pi->extra && pi->extra->damp_info) {
14195 pi_temp = pi->next;
14196 bgp_damp_info_free(
14197 &pi->extra->damp_info,
14198 &bgp->damp[afi][safi],
14199 1, afi, safi);
14200 pi = pi_temp;
14201 } else
14202 pi = pi->next;
14203 }
14204 }
14205
14206 bgp_dest_unlock_node(rm);
14207 }
14208 } else {
14209 if ((dest = bgp_node_match(bgp->rib[afi][safi], &match))
14210 != NULL) {
14211 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14212
14213 if (!prefix_check
14214 || dest_p->prefixlen == match.prefixlen) {
14215 pi = bgp_dest_get_bgp_path_info(dest);
14216 while (pi) {
14217 if (pi->extra && pi->extra->damp_info) {
14218 pi_temp = pi->next;
14219 bgp_damp_info_free(
14220 &pi->extra->damp_info,
14221 &bgp->damp[afi][safi],
14222 1, afi, safi);
14223 pi = pi_temp;
14224 } else
14225 pi = pi->next;
14226 }
14227 }
14228
14229 bgp_dest_unlock_node(dest);
14230 }
14231 }
14232
14233 return CMD_SUCCESS;
14234 }
14235
14236 DEFUN (clear_ip_bgp_dampening,
14237 clear_ip_bgp_dampening_cmd,
14238 "clear ip bgp dampening",
14239 CLEAR_STR
14240 IP_STR
14241 BGP_STR
14242 "Clear route flap dampening information\n")
14243 {
14244 VTY_DECLVAR_CONTEXT(bgp, bgp);
14245 bgp_damp_info_clean(&bgp->damp[AFI_IP][SAFI_UNICAST], AFI_IP,
14246 SAFI_UNICAST);
14247 return CMD_SUCCESS;
14248 }
14249
14250 DEFUN (clear_ip_bgp_dampening_prefix,
14251 clear_ip_bgp_dampening_prefix_cmd,
14252 "clear ip bgp dampening A.B.C.D/M",
14253 CLEAR_STR
14254 IP_STR
14255 BGP_STR
14256 "Clear route flap dampening information\n"
14257 "IPv4 prefix\n")
14258 {
14259 int idx_ipv4_prefixlen = 4;
14260 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
14261 AFI_IP, SAFI_UNICAST, NULL, 1);
14262 }
14263
14264 DEFUN (clear_ip_bgp_dampening_address,
14265 clear_ip_bgp_dampening_address_cmd,
14266 "clear ip bgp dampening A.B.C.D",
14267 CLEAR_STR
14268 IP_STR
14269 BGP_STR
14270 "Clear route flap dampening information\n"
14271 "Network to clear damping information\n")
14272 {
14273 int idx_ipv4 = 4;
14274 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
14275 SAFI_UNICAST, NULL, 0);
14276 }
14277
14278 DEFUN (clear_ip_bgp_dampening_address_mask,
14279 clear_ip_bgp_dampening_address_mask_cmd,
14280 "clear ip bgp dampening A.B.C.D A.B.C.D",
14281 CLEAR_STR
14282 IP_STR
14283 BGP_STR
14284 "Clear route flap dampening information\n"
14285 "Network to clear damping information\n"
14286 "Network mask\n")
14287 {
14288 int idx_ipv4 = 4;
14289 int idx_ipv4_2 = 5;
14290 int ret;
14291 char prefix_str[BUFSIZ];
14292
14293 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
14294 prefix_str);
14295 if (!ret) {
14296 vty_out(vty, "%% Inconsistent address and mask\n");
14297 return CMD_WARNING;
14298 }
14299
14300 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
14301 NULL, 0);
14302 }
14303
14304 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
14305 {
14306 struct vty *vty = arg;
14307 struct peer *peer = bucket->data;
14308 char buf[SU_ADDRSTRLEN];
14309
14310 vty_out(vty, "\tPeer: %s %s\n", peer->host,
14311 sockunion2str(&peer->su, buf, sizeof(buf)));
14312 }
14313
14314 DEFUN (show_bgp_listeners,
14315 show_bgp_listeners_cmd,
14316 "show bgp listeners",
14317 SHOW_STR
14318 BGP_STR
14319 "Display Listen Sockets and who created them\n")
14320 {
14321 bgp_dump_listener_info(vty);
14322
14323 return CMD_SUCCESS;
14324 }
14325
14326 DEFUN (show_bgp_peerhash,
14327 show_bgp_peerhash_cmd,
14328 "show bgp peerhash",
14329 SHOW_STR
14330 BGP_STR
14331 "Display information about the BGP peerhash\n")
14332 {
14333 struct list *instances = bm->bgp;
14334 struct listnode *node;
14335 struct bgp *bgp;
14336
14337 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
14338 vty_out(vty, "BGP: %s\n", bgp->name);
14339 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
14340 vty);
14341 }
14342
14343 return CMD_SUCCESS;
14344 }
14345
14346 /* also used for encap safi */
14347 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
14348 afi_t afi, safi_t safi)
14349 {
14350 struct bgp_dest *pdest;
14351 struct bgp_dest *dest;
14352 struct bgp_table *table;
14353 const struct prefix *p;
14354 const struct prefix_rd *prd;
14355 struct bgp_static *bgp_static;
14356 mpls_label_t label;
14357 char rdbuf[RD_ADDRSTRLEN];
14358
14359 /* Network configuration. */
14360 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
14361 pdest = bgp_route_next(pdest)) {
14362 table = bgp_dest_get_bgp_table_info(pdest);
14363 if (!table)
14364 continue;
14365
14366 for (dest = bgp_table_top(table); dest;
14367 dest = bgp_route_next(dest)) {
14368 bgp_static = bgp_dest_get_bgp_static_info(dest);
14369 if (bgp_static == NULL)
14370 continue;
14371
14372 p = bgp_dest_get_prefix(dest);
14373 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14374 pdest);
14375
14376 /* "network" configuration display. */
14377 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
14378 label = decode_label(&bgp_static->label);
14379
14380 vty_out(vty, " network %pFX rd %s", p, rdbuf);
14381 if (safi == SAFI_MPLS_VPN)
14382 vty_out(vty, " label %u", label);
14383
14384 if (bgp_static->rmap.name)
14385 vty_out(vty, " route-map %s",
14386 bgp_static->rmap.name);
14387
14388 if (bgp_static->backdoor)
14389 vty_out(vty, " backdoor");
14390
14391 vty_out(vty, "\n");
14392 }
14393 }
14394 }
14395
14396 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
14397 afi_t afi, safi_t safi)
14398 {
14399 struct bgp_dest *pdest;
14400 struct bgp_dest *dest;
14401 struct bgp_table *table;
14402 const struct prefix *p;
14403 const struct prefix_rd *prd;
14404 struct bgp_static *bgp_static;
14405 char buf[PREFIX_STRLEN * 2];
14406 char buf2[SU_ADDRSTRLEN];
14407 char rdbuf[RD_ADDRSTRLEN];
14408 char esi_buf[ESI_BYTES];
14409
14410 /* Network configuration. */
14411 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
14412 pdest = bgp_route_next(pdest)) {
14413 table = bgp_dest_get_bgp_table_info(pdest);
14414 if (!table)
14415 continue;
14416
14417 for (dest = bgp_table_top(table); dest;
14418 dest = bgp_route_next(dest)) {
14419 bgp_static = bgp_dest_get_bgp_static_info(dest);
14420 if (bgp_static == NULL)
14421 continue;
14422
14423 char *macrouter = NULL;
14424
14425 if (bgp_static->router_mac)
14426 macrouter = prefix_mac2str(
14427 bgp_static->router_mac, NULL, 0);
14428 if (bgp_static->eth_s_id)
14429 esi_to_str(bgp_static->eth_s_id,
14430 esi_buf, sizeof(esi_buf));
14431 p = bgp_dest_get_prefix(dest);
14432 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
14433
14434 /* "network" configuration display. */
14435 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
14436 if (p->u.prefix_evpn.route_type == 5) {
14437 char local_buf[PREFIX_STRLEN];
14438 uint8_t family = is_evpn_prefix_ipaddr_v4((
14439 struct prefix_evpn *)p)
14440 ? AF_INET
14441 : AF_INET6;
14442 inet_ntop(family,
14443 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
14444 local_buf, PREFIX_STRLEN);
14445 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
14446 p->u.prefix_evpn.prefix_addr
14447 .ip_prefix_length);
14448 } else {
14449 prefix2str(p, buf, sizeof(buf));
14450 }
14451
14452 if (bgp_static->gatewayIp.family == AF_INET
14453 || bgp_static->gatewayIp.family == AF_INET6)
14454 inet_ntop(bgp_static->gatewayIp.family,
14455 &bgp_static->gatewayIp.u.prefix, buf2,
14456 sizeof(buf2));
14457 vty_out(vty,
14458 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
14459 buf, rdbuf,
14460 p->u.prefix_evpn.prefix_addr.eth_tag,
14461 decode_label(&bgp_static->label), esi_buf, buf2,
14462 macrouter);
14463
14464 XFREE(MTYPE_TMP, macrouter);
14465 }
14466 }
14467 }
14468
14469 /* Configuration of static route announcement and aggregate
14470 information. */
14471 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
14472 safi_t safi)
14473 {
14474 struct bgp_dest *dest;
14475 const struct prefix *p;
14476 struct bgp_static *bgp_static;
14477 struct bgp_aggregate *bgp_aggregate;
14478
14479 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
14480 bgp_config_write_network_vpn(vty, bgp, afi, safi);
14481 return;
14482 }
14483
14484 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
14485 bgp_config_write_network_evpn(vty, bgp, afi, safi);
14486 return;
14487 }
14488
14489 /* Network configuration. */
14490 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
14491 dest = bgp_route_next(dest)) {
14492 bgp_static = bgp_dest_get_bgp_static_info(dest);
14493 if (bgp_static == NULL)
14494 continue;
14495
14496 p = bgp_dest_get_prefix(dest);
14497
14498 vty_out(vty, " network %pFX", p);
14499
14500 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
14501 vty_out(vty, " label-index %u",
14502 bgp_static->label_index);
14503
14504 if (bgp_static->rmap.name)
14505 vty_out(vty, " route-map %s", bgp_static->rmap.name);
14506
14507 if (bgp_static->backdoor)
14508 vty_out(vty, " backdoor");
14509
14510 vty_out(vty, "\n");
14511 }
14512
14513 /* Aggregate-address configuration. */
14514 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
14515 dest = bgp_route_next(dest)) {
14516 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
14517 if (bgp_aggregate == NULL)
14518 continue;
14519
14520 p = bgp_dest_get_prefix(dest);
14521
14522 vty_out(vty, " aggregate-address %pFX", p);
14523
14524 if (bgp_aggregate->as_set)
14525 vty_out(vty, " as-set");
14526
14527 if (bgp_aggregate->summary_only)
14528 vty_out(vty, " summary-only");
14529
14530 if (bgp_aggregate->rmap.name)
14531 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
14532
14533 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
14534 vty_out(vty, " origin %s",
14535 bgp_origin2str(bgp_aggregate->origin));
14536
14537 if (bgp_aggregate->match_med)
14538 vty_out(vty, " matching-MED-only");
14539
14540 if (bgp_aggregate->suppress_map_name)
14541 vty_out(vty, " suppress-map %s",
14542 bgp_aggregate->suppress_map_name);
14543
14544 vty_out(vty, "\n");
14545 }
14546 }
14547
14548 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
14549 safi_t safi)
14550 {
14551 struct bgp_dest *dest;
14552 struct bgp_distance *bdistance;
14553
14554 /* Distance configuration. */
14555 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
14556 && bgp->distance_local[afi][safi]
14557 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
14558 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
14559 || bgp->distance_local[afi][safi]
14560 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
14561 vty_out(vty, " distance bgp %d %d %d\n",
14562 bgp->distance_ebgp[afi][safi],
14563 bgp->distance_ibgp[afi][safi],
14564 bgp->distance_local[afi][safi]);
14565 }
14566
14567 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
14568 dest = bgp_route_next(dest)) {
14569 bdistance = bgp_dest_get_bgp_distance_info(dest);
14570 if (bdistance != NULL)
14571 vty_out(vty, " distance %d %pBD %s\n",
14572 bdistance->distance, dest,
14573 bdistance->access_list ? bdistance->access_list
14574 : "");
14575 }
14576 }
14577
14578 /* Allocate routing table structure and install commands. */
14579 void bgp_route_init(void)
14580 {
14581 afi_t afi;
14582 safi_t safi;
14583
14584 /* Init BGP distance table. */
14585 FOREACH_AFI_SAFI (afi, safi)
14586 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
14587
14588 /* IPv4 BGP commands. */
14589 install_element(BGP_NODE, &bgp_table_map_cmd);
14590 install_element(BGP_NODE, &bgp_network_cmd);
14591 install_element(BGP_NODE, &no_bgp_table_map_cmd);
14592
14593 install_element(BGP_NODE, &aggregate_addressv4_cmd);
14594
14595 /* IPv4 unicast configuration. */
14596 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
14597 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
14598 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
14599
14600 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
14601
14602 /* IPv4 multicast configuration. */
14603 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
14604 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
14605 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
14606 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
14607
14608 /* IPv4 labeled-unicast configuration. */
14609 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
14610 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
14611
14612 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
14613 install_element(VIEW_NODE, &show_ip_bgp_cmd);
14614 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
14615 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
14616 install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
14617 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
14618 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
14619 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
14620
14621 install_element(VIEW_NODE,
14622 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
14623 install_element(VIEW_NODE,
14624 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
14625 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
14626 install_element(VIEW_NODE,
14627 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
14628 #ifdef KEEP_OLD_VPN_COMMANDS
14629 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
14630 #endif /* KEEP_OLD_VPN_COMMANDS */
14631 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
14632 install_element(VIEW_NODE,
14633 &show_bgp_l2vpn_evpn_route_prefix_cmd);
14634
14635 /* BGP dampening clear commands */
14636 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
14637 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
14638
14639 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
14640 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
14641
14642 /* prefix count */
14643 install_element(ENABLE_NODE,
14644 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
14645 #ifdef KEEP_OLD_VPN_COMMANDS
14646 install_element(ENABLE_NODE,
14647 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
14648 #endif /* KEEP_OLD_VPN_COMMANDS */
14649
14650 /* New config IPv6 BGP commands. */
14651 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
14652 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
14653 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
14654
14655 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
14656
14657 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
14658
14659 /* IPv6 labeled unicast address family. */
14660 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
14661 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
14662
14663 install_element(BGP_NODE, &bgp_distance_cmd);
14664 install_element(BGP_NODE, &no_bgp_distance_cmd);
14665 install_element(BGP_NODE, &bgp_distance_source_cmd);
14666 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
14667 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
14668 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
14669 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
14670 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
14671 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
14672 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
14673 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
14674 install_element(BGP_IPV6_NODE, &bgp_distance_source_cmd);
14675 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
14676 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
14677 install_element(BGP_IPV6M_NODE, &bgp_distance_source_cmd);
14678
14679 /* BGP dampening */
14680 install_element(BGP_NODE, &bgp_dampening_cmd);
14681 install_element(BGP_IPV4_NODE, &bgp_dampening_cmd);
14682 install_element(BGP_IPV4M_NODE, &bgp_dampening_cmd);
14683 install_element(BGP_IPV4L_NODE, &bgp_dampening_cmd);
14684 install_element(BGP_IPV6_NODE, &bgp_dampening_cmd);
14685 install_element(BGP_IPV6M_NODE, &bgp_dampening_cmd);
14686 install_element(BGP_IPV6L_NODE, &bgp_dampening_cmd);
14687
14688 /* Large Communities */
14689 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
14690 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
14691
14692 /* show bgp ipv4 flowspec detailed */
14693 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
14694
14695 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
14696 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
14697 }
14698
14699 void bgp_route_finish(void)
14700 {
14701 afi_t afi;
14702 safi_t safi;
14703
14704 FOREACH_AFI_SAFI (afi, safi) {
14705 bgp_table_unlock(bgp_distance_table[afi][safi]);
14706 bgp_distance_table[afi][safi] = NULL;
14707 }
14708 }