]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
bgpd: simplify aggregate address commands
[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
74 #ifdef ENABLE_BGP_VNC
75 #include "bgpd/rfapi/rfapi_backend.h"
76 #include "bgpd/rfapi/vnc_import_bgp.h"
77 #include "bgpd/rfapi/vnc_export_bgp.h"
78 #endif
79 #include "bgpd/bgp_encap_types.h"
80 #include "bgpd/bgp_encap_tlv.h"
81 #include "bgpd/bgp_evpn.h"
82 #include "bgpd/bgp_evpn_mh.h"
83 #include "bgpd/bgp_evpn_vty.h"
84 #include "bgpd/bgp_flowspec.h"
85 #include "bgpd/bgp_flowspec_util.h"
86 #include "bgpd/bgp_pbr.h"
87
88 #ifndef VTYSH_EXTRACT_PL
89 #include "bgpd/bgp_route_clippy.c"
90 #endif
91
92 /* Extern from bgp_dump.c */
93 extern const char *bgp_origin_str[];
94 extern const char *bgp_origin_long_str[];
95 const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json);
96 /* PMSI strings. */
97 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
98 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
99 static const struct message bgp_pmsi_tnltype_str[] = {
100 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
101 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
102 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
103 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
104 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
105 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
106 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
107 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
108 {0}
109 };
110
111 #define VRFID_NONE_STR "-"
112
113 DEFINE_HOOK(bgp_process,
114 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
115 struct peer *peer, bool withdraw),
116 (bgp, afi, safi, bn, peer, withdraw))
117
118
119 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
120 safi_t safi, const struct prefix *p,
121 struct prefix_rd *prd)
122 {
123 struct bgp_dest *dest;
124 struct bgp_dest *pdest = NULL;
125
126 assert(table);
127
128 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
129 || (safi == SAFI_EVPN)) {
130 pdest = bgp_node_get(table, (struct prefix *)prd);
131
132 if (!bgp_dest_has_bgp_path_info_data(pdest))
133 bgp_dest_set_bgp_table_info(
134 pdest, bgp_table_init(table->bgp, afi, safi));
135 else
136 bgp_dest_unlock_node(pdest);
137 table = bgp_dest_get_bgp_table_info(pdest);
138 }
139
140 dest = bgp_node_get(table, p);
141
142 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
143 || (safi == SAFI_EVPN))
144 dest->pdest = pdest;
145
146 return dest;
147 }
148
149 struct bgp_dest *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
150 safi_t safi, const struct prefix *p,
151 struct prefix_rd *prd)
152 {
153 struct bgp_dest *dest;
154 struct bgp_dest *pdest = NULL;
155
156 if (!table)
157 return NULL;
158
159 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
160 || (safi == SAFI_EVPN)) {
161 pdest = bgp_node_lookup(table, (struct prefix *)prd);
162 if (!pdest)
163 return NULL;
164
165 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
166 bgp_dest_unlock_node(pdest);
167 return NULL;
168 }
169
170 table = bgp_dest_get_bgp_table_info(pdest);
171 }
172
173 dest = bgp_node_lookup(table, p);
174
175 return dest;
176 }
177
178 /* Allocate bgp_path_info_extra */
179 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
180 {
181 struct bgp_path_info_extra *new;
182 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
183 sizeof(struct bgp_path_info_extra));
184 new->label[0] = MPLS_INVALID_LABEL;
185 new->num_labels = 0;
186 new->bgp_fs_pbr = NULL;
187 new->bgp_fs_iprule = NULL;
188 return new;
189 }
190
191 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
192 {
193 struct bgp_path_info_extra *e;
194
195 if (!extra || !*extra)
196 return;
197
198 e = *extra;
199 if (e->damp_info)
200 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
201 e->damp_info->safi);
202
203 e->damp_info = NULL;
204 if (e->parent) {
205 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
206
207 if (bpi->net) {
208 /* FIXME: since multiple e may have the same e->parent
209 * and e->parent->net is holding a refcount for each
210 * of them, we need to do some fudging here.
211 *
212 * WARNING: if bpi->net->lock drops to 0, bpi may be
213 * freed as well (because bpi->net was holding the
214 * last reference to bpi) => write after free!
215 */
216 unsigned refcount;
217
218 bpi = bgp_path_info_lock(bpi);
219 refcount = bpi->net->lock - 1;
220 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
221 if (!refcount)
222 bpi->net = NULL;
223 bgp_path_info_unlock(bpi);
224 }
225 bgp_path_info_unlock(e->parent);
226 e->parent = NULL;
227 }
228
229 if (e->bgp_orig)
230 bgp_unlock(e->bgp_orig);
231
232 if ((*extra)->bgp_fs_iprule)
233 list_delete(&((*extra)->bgp_fs_iprule));
234 if ((*extra)->bgp_fs_pbr)
235 list_delete(&((*extra)->bgp_fs_pbr));
236 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
237 }
238
239 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
240 * allocated if required.
241 */
242 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
243 {
244 if (!pi->extra)
245 pi->extra = bgp_path_info_extra_new();
246 return pi->extra;
247 }
248
249 /* Free bgp route information. */
250 static void bgp_path_info_free(struct bgp_path_info *path)
251 {
252 bgp_attr_unintern(&path->attr);
253
254 bgp_unlink_nexthop(path);
255 bgp_path_info_extra_free(&path->extra);
256 bgp_path_info_mpath_free(&path->mpath);
257 if (path->net)
258 bgp_addpath_free_info_data(&path->tx_addpath,
259 &path->net->tx_addpath);
260
261 peer_unlock(path->peer); /* bgp_path_info peer reference */
262
263 XFREE(MTYPE_BGP_ROUTE, path);
264 }
265
266 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
267 {
268 path->lock++;
269 return path;
270 }
271
272 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
273 {
274 assert(path && path->lock > 0);
275 path->lock--;
276
277 if (path->lock == 0) {
278 #if 0
279 zlog_debug ("%s: unlocked and freeing", __func__);
280 zlog_backtrace (LOG_DEBUG);
281 #endif
282 bgp_path_info_free(path);
283 return NULL;
284 }
285
286 #if 0
287 if (path->lock == 1)
288 {
289 zlog_debug ("%s: unlocked to 1", __func__);
290 zlog_backtrace (LOG_DEBUG);
291 }
292 #endif
293
294 return path;
295 }
296
297 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
298 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
299 {
300 struct peer *peer;
301 struct bgp_path_info *old_pi, *nextpi;
302 bool set_flag = false;
303 struct bgp *bgp = NULL;
304 struct bgp_table *table = NULL;
305 afi_t afi = 0;
306 safi_t safi = 0;
307
308 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
309 * then the route selection is deferred
310 */
311 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
312 return 0;
313
314 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
315 if (BGP_DEBUG(update, UPDATE_OUT))
316 zlog_debug(
317 "Route %pRN is in workqueue and being processed, not deferred.",
318 bgp_dest_to_rnode(dest));
319
320 return 0;
321 }
322
323 table = bgp_dest_table(dest);
324 if (table) {
325 bgp = table->bgp;
326 afi = table->afi;
327 safi = table->safi;
328 }
329
330 for (old_pi = bgp_dest_get_bgp_path_info(dest);
331 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
332 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
333 continue;
334
335 /* Route selection is deferred if there is a stale path which
336 * which indicates peer is in restart mode
337 */
338 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
339 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
340 set_flag = true;
341 } else {
342 /* If the peer is graceful restart capable and peer is
343 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
344 */
345 peer = old_pi->peer;
346 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
347 && BGP_PEER_RESTARTING_MODE(peer)
348 && (old_pi
349 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
350 set_flag = true;
351 }
352 }
353 if (set_flag)
354 break;
355 }
356
357 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
358 * is active
359 */
360 if (set_flag && table) {
361 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
362 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
363 if (dest->rt_node == NULL)
364 dest->rt_node = listnode_add(
365 bgp->gr_info[afi][safi].route_list,
366 dest);
367 if (BGP_DEBUG(update, UPDATE_OUT))
368 zlog_debug("DEFER route %pRN, dest %p, node %p",
369 dest, dest, dest->rt_node);
370 return 0;
371 }
372 }
373 return -1;
374 }
375
376 void bgp_path_info_add(struct bgp_dest *dest, struct bgp_path_info *pi)
377 {
378 struct bgp_path_info *top;
379
380 top = bgp_dest_get_bgp_path_info(dest);
381
382 pi->next = top;
383 pi->prev = NULL;
384 if (top)
385 top->prev = pi;
386 bgp_dest_set_bgp_path_info(dest, pi);
387
388 bgp_path_info_lock(pi);
389 bgp_dest_lock_node(dest);
390 peer_lock(pi->peer); /* bgp_path_info peer reference */
391 bgp_dest_set_defer_flag(dest, false);
392 }
393
394 /* Do the actual removal of info from RIB, for use by bgp_process
395 completion callback *only* */
396 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
397 {
398 if (pi->next)
399 pi->next->prev = pi->prev;
400 if (pi->prev)
401 pi->prev->next = pi->next;
402 else
403 bgp_dest_set_bgp_path_info(dest, pi->next);
404
405 bgp_path_info_mpath_dequeue(pi);
406 bgp_path_info_unlock(pi);
407 bgp_dest_unlock_node(dest);
408 }
409
410 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
411 {
412 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
413 /* set of previous already took care of pcount */
414 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
415 }
416
417 /* undo the effects of a previous call to bgp_path_info_delete; typically
418 called when a route is deleted and then quickly re-added before the
419 deletion has been processed */
420 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
421 {
422 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
423 /* unset of previous already took care of pcount */
424 SET_FLAG(pi->flags, BGP_PATH_VALID);
425 }
426
427 /* Adjust pcount as required */
428 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
429 {
430 struct bgp_table *table;
431
432 assert(dest && bgp_dest_table(dest));
433 assert(pi && pi->peer && pi->peer->bgp);
434
435 table = bgp_dest_table(dest);
436
437 if (pi->peer == pi->peer->bgp->peer_self)
438 return;
439
440 if (!BGP_PATH_COUNTABLE(pi)
441 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
442
443 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
444
445 /* slight hack, but more robust against errors. */
446 if (pi->peer->pcount[table->afi][table->safi])
447 pi->peer->pcount[table->afi][table->safi]--;
448 else
449 flog_err(EC_LIB_DEVELOPMENT,
450 "Asked to decrement 0 prefix count for peer");
451 } else if (BGP_PATH_COUNTABLE(pi)
452 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
453 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
454 pi->peer->pcount[table->afi][table->safi]++;
455 }
456 }
457
458 static int bgp_label_index_differs(struct bgp_path_info *pi1,
459 struct bgp_path_info *pi2)
460 {
461 return (!(pi1->attr->label_index == pi2->attr->label_index));
462 }
463
464 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
465 * This is here primarily to keep prefix-count in check.
466 */
467 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
468 uint32_t flag)
469 {
470 SET_FLAG(pi->flags, flag);
471
472 /* early bath if we know it's not a flag that changes countability state
473 */
474 if (!CHECK_FLAG(flag,
475 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
476 return;
477
478 bgp_pcount_adjust(dest, pi);
479 }
480
481 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
482 uint32_t flag)
483 {
484 UNSET_FLAG(pi->flags, flag);
485
486 /* early bath if we know it's not a flag that changes countability state
487 */
488 if (!CHECK_FLAG(flag,
489 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
490 return;
491
492 bgp_pcount_adjust(dest, pi);
493 }
494
495 /* Get MED value. If MED value is missing and "bgp bestpath
496 missing-as-worst" is specified, treat it as the worst value. */
497 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
498 {
499 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
500 return attr->med;
501 else {
502 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
503 return BGP_MED_MAX;
504 else
505 return 0;
506 }
507 }
508
509 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf)
510 {
511 if (pi->addpath_rx_id)
512 sprintf(buf, "path %s (addpath rxid %d)", pi->peer->host,
513 pi->addpath_rx_id);
514 else
515 sprintf(buf, "path %s", pi->peer->host);
516 }
517
518 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
519 */
520 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
521 struct bgp_path_info *exist, int *paths_eq,
522 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
523 char *pfx_buf, afi_t afi, safi_t safi,
524 enum bgp_path_selection_reason *reason)
525 {
526 struct attr *newattr, *existattr;
527 bgp_peer_sort_t new_sort;
528 bgp_peer_sort_t exist_sort;
529 uint32_t new_pref;
530 uint32_t exist_pref;
531 uint32_t new_med;
532 uint32_t exist_med;
533 uint32_t new_weight;
534 uint32_t exist_weight;
535 uint32_t newm, existm;
536 struct in_addr new_id;
537 struct in_addr exist_id;
538 int new_cluster;
539 int exist_cluster;
540 int internal_as_route;
541 int confed_as_route;
542 int ret = 0;
543 char new_buf[PATH_ADDPATH_STR_BUFFER];
544 char exist_buf[PATH_ADDPATH_STR_BUFFER];
545 uint32_t new_mm_seq;
546 uint32_t exist_mm_seq;
547 int nh_cmp;
548 esi_t *exist_esi;
549 esi_t *new_esi;
550 bool same_esi;
551 bool old_proxy;
552 bool new_proxy;
553
554 *paths_eq = 0;
555
556 /* 0. Null check. */
557 if (new == NULL) {
558 *reason = bgp_path_selection_none;
559 if (debug)
560 zlog_debug("%s: new is NULL", pfx_buf);
561 return 0;
562 }
563
564 if (debug)
565 bgp_path_info_path_with_addpath_rx_str(new, new_buf);
566
567 if (exist == NULL) {
568 *reason = bgp_path_selection_first;
569 if (debug)
570 zlog_debug("%s: %s is the initial bestpath", pfx_buf,
571 new_buf);
572 return 1;
573 }
574
575 if (debug) {
576 bgp_path_info_path_with_addpath_rx_str(exist, exist_buf);
577 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
578 pfx_buf, new_buf, new->flags, exist_buf,
579 exist->flags);
580 }
581
582 newattr = new->attr;
583 existattr = exist->attr;
584
585 /* For EVPN routes, we cannot just go by local vs remote, we have to
586 * look at the MAC mobility sequence number, if present.
587 */
588 if (safi == SAFI_EVPN) {
589 /* This is an error condition described in RFC 7432 Section
590 * 15.2. The RFC
591 * states that in this scenario "the PE MUST alert the operator"
592 * but it
593 * does not state what other action to take. In order to provide
594 * some
595 * consistency in this scenario we are going to prefer the path
596 * with the
597 * sticky flag.
598 */
599 if (newattr->sticky != existattr->sticky) {
600 if (!debug) {
601 prefix2str(
602 bgp_dest_get_prefix(new->net), pfx_buf,
603 sizeof(*pfx_buf) * PREFIX2STR_BUFFER);
604 bgp_path_info_path_with_addpath_rx_str(new,
605 new_buf);
606 bgp_path_info_path_with_addpath_rx_str(
607 exist, exist_buf);
608 }
609
610 if (newattr->sticky && !existattr->sticky) {
611 *reason = bgp_path_selection_evpn_sticky_mac;
612 if (debug)
613 zlog_debug(
614 "%s: %s wins over %s due to sticky MAC flag",
615 pfx_buf, new_buf, exist_buf);
616 return 1;
617 }
618
619 if (!newattr->sticky && existattr->sticky) {
620 *reason = bgp_path_selection_evpn_sticky_mac;
621 if (debug)
622 zlog_debug(
623 "%s: %s loses to %s due to sticky MAC flag",
624 pfx_buf, new_buf, exist_buf);
625 return 0;
626 }
627 }
628
629 new_esi = bgp_evpn_attr_get_esi(newattr);
630 exist_esi = bgp_evpn_attr_get_esi(existattr);
631 if (bgp_evpn_is_esi_valid(new_esi) &&
632 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
633 same_esi = true;
634 } else {
635 same_esi = false;
636 }
637
638 /* If both paths have the same non-zero ES and
639 * one path is local it wins.
640 * PS: Note the local path wins even if the remote
641 * has the higher MM seq. The local path's
642 * MM seq will be fixed up to match the highest
643 * rem seq, subsequently.
644 */
645 if (same_esi) {
646 char esi_buf[ESI_STR_LEN];
647
648 if (bgp_evpn_is_path_local(bgp, new)) {
649 *reason = bgp_path_selection_evpn_local_path;
650 if (debug)
651 zlog_debug(
652 "%s: %s wins over %s as ES %s is same and local",
653 pfx_buf, new_buf, exist_buf,
654 esi_to_str(new_esi, esi_buf,
655 sizeof(esi_buf)));
656 return 1;
657 }
658 if (bgp_evpn_is_path_local(bgp, exist)) {
659 *reason = bgp_path_selection_evpn_local_path;
660 if (debug)
661 zlog_debug(
662 "%s: %s loses to %s as ES %s is same and local",
663 pfx_buf, new_buf, exist_buf,
664 esi_to_str(new_esi, esi_buf,
665 sizeof(esi_buf)));
666 return 0;
667 }
668 }
669
670 new_mm_seq = mac_mobility_seqnum(newattr);
671 exist_mm_seq = mac_mobility_seqnum(existattr);
672
673 if (new_mm_seq > exist_mm_seq) {
674 *reason = bgp_path_selection_evpn_seq;
675 if (debug)
676 zlog_debug(
677 "%s: %s wins over %s due to MM seq %u > %u",
678 pfx_buf, new_buf, exist_buf, new_mm_seq,
679 exist_mm_seq);
680 return 1;
681 }
682
683 if (new_mm_seq < exist_mm_seq) {
684 *reason = bgp_path_selection_evpn_seq;
685 if (debug)
686 zlog_debug(
687 "%s: %s loses to %s due to MM seq %u < %u",
688 pfx_buf, new_buf, exist_buf, new_mm_seq,
689 exist_mm_seq);
690 return 0;
691 }
692
693 /* if the sequence numbers and ESI are the same and one path
694 * is non-proxy it wins (over proxy)
695 */
696 new_proxy = bgp_evpn_attr_is_proxy(newattr);
697 old_proxy = bgp_evpn_attr_is_proxy(existattr);
698 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
699 old_proxy != new_proxy) {
700 if (!new_proxy) {
701 *reason = bgp_path_selection_evpn_non_proxy;
702 if (debug)
703 zlog_debug(
704 "%s: %s wins over %s, same seq/es and non-proxy",
705 pfx_buf, new_buf, exist_buf);
706 return 1;
707 }
708
709 *reason = bgp_path_selection_evpn_non_proxy;
710 if (debug)
711 zlog_debug(
712 "%s: %s loses to %s, same seq/es and non-proxy",
713 pfx_buf, new_buf, exist_buf);
714 return 0;
715 }
716
717 /*
718 * if sequence numbers are the same path with the lowest IP
719 * wins
720 */
721 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
722 if (nh_cmp < 0) {
723 *reason = bgp_path_selection_evpn_lower_ip;
724 if (debug)
725 zlog_debug(
726 "%s: %s wins over %s due to same MM seq %u and lower IP %s",
727 pfx_buf, new_buf, exist_buf, new_mm_seq,
728 inet_ntoa(new->attr->nexthop));
729 return 1;
730 }
731 if (nh_cmp > 0) {
732 *reason = bgp_path_selection_evpn_lower_ip;
733 if (debug)
734 zlog_debug(
735 "%s: %s loses to %s due to same MM seq %u and higher IP %s",
736 pfx_buf, new_buf, exist_buf, new_mm_seq,
737 inet_ntoa(new->attr->nexthop));
738 return 0;
739 }
740 }
741
742 /* 1. Weight check. */
743 new_weight = newattr->weight;
744 exist_weight = existattr->weight;
745
746 if (new_weight > exist_weight) {
747 *reason = bgp_path_selection_weight;
748 if (debug)
749 zlog_debug("%s: %s wins over %s due to weight %d > %d",
750 pfx_buf, new_buf, exist_buf, new_weight,
751 exist_weight);
752 return 1;
753 }
754
755 if (new_weight < exist_weight) {
756 *reason = bgp_path_selection_weight;
757 if (debug)
758 zlog_debug("%s: %s loses to %s due to weight %d < %d",
759 pfx_buf, new_buf, exist_buf, new_weight,
760 exist_weight);
761 return 0;
762 }
763
764 /* 2. Local preference check. */
765 new_pref = exist_pref = bgp->default_local_pref;
766
767 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
768 new_pref = newattr->local_pref;
769 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
770 exist_pref = existattr->local_pref;
771
772 if (new_pref > exist_pref) {
773 *reason = bgp_path_selection_local_pref;
774 if (debug)
775 zlog_debug(
776 "%s: %s wins over %s due to localpref %d > %d",
777 pfx_buf, new_buf, exist_buf, new_pref,
778 exist_pref);
779 return 1;
780 }
781
782 if (new_pref < exist_pref) {
783 *reason = bgp_path_selection_local_pref;
784 if (debug)
785 zlog_debug(
786 "%s: %s loses to %s due to localpref %d < %d",
787 pfx_buf, new_buf, exist_buf, new_pref,
788 exist_pref);
789 return 0;
790 }
791
792 /* 3. Local route check. We prefer:
793 * - BGP_ROUTE_STATIC
794 * - BGP_ROUTE_AGGREGATE
795 * - BGP_ROUTE_REDISTRIBUTE
796 */
797 if (!(new->sub_type == BGP_ROUTE_NORMAL ||
798 new->sub_type == BGP_ROUTE_IMPORTED)) {
799 *reason = bgp_path_selection_local_route;
800 if (debug)
801 zlog_debug(
802 "%s: %s wins over %s due to preferred BGP_ROUTE type",
803 pfx_buf, new_buf, exist_buf);
804 return 1;
805 }
806
807 if (!(exist->sub_type == BGP_ROUTE_NORMAL ||
808 exist->sub_type == BGP_ROUTE_IMPORTED)) {
809 *reason = bgp_path_selection_local_route;
810 if (debug)
811 zlog_debug(
812 "%s: %s loses to %s due to preferred BGP_ROUTE type",
813 pfx_buf, new_buf, exist_buf);
814 return 0;
815 }
816
817 /* 4. AS path length check. */
818 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
819 int exist_hops = aspath_count_hops(existattr->aspath);
820 int exist_confeds = aspath_count_confeds(existattr->aspath);
821
822 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
823 int aspath_hops;
824
825 aspath_hops = aspath_count_hops(newattr->aspath);
826 aspath_hops += aspath_count_confeds(newattr->aspath);
827
828 if (aspath_hops < (exist_hops + exist_confeds)) {
829 *reason = bgp_path_selection_confed_as_path;
830 if (debug)
831 zlog_debug(
832 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
833 pfx_buf, new_buf, exist_buf,
834 aspath_hops,
835 (exist_hops + exist_confeds));
836 return 1;
837 }
838
839 if (aspath_hops > (exist_hops + exist_confeds)) {
840 *reason = bgp_path_selection_confed_as_path;
841 if (debug)
842 zlog_debug(
843 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
844 pfx_buf, new_buf, exist_buf,
845 aspath_hops,
846 (exist_hops + exist_confeds));
847 return 0;
848 }
849 } else {
850 int newhops = aspath_count_hops(newattr->aspath);
851
852 if (newhops < exist_hops) {
853 *reason = bgp_path_selection_as_path;
854 if (debug)
855 zlog_debug(
856 "%s: %s wins over %s due to aspath hopcount %d < %d",
857 pfx_buf, new_buf, exist_buf,
858 newhops, exist_hops);
859 return 1;
860 }
861
862 if (newhops > exist_hops) {
863 *reason = bgp_path_selection_as_path;
864 if (debug)
865 zlog_debug(
866 "%s: %s loses to %s due to aspath hopcount %d > %d",
867 pfx_buf, new_buf, exist_buf,
868 newhops, exist_hops);
869 return 0;
870 }
871 }
872 }
873
874 /* 5. Origin check. */
875 if (newattr->origin < existattr->origin) {
876 *reason = bgp_path_selection_origin;
877 if (debug)
878 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
879 pfx_buf, new_buf, exist_buf,
880 bgp_origin_long_str[newattr->origin],
881 bgp_origin_long_str[existattr->origin]);
882 return 1;
883 }
884
885 if (newattr->origin > existattr->origin) {
886 *reason = bgp_path_selection_origin;
887 if (debug)
888 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
889 pfx_buf, new_buf, exist_buf,
890 bgp_origin_long_str[newattr->origin],
891 bgp_origin_long_str[existattr->origin]);
892 return 0;
893 }
894
895 /* 6. MED check. */
896 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
897 && aspath_count_hops(existattr->aspath) == 0);
898 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
899 && aspath_count_confeds(existattr->aspath) > 0
900 && aspath_count_hops(newattr->aspath) == 0
901 && aspath_count_hops(existattr->aspath) == 0);
902
903 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
904 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
905 || aspath_cmp_left(newattr->aspath, existattr->aspath)
906 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
907 || internal_as_route) {
908 new_med = bgp_med_value(new->attr, bgp);
909 exist_med = bgp_med_value(exist->attr, bgp);
910
911 if (new_med < exist_med) {
912 *reason = bgp_path_selection_med;
913 if (debug)
914 zlog_debug(
915 "%s: %s wins over %s due to MED %d < %d",
916 pfx_buf, new_buf, exist_buf, new_med,
917 exist_med);
918 return 1;
919 }
920
921 if (new_med > exist_med) {
922 *reason = bgp_path_selection_med;
923 if (debug)
924 zlog_debug(
925 "%s: %s loses to %s due to MED %d > %d",
926 pfx_buf, new_buf, exist_buf, new_med,
927 exist_med);
928 return 0;
929 }
930 }
931
932 /* 7. Peer type check. */
933 new_sort = new->peer->sort;
934 exist_sort = exist->peer->sort;
935
936 if (new_sort == BGP_PEER_EBGP
937 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
938 *reason = bgp_path_selection_peer;
939 if (debug)
940 zlog_debug(
941 "%s: %s wins over %s due to eBGP peer > iBGP peer",
942 pfx_buf, new_buf, exist_buf);
943 return 1;
944 }
945
946 if (exist_sort == BGP_PEER_EBGP
947 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
948 *reason = bgp_path_selection_peer;
949 if (debug)
950 zlog_debug(
951 "%s: %s loses to %s due to iBGP peer < eBGP peer",
952 pfx_buf, new_buf, exist_buf);
953 return 0;
954 }
955
956 /* 8. IGP metric check. */
957 newm = existm = 0;
958
959 if (new->extra)
960 newm = new->extra->igpmetric;
961 if (exist->extra)
962 existm = exist->extra->igpmetric;
963
964 if (newm < existm) {
965 if (debug)
966 zlog_debug(
967 "%s: %s wins over %s due to IGP metric %d < %d",
968 pfx_buf, new_buf, exist_buf, newm, existm);
969 ret = 1;
970 }
971
972 if (newm > existm) {
973 if (debug)
974 zlog_debug(
975 "%s: %s loses to %s due to IGP metric %d > %d",
976 pfx_buf, new_buf, exist_buf, newm, existm);
977 ret = 0;
978 }
979
980 /* 9. Same IGP metric. Compare the cluster list length as
981 representative of IGP hops metric. Rewrite the metric value
982 pair (newm, existm) with the cluster list length. Prefer the
983 path with smaller cluster list length. */
984 if (newm == existm) {
985 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP
986 && peer_sort_lookup(exist->peer) == BGP_PEER_IBGP
987 && (mpath_cfg == NULL
988 || CHECK_FLAG(
989 mpath_cfg->ibgp_flags,
990 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN))) {
991 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
992 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
993
994 if (newm < existm) {
995 if (debug)
996 zlog_debug(
997 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
998 pfx_buf, new_buf, exist_buf,
999 newm, existm);
1000 ret = 1;
1001 }
1002
1003 if (newm > existm) {
1004 if (debug)
1005 zlog_debug(
1006 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1007 pfx_buf, new_buf, exist_buf,
1008 newm, existm);
1009 ret = 0;
1010 }
1011 }
1012 }
1013
1014 /* 10. confed-external vs. confed-internal */
1015 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1016 if (new_sort == BGP_PEER_CONFED
1017 && exist_sort == BGP_PEER_IBGP) {
1018 *reason = bgp_path_selection_confed;
1019 if (debug)
1020 zlog_debug(
1021 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1022 pfx_buf, new_buf, exist_buf);
1023 return 1;
1024 }
1025
1026 if (exist_sort == BGP_PEER_CONFED
1027 && new_sort == BGP_PEER_IBGP) {
1028 *reason = bgp_path_selection_confed;
1029 if (debug)
1030 zlog_debug(
1031 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1032 pfx_buf, new_buf, exist_buf);
1033 return 0;
1034 }
1035 }
1036
1037 /* 11. Maximum path check. */
1038 if (newm == existm) {
1039 /* If one path has a label but the other does not, do not treat
1040 * them as equals for multipath
1041 */
1042 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1043 != (exist->extra
1044 && bgp_is_valid_label(&exist->extra->label[0]))) {
1045 if (debug)
1046 zlog_debug(
1047 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1048 pfx_buf, new_buf, exist_buf);
1049 } else if (CHECK_FLAG(bgp->flags,
1050 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1051
1052 /*
1053 * For the two paths, all comparison steps till IGP
1054 * metric
1055 * have succeeded - including AS_PATH hop count. Since
1056 * 'bgp
1057 * bestpath as-path multipath-relax' knob is on, we
1058 * don't need
1059 * an exact match of AS_PATH. Thus, mark the paths are
1060 * equal.
1061 * That will trigger both these paths to get into the
1062 * multipath
1063 * array.
1064 */
1065 *paths_eq = 1;
1066
1067 if (debug)
1068 zlog_debug(
1069 "%s: %s and %s are equal via multipath-relax",
1070 pfx_buf, new_buf, exist_buf);
1071 } else if (new->peer->sort == BGP_PEER_IBGP) {
1072 if (aspath_cmp(new->attr->aspath,
1073 exist->attr->aspath)) {
1074 *paths_eq = 1;
1075
1076 if (debug)
1077 zlog_debug(
1078 "%s: %s and %s are equal via matching aspaths",
1079 pfx_buf, new_buf, exist_buf);
1080 }
1081 } else if (new->peer->as == exist->peer->as) {
1082 *paths_eq = 1;
1083
1084 if (debug)
1085 zlog_debug(
1086 "%s: %s and %s are equal via same remote-as",
1087 pfx_buf, new_buf, exist_buf);
1088 }
1089 } else {
1090 /*
1091 * TODO: If unequal cost ibgp multipath is enabled we can
1092 * mark the paths as equal here instead of returning
1093 */
1094 if (debug) {
1095 if (ret == 1)
1096 zlog_debug(
1097 "%s: %s wins over %s after IGP metric comparison",
1098 pfx_buf, new_buf, exist_buf);
1099 else
1100 zlog_debug(
1101 "%s: %s loses to %s after IGP metric comparison",
1102 pfx_buf, new_buf, exist_buf);
1103 }
1104 *reason = bgp_path_selection_igp_metric;
1105 return ret;
1106 }
1107
1108 /* 12. If both paths are external, prefer the path that was received
1109 first (the oldest one). This step minimizes route-flap, since a
1110 newer path won't displace an older one, even if it was the
1111 preferred route based on the additional decision criteria below. */
1112 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1113 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1114 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1115 *reason = bgp_path_selection_older;
1116 if (debug)
1117 zlog_debug(
1118 "%s: %s wins over %s due to oldest external",
1119 pfx_buf, new_buf, exist_buf);
1120 return 1;
1121 }
1122
1123 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1124 *reason = bgp_path_selection_older;
1125 if (debug)
1126 zlog_debug(
1127 "%s: %s loses to %s due to oldest external",
1128 pfx_buf, new_buf, exist_buf);
1129 return 0;
1130 }
1131 }
1132
1133 /* 13. Router-ID comparision. */
1134 /* If one of the paths is "stale", the corresponding peer router-id will
1135 * be 0 and would always win over the other path. If originator id is
1136 * used for the comparision, it will decide which path is better.
1137 */
1138 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1139 new_id.s_addr = newattr->originator_id.s_addr;
1140 else
1141 new_id.s_addr = new->peer->remote_id.s_addr;
1142 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1143 exist_id.s_addr = existattr->originator_id.s_addr;
1144 else
1145 exist_id.s_addr = exist->peer->remote_id.s_addr;
1146
1147 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1148 *reason = bgp_path_selection_router_id;
1149 if (debug)
1150 zlog_debug(
1151 "%s: %s wins over %s due to Router-ID comparison",
1152 pfx_buf, new_buf, exist_buf);
1153 return 1;
1154 }
1155
1156 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1157 *reason = bgp_path_selection_router_id;
1158 if (debug)
1159 zlog_debug(
1160 "%s: %s loses to %s due to Router-ID comparison",
1161 pfx_buf, new_buf, exist_buf);
1162 return 0;
1163 }
1164
1165 /* 14. Cluster length comparision. */
1166 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1167 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1168
1169 if (new_cluster < exist_cluster) {
1170 *reason = bgp_path_selection_cluster_length;
1171 if (debug)
1172 zlog_debug(
1173 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1174 pfx_buf, new_buf, exist_buf, new_cluster,
1175 exist_cluster);
1176 return 1;
1177 }
1178
1179 if (new_cluster > exist_cluster) {
1180 *reason = bgp_path_selection_cluster_length;
1181 if (debug)
1182 zlog_debug(
1183 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1184 pfx_buf, new_buf, exist_buf, new_cluster,
1185 exist_cluster);
1186 return 0;
1187 }
1188
1189 /* 15. Neighbor address comparision. */
1190 /* Do this only if neither path is "stale" as stale paths do not have
1191 * valid peer information (as the connection may or may not be up).
1192 */
1193 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1194 *reason = bgp_path_selection_stale;
1195 if (debug)
1196 zlog_debug(
1197 "%s: %s wins over %s due to latter path being STALE",
1198 pfx_buf, new_buf, exist_buf);
1199 return 1;
1200 }
1201
1202 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1203 *reason = bgp_path_selection_stale;
1204 if (debug)
1205 zlog_debug(
1206 "%s: %s loses to %s due to former path being STALE",
1207 pfx_buf, new_buf, exist_buf);
1208 return 0;
1209 }
1210
1211 /* locally configured routes to advertise do not have su_remote */
1212 if (new->peer->su_remote == NULL) {
1213 *reason = bgp_path_selection_local_configured;
1214 return 0;
1215 }
1216 if (exist->peer->su_remote == NULL) {
1217 *reason = bgp_path_selection_local_configured;
1218 return 1;
1219 }
1220
1221 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1222
1223 if (ret == 1) {
1224 *reason = bgp_path_selection_neighbor_ip;
1225 if (debug)
1226 zlog_debug(
1227 "%s: %s loses to %s due to Neighor IP comparison",
1228 pfx_buf, new_buf, exist_buf);
1229 return 0;
1230 }
1231
1232 if (ret == -1) {
1233 *reason = bgp_path_selection_neighbor_ip;
1234 if (debug)
1235 zlog_debug(
1236 "%s: %s wins over %s due to Neighor IP comparison",
1237 pfx_buf, new_buf, exist_buf);
1238 return 1;
1239 }
1240
1241 *reason = bgp_path_selection_default;
1242 if (debug)
1243 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1244 pfx_buf, new_buf, exist_buf);
1245
1246 return 1;
1247 }
1248
1249
1250 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1251 struct bgp_path_info *exist, int *paths_eq)
1252 {
1253 enum bgp_path_selection_reason reason;
1254 char pfx_buf[PREFIX2STR_BUFFER];
1255
1256 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1257 AFI_L2VPN, SAFI_EVPN, &reason);
1258 }
1259
1260 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1261 * is preferred, or 0 if they are the same (usually will only occur if
1262 * multipath is enabled
1263 * This version is compatible with */
1264 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1265 struct bgp_path_info *exist, char *pfx_buf,
1266 afi_t afi, safi_t safi,
1267 enum bgp_path_selection_reason *reason)
1268 {
1269 int paths_eq;
1270 int ret;
1271 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1272 afi, safi, reason);
1273
1274 if (paths_eq)
1275 ret = 0;
1276 else {
1277 if (ret == 1)
1278 ret = -1;
1279 else
1280 ret = 1;
1281 }
1282 return ret;
1283 }
1284
1285 static enum filter_type bgp_input_filter(struct peer *peer,
1286 const struct prefix *p,
1287 struct attr *attr, afi_t afi,
1288 safi_t safi)
1289 {
1290 struct bgp_filter *filter;
1291
1292 filter = &peer->filter[afi][safi];
1293
1294 #define FILTER_EXIST_WARN(F, f, filter) \
1295 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1296 zlog_debug("%s: Could not find configured input %s-list %s!", \
1297 peer->host, #f, F##_IN_NAME(filter));
1298
1299 if (DISTRIBUTE_IN_NAME(filter)) {
1300 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1301
1302 if (access_list_apply(DISTRIBUTE_IN(filter), p) == FILTER_DENY)
1303 return FILTER_DENY;
1304 }
1305
1306 if (PREFIX_LIST_IN_NAME(filter)) {
1307 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1308
1309 if (prefix_list_apply(PREFIX_LIST_IN(filter), p) == PREFIX_DENY)
1310 return FILTER_DENY;
1311 }
1312
1313 if (FILTER_LIST_IN_NAME(filter)) {
1314 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1315
1316 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1317 == AS_FILTER_DENY)
1318 return FILTER_DENY;
1319 }
1320
1321 return FILTER_PERMIT;
1322 #undef FILTER_EXIST_WARN
1323 }
1324
1325 static enum filter_type bgp_output_filter(struct peer *peer,
1326 const struct prefix *p,
1327 struct attr *attr, afi_t afi,
1328 safi_t safi)
1329 {
1330 struct bgp_filter *filter;
1331
1332 filter = &peer->filter[afi][safi];
1333
1334 #define FILTER_EXIST_WARN(F, f, filter) \
1335 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1336 zlog_debug("%s: Could not find configured output %s-list %s!", \
1337 peer->host, #f, F##_OUT_NAME(filter));
1338
1339 if (DISTRIBUTE_OUT_NAME(filter)) {
1340 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1341
1342 if (access_list_apply(DISTRIBUTE_OUT(filter), p) == FILTER_DENY)
1343 return FILTER_DENY;
1344 }
1345
1346 if (PREFIX_LIST_OUT_NAME(filter)) {
1347 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1348
1349 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1350 == PREFIX_DENY)
1351 return FILTER_DENY;
1352 }
1353
1354 if (FILTER_LIST_OUT_NAME(filter)) {
1355 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1356
1357 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1358 == AS_FILTER_DENY)
1359 return FILTER_DENY;
1360 }
1361
1362 return FILTER_PERMIT;
1363 #undef FILTER_EXIST_WARN
1364 }
1365
1366 /* If community attribute includes no_export then return 1. */
1367 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1368 {
1369 if (attr->community) {
1370 /* NO_ADVERTISE check. */
1371 if (community_include(attr->community, COMMUNITY_NO_ADVERTISE))
1372 return true;
1373
1374 /* NO_EXPORT check. */
1375 if (peer->sort == BGP_PEER_EBGP
1376 && community_include(attr->community, COMMUNITY_NO_EXPORT))
1377 return true;
1378
1379 /* NO_EXPORT_SUBCONFED check. */
1380 if (peer->sort == BGP_PEER_EBGP
1381 || peer->sort == BGP_PEER_CONFED)
1382 if (community_include(attr->community,
1383 COMMUNITY_NO_EXPORT_SUBCONFED))
1384 return true;
1385 }
1386 return false;
1387 }
1388
1389 /* Route reflection loop check. */
1390 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1391 {
1392 struct in_addr cluster_id;
1393
1394 if (attr->cluster) {
1395 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1396 cluster_id = peer->bgp->cluster_id;
1397 else
1398 cluster_id = peer->bgp->router_id;
1399
1400 if (cluster_loop_check(attr->cluster, cluster_id))
1401 return true;
1402 }
1403 return false;
1404 }
1405
1406 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1407 struct attr *attr, afi_t afi, safi_t safi,
1408 const char *rmap_name, mpls_label_t *label,
1409 uint32_t num_labels, struct bgp_dest *dest)
1410 {
1411 struct bgp_filter *filter;
1412 struct bgp_path_info rmap_path = { 0 };
1413 struct bgp_path_info_extra extra = { 0 };
1414 route_map_result_t ret;
1415 struct route_map *rmap = NULL;
1416
1417 filter = &peer->filter[afi][safi];
1418
1419 /* Apply default weight value. */
1420 if (peer->weight[afi][safi])
1421 attr->weight = peer->weight[afi][safi];
1422
1423 if (rmap_name) {
1424 rmap = route_map_lookup_by_name(rmap_name);
1425
1426 if (rmap == NULL)
1427 return RMAP_DENY;
1428 } else {
1429 if (ROUTE_MAP_IN_NAME(filter)) {
1430 rmap = ROUTE_MAP_IN(filter);
1431
1432 if (rmap == NULL)
1433 return RMAP_DENY;
1434 }
1435 }
1436
1437 /* Route map apply. */
1438 if (rmap) {
1439 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1440 /* Duplicate current value to new strucutre for modification. */
1441 rmap_path.peer = peer;
1442 rmap_path.attr = attr;
1443 rmap_path.extra = &extra;
1444 rmap_path.net = dest;
1445
1446 extra.num_labels = num_labels;
1447 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1448 memcpy(extra.label, label,
1449 num_labels * sizeof(mpls_label_t));
1450
1451 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1452
1453 /* Apply BGP route map to the attribute. */
1454 ret = route_map_apply(rmap, p, RMAP_BGP, &rmap_path);
1455
1456 peer->rmap_type = 0;
1457
1458 if (ret == RMAP_DENYMATCH)
1459 return RMAP_DENY;
1460 }
1461 return RMAP_PERMIT;
1462 }
1463
1464 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1465 struct attr *attr, afi_t afi, safi_t safi,
1466 const char *rmap_name)
1467 {
1468 struct bgp_path_info rmap_path;
1469 route_map_result_t ret;
1470 struct route_map *rmap = NULL;
1471 uint8_t rmap_type;
1472
1473 /*
1474 * So if we get to this point and have no rmap_name
1475 * we want to just show the output as it currently
1476 * exists.
1477 */
1478 if (!rmap_name)
1479 return RMAP_PERMIT;
1480
1481 /* Apply default weight value. */
1482 if (peer->weight[afi][safi])
1483 attr->weight = peer->weight[afi][safi];
1484
1485 rmap = route_map_lookup_by_name(rmap_name);
1486
1487 /*
1488 * If we have a route map name and we do not find
1489 * the routemap that means we have an implicit
1490 * deny.
1491 */
1492 if (rmap == NULL)
1493 return RMAP_DENY;
1494
1495 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1496 /* Route map apply. */
1497 /* Duplicate current value to new strucutre for modification. */
1498 rmap_path.peer = peer;
1499 rmap_path.attr = attr;
1500
1501 rmap_type = peer->rmap_type;
1502 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1503
1504 /* Apply BGP route map to the attribute. */
1505 ret = route_map_apply(rmap, p, RMAP_BGP, &rmap_path);
1506
1507 peer->rmap_type = rmap_type;
1508
1509 if (ret == RMAP_DENYMATCH)
1510 /*
1511 * caller has multiple error paths with bgp_attr_flush()
1512 */
1513 return RMAP_DENY;
1514
1515 return RMAP_PERMIT;
1516 }
1517
1518 /* If this is an EBGP peer with remove-private-AS */
1519 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1520 struct peer *peer, struct attr *attr)
1521 {
1522 if (peer->sort == BGP_PEER_EBGP
1523 && (peer_af_flag_check(peer, afi, safi,
1524 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1525 || peer_af_flag_check(peer, afi, safi,
1526 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1527 || peer_af_flag_check(peer, afi, safi,
1528 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1529 || peer_af_flag_check(peer, afi, safi,
1530 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1531 // Take action on the entire aspath
1532 if (peer_af_flag_check(peer, afi, safi,
1533 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1534 || peer_af_flag_check(peer, afi, safi,
1535 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1536 if (peer_af_flag_check(
1537 peer, afi, safi,
1538 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1539 attr->aspath = aspath_replace_private_asns(
1540 attr->aspath, bgp->as, peer->as);
1541
1542 // The entire aspath consists of private ASNs so create
1543 // an empty aspath
1544 else if (aspath_private_as_check(attr->aspath))
1545 attr->aspath = aspath_empty_get();
1546
1547 // There are some public and some private ASNs, remove
1548 // the private ASNs
1549 else
1550 attr->aspath = aspath_remove_private_asns(
1551 attr->aspath, peer->as);
1552 }
1553
1554 // 'all' was not specified so the entire aspath must be private
1555 // ASNs
1556 // for us to do anything
1557 else if (aspath_private_as_check(attr->aspath)) {
1558 if (peer_af_flag_check(
1559 peer, afi, safi,
1560 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1561 attr->aspath = aspath_replace_private_asns(
1562 attr->aspath, bgp->as, peer->as);
1563 else
1564 attr->aspath = aspath_empty_get();
1565 }
1566 }
1567 }
1568
1569 /* If this is an EBGP peer with as-override */
1570 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1571 struct peer *peer, struct attr *attr)
1572 {
1573 if (peer->sort == BGP_PEER_EBGP
1574 && peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1575 if (aspath_single_asn_check(attr->aspath, peer->as))
1576 attr->aspath = aspath_replace_specific_asn(
1577 attr->aspath, peer->as, bgp->as);
1578 }
1579 }
1580
1581 void bgp_attr_add_gshut_community(struct attr *attr)
1582 {
1583 struct community *old;
1584 struct community *new;
1585 struct community *merge;
1586 struct community *gshut;
1587
1588 old = attr->community;
1589 gshut = community_str2com("graceful-shutdown");
1590
1591 assert(gshut);
1592
1593 if (old) {
1594 merge = community_merge(community_dup(old), gshut);
1595
1596 if (old->refcnt == 0)
1597 community_free(&old);
1598
1599 new = community_uniq_sort(merge);
1600 community_free(&merge);
1601 } else {
1602 new = community_dup(gshut);
1603 }
1604
1605 community_free(&gshut);
1606 attr->community = new;
1607 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
1608
1609 /* When we add the graceful-shutdown community we must also
1610 * lower the local-preference */
1611 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1612 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1613 }
1614
1615
1616 static void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1617 {
1618 if (family == AF_INET) {
1619 attr->nexthop.s_addr = INADDR_ANY;
1620 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1621 }
1622 if (family == AF_INET6)
1623 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1624 if (family == AF_EVPN)
1625 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1626 }
1627
1628 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1629 struct update_subgroup *subgrp,
1630 const struct prefix *p, struct attr *attr)
1631 {
1632 struct bgp_filter *filter;
1633 struct peer *from;
1634 struct peer *peer;
1635 struct peer *onlypeer;
1636 struct bgp *bgp;
1637 struct attr *piattr;
1638 char buf[PREFIX_STRLEN];
1639 route_map_result_t ret;
1640 int transparent;
1641 int reflect;
1642 afi_t afi;
1643 safi_t safi;
1644 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1645 bool nh_reset = false;
1646 uint64_t cum_bw;
1647
1648 if (DISABLE_BGP_ANNOUNCE)
1649 return false;
1650
1651 afi = SUBGRP_AFI(subgrp);
1652 safi = SUBGRP_SAFI(subgrp);
1653 peer = SUBGRP_PEER(subgrp);
1654 onlypeer = NULL;
1655 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1656 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1657
1658 from = pi->peer;
1659 filter = &peer->filter[afi][safi];
1660 bgp = SUBGRP_INST(subgrp);
1661 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
1662 : pi->attr;
1663
1664 #ifdef ENABLE_BGP_VNC
1665 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
1666 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
1667 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
1668
1669 /*
1670 * direct and direct_ext type routes originate internally even
1671 * though they can have peer pointers that reference other
1672 * systems
1673 */
1674 prefix2str(p, buf, PREFIX_STRLEN);
1675 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe",
1676 __func__, buf);
1677 samepeer_safe = 1;
1678 }
1679 #endif
1680
1681 if (((afi == AFI_IP) || (afi == AFI_IP6))
1682 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
1683 && (pi->type == ZEBRA_ROUTE_BGP)
1684 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
1685
1686 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1687
1688 samepeer_safe = 1;
1689 }
1690
1691 /* With addpath we may be asked to TX all kinds of paths so make sure
1692 * pi is valid */
1693 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
1694 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
1695 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
1696 return false;
1697 }
1698
1699 /* If this is not the bestpath then check to see if there is an enabled
1700 * addpath
1701 * feature that requires us to advertise it */
1702 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
1703 if (!bgp_addpath_tx_path(peer->addpath_type[afi][safi], pi)) {
1704 return false;
1705 }
1706 }
1707
1708 /* Aggregate-address suppress check. */
1709 if (pi->extra && pi->extra->suppress)
1710 if (!UNSUPPRESS_MAP_NAME(filter)) {
1711 return false;
1712 }
1713
1714 /*
1715 * If we are doing VRF 2 VRF leaking via the import
1716 * statement, we want to prevent the route going
1717 * off box as that the RT and RD created are localy
1718 * significant and globaly useless.
1719 */
1720 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
1721 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
1722 return false;
1723
1724 /* If it's labeled safi, make sure the route has a valid label. */
1725 if (safi == SAFI_LABELED_UNICAST) {
1726 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
1727 if (!bgp_is_valid_label(&label)) {
1728 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1729 zlog_debug("u%" PRIu64 ":s%" PRIu64" %s/%d is filtered - no label (%p)",
1730 subgrp->update_group->id, subgrp->id,
1731 inet_ntop(p->family, &p->u.prefix,
1732 buf, SU_ADDRSTRLEN),
1733 p->prefixlen, &label);
1734 return false;
1735 }
1736 }
1737
1738 /* Do not send back route to sender. */
1739 if (onlypeer && from == onlypeer) {
1740 return false;
1741 }
1742
1743 /* Do not send the default route in the BGP table if the neighbor is
1744 * configured for default-originate */
1745 if (CHECK_FLAG(peer->af_flags[afi][safi],
1746 PEER_FLAG_DEFAULT_ORIGINATE)) {
1747 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
1748 return false;
1749 else if (p->family == AF_INET6 && p->prefixlen == 0)
1750 return false;
1751 }
1752
1753 /* Transparency check. */
1754 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
1755 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1756 transparent = 1;
1757 else
1758 transparent = 0;
1759
1760 /* If community is not disabled check the no-export and local. */
1761 if (!transparent && bgp_community_filter(peer, piattr)) {
1762 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1763 zlog_debug(
1764 "subgrpannouncecheck: community filter check fail");
1765 return false;
1766 }
1767
1768 /* If the attribute has originator-id and it is same as remote
1769 peer's id. */
1770 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
1771 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
1772 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1773 zlog_debug(
1774 "%s [Update:SEND] %s originator-id is same as remote router-id",
1775 onlypeer->host,
1776 prefix2str(p, buf, sizeof(buf)));
1777 return false;
1778 }
1779
1780 /* ORF prefix-list filter check */
1781 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
1782 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
1783 || CHECK_FLAG(peer->af_cap[afi][safi],
1784 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
1785 if (peer->orf_plist[afi][safi]) {
1786 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
1787 == PREFIX_DENY) {
1788 if (bgp_debug_update(NULL, p,
1789 subgrp->update_group, 0))
1790 zlog_debug(
1791 "%s [Update:SEND] %s is filtered via ORF",
1792 peer->host,
1793 prefix2str(p, buf,
1794 sizeof(buf)));
1795 return false;
1796 }
1797 }
1798
1799 /* Output filter check. */
1800 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
1801 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1802 zlog_debug("%s [Update:SEND] %s is filtered",
1803 peer->host, prefix2str(p, buf, sizeof(buf)));
1804 return false;
1805 }
1806
1807 /* AS path loop check. */
1808 if (onlypeer && onlypeer->as_path_loop_detection
1809 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
1810 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1811 zlog_debug(
1812 "%s [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
1813 onlypeer->host, onlypeer->as);
1814 return false;
1815 }
1816
1817 /* If we're a CONFED we need to loop check the CONFED ID too */
1818 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1819 if (aspath_loop_check(piattr->aspath, bgp->confed_id)) {
1820 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1821 zlog_debug(
1822 "%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
1823 peer->host, bgp->confed_id);
1824 return false;
1825 }
1826 }
1827
1828 /* Route-Reflect check. */
1829 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
1830 reflect = 1;
1831 else
1832 reflect = 0;
1833
1834 /* IBGP reflection check. */
1835 if (reflect && !samepeer_safe) {
1836 /* A route from a Client peer. */
1837 if (CHECK_FLAG(from->af_flags[afi][safi],
1838 PEER_FLAG_REFLECTOR_CLIENT)) {
1839 /* Reflect to all the Non-Client peers and also to the
1840 Client peers other than the originator. Originator
1841 check
1842 is already done. So there is noting to do. */
1843 /* no bgp client-to-client reflection check. */
1844 if (CHECK_FLAG(bgp->flags,
1845 BGP_FLAG_NO_CLIENT_TO_CLIENT))
1846 if (CHECK_FLAG(peer->af_flags[afi][safi],
1847 PEER_FLAG_REFLECTOR_CLIENT))
1848 return false;
1849 } else {
1850 /* A route from a Non-client peer. Reflect to all other
1851 clients. */
1852 if (!CHECK_FLAG(peer->af_flags[afi][safi],
1853 PEER_FLAG_REFLECTOR_CLIENT))
1854 return false;
1855 }
1856 }
1857
1858 /* For modify attribute, copy it to temporary structure. */
1859 *attr = *piattr;
1860
1861 /* If local-preference is not set. */
1862 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
1863 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
1864 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1865 attr->local_pref = bgp->default_local_pref;
1866 }
1867
1868 /* If originator-id is not set and the route is to be reflected,
1869 set the originator id */
1870 if (reflect
1871 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
1872 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
1873 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
1874 }
1875
1876 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
1877 */
1878 if (peer->sort == BGP_PEER_EBGP
1879 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
1880 if (from != bgp->peer_self && !transparent
1881 && !CHECK_FLAG(peer->af_flags[afi][safi],
1882 PEER_FLAG_MED_UNCHANGED))
1883 attr->flag &=
1884 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
1885 }
1886
1887 /* Since the nexthop attribute can vary per peer, it is not explicitly
1888 * set
1889 * in announce check, only certain flags and length (or number of
1890 * nexthops
1891 * -- for IPv6/MP_REACH) are set here in order to guide the update
1892 * formation
1893 * code in setting the nexthop(s) on a per peer basis in
1894 * reformat_peer().
1895 * Typically, the source nexthop in the attribute is preserved but in
1896 * the
1897 * scenarios where we know it will always be overwritten, we reset the
1898 * nexthop to "0" in an attempt to achieve better Update packing. An
1899 * example of this is when a prefix from each of 2 IBGP peers needs to
1900 * be
1901 * announced to an EBGP peer (and they have the same attributes barring
1902 * their nexthop).
1903 */
1904 if (reflect)
1905 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
1906
1907 #define NEXTHOP_IS_V6 \
1908 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
1909 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
1910 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
1911 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1912
1913 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
1914 * if
1915 * the peer (group) is configured to receive link-local nexthop
1916 * unchanged
1917 * and it is available in the prefix OR we're not reflecting the route,
1918 * link-local nexthop address is valid and
1919 * the peer (group) to whom we're going to announce is on a shared
1920 * network
1921 * and this is either a self-originated route or the peer is EBGP.
1922 * By checking if nexthop LL address is valid we are sure that
1923 * we do not announce LL address as `::`.
1924 */
1925 if (NEXTHOP_IS_V6) {
1926 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
1927 if ((CHECK_FLAG(peer->af_flags[afi][safi],
1928 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
1929 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
1930 || (!reflect
1931 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
1932 && peer->shared_network
1933 && (from == bgp->peer_self
1934 || peer->sort == BGP_PEER_EBGP))) {
1935 attr->mp_nexthop_len =
1936 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
1937 }
1938
1939 /* Clear off link-local nexthop in source, whenever it is not
1940 * needed to
1941 * ensure more prefixes share the same attribute for
1942 * announcement.
1943 */
1944 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
1945 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
1946 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
1947 }
1948
1949 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
1950 bgp_peer_as_override(bgp, afi, safi, peer, attr);
1951
1952 /* Route map & unsuppress-map apply. */
1953 if (ROUTE_MAP_OUT_NAME(filter) || (pi->extra && pi->extra->suppress)) {
1954 struct bgp_path_info rmap_path = {0};
1955 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
1956 struct attr dummy_attr = {0};
1957
1958 /* Fill temp path_info */
1959 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
1960 pi, peer, attr);
1961
1962 /* don't confuse inbound and outbound setting */
1963 RESET_FLAG(attr->rmap_change_flags);
1964
1965 /*
1966 * The route reflector is not allowed to modify the attributes
1967 * of the reflected IBGP routes unless explicitly allowed.
1968 */
1969 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
1970 && !CHECK_FLAG(bgp->flags,
1971 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
1972 dummy_attr = *attr;
1973 rmap_path.attr = &dummy_attr;
1974 }
1975
1976 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1977
1978 if (pi->extra && pi->extra->suppress)
1979 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
1980 RMAP_BGP, &rmap_path);
1981 else
1982 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
1983 RMAP_BGP, &rmap_path);
1984
1985 peer->rmap_type = 0;
1986
1987 if (ret == RMAP_DENYMATCH) {
1988 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1989 zlog_debug("%s [Update:SEND] %s is filtered by route-map",
1990 peer->host, prefix2str(p, buf, sizeof(buf)));
1991
1992 bgp_attr_flush(attr);
1993 return false;
1994 }
1995 }
1996
1997 /* RFC 8212 to prevent route leaks.
1998 * This specification intends to improve this situation by requiring the
1999 * explicit configuration of both BGP Import and Export Policies for any
2000 * External BGP (EBGP) session such as customers, peers, or
2001 * confederation boundaries for all enabled address families. Through
2002 * codification of the aforementioned requirement, operators will
2003 * benefit from consistent behavior across different BGP
2004 * implementations.
2005 */
2006 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2007 if (!bgp_outbound_policy_exists(peer, filter))
2008 return false;
2009
2010 /* draft-ietf-idr-deprecate-as-set-confed-set
2011 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2012 * Eventually, This document (if approved) updates RFC 4271
2013 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2014 * and obsoletes RFC 6472.
2015 */
2016 if (peer->bgp->reject_as_sets)
2017 if (aspath_check_as_sets(attr->aspath))
2018 return false;
2019
2020 /* Codification of AS 0 Processing */
2021 if (aspath_check_as_zero(attr->aspath))
2022 return false;
2023
2024 if (bgp_in_graceful_shutdown(bgp)) {
2025 if (peer->sort == BGP_PEER_IBGP
2026 || peer->sort == BGP_PEER_CONFED) {
2027 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2028 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2029 } else {
2030 bgp_attr_add_gshut_community(attr);
2031 }
2032 }
2033
2034 /* After route-map has been applied, we check to see if the nexthop to
2035 * be carried in the attribute (that is used for the announcement) can
2036 * be cleared off or not. We do this in all cases where we would be
2037 * setting the nexthop to "ourselves". For IPv6, we only need to
2038 * consider
2039 * the global nexthop here; the link-local nexthop would have been
2040 * cleared
2041 * already, and if not, it is required by the update formation code.
2042 * Also see earlier comments in this function.
2043 */
2044 /*
2045 * If route-map has performed some operation on the nexthop or the peer
2046 * configuration says to pass it unchanged, we cannot reset the nexthop
2047 * here, so only attempt to do it if these aren't true. Note that the
2048 * route-map handler itself might have cleared the nexthop, if for
2049 * example,
2050 * it is configured as 'peer-address'.
2051 */
2052 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2053 piattr->rmap_change_flags)
2054 && !transparent
2055 && !CHECK_FLAG(peer->af_flags[afi][safi],
2056 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2057 /* We can reset the nexthop, if setting (or forcing) it to
2058 * 'self' */
2059 if (CHECK_FLAG(peer->af_flags[afi][safi],
2060 PEER_FLAG_NEXTHOP_SELF)
2061 || CHECK_FLAG(peer->af_flags[afi][safi],
2062 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2063 if (!reflect
2064 || CHECK_FLAG(peer->af_flags[afi][safi],
2065 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2066 subgroup_announce_reset_nhop(
2067 (peer_cap_enhe(peer, afi, safi)
2068 ? AF_INET6
2069 : p->family),
2070 attr);
2071 nh_reset = true;
2072 }
2073 } else if (peer->sort == BGP_PEER_EBGP) {
2074 /* Can also reset the nexthop if announcing to EBGP, but
2075 * only if
2076 * no peer in the subgroup is on a shared subnet.
2077 * Note: 3rd party nexthop currently implemented for
2078 * IPv4 only.
2079 */
2080 if ((p->family == AF_INET) &&
2081 (!bgp_subgrp_multiaccess_check_v4(
2082 piattr->nexthop,
2083 subgrp, from))) {
2084 subgroup_announce_reset_nhop(
2085 (peer_cap_enhe(peer, afi, safi)
2086 ? AF_INET6
2087 : p->family),
2088 attr);
2089 nh_reset = true;
2090 }
2091
2092 if ((p->family == AF_INET6) &&
2093 (!bgp_subgrp_multiaccess_check_v6(
2094 piattr->mp_nexthop_global,
2095 subgrp, from))) {
2096 subgroup_announce_reset_nhop(
2097 (peer_cap_enhe(peer, afi, safi)
2098 ? AF_INET6
2099 : p->family),
2100 attr);
2101 nh_reset = true;
2102 }
2103
2104
2105
2106 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2107 /*
2108 * This flag is used for leaked vpn-vrf routes
2109 */
2110 int family = p->family;
2111
2112 if (peer_cap_enhe(peer, afi, safi))
2113 family = AF_INET6;
2114
2115 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2116 zlog_debug(
2117 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
2118 __func__, family2str(family));
2119 subgroup_announce_reset_nhop(family, attr);
2120 nh_reset = true;
2121 }
2122 }
2123
2124 /* If IPv6/MP and nexthop does not have any override and happens
2125 * to
2126 * be a link-local address, reset it so that we don't pass along
2127 * the
2128 * source's link-local IPv6 address to recipients who may not be
2129 * on
2130 * the same interface.
2131 */
2132 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2133 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2134 subgroup_announce_reset_nhop(AF_INET6, attr);
2135 nh_reset = true;
2136 }
2137 }
2138
2139 /*
2140 * When the next hop is set to ourselves, if all multipaths have
2141 * link-bandwidth announce the cumulative bandwidth as that makes
2142 * the most sense. However, don't modify if the link-bandwidth has
2143 * been explicitly set by user policy.
2144 */
2145 if (nh_reset &&
2146 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2147 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2148 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2149 attr->ecommunity = ecommunity_replace_linkbw(
2150 bgp->as, attr->ecommunity, cum_bw);
2151
2152 return true;
2153 }
2154
2155 static int bgp_route_select_timer_expire(struct thread *thread)
2156 {
2157 struct afi_safi_info *info;
2158 afi_t afi;
2159 safi_t safi;
2160 struct bgp *bgp;
2161
2162 info = THREAD_ARG(thread);
2163 afi = info->afi;
2164 safi = info->safi;
2165 bgp = info->bgp;
2166
2167 if (BGP_DEBUG(update, UPDATE_OUT))
2168 zlog_debug("afi %d, safi %d : route select timer expired", afi,
2169 safi);
2170
2171 bgp->gr_info[afi][safi].t_route_select = NULL;
2172
2173 XFREE(MTYPE_TMP, info);
2174
2175 /* Best path selection */
2176 return bgp_best_path_select_defer(bgp, afi, safi);
2177 }
2178
2179 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2180 struct bgp_maxpaths_cfg *mpath_cfg,
2181 struct bgp_path_info_pair *result, afi_t afi,
2182 safi_t safi)
2183 {
2184 struct bgp_path_info *new_select;
2185 struct bgp_path_info *old_select;
2186 struct bgp_path_info *pi;
2187 struct bgp_path_info *pi1;
2188 struct bgp_path_info *pi2;
2189 struct bgp_path_info *nextpi = NULL;
2190 int paths_eq, do_mpath, debug;
2191 struct list mp_list;
2192 char pfx_buf[PREFIX2STR_BUFFER];
2193 char path_buf[PATH_ADDPATH_STR_BUFFER];
2194
2195 bgp_mp_list_init(&mp_list);
2196 do_mpath =
2197 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2198
2199 debug = bgp_debug_bestpath(dest);
2200
2201 if (debug)
2202 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2203
2204 dest->reason = bgp_path_selection_none;
2205 /* bgp deterministic-med */
2206 new_select = NULL;
2207 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2208
2209 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2210 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2211 pi1 = pi1->next)
2212 bgp_path_info_unset_flag(dest, pi1,
2213 BGP_PATH_DMED_SELECTED);
2214
2215 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2216 pi1 = pi1->next) {
2217 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2218 continue;
2219 if (BGP_PATH_HOLDDOWN(pi1))
2220 continue;
2221 if (pi1->peer != bgp->peer_self)
2222 if (pi1->peer->status != Established)
2223 continue;
2224
2225 new_select = pi1;
2226 if (pi1->next) {
2227 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2228 if (CHECK_FLAG(pi2->flags,
2229 BGP_PATH_DMED_CHECK))
2230 continue;
2231 if (BGP_PATH_HOLDDOWN(pi2))
2232 continue;
2233 if (pi2->peer != bgp->peer_self
2234 && !CHECK_FLAG(
2235 pi2->peer->sflags,
2236 PEER_STATUS_NSF_WAIT))
2237 if (pi2->peer->status
2238 != Established)
2239 continue;
2240
2241 if (!aspath_cmp_left(pi1->attr->aspath,
2242 pi2->attr->aspath)
2243 && !aspath_cmp_left_confed(
2244 pi1->attr->aspath,
2245 pi2->attr->aspath))
2246 continue;
2247
2248 if (bgp_path_info_cmp(
2249 bgp, pi2, new_select,
2250 &paths_eq, mpath_cfg, debug,
2251 pfx_buf, afi, safi,
2252 &dest->reason)) {
2253 bgp_path_info_unset_flag(
2254 dest, new_select,
2255 BGP_PATH_DMED_SELECTED);
2256 new_select = pi2;
2257 }
2258
2259 bgp_path_info_set_flag(
2260 dest, pi2, BGP_PATH_DMED_CHECK);
2261 }
2262 }
2263 bgp_path_info_set_flag(dest, new_select,
2264 BGP_PATH_DMED_CHECK);
2265 bgp_path_info_set_flag(dest, new_select,
2266 BGP_PATH_DMED_SELECTED);
2267
2268 if (debug) {
2269 bgp_path_info_path_with_addpath_rx_str(
2270 new_select, path_buf);
2271 zlog_debug("%s: %s is the bestpath from AS %u",
2272 pfx_buf, path_buf,
2273 aspath_get_first_as(
2274 new_select->attr->aspath));
2275 }
2276 }
2277 }
2278
2279 /* Check old selected route and new selected route. */
2280 old_select = NULL;
2281 new_select = NULL;
2282 for (pi = bgp_dest_get_bgp_path_info(dest);
2283 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2284 enum bgp_path_selection_reason reason;
2285
2286 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2287 old_select = pi;
2288
2289 if (BGP_PATH_HOLDDOWN(pi)) {
2290 /* reap REMOVED routes, if needs be
2291 * selected route must stay for a while longer though
2292 */
2293 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2294 && (pi != old_select))
2295 bgp_path_info_reap(dest, pi);
2296
2297 if (debug)
2298 zlog_debug("%s: pi %p in holddown", __func__,
2299 pi);
2300
2301 continue;
2302 }
2303
2304 if (pi->peer && pi->peer != bgp->peer_self
2305 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2306 if (pi->peer->status != Established) {
2307
2308 if (debug)
2309 zlog_debug(
2310 "%s: pi %p non self peer %s not estab state",
2311 __func__, pi, pi->peer->host);
2312
2313 continue;
2314 }
2315
2316 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2317 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2318 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2319 if (debug)
2320 zlog_debug("%s: pi %p dmed", __func__, pi);
2321 continue;
2322 }
2323
2324 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2325
2326 reason = dest->reason;
2327 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2328 debug, pfx_buf, afi, safi,
2329 &dest->reason)) {
2330 if (new_select == NULL &&
2331 reason != bgp_path_selection_none)
2332 dest->reason = reason;
2333 new_select = pi;
2334 }
2335 }
2336
2337 /* Now that we know which path is the bestpath see if any of the other
2338 * paths
2339 * qualify as multipaths
2340 */
2341 if (debug) {
2342 if (new_select)
2343 bgp_path_info_path_with_addpath_rx_str(new_select,
2344 path_buf);
2345 else
2346 snprintf(path_buf, sizeof(path_buf), "NONE");
2347 zlog_debug(
2348 "%s: After path selection, newbest is %s oldbest was %s",
2349 pfx_buf, path_buf,
2350 old_select ? old_select->peer->host : "NONE");
2351 }
2352
2353 if (do_mpath && new_select) {
2354 for (pi = bgp_dest_get_bgp_path_info(dest);
2355 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2356
2357 if (debug)
2358 bgp_path_info_path_with_addpath_rx_str(
2359 pi, path_buf);
2360
2361 if (pi == new_select) {
2362 if (debug)
2363 zlog_debug(
2364 "%s: %s is the bestpath, add to the multipath list",
2365 pfx_buf, path_buf);
2366 bgp_mp_list_add(&mp_list, pi);
2367 continue;
2368 }
2369
2370 if (BGP_PATH_HOLDDOWN(pi))
2371 continue;
2372
2373 if (pi->peer && pi->peer != bgp->peer_self
2374 && !CHECK_FLAG(pi->peer->sflags,
2375 PEER_STATUS_NSF_WAIT))
2376 if (pi->peer->status != Established)
2377 continue;
2378
2379 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2380 if (debug)
2381 zlog_debug(
2382 "%s: %s has the same nexthop as the bestpath, skip it",
2383 pfx_buf, path_buf);
2384 continue;
2385 }
2386
2387 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2388 mpath_cfg, debug, pfx_buf, afi, safi,
2389 &dest->reason);
2390
2391 if (paths_eq) {
2392 if (debug)
2393 zlog_debug(
2394 "%s: %s is equivalent to the bestpath, add to the multipath list",
2395 pfx_buf, path_buf);
2396 bgp_mp_list_add(&mp_list, pi);
2397 }
2398 }
2399 }
2400
2401 bgp_path_info_mpath_update(dest, new_select, old_select, &mp_list,
2402 mpath_cfg);
2403 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2404 bgp_mp_list_clear(&mp_list);
2405
2406 bgp_addpath_update_ids(bgp, dest, afi, safi);
2407
2408 result->old = old_select;
2409 result->new = new_select;
2410
2411 return;
2412 }
2413
2414 /*
2415 * A new route/change in bestpath of an existing route. Evaluate the path
2416 * for advertisement to the subgroup.
2417 */
2418 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2419 struct bgp_path_info *selected,
2420 struct bgp_dest *dest,
2421 uint32_t addpath_tx_id)
2422 {
2423 const struct prefix *p;
2424 struct peer *onlypeer;
2425 struct attr attr;
2426 afi_t afi;
2427 safi_t safi;
2428
2429 p = bgp_dest_get_prefix(dest);
2430 afi = SUBGRP_AFI(subgrp);
2431 safi = SUBGRP_SAFI(subgrp);
2432 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2433 : NULL);
2434
2435 if (BGP_DEBUG(update, UPDATE_OUT)) {
2436 char buf_prefix[PREFIX_STRLEN];
2437 prefix2str(p, buf_prefix, sizeof(buf_prefix));
2438 zlog_debug("%s: p=%s, selected=%p", __func__, buf_prefix,
2439 selected);
2440 }
2441
2442 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2443 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2444 PEER_STATUS_ORF_WAIT_REFRESH))
2445 return;
2446
2447 memset(&attr, 0, sizeof(struct attr));
2448 /* It's initialized in bgp_announce_check() */
2449
2450 /* Announcement to the subgroup. If the route is filtered withdraw it.
2451 */
2452 if (selected) {
2453 if (subgroup_announce_check(dest, selected, subgrp, p, &attr))
2454 bgp_adj_out_set_subgroup(dest, subgrp, &attr, selected);
2455 else
2456 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2457 addpath_tx_id);
2458 }
2459
2460 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2461 else {
2462 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2463 }
2464 }
2465
2466 /*
2467 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2468 * This is called at the end of route processing.
2469 */
2470 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2471 {
2472 struct bgp_path_info *pi;
2473
2474 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2475 if (BGP_PATH_HOLDDOWN(pi))
2476 continue;
2477 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2478 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2479 }
2480 }
2481
2482 /*
2483 * Has the route changed from the RIB's perspective? This is invoked only
2484 * if the route selection returns the same best route as earlier - to
2485 * determine if we need to update zebra or not.
2486 */
2487 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2488 {
2489 struct bgp_path_info *mpinfo;
2490
2491 /* If this is multipath, check all selected paths for any nexthop
2492 * change or attribute change. Some attribute changes (e.g., community)
2493 * aren't of relevance to the RIB, but we'll update zebra to ensure
2494 * we handle the case of BGP nexthop change. This is the behavior
2495 * when the best path has an attribute change anyway.
2496 */
2497 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2498 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2499 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2500 return true;
2501
2502 /*
2503 * If this is multipath, check all selected paths for any nexthop change
2504 */
2505 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2506 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2507 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2508 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2509 return true;
2510 }
2511
2512 /* Nothing has changed from the RIB's perspective. */
2513 return false;
2514 }
2515
2516 struct bgp_process_queue {
2517 struct bgp *bgp;
2518 STAILQ_HEAD(, bgp_dest) pqueue;
2519 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2520 unsigned int flags;
2521 unsigned int queued;
2522 };
2523
2524 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
2525 safi_t safi, struct bgp_dest *dest,
2526 struct bgp_path_info *new_select,
2527 struct bgp_path_info *old_select)
2528 {
2529 const struct prefix *p = bgp_dest_get_prefix(dest);
2530
2531 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
2532 return;
2533
2534 if (advertise_type5_routes(bgp, afi) && new_select
2535 && is_route_injectable_into_evpn(new_select)) {
2536
2537 /* apply the route-map */
2538 if (bgp->adv_cmd_rmap[afi][safi].map) {
2539 route_map_result_t ret;
2540 struct bgp_path_info rmap_path;
2541 struct bgp_path_info_extra rmap_path_extra;
2542 struct attr dummy_attr;
2543
2544 dummy_attr = *new_select->attr;
2545
2546 /* Fill temp path_info */
2547 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
2548 new_select, new_select->peer,
2549 &dummy_attr);
2550
2551 RESET_FLAG(dummy_attr.rmap_change_flags);
2552
2553 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
2554 p, RMAP_BGP, &rmap_path);
2555
2556 if (ret == RMAP_DENYMATCH) {
2557 bgp_attr_flush(&dummy_attr);
2558 bgp_evpn_withdraw_type5_route(bgp, p, afi,
2559 safi);
2560 } else
2561 bgp_evpn_advertise_type5_route(
2562 bgp, p, &dummy_attr, afi, safi);
2563 } else {
2564 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
2565 afi, safi);
2566 }
2567 } else if (advertise_type5_routes(bgp, afi) && old_select
2568 && is_route_injectable_into_evpn(old_select))
2569 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
2570 }
2571
2572 /*
2573 * old_select = The old best path
2574 * new_select = the new best path
2575 *
2576 * if (!old_select && new_select)
2577 * We are sending new information on.
2578 *
2579 * if (old_select && new_select) {
2580 * if (new_select != old_select)
2581 * We have a new best path send a change
2582 * else
2583 * We've received a update with new attributes that needs
2584 * to be passed on.
2585 * }
2586 *
2587 * if (old_select && !new_select)
2588 * We have no eligible route that we can announce or the rn
2589 * is being removed.
2590 */
2591 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
2592 afi_t afi, safi_t safi)
2593 {
2594 struct bgp_path_info *new_select;
2595 struct bgp_path_info *old_select;
2596 struct bgp_path_info_pair old_and_new;
2597 int debug = 0;
2598
2599 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
2600 if (dest)
2601 debug = bgp_debug_bestpath(dest);
2602 if (debug)
2603 zlog_debug(
2604 "%s: bgp delete in progress, ignoring event, p=%pRN",
2605 __func__, dest);
2606 return;
2607 }
2608 /* Is it end of initial update? (after startup) */
2609 if (!dest) {
2610 quagga_timestamp(3, bgp->update_delay_zebra_resume_time,
2611 sizeof(bgp->update_delay_zebra_resume_time));
2612
2613 bgp->main_zebra_update_hold = 0;
2614 FOREACH_AFI_SAFI (afi, safi) {
2615 if (bgp_fibupd_safi(safi))
2616 bgp_zebra_announce_table(bgp, afi, safi);
2617 }
2618 bgp->main_peers_update_hold = 0;
2619
2620 bgp_start_routeadv(bgp);
2621 return;
2622 }
2623
2624 const struct prefix *p = bgp_dest_get_prefix(dest);
2625
2626 debug = bgp_debug_bestpath(dest);
2627 if (debug)
2628 zlog_debug("%s: p=%pRN afi=%s, safi=%s start", __func__, dest,
2629 afi2str(afi), safi2str(safi));
2630
2631 /* The best path calculation for the route is deferred if
2632 * BGP_NODE_SELECT_DEFER is set
2633 */
2634 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
2635 if (BGP_DEBUG(update, UPDATE_OUT))
2636 zlog_debug("SELECT_DEFER falg set for route %p", dest);
2637 return;
2638 }
2639
2640 /* Best path selection. */
2641 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
2642 afi, safi);
2643 old_select = old_and_new.old;
2644 new_select = old_and_new.new;
2645
2646 /* Do we need to allocate or free labels?
2647 * Right now, since we only deal with per-prefix labels, it is not
2648 * necessary to do this upon changes to best path. Exceptions:
2649 * - label index has changed -> recalculate resulting label
2650 * - path_info sub_type changed -> switch to/from implicit-null
2651 * - no valid label (due to removed static label binding) -> get new one
2652 */
2653 if (bgp->allocate_mpls_labels[afi][safi]) {
2654 if (new_select) {
2655 if (!old_select
2656 || bgp_label_index_differs(new_select, old_select)
2657 || new_select->sub_type != old_select->sub_type
2658 || !bgp_is_valid_label(&dest->local_label)) {
2659 /* Enforced penultimate hop popping:
2660 * implicit-null for local routes, aggregate
2661 * and redistributed routes
2662 */
2663 if (new_select->sub_type == BGP_ROUTE_STATIC
2664 || new_select->sub_type
2665 == BGP_ROUTE_AGGREGATE
2666 || new_select->sub_type
2667 == BGP_ROUTE_REDISTRIBUTE) {
2668 if (CHECK_FLAG(
2669 dest->flags,
2670 BGP_NODE_REGISTERED_FOR_LABEL))
2671 bgp_unregister_for_label(dest);
2672 label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1,
2673 &dest->local_label);
2674 bgp_set_valid_label(&dest->local_label);
2675 } else
2676 bgp_register_for_label(dest,
2677 new_select);
2678 }
2679 } else if (CHECK_FLAG(dest->flags,
2680 BGP_NODE_REGISTERED_FOR_LABEL)) {
2681 bgp_unregister_for_label(dest);
2682 }
2683 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)) {
2684 bgp_unregister_for_label(dest);
2685 }
2686
2687 if (debug)
2688 zlog_debug(
2689 "%s: p=%pRN afi=%s, safi=%s, old_select=%p, new_select=%p",
2690 __func__, dest, afi2str(afi), safi2str(safi),
2691 old_select, new_select);
2692
2693 /* If best route remains the same and this is not due to user-initiated
2694 * clear, see exactly what needs to be done.
2695 */
2696 if (old_select && old_select == new_select
2697 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
2698 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2699 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
2700 if (bgp_zebra_has_route_changed(old_select)) {
2701 #ifdef ENABLE_BGP_VNC
2702 vnc_import_bgp_add_route(bgp, p, old_select);
2703 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
2704 #endif
2705 if (bgp_fibupd_safi(safi)
2706 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2707
2708 if (new_select->type == ZEBRA_ROUTE_BGP
2709 && (new_select->sub_type == BGP_ROUTE_NORMAL
2710 || new_select->sub_type
2711 == BGP_ROUTE_IMPORTED))
2712
2713 bgp_zebra_announce(dest, p, old_select,
2714 bgp, afi, safi);
2715 }
2716 }
2717
2718 /* If there is a change of interest to peers, reannounce the
2719 * route. */
2720 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2721 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
2722 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
2723 group_announce_route(bgp, afi, safi, dest, new_select);
2724
2725 /* unicast routes must also be annouced to
2726 * labeled-unicast update-groups */
2727 if (safi == SAFI_UNICAST)
2728 group_announce_route(bgp, afi,
2729 SAFI_LABELED_UNICAST, dest,
2730 new_select);
2731
2732 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
2733 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
2734 }
2735
2736 /* advertise/withdraw type-5 routes */
2737 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
2738 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
2739 bgp_process_evpn_route_injection(
2740 bgp, afi, safi, dest, old_select, old_select);
2741
2742 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
2743 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
2744 bgp_zebra_clear_route_change_flags(dest);
2745 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
2746 return;
2747 }
2748
2749 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2750 */
2751 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
2752
2753 /* bestpath has changed; bump version */
2754 if (old_select || new_select) {
2755 bgp_bump_version(dest);
2756
2757 if (!bgp->t_rmap_def_originate_eval) {
2758 bgp_lock(bgp);
2759 thread_add_timer(
2760 bm->master,
2761 update_group_refresh_default_originate_route_map,
2762 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
2763 &bgp->t_rmap_def_originate_eval);
2764 }
2765 }
2766
2767 if (old_select)
2768 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
2769 if (new_select) {
2770 if (debug)
2771 zlog_debug("%s: setting SELECTED flag", __func__);
2772 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
2773 bgp_path_info_unset_flag(dest, new_select,
2774 BGP_PATH_ATTR_CHANGED);
2775 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
2776 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
2777 }
2778
2779 #ifdef ENABLE_BGP_VNC
2780 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
2781 if (old_select != new_select) {
2782 if (old_select) {
2783 vnc_import_bgp_exterior_del_route(bgp, p,
2784 old_select);
2785 vnc_import_bgp_del_route(bgp, p, old_select);
2786 }
2787 if (new_select) {
2788 vnc_import_bgp_exterior_add_route(bgp, p,
2789 new_select);
2790 vnc_import_bgp_add_route(bgp, p, new_select);
2791 }
2792 }
2793 }
2794 #endif
2795
2796 group_announce_route(bgp, afi, safi, dest, new_select);
2797
2798 /* unicast routes must also be annouced to labeled-unicast update-groups
2799 */
2800 if (safi == SAFI_UNICAST)
2801 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
2802 new_select);
2803
2804 /* FIB update. */
2805 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
2806 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2807 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
2808 && (new_select->sub_type == BGP_ROUTE_NORMAL
2809 || new_select->sub_type == BGP_ROUTE_AGGREGATE
2810 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
2811
2812 /* if this is an evpn imported type-5 prefix,
2813 * we need to withdraw the route first to clear
2814 * the nh neigh and the RMAC entry.
2815 */
2816 if (old_select &&
2817 is_route_parent_evpn(old_select))
2818 bgp_zebra_withdraw(p, old_select, bgp, safi);
2819
2820 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
2821 } else {
2822 /* Withdraw the route from the kernel. */
2823 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
2824 && (old_select->sub_type == BGP_ROUTE_NORMAL
2825 || old_select->sub_type == BGP_ROUTE_AGGREGATE
2826 || old_select->sub_type == BGP_ROUTE_IMPORTED))
2827
2828 bgp_zebra_withdraw(p, old_select, bgp, safi);
2829 }
2830 }
2831
2832 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
2833 old_select);
2834
2835 /* Clear any route change flags. */
2836 bgp_zebra_clear_route_change_flags(dest);
2837
2838 /* Reap old select bgp_path_info, if it has been removed */
2839 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
2840 bgp_path_info_reap(dest, old_select);
2841
2842 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
2843 return;
2844 }
2845
2846 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
2847 int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
2848 {
2849 struct bgp_dest *dest;
2850 int cnt = 0;
2851 struct afi_safi_info *thread_info;
2852 struct listnode *node = NULL, *nnode = NULL;
2853
2854 if (bgp->gr_info[afi][safi].t_route_select)
2855 BGP_TIMER_OFF(bgp->gr_info[afi][safi].t_route_select);
2856
2857 if (BGP_DEBUG(update, UPDATE_OUT)) {
2858 zlog_debug("%s: processing route for %s : cnt %d", __func__,
2859 get_afi_safi_str(afi, safi, false),
2860 listcount(bgp->gr_info[afi][safi].route_list));
2861 }
2862
2863 /* Process the route list */
2864 node = listhead(bgp->gr_info[afi][safi].route_list);
2865 while (node) {
2866 dest = listgetdata(node);
2867 nnode = node->next;
2868 list_delete_node(bgp->gr_info[afi][safi].route_list, node);
2869 dest->rt_node = NULL;
2870
2871 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
2872 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
2873 bgp_process_main_one(bgp, dest, afi, safi);
2874 cnt++;
2875 if (cnt >= BGP_MAX_BEST_ROUTE_SELECT)
2876 break;
2877 }
2878 node = nnode;
2879 }
2880
2881 /* Send EOR message when all routes are processed */
2882 if (list_isempty(bgp->gr_info[afi][safi].route_list)) {
2883 bgp_send_delayed_eor(bgp);
2884 /* Send route processing complete message to RIB */
2885 bgp_zebra_update(afi, safi, bgp->vrf_id,
2886 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
2887 return 0;
2888 }
2889
2890 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
2891
2892 thread_info->afi = afi;
2893 thread_info->safi = safi;
2894 thread_info->bgp = bgp;
2895
2896 /* If there are more routes to be processed, start the
2897 * selection timer
2898 */
2899 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
2900 BGP_ROUTE_SELECT_DELAY,
2901 &bgp->gr_info[afi][safi].t_route_select);
2902 return 0;
2903 }
2904
2905 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
2906 {
2907 struct bgp_process_queue *pqnode = data;
2908 struct bgp *bgp = pqnode->bgp;
2909 struct bgp_table *table;
2910 struct bgp_dest *dest;
2911
2912 /* eoiu marker */
2913 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
2914 bgp_process_main_one(bgp, NULL, 0, 0);
2915 /* should always have dedicated wq call */
2916 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
2917 return WQ_SUCCESS;
2918 }
2919
2920 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
2921 dest = STAILQ_FIRST(&pqnode->pqueue);
2922 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
2923 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
2924 table = bgp_dest_table(dest);
2925 /* note, new DESTs may be added as part of processing */
2926 bgp_process_main_one(bgp, dest, table->afi, table->safi);
2927
2928 bgp_dest_unlock_node(dest);
2929 bgp_table_unlock(table);
2930 }
2931
2932 return WQ_SUCCESS;
2933 }
2934
2935 static void bgp_processq_del(struct work_queue *wq, void *data)
2936 {
2937 struct bgp_process_queue *pqnode = data;
2938
2939 bgp_unlock(pqnode->bgp);
2940
2941 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
2942 }
2943
2944 void bgp_process_queue_init(void)
2945 {
2946 if (!bm->process_main_queue)
2947 bm->process_main_queue =
2948 work_queue_new(bm->master, "process_main_queue");
2949
2950 bm->process_main_queue->spec.workfunc = &bgp_process_wq;
2951 bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
2952 bm->process_main_queue->spec.max_retries = 0;
2953 bm->process_main_queue->spec.hold = 50;
2954 /* Use a higher yield value of 50ms for main queue processing */
2955 bm->process_main_queue->spec.yield = 50 * 1000L;
2956 }
2957
2958 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
2959 {
2960 struct bgp_process_queue *pqnode;
2961
2962 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
2963 sizeof(struct bgp_process_queue));
2964
2965 /* unlocked in bgp_processq_del */
2966 pqnode->bgp = bgp_lock(bgp);
2967 STAILQ_INIT(&pqnode->pqueue);
2968
2969 return pqnode;
2970 }
2971
2972 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
2973 {
2974 #define ARBITRARY_PROCESS_QLEN 10000
2975 struct work_queue *wq = bm->process_main_queue;
2976 struct bgp_process_queue *pqnode;
2977 int pqnode_reuse = 0;
2978
2979 /* already scheduled for processing? */
2980 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
2981 return;
2982
2983 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
2984 * the workqueue
2985 */
2986 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
2987 if (BGP_DEBUG(update, UPDATE_OUT))
2988 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
2989 dest);
2990 return;
2991 }
2992
2993 if (wq == NULL)
2994 return;
2995
2996 /* Add route nodes to an existing work queue item until reaching the
2997 limit only if is from the same BGP view and it's not an EOIU marker
2998 */
2999 if (work_queue_item_count(wq)) {
3000 struct work_queue_item *item = work_queue_last_item(wq);
3001 pqnode = item->data;
3002
3003 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3004 || pqnode->bgp != bgp
3005 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3006 pqnode = bgp_processq_alloc(bgp);
3007 else
3008 pqnode_reuse = 1;
3009 } else
3010 pqnode = bgp_processq_alloc(bgp);
3011 /* all unlocked in bgp_process_wq */
3012 bgp_table_lock(bgp_dest_table(dest));
3013
3014 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3015 bgp_dest_lock_node(dest);
3016
3017 /* can't be enqueued twice */
3018 assert(STAILQ_NEXT(dest, pq) == NULL);
3019 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3020 pqnode->queued++;
3021
3022 if (!pqnode_reuse)
3023 work_queue_add(wq, pqnode);
3024
3025 return;
3026 }
3027
3028 void bgp_add_eoiu_mark(struct bgp *bgp)
3029 {
3030 struct bgp_process_queue *pqnode;
3031
3032 if (bm->process_main_queue == NULL)
3033 return;
3034
3035 pqnode = bgp_processq_alloc(bgp);
3036
3037 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3038 work_queue_add(bm->process_main_queue, pqnode);
3039 }
3040
3041 static int bgp_maximum_prefix_restart_timer(struct thread *thread)
3042 {
3043 struct peer *peer;
3044
3045 peer = THREAD_ARG(thread);
3046 peer->t_pmax_restart = NULL;
3047
3048 if (bgp_debug_neighbor_events(peer))
3049 zlog_debug(
3050 "%s Maximum-prefix restart timer expired, restore peering",
3051 peer->host);
3052
3053 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3054 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3055
3056 return 0;
3057 }
3058
3059 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3060 safi_t safi)
3061 {
3062 uint32_t count = 0;
3063 bool filtered = false;
3064 struct bgp_dest *dest;
3065 struct bgp_adj_in *ain;
3066 struct attr attr = {};
3067 struct bgp_table *table = peer->bgp->rib[afi][safi];
3068
3069 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3070 for (ain = dest->adj_in; ain; ain = ain->next) {
3071 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3072
3073 attr = *ain->attr;
3074
3075 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3076 == FILTER_DENY)
3077 filtered = true;
3078
3079 if (bgp_input_modifier(
3080 peer, rn_p, &attr, afi, safi,
3081 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3082 NULL, 0, NULL)
3083 == RMAP_DENY)
3084 filtered = true;
3085
3086 if (filtered)
3087 count++;
3088
3089 bgp_attr_undup(&attr, ain->attr);
3090 }
3091 }
3092
3093 return count;
3094 }
3095
3096 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3097 int always)
3098 {
3099 iana_afi_t pkt_afi;
3100 iana_safi_t pkt_safi;
3101 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3102 PEER_FLAG_MAX_PREFIX_FORCE))
3103 ? bgp_filtered_routes_count(peer, afi, safi)
3104 + peer->pcount[afi][safi]
3105 : peer->pcount[afi][safi];
3106
3107 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3108 return false;
3109
3110 if (pcount > peer->pmax[afi][safi]) {
3111 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3112 PEER_STATUS_PREFIX_LIMIT)
3113 && !always)
3114 return false;
3115
3116 zlog_info(
3117 "%%MAXPFXEXCEED: No. of %s prefix received from %s %u exceed, limit %u",
3118 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3119 peer->pmax[afi][safi]);
3120 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3121
3122 if (CHECK_FLAG(peer->af_flags[afi][safi],
3123 PEER_FLAG_MAX_PREFIX_WARNING))
3124 return false;
3125
3126 /* Convert AFI, SAFI to values for packet. */
3127 pkt_afi = afi_int2iana(afi);
3128 pkt_safi = safi_int2iana(safi);
3129 {
3130 uint8_t ndata[7];
3131
3132 ndata[0] = (pkt_afi >> 8);
3133 ndata[1] = pkt_afi;
3134 ndata[2] = pkt_safi;
3135 ndata[3] = (peer->pmax[afi][safi] >> 24);
3136 ndata[4] = (peer->pmax[afi][safi] >> 16);
3137 ndata[5] = (peer->pmax[afi][safi] >> 8);
3138 ndata[6] = (peer->pmax[afi][safi]);
3139
3140 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3141 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3142 BGP_NOTIFY_CEASE_MAX_PREFIX,
3143 ndata, 7);
3144 }
3145
3146 /* Dynamic peers will just close their connection. */
3147 if (peer_dynamic_neighbor(peer))
3148 return true;
3149
3150 /* restart timer start */
3151 if (peer->pmax_restart[afi][safi]) {
3152 peer->v_pmax_restart =
3153 peer->pmax_restart[afi][safi] * 60;
3154
3155 if (bgp_debug_neighbor_events(peer))
3156 zlog_debug(
3157 "%s Maximum-prefix restart timer started for %d secs",
3158 peer->host, peer->v_pmax_restart);
3159
3160 BGP_TIMER_ON(peer->t_pmax_restart,
3161 bgp_maximum_prefix_restart_timer,
3162 peer->v_pmax_restart);
3163 }
3164
3165 return true;
3166 } else
3167 UNSET_FLAG(peer->af_sflags[afi][safi],
3168 PEER_STATUS_PREFIX_LIMIT);
3169
3170 if (pcount > (pcount * peer->pmax_threshold[afi][safi] / 100)) {
3171 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3172 PEER_STATUS_PREFIX_THRESHOLD)
3173 && !always)
3174 return false;
3175
3176 zlog_info(
3177 "%%MAXPFX: No. of %s prefix received from %s reaches %u, max %u",
3178 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3179 peer->pmax[afi][safi]);
3180 SET_FLAG(peer->af_sflags[afi][safi],
3181 PEER_STATUS_PREFIX_THRESHOLD);
3182 } else
3183 UNSET_FLAG(peer->af_sflags[afi][safi],
3184 PEER_STATUS_PREFIX_THRESHOLD);
3185 return false;
3186 }
3187
3188 /* Unconditionally remove the route from the RIB, without taking
3189 * damping into consideration (eg, because the session went down)
3190 */
3191 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3192 struct peer *peer, afi_t afi, safi_t safi)
3193 {
3194
3195 struct bgp *bgp = NULL;
3196 bool delete_route = false;
3197
3198 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3199 safi);
3200
3201 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3202 bgp_path_info_delete(dest, pi); /* keep historical info */
3203
3204 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3205 * flag
3206 */
3207 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3208 delete_route = true;
3209 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3210 delete_route = true;
3211 if (delete_route) {
3212 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3213 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3214 bgp = pi->peer->bgp;
3215 if ((dest->rt_node)
3216 && (bgp->gr_info[afi][safi].route_list)) {
3217 list_delete_node(bgp->gr_info[afi][safi]
3218 .route_list,
3219 dest->rt_node);
3220 dest->rt_node = NULL;
3221 }
3222 }
3223 }
3224 }
3225
3226 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3227 bgp_process(peer->bgp, dest, afi, safi);
3228 }
3229
3230 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3231 struct peer *peer, afi_t afi, safi_t safi,
3232 struct prefix_rd *prd)
3233 {
3234 const struct prefix *p = bgp_dest_get_prefix(dest);
3235
3236 /* apply dampening, if result is suppressed, we'll be retaining
3237 * the bgp_path_info in the RIB for historical reference.
3238 */
3239 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3240 && peer->sort == BGP_PEER_EBGP)
3241 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3242 == BGP_DAMP_SUPPRESSED) {
3243 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3244 safi);
3245 return;
3246 }
3247
3248 #ifdef ENABLE_BGP_VNC
3249 if (safi == SAFI_MPLS_VPN) {
3250 struct bgp_dest *pdest = NULL;
3251 struct bgp_table *table = NULL;
3252
3253 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3254 (struct prefix *)prd);
3255 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3256 table = bgp_dest_get_bgp_table_info(pdest);
3257
3258 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3259 peer->bgp, prd, table, p, pi);
3260 }
3261 bgp_dest_unlock_node(pdest);
3262 }
3263 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3264 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3265
3266 vnc_import_bgp_del_route(peer->bgp, p, pi);
3267 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3268 }
3269 }
3270 #endif
3271
3272 /* If this is an EVPN route, process for un-import. */
3273 if (safi == SAFI_EVPN)
3274 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3275
3276 bgp_rib_remove(dest, pi, peer, afi, safi);
3277 }
3278
3279 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3280 struct peer *peer, struct attr *attr,
3281 struct bgp_dest *dest)
3282 {
3283 struct bgp_path_info *new;
3284
3285 /* Make new BGP info. */
3286 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3287 new->type = type;
3288 new->instance = instance;
3289 new->sub_type = sub_type;
3290 new->peer = peer;
3291 new->attr = attr;
3292 new->uptime = bgp_clock();
3293 new->net = dest;
3294 return new;
3295 }
3296
3297 static void overlay_index_update(struct attr *attr,
3298 union gw_addr *gw_ip)
3299 {
3300 if (!attr)
3301 return;
3302 if (gw_ip == NULL) {
3303 memset(&(attr->evpn_overlay.gw_ip), 0, sizeof(union gw_addr));
3304 } else {
3305 memcpy(&(attr->evpn_overlay.gw_ip), gw_ip,
3306 sizeof(union gw_addr));
3307 }
3308 }
3309
3310 static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path,
3311 union gw_addr *gw_ip)
3312 {
3313 union gw_addr *path_gw_ip, *path_gw_ip_remote;
3314 union {
3315 esi_t esi;
3316 union gw_addr ip;
3317 } temp;
3318
3319 if (afi != AFI_L2VPN)
3320 return true;
3321
3322 path_gw_ip = &(path->attr->evpn_overlay.gw_ip);
3323
3324 if (gw_ip == NULL) {
3325 memset(&temp, 0, sizeof(temp));
3326 path_gw_ip_remote = &temp.ip;
3327 } else
3328 path_gw_ip_remote = gw_ip;
3329
3330 return !!memcmp(path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr));
3331 }
3332
3333 /* Check if received nexthop is valid or not. */
3334 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3335 uint8_t type, uint8_t stype, struct attr *attr,
3336 struct bgp_dest *dest)
3337 {
3338 bool ret = false;
3339 bool is_bgp_static_route =
3340 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3341 : false;
3342
3343 /*
3344 * Only validated for unicast and multicast currently.
3345 * Also valid for EVPN where the nexthop is an IP address.
3346 * If we are a bgp static route being checked then there is
3347 * no need to check to see if the nexthop is martian as
3348 * that it should be ok.
3349 */
3350 if (is_bgp_static_route ||
3351 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3352 return false;
3353
3354 /* If NEXT_HOP is present, validate it. */
3355 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3356 if (attr->nexthop.s_addr == INADDR_ANY
3357 || IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr))
3358 || bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3359 return true;
3360 }
3361
3362 /* If MP_NEXTHOP is present, validate it. */
3363 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3364 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3365 * it is not an IPv6 link-local address.
3366 *
3367 * If we receive an UPDATE with nexthop length set to 32 bytes
3368 * we shouldn't discard an UPDATE if it's set to (::).
3369 * The link-local (2st) is validated along the code path later.
3370 */
3371 if (attr->mp_nexthop_len) {
3372 switch (attr->mp_nexthop_len) {
3373 case BGP_ATTR_NHLEN_IPV4:
3374 case BGP_ATTR_NHLEN_VPNV4:
3375 ret = (attr->mp_nexthop_global_in.s_addr == INADDR_ANY
3376 || IPV4_CLASS_DE(
3377 ntohl(attr->mp_nexthop_global_in.s_addr))
3378 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3379 dest));
3380 break;
3381
3382 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3383 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3384 ret = (IN6_IS_ADDR_UNSPECIFIED(
3385 &attr->mp_nexthop_global)
3386 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3387 || IN6_IS_ADDR_MULTICAST(
3388 &attr->mp_nexthop_global)
3389 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3390 dest));
3391 break;
3392 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3393 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3394 || IN6_IS_ADDR_MULTICAST(
3395 &attr->mp_nexthop_global)
3396 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3397 dest));
3398 break;
3399
3400 default:
3401 ret = true;
3402 break;
3403 }
3404 }
3405
3406 return ret;
3407 }
3408
3409 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3410 struct attr *attr, afi_t afi, safi_t safi, int type,
3411 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3412 uint32_t num_labels, int soft_reconfig,
3413 struct bgp_route_evpn *evpn)
3414 {
3415 int ret;
3416 int aspath_loop_count = 0;
3417 struct bgp_dest *dest;
3418 struct bgp *bgp;
3419 struct attr new_attr;
3420 struct attr *attr_new;
3421 struct bgp_path_info *pi;
3422 struct bgp_path_info *new;
3423 struct bgp_path_info_extra *extra;
3424 const char *reason;
3425 char pfx_buf[BGP_PRD_PATH_STRLEN];
3426 int connected = 0;
3427 int do_loop_check = 1;
3428 int has_valid_label = 0;
3429 afi_t nh_afi;
3430 uint8_t pi_type = 0;
3431 uint8_t pi_sub_type = 0;
3432
3433 #ifdef ENABLE_BGP_VNC
3434 int vnc_implicit_withdraw = 0;
3435 #endif
3436 int same_attr = 0;
3437
3438 memset(&new_attr, 0, sizeof(struct attr));
3439 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
3440 new_attr.label = MPLS_INVALID_LABEL;
3441
3442 bgp = peer->bgp;
3443 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3444 /* TODO: Check to see if we can get rid of "is_valid_label" */
3445 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3446 has_valid_label = (num_labels > 0) ? 1 : 0;
3447 else
3448 has_valid_label = bgp_is_valid_label(label);
3449
3450 /* When peer's soft reconfiguration enabled. Record input packet in
3451 Adj-RIBs-In. */
3452 if (!soft_reconfig
3453 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3454 && peer != bgp->peer_self)
3455 bgp_adj_in_set(dest, peer, attr, addpath_id);
3456
3457 /* Check previously received route. */
3458 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
3459 if (pi->peer == peer && pi->type == type
3460 && pi->sub_type == sub_type
3461 && pi->addpath_rx_id == addpath_id)
3462 break;
3463
3464 /* AS path local-as loop check. */
3465 if (peer->change_local_as) {
3466 if (peer->allowas_in[afi][safi])
3467 aspath_loop_count = peer->allowas_in[afi][safi];
3468 else if (!CHECK_FLAG(peer->flags,
3469 PEER_FLAG_LOCAL_AS_NO_PREPEND))
3470 aspath_loop_count = 1;
3471
3472 if (aspath_loop_check(attr->aspath, peer->change_local_as)
3473 > aspath_loop_count) {
3474 peer->stat_pfx_aspath_loop++;
3475 reason = "as-path contains our own AS A;";
3476 goto filtered;
3477 }
3478 }
3479
3480 /* If the peer is configured for "allowas-in origin" and the last ASN in
3481 * the
3482 * as-path is our ASN then we do not need to call aspath_loop_check
3483 */
3484 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
3485 if (aspath_get_last_as(attr->aspath) == bgp->as)
3486 do_loop_check = 0;
3487
3488 /* AS path loop check. */
3489 if (do_loop_check) {
3490 if (aspath_loop_check(attr->aspath, bgp->as)
3491 > peer->allowas_in[afi][safi]
3492 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
3493 && aspath_loop_check(attr->aspath, bgp->confed_id)
3494 > peer->allowas_in[afi][safi])) {
3495 peer->stat_pfx_aspath_loop++;
3496 reason = "as-path contains our own AS;";
3497 goto filtered;
3498 }
3499 }
3500
3501 /* Route reflector originator ID check. */
3502 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
3503 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
3504 peer->stat_pfx_originator_loop++;
3505 reason = "originator is us;";
3506 goto filtered;
3507 }
3508
3509 /* Route reflector cluster ID check. */
3510 if (bgp_cluster_filter(peer, attr)) {
3511 peer->stat_pfx_cluster_loop++;
3512 reason = "reflected from the same cluster;";
3513 goto filtered;
3514 }
3515
3516 /* Apply incoming filter. */
3517 if (bgp_input_filter(peer, p, attr, afi, safi) == FILTER_DENY) {
3518 peer->stat_pfx_filter++;
3519 reason = "filter;";
3520 goto filtered;
3521 }
3522
3523 /* RFC 8212 to prevent route leaks.
3524 * This specification intends to improve this situation by requiring the
3525 * explicit configuration of both BGP Import and Export Policies for any
3526 * External BGP (EBGP) session such as customers, peers, or
3527 * confederation boundaries for all enabled address families. Through
3528 * codification of the aforementioned requirement, operators will
3529 * benefit from consistent behavior across different BGP
3530 * implementations.
3531 */
3532 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
3533 if (!bgp_inbound_policy_exists(peer,
3534 &peer->filter[afi][safi])) {
3535 reason = "inbound policy missing";
3536 goto filtered;
3537 }
3538
3539 /* draft-ietf-idr-deprecate-as-set-confed-set
3540 * Filter routes having AS_SET or AS_CONFED_SET in the path.
3541 * Eventually, This document (if approved) updates RFC 4271
3542 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
3543 * and obsoletes RFC 6472.
3544 */
3545 if (peer->bgp->reject_as_sets)
3546 if (aspath_check_as_sets(attr->aspath)) {
3547 reason =
3548 "as-path contains AS_SET or AS_CONFED_SET type;";
3549 goto filtered;
3550 }
3551
3552 new_attr = *attr;
3553
3554 /* Apply incoming route-map.
3555 * NB: new_attr may now contain newly allocated values from route-map
3556 * "set"
3557 * commands, so we need bgp_attr_flush in the error paths, until we
3558 * intern
3559 * the attr (which takes over the memory references) */
3560 if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL, label,
3561 num_labels, dest)
3562 == RMAP_DENY) {
3563 peer->stat_pfx_filter++;
3564 reason = "route-map;";
3565 bgp_attr_flush(&new_attr);
3566 goto filtered;
3567 }
3568
3569 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
3570 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3571 /* remove from RIB previous entry */
3572 bgp_zebra_withdraw(p, pi, bgp, safi);
3573 }
3574
3575 if (peer->sort == BGP_PEER_EBGP) {
3576
3577 /* If we receive the graceful-shutdown community from an eBGP
3578 * peer we must lower local-preference */
3579 if (new_attr.community
3580 && community_include(new_attr.community, COMMUNITY_GSHUT)) {
3581 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
3582 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
3583
3584 /* If graceful-shutdown is configured then add the GSHUT
3585 * community to all paths received from eBGP peers */
3586 } else if (bgp_in_graceful_shutdown(peer->bgp))
3587 bgp_attr_add_gshut_community(&new_attr);
3588 }
3589
3590 if (pi) {
3591 pi_type = pi->type;
3592 pi_sub_type = pi->sub_type;
3593 }
3594
3595 /* next hop check. */
3596 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
3597 && bgp_update_martian_nexthop(bgp, afi, safi, pi_type, pi_sub_type,
3598 &new_attr, dest)) {
3599 peer->stat_pfx_nh_invalid++;
3600 reason = "martian or self next-hop;";
3601 bgp_attr_flush(&new_attr);
3602 goto filtered;
3603 }
3604
3605 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
3606 peer->stat_pfx_nh_invalid++;
3607 reason = "self mac;";
3608 goto filtered;
3609 }
3610
3611 /* Update Overlay Index */
3612 if (afi == AFI_L2VPN) {
3613 overlay_index_update(&new_attr,
3614 evpn == NULL ? NULL : &evpn->gw_ip);
3615 }
3616
3617 attr_new = bgp_attr_intern(&new_attr);
3618
3619 /* If maximum prefix count is configured and current prefix
3620 * count exeed it.
3621 */
3622 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0))
3623 return -1;
3624
3625 /* If the update is implicit withdraw. */
3626 if (pi) {
3627 pi->uptime = bgp_clock();
3628 same_attr = attrhash_cmp(pi->attr, attr_new);
3629
3630 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
3631
3632 /* Same attribute comes in. */
3633 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
3634 && attrhash_cmp(pi->attr, attr_new)
3635 && (!has_valid_label
3636 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
3637 num_labels * sizeof(mpls_label_t))
3638 == 0)
3639 && (overlay_index_equal(
3640 afi, pi,
3641 evpn == NULL ? NULL : &evpn->gw_ip))) {
3642 if (CHECK_FLAG(bgp->af_flags[afi][safi],
3643 BGP_CONFIG_DAMPENING)
3644 && peer->sort == BGP_PEER_EBGP
3645 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3646 if (bgp_debug_update(peer, p, NULL, 1)) {
3647 bgp_debug_rdpfxpath2str(
3648 afi, safi, prd, p, label,
3649 num_labels, addpath_id ? 1 : 0,
3650 addpath_id, pfx_buf,
3651 sizeof(pfx_buf));
3652 zlog_debug("%s rcvd %s", peer->host,
3653 pfx_buf);
3654 }
3655
3656 if (bgp_damp_update(pi, dest, afi, safi)
3657 != BGP_DAMP_SUPPRESSED) {
3658 bgp_aggregate_increment(bgp, p, pi, afi,
3659 safi);
3660 bgp_process(bgp, dest, afi, safi);
3661 }
3662 } else /* Duplicate - odd */
3663 {
3664 if (bgp_debug_update(peer, p, NULL, 1)) {
3665 if (!peer->rcvd_attr_printed) {
3666 zlog_debug(
3667 "%s rcvd UPDATE w/ attr: %s",
3668 peer->host,
3669 peer->rcvd_attr_str);
3670 peer->rcvd_attr_printed = 1;
3671 }
3672
3673 bgp_debug_rdpfxpath2str(
3674 afi, safi, prd, p, label,
3675 num_labels, addpath_id ? 1 : 0,
3676 addpath_id, pfx_buf,
3677 sizeof(pfx_buf));
3678 zlog_debug(
3679 "%s rcvd %s...duplicate ignored",
3680 peer->host, pfx_buf);
3681 }
3682
3683 /* graceful restart STALE flag unset. */
3684 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3685 bgp_path_info_unset_flag(
3686 dest, pi, BGP_PATH_STALE);
3687 bgp_dest_set_defer_flag(dest, false);
3688 bgp_process(bgp, dest, afi, safi);
3689 }
3690 }
3691
3692 bgp_dest_unlock_node(dest);
3693 bgp_attr_unintern(&attr_new);
3694
3695 return 0;
3696 }
3697
3698 /* Withdraw/Announce before we fully processed the withdraw */
3699 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
3700 if (bgp_debug_update(peer, p, NULL, 1)) {
3701 bgp_debug_rdpfxpath2str(
3702 afi, safi, prd, p, label, num_labels,
3703 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3704 sizeof(pfx_buf));
3705 zlog_debug(
3706 "%s rcvd %s, flapped quicker than processing",
3707 peer->host, pfx_buf);
3708 }
3709
3710 bgp_path_info_restore(dest, pi);
3711 }
3712
3713 /* Received Logging. */
3714 if (bgp_debug_update(peer, p, NULL, 1)) {
3715 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
3716 num_labels, addpath_id ? 1 : 0,
3717 addpath_id, pfx_buf,
3718 sizeof(pfx_buf));
3719 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3720 }
3721
3722 /* graceful restart STALE flag unset. */
3723 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3724 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
3725 bgp_dest_set_defer_flag(dest, false);
3726 }
3727
3728 /* The attribute is changed. */
3729 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
3730
3731 /* implicit withdraw, decrement aggregate and pcount here.
3732 * only if update is accepted, they'll increment below.
3733 */
3734 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
3735
3736 /* Update bgp route dampening information. */
3737 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3738 && peer->sort == BGP_PEER_EBGP) {
3739 /* This is implicit withdraw so we should update
3740 dampening
3741 information. */
3742 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
3743 bgp_damp_withdraw(pi, dest, afi, safi, 1);
3744 }
3745 #ifdef ENABLE_BGP_VNC
3746 if (safi == SAFI_MPLS_VPN) {
3747 struct bgp_dest *pdest = NULL;
3748 struct bgp_table *table = NULL;
3749
3750 pdest = bgp_node_get(bgp->rib[afi][safi],
3751 (struct prefix *)prd);
3752 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3753 table = bgp_dest_get_bgp_table_info(pdest);
3754
3755 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3756 bgp, prd, table, p, pi);
3757 }
3758 bgp_dest_unlock_node(pdest);
3759 }
3760 if ((afi == AFI_IP || afi == AFI_IP6)
3761 && (safi == SAFI_UNICAST)) {
3762 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3763 /*
3764 * Implicit withdraw case.
3765 */
3766 ++vnc_implicit_withdraw;
3767 vnc_import_bgp_del_route(bgp, p, pi);
3768 vnc_import_bgp_exterior_del_route(bgp, p, pi);
3769 }
3770 }
3771 #endif
3772
3773 /* Special handling for EVPN update of an existing route. If the
3774 * extended community attribute has changed, we need to
3775 * un-import
3776 * the route using its existing extended community. It will be
3777 * subsequently processed for import with the new extended
3778 * community.
3779 */
3780 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
3781 && !same_attr) {
3782 if ((pi->attr->flag
3783 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
3784 && (attr_new->flag
3785 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
3786 int cmp;
3787
3788 cmp = ecommunity_cmp(pi->attr->ecommunity,
3789 attr_new->ecommunity);
3790 if (!cmp) {
3791 if (bgp_debug_update(peer, p, NULL, 1))
3792 zlog_debug(
3793 "Change in EXT-COMM, existing %s new %s",
3794 ecommunity_str(
3795 pi->attr->ecommunity),
3796 ecommunity_str(
3797 attr_new->ecommunity));
3798 if (safi == SAFI_EVPN)
3799 bgp_evpn_unimport_route(
3800 bgp, afi, safi, p, pi);
3801 else /* SAFI_MPLS_VPN */
3802 vpn_leak_to_vrf_withdraw(bgp,
3803 pi);
3804 }
3805 }
3806 }
3807
3808 /* Update to new attribute. */
3809 bgp_attr_unintern(&pi->attr);
3810 pi->attr = attr_new;
3811
3812 /* Update MPLS label */
3813 if (has_valid_label) {
3814 extra = bgp_path_info_extra_get(pi);
3815 if (extra->label != label) {
3816 memcpy(&extra->label, label,
3817 num_labels * sizeof(mpls_label_t));
3818 extra->num_labels = num_labels;
3819 }
3820 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
3821 bgp_set_valid_label(&extra->label[0]);
3822 }
3823
3824 /* Update SRv6 SID */
3825 if (attr->srv6_l3vpn) {
3826 extra = bgp_path_info_extra_get(pi);
3827 if (sid_diff(&extra->sid[0], &attr->srv6_l3vpn->sid)) {
3828 sid_copy(&extra->sid[0],
3829 &attr->srv6_l3vpn->sid);
3830 extra->num_sids = 1;
3831 }
3832 } else if (attr->srv6_vpn) {
3833 extra = bgp_path_info_extra_get(pi);
3834 if (sid_diff(&extra->sid[0], &attr->srv6_vpn->sid)) {
3835 sid_copy(&extra->sid[0], &attr->srv6_vpn->sid);
3836 extra->num_sids = 1;
3837 }
3838 }
3839
3840 #ifdef ENABLE_BGP_VNC
3841 if ((afi == AFI_IP || afi == AFI_IP6)
3842 && (safi == SAFI_UNICAST)) {
3843 if (vnc_implicit_withdraw) {
3844 /*
3845 * Add back the route with its new attributes
3846 * (e.g., nexthop).
3847 * The route is still selected, until the route
3848 * selection
3849 * queued by bgp_process actually runs. We have
3850 * to make this
3851 * update to the VNC side immediately to avoid
3852 * racing against
3853 * configuration changes (e.g., route-map
3854 * changes) which
3855 * trigger re-importation of the entire RIB.
3856 */
3857 vnc_import_bgp_add_route(bgp, p, pi);
3858 vnc_import_bgp_exterior_add_route(bgp, p, pi);
3859 }
3860 }
3861 #endif
3862
3863 /* Update bgp route dampening information. */
3864 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3865 && peer->sort == BGP_PEER_EBGP) {
3866 /* Now we do normal update dampening. */
3867 ret = bgp_damp_update(pi, dest, afi, safi);
3868 if (ret == BGP_DAMP_SUPPRESSED) {
3869 bgp_dest_unlock_node(dest);
3870 return 0;
3871 }
3872 }
3873
3874 /* Nexthop reachability check - for unicast and
3875 * labeled-unicast.. */
3876 if (((afi == AFI_IP || afi == AFI_IP6)
3877 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
3878 || (safi == SAFI_EVPN &&
3879 bgp_evpn_is_prefix_nht_supported(p))) {
3880 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
3881 && peer->ttl == BGP_DEFAULT_TTL
3882 && !CHECK_FLAG(peer->flags,
3883 PEER_FLAG_DISABLE_CONNECTED_CHECK)
3884 && !CHECK_FLAG(bgp->flags,
3885 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
3886 connected = 1;
3887 else
3888 connected = 0;
3889
3890 struct bgp *bgp_nexthop = bgp;
3891
3892 if (pi->extra && pi->extra->bgp_orig)
3893 bgp_nexthop = pi->extra->bgp_orig;
3894
3895 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
3896
3897 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
3898 pi, NULL, connected)
3899 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
3900 bgp_path_info_set_flag(dest, pi,
3901 BGP_PATH_VALID);
3902 else {
3903 if (BGP_DEBUG(nht, NHT)) {
3904 zlog_debug("%s(%pI4): NH unresolved",
3905 __func__,
3906 (in_addr_t *)&attr_new->nexthop);
3907 }
3908 bgp_path_info_unset_flag(dest, pi,
3909 BGP_PATH_VALID);
3910 }
3911 } else
3912 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
3913
3914 #ifdef ENABLE_BGP_VNC
3915 if (safi == SAFI_MPLS_VPN) {
3916 struct bgp_dest *pdest = NULL;
3917 struct bgp_table *table = NULL;
3918
3919 pdest = bgp_node_get(bgp->rib[afi][safi],
3920 (struct prefix *)prd);
3921 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3922 table = bgp_dest_get_bgp_table_info(pdest);
3923
3924 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3925 bgp, prd, table, p, pi);
3926 }
3927 bgp_dest_unlock_node(pdest);
3928 }
3929 #endif
3930
3931 /* If this is an EVPN route and some attribute has changed,
3932 * process
3933 * route for import. If the extended community has changed, we
3934 * would
3935 * have done the un-import earlier and the import would result
3936 * in the
3937 * route getting injected into appropriate L2 VNIs. If it is
3938 * just
3939 * some other attribute change, the import will result in
3940 * updating
3941 * the attributes for the route in the VNI(s).
3942 */
3943 if (safi == SAFI_EVPN && !same_attr &&
3944 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
3945 bgp_evpn_import_route(bgp, afi, safi, p, pi);
3946
3947 /* Process change. */
3948 bgp_aggregate_increment(bgp, p, pi, afi, safi);
3949
3950 bgp_process(bgp, dest, afi, safi);
3951 bgp_dest_unlock_node(dest);
3952
3953 if (SAFI_UNICAST == safi
3954 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
3955 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3956
3957 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
3958 }
3959 if ((SAFI_MPLS_VPN == safi)
3960 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3961
3962 vpn_leak_to_vrf_update(bgp, pi);
3963 }
3964
3965 #ifdef ENABLE_BGP_VNC
3966 if (SAFI_MPLS_VPN == safi) {
3967 mpls_label_t label_decoded = decode_label(label);
3968
3969 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
3970 type, sub_type, &label_decoded);
3971 }
3972 if (SAFI_ENCAP == safi) {
3973 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
3974 type, sub_type, NULL);
3975 }
3976 #endif
3977
3978 return 0;
3979 } // End of implicit withdraw
3980
3981 /* Received Logging. */
3982 if (bgp_debug_update(peer, p, NULL, 1)) {
3983 if (!peer->rcvd_attr_printed) {
3984 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
3985 peer->rcvd_attr_str);
3986 peer->rcvd_attr_printed = 1;
3987 }
3988
3989 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
3990 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3991 sizeof(pfx_buf));
3992 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3993 }
3994
3995 /* Make new BGP info. */
3996 new = info_make(type, sub_type, 0, peer, attr_new, dest);
3997
3998 /* Update MPLS label */
3999 if (has_valid_label) {
4000 extra = bgp_path_info_extra_get(new);
4001 if (extra->label != label) {
4002 memcpy(&extra->label, label,
4003 num_labels * sizeof(mpls_label_t));
4004 extra->num_labels = num_labels;
4005 }
4006 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4007 bgp_set_valid_label(&extra->label[0]);
4008 }
4009
4010 /* Update SRv6 SID */
4011 if (safi == SAFI_MPLS_VPN) {
4012 extra = bgp_path_info_extra_get(new);
4013 if (attr->srv6_l3vpn) {
4014 sid_copy(&extra->sid[0], &attr->srv6_l3vpn->sid);
4015 extra->num_sids = 1;
4016 } else if (attr->srv6_vpn) {
4017 sid_copy(&extra->sid[0], &attr->srv6_vpn->sid);
4018 extra->num_sids = 1;
4019 }
4020 }
4021
4022 /* Update Overlay Index */
4023 if (afi == AFI_L2VPN) {
4024 overlay_index_update(new->attr,
4025 evpn == NULL ? NULL : &evpn->gw_ip);
4026 }
4027 /* Nexthop reachability check. */
4028 if (((afi == AFI_IP || afi == AFI_IP6)
4029 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4030 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4031 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4032 && peer->ttl == BGP_DEFAULT_TTL
4033 && !CHECK_FLAG(peer->flags,
4034 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4035 && !CHECK_FLAG(bgp->flags,
4036 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4037 connected = 1;
4038 else
4039 connected = 0;
4040
4041 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4042
4043 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, new, NULL,
4044 connected)
4045 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4046 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4047 else {
4048 if (BGP_DEBUG(nht, NHT)) {
4049 char buf1[INET6_ADDRSTRLEN];
4050 inet_ntop(AF_INET,
4051 (const void *)&attr_new->nexthop,
4052 buf1, INET6_ADDRSTRLEN);
4053 zlog_debug("%s(%s): NH unresolved", __func__,
4054 buf1);
4055 }
4056 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4057 }
4058 } else
4059 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4060
4061 /* Addpath ID */
4062 new->addpath_rx_id = addpath_id;
4063
4064 /* Increment prefix */
4065 bgp_aggregate_increment(bgp, p, new, afi, safi);
4066
4067 /* Register new BGP information. */
4068 bgp_path_info_add(dest, new);
4069
4070 /* route_node_get lock */
4071 bgp_dest_unlock_node(dest);
4072
4073 #ifdef ENABLE_BGP_VNC
4074 if (safi == SAFI_MPLS_VPN) {
4075 struct bgp_dest *pdest = NULL;
4076 struct bgp_table *table = NULL;
4077
4078 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4079 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4080 table = bgp_dest_get_bgp_table_info(pdest);
4081
4082 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4083 bgp, prd, table, p, new);
4084 }
4085 bgp_dest_unlock_node(pdest);
4086 }
4087 #endif
4088
4089 /* If this is an EVPN route, process for import. */
4090 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4091 bgp_evpn_import_route(bgp, afi, safi, p, new);
4092
4093 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4094
4095 /* Process change. */
4096 bgp_process(bgp, dest, afi, safi);
4097
4098 if (SAFI_UNICAST == safi
4099 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4100 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4101 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4102 }
4103 if ((SAFI_MPLS_VPN == safi)
4104 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4105
4106 vpn_leak_to_vrf_update(bgp, new);
4107 }
4108 #ifdef ENABLE_BGP_VNC
4109 if (SAFI_MPLS_VPN == safi) {
4110 mpls_label_t label_decoded = decode_label(label);
4111
4112 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4113 sub_type, &label_decoded);
4114 }
4115 if (SAFI_ENCAP == safi) {
4116 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4117 sub_type, NULL);
4118 }
4119 #endif
4120
4121 return 0;
4122
4123 /* This BGP update is filtered. Log the reason then update BGP
4124 entry. */
4125 filtered:
4126 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4127
4128 if (bgp_debug_update(peer, p, NULL, 1)) {
4129 if (!peer->rcvd_attr_printed) {
4130 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
4131 peer->rcvd_attr_str);
4132 peer->rcvd_attr_printed = 1;
4133 }
4134
4135 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4136 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4137 sizeof(pfx_buf));
4138 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
4139 peer->host, pfx_buf, reason);
4140 }
4141
4142 if (pi) {
4143 /* If this is an EVPN route, un-import it as it is now filtered.
4144 */
4145 if (safi == SAFI_EVPN)
4146 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4147
4148 if (SAFI_UNICAST == safi
4149 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4150 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4151
4152 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4153 }
4154 if ((SAFI_MPLS_VPN == safi)
4155 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4156
4157 vpn_leak_to_vrf_withdraw(bgp, pi);
4158 }
4159
4160 bgp_rib_remove(dest, pi, peer, afi, safi);
4161 }
4162
4163 bgp_dest_unlock_node(dest);
4164
4165 #ifdef ENABLE_BGP_VNC
4166 /*
4167 * Filtered update is treated as an implicit withdrawal (see
4168 * bgp_rib_remove()
4169 * a few lines above)
4170 */
4171 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4172 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4173 0);
4174 }
4175 #endif
4176
4177 return 0;
4178 }
4179
4180 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4181 struct attr *attr, afi_t afi, safi_t safi, int type,
4182 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4183 uint32_t num_labels, struct bgp_route_evpn *evpn)
4184 {
4185 struct bgp *bgp;
4186 char pfx_buf[BGP_PRD_PATH_STRLEN];
4187 struct bgp_dest *dest;
4188 struct bgp_path_info *pi;
4189
4190 #ifdef ENABLE_BGP_VNC
4191 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4192 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4193 0);
4194 }
4195 #endif
4196
4197 bgp = peer->bgp;
4198
4199 /* Lookup node. */
4200 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4201
4202 /* If peer is soft reconfiguration enabled. Record input packet for
4203 * further calculation.
4204 *
4205 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4206 * routes that are filtered. This tanks out Quagga RS pretty badly due
4207 * to
4208 * the iteration over all RS clients.
4209 * Since we need to remove the entry from adj_in anyway, do that first
4210 * and
4211 * if there was no entry, we don't need to do anything more.
4212 */
4213 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4214 && peer != bgp->peer_self)
4215 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4216 peer->stat_pfx_dup_withdraw++;
4217
4218 if (bgp_debug_update(peer, p, NULL, 1)) {
4219 bgp_debug_rdpfxpath2str(
4220 afi, safi, prd, p, label, num_labels,
4221 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4222 sizeof(pfx_buf));
4223 zlog_debug(
4224 "%s withdrawing route %s not in adj-in",
4225 peer->host, pfx_buf);
4226 }
4227 bgp_dest_unlock_node(dest);
4228 return 0;
4229 }
4230
4231 /* Lookup withdrawn route. */
4232 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4233 if (pi->peer == peer && pi->type == type
4234 && pi->sub_type == sub_type
4235 && pi->addpath_rx_id == addpath_id)
4236 break;
4237
4238 /* Logging. */
4239 if (bgp_debug_update(peer, p, NULL, 1)) {
4240 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4241 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4242 sizeof(pfx_buf));
4243 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
4244 pfx_buf);
4245 }
4246
4247 /* Withdraw specified route from routing table. */
4248 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4249 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4250 if (SAFI_UNICAST == safi
4251 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4252 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4253 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4254 }
4255 if ((SAFI_MPLS_VPN == safi)
4256 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4257
4258 vpn_leak_to_vrf_withdraw(bgp, pi);
4259 }
4260 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4261 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4262 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4263 sizeof(pfx_buf));
4264 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4265 }
4266
4267 /* Unlock bgp_node_get() lock. */
4268 bgp_dest_unlock_node(dest);
4269
4270 return 0;
4271 }
4272
4273 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4274 int withdraw)
4275 {
4276 struct update_subgroup *subgrp;
4277 subgrp = peer_subgroup(peer, afi, safi);
4278 subgroup_default_originate(subgrp, withdraw);
4279 }
4280
4281
4282 /*
4283 * bgp_stop_announce_route_timer
4284 */
4285 void bgp_stop_announce_route_timer(struct peer_af *paf)
4286 {
4287 if (!paf->t_announce_route)
4288 return;
4289
4290 THREAD_TIMER_OFF(paf->t_announce_route);
4291 }
4292
4293 /*
4294 * bgp_announce_route_timer_expired
4295 *
4296 * Callback that is invoked when the route announcement timer for a
4297 * peer_af expires.
4298 */
4299 static int bgp_announce_route_timer_expired(struct thread *t)
4300 {
4301 struct peer_af *paf;
4302 struct peer *peer;
4303
4304 paf = THREAD_ARG(t);
4305 peer = paf->peer;
4306
4307 if (peer->status != Established)
4308 return 0;
4309
4310 if (!peer->afc_nego[paf->afi][paf->safi])
4311 return 0;
4312
4313 peer_af_announce_route(paf, 1);
4314 return 0;
4315 }
4316
4317 /*
4318 * bgp_announce_route
4319 *
4320 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
4321 */
4322 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi)
4323 {
4324 struct peer_af *paf;
4325 struct update_subgroup *subgrp;
4326
4327 paf = peer_af_find(peer, afi, safi);
4328 if (!paf)
4329 return;
4330 subgrp = PAF_SUBGRP(paf);
4331
4332 /*
4333 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
4334 * or a refresh has already been triggered.
4335 */
4336 if (!subgrp || paf->t_announce_route)
4337 return;
4338
4339 /*
4340 * Start a timer to stagger/delay the announce. This serves
4341 * two purposes - announcement can potentially be combined for
4342 * multiple peers and the announcement doesn't happen in the
4343 * vty context.
4344 */
4345 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
4346 (subgrp->peer_count == 1)
4347 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
4348 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
4349 &paf->t_announce_route);
4350 }
4351
4352 /*
4353 * Announce routes from all AF tables to a peer.
4354 *
4355 * This should ONLY be called when there is a need to refresh the
4356 * routes to the peer based on a policy change for this peer alone
4357 * or a route refresh request received from the peer.
4358 * The operation will result in splitting the peer from its existing
4359 * subgroups and putting it in new subgroups.
4360 */
4361 void bgp_announce_route_all(struct peer *peer)
4362 {
4363 afi_t afi;
4364 safi_t safi;
4365
4366 FOREACH_AFI_SAFI (afi, safi)
4367 bgp_announce_route(peer, afi, safi);
4368 }
4369
4370 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
4371 struct bgp_table *table,
4372 struct prefix_rd *prd)
4373 {
4374 int ret;
4375 struct bgp_dest *dest;
4376 struct bgp_adj_in *ain;
4377
4378 if (!table)
4379 table = peer->bgp->rib[afi][safi];
4380
4381 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
4382 for (ain = dest->adj_in; ain; ain = ain->next) {
4383 if (ain->peer != peer)
4384 continue;
4385
4386 struct bgp_path_info *pi;
4387 uint32_t num_labels = 0;
4388 mpls_label_t *label_pnt = NULL;
4389 struct bgp_route_evpn evpn;
4390
4391 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
4392 pi = pi->next)
4393 if (pi->peer == peer)
4394 break;
4395
4396 if (pi && pi->extra)
4397 num_labels = pi->extra->num_labels;
4398 if (num_labels)
4399 label_pnt = &pi->extra->label[0];
4400 if (pi)
4401 memcpy(&evpn, &pi->attr->evpn_overlay,
4402 sizeof(evpn));
4403 else
4404 memset(&evpn, 0, sizeof(evpn));
4405
4406 ret = bgp_update(peer, bgp_dest_get_prefix(dest),
4407 ain->addpath_rx_id, ain->attr, afi,
4408 safi, ZEBRA_ROUTE_BGP,
4409 BGP_ROUTE_NORMAL, prd, label_pnt,
4410 num_labels, 1, &evpn);
4411
4412 if (ret < 0) {
4413 bgp_dest_unlock_node(dest);
4414 return;
4415 }
4416 }
4417 }
4418
4419 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
4420 {
4421 struct bgp_dest *dest;
4422 struct bgp_table *table;
4423
4424 if (peer->status != Established)
4425 return;
4426
4427 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
4428 && (safi != SAFI_EVPN))
4429 bgp_soft_reconfig_table(peer, afi, safi, NULL, NULL);
4430 else
4431 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4432 dest = bgp_route_next(dest)) {
4433 table = bgp_dest_get_bgp_table_info(dest);
4434
4435 if (table == NULL)
4436 continue;
4437
4438 const struct prefix *p = bgp_dest_get_prefix(dest);
4439 struct prefix_rd prd;
4440
4441 prd.family = AF_UNSPEC;
4442 prd.prefixlen = 64;
4443 memcpy(&prd.val, p->u.val, 8);
4444
4445 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
4446 }
4447 }
4448
4449
4450 struct bgp_clear_node_queue {
4451 struct bgp_dest *dest;
4452 };
4453
4454 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
4455 {
4456 struct bgp_clear_node_queue *cnq = data;
4457 struct bgp_dest *dest = cnq->dest;
4458 struct peer *peer = wq->spec.data;
4459 struct bgp_path_info *pi;
4460 struct bgp *bgp;
4461 afi_t afi = bgp_dest_table(dest)->afi;
4462 safi_t safi = bgp_dest_table(dest)->safi;
4463
4464 assert(dest && peer);
4465 bgp = peer->bgp;
4466
4467 /* It is possible that we have multiple paths for a prefix from a peer
4468 * if that peer is using AddPath.
4469 */
4470 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
4471 if (pi->peer != peer)
4472 continue;
4473
4474 /* graceful restart STALE flag set. */
4475 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
4476 && peer->nsf[afi][safi]
4477 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
4478 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
4479 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
4480 else {
4481 /* If this is an EVPN route, process for
4482 * un-import. */
4483 if (safi == SAFI_EVPN)
4484 bgp_evpn_unimport_route(
4485 bgp, afi, safi,
4486 bgp_dest_get_prefix(dest), pi);
4487 /* Handle withdraw for VRF route-leaking and L3VPN */
4488 if (SAFI_UNICAST == safi
4489 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
4490 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4491 vpn_leak_from_vrf_withdraw(bgp_get_default(),
4492 bgp, pi);
4493 }
4494 if (SAFI_MPLS_VPN == safi &&
4495 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4496 vpn_leak_to_vrf_withdraw(bgp, pi);
4497 }
4498
4499 bgp_rib_remove(dest, pi, peer, afi, safi);
4500 }
4501 }
4502 return WQ_SUCCESS;
4503 }
4504
4505 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
4506 {
4507 struct bgp_clear_node_queue *cnq = data;
4508 struct bgp_dest *dest = cnq->dest;
4509 struct bgp_table *table = bgp_dest_table(dest);
4510
4511 bgp_dest_unlock_node(dest);
4512 bgp_table_unlock(table);
4513 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
4514 }
4515
4516 static void bgp_clear_node_complete(struct work_queue *wq)
4517 {
4518 struct peer *peer = wq->spec.data;
4519
4520 /* Tickle FSM to start moving again */
4521 BGP_EVENT_ADD(peer, Clearing_Completed);
4522
4523 peer_unlock(peer); /* bgp_clear_route */
4524 }
4525
4526 static void bgp_clear_node_queue_init(struct peer *peer)
4527 {
4528 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
4529
4530 snprintf(wname, sizeof(wname), "clear %s", peer->host);
4531 #undef CLEAR_QUEUE_NAME_LEN
4532
4533 peer->clear_node_queue = work_queue_new(bm->master, wname);
4534 peer->clear_node_queue->spec.hold = 10;
4535 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
4536 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
4537 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
4538 peer->clear_node_queue->spec.max_retries = 0;
4539
4540 /* we only 'lock' this peer reference when the queue is actually active
4541 */
4542 peer->clear_node_queue->spec.data = peer;
4543 }
4544
4545 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
4546 struct bgp_table *table)
4547 {
4548 struct bgp_dest *dest;
4549 int force = bm->process_main_queue ? 0 : 1;
4550
4551 if (!table)
4552 table = peer->bgp->rib[afi][safi];
4553
4554 /* If still no table => afi/safi isn't configured at all or smth. */
4555 if (!table)
4556 return;
4557
4558 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4559 struct bgp_path_info *pi, *next;
4560 struct bgp_adj_in *ain;
4561 struct bgp_adj_in *ain_next;
4562
4563 /* XXX:TODO: This is suboptimal, every non-empty route_node is
4564 * queued for every clearing peer, regardless of whether it is
4565 * relevant to the peer at hand.
4566 *
4567 * Overview: There are 3 different indices which need to be
4568 * scrubbed, potentially, when a peer is removed:
4569 *
4570 * 1 peer's routes visible via the RIB (ie accepted routes)
4571 * 2 peer's routes visible by the (optional) peer's adj-in index
4572 * 3 other routes visible by the peer's adj-out index
4573 *
4574 * 3 there is no hurry in scrubbing, once the struct peer is
4575 * removed from bgp->peer, we could just GC such deleted peer's
4576 * adj-outs at our leisure.
4577 *
4578 * 1 and 2 must be 'scrubbed' in some way, at least made
4579 * invisible via RIB index before peer session is allowed to be
4580 * brought back up. So one needs to know when such a 'search' is
4581 * complete.
4582 *
4583 * Ideally:
4584 *
4585 * - there'd be a single global queue or a single RIB walker
4586 * - rather than tracking which route_nodes still need to be
4587 * examined on a peer basis, we'd track which peers still
4588 * aren't cleared
4589 *
4590 * Given that our per-peer prefix-counts now should be reliable,
4591 * this may actually be achievable. It doesn't seem to be a huge
4592 * problem at this time,
4593 *
4594 * It is possible that we have multiple paths for a prefix from
4595 * a peer
4596 * if that peer is using AddPath.
4597 */
4598 ain = dest->adj_in;
4599 while (ain) {
4600 ain_next = ain->next;
4601
4602 if (ain->peer == peer) {
4603 bgp_adj_in_remove(dest, ain);
4604 bgp_dest_unlock_node(dest);
4605 }
4606
4607 ain = ain_next;
4608 }
4609
4610 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
4611 next = pi->next;
4612 if (pi->peer != peer)
4613 continue;
4614
4615 if (force)
4616 bgp_path_info_reap(dest, pi);
4617 else {
4618 struct bgp_clear_node_queue *cnq;
4619
4620 /* both unlocked in bgp_clear_node_queue_del */
4621 bgp_table_lock(bgp_dest_table(dest));
4622 bgp_dest_lock_node(dest);
4623 cnq = XCALLOC(
4624 MTYPE_BGP_CLEAR_NODE_QUEUE,
4625 sizeof(struct bgp_clear_node_queue));
4626 cnq->dest = dest;
4627 work_queue_add(peer->clear_node_queue, cnq);
4628 break;
4629 }
4630 }
4631 }
4632 return;
4633 }
4634
4635 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
4636 {
4637 struct bgp_dest *dest;
4638 struct bgp_table *table;
4639
4640 if (peer->clear_node_queue == NULL)
4641 bgp_clear_node_queue_init(peer);
4642
4643 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
4644 * Idle until it receives a Clearing_Completed event. This protects
4645 * against peers which flap faster than we can we clear, which could
4646 * lead to:
4647 *
4648 * a) race with routes from the new session being installed before
4649 * clear_route_node visits the node (to delete the route of that
4650 * peer)
4651 * b) resource exhaustion, clear_route_node likely leads to an entry
4652 * on the process_main queue. Fast-flapping could cause that queue
4653 * to grow and grow.
4654 */
4655
4656 /* lock peer in assumption that clear-node-queue will get nodes; if so,
4657 * the unlock will happen upon work-queue completion; other wise, the
4658 * unlock happens at the end of this function.
4659 */
4660 if (!peer->clear_node_queue->thread)
4661 peer_lock(peer);
4662
4663 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
4664 bgp_clear_route_table(peer, afi, safi, NULL);
4665 else
4666 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4667 dest = bgp_route_next(dest)) {
4668 table = bgp_dest_get_bgp_table_info(dest);
4669 if (!table)
4670 continue;
4671
4672 bgp_clear_route_table(peer, afi, safi, table);
4673 }
4674
4675 /* unlock if no nodes got added to the clear-node-queue. */
4676 if (!peer->clear_node_queue->thread)
4677 peer_unlock(peer);
4678 }
4679
4680 void bgp_clear_route_all(struct peer *peer)
4681 {
4682 afi_t afi;
4683 safi_t safi;
4684
4685 FOREACH_AFI_SAFI (afi, safi)
4686 bgp_clear_route(peer, afi, safi);
4687
4688 #ifdef ENABLE_BGP_VNC
4689 rfapiProcessPeerDown(peer);
4690 #endif
4691 }
4692
4693 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
4694 {
4695 struct bgp_table *table;
4696 struct bgp_dest *dest;
4697 struct bgp_adj_in *ain;
4698 struct bgp_adj_in *ain_next;
4699
4700 table = peer->bgp->rib[afi][safi];
4701
4702 /* It is possible that we have multiple paths for a prefix from a peer
4703 * if that peer is using AddPath.
4704 */
4705 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4706 ain = dest->adj_in;
4707
4708 while (ain) {
4709 ain_next = ain->next;
4710
4711 if (ain->peer == peer) {
4712 bgp_adj_in_remove(dest, ain);
4713 bgp_dest_unlock_node(dest);
4714 }
4715
4716 ain = ain_next;
4717 }
4718 }
4719 }
4720
4721 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
4722 {
4723 struct bgp_dest *dest;
4724 struct bgp_path_info *pi;
4725 struct bgp_table *table;
4726
4727 if (safi == SAFI_MPLS_VPN) {
4728 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4729 dest = bgp_route_next(dest)) {
4730 struct bgp_dest *rm;
4731
4732 /* look for neighbor in tables */
4733 table = bgp_dest_get_bgp_table_info(dest);
4734 if (!table)
4735 continue;
4736
4737 for (rm = bgp_table_top(table); rm;
4738 rm = bgp_route_next(rm))
4739 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
4740 pi = pi->next) {
4741 if (pi->peer != peer)
4742 continue;
4743 if (!CHECK_FLAG(pi->flags,
4744 BGP_PATH_STALE))
4745 break;
4746
4747 bgp_rib_remove(rm, pi, peer, afi, safi);
4748 break;
4749 }
4750 }
4751 } else {
4752 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4753 dest = bgp_route_next(dest))
4754 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
4755 pi = pi->next) {
4756 if (pi->peer != peer)
4757 continue;
4758 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
4759 break;
4760 bgp_rib_remove(dest, pi, peer, afi, safi);
4761 break;
4762 }
4763 }
4764 }
4765
4766 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
4767 {
4768 if (peer->sort == BGP_PEER_IBGP)
4769 return true;
4770
4771 if (peer->sort == BGP_PEER_EBGP
4772 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
4773 || FILTER_LIST_OUT_NAME(filter)
4774 || DISTRIBUTE_OUT_NAME(filter)))
4775 return true;
4776 return false;
4777 }
4778
4779 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
4780 {
4781 if (peer->sort == BGP_PEER_IBGP)
4782 return true;
4783
4784 if (peer->sort == BGP_PEER_EBGP
4785 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
4786 || FILTER_LIST_IN_NAME(filter)
4787 || DISTRIBUTE_IN_NAME(filter)))
4788 return true;
4789 return false;
4790 }
4791
4792 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
4793 safi_t safi)
4794 {
4795 struct bgp_dest *dest;
4796 struct bgp_path_info *pi;
4797 struct bgp_path_info *next;
4798
4799 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
4800 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
4801 const struct prefix *p = bgp_dest_get_prefix(dest);
4802
4803 next = pi->next;
4804
4805 /* Unimport EVPN routes from VRFs */
4806 if (safi == SAFI_EVPN)
4807 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
4808 SAFI_EVPN, p, pi);
4809
4810 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
4811 && pi->type == ZEBRA_ROUTE_BGP
4812 && (pi->sub_type == BGP_ROUTE_NORMAL
4813 || pi->sub_type == BGP_ROUTE_AGGREGATE
4814 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
4815
4816 if (bgp_fibupd_safi(safi))
4817 bgp_zebra_withdraw(p, pi, bgp, safi);
4818 }
4819
4820 bgp_path_info_reap(dest, pi);
4821 }
4822 }
4823
4824 /* Delete all kernel routes. */
4825 void bgp_cleanup_routes(struct bgp *bgp)
4826 {
4827 afi_t afi;
4828 struct bgp_dest *dest;
4829 struct bgp_table *table;
4830
4831 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
4832 if (afi == AFI_L2VPN)
4833 continue;
4834 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
4835 SAFI_UNICAST);
4836 /*
4837 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
4838 */
4839 if (afi != AFI_L2VPN) {
4840 safi_t safi;
4841 safi = SAFI_MPLS_VPN;
4842 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
4843 dest = bgp_route_next(dest)) {
4844 table = bgp_dest_get_bgp_table_info(dest);
4845 if (table != NULL) {
4846 bgp_cleanup_table(bgp, table, safi);
4847 bgp_table_finish(&table);
4848 bgp_dest_set_bgp_table_info(dest, NULL);
4849 bgp_dest_unlock_node(dest);
4850 }
4851 }
4852 safi = SAFI_ENCAP;
4853 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
4854 dest = bgp_route_next(dest)) {
4855 table = bgp_dest_get_bgp_table_info(dest);
4856 if (table != NULL) {
4857 bgp_cleanup_table(bgp, table, safi);
4858 bgp_table_finish(&table);
4859 bgp_dest_set_bgp_table_info(dest, NULL);
4860 bgp_dest_unlock_node(dest);
4861 }
4862 }
4863 }
4864 }
4865 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
4866 dest = bgp_route_next(dest)) {
4867 table = bgp_dest_get_bgp_table_info(dest);
4868 if (table != NULL) {
4869 bgp_cleanup_table(bgp, table, SAFI_EVPN);
4870 bgp_table_finish(&table);
4871 bgp_dest_set_bgp_table_info(dest, NULL);
4872 bgp_dest_unlock_node(dest);
4873 }
4874 }
4875 }
4876
4877 void bgp_reset(void)
4878 {
4879 vty_reset();
4880 bgp_zclient_reset();
4881 access_list_reset();
4882 prefix_list_reset();
4883 }
4884
4885 static int bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
4886 {
4887 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
4888 && CHECK_FLAG(peer->af_cap[afi][safi],
4889 PEER_CAP_ADDPATH_AF_TX_RCV));
4890 }
4891
4892 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
4893 value. */
4894 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
4895 struct bgp_nlri *packet)
4896 {
4897 uint8_t *pnt;
4898 uint8_t *lim;
4899 struct prefix p;
4900 int psize;
4901 int ret;
4902 afi_t afi;
4903 safi_t safi;
4904 int addpath_encoded;
4905 uint32_t addpath_id;
4906
4907 pnt = packet->nlri;
4908 lim = pnt + packet->length;
4909 afi = packet->afi;
4910 safi = packet->safi;
4911 addpath_id = 0;
4912 addpath_encoded = bgp_addpath_encode_rx(peer, afi, safi);
4913
4914 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
4915 syntactic validity. If the field is syntactically incorrect,
4916 then the Error Subcode is set to Invalid Network Field. */
4917 for (; pnt < lim; pnt += psize) {
4918 /* Clear prefix structure. */
4919 memset(&p, 0, sizeof(struct prefix));
4920
4921 if (addpath_encoded) {
4922
4923 /* When packet overflow occurs return immediately. */
4924 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
4925 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
4926
4927 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
4928 addpath_id = ntohl(addpath_id);
4929 pnt += BGP_ADDPATH_ID_LEN;
4930 }
4931
4932 /* Fetch prefix length. */
4933 p.prefixlen = *pnt++;
4934 /* afi/safi validity already verified by caller,
4935 * bgp_update_receive */
4936 p.family = afi2family(afi);
4937
4938 /* Prefix length check. */
4939 if (p.prefixlen > prefix_blen(&p) * 8) {
4940 flog_err(
4941 EC_BGP_UPDATE_RCV,
4942 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
4943 peer->host, p.prefixlen, packet->afi);
4944 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
4945 }
4946
4947 /* Packet size overflow check. */
4948 psize = PSIZE(p.prefixlen);
4949
4950 /* When packet overflow occur return immediately. */
4951 if (pnt + psize > lim) {
4952 flog_err(
4953 EC_BGP_UPDATE_RCV,
4954 "%s [Error] Update packet error (prefix length %d overflows packet)",
4955 peer->host, p.prefixlen);
4956 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
4957 }
4958
4959 /* Defensive coding, double-check the psize fits in a struct
4960 * prefix */
4961 if (psize > (ssize_t)sizeof(p.u)) {
4962 flog_err(
4963 EC_BGP_UPDATE_RCV,
4964 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
4965 peer->host, p.prefixlen, sizeof(p.u));
4966 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
4967 }
4968
4969 /* Fetch prefix from NLRI packet. */
4970 memcpy(p.u.val, pnt, psize);
4971
4972 /* Check address. */
4973 if (afi == AFI_IP && safi == SAFI_UNICAST) {
4974 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
4975 /* From RFC4271 Section 6.3:
4976 *
4977 * If a prefix in the NLRI field is semantically
4978 * incorrect
4979 * (e.g., an unexpected multicast IP address),
4980 * an error SHOULD
4981 * be logged locally, and the prefix SHOULD be
4982 * ignored.
4983 */
4984 flog_err(
4985 EC_BGP_UPDATE_RCV,
4986 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
4987 peer->host, inet_ntoa(p.u.prefix4));
4988 continue;
4989 }
4990 }
4991
4992 /* Check address. */
4993 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
4994 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
4995 char buf[BUFSIZ];
4996
4997 flog_err(
4998 EC_BGP_UPDATE_RCV,
4999 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
5000 peer->host,
5001 inet_ntop(AF_INET6, &p.u.prefix6, buf,
5002 BUFSIZ));
5003
5004 continue;
5005 }
5006 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
5007 char buf[BUFSIZ];
5008
5009 flog_err(
5010 EC_BGP_UPDATE_RCV,
5011 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
5012 peer->host,
5013 inet_ntop(AF_INET6, &p.u.prefix6, buf,
5014 BUFSIZ));
5015
5016 continue;
5017 }
5018 }
5019
5020 /* Normal process. */
5021 if (attr)
5022 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
5023 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
5024 NULL, NULL, 0, 0, NULL);
5025 else
5026 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
5027 safi, ZEBRA_ROUTE_BGP,
5028 BGP_ROUTE_NORMAL, NULL, NULL, 0,
5029 NULL);
5030
5031 /* Do not send BGP notification twice when maximum-prefix count
5032 * overflow. */
5033 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
5034 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
5035
5036 /* Address family configuration mismatch. */
5037 if (ret < 0)
5038 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
5039 }
5040
5041 /* Packet length consistency check. */
5042 if (pnt != lim) {
5043 flog_err(
5044 EC_BGP_UPDATE_RCV,
5045 "%s [Error] Update packet error (prefix length mismatch with total length)",
5046 peer->host);
5047 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5048 }
5049
5050 return BGP_NLRI_PARSE_OK;
5051 }
5052
5053 static struct bgp_static *bgp_static_new(void)
5054 {
5055 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
5056 }
5057
5058 static void bgp_static_free(struct bgp_static *bgp_static)
5059 {
5060 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5061 route_map_counter_decrement(bgp_static->rmap.map);
5062
5063 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
5064 XFREE(MTYPE_BGP_STATIC, bgp_static);
5065 }
5066
5067 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
5068 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
5069 {
5070 struct bgp_dest *dest;
5071 struct bgp_path_info *pi;
5072 struct bgp_path_info *new;
5073 struct bgp_path_info rmap_path;
5074 struct attr attr;
5075 struct attr *attr_new;
5076 route_map_result_t ret;
5077 #ifdef ENABLE_BGP_VNC
5078 int vnc_implicit_withdraw = 0;
5079 #endif
5080
5081 assert(bgp_static);
5082
5083 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5084
5085 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5086
5087 attr.nexthop = bgp_static->igpnexthop;
5088 attr.med = bgp_static->igpmetric;
5089 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5090
5091 if (bgp_static->atomic)
5092 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
5093
5094 /* Store label index, if required. */
5095 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
5096 attr.label_index = bgp_static->label_index;
5097 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
5098 }
5099
5100 /* Apply route-map. */
5101 if (bgp_static->rmap.name) {
5102 struct attr attr_tmp = attr;
5103
5104 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
5105 rmap_path.peer = bgp->peer_self;
5106 rmap_path.attr = &attr_tmp;
5107
5108 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5109
5110 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
5111 &rmap_path);
5112
5113 bgp->peer_self->rmap_type = 0;
5114
5115 if (ret == RMAP_DENYMATCH) {
5116 /* Free uninterned attribute. */
5117 bgp_attr_flush(&attr_tmp);
5118
5119 /* Unintern original. */
5120 aspath_unintern(&attr.aspath);
5121 bgp_static_withdraw(bgp, p, afi, safi);
5122 return;
5123 }
5124
5125 if (bgp_in_graceful_shutdown(bgp))
5126 bgp_attr_add_gshut_community(&attr_tmp);
5127
5128 attr_new = bgp_attr_intern(&attr_tmp);
5129 } else {
5130
5131 if (bgp_in_graceful_shutdown(bgp))
5132 bgp_attr_add_gshut_community(&attr);
5133
5134 attr_new = bgp_attr_intern(&attr);
5135 }
5136
5137 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5138 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5139 && pi->sub_type == BGP_ROUTE_STATIC)
5140 break;
5141
5142 if (pi) {
5143 if (attrhash_cmp(pi->attr, attr_new)
5144 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
5145 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
5146 bgp_dest_unlock_node(dest);
5147 bgp_attr_unintern(&attr_new);
5148 aspath_unintern(&attr.aspath);
5149 return;
5150 } else {
5151 /* The attribute is changed. */
5152 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5153
5154 /* Rewrite BGP route information. */
5155 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5156 bgp_path_info_restore(dest, pi);
5157 else
5158 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5159 #ifdef ENABLE_BGP_VNC
5160 if ((afi == AFI_IP || afi == AFI_IP6)
5161 && (safi == SAFI_UNICAST)) {
5162 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
5163 /*
5164 * Implicit withdraw case.
5165 * We have to do this before pi is
5166 * changed
5167 */
5168 ++vnc_implicit_withdraw;
5169 vnc_import_bgp_del_route(bgp, p, pi);
5170 vnc_import_bgp_exterior_del_route(
5171 bgp, p, pi);
5172 }
5173 }
5174 #endif
5175 bgp_attr_unintern(&pi->attr);
5176 pi->attr = attr_new;
5177 pi->uptime = bgp_clock();
5178 #ifdef ENABLE_BGP_VNC
5179 if ((afi == AFI_IP || afi == AFI_IP6)
5180 && (safi == SAFI_UNICAST)) {
5181 if (vnc_implicit_withdraw) {
5182 vnc_import_bgp_add_route(bgp, p, pi);
5183 vnc_import_bgp_exterior_add_route(
5184 bgp, p, pi);
5185 }
5186 }
5187 #endif
5188
5189 /* Nexthop reachability check. */
5190 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5191 && (safi == SAFI_UNICAST
5192 || safi == SAFI_LABELED_UNICAST)) {
5193
5194 struct bgp *bgp_nexthop = bgp;
5195
5196 if (pi->extra && pi->extra->bgp_orig)
5197 bgp_nexthop = pi->extra->bgp_orig;
5198
5199 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
5200 afi, pi, NULL, 0))
5201 bgp_path_info_set_flag(dest, pi,
5202 BGP_PATH_VALID);
5203 else {
5204 if (BGP_DEBUG(nht, NHT)) {
5205 char buf1[INET6_ADDRSTRLEN];
5206 inet_ntop(p->family,
5207 &p->u.prefix, buf1,
5208 INET6_ADDRSTRLEN);
5209 zlog_debug(
5210 "%s(%s): Route not in table, not advertising",
5211 __func__, buf1);
5212 }
5213 bgp_path_info_unset_flag(
5214 dest, pi, BGP_PATH_VALID);
5215 }
5216 } else {
5217 /* Delete the NHT structure if any, if we're
5218 * toggling between
5219 * enabling/disabling import check. We
5220 * deregister the route
5221 * from NHT to avoid overloading NHT and the
5222 * process interaction
5223 */
5224 bgp_unlink_nexthop(pi);
5225 bgp_path_info_set_flag(dest, pi,
5226 BGP_PATH_VALID);
5227 }
5228 /* Process change. */
5229 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5230 bgp_process(bgp, dest, afi, safi);
5231
5232 if (SAFI_UNICAST == safi
5233 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5234 || bgp->inst_type
5235 == BGP_INSTANCE_TYPE_DEFAULT)) {
5236 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
5237 pi);
5238 }
5239
5240 bgp_dest_unlock_node(dest);
5241 aspath_unintern(&attr.aspath);
5242 return;
5243 }
5244 }
5245
5246 /* Make new BGP info. */
5247 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5248 attr_new, dest);
5249 /* Nexthop reachability check. */
5250 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5251 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
5252 if (bgp_find_or_add_nexthop(bgp, bgp, afi, new, NULL, 0))
5253 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5254 else {
5255 if (BGP_DEBUG(nht, NHT)) {
5256 char buf1[INET6_ADDRSTRLEN];
5257 inet_ntop(p->family, &p->u.prefix, buf1,
5258 INET6_ADDRSTRLEN);
5259 zlog_debug(
5260 "%s(%s): Route not in table, not advertising",
5261 __func__, buf1);
5262 }
5263 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
5264 }
5265 } else {
5266 /* Delete the NHT structure if any, if we're toggling between
5267 * enabling/disabling import check. We deregister the route
5268 * from NHT to avoid overloading NHT and the process interaction
5269 */
5270 bgp_unlink_nexthop(new);
5271
5272 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5273 }
5274
5275 /* Aggregate address increment. */
5276 bgp_aggregate_increment(bgp, p, new, afi, safi);
5277
5278 /* Register new BGP information. */
5279 bgp_path_info_add(dest, new);
5280
5281 /* route_node_get lock */
5282 bgp_dest_unlock_node(dest);
5283
5284 /* Process change. */
5285 bgp_process(bgp, dest, afi, safi);
5286
5287 if (SAFI_UNICAST == safi
5288 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5289 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5290 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
5291 }
5292
5293 /* Unintern original. */
5294 aspath_unintern(&attr.aspath);
5295 }
5296
5297 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
5298 safi_t safi)
5299 {
5300 struct bgp_dest *dest;
5301 struct bgp_path_info *pi;
5302
5303 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5304
5305 /* Check selected route and self inserted route. */
5306 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5307 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5308 && pi->sub_type == BGP_ROUTE_STATIC)
5309 break;
5310
5311 /* Withdraw static BGP route from routing table. */
5312 if (pi) {
5313 if (SAFI_UNICAST == safi
5314 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5315 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5316 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5317 }
5318 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5319 bgp_unlink_nexthop(pi);
5320 bgp_path_info_delete(dest, pi);
5321 bgp_process(bgp, dest, afi, safi);
5322 }
5323
5324 /* Unlock bgp_node_lookup. */
5325 bgp_dest_unlock_node(dest);
5326 }
5327
5328 /*
5329 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
5330 */
5331 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
5332 afi_t afi, safi_t safi,
5333 struct prefix_rd *prd)
5334 {
5335 struct bgp_dest *dest;
5336 struct bgp_path_info *pi;
5337
5338 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
5339
5340 /* Check selected route and self inserted route. */
5341 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5342 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5343 && pi->sub_type == BGP_ROUTE_STATIC)
5344 break;
5345
5346 /* Withdraw static BGP route from routing table. */
5347 if (pi) {
5348 #ifdef ENABLE_BGP_VNC
5349 rfapiProcessWithdraw(
5350 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
5351 1); /* Kill, since it is an administrative change */
5352 #endif
5353 if (SAFI_MPLS_VPN == safi
5354 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5355 vpn_leak_to_vrf_withdraw(bgp, pi);
5356 }
5357 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5358 bgp_path_info_delete(dest, pi);
5359 bgp_process(bgp, dest, afi, safi);
5360 }
5361
5362 /* Unlock bgp_node_lookup. */
5363 bgp_dest_unlock_node(dest);
5364 }
5365
5366 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
5367 struct bgp_static *bgp_static, afi_t afi,
5368 safi_t safi)
5369 {
5370 struct bgp_dest *dest;
5371 struct bgp_path_info *new;
5372 struct attr *attr_new;
5373 struct attr attr = {0};
5374 struct bgp_path_info *pi;
5375 #ifdef ENABLE_BGP_VNC
5376 mpls_label_t label = 0;
5377 #endif
5378 uint32_t num_labels = 0;
5379 union gw_addr add;
5380
5381 assert(bgp_static);
5382
5383 if (bgp_static->label != MPLS_INVALID_LABEL)
5384 num_labels = 1;
5385 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
5386 &bgp_static->prd);
5387
5388 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5389
5390 attr.nexthop = bgp_static->igpnexthop;
5391 attr.med = bgp_static->igpmetric;
5392 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5393
5394 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
5395 || (safi == SAFI_ENCAP)) {
5396 if (afi == AFI_IP) {
5397 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
5398 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
5399 }
5400 }
5401 if (afi == AFI_L2VPN) {
5402 if (bgp_static->gatewayIp.family == AF_INET)
5403 add.ipv4.s_addr =
5404 bgp_static->gatewayIp.u.prefix4.s_addr;
5405 else if (bgp_static->gatewayIp.family == AF_INET6)
5406 memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
5407 sizeof(struct in6_addr));
5408 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
5409 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
5410 struct bgp_encap_type_vxlan bet;
5411 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
5412 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
5413 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
5414 }
5415 if (bgp_static->router_mac) {
5416 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
5417 }
5418 }
5419 /* Apply route-map. */
5420 if (bgp_static->rmap.name) {
5421 struct attr attr_tmp = attr;
5422 struct bgp_path_info rmap_path;
5423 route_map_result_t ret;
5424
5425 rmap_path.peer = bgp->peer_self;
5426 rmap_path.attr = &attr_tmp;
5427
5428 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5429
5430 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
5431 &rmap_path);
5432
5433 bgp->peer_self->rmap_type = 0;
5434
5435 if (ret == RMAP_DENYMATCH) {
5436 /* Free uninterned attribute. */
5437 bgp_attr_flush(&attr_tmp);
5438
5439 /* Unintern original. */
5440 aspath_unintern(&attr.aspath);
5441 bgp_static_withdraw_safi(bgp, p, afi, safi,
5442 &bgp_static->prd);
5443 return;
5444 }
5445
5446 attr_new = bgp_attr_intern(&attr_tmp);
5447 } else {
5448 attr_new = bgp_attr_intern(&attr);
5449 }
5450
5451 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5452 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5453 && pi->sub_type == BGP_ROUTE_STATIC)
5454 break;
5455
5456 if (pi) {
5457 memset(&add, 0, sizeof(union gw_addr));
5458 if (attrhash_cmp(pi->attr, attr_new)
5459 && overlay_index_equal(afi, pi, &add)
5460 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
5461 bgp_dest_unlock_node(dest);
5462 bgp_attr_unintern(&attr_new);
5463 aspath_unintern(&attr.aspath);
5464 return;
5465 } else {
5466 /* The attribute is changed. */
5467 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5468
5469 /* Rewrite BGP route information. */
5470 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5471 bgp_path_info_restore(dest, pi);
5472 else
5473 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5474 bgp_attr_unintern(&pi->attr);
5475 pi->attr = attr_new;
5476 pi->uptime = bgp_clock();
5477 #ifdef ENABLE_BGP_VNC
5478 if (pi->extra)
5479 label = decode_label(&pi->extra->label[0]);
5480 #endif
5481
5482 /* Process change. */
5483 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5484 bgp_process(bgp, dest, afi, safi);
5485
5486 if (SAFI_MPLS_VPN == safi
5487 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5488 vpn_leak_to_vrf_update(bgp, pi);
5489 }
5490 #ifdef ENABLE_BGP_VNC
5491 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
5492 pi->attr, afi, safi, pi->type,
5493 pi->sub_type, &label);
5494 #endif
5495 bgp_dest_unlock_node(dest);
5496 aspath_unintern(&attr.aspath);
5497 return;
5498 }
5499 }
5500
5501
5502 /* Make new BGP info. */
5503 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5504 attr_new, dest);
5505 SET_FLAG(new->flags, BGP_PATH_VALID);
5506 new->extra = bgp_path_info_extra_new();
5507 if (num_labels) {
5508 new->extra->label[0] = bgp_static->label;
5509 new->extra->num_labels = num_labels;
5510 }
5511 #ifdef ENABLE_BGP_VNC
5512 label = decode_label(&bgp_static->label);
5513 #endif
5514
5515 /* Aggregate address increment. */
5516 bgp_aggregate_increment(bgp, p, new, afi, safi);
5517
5518 /* Register new BGP information. */
5519 bgp_path_info_add(dest, new);
5520 /* route_node_get lock */
5521 bgp_dest_unlock_node(dest);
5522
5523 /* Process change. */
5524 bgp_process(bgp, dest, afi, safi);
5525
5526 if (SAFI_MPLS_VPN == safi
5527 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5528 vpn_leak_to_vrf_update(bgp, new);
5529 }
5530 #ifdef ENABLE_BGP_VNC
5531 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
5532 safi, new->type, new->sub_type, &label);
5533 #endif
5534
5535 /* Unintern original. */
5536 aspath_unintern(&attr.aspath);
5537 }
5538
5539 /* Configure static BGP network. When user don't run zebra, static
5540 route should be installed as valid. */
5541 static int bgp_static_set(struct vty *vty, const char *negate,
5542 const char *ip_str, afi_t afi, safi_t safi,
5543 const char *rmap, int backdoor, uint32_t label_index)
5544 {
5545 VTY_DECLVAR_CONTEXT(bgp, bgp);
5546 int ret;
5547 struct prefix p;
5548 struct bgp_static *bgp_static;
5549 struct bgp_dest *dest;
5550 uint8_t need_update = 0;
5551
5552 /* Convert IP prefix string to struct prefix. */
5553 ret = str2prefix(ip_str, &p);
5554 if (!ret) {
5555 vty_out(vty, "%% Malformed prefix\n");
5556 return CMD_WARNING_CONFIG_FAILED;
5557 }
5558 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
5559 vty_out(vty, "%% Malformed prefix (link-local address)\n");
5560 return CMD_WARNING_CONFIG_FAILED;
5561 }
5562
5563 apply_mask(&p);
5564
5565 if (negate) {
5566
5567 /* Set BGP static route configuration. */
5568 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
5569
5570 if (!dest) {
5571 vty_out(vty, "%% Can't find static route specified\n");
5572 return CMD_WARNING_CONFIG_FAILED;
5573 }
5574
5575 bgp_static = bgp_dest_get_bgp_static_info(dest);
5576
5577 if ((label_index != BGP_INVALID_LABEL_INDEX)
5578 && (label_index != bgp_static->label_index)) {
5579 vty_out(vty,
5580 "%% label-index doesn't match static route\n");
5581 return CMD_WARNING_CONFIG_FAILED;
5582 }
5583
5584 if ((rmap && bgp_static->rmap.name)
5585 && strcmp(rmap, bgp_static->rmap.name)) {
5586 vty_out(vty,
5587 "%% route-map name doesn't match static route\n");
5588 return CMD_WARNING_CONFIG_FAILED;
5589 }
5590
5591 /* Update BGP RIB. */
5592 if (!bgp_static->backdoor)
5593 bgp_static_withdraw(bgp, &p, afi, safi);
5594
5595 /* Clear configuration. */
5596 bgp_static_free(bgp_static);
5597 bgp_dest_set_bgp_static_info(dest, NULL);
5598 bgp_dest_unlock_node(dest);
5599 bgp_dest_unlock_node(dest);
5600 } else {
5601
5602 /* Set BGP static route configuration. */
5603 dest = bgp_node_get(bgp->route[afi][safi], &p);
5604 bgp_static = bgp_dest_get_bgp_static_info(dest);
5605 if (bgp_static) {
5606 /* Configuration change. */
5607 /* Label index cannot be changed. */
5608 if (bgp_static->label_index != label_index) {
5609 vty_out(vty, "%% cannot change label-index\n");
5610 return CMD_WARNING_CONFIG_FAILED;
5611 }
5612
5613 /* Check previous routes are installed into BGP. */
5614 if (bgp_static->valid
5615 && bgp_static->backdoor != backdoor)
5616 need_update = 1;
5617
5618 bgp_static->backdoor = backdoor;
5619
5620 if (rmap) {
5621 XFREE(MTYPE_ROUTE_MAP_NAME,
5622 bgp_static->rmap.name);
5623 route_map_counter_decrement(
5624 bgp_static->rmap.map);
5625 bgp_static->rmap.name =
5626 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5627 bgp_static->rmap.map =
5628 route_map_lookup_by_name(rmap);
5629 route_map_counter_increment(
5630 bgp_static->rmap.map);
5631 } else {
5632 XFREE(MTYPE_ROUTE_MAP_NAME,
5633 bgp_static->rmap.name);
5634 route_map_counter_decrement(
5635 bgp_static->rmap.map);
5636 bgp_static->rmap.map = NULL;
5637 bgp_static->valid = 0;
5638 }
5639 bgp_dest_unlock_node(dest);
5640 } else {
5641 /* New configuration. */
5642 bgp_static = bgp_static_new();
5643 bgp_static->backdoor = backdoor;
5644 bgp_static->valid = 0;
5645 bgp_static->igpmetric = 0;
5646 bgp_static->igpnexthop.s_addr = INADDR_ANY;
5647 bgp_static->label_index = label_index;
5648
5649 if (rmap) {
5650 XFREE(MTYPE_ROUTE_MAP_NAME,
5651 bgp_static->rmap.name);
5652 route_map_counter_decrement(
5653 bgp_static->rmap.map);
5654 bgp_static->rmap.name =
5655 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5656 bgp_static->rmap.map =
5657 route_map_lookup_by_name(rmap);
5658 route_map_counter_increment(
5659 bgp_static->rmap.map);
5660 }
5661 bgp_dest_set_bgp_static_info(dest, bgp_static);
5662 }
5663
5664 bgp_static->valid = 1;
5665 if (need_update)
5666 bgp_static_withdraw(bgp, &p, afi, safi);
5667
5668 if (!bgp_static->backdoor)
5669 bgp_static_update(bgp, &p, bgp_static, afi, safi);
5670 }
5671
5672 return CMD_SUCCESS;
5673 }
5674
5675 void bgp_static_add(struct bgp *bgp)
5676 {
5677 afi_t afi;
5678 safi_t safi;
5679 struct bgp_dest *dest;
5680 struct bgp_dest *rm;
5681 struct bgp_table *table;
5682 struct bgp_static *bgp_static;
5683
5684 FOREACH_AFI_SAFI (afi, safi)
5685 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
5686 dest = bgp_route_next(dest)) {
5687 if (!bgp_dest_has_bgp_path_info_data(dest))
5688 continue;
5689
5690 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5691 || (safi == SAFI_EVPN)) {
5692 table = bgp_dest_get_bgp_table_info(dest);
5693
5694 for (rm = bgp_table_top(table); rm;
5695 rm = bgp_route_next(rm)) {
5696 bgp_static =
5697 bgp_dest_get_bgp_static_info(
5698 rm);
5699 bgp_static_update_safi(
5700 bgp, bgp_dest_get_prefix(rm),
5701 bgp_static, afi, safi);
5702 }
5703 } else {
5704 bgp_static_update(
5705 bgp, bgp_dest_get_prefix(dest),
5706 bgp_dest_get_bgp_static_info(dest), afi,
5707 safi);
5708 }
5709 }
5710 }
5711
5712 /* Called from bgp_delete(). Delete all static routes from the BGP
5713 instance. */
5714 void bgp_static_delete(struct bgp *bgp)
5715 {
5716 afi_t afi;
5717 safi_t safi;
5718 struct bgp_dest *dest;
5719 struct bgp_dest *rm;
5720 struct bgp_table *table;
5721 struct bgp_static *bgp_static;
5722
5723 FOREACH_AFI_SAFI (afi, safi)
5724 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
5725 dest = bgp_route_next(dest)) {
5726 if (!bgp_dest_has_bgp_path_info_data(dest))
5727 continue;
5728
5729 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5730 || (safi == SAFI_EVPN)) {
5731 table = bgp_dest_get_bgp_table_info(dest);
5732
5733 for (rm = bgp_table_top(table); rm;
5734 rm = bgp_route_next(rm)) {
5735 bgp_static =
5736 bgp_dest_get_bgp_static_info(
5737 rm);
5738 if (!bgp_static)
5739 continue;
5740
5741 bgp_static_withdraw_safi(
5742 bgp, bgp_dest_get_prefix(rm),
5743 AFI_IP, safi,
5744 (struct prefix_rd *)
5745 bgp_dest_get_prefix(
5746 dest));
5747 bgp_static_free(bgp_static);
5748 bgp_dest_set_bgp_static_info(dest,
5749 NULL);
5750 bgp_dest_unlock_node(dest);
5751 }
5752 } else {
5753 bgp_static = bgp_dest_get_bgp_static_info(dest);
5754 bgp_static_withdraw(bgp,
5755 bgp_dest_get_prefix(dest),
5756 afi, safi);
5757 bgp_static_free(bgp_static);
5758 bgp_dest_set_bgp_static_info(dest, NULL);
5759 bgp_dest_unlock_node(dest);
5760 }
5761 }
5762 }
5763
5764 void bgp_static_redo_import_check(struct bgp *bgp)
5765 {
5766 afi_t afi;
5767 safi_t safi;
5768 struct bgp_dest *dest;
5769 struct bgp_dest *rm;
5770 struct bgp_table *table;
5771 struct bgp_static *bgp_static;
5772
5773 /* Use this flag to force reprocessing of the route */
5774 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
5775 FOREACH_AFI_SAFI (afi, safi) {
5776 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
5777 dest = bgp_route_next(dest)) {
5778 if (!bgp_dest_has_bgp_path_info_data(dest))
5779 continue;
5780
5781 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5782 || (safi == SAFI_EVPN)) {
5783 table = bgp_dest_get_bgp_table_info(dest);
5784
5785 for (rm = bgp_table_top(table); rm;
5786 rm = bgp_route_next(rm)) {
5787 bgp_static =
5788 bgp_dest_get_bgp_static_info(
5789 rm);
5790 bgp_static_update_safi(
5791 bgp, bgp_dest_get_prefix(rm),
5792 bgp_static, afi, safi);
5793 }
5794 } else {
5795 bgp_static = bgp_dest_get_bgp_static_info(dest);
5796 bgp_static_update(bgp,
5797 bgp_dest_get_prefix(dest),
5798 bgp_static, afi, safi);
5799 }
5800 }
5801 }
5802 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
5803 }
5804
5805 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
5806 safi_t safi)
5807 {
5808 struct bgp_table *table;
5809 struct bgp_dest *dest;
5810 struct bgp_path_info *pi;
5811
5812 /* Do not install the aggregate route if BGP is in the
5813 * process of termination.
5814 */
5815 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
5816 || (bgp->peer_self == NULL))
5817 return;
5818
5819 table = bgp->rib[afi][safi];
5820 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5821 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5822 if (pi->peer == bgp->peer_self
5823 && ((pi->type == ZEBRA_ROUTE_BGP
5824 && pi->sub_type == BGP_ROUTE_STATIC)
5825 || (pi->type != ZEBRA_ROUTE_BGP
5826 && pi->sub_type
5827 == BGP_ROUTE_REDISTRIBUTE))) {
5828 bgp_aggregate_decrement(
5829 bgp, bgp_dest_get_prefix(dest), pi, afi,
5830 safi);
5831 bgp_unlink_nexthop(pi);
5832 bgp_path_info_delete(dest, pi);
5833 bgp_process(bgp, dest, afi, safi);
5834 }
5835 }
5836 }
5837 }
5838
5839 /*
5840 * Purge all networks and redistributed routes from routing table.
5841 * Invoked upon the instance going down.
5842 */
5843 void bgp_purge_static_redist_routes(struct bgp *bgp)
5844 {
5845 afi_t afi;
5846 safi_t safi;
5847
5848 FOREACH_AFI_SAFI (afi, safi)
5849 bgp_purge_af_static_redist_routes(bgp, afi, safi);
5850 }
5851
5852 /*
5853 * gpz 110624
5854 * Currently this is used to set static routes for VPN and ENCAP.
5855 * I think it can probably be factored with bgp_static_set.
5856 */
5857 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
5858 const char *ip_str, const char *rd_str,
5859 const char *label_str, const char *rmap_str,
5860 int evpn_type, const char *esi, const char *gwip,
5861 const char *ethtag, const char *routermac)
5862 {
5863 VTY_DECLVAR_CONTEXT(bgp, bgp);
5864 int ret;
5865 struct prefix p;
5866 struct prefix_rd prd;
5867 struct bgp_dest *pdest;
5868 struct bgp_dest *dest;
5869 struct bgp_table *table;
5870 struct bgp_static *bgp_static;
5871 mpls_label_t label = MPLS_INVALID_LABEL;
5872 struct prefix gw_ip;
5873
5874 /* validate ip prefix */
5875 ret = str2prefix(ip_str, &p);
5876 if (!ret) {
5877 vty_out(vty, "%% Malformed prefix\n");
5878 return CMD_WARNING_CONFIG_FAILED;
5879 }
5880 apply_mask(&p);
5881 if ((afi == AFI_L2VPN)
5882 && (bgp_build_evpn_prefix(evpn_type,
5883 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5884 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5885 return CMD_WARNING_CONFIG_FAILED;
5886 }
5887
5888 ret = str2prefix_rd(rd_str, &prd);
5889 if (!ret) {
5890 vty_out(vty, "%% Malformed rd\n");
5891 return CMD_WARNING_CONFIG_FAILED;
5892 }
5893
5894 if (label_str) {
5895 unsigned long label_val;
5896 label_val = strtoul(label_str, NULL, 10);
5897 encode_label(label_val, &label);
5898 }
5899
5900 if (safi == SAFI_EVPN) {
5901 if (esi && str2esi(esi, NULL) == 0) {
5902 vty_out(vty, "%% Malformed ESI\n");
5903 return CMD_WARNING_CONFIG_FAILED;
5904 }
5905 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
5906 vty_out(vty, "%% Malformed Router MAC\n");
5907 return CMD_WARNING_CONFIG_FAILED;
5908 }
5909 if (gwip) {
5910 memset(&gw_ip, 0, sizeof(struct prefix));
5911 ret = str2prefix(gwip, &gw_ip);
5912 if (!ret) {
5913 vty_out(vty, "%% Malformed GatewayIp\n");
5914 return CMD_WARNING_CONFIG_FAILED;
5915 }
5916 if ((gw_ip.family == AF_INET
5917 && is_evpn_prefix_ipaddr_v6(
5918 (struct prefix_evpn *)&p))
5919 || (gw_ip.family == AF_INET6
5920 && is_evpn_prefix_ipaddr_v4(
5921 (struct prefix_evpn *)&p))) {
5922 vty_out(vty,
5923 "%% GatewayIp family differs with IP prefix\n");
5924 return CMD_WARNING_CONFIG_FAILED;
5925 }
5926 }
5927 }
5928 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5929 if (!bgp_dest_has_bgp_path_info_data(pdest))
5930 bgp_dest_set_bgp_table_info(pdest,
5931 bgp_table_init(bgp, afi, safi));
5932 table = bgp_dest_get_bgp_table_info(pdest);
5933
5934 dest = bgp_node_get(table, &p);
5935
5936 if (bgp_dest_has_bgp_path_info_data(dest)) {
5937 vty_out(vty, "%% Same network configuration exists\n");
5938 bgp_dest_unlock_node(dest);
5939 } else {
5940 /* New configuration. */
5941 bgp_static = bgp_static_new();
5942 bgp_static->backdoor = 0;
5943 bgp_static->valid = 0;
5944 bgp_static->igpmetric = 0;
5945 bgp_static->igpnexthop.s_addr = INADDR_ANY;
5946 bgp_static->label = label;
5947 bgp_static->prd = prd;
5948
5949 if (rmap_str) {
5950 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5951 route_map_counter_decrement(bgp_static->rmap.map);
5952 bgp_static->rmap.name =
5953 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
5954 bgp_static->rmap.map =
5955 route_map_lookup_by_name(rmap_str);
5956 route_map_counter_increment(bgp_static->rmap.map);
5957 }
5958
5959 if (safi == SAFI_EVPN) {
5960 if (esi) {
5961 bgp_static->eth_s_id =
5962 XCALLOC(MTYPE_ATTR,
5963 sizeof(esi_t));
5964 str2esi(esi, bgp_static->eth_s_id);
5965 }
5966 if (routermac) {
5967 bgp_static->router_mac =
5968 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
5969 (void)prefix_str2mac(routermac,
5970 bgp_static->router_mac);
5971 }
5972 if (gwip)
5973 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
5974 }
5975 bgp_dest_set_bgp_static_info(dest, bgp_static);
5976
5977 bgp_static->valid = 1;
5978 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
5979 }
5980
5981 return CMD_SUCCESS;
5982 }
5983
5984 /* Configure static BGP network. */
5985 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
5986 const char *ip_str, const char *rd_str,
5987 const char *label_str, int evpn_type, const char *esi,
5988 const char *gwip, const char *ethtag)
5989 {
5990 VTY_DECLVAR_CONTEXT(bgp, bgp);
5991 int ret;
5992 struct prefix p;
5993 struct prefix_rd prd;
5994 struct bgp_dest *pdest;
5995 struct bgp_dest *dest;
5996 struct bgp_table *table;
5997 struct bgp_static *bgp_static;
5998 mpls_label_t label = MPLS_INVALID_LABEL;
5999
6000 /* Convert IP prefix string to struct prefix. */
6001 ret = str2prefix(ip_str, &p);
6002 if (!ret) {
6003 vty_out(vty, "%% Malformed prefix\n");
6004 return CMD_WARNING_CONFIG_FAILED;
6005 }
6006 apply_mask(&p);
6007 if ((afi == AFI_L2VPN)
6008 && (bgp_build_evpn_prefix(evpn_type,
6009 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6010 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6011 return CMD_WARNING_CONFIG_FAILED;
6012 }
6013 ret = str2prefix_rd(rd_str, &prd);
6014 if (!ret) {
6015 vty_out(vty, "%% Malformed rd\n");
6016 return CMD_WARNING_CONFIG_FAILED;
6017 }
6018
6019 if (label_str) {
6020 unsigned long label_val;
6021 label_val = strtoul(label_str, NULL, 10);
6022 encode_label(label_val, &label);
6023 }
6024
6025 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6026 if (!bgp_dest_has_bgp_path_info_data(pdest))
6027 bgp_dest_set_bgp_table_info(pdest,
6028 bgp_table_init(bgp, afi, safi));
6029 else
6030 bgp_dest_unlock_node(pdest);
6031 table = bgp_dest_get_bgp_table_info(pdest);
6032
6033 dest = bgp_node_lookup(table, &p);
6034
6035 if (dest) {
6036 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
6037
6038 bgp_static = bgp_dest_get_bgp_static_info(dest);
6039 bgp_static_free(bgp_static);
6040 bgp_dest_set_bgp_static_info(dest, NULL);
6041 bgp_dest_unlock_node(dest);
6042 bgp_dest_unlock_node(dest);
6043 } else
6044 vty_out(vty, "%% Can't find the route\n");
6045
6046 return CMD_SUCCESS;
6047 }
6048
6049 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
6050 const char *rmap_name)
6051 {
6052 VTY_DECLVAR_CONTEXT(bgp, bgp);
6053 struct bgp_rmap *rmap;
6054
6055 rmap = &bgp->table_map[afi][safi];
6056 if (rmap_name) {
6057 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6058 route_map_counter_decrement(rmap->map);
6059 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
6060 rmap->map = route_map_lookup_by_name(rmap_name);
6061 route_map_counter_increment(rmap->map);
6062 } else {
6063 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6064 route_map_counter_decrement(rmap->map);
6065 rmap->map = NULL;
6066 }
6067
6068 if (bgp_fibupd_safi(safi))
6069 bgp_zebra_announce_table(bgp, afi, safi);
6070
6071 return CMD_SUCCESS;
6072 }
6073
6074 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
6075 const char *rmap_name)
6076 {
6077 VTY_DECLVAR_CONTEXT(bgp, bgp);
6078 struct bgp_rmap *rmap;
6079
6080 rmap = &bgp->table_map[afi][safi];
6081 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6082 route_map_counter_decrement(rmap->map);
6083 rmap->map = NULL;
6084
6085 if (bgp_fibupd_safi(safi))
6086 bgp_zebra_announce_table(bgp, afi, safi);
6087
6088 return CMD_SUCCESS;
6089 }
6090
6091 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
6092 safi_t safi)
6093 {
6094 if (bgp->table_map[afi][safi].name) {
6095 vty_out(vty, " table-map %s\n",
6096 bgp->table_map[afi][safi].name);
6097 }
6098 }
6099
6100 DEFUN (bgp_table_map,
6101 bgp_table_map_cmd,
6102 "table-map WORD",
6103 "BGP table to RIB route download filter\n"
6104 "Name of the route map\n")
6105 {
6106 int idx_word = 1;
6107 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6108 argv[idx_word]->arg);
6109 }
6110 DEFUN (no_bgp_table_map,
6111 no_bgp_table_map_cmd,
6112 "no table-map WORD",
6113 NO_STR
6114 "BGP table to RIB route download filter\n"
6115 "Name of the route map\n")
6116 {
6117 int idx_word = 2;
6118 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6119 argv[idx_word]->arg);
6120 }
6121
6122 DEFPY(bgp_network,
6123 bgp_network_cmd,
6124 "[no] network \
6125 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
6126 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
6127 backdoor$backdoor}]",
6128 NO_STR
6129 "Specify a network to announce via BGP\n"
6130 "IPv4 prefix\n"
6131 "Network number\n"
6132 "Network mask\n"
6133 "Network mask\n"
6134 "Route-map to modify the attributes\n"
6135 "Name of the route map\n"
6136 "Label index to associate with the prefix\n"
6137 "Label index value\n"
6138 "Specify a BGP backdoor route\n")
6139 {
6140 char addr_prefix_str[BUFSIZ];
6141
6142 if (address_str) {
6143 int ret;
6144
6145 ret = netmask_str2prefix_str(address_str, netmask_str,
6146 addr_prefix_str);
6147 if (!ret) {
6148 vty_out(vty, "%% Inconsistent address and mask\n");
6149 return CMD_WARNING_CONFIG_FAILED;
6150 }
6151 }
6152
6153 return bgp_static_set(
6154 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
6155 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
6156 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
6157 }
6158
6159 DEFPY(ipv6_bgp_network,
6160 ipv6_bgp_network_cmd,
6161 "[no] network X:X::X:X/M$prefix \
6162 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
6163 NO_STR
6164 "Specify a network to announce via BGP\n"
6165 "IPv6 prefix\n"
6166 "Route-map to modify the attributes\n"
6167 "Name of the route map\n"
6168 "Label index to associate with the prefix\n"
6169 "Label index value\n")
6170 {
6171 return bgp_static_set(
6172 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
6173 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
6174 }
6175
6176 static struct bgp_aggregate *bgp_aggregate_new(void)
6177 {
6178 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
6179 }
6180
6181 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
6182 {
6183 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
6184 route_map_counter_decrement(aggregate->rmap.map);
6185 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
6186 }
6187
6188 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
6189 struct aspath *aspath,
6190 struct community *comm,
6191 struct ecommunity *ecomm,
6192 struct lcommunity *lcomm)
6193 {
6194 static struct aspath *ae = NULL;
6195
6196 if (!ae)
6197 ae = aspath_empty();
6198
6199 if (!pi)
6200 return false;
6201
6202 if (origin != pi->attr->origin)
6203 return false;
6204
6205 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
6206 return false;
6207
6208 if (!community_cmp(pi->attr->community, comm))
6209 return false;
6210
6211 if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
6212 return false;
6213
6214 if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
6215 return false;
6216
6217 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
6218 return false;
6219
6220 return true;
6221 }
6222
6223 static void bgp_aggregate_install(
6224 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
6225 uint8_t origin, struct aspath *aspath, struct community *community,
6226 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
6227 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
6228 {
6229 struct bgp_dest *dest;
6230 struct bgp_table *table;
6231 struct bgp_path_info *pi, *orig, *new;
6232 struct attr *attr;
6233
6234 table = bgp->rib[afi][safi];
6235
6236 dest = bgp_node_get(table, p);
6237
6238 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6239 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6240 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6241 break;
6242
6243 if (aggregate->count > 0) {
6244 /*
6245 * If the aggregate information has not changed
6246 * no need to re-install it again.
6247 */
6248 if (bgp_aggregate_info_same(orig, origin, aspath, community,
6249 ecommunity, lcommunity)) {
6250 bgp_dest_unlock_node(dest);
6251
6252 if (aspath)
6253 aspath_free(aspath);
6254 if (community)
6255 community_free(&community);
6256 if (ecommunity)
6257 ecommunity_free(&ecommunity);
6258 if (lcommunity)
6259 lcommunity_free(&lcommunity);
6260
6261 return;
6262 }
6263
6264 /*
6265 * Mark the old as unusable
6266 */
6267 if (pi)
6268 bgp_path_info_delete(dest, pi);
6269
6270 attr = bgp_attr_aggregate_intern(
6271 bgp, origin, aspath, community, ecommunity, lcommunity,
6272 aggregate, atomic_aggregate, p);
6273
6274 if (!attr) {
6275 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
6276 return;
6277 }
6278
6279 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
6280 bgp->peer_self, attr, dest);
6281
6282 SET_FLAG(new->flags, BGP_PATH_VALID);
6283
6284 bgp_path_info_add(dest, new);
6285 bgp_process(bgp, dest, afi, safi);
6286 } else {
6287 for (pi = orig; pi; pi = pi->next)
6288 if (pi->peer == bgp->peer_self
6289 && pi->type == ZEBRA_ROUTE_BGP
6290 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6291 break;
6292
6293 /* Withdraw static BGP route from routing table. */
6294 if (pi) {
6295 bgp_path_info_delete(dest, pi);
6296 bgp_process(bgp, dest, afi, safi);
6297 }
6298 }
6299
6300 bgp_dest_unlock_node(dest);
6301 }
6302
6303 /* Update an aggregate as routes are added/removed from the BGP table */
6304 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
6305 safi_t safi, struct bgp_aggregate *aggregate)
6306 {
6307 struct bgp_table *table;
6308 struct bgp_dest *top;
6309 struct bgp_dest *dest;
6310 uint8_t origin;
6311 struct aspath *aspath = NULL;
6312 struct community *community = NULL;
6313 struct ecommunity *ecommunity = NULL;
6314 struct lcommunity *lcommunity = NULL;
6315 struct bgp_path_info *pi;
6316 unsigned long match = 0;
6317 uint8_t atomic_aggregate = 0;
6318
6319 /* If the bgp instance is being deleted or self peer is deleted
6320 * then do not create aggregate route
6321 */
6322 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6323 || (bgp->peer_self == NULL))
6324 return;
6325
6326 /* ORIGIN attribute: If at least one route among routes that are
6327 aggregated has ORIGIN with the value INCOMPLETE, then the
6328 aggregated route must have the ORIGIN attribute with the value
6329 INCOMPLETE. Otherwise, if at least one route among routes that
6330 are aggregated has ORIGIN with the value EGP, then the aggregated
6331 route must have the origin attribute with the value EGP. In all
6332 other case the value of the ORIGIN attribute of the aggregated
6333 route is INTERNAL. */
6334 origin = BGP_ORIGIN_IGP;
6335
6336 table = bgp->rib[afi][safi];
6337
6338 top = bgp_node_get(table, p);
6339 for (dest = bgp_node_get(table, p); dest;
6340 dest = bgp_route_next_until(dest, top)) {
6341 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
6342
6343 if (dest_p->prefixlen <= p->prefixlen)
6344 continue;
6345
6346 match = 0;
6347
6348 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6349 if (BGP_PATH_HOLDDOWN(pi))
6350 continue;
6351
6352 if (pi->attr->flag
6353 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
6354 atomic_aggregate = 1;
6355
6356 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6357 continue;
6358
6359 /*
6360 * summary-only aggregate route suppress
6361 * aggregated route announcements.
6362 */
6363 if (aggregate->summary_only) {
6364 (bgp_path_info_extra_get(pi))->suppress++;
6365 bgp_path_info_set_flag(dest, pi,
6366 BGP_PATH_ATTR_CHANGED);
6367 match++;
6368 }
6369
6370 aggregate->count++;
6371
6372 /*
6373 * If at least one route among routes that are
6374 * aggregated has ORIGIN with the value INCOMPLETE,
6375 * then the aggregated route MUST have the ORIGIN
6376 * attribute with the value INCOMPLETE. Otherwise, if
6377 * at least one route among routes that are aggregated
6378 * has ORIGIN with the value EGP, then the aggregated
6379 * route MUST have the ORIGIN attribute with the value
6380 * EGP.
6381 */
6382 switch (pi->attr->origin) {
6383 case BGP_ORIGIN_INCOMPLETE:
6384 aggregate->incomplete_origin_count++;
6385 break;
6386 case BGP_ORIGIN_EGP:
6387 aggregate->egp_origin_count++;
6388 break;
6389 default:
6390 /*Do nothing.
6391 */
6392 break;
6393 }
6394
6395 if (!aggregate->as_set)
6396 continue;
6397
6398 /*
6399 * as-set aggregate route generate origin, as path,
6400 * and community aggregation.
6401 */
6402 /* Compute aggregate route's as-path.
6403 */
6404 bgp_compute_aggregate_aspath_hash(aggregate,
6405 pi->attr->aspath);
6406
6407 /* Compute aggregate route's community.
6408 */
6409 if (pi->attr->community)
6410 bgp_compute_aggregate_community_hash(
6411 aggregate,
6412 pi->attr->community);
6413
6414 /* Compute aggregate route's extended community.
6415 */
6416 if (pi->attr->ecommunity)
6417 bgp_compute_aggregate_ecommunity_hash(
6418 aggregate,
6419 pi->attr->ecommunity);
6420
6421 /* Compute aggregate route's large community.
6422 */
6423 if (pi->attr->lcommunity)
6424 bgp_compute_aggregate_lcommunity_hash(
6425 aggregate,
6426 pi->attr->lcommunity);
6427 }
6428 if (match)
6429 bgp_process(bgp, dest, afi, safi);
6430 }
6431 if (aggregate->as_set) {
6432 bgp_compute_aggregate_aspath_val(aggregate);
6433 bgp_compute_aggregate_community_val(aggregate);
6434 bgp_compute_aggregate_ecommunity_val(aggregate);
6435 bgp_compute_aggregate_lcommunity_val(aggregate);
6436 }
6437
6438
6439 bgp_dest_unlock_node(top);
6440
6441
6442 if (aggregate->incomplete_origin_count > 0)
6443 origin = BGP_ORIGIN_INCOMPLETE;
6444 else if (aggregate->egp_origin_count > 0)
6445 origin = BGP_ORIGIN_EGP;
6446
6447 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
6448 origin = aggregate->origin;
6449
6450 if (aggregate->as_set) {
6451 if (aggregate->aspath)
6452 /* Retrieve aggregate route's as-path.
6453 */
6454 aspath = aspath_dup(aggregate->aspath);
6455
6456 if (aggregate->community)
6457 /* Retrieve aggregate route's community.
6458 */
6459 community = community_dup(aggregate->community);
6460
6461 if (aggregate->ecommunity)
6462 /* Retrieve aggregate route's ecommunity.
6463 */
6464 ecommunity = ecommunity_dup(aggregate->ecommunity);
6465
6466 if (aggregate->lcommunity)
6467 /* Retrieve aggregate route's lcommunity.
6468 */
6469 lcommunity = lcommunity_dup(aggregate->lcommunity);
6470 }
6471
6472 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
6473 ecommunity, lcommunity, atomic_aggregate,
6474 aggregate);
6475 }
6476
6477 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
6478 safi_t safi, struct bgp_aggregate *aggregate)
6479 {
6480 struct bgp_table *table;
6481 struct bgp_dest *top;
6482 struct bgp_dest *dest;
6483 struct bgp_path_info *pi;
6484 unsigned long match;
6485
6486 table = bgp->rib[afi][safi];
6487
6488 /* If routes exists below this node, generate aggregate routes. */
6489 top = bgp_node_get(table, p);
6490 for (dest = bgp_node_get(table, p); dest;
6491 dest = bgp_route_next_until(dest, top)) {
6492 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
6493
6494 if (dest_p->prefixlen <= p->prefixlen)
6495 continue;
6496 match = 0;
6497
6498 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6499 if (BGP_PATH_HOLDDOWN(pi))
6500 continue;
6501
6502 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6503 continue;
6504
6505 if (aggregate->summary_only && pi->extra) {
6506 pi->extra->suppress--;
6507
6508 if (pi->extra->suppress == 0) {
6509 bgp_path_info_set_flag(
6510 dest, pi,
6511 BGP_PATH_ATTR_CHANGED);
6512 match++;
6513 }
6514 }
6515 aggregate->count--;
6516
6517 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
6518 aggregate->incomplete_origin_count--;
6519 else if (pi->attr->origin == BGP_ORIGIN_EGP)
6520 aggregate->egp_origin_count--;
6521
6522 if (aggregate->as_set) {
6523 /* Remove as-path from aggregate.
6524 */
6525 bgp_remove_aspath_from_aggregate_hash(
6526 aggregate,
6527 pi->attr->aspath);
6528
6529 if (pi->attr->community)
6530 /* Remove community from aggregate.
6531 */
6532 bgp_remove_comm_from_aggregate_hash(
6533 aggregate,
6534 pi->attr->community);
6535
6536 if (pi->attr->ecommunity)
6537 /* Remove ecommunity from aggregate.
6538 */
6539 bgp_remove_ecomm_from_aggregate_hash(
6540 aggregate,
6541 pi->attr->ecommunity);
6542
6543 if (pi->attr->lcommunity)
6544 /* Remove lcommunity from aggregate.
6545 */
6546 bgp_remove_lcomm_from_aggregate_hash(
6547 aggregate,
6548 pi->attr->lcommunity);
6549 }
6550 }
6551
6552 /* If this node was suppressed, process the change. */
6553 if (match)
6554 bgp_process(bgp, dest, afi, safi);
6555 }
6556 if (aggregate->as_set) {
6557 aspath_free(aggregate->aspath);
6558 aggregate->aspath = NULL;
6559 if (aggregate->community)
6560 community_free(&aggregate->community);
6561 if (aggregate->ecommunity)
6562 ecommunity_free(&aggregate->ecommunity);
6563 if (aggregate->lcommunity)
6564 lcommunity_free(&aggregate->lcommunity);
6565 }
6566
6567 bgp_dest_unlock_node(top);
6568 }
6569
6570 static void bgp_add_route_to_aggregate(struct bgp *bgp,
6571 const struct prefix *aggr_p,
6572 struct bgp_path_info *pinew, afi_t afi,
6573 safi_t safi,
6574 struct bgp_aggregate *aggregate)
6575 {
6576 uint8_t origin;
6577 struct aspath *aspath = NULL;
6578 uint8_t atomic_aggregate = 0;
6579 struct community *community = NULL;
6580 struct ecommunity *ecommunity = NULL;
6581 struct lcommunity *lcommunity = NULL;
6582
6583 /* ORIGIN attribute: If at least one route among routes that are
6584 * aggregated has ORIGIN with the value INCOMPLETE, then the
6585 * aggregated route must have the ORIGIN attribute with the value
6586 * INCOMPLETE. Otherwise, if at least one route among routes that
6587 * are aggregated has ORIGIN with the value EGP, then the aggregated
6588 * route must have the origin attribute with the value EGP. In all
6589 * other case the value of the ORIGIN attribute of the aggregated
6590 * route is INTERNAL.
6591 */
6592 origin = BGP_ORIGIN_IGP;
6593
6594 aggregate->count++;
6595
6596 if (aggregate->summary_only)
6597 (bgp_path_info_extra_get(pinew))->suppress++;
6598
6599 switch (pinew->attr->origin) {
6600 case BGP_ORIGIN_INCOMPLETE:
6601 aggregate->incomplete_origin_count++;
6602 break;
6603 case BGP_ORIGIN_EGP:
6604 aggregate->egp_origin_count++;
6605 break;
6606 default:
6607 /* Do nothing.
6608 */
6609 break;
6610 }
6611
6612 if (aggregate->incomplete_origin_count > 0)
6613 origin = BGP_ORIGIN_INCOMPLETE;
6614 else if (aggregate->egp_origin_count > 0)
6615 origin = BGP_ORIGIN_EGP;
6616
6617 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
6618 origin = aggregate->origin;
6619
6620 if (aggregate->as_set) {
6621 /* Compute aggregate route's as-path.
6622 */
6623 bgp_compute_aggregate_aspath(aggregate,
6624 pinew->attr->aspath);
6625
6626 /* Compute aggregate route's community.
6627 */
6628 if (pinew->attr->community)
6629 bgp_compute_aggregate_community(
6630 aggregate,
6631 pinew->attr->community);
6632
6633 /* Compute aggregate route's extended community.
6634 */
6635 if (pinew->attr->ecommunity)
6636 bgp_compute_aggregate_ecommunity(
6637 aggregate,
6638 pinew->attr->ecommunity);
6639
6640 /* Compute aggregate route's large community.
6641 */
6642 if (pinew->attr->lcommunity)
6643 bgp_compute_aggregate_lcommunity(
6644 aggregate,
6645 pinew->attr->lcommunity);
6646
6647 /* Retrieve aggregate route's as-path.
6648 */
6649 if (aggregate->aspath)
6650 aspath = aspath_dup(aggregate->aspath);
6651
6652 /* Retrieve aggregate route's community.
6653 */
6654 if (aggregate->community)
6655 community = community_dup(aggregate->community);
6656
6657 /* Retrieve aggregate route's ecommunity.
6658 */
6659 if (aggregate->ecommunity)
6660 ecommunity = ecommunity_dup(aggregate->ecommunity);
6661
6662 /* Retrieve aggregate route's lcommunity.
6663 */
6664 if (aggregate->lcommunity)
6665 lcommunity = lcommunity_dup(aggregate->lcommunity);
6666 }
6667
6668 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
6669 aspath, community, ecommunity,
6670 lcommunity, atomic_aggregate, aggregate);
6671 }
6672
6673 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
6674 safi_t safi,
6675 struct bgp_path_info *pi,
6676 struct bgp_aggregate *aggregate,
6677 const struct prefix *aggr_p)
6678 {
6679 uint8_t origin;
6680 struct aspath *aspath = NULL;
6681 uint8_t atomic_aggregate = 0;
6682 struct community *community = NULL;
6683 struct ecommunity *ecommunity = NULL;
6684 struct lcommunity *lcommunity = NULL;
6685 unsigned long match = 0;
6686
6687 if (BGP_PATH_HOLDDOWN(pi))
6688 return;
6689
6690 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6691 return;
6692
6693 if (aggregate->summary_only
6694 && pi->extra
6695 && pi->extra->suppress > 0) {
6696 pi->extra->suppress--;
6697
6698 if (pi->extra->suppress == 0) {
6699 bgp_path_info_set_flag(pi->net, pi,
6700 BGP_PATH_ATTR_CHANGED);
6701 match++;
6702 }
6703 }
6704
6705 if (aggregate->count > 0)
6706 aggregate->count--;
6707
6708 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
6709 aggregate->incomplete_origin_count--;
6710 else if (pi->attr->origin == BGP_ORIGIN_EGP)
6711 aggregate->egp_origin_count--;
6712
6713 if (aggregate->as_set) {
6714 /* Remove as-path from aggregate.
6715 */
6716 bgp_remove_aspath_from_aggregate(aggregate,
6717 pi->attr->aspath);
6718
6719 if (pi->attr->community)
6720 /* Remove community from aggregate.
6721 */
6722 bgp_remove_community_from_aggregate(
6723 aggregate,
6724 pi->attr->community);
6725
6726 if (pi->attr->ecommunity)
6727 /* Remove ecommunity from aggregate.
6728 */
6729 bgp_remove_ecommunity_from_aggregate(
6730 aggregate,
6731 pi->attr->ecommunity);
6732
6733 if (pi->attr->lcommunity)
6734 /* Remove lcommunity from aggregate.
6735 */
6736 bgp_remove_lcommunity_from_aggregate(
6737 aggregate,
6738 pi->attr->lcommunity);
6739 }
6740
6741 /* If this node was suppressed, process the change. */
6742 if (match)
6743 bgp_process(bgp, pi->net, afi, safi);
6744
6745 origin = BGP_ORIGIN_IGP;
6746 if (aggregate->incomplete_origin_count > 0)
6747 origin = BGP_ORIGIN_INCOMPLETE;
6748 else if (aggregate->egp_origin_count > 0)
6749 origin = BGP_ORIGIN_EGP;
6750
6751 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
6752 origin = aggregate->origin;
6753
6754 if (aggregate->as_set) {
6755 /* Retrieve aggregate route's as-path.
6756 */
6757 if (aggregate->aspath)
6758 aspath = aspath_dup(aggregate->aspath);
6759
6760 /* Retrieve aggregate route's community.
6761 */
6762 if (aggregate->community)
6763 community = community_dup(aggregate->community);
6764
6765 /* Retrieve aggregate route's ecommunity.
6766 */
6767 if (aggregate->ecommunity)
6768 ecommunity = ecommunity_dup(aggregate->ecommunity);
6769
6770 /* Retrieve aggregate route's lcommunity.
6771 */
6772 if (aggregate->lcommunity)
6773 lcommunity = lcommunity_dup(aggregate->lcommunity);
6774 }
6775
6776 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
6777 aspath, community, ecommunity,
6778 lcommunity, atomic_aggregate, aggregate);
6779 }
6780
6781 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
6782 struct bgp_path_info *pi, afi_t afi, safi_t safi)
6783 {
6784 struct bgp_dest *child;
6785 struct bgp_dest *dest;
6786 struct bgp_aggregate *aggregate;
6787 struct bgp_table *table;
6788
6789 table = bgp->aggregate[afi][safi];
6790
6791 /* No aggregates configured. */
6792 if (bgp_table_top_nolock(table) == NULL)
6793 return;
6794
6795 if (p->prefixlen == 0)
6796 return;
6797
6798 if (BGP_PATH_HOLDDOWN(pi))
6799 return;
6800
6801 child = bgp_node_get(table, p);
6802
6803 /* Aggregate address configuration check. */
6804 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
6805 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
6806
6807 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
6808 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
6809 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
6810 aggregate);
6811 }
6812 }
6813 bgp_dest_unlock_node(child);
6814 }
6815
6816 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
6817 struct bgp_path_info *del, afi_t afi, safi_t safi)
6818 {
6819 struct bgp_dest *child;
6820 struct bgp_dest *dest;
6821 struct bgp_aggregate *aggregate;
6822 struct bgp_table *table;
6823
6824 table = bgp->aggregate[afi][safi];
6825
6826 /* No aggregates configured. */
6827 if (bgp_table_top_nolock(table) == NULL)
6828 return;
6829
6830 if (p->prefixlen == 0)
6831 return;
6832
6833 child = bgp_node_get(table, p);
6834
6835 /* Aggregate address configuration check. */
6836 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
6837 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
6838
6839 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
6840 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
6841 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
6842 aggregate, dest_p);
6843 }
6844 }
6845 bgp_dest_unlock_node(child);
6846 }
6847
6848 /* Aggregate route attribute. */
6849 #define AGGREGATE_SUMMARY_ONLY 1
6850 #define AGGREGATE_AS_SET 1
6851 #define AGGREGATE_AS_UNSET 0
6852
6853 static const char *bgp_origin2str(uint8_t origin)
6854 {
6855 switch (origin) {
6856 case BGP_ORIGIN_IGP:
6857 return "igp";
6858 case BGP_ORIGIN_EGP:
6859 return "egp";
6860 case BGP_ORIGIN_INCOMPLETE:
6861 return "incomplete";
6862 }
6863 return "n/a";
6864 }
6865
6866 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
6867 afi_t afi, safi_t safi)
6868 {
6869 VTY_DECLVAR_CONTEXT(bgp, bgp);
6870 int ret;
6871 struct prefix p;
6872 struct bgp_dest *dest;
6873 struct bgp_aggregate *aggregate;
6874
6875 /* Convert string to prefix structure. */
6876 ret = str2prefix(prefix_str, &p);
6877 if (!ret) {
6878 vty_out(vty, "Malformed prefix\n");
6879 return CMD_WARNING_CONFIG_FAILED;
6880 }
6881 apply_mask(&p);
6882
6883 /* Old configuration check. */
6884 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
6885 if (!dest) {
6886 vty_out(vty,
6887 "%% There is no aggregate-address configuration.\n");
6888 return CMD_WARNING_CONFIG_FAILED;
6889 }
6890
6891 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
6892 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
6893 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
6894 NULL, NULL, 0, aggregate);
6895
6896 /* Unlock aggregate address configuration. */
6897 bgp_dest_set_bgp_aggregate_info(dest, NULL);
6898
6899 if (aggregate->community)
6900 community_free(&aggregate->community);
6901
6902 if (aggregate->community_hash) {
6903 /* Delete all communities in the hash.
6904 */
6905 hash_clean(aggregate->community_hash,
6906 bgp_aggr_community_remove);
6907 /* Free up the community_hash.
6908 */
6909 hash_free(aggregate->community_hash);
6910 }
6911
6912 if (aggregate->ecommunity)
6913 ecommunity_free(&aggregate->ecommunity);
6914
6915 if (aggregate->ecommunity_hash) {
6916 /* Delete all ecommunities in the hash.
6917 */
6918 hash_clean(aggregate->ecommunity_hash,
6919 bgp_aggr_ecommunity_remove);
6920 /* Free up the ecommunity_hash.
6921 */
6922 hash_free(aggregate->ecommunity_hash);
6923 }
6924
6925 if (aggregate->lcommunity)
6926 lcommunity_free(&aggregate->lcommunity);
6927
6928 if (aggregate->lcommunity_hash) {
6929 /* Delete all lcommunities in the hash.
6930 */
6931 hash_clean(aggregate->lcommunity_hash,
6932 bgp_aggr_lcommunity_remove);
6933 /* Free up the lcommunity_hash.
6934 */
6935 hash_free(aggregate->lcommunity_hash);
6936 }
6937
6938 if (aggregate->aspath)
6939 aspath_free(aggregate->aspath);
6940
6941 if (aggregate->aspath_hash) {
6942 /* Delete all as-paths in the hash.
6943 */
6944 hash_clean(aggregate->aspath_hash,
6945 bgp_aggr_aspath_remove);
6946 /* Free up the aspath_hash.
6947 */
6948 hash_free(aggregate->aspath_hash);
6949 }
6950
6951 bgp_aggregate_free(aggregate);
6952 bgp_dest_unlock_node(dest);
6953 bgp_dest_unlock_node(dest);
6954
6955 return CMD_SUCCESS;
6956 }
6957
6958 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
6959 safi_t safi, const char *rmap,
6960 uint8_t summary_only, uint8_t as_set,
6961 uint8_t origin)
6962 {
6963 VTY_DECLVAR_CONTEXT(bgp, bgp);
6964 int ret;
6965 struct prefix p;
6966 struct bgp_dest *dest;
6967 struct bgp_aggregate *aggregate;
6968 uint8_t as_set_new = as_set;
6969
6970 /* Convert string to prefix structure. */
6971 ret = str2prefix(prefix_str, &p);
6972 if (!ret) {
6973 vty_out(vty, "Malformed prefix\n");
6974 return CMD_WARNING_CONFIG_FAILED;
6975 }
6976 apply_mask(&p);
6977
6978 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
6979 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
6980 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
6981 prefix_str);
6982 return CMD_WARNING_CONFIG_FAILED;
6983 }
6984
6985 /* Old configuration check. */
6986 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
6987 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
6988
6989 if (aggregate) {
6990 vty_out(vty, "There is already same aggregate network.\n");
6991 /* try to remove the old entry */
6992 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
6993 if (ret) {
6994 vty_out(vty, "Error deleting aggregate.\n");
6995 bgp_dest_unlock_node(dest);
6996 return CMD_WARNING_CONFIG_FAILED;
6997 }
6998 }
6999
7000 /* Make aggregate address structure. */
7001 aggregate = bgp_aggregate_new();
7002 aggregate->summary_only = summary_only;
7003
7004 /* Network operators MUST NOT locally generate any new
7005 * announcements containing AS_SET or AS_CONFED_SET. If they have
7006 * announced routes with AS_SET or AS_CONFED_SET in them, then they
7007 * SHOULD withdraw those routes and re-announce routes for the
7008 * aggregate or component prefixes (i.e., the more-specific routes
7009 * subsumed by the previously aggregated route) without AS_SET
7010 * or AS_CONFED_SET in the updates.
7011 */
7012 if (bgp->reject_as_sets) {
7013 if (as_set == AGGREGATE_AS_SET) {
7014 as_set_new = AGGREGATE_AS_UNSET;
7015 zlog_warn(
7016 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
7017 __func__);
7018 vty_out(vty,
7019 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
7020 }
7021 }
7022
7023 aggregate->as_set = as_set_new;
7024 aggregate->safi = safi;
7025 /* Override ORIGIN attribute if defined.
7026 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
7027 * to IGP which is not what rfc4271 says.
7028 * This enables the same behavior, optionally.
7029 */
7030 aggregate->origin = origin;
7031
7032 if (rmap) {
7033 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7034 route_map_counter_decrement(aggregate->rmap.map);
7035 aggregate->rmap.name =
7036 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
7037 aggregate->rmap.map = route_map_lookup_by_name(rmap);
7038 route_map_counter_increment(aggregate->rmap.map);
7039 }
7040 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
7041
7042 /* Aggregate address insert into BGP routing table. */
7043 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
7044
7045 return CMD_SUCCESS;
7046 }
7047
7048 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
7049 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> {"
7050 "as-set$as_set_s"
7051 "|summary-only$summary_only"
7052 "|route-map WORD$rmap_name"
7053 "|origin <egp|igp|incomplete>$origin_s"
7054 "}",
7055 NO_STR
7056 "Configure BGP aggregate entries\n"
7057 "Aggregate prefix\n" "Aggregate address\n" "Aggregate mask\n"
7058 "Generate AS set path information\n"
7059 "Filter more specific routes from updates\n"
7060 "Apply route map to aggregate network\n"
7061 "Route map name\n"
7062 "BGP origin code\n"
7063 "Remote EGP\n"
7064 "Local IGP\n"
7065 "Unknown heritage\n")
7066 {
7067 const char *prefix_s = NULL;
7068 safi_t safi = bgp_node_safi(vty);
7069 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
7070 int as_set = AGGREGATE_AS_UNSET;
7071 char prefix_buf[PREFIX2STR_BUFFER];
7072
7073 if (addr_str) {
7074 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf)
7075 == 0) {
7076 vty_out(vty, "%% Inconsistent address and mask\n");
7077 return CMD_WARNING_CONFIG_FAILED;
7078 }
7079 prefix_s = prefix_buf;
7080 } else
7081 prefix_s = prefix_str;
7082
7083 if (origin_s) {
7084 if (strcmp(origin_s, "egp") == 0)
7085 origin = BGP_ORIGIN_EGP;
7086 else if (strcmp(origin_s, "igp") == 0)
7087 origin = BGP_ORIGIN_IGP;
7088 else if (strcmp(origin_s, "incomplete") == 0)
7089 origin = BGP_ORIGIN_INCOMPLETE;
7090 }
7091
7092 if (as_set_s)
7093 as_set = AGGREGATE_AS_SET;
7094
7095 /* Handle configuration removal, otherwise installation. */
7096 if (no)
7097 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
7098
7099 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
7100 summary_only != NULL, as_set, origin);
7101 }
7102
7103 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
7104 "[no] aggregate-address X:X::X:X/M$prefix {"
7105 "as-set$as_set_s"
7106 "|summary-only$summary_only"
7107 "|route-map WORD$rmap_name"
7108 "|origin <egp|igp|incomplete>$origin_s"
7109 "}",
7110 NO_STR
7111 "Configure BGP aggregate entries\n"
7112 "Aggregate prefix\n"
7113 "Generate AS set path information\n"
7114 "Filter more specific routes from updates\n"
7115 "Apply route map to aggregate network\n"
7116 "Route map name\n"
7117 "BGP origin code\n"
7118 "Remote EGP\n"
7119 "Local IGP\n"
7120 "Unknown heritage\n")
7121 {
7122 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
7123 int as_set = AGGREGATE_AS_UNSET;
7124
7125 if (origin_s) {
7126 if (strcmp(origin_s, "egp") == 0)
7127 origin = BGP_ORIGIN_EGP;
7128 else if (strcmp(origin_s, "igp") == 0)
7129 origin = BGP_ORIGIN_IGP;
7130 else if (strcmp(origin_s, "incomplete") == 0)
7131 origin = BGP_ORIGIN_INCOMPLETE;
7132 }
7133
7134 if (as_set_s)
7135 as_set = AGGREGATE_AS_SET;
7136
7137 /* Handle configuration removal, otherwise installation. */
7138 if (no)
7139 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
7140 SAFI_UNICAST);
7141
7142 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
7143 rmap_name, summary_only != NULL, as_set,
7144 origin);
7145 }
7146
7147 /* Redistribute route treatment. */
7148 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
7149 const union g_addr *nexthop, ifindex_t ifindex,
7150 enum nexthop_types_t nhtype, uint32_t metric,
7151 uint8_t type, unsigned short instance,
7152 route_tag_t tag)
7153 {
7154 struct bgp_path_info *new;
7155 struct bgp_path_info *bpi;
7156 struct bgp_path_info rmap_path;
7157 struct bgp_dest *bn;
7158 struct attr attr;
7159 struct attr *new_attr;
7160 afi_t afi;
7161 route_map_result_t ret;
7162 struct bgp_redist *red;
7163
7164 /* Make default attribute. */
7165 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
7166 /*
7167 * This must not be NULL to satisfy Coverity SA
7168 */
7169 assert(attr.aspath);
7170
7171 switch (nhtype) {
7172 case NEXTHOP_TYPE_IFINDEX:
7173 break;
7174 case NEXTHOP_TYPE_IPV4:
7175 case NEXTHOP_TYPE_IPV4_IFINDEX:
7176 attr.nexthop = nexthop->ipv4;
7177 break;
7178 case NEXTHOP_TYPE_IPV6:
7179 case NEXTHOP_TYPE_IPV6_IFINDEX:
7180 attr.mp_nexthop_global = nexthop->ipv6;
7181 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
7182 break;
7183 case NEXTHOP_TYPE_BLACKHOLE:
7184 switch (p->family) {
7185 case AF_INET:
7186 attr.nexthop.s_addr = INADDR_ANY;
7187 break;
7188 case AF_INET6:
7189 memset(&attr.mp_nexthop_global, 0,
7190 sizeof(attr.mp_nexthop_global));
7191 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
7192 break;
7193 }
7194 break;
7195 }
7196 attr.nh_ifindex = ifindex;
7197
7198 attr.med = metric;
7199 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
7200 attr.tag = tag;
7201
7202 afi = family2afi(p->family);
7203
7204 red = bgp_redist_lookup(bgp, afi, type, instance);
7205 if (red) {
7206 struct attr attr_new;
7207
7208 /* Copy attribute for modification. */
7209 attr_new = attr;
7210
7211 if (red->redist_metric_flag)
7212 attr_new.med = red->redist_metric;
7213
7214 /* Apply route-map. */
7215 if (red->rmap.name) {
7216 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
7217 rmap_path.peer = bgp->peer_self;
7218 rmap_path.attr = &attr_new;
7219
7220 SET_FLAG(bgp->peer_self->rmap_type,
7221 PEER_RMAP_TYPE_REDISTRIBUTE);
7222
7223 ret = route_map_apply(red->rmap.map, p, RMAP_BGP,
7224 &rmap_path);
7225
7226 bgp->peer_self->rmap_type = 0;
7227
7228 if (ret == RMAP_DENYMATCH) {
7229 /* Free uninterned attribute. */
7230 bgp_attr_flush(&attr_new);
7231
7232 /* Unintern original. */
7233 aspath_unintern(&attr.aspath);
7234 bgp_redistribute_delete(bgp, p, type, instance);
7235 return;
7236 }
7237 }
7238
7239 if (bgp_in_graceful_shutdown(bgp))
7240 bgp_attr_add_gshut_community(&attr_new);
7241
7242 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
7243 SAFI_UNICAST, p, NULL);
7244
7245 new_attr = bgp_attr_intern(&attr_new);
7246
7247 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
7248 if (bpi->peer == bgp->peer_self
7249 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
7250 break;
7251
7252 if (bpi) {
7253 /* Ensure the (source route) type is updated. */
7254 bpi->type = type;
7255 if (attrhash_cmp(bpi->attr, new_attr)
7256 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
7257 bgp_attr_unintern(&new_attr);
7258 aspath_unintern(&attr.aspath);
7259 bgp_dest_unlock_node(bn);
7260 return;
7261 } else {
7262 /* The attribute is changed. */
7263 bgp_path_info_set_flag(bn, bpi,
7264 BGP_PATH_ATTR_CHANGED);
7265
7266 /* Rewrite BGP route information. */
7267 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
7268 bgp_path_info_restore(bn, bpi);
7269 else
7270 bgp_aggregate_decrement(
7271 bgp, p, bpi, afi, SAFI_UNICAST);
7272 bgp_attr_unintern(&bpi->attr);
7273 bpi->attr = new_attr;
7274 bpi->uptime = bgp_clock();
7275
7276 /* Process change. */
7277 bgp_aggregate_increment(bgp, p, bpi, afi,
7278 SAFI_UNICAST);
7279 bgp_process(bgp, bn, afi, SAFI_UNICAST);
7280 bgp_dest_unlock_node(bn);
7281 aspath_unintern(&attr.aspath);
7282
7283 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7284 || (bgp->inst_type
7285 == BGP_INSTANCE_TYPE_DEFAULT)) {
7286
7287 vpn_leak_from_vrf_update(
7288 bgp_get_default(), bgp, bpi);
7289 }
7290 return;
7291 }
7292 }
7293
7294 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
7295 bgp->peer_self, new_attr, bn);
7296 SET_FLAG(new->flags, BGP_PATH_VALID);
7297
7298 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
7299 bgp_path_info_add(bn, new);
7300 bgp_dest_unlock_node(bn);
7301 bgp_process(bgp, bn, afi, SAFI_UNICAST);
7302
7303 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7304 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
7305
7306 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
7307 }
7308 }
7309
7310 /* Unintern original. */
7311 aspath_unintern(&attr.aspath);
7312 }
7313
7314 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
7315 unsigned short instance)
7316 {
7317 afi_t afi;
7318 struct bgp_dest *dest;
7319 struct bgp_path_info *pi;
7320 struct bgp_redist *red;
7321
7322 afi = family2afi(p->family);
7323
7324 red = bgp_redist_lookup(bgp, afi, type, instance);
7325 if (red) {
7326 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
7327 SAFI_UNICAST, p, NULL);
7328
7329 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7330 if (pi->peer == bgp->peer_self && pi->type == type)
7331 break;
7332
7333 if (pi) {
7334 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7335 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
7336
7337 vpn_leak_from_vrf_withdraw(bgp_get_default(),
7338 bgp, pi);
7339 }
7340 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
7341 bgp_path_info_delete(dest, pi);
7342 bgp_process(bgp, dest, afi, SAFI_UNICAST);
7343 }
7344 bgp_dest_unlock_node(dest);
7345 }
7346 }
7347
7348 /* Withdraw specified route type's route. */
7349 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
7350 unsigned short instance)
7351 {
7352 struct bgp_dest *dest;
7353 struct bgp_path_info *pi;
7354 struct bgp_table *table;
7355
7356 table = bgp->rib[afi][SAFI_UNICAST];
7357
7358 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
7359 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7360 if (pi->peer == bgp->peer_self && pi->type == type
7361 && pi->instance == instance)
7362 break;
7363
7364 if (pi) {
7365 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7366 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
7367
7368 vpn_leak_from_vrf_withdraw(bgp_get_default(),
7369 bgp, pi);
7370 }
7371 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
7372 pi, afi, SAFI_UNICAST);
7373 bgp_path_info_delete(dest, pi);
7374 bgp_process(bgp, dest, afi, SAFI_UNICAST);
7375 }
7376 }
7377 }
7378
7379 /* Static function to display route. */
7380 static void route_vty_out_route(const struct prefix *p, struct vty *vty,
7381 json_object *json, bool wide)
7382 {
7383 int len = 0;
7384 char buf[BUFSIZ];
7385 char buf2[BUFSIZ];
7386
7387 if (p->family == AF_INET) {
7388 if (!json) {
7389 len = vty_out(
7390 vty, "%s/%d",
7391 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
7392 p->prefixlen);
7393 } else {
7394 json_object_string_add(json, "prefix",
7395 inet_ntop(p->family,
7396 &p->u.prefix, buf,
7397 BUFSIZ));
7398 json_object_int_add(json, "prefixLen", p->prefixlen);
7399 prefix2str(p, buf2, PREFIX_STRLEN);
7400 json_object_string_add(json, "network", buf2);
7401 }
7402 } else if (p->family == AF_ETHERNET) {
7403 prefix2str(p, buf, PREFIX_STRLEN);
7404 len = vty_out(vty, "%s", buf);
7405 } else if (p->family == AF_EVPN) {
7406 if (!json)
7407 len = vty_out(
7408 vty, "%s",
7409 bgp_evpn_route2str((struct prefix_evpn *)p, buf,
7410 BUFSIZ));
7411 else
7412 bgp_evpn_route2json((struct prefix_evpn *)p, json);
7413 } else if (p->family == AF_FLOWSPEC) {
7414 route_vty_out_flowspec(vty, p, NULL,
7415 json ?
7416 NLRI_STRING_FORMAT_JSON_SIMPLE :
7417 NLRI_STRING_FORMAT_MIN, json);
7418 } else {
7419 if (!json)
7420 len = vty_out(
7421 vty, "%s/%d",
7422 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
7423 p->prefixlen);
7424 else {
7425 json_object_string_add(json, "prefix",
7426 inet_ntop(p->family,
7427 &p->u.prefix, buf,
7428 BUFSIZ));
7429 json_object_int_add(json, "prefixLen", p->prefixlen);
7430 prefix2str(p, buf2, PREFIX_STRLEN);
7431 json_object_string_add(json, "network", buf2);
7432 }
7433 }
7434
7435 if (!json) {
7436 len = wide ? (45 - len) : (17 - len);
7437 if (len < 1)
7438 vty_out(vty, "\n%*s", 20, " ");
7439 else
7440 vty_out(vty, "%*s", len, " ");
7441 }
7442 }
7443
7444 enum bgp_display_type {
7445 normal_list,
7446 };
7447
7448 /* Print the short form route status for a bgp_path_info */
7449 static void route_vty_short_status_out(struct vty *vty,
7450 struct bgp_path_info *path,
7451 json_object *json_path)
7452 {
7453 if (json_path) {
7454
7455 /* Route status display. */
7456 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
7457 json_object_boolean_true_add(json_path, "removed");
7458
7459 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
7460 json_object_boolean_true_add(json_path, "stale");
7461
7462 if (path->extra && path->extra->suppress)
7463 json_object_boolean_true_add(json_path, "suppressed");
7464
7465 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
7466 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7467 json_object_boolean_true_add(json_path, "valid");
7468
7469 /* Selected */
7470 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7471 json_object_boolean_true_add(json_path, "history");
7472
7473 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
7474 json_object_boolean_true_add(json_path, "damped");
7475
7476 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
7477 json_object_boolean_true_add(json_path, "bestpath");
7478
7479 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
7480 json_object_boolean_true_add(json_path, "multipath");
7481
7482 /* Internal route. */
7483 if ((path->peer->as)
7484 && (path->peer->as == path->peer->local_as))
7485 json_object_string_add(json_path, "pathFrom",
7486 "internal");
7487 else
7488 json_object_string_add(json_path, "pathFrom",
7489 "external");
7490
7491 return;
7492 }
7493
7494 /* Route status display. */
7495 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
7496 vty_out(vty, "R");
7497 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
7498 vty_out(vty, "S");
7499 else if (path->extra && path->extra->suppress)
7500 vty_out(vty, "s");
7501 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
7502 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7503 vty_out(vty, "*");
7504 else
7505 vty_out(vty, " ");
7506
7507 /* Selected */
7508 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7509 vty_out(vty, "h");
7510 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
7511 vty_out(vty, "d");
7512 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
7513 vty_out(vty, ">");
7514 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
7515 vty_out(vty, "=");
7516 else
7517 vty_out(vty, " ");
7518
7519 /* Internal route. */
7520 if (path->peer && (path->peer->as)
7521 && (path->peer->as == path->peer->local_as))
7522 vty_out(vty, "i");
7523 else
7524 vty_out(vty, " ");
7525 }
7526
7527 static char *bgp_nexthop_hostname(struct peer *peer,
7528 struct bgp_nexthop_cache *bnc)
7529 {
7530 if (peer->hostname
7531 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
7532 return peer->hostname;
7533 return NULL;
7534 }
7535
7536 /* called from terminal list command */
7537 void route_vty_out(struct vty *vty, const struct prefix *p,
7538 struct bgp_path_info *path, int display, safi_t safi,
7539 json_object *json_paths, bool wide)
7540 {
7541 int len;
7542 struct attr *attr = path->attr;
7543 json_object *json_path = NULL;
7544 json_object *json_nexthops = NULL;
7545 json_object *json_nexthop_global = NULL;
7546 json_object *json_nexthop_ll = NULL;
7547 json_object *json_ext_community = NULL;
7548 char vrf_id_str[VRF_NAMSIZ] = {0};
7549 bool nexthop_self =
7550 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
7551 bool nexthop_othervrf = false;
7552 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
7553 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
7554 char *nexthop_hostname =
7555 bgp_nexthop_hostname(path->peer, path->nexthop);
7556 char esi_buf[ESI_STR_LEN];
7557
7558 if (json_paths)
7559 json_path = json_object_new_object();
7560
7561 /* short status lead text */
7562 route_vty_short_status_out(vty, path, json_path);
7563
7564 if (!json_paths) {
7565 /* print prefix and mask */
7566 if (!display)
7567 route_vty_out_route(p, vty, json_path, wide);
7568 else
7569 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
7570 } else {
7571 route_vty_out_route(p, vty, json_path, wide);
7572 }
7573
7574 /*
7575 * If vrf id of nexthop is different from that of prefix,
7576 * set up printable string to append
7577 */
7578 if (path->extra && path->extra->bgp_orig) {
7579 const char *self = "";
7580
7581 if (nexthop_self)
7582 self = "<";
7583
7584 nexthop_othervrf = true;
7585 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
7586
7587 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
7588 snprintf(vrf_id_str, sizeof(vrf_id_str),
7589 "@%s%s", VRFID_NONE_STR, self);
7590 else
7591 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
7592 path->extra->bgp_orig->vrf_id, self);
7593
7594 if (path->extra->bgp_orig->inst_type
7595 != BGP_INSTANCE_TYPE_DEFAULT)
7596
7597 nexthop_vrfname = path->extra->bgp_orig->name;
7598 } else {
7599 const char *self = "";
7600
7601 if (nexthop_self)
7602 self = "<";
7603
7604 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
7605 }
7606
7607 /*
7608 * For ENCAP and EVPN routes, nexthop address family is not
7609 * neccessarily the same as the prefix address family.
7610 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
7611 * EVPN routes are also exchanged with a MP nexthop. Currently,
7612 * this
7613 * is only IPv4, the value will be present in either
7614 * attr->nexthop or
7615 * attr->mp_nexthop_global_in
7616 */
7617 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
7618 char buf[BUFSIZ];
7619 char nexthop[128];
7620 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
7621
7622 switch (af) {
7623 case AF_INET:
7624 snprintf(nexthop, sizeof(nexthop), "%s",
7625 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
7626 BUFSIZ));
7627 break;
7628 case AF_INET6:
7629 snprintf(nexthop, sizeof(nexthop), "%s",
7630 inet_ntop(af, &attr->mp_nexthop_global, buf,
7631 BUFSIZ));
7632 break;
7633 default:
7634 snprintf(nexthop, sizeof(nexthop), "?");
7635 break;
7636 }
7637
7638 if (json_paths) {
7639 json_nexthop_global = json_object_new_object();
7640
7641 json_object_string_add(json_nexthop_global, "ip",
7642 nexthop);
7643
7644 if (path->peer->hostname)
7645 json_object_string_add(json_nexthop_global,
7646 "hostname",
7647 path->peer->hostname);
7648
7649 json_object_string_add(json_nexthop_global, "afi",
7650 (af == AF_INET) ? "ipv4"
7651 : "ipv6");
7652 json_object_boolean_true_add(json_nexthop_global,
7653 "used");
7654 } else {
7655 if (nexthop_hostname)
7656 len = vty_out(vty, "%s(%s)%s", nexthop,
7657 nexthop_hostname, vrf_id_str);
7658 else
7659 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
7660
7661 len = wide ? (41 - len) : (16 - len);
7662 if (len < 1)
7663 vty_out(vty, "\n%*s", 36, " ");
7664 else
7665 vty_out(vty, "%*s", len, " ");
7666 }
7667 } else if (safi == SAFI_EVPN) {
7668 if (json_paths) {
7669 json_nexthop_global = json_object_new_object();
7670
7671 json_object_string_add(json_nexthop_global, "ip",
7672 inet_ntoa(attr->nexthop));
7673
7674 if (path->peer->hostname)
7675 json_object_string_add(json_nexthop_global,
7676 "hostname",
7677 path->peer->hostname);
7678
7679 json_object_string_add(json_nexthop_global, "afi",
7680 "ipv4");
7681 json_object_boolean_true_add(json_nexthop_global,
7682 "used");
7683 } else {
7684 if (nexthop_hostname)
7685 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
7686 nexthop_hostname, vrf_id_str);
7687 else
7688 len = vty_out(vty, "%pI4%s", &attr->nexthop,
7689 vrf_id_str);
7690
7691 len = wide ? (41 - len) : (16 - len);
7692 if (len < 1)
7693 vty_out(vty, "\n%*s", 36, " ");
7694 else
7695 vty_out(vty, "%*s", len, " ");
7696 }
7697 } else if (safi == SAFI_FLOWSPEC) {
7698 if (attr->nexthop.s_addr != INADDR_ANY) {
7699 if (json_paths) {
7700 json_nexthop_global = json_object_new_object();
7701
7702 json_object_string_add(json_nexthop_global,
7703 "afi", "ipv4");
7704 json_object_string_add(
7705 json_nexthop_global, "ip",
7706 inet_ntoa(attr->nexthop));
7707
7708 if (path->peer->hostname)
7709 json_object_string_add(
7710 json_nexthop_global, "hostname",
7711 path->peer->hostname);
7712
7713 json_object_boolean_true_add(
7714 json_nexthop_global,
7715 "used");
7716 } else {
7717 if (nexthop_hostname)
7718 len = vty_out(vty, "%pI4(%s)%s",
7719 &attr->nexthop,
7720 nexthop_hostname,
7721 vrf_id_str);
7722 else
7723 len = vty_out(vty, "%pI4%s",
7724 &attr->nexthop,
7725 vrf_id_str);
7726
7727 len = wide ? (41 - len) : (16 - len);
7728 if (len < 1)
7729 vty_out(vty, "\n%*s", 36, " ");
7730 else
7731 vty_out(vty, "%*s", len, " ");
7732 }
7733 }
7734 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7735 if (json_paths) {
7736 json_nexthop_global = json_object_new_object();
7737
7738 json_object_string_add(json_nexthop_global, "ip",
7739 inet_ntoa(attr->nexthop));
7740
7741 if (path->peer->hostname)
7742 json_object_string_add(json_nexthop_global,
7743 "hostname",
7744 path->peer->hostname);
7745
7746 json_object_string_add(json_nexthop_global, "afi",
7747 "ipv4");
7748 json_object_boolean_true_add(json_nexthop_global,
7749 "used");
7750 } else {
7751 if (nexthop_hostname)
7752 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
7753 nexthop_hostname, vrf_id_str);
7754 else
7755 len = vty_out(vty, "%pI4%s", &attr->nexthop,
7756 vrf_id_str);
7757
7758 len = wide ? (41 - len) : (16 - len);
7759 if (len < 1)
7760 vty_out(vty, "\n%*s", 36, " ");
7761 else
7762 vty_out(vty, "%*s", len, " ");
7763 }
7764 }
7765
7766 /* IPv6 Next Hop */
7767 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7768 char buf[BUFSIZ];
7769
7770 if (json_paths) {
7771 json_nexthop_global = json_object_new_object();
7772 json_object_string_add(
7773 json_nexthop_global, "ip",
7774 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
7775 buf, BUFSIZ));
7776
7777 if (path->peer->hostname)
7778 json_object_string_add(json_nexthop_global,
7779 "hostname",
7780 path->peer->hostname);
7781
7782 json_object_string_add(json_nexthop_global, "afi",
7783 "ipv6");
7784 json_object_string_add(json_nexthop_global, "scope",
7785 "global");
7786
7787 /* We display both LL & GL if both have been
7788 * received */
7789 if ((attr->mp_nexthop_len
7790 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
7791 || (path->peer->conf_if)) {
7792 json_nexthop_ll = json_object_new_object();
7793 json_object_string_add(
7794 json_nexthop_ll, "ip",
7795 inet_ntop(AF_INET6,
7796 &attr->mp_nexthop_local, buf,
7797 BUFSIZ));
7798
7799 if (path->peer->hostname)
7800 json_object_string_add(
7801 json_nexthop_ll, "hostname",
7802 path->peer->hostname);
7803
7804 json_object_string_add(json_nexthop_ll, "afi",
7805 "ipv6");
7806 json_object_string_add(json_nexthop_ll, "scope",
7807 "link-local");
7808
7809 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
7810 &attr->mp_nexthop_local)
7811 != 0)
7812 && !attr->mp_nexthop_prefer_global)
7813 json_object_boolean_true_add(
7814 json_nexthop_ll, "used");
7815 else
7816 json_object_boolean_true_add(
7817 json_nexthop_global, "used");
7818 } else
7819 json_object_boolean_true_add(
7820 json_nexthop_global, "used");
7821 } else {
7822 /* Display LL if LL/Global both in table unless
7823 * prefer-global is set */
7824 if (((attr->mp_nexthop_len
7825 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
7826 && !attr->mp_nexthop_prefer_global)
7827 || (path->peer->conf_if)) {
7828 if (path->peer->conf_if) {
7829 len = vty_out(vty, "%s",
7830 path->peer->conf_if);
7831 /* len of IPv6 addr + max len of def
7832 * ifname */
7833 len = wide ? (41 - len) : (16 - len);
7834
7835 if (len < 1)
7836 vty_out(vty, "\n%*s", 36, " ");
7837 else
7838 vty_out(vty, "%*s", len, " ");
7839 } else {
7840 if (nexthop_hostname)
7841 len = vty_out(
7842 vty, "%pI6(%s)%s",
7843 &attr->mp_nexthop_local,
7844 nexthop_hostname,
7845 vrf_id_str);
7846 else
7847 len = vty_out(
7848 vty, "%pI6%s",
7849 &attr->mp_nexthop_local,
7850 vrf_id_str);
7851
7852 len = wide ? (41 - len) : (16 - len);
7853
7854 if (len < 1)
7855 vty_out(vty, "\n%*s", 36, " ");
7856 else
7857 vty_out(vty, "%*s", len, " ");
7858 }
7859 } else {
7860 if (nexthop_hostname)
7861 len = vty_out(vty, "%pI6(%s)%s",
7862 &attr->mp_nexthop_global,
7863 nexthop_hostname,
7864 vrf_id_str);
7865 else
7866 len = vty_out(vty, "%pI6%s",
7867 &attr->mp_nexthop_global,
7868 vrf_id_str);
7869
7870 len = wide ? (41 - len) : (16 - len);
7871
7872 if (len < 1)
7873 vty_out(vty, "\n%*s", 36, " ");
7874 else
7875 vty_out(vty, "%*s", len, " ");
7876 }
7877 }
7878 }
7879
7880 /* MED/Metric */
7881 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7882 if (json_paths)
7883 json_object_int_add(json_path, "metric", attr->med);
7884 else if (wide)
7885 vty_out(vty, "%7u", attr->med);
7886 else
7887 vty_out(vty, "%10u", attr->med);
7888 else if (!json_paths) {
7889 if (wide)
7890 vty_out(vty, "%*s", 7, " ");
7891 else
7892 vty_out(vty, "%*s", 10, " ");
7893 }
7894
7895 /* Local Pref */
7896 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
7897 if (json_paths)
7898 json_object_int_add(json_path, "locPrf",
7899 attr->local_pref);
7900 else
7901 vty_out(vty, "%7u", attr->local_pref);
7902 else if (!json_paths)
7903 vty_out(vty, " ");
7904
7905 if (json_paths)
7906 json_object_int_add(json_path, "weight", attr->weight);
7907 else
7908 vty_out(vty, "%7u ", attr->weight);
7909
7910 if (json_paths) {
7911 char buf[BUFSIZ];
7912 json_object_string_add(
7913 json_path, "peerId",
7914 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
7915 }
7916
7917 /* Print aspath */
7918 if (attr->aspath) {
7919 if (json_paths)
7920 json_object_string_add(json_path, "path",
7921 attr->aspath->str);
7922 else
7923 aspath_print_vty(vty, "%s", attr->aspath, " ");
7924 }
7925
7926 /* Print origin */
7927 if (json_paths)
7928 json_object_string_add(json_path, "origin",
7929 bgp_origin_long_str[attr->origin]);
7930 else
7931 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7932
7933 if (json_paths) {
7934 if (bgp_evpn_is_esi_valid(&attr->esi)) {
7935 json_object_string_add(json_path, "esi",
7936 esi_to_str(&attr->esi,
7937 esi_buf, sizeof(esi_buf)));
7938 }
7939 if (safi == SAFI_EVPN &&
7940 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
7941 json_ext_community = json_object_new_object();
7942 json_object_string_add(json_ext_community,
7943 "string",
7944 attr->ecommunity->str);
7945 json_object_object_add(json_path,
7946 "extendedCommunity",
7947 json_ext_community);
7948 }
7949
7950 if (nexthop_self)
7951 json_object_boolean_true_add(json_path,
7952 "announceNexthopSelf");
7953 if (nexthop_othervrf) {
7954 json_object_string_add(json_path, "nhVrfName",
7955 nexthop_vrfname);
7956
7957 json_object_int_add(json_path, "nhVrfId",
7958 ((nexthop_vrfid == VRF_UNKNOWN)
7959 ? -1
7960 : (int)nexthop_vrfid));
7961 }
7962 }
7963
7964 if (json_paths) {
7965 if (json_nexthop_global || json_nexthop_ll) {
7966 json_nexthops = json_object_new_array();
7967
7968 if (json_nexthop_global)
7969 json_object_array_add(json_nexthops,
7970 json_nexthop_global);
7971
7972 if (json_nexthop_ll)
7973 json_object_array_add(json_nexthops,
7974 json_nexthop_ll);
7975
7976 json_object_object_add(json_path, "nexthops",
7977 json_nexthops);
7978 }
7979
7980 json_object_array_add(json_paths, json_path);
7981 } else {
7982 vty_out(vty, "\n");
7983
7984 if (safi == SAFI_EVPN) {
7985 if (bgp_evpn_is_esi_valid(&attr->esi)) {
7986 vty_out(vty, "%*s", 20, " ");
7987 vty_out(vty, "ESI:%s\n",
7988 esi_to_str(&attr->esi,
7989 esi_buf, sizeof(esi_buf)));
7990 }
7991 if (attr->flag &
7992 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
7993 vty_out(vty, "%*s", 20, " ");
7994 vty_out(vty, "%s\n", attr->ecommunity->str);
7995 }
7996 }
7997
7998 #ifdef ENABLE_BGP_VNC
7999 /* prints an additional line, indented, with VNC info, if
8000 * present */
8001 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
8002 rfapi_vty_out_vncinfo(vty, p, path, safi);
8003 #endif
8004 }
8005 }
8006
8007 /* called from terminal list command */
8008 void route_vty_out_tmp(struct vty *vty, const struct prefix *p,
8009 struct attr *attr, safi_t safi, bool use_json,
8010 json_object *json_ar, bool wide)
8011 {
8012 json_object *json_status = NULL;
8013 json_object *json_net = NULL;
8014 int len;
8015 char buff[BUFSIZ];
8016
8017 /* Route status display. */
8018 if (use_json) {
8019 json_status = json_object_new_object();
8020 json_net = json_object_new_object();
8021 } else {
8022 vty_out(vty, "*");
8023 vty_out(vty, ">");
8024 vty_out(vty, " ");
8025 }
8026
8027 /* print prefix and mask */
8028 if (use_json) {
8029 if (safi == SAFI_EVPN)
8030 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
8031 else if (p->family == AF_INET || p->family == AF_INET6) {
8032 json_object_string_add(
8033 json_net, "addrPrefix",
8034 inet_ntop(p->family, &p->u.prefix, buff,
8035 BUFSIZ));
8036 json_object_int_add(json_net, "prefixLen",
8037 p->prefixlen);
8038 prefix2str(p, buff, PREFIX_STRLEN);
8039 json_object_string_add(json_net, "network", buff);
8040 }
8041 } else
8042 route_vty_out_route(p, vty, NULL, wide);
8043
8044 /* Print attribute */
8045 if (attr) {
8046 if (use_json) {
8047 if (p->family == AF_INET
8048 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8049 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8050 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
8051 json_object_string_add(
8052 json_net, "nextHop",
8053 inet_ntoa(
8054 attr->mp_nexthop_global_in));
8055 else
8056 json_object_string_add(
8057 json_net, "nextHop",
8058 inet_ntoa(attr->nexthop));
8059 } else if (p->family == AF_INET6
8060 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8061 char buf[BUFSIZ];
8062
8063 json_object_string_add(
8064 json_net, "nextHopGlobal",
8065 inet_ntop(AF_INET6,
8066 &attr->mp_nexthop_global, buf,
8067 BUFSIZ));
8068 } else if (p->family == AF_EVPN &&
8069 !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
8070 json_object_string_add(json_net,
8071 "nextHop", inet_ntoa(
8072 attr->mp_nexthop_global_in));
8073
8074 if (attr->flag
8075 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
8076 json_object_int_add(json_net, "metric",
8077 attr->med);
8078
8079 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
8080 json_object_int_add(json_net, "locPrf",
8081 attr->local_pref);
8082
8083 json_object_int_add(json_net, "weight", attr->weight);
8084
8085 /* Print aspath */
8086 if (attr->aspath)
8087 json_object_string_add(json_net, "path",
8088 attr->aspath->str);
8089
8090 /* Print origin */
8091 json_object_string_add(json_net, "bgpOriginCode",
8092 bgp_origin_str[attr->origin]);
8093 } else {
8094 if (p->family == AF_INET
8095 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8096 || safi == SAFI_EVPN
8097 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8098 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8099 || safi == SAFI_EVPN)
8100 vty_out(vty, "%-16s",
8101 inet_ntoa(
8102 attr->mp_nexthop_global_in));
8103 else if (wide)
8104 vty_out(vty, "%-41s",
8105 inet_ntoa(attr->nexthop));
8106 else
8107 vty_out(vty, "%-16s",
8108 inet_ntoa(attr->nexthop));
8109 } else if (p->family == AF_INET6
8110 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8111 char buf[BUFSIZ];
8112
8113 len = vty_out(
8114 vty, "%s",
8115 inet_ntop(AF_INET6,
8116 &attr->mp_nexthop_global, buf,
8117 BUFSIZ));
8118 len = wide ? (41 - len) : (16 - len);
8119 if (len < 1)
8120 vty_out(vty, "\n%*s", 36, " ");
8121 else
8122 vty_out(vty, "%*s", len, " ");
8123 }
8124 if (attr->flag
8125 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
8126 if (wide)
8127 vty_out(vty, "%7u", attr->med);
8128 else
8129 vty_out(vty, "%10u", attr->med);
8130 else if (wide)
8131 vty_out(vty, " ");
8132 else
8133 vty_out(vty, " ");
8134
8135 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
8136 vty_out(vty, "%7u", attr->local_pref);
8137 else
8138 vty_out(vty, " ");
8139
8140 vty_out(vty, "%7u ", attr->weight);
8141
8142 /* Print aspath */
8143 if (attr->aspath)
8144 aspath_print_vty(vty, "%s", attr->aspath, " ");
8145
8146 /* Print origin */
8147 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8148 }
8149 }
8150 if (use_json) {
8151 json_object_boolean_true_add(json_status, "*");
8152 json_object_boolean_true_add(json_status, ">");
8153 json_object_object_add(json_net, "appliedStatusSymbols",
8154 json_status);
8155
8156 prefix2str(p, buff, PREFIX_STRLEN);
8157 json_object_object_add(json_ar, buff, json_net);
8158 } else
8159 vty_out(vty, "\n");
8160 }
8161
8162 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
8163 struct bgp_path_info *path, int display, safi_t safi,
8164 json_object *json)
8165 {
8166 json_object *json_out = NULL;
8167 struct attr *attr;
8168 mpls_label_t label = MPLS_INVALID_LABEL;
8169
8170 if (!path->extra)
8171 return;
8172
8173 if (json)
8174 json_out = json_object_new_object();
8175
8176 /* short status lead text */
8177 route_vty_short_status_out(vty, path, json_out);
8178
8179 /* print prefix and mask */
8180 if (json == NULL) {
8181 if (!display)
8182 route_vty_out_route(p, vty, NULL, false);
8183 else
8184 vty_out(vty, "%*s", 17, " ");
8185 }
8186
8187 /* Print attribute */
8188 attr = path->attr;
8189 if (((p->family == AF_INET)
8190 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
8191 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
8192 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8193 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8194 || safi == SAFI_EVPN) {
8195 if (json)
8196 json_object_string_add(
8197 json_out, "mpNexthopGlobalIn",
8198 inet_ntoa(attr->mp_nexthop_global_in));
8199 else
8200 vty_out(vty, "%-16s",
8201 inet_ntoa(attr->mp_nexthop_global_in));
8202 } else {
8203 if (json)
8204 json_object_string_add(
8205 json_out, "nexthop",
8206 inet_ntoa(attr->nexthop));
8207 else
8208 vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
8209 }
8210 } else if (((p->family == AF_INET6)
8211 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
8212 || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
8213 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8214 char buf_a[512];
8215
8216 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
8217 if (json)
8218 json_object_string_add(
8219 json_out, "mpNexthopGlobalIn",
8220 inet_ntop(AF_INET6,
8221 &attr->mp_nexthop_global,
8222 buf_a, sizeof(buf_a)));
8223 else
8224 vty_out(vty, "%s",
8225 inet_ntop(AF_INET6,
8226 &attr->mp_nexthop_global,
8227 buf_a, sizeof(buf_a)));
8228 } else if (attr->mp_nexthop_len
8229 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
8230 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
8231 &attr->mp_nexthop_global,
8232 &attr->mp_nexthop_local);
8233 if (json)
8234 json_object_string_add(json_out,
8235 "mpNexthopGlobalLocal",
8236 buf_a);
8237 else
8238 vty_out(vty, "%s", buf_a);
8239 }
8240 }
8241
8242 label = decode_label(&path->extra->label[0]);
8243
8244 if (bgp_is_valid_label(&label)) {
8245 if (json) {
8246 json_object_int_add(json_out, "notag", label);
8247 json_object_array_add(json, json_out);
8248 } else {
8249 vty_out(vty, "notag/%d", label);
8250 vty_out(vty, "\n");
8251 }
8252 }
8253 }
8254
8255 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
8256 struct bgp_path_info *path, int display,
8257 json_object *json_paths)
8258 {
8259 struct attr *attr;
8260 char buf[BUFSIZ] = {0};
8261 json_object *json_path = NULL;
8262 json_object *json_nexthop = NULL;
8263 json_object *json_overlay = NULL;
8264
8265 if (!path->extra)
8266 return;
8267
8268 if (json_paths) {
8269 json_path = json_object_new_object();
8270 json_overlay = json_object_new_object();
8271 json_nexthop = json_object_new_object();
8272 }
8273
8274 /* short status lead text */
8275 route_vty_short_status_out(vty, path, json_path);
8276
8277 /* print prefix and mask */
8278 if (!display)
8279 route_vty_out_route(p, vty, json_path, false);
8280 else
8281 vty_out(vty, "%*s", 17, " ");
8282
8283 /* Print attribute */
8284 attr = path->attr;
8285 char buf1[BUFSIZ];
8286 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
8287
8288 switch (af) {
8289 case AF_INET:
8290 inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ);
8291 if (!json_path) {
8292 vty_out(vty, "%-16s", buf);
8293 } else {
8294 json_object_string_add(json_nexthop, "ip", buf);
8295
8296 json_object_string_add(json_nexthop, "afi", "ipv4");
8297
8298 json_object_object_add(json_path, "nexthop",
8299 json_nexthop);
8300 }
8301 break;
8302 case AF_INET6:
8303 inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ);
8304 inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ);
8305 if (!json_path) {
8306 vty_out(vty, "%s(%s)", buf, buf1);
8307 } else {
8308 json_object_string_add(json_nexthop, "ipv6Global", buf);
8309
8310 json_object_string_add(json_nexthop, "ipv6LinkLocal",
8311 buf1);
8312
8313 json_object_string_add(json_nexthop, "afi", "ipv6");
8314
8315 json_object_object_add(json_path, "nexthop",
8316 json_nexthop);
8317 }
8318 break;
8319 default:
8320 if (!json_path) {
8321 vty_out(vty, "?");
8322 } else {
8323 json_object_string_add(json_nexthop, "Error",
8324 "Unsupported address-family");
8325 }
8326 }
8327
8328 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) {
8329 inet_ntop(AF_INET, &(attr->evpn_overlay.gw_ip.ipv4), buf,
8330 BUFSIZ);
8331 } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) {
8332 inet_ntop(AF_INET6, &(attr->evpn_overlay.gw_ip.ipv6), buf,
8333 BUFSIZ);
8334 }
8335
8336 if (!json_path)
8337 vty_out(vty, "/%s", buf);
8338 else
8339 json_object_string_add(json_overlay, "gw", buf);
8340
8341 if (attr->ecommunity) {
8342 char *mac = NULL;
8343 struct ecommunity_val *routermac = ecommunity_lookup(
8344 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
8345 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
8346
8347 if (routermac)
8348 mac = ecom_mac2str((char *)routermac->val);
8349 if (mac) {
8350 if (!json_path) {
8351 vty_out(vty, "/%s", mac);
8352 } else {
8353 json_object_string_add(json_overlay, "rmac",
8354 mac);
8355 }
8356 XFREE(MTYPE_TMP, mac);
8357 }
8358 }
8359
8360 if (!json_path) {
8361 vty_out(vty, "\n");
8362 } else {
8363 json_object_object_add(json_path, "overlay", json_overlay);
8364
8365 json_object_array_add(json_paths, json_path);
8366 }
8367 }
8368
8369 /* dampening route */
8370 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
8371 struct bgp_path_info *path, int display,
8372 afi_t afi, safi_t safi, bool use_json,
8373 json_object *json)
8374 {
8375 struct attr *attr;
8376 int len;
8377 char timebuf[BGP_UPTIME_LEN];
8378
8379 /* short status lead text */
8380 route_vty_short_status_out(vty, path, json);
8381
8382 /* print prefix and mask */
8383 if (!use_json) {
8384 if (!display)
8385 route_vty_out_route(p, vty, NULL, false);
8386 else
8387 vty_out(vty, "%*s", 17, " ");
8388 }
8389
8390 len = vty_out(vty, "%s", path->peer->host);
8391 len = 17 - len;
8392 if (len < 1) {
8393 if (!use_json)
8394 vty_out(vty, "\n%*s", 34, " ");
8395 } else {
8396 if (use_json)
8397 json_object_int_add(json, "peerHost", len);
8398 else
8399 vty_out(vty, "%*s", len, " ");
8400 }
8401
8402 if (use_json)
8403 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
8404 safi, use_json, json);
8405 else
8406 vty_out(vty, "%s ",
8407 bgp_damp_reuse_time_vty(vty, path, timebuf,
8408 BGP_UPTIME_LEN, afi, safi,
8409 use_json, json));
8410
8411 /* Print attribute */
8412 attr = path->attr;
8413
8414 /* Print aspath */
8415 if (attr->aspath) {
8416 if (use_json)
8417 json_object_string_add(json, "asPath",
8418 attr->aspath->str);
8419 else
8420 aspath_print_vty(vty, "%s", attr->aspath, " ");
8421 }
8422
8423 /* Print origin */
8424 if (use_json)
8425 json_object_string_add(json, "origin",
8426 bgp_origin_str[attr->origin]);
8427 else
8428 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8429
8430 if (!use_json)
8431 vty_out(vty, "\n");
8432 }
8433
8434 /* flap route */
8435 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
8436 struct bgp_path_info *path, int display,
8437 afi_t afi, safi_t safi, bool use_json,
8438 json_object *json)
8439 {
8440 struct attr *attr;
8441 struct bgp_damp_info *bdi;
8442 char timebuf[BGP_UPTIME_LEN];
8443 int len;
8444
8445 if (!path->extra)
8446 return;
8447
8448 bdi = path->extra->damp_info;
8449
8450 /* short status lead text */
8451 route_vty_short_status_out(vty, path, json);
8452
8453 /* print prefix and mask */
8454 if (!use_json) {
8455 if (!display)
8456 route_vty_out_route(p, vty, NULL, false);
8457 else
8458 vty_out(vty, "%*s", 17, " ");
8459 }
8460
8461 len = vty_out(vty, "%s", path->peer->host);
8462 len = 16 - len;
8463 if (len < 1) {
8464 if (!use_json)
8465 vty_out(vty, "\n%*s", 33, " ");
8466 } else {
8467 if (use_json)
8468 json_object_int_add(json, "peerHost", len);
8469 else
8470 vty_out(vty, "%*s", len, " ");
8471 }
8472
8473 len = vty_out(vty, "%d", bdi->flap);
8474 len = 5 - len;
8475 if (len < 1) {
8476 if (!use_json)
8477 vty_out(vty, " ");
8478 } else {
8479 if (use_json)
8480 json_object_int_add(json, "bdiFlap", len);
8481 else
8482 vty_out(vty, "%*s", len, " ");
8483 }
8484
8485 if (use_json)
8486 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
8487 json);
8488 else
8489 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
8490 BGP_UPTIME_LEN, 0, NULL));
8491
8492 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
8493 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8494 if (use_json)
8495 bgp_damp_reuse_time_vty(vty, path, timebuf,
8496 BGP_UPTIME_LEN, afi, safi,
8497 use_json, json);
8498 else
8499 vty_out(vty, "%s ",
8500 bgp_damp_reuse_time_vty(vty, path, timebuf,
8501 BGP_UPTIME_LEN, afi,
8502 safi, use_json, json));
8503 } else {
8504 if (!use_json)
8505 vty_out(vty, "%*s ", 8, " ");
8506 }
8507
8508 /* Print attribute */
8509 attr = path->attr;
8510
8511 /* Print aspath */
8512 if (attr->aspath) {
8513 if (use_json)
8514 json_object_string_add(json, "asPath",
8515 attr->aspath->str);
8516 else
8517 aspath_print_vty(vty, "%s", attr->aspath, " ");
8518 }
8519
8520 /* Print origin */
8521 if (use_json)
8522 json_object_string_add(json, "origin",
8523 bgp_origin_str[attr->origin]);
8524 else
8525 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8526
8527 if (!use_json)
8528 vty_out(vty, "\n");
8529 }
8530
8531 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
8532 int *first, const char *header,
8533 json_object *json_adv_to)
8534 {
8535 char buf1[INET6_ADDRSTRLEN];
8536 json_object *json_peer = NULL;
8537
8538 if (json_adv_to) {
8539 /* 'advertised-to' is a dictionary of peers we have advertised
8540 * this
8541 * prefix too. The key is the peer's IP or swpX, the value is
8542 * the
8543 * hostname if we know it and "" if not.
8544 */
8545 json_peer = json_object_new_object();
8546
8547 if (peer->hostname)
8548 json_object_string_add(json_peer, "hostname",
8549 peer->hostname);
8550
8551 if (peer->conf_if)
8552 json_object_object_add(json_adv_to, peer->conf_if,
8553 json_peer);
8554 else
8555 json_object_object_add(
8556 json_adv_to,
8557 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
8558 json_peer);
8559 } else {
8560 if (*first) {
8561 vty_out(vty, "%s", header);
8562 *first = 0;
8563 }
8564
8565 if (peer->hostname
8566 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
8567 if (peer->conf_if)
8568 vty_out(vty, " %s(%s)", peer->hostname,
8569 peer->conf_if);
8570 else
8571 vty_out(vty, " %s(%s)", peer->hostname,
8572 sockunion2str(&peer->su, buf1,
8573 SU_ADDRSTRLEN));
8574 } else {
8575 if (peer->conf_if)
8576 vty_out(vty, " %s", peer->conf_if);
8577 else
8578 vty_out(vty, " %s",
8579 sockunion2str(&peer->su, buf1,
8580 SU_ADDRSTRLEN));
8581 }
8582 }
8583 }
8584
8585 static void route_vty_out_tx_ids(struct vty *vty,
8586 struct bgp_addpath_info_data *d)
8587 {
8588 int i;
8589
8590 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
8591 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
8592 d->addpath_tx_id[i],
8593 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
8594 }
8595 }
8596
8597 static const char *bgp_path_selection_reason2str(
8598 enum bgp_path_selection_reason reason)
8599 {
8600 switch (reason) {
8601 case bgp_path_selection_none:
8602 return "Nothing to Select";
8603 case bgp_path_selection_first:
8604 return "First path received";
8605 case bgp_path_selection_evpn_sticky_mac:
8606 return "EVPN Sticky Mac";
8607 case bgp_path_selection_evpn_seq:
8608 return "EVPN sequence number";
8609 case bgp_path_selection_evpn_lower_ip:
8610 return "EVPN lower IP";
8611 case bgp_path_selection_evpn_local_path:
8612 return "EVPN local ES path";
8613 case bgp_path_selection_evpn_non_proxy:
8614 return "EVPN non proxy";
8615 case bgp_path_selection_weight:
8616 return "Weight";
8617 case bgp_path_selection_local_pref:
8618 return "Local Pref";
8619 case bgp_path_selection_local_route:
8620 return "Local Route";
8621 case bgp_path_selection_confed_as_path:
8622 return "Confederation based AS Path";
8623 case bgp_path_selection_as_path:
8624 return "AS Path";
8625 case bgp_path_selection_origin:
8626 return "Origin";
8627 case bgp_path_selection_med:
8628 return "MED";
8629 case bgp_path_selection_peer:
8630 return "Peer Type";
8631 case bgp_path_selection_confed:
8632 return "Confed Peer Type";
8633 case bgp_path_selection_igp_metric:
8634 return "IGP Metric";
8635 case bgp_path_selection_older:
8636 return "Older Path";
8637 case bgp_path_selection_router_id:
8638 return "Router ID";
8639 case bgp_path_selection_cluster_length:
8640 return "Cluser length";
8641 case bgp_path_selection_stale:
8642 return "Path Staleness";
8643 case bgp_path_selection_local_configured:
8644 return "Locally configured route";
8645 case bgp_path_selection_neighbor_ip:
8646 return "Neighbor IP";
8647 case bgp_path_selection_default:
8648 return "Nothing left to compare";
8649 }
8650 return "Invalid (internal error)";
8651 }
8652
8653 static void route_vty_out_detail_es_info(struct vty *vty,
8654 struct attr *attr, json_object *json_path)
8655 {
8656 char esi_buf[ESI_STR_LEN];
8657 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
8658 bool peer_router = !!CHECK_FLAG(attr->es_flags,
8659 ATTR_ES_PEER_ROUTER);
8660 bool peer_active = !!CHECK_FLAG(attr->es_flags,
8661 ATTR_ES_PEER_ACTIVE);
8662 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
8663 ATTR_ES_PEER_PROXY);
8664
8665 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
8666 if (json_path) {
8667 json_object *json_es_info = NULL;
8668
8669 json_object_string_add(
8670 json_path, "esi",
8671 esi_buf);
8672 if (es_local || bgp_evpn_attr_is_sync(attr)) {
8673 json_es_info = json_object_new_object();
8674 if (es_local)
8675 json_object_boolean_true_add(
8676 json_es_info, "localEs");
8677 if (peer_active)
8678 json_object_boolean_true_add(
8679 json_es_info, "peerActive");
8680 if (peer_proxy)
8681 json_object_boolean_true_add(
8682 json_es_info, "peerProxy");
8683 if (peer_router)
8684 json_object_boolean_true_add(
8685 json_es_info, "peerRouter");
8686 if (attr->mm_sync_seqnum)
8687 json_object_int_add(
8688 json_es_info, "peerSeq",
8689 attr->mm_sync_seqnum);
8690 json_object_object_add(
8691 json_path, "es_info",
8692 json_es_info);
8693 }
8694 } else {
8695 if (bgp_evpn_attr_is_sync(attr))
8696 vty_out(vty,
8697 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
8698 esi_buf,
8699 es_local ? "local-es":"",
8700 peer_proxy ? "proxy " : "",
8701 peer_active ? "active ":"",
8702 peer_router ? "router ":"",
8703 attr->mm_sync_seqnum);
8704 else
8705 vty_out(vty, " ESI %s %s\n",
8706 esi_buf,
8707 es_local ? "local-es":"");
8708 }
8709 }
8710
8711 void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
8712 struct bgp_dest *bn, struct bgp_path_info *path,
8713 afi_t afi, safi_t safi, json_object *json_paths)
8714 {
8715 char buf[INET6_ADDRSTRLEN];
8716 char buf1[BUFSIZ];
8717 char buf2[EVPN_ROUTE_STRLEN];
8718 struct attr *attr = path->attr;
8719 int sockunion_vty_out(struct vty *, union sockunion *);
8720 time_t tbuf;
8721 json_object *json_bestpath = NULL;
8722 json_object *json_cluster_list = NULL;
8723 json_object *json_cluster_list_list = NULL;
8724 json_object *json_ext_community = NULL;
8725 json_object *json_last_update = NULL;
8726 json_object *json_pmsi = NULL;
8727 json_object *json_nexthop_global = NULL;
8728 json_object *json_nexthop_ll = NULL;
8729 json_object *json_nexthops = NULL;
8730 json_object *json_path = NULL;
8731 json_object *json_peer = NULL;
8732 json_object *json_string = NULL;
8733 json_object *json_adv_to = NULL;
8734 int first = 0;
8735 struct listnode *node, *nnode;
8736 struct peer *peer;
8737 int addpath_capable;
8738 int has_adj;
8739 unsigned int first_as;
8740 bool nexthop_self =
8741 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8742 int i;
8743 char *nexthop_hostname =
8744 bgp_nexthop_hostname(path->peer, path->nexthop);
8745
8746 if (json_paths) {
8747 json_path = json_object_new_object();
8748 json_peer = json_object_new_object();
8749 json_nexthop_global = json_object_new_object();
8750 }
8751
8752 if (path->extra) {
8753 char tag_buf[30];
8754
8755 buf2[0] = '\0';
8756 tag_buf[0] = '\0';
8757 if (path->extra && path->extra->num_labels) {
8758 bgp_evpn_label2str(path->extra->label,
8759 path->extra->num_labels, tag_buf,
8760 sizeof(tag_buf));
8761 }
8762 if (safi == SAFI_EVPN) {
8763 if (!json_paths) {
8764 bgp_evpn_route2str(
8765 (struct prefix_evpn *)
8766 bgp_dest_get_prefix(bn),
8767 buf2, sizeof(buf2));
8768 vty_out(vty, " Route %s", buf2);
8769 if (tag_buf[0] != '\0')
8770 vty_out(vty, " VNI %s", tag_buf);
8771 vty_out(vty, "\n");
8772 } else {
8773 if (tag_buf[0])
8774 json_object_string_add(json_path, "VNI",
8775 tag_buf);
8776 }
8777 }
8778
8779 if (path->extra && path->extra->parent && !json_paths) {
8780 struct bgp_path_info *parent_ri;
8781 struct bgp_dest *dest, *pdest;
8782
8783 parent_ri = (struct bgp_path_info *)path->extra->parent;
8784 dest = parent_ri->net;
8785 if (dest && dest->pdest) {
8786 pdest = dest->pdest;
8787 prefix_rd2str(
8788 (struct prefix_rd *)bgp_dest_get_prefix(
8789 pdest),
8790 buf1, sizeof(buf1));
8791 if (is_pi_family_evpn(parent_ri)) {
8792 bgp_evpn_route2str(
8793 (struct prefix_evpn *)
8794 bgp_dest_get_prefix(
8795 dest),
8796 buf2, sizeof(buf2));
8797 vty_out(vty, " Imported from %s:%s, VNI %s\n", buf1, buf2, tag_buf);
8798 } else
8799 vty_out(vty, " Imported from %s:%s\n", buf1, buf2);
8800 }
8801 }
8802 }
8803
8804 /* Line1 display AS-path, Aggregator */
8805 if (attr->aspath) {
8806 if (json_paths) {
8807 if (!attr->aspath->json)
8808 aspath_str_update(attr->aspath, true);
8809 json_object_lock(attr->aspath->json);
8810 json_object_object_add(json_path, "aspath",
8811 attr->aspath->json);
8812 } else {
8813 if (attr->aspath->segments)
8814 aspath_print_vty(vty, " %s", attr->aspath, "");
8815 else
8816 vty_out(vty, " Local");
8817 }
8818 }
8819
8820 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
8821 if (json_paths)
8822 json_object_boolean_true_add(json_path, "removed");
8823 else
8824 vty_out(vty, ", (removed)");
8825 }
8826
8827 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
8828 if (json_paths)
8829 json_object_boolean_true_add(json_path, "stale");
8830 else
8831 vty_out(vty, ", (stale)");
8832 }
8833
8834 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
8835 if (json_paths) {
8836 json_object_int_add(json_path, "aggregatorAs",
8837 attr->aggregator_as);
8838 json_object_string_add(
8839 json_path, "aggregatorId",
8840 inet_ntoa(attr->aggregator_addr));
8841 if (attr->aggregator_as == BGP_AS_ZERO)
8842 json_object_boolean_true_add(
8843 json_path, "aggregatorAsMalformed");
8844 else
8845 json_object_boolean_false_add(
8846 json_path, "aggregatorAsMalformed");
8847 } else {
8848 if (attr->aggregator_as == BGP_AS_ZERO)
8849 vty_out(vty,
8850 ", (aggregated by %u(malformed) %s)",
8851 attr->aggregator_as,
8852 inet_ntoa(attr->aggregator_addr));
8853 else
8854 vty_out(vty, ", (aggregated by %u %s)",
8855 attr->aggregator_as,
8856 inet_ntoa(attr->aggregator_addr));
8857 }
8858 }
8859
8860 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
8861 PEER_FLAG_REFLECTOR_CLIENT)) {
8862 if (json_paths)
8863 json_object_boolean_true_add(json_path,
8864 "rxedFromRrClient");
8865 else
8866 vty_out(vty, ", (Received from a RR-client)");
8867 }
8868
8869 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
8870 PEER_FLAG_RSERVER_CLIENT)) {
8871 if (json_paths)
8872 json_object_boolean_true_add(json_path,
8873 "rxedFromRsClient");
8874 else
8875 vty_out(vty, ", (Received from a RS-client)");
8876 }
8877
8878 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8879 if (json_paths)
8880 json_object_boolean_true_add(json_path,
8881 "dampeningHistoryEntry");
8882 else
8883 vty_out(vty, ", (history entry)");
8884 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
8885 if (json_paths)
8886 json_object_boolean_true_add(json_path,
8887 "dampeningSuppressed");
8888 else
8889 vty_out(vty, ", (suppressed due to dampening)");
8890 }
8891
8892 if (!json_paths)
8893 vty_out(vty, "\n");
8894
8895 /* Line2 display Next-hop, Neighbor, Router-id */
8896 /* Display the nexthop */
8897 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
8898
8899 if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET
8900 || bn_p->family == AF_EVPN)
8901 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
8902 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8903 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8904 || safi == SAFI_EVPN) {
8905 if (json_paths) {
8906 json_object_string_add(
8907 json_nexthop_global, "ip",
8908 inet_ntoa(attr->mp_nexthop_global_in));
8909
8910 if (path->peer->hostname)
8911 json_object_string_add(
8912 json_nexthop_global, "hostname",
8913 path->peer->hostname);
8914 } else {
8915 if (nexthop_hostname)
8916 vty_out(vty, " %pI4(%s)",
8917 &attr->mp_nexthop_global_in,
8918 nexthop_hostname);
8919 else
8920 vty_out(vty, " %pI4",
8921 &attr->mp_nexthop_global_in);
8922 }
8923 } else {
8924 if (json_paths) {
8925 json_object_string_add(
8926 json_nexthop_global, "ip",
8927 inet_ntoa(attr->nexthop));
8928
8929 if (path->peer->hostname)
8930 json_object_string_add(
8931 json_nexthop_global, "hostname",
8932 path->peer->hostname);
8933 } else {
8934 if (nexthop_hostname)
8935 vty_out(vty, " %pI4(%s)",
8936 &attr->nexthop,
8937 nexthop_hostname);
8938 else
8939 vty_out(vty, " %pI4",
8940 &attr->nexthop);
8941 }
8942 }
8943
8944 if (json_paths)
8945 json_object_string_add(json_nexthop_global, "afi",
8946 "ipv4");
8947 } else {
8948 if (json_paths) {
8949 json_object_string_add(
8950 json_nexthop_global, "ip",
8951 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
8952 buf, INET6_ADDRSTRLEN));
8953
8954 if (path->peer->hostname)
8955 json_object_string_add(json_nexthop_global,
8956 "hostname",
8957 path->peer->hostname);
8958
8959 json_object_string_add(json_nexthop_global, "afi",
8960 "ipv6");
8961 json_object_string_add(json_nexthop_global, "scope",
8962 "global");
8963 } else {
8964 if (nexthop_hostname)
8965 vty_out(vty, " %pI6(%s)",
8966 &attr->mp_nexthop_global,
8967 nexthop_hostname);
8968 else
8969 vty_out(vty, " %pI6",
8970 &attr->mp_nexthop_global);
8971 }
8972 }
8973
8974 /* Display the IGP cost or 'inaccessible' */
8975 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
8976 if (json_paths)
8977 json_object_boolean_false_add(json_nexthop_global,
8978 "accessible");
8979 else
8980 vty_out(vty, " (inaccessible)");
8981 } else {
8982 if (path->extra && path->extra->igpmetric) {
8983 if (json_paths)
8984 json_object_int_add(json_nexthop_global,
8985 "metric",
8986 path->extra->igpmetric);
8987 else
8988 vty_out(vty, " (metric %u)",
8989 path->extra->igpmetric);
8990 }
8991
8992 /* IGP cost is 0, display this only for json */
8993 else {
8994 if (json_paths)
8995 json_object_int_add(json_nexthop_global,
8996 "metric", 0);
8997 }
8998
8999 if (json_paths)
9000 json_object_boolean_true_add(json_nexthop_global,
9001 "accessible");
9002 }
9003
9004 /* Display peer "from" output */
9005 /* This path was originated locally */
9006 if (path->peer == bgp->peer_self) {
9007
9008 if (safi == SAFI_EVPN
9009 || (bn_p->family == AF_INET
9010 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9011 if (json_paths)
9012 json_object_string_add(json_peer, "peerId",
9013 "0.0.0.0");
9014 else
9015 vty_out(vty, " from 0.0.0.0 ");
9016 } else {
9017 if (json_paths)
9018 json_object_string_add(json_peer, "peerId",
9019 "::");
9020 else
9021 vty_out(vty, " from :: ");
9022 }
9023
9024 if (json_paths)
9025 json_object_string_add(json_peer, "routerId",
9026 inet_ntoa(bgp->router_id));
9027 else
9028 vty_out(vty, "(%s)", inet_ntoa(bgp->router_id));
9029 }
9030
9031 /* We RXed this path from one of our peers */
9032 else {
9033
9034 if (json_paths) {
9035 json_object_string_add(json_peer, "peerId",
9036 sockunion2str(&path->peer->su,
9037 buf,
9038 SU_ADDRSTRLEN));
9039 json_object_string_add(json_peer, "routerId",
9040 inet_ntop(AF_INET,
9041 &path->peer->remote_id,
9042 buf1, sizeof(buf1)));
9043
9044 if (path->peer->hostname)
9045 json_object_string_add(json_peer, "hostname",
9046 path->peer->hostname);
9047
9048 if (path->peer->domainname)
9049 json_object_string_add(json_peer, "domainname",
9050 path->peer->domainname);
9051
9052 if (path->peer->conf_if)
9053 json_object_string_add(json_peer, "interface",
9054 path->peer->conf_if);
9055 } else {
9056 if (path->peer->conf_if) {
9057 if (path->peer->hostname
9058 && CHECK_FLAG(path->peer->bgp->flags,
9059 BGP_FLAG_SHOW_HOSTNAME))
9060 vty_out(vty, " from %s(%s)",
9061 path->peer->hostname,
9062 path->peer->conf_if);
9063 else
9064 vty_out(vty, " from %s",
9065 path->peer->conf_if);
9066 } else {
9067 if (path->peer->hostname
9068 && CHECK_FLAG(path->peer->bgp->flags,
9069 BGP_FLAG_SHOW_HOSTNAME))
9070 vty_out(vty, " from %s(%s)",
9071 path->peer->hostname,
9072 path->peer->host);
9073 else
9074 vty_out(vty, " from %s",
9075 sockunion2str(&path->peer->su,
9076 buf,
9077 SU_ADDRSTRLEN));
9078 }
9079
9080 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
9081 vty_out(vty, " (%s)",
9082 inet_ntoa(attr->originator_id));
9083 else
9084 vty_out(vty, " (%s)",
9085 inet_ntop(AF_INET,
9086 &path->peer->remote_id, buf1,
9087 sizeof(buf1)));
9088 }
9089 }
9090
9091 /*
9092 * Note when vrfid of nexthop is different from that of prefix
9093 */
9094 if (path->extra && path->extra->bgp_orig) {
9095 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9096
9097 if (json_paths) {
9098 const char *vn;
9099
9100 if (path->extra->bgp_orig->inst_type
9101 == BGP_INSTANCE_TYPE_DEFAULT)
9102 vn = VRF_DEFAULT_NAME;
9103 else
9104 vn = path->extra->bgp_orig->name;
9105
9106 json_object_string_add(json_path, "nhVrfName", vn);
9107
9108 if (nexthop_vrfid == VRF_UNKNOWN) {
9109 json_object_int_add(json_path, "nhVrfId", -1);
9110 } else {
9111 json_object_int_add(json_path, "nhVrfId",
9112 (int)nexthop_vrfid);
9113 }
9114 } else {
9115 if (nexthop_vrfid == VRF_UNKNOWN)
9116 vty_out(vty, " vrf ?");
9117 else {
9118 struct vrf *vrf;
9119
9120 vrf = vrf_lookup_by_id(nexthop_vrfid);
9121 vty_out(vty, " vrf %s(%u)",
9122 VRF_LOGNAME(vrf), nexthop_vrfid);
9123 }
9124 }
9125 }
9126
9127 if (nexthop_self) {
9128 if (json_paths) {
9129 json_object_boolean_true_add(json_path,
9130 "announceNexthopSelf");
9131 } else {
9132 vty_out(vty, " announce-nh-self");
9133 }
9134 }
9135
9136 if (!json_paths)
9137 vty_out(vty, "\n");
9138
9139 /* display the link-local nexthop */
9140 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9141 if (json_paths) {
9142 json_nexthop_ll = json_object_new_object();
9143 json_object_string_add(
9144 json_nexthop_ll, "ip",
9145 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
9146 buf, INET6_ADDRSTRLEN));
9147
9148 if (path->peer->hostname)
9149 json_object_string_add(json_nexthop_ll,
9150 "hostname",
9151 path->peer->hostname);
9152
9153 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
9154 json_object_string_add(json_nexthop_ll, "scope",
9155 "link-local");
9156
9157 json_object_boolean_true_add(json_nexthop_ll,
9158 "accessible");
9159
9160 if (!attr->mp_nexthop_prefer_global)
9161 json_object_boolean_true_add(json_nexthop_ll,
9162 "used");
9163 else
9164 json_object_boolean_true_add(
9165 json_nexthop_global, "used");
9166 } else {
9167 vty_out(vty, " (%s) %s\n",
9168 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
9169 buf, INET6_ADDRSTRLEN),
9170 attr->mp_nexthop_prefer_global
9171 ? "(prefer-global)"
9172 : "(used)");
9173 }
9174 }
9175 /* If we do not have a link-local nexthop then we must flag the
9176 global as "used" */
9177 else {
9178 if (json_paths)
9179 json_object_boolean_true_add(json_nexthop_global,
9180 "used");
9181 }
9182
9183 if (safi == SAFI_EVPN &&
9184 bgp_evpn_is_esi_valid(&attr->esi)) {
9185 route_vty_out_detail_es_info(vty, attr, json_path);
9186 }
9187
9188 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
9189 * Int/Ext/Local, Atomic, best */
9190 if (json_paths)
9191 json_object_string_add(json_path, "origin",
9192 bgp_origin_long_str[attr->origin]);
9193 else
9194 vty_out(vty, " Origin %s",
9195 bgp_origin_long_str[attr->origin]);
9196
9197 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
9198 if (json_paths)
9199 json_object_int_add(json_path, "metric", attr->med);
9200 else
9201 vty_out(vty, ", metric %u", attr->med);
9202 }
9203
9204 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
9205 if (json_paths)
9206 json_object_int_add(json_path, "locPrf",
9207 attr->local_pref);
9208 else
9209 vty_out(vty, ", localpref %u", attr->local_pref);
9210 }
9211
9212 if (attr->weight != 0) {
9213 if (json_paths)
9214 json_object_int_add(json_path, "weight", attr->weight);
9215 else
9216 vty_out(vty, ", weight %u", attr->weight);
9217 }
9218
9219 if (attr->tag != 0) {
9220 if (json_paths)
9221 json_object_int_add(json_path, "tag", attr->tag);
9222 else
9223 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
9224 }
9225
9226 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
9227 if (json_paths)
9228 json_object_boolean_false_add(json_path, "valid");
9229 else
9230 vty_out(vty, ", invalid");
9231 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
9232 if (json_paths)
9233 json_object_boolean_true_add(json_path, "valid");
9234 else
9235 vty_out(vty, ", valid");
9236 }
9237
9238 if (path->peer != bgp->peer_self) {
9239 if (path->peer->as == path->peer->local_as) {
9240 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
9241 if (json_paths)
9242 json_object_string_add(
9243 json_peer, "type",
9244 "confed-internal");
9245 else
9246 vty_out(vty, ", confed-internal");
9247 } else {
9248 if (json_paths)
9249 json_object_string_add(
9250 json_peer, "type", "internal");
9251 else
9252 vty_out(vty, ", internal");
9253 }
9254 } else {
9255 if (bgp_confederation_peers_check(bgp,
9256 path->peer->as)) {
9257 if (json_paths)
9258 json_object_string_add(
9259 json_peer, "type",
9260 "confed-external");
9261 else
9262 vty_out(vty, ", confed-external");
9263 } else {
9264 if (json_paths)
9265 json_object_string_add(
9266 json_peer, "type", "external");
9267 else
9268 vty_out(vty, ", external");
9269 }
9270 }
9271 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
9272 if (json_paths) {
9273 json_object_boolean_true_add(json_path, "aggregated");
9274 json_object_boolean_true_add(json_path, "local");
9275 } else {
9276 vty_out(vty, ", aggregated, local");
9277 }
9278 } else if (path->type != ZEBRA_ROUTE_BGP) {
9279 if (json_paths)
9280 json_object_boolean_true_add(json_path, "sourced");
9281 else
9282 vty_out(vty, ", sourced");
9283 } else {
9284 if (json_paths) {
9285 json_object_boolean_true_add(json_path, "sourced");
9286 json_object_boolean_true_add(json_path, "local");
9287 } else {
9288 vty_out(vty, ", sourced, local");
9289 }
9290 }
9291
9292 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
9293 if (json_paths)
9294 json_object_boolean_true_add(json_path,
9295 "atomicAggregate");
9296 else
9297 vty_out(vty, ", atomic-aggregate");
9298 }
9299
9300 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
9301 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
9302 && bgp_path_info_mpath_count(path))) {
9303 if (json_paths)
9304 json_object_boolean_true_add(json_path, "multipath");
9305 else
9306 vty_out(vty, ", multipath");
9307 }
9308
9309 // Mark the bestpath(s)
9310 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
9311 first_as = aspath_get_first_as(attr->aspath);
9312
9313 if (json_paths) {
9314 if (!json_bestpath)
9315 json_bestpath = json_object_new_object();
9316 json_object_int_add(json_bestpath, "bestpathFromAs",
9317 first_as);
9318 } else {
9319 if (first_as)
9320 vty_out(vty, ", bestpath-from-AS %u", first_as);
9321 else
9322 vty_out(vty, ", bestpath-from-AS Local");
9323 }
9324 }
9325
9326 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9327 if (json_paths) {
9328 if (!json_bestpath)
9329 json_bestpath = json_object_new_object();
9330 json_object_boolean_true_add(json_bestpath, "overall");
9331 json_object_string_add(
9332 json_bestpath, "selectionReason",
9333 bgp_path_selection_reason2str(bn->reason));
9334 } else {
9335 vty_out(vty, ", best");
9336 vty_out(vty, " (%s)",
9337 bgp_path_selection_reason2str(bn->reason));
9338 }
9339 }
9340
9341 if (json_bestpath)
9342 json_object_object_add(json_path, "bestpath", json_bestpath);
9343
9344 if (!json_paths)
9345 vty_out(vty, "\n");
9346
9347 /* Line 4 display Community */
9348 if (attr->community) {
9349 if (json_paths) {
9350 if (!attr->community->json)
9351 community_str(attr->community, true);
9352 json_object_lock(attr->community->json);
9353 json_object_object_add(json_path, "community",
9354 attr->community->json);
9355 } else {
9356 vty_out(vty, " Community: %s\n",
9357 attr->community->str);
9358 }
9359 }
9360
9361 /* Line 5 display Extended-community */
9362 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9363 if (json_paths) {
9364 json_ext_community = json_object_new_object();
9365 json_object_string_add(json_ext_community, "string",
9366 attr->ecommunity->str);
9367 json_object_object_add(json_path, "extendedCommunity",
9368 json_ext_community);
9369 } else {
9370 vty_out(vty, " Extended Community: %s\n",
9371 attr->ecommunity->str);
9372 }
9373 }
9374
9375 /* Line 6 display Large community */
9376 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
9377 if (json_paths) {
9378 if (!attr->lcommunity->json)
9379 lcommunity_str(attr->lcommunity, true);
9380 json_object_lock(attr->lcommunity->json);
9381 json_object_object_add(json_path, "largeCommunity",
9382 attr->lcommunity->json);
9383 } else {
9384 vty_out(vty, " Large Community: %s\n",
9385 attr->lcommunity->str);
9386 }
9387 }
9388
9389 /* Line 7 display Originator, Cluster-id */
9390 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
9391 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
9392 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
9393 if (json_paths)
9394 json_object_string_add(
9395 json_path, "originatorId",
9396 inet_ntoa(attr->originator_id));
9397 else
9398 vty_out(vty, " Originator: %s",
9399 inet_ntoa(attr->originator_id));
9400 }
9401
9402 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
9403 int i;
9404
9405 if (json_paths) {
9406 json_cluster_list = json_object_new_object();
9407 json_cluster_list_list =
9408 json_object_new_array();
9409
9410 for (i = 0; i < attr->cluster->length / 4;
9411 i++) {
9412 json_string = json_object_new_string(
9413 inet_ntoa(attr->cluster
9414 ->list[i]));
9415 json_object_array_add(
9416 json_cluster_list_list,
9417 json_string);
9418 }
9419
9420 /*
9421 * struct cluster_list does not have
9422 * "str" variable like aspath and community
9423 * do. Add this someday if someone asks
9424 * for it.
9425 * json_object_string_add(json_cluster_list,
9426 * "string", attr->cluster->str);
9427 */
9428 json_object_object_add(json_cluster_list,
9429 "list",
9430 json_cluster_list_list);
9431 json_object_object_add(json_path, "clusterList",
9432 json_cluster_list);
9433 } else {
9434 vty_out(vty, ", Cluster list: ");
9435
9436 for (i = 0; i < attr->cluster->length / 4;
9437 i++) {
9438 vty_out(vty, "%s ",
9439 inet_ntoa(attr->cluster
9440 ->list[i]));
9441 }
9442 }
9443 }
9444
9445 if (!json_paths)
9446 vty_out(vty, "\n");
9447 }
9448
9449 if (path->extra && path->extra->damp_info)
9450 bgp_damp_info_vty(vty, path, afi, safi, json_path);
9451
9452 /* Remote Label */
9453 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
9454 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
9455 mpls_label_t label = label_pton(&path->extra->label[0]);
9456
9457 if (json_paths)
9458 json_object_int_add(json_path, "remoteLabel", label);
9459 else
9460 vty_out(vty, " Remote label: %d\n", label);
9461 }
9462
9463 /* Remote SID */
9464 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
9465 inet_ntop(AF_INET6, &path->extra->sid, buf, sizeof(buf));
9466 if (json_paths)
9467 json_object_string_add(json_path, "remoteSid", buf);
9468 else
9469 vty_out(vty, " Remote SID: %s\n", buf);
9470 }
9471
9472 /* Label Index */
9473 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
9474 if (json_paths)
9475 json_object_int_add(json_path, "labelIndex",
9476 attr->label_index);
9477 else
9478 vty_out(vty, " Label Index: %d\n",
9479 attr->label_index);
9480 }
9481
9482 /* Line 8 display Addpath IDs */
9483 if (path->addpath_rx_id
9484 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
9485 if (json_paths) {
9486 json_object_int_add(json_path, "addpathRxId",
9487 path->addpath_rx_id);
9488
9489 /* Keep backwards compatibility with the old API
9490 * by putting TX All's ID in the old field
9491 */
9492 json_object_int_add(
9493 json_path, "addpathTxId",
9494 path->tx_addpath
9495 .addpath_tx_id[BGP_ADDPATH_ALL]);
9496
9497 /* ... but create a specific field for each
9498 * strategy
9499 */
9500 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9501 json_object_int_add(
9502 json_path,
9503 bgp_addpath_names(i)->id_json_name,
9504 path->tx_addpath.addpath_tx_id[i]);
9505 }
9506 } else {
9507 vty_out(vty, " AddPath ID: RX %u, ",
9508 path->addpath_rx_id);
9509
9510 route_vty_out_tx_ids(vty, &path->tx_addpath);
9511 }
9512 }
9513
9514 /* If we used addpath to TX a non-bestpath we need to display
9515 * "Advertised to" on a path-by-path basis
9516 */
9517 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
9518 first = 1;
9519
9520 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
9521 addpath_capable =
9522 bgp_addpath_encode_tx(peer, afi, safi);
9523 has_adj = bgp_adj_out_lookup(
9524 peer, path->net,
9525 bgp_addpath_id_for_peer(peer, afi, safi,
9526 &path->tx_addpath));
9527
9528 if ((addpath_capable && has_adj)
9529 || (!addpath_capable && has_adj
9530 && CHECK_FLAG(path->flags,
9531 BGP_PATH_SELECTED))) {
9532 if (json_path && !json_adv_to)
9533 json_adv_to = json_object_new_object();
9534
9535 route_vty_out_advertised_to(
9536 vty, peer, &first,
9537 " Advertised to:", json_adv_to);
9538 }
9539 }
9540
9541 if (json_path) {
9542 if (json_adv_to) {
9543 json_object_object_add(
9544 json_path, "advertisedTo", json_adv_to);
9545 }
9546 } else {
9547 if (!first) {
9548 vty_out(vty, "\n");
9549 }
9550 }
9551 }
9552
9553 /* Line 9 display Uptime */
9554 tbuf = time(NULL) - (bgp_clock() - path->uptime);
9555 if (json_paths) {
9556 json_last_update = json_object_new_object();
9557 json_object_int_add(json_last_update, "epoch", tbuf);
9558 json_object_string_add(json_last_update, "string",
9559 ctime(&tbuf));
9560 json_object_object_add(json_path, "lastUpdate",
9561 json_last_update);
9562 } else
9563 vty_out(vty, " Last update: %s", ctime(&tbuf));
9564
9565 /* Line 10 display PMSI tunnel attribute, if present */
9566 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
9567 const char *str =
9568 lookup_msg(bgp_pmsi_tnltype_str, attr->pmsi_tnl_type,
9569 PMSI_TNLTYPE_STR_DEFAULT);
9570
9571 if (json_paths) {
9572 json_pmsi = json_object_new_object();
9573 json_object_string_add(json_pmsi, "tunnelType", str);
9574 json_object_int_add(json_pmsi, "label",
9575 label2vni(&attr->label));
9576 json_object_object_add(json_path, "pmsi", json_pmsi);
9577 } else
9578 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
9579 str, label2vni(&attr->label));
9580 }
9581
9582 /* We've constructed the json object for this path, add it to the json
9583 * array of paths
9584 */
9585 if (json_paths) {
9586 if (json_nexthop_global || json_nexthop_ll) {
9587 json_nexthops = json_object_new_array();
9588
9589 if (json_nexthop_global)
9590 json_object_array_add(json_nexthops,
9591 json_nexthop_global);
9592
9593 if (json_nexthop_ll)
9594 json_object_array_add(json_nexthops,
9595 json_nexthop_ll);
9596
9597 json_object_object_add(json_path, "nexthops",
9598 json_nexthops);
9599 }
9600
9601 json_object_object_add(json_path, "peer", json_peer);
9602 json_object_array_add(json_paths, json_path);
9603 }
9604 }
9605
9606 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
9607 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
9608 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
9609
9610 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
9611 const char *prefix_list_str, afi_t afi,
9612 safi_t safi, enum bgp_show_type type);
9613 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
9614 const char *filter, afi_t afi, safi_t safi,
9615 enum bgp_show_type type);
9616 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
9617 const char *rmap_str, afi_t afi, safi_t safi,
9618 enum bgp_show_type type);
9619 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
9620 const char *com, int exact, afi_t afi,
9621 safi_t safi);
9622 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
9623 const char *prefix, afi_t afi, safi_t safi,
9624 enum bgp_show_type type);
9625 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
9626 afi_t afi, safi_t safi, enum bgp_show_type type,
9627 bool use_json);
9628 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
9629 const char *comstr, int exact, afi_t afi,
9630 safi_t safi, uint8_t show_flags);
9631
9632
9633 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
9634 struct bgp_table *table, enum bgp_show_type type,
9635 void *output_arg, char *rd, int is_last,
9636 unsigned long *output_cum, unsigned long *total_cum,
9637 unsigned long *json_header_depth, uint8_t show_flags)
9638 {
9639 struct bgp_path_info *pi;
9640 struct bgp_dest *dest;
9641 int header = 1;
9642 int display;
9643 unsigned long output_count = 0;
9644 unsigned long total_count = 0;
9645 struct prefix *p;
9646 json_object *json_paths = NULL;
9647 int first = 1;
9648 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
9649 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
9650 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
9651
9652 if (output_cum && *output_cum != 0)
9653 header = 0;
9654
9655 if (use_json && !*json_header_depth) {
9656 if (all)
9657 *json_header_depth = 1;
9658 else {
9659 vty_out(vty, "{\n");
9660 *json_header_depth = 2;
9661 }
9662
9663 vty_out(vty,
9664 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n"
9665 " \"localAS\": %u,\n \"routes\": { ",
9666 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
9667 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
9668 ? VRF_DEFAULT_NAME
9669 : bgp->name,
9670 table->version, inet_ntoa(bgp->router_id),
9671 bgp->default_local_pref, bgp->as);
9672 if (rd) {
9673 vty_out(vty, " \"routeDistinguishers\" : {");
9674 ++*json_header_depth;
9675 }
9676 }
9677
9678 if (use_json && rd) {
9679 vty_out(vty, " \"%s\" : { ", rd);
9680 }
9681
9682 /* Start processing of routes. */
9683 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
9684 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
9685
9686 pi = bgp_dest_get_bgp_path_info(dest);
9687 if (pi == NULL)
9688 continue;
9689
9690 display = 0;
9691 if (use_json)
9692 json_paths = json_object_new_array();
9693 else
9694 json_paths = NULL;
9695
9696 for (; pi; pi = pi->next) {
9697 total_count++;
9698 if (type == bgp_show_type_flap_statistics
9699 || type == bgp_show_type_flap_neighbor
9700 || type == bgp_show_type_dampend_paths
9701 || type == bgp_show_type_damp_neighbor) {
9702 if (!(pi->extra && pi->extra->damp_info))
9703 continue;
9704 }
9705 if (type == bgp_show_type_regexp) {
9706 regex_t *regex = output_arg;
9707
9708 if (bgp_regexec(regex, pi->attr->aspath)
9709 == REG_NOMATCH)
9710 continue;
9711 }
9712 if (type == bgp_show_type_prefix_list) {
9713 struct prefix_list *plist = output_arg;
9714
9715 if (prefix_list_apply(plist, dest_p)
9716 != PREFIX_PERMIT)
9717 continue;
9718 }
9719 if (type == bgp_show_type_filter_list) {
9720 struct as_list *as_list = output_arg;
9721
9722 if (as_list_apply(as_list, pi->attr->aspath)
9723 != AS_FILTER_PERMIT)
9724 continue;
9725 }
9726 if (type == bgp_show_type_route_map) {
9727 struct route_map *rmap = output_arg;
9728 struct bgp_path_info path;
9729 struct attr dummy_attr;
9730 route_map_result_t ret;
9731
9732 dummy_attr = *pi->attr;
9733
9734 path.peer = pi->peer;
9735 path.attr = &dummy_attr;
9736
9737 ret = route_map_apply(rmap, dest_p, RMAP_BGP,
9738 &path);
9739 if (ret == RMAP_DENYMATCH)
9740 continue;
9741 }
9742 if (type == bgp_show_type_neighbor
9743 || type == bgp_show_type_flap_neighbor
9744 || type == bgp_show_type_damp_neighbor) {
9745 union sockunion *su = output_arg;
9746
9747 if (pi->peer == NULL
9748 || pi->peer->su_remote == NULL
9749 || !sockunion_same(pi->peer->su_remote, su))
9750 continue;
9751 }
9752 if (type == bgp_show_type_cidr_only) {
9753 uint32_t destination;
9754
9755 destination = ntohl(dest_p->u.prefix4.s_addr);
9756 if (IN_CLASSC(destination)
9757 && dest_p->prefixlen == 24)
9758 continue;
9759 if (IN_CLASSB(destination)
9760 && dest_p->prefixlen == 16)
9761 continue;
9762 if (IN_CLASSA(destination)
9763 && dest_p->prefixlen == 8)
9764 continue;
9765 }
9766 if (type == bgp_show_type_prefix_longer) {
9767 p = output_arg;
9768 if (!prefix_match(p, dest_p))
9769 continue;
9770 }
9771 if (type == bgp_show_type_community_all) {
9772 if (!pi->attr->community)
9773 continue;
9774 }
9775 if (type == bgp_show_type_community) {
9776 struct community *com = output_arg;
9777
9778 if (!pi->attr->community
9779 || !community_match(pi->attr->community,
9780 com))
9781 continue;
9782 }
9783 if (type == bgp_show_type_community_exact) {
9784 struct community *com = output_arg;
9785
9786 if (!pi->attr->community
9787 || !community_cmp(pi->attr->community, com))
9788 continue;
9789 }
9790 if (type == bgp_show_type_community_list) {
9791 struct community_list *list = output_arg;
9792
9793 if (!community_list_match(pi->attr->community,
9794 list))
9795 continue;
9796 }
9797 if (type == bgp_show_type_community_list_exact) {
9798 struct community_list *list = output_arg;
9799
9800 if (!community_list_exact_match(
9801 pi->attr->community, list))
9802 continue;
9803 }
9804 if (type == bgp_show_type_lcommunity) {
9805 struct lcommunity *lcom = output_arg;
9806
9807 if (!pi->attr->lcommunity
9808 || !lcommunity_match(pi->attr->lcommunity,
9809 lcom))
9810 continue;
9811 }
9812
9813 if (type == bgp_show_type_lcommunity_exact) {
9814 struct lcommunity *lcom = output_arg;
9815
9816 if (!pi->attr->lcommunity
9817 || !lcommunity_cmp(pi->attr->lcommunity,
9818 lcom))
9819 continue;
9820 }
9821 if (type == bgp_show_type_lcommunity_list) {
9822 struct community_list *list = output_arg;
9823
9824 if (!lcommunity_list_match(pi->attr->lcommunity,
9825 list))
9826 continue;
9827 }
9828 if (type
9829 == bgp_show_type_lcommunity_list_exact) {
9830 struct community_list *list = output_arg;
9831
9832 if (!lcommunity_list_exact_match(
9833 pi->attr->lcommunity, list))
9834 continue;
9835 }
9836 if (type == bgp_show_type_lcommunity_all) {
9837 if (!pi->attr->lcommunity)
9838 continue;
9839 }
9840 if (type == bgp_show_type_dampend_paths
9841 || type == bgp_show_type_damp_neighbor) {
9842 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
9843 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
9844 continue;
9845 }
9846
9847 if (!use_json && header) {
9848 vty_out(vty, "BGP table version is %" PRIu64", local router ID is %s, vrf id ",
9849 table->version,
9850 inet_ntoa(bgp->router_id));
9851 if (bgp->vrf_id == VRF_UNKNOWN)
9852 vty_out(vty, "%s", VRFID_NONE_STR);
9853 else
9854 vty_out(vty, "%u", bgp->vrf_id);
9855 vty_out(vty, "\n");
9856 vty_out(vty, "Default local pref %u, ",
9857 bgp->default_local_pref);
9858 vty_out(vty, "local AS %u\n", bgp->as);
9859 vty_out(vty, BGP_SHOW_SCODE_HEADER);
9860 vty_out(vty, BGP_SHOW_NCODE_HEADER);
9861 vty_out(vty, BGP_SHOW_OCODE_HEADER);
9862 if (type == bgp_show_type_dampend_paths
9863 || type == bgp_show_type_damp_neighbor)
9864 vty_out(vty, BGP_SHOW_DAMP_HEADER);
9865 else if (type == bgp_show_type_flap_statistics
9866 || type == bgp_show_type_flap_neighbor)
9867 vty_out(vty, BGP_SHOW_FLAP_HEADER);
9868 else
9869 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
9870 : BGP_SHOW_HEADER));
9871 header = 0;
9872 }
9873 if (rd != NULL && !display && !output_count) {
9874 if (!use_json)
9875 vty_out(vty,
9876 "Route Distinguisher: %s\n",
9877 rd);
9878 }
9879 if (type == bgp_show_type_dampend_paths
9880 || type == bgp_show_type_damp_neighbor)
9881 damp_route_vty_out(vty, dest_p, pi, display,
9882 AFI_IP, safi, use_json,
9883 json_paths);
9884 else if (type == bgp_show_type_flap_statistics
9885 || type == bgp_show_type_flap_neighbor)
9886 flap_route_vty_out(vty, dest_p, pi, display,
9887 AFI_IP, safi, use_json,
9888 json_paths);
9889 else
9890 route_vty_out(vty, dest_p, pi, display, safi,
9891 json_paths, wide);
9892 display++;
9893 }
9894
9895 if (display) {
9896 output_count++;
9897 if (!use_json)
9898 continue;
9899
9900 /* encode prefix */
9901 if (dest_p->family == AF_FLOWSPEC) {
9902 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
9903
9904
9905 bgp_fs_nlri_get_string(
9906 (unsigned char *)
9907 dest_p->u.prefix_flowspec.ptr,
9908 dest_p->u.prefix_flowspec.prefixlen,
9909 retstr, NLRI_STRING_FORMAT_MIN, NULL,
9910 family2afi(dest_p->u
9911 .prefix_flowspec.family));
9912 if (first)
9913 vty_out(vty, "\"%s/%d\": ", retstr,
9914 dest_p->u.prefix_flowspec
9915 .prefixlen);
9916 else
9917 vty_out(vty, ",\"%s/%d\": ", retstr,
9918 dest_p->u.prefix_flowspec
9919 .prefixlen);
9920 } else {
9921 if (first)
9922 vty_out(vty, "\"%pFX\": ", dest_p);
9923 else
9924 vty_out(vty, ",\"%pFX\": ", dest_p);
9925 }
9926 vty_out(vty, "%s",
9927 json_object_to_json_string_ext(
9928 json_paths, JSON_C_TO_STRING_PRETTY));
9929 json_object_free(json_paths);
9930 json_paths = NULL;
9931 first = 0;
9932 } else
9933 json_object_free(json_paths);
9934 }
9935
9936 if (output_cum) {
9937 output_count += *output_cum;
9938 *output_cum = output_count;
9939 }
9940 if (total_cum) {
9941 total_count += *total_cum;
9942 *total_cum = total_count;
9943 }
9944 if (use_json) {
9945 if (rd) {
9946 vty_out(vty, " }%s ", (is_last ? "" : ","));
9947 }
9948 if (is_last) {
9949 unsigned long i;
9950 for (i = 0; i < *json_header_depth; ++i)
9951 vty_out(vty, " } ");
9952 if (!all)
9953 vty_out(vty, "\n");
9954 }
9955 } else {
9956 if (is_last) {
9957 /* No route is displayed */
9958 if (output_count == 0) {
9959 if (type == bgp_show_type_normal)
9960 vty_out(vty,
9961 "No BGP prefixes displayed, %ld exist\n",
9962 total_count);
9963 } else
9964 vty_out(vty,
9965 "\nDisplayed %ld routes and %ld total paths\n",
9966 output_count, total_count);
9967 }
9968 }
9969
9970 return CMD_SUCCESS;
9971 }
9972
9973 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
9974 struct bgp_table *table, struct prefix_rd *prd_match,
9975 enum bgp_show_type type, void *output_arg, bool use_json)
9976 {
9977 struct bgp_dest *dest, *next;
9978 unsigned long output_cum = 0;
9979 unsigned long total_cum = 0;
9980 unsigned long json_header_depth = 0;
9981 struct bgp_table *itable;
9982 bool show_msg;
9983 uint8_t show_flags = 0;
9984
9985 show_msg = (!use_json && type == bgp_show_type_normal);
9986
9987 if (use_json)
9988 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
9989
9990 for (dest = bgp_table_top(table); dest; dest = next) {
9991 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
9992
9993 next = bgp_route_next(dest);
9994 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
9995 continue;
9996
9997 itable = bgp_dest_get_bgp_table_info(dest);
9998 if (itable != NULL) {
9999 struct prefix_rd prd;
10000 char rd[RD_ADDRSTRLEN];
10001
10002 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
10003 prefix_rd2str(&prd, rd, sizeof(rd));
10004 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
10005 rd, next == NULL, &output_cum,
10006 &total_cum, &json_header_depth,
10007 show_flags);
10008 if (next == NULL)
10009 show_msg = false;
10010 }
10011 }
10012 if (show_msg) {
10013 if (output_cum == 0)
10014 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
10015 total_cum);
10016 else
10017 vty_out(vty,
10018 "\nDisplayed %ld routes and %ld total paths\n",
10019 output_cum, total_cum);
10020 }
10021 return CMD_SUCCESS;
10022 }
10023 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
10024 enum bgp_show_type type, void *output_arg,
10025 uint8_t show_flags)
10026 {
10027 struct bgp_table *table;
10028 unsigned long json_header_depth = 0;
10029 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10030
10031 if (bgp == NULL) {
10032 bgp = bgp_get_default();
10033 }
10034
10035 if (bgp == NULL) {
10036 if (!use_json)
10037 vty_out(vty, "No BGP process is configured\n");
10038 else
10039 vty_out(vty, "{}\n");
10040 return CMD_WARNING;
10041 }
10042
10043 table = bgp->rib[afi][safi];
10044 /* use MPLS and ENCAP specific shows until they are merged */
10045 if (safi == SAFI_MPLS_VPN) {
10046 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
10047 output_arg, use_json);
10048 }
10049
10050 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
10051 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
10052 output_arg, use_json,
10053 1, NULL, NULL);
10054 }
10055 /* labeled-unicast routes live in the unicast table */
10056 else if (safi == SAFI_LABELED_UNICAST)
10057 safi = SAFI_UNICAST;
10058
10059 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
10060 NULL, NULL, &json_header_depth, show_flags);
10061 }
10062
10063 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
10064 safi_t safi, uint8_t show_flags)
10065 {
10066 struct listnode *node, *nnode;
10067 struct bgp *bgp;
10068 int is_first = 1;
10069 bool route_output = false;
10070 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10071
10072 if (use_json)
10073 vty_out(vty, "{\n");
10074
10075 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
10076 route_output = true;
10077 if (use_json) {
10078 if (!is_first)
10079 vty_out(vty, ",\n");
10080 else
10081 is_first = 0;
10082
10083 vty_out(vty, "\"%s\":",
10084 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
10085 ? VRF_DEFAULT_NAME
10086 : bgp->name);
10087 } else {
10088 vty_out(vty, "\nInstance %s:\n",
10089 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
10090 ? VRF_DEFAULT_NAME
10091 : bgp->name);
10092 }
10093 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
10094 show_flags);
10095 }
10096
10097 if (use_json)
10098 vty_out(vty, "}\n");
10099 else if (!route_output)
10100 vty_out(vty, "%% BGP instance not found\n");
10101 }
10102
10103 /* Header of detailed BGP route information */
10104 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
10105 struct bgp_dest *dest, struct prefix_rd *prd,
10106 afi_t afi, safi_t safi, json_object *json)
10107 {
10108 struct bgp_path_info *pi;
10109 const struct prefix *p;
10110 struct peer *peer;
10111 struct listnode *node, *nnode;
10112 char buf1[RD_ADDRSTRLEN];
10113 char buf2[INET6_ADDRSTRLEN];
10114 char buf3[EVPN_ROUTE_STRLEN];
10115 char prefix_str[BUFSIZ];
10116 int count = 0;
10117 int best = 0;
10118 int suppress = 0;
10119 int accept_own = 0;
10120 int route_filter_translated_v4 = 0;
10121 int route_filter_v4 = 0;
10122 int route_filter_translated_v6 = 0;
10123 int route_filter_v6 = 0;
10124 int llgr_stale = 0;
10125 int no_llgr = 0;
10126 int accept_own_nexthop = 0;
10127 int blackhole = 0;
10128 int no_export = 0;
10129 int no_advertise = 0;
10130 int local_as = 0;
10131 int no_peer = 0;
10132 int first = 1;
10133 int has_valid_label = 0;
10134 mpls_label_t label = 0;
10135 json_object *json_adv_to = NULL;
10136
10137 p = bgp_dest_get_prefix(dest);
10138 has_valid_label = bgp_is_valid_label(&dest->local_label);
10139
10140 if (has_valid_label)
10141 label = label_pton(&dest->local_label);
10142
10143 if (safi == SAFI_EVPN) {
10144
10145 if (!json) {
10146 vty_out(vty, "BGP routing table entry for %s%s%s\n",
10147 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
10148 : "", prd ? ":" : "",
10149 bgp_evpn_route2str((struct prefix_evpn *)p,
10150 buf3, sizeof(buf3)));
10151 } else {
10152 json_object_string_add(json, "rd",
10153 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
10154 "");
10155 bgp_evpn_route2json((struct prefix_evpn *)p, json);
10156 }
10157 } else {
10158 if (!json) {
10159 vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
10160 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
10161 ? prefix_rd2str(prd, buf1,
10162 sizeof(buf1))
10163 : ""),
10164 safi == SAFI_MPLS_VPN ? ":" : "",
10165 inet_ntop(p->family, &p->u.prefix, buf2,
10166 INET6_ADDRSTRLEN),
10167 p->prefixlen);
10168
10169 } else
10170 json_object_string_add(json, "prefix",
10171 prefix2str(p, prefix_str, sizeof(prefix_str)));
10172 }
10173
10174 if (has_valid_label) {
10175 if (json)
10176 json_object_int_add(json, "localLabel", label);
10177 else
10178 vty_out(vty, "Local label: %d\n", label);
10179 }
10180
10181 if (!json)
10182 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
10183 vty_out(vty, "not allocated\n");
10184
10185 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
10186 count++;
10187 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
10188 best = count;
10189 if (pi->extra && pi->extra->suppress)
10190 suppress = 1;
10191
10192 if (pi->attr->community == NULL)
10193 continue;
10194
10195 no_advertise += community_include(
10196 pi->attr->community, COMMUNITY_NO_ADVERTISE);
10197 no_export += community_include(pi->attr->community,
10198 COMMUNITY_NO_EXPORT);
10199 local_as += community_include(pi->attr->community,
10200 COMMUNITY_LOCAL_AS);
10201 accept_own += community_include(pi->attr->community,
10202 COMMUNITY_ACCEPT_OWN);
10203 route_filter_translated_v4 += community_include(
10204 pi->attr->community,
10205 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
10206 route_filter_translated_v6 += community_include(
10207 pi->attr->community,
10208 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
10209 route_filter_v4 += community_include(
10210 pi->attr->community, COMMUNITY_ROUTE_FILTER_v4);
10211 route_filter_v6 += community_include(
10212 pi->attr->community, COMMUNITY_ROUTE_FILTER_v6);
10213 llgr_stale += community_include(pi->attr->community,
10214 COMMUNITY_LLGR_STALE);
10215 no_llgr += community_include(pi->attr->community,
10216 COMMUNITY_NO_LLGR);
10217 accept_own_nexthop +=
10218 community_include(pi->attr->community,
10219 COMMUNITY_ACCEPT_OWN_NEXTHOP);
10220 blackhole += community_include(pi->attr->community,
10221 COMMUNITY_BLACKHOLE);
10222 no_peer += community_include(pi->attr->community,
10223 COMMUNITY_NO_PEER);
10224 }
10225 }
10226
10227 if (!json) {
10228 vty_out(vty, "Paths: (%d available", count);
10229 if (best) {
10230 vty_out(vty, ", best #%d", best);
10231 if (safi == SAFI_UNICAST) {
10232 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
10233 vty_out(vty, ", table %s",
10234 VRF_DEFAULT_NAME);
10235 else
10236 vty_out(vty, ", vrf %s",
10237 bgp->name);
10238 }
10239 } else
10240 vty_out(vty, ", no best path");
10241
10242 if (accept_own)
10243 vty_out(vty,
10244 ", accept own local route exported and imported in different VRF");
10245 else if (route_filter_translated_v4)
10246 vty_out(vty,
10247 ", mark translated RTs for VPNv4 route filtering");
10248 else if (route_filter_v4)
10249 vty_out(vty,
10250 ", attach RT as-is for VPNv4 route filtering");
10251 else if (route_filter_translated_v6)
10252 vty_out(vty,
10253 ", mark translated RTs for VPNv6 route filtering");
10254 else if (route_filter_v6)
10255 vty_out(vty,
10256 ", attach RT as-is for VPNv6 route filtering");
10257 else if (llgr_stale)
10258 vty_out(vty,
10259 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
10260 else if (no_llgr)
10261 vty_out(vty,
10262 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
10263 else if (accept_own_nexthop)
10264 vty_out(vty,
10265 ", accept local nexthop");
10266 else if (blackhole)
10267 vty_out(vty, ", inform peer to blackhole prefix");
10268 else if (no_export)
10269 vty_out(vty, ", not advertised to EBGP peer");
10270 else if (no_advertise)
10271 vty_out(vty, ", not advertised to any peer");
10272 else if (local_as)
10273 vty_out(vty, ", not advertised outside local AS");
10274 else if (no_peer)
10275 vty_out(vty,
10276 ", inform EBGP peer not to advertise to their EBGP peers");
10277
10278 if (suppress)
10279 vty_out(vty,
10280 ", Advertisements suppressed by an aggregate.");
10281 vty_out(vty, ")\n");
10282 }
10283
10284 /* If we are not using addpath then we can display Advertised to and
10285 * that will
10286 * show what peers we advertised the bestpath to. If we are using
10287 * addpath
10288 * though then we must display Advertised to on a path-by-path basis. */
10289 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
10290 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
10291 if (bgp_adj_out_lookup(peer, dest, 0)) {
10292 if (json && !json_adv_to)
10293 json_adv_to = json_object_new_object();
10294
10295 route_vty_out_advertised_to(
10296 vty, peer, &first,
10297 " Advertised to non peer-group peers:\n ",
10298 json_adv_to);
10299 }
10300 }
10301
10302 if (json) {
10303 if (json_adv_to) {
10304 json_object_object_add(json, "advertisedTo",
10305 json_adv_to);
10306 }
10307 } else {
10308 if (first)
10309 vty_out(vty, " Not advertised to any peer");
10310 vty_out(vty, "\n");
10311 }
10312 }
10313 }
10314
10315 static void bgp_show_path_info(struct prefix_rd *pfx_rd,
10316 struct bgp_dest *bgp_node, struct vty *vty,
10317 struct bgp *bgp, afi_t afi, safi_t safi,
10318 json_object *json, enum bgp_path_type pathtype,
10319 int *display)
10320 {
10321 struct bgp_path_info *pi;
10322 int header = 1;
10323 char rdbuf[RD_ADDRSTRLEN];
10324 json_object *json_header = NULL;
10325 json_object *json_paths = NULL;
10326
10327 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
10328
10329 if (json && !json_paths) {
10330 /* Instantiate json_paths only if path is valid */
10331 json_paths = json_object_new_array();
10332 if (pfx_rd) {
10333 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
10334 json_header = json_object_new_object();
10335 } else
10336 json_header = json;
10337 }
10338
10339 if (header) {
10340 route_vty_out_detail_header(
10341 vty, bgp, bgp_node, pfx_rd,
10342 AFI_IP, safi, json_header);
10343 header = 0;
10344 }
10345 (*display)++;
10346
10347 if (pathtype == BGP_PATH_SHOW_ALL
10348 || (pathtype == BGP_PATH_SHOW_BESTPATH
10349 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
10350 || (pathtype == BGP_PATH_SHOW_MULTIPATH
10351 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
10352 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
10353 route_vty_out_detail(vty, bgp, bgp_node,
10354 pi, AFI_IP, safi,
10355 json_paths);
10356 }
10357
10358 if (json && json_paths) {
10359 json_object_object_add(json_header, "paths", json_paths);
10360
10361 if (pfx_rd)
10362 json_object_object_add(json, rdbuf, json_header);
10363 }
10364 }
10365
10366 /* Display specified route of BGP table. */
10367 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
10368 struct bgp_table *rib, const char *ip_str,
10369 afi_t afi, safi_t safi,
10370 struct prefix_rd *prd, int prefix_check,
10371 enum bgp_path_type pathtype, bool use_json)
10372 {
10373 int ret;
10374 int display = 0;
10375 struct prefix match;
10376 struct bgp_dest *dest;
10377 struct bgp_dest *rm;
10378 struct bgp_table *table;
10379 json_object *json = NULL;
10380 json_object *json_paths = NULL;
10381
10382 /* Check IP address argument. */
10383 ret = str2prefix(ip_str, &match);
10384 if (!ret) {
10385 vty_out(vty, "address is malformed\n");
10386 return CMD_WARNING;
10387 }
10388
10389 match.family = afi2family(afi);
10390
10391 if (use_json)
10392 json = json_object_new_object();
10393
10394 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
10395 for (dest = bgp_table_top(rib); dest;
10396 dest = bgp_route_next(dest)) {
10397 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10398
10399 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
10400 continue;
10401 table = bgp_dest_get_bgp_table_info(dest);
10402 if (!table)
10403 continue;
10404
10405 if ((rm = bgp_node_match(table, &match)) == NULL)
10406 continue;
10407
10408 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
10409 if (prefix_check
10410 && rm_p->prefixlen != match.prefixlen) {
10411 bgp_dest_unlock_node(rm);
10412 continue;
10413 }
10414
10415 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
10416 bgp, afi, safi, json, pathtype,
10417 &display);
10418
10419 bgp_dest_unlock_node(rm);
10420 }
10421 } else if (safi == SAFI_EVPN) {
10422 struct bgp_dest *longest_pfx;
10423 bool is_exact_pfxlen_match = false;
10424
10425 for (dest = bgp_table_top(rib); dest;
10426 dest = bgp_route_next(dest)) {
10427 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10428
10429 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
10430 continue;
10431 table = bgp_dest_get_bgp_table_info(dest);
10432 if (!table)
10433 continue;
10434
10435 longest_pfx = NULL;
10436 is_exact_pfxlen_match = false;
10437 /*
10438 * Search through all the prefixes for a match. The
10439 * pfx's are enumerated in ascending order of pfxlens.
10440 * So, the last pfx match is the longest match. Set
10441 * is_exact_pfxlen_match when we get exact pfxlen match
10442 */
10443 for (rm = bgp_table_top(table); rm;
10444 rm = bgp_route_next(rm)) {
10445 const struct prefix *rm_p =
10446 bgp_dest_get_prefix(rm);
10447 /*
10448 * Get prefixlen of the ip-prefix within type5
10449 * evpn route
10450 */
10451 if (evpn_type5_prefix_match(rm_p, &match)
10452 && rm->info) {
10453 longest_pfx = rm;
10454 int type5_pfxlen =
10455 bgp_evpn_get_type5_prefixlen(
10456 rm_p);
10457 if (type5_pfxlen == match.prefixlen) {
10458 is_exact_pfxlen_match = true;
10459 bgp_dest_unlock_node(rm);
10460 break;
10461 }
10462 }
10463 }
10464
10465 if (!longest_pfx)
10466 continue;
10467
10468 if (prefix_check && !is_exact_pfxlen_match)
10469 continue;
10470
10471 rm = longest_pfx;
10472 bgp_dest_lock_node(rm);
10473
10474 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
10475 bgp, afi, safi, json, pathtype,
10476 &display);
10477
10478 bgp_dest_unlock_node(rm);
10479 }
10480 } else if (safi == SAFI_FLOWSPEC) {
10481 if (use_json)
10482 json_paths = json_object_new_array();
10483
10484 display = bgp_flowspec_display_match_per_ip(afi, rib,
10485 &match, prefix_check,
10486 vty,
10487 use_json,
10488 json_paths);
10489 if (use_json && display)
10490 json_object_object_add(json, "paths", json_paths);
10491 } else {
10492 if ((dest = bgp_node_match(rib, &match)) != NULL) {
10493 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10494 if (!prefix_check
10495 || dest_p->prefixlen == match.prefixlen) {
10496 bgp_show_path_info(NULL, dest, vty, bgp, afi,
10497 safi, json, pathtype,
10498 &display);
10499 }
10500
10501 bgp_dest_unlock_node(dest);
10502 }
10503 }
10504
10505 if (use_json) {
10506 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10507 json, JSON_C_TO_STRING_PRETTY |
10508 JSON_C_TO_STRING_NOSLASHESCAPE));
10509 json_object_free(json);
10510 } else {
10511 if (!display) {
10512 vty_out(vty, "%% Network not in table\n");
10513 return CMD_WARNING;
10514 }
10515 }
10516
10517 return CMD_SUCCESS;
10518 }
10519
10520 /* Display specified route of Main RIB */
10521 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
10522 afi_t afi, safi_t safi, struct prefix_rd *prd,
10523 int prefix_check, enum bgp_path_type pathtype,
10524 bool use_json)
10525 {
10526 if (!bgp) {
10527 bgp = bgp_get_default();
10528 if (!bgp) {
10529 if (!use_json)
10530 vty_out(vty, "No BGP process is configured\n");
10531 else
10532 vty_out(vty, "{}\n");
10533 return CMD_WARNING;
10534 }
10535 }
10536
10537 /* labeled-unicast routes live in the unicast table */
10538 if (safi == SAFI_LABELED_UNICAST)
10539 safi = SAFI_UNICAST;
10540
10541 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
10542 afi, safi, prd, prefix_check, pathtype,
10543 use_json);
10544 }
10545
10546 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
10547 struct cmd_token **argv, bool exact, afi_t afi,
10548 safi_t safi, bool uj)
10549 {
10550 struct lcommunity *lcom;
10551 struct buffer *b;
10552 int i;
10553 char *str;
10554 int first = 0;
10555 uint8_t show_flags = 0;
10556
10557 if (uj)
10558 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10559
10560 b = buffer_new(1024);
10561 for (i = 0; i < argc; i++) {
10562 if (first)
10563 buffer_putc(b, ' ');
10564 else {
10565 if (strmatch(argv[i]->text, "AA:BB:CC")) {
10566 first = 1;
10567 buffer_putstr(b, argv[i]->arg);
10568 }
10569 }
10570 }
10571 buffer_putc(b, '\0');
10572
10573 str = buffer_getstr(b);
10574 buffer_free(b);
10575
10576 lcom = lcommunity_str2com(str);
10577 XFREE(MTYPE_TMP, str);
10578 if (!lcom) {
10579 vty_out(vty, "%% Large-community malformed\n");
10580 return CMD_WARNING;
10581 }
10582
10583 return bgp_show(vty, bgp, afi, safi,
10584 (exact ? bgp_show_type_lcommunity_exact
10585 : bgp_show_type_lcommunity),
10586 lcom, show_flags);
10587 }
10588
10589 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
10590 const char *lcom, bool exact, afi_t afi,
10591 safi_t safi, bool uj)
10592 {
10593 struct community_list *list;
10594 uint8_t show_flags = 0;
10595
10596 if (uj)
10597 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10598
10599
10600 list = community_list_lookup(bgp_clist, lcom, 0,
10601 LARGE_COMMUNITY_LIST_MASTER);
10602 if (list == NULL) {
10603 vty_out(vty, "%% %s is not a valid large-community-list name\n",
10604 lcom);
10605 return CMD_WARNING;
10606 }
10607
10608 return bgp_show(vty, bgp, afi, safi,
10609 (exact ? bgp_show_type_lcommunity_list_exact
10610 : bgp_show_type_lcommunity_list),
10611 list, show_flags);
10612 }
10613
10614 DEFUN (show_ip_bgp_large_community_list,
10615 show_ip_bgp_large_community_list_cmd,
10616 "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]",
10617 SHOW_STR
10618 IP_STR
10619 BGP_STR
10620 BGP_INSTANCE_HELP_STR
10621 BGP_AFI_HELP_STR
10622 BGP_SAFI_WITH_LABEL_HELP_STR
10623 "Display routes matching the large-community-list\n"
10624 "large-community-list number\n"
10625 "large-community-list name\n"
10626 "Exact match of the large-communities\n"
10627 JSON_STR)
10628 {
10629 afi_t afi = AFI_IP6;
10630 safi_t safi = SAFI_UNICAST;
10631 int idx = 0;
10632 bool exact_match = 0;
10633 struct bgp *bgp = NULL;
10634 bool uj = use_json(argc, argv);
10635
10636 if (uj)
10637 argc--;
10638
10639 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10640 &bgp, uj);
10641 if (!idx)
10642 return CMD_WARNING;
10643
10644 argv_find(argv, argc, "large-community-list", &idx);
10645
10646 const char *clist_number_or_name = argv[++idx]->arg;
10647
10648 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
10649 exact_match = 1;
10650
10651 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
10652 exact_match, afi, safi, uj);
10653 }
10654 DEFUN (show_ip_bgp_large_community,
10655 show_ip_bgp_large_community_cmd,
10656 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
10657 SHOW_STR
10658 IP_STR
10659 BGP_STR
10660 BGP_INSTANCE_HELP_STR
10661 BGP_AFI_HELP_STR
10662 BGP_SAFI_WITH_LABEL_HELP_STR
10663 "Display routes matching the large-communities\n"
10664 "List of large-community numbers\n"
10665 "Exact match of the large-communities\n"
10666 JSON_STR)
10667 {
10668 afi_t afi = AFI_IP6;
10669 safi_t safi = SAFI_UNICAST;
10670 int idx = 0;
10671 bool exact_match = 0;
10672 struct bgp *bgp = NULL;
10673 bool uj = use_json(argc, argv);
10674 uint8_t show_flags = 0;
10675
10676 if (uj) {
10677 argc--;
10678 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10679 }
10680
10681 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10682 &bgp, uj);
10683 if (!idx)
10684 return CMD_WARNING;
10685
10686 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
10687 if (argv_find(argv, argc, "exact-match", &idx))
10688 exact_match = 1;
10689 return bgp_show_lcommunity(vty, bgp, argc, argv,
10690 exact_match, afi, safi, uj);
10691 } else
10692 return bgp_show(vty, bgp, afi, safi,
10693 bgp_show_type_lcommunity_all, NULL, show_flags);
10694 }
10695
10696 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
10697 safi_t safi, struct json_object *json_array);
10698 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
10699 safi_t safi, struct json_object *json);
10700
10701
10702 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
10703 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
10704 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
10705 "Display number of prefixes for all afi/safi\n" JSON_STR)
10706 {
10707 bool uj = use_json(argc, argv);
10708 struct bgp *bgp = NULL;
10709 safi_t safi = SAFI_UNICAST;
10710 afi_t afi = AFI_IP6;
10711 int idx = 0;
10712 struct json_object *json_all = NULL;
10713 struct json_object *json_afi_safi = NULL;
10714
10715 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10716 &bgp, false);
10717 if (!idx)
10718 return CMD_WARNING;
10719
10720 if (uj)
10721 json_all = json_object_new_object();
10722
10723 FOREACH_AFI_SAFI (afi, safi) {
10724 /*
10725 * So limit output to those afi/safi pairs that
10726 * actually have something interesting in them
10727 */
10728 if (strmatch(get_afi_safi_str(afi, safi, true),
10729 "Unknown")) {
10730 continue;
10731 }
10732 if (uj) {
10733 json_afi_safi = json_object_new_array();
10734 json_object_object_add(
10735 json_all,
10736 get_afi_safi_str(afi, safi, true),
10737 json_afi_safi);
10738 } else {
10739 json_afi_safi = NULL;
10740 }
10741
10742 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
10743 }
10744
10745 if (uj) {
10746 vty_out(vty, "%s",
10747 json_object_to_json_string_ext(
10748 json_all, JSON_C_TO_STRING_PRETTY));
10749 json_object_free(json_all);
10750 }
10751
10752 return CMD_SUCCESS;
10753 }
10754
10755 /* BGP route print out function without JSON */
10756 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
10757 show_ip_bgp_l2vpn_evpn_statistics_cmd,
10758 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
10759 SHOW_STR
10760 IP_STR
10761 BGP_STR
10762 BGP_INSTANCE_HELP_STR
10763 L2VPN_HELP_STR
10764 EVPN_HELP_STR
10765 "BGP RIB advertisement statistics\n"
10766 JSON_STR)
10767 {
10768 afi_t afi = AFI_IP6;
10769 safi_t safi = SAFI_UNICAST;
10770 struct bgp *bgp = NULL;
10771 int idx = 0, ret;
10772 bool uj = use_json(argc, argv);
10773 struct json_object *json_afi_safi = NULL, *json = NULL;
10774
10775 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10776 &bgp, false);
10777 if (!idx)
10778 return CMD_WARNING;
10779
10780 if (uj)
10781 json_afi_safi = json_object_new_array();
10782 else
10783 json_afi_safi = NULL;
10784
10785 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
10786
10787 if (uj) {
10788 json = json_object_new_object();
10789 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
10790 json_afi_safi);
10791 vty_out(vty, "%s", json_object_to_json_string_ext(
10792 json, JSON_C_TO_STRING_PRETTY));
10793 json_object_free(json);
10794 }
10795 return ret;
10796 }
10797
10798 /* BGP route print out function without JSON */
10799 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
10800 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
10801 " [" BGP_SAFI_WITH_LABEL_CMD_STR
10802 "]]\
10803 statistics [json]",
10804 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
10805 BGP_SAFI_WITH_LABEL_HELP_STR
10806 "BGP RIB advertisement statistics\n" JSON_STR)
10807 {
10808 afi_t afi = AFI_IP6;
10809 safi_t safi = SAFI_UNICAST;
10810 struct bgp *bgp = NULL;
10811 int idx = 0, ret;
10812 bool uj = use_json(argc, argv);
10813 struct json_object *json_afi_safi = NULL, *json = NULL;
10814
10815 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10816 &bgp, false);
10817 if (!idx)
10818 return CMD_WARNING;
10819
10820 if (uj)
10821 json_afi_safi = json_object_new_array();
10822 else
10823 json_afi_safi = NULL;
10824
10825 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
10826
10827 if (uj) {
10828 json = json_object_new_object();
10829 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
10830 json_afi_safi);
10831 vty_out(vty, "%s",
10832 json_object_to_json_string_ext(
10833 json, JSON_C_TO_STRING_PRETTY));
10834 json_object_free(json);
10835 }
10836 return ret;
10837 }
10838
10839 /* BGP route print out function without JSON */
10840 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
10841 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
10842 " [" BGP_SAFI_WITH_LABEL_CMD_STR
10843 "]]\
10844 <[all$all] dampening <parameters>\
10845 |route-map WORD\
10846 |prefix-list WORD\
10847 |filter-list WORD\
10848 |community-list <(1-500)|WORD> [exact-match]\
10849 |A.B.C.D/M longer-prefixes\
10850 |X:X::X:X/M longer-prefixes\
10851 >",
10852 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
10853 BGP_SAFI_WITH_LABEL_HELP_STR
10854 "Display the entries for all address families\n"
10855 "Display detailed information about dampening\n"
10856 "Display detail of configured dampening parameters\n"
10857 "Display routes matching the route-map\n"
10858 "A route-map to match on\n"
10859 "Display routes conforming to the prefix-list\n"
10860 "Prefix-list name\n"
10861 "Display routes conforming to the filter-list\n"
10862 "Regular expression access list name\n"
10863 "Display routes matching the community-list\n"
10864 "community-list number\n"
10865 "community-list name\n"
10866 "Exact match of the communities\n"
10867 "IPv4 prefix\n"
10868 "Display route and more specific routes\n"
10869 "IPv6 prefix\n"
10870 "Display route and more specific routes\n")
10871 {
10872 afi_t afi = AFI_IP6;
10873 safi_t safi = SAFI_UNICAST;
10874 int exact_match = 0;
10875 struct bgp *bgp = NULL;
10876 int idx = 0;
10877 uint8_t show_flags = 0;
10878
10879 /* [<ipv4|ipv6> [all]] */
10880 if (all) {
10881 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
10882 if (argv_find(argv, argc, "ipv4", &idx))
10883 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
10884
10885 if (argv_find(argv, argc, "ipv6", &idx))
10886 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
10887 }
10888
10889 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10890 &bgp, false);
10891 if (!idx)
10892 return CMD_WARNING;
10893
10894 if (argv_find(argv, argc, "dampening", &idx)) {
10895 if (argv_find(argv, argc, "parameters", &idx))
10896 return bgp_show_dampening_parameters(vty, afi, safi,
10897 show_flags);
10898 }
10899
10900 if (argv_find(argv, argc, "prefix-list", &idx))
10901 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
10902 safi, bgp_show_type_prefix_list);
10903
10904 if (argv_find(argv, argc, "filter-list", &idx))
10905 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
10906 safi, bgp_show_type_filter_list);
10907
10908 if (argv_find(argv, argc, "route-map", &idx))
10909 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
10910 safi, bgp_show_type_route_map);
10911
10912 if (argv_find(argv, argc, "community-list", &idx)) {
10913 const char *clist_number_or_name = argv[++idx]->arg;
10914 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
10915 exact_match = 1;
10916 return bgp_show_community_list(vty, bgp, clist_number_or_name,
10917 exact_match, afi, safi);
10918 }
10919 /* prefix-longer */
10920 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
10921 || argv_find(argv, argc, "X:X::X:X/M", &idx))
10922 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
10923 safi,
10924 bgp_show_type_prefix_longer);
10925
10926 return CMD_WARNING;
10927 }
10928
10929 /* BGP route print out function with JSON */
10930 DEFPY (show_ip_bgp_json,
10931 show_ip_bgp_json_cmd,
10932 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
10933 [all$all]\
10934 [cidr-only\
10935 |dampening <flap-statistics|dampened-paths>\
10936 |community [AA:NN|local-AS|no-advertise|no-export\
10937 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
10938 |accept-own|accept-own-nexthop|route-filter-v6\
10939 |route-filter-v4|route-filter-translated-v6\
10940 |route-filter-translated-v4] [exact-match]\
10941 ] [json$uj | wide$wide]",
10942 SHOW_STR
10943 IP_STR
10944 BGP_STR
10945 BGP_INSTANCE_HELP_STR
10946 BGP_AFI_HELP_STR
10947 BGP_SAFI_WITH_LABEL_HELP_STR
10948 "Display the entries for all address families\n"
10949 "Display only routes with non-natural netmasks\n"
10950 "Display detailed information about dampening\n"
10951 "Display flap statistics of routes\n"
10952 "Display paths suppressed due to dampening\n"
10953 "Display routes matching the communities\n"
10954 COMMUNITY_AANN_STR
10955 "Do not send outside local AS (well-known community)\n"
10956 "Do not advertise to any peer (well-known community)\n"
10957 "Do not export to next AS (well-known community)\n"
10958 "Graceful shutdown (well-known community)\n"
10959 "Do not export to any peer (well-known community)\n"
10960 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
10961 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
10962 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
10963 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
10964 "Should accept VPN route with local nexthop (well-known community)\n"
10965 "RT VPNv6 route filtering (well-known community)\n"
10966 "RT VPNv4 route filtering (well-known community)\n"
10967 "RT translated VPNv6 route filtering (well-known community)\n"
10968 "RT translated VPNv4 route filtering (well-known community)\n"
10969 "Exact match of the communities\n"
10970 JSON_STR
10971 "Increase table width for longer prefixes\n")
10972 {
10973 afi_t afi = AFI_IP6;
10974 safi_t safi = SAFI_UNICAST;
10975 enum bgp_show_type sh_type = bgp_show_type_normal;
10976 struct bgp *bgp = NULL;
10977 int idx = 0;
10978 int exact_match = 0;
10979 char *community = NULL;
10980 bool first = true;
10981 uint8_t show_flags = 0;
10982
10983
10984 if (uj) {
10985 argc--;
10986 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10987 }
10988
10989 /* [<ipv4|ipv6> [all]] */
10990 if (all) {
10991 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
10992
10993 if (argv_find(argv, argc, "ipv4", &idx))
10994 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
10995
10996 if (argv_find(argv, argc, "ipv6", &idx))
10997 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
10998 }
10999
11000 if (wide)
11001 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11002
11003 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11004 &bgp, uj);
11005 if (!idx)
11006 return CMD_WARNING;
11007
11008 if (argv_find(argv, argc, "cidr-only", &idx))
11009 sh_type = bgp_show_type_cidr_only;
11010
11011 if (argv_find(argv, argc, "dampening", &idx)) {
11012 if (argv_find(argv, argc, "dampened-paths", &idx))
11013 sh_type = bgp_show_type_dampend_paths;
11014 else if (argv_find(argv, argc, "flap-statistics", &idx))
11015 sh_type = bgp_show_type_flap_statistics;
11016 }
11017
11018 if (argv_find(argv, argc, "community", &idx)) {
11019 char *maybecomm = NULL;
11020
11021 if (idx + 1 < argc) {
11022 if (argv[idx + 1]->type == VARIABLE_TKN)
11023 maybecomm = argv[idx + 1]->arg;
11024 else
11025 maybecomm = argv[idx + 1]->text;
11026 }
11027
11028 if (maybecomm && !strmatch(maybecomm, "json")
11029 && !strmatch(maybecomm, "exact-match"))
11030 community = maybecomm;
11031
11032 if (argv_find(argv, argc, "exact-match", &idx))
11033 exact_match = 1;
11034
11035 if (!community)
11036 sh_type = bgp_show_type_community_all;
11037 }
11038
11039 if (!all) {
11040 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
11041 if (community)
11042 return bgp_show_community(vty, bgp, community,
11043 exact_match, afi, safi,
11044 show_flags);
11045 else
11046 return bgp_show(vty, bgp, afi, safi, sh_type, NULL,
11047 show_flags);
11048 } else {
11049 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
11050 * AFI_IP6 */
11051
11052 if (uj)
11053 vty_out(vty, "{\n");
11054
11055 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
11056 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
11057 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
11058 ? AFI_IP
11059 : AFI_IP6;
11060 FOREACH_SAFI (safi) {
11061 if (strmatch(get_afi_safi_str(afi, safi, true),
11062 "Unknown"))
11063 continue;
11064
11065 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
11066 continue;
11067
11068 if (uj) {
11069 if (first)
11070 first = false;
11071 else
11072 vty_out(vty, ",\n");
11073 vty_out(vty, "\"%s\":{\n",
11074 get_afi_safi_str(afi, safi,
11075 true));
11076 } else
11077 vty_out(vty,
11078 "\nFor address family: %s\n",
11079 get_afi_safi_str(afi, safi,
11080 false));
11081
11082 if (community)
11083 bgp_show_community(vty, bgp, community,
11084 exact_match, afi,
11085 safi, show_flags);
11086 else
11087 bgp_show(vty, bgp, afi, safi, sh_type,
11088 NULL, show_flags);
11089 if (uj)
11090 vty_out(vty, "}\n");
11091 }
11092 } else {
11093 /* show <ip> bgp all: for each AFI and SAFI*/
11094 FOREACH_AFI_SAFI (afi, safi) {
11095 if (strmatch(get_afi_safi_str(afi, safi, true),
11096 "Unknown"))
11097 continue;
11098
11099 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
11100 continue;
11101
11102 if (uj) {
11103 if (first)
11104 first = false;
11105 else
11106 vty_out(vty, ",\n");
11107
11108 vty_out(vty, "\"%s\":{\n",
11109 get_afi_safi_str(afi, safi,
11110 true));
11111 } else
11112 vty_out(vty,
11113 "\nFor address family: %s\n",
11114 get_afi_safi_str(afi, safi,
11115 false));
11116
11117 if (community)
11118 bgp_show_community(vty, bgp, community,
11119 exact_match, afi,
11120 safi, show_flags);
11121 else
11122 bgp_show(vty, bgp, afi, safi, sh_type,
11123 NULL, show_flags);
11124 if (uj)
11125 vty_out(vty, "}\n");
11126 }
11127 }
11128 if (uj)
11129 vty_out(vty, "}\n");
11130 }
11131 return CMD_SUCCESS;
11132 }
11133
11134 DEFUN (show_ip_bgp_route,
11135 show_ip_bgp_route_cmd,
11136 "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]",
11137 SHOW_STR
11138 IP_STR
11139 BGP_STR
11140 BGP_INSTANCE_HELP_STR
11141 BGP_AFI_HELP_STR
11142 BGP_SAFI_WITH_LABEL_HELP_STR
11143 "Network in the BGP routing table to display\n"
11144 "IPv4 prefix\n"
11145 "Network in the BGP routing table to display\n"
11146 "IPv6 prefix\n"
11147 "Display only the bestpath\n"
11148 "Display only multipaths\n"
11149 JSON_STR)
11150 {
11151 int prefix_check = 0;
11152
11153 afi_t afi = AFI_IP6;
11154 safi_t safi = SAFI_UNICAST;
11155 char *prefix = NULL;
11156 struct bgp *bgp = NULL;
11157 enum bgp_path_type path_type;
11158 bool uj = use_json(argc, argv);
11159
11160 int idx = 0;
11161
11162 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11163 &bgp, uj);
11164 if (!idx)
11165 return CMD_WARNING;
11166
11167 if (!bgp) {
11168 vty_out(vty,
11169 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
11170 return CMD_WARNING;
11171 }
11172
11173 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
11174 if (argv_find(argv, argc, "A.B.C.D", &idx)
11175 || argv_find(argv, argc, "X:X::X:X", &idx))
11176 prefix_check = 0;
11177 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
11178 || argv_find(argv, argc, "X:X::X:X/M", &idx))
11179 prefix_check = 1;
11180
11181 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
11182 && afi != AFI_IP6) {
11183 vty_out(vty,
11184 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
11185 return CMD_WARNING;
11186 }
11187 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
11188 && afi != AFI_IP) {
11189 vty_out(vty,
11190 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
11191 return CMD_WARNING;
11192 }
11193
11194 prefix = argv[idx]->arg;
11195
11196 /* [<bestpath|multipath>] */
11197 if (argv_find(argv, argc, "bestpath", &idx))
11198 path_type = BGP_PATH_SHOW_BESTPATH;
11199 else if (argv_find(argv, argc, "multipath", &idx))
11200 path_type = BGP_PATH_SHOW_MULTIPATH;
11201 else
11202 path_type = BGP_PATH_SHOW_ALL;
11203
11204 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
11205 path_type, uj);
11206 }
11207
11208 DEFUN (show_ip_bgp_regexp,
11209 show_ip_bgp_regexp_cmd,
11210 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
11211 SHOW_STR
11212 IP_STR
11213 BGP_STR
11214 BGP_INSTANCE_HELP_STR
11215 BGP_AFI_HELP_STR
11216 BGP_SAFI_WITH_LABEL_HELP_STR
11217 "Display routes matching the AS path regular expression\n"
11218 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
11219 JSON_STR)
11220 {
11221 afi_t afi = AFI_IP6;
11222 safi_t safi = SAFI_UNICAST;
11223 struct bgp *bgp = NULL;
11224 bool uj = use_json(argc, argv);
11225 char *regstr = NULL;
11226
11227 int idx = 0;
11228 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11229 &bgp, false);
11230 if (!idx)
11231 return CMD_WARNING;
11232
11233 // get index of regex
11234 if (argv_find(argv, argc, "REGEX", &idx))
11235 regstr = argv[idx]->arg;
11236
11237 assert(regstr);
11238 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
11239 bgp_show_type_regexp, uj);
11240 }
11241
11242 DEFPY (show_ip_bgp_instance_all,
11243 show_ip_bgp_instance_all_cmd,
11244 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
11245 SHOW_STR
11246 IP_STR
11247 BGP_STR
11248 BGP_INSTANCE_ALL_HELP_STR
11249 BGP_AFI_HELP_STR
11250 BGP_SAFI_WITH_LABEL_HELP_STR
11251 JSON_STR
11252 "Increase table width for longer prefixes\n")
11253 {
11254 afi_t afi = AFI_IP;
11255 safi_t safi = SAFI_UNICAST;
11256 struct bgp *bgp = NULL;
11257 int idx = 0;
11258 uint8_t show_flags = 0;
11259
11260 if (uj) {
11261 argc--;
11262 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11263 }
11264
11265 if (wide)
11266 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11267
11268 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11269 &bgp, uj);
11270 if (!idx)
11271 return CMD_WARNING;
11272
11273 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
11274 return CMD_SUCCESS;
11275 }
11276
11277 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11278 afi_t afi, safi_t safi, enum bgp_show_type type,
11279 bool use_json)
11280 {
11281 regex_t *regex;
11282 int rc;
11283 uint8_t show_flags = 0;
11284
11285 if (use_json)
11286 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11287
11288 if (!config_bgp_aspath_validate(regstr)) {
11289 vty_out(vty, "Invalid character in REGEX %s\n",
11290 regstr);
11291 return CMD_WARNING_CONFIG_FAILED;
11292 }
11293
11294 regex = bgp_regcomp(regstr);
11295 if (!regex) {
11296 vty_out(vty, "Can't compile regexp %s\n", regstr);
11297 return CMD_WARNING;
11298 }
11299
11300 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags);
11301 bgp_regex_free(regex);
11302 return rc;
11303 }
11304
11305 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
11306 const char *prefix_list_str, afi_t afi,
11307 safi_t safi, enum bgp_show_type type)
11308 {
11309 struct prefix_list *plist;
11310 uint8_t show_flags = 0;
11311
11312 plist = prefix_list_lookup(afi, prefix_list_str);
11313 if (plist == NULL) {
11314 vty_out(vty, "%% %s is not a valid prefix-list name\n",
11315 prefix_list_str);
11316 return CMD_WARNING;
11317 }
11318
11319 return bgp_show(vty, bgp, afi, safi, type, plist, show_flags);
11320 }
11321
11322 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
11323 const char *filter, afi_t afi, safi_t safi,
11324 enum bgp_show_type type)
11325 {
11326 struct as_list *as_list;
11327 uint8_t show_flags = 0;
11328
11329 as_list = as_list_lookup(filter);
11330 if (as_list == NULL) {
11331 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
11332 filter);
11333 return CMD_WARNING;
11334 }
11335
11336 return bgp_show(vty, bgp, afi, safi, type, as_list, show_flags);
11337 }
11338
11339 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
11340 const char *rmap_str, afi_t afi, safi_t safi,
11341 enum bgp_show_type type)
11342 {
11343 struct route_map *rmap;
11344 uint8_t show_flags = 0;
11345
11346 rmap = route_map_lookup_by_name(rmap_str);
11347 if (!rmap) {
11348 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
11349 return CMD_WARNING;
11350 }
11351
11352 return bgp_show(vty, bgp, afi, safi, type, rmap, show_flags);
11353 }
11354
11355 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11356 const char *comstr, int exact, afi_t afi,
11357 safi_t safi, uint8_t show_flags)
11358 {
11359 struct community *com;
11360 int ret = 0;
11361
11362 com = community_str2com(comstr);
11363 if (!com) {
11364 vty_out(vty, "%% Community malformed: %s\n", comstr);
11365 return CMD_WARNING;
11366 }
11367
11368 ret = bgp_show(vty, bgp, afi, safi,
11369 (exact ? bgp_show_type_community_exact
11370 : bgp_show_type_community),
11371 com, show_flags);
11372 community_free(&com);
11373
11374 return ret;
11375 }
11376
11377 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
11378 const char *com, int exact, afi_t afi,
11379 safi_t safi)
11380 {
11381 struct community_list *list;
11382 uint8_t show_flags = 0;
11383
11384 list = community_list_lookup(bgp_clist, com, 0, COMMUNITY_LIST_MASTER);
11385 if (list == NULL) {
11386 vty_out(vty, "%% %s is not a valid community-list name\n", com);
11387 return CMD_WARNING;
11388 }
11389
11390 return bgp_show(vty, bgp, afi, safi,
11391 (exact ? bgp_show_type_community_list_exact
11392 : bgp_show_type_community_list),
11393 list, show_flags);
11394 }
11395
11396 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
11397 const char *prefix, afi_t afi, safi_t safi,
11398 enum bgp_show_type type)
11399 {
11400 int ret;
11401 struct prefix *p;
11402 uint8_t show_flags = 0;
11403
11404 p = prefix_new();
11405
11406 ret = str2prefix(prefix, p);
11407 if (!ret) {
11408 vty_out(vty, "%% Malformed Prefix\n");
11409 return CMD_WARNING;
11410 }
11411
11412 ret = bgp_show(vty, bgp, afi, safi, type, p, show_flags);
11413 prefix_free(&p);
11414 return ret;
11415 }
11416
11417 enum bgp_stats {
11418 BGP_STATS_MAXBITLEN = 0,
11419 BGP_STATS_RIB,
11420 BGP_STATS_PREFIXES,
11421 BGP_STATS_TOTPLEN,
11422 BGP_STATS_UNAGGREGATEABLE,
11423 BGP_STATS_MAX_AGGREGATEABLE,
11424 BGP_STATS_AGGREGATES,
11425 BGP_STATS_SPACE,
11426 BGP_STATS_ASPATH_COUNT,
11427 BGP_STATS_ASPATH_MAXHOPS,
11428 BGP_STATS_ASPATH_TOTHOPS,
11429 BGP_STATS_ASPATH_MAXSIZE,
11430 BGP_STATS_ASPATH_TOTSIZE,
11431 BGP_STATS_ASN_HIGHEST,
11432 BGP_STATS_MAX,
11433 };
11434
11435 #define TABLE_STATS_IDX_VTY 0
11436 #define TABLE_STATS_IDX_JSON 1
11437
11438 static const char *table_stats_strs[][2] = {
11439 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
11440 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
11441 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
11442 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
11443 "unaggregateablePrefixes"},
11444 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
11445 "maximumAggregateablePrefixes"},
11446 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
11447 "bgpAggregateAdvertisements"},
11448 [BGP_STATS_SPACE] = {"Address space advertised",
11449 "addressSpaceAdvertised"},
11450 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
11451 "advertisementsWithPaths"},
11452 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
11453 "longestAsPath"},
11454 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
11455 "largestAsPath"},
11456 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
11457 "averageAsPathLengthHops"},
11458 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
11459 "averageAsPathSizeBytes"},
11460 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
11461 [BGP_STATS_MAX] = {NULL, NULL}
11462 };
11463
11464 struct bgp_table_stats {
11465 struct bgp_table *table;
11466 unsigned long long counts[BGP_STATS_MAX];
11467 double total_space;
11468 };
11469
11470 #if 0
11471 #define TALLY_SIGFIG 100000
11472 static unsigned long
11473 ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
11474 {
11475 unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
11476 unsigned long res = (newtot * TALLY_SIGFIG) / count;
11477 unsigned long ret = newtot / count;
11478
11479 if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
11480 return ret + 1;
11481 else
11482 return ret;
11483 }
11484 #endif
11485
11486 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
11487 struct bgp_table_stats *ts, unsigned int space)
11488 {
11489 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
11490 struct bgp_path_info *pi;
11491 const struct prefix *rn_p;
11492
11493 if (dest == top)
11494 return;
11495
11496 if (!bgp_dest_has_bgp_path_info_data(dest))
11497 return;
11498
11499 rn_p = bgp_dest_get_prefix(dest);
11500 ts->counts[BGP_STATS_PREFIXES]++;
11501 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
11502
11503 #if 0
11504 ts->counts[BGP_STATS_AVGPLEN]
11505 = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
11506 ts->counts[BGP_STATS_AVGPLEN],
11507 rn_p->prefixlen);
11508 #endif
11509
11510 /* check if the prefix is included by any other announcements */
11511 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
11512 pdest = bgp_dest_parent_nolock(pdest);
11513
11514 if (pdest == NULL || pdest == top) {
11515 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
11516 /* announced address space */
11517 if (space)
11518 ts->total_space += pow(2.0, space - rn_p->prefixlen);
11519 } else if (bgp_dest_has_bgp_path_info_data(pdest))
11520 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
11521
11522
11523 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11524 ts->counts[BGP_STATS_RIB]++;
11525
11526 if (CHECK_FLAG(pi->attr->flag,
11527 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
11528 ts->counts[BGP_STATS_AGGREGATES]++;
11529
11530 /* as-path stats */
11531 if (pi->attr->aspath) {
11532 unsigned int hops = aspath_count_hops(pi->attr->aspath);
11533 unsigned int size = aspath_size(pi->attr->aspath);
11534 as_t highest = aspath_highest(pi->attr->aspath);
11535
11536 ts->counts[BGP_STATS_ASPATH_COUNT]++;
11537
11538 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
11539 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
11540
11541 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
11542 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
11543
11544 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
11545 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
11546 #if 0
11547 ts->counts[BGP_STATS_ASPATH_AVGHOPS]
11548 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
11549 ts->counts[BGP_STATS_ASPATH_AVGHOPS],
11550 hops);
11551 ts->counts[BGP_STATS_ASPATH_AVGSIZE]
11552 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
11553 ts->counts[BGP_STATS_ASPATH_AVGSIZE],
11554 size);
11555 #endif
11556 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
11557 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
11558 }
11559 }
11560 }
11561
11562 static int bgp_table_stats_walker(struct thread *t)
11563 {
11564 struct bgp_dest *dest, *ndest;
11565 struct bgp_dest *top;
11566 struct bgp_table_stats *ts = THREAD_ARG(t);
11567 unsigned int space = 0;
11568
11569 if (!(top = bgp_table_top(ts->table)))
11570 return 0;
11571
11572 switch (ts->table->afi) {
11573 case AFI_IP:
11574 space = IPV4_MAX_BITLEN;
11575 break;
11576 case AFI_IP6:
11577 space = IPV6_MAX_BITLEN;
11578 break;
11579 default:
11580 return 0;
11581 }
11582
11583 ts->counts[BGP_STATS_MAXBITLEN] = space;
11584
11585 for (dest = top; dest; dest = bgp_route_next(dest)) {
11586 if (ts->table->safi == SAFI_MPLS_VPN
11587 || ts->table->safi == SAFI_ENCAP
11588 || ts->table->safi == SAFI_EVPN) {
11589 struct bgp_table *table;
11590
11591 table = bgp_dest_get_bgp_table_info(dest);
11592 if (!table)
11593 continue;
11594
11595 top = bgp_table_top(table);
11596 for (ndest = bgp_table_top(table); ndest;
11597 ndest = bgp_route_next(ndest))
11598 bgp_table_stats_rn(ndest, top, ts, space);
11599 } else {
11600 bgp_table_stats_rn(dest, top, ts, space);
11601 }
11602 }
11603
11604 return 0;
11605 }
11606
11607 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
11608 struct json_object *json_array)
11609 {
11610 struct listnode *node, *nnode;
11611 struct bgp *bgp;
11612
11613 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
11614 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
11615 }
11616
11617 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
11618 safi_t safi, struct json_object *json_array)
11619 {
11620 struct bgp_table_stats ts;
11621 unsigned int i;
11622 int ret = CMD_SUCCESS;
11623 char temp_buf[20];
11624 struct json_object *json = NULL;
11625
11626 if (json_array)
11627 json = json_object_new_object();
11628
11629 if (!bgp->rib[afi][safi]) {
11630 char warning_msg[50];
11631
11632 snprintf(warning_msg, sizeof(warning_msg),
11633 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
11634 safi);
11635
11636 if (!json)
11637 vty_out(vty, "%s\n", warning_msg);
11638 else
11639 json_object_string_add(json, "warning", warning_msg);
11640
11641 ret = CMD_WARNING;
11642 goto end_table_stats;
11643 }
11644
11645 if (!json)
11646 vty_out(vty, "BGP %s RIB statistics (%s)\n",
11647 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
11648 else
11649 json_object_string_add(json, "instance", bgp->name_pretty);
11650
11651 /* labeled-unicast routes live in the unicast table */
11652 if (safi == SAFI_LABELED_UNICAST)
11653 safi = SAFI_UNICAST;
11654
11655 memset(&ts, 0, sizeof(ts));
11656 ts.table = bgp->rib[afi][safi];
11657 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
11658
11659 for (i = 0; i < BGP_STATS_MAX; i++) {
11660 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
11661 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
11662 continue;
11663
11664 switch (i) {
11665 #if 0
11666 case BGP_STATS_ASPATH_AVGHOPS:
11667 case BGP_STATS_ASPATH_AVGSIZE:
11668 case BGP_STATS_AVGPLEN:
11669 vty_out (vty, "%-30s: ", table_stats_strs[i]);
11670 vty_out (vty, "%12.2f",
11671 (float)ts.counts[i] / (float)TALLY_SIGFIG);
11672 break;
11673 #endif
11674 case BGP_STATS_ASPATH_TOTHOPS:
11675 case BGP_STATS_ASPATH_TOTSIZE:
11676 if (!json) {
11677 snprintf(
11678 temp_buf, sizeof(temp_buf), "%12.2f",
11679 ts.counts[i]
11680 ? (float)ts.counts[i]
11681 / (float)ts.counts
11682 [BGP_STATS_ASPATH_COUNT]
11683 : 0);
11684 vty_out(vty, "%-30s: %s",
11685 table_stats_strs[i]
11686 [TABLE_STATS_IDX_VTY],
11687 temp_buf);
11688 } else {
11689 json_object_double_add(
11690 json,
11691 table_stats_strs[i]
11692 [TABLE_STATS_IDX_JSON],
11693 ts.counts[i]
11694 ? (double)ts.counts[i]
11695 / (double)ts.counts
11696 [BGP_STATS_ASPATH_COUNT]
11697 : 0);
11698 }
11699 break;
11700 case BGP_STATS_TOTPLEN:
11701 if (!json) {
11702 snprintf(
11703 temp_buf, sizeof(temp_buf), "%12.2f",
11704 ts.counts[i]
11705 ? (float)ts.counts[i]
11706 / (float)ts.counts
11707 [BGP_STATS_PREFIXES]
11708 : 0);
11709 vty_out(vty, "%-30s: %s",
11710 table_stats_strs[i]
11711 [TABLE_STATS_IDX_VTY],
11712 temp_buf);
11713 } else {
11714 json_object_double_add(
11715 json,
11716 table_stats_strs[i]
11717 [TABLE_STATS_IDX_JSON],
11718 ts.counts[i]
11719 ? (double)ts.counts[i]
11720 / (double)ts.counts
11721 [BGP_STATS_PREFIXES]
11722 : 0);
11723 }
11724 break;
11725 case BGP_STATS_SPACE:
11726 if (!json) {
11727 snprintf(temp_buf, sizeof(temp_buf), "%12g",
11728 ts.total_space);
11729 vty_out(vty, "%-30s: %s\n",
11730 table_stats_strs[i]
11731 [TABLE_STATS_IDX_VTY],
11732 temp_buf);
11733 } else {
11734 json_object_double_add(
11735 json,
11736 table_stats_strs[i]
11737 [TABLE_STATS_IDX_JSON],
11738 (double)ts.total_space);
11739 }
11740 if (afi == AFI_IP6) {
11741 if (!json) {
11742 snprintf(temp_buf, sizeof(temp_buf),
11743 "%12g",
11744 ts.total_space
11745 * pow(2.0, -128 + 32));
11746 vty_out(vty, "%30s: %s\n",
11747 "/32 equivalent %s\n",
11748 temp_buf);
11749 } else {
11750 json_object_double_add(
11751 json, "/32equivalent",
11752 (double)(ts.total_space
11753 * pow(2.0,
11754 -128 + 32)));
11755 }
11756 if (!json) {
11757 snprintf(temp_buf, sizeof(temp_buf),
11758 "%12g",
11759 ts.total_space
11760 * pow(2.0, -128 + 48));
11761 vty_out(vty, "%30s: %s\n",
11762 "/48 equivalent %s\n",
11763 temp_buf);
11764 } else {
11765 json_object_double_add(
11766 json, "/48equivalent",
11767 (double)(ts.total_space
11768 * pow(2.0,
11769 -128 + 48)));
11770 }
11771 } else {
11772 if (!json) {
11773 snprintf(temp_buf, sizeof(temp_buf),
11774 "%12.2f",
11775 ts.total_space * 100.
11776 * pow(2.0, -32));
11777 vty_out(vty, "%30s: %s\n",
11778 "% announced ", temp_buf);
11779 } else {
11780 json_object_double_add(
11781 json, "%announced",
11782 (double)(ts.total_space * 100.
11783 * pow(2.0, -32)));
11784 }
11785 if (!json) {
11786 snprintf(temp_buf, sizeof(temp_buf),
11787 "%12.2f",
11788 ts.total_space
11789 * pow(2.0, -32 + 8));
11790 vty_out(vty, "%30s: %s\n",
11791 "/8 equivalent ", temp_buf);
11792 } else {
11793 json_object_double_add(
11794 json, "/8equivalent",
11795 (double)(ts.total_space
11796 * pow(2.0, -32 + 8)));
11797 }
11798 if (!json) {
11799 snprintf(temp_buf, sizeof(temp_buf),
11800 "%12.2f",
11801 ts.total_space
11802 * pow(2.0, -32 + 24));
11803 vty_out(vty, "%30s: %s\n",
11804 "/24 equivalent ", temp_buf);
11805 } else {
11806 json_object_double_add(
11807 json, "/24equivalent",
11808 (double)(ts.total_space
11809 * pow(2.0, -32 + 24)));
11810 }
11811 }
11812 break;
11813 default:
11814 if (!json) {
11815 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
11816 ts.counts[i]);
11817 vty_out(vty, "%-30s: %s",
11818 table_stats_strs[i]
11819 [TABLE_STATS_IDX_VTY],
11820 temp_buf);
11821 } else {
11822 json_object_int_add(
11823 json,
11824 table_stats_strs[i]
11825 [TABLE_STATS_IDX_JSON],
11826 ts.counts[i]);
11827 }
11828 }
11829 if (!json)
11830 vty_out(vty, "\n");
11831 }
11832 end_table_stats:
11833 if (json)
11834 json_object_array_add(json_array, json);
11835 return ret;
11836 }
11837
11838 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
11839 safi_t safi, struct json_object *json_array)
11840 {
11841 if (!bgp) {
11842 bgp_table_stats_all(vty, afi, safi, json_array);
11843 return CMD_SUCCESS;
11844 }
11845
11846 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
11847 }
11848
11849 enum bgp_pcounts {
11850 PCOUNT_ADJ_IN = 0,
11851 PCOUNT_DAMPED,
11852 PCOUNT_REMOVED,
11853 PCOUNT_HISTORY,
11854 PCOUNT_STALE,
11855 PCOUNT_VALID,
11856 PCOUNT_ALL,
11857 PCOUNT_COUNTED,
11858 PCOUNT_BPATH_SELECTED,
11859 PCOUNT_PFCNT, /* the figure we display to users */
11860 PCOUNT_MAX,
11861 };
11862
11863 static const char *const pcount_strs[] = {
11864 [PCOUNT_ADJ_IN] = "Adj-in",
11865 [PCOUNT_DAMPED] = "Damped",
11866 [PCOUNT_REMOVED] = "Removed",
11867 [PCOUNT_HISTORY] = "History",
11868 [PCOUNT_STALE] = "Stale",
11869 [PCOUNT_VALID] = "Valid",
11870 [PCOUNT_ALL] = "All RIB",
11871 [PCOUNT_COUNTED] = "PfxCt counted",
11872 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
11873 [PCOUNT_PFCNT] = "Useable",
11874 [PCOUNT_MAX] = NULL,
11875 };
11876
11877 struct peer_pcounts {
11878 unsigned int count[PCOUNT_MAX];
11879 const struct peer *peer;
11880 const struct bgp_table *table;
11881 safi_t safi;
11882 };
11883
11884 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
11885 {
11886 const struct bgp_adj_in *ain;
11887 const struct bgp_path_info *pi;
11888 const struct peer *peer = pc->peer;
11889
11890 for (ain = rn->adj_in; ain; ain = ain->next)
11891 if (ain->peer == peer)
11892 pc->count[PCOUNT_ADJ_IN]++;
11893
11894 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
11895
11896 if (pi->peer != peer)
11897 continue;
11898
11899 pc->count[PCOUNT_ALL]++;
11900
11901 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
11902 pc->count[PCOUNT_DAMPED]++;
11903 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11904 pc->count[PCOUNT_HISTORY]++;
11905 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
11906 pc->count[PCOUNT_REMOVED]++;
11907 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
11908 pc->count[PCOUNT_STALE]++;
11909 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
11910 pc->count[PCOUNT_VALID]++;
11911 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
11912 pc->count[PCOUNT_PFCNT]++;
11913 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
11914 pc->count[PCOUNT_BPATH_SELECTED]++;
11915
11916 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
11917 pc->count[PCOUNT_COUNTED]++;
11918 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
11919 flog_err(
11920 EC_LIB_DEVELOPMENT,
11921 "Attempting to count but flags say it is unusable");
11922 } else {
11923 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
11924 flog_err(
11925 EC_LIB_DEVELOPMENT,
11926 "Not counted but flags say we should");
11927 }
11928 }
11929 }
11930
11931 static int bgp_peer_count_walker(struct thread *t)
11932 {
11933 struct bgp_dest *rn, *rm;
11934 const struct bgp_table *table;
11935 struct peer_pcounts *pc = THREAD_ARG(t);
11936
11937 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
11938 || pc->safi == SAFI_EVPN) {
11939 /* Special handling for 2-level routing tables. */
11940 for (rn = bgp_table_top(pc->table); rn;
11941 rn = bgp_route_next(rn)) {
11942 table = bgp_dest_get_bgp_table_info(rn);
11943 if (table != NULL)
11944 for (rm = bgp_table_top(table); rm;
11945 rm = bgp_route_next(rm))
11946 bgp_peer_count_proc(rm, pc);
11947 }
11948 } else
11949 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
11950 bgp_peer_count_proc(rn, pc);
11951
11952 return 0;
11953 }
11954
11955 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
11956 safi_t safi, bool use_json)
11957 {
11958 struct peer_pcounts pcounts = {.peer = peer};
11959 unsigned int i;
11960 json_object *json = NULL;
11961 json_object *json_loop = NULL;
11962
11963 if (use_json) {
11964 json = json_object_new_object();
11965 json_loop = json_object_new_object();
11966 }
11967
11968 if (!peer || !peer->bgp || !peer->afc[afi][safi]
11969 || !peer->bgp->rib[afi][safi]) {
11970 if (use_json) {
11971 json_object_string_add(
11972 json, "warning",
11973 "No such neighbor or address family");
11974 vty_out(vty, "%s\n", json_object_to_json_string(json));
11975 json_object_free(json);
11976 } else
11977 vty_out(vty, "%% No such neighbor or address family\n");
11978
11979 return CMD_WARNING;
11980 }
11981
11982 memset(&pcounts, 0, sizeof(pcounts));
11983 pcounts.peer = peer;
11984 pcounts.table = peer->bgp->rib[afi][safi];
11985 pcounts.safi = safi;
11986
11987 /* in-place call via thread subsystem so as to record execution time
11988 * stats for the thread-walk (i.e. ensure this can't be blamed on
11989 * on just vty_read()).
11990 */
11991 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
11992
11993 if (use_json) {
11994 json_object_string_add(json, "prefixCountsFor", peer->host);
11995 json_object_string_add(json, "multiProtocol",
11996 get_afi_safi_str(afi, safi, true));
11997 json_object_int_add(json, "pfxCounter",
11998 peer->pcount[afi][safi]);
11999
12000 for (i = 0; i < PCOUNT_MAX; i++)
12001 json_object_int_add(json_loop, pcount_strs[i],
12002 pcounts.count[i]);
12003
12004 json_object_object_add(json, "ribTableWalkCounters", json_loop);
12005
12006 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
12007 json_object_string_add(json, "pfxctDriftFor",
12008 peer->host);
12009 json_object_string_add(
12010 json, "recommended",
12011 "Please report this bug, with the above command output");
12012 }
12013 vty_out(vty, "%s\n", json_object_to_json_string_ext(
12014 json, JSON_C_TO_STRING_PRETTY));
12015 json_object_free(json);
12016 } else {
12017
12018 if (peer->hostname
12019 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
12020 vty_out(vty, "Prefix counts for %s/%s, %s\n",
12021 peer->hostname, peer->host,
12022 get_afi_safi_str(afi, safi, false));
12023 } else {
12024 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
12025 get_afi_safi_str(afi, safi, false));
12026 }
12027
12028 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
12029 vty_out(vty, "\nCounts from RIB table walk:\n\n");
12030
12031 for (i = 0; i < PCOUNT_MAX; i++)
12032 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
12033 pcounts.count[i]);
12034
12035 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
12036 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
12037 vty_out(vty,
12038 "Please report this bug, with the above command output\n");
12039 }
12040 }
12041
12042 return CMD_SUCCESS;
12043 }
12044
12045 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
12046 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
12047 "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]",
12048 SHOW_STR
12049 IP_STR
12050 BGP_STR
12051 BGP_INSTANCE_HELP_STR
12052 BGP_AFI_HELP_STR
12053 BGP_SAFI_HELP_STR
12054 "Detailed information on TCP and BGP neighbor connections\n"
12055 "Neighbor to display information about\n"
12056 "Neighbor to display information about\n"
12057 "Neighbor on BGP configured interface\n"
12058 "Display detailed prefix count information\n"
12059 JSON_STR)
12060 {
12061 afi_t afi = AFI_IP6;
12062 safi_t safi = SAFI_UNICAST;
12063 struct peer *peer;
12064 int idx = 0;
12065 struct bgp *bgp = NULL;
12066 bool uj = use_json(argc, argv);
12067
12068 if (uj)
12069 argc--;
12070
12071 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12072 &bgp, uj);
12073 if (!idx)
12074 return CMD_WARNING;
12075
12076 argv_find(argv, argc, "neighbors", &idx);
12077 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
12078 if (!peer)
12079 return CMD_WARNING;
12080
12081 return bgp_peer_counts(vty, peer, afi, safi, uj);
12082 }
12083
12084 #ifdef KEEP_OLD_VPN_COMMANDS
12085 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
12086 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
12087 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
12088 SHOW_STR
12089 IP_STR
12090 BGP_STR
12091 BGP_VPNVX_HELP_STR
12092 "Display information about all VPNv4 NLRIs\n"
12093 "Detailed information on TCP and BGP neighbor connections\n"
12094 "Neighbor to display information about\n"
12095 "Neighbor to display information about\n"
12096 "Neighbor on BGP configured interface\n"
12097 "Display detailed prefix count information\n"
12098 JSON_STR)
12099 {
12100 int idx_peer = 6;
12101 struct peer *peer;
12102 bool uj = use_json(argc, argv);
12103
12104 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
12105 if (!peer)
12106 return CMD_WARNING;
12107
12108 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
12109 }
12110
12111 DEFUN (show_ip_bgp_vpn_all_route_prefix,
12112 show_ip_bgp_vpn_all_route_prefix_cmd,
12113 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
12114 SHOW_STR
12115 IP_STR
12116 BGP_STR
12117 BGP_VPNVX_HELP_STR
12118 "Display information about all VPNv4 NLRIs\n"
12119 "Network in the BGP routing table to display\n"
12120 "Network in the BGP routing table to display\n"
12121 JSON_STR)
12122 {
12123 int idx = 0;
12124 char *network = NULL;
12125 struct bgp *bgp = bgp_get_default();
12126 if (!bgp) {
12127 vty_out(vty, "Can't find default instance\n");
12128 return CMD_WARNING;
12129 }
12130
12131 if (argv_find(argv, argc, "A.B.C.D", &idx))
12132 network = argv[idx]->arg;
12133 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
12134 network = argv[idx]->arg;
12135 else {
12136 vty_out(vty, "Unable to figure out Network\n");
12137 return CMD_WARNING;
12138 }
12139
12140 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
12141 BGP_PATH_SHOW_ALL, use_json(argc, argv));
12142 }
12143 #endif /* KEEP_OLD_VPN_COMMANDS */
12144
12145 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
12146 show_bgp_l2vpn_evpn_route_prefix_cmd,
12147 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
12148 SHOW_STR
12149 BGP_STR
12150 L2VPN_HELP_STR
12151 EVPN_HELP_STR
12152 "Network in the BGP routing table to display\n"
12153 "Network in the BGP routing table to display\n"
12154 "Network in the BGP routing table to display\n"
12155 "Network in the BGP routing table to display\n"
12156 JSON_STR)
12157 {
12158 int idx = 0;
12159 char *network = NULL;
12160 int prefix_check = 0;
12161
12162 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
12163 argv_find(argv, argc, "X:X::X:X", &idx))
12164 network = argv[idx]->arg;
12165 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
12166 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12167 network = argv[idx]->arg;
12168 prefix_check = 1;
12169 } else {
12170 vty_out(vty, "Unable to figure out Network\n");
12171 return CMD_WARNING;
12172 }
12173 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
12174 prefix_check, BGP_PATH_SHOW_ALL,
12175 use_json(argc, argv));
12176 }
12177
12178 static void show_adj_route_header(struct vty *vty, struct bgp *bgp,
12179 struct bgp_table *table, int *header1,
12180 int *header2, json_object *json,
12181 json_object *json_scode,
12182 json_object *json_ocode, bool wide)
12183 {
12184 uint64_t version = table ? table->version : 0;
12185
12186 if (*header1) {
12187 if (json) {
12188 json_object_int_add(json, "bgpTableVersion", version);
12189 json_object_string_add(json, "bgpLocalRouterId",
12190 inet_ntoa(bgp->router_id));
12191 json_object_int_add(json, "defaultLocPrf",
12192 bgp->default_local_pref);
12193 json_object_int_add(json, "localAS", bgp->as);
12194 json_object_object_add(json, "bgpStatusCodes",
12195 json_scode);
12196 json_object_object_add(json, "bgpOriginCodes",
12197 json_ocode);
12198 } else {
12199 vty_out(vty,
12200 "BGP table version is %" PRIu64 ", local router ID is %s, vrf id ",
12201 version, inet_ntoa(bgp->router_id));
12202 if (bgp->vrf_id == VRF_UNKNOWN)
12203 vty_out(vty, "%s", VRFID_NONE_STR);
12204 else
12205 vty_out(vty, "%u", bgp->vrf_id);
12206 vty_out(vty, "\n");
12207 vty_out(vty, "Default local pref %u, ",
12208 bgp->default_local_pref);
12209 vty_out(vty, "local AS %u\n", bgp->as);
12210 vty_out(vty, BGP_SHOW_SCODE_HEADER);
12211 vty_out(vty, BGP_SHOW_NCODE_HEADER);
12212 vty_out(vty, BGP_SHOW_OCODE_HEADER);
12213 }
12214 *header1 = 0;
12215 }
12216 if (*header2) {
12217 if (!json)
12218 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
12219 : BGP_SHOW_HEADER));
12220 *header2 = 0;
12221 }
12222 }
12223
12224 static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
12225 safi_t safi, enum bgp_show_adj_route_type type,
12226 const char *rmap_name, json_object *json,
12227 uint8_t show_flags)
12228 {
12229 struct bgp_table *table;
12230 struct bgp_adj_in *ain;
12231 struct bgp_adj_out *adj;
12232 unsigned long output_count = 0;
12233 unsigned long filtered_count = 0;
12234 struct bgp_dest *dest;
12235 int header1 = 1;
12236 struct bgp *bgp;
12237 int header2 = 1;
12238 struct attr attr;
12239 int ret;
12240 struct update_subgroup *subgrp;
12241 json_object *json_scode = NULL;
12242 json_object *json_ocode = NULL;
12243 json_object *json_ar = NULL;
12244 struct peer_af *paf;
12245 bool route_filtered;
12246 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12247 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12248
12249 if (use_json) {
12250 json_scode = json_object_new_object();
12251 json_ocode = json_object_new_object();
12252 json_ar = json_object_new_object();
12253
12254 json_object_string_add(json_scode, "suppressed", "s");
12255 json_object_string_add(json_scode, "damped", "d");
12256 json_object_string_add(json_scode, "history", "h");
12257 json_object_string_add(json_scode, "valid", "*");
12258 json_object_string_add(json_scode, "best", ">");
12259 json_object_string_add(json_scode, "multipath", "=");
12260 json_object_string_add(json_scode, "internal", "i");
12261 json_object_string_add(json_scode, "ribFailure", "r");
12262 json_object_string_add(json_scode, "stale", "S");
12263 json_object_string_add(json_scode, "removed", "R");
12264
12265 json_object_string_add(json_ocode, "igp", "i");
12266 json_object_string_add(json_ocode, "egp", "e");
12267 json_object_string_add(json_ocode, "incomplete", "?");
12268 }
12269
12270 bgp = peer->bgp;
12271
12272 if (!bgp) {
12273 if (use_json) {
12274 json_object_string_add(json, "alert", "no BGP");
12275 vty_out(vty, "%s\n", json_object_to_json_string(json));
12276 json_object_free(json);
12277 } else
12278 vty_out(vty, "%% No bgp\n");
12279 return;
12280 }
12281
12282 /* labeled-unicast routes live in the unicast table */
12283 if (safi == SAFI_LABELED_UNICAST)
12284 table = bgp->rib[afi][SAFI_UNICAST];
12285 else
12286 table = bgp->rib[afi][safi];
12287
12288 output_count = filtered_count = 0;
12289 subgrp = peer_subgroup(peer, afi, safi);
12290
12291 if (type == bgp_show_adj_route_advertised && subgrp
12292 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
12293 if (use_json) {
12294 json_object_int_add(json, "bgpTableVersion",
12295 table->version);
12296 json_object_string_add(json, "bgpLocalRouterId",
12297 inet_ntoa(bgp->router_id));
12298 json_object_int_add(json, "defaultLocPrf",
12299 bgp->default_local_pref);
12300 json_object_int_add(json, "localAS", bgp->as);
12301 json_object_object_add(json, "bgpStatusCodes",
12302 json_scode);
12303 json_object_object_add(json, "bgpOriginCodes",
12304 json_ocode);
12305 json_object_string_add(
12306 json, "bgpOriginatingDefaultNetwork",
12307 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
12308 } else {
12309 vty_out(vty, "BGP table version is %" PRIu64", local router ID is %s, vrf id ",
12310 table->version, inet_ntoa(bgp->router_id));
12311 if (bgp->vrf_id == VRF_UNKNOWN)
12312 vty_out(vty, "%s", VRFID_NONE_STR);
12313 else
12314 vty_out(vty, "%u", bgp->vrf_id);
12315 vty_out(vty, "\n");
12316 vty_out(vty, "Default local pref %u, ",
12317 bgp->default_local_pref);
12318 vty_out(vty, "local AS %u\n", bgp->as);
12319 vty_out(vty, BGP_SHOW_SCODE_HEADER);
12320 vty_out(vty, BGP_SHOW_NCODE_HEADER);
12321 vty_out(vty, BGP_SHOW_OCODE_HEADER);
12322
12323 vty_out(vty, "Originating default network %s\n\n",
12324 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
12325 }
12326 header1 = 0;
12327 }
12328
12329 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
12330 if (type == bgp_show_adj_route_received
12331 || type == bgp_show_adj_route_filtered) {
12332 for (ain = dest->adj_in; ain; ain = ain->next) {
12333 if (ain->peer != peer)
12334 continue;
12335
12336 show_adj_route_header(
12337 vty, bgp, table, &header1, &header2,
12338 json, json_scode, json_ocode, wide);
12339
12340 attr = *ain->attr;
12341 route_filtered = false;
12342
12343 /* Filter prefix using distribute list,
12344 * filter list or prefix list
12345 */
12346 const struct prefix *rn_p =
12347 bgp_dest_get_prefix(dest);
12348 if ((bgp_input_filter(peer, rn_p, &attr, afi,
12349 safi))
12350 == FILTER_DENY)
12351 route_filtered = true;
12352
12353 /* Filter prefix using route-map */
12354 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
12355 safi, rmap_name, NULL,
12356 0, NULL);
12357
12358 if (type == bgp_show_adj_route_filtered &&
12359 !route_filtered && ret != RMAP_DENY) {
12360 bgp_attr_undup(&attr, ain->attr);
12361 continue;
12362 }
12363
12364 if (type == bgp_show_adj_route_received &&
12365 (route_filtered || ret == RMAP_DENY))
12366 filtered_count++;
12367
12368 route_vty_out_tmp(vty, rn_p, &attr, safi,
12369 use_json, json_ar, wide);
12370 bgp_attr_undup(&attr, ain->attr);
12371 output_count++;
12372 }
12373 } else if (type == bgp_show_adj_route_advertised) {
12374 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
12375 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
12376 if (paf->peer != peer || !adj->attr)
12377 continue;
12378
12379 show_adj_route_header(
12380 vty, bgp, table, &header1,
12381 &header2, json, json_scode,
12382 json_ocode, wide);
12383
12384 const struct prefix *rn_p =
12385 bgp_dest_get_prefix(dest);
12386
12387 attr = *adj->attr;
12388 ret = bgp_output_modifier(
12389 peer, rn_p, &attr, afi, safi,
12390 rmap_name);
12391
12392 if (ret != RMAP_DENY) {
12393 route_vty_out_tmp(
12394 vty, rn_p, &attr, safi,
12395 use_json, json_ar,
12396 wide);
12397 output_count++;
12398 } else {
12399 filtered_count++;
12400 }
12401
12402 bgp_attr_undup(&attr, adj->attr);
12403 }
12404 } else if (type == bgp_show_adj_route_bestpath) {
12405 struct bgp_path_info *pi;
12406
12407 show_adj_route_header(vty, bgp, table, &header1,
12408 &header2, json, json_scode,
12409 json_ocode, wide);
12410
12411 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
12412 pi = pi->next) {
12413 if (pi->peer != peer)
12414 continue;
12415
12416 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12417 continue;
12418
12419 route_vty_out_tmp(vty,
12420 bgp_dest_get_prefix(dest),
12421 pi->attr, safi, use_json,
12422 json_ar, wide);
12423 output_count++;
12424 }
12425 }
12426 }
12427
12428 if (use_json) {
12429 json_object_object_add(json, "advertisedRoutes", json_ar);
12430 json_object_int_add(json, "totalPrefixCounter", output_count);
12431 json_object_int_add(json, "filteredPrefixCounter",
12432 filtered_count);
12433
12434 vty_out(vty, "%s\n", json_object_to_json_string_ext(
12435 json, JSON_C_TO_STRING_PRETTY));
12436
12437 if (!output_count && !filtered_count) {
12438 json_object_free(json_scode);
12439 json_object_free(json_ocode);
12440 }
12441
12442 json_object_free(json);
12443 } else if (output_count > 0) {
12444 if (filtered_count > 0)
12445 vty_out(vty,
12446 "\nTotal number of prefixes %ld (%ld filtered)\n",
12447 output_count, filtered_count);
12448 else
12449 vty_out(vty, "\nTotal number of prefixes %ld\n",
12450 output_count);
12451 }
12452 }
12453
12454 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
12455 safi_t safi, enum bgp_show_adj_route_type type,
12456 const char *rmap_name, uint8_t show_flags)
12457 {
12458 json_object *json = NULL;
12459 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12460
12461 if (use_json)
12462 json = json_object_new_object();
12463
12464 if (!peer || !peer->afc[afi][safi]) {
12465 if (use_json) {
12466 json_object_string_add(
12467 json, "warning",
12468 "No such neighbor or address family");
12469 vty_out(vty, "%s\n", json_object_to_json_string(json));
12470 json_object_free(json);
12471 } else
12472 vty_out(vty, "%% No such neighbor or address family\n");
12473
12474 return CMD_WARNING;
12475 }
12476
12477 if ((type == bgp_show_adj_route_received
12478 || type == bgp_show_adj_route_filtered)
12479 && !CHECK_FLAG(peer->af_flags[afi][safi],
12480 PEER_FLAG_SOFT_RECONFIG)) {
12481 if (use_json) {
12482 json_object_string_add(
12483 json, "warning",
12484 "Inbound soft reconfiguration not enabled");
12485 vty_out(vty, "%s\n", json_object_to_json_string(json));
12486 json_object_free(json);
12487 } else
12488 vty_out(vty,
12489 "%% Inbound soft reconfiguration not enabled\n");
12490
12491 return CMD_WARNING;
12492 }
12493
12494 show_adj_route(vty, peer, afi, safi, type, rmap_name, json, show_flags);
12495
12496 return CMD_SUCCESS;
12497 }
12498
12499 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
12500 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
12501 "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]",
12502 SHOW_STR
12503 IP_STR
12504 BGP_STR
12505 BGP_INSTANCE_HELP_STR
12506 BGP_AFI_HELP_STR
12507 BGP_SAFI_WITH_LABEL_HELP_STR
12508 "Detailed information on TCP and BGP neighbor connections\n"
12509 "Neighbor to display information about\n"
12510 "Neighbor to display information about\n"
12511 "Neighbor on BGP configured interface\n"
12512 "Display the routes selected by best path\n"
12513 JSON_STR
12514 "Increase table width for longer prefixes\n")
12515 {
12516 afi_t afi = AFI_IP6;
12517 safi_t safi = SAFI_UNICAST;
12518 char *rmap_name = NULL;
12519 char *peerstr = NULL;
12520 struct bgp *bgp = NULL;
12521 struct peer *peer;
12522 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
12523 int idx = 0;
12524 uint8_t show_flags = 0;
12525
12526 if (uj)
12527 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12528
12529 if (wide)
12530 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12531
12532 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12533 &bgp, uj);
12534
12535 if (!idx)
12536 return CMD_WARNING;
12537
12538 argv_find(argv, argc, "neighbors", &idx);
12539 peerstr = argv[++idx]->arg;
12540
12541 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
12542 if (!peer)
12543 return CMD_WARNING;
12544
12545 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
12546 show_flags);
12547 }
12548
12549 DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
12550 show_ip_bgp_instance_neighbor_advertised_route_cmd,
12551 "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]",
12552 SHOW_STR
12553 IP_STR
12554 BGP_STR
12555 BGP_INSTANCE_HELP_STR
12556 BGP_AFI_HELP_STR
12557 BGP_SAFI_WITH_LABEL_HELP_STR
12558 "Display the entries for all address families\n"
12559 "Detailed information on TCP and BGP neighbor connections\n"
12560 "Neighbor to display information about\n"
12561 "Neighbor to display information about\n"
12562 "Neighbor on BGP configured interface\n"
12563 "Display the routes advertised to a BGP neighbor\n"
12564 "Display the received routes from neighbor\n"
12565 "Display the filtered routes received from neighbor\n"
12566 "Route-map to modify the attributes\n"
12567 "Name of the route map\n"
12568 JSON_STR
12569 "Increase table width for longer prefixes\n")
12570 {
12571 afi_t afi = AFI_IP6;
12572 safi_t safi = SAFI_UNICAST;
12573 char *rmap_name = NULL;
12574 char *peerstr = NULL;
12575 struct bgp *bgp = NULL;
12576 struct peer *peer;
12577 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
12578 int idx = 0;
12579 bool first = true;
12580 uint8_t show_flags = 0;
12581
12582 if (uj) {
12583 argc--;
12584 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12585 }
12586
12587 if (all) {
12588 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12589 if (argv_find(argv, argc, "ipv4", &idx))
12590 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12591
12592 if (argv_find(argv, argc, "ipv6", &idx))
12593 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12594 }
12595
12596 if (wide)
12597 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12598
12599 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12600 &bgp, uj);
12601 if (!idx)
12602 return CMD_WARNING;
12603
12604 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
12605 argv_find(argv, argc, "neighbors", &idx);
12606 peerstr = argv[++idx]->arg;
12607
12608 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
12609 if (!peer)
12610 return CMD_WARNING;
12611
12612 if (argv_find(argv, argc, "advertised-routes", &idx))
12613 type = bgp_show_adj_route_advertised;
12614 else if (argv_find(argv, argc, "received-routes", &idx))
12615 type = bgp_show_adj_route_received;
12616 else if (argv_find(argv, argc, "filtered-routes", &idx))
12617 type = bgp_show_adj_route_filtered;
12618
12619 if (argv_find(argv, argc, "route-map", &idx))
12620 rmap_name = argv[++idx]->arg;
12621
12622 if (!all)
12623 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
12624 show_flags);
12625 if (uj)
12626 vty_out(vty, "{\n");
12627
12628 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12629 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12630 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
12631 : AFI_IP6;
12632 FOREACH_SAFI (safi) {
12633 if (strmatch(get_afi_safi_str(afi, safi, true),
12634 "Unknown"))
12635 continue;
12636
12637 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
12638 continue;
12639
12640 if (uj) {
12641 if (first)
12642 first = false;
12643 else
12644 vty_out(vty, ",\n");
12645 vty_out(vty, "\"%s\":",
12646 get_afi_safi_str(afi, safi, true));
12647 } else
12648 vty_out(vty, "\nFor address family: %s\n",
12649 get_afi_safi_str(afi, safi, false));
12650
12651 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
12652 show_flags);
12653 }
12654 } else {
12655 FOREACH_AFI_SAFI (afi, safi) {
12656 if (strmatch(get_afi_safi_str(afi, safi, true),
12657 "Unknown"))
12658 continue;
12659
12660 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
12661 continue;
12662
12663 if (uj) {
12664 if (first)
12665 first = false;
12666 else
12667 vty_out(vty, ",\n");
12668 vty_out(vty, "\"%s\":",
12669 get_afi_safi_str(afi, safi, true));
12670 } else
12671 vty_out(vty, "\nFor address family: %s\n",
12672 get_afi_safi_str(afi, safi, false));
12673
12674 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
12675 show_flags);
12676 }
12677 }
12678 if (uj)
12679 vty_out(vty, "}\n");
12680
12681 return CMD_SUCCESS;
12682 }
12683
12684 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
12685 show_ip_bgp_neighbor_received_prefix_filter_cmd,
12686 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
12687 SHOW_STR
12688 IP_STR
12689 BGP_STR
12690 "Address Family\n"
12691 "Address Family\n"
12692 "Address Family modifier\n"
12693 "Detailed information on TCP and BGP neighbor connections\n"
12694 "Neighbor to display information about\n"
12695 "Neighbor to display information about\n"
12696 "Neighbor on BGP configured interface\n"
12697 "Display information received from a BGP neighbor\n"
12698 "Display the prefixlist filter\n"
12699 JSON_STR)
12700 {
12701 afi_t afi = AFI_IP6;
12702 safi_t safi = SAFI_UNICAST;
12703 char *peerstr = NULL;
12704
12705 char name[BUFSIZ];
12706 union sockunion su;
12707 struct peer *peer;
12708 int count, ret;
12709
12710 int idx = 0;
12711
12712 /* show [ip] bgp */
12713 if (argv_find(argv, argc, "ip", &idx))
12714 afi = AFI_IP;
12715 /* [<ipv4|ipv6> [unicast]] */
12716 if (argv_find(argv, argc, "ipv4", &idx))
12717 afi = AFI_IP;
12718 if (argv_find(argv, argc, "ipv6", &idx))
12719 afi = AFI_IP6;
12720 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
12721 argv_find(argv, argc, "neighbors", &idx);
12722 peerstr = argv[++idx]->arg;
12723
12724 bool uj = use_json(argc, argv);
12725
12726 ret = str2sockunion(peerstr, &su);
12727 if (ret < 0) {
12728 peer = peer_lookup_by_conf_if(NULL, peerstr);
12729 if (!peer) {
12730 if (uj)
12731 vty_out(vty, "{}\n");
12732 else
12733 vty_out(vty,
12734 "%% Malformed address or name: %s\n",
12735 peerstr);
12736 return CMD_WARNING;
12737 }
12738 } else {
12739 peer = peer_lookup(NULL, &su);
12740 if (!peer) {
12741 if (uj)
12742 vty_out(vty, "{}\n");
12743 else
12744 vty_out(vty, "No peer\n");
12745 return CMD_WARNING;
12746 }
12747 }
12748
12749 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
12750 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
12751 if (count) {
12752 if (!uj)
12753 vty_out(vty, "Address Family: %s\n",
12754 get_afi_safi_str(afi, safi, false));
12755 prefix_bgp_show_prefix_list(vty, afi, name, uj);
12756 } else {
12757 if (uj)
12758 vty_out(vty, "{}\n");
12759 else
12760 vty_out(vty, "No functional output\n");
12761 }
12762
12763 return CMD_SUCCESS;
12764 }
12765
12766 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
12767 afi_t afi, safi_t safi,
12768 enum bgp_show_type type, bool use_json)
12769 {
12770 uint8_t show_flags = 0;
12771
12772 if (use_json)
12773 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12774
12775 /* labeled-unicast routes live in the unicast table */
12776 if (safi == SAFI_LABELED_UNICAST)
12777 safi = SAFI_UNICAST;
12778
12779 if (!peer || !peer->afc[afi][safi]) {
12780 if (use_json) {
12781 json_object *json_no = NULL;
12782 json_no = json_object_new_object();
12783 json_object_string_add(
12784 json_no, "warning",
12785 "No such neighbor or address family");
12786 vty_out(vty, "%s\n",
12787 json_object_to_json_string(json_no));
12788 json_object_free(json_no);
12789 } else
12790 vty_out(vty, "%% No such neighbor or address family\n");
12791 return CMD_WARNING;
12792 }
12793
12794 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags);
12795 }
12796
12797 DEFUN (show_ip_bgp_flowspec_routes_detailed,
12798 show_ip_bgp_flowspec_routes_detailed_cmd,
12799 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
12800 SHOW_STR
12801 IP_STR
12802 BGP_STR
12803 BGP_INSTANCE_HELP_STR
12804 BGP_AFI_HELP_STR
12805 "SAFI Flowspec\n"
12806 "Detailed information on flowspec entries\n"
12807 JSON_STR)
12808 {
12809 afi_t afi = AFI_IP;
12810 safi_t safi = SAFI_UNICAST;
12811 struct bgp *bgp = NULL;
12812 int idx = 0;
12813 bool uj = use_json(argc, argv);
12814 uint8_t show_flags = 0;
12815
12816 if (uj) {
12817 argc--;
12818 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12819 }
12820
12821 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12822 &bgp, uj);
12823 if (!idx)
12824 return CMD_WARNING;
12825
12826 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
12827 show_flags);
12828 }
12829
12830 DEFUN (show_ip_bgp_neighbor_routes,
12831 show_ip_bgp_neighbor_routes_cmd,
12832 "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]",
12833 SHOW_STR
12834 IP_STR
12835 BGP_STR
12836 BGP_INSTANCE_HELP_STR
12837 BGP_AFI_HELP_STR
12838 BGP_SAFI_WITH_LABEL_HELP_STR
12839 "Detailed information on TCP and BGP neighbor connections\n"
12840 "Neighbor to display information about\n"
12841 "Neighbor to display information about\n"
12842 "Neighbor on BGP configured interface\n"
12843 "Display flap statistics of the routes learned from neighbor\n"
12844 "Display the dampened routes received from neighbor\n"
12845 "Display routes learned from neighbor\n"
12846 JSON_STR)
12847 {
12848 char *peerstr = NULL;
12849 struct bgp *bgp = NULL;
12850 afi_t afi = AFI_IP6;
12851 safi_t safi = SAFI_UNICAST;
12852 struct peer *peer;
12853 enum bgp_show_type sh_type = bgp_show_type_neighbor;
12854 int idx = 0;
12855 bool uj = use_json(argc, argv);
12856
12857 if (uj)
12858 argc--;
12859
12860 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12861 &bgp, uj);
12862 if (!idx)
12863 return CMD_WARNING;
12864
12865 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
12866 argv_find(argv, argc, "neighbors", &idx);
12867 peerstr = argv[++idx]->arg;
12868
12869 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
12870 if (!peer)
12871 return CMD_WARNING;
12872
12873 if (argv_find(argv, argc, "flap-statistics", &idx))
12874 sh_type = bgp_show_type_flap_neighbor;
12875 else if (argv_find(argv, argc, "dampened-routes", &idx))
12876 sh_type = bgp_show_type_damp_neighbor;
12877 else if (argv_find(argv, argc, "routes", &idx))
12878 sh_type = bgp_show_type_neighbor;
12879
12880 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
12881 }
12882
12883 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
12884
12885 struct bgp_distance {
12886 /* Distance value for the IP source prefix. */
12887 uint8_t distance;
12888
12889 /* Name of the access-list to be matched. */
12890 char *access_list;
12891 };
12892
12893 DEFUN (show_bgp_afi_vpn_rd_route,
12894 show_bgp_afi_vpn_rd_route_cmd,
12895 "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]",
12896 SHOW_STR
12897 BGP_STR
12898 BGP_AFI_HELP_STR
12899 "Address Family modifier\n"
12900 "Display information for a route distinguisher\n"
12901 "Route Distinguisher\n"
12902 "Network in the BGP routing table to display\n"
12903 "Network in the BGP routing table to display\n"
12904 JSON_STR)
12905 {
12906 int ret;
12907 struct prefix_rd prd;
12908 afi_t afi = AFI_MAX;
12909 int idx = 0;
12910
12911 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
12912 vty_out(vty, "%% Malformed Address Family\n");
12913 return CMD_WARNING;
12914 }
12915
12916 ret = str2prefix_rd(argv[5]->arg, &prd);
12917 if (!ret) {
12918 vty_out(vty, "%% Malformed Route Distinguisher\n");
12919 return CMD_WARNING;
12920 }
12921
12922 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
12923 0, BGP_PATH_SHOW_ALL, use_json(argc, argv));
12924 }
12925
12926 static struct bgp_distance *bgp_distance_new(void)
12927 {
12928 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
12929 }
12930
12931 static void bgp_distance_free(struct bgp_distance *bdistance)
12932 {
12933 XFREE(MTYPE_BGP_DISTANCE, bdistance);
12934 }
12935
12936 static int bgp_distance_set(struct vty *vty, const char *distance_str,
12937 const char *ip_str, const char *access_list_str)
12938 {
12939 int ret;
12940 afi_t afi;
12941 safi_t safi;
12942 struct prefix p;
12943 uint8_t distance;
12944 struct bgp_dest *dest;
12945 struct bgp_distance *bdistance;
12946
12947 afi = bgp_node_afi(vty);
12948 safi = bgp_node_safi(vty);
12949
12950 ret = str2prefix(ip_str, &p);
12951 if (ret == 0) {
12952 vty_out(vty, "Malformed prefix\n");
12953 return CMD_WARNING_CONFIG_FAILED;
12954 }
12955
12956 distance = atoi(distance_str);
12957
12958 /* Get BGP distance node. */
12959 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
12960 bdistance = bgp_dest_get_bgp_distance_info(dest);
12961 if (bdistance)
12962 bgp_dest_unlock_node(dest);
12963 else {
12964 bdistance = bgp_distance_new();
12965 bgp_dest_set_bgp_distance_info(dest, bdistance);
12966 }
12967
12968 /* Set distance value. */
12969 bdistance->distance = distance;
12970
12971 /* Reset access-list configuration. */
12972 XFREE(MTYPE_AS_LIST, bdistance->access_list);
12973 if (access_list_str)
12974 bdistance->access_list =
12975 XSTRDUP(MTYPE_AS_LIST, access_list_str);
12976
12977 return CMD_SUCCESS;
12978 }
12979
12980 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
12981 const char *ip_str, const char *access_list_str)
12982 {
12983 int ret;
12984 afi_t afi;
12985 safi_t safi;
12986 struct prefix p;
12987 int distance;
12988 struct bgp_dest *dest;
12989 struct bgp_distance *bdistance;
12990
12991 afi = bgp_node_afi(vty);
12992 safi = bgp_node_safi(vty);
12993
12994 ret = str2prefix(ip_str, &p);
12995 if (ret == 0) {
12996 vty_out(vty, "Malformed prefix\n");
12997 return CMD_WARNING_CONFIG_FAILED;
12998 }
12999
13000 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
13001 if (!dest) {
13002 vty_out(vty, "Can't find specified prefix\n");
13003 return CMD_WARNING_CONFIG_FAILED;
13004 }
13005
13006 bdistance = bgp_dest_get_bgp_distance_info(dest);
13007 distance = atoi(distance_str);
13008
13009 if (bdistance->distance != distance) {
13010 vty_out(vty, "Distance does not match configured\n");
13011 return CMD_WARNING_CONFIG_FAILED;
13012 }
13013
13014 XFREE(MTYPE_AS_LIST, bdistance->access_list);
13015 bgp_distance_free(bdistance);
13016
13017 bgp_dest_set_bgp_path_info(dest, NULL);
13018 bgp_dest_unlock_node(dest);
13019 bgp_dest_unlock_node(dest);
13020
13021 return CMD_SUCCESS;
13022 }
13023
13024 /* Apply BGP information to distance method. */
13025 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
13026 afi_t afi, safi_t safi, struct bgp *bgp)
13027 {
13028 struct bgp_dest *dest;
13029 struct prefix q;
13030 struct peer *peer;
13031 struct bgp_distance *bdistance;
13032 struct access_list *alist;
13033 struct bgp_static *bgp_static;
13034
13035 if (!bgp)
13036 return 0;
13037
13038 peer = pinfo->peer;
13039
13040 if (pinfo->attr->distance)
13041 return pinfo->attr->distance;
13042
13043 /* Check source address. */
13044 sockunion2hostprefix(&peer->su, &q);
13045 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
13046 if (dest) {
13047 bdistance = bgp_dest_get_bgp_distance_info(dest);
13048 bgp_dest_unlock_node(dest);
13049
13050 if (bdistance->access_list) {
13051 alist = access_list_lookup(afi, bdistance->access_list);
13052 if (alist
13053 && access_list_apply(alist, p) == FILTER_PERMIT)
13054 return bdistance->distance;
13055 } else
13056 return bdistance->distance;
13057 }
13058
13059 /* Backdoor check. */
13060 dest = bgp_node_lookup(bgp->route[afi][safi], p);
13061 if (dest) {
13062 bgp_static = bgp_dest_get_bgp_static_info(dest);
13063 bgp_dest_unlock_node(dest);
13064
13065 if (bgp_static->backdoor) {
13066 if (bgp->distance_local[afi][safi])
13067 return bgp->distance_local[afi][safi];
13068 else
13069 return ZEBRA_IBGP_DISTANCE_DEFAULT;
13070 }
13071 }
13072
13073 if (peer->sort == BGP_PEER_EBGP) {
13074 if (bgp->distance_ebgp[afi][safi])
13075 return bgp->distance_ebgp[afi][safi];
13076 return ZEBRA_EBGP_DISTANCE_DEFAULT;
13077 } else {
13078 if (bgp->distance_ibgp[afi][safi])
13079 return bgp->distance_ibgp[afi][safi];
13080 return ZEBRA_IBGP_DISTANCE_DEFAULT;
13081 }
13082 }
13083
13084 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
13085 * we should tell ZEBRA update the routes for a specific
13086 * AFI/SAFI to reflect changes in RIB.
13087 */
13088 static void bgp_announce_routes_distance_update(struct bgp *bgp,
13089 afi_t update_afi,
13090 safi_t update_safi)
13091 {
13092 afi_t afi;
13093 safi_t safi;
13094
13095 FOREACH_AFI_SAFI (afi, safi) {
13096 if (!bgp_fibupd_safi(safi))
13097 continue;
13098
13099 if (afi != update_afi && safi != update_safi)
13100 continue;
13101
13102 if (BGP_DEBUG(zebra, ZEBRA))
13103 zlog_debug(
13104 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
13105 __func__, afi, safi);
13106 bgp_zebra_announce_table(bgp, afi, safi);
13107 }
13108 }
13109
13110 DEFUN (bgp_distance,
13111 bgp_distance_cmd,
13112 "distance bgp (1-255) (1-255) (1-255)",
13113 "Define an administrative distance\n"
13114 "BGP distance\n"
13115 "Distance for routes external to the AS\n"
13116 "Distance for routes internal to the AS\n"
13117 "Distance for local routes\n")
13118 {
13119 VTY_DECLVAR_CONTEXT(bgp, bgp);
13120 int idx_number = 2;
13121 int idx_number_2 = 3;
13122 int idx_number_3 = 4;
13123 int distance_ebgp = atoi(argv[idx_number]->arg);
13124 int distance_ibgp = atoi(argv[idx_number_2]->arg);
13125 int distance_local = atoi(argv[idx_number_3]->arg);
13126 afi_t afi;
13127 safi_t safi;
13128
13129 afi = bgp_node_afi(vty);
13130 safi = bgp_node_safi(vty);
13131
13132 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
13133 || bgp->distance_ibgp[afi][safi] != distance_ibgp
13134 || bgp->distance_local[afi][safi] != distance_local) {
13135 bgp->distance_ebgp[afi][safi] = distance_ebgp;
13136 bgp->distance_ibgp[afi][safi] = distance_ibgp;
13137 bgp->distance_local[afi][safi] = distance_local;
13138 bgp_announce_routes_distance_update(bgp, afi, safi);
13139 }
13140 return CMD_SUCCESS;
13141 }
13142
13143 DEFUN (no_bgp_distance,
13144 no_bgp_distance_cmd,
13145 "no distance bgp [(1-255) (1-255) (1-255)]",
13146 NO_STR
13147 "Define an administrative distance\n"
13148 "BGP distance\n"
13149 "Distance for routes external to the AS\n"
13150 "Distance for routes internal to the AS\n"
13151 "Distance for local routes\n")
13152 {
13153 VTY_DECLVAR_CONTEXT(bgp, bgp);
13154 afi_t afi;
13155 safi_t safi;
13156
13157 afi = bgp_node_afi(vty);
13158 safi = bgp_node_safi(vty);
13159
13160 if (bgp->distance_ebgp[afi][safi] != 0
13161 || bgp->distance_ibgp[afi][safi] != 0
13162 || bgp->distance_local[afi][safi] != 0) {
13163 bgp->distance_ebgp[afi][safi] = 0;
13164 bgp->distance_ibgp[afi][safi] = 0;
13165 bgp->distance_local[afi][safi] = 0;
13166 bgp_announce_routes_distance_update(bgp, afi, safi);
13167 }
13168 return CMD_SUCCESS;
13169 }
13170
13171
13172 DEFUN (bgp_distance_source,
13173 bgp_distance_source_cmd,
13174 "distance (1-255) A.B.C.D/M",
13175 "Define an administrative distance\n"
13176 "Administrative distance\n"
13177 "IP source prefix\n")
13178 {
13179 int idx_number = 1;
13180 int idx_ipv4_prefixlen = 2;
13181 bgp_distance_set(vty, argv[idx_number]->arg,
13182 argv[idx_ipv4_prefixlen]->arg, NULL);
13183 return CMD_SUCCESS;
13184 }
13185
13186 DEFUN (no_bgp_distance_source,
13187 no_bgp_distance_source_cmd,
13188 "no distance (1-255) A.B.C.D/M",
13189 NO_STR
13190 "Define an administrative distance\n"
13191 "Administrative distance\n"
13192 "IP source prefix\n")
13193 {
13194 int idx_number = 2;
13195 int idx_ipv4_prefixlen = 3;
13196 bgp_distance_unset(vty, argv[idx_number]->arg,
13197 argv[idx_ipv4_prefixlen]->arg, NULL);
13198 return CMD_SUCCESS;
13199 }
13200
13201 DEFUN (bgp_distance_source_access_list,
13202 bgp_distance_source_access_list_cmd,
13203 "distance (1-255) A.B.C.D/M WORD",
13204 "Define an administrative distance\n"
13205 "Administrative distance\n"
13206 "IP source prefix\n"
13207 "Access list name\n")
13208 {
13209 int idx_number = 1;
13210 int idx_ipv4_prefixlen = 2;
13211 int idx_word = 3;
13212 bgp_distance_set(vty, argv[idx_number]->arg,
13213 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
13214 return CMD_SUCCESS;
13215 }
13216
13217 DEFUN (no_bgp_distance_source_access_list,
13218 no_bgp_distance_source_access_list_cmd,
13219 "no distance (1-255) A.B.C.D/M WORD",
13220 NO_STR
13221 "Define an administrative distance\n"
13222 "Administrative distance\n"
13223 "IP source prefix\n"
13224 "Access list name\n")
13225 {
13226 int idx_number = 2;
13227 int idx_ipv4_prefixlen = 3;
13228 int idx_word = 4;
13229 bgp_distance_unset(vty, argv[idx_number]->arg,
13230 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
13231 return CMD_SUCCESS;
13232 }
13233
13234 DEFUN (ipv6_bgp_distance_source,
13235 ipv6_bgp_distance_source_cmd,
13236 "distance (1-255) X:X::X:X/M",
13237 "Define an administrative distance\n"
13238 "Administrative distance\n"
13239 "IP source prefix\n")
13240 {
13241 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
13242 return CMD_SUCCESS;
13243 }
13244
13245 DEFUN (no_ipv6_bgp_distance_source,
13246 no_ipv6_bgp_distance_source_cmd,
13247 "no distance (1-255) X:X::X:X/M",
13248 NO_STR
13249 "Define an administrative distance\n"
13250 "Administrative distance\n"
13251 "IP source prefix\n")
13252 {
13253 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
13254 return CMD_SUCCESS;
13255 }
13256
13257 DEFUN (ipv6_bgp_distance_source_access_list,
13258 ipv6_bgp_distance_source_access_list_cmd,
13259 "distance (1-255) X:X::X:X/M WORD",
13260 "Define an administrative distance\n"
13261 "Administrative distance\n"
13262 "IP source prefix\n"
13263 "Access list name\n")
13264 {
13265 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
13266 return CMD_SUCCESS;
13267 }
13268
13269 DEFUN (no_ipv6_bgp_distance_source_access_list,
13270 no_ipv6_bgp_distance_source_access_list_cmd,
13271 "no distance (1-255) X:X::X:X/M WORD",
13272 NO_STR
13273 "Define an administrative distance\n"
13274 "Administrative distance\n"
13275 "IP source prefix\n"
13276 "Access list name\n")
13277 {
13278 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
13279 return CMD_SUCCESS;
13280 }
13281
13282 DEFUN (bgp_damp_set,
13283 bgp_damp_set_cmd,
13284 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
13285 "BGP Specific commands\n"
13286 "Enable route-flap dampening\n"
13287 "Half-life time for the penalty\n"
13288 "Value to start reusing a route\n"
13289 "Value to start suppressing a route\n"
13290 "Maximum duration to suppress a stable route\n")
13291 {
13292 VTY_DECLVAR_CONTEXT(bgp, bgp);
13293 int idx_half_life = 2;
13294 int idx_reuse = 3;
13295 int idx_suppress = 4;
13296 int idx_max_suppress = 5;
13297 int half = DEFAULT_HALF_LIFE * 60;
13298 int reuse = DEFAULT_REUSE;
13299 int suppress = DEFAULT_SUPPRESS;
13300 int max = 4 * half;
13301
13302 if (argc == 6) {
13303 half = atoi(argv[idx_half_life]->arg) * 60;
13304 reuse = atoi(argv[idx_reuse]->arg);
13305 suppress = atoi(argv[idx_suppress]->arg);
13306 max = atoi(argv[idx_max_suppress]->arg) * 60;
13307 } else if (argc == 3) {
13308 half = atoi(argv[idx_half_life]->arg) * 60;
13309 max = 4 * half;
13310 }
13311
13312 /*
13313 * These can't be 0 but our SA doesn't understand the
13314 * way our cli is constructed
13315 */
13316 assert(reuse);
13317 assert(half);
13318 if (suppress < reuse) {
13319 vty_out(vty,
13320 "Suppress value cannot be less than reuse value \n");
13321 return 0;
13322 }
13323
13324 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
13325 reuse, suppress, max);
13326 }
13327
13328 DEFUN (bgp_damp_unset,
13329 bgp_damp_unset_cmd,
13330 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
13331 NO_STR
13332 "BGP Specific commands\n"
13333 "Enable route-flap dampening\n"
13334 "Half-life time for the penalty\n"
13335 "Value to start reusing a route\n"
13336 "Value to start suppressing a route\n"
13337 "Maximum duration to suppress a stable route\n")
13338 {
13339 VTY_DECLVAR_CONTEXT(bgp, bgp);
13340 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
13341 }
13342
13343 /* Display specified route of BGP table. */
13344 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
13345 const char *ip_str, afi_t afi, safi_t safi,
13346 struct prefix_rd *prd, int prefix_check)
13347 {
13348 int ret;
13349 struct prefix match;
13350 struct bgp_dest *dest;
13351 struct bgp_dest *rm;
13352 struct bgp_path_info *pi;
13353 struct bgp_path_info *pi_temp;
13354 struct bgp *bgp;
13355 struct bgp_table *table;
13356
13357 /* BGP structure lookup. */
13358 if (view_name) {
13359 bgp = bgp_lookup_by_name(view_name);
13360 if (bgp == NULL) {
13361 vty_out(vty, "%% Can't find BGP instance %s\n",
13362 view_name);
13363 return CMD_WARNING;
13364 }
13365 } else {
13366 bgp = bgp_get_default();
13367 if (bgp == NULL) {
13368 vty_out(vty, "%% No BGP process is configured\n");
13369 return CMD_WARNING;
13370 }
13371 }
13372
13373 /* Check IP address argument. */
13374 ret = str2prefix(ip_str, &match);
13375 if (!ret) {
13376 vty_out(vty, "%% address is malformed\n");
13377 return CMD_WARNING;
13378 }
13379
13380 match.family = afi2family(afi);
13381
13382 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13383 || (safi == SAFI_EVPN)) {
13384 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
13385 dest = bgp_route_next(dest)) {
13386 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
13387
13388 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
13389 continue;
13390 table = bgp_dest_get_bgp_table_info(dest);
13391 if (!table)
13392 continue;
13393 if ((rm = bgp_node_match(table, &match)) == NULL)
13394 continue;
13395
13396 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
13397
13398 if (!prefix_check
13399 || rm_p->prefixlen == match.prefixlen) {
13400 pi = bgp_dest_get_bgp_path_info(rm);
13401 while (pi) {
13402 if (pi->extra && pi->extra->damp_info) {
13403 pi_temp = pi->next;
13404 bgp_damp_info_free(
13405 pi->extra->damp_info,
13406 1, afi, safi);
13407 pi = pi_temp;
13408 } else
13409 pi = pi->next;
13410 }
13411 }
13412
13413 bgp_dest_unlock_node(rm);
13414 }
13415 } else {
13416 if ((dest = bgp_node_match(bgp->rib[afi][safi], &match))
13417 != NULL) {
13418 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
13419
13420 if (!prefix_check
13421 || dest_p->prefixlen == match.prefixlen) {
13422 pi = bgp_dest_get_bgp_path_info(dest);
13423 while (pi) {
13424 if (pi->extra && pi->extra->damp_info) {
13425 pi_temp = pi->next;
13426 bgp_damp_info_free(
13427 pi->extra->damp_info,
13428 1, afi, safi);
13429 pi = pi_temp;
13430 } else
13431 pi = pi->next;
13432 }
13433 }
13434
13435 bgp_dest_unlock_node(dest);
13436 }
13437 }
13438
13439 return CMD_SUCCESS;
13440 }
13441
13442 DEFUN (clear_ip_bgp_dampening,
13443 clear_ip_bgp_dampening_cmd,
13444 "clear ip bgp dampening",
13445 CLEAR_STR
13446 IP_STR
13447 BGP_STR
13448 "Clear route flap dampening information\n")
13449 {
13450 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
13451 return CMD_SUCCESS;
13452 }
13453
13454 DEFUN (clear_ip_bgp_dampening_prefix,
13455 clear_ip_bgp_dampening_prefix_cmd,
13456 "clear ip bgp dampening A.B.C.D/M",
13457 CLEAR_STR
13458 IP_STR
13459 BGP_STR
13460 "Clear route flap dampening information\n"
13461 "IPv4 prefix\n")
13462 {
13463 int idx_ipv4_prefixlen = 4;
13464 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
13465 AFI_IP, SAFI_UNICAST, NULL, 1);
13466 }
13467
13468 DEFUN (clear_ip_bgp_dampening_address,
13469 clear_ip_bgp_dampening_address_cmd,
13470 "clear ip bgp dampening A.B.C.D",
13471 CLEAR_STR
13472 IP_STR
13473 BGP_STR
13474 "Clear route flap dampening information\n"
13475 "Network to clear damping information\n")
13476 {
13477 int idx_ipv4 = 4;
13478 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
13479 SAFI_UNICAST, NULL, 0);
13480 }
13481
13482 DEFUN (clear_ip_bgp_dampening_address_mask,
13483 clear_ip_bgp_dampening_address_mask_cmd,
13484 "clear ip bgp dampening A.B.C.D A.B.C.D",
13485 CLEAR_STR
13486 IP_STR
13487 BGP_STR
13488 "Clear route flap dampening information\n"
13489 "Network to clear damping information\n"
13490 "Network mask\n")
13491 {
13492 int idx_ipv4 = 4;
13493 int idx_ipv4_2 = 5;
13494 int ret;
13495 char prefix_str[BUFSIZ];
13496
13497 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
13498 prefix_str);
13499 if (!ret) {
13500 vty_out(vty, "%% Inconsistent address and mask\n");
13501 return CMD_WARNING;
13502 }
13503
13504 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
13505 NULL, 0);
13506 }
13507
13508 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
13509 {
13510 struct vty *vty = arg;
13511 struct peer *peer = bucket->data;
13512 char buf[SU_ADDRSTRLEN];
13513
13514 vty_out(vty, "\tPeer: %s %s\n", peer->host,
13515 sockunion2str(&peer->su, buf, sizeof(buf)));
13516 }
13517
13518 DEFUN (show_bgp_listeners,
13519 show_bgp_listeners_cmd,
13520 "show bgp listeners",
13521 SHOW_STR
13522 BGP_STR
13523 "Display Listen Sockets and who created them\n")
13524 {
13525 bgp_dump_listener_info(vty);
13526
13527 return CMD_SUCCESS;
13528 }
13529
13530 DEFUN (show_bgp_peerhash,
13531 show_bgp_peerhash_cmd,
13532 "show bgp peerhash",
13533 SHOW_STR
13534 BGP_STR
13535 "Display information about the BGP peerhash\n")
13536 {
13537 struct list *instances = bm->bgp;
13538 struct listnode *node;
13539 struct bgp *bgp;
13540
13541 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
13542 vty_out(vty, "BGP: %s\n", bgp->name);
13543 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
13544 vty);
13545 }
13546
13547 return CMD_SUCCESS;
13548 }
13549
13550 /* also used for encap safi */
13551 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
13552 afi_t afi, safi_t safi)
13553 {
13554 struct bgp_dest *pdest;
13555 struct bgp_dest *dest;
13556 struct bgp_table *table;
13557 const struct prefix *p;
13558 const struct prefix_rd *prd;
13559 struct bgp_static *bgp_static;
13560 mpls_label_t label;
13561 char buf[SU_ADDRSTRLEN];
13562 char rdbuf[RD_ADDRSTRLEN];
13563
13564 /* Network configuration. */
13565 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
13566 pdest = bgp_route_next(pdest)) {
13567 table = bgp_dest_get_bgp_table_info(pdest);
13568 if (!table)
13569 continue;
13570
13571 for (dest = bgp_table_top(table); dest;
13572 dest = bgp_route_next(dest)) {
13573 bgp_static = bgp_dest_get_bgp_static_info(dest);
13574 if (bgp_static == NULL)
13575 continue;
13576
13577 p = bgp_dest_get_prefix(dest);
13578 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
13579 pdest);
13580
13581 /* "network" configuration display. */
13582 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
13583 label = decode_label(&bgp_static->label);
13584
13585 vty_out(vty, " network %s/%d rd %s",
13586 inet_ntop(p->family, &p->u.prefix, buf,
13587 SU_ADDRSTRLEN),
13588 p->prefixlen, rdbuf);
13589 if (safi == SAFI_MPLS_VPN)
13590 vty_out(vty, " label %u", label);
13591
13592 if (bgp_static->rmap.name)
13593 vty_out(vty, " route-map %s",
13594 bgp_static->rmap.name);
13595
13596 if (bgp_static->backdoor)
13597 vty_out(vty, " backdoor");
13598
13599 vty_out(vty, "\n");
13600 }
13601 }
13602 }
13603
13604 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
13605 afi_t afi, safi_t safi)
13606 {
13607 struct bgp_dest *pdest;
13608 struct bgp_dest *dest;
13609 struct bgp_table *table;
13610 const struct prefix *p;
13611 const struct prefix_rd *prd;
13612 struct bgp_static *bgp_static;
13613 char buf[PREFIX_STRLEN * 2];
13614 char buf2[SU_ADDRSTRLEN];
13615 char rdbuf[RD_ADDRSTRLEN];
13616 char esi_buf[ESI_BYTES];
13617
13618 /* Network configuration. */
13619 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
13620 pdest = bgp_route_next(pdest)) {
13621 table = bgp_dest_get_bgp_table_info(pdest);
13622 if (!table)
13623 continue;
13624
13625 for (dest = bgp_table_top(table); dest;
13626 dest = bgp_route_next(dest)) {
13627 bgp_static = bgp_dest_get_bgp_static_info(dest);
13628 if (bgp_static == NULL)
13629 continue;
13630
13631 char *macrouter = NULL;
13632
13633 if (bgp_static->router_mac)
13634 macrouter = prefix_mac2str(
13635 bgp_static->router_mac, NULL, 0);
13636 if (bgp_static->eth_s_id)
13637 esi_to_str(bgp_static->eth_s_id,
13638 esi_buf, sizeof(esi_buf));
13639 p = bgp_dest_get_prefix(dest);
13640 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
13641
13642 /* "network" configuration display. */
13643 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
13644 if (p->u.prefix_evpn.route_type == 5) {
13645 char local_buf[PREFIX_STRLEN];
13646 uint8_t family = is_evpn_prefix_ipaddr_v4((
13647 struct prefix_evpn *)p)
13648 ? AF_INET
13649 : AF_INET6;
13650 inet_ntop(family,
13651 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
13652 local_buf, PREFIX_STRLEN);
13653 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
13654 p->u.prefix_evpn.prefix_addr
13655 .ip_prefix_length);
13656 } else {
13657 prefix2str(p, buf, sizeof(buf));
13658 }
13659
13660 if (bgp_static->gatewayIp.family == AF_INET
13661 || bgp_static->gatewayIp.family == AF_INET6)
13662 inet_ntop(bgp_static->gatewayIp.family,
13663 &bgp_static->gatewayIp.u.prefix, buf2,
13664 sizeof(buf2));
13665 vty_out(vty,
13666 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
13667 buf, rdbuf,
13668 p->u.prefix_evpn.prefix_addr.eth_tag,
13669 decode_label(&bgp_static->label), esi_buf, buf2,
13670 macrouter);
13671
13672 XFREE(MTYPE_TMP, macrouter);
13673 }
13674 }
13675 }
13676
13677 /* Configuration of static route announcement and aggregate
13678 information. */
13679 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
13680 safi_t safi)
13681 {
13682 struct bgp_dest *dest;
13683 const struct prefix *p;
13684 struct bgp_static *bgp_static;
13685 struct bgp_aggregate *bgp_aggregate;
13686 char buf[SU_ADDRSTRLEN];
13687
13688 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
13689 bgp_config_write_network_vpn(vty, bgp, afi, safi);
13690 return;
13691 }
13692
13693 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
13694 bgp_config_write_network_evpn(vty, bgp, afi, safi);
13695 return;
13696 }
13697
13698 /* Network configuration. */
13699 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
13700 dest = bgp_route_next(dest)) {
13701 bgp_static = bgp_dest_get_bgp_static_info(dest);
13702 if (bgp_static == NULL)
13703 continue;
13704
13705 p = bgp_dest_get_prefix(dest);
13706
13707 vty_out(vty, " network %s/%d",
13708 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
13709 p->prefixlen);
13710
13711 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
13712 vty_out(vty, " label-index %u",
13713 bgp_static->label_index);
13714
13715 if (bgp_static->rmap.name)
13716 vty_out(vty, " route-map %s", bgp_static->rmap.name);
13717
13718 if (bgp_static->backdoor)
13719 vty_out(vty, " backdoor");
13720
13721 vty_out(vty, "\n");
13722 }
13723
13724 /* Aggregate-address configuration. */
13725 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
13726 dest = bgp_route_next(dest)) {
13727 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
13728 if (bgp_aggregate == NULL)
13729 continue;
13730
13731 p = bgp_dest_get_prefix(dest);
13732
13733 vty_out(vty, " aggregate-address %s/%d",
13734 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
13735 p->prefixlen);
13736
13737 if (bgp_aggregate->as_set)
13738 vty_out(vty, " as-set");
13739
13740 if (bgp_aggregate->summary_only)
13741 vty_out(vty, " summary-only");
13742
13743 if (bgp_aggregate->rmap.name)
13744 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
13745
13746 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
13747 vty_out(vty, " origin %s",
13748 bgp_origin2str(bgp_aggregate->origin));
13749
13750 vty_out(vty, "\n");
13751 }
13752 }
13753
13754 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
13755 safi_t safi)
13756 {
13757 struct bgp_dest *dest;
13758 struct bgp_distance *bdistance;
13759
13760 /* Distance configuration. */
13761 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
13762 && bgp->distance_local[afi][safi]
13763 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
13764 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
13765 || bgp->distance_local[afi][safi]
13766 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
13767 vty_out(vty, " distance bgp %d %d %d\n",
13768 bgp->distance_ebgp[afi][safi],
13769 bgp->distance_ibgp[afi][safi],
13770 bgp->distance_local[afi][safi]);
13771 }
13772
13773 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
13774 dest = bgp_route_next(dest)) {
13775 bdistance = bgp_dest_get_bgp_distance_info(dest);
13776 if (bdistance != NULL)
13777 vty_out(vty, " distance %d %pRN %s\n",
13778 bdistance->distance, dest,
13779 bdistance->access_list ? bdistance->access_list
13780 : "");
13781 }
13782 }
13783
13784 /* Allocate routing table structure and install commands. */
13785 void bgp_route_init(void)
13786 {
13787 afi_t afi;
13788 safi_t safi;
13789
13790 /* Init BGP distance table. */
13791 FOREACH_AFI_SAFI (afi, safi)
13792 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
13793
13794 /* IPv4 BGP commands. */
13795 install_element(BGP_NODE, &bgp_table_map_cmd);
13796 install_element(BGP_NODE, &bgp_network_cmd);
13797 install_element(BGP_NODE, &no_bgp_table_map_cmd);
13798
13799 install_element(BGP_NODE, &aggregate_addressv4_cmd);
13800
13801 /* IPv4 unicast configuration. */
13802 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
13803 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
13804 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
13805
13806 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
13807
13808 /* IPv4 multicast configuration. */
13809 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
13810 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
13811 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
13812 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
13813
13814 /* IPv4 labeled-unicast configuration. */
13815 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
13816 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
13817
13818 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
13819 install_element(VIEW_NODE, &show_ip_bgp_cmd);
13820 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
13821 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
13822 install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
13823 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
13824 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
13825 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
13826
13827 install_element(VIEW_NODE,
13828 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
13829 install_element(VIEW_NODE,
13830 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
13831 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
13832 install_element(VIEW_NODE,
13833 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
13834 #ifdef KEEP_OLD_VPN_COMMANDS
13835 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
13836 #endif /* KEEP_OLD_VPN_COMMANDS */
13837 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
13838 install_element(VIEW_NODE,
13839 &show_bgp_l2vpn_evpn_route_prefix_cmd);
13840
13841 /* BGP dampening clear commands */
13842 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
13843 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
13844
13845 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
13846 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
13847
13848 /* prefix count */
13849 install_element(ENABLE_NODE,
13850 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
13851 #ifdef KEEP_OLD_VPN_COMMANDS
13852 install_element(ENABLE_NODE,
13853 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
13854 #endif /* KEEP_OLD_VPN_COMMANDS */
13855
13856 /* New config IPv6 BGP commands. */
13857 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
13858 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
13859 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
13860
13861 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
13862
13863 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
13864
13865 /* IPv6 labeled unicast address family. */
13866 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
13867 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
13868
13869 install_element(BGP_NODE, &bgp_distance_cmd);
13870 install_element(BGP_NODE, &no_bgp_distance_cmd);
13871 install_element(BGP_NODE, &bgp_distance_source_cmd);
13872 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
13873 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
13874 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
13875 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
13876 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
13877 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
13878 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
13879 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
13880 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
13881 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
13882 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
13883 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
13884 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
13885 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
13886 install_element(BGP_IPV4M_NODE,
13887 &no_bgp_distance_source_access_list_cmd);
13888 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
13889 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
13890 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
13891 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
13892 install_element(BGP_IPV6_NODE,
13893 &ipv6_bgp_distance_source_access_list_cmd);
13894 install_element(BGP_IPV6_NODE,
13895 &no_ipv6_bgp_distance_source_access_list_cmd);
13896 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
13897 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
13898 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
13899 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
13900 install_element(BGP_IPV6M_NODE,
13901 &ipv6_bgp_distance_source_access_list_cmd);
13902 install_element(BGP_IPV6M_NODE,
13903 &no_ipv6_bgp_distance_source_access_list_cmd);
13904
13905 /* BGP dampening */
13906 install_element(BGP_NODE, &bgp_damp_set_cmd);
13907 install_element(BGP_NODE, &bgp_damp_unset_cmd);
13908 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
13909 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
13910 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
13911 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
13912 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
13913 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
13914 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
13915 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
13916 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
13917 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
13918 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
13919 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
13920
13921 /* Large Communities */
13922 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
13923 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
13924
13925 /* show bgp ipv4 flowspec detailed */
13926 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
13927
13928 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
13929 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
13930 }
13931
13932 void bgp_route_finish(void)
13933 {
13934 afi_t afi;
13935 safi_t safi;
13936
13937 FOREACH_AFI_SAFI (afi, safi) {
13938 bgp_table_unlock(bgp_distance_table[afi][safi]);
13939 bgp_distance_table[afi][safi] = NULL;
13940 }
13941 }