]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
bgpd: Correctly calculate threshold being reached
[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
3171 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3172 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3173 PEER_STATUS_PREFIX_THRESHOLD)
3174 && !always)
3175 return false;
3176
3177 zlog_info(
3178 "%%MAXPFX: No. of %s prefix received from %s reaches %u, max %u",
3179 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3180 peer->pmax[afi][safi]);
3181 SET_FLAG(peer->af_sflags[afi][safi],
3182 PEER_STATUS_PREFIX_THRESHOLD);
3183 } else
3184 UNSET_FLAG(peer->af_sflags[afi][safi],
3185 PEER_STATUS_PREFIX_THRESHOLD);
3186 return false;
3187 }
3188
3189 /* Unconditionally remove the route from the RIB, without taking
3190 * damping into consideration (eg, because the session went down)
3191 */
3192 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3193 struct peer *peer, afi_t afi, safi_t safi)
3194 {
3195
3196 struct bgp *bgp = NULL;
3197 bool delete_route = false;
3198
3199 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3200 safi);
3201
3202 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3203 bgp_path_info_delete(dest, pi); /* keep historical info */
3204
3205 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3206 * flag
3207 */
3208 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3209 delete_route = true;
3210 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3211 delete_route = true;
3212 if (delete_route) {
3213 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3214 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3215 bgp = pi->peer->bgp;
3216 if ((dest->rt_node)
3217 && (bgp->gr_info[afi][safi].route_list)) {
3218 list_delete_node(bgp->gr_info[afi][safi]
3219 .route_list,
3220 dest->rt_node);
3221 dest->rt_node = NULL;
3222 }
3223 }
3224 }
3225 }
3226
3227 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3228 bgp_process(peer->bgp, dest, afi, safi);
3229 }
3230
3231 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3232 struct peer *peer, afi_t afi, safi_t safi,
3233 struct prefix_rd *prd)
3234 {
3235 const struct prefix *p = bgp_dest_get_prefix(dest);
3236
3237 /* apply dampening, if result is suppressed, we'll be retaining
3238 * the bgp_path_info in the RIB for historical reference.
3239 */
3240 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3241 && peer->sort == BGP_PEER_EBGP)
3242 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3243 == BGP_DAMP_SUPPRESSED) {
3244 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3245 safi);
3246 return;
3247 }
3248
3249 #ifdef ENABLE_BGP_VNC
3250 if (safi == SAFI_MPLS_VPN) {
3251 struct bgp_dest *pdest = NULL;
3252 struct bgp_table *table = NULL;
3253
3254 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3255 (struct prefix *)prd);
3256 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3257 table = bgp_dest_get_bgp_table_info(pdest);
3258
3259 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3260 peer->bgp, prd, table, p, pi);
3261 }
3262 bgp_dest_unlock_node(pdest);
3263 }
3264 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3265 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3266
3267 vnc_import_bgp_del_route(peer->bgp, p, pi);
3268 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3269 }
3270 }
3271 #endif
3272
3273 /* If this is an EVPN route, process for un-import. */
3274 if (safi == SAFI_EVPN)
3275 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3276
3277 bgp_rib_remove(dest, pi, peer, afi, safi);
3278 }
3279
3280 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3281 struct peer *peer, struct attr *attr,
3282 struct bgp_dest *dest)
3283 {
3284 struct bgp_path_info *new;
3285
3286 /* Make new BGP info. */
3287 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3288 new->type = type;
3289 new->instance = instance;
3290 new->sub_type = sub_type;
3291 new->peer = peer;
3292 new->attr = attr;
3293 new->uptime = bgp_clock();
3294 new->net = dest;
3295 return new;
3296 }
3297
3298 static void overlay_index_update(struct attr *attr,
3299 union gw_addr *gw_ip)
3300 {
3301 if (!attr)
3302 return;
3303 if (gw_ip == NULL) {
3304 memset(&(attr->evpn_overlay.gw_ip), 0, sizeof(union gw_addr));
3305 } else {
3306 memcpy(&(attr->evpn_overlay.gw_ip), gw_ip,
3307 sizeof(union gw_addr));
3308 }
3309 }
3310
3311 static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path,
3312 union gw_addr *gw_ip)
3313 {
3314 union gw_addr *path_gw_ip, *path_gw_ip_remote;
3315 union {
3316 esi_t esi;
3317 union gw_addr ip;
3318 } temp;
3319
3320 if (afi != AFI_L2VPN)
3321 return true;
3322
3323 path_gw_ip = &(path->attr->evpn_overlay.gw_ip);
3324
3325 if (gw_ip == NULL) {
3326 memset(&temp, 0, sizeof(temp));
3327 path_gw_ip_remote = &temp.ip;
3328 } else
3329 path_gw_ip_remote = gw_ip;
3330
3331 return !!memcmp(path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr));
3332 }
3333
3334 /* Check if received nexthop is valid or not. */
3335 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3336 uint8_t type, uint8_t stype, struct attr *attr,
3337 struct bgp_dest *dest)
3338 {
3339 bool ret = false;
3340 bool is_bgp_static_route =
3341 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3342 : false;
3343
3344 /*
3345 * Only validated for unicast and multicast currently.
3346 * Also valid for EVPN where the nexthop is an IP address.
3347 * If we are a bgp static route being checked then there is
3348 * no need to check to see if the nexthop is martian as
3349 * that it should be ok.
3350 */
3351 if (is_bgp_static_route ||
3352 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3353 return false;
3354
3355 /* If NEXT_HOP is present, validate it. */
3356 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3357 if (attr->nexthop.s_addr == INADDR_ANY
3358 || IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr))
3359 || bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3360 return true;
3361 }
3362
3363 /* If MP_NEXTHOP is present, validate it. */
3364 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3365 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3366 * it is not an IPv6 link-local address.
3367 *
3368 * If we receive an UPDATE with nexthop length set to 32 bytes
3369 * we shouldn't discard an UPDATE if it's set to (::).
3370 * The link-local (2st) is validated along the code path later.
3371 */
3372 if (attr->mp_nexthop_len) {
3373 switch (attr->mp_nexthop_len) {
3374 case BGP_ATTR_NHLEN_IPV4:
3375 case BGP_ATTR_NHLEN_VPNV4:
3376 ret = (attr->mp_nexthop_global_in.s_addr == INADDR_ANY
3377 || IPV4_CLASS_DE(
3378 ntohl(attr->mp_nexthop_global_in.s_addr))
3379 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3380 dest));
3381 break;
3382
3383 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3384 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3385 ret = (IN6_IS_ADDR_UNSPECIFIED(
3386 &attr->mp_nexthop_global)
3387 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3388 || IN6_IS_ADDR_MULTICAST(
3389 &attr->mp_nexthop_global)
3390 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3391 dest));
3392 break;
3393 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3394 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3395 || IN6_IS_ADDR_MULTICAST(
3396 &attr->mp_nexthop_global)
3397 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3398 dest));
3399 break;
3400
3401 default:
3402 ret = true;
3403 break;
3404 }
3405 }
3406
3407 return ret;
3408 }
3409
3410 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3411 struct attr *attr, afi_t afi, safi_t safi, int type,
3412 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3413 uint32_t num_labels, int soft_reconfig,
3414 struct bgp_route_evpn *evpn)
3415 {
3416 int ret;
3417 int aspath_loop_count = 0;
3418 struct bgp_dest *dest;
3419 struct bgp *bgp;
3420 struct attr new_attr;
3421 struct attr *attr_new;
3422 struct bgp_path_info *pi;
3423 struct bgp_path_info *new;
3424 struct bgp_path_info_extra *extra;
3425 const char *reason;
3426 char pfx_buf[BGP_PRD_PATH_STRLEN];
3427 int connected = 0;
3428 int do_loop_check = 1;
3429 int has_valid_label = 0;
3430 afi_t nh_afi;
3431 uint8_t pi_type = 0;
3432 uint8_t pi_sub_type = 0;
3433
3434 #ifdef ENABLE_BGP_VNC
3435 int vnc_implicit_withdraw = 0;
3436 #endif
3437 int same_attr = 0;
3438
3439 memset(&new_attr, 0, sizeof(struct attr));
3440 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
3441 new_attr.label = MPLS_INVALID_LABEL;
3442
3443 bgp = peer->bgp;
3444 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3445 /* TODO: Check to see if we can get rid of "is_valid_label" */
3446 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3447 has_valid_label = (num_labels > 0) ? 1 : 0;
3448 else
3449 has_valid_label = bgp_is_valid_label(label);
3450
3451 /* When peer's soft reconfiguration enabled. Record input packet in
3452 Adj-RIBs-In. */
3453 if (!soft_reconfig
3454 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3455 && peer != bgp->peer_self)
3456 bgp_adj_in_set(dest, peer, attr, addpath_id);
3457
3458 /* Check previously received route. */
3459 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
3460 if (pi->peer == peer && pi->type == type
3461 && pi->sub_type == sub_type
3462 && pi->addpath_rx_id == addpath_id)
3463 break;
3464
3465 /* AS path local-as loop check. */
3466 if (peer->change_local_as) {
3467 if (peer->allowas_in[afi][safi])
3468 aspath_loop_count = peer->allowas_in[afi][safi];
3469 else if (!CHECK_FLAG(peer->flags,
3470 PEER_FLAG_LOCAL_AS_NO_PREPEND))
3471 aspath_loop_count = 1;
3472
3473 if (aspath_loop_check(attr->aspath, peer->change_local_as)
3474 > aspath_loop_count) {
3475 peer->stat_pfx_aspath_loop++;
3476 reason = "as-path contains our own AS A;";
3477 goto filtered;
3478 }
3479 }
3480
3481 /* If the peer is configured for "allowas-in origin" and the last ASN in
3482 * the
3483 * as-path is our ASN then we do not need to call aspath_loop_check
3484 */
3485 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
3486 if (aspath_get_last_as(attr->aspath) == bgp->as)
3487 do_loop_check = 0;
3488
3489 /* AS path loop check. */
3490 if (do_loop_check) {
3491 if (aspath_loop_check(attr->aspath, bgp->as)
3492 > peer->allowas_in[afi][safi]
3493 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
3494 && aspath_loop_check(attr->aspath, bgp->confed_id)
3495 > peer->allowas_in[afi][safi])) {
3496 peer->stat_pfx_aspath_loop++;
3497 reason = "as-path contains our own AS;";
3498 goto filtered;
3499 }
3500 }
3501
3502 /* Route reflector originator ID check. */
3503 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
3504 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
3505 peer->stat_pfx_originator_loop++;
3506 reason = "originator is us;";
3507 goto filtered;
3508 }
3509
3510 /* Route reflector cluster ID check. */
3511 if (bgp_cluster_filter(peer, attr)) {
3512 peer->stat_pfx_cluster_loop++;
3513 reason = "reflected from the same cluster;";
3514 goto filtered;
3515 }
3516
3517 /* Apply incoming filter. */
3518 if (bgp_input_filter(peer, p, attr, afi, safi) == FILTER_DENY) {
3519 peer->stat_pfx_filter++;
3520 reason = "filter;";
3521 goto filtered;
3522 }
3523
3524 /* RFC 8212 to prevent route leaks.
3525 * This specification intends to improve this situation by requiring the
3526 * explicit configuration of both BGP Import and Export Policies for any
3527 * External BGP (EBGP) session such as customers, peers, or
3528 * confederation boundaries for all enabled address families. Through
3529 * codification of the aforementioned requirement, operators will
3530 * benefit from consistent behavior across different BGP
3531 * implementations.
3532 */
3533 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
3534 if (!bgp_inbound_policy_exists(peer,
3535 &peer->filter[afi][safi])) {
3536 reason = "inbound policy missing";
3537 goto filtered;
3538 }
3539
3540 /* draft-ietf-idr-deprecate-as-set-confed-set
3541 * Filter routes having AS_SET or AS_CONFED_SET in the path.
3542 * Eventually, This document (if approved) updates RFC 4271
3543 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
3544 * and obsoletes RFC 6472.
3545 */
3546 if (peer->bgp->reject_as_sets)
3547 if (aspath_check_as_sets(attr->aspath)) {
3548 reason =
3549 "as-path contains AS_SET or AS_CONFED_SET type;";
3550 goto filtered;
3551 }
3552
3553 new_attr = *attr;
3554
3555 /* Apply incoming route-map.
3556 * NB: new_attr may now contain newly allocated values from route-map
3557 * "set"
3558 * commands, so we need bgp_attr_flush in the error paths, until we
3559 * intern
3560 * the attr (which takes over the memory references) */
3561 if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL, label,
3562 num_labels, dest)
3563 == RMAP_DENY) {
3564 peer->stat_pfx_filter++;
3565 reason = "route-map;";
3566 bgp_attr_flush(&new_attr);
3567 goto filtered;
3568 }
3569
3570 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
3571 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3572 /* remove from RIB previous entry */
3573 bgp_zebra_withdraw(p, pi, bgp, safi);
3574 }
3575
3576 if (peer->sort == BGP_PEER_EBGP) {
3577
3578 /* If we receive the graceful-shutdown community from an eBGP
3579 * peer we must lower local-preference */
3580 if (new_attr.community
3581 && community_include(new_attr.community, COMMUNITY_GSHUT)) {
3582 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
3583 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
3584
3585 /* If graceful-shutdown is configured then add the GSHUT
3586 * community to all paths received from eBGP peers */
3587 } else if (bgp_in_graceful_shutdown(peer->bgp))
3588 bgp_attr_add_gshut_community(&new_attr);
3589 }
3590
3591 if (pi) {
3592 pi_type = pi->type;
3593 pi_sub_type = pi->sub_type;
3594 }
3595
3596 /* next hop check. */
3597 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
3598 && bgp_update_martian_nexthop(bgp, afi, safi, pi_type, pi_sub_type,
3599 &new_attr, dest)) {
3600 peer->stat_pfx_nh_invalid++;
3601 reason = "martian or self next-hop;";
3602 bgp_attr_flush(&new_attr);
3603 goto filtered;
3604 }
3605
3606 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
3607 peer->stat_pfx_nh_invalid++;
3608 reason = "self mac;";
3609 goto filtered;
3610 }
3611
3612 /* Update Overlay Index */
3613 if (afi == AFI_L2VPN) {
3614 overlay_index_update(&new_attr,
3615 evpn == NULL ? NULL : &evpn->gw_ip);
3616 }
3617
3618 attr_new = bgp_attr_intern(&new_attr);
3619
3620 /* If maximum prefix count is configured and current prefix
3621 * count exeed it.
3622 */
3623 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0))
3624 return -1;
3625
3626 /* If the update is implicit withdraw. */
3627 if (pi) {
3628 pi->uptime = bgp_clock();
3629 same_attr = attrhash_cmp(pi->attr, attr_new);
3630
3631 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
3632
3633 /* Same attribute comes in. */
3634 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
3635 && attrhash_cmp(pi->attr, attr_new)
3636 && (!has_valid_label
3637 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
3638 num_labels * sizeof(mpls_label_t))
3639 == 0)
3640 && (overlay_index_equal(
3641 afi, pi,
3642 evpn == NULL ? NULL : &evpn->gw_ip))) {
3643 if (CHECK_FLAG(bgp->af_flags[afi][safi],
3644 BGP_CONFIG_DAMPENING)
3645 && peer->sort == BGP_PEER_EBGP
3646 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3647 if (bgp_debug_update(peer, p, NULL, 1)) {
3648 bgp_debug_rdpfxpath2str(
3649 afi, safi, prd, p, label,
3650 num_labels, addpath_id ? 1 : 0,
3651 addpath_id, pfx_buf,
3652 sizeof(pfx_buf));
3653 zlog_debug("%s rcvd %s", peer->host,
3654 pfx_buf);
3655 }
3656
3657 if (bgp_damp_update(pi, dest, afi, safi)
3658 != BGP_DAMP_SUPPRESSED) {
3659 bgp_aggregate_increment(bgp, p, pi, afi,
3660 safi);
3661 bgp_process(bgp, dest, afi, safi);
3662 }
3663 } else /* Duplicate - odd */
3664 {
3665 if (bgp_debug_update(peer, p, NULL, 1)) {
3666 if (!peer->rcvd_attr_printed) {
3667 zlog_debug(
3668 "%s rcvd UPDATE w/ attr: %s",
3669 peer->host,
3670 peer->rcvd_attr_str);
3671 peer->rcvd_attr_printed = 1;
3672 }
3673
3674 bgp_debug_rdpfxpath2str(
3675 afi, safi, prd, p, label,
3676 num_labels, addpath_id ? 1 : 0,
3677 addpath_id, pfx_buf,
3678 sizeof(pfx_buf));
3679 zlog_debug(
3680 "%s rcvd %s...duplicate ignored",
3681 peer->host, pfx_buf);
3682 }
3683
3684 /* graceful restart STALE flag unset. */
3685 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3686 bgp_path_info_unset_flag(
3687 dest, pi, BGP_PATH_STALE);
3688 bgp_dest_set_defer_flag(dest, false);
3689 bgp_process(bgp, dest, afi, safi);
3690 }
3691 }
3692
3693 bgp_dest_unlock_node(dest);
3694 bgp_attr_unintern(&attr_new);
3695
3696 return 0;
3697 }
3698
3699 /* Withdraw/Announce before we fully processed the withdraw */
3700 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
3701 if (bgp_debug_update(peer, p, NULL, 1)) {
3702 bgp_debug_rdpfxpath2str(
3703 afi, safi, prd, p, label, num_labels,
3704 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3705 sizeof(pfx_buf));
3706 zlog_debug(
3707 "%s rcvd %s, flapped quicker than processing",
3708 peer->host, pfx_buf);
3709 }
3710
3711 bgp_path_info_restore(dest, pi);
3712 }
3713
3714 /* Received Logging. */
3715 if (bgp_debug_update(peer, p, NULL, 1)) {
3716 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
3717 num_labels, addpath_id ? 1 : 0,
3718 addpath_id, pfx_buf,
3719 sizeof(pfx_buf));
3720 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3721 }
3722
3723 /* graceful restart STALE flag unset. */
3724 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3725 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
3726 bgp_dest_set_defer_flag(dest, false);
3727 }
3728
3729 /* The attribute is changed. */
3730 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
3731
3732 /* implicit withdraw, decrement aggregate and pcount here.
3733 * only if update is accepted, they'll increment below.
3734 */
3735 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
3736
3737 /* Update bgp route dampening information. */
3738 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3739 && peer->sort == BGP_PEER_EBGP) {
3740 /* This is implicit withdraw so we should update
3741 dampening
3742 information. */
3743 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
3744 bgp_damp_withdraw(pi, dest, afi, safi, 1);
3745 }
3746 #ifdef ENABLE_BGP_VNC
3747 if (safi == SAFI_MPLS_VPN) {
3748 struct bgp_dest *pdest = NULL;
3749 struct bgp_table *table = NULL;
3750
3751 pdest = bgp_node_get(bgp->rib[afi][safi],
3752 (struct prefix *)prd);
3753 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3754 table = bgp_dest_get_bgp_table_info(pdest);
3755
3756 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3757 bgp, prd, table, p, pi);
3758 }
3759 bgp_dest_unlock_node(pdest);
3760 }
3761 if ((afi == AFI_IP || afi == AFI_IP6)
3762 && (safi == SAFI_UNICAST)) {
3763 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3764 /*
3765 * Implicit withdraw case.
3766 */
3767 ++vnc_implicit_withdraw;
3768 vnc_import_bgp_del_route(bgp, p, pi);
3769 vnc_import_bgp_exterior_del_route(bgp, p, pi);
3770 }
3771 }
3772 #endif
3773
3774 /* Special handling for EVPN update of an existing route. If the
3775 * extended community attribute has changed, we need to
3776 * un-import
3777 * the route using its existing extended community. It will be
3778 * subsequently processed for import with the new extended
3779 * community.
3780 */
3781 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
3782 && !same_attr) {
3783 if ((pi->attr->flag
3784 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
3785 && (attr_new->flag
3786 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
3787 int cmp;
3788
3789 cmp = ecommunity_cmp(pi->attr->ecommunity,
3790 attr_new->ecommunity);
3791 if (!cmp) {
3792 if (bgp_debug_update(peer, p, NULL, 1))
3793 zlog_debug(
3794 "Change in EXT-COMM, existing %s new %s",
3795 ecommunity_str(
3796 pi->attr->ecommunity),
3797 ecommunity_str(
3798 attr_new->ecommunity));
3799 if (safi == SAFI_EVPN)
3800 bgp_evpn_unimport_route(
3801 bgp, afi, safi, p, pi);
3802 else /* SAFI_MPLS_VPN */
3803 vpn_leak_to_vrf_withdraw(bgp,
3804 pi);
3805 }
3806 }
3807 }
3808
3809 /* Update to new attribute. */
3810 bgp_attr_unintern(&pi->attr);
3811 pi->attr = attr_new;
3812
3813 /* Update MPLS label */
3814 if (has_valid_label) {
3815 extra = bgp_path_info_extra_get(pi);
3816 if (extra->label != label) {
3817 memcpy(&extra->label, label,
3818 num_labels * sizeof(mpls_label_t));
3819 extra->num_labels = num_labels;
3820 }
3821 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
3822 bgp_set_valid_label(&extra->label[0]);
3823 }
3824
3825 /* Update SRv6 SID */
3826 if (attr->srv6_l3vpn) {
3827 extra = bgp_path_info_extra_get(pi);
3828 if (sid_diff(&extra->sid[0], &attr->srv6_l3vpn->sid)) {
3829 sid_copy(&extra->sid[0],
3830 &attr->srv6_l3vpn->sid);
3831 extra->num_sids = 1;
3832 }
3833 } else if (attr->srv6_vpn) {
3834 extra = bgp_path_info_extra_get(pi);
3835 if (sid_diff(&extra->sid[0], &attr->srv6_vpn->sid)) {
3836 sid_copy(&extra->sid[0], &attr->srv6_vpn->sid);
3837 extra->num_sids = 1;
3838 }
3839 }
3840
3841 #ifdef ENABLE_BGP_VNC
3842 if ((afi == AFI_IP || afi == AFI_IP6)
3843 && (safi == SAFI_UNICAST)) {
3844 if (vnc_implicit_withdraw) {
3845 /*
3846 * Add back the route with its new attributes
3847 * (e.g., nexthop).
3848 * The route is still selected, until the route
3849 * selection
3850 * queued by bgp_process actually runs. We have
3851 * to make this
3852 * update to the VNC side immediately to avoid
3853 * racing against
3854 * configuration changes (e.g., route-map
3855 * changes) which
3856 * trigger re-importation of the entire RIB.
3857 */
3858 vnc_import_bgp_add_route(bgp, p, pi);
3859 vnc_import_bgp_exterior_add_route(bgp, p, pi);
3860 }
3861 }
3862 #endif
3863
3864 /* Update bgp route dampening information. */
3865 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3866 && peer->sort == BGP_PEER_EBGP) {
3867 /* Now we do normal update dampening. */
3868 ret = bgp_damp_update(pi, dest, afi, safi);
3869 if (ret == BGP_DAMP_SUPPRESSED) {
3870 bgp_dest_unlock_node(dest);
3871 return 0;
3872 }
3873 }
3874
3875 /* Nexthop reachability check - for unicast and
3876 * labeled-unicast.. */
3877 if (((afi == AFI_IP || afi == AFI_IP6)
3878 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
3879 || (safi == SAFI_EVPN &&
3880 bgp_evpn_is_prefix_nht_supported(p))) {
3881 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
3882 && peer->ttl == BGP_DEFAULT_TTL
3883 && !CHECK_FLAG(peer->flags,
3884 PEER_FLAG_DISABLE_CONNECTED_CHECK)
3885 && !CHECK_FLAG(bgp->flags,
3886 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
3887 connected = 1;
3888 else
3889 connected = 0;
3890
3891 struct bgp *bgp_nexthop = bgp;
3892
3893 if (pi->extra && pi->extra->bgp_orig)
3894 bgp_nexthop = pi->extra->bgp_orig;
3895
3896 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
3897
3898 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
3899 pi, NULL, connected)
3900 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
3901 bgp_path_info_set_flag(dest, pi,
3902 BGP_PATH_VALID);
3903 else {
3904 if (BGP_DEBUG(nht, NHT)) {
3905 zlog_debug("%s(%pI4): NH unresolved",
3906 __func__,
3907 (in_addr_t *)&attr_new->nexthop);
3908 }
3909 bgp_path_info_unset_flag(dest, pi,
3910 BGP_PATH_VALID);
3911 }
3912 } else
3913 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
3914
3915 #ifdef ENABLE_BGP_VNC
3916 if (safi == SAFI_MPLS_VPN) {
3917 struct bgp_dest *pdest = NULL;
3918 struct bgp_table *table = NULL;
3919
3920 pdest = bgp_node_get(bgp->rib[afi][safi],
3921 (struct prefix *)prd);
3922 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3923 table = bgp_dest_get_bgp_table_info(pdest);
3924
3925 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3926 bgp, prd, table, p, pi);
3927 }
3928 bgp_dest_unlock_node(pdest);
3929 }
3930 #endif
3931
3932 /* If this is an EVPN route and some attribute has changed,
3933 * process
3934 * route for import. If the extended community has changed, we
3935 * would
3936 * have done the un-import earlier and the import would result
3937 * in the
3938 * route getting injected into appropriate L2 VNIs. If it is
3939 * just
3940 * some other attribute change, the import will result in
3941 * updating
3942 * the attributes for the route in the VNI(s).
3943 */
3944 if (safi == SAFI_EVPN && !same_attr &&
3945 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
3946 bgp_evpn_import_route(bgp, afi, safi, p, pi);
3947
3948 /* Process change. */
3949 bgp_aggregate_increment(bgp, p, pi, afi, safi);
3950
3951 bgp_process(bgp, dest, afi, safi);
3952 bgp_dest_unlock_node(dest);
3953
3954 if (SAFI_UNICAST == safi
3955 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
3956 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3957
3958 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
3959 }
3960 if ((SAFI_MPLS_VPN == safi)
3961 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3962
3963 vpn_leak_to_vrf_update(bgp, pi);
3964 }
3965
3966 #ifdef ENABLE_BGP_VNC
3967 if (SAFI_MPLS_VPN == safi) {
3968 mpls_label_t label_decoded = decode_label(label);
3969
3970 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
3971 type, sub_type, &label_decoded);
3972 }
3973 if (SAFI_ENCAP == safi) {
3974 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
3975 type, sub_type, NULL);
3976 }
3977 #endif
3978
3979 return 0;
3980 } // End of implicit withdraw
3981
3982 /* Received Logging. */
3983 if (bgp_debug_update(peer, p, NULL, 1)) {
3984 if (!peer->rcvd_attr_printed) {
3985 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
3986 peer->rcvd_attr_str);
3987 peer->rcvd_attr_printed = 1;
3988 }
3989
3990 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
3991 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3992 sizeof(pfx_buf));
3993 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3994 }
3995
3996 /* Make new BGP info. */
3997 new = info_make(type, sub_type, 0, peer, attr_new, dest);
3998
3999 /* Update MPLS label */
4000 if (has_valid_label) {
4001 extra = bgp_path_info_extra_get(new);
4002 if (extra->label != label) {
4003 memcpy(&extra->label, label,
4004 num_labels * sizeof(mpls_label_t));
4005 extra->num_labels = num_labels;
4006 }
4007 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4008 bgp_set_valid_label(&extra->label[0]);
4009 }
4010
4011 /* Update SRv6 SID */
4012 if (safi == SAFI_MPLS_VPN) {
4013 extra = bgp_path_info_extra_get(new);
4014 if (attr->srv6_l3vpn) {
4015 sid_copy(&extra->sid[0], &attr->srv6_l3vpn->sid);
4016 extra->num_sids = 1;
4017 } else if (attr->srv6_vpn) {
4018 sid_copy(&extra->sid[0], &attr->srv6_vpn->sid);
4019 extra->num_sids = 1;
4020 }
4021 }
4022
4023 /* Update Overlay Index */
4024 if (afi == AFI_L2VPN) {
4025 overlay_index_update(new->attr,
4026 evpn == NULL ? NULL : &evpn->gw_ip);
4027 }
4028 /* Nexthop reachability check. */
4029 if (((afi == AFI_IP || afi == AFI_IP6)
4030 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4031 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4032 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4033 && peer->ttl == BGP_DEFAULT_TTL
4034 && !CHECK_FLAG(peer->flags,
4035 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4036 && !CHECK_FLAG(bgp->flags,
4037 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4038 connected = 1;
4039 else
4040 connected = 0;
4041
4042 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4043
4044 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, new, NULL,
4045 connected)
4046 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4047 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4048 else {
4049 if (BGP_DEBUG(nht, NHT)) {
4050 char buf1[INET6_ADDRSTRLEN];
4051 inet_ntop(AF_INET,
4052 (const void *)&attr_new->nexthop,
4053 buf1, INET6_ADDRSTRLEN);
4054 zlog_debug("%s(%s): NH unresolved", __func__,
4055 buf1);
4056 }
4057 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4058 }
4059 } else
4060 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4061
4062 /* Addpath ID */
4063 new->addpath_rx_id = addpath_id;
4064
4065 /* Increment prefix */
4066 bgp_aggregate_increment(bgp, p, new, afi, safi);
4067
4068 /* Register new BGP information. */
4069 bgp_path_info_add(dest, new);
4070
4071 /* route_node_get lock */
4072 bgp_dest_unlock_node(dest);
4073
4074 #ifdef ENABLE_BGP_VNC
4075 if (safi == SAFI_MPLS_VPN) {
4076 struct bgp_dest *pdest = NULL;
4077 struct bgp_table *table = NULL;
4078
4079 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4080 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4081 table = bgp_dest_get_bgp_table_info(pdest);
4082
4083 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4084 bgp, prd, table, p, new);
4085 }
4086 bgp_dest_unlock_node(pdest);
4087 }
4088 #endif
4089
4090 /* If this is an EVPN route, process for import. */
4091 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4092 bgp_evpn_import_route(bgp, afi, safi, p, new);
4093
4094 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4095
4096 /* Process change. */
4097 bgp_process(bgp, dest, afi, safi);
4098
4099 if (SAFI_UNICAST == safi
4100 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4101 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4102 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4103 }
4104 if ((SAFI_MPLS_VPN == safi)
4105 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4106
4107 vpn_leak_to_vrf_update(bgp, new);
4108 }
4109 #ifdef ENABLE_BGP_VNC
4110 if (SAFI_MPLS_VPN == safi) {
4111 mpls_label_t label_decoded = decode_label(label);
4112
4113 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4114 sub_type, &label_decoded);
4115 }
4116 if (SAFI_ENCAP == safi) {
4117 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4118 sub_type, NULL);
4119 }
4120 #endif
4121
4122 return 0;
4123
4124 /* This BGP update is filtered. Log the reason then update BGP
4125 entry. */
4126 filtered:
4127 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4128
4129 if (bgp_debug_update(peer, p, NULL, 1)) {
4130 if (!peer->rcvd_attr_printed) {
4131 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
4132 peer->rcvd_attr_str);
4133 peer->rcvd_attr_printed = 1;
4134 }
4135
4136 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4137 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4138 sizeof(pfx_buf));
4139 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
4140 peer->host, pfx_buf, reason);
4141 }
4142
4143 if (pi) {
4144 /* If this is an EVPN route, un-import it as it is now filtered.
4145 */
4146 if (safi == SAFI_EVPN)
4147 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4148
4149 if (SAFI_UNICAST == safi
4150 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4151 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4152
4153 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4154 }
4155 if ((SAFI_MPLS_VPN == safi)
4156 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4157
4158 vpn_leak_to_vrf_withdraw(bgp, pi);
4159 }
4160
4161 bgp_rib_remove(dest, pi, peer, afi, safi);
4162 }
4163
4164 bgp_dest_unlock_node(dest);
4165
4166 #ifdef ENABLE_BGP_VNC
4167 /*
4168 * Filtered update is treated as an implicit withdrawal (see
4169 * bgp_rib_remove()
4170 * a few lines above)
4171 */
4172 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4173 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4174 0);
4175 }
4176 #endif
4177
4178 return 0;
4179 }
4180
4181 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4182 struct attr *attr, afi_t afi, safi_t safi, int type,
4183 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4184 uint32_t num_labels, struct bgp_route_evpn *evpn)
4185 {
4186 struct bgp *bgp;
4187 char pfx_buf[BGP_PRD_PATH_STRLEN];
4188 struct bgp_dest *dest;
4189 struct bgp_path_info *pi;
4190
4191 #ifdef ENABLE_BGP_VNC
4192 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4193 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4194 0);
4195 }
4196 #endif
4197
4198 bgp = peer->bgp;
4199
4200 /* Lookup node. */
4201 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4202
4203 /* If peer is soft reconfiguration enabled. Record input packet for
4204 * further calculation.
4205 *
4206 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4207 * routes that are filtered. This tanks out Quagga RS pretty badly due
4208 * to
4209 * the iteration over all RS clients.
4210 * Since we need to remove the entry from adj_in anyway, do that first
4211 * and
4212 * if there was no entry, we don't need to do anything more.
4213 */
4214 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4215 && peer != bgp->peer_self)
4216 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4217 peer->stat_pfx_dup_withdraw++;
4218
4219 if (bgp_debug_update(peer, p, NULL, 1)) {
4220 bgp_debug_rdpfxpath2str(
4221 afi, safi, prd, p, label, num_labels,
4222 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4223 sizeof(pfx_buf));
4224 zlog_debug(
4225 "%s withdrawing route %s not in adj-in",
4226 peer->host, pfx_buf);
4227 }
4228 bgp_dest_unlock_node(dest);
4229 return 0;
4230 }
4231
4232 /* Lookup withdrawn route. */
4233 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4234 if (pi->peer == peer && pi->type == type
4235 && pi->sub_type == sub_type
4236 && pi->addpath_rx_id == addpath_id)
4237 break;
4238
4239 /* Logging. */
4240 if (bgp_debug_update(peer, p, NULL, 1)) {
4241 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4242 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4243 sizeof(pfx_buf));
4244 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
4245 pfx_buf);
4246 }
4247
4248 /* Withdraw specified route from routing table. */
4249 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4250 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4251 if (SAFI_UNICAST == safi
4252 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4253 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4254 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4255 }
4256 if ((SAFI_MPLS_VPN == safi)
4257 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4258
4259 vpn_leak_to_vrf_withdraw(bgp, pi);
4260 }
4261 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4262 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4263 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4264 sizeof(pfx_buf));
4265 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4266 }
4267
4268 /* Unlock bgp_node_get() lock. */
4269 bgp_dest_unlock_node(dest);
4270
4271 return 0;
4272 }
4273
4274 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4275 int withdraw)
4276 {
4277 struct update_subgroup *subgrp;
4278 subgrp = peer_subgroup(peer, afi, safi);
4279 subgroup_default_originate(subgrp, withdraw);
4280 }
4281
4282
4283 /*
4284 * bgp_stop_announce_route_timer
4285 */
4286 void bgp_stop_announce_route_timer(struct peer_af *paf)
4287 {
4288 if (!paf->t_announce_route)
4289 return;
4290
4291 THREAD_TIMER_OFF(paf->t_announce_route);
4292 }
4293
4294 /*
4295 * bgp_announce_route_timer_expired
4296 *
4297 * Callback that is invoked when the route announcement timer for a
4298 * peer_af expires.
4299 */
4300 static int bgp_announce_route_timer_expired(struct thread *t)
4301 {
4302 struct peer_af *paf;
4303 struct peer *peer;
4304
4305 paf = THREAD_ARG(t);
4306 peer = paf->peer;
4307
4308 if (peer->status != Established)
4309 return 0;
4310
4311 if (!peer->afc_nego[paf->afi][paf->safi])
4312 return 0;
4313
4314 peer_af_announce_route(paf, 1);
4315 return 0;
4316 }
4317
4318 /*
4319 * bgp_announce_route
4320 *
4321 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
4322 */
4323 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi)
4324 {
4325 struct peer_af *paf;
4326 struct update_subgroup *subgrp;
4327
4328 paf = peer_af_find(peer, afi, safi);
4329 if (!paf)
4330 return;
4331 subgrp = PAF_SUBGRP(paf);
4332
4333 /*
4334 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
4335 * or a refresh has already been triggered.
4336 */
4337 if (!subgrp || paf->t_announce_route)
4338 return;
4339
4340 /*
4341 * Start a timer to stagger/delay the announce. This serves
4342 * two purposes - announcement can potentially be combined for
4343 * multiple peers and the announcement doesn't happen in the
4344 * vty context.
4345 */
4346 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
4347 (subgrp->peer_count == 1)
4348 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
4349 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
4350 &paf->t_announce_route);
4351 }
4352
4353 /*
4354 * Announce routes from all AF tables to a peer.
4355 *
4356 * This should ONLY be called when there is a need to refresh the
4357 * routes to the peer based on a policy change for this peer alone
4358 * or a route refresh request received from the peer.
4359 * The operation will result in splitting the peer from its existing
4360 * subgroups and putting it in new subgroups.
4361 */
4362 void bgp_announce_route_all(struct peer *peer)
4363 {
4364 afi_t afi;
4365 safi_t safi;
4366
4367 FOREACH_AFI_SAFI (afi, safi)
4368 bgp_announce_route(peer, afi, safi);
4369 }
4370
4371 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
4372 struct bgp_table *table,
4373 struct prefix_rd *prd)
4374 {
4375 int ret;
4376 struct bgp_dest *dest;
4377 struct bgp_adj_in *ain;
4378
4379 if (!table)
4380 table = peer->bgp->rib[afi][safi];
4381
4382 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
4383 for (ain = dest->adj_in; ain; ain = ain->next) {
4384 if (ain->peer != peer)
4385 continue;
4386
4387 struct bgp_path_info *pi;
4388 uint32_t num_labels = 0;
4389 mpls_label_t *label_pnt = NULL;
4390 struct bgp_route_evpn evpn;
4391
4392 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
4393 pi = pi->next)
4394 if (pi->peer == peer)
4395 break;
4396
4397 if (pi && pi->extra)
4398 num_labels = pi->extra->num_labels;
4399 if (num_labels)
4400 label_pnt = &pi->extra->label[0];
4401 if (pi)
4402 memcpy(&evpn, &pi->attr->evpn_overlay,
4403 sizeof(evpn));
4404 else
4405 memset(&evpn, 0, sizeof(evpn));
4406
4407 ret = bgp_update(peer, bgp_dest_get_prefix(dest),
4408 ain->addpath_rx_id, ain->attr, afi,
4409 safi, ZEBRA_ROUTE_BGP,
4410 BGP_ROUTE_NORMAL, prd, label_pnt,
4411 num_labels, 1, &evpn);
4412
4413 if (ret < 0) {
4414 bgp_dest_unlock_node(dest);
4415 return;
4416 }
4417 }
4418 }
4419
4420 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
4421 {
4422 struct bgp_dest *dest;
4423 struct bgp_table *table;
4424
4425 if (peer->status != Established)
4426 return;
4427
4428 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
4429 && (safi != SAFI_EVPN))
4430 bgp_soft_reconfig_table(peer, afi, safi, NULL, NULL);
4431 else
4432 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4433 dest = bgp_route_next(dest)) {
4434 table = bgp_dest_get_bgp_table_info(dest);
4435
4436 if (table == NULL)
4437 continue;
4438
4439 const struct prefix *p = bgp_dest_get_prefix(dest);
4440 struct prefix_rd prd;
4441
4442 prd.family = AF_UNSPEC;
4443 prd.prefixlen = 64;
4444 memcpy(&prd.val, p->u.val, 8);
4445
4446 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
4447 }
4448 }
4449
4450
4451 struct bgp_clear_node_queue {
4452 struct bgp_dest *dest;
4453 };
4454
4455 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
4456 {
4457 struct bgp_clear_node_queue *cnq = data;
4458 struct bgp_dest *dest = cnq->dest;
4459 struct peer *peer = wq->spec.data;
4460 struct bgp_path_info *pi;
4461 struct bgp *bgp;
4462 afi_t afi = bgp_dest_table(dest)->afi;
4463 safi_t safi = bgp_dest_table(dest)->safi;
4464
4465 assert(dest && peer);
4466 bgp = peer->bgp;
4467
4468 /* It is possible that we have multiple paths for a prefix from a peer
4469 * if that peer is using AddPath.
4470 */
4471 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
4472 if (pi->peer != peer)
4473 continue;
4474
4475 /* graceful restart STALE flag set. */
4476 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
4477 && peer->nsf[afi][safi]
4478 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
4479 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
4480 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
4481 else {
4482 /* If this is an EVPN route, process for
4483 * un-import. */
4484 if (safi == SAFI_EVPN)
4485 bgp_evpn_unimport_route(
4486 bgp, afi, safi,
4487 bgp_dest_get_prefix(dest), pi);
4488 /* Handle withdraw for VRF route-leaking and L3VPN */
4489 if (SAFI_UNICAST == safi
4490 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
4491 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4492 vpn_leak_from_vrf_withdraw(bgp_get_default(),
4493 bgp, pi);
4494 }
4495 if (SAFI_MPLS_VPN == safi &&
4496 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4497 vpn_leak_to_vrf_withdraw(bgp, pi);
4498 }
4499
4500 bgp_rib_remove(dest, pi, peer, afi, safi);
4501 }
4502 }
4503 return WQ_SUCCESS;
4504 }
4505
4506 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
4507 {
4508 struct bgp_clear_node_queue *cnq = data;
4509 struct bgp_dest *dest = cnq->dest;
4510 struct bgp_table *table = bgp_dest_table(dest);
4511
4512 bgp_dest_unlock_node(dest);
4513 bgp_table_unlock(table);
4514 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
4515 }
4516
4517 static void bgp_clear_node_complete(struct work_queue *wq)
4518 {
4519 struct peer *peer = wq->spec.data;
4520
4521 /* Tickle FSM to start moving again */
4522 BGP_EVENT_ADD(peer, Clearing_Completed);
4523
4524 peer_unlock(peer); /* bgp_clear_route */
4525 }
4526
4527 static void bgp_clear_node_queue_init(struct peer *peer)
4528 {
4529 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
4530
4531 snprintf(wname, sizeof(wname), "clear %s", peer->host);
4532 #undef CLEAR_QUEUE_NAME_LEN
4533
4534 peer->clear_node_queue = work_queue_new(bm->master, wname);
4535 peer->clear_node_queue->spec.hold = 10;
4536 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
4537 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
4538 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
4539 peer->clear_node_queue->spec.max_retries = 0;
4540
4541 /* we only 'lock' this peer reference when the queue is actually active
4542 */
4543 peer->clear_node_queue->spec.data = peer;
4544 }
4545
4546 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
4547 struct bgp_table *table)
4548 {
4549 struct bgp_dest *dest;
4550 int force = bm->process_main_queue ? 0 : 1;
4551
4552 if (!table)
4553 table = peer->bgp->rib[afi][safi];
4554
4555 /* If still no table => afi/safi isn't configured at all or smth. */
4556 if (!table)
4557 return;
4558
4559 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4560 struct bgp_path_info *pi, *next;
4561 struct bgp_adj_in *ain;
4562 struct bgp_adj_in *ain_next;
4563
4564 /* XXX:TODO: This is suboptimal, every non-empty route_node is
4565 * queued for every clearing peer, regardless of whether it is
4566 * relevant to the peer at hand.
4567 *
4568 * Overview: There are 3 different indices which need to be
4569 * scrubbed, potentially, when a peer is removed:
4570 *
4571 * 1 peer's routes visible via the RIB (ie accepted routes)
4572 * 2 peer's routes visible by the (optional) peer's adj-in index
4573 * 3 other routes visible by the peer's adj-out index
4574 *
4575 * 3 there is no hurry in scrubbing, once the struct peer is
4576 * removed from bgp->peer, we could just GC such deleted peer's
4577 * adj-outs at our leisure.
4578 *
4579 * 1 and 2 must be 'scrubbed' in some way, at least made
4580 * invisible via RIB index before peer session is allowed to be
4581 * brought back up. So one needs to know when such a 'search' is
4582 * complete.
4583 *
4584 * Ideally:
4585 *
4586 * - there'd be a single global queue or a single RIB walker
4587 * - rather than tracking which route_nodes still need to be
4588 * examined on a peer basis, we'd track which peers still
4589 * aren't cleared
4590 *
4591 * Given that our per-peer prefix-counts now should be reliable,
4592 * this may actually be achievable. It doesn't seem to be a huge
4593 * problem at this time,
4594 *
4595 * It is possible that we have multiple paths for a prefix from
4596 * a peer
4597 * if that peer is using AddPath.
4598 */
4599 ain = dest->adj_in;
4600 while (ain) {
4601 ain_next = ain->next;
4602
4603 if (ain->peer == peer) {
4604 bgp_adj_in_remove(dest, ain);
4605 bgp_dest_unlock_node(dest);
4606 }
4607
4608 ain = ain_next;
4609 }
4610
4611 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
4612 next = pi->next;
4613 if (pi->peer != peer)
4614 continue;
4615
4616 if (force)
4617 bgp_path_info_reap(dest, pi);
4618 else {
4619 struct bgp_clear_node_queue *cnq;
4620
4621 /* both unlocked in bgp_clear_node_queue_del */
4622 bgp_table_lock(bgp_dest_table(dest));
4623 bgp_dest_lock_node(dest);
4624 cnq = XCALLOC(
4625 MTYPE_BGP_CLEAR_NODE_QUEUE,
4626 sizeof(struct bgp_clear_node_queue));
4627 cnq->dest = dest;
4628 work_queue_add(peer->clear_node_queue, cnq);
4629 break;
4630 }
4631 }
4632 }
4633 return;
4634 }
4635
4636 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
4637 {
4638 struct bgp_dest *dest;
4639 struct bgp_table *table;
4640
4641 if (peer->clear_node_queue == NULL)
4642 bgp_clear_node_queue_init(peer);
4643
4644 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
4645 * Idle until it receives a Clearing_Completed event. This protects
4646 * against peers which flap faster than we can we clear, which could
4647 * lead to:
4648 *
4649 * a) race with routes from the new session being installed before
4650 * clear_route_node visits the node (to delete the route of that
4651 * peer)
4652 * b) resource exhaustion, clear_route_node likely leads to an entry
4653 * on the process_main queue. Fast-flapping could cause that queue
4654 * to grow and grow.
4655 */
4656
4657 /* lock peer in assumption that clear-node-queue will get nodes; if so,
4658 * the unlock will happen upon work-queue completion; other wise, the
4659 * unlock happens at the end of this function.
4660 */
4661 if (!peer->clear_node_queue->thread)
4662 peer_lock(peer);
4663
4664 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
4665 bgp_clear_route_table(peer, afi, safi, NULL);
4666 else
4667 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4668 dest = bgp_route_next(dest)) {
4669 table = bgp_dest_get_bgp_table_info(dest);
4670 if (!table)
4671 continue;
4672
4673 bgp_clear_route_table(peer, afi, safi, table);
4674 }
4675
4676 /* unlock if no nodes got added to the clear-node-queue. */
4677 if (!peer->clear_node_queue->thread)
4678 peer_unlock(peer);
4679 }
4680
4681 void bgp_clear_route_all(struct peer *peer)
4682 {
4683 afi_t afi;
4684 safi_t safi;
4685
4686 FOREACH_AFI_SAFI (afi, safi)
4687 bgp_clear_route(peer, afi, safi);
4688
4689 #ifdef ENABLE_BGP_VNC
4690 rfapiProcessPeerDown(peer);
4691 #endif
4692 }
4693
4694 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
4695 {
4696 struct bgp_table *table;
4697 struct bgp_dest *dest;
4698 struct bgp_adj_in *ain;
4699 struct bgp_adj_in *ain_next;
4700
4701 table = peer->bgp->rib[afi][safi];
4702
4703 /* It is possible that we have multiple paths for a prefix from a peer
4704 * if that peer is using AddPath.
4705 */
4706 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4707 ain = dest->adj_in;
4708
4709 while (ain) {
4710 ain_next = ain->next;
4711
4712 if (ain->peer == peer) {
4713 bgp_adj_in_remove(dest, ain);
4714 bgp_dest_unlock_node(dest);
4715 }
4716
4717 ain = ain_next;
4718 }
4719 }
4720 }
4721
4722 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
4723 {
4724 struct bgp_dest *dest;
4725 struct bgp_path_info *pi;
4726 struct bgp_table *table;
4727
4728 if (safi == SAFI_MPLS_VPN) {
4729 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4730 dest = bgp_route_next(dest)) {
4731 struct bgp_dest *rm;
4732
4733 /* look for neighbor in tables */
4734 table = bgp_dest_get_bgp_table_info(dest);
4735 if (!table)
4736 continue;
4737
4738 for (rm = bgp_table_top(table); rm;
4739 rm = bgp_route_next(rm))
4740 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
4741 pi = pi->next) {
4742 if (pi->peer != peer)
4743 continue;
4744 if (!CHECK_FLAG(pi->flags,
4745 BGP_PATH_STALE))
4746 break;
4747
4748 bgp_rib_remove(rm, pi, peer, afi, safi);
4749 break;
4750 }
4751 }
4752 } else {
4753 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4754 dest = bgp_route_next(dest))
4755 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
4756 pi = pi->next) {
4757 if (pi->peer != peer)
4758 continue;
4759 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
4760 break;
4761 bgp_rib_remove(dest, pi, peer, afi, safi);
4762 break;
4763 }
4764 }
4765 }
4766
4767 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
4768 {
4769 if (peer->sort == BGP_PEER_IBGP)
4770 return true;
4771
4772 if (peer->sort == BGP_PEER_EBGP
4773 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
4774 || FILTER_LIST_OUT_NAME(filter)
4775 || DISTRIBUTE_OUT_NAME(filter)))
4776 return true;
4777 return false;
4778 }
4779
4780 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
4781 {
4782 if (peer->sort == BGP_PEER_IBGP)
4783 return true;
4784
4785 if (peer->sort == BGP_PEER_EBGP
4786 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
4787 || FILTER_LIST_IN_NAME(filter)
4788 || DISTRIBUTE_IN_NAME(filter)))
4789 return true;
4790 return false;
4791 }
4792
4793 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
4794 safi_t safi)
4795 {
4796 struct bgp_dest *dest;
4797 struct bgp_path_info *pi;
4798 struct bgp_path_info *next;
4799
4800 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
4801 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
4802 const struct prefix *p = bgp_dest_get_prefix(dest);
4803
4804 next = pi->next;
4805
4806 /* Unimport EVPN routes from VRFs */
4807 if (safi == SAFI_EVPN)
4808 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
4809 SAFI_EVPN, p, pi);
4810
4811 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
4812 && pi->type == ZEBRA_ROUTE_BGP
4813 && (pi->sub_type == BGP_ROUTE_NORMAL
4814 || pi->sub_type == BGP_ROUTE_AGGREGATE
4815 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
4816
4817 if (bgp_fibupd_safi(safi))
4818 bgp_zebra_withdraw(p, pi, bgp, safi);
4819 }
4820
4821 bgp_path_info_reap(dest, pi);
4822 }
4823 }
4824
4825 /* Delete all kernel routes. */
4826 void bgp_cleanup_routes(struct bgp *bgp)
4827 {
4828 afi_t afi;
4829 struct bgp_dest *dest;
4830 struct bgp_table *table;
4831
4832 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
4833 if (afi == AFI_L2VPN)
4834 continue;
4835 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
4836 SAFI_UNICAST);
4837 /*
4838 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
4839 */
4840 if (afi != AFI_L2VPN) {
4841 safi_t safi;
4842 safi = SAFI_MPLS_VPN;
4843 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
4844 dest = bgp_route_next(dest)) {
4845 table = bgp_dest_get_bgp_table_info(dest);
4846 if (table != NULL) {
4847 bgp_cleanup_table(bgp, table, safi);
4848 bgp_table_finish(&table);
4849 bgp_dest_set_bgp_table_info(dest, NULL);
4850 bgp_dest_unlock_node(dest);
4851 }
4852 }
4853 safi = SAFI_ENCAP;
4854 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
4855 dest = bgp_route_next(dest)) {
4856 table = bgp_dest_get_bgp_table_info(dest);
4857 if (table != NULL) {
4858 bgp_cleanup_table(bgp, table, safi);
4859 bgp_table_finish(&table);
4860 bgp_dest_set_bgp_table_info(dest, NULL);
4861 bgp_dest_unlock_node(dest);
4862 }
4863 }
4864 }
4865 }
4866 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
4867 dest = bgp_route_next(dest)) {
4868 table = bgp_dest_get_bgp_table_info(dest);
4869 if (table != NULL) {
4870 bgp_cleanup_table(bgp, table, SAFI_EVPN);
4871 bgp_table_finish(&table);
4872 bgp_dest_set_bgp_table_info(dest, NULL);
4873 bgp_dest_unlock_node(dest);
4874 }
4875 }
4876 }
4877
4878 void bgp_reset(void)
4879 {
4880 vty_reset();
4881 bgp_zclient_reset();
4882 access_list_reset();
4883 prefix_list_reset();
4884 }
4885
4886 static int bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
4887 {
4888 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
4889 && CHECK_FLAG(peer->af_cap[afi][safi],
4890 PEER_CAP_ADDPATH_AF_TX_RCV));
4891 }
4892
4893 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
4894 value. */
4895 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
4896 struct bgp_nlri *packet)
4897 {
4898 uint8_t *pnt;
4899 uint8_t *lim;
4900 struct prefix p;
4901 int psize;
4902 int ret;
4903 afi_t afi;
4904 safi_t safi;
4905 int addpath_encoded;
4906 uint32_t addpath_id;
4907
4908 pnt = packet->nlri;
4909 lim = pnt + packet->length;
4910 afi = packet->afi;
4911 safi = packet->safi;
4912 addpath_id = 0;
4913 addpath_encoded = bgp_addpath_encode_rx(peer, afi, safi);
4914
4915 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
4916 syntactic validity. If the field is syntactically incorrect,
4917 then the Error Subcode is set to Invalid Network Field. */
4918 for (; pnt < lim; pnt += psize) {
4919 /* Clear prefix structure. */
4920 memset(&p, 0, sizeof(struct prefix));
4921
4922 if (addpath_encoded) {
4923
4924 /* When packet overflow occurs return immediately. */
4925 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
4926 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
4927
4928 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
4929 addpath_id = ntohl(addpath_id);
4930 pnt += BGP_ADDPATH_ID_LEN;
4931 }
4932
4933 /* Fetch prefix length. */
4934 p.prefixlen = *pnt++;
4935 /* afi/safi validity already verified by caller,
4936 * bgp_update_receive */
4937 p.family = afi2family(afi);
4938
4939 /* Prefix length check. */
4940 if (p.prefixlen > prefix_blen(&p) * 8) {
4941 flog_err(
4942 EC_BGP_UPDATE_RCV,
4943 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
4944 peer->host, p.prefixlen, packet->afi);
4945 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
4946 }
4947
4948 /* Packet size overflow check. */
4949 psize = PSIZE(p.prefixlen);
4950
4951 /* When packet overflow occur return immediately. */
4952 if (pnt + psize > lim) {
4953 flog_err(
4954 EC_BGP_UPDATE_RCV,
4955 "%s [Error] Update packet error (prefix length %d overflows packet)",
4956 peer->host, p.prefixlen);
4957 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
4958 }
4959
4960 /* Defensive coding, double-check the psize fits in a struct
4961 * prefix */
4962 if (psize > (ssize_t)sizeof(p.u)) {
4963 flog_err(
4964 EC_BGP_UPDATE_RCV,
4965 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
4966 peer->host, p.prefixlen, sizeof(p.u));
4967 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
4968 }
4969
4970 /* Fetch prefix from NLRI packet. */
4971 memcpy(p.u.val, pnt, psize);
4972
4973 /* Check address. */
4974 if (afi == AFI_IP && safi == SAFI_UNICAST) {
4975 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
4976 /* From RFC4271 Section 6.3:
4977 *
4978 * If a prefix in the NLRI field is semantically
4979 * incorrect
4980 * (e.g., an unexpected multicast IP address),
4981 * an error SHOULD
4982 * be logged locally, and the prefix SHOULD be
4983 * ignored.
4984 */
4985 flog_err(
4986 EC_BGP_UPDATE_RCV,
4987 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
4988 peer->host, inet_ntoa(p.u.prefix4));
4989 continue;
4990 }
4991 }
4992
4993 /* Check address. */
4994 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
4995 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
4996 char buf[BUFSIZ];
4997
4998 flog_err(
4999 EC_BGP_UPDATE_RCV,
5000 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
5001 peer->host,
5002 inet_ntop(AF_INET6, &p.u.prefix6, buf,
5003 BUFSIZ));
5004
5005 continue;
5006 }
5007 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
5008 char buf[BUFSIZ];
5009
5010 flog_err(
5011 EC_BGP_UPDATE_RCV,
5012 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
5013 peer->host,
5014 inet_ntop(AF_INET6, &p.u.prefix6, buf,
5015 BUFSIZ));
5016
5017 continue;
5018 }
5019 }
5020
5021 /* Normal process. */
5022 if (attr)
5023 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
5024 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
5025 NULL, NULL, 0, 0, NULL);
5026 else
5027 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
5028 safi, ZEBRA_ROUTE_BGP,
5029 BGP_ROUTE_NORMAL, NULL, NULL, 0,
5030 NULL);
5031
5032 /* Do not send BGP notification twice when maximum-prefix count
5033 * overflow. */
5034 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
5035 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
5036
5037 /* Address family configuration mismatch. */
5038 if (ret < 0)
5039 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
5040 }
5041
5042 /* Packet length consistency check. */
5043 if (pnt != lim) {
5044 flog_err(
5045 EC_BGP_UPDATE_RCV,
5046 "%s [Error] Update packet error (prefix length mismatch with total length)",
5047 peer->host);
5048 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5049 }
5050
5051 return BGP_NLRI_PARSE_OK;
5052 }
5053
5054 static struct bgp_static *bgp_static_new(void)
5055 {
5056 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
5057 }
5058
5059 static void bgp_static_free(struct bgp_static *bgp_static)
5060 {
5061 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5062 route_map_counter_decrement(bgp_static->rmap.map);
5063
5064 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
5065 XFREE(MTYPE_BGP_STATIC, bgp_static);
5066 }
5067
5068 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
5069 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
5070 {
5071 struct bgp_dest *dest;
5072 struct bgp_path_info *pi;
5073 struct bgp_path_info *new;
5074 struct bgp_path_info rmap_path;
5075 struct attr attr;
5076 struct attr *attr_new;
5077 route_map_result_t ret;
5078 #ifdef ENABLE_BGP_VNC
5079 int vnc_implicit_withdraw = 0;
5080 #endif
5081
5082 assert(bgp_static);
5083
5084 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5085
5086 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5087
5088 attr.nexthop = bgp_static->igpnexthop;
5089 attr.med = bgp_static->igpmetric;
5090 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5091
5092 if (bgp_static->atomic)
5093 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
5094
5095 /* Store label index, if required. */
5096 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
5097 attr.label_index = bgp_static->label_index;
5098 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
5099 }
5100
5101 /* Apply route-map. */
5102 if (bgp_static->rmap.name) {
5103 struct attr attr_tmp = attr;
5104
5105 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
5106 rmap_path.peer = bgp->peer_self;
5107 rmap_path.attr = &attr_tmp;
5108
5109 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5110
5111 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
5112 &rmap_path);
5113
5114 bgp->peer_self->rmap_type = 0;
5115
5116 if (ret == RMAP_DENYMATCH) {
5117 /* Free uninterned attribute. */
5118 bgp_attr_flush(&attr_tmp);
5119
5120 /* Unintern original. */
5121 aspath_unintern(&attr.aspath);
5122 bgp_static_withdraw(bgp, p, afi, safi);
5123 return;
5124 }
5125
5126 if (bgp_in_graceful_shutdown(bgp))
5127 bgp_attr_add_gshut_community(&attr_tmp);
5128
5129 attr_new = bgp_attr_intern(&attr_tmp);
5130 } else {
5131
5132 if (bgp_in_graceful_shutdown(bgp))
5133 bgp_attr_add_gshut_community(&attr);
5134
5135 attr_new = bgp_attr_intern(&attr);
5136 }
5137
5138 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5139 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5140 && pi->sub_type == BGP_ROUTE_STATIC)
5141 break;
5142
5143 if (pi) {
5144 if (attrhash_cmp(pi->attr, attr_new)
5145 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
5146 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
5147 bgp_dest_unlock_node(dest);
5148 bgp_attr_unintern(&attr_new);
5149 aspath_unintern(&attr.aspath);
5150 return;
5151 } else {
5152 /* The attribute is changed. */
5153 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5154
5155 /* Rewrite BGP route information. */
5156 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5157 bgp_path_info_restore(dest, pi);
5158 else
5159 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5160 #ifdef ENABLE_BGP_VNC
5161 if ((afi == AFI_IP || afi == AFI_IP6)
5162 && (safi == SAFI_UNICAST)) {
5163 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
5164 /*
5165 * Implicit withdraw case.
5166 * We have to do this before pi is
5167 * changed
5168 */
5169 ++vnc_implicit_withdraw;
5170 vnc_import_bgp_del_route(bgp, p, pi);
5171 vnc_import_bgp_exterior_del_route(
5172 bgp, p, pi);
5173 }
5174 }
5175 #endif
5176 bgp_attr_unintern(&pi->attr);
5177 pi->attr = attr_new;
5178 pi->uptime = bgp_clock();
5179 #ifdef ENABLE_BGP_VNC
5180 if ((afi == AFI_IP || afi == AFI_IP6)
5181 && (safi == SAFI_UNICAST)) {
5182 if (vnc_implicit_withdraw) {
5183 vnc_import_bgp_add_route(bgp, p, pi);
5184 vnc_import_bgp_exterior_add_route(
5185 bgp, p, pi);
5186 }
5187 }
5188 #endif
5189
5190 /* Nexthop reachability check. */
5191 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5192 && (safi == SAFI_UNICAST
5193 || safi == SAFI_LABELED_UNICAST)) {
5194
5195 struct bgp *bgp_nexthop = bgp;
5196
5197 if (pi->extra && pi->extra->bgp_orig)
5198 bgp_nexthop = pi->extra->bgp_orig;
5199
5200 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
5201 afi, pi, NULL, 0))
5202 bgp_path_info_set_flag(dest, pi,
5203 BGP_PATH_VALID);
5204 else {
5205 if (BGP_DEBUG(nht, NHT)) {
5206 char buf1[INET6_ADDRSTRLEN];
5207 inet_ntop(p->family,
5208 &p->u.prefix, buf1,
5209 INET6_ADDRSTRLEN);
5210 zlog_debug(
5211 "%s(%s): Route not in table, not advertising",
5212 __func__, buf1);
5213 }
5214 bgp_path_info_unset_flag(
5215 dest, pi, BGP_PATH_VALID);
5216 }
5217 } else {
5218 /* Delete the NHT structure if any, if we're
5219 * toggling between
5220 * enabling/disabling import check. We
5221 * deregister the route
5222 * from NHT to avoid overloading NHT and the
5223 * process interaction
5224 */
5225 bgp_unlink_nexthop(pi);
5226 bgp_path_info_set_flag(dest, pi,
5227 BGP_PATH_VALID);
5228 }
5229 /* Process change. */
5230 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5231 bgp_process(bgp, dest, afi, safi);
5232
5233 if (SAFI_UNICAST == safi
5234 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5235 || bgp->inst_type
5236 == BGP_INSTANCE_TYPE_DEFAULT)) {
5237 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
5238 pi);
5239 }
5240
5241 bgp_dest_unlock_node(dest);
5242 aspath_unintern(&attr.aspath);
5243 return;
5244 }
5245 }
5246
5247 /* Make new BGP info. */
5248 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5249 attr_new, dest);
5250 /* Nexthop reachability check. */
5251 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5252 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
5253 if (bgp_find_or_add_nexthop(bgp, bgp, afi, new, NULL, 0))
5254 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5255 else {
5256 if (BGP_DEBUG(nht, NHT)) {
5257 char buf1[INET6_ADDRSTRLEN];
5258 inet_ntop(p->family, &p->u.prefix, buf1,
5259 INET6_ADDRSTRLEN);
5260 zlog_debug(
5261 "%s(%s): Route not in table, not advertising",
5262 __func__, buf1);
5263 }
5264 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
5265 }
5266 } else {
5267 /* Delete the NHT structure if any, if we're toggling between
5268 * enabling/disabling import check. We deregister the route
5269 * from NHT to avoid overloading NHT and the process interaction
5270 */
5271 bgp_unlink_nexthop(new);
5272
5273 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5274 }
5275
5276 /* Aggregate address increment. */
5277 bgp_aggregate_increment(bgp, p, new, afi, safi);
5278
5279 /* Register new BGP information. */
5280 bgp_path_info_add(dest, new);
5281
5282 /* route_node_get lock */
5283 bgp_dest_unlock_node(dest);
5284
5285 /* Process change. */
5286 bgp_process(bgp, dest, afi, safi);
5287
5288 if (SAFI_UNICAST == safi
5289 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5290 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5291 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
5292 }
5293
5294 /* Unintern original. */
5295 aspath_unintern(&attr.aspath);
5296 }
5297
5298 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
5299 safi_t safi)
5300 {
5301 struct bgp_dest *dest;
5302 struct bgp_path_info *pi;
5303
5304 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5305
5306 /* Check selected route and self inserted route. */
5307 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5308 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5309 && pi->sub_type == BGP_ROUTE_STATIC)
5310 break;
5311
5312 /* Withdraw static BGP route from routing table. */
5313 if (pi) {
5314 if (SAFI_UNICAST == safi
5315 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5316 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5317 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5318 }
5319 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5320 bgp_unlink_nexthop(pi);
5321 bgp_path_info_delete(dest, pi);
5322 bgp_process(bgp, dest, afi, safi);
5323 }
5324
5325 /* Unlock bgp_node_lookup. */
5326 bgp_dest_unlock_node(dest);
5327 }
5328
5329 /*
5330 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
5331 */
5332 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
5333 afi_t afi, safi_t safi,
5334 struct prefix_rd *prd)
5335 {
5336 struct bgp_dest *dest;
5337 struct bgp_path_info *pi;
5338
5339 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
5340
5341 /* Check selected route and self inserted route. */
5342 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5343 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5344 && pi->sub_type == BGP_ROUTE_STATIC)
5345 break;
5346
5347 /* Withdraw static BGP route from routing table. */
5348 if (pi) {
5349 #ifdef ENABLE_BGP_VNC
5350 rfapiProcessWithdraw(
5351 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
5352 1); /* Kill, since it is an administrative change */
5353 #endif
5354 if (SAFI_MPLS_VPN == safi
5355 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5356 vpn_leak_to_vrf_withdraw(bgp, pi);
5357 }
5358 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5359 bgp_path_info_delete(dest, pi);
5360 bgp_process(bgp, dest, afi, safi);
5361 }
5362
5363 /* Unlock bgp_node_lookup. */
5364 bgp_dest_unlock_node(dest);
5365 }
5366
5367 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
5368 struct bgp_static *bgp_static, afi_t afi,
5369 safi_t safi)
5370 {
5371 struct bgp_dest *dest;
5372 struct bgp_path_info *new;
5373 struct attr *attr_new;
5374 struct attr attr = {0};
5375 struct bgp_path_info *pi;
5376 #ifdef ENABLE_BGP_VNC
5377 mpls_label_t label = 0;
5378 #endif
5379 uint32_t num_labels = 0;
5380 union gw_addr add;
5381
5382 assert(bgp_static);
5383
5384 if (bgp_static->label != MPLS_INVALID_LABEL)
5385 num_labels = 1;
5386 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
5387 &bgp_static->prd);
5388
5389 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5390
5391 attr.nexthop = bgp_static->igpnexthop;
5392 attr.med = bgp_static->igpmetric;
5393 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5394
5395 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
5396 || (safi == SAFI_ENCAP)) {
5397 if (afi == AFI_IP) {
5398 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
5399 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
5400 }
5401 }
5402 if (afi == AFI_L2VPN) {
5403 if (bgp_static->gatewayIp.family == AF_INET)
5404 add.ipv4.s_addr =
5405 bgp_static->gatewayIp.u.prefix4.s_addr;
5406 else if (bgp_static->gatewayIp.family == AF_INET6)
5407 memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
5408 sizeof(struct in6_addr));
5409 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
5410 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
5411 struct bgp_encap_type_vxlan bet;
5412 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
5413 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
5414 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
5415 }
5416 if (bgp_static->router_mac) {
5417 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
5418 }
5419 }
5420 /* Apply route-map. */
5421 if (bgp_static->rmap.name) {
5422 struct attr attr_tmp = attr;
5423 struct bgp_path_info rmap_path;
5424 route_map_result_t ret;
5425
5426 rmap_path.peer = bgp->peer_self;
5427 rmap_path.attr = &attr_tmp;
5428
5429 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5430
5431 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
5432 &rmap_path);
5433
5434 bgp->peer_self->rmap_type = 0;
5435
5436 if (ret == RMAP_DENYMATCH) {
5437 /* Free uninterned attribute. */
5438 bgp_attr_flush(&attr_tmp);
5439
5440 /* Unintern original. */
5441 aspath_unintern(&attr.aspath);
5442 bgp_static_withdraw_safi(bgp, p, afi, safi,
5443 &bgp_static->prd);
5444 return;
5445 }
5446
5447 attr_new = bgp_attr_intern(&attr_tmp);
5448 } else {
5449 attr_new = bgp_attr_intern(&attr);
5450 }
5451
5452 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5453 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5454 && pi->sub_type == BGP_ROUTE_STATIC)
5455 break;
5456
5457 if (pi) {
5458 memset(&add, 0, sizeof(union gw_addr));
5459 if (attrhash_cmp(pi->attr, attr_new)
5460 && overlay_index_equal(afi, pi, &add)
5461 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
5462 bgp_dest_unlock_node(dest);
5463 bgp_attr_unintern(&attr_new);
5464 aspath_unintern(&attr.aspath);
5465 return;
5466 } else {
5467 /* The attribute is changed. */
5468 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5469
5470 /* Rewrite BGP route information. */
5471 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5472 bgp_path_info_restore(dest, pi);
5473 else
5474 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5475 bgp_attr_unintern(&pi->attr);
5476 pi->attr = attr_new;
5477 pi->uptime = bgp_clock();
5478 #ifdef ENABLE_BGP_VNC
5479 if (pi->extra)
5480 label = decode_label(&pi->extra->label[0]);
5481 #endif
5482
5483 /* Process change. */
5484 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5485 bgp_process(bgp, dest, afi, safi);
5486
5487 if (SAFI_MPLS_VPN == safi
5488 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5489 vpn_leak_to_vrf_update(bgp, pi);
5490 }
5491 #ifdef ENABLE_BGP_VNC
5492 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
5493 pi->attr, afi, safi, pi->type,
5494 pi->sub_type, &label);
5495 #endif
5496 bgp_dest_unlock_node(dest);
5497 aspath_unintern(&attr.aspath);
5498 return;
5499 }
5500 }
5501
5502
5503 /* Make new BGP info. */
5504 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5505 attr_new, dest);
5506 SET_FLAG(new->flags, BGP_PATH_VALID);
5507 new->extra = bgp_path_info_extra_new();
5508 if (num_labels) {
5509 new->extra->label[0] = bgp_static->label;
5510 new->extra->num_labels = num_labels;
5511 }
5512 #ifdef ENABLE_BGP_VNC
5513 label = decode_label(&bgp_static->label);
5514 #endif
5515
5516 /* Aggregate address increment. */
5517 bgp_aggregate_increment(bgp, p, new, afi, safi);
5518
5519 /* Register new BGP information. */
5520 bgp_path_info_add(dest, new);
5521 /* route_node_get lock */
5522 bgp_dest_unlock_node(dest);
5523
5524 /* Process change. */
5525 bgp_process(bgp, dest, afi, safi);
5526
5527 if (SAFI_MPLS_VPN == safi
5528 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5529 vpn_leak_to_vrf_update(bgp, new);
5530 }
5531 #ifdef ENABLE_BGP_VNC
5532 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
5533 safi, new->type, new->sub_type, &label);
5534 #endif
5535
5536 /* Unintern original. */
5537 aspath_unintern(&attr.aspath);
5538 }
5539
5540 /* Configure static BGP network. When user don't run zebra, static
5541 route should be installed as valid. */
5542 static int bgp_static_set(struct vty *vty, const char *negate,
5543 const char *ip_str, afi_t afi, safi_t safi,
5544 const char *rmap, int backdoor, uint32_t label_index)
5545 {
5546 VTY_DECLVAR_CONTEXT(bgp, bgp);
5547 int ret;
5548 struct prefix p;
5549 struct bgp_static *bgp_static;
5550 struct bgp_dest *dest;
5551 uint8_t need_update = 0;
5552
5553 /* Convert IP prefix string to struct prefix. */
5554 ret = str2prefix(ip_str, &p);
5555 if (!ret) {
5556 vty_out(vty, "%% Malformed prefix\n");
5557 return CMD_WARNING_CONFIG_FAILED;
5558 }
5559 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
5560 vty_out(vty, "%% Malformed prefix (link-local address)\n");
5561 return CMD_WARNING_CONFIG_FAILED;
5562 }
5563
5564 apply_mask(&p);
5565
5566 if (negate) {
5567
5568 /* Set BGP static route configuration. */
5569 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
5570
5571 if (!dest) {
5572 vty_out(vty, "%% Can't find static route specified\n");
5573 return CMD_WARNING_CONFIG_FAILED;
5574 }
5575
5576 bgp_static = bgp_dest_get_bgp_static_info(dest);
5577
5578 if ((label_index != BGP_INVALID_LABEL_INDEX)
5579 && (label_index != bgp_static->label_index)) {
5580 vty_out(vty,
5581 "%% label-index doesn't match static route\n");
5582 return CMD_WARNING_CONFIG_FAILED;
5583 }
5584
5585 if ((rmap && bgp_static->rmap.name)
5586 && strcmp(rmap, bgp_static->rmap.name)) {
5587 vty_out(vty,
5588 "%% route-map name doesn't match static route\n");
5589 return CMD_WARNING_CONFIG_FAILED;
5590 }
5591
5592 /* Update BGP RIB. */
5593 if (!bgp_static->backdoor)
5594 bgp_static_withdraw(bgp, &p, afi, safi);
5595
5596 /* Clear configuration. */
5597 bgp_static_free(bgp_static);
5598 bgp_dest_set_bgp_static_info(dest, NULL);
5599 bgp_dest_unlock_node(dest);
5600 bgp_dest_unlock_node(dest);
5601 } else {
5602
5603 /* Set BGP static route configuration. */
5604 dest = bgp_node_get(bgp->route[afi][safi], &p);
5605 bgp_static = bgp_dest_get_bgp_static_info(dest);
5606 if (bgp_static) {
5607 /* Configuration change. */
5608 /* Label index cannot be changed. */
5609 if (bgp_static->label_index != label_index) {
5610 vty_out(vty, "%% cannot change label-index\n");
5611 return CMD_WARNING_CONFIG_FAILED;
5612 }
5613
5614 /* Check previous routes are installed into BGP. */
5615 if (bgp_static->valid
5616 && bgp_static->backdoor != backdoor)
5617 need_update = 1;
5618
5619 bgp_static->backdoor = backdoor;
5620
5621 if (rmap) {
5622 XFREE(MTYPE_ROUTE_MAP_NAME,
5623 bgp_static->rmap.name);
5624 route_map_counter_decrement(
5625 bgp_static->rmap.map);
5626 bgp_static->rmap.name =
5627 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5628 bgp_static->rmap.map =
5629 route_map_lookup_by_name(rmap);
5630 route_map_counter_increment(
5631 bgp_static->rmap.map);
5632 } else {
5633 XFREE(MTYPE_ROUTE_MAP_NAME,
5634 bgp_static->rmap.name);
5635 route_map_counter_decrement(
5636 bgp_static->rmap.map);
5637 bgp_static->rmap.map = NULL;
5638 bgp_static->valid = 0;
5639 }
5640 bgp_dest_unlock_node(dest);
5641 } else {
5642 /* New configuration. */
5643 bgp_static = bgp_static_new();
5644 bgp_static->backdoor = backdoor;
5645 bgp_static->valid = 0;
5646 bgp_static->igpmetric = 0;
5647 bgp_static->igpnexthop.s_addr = INADDR_ANY;
5648 bgp_static->label_index = label_index;
5649
5650 if (rmap) {
5651 XFREE(MTYPE_ROUTE_MAP_NAME,
5652 bgp_static->rmap.name);
5653 route_map_counter_decrement(
5654 bgp_static->rmap.map);
5655 bgp_static->rmap.name =
5656 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5657 bgp_static->rmap.map =
5658 route_map_lookup_by_name(rmap);
5659 route_map_counter_increment(
5660 bgp_static->rmap.map);
5661 }
5662 bgp_dest_set_bgp_static_info(dest, bgp_static);
5663 }
5664
5665 bgp_static->valid = 1;
5666 if (need_update)
5667 bgp_static_withdraw(bgp, &p, afi, safi);
5668
5669 if (!bgp_static->backdoor)
5670 bgp_static_update(bgp, &p, bgp_static, afi, safi);
5671 }
5672
5673 return CMD_SUCCESS;
5674 }
5675
5676 void bgp_static_add(struct bgp *bgp)
5677 {
5678 afi_t afi;
5679 safi_t safi;
5680 struct bgp_dest *dest;
5681 struct bgp_dest *rm;
5682 struct bgp_table *table;
5683 struct bgp_static *bgp_static;
5684
5685 FOREACH_AFI_SAFI (afi, safi)
5686 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
5687 dest = bgp_route_next(dest)) {
5688 if (!bgp_dest_has_bgp_path_info_data(dest))
5689 continue;
5690
5691 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5692 || (safi == SAFI_EVPN)) {
5693 table = bgp_dest_get_bgp_table_info(dest);
5694
5695 for (rm = bgp_table_top(table); rm;
5696 rm = bgp_route_next(rm)) {
5697 bgp_static =
5698 bgp_dest_get_bgp_static_info(
5699 rm);
5700 bgp_static_update_safi(
5701 bgp, bgp_dest_get_prefix(rm),
5702 bgp_static, afi, safi);
5703 }
5704 } else {
5705 bgp_static_update(
5706 bgp, bgp_dest_get_prefix(dest),
5707 bgp_dest_get_bgp_static_info(dest), afi,
5708 safi);
5709 }
5710 }
5711 }
5712
5713 /* Called from bgp_delete(). Delete all static routes from the BGP
5714 instance. */
5715 void bgp_static_delete(struct bgp *bgp)
5716 {
5717 afi_t afi;
5718 safi_t safi;
5719 struct bgp_dest *dest;
5720 struct bgp_dest *rm;
5721 struct bgp_table *table;
5722 struct bgp_static *bgp_static;
5723
5724 FOREACH_AFI_SAFI (afi, safi)
5725 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
5726 dest = bgp_route_next(dest)) {
5727 if (!bgp_dest_has_bgp_path_info_data(dest))
5728 continue;
5729
5730 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5731 || (safi == SAFI_EVPN)) {
5732 table = bgp_dest_get_bgp_table_info(dest);
5733
5734 for (rm = bgp_table_top(table); rm;
5735 rm = bgp_route_next(rm)) {
5736 bgp_static =
5737 bgp_dest_get_bgp_static_info(
5738 rm);
5739 if (!bgp_static)
5740 continue;
5741
5742 bgp_static_withdraw_safi(
5743 bgp, bgp_dest_get_prefix(rm),
5744 AFI_IP, safi,
5745 (struct prefix_rd *)
5746 bgp_dest_get_prefix(
5747 dest));
5748 bgp_static_free(bgp_static);
5749 bgp_dest_set_bgp_static_info(dest,
5750 NULL);
5751 bgp_dest_unlock_node(dest);
5752 }
5753 } else {
5754 bgp_static = bgp_dest_get_bgp_static_info(dest);
5755 bgp_static_withdraw(bgp,
5756 bgp_dest_get_prefix(dest),
5757 afi, safi);
5758 bgp_static_free(bgp_static);
5759 bgp_dest_set_bgp_static_info(dest, NULL);
5760 bgp_dest_unlock_node(dest);
5761 }
5762 }
5763 }
5764
5765 void bgp_static_redo_import_check(struct bgp *bgp)
5766 {
5767 afi_t afi;
5768 safi_t safi;
5769 struct bgp_dest *dest;
5770 struct bgp_dest *rm;
5771 struct bgp_table *table;
5772 struct bgp_static *bgp_static;
5773
5774 /* Use this flag to force reprocessing of the route */
5775 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
5776 FOREACH_AFI_SAFI (afi, safi) {
5777 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
5778 dest = bgp_route_next(dest)) {
5779 if (!bgp_dest_has_bgp_path_info_data(dest))
5780 continue;
5781
5782 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5783 || (safi == SAFI_EVPN)) {
5784 table = bgp_dest_get_bgp_table_info(dest);
5785
5786 for (rm = bgp_table_top(table); rm;
5787 rm = bgp_route_next(rm)) {
5788 bgp_static =
5789 bgp_dest_get_bgp_static_info(
5790 rm);
5791 bgp_static_update_safi(
5792 bgp, bgp_dest_get_prefix(rm),
5793 bgp_static, afi, safi);
5794 }
5795 } else {
5796 bgp_static = bgp_dest_get_bgp_static_info(dest);
5797 bgp_static_update(bgp,
5798 bgp_dest_get_prefix(dest),
5799 bgp_static, afi, safi);
5800 }
5801 }
5802 }
5803 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
5804 }
5805
5806 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
5807 safi_t safi)
5808 {
5809 struct bgp_table *table;
5810 struct bgp_dest *dest;
5811 struct bgp_path_info *pi;
5812
5813 /* Do not install the aggregate route if BGP is in the
5814 * process of termination.
5815 */
5816 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
5817 || (bgp->peer_self == NULL))
5818 return;
5819
5820 table = bgp->rib[afi][safi];
5821 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5822 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5823 if (pi->peer == bgp->peer_self
5824 && ((pi->type == ZEBRA_ROUTE_BGP
5825 && pi->sub_type == BGP_ROUTE_STATIC)
5826 || (pi->type != ZEBRA_ROUTE_BGP
5827 && pi->sub_type
5828 == BGP_ROUTE_REDISTRIBUTE))) {
5829 bgp_aggregate_decrement(
5830 bgp, bgp_dest_get_prefix(dest), pi, afi,
5831 safi);
5832 bgp_unlink_nexthop(pi);
5833 bgp_path_info_delete(dest, pi);
5834 bgp_process(bgp, dest, afi, safi);
5835 }
5836 }
5837 }
5838 }
5839
5840 /*
5841 * Purge all networks and redistributed routes from routing table.
5842 * Invoked upon the instance going down.
5843 */
5844 void bgp_purge_static_redist_routes(struct bgp *bgp)
5845 {
5846 afi_t afi;
5847 safi_t safi;
5848
5849 FOREACH_AFI_SAFI (afi, safi)
5850 bgp_purge_af_static_redist_routes(bgp, afi, safi);
5851 }
5852
5853 /*
5854 * gpz 110624
5855 * Currently this is used to set static routes for VPN and ENCAP.
5856 * I think it can probably be factored with bgp_static_set.
5857 */
5858 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
5859 const char *ip_str, const char *rd_str,
5860 const char *label_str, const char *rmap_str,
5861 int evpn_type, const char *esi, const char *gwip,
5862 const char *ethtag, const char *routermac)
5863 {
5864 VTY_DECLVAR_CONTEXT(bgp, bgp);
5865 int ret;
5866 struct prefix p;
5867 struct prefix_rd prd;
5868 struct bgp_dest *pdest;
5869 struct bgp_dest *dest;
5870 struct bgp_table *table;
5871 struct bgp_static *bgp_static;
5872 mpls_label_t label = MPLS_INVALID_LABEL;
5873 struct prefix gw_ip;
5874
5875 /* validate ip prefix */
5876 ret = str2prefix(ip_str, &p);
5877 if (!ret) {
5878 vty_out(vty, "%% Malformed prefix\n");
5879 return CMD_WARNING_CONFIG_FAILED;
5880 }
5881 apply_mask(&p);
5882 if ((afi == AFI_L2VPN)
5883 && (bgp_build_evpn_prefix(evpn_type,
5884 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5885 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5886 return CMD_WARNING_CONFIG_FAILED;
5887 }
5888
5889 ret = str2prefix_rd(rd_str, &prd);
5890 if (!ret) {
5891 vty_out(vty, "%% Malformed rd\n");
5892 return CMD_WARNING_CONFIG_FAILED;
5893 }
5894
5895 if (label_str) {
5896 unsigned long label_val;
5897 label_val = strtoul(label_str, NULL, 10);
5898 encode_label(label_val, &label);
5899 }
5900
5901 if (safi == SAFI_EVPN) {
5902 if (esi && str2esi(esi, NULL) == 0) {
5903 vty_out(vty, "%% Malformed ESI\n");
5904 return CMD_WARNING_CONFIG_FAILED;
5905 }
5906 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
5907 vty_out(vty, "%% Malformed Router MAC\n");
5908 return CMD_WARNING_CONFIG_FAILED;
5909 }
5910 if (gwip) {
5911 memset(&gw_ip, 0, sizeof(struct prefix));
5912 ret = str2prefix(gwip, &gw_ip);
5913 if (!ret) {
5914 vty_out(vty, "%% Malformed GatewayIp\n");
5915 return CMD_WARNING_CONFIG_FAILED;
5916 }
5917 if ((gw_ip.family == AF_INET
5918 && is_evpn_prefix_ipaddr_v6(
5919 (struct prefix_evpn *)&p))
5920 || (gw_ip.family == AF_INET6
5921 && is_evpn_prefix_ipaddr_v4(
5922 (struct prefix_evpn *)&p))) {
5923 vty_out(vty,
5924 "%% GatewayIp family differs with IP prefix\n");
5925 return CMD_WARNING_CONFIG_FAILED;
5926 }
5927 }
5928 }
5929 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5930 if (!bgp_dest_has_bgp_path_info_data(pdest))
5931 bgp_dest_set_bgp_table_info(pdest,
5932 bgp_table_init(bgp, afi, safi));
5933 table = bgp_dest_get_bgp_table_info(pdest);
5934
5935 dest = bgp_node_get(table, &p);
5936
5937 if (bgp_dest_has_bgp_path_info_data(dest)) {
5938 vty_out(vty, "%% Same network configuration exists\n");
5939 bgp_dest_unlock_node(dest);
5940 } else {
5941 /* New configuration. */
5942 bgp_static = bgp_static_new();
5943 bgp_static->backdoor = 0;
5944 bgp_static->valid = 0;
5945 bgp_static->igpmetric = 0;
5946 bgp_static->igpnexthop.s_addr = INADDR_ANY;
5947 bgp_static->label = label;
5948 bgp_static->prd = prd;
5949
5950 if (rmap_str) {
5951 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5952 route_map_counter_decrement(bgp_static->rmap.map);
5953 bgp_static->rmap.name =
5954 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
5955 bgp_static->rmap.map =
5956 route_map_lookup_by_name(rmap_str);
5957 route_map_counter_increment(bgp_static->rmap.map);
5958 }
5959
5960 if (safi == SAFI_EVPN) {
5961 if (esi) {
5962 bgp_static->eth_s_id =
5963 XCALLOC(MTYPE_ATTR,
5964 sizeof(esi_t));
5965 str2esi(esi, bgp_static->eth_s_id);
5966 }
5967 if (routermac) {
5968 bgp_static->router_mac =
5969 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
5970 (void)prefix_str2mac(routermac,
5971 bgp_static->router_mac);
5972 }
5973 if (gwip)
5974 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
5975 }
5976 bgp_dest_set_bgp_static_info(dest, bgp_static);
5977
5978 bgp_static->valid = 1;
5979 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
5980 }
5981
5982 return CMD_SUCCESS;
5983 }
5984
5985 /* Configure static BGP network. */
5986 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
5987 const char *ip_str, const char *rd_str,
5988 const char *label_str, int evpn_type, const char *esi,
5989 const char *gwip, const char *ethtag)
5990 {
5991 VTY_DECLVAR_CONTEXT(bgp, bgp);
5992 int ret;
5993 struct prefix p;
5994 struct prefix_rd prd;
5995 struct bgp_dest *pdest;
5996 struct bgp_dest *dest;
5997 struct bgp_table *table;
5998 struct bgp_static *bgp_static;
5999 mpls_label_t label = MPLS_INVALID_LABEL;
6000
6001 /* Convert IP prefix string to struct prefix. */
6002 ret = str2prefix(ip_str, &p);
6003 if (!ret) {
6004 vty_out(vty, "%% Malformed prefix\n");
6005 return CMD_WARNING_CONFIG_FAILED;
6006 }
6007 apply_mask(&p);
6008 if ((afi == AFI_L2VPN)
6009 && (bgp_build_evpn_prefix(evpn_type,
6010 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6011 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6012 return CMD_WARNING_CONFIG_FAILED;
6013 }
6014 ret = str2prefix_rd(rd_str, &prd);
6015 if (!ret) {
6016 vty_out(vty, "%% Malformed rd\n");
6017 return CMD_WARNING_CONFIG_FAILED;
6018 }
6019
6020 if (label_str) {
6021 unsigned long label_val;
6022 label_val = strtoul(label_str, NULL, 10);
6023 encode_label(label_val, &label);
6024 }
6025
6026 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6027 if (!bgp_dest_has_bgp_path_info_data(pdest))
6028 bgp_dest_set_bgp_table_info(pdest,
6029 bgp_table_init(bgp, afi, safi));
6030 else
6031 bgp_dest_unlock_node(pdest);
6032 table = bgp_dest_get_bgp_table_info(pdest);
6033
6034 dest = bgp_node_lookup(table, &p);
6035
6036 if (dest) {
6037 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
6038
6039 bgp_static = bgp_dest_get_bgp_static_info(dest);
6040 bgp_static_free(bgp_static);
6041 bgp_dest_set_bgp_static_info(dest, NULL);
6042 bgp_dest_unlock_node(dest);
6043 bgp_dest_unlock_node(dest);
6044 } else
6045 vty_out(vty, "%% Can't find the route\n");
6046
6047 return CMD_SUCCESS;
6048 }
6049
6050 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
6051 const char *rmap_name)
6052 {
6053 VTY_DECLVAR_CONTEXT(bgp, bgp);
6054 struct bgp_rmap *rmap;
6055
6056 rmap = &bgp->table_map[afi][safi];
6057 if (rmap_name) {
6058 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6059 route_map_counter_decrement(rmap->map);
6060 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
6061 rmap->map = route_map_lookup_by_name(rmap_name);
6062 route_map_counter_increment(rmap->map);
6063 } else {
6064 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6065 route_map_counter_decrement(rmap->map);
6066 rmap->map = NULL;
6067 }
6068
6069 if (bgp_fibupd_safi(safi))
6070 bgp_zebra_announce_table(bgp, afi, safi);
6071
6072 return CMD_SUCCESS;
6073 }
6074
6075 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
6076 const char *rmap_name)
6077 {
6078 VTY_DECLVAR_CONTEXT(bgp, bgp);
6079 struct bgp_rmap *rmap;
6080
6081 rmap = &bgp->table_map[afi][safi];
6082 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6083 route_map_counter_decrement(rmap->map);
6084 rmap->map = NULL;
6085
6086 if (bgp_fibupd_safi(safi))
6087 bgp_zebra_announce_table(bgp, afi, safi);
6088
6089 return CMD_SUCCESS;
6090 }
6091
6092 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
6093 safi_t safi)
6094 {
6095 if (bgp->table_map[afi][safi].name) {
6096 vty_out(vty, " table-map %s\n",
6097 bgp->table_map[afi][safi].name);
6098 }
6099 }
6100
6101 DEFUN (bgp_table_map,
6102 bgp_table_map_cmd,
6103 "table-map WORD",
6104 "BGP table to RIB route download filter\n"
6105 "Name of the route map\n")
6106 {
6107 int idx_word = 1;
6108 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6109 argv[idx_word]->arg);
6110 }
6111 DEFUN (no_bgp_table_map,
6112 no_bgp_table_map_cmd,
6113 "no table-map WORD",
6114 NO_STR
6115 "BGP table to RIB route download filter\n"
6116 "Name of the route map\n")
6117 {
6118 int idx_word = 2;
6119 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6120 argv[idx_word]->arg);
6121 }
6122
6123 DEFPY(bgp_network,
6124 bgp_network_cmd,
6125 "[no] network \
6126 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
6127 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
6128 backdoor$backdoor}]",
6129 NO_STR
6130 "Specify a network to announce via BGP\n"
6131 "IPv4 prefix\n"
6132 "Network number\n"
6133 "Network mask\n"
6134 "Network mask\n"
6135 "Route-map to modify the attributes\n"
6136 "Name of the route map\n"
6137 "Label index to associate with the prefix\n"
6138 "Label index value\n"
6139 "Specify a BGP backdoor route\n")
6140 {
6141 char addr_prefix_str[BUFSIZ];
6142
6143 if (address_str) {
6144 int ret;
6145
6146 ret = netmask_str2prefix_str(address_str, netmask_str,
6147 addr_prefix_str);
6148 if (!ret) {
6149 vty_out(vty, "%% Inconsistent address and mask\n");
6150 return CMD_WARNING_CONFIG_FAILED;
6151 }
6152 }
6153
6154 return bgp_static_set(
6155 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
6156 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
6157 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
6158 }
6159
6160 DEFPY(ipv6_bgp_network,
6161 ipv6_bgp_network_cmd,
6162 "[no] network X:X::X:X/M$prefix \
6163 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
6164 NO_STR
6165 "Specify a network to announce via BGP\n"
6166 "IPv6 prefix\n"
6167 "Route-map to modify the attributes\n"
6168 "Name of the route map\n"
6169 "Label index to associate with the prefix\n"
6170 "Label index value\n")
6171 {
6172 return bgp_static_set(
6173 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
6174 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
6175 }
6176
6177 static struct bgp_aggregate *bgp_aggregate_new(void)
6178 {
6179 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
6180 }
6181
6182 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
6183 {
6184 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
6185 route_map_counter_decrement(aggregate->rmap.map);
6186 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
6187 }
6188
6189 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
6190 struct aspath *aspath,
6191 struct community *comm,
6192 struct ecommunity *ecomm,
6193 struct lcommunity *lcomm)
6194 {
6195 static struct aspath *ae = NULL;
6196
6197 if (!ae)
6198 ae = aspath_empty();
6199
6200 if (!pi)
6201 return false;
6202
6203 if (origin != pi->attr->origin)
6204 return false;
6205
6206 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
6207 return false;
6208
6209 if (!community_cmp(pi->attr->community, comm))
6210 return false;
6211
6212 if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
6213 return false;
6214
6215 if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
6216 return false;
6217
6218 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
6219 return false;
6220
6221 return true;
6222 }
6223
6224 static void bgp_aggregate_install(
6225 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
6226 uint8_t origin, struct aspath *aspath, struct community *community,
6227 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
6228 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
6229 {
6230 struct bgp_dest *dest;
6231 struct bgp_table *table;
6232 struct bgp_path_info *pi, *orig, *new;
6233 struct attr *attr;
6234
6235 table = bgp->rib[afi][safi];
6236
6237 dest = bgp_node_get(table, p);
6238
6239 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6240 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6241 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6242 break;
6243
6244 /*
6245 * If we have paths with different MEDs, then don't install
6246 * (or uninstall) the aggregate route.
6247 */
6248 if (aggregate->match_med && aggregate->med_mismatched)
6249 goto uninstall_aggregate_route;
6250
6251 if (aggregate->count > 0) {
6252 /*
6253 * If the aggregate information has not changed
6254 * no need to re-install it again.
6255 */
6256 if (bgp_aggregate_info_same(orig, origin, aspath, community,
6257 ecommunity, lcommunity)) {
6258 bgp_dest_unlock_node(dest);
6259
6260 if (aspath)
6261 aspath_free(aspath);
6262 if (community)
6263 community_free(&community);
6264 if (ecommunity)
6265 ecommunity_free(&ecommunity);
6266 if (lcommunity)
6267 lcommunity_free(&lcommunity);
6268
6269 return;
6270 }
6271
6272 /*
6273 * Mark the old as unusable
6274 */
6275 if (pi)
6276 bgp_path_info_delete(dest, pi);
6277
6278 attr = bgp_attr_aggregate_intern(
6279 bgp, origin, aspath, community, ecommunity, lcommunity,
6280 aggregate, atomic_aggregate, p);
6281
6282 if (!attr) {
6283 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
6284 return;
6285 }
6286
6287 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
6288 bgp->peer_self, attr, dest);
6289
6290 SET_FLAG(new->flags, BGP_PATH_VALID);
6291
6292 bgp_path_info_add(dest, new);
6293 bgp_process(bgp, dest, afi, safi);
6294 } else {
6295 uninstall_aggregate_route:
6296 for (pi = orig; pi; pi = pi->next)
6297 if (pi->peer == bgp->peer_self
6298 && pi->type == ZEBRA_ROUTE_BGP
6299 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6300 break;
6301
6302 /* Withdraw static BGP route from routing table. */
6303 if (pi) {
6304 bgp_path_info_delete(dest, pi);
6305 bgp_process(bgp, dest, afi, safi);
6306 }
6307 }
6308
6309 bgp_dest_unlock_node(dest);
6310 }
6311
6312 /**
6313 * Check if the current path has different MED than other known paths.
6314 *
6315 * \returns `true` if the MED matched the others else `false`.
6316 */
6317 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
6318 struct bgp *bgp, struct bgp_path_info *pi)
6319 {
6320 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
6321
6322 /* This is the first route being analyzed. */
6323 if (!aggregate->med_initialized) {
6324 aggregate->med_initialized = true;
6325 aggregate->med_mismatched = false;
6326 aggregate->med_matched_value = cur_med;
6327 } else {
6328 /* Check if routes with different MED showed up. */
6329 if (cur_med != aggregate->med_matched_value)
6330 aggregate->med_mismatched = true;
6331 }
6332
6333 return !aggregate->med_mismatched;
6334 }
6335
6336 /**
6337 * Initializes and tests all routes in the aggregate address path for MED
6338 * values.
6339 *
6340 * \returns `true` if all MEDs are the same otherwise `false`.
6341 */
6342 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
6343 struct bgp *bgp, const struct prefix *p,
6344 afi_t afi, safi_t safi)
6345 {
6346 struct bgp_table *table = bgp->rib[afi][safi];
6347 const struct prefix *dest_p;
6348 struct bgp_dest *dest, *top;
6349 struct bgp_path_info *pi;
6350 bool med_matched = true;
6351
6352 aggregate->med_initialized = false;
6353
6354 top = bgp_node_get(table, p);
6355 for (dest = bgp_node_get(table, p); dest;
6356 dest = bgp_route_next_until(dest, top)) {
6357 dest_p = bgp_dest_get_prefix(dest);
6358 if (dest_p->prefixlen <= p->prefixlen)
6359 continue;
6360
6361 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6362 if (BGP_PATH_HOLDDOWN(pi))
6363 continue;
6364 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6365 continue;
6366 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
6367 med_matched = false;
6368 break;
6369 }
6370 }
6371 if (!med_matched)
6372 break;
6373 }
6374 bgp_dest_unlock_node(top);
6375
6376 return med_matched;
6377 }
6378
6379 /**
6380 * Toggles the route suppression status for this aggregate address
6381 * configuration.
6382 */
6383 static void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
6384 struct bgp *bgp,
6385 const struct prefix *p, afi_t afi,
6386 safi_t safi, bool suppress)
6387 {
6388 struct bgp_table *table = bgp->rib[afi][safi];
6389 struct bgp_path_info_extra *pie;
6390 const struct prefix *dest_p;
6391 struct bgp_dest *dest, *top;
6392 struct bgp_path_info *pi;
6393 bool toggle_suppression;
6394
6395 /* We've found a different MED we must revert any suppressed routes. */
6396 top = bgp_node_get(table, p);
6397 for (dest = bgp_node_get(table, p); dest;
6398 dest = bgp_route_next_until(dest, top)) {
6399 dest_p = bgp_dest_get_prefix(dest);
6400 if (dest_p->prefixlen <= p->prefixlen)
6401 continue;
6402
6403 toggle_suppression = false;
6404 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6405 if (BGP_PATH_HOLDDOWN(pi))
6406 continue;
6407 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6408 continue;
6409
6410 /*
6411 * On installation it is possible that pi->extra is
6412 * set to NULL, otherwise it must exists.
6413 */
6414 assert(!suppress && pi->extra != NULL);
6415
6416 /* We are toggling suppression back. */
6417 if (suppress) {
6418 pie = bgp_path_info_extra_get(pi);
6419 /* Suppress route if not suppressed already. */
6420 pie->suppress++;
6421 bgp_path_info_set_flag(dest, pi,
6422 BGP_PATH_ATTR_CHANGED);
6423 toggle_suppression = true;
6424 continue;
6425 }
6426
6427 pie = pi->extra;
6428 assert(pie->suppress > 0);
6429 pie->suppress--;
6430 /* Install route if there is no more suppression. */
6431 if (pie->suppress == 0) {
6432 bgp_path_info_set_flag(dest, pi,
6433 BGP_PATH_ATTR_CHANGED);
6434 toggle_suppression = true;
6435 }
6436 }
6437
6438 if (toggle_suppression)
6439 bgp_process(bgp, dest, afi, safi);
6440 }
6441 bgp_dest_unlock_node(top);
6442 }
6443
6444 /**
6445 * Aggregate address MED matching incremental test: this function is called
6446 * when the initial aggregation occurred and we are only testing a single
6447 * new path.
6448 *
6449 * In addition to testing and setting the MED validity it also installs back
6450 * suppressed routes (if summary is configured).
6451 *
6452 * Must not be called in `bgp_aggregate_route`.
6453 */
6454 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
6455 struct bgp *bgp, const struct prefix *p,
6456 afi_t afi, safi_t safi,
6457 struct bgp_path_info *pi, bool is_adding)
6458 {
6459 /* MED matching disabled. */
6460 if (!aggregate->match_med)
6461 return;
6462
6463 /* Aggregation with different MED, nothing to do. */
6464 if (aggregate->med_mismatched)
6465 return;
6466
6467 /*
6468 * Test the current entry:
6469 *
6470 * is_adding == true: if the new entry doesn't match then we must
6471 * install all suppressed routes.
6472 *
6473 * is_adding == false: if the entry being removed was the last
6474 * unmatching entry then we can suppress all routes.
6475 */
6476 if (!is_adding) {
6477 if (bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi)
6478 && aggregate->summary_only)
6479 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi,
6480 safi, true);
6481 } else
6482 bgp_aggregate_med_match(aggregate, bgp, pi);
6483
6484 /* No mismatches, just quit. */
6485 if (!aggregate->med_mismatched)
6486 return;
6487
6488 /* Route summarization is disabled. */
6489 if (!aggregate->summary_only)
6490 return;
6491
6492 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
6493 }
6494
6495 /* Update an aggregate as routes are added/removed from the BGP table */
6496 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
6497 safi_t safi, struct bgp_aggregate *aggregate)
6498 {
6499 struct bgp_table *table;
6500 struct bgp_dest *top;
6501 struct bgp_dest *dest;
6502 uint8_t origin;
6503 struct aspath *aspath = NULL;
6504 struct community *community = NULL;
6505 struct ecommunity *ecommunity = NULL;
6506 struct lcommunity *lcommunity = NULL;
6507 struct bgp_path_info *pi;
6508 unsigned long match = 0;
6509 uint8_t atomic_aggregate = 0;
6510
6511 /* If the bgp instance is being deleted or self peer is deleted
6512 * then do not create aggregate route
6513 */
6514 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6515 || (bgp->peer_self == NULL))
6516 return;
6517
6518 /* Initialize and test routes for MED difference. */
6519 if (aggregate->match_med)
6520 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
6521
6522 /* ORIGIN attribute: If at least one route among routes that are
6523 aggregated has ORIGIN with the value INCOMPLETE, then the
6524 aggregated route must have the ORIGIN attribute with the value
6525 INCOMPLETE. Otherwise, if at least one route among routes that
6526 are aggregated has ORIGIN with the value EGP, then the aggregated
6527 route must have the origin attribute with the value EGP. In all
6528 other case the value of the ORIGIN attribute of the aggregated
6529 route is INTERNAL. */
6530 origin = BGP_ORIGIN_IGP;
6531
6532 table = bgp->rib[afi][safi];
6533
6534 top = bgp_node_get(table, p);
6535 for (dest = bgp_node_get(table, p); dest;
6536 dest = bgp_route_next_until(dest, top)) {
6537 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
6538
6539 if (dest_p->prefixlen <= p->prefixlen)
6540 continue;
6541
6542 match = 0;
6543
6544 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6545 if (BGP_PATH_HOLDDOWN(pi))
6546 continue;
6547
6548 if (pi->attr->flag
6549 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
6550 atomic_aggregate = 1;
6551
6552 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6553 continue;
6554
6555 /*
6556 * summary-only aggregate route suppress
6557 * aggregated route announcements.
6558 *
6559 * MED matching:
6560 * Don't create summaries if MED didn't match
6561 * otherwise neither the specific routes and the
6562 * aggregation will be announced.
6563 */
6564 if (aggregate->summary_only
6565 && AGGREGATE_MED_VALID(aggregate)) {
6566 (bgp_path_info_extra_get(pi))->suppress++;
6567 bgp_path_info_set_flag(dest, pi,
6568 BGP_PATH_ATTR_CHANGED);
6569 match++;
6570 }
6571
6572 aggregate->count++;
6573
6574 /*
6575 * If at least one route among routes that are
6576 * aggregated has ORIGIN with the value INCOMPLETE,
6577 * then the aggregated route MUST have the ORIGIN
6578 * attribute with the value INCOMPLETE. Otherwise, if
6579 * at least one route among routes that are aggregated
6580 * has ORIGIN with the value EGP, then the aggregated
6581 * route MUST have the ORIGIN attribute with the value
6582 * EGP.
6583 */
6584 switch (pi->attr->origin) {
6585 case BGP_ORIGIN_INCOMPLETE:
6586 aggregate->incomplete_origin_count++;
6587 break;
6588 case BGP_ORIGIN_EGP:
6589 aggregate->egp_origin_count++;
6590 break;
6591 default:
6592 /*Do nothing.
6593 */
6594 break;
6595 }
6596
6597 if (!aggregate->as_set)
6598 continue;
6599
6600 /*
6601 * as-set aggregate route generate origin, as path,
6602 * and community aggregation.
6603 */
6604 /* Compute aggregate route's as-path.
6605 */
6606 bgp_compute_aggregate_aspath_hash(aggregate,
6607 pi->attr->aspath);
6608
6609 /* Compute aggregate route's community.
6610 */
6611 if (pi->attr->community)
6612 bgp_compute_aggregate_community_hash(
6613 aggregate,
6614 pi->attr->community);
6615
6616 /* Compute aggregate route's extended community.
6617 */
6618 if (pi->attr->ecommunity)
6619 bgp_compute_aggregate_ecommunity_hash(
6620 aggregate,
6621 pi->attr->ecommunity);
6622
6623 /* Compute aggregate route's large community.
6624 */
6625 if (pi->attr->lcommunity)
6626 bgp_compute_aggregate_lcommunity_hash(
6627 aggregate,
6628 pi->attr->lcommunity);
6629 }
6630 if (match)
6631 bgp_process(bgp, dest, afi, safi);
6632 }
6633 if (aggregate->as_set) {
6634 bgp_compute_aggregate_aspath_val(aggregate);
6635 bgp_compute_aggregate_community_val(aggregate);
6636 bgp_compute_aggregate_ecommunity_val(aggregate);
6637 bgp_compute_aggregate_lcommunity_val(aggregate);
6638 }
6639
6640
6641 bgp_dest_unlock_node(top);
6642
6643
6644 if (aggregate->incomplete_origin_count > 0)
6645 origin = BGP_ORIGIN_INCOMPLETE;
6646 else if (aggregate->egp_origin_count > 0)
6647 origin = BGP_ORIGIN_EGP;
6648
6649 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
6650 origin = aggregate->origin;
6651
6652 if (aggregate->as_set) {
6653 if (aggregate->aspath)
6654 /* Retrieve aggregate route's as-path.
6655 */
6656 aspath = aspath_dup(aggregate->aspath);
6657
6658 if (aggregate->community)
6659 /* Retrieve aggregate route's community.
6660 */
6661 community = community_dup(aggregate->community);
6662
6663 if (aggregate->ecommunity)
6664 /* Retrieve aggregate route's ecommunity.
6665 */
6666 ecommunity = ecommunity_dup(aggregate->ecommunity);
6667
6668 if (aggregate->lcommunity)
6669 /* Retrieve aggregate route's lcommunity.
6670 */
6671 lcommunity = lcommunity_dup(aggregate->lcommunity);
6672 }
6673
6674 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
6675 ecommunity, lcommunity, atomic_aggregate,
6676 aggregate);
6677 }
6678
6679 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
6680 safi_t safi, struct bgp_aggregate *aggregate)
6681 {
6682 struct bgp_table *table;
6683 struct bgp_dest *top;
6684 struct bgp_dest *dest;
6685 struct bgp_path_info *pi;
6686 unsigned long match;
6687
6688 table = bgp->rib[afi][safi];
6689
6690 /* If routes exists below this node, generate aggregate routes. */
6691 top = bgp_node_get(table, p);
6692 for (dest = bgp_node_get(table, p); dest;
6693 dest = bgp_route_next_until(dest, top)) {
6694 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
6695
6696 if (dest_p->prefixlen <= p->prefixlen)
6697 continue;
6698 match = 0;
6699
6700 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6701 if (BGP_PATH_HOLDDOWN(pi))
6702 continue;
6703
6704 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6705 continue;
6706
6707 if (aggregate->summary_only && pi->extra
6708 && AGGREGATE_MED_VALID(aggregate)) {
6709 pi->extra->suppress--;
6710
6711 if (pi->extra->suppress == 0) {
6712 bgp_path_info_set_flag(
6713 dest, pi,
6714 BGP_PATH_ATTR_CHANGED);
6715 match++;
6716 }
6717 }
6718 aggregate->count--;
6719
6720 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
6721 aggregate->incomplete_origin_count--;
6722 else if (pi->attr->origin == BGP_ORIGIN_EGP)
6723 aggregate->egp_origin_count--;
6724
6725 if (aggregate->as_set) {
6726 /* Remove as-path from aggregate.
6727 */
6728 bgp_remove_aspath_from_aggregate_hash(
6729 aggregate,
6730 pi->attr->aspath);
6731
6732 if (pi->attr->community)
6733 /* Remove community from aggregate.
6734 */
6735 bgp_remove_comm_from_aggregate_hash(
6736 aggregate,
6737 pi->attr->community);
6738
6739 if (pi->attr->ecommunity)
6740 /* Remove ecommunity from aggregate.
6741 */
6742 bgp_remove_ecomm_from_aggregate_hash(
6743 aggregate,
6744 pi->attr->ecommunity);
6745
6746 if (pi->attr->lcommunity)
6747 /* Remove lcommunity from aggregate.
6748 */
6749 bgp_remove_lcomm_from_aggregate_hash(
6750 aggregate,
6751 pi->attr->lcommunity);
6752 }
6753 }
6754
6755 /* If this node was suppressed, process the change. */
6756 if (match)
6757 bgp_process(bgp, dest, afi, safi);
6758 }
6759 if (aggregate->as_set) {
6760 aspath_free(aggregate->aspath);
6761 aggregate->aspath = NULL;
6762 if (aggregate->community)
6763 community_free(&aggregate->community);
6764 if (aggregate->ecommunity)
6765 ecommunity_free(&aggregate->ecommunity);
6766 if (aggregate->lcommunity)
6767 lcommunity_free(&aggregate->lcommunity);
6768 }
6769
6770 bgp_dest_unlock_node(top);
6771 }
6772
6773 static void bgp_add_route_to_aggregate(struct bgp *bgp,
6774 const struct prefix *aggr_p,
6775 struct bgp_path_info *pinew, afi_t afi,
6776 safi_t safi,
6777 struct bgp_aggregate *aggregate)
6778 {
6779 uint8_t origin;
6780 struct aspath *aspath = NULL;
6781 uint8_t atomic_aggregate = 0;
6782 struct community *community = NULL;
6783 struct ecommunity *ecommunity = NULL;
6784 struct lcommunity *lcommunity = NULL;
6785
6786 /* ORIGIN attribute: If at least one route among routes that are
6787 * aggregated has ORIGIN with the value INCOMPLETE, then the
6788 * aggregated route must have the ORIGIN attribute with the value
6789 * INCOMPLETE. Otherwise, if at least one route among routes that
6790 * are aggregated has ORIGIN with the value EGP, then the aggregated
6791 * route must have the origin attribute with the value EGP. In all
6792 * other case the value of the ORIGIN attribute of the aggregated
6793 * route is INTERNAL.
6794 */
6795 origin = BGP_ORIGIN_IGP;
6796
6797 aggregate->count++;
6798
6799 /*
6800 * This must be called before `summary` check to avoid
6801 * "suppressing" twice.
6802 */
6803 if (aggregate->match_med)
6804 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
6805 pinew, true);
6806
6807 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
6808 (bgp_path_info_extra_get(pinew))->suppress++;
6809
6810 switch (pinew->attr->origin) {
6811 case BGP_ORIGIN_INCOMPLETE:
6812 aggregate->incomplete_origin_count++;
6813 break;
6814 case BGP_ORIGIN_EGP:
6815 aggregate->egp_origin_count++;
6816 break;
6817 default:
6818 /* Do nothing.
6819 */
6820 break;
6821 }
6822
6823 if (aggregate->incomplete_origin_count > 0)
6824 origin = BGP_ORIGIN_INCOMPLETE;
6825 else if (aggregate->egp_origin_count > 0)
6826 origin = BGP_ORIGIN_EGP;
6827
6828 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
6829 origin = aggregate->origin;
6830
6831 if (aggregate->as_set) {
6832 /* Compute aggregate route's as-path.
6833 */
6834 bgp_compute_aggregate_aspath(aggregate,
6835 pinew->attr->aspath);
6836
6837 /* Compute aggregate route's community.
6838 */
6839 if (pinew->attr->community)
6840 bgp_compute_aggregate_community(
6841 aggregate,
6842 pinew->attr->community);
6843
6844 /* Compute aggregate route's extended community.
6845 */
6846 if (pinew->attr->ecommunity)
6847 bgp_compute_aggregate_ecommunity(
6848 aggregate,
6849 pinew->attr->ecommunity);
6850
6851 /* Compute aggregate route's large community.
6852 */
6853 if (pinew->attr->lcommunity)
6854 bgp_compute_aggregate_lcommunity(
6855 aggregate,
6856 pinew->attr->lcommunity);
6857
6858 /* Retrieve aggregate route's as-path.
6859 */
6860 if (aggregate->aspath)
6861 aspath = aspath_dup(aggregate->aspath);
6862
6863 /* Retrieve aggregate route's community.
6864 */
6865 if (aggregate->community)
6866 community = community_dup(aggregate->community);
6867
6868 /* Retrieve aggregate route's ecommunity.
6869 */
6870 if (aggregate->ecommunity)
6871 ecommunity = ecommunity_dup(aggregate->ecommunity);
6872
6873 /* Retrieve aggregate route's lcommunity.
6874 */
6875 if (aggregate->lcommunity)
6876 lcommunity = lcommunity_dup(aggregate->lcommunity);
6877 }
6878
6879 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
6880 aspath, community, ecommunity,
6881 lcommunity, atomic_aggregate, aggregate);
6882 }
6883
6884 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
6885 safi_t safi,
6886 struct bgp_path_info *pi,
6887 struct bgp_aggregate *aggregate,
6888 const struct prefix *aggr_p)
6889 {
6890 uint8_t origin;
6891 struct aspath *aspath = NULL;
6892 uint8_t atomic_aggregate = 0;
6893 struct community *community = NULL;
6894 struct ecommunity *ecommunity = NULL;
6895 struct lcommunity *lcommunity = NULL;
6896 unsigned long match = 0;
6897
6898 if (BGP_PATH_HOLDDOWN(pi))
6899 return;
6900
6901 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6902 return;
6903
6904 if (aggregate->summary_only && pi->extra && pi->extra->suppress > 0
6905 && AGGREGATE_MED_VALID(aggregate)) {
6906 pi->extra->suppress--;
6907
6908 if (pi->extra->suppress == 0) {
6909 bgp_path_info_set_flag(pi->net, pi,
6910 BGP_PATH_ATTR_CHANGED);
6911 match++;
6912 }
6913 }
6914
6915 /*
6916 * This must be called after `summary` check to avoid
6917 * "unsuppressing" twice.
6918 */
6919 if (aggregate->match_med)
6920 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi,
6921 true);
6922
6923 if (aggregate->count > 0)
6924 aggregate->count--;
6925
6926 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
6927 aggregate->incomplete_origin_count--;
6928 else if (pi->attr->origin == BGP_ORIGIN_EGP)
6929 aggregate->egp_origin_count--;
6930
6931 if (aggregate->as_set) {
6932 /* Remove as-path from aggregate.
6933 */
6934 bgp_remove_aspath_from_aggregate(aggregate,
6935 pi->attr->aspath);
6936
6937 if (pi->attr->community)
6938 /* Remove community from aggregate.
6939 */
6940 bgp_remove_community_from_aggregate(
6941 aggregate,
6942 pi->attr->community);
6943
6944 if (pi->attr->ecommunity)
6945 /* Remove ecommunity from aggregate.
6946 */
6947 bgp_remove_ecommunity_from_aggregate(
6948 aggregate,
6949 pi->attr->ecommunity);
6950
6951 if (pi->attr->lcommunity)
6952 /* Remove lcommunity from aggregate.
6953 */
6954 bgp_remove_lcommunity_from_aggregate(
6955 aggregate,
6956 pi->attr->lcommunity);
6957 }
6958
6959 /* If this node was suppressed, process the change. */
6960 if (match)
6961 bgp_process(bgp, pi->net, afi, safi);
6962
6963 origin = BGP_ORIGIN_IGP;
6964 if (aggregate->incomplete_origin_count > 0)
6965 origin = BGP_ORIGIN_INCOMPLETE;
6966 else if (aggregate->egp_origin_count > 0)
6967 origin = BGP_ORIGIN_EGP;
6968
6969 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
6970 origin = aggregate->origin;
6971
6972 if (aggregate->as_set) {
6973 /* Retrieve aggregate route's as-path.
6974 */
6975 if (aggregate->aspath)
6976 aspath = aspath_dup(aggregate->aspath);
6977
6978 /* Retrieve aggregate route's community.
6979 */
6980 if (aggregate->community)
6981 community = community_dup(aggregate->community);
6982
6983 /* Retrieve aggregate route's ecommunity.
6984 */
6985 if (aggregate->ecommunity)
6986 ecommunity = ecommunity_dup(aggregate->ecommunity);
6987
6988 /* Retrieve aggregate route's lcommunity.
6989 */
6990 if (aggregate->lcommunity)
6991 lcommunity = lcommunity_dup(aggregate->lcommunity);
6992 }
6993
6994 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
6995 aspath, community, ecommunity,
6996 lcommunity, atomic_aggregate, aggregate);
6997 }
6998
6999 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
7000 struct bgp_path_info *pi, afi_t afi, safi_t safi)
7001 {
7002 struct bgp_dest *child;
7003 struct bgp_dest *dest;
7004 struct bgp_aggregate *aggregate;
7005 struct bgp_table *table;
7006
7007 table = bgp->aggregate[afi][safi];
7008
7009 /* No aggregates configured. */
7010 if (bgp_table_top_nolock(table) == NULL)
7011 return;
7012
7013 if (p->prefixlen == 0)
7014 return;
7015
7016 if (BGP_PATH_HOLDDOWN(pi))
7017 return;
7018
7019 child = bgp_node_get(table, p);
7020
7021 /* Aggregate address configuration check. */
7022 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
7023 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7024
7025 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7026 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
7027 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
7028 aggregate);
7029 }
7030 }
7031 bgp_dest_unlock_node(child);
7032 }
7033
7034 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
7035 struct bgp_path_info *del, afi_t afi, safi_t safi)
7036 {
7037 struct bgp_dest *child;
7038 struct bgp_dest *dest;
7039 struct bgp_aggregate *aggregate;
7040 struct bgp_table *table;
7041
7042 table = bgp->aggregate[afi][safi];
7043
7044 /* No aggregates configured. */
7045 if (bgp_table_top_nolock(table) == NULL)
7046 return;
7047
7048 if (p->prefixlen == 0)
7049 return;
7050
7051 child = bgp_node_get(table, p);
7052
7053 /* Aggregate address configuration check. */
7054 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
7055 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7056
7057 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7058 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
7059 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
7060 aggregate, dest_p);
7061 }
7062 }
7063 bgp_dest_unlock_node(child);
7064 }
7065
7066 /* Aggregate route attribute. */
7067 #define AGGREGATE_SUMMARY_ONLY 1
7068 #define AGGREGATE_AS_SET 1
7069 #define AGGREGATE_AS_UNSET 0
7070
7071 static const char *bgp_origin2str(uint8_t origin)
7072 {
7073 switch (origin) {
7074 case BGP_ORIGIN_IGP:
7075 return "igp";
7076 case BGP_ORIGIN_EGP:
7077 return "egp";
7078 case BGP_ORIGIN_INCOMPLETE:
7079 return "incomplete";
7080 }
7081 return "n/a";
7082 }
7083
7084 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
7085 afi_t afi, safi_t safi)
7086 {
7087 VTY_DECLVAR_CONTEXT(bgp, bgp);
7088 int ret;
7089 struct prefix p;
7090 struct bgp_dest *dest;
7091 struct bgp_aggregate *aggregate;
7092
7093 /* Convert string to prefix structure. */
7094 ret = str2prefix(prefix_str, &p);
7095 if (!ret) {
7096 vty_out(vty, "Malformed prefix\n");
7097 return CMD_WARNING_CONFIG_FAILED;
7098 }
7099 apply_mask(&p);
7100
7101 /* Old configuration check. */
7102 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
7103 if (!dest) {
7104 vty_out(vty,
7105 "%% There is no aggregate-address configuration.\n");
7106 return CMD_WARNING_CONFIG_FAILED;
7107 }
7108
7109 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7110 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
7111 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
7112 NULL, NULL, 0, aggregate);
7113
7114 /* Unlock aggregate address configuration. */
7115 bgp_dest_set_bgp_aggregate_info(dest, NULL);
7116
7117 if (aggregate->community)
7118 community_free(&aggregate->community);
7119
7120 if (aggregate->community_hash) {
7121 /* Delete all communities in the hash.
7122 */
7123 hash_clean(aggregate->community_hash,
7124 bgp_aggr_community_remove);
7125 /* Free up the community_hash.
7126 */
7127 hash_free(aggregate->community_hash);
7128 }
7129
7130 if (aggregate->ecommunity)
7131 ecommunity_free(&aggregate->ecommunity);
7132
7133 if (aggregate->ecommunity_hash) {
7134 /* Delete all ecommunities in the hash.
7135 */
7136 hash_clean(aggregate->ecommunity_hash,
7137 bgp_aggr_ecommunity_remove);
7138 /* Free up the ecommunity_hash.
7139 */
7140 hash_free(aggregate->ecommunity_hash);
7141 }
7142
7143 if (aggregate->lcommunity)
7144 lcommunity_free(&aggregate->lcommunity);
7145
7146 if (aggregate->lcommunity_hash) {
7147 /* Delete all lcommunities in the hash.
7148 */
7149 hash_clean(aggregate->lcommunity_hash,
7150 bgp_aggr_lcommunity_remove);
7151 /* Free up the lcommunity_hash.
7152 */
7153 hash_free(aggregate->lcommunity_hash);
7154 }
7155
7156 if (aggregate->aspath)
7157 aspath_free(aggregate->aspath);
7158
7159 if (aggregate->aspath_hash) {
7160 /* Delete all as-paths in the hash.
7161 */
7162 hash_clean(aggregate->aspath_hash,
7163 bgp_aggr_aspath_remove);
7164 /* Free up the aspath_hash.
7165 */
7166 hash_free(aggregate->aspath_hash);
7167 }
7168
7169 bgp_aggregate_free(aggregate);
7170 bgp_dest_unlock_node(dest);
7171 bgp_dest_unlock_node(dest);
7172
7173 return CMD_SUCCESS;
7174 }
7175
7176 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
7177 safi_t safi, const char *rmap,
7178 uint8_t summary_only, uint8_t as_set,
7179 uint8_t origin, bool match_med)
7180 {
7181 VTY_DECLVAR_CONTEXT(bgp, bgp);
7182 int ret;
7183 struct prefix p;
7184 struct bgp_dest *dest;
7185 struct bgp_aggregate *aggregate;
7186 uint8_t as_set_new = as_set;
7187
7188 /* Convert string to prefix structure. */
7189 ret = str2prefix(prefix_str, &p);
7190 if (!ret) {
7191 vty_out(vty, "Malformed prefix\n");
7192 return CMD_WARNING_CONFIG_FAILED;
7193 }
7194 apply_mask(&p);
7195
7196 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
7197 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
7198 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
7199 prefix_str);
7200 return CMD_WARNING_CONFIG_FAILED;
7201 }
7202
7203 /* Old configuration check. */
7204 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
7205 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7206
7207 if (aggregate) {
7208 vty_out(vty, "There is already same aggregate network.\n");
7209 /* try to remove the old entry */
7210 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
7211 if (ret) {
7212 vty_out(vty, "Error deleting aggregate.\n");
7213 bgp_dest_unlock_node(dest);
7214 return CMD_WARNING_CONFIG_FAILED;
7215 }
7216 }
7217
7218 /* Make aggregate address structure. */
7219 aggregate = bgp_aggregate_new();
7220 aggregate->summary_only = summary_only;
7221 aggregate->match_med = match_med;
7222
7223 /* Network operators MUST NOT locally generate any new
7224 * announcements containing AS_SET or AS_CONFED_SET. If they have
7225 * announced routes with AS_SET or AS_CONFED_SET in them, then they
7226 * SHOULD withdraw those routes and re-announce routes for the
7227 * aggregate or component prefixes (i.e., the more-specific routes
7228 * subsumed by the previously aggregated route) without AS_SET
7229 * or AS_CONFED_SET in the updates.
7230 */
7231 if (bgp->reject_as_sets) {
7232 if (as_set == AGGREGATE_AS_SET) {
7233 as_set_new = AGGREGATE_AS_UNSET;
7234 zlog_warn(
7235 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
7236 __func__);
7237 vty_out(vty,
7238 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
7239 }
7240 }
7241
7242 aggregate->as_set = as_set_new;
7243 aggregate->safi = safi;
7244 /* Override ORIGIN attribute if defined.
7245 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
7246 * to IGP which is not what rfc4271 says.
7247 * This enables the same behavior, optionally.
7248 */
7249 aggregate->origin = origin;
7250
7251 if (rmap) {
7252 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7253 route_map_counter_decrement(aggregate->rmap.map);
7254 aggregate->rmap.name =
7255 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
7256 aggregate->rmap.map = route_map_lookup_by_name(rmap);
7257 route_map_counter_increment(aggregate->rmap.map);
7258 }
7259 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
7260
7261 /* Aggregate address insert into BGP routing table. */
7262 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
7263
7264 return CMD_SUCCESS;
7265 }
7266
7267 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
7268 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> {"
7269 "as-set$as_set_s"
7270 "|summary-only$summary_only"
7271 "|route-map WORD$rmap_name"
7272 "|origin <egp|igp|incomplete>$origin_s"
7273 "|matching-MED-only$match_med"
7274 "}",
7275 NO_STR
7276 "Configure BGP aggregate entries\n"
7277 "Aggregate prefix\n" "Aggregate address\n" "Aggregate mask\n"
7278 "Generate AS set path information\n"
7279 "Filter more specific routes from updates\n"
7280 "Apply route map to aggregate network\n"
7281 "Route map name\n"
7282 "BGP origin code\n"
7283 "Remote EGP\n"
7284 "Local IGP\n"
7285 "Unknown heritage\n"
7286 "Only aggregate routes with matching MED\n")
7287 {
7288 const char *prefix_s = NULL;
7289 safi_t safi = bgp_node_safi(vty);
7290 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
7291 int as_set = AGGREGATE_AS_UNSET;
7292 char prefix_buf[PREFIX2STR_BUFFER];
7293
7294 if (addr_str) {
7295 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf)
7296 == 0) {
7297 vty_out(vty, "%% Inconsistent address and mask\n");
7298 return CMD_WARNING_CONFIG_FAILED;
7299 }
7300 prefix_s = prefix_buf;
7301 } else
7302 prefix_s = prefix_str;
7303
7304 if (origin_s) {
7305 if (strcmp(origin_s, "egp") == 0)
7306 origin = BGP_ORIGIN_EGP;
7307 else if (strcmp(origin_s, "igp") == 0)
7308 origin = BGP_ORIGIN_IGP;
7309 else if (strcmp(origin_s, "incomplete") == 0)
7310 origin = BGP_ORIGIN_INCOMPLETE;
7311 }
7312
7313 if (as_set_s)
7314 as_set = AGGREGATE_AS_SET;
7315
7316 /* Handle configuration removal, otherwise installation. */
7317 if (no)
7318 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
7319
7320 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
7321 summary_only != NULL, as_set, origin,
7322 match_med != NULL);
7323 }
7324
7325 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
7326 "[no] aggregate-address X:X::X:X/M$prefix {"
7327 "as-set$as_set_s"
7328 "|summary-only$summary_only"
7329 "|route-map WORD$rmap_name"
7330 "|origin <egp|igp|incomplete>$origin_s"
7331 "|matching-MED-only$match_med"
7332 "}",
7333 NO_STR
7334 "Configure BGP aggregate entries\n"
7335 "Aggregate prefix\n"
7336 "Generate AS set path information\n"
7337 "Filter more specific routes from updates\n"
7338 "Apply route map to aggregate network\n"
7339 "Route map name\n"
7340 "BGP origin code\n"
7341 "Remote EGP\n"
7342 "Local IGP\n"
7343 "Unknown heritage\n"
7344 "Only aggregate routes with matching MED\n")
7345 {
7346 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
7347 int as_set = AGGREGATE_AS_UNSET;
7348
7349 if (origin_s) {
7350 if (strcmp(origin_s, "egp") == 0)
7351 origin = BGP_ORIGIN_EGP;
7352 else if (strcmp(origin_s, "igp") == 0)
7353 origin = BGP_ORIGIN_IGP;
7354 else if (strcmp(origin_s, "incomplete") == 0)
7355 origin = BGP_ORIGIN_INCOMPLETE;
7356 }
7357
7358 if (as_set_s)
7359 as_set = AGGREGATE_AS_SET;
7360
7361 /* Handle configuration removal, otherwise installation. */
7362 if (no)
7363 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
7364 SAFI_UNICAST);
7365
7366 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
7367 rmap_name, summary_only != NULL, as_set,
7368 origin, match_med != NULL);
7369 }
7370
7371 /* Redistribute route treatment. */
7372 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
7373 const union g_addr *nexthop, ifindex_t ifindex,
7374 enum nexthop_types_t nhtype, uint32_t metric,
7375 uint8_t type, unsigned short instance,
7376 route_tag_t tag)
7377 {
7378 struct bgp_path_info *new;
7379 struct bgp_path_info *bpi;
7380 struct bgp_path_info rmap_path;
7381 struct bgp_dest *bn;
7382 struct attr attr;
7383 struct attr *new_attr;
7384 afi_t afi;
7385 route_map_result_t ret;
7386 struct bgp_redist *red;
7387
7388 /* Make default attribute. */
7389 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
7390 /*
7391 * This must not be NULL to satisfy Coverity SA
7392 */
7393 assert(attr.aspath);
7394
7395 switch (nhtype) {
7396 case NEXTHOP_TYPE_IFINDEX:
7397 break;
7398 case NEXTHOP_TYPE_IPV4:
7399 case NEXTHOP_TYPE_IPV4_IFINDEX:
7400 attr.nexthop = nexthop->ipv4;
7401 break;
7402 case NEXTHOP_TYPE_IPV6:
7403 case NEXTHOP_TYPE_IPV6_IFINDEX:
7404 attr.mp_nexthop_global = nexthop->ipv6;
7405 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
7406 break;
7407 case NEXTHOP_TYPE_BLACKHOLE:
7408 switch (p->family) {
7409 case AF_INET:
7410 attr.nexthop.s_addr = INADDR_ANY;
7411 break;
7412 case AF_INET6:
7413 memset(&attr.mp_nexthop_global, 0,
7414 sizeof(attr.mp_nexthop_global));
7415 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
7416 break;
7417 }
7418 break;
7419 }
7420 attr.nh_ifindex = ifindex;
7421
7422 attr.med = metric;
7423 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
7424 attr.tag = tag;
7425
7426 afi = family2afi(p->family);
7427
7428 red = bgp_redist_lookup(bgp, afi, type, instance);
7429 if (red) {
7430 struct attr attr_new;
7431
7432 /* Copy attribute for modification. */
7433 attr_new = attr;
7434
7435 if (red->redist_metric_flag)
7436 attr_new.med = red->redist_metric;
7437
7438 /* Apply route-map. */
7439 if (red->rmap.name) {
7440 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
7441 rmap_path.peer = bgp->peer_self;
7442 rmap_path.attr = &attr_new;
7443
7444 SET_FLAG(bgp->peer_self->rmap_type,
7445 PEER_RMAP_TYPE_REDISTRIBUTE);
7446
7447 ret = route_map_apply(red->rmap.map, p, RMAP_BGP,
7448 &rmap_path);
7449
7450 bgp->peer_self->rmap_type = 0;
7451
7452 if (ret == RMAP_DENYMATCH) {
7453 /* Free uninterned attribute. */
7454 bgp_attr_flush(&attr_new);
7455
7456 /* Unintern original. */
7457 aspath_unintern(&attr.aspath);
7458 bgp_redistribute_delete(bgp, p, type, instance);
7459 return;
7460 }
7461 }
7462
7463 if (bgp_in_graceful_shutdown(bgp))
7464 bgp_attr_add_gshut_community(&attr_new);
7465
7466 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
7467 SAFI_UNICAST, p, NULL);
7468
7469 new_attr = bgp_attr_intern(&attr_new);
7470
7471 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
7472 if (bpi->peer == bgp->peer_self
7473 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
7474 break;
7475
7476 if (bpi) {
7477 /* Ensure the (source route) type is updated. */
7478 bpi->type = type;
7479 if (attrhash_cmp(bpi->attr, new_attr)
7480 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
7481 bgp_attr_unintern(&new_attr);
7482 aspath_unintern(&attr.aspath);
7483 bgp_dest_unlock_node(bn);
7484 return;
7485 } else {
7486 /* The attribute is changed. */
7487 bgp_path_info_set_flag(bn, bpi,
7488 BGP_PATH_ATTR_CHANGED);
7489
7490 /* Rewrite BGP route information. */
7491 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
7492 bgp_path_info_restore(bn, bpi);
7493 else
7494 bgp_aggregate_decrement(
7495 bgp, p, bpi, afi, SAFI_UNICAST);
7496 bgp_attr_unintern(&bpi->attr);
7497 bpi->attr = new_attr;
7498 bpi->uptime = bgp_clock();
7499
7500 /* Process change. */
7501 bgp_aggregate_increment(bgp, p, bpi, afi,
7502 SAFI_UNICAST);
7503 bgp_process(bgp, bn, afi, SAFI_UNICAST);
7504 bgp_dest_unlock_node(bn);
7505 aspath_unintern(&attr.aspath);
7506
7507 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7508 || (bgp->inst_type
7509 == BGP_INSTANCE_TYPE_DEFAULT)) {
7510
7511 vpn_leak_from_vrf_update(
7512 bgp_get_default(), bgp, bpi);
7513 }
7514 return;
7515 }
7516 }
7517
7518 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
7519 bgp->peer_self, new_attr, bn);
7520 SET_FLAG(new->flags, BGP_PATH_VALID);
7521
7522 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
7523 bgp_path_info_add(bn, new);
7524 bgp_dest_unlock_node(bn);
7525 bgp_process(bgp, bn, afi, SAFI_UNICAST);
7526
7527 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7528 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
7529
7530 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
7531 }
7532 }
7533
7534 /* Unintern original. */
7535 aspath_unintern(&attr.aspath);
7536 }
7537
7538 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
7539 unsigned short instance)
7540 {
7541 afi_t afi;
7542 struct bgp_dest *dest;
7543 struct bgp_path_info *pi;
7544 struct bgp_redist *red;
7545
7546 afi = family2afi(p->family);
7547
7548 red = bgp_redist_lookup(bgp, afi, type, instance);
7549 if (red) {
7550 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
7551 SAFI_UNICAST, p, NULL);
7552
7553 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7554 if (pi->peer == bgp->peer_self && pi->type == type)
7555 break;
7556
7557 if (pi) {
7558 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7559 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
7560
7561 vpn_leak_from_vrf_withdraw(bgp_get_default(),
7562 bgp, pi);
7563 }
7564 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
7565 bgp_path_info_delete(dest, pi);
7566 bgp_process(bgp, dest, afi, SAFI_UNICAST);
7567 }
7568 bgp_dest_unlock_node(dest);
7569 }
7570 }
7571
7572 /* Withdraw specified route type's route. */
7573 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
7574 unsigned short instance)
7575 {
7576 struct bgp_dest *dest;
7577 struct bgp_path_info *pi;
7578 struct bgp_table *table;
7579
7580 table = bgp->rib[afi][SAFI_UNICAST];
7581
7582 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
7583 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7584 if (pi->peer == bgp->peer_self && pi->type == type
7585 && pi->instance == instance)
7586 break;
7587
7588 if (pi) {
7589 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7590 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
7591
7592 vpn_leak_from_vrf_withdraw(bgp_get_default(),
7593 bgp, pi);
7594 }
7595 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
7596 pi, afi, SAFI_UNICAST);
7597 bgp_path_info_delete(dest, pi);
7598 bgp_process(bgp, dest, afi, SAFI_UNICAST);
7599 }
7600 }
7601 }
7602
7603 /* Static function to display route. */
7604 static void route_vty_out_route(const struct prefix *p, struct vty *vty,
7605 json_object *json, bool wide)
7606 {
7607 int len = 0;
7608 char buf[BUFSIZ];
7609 char buf2[BUFSIZ];
7610
7611 if (p->family == AF_INET) {
7612 if (!json) {
7613 len = vty_out(
7614 vty, "%s/%d",
7615 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
7616 p->prefixlen);
7617 } else {
7618 json_object_string_add(json, "prefix",
7619 inet_ntop(p->family,
7620 &p->u.prefix, buf,
7621 BUFSIZ));
7622 json_object_int_add(json, "prefixLen", p->prefixlen);
7623 prefix2str(p, buf2, PREFIX_STRLEN);
7624 json_object_string_add(json, "network", buf2);
7625 }
7626 } else if (p->family == AF_ETHERNET) {
7627 prefix2str(p, buf, PREFIX_STRLEN);
7628 len = vty_out(vty, "%s", buf);
7629 } else if (p->family == AF_EVPN) {
7630 if (!json)
7631 len = vty_out(
7632 vty, "%s",
7633 bgp_evpn_route2str((struct prefix_evpn *)p, buf,
7634 BUFSIZ));
7635 else
7636 bgp_evpn_route2json((struct prefix_evpn *)p, json);
7637 } else if (p->family == AF_FLOWSPEC) {
7638 route_vty_out_flowspec(vty, p, NULL,
7639 json ?
7640 NLRI_STRING_FORMAT_JSON_SIMPLE :
7641 NLRI_STRING_FORMAT_MIN, json);
7642 } else {
7643 if (!json)
7644 len = vty_out(
7645 vty, "%s/%d",
7646 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
7647 p->prefixlen);
7648 else {
7649 json_object_string_add(json, "prefix",
7650 inet_ntop(p->family,
7651 &p->u.prefix, buf,
7652 BUFSIZ));
7653 json_object_int_add(json, "prefixLen", p->prefixlen);
7654 prefix2str(p, buf2, PREFIX_STRLEN);
7655 json_object_string_add(json, "network", buf2);
7656 }
7657 }
7658
7659 if (!json) {
7660 len = wide ? (45 - len) : (17 - len);
7661 if (len < 1)
7662 vty_out(vty, "\n%*s", 20, " ");
7663 else
7664 vty_out(vty, "%*s", len, " ");
7665 }
7666 }
7667
7668 enum bgp_display_type {
7669 normal_list,
7670 };
7671
7672 /* Print the short form route status for a bgp_path_info */
7673 static void route_vty_short_status_out(struct vty *vty,
7674 struct bgp_path_info *path,
7675 json_object *json_path)
7676 {
7677 if (json_path) {
7678
7679 /* Route status display. */
7680 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
7681 json_object_boolean_true_add(json_path, "removed");
7682
7683 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
7684 json_object_boolean_true_add(json_path, "stale");
7685
7686 if (path->extra && path->extra->suppress)
7687 json_object_boolean_true_add(json_path, "suppressed");
7688
7689 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
7690 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7691 json_object_boolean_true_add(json_path, "valid");
7692
7693 /* Selected */
7694 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7695 json_object_boolean_true_add(json_path, "history");
7696
7697 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
7698 json_object_boolean_true_add(json_path, "damped");
7699
7700 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
7701 json_object_boolean_true_add(json_path, "bestpath");
7702
7703 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
7704 json_object_boolean_true_add(json_path, "multipath");
7705
7706 /* Internal route. */
7707 if ((path->peer->as)
7708 && (path->peer->as == path->peer->local_as))
7709 json_object_string_add(json_path, "pathFrom",
7710 "internal");
7711 else
7712 json_object_string_add(json_path, "pathFrom",
7713 "external");
7714
7715 return;
7716 }
7717
7718 /* Route status display. */
7719 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
7720 vty_out(vty, "R");
7721 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
7722 vty_out(vty, "S");
7723 else if (path->extra && path->extra->suppress)
7724 vty_out(vty, "s");
7725 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
7726 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7727 vty_out(vty, "*");
7728 else
7729 vty_out(vty, " ");
7730
7731 /* Selected */
7732 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7733 vty_out(vty, "h");
7734 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
7735 vty_out(vty, "d");
7736 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
7737 vty_out(vty, ">");
7738 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
7739 vty_out(vty, "=");
7740 else
7741 vty_out(vty, " ");
7742
7743 /* Internal route. */
7744 if (path->peer && (path->peer->as)
7745 && (path->peer->as == path->peer->local_as))
7746 vty_out(vty, "i");
7747 else
7748 vty_out(vty, " ");
7749 }
7750
7751 static char *bgp_nexthop_hostname(struct peer *peer,
7752 struct bgp_nexthop_cache *bnc)
7753 {
7754 if (peer->hostname
7755 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
7756 return peer->hostname;
7757 return NULL;
7758 }
7759
7760 /* called from terminal list command */
7761 void route_vty_out(struct vty *vty, const struct prefix *p,
7762 struct bgp_path_info *path, int display, safi_t safi,
7763 json_object *json_paths, bool wide)
7764 {
7765 int len;
7766 struct attr *attr = path->attr;
7767 json_object *json_path = NULL;
7768 json_object *json_nexthops = NULL;
7769 json_object *json_nexthop_global = NULL;
7770 json_object *json_nexthop_ll = NULL;
7771 json_object *json_ext_community = NULL;
7772 char vrf_id_str[VRF_NAMSIZ] = {0};
7773 bool nexthop_self =
7774 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
7775 bool nexthop_othervrf = false;
7776 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
7777 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
7778 char *nexthop_hostname =
7779 bgp_nexthop_hostname(path->peer, path->nexthop);
7780 char esi_buf[ESI_STR_LEN];
7781
7782 if (json_paths)
7783 json_path = json_object_new_object();
7784
7785 /* short status lead text */
7786 route_vty_short_status_out(vty, path, json_path);
7787
7788 if (!json_paths) {
7789 /* print prefix and mask */
7790 if (!display)
7791 route_vty_out_route(p, vty, json_path, wide);
7792 else
7793 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
7794 } else {
7795 route_vty_out_route(p, vty, json_path, wide);
7796 }
7797
7798 /*
7799 * If vrf id of nexthop is different from that of prefix,
7800 * set up printable string to append
7801 */
7802 if (path->extra && path->extra->bgp_orig) {
7803 const char *self = "";
7804
7805 if (nexthop_self)
7806 self = "<";
7807
7808 nexthop_othervrf = true;
7809 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
7810
7811 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
7812 snprintf(vrf_id_str, sizeof(vrf_id_str),
7813 "@%s%s", VRFID_NONE_STR, self);
7814 else
7815 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
7816 path->extra->bgp_orig->vrf_id, self);
7817
7818 if (path->extra->bgp_orig->inst_type
7819 != BGP_INSTANCE_TYPE_DEFAULT)
7820
7821 nexthop_vrfname = path->extra->bgp_orig->name;
7822 } else {
7823 const char *self = "";
7824
7825 if (nexthop_self)
7826 self = "<";
7827
7828 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
7829 }
7830
7831 /*
7832 * For ENCAP and EVPN routes, nexthop address family is not
7833 * neccessarily the same as the prefix address family.
7834 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
7835 * EVPN routes are also exchanged with a MP nexthop. Currently,
7836 * this
7837 * is only IPv4, the value will be present in either
7838 * attr->nexthop or
7839 * attr->mp_nexthop_global_in
7840 */
7841 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
7842 char buf[BUFSIZ];
7843 char nexthop[128];
7844 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
7845
7846 switch (af) {
7847 case AF_INET:
7848 snprintf(nexthop, sizeof(nexthop), "%s",
7849 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
7850 BUFSIZ));
7851 break;
7852 case AF_INET6:
7853 snprintf(nexthop, sizeof(nexthop), "%s",
7854 inet_ntop(af, &attr->mp_nexthop_global, buf,
7855 BUFSIZ));
7856 break;
7857 default:
7858 snprintf(nexthop, sizeof(nexthop), "?");
7859 break;
7860 }
7861
7862 if (json_paths) {
7863 json_nexthop_global = json_object_new_object();
7864
7865 json_object_string_add(json_nexthop_global, "ip",
7866 nexthop);
7867
7868 if (path->peer->hostname)
7869 json_object_string_add(json_nexthop_global,
7870 "hostname",
7871 path->peer->hostname);
7872
7873 json_object_string_add(json_nexthop_global, "afi",
7874 (af == AF_INET) ? "ipv4"
7875 : "ipv6");
7876 json_object_boolean_true_add(json_nexthop_global,
7877 "used");
7878 } else {
7879 if (nexthop_hostname)
7880 len = vty_out(vty, "%s(%s)%s", nexthop,
7881 nexthop_hostname, vrf_id_str);
7882 else
7883 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
7884
7885 len = wide ? (41 - len) : (16 - len);
7886 if (len < 1)
7887 vty_out(vty, "\n%*s", 36, " ");
7888 else
7889 vty_out(vty, "%*s", len, " ");
7890 }
7891 } else if (safi == SAFI_EVPN) {
7892 if (json_paths) {
7893 json_nexthop_global = json_object_new_object();
7894
7895 json_object_string_add(json_nexthop_global, "ip",
7896 inet_ntoa(attr->nexthop));
7897
7898 if (path->peer->hostname)
7899 json_object_string_add(json_nexthop_global,
7900 "hostname",
7901 path->peer->hostname);
7902
7903 json_object_string_add(json_nexthop_global, "afi",
7904 "ipv4");
7905 json_object_boolean_true_add(json_nexthop_global,
7906 "used");
7907 } else {
7908 if (nexthop_hostname)
7909 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
7910 nexthop_hostname, vrf_id_str);
7911 else
7912 len = vty_out(vty, "%pI4%s", &attr->nexthop,
7913 vrf_id_str);
7914
7915 len = wide ? (41 - len) : (16 - len);
7916 if (len < 1)
7917 vty_out(vty, "\n%*s", 36, " ");
7918 else
7919 vty_out(vty, "%*s", len, " ");
7920 }
7921 } else if (safi == SAFI_FLOWSPEC) {
7922 if (attr->nexthop.s_addr != INADDR_ANY) {
7923 if (json_paths) {
7924 json_nexthop_global = json_object_new_object();
7925
7926 json_object_string_add(json_nexthop_global,
7927 "afi", "ipv4");
7928 json_object_string_add(
7929 json_nexthop_global, "ip",
7930 inet_ntoa(attr->nexthop));
7931
7932 if (path->peer->hostname)
7933 json_object_string_add(
7934 json_nexthop_global, "hostname",
7935 path->peer->hostname);
7936
7937 json_object_boolean_true_add(
7938 json_nexthop_global,
7939 "used");
7940 } else {
7941 if (nexthop_hostname)
7942 len = vty_out(vty, "%pI4(%s)%s",
7943 &attr->nexthop,
7944 nexthop_hostname,
7945 vrf_id_str);
7946 else
7947 len = vty_out(vty, "%pI4%s",
7948 &attr->nexthop,
7949 vrf_id_str);
7950
7951 len = wide ? (41 - len) : (16 - len);
7952 if (len < 1)
7953 vty_out(vty, "\n%*s", 36, " ");
7954 else
7955 vty_out(vty, "%*s", len, " ");
7956 }
7957 }
7958 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7959 if (json_paths) {
7960 json_nexthop_global = json_object_new_object();
7961
7962 json_object_string_add(json_nexthop_global, "ip",
7963 inet_ntoa(attr->nexthop));
7964
7965 if (path->peer->hostname)
7966 json_object_string_add(json_nexthop_global,
7967 "hostname",
7968 path->peer->hostname);
7969
7970 json_object_string_add(json_nexthop_global, "afi",
7971 "ipv4");
7972 json_object_boolean_true_add(json_nexthop_global,
7973 "used");
7974 } else {
7975 if (nexthop_hostname)
7976 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
7977 nexthop_hostname, vrf_id_str);
7978 else
7979 len = vty_out(vty, "%pI4%s", &attr->nexthop,
7980 vrf_id_str);
7981
7982 len = wide ? (41 - len) : (16 - len);
7983 if (len < 1)
7984 vty_out(vty, "\n%*s", 36, " ");
7985 else
7986 vty_out(vty, "%*s", len, " ");
7987 }
7988 }
7989
7990 /* IPv6 Next Hop */
7991 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7992 char buf[BUFSIZ];
7993
7994 if (json_paths) {
7995 json_nexthop_global = json_object_new_object();
7996 json_object_string_add(
7997 json_nexthop_global, "ip",
7998 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
7999 buf, BUFSIZ));
8000
8001 if (path->peer->hostname)
8002 json_object_string_add(json_nexthop_global,
8003 "hostname",
8004 path->peer->hostname);
8005
8006 json_object_string_add(json_nexthop_global, "afi",
8007 "ipv6");
8008 json_object_string_add(json_nexthop_global, "scope",
8009 "global");
8010
8011 /* We display both LL & GL if both have been
8012 * received */
8013 if ((attr->mp_nexthop_len
8014 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
8015 || (path->peer->conf_if)) {
8016 json_nexthop_ll = json_object_new_object();
8017 json_object_string_add(
8018 json_nexthop_ll, "ip",
8019 inet_ntop(AF_INET6,
8020 &attr->mp_nexthop_local, buf,
8021 BUFSIZ));
8022
8023 if (path->peer->hostname)
8024 json_object_string_add(
8025 json_nexthop_ll, "hostname",
8026 path->peer->hostname);
8027
8028 json_object_string_add(json_nexthop_ll, "afi",
8029 "ipv6");
8030 json_object_string_add(json_nexthop_ll, "scope",
8031 "link-local");
8032
8033 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
8034 &attr->mp_nexthop_local)
8035 != 0)
8036 && !attr->mp_nexthop_prefer_global)
8037 json_object_boolean_true_add(
8038 json_nexthop_ll, "used");
8039 else
8040 json_object_boolean_true_add(
8041 json_nexthop_global, "used");
8042 } else
8043 json_object_boolean_true_add(
8044 json_nexthop_global, "used");
8045 } else {
8046 /* Display LL if LL/Global both in table unless
8047 * prefer-global is set */
8048 if (((attr->mp_nexthop_len
8049 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
8050 && !attr->mp_nexthop_prefer_global)
8051 || (path->peer->conf_if)) {
8052 if (path->peer->conf_if) {
8053 len = vty_out(vty, "%s",
8054 path->peer->conf_if);
8055 /* len of IPv6 addr + max len of def
8056 * ifname */
8057 len = wide ? (41 - len) : (16 - len);
8058
8059 if (len < 1)
8060 vty_out(vty, "\n%*s", 36, " ");
8061 else
8062 vty_out(vty, "%*s", len, " ");
8063 } else {
8064 if (nexthop_hostname)
8065 len = vty_out(
8066 vty, "%pI6(%s)%s",
8067 &attr->mp_nexthop_local,
8068 nexthop_hostname,
8069 vrf_id_str);
8070 else
8071 len = vty_out(
8072 vty, "%pI6%s",
8073 &attr->mp_nexthop_local,
8074 vrf_id_str);
8075
8076 len = wide ? (41 - len) : (16 - len);
8077
8078 if (len < 1)
8079 vty_out(vty, "\n%*s", 36, " ");
8080 else
8081 vty_out(vty, "%*s", len, " ");
8082 }
8083 } else {
8084 if (nexthop_hostname)
8085 len = vty_out(vty, "%pI6(%s)%s",
8086 &attr->mp_nexthop_global,
8087 nexthop_hostname,
8088 vrf_id_str);
8089 else
8090 len = vty_out(vty, "%pI6%s",
8091 &attr->mp_nexthop_global,
8092 vrf_id_str);
8093
8094 len = wide ? (41 - len) : (16 - len);
8095
8096 if (len < 1)
8097 vty_out(vty, "\n%*s", 36, " ");
8098 else
8099 vty_out(vty, "%*s", len, " ");
8100 }
8101 }
8102 }
8103
8104 /* MED/Metric */
8105 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
8106 if (json_paths)
8107 json_object_int_add(json_path, "metric", attr->med);
8108 else if (wide)
8109 vty_out(vty, "%7u", attr->med);
8110 else
8111 vty_out(vty, "%10u", attr->med);
8112 else if (!json_paths) {
8113 if (wide)
8114 vty_out(vty, "%*s", 7, " ");
8115 else
8116 vty_out(vty, "%*s", 10, " ");
8117 }
8118
8119 /* Local Pref */
8120 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
8121 if (json_paths)
8122 json_object_int_add(json_path, "locPrf",
8123 attr->local_pref);
8124 else
8125 vty_out(vty, "%7u", attr->local_pref);
8126 else if (!json_paths)
8127 vty_out(vty, " ");
8128
8129 if (json_paths)
8130 json_object_int_add(json_path, "weight", attr->weight);
8131 else
8132 vty_out(vty, "%7u ", attr->weight);
8133
8134 if (json_paths) {
8135 char buf[BUFSIZ];
8136 json_object_string_add(
8137 json_path, "peerId",
8138 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
8139 }
8140
8141 /* Print aspath */
8142 if (attr->aspath) {
8143 if (json_paths)
8144 json_object_string_add(json_path, "path",
8145 attr->aspath->str);
8146 else
8147 aspath_print_vty(vty, "%s", attr->aspath, " ");
8148 }
8149
8150 /* Print origin */
8151 if (json_paths)
8152 json_object_string_add(json_path, "origin",
8153 bgp_origin_long_str[attr->origin]);
8154 else
8155 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8156
8157 if (json_paths) {
8158 if (bgp_evpn_is_esi_valid(&attr->esi)) {
8159 json_object_string_add(json_path, "esi",
8160 esi_to_str(&attr->esi,
8161 esi_buf, sizeof(esi_buf)));
8162 }
8163 if (safi == SAFI_EVPN &&
8164 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8165 json_ext_community = json_object_new_object();
8166 json_object_string_add(json_ext_community,
8167 "string",
8168 attr->ecommunity->str);
8169 json_object_object_add(json_path,
8170 "extendedCommunity",
8171 json_ext_community);
8172 }
8173
8174 if (nexthop_self)
8175 json_object_boolean_true_add(json_path,
8176 "announceNexthopSelf");
8177 if (nexthop_othervrf) {
8178 json_object_string_add(json_path, "nhVrfName",
8179 nexthop_vrfname);
8180
8181 json_object_int_add(json_path, "nhVrfId",
8182 ((nexthop_vrfid == VRF_UNKNOWN)
8183 ? -1
8184 : (int)nexthop_vrfid));
8185 }
8186 }
8187
8188 if (json_paths) {
8189 if (json_nexthop_global || json_nexthop_ll) {
8190 json_nexthops = json_object_new_array();
8191
8192 if (json_nexthop_global)
8193 json_object_array_add(json_nexthops,
8194 json_nexthop_global);
8195
8196 if (json_nexthop_ll)
8197 json_object_array_add(json_nexthops,
8198 json_nexthop_ll);
8199
8200 json_object_object_add(json_path, "nexthops",
8201 json_nexthops);
8202 }
8203
8204 json_object_array_add(json_paths, json_path);
8205 } else {
8206 vty_out(vty, "\n");
8207
8208 if (safi == SAFI_EVPN) {
8209 if (bgp_evpn_is_esi_valid(&attr->esi)) {
8210 vty_out(vty, "%*s", 20, " ");
8211 vty_out(vty, "ESI:%s\n",
8212 esi_to_str(&attr->esi,
8213 esi_buf, sizeof(esi_buf)));
8214 }
8215 if (attr->flag &
8216 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8217 vty_out(vty, "%*s", 20, " ");
8218 vty_out(vty, "%s\n", attr->ecommunity->str);
8219 }
8220 }
8221
8222 #ifdef ENABLE_BGP_VNC
8223 /* prints an additional line, indented, with VNC info, if
8224 * present */
8225 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
8226 rfapi_vty_out_vncinfo(vty, p, path, safi);
8227 #endif
8228 }
8229 }
8230
8231 /* called from terminal list command */
8232 void route_vty_out_tmp(struct vty *vty, const struct prefix *p,
8233 struct attr *attr, safi_t safi, bool use_json,
8234 json_object *json_ar, bool wide)
8235 {
8236 json_object *json_status = NULL;
8237 json_object *json_net = NULL;
8238 int len;
8239 char buff[BUFSIZ];
8240
8241 /* Route status display. */
8242 if (use_json) {
8243 json_status = json_object_new_object();
8244 json_net = json_object_new_object();
8245 } else {
8246 vty_out(vty, "*");
8247 vty_out(vty, ">");
8248 vty_out(vty, " ");
8249 }
8250
8251 /* print prefix and mask */
8252 if (use_json) {
8253 if (safi == SAFI_EVPN)
8254 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
8255 else if (p->family == AF_INET || p->family == AF_INET6) {
8256 json_object_string_add(
8257 json_net, "addrPrefix",
8258 inet_ntop(p->family, &p->u.prefix, buff,
8259 BUFSIZ));
8260 json_object_int_add(json_net, "prefixLen",
8261 p->prefixlen);
8262 prefix2str(p, buff, PREFIX_STRLEN);
8263 json_object_string_add(json_net, "network", buff);
8264 }
8265 } else
8266 route_vty_out_route(p, vty, NULL, wide);
8267
8268 /* Print attribute */
8269 if (attr) {
8270 if (use_json) {
8271 if (p->family == AF_INET
8272 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8273 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8274 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
8275 json_object_string_add(
8276 json_net, "nextHop",
8277 inet_ntoa(
8278 attr->mp_nexthop_global_in));
8279 else
8280 json_object_string_add(
8281 json_net, "nextHop",
8282 inet_ntoa(attr->nexthop));
8283 } else if (p->family == AF_INET6
8284 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8285 char buf[BUFSIZ];
8286
8287 json_object_string_add(
8288 json_net, "nextHopGlobal",
8289 inet_ntop(AF_INET6,
8290 &attr->mp_nexthop_global, buf,
8291 BUFSIZ));
8292 } else if (p->family == AF_EVPN &&
8293 !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
8294 json_object_string_add(json_net,
8295 "nextHop", inet_ntoa(
8296 attr->mp_nexthop_global_in));
8297
8298 if (attr->flag
8299 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
8300 json_object_int_add(json_net, "metric",
8301 attr->med);
8302
8303 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
8304 json_object_int_add(json_net, "locPrf",
8305 attr->local_pref);
8306
8307 json_object_int_add(json_net, "weight", attr->weight);
8308
8309 /* Print aspath */
8310 if (attr->aspath)
8311 json_object_string_add(json_net, "path",
8312 attr->aspath->str);
8313
8314 /* Print origin */
8315 json_object_string_add(json_net, "bgpOriginCode",
8316 bgp_origin_str[attr->origin]);
8317 } else {
8318 if (p->family == AF_INET
8319 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8320 || safi == SAFI_EVPN
8321 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8322 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8323 || safi == SAFI_EVPN)
8324 vty_out(vty, "%-16s",
8325 inet_ntoa(
8326 attr->mp_nexthop_global_in));
8327 else if (wide)
8328 vty_out(vty, "%-41s",
8329 inet_ntoa(attr->nexthop));
8330 else
8331 vty_out(vty, "%-16s",
8332 inet_ntoa(attr->nexthop));
8333 } else if (p->family == AF_INET6
8334 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8335 char buf[BUFSIZ];
8336
8337 len = vty_out(
8338 vty, "%s",
8339 inet_ntop(AF_INET6,
8340 &attr->mp_nexthop_global, buf,
8341 BUFSIZ));
8342 len = wide ? (41 - len) : (16 - len);
8343 if (len < 1)
8344 vty_out(vty, "\n%*s", 36, " ");
8345 else
8346 vty_out(vty, "%*s", len, " ");
8347 }
8348 if (attr->flag
8349 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
8350 if (wide)
8351 vty_out(vty, "%7u", attr->med);
8352 else
8353 vty_out(vty, "%10u", attr->med);
8354 else if (wide)
8355 vty_out(vty, " ");
8356 else
8357 vty_out(vty, " ");
8358
8359 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
8360 vty_out(vty, "%7u", attr->local_pref);
8361 else
8362 vty_out(vty, " ");
8363
8364 vty_out(vty, "%7u ", attr->weight);
8365
8366 /* Print aspath */
8367 if (attr->aspath)
8368 aspath_print_vty(vty, "%s", attr->aspath, " ");
8369
8370 /* Print origin */
8371 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8372 }
8373 }
8374 if (use_json) {
8375 json_object_boolean_true_add(json_status, "*");
8376 json_object_boolean_true_add(json_status, ">");
8377 json_object_object_add(json_net, "appliedStatusSymbols",
8378 json_status);
8379
8380 prefix2str(p, buff, PREFIX_STRLEN);
8381 json_object_object_add(json_ar, buff, json_net);
8382 } else
8383 vty_out(vty, "\n");
8384 }
8385
8386 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
8387 struct bgp_path_info *path, int display, safi_t safi,
8388 json_object *json)
8389 {
8390 json_object *json_out = NULL;
8391 struct attr *attr;
8392 mpls_label_t label = MPLS_INVALID_LABEL;
8393
8394 if (!path->extra)
8395 return;
8396
8397 if (json)
8398 json_out = json_object_new_object();
8399
8400 /* short status lead text */
8401 route_vty_short_status_out(vty, path, json_out);
8402
8403 /* print prefix and mask */
8404 if (json == NULL) {
8405 if (!display)
8406 route_vty_out_route(p, vty, NULL, false);
8407 else
8408 vty_out(vty, "%*s", 17, " ");
8409 }
8410
8411 /* Print attribute */
8412 attr = path->attr;
8413 if (((p->family == AF_INET)
8414 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
8415 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
8416 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8417 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8418 || safi == SAFI_EVPN) {
8419 if (json)
8420 json_object_string_add(
8421 json_out, "mpNexthopGlobalIn",
8422 inet_ntoa(attr->mp_nexthop_global_in));
8423 else
8424 vty_out(vty, "%-16s",
8425 inet_ntoa(attr->mp_nexthop_global_in));
8426 } else {
8427 if (json)
8428 json_object_string_add(
8429 json_out, "nexthop",
8430 inet_ntoa(attr->nexthop));
8431 else
8432 vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
8433 }
8434 } else if (((p->family == AF_INET6)
8435 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
8436 || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
8437 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8438 char buf_a[512];
8439
8440 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
8441 if (json)
8442 json_object_string_add(
8443 json_out, "mpNexthopGlobalIn",
8444 inet_ntop(AF_INET6,
8445 &attr->mp_nexthop_global,
8446 buf_a, sizeof(buf_a)));
8447 else
8448 vty_out(vty, "%s",
8449 inet_ntop(AF_INET6,
8450 &attr->mp_nexthop_global,
8451 buf_a, sizeof(buf_a)));
8452 } else if (attr->mp_nexthop_len
8453 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
8454 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
8455 &attr->mp_nexthop_global,
8456 &attr->mp_nexthop_local);
8457 if (json)
8458 json_object_string_add(json_out,
8459 "mpNexthopGlobalLocal",
8460 buf_a);
8461 else
8462 vty_out(vty, "%s", buf_a);
8463 }
8464 }
8465
8466 label = decode_label(&path->extra->label[0]);
8467
8468 if (bgp_is_valid_label(&label)) {
8469 if (json) {
8470 json_object_int_add(json_out, "notag", label);
8471 json_object_array_add(json, json_out);
8472 } else {
8473 vty_out(vty, "notag/%d", label);
8474 vty_out(vty, "\n");
8475 }
8476 }
8477 }
8478
8479 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
8480 struct bgp_path_info *path, int display,
8481 json_object *json_paths)
8482 {
8483 struct attr *attr;
8484 char buf[BUFSIZ] = {0};
8485 json_object *json_path = NULL;
8486 json_object *json_nexthop = NULL;
8487 json_object *json_overlay = NULL;
8488
8489 if (!path->extra)
8490 return;
8491
8492 if (json_paths) {
8493 json_path = json_object_new_object();
8494 json_overlay = json_object_new_object();
8495 json_nexthop = json_object_new_object();
8496 }
8497
8498 /* short status lead text */
8499 route_vty_short_status_out(vty, path, json_path);
8500
8501 /* print prefix and mask */
8502 if (!display)
8503 route_vty_out_route(p, vty, json_path, false);
8504 else
8505 vty_out(vty, "%*s", 17, " ");
8506
8507 /* Print attribute */
8508 attr = path->attr;
8509 char buf1[BUFSIZ];
8510 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
8511
8512 switch (af) {
8513 case AF_INET:
8514 inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ);
8515 if (!json_path) {
8516 vty_out(vty, "%-16s", buf);
8517 } else {
8518 json_object_string_add(json_nexthop, "ip", buf);
8519
8520 json_object_string_add(json_nexthop, "afi", "ipv4");
8521
8522 json_object_object_add(json_path, "nexthop",
8523 json_nexthop);
8524 }
8525 break;
8526 case AF_INET6:
8527 inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ);
8528 inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ);
8529 if (!json_path) {
8530 vty_out(vty, "%s(%s)", buf, buf1);
8531 } else {
8532 json_object_string_add(json_nexthop, "ipv6Global", buf);
8533
8534 json_object_string_add(json_nexthop, "ipv6LinkLocal",
8535 buf1);
8536
8537 json_object_string_add(json_nexthop, "afi", "ipv6");
8538
8539 json_object_object_add(json_path, "nexthop",
8540 json_nexthop);
8541 }
8542 break;
8543 default:
8544 if (!json_path) {
8545 vty_out(vty, "?");
8546 } else {
8547 json_object_string_add(json_nexthop, "Error",
8548 "Unsupported address-family");
8549 }
8550 }
8551
8552 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) {
8553 inet_ntop(AF_INET, &(attr->evpn_overlay.gw_ip.ipv4), buf,
8554 BUFSIZ);
8555 } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) {
8556 inet_ntop(AF_INET6, &(attr->evpn_overlay.gw_ip.ipv6), buf,
8557 BUFSIZ);
8558 }
8559
8560 if (!json_path)
8561 vty_out(vty, "/%s", buf);
8562 else
8563 json_object_string_add(json_overlay, "gw", buf);
8564
8565 if (attr->ecommunity) {
8566 char *mac = NULL;
8567 struct ecommunity_val *routermac = ecommunity_lookup(
8568 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
8569 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
8570
8571 if (routermac)
8572 mac = ecom_mac2str((char *)routermac->val);
8573 if (mac) {
8574 if (!json_path) {
8575 vty_out(vty, "/%s", mac);
8576 } else {
8577 json_object_string_add(json_overlay, "rmac",
8578 mac);
8579 }
8580 XFREE(MTYPE_TMP, mac);
8581 }
8582 }
8583
8584 if (!json_path) {
8585 vty_out(vty, "\n");
8586 } else {
8587 json_object_object_add(json_path, "overlay", json_overlay);
8588
8589 json_object_array_add(json_paths, json_path);
8590 }
8591 }
8592
8593 /* dampening route */
8594 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
8595 struct bgp_path_info *path, int display,
8596 afi_t afi, safi_t safi, bool use_json,
8597 json_object *json)
8598 {
8599 struct attr *attr;
8600 int len;
8601 char timebuf[BGP_UPTIME_LEN];
8602
8603 /* short status lead text */
8604 route_vty_short_status_out(vty, path, json);
8605
8606 /* print prefix and mask */
8607 if (!use_json) {
8608 if (!display)
8609 route_vty_out_route(p, vty, NULL, false);
8610 else
8611 vty_out(vty, "%*s", 17, " ");
8612 }
8613
8614 len = vty_out(vty, "%s", path->peer->host);
8615 len = 17 - len;
8616 if (len < 1) {
8617 if (!use_json)
8618 vty_out(vty, "\n%*s", 34, " ");
8619 } else {
8620 if (use_json)
8621 json_object_int_add(json, "peerHost", len);
8622 else
8623 vty_out(vty, "%*s", len, " ");
8624 }
8625
8626 if (use_json)
8627 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
8628 safi, use_json, json);
8629 else
8630 vty_out(vty, "%s ",
8631 bgp_damp_reuse_time_vty(vty, path, timebuf,
8632 BGP_UPTIME_LEN, afi, safi,
8633 use_json, json));
8634
8635 /* Print attribute */
8636 attr = path->attr;
8637
8638 /* Print aspath */
8639 if (attr->aspath) {
8640 if (use_json)
8641 json_object_string_add(json, "asPath",
8642 attr->aspath->str);
8643 else
8644 aspath_print_vty(vty, "%s", attr->aspath, " ");
8645 }
8646
8647 /* Print origin */
8648 if (use_json)
8649 json_object_string_add(json, "origin",
8650 bgp_origin_str[attr->origin]);
8651 else
8652 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8653
8654 if (!use_json)
8655 vty_out(vty, "\n");
8656 }
8657
8658 /* flap route */
8659 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
8660 struct bgp_path_info *path, int display,
8661 afi_t afi, safi_t safi, bool use_json,
8662 json_object *json)
8663 {
8664 struct attr *attr;
8665 struct bgp_damp_info *bdi;
8666 char timebuf[BGP_UPTIME_LEN];
8667 int len;
8668
8669 if (!path->extra)
8670 return;
8671
8672 bdi = path->extra->damp_info;
8673
8674 /* short status lead text */
8675 route_vty_short_status_out(vty, path, json);
8676
8677 /* print prefix and mask */
8678 if (!use_json) {
8679 if (!display)
8680 route_vty_out_route(p, vty, NULL, false);
8681 else
8682 vty_out(vty, "%*s", 17, " ");
8683 }
8684
8685 len = vty_out(vty, "%s", path->peer->host);
8686 len = 16 - len;
8687 if (len < 1) {
8688 if (!use_json)
8689 vty_out(vty, "\n%*s", 33, " ");
8690 } else {
8691 if (use_json)
8692 json_object_int_add(json, "peerHost", len);
8693 else
8694 vty_out(vty, "%*s", len, " ");
8695 }
8696
8697 len = vty_out(vty, "%d", bdi->flap);
8698 len = 5 - len;
8699 if (len < 1) {
8700 if (!use_json)
8701 vty_out(vty, " ");
8702 } else {
8703 if (use_json)
8704 json_object_int_add(json, "bdiFlap", len);
8705 else
8706 vty_out(vty, "%*s", len, " ");
8707 }
8708
8709 if (use_json)
8710 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
8711 json);
8712 else
8713 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
8714 BGP_UPTIME_LEN, 0, NULL));
8715
8716 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
8717 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8718 if (use_json)
8719 bgp_damp_reuse_time_vty(vty, path, timebuf,
8720 BGP_UPTIME_LEN, afi, safi,
8721 use_json, json);
8722 else
8723 vty_out(vty, "%s ",
8724 bgp_damp_reuse_time_vty(vty, path, timebuf,
8725 BGP_UPTIME_LEN, afi,
8726 safi, use_json, json));
8727 } else {
8728 if (!use_json)
8729 vty_out(vty, "%*s ", 8, " ");
8730 }
8731
8732 /* Print attribute */
8733 attr = path->attr;
8734
8735 /* Print aspath */
8736 if (attr->aspath) {
8737 if (use_json)
8738 json_object_string_add(json, "asPath",
8739 attr->aspath->str);
8740 else
8741 aspath_print_vty(vty, "%s", attr->aspath, " ");
8742 }
8743
8744 /* Print origin */
8745 if (use_json)
8746 json_object_string_add(json, "origin",
8747 bgp_origin_str[attr->origin]);
8748 else
8749 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8750
8751 if (!use_json)
8752 vty_out(vty, "\n");
8753 }
8754
8755 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
8756 int *first, const char *header,
8757 json_object *json_adv_to)
8758 {
8759 char buf1[INET6_ADDRSTRLEN];
8760 json_object *json_peer = NULL;
8761
8762 if (json_adv_to) {
8763 /* 'advertised-to' is a dictionary of peers we have advertised
8764 * this
8765 * prefix too. The key is the peer's IP or swpX, the value is
8766 * the
8767 * hostname if we know it and "" if not.
8768 */
8769 json_peer = json_object_new_object();
8770
8771 if (peer->hostname)
8772 json_object_string_add(json_peer, "hostname",
8773 peer->hostname);
8774
8775 if (peer->conf_if)
8776 json_object_object_add(json_adv_to, peer->conf_if,
8777 json_peer);
8778 else
8779 json_object_object_add(
8780 json_adv_to,
8781 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
8782 json_peer);
8783 } else {
8784 if (*first) {
8785 vty_out(vty, "%s", header);
8786 *first = 0;
8787 }
8788
8789 if (peer->hostname
8790 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
8791 if (peer->conf_if)
8792 vty_out(vty, " %s(%s)", peer->hostname,
8793 peer->conf_if);
8794 else
8795 vty_out(vty, " %s(%s)", peer->hostname,
8796 sockunion2str(&peer->su, buf1,
8797 SU_ADDRSTRLEN));
8798 } else {
8799 if (peer->conf_if)
8800 vty_out(vty, " %s", peer->conf_if);
8801 else
8802 vty_out(vty, " %s",
8803 sockunion2str(&peer->su, buf1,
8804 SU_ADDRSTRLEN));
8805 }
8806 }
8807 }
8808
8809 static void route_vty_out_tx_ids(struct vty *vty,
8810 struct bgp_addpath_info_data *d)
8811 {
8812 int i;
8813
8814 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
8815 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
8816 d->addpath_tx_id[i],
8817 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
8818 }
8819 }
8820
8821 static const char *bgp_path_selection_reason2str(
8822 enum bgp_path_selection_reason reason)
8823 {
8824 switch (reason) {
8825 case bgp_path_selection_none:
8826 return "Nothing to Select";
8827 case bgp_path_selection_first:
8828 return "First path received";
8829 case bgp_path_selection_evpn_sticky_mac:
8830 return "EVPN Sticky Mac";
8831 case bgp_path_selection_evpn_seq:
8832 return "EVPN sequence number";
8833 case bgp_path_selection_evpn_lower_ip:
8834 return "EVPN lower IP";
8835 case bgp_path_selection_evpn_local_path:
8836 return "EVPN local ES path";
8837 case bgp_path_selection_evpn_non_proxy:
8838 return "EVPN non proxy";
8839 case bgp_path_selection_weight:
8840 return "Weight";
8841 case bgp_path_selection_local_pref:
8842 return "Local Pref";
8843 case bgp_path_selection_local_route:
8844 return "Local Route";
8845 case bgp_path_selection_confed_as_path:
8846 return "Confederation based AS Path";
8847 case bgp_path_selection_as_path:
8848 return "AS Path";
8849 case bgp_path_selection_origin:
8850 return "Origin";
8851 case bgp_path_selection_med:
8852 return "MED";
8853 case bgp_path_selection_peer:
8854 return "Peer Type";
8855 case bgp_path_selection_confed:
8856 return "Confed Peer Type";
8857 case bgp_path_selection_igp_metric:
8858 return "IGP Metric";
8859 case bgp_path_selection_older:
8860 return "Older Path";
8861 case bgp_path_selection_router_id:
8862 return "Router ID";
8863 case bgp_path_selection_cluster_length:
8864 return "Cluser length";
8865 case bgp_path_selection_stale:
8866 return "Path Staleness";
8867 case bgp_path_selection_local_configured:
8868 return "Locally configured route";
8869 case bgp_path_selection_neighbor_ip:
8870 return "Neighbor IP";
8871 case bgp_path_selection_default:
8872 return "Nothing left to compare";
8873 }
8874 return "Invalid (internal error)";
8875 }
8876
8877 static void route_vty_out_detail_es_info(struct vty *vty,
8878 struct attr *attr, json_object *json_path)
8879 {
8880 char esi_buf[ESI_STR_LEN];
8881 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
8882 bool peer_router = !!CHECK_FLAG(attr->es_flags,
8883 ATTR_ES_PEER_ROUTER);
8884 bool peer_active = !!CHECK_FLAG(attr->es_flags,
8885 ATTR_ES_PEER_ACTIVE);
8886 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
8887 ATTR_ES_PEER_PROXY);
8888
8889 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
8890 if (json_path) {
8891 json_object *json_es_info = NULL;
8892
8893 json_object_string_add(
8894 json_path, "esi",
8895 esi_buf);
8896 if (es_local || bgp_evpn_attr_is_sync(attr)) {
8897 json_es_info = json_object_new_object();
8898 if (es_local)
8899 json_object_boolean_true_add(
8900 json_es_info, "localEs");
8901 if (peer_active)
8902 json_object_boolean_true_add(
8903 json_es_info, "peerActive");
8904 if (peer_proxy)
8905 json_object_boolean_true_add(
8906 json_es_info, "peerProxy");
8907 if (peer_router)
8908 json_object_boolean_true_add(
8909 json_es_info, "peerRouter");
8910 if (attr->mm_sync_seqnum)
8911 json_object_int_add(
8912 json_es_info, "peerSeq",
8913 attr->mm_sync_seqnum);
8914 json_object_object_add(
8915 json_path, "es_info",
8916 json_es_info);
8917 }
8918 } else {
8919 if (bgp_evpn_attr_is_sync(attr))
8920 vty_out(vty,
8921 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
8922 esi_buf,
8923 es_local ? "local-es":"",
8924 peer_proxy ? "proxy " : "",
8925 peer_active ? "active ":"",
8926 peer_router ? "router ":"",
8927 attr->mm_sync_seqnum);
8928 else
8929 vty_out(vty, " ESI %s %s\n",
8930 esi_buf,
8931 es_local ? "local-es":"");
8932 }
8933 }
8934
8935 void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
8936 struct bgp_dest *bn, struct bgp_path_info *path,
8937 afi_t afi, safi_t safi, json_object *json_paths)
8938 {
8939 char buf[INET6_ADDRSTRLEN];
8940 char buf1[BUFSIZ];
8941 char buf2[EVPN_ROUTE_STRLEN];
8942 struct attr *attr = path->attr;
8943 int sockunion_vty_out(struct vty *, union sockunion *);
8944 time_t tbuf;
8945 json_object *json_bestpath = NULL;
8946 json_object *json_cluster_list = NULL;
8947 json_object *json_cluster_list_list = NULL;
8948 json_object *json_ext_community = NULL;
8949 json_object *json_last_update = NULL;
8950 json_object *json_pmsi = NULL;
8951 json_object *json_nexthop_global = NULL;
8952 json_object *json_nexthop_ll = NULL;
8953 json_object *json_nexthops = NULL;
8954 json_object *json_path = NULL;
8955 json_object *json_peer = NULL;
8956 json_object *json_string = NULL;
8957 json_object *json_adv_to = NULL;
8958 int first = 0;
8959 struct listnode *node, *nnode;
8960 struct peer *peer;
8961 int addpath_capable;
8962 int has_adj;
8963 unsigned int first_as;
8964 bool nexthop_self =
8965 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8966 int i;
8967 char *nexthop_hostname =
8968 bgp_nexthop_hostname(path->peer, path->nexthop);
8969
8970 if (json_paths) {
8971 json_path = json_object_new_object();
8972 json_peer = json_object_new_object();
8973 json_nexthop_global = json_object_new_object();
8974 }
8975
8976 if (path->extra) {
8977 char tag_buf[30];
8978
8979 buf2[0] = '\0';
8980 tag_buf[0] = '\0';
8981 if (path->extra && path->extra->num_labels) {
8982 bgp_evpn_label2str(path->extra->label,
8983 path->extra->num_labels, tag_buf,
8984 sizeof(tag_buf));
8985 }
8986 if (safi == SAFI_EVPN) {
8987 if (!json_paths) {
8988 bgp_evpn_route2str(
8989 (struct prefix_evpn *)
8990 bgp_dest_get_prefix(bn),
8991 buf2, sizeof(buf2));
8992 vty_out(vty, " Route %s", buf2);
8993 if (tag_buf[0] != '\0')
8994 vty_out(vty, " VNI %s", tag_buf);
8995 vty_out(vty, "\n");
8996 } else {
8997 if (tag_buf[0])
8998 json_object_string_add(json_path, "VNI",
8999 tag_buf);
9000 }
9001 }
9002
9003 if (path->extra && path->extra->parent && !json_paths) {
9004 struct bgp_path_info *parent_ri;
9005 struct bgp_dest *dest, *pdest;
9006
9007 parent_ri = (struct bgp_path_info *)path->extra->parent;
9008 dest = parent_ri->net;
9009 if (dest && dest->pdest) {
9010 pdest = dest->pdest;
9011 prefix_rd2str(
9012 (struct prefix_rd *)bgp_dest_get_prefix(
9013 pdest),
9014 buf1, sizeof(buf1));
9015 if (is_pi_family_evpn(parent_ri)) {
9016 bgp_evpn_route2str(
9017 (struct prefix_evpn *)
9018 bgp_dest_get_prefix(
9019 dest),
9020 buf2, sizeof(buf2));
9021 vty_out(vty, " Imported from %s:%s, VNI %s\n", buf1, buf2, tag_buf);
9022 } else
9023 vty_out(vty, " Imported from %s:%s\n", buf1, buf2);
9024 }
9025 }
9026 }
9027
9028 /* Line1 display AS-path, Aggregator */
9029 if (attr->aspath) {
9030 if (json_paths) {
9031 if (!attr->aspath->json)
9032 aspath_str_update(attr->aspath, true);
9033 json_object_lock(attr->aspath->json);
9034 json_object_object_add(json_path, "aspath",
9035 attr->aspath->json);
9036 } else {
9037 if (attr->aspath->segments)
9038 aspath_print_vty(vty, " %s", attr->aspath, "");
9039 else
9040 vty_out(vty, " Local");
9041 }
9042 }
9043
9044 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
9045 if (json_paths)
9046 json_object_boolean_true_add(json_path, "removed");
9047 else
9048 vty_out(vty, ", (removed)");
9049 }
9050
9051 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
9052 if (json_paths)
9053 json_object_boolean_true_add(json_path, "stale");
9054 else
9055 vty_out(vty, ", (stale)");
9056 }
9057
9058 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
9059 if (json_paths) {
9060 json_object_int_add(json_path, "aggregatorAs",
9061 attr->aggregator_as);
9062 json_object_string_add(
9063 json_path, "aggregatorId",
9064 inet_ntoa(attr->aggregator_addr));
9065 if (attr->aggregator_as == BGP_AS_ZERO)
9066 json_object_boolean_true_add(
9067 json_path, "aggregatorAsMalformed");
9068 else
9069 json_object_boolean_false_add(
9070 json_path, "aggregatorAsMalformed");
9071 } else {
9072 if (attr->aggregator_as == BGP_AS_ZERO)
9073 vty_out(vty,
9074 ", (aggregated by %u(malformed) %s)",
9075 attr->aggregator_as,
9076 inet_ntoa(attr->aggregator_addr));
9077 else
9078 vty_out(vty, ", (aggregated by %u %s)",
9079 attr->aggregator_as,
9080 inet_ntoa(attr->aggregator_addr));
9081 }
9082 }
9083
9084 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
9085 PEER_FLAG_REFLECTOR_CLIENT)) {
9086 if (json_paths)
9087 json_object_boolean_true_add(json_path,
9088 "rxedFromRrClient");
9089 else
9090 vty_out(vty, ", (Received from a RR-client)");
9091 }
9092
9093 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
9094 PEER_FLAG_RSERVER_CLIENT)) {
9095 if (json_paths)
9096 json_object_boolean_true_add(json_path,
9097 "rxedFromRsClient");
9098 else
9099 vty_out(vty, ", (Received from a RS-client)");
9100 }
9101
9102 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
9103 if (json_paths)
9104 json_object_boolean_true_add(json_path,
9105 "dampeningHistoryEntry");
9106 else
9107 vty_out(vty, ", (history entry)");
9108 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
9109 if (json_paths)
9110 json_object_boolean_true_add(json_path,
9111 "dampeningSuppressed");
9112 else
9113 vty_out(vty, ", (suppressed due to dampening)");
9114 }
9115
9116 if (!json_paths)
9117 vty_out(vty, "\n");
9118
9119 /* Line2 display Next-hop, Neighbor, Router-id */
9120 /* Display the nexthop */
9121 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
9122
9123 if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET
9124 || bn_p->family == AF_EVPN)
9125 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
9126 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9127 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9128 || safi == SAFI_EVPN) {
9129 if (json_paths) {
9130 json_object_string_add(
9131 json_nexthop_global, "ip",
9132 inet_ntoa(attr->mp_nexthop_global_in));
9133
9134 if (path->peer->hostname)
9135 json_object_string_add(
9136 json_nexthop_global, "hostname",
9137 path->peer->hostname);
9138 } else {
9139 if (nexthop_hostname)
9140 vty_out(vty, " %pI4(%s)",
9141 &attr->mp_nexthop_global_in,
9142 nexthop_hostname);
9143 else
9144 vty_out(vty, " %pI4",
9145 &attr->mp_nexthop_global_in);
9146 }
9147 } else {
9148 if (json_paths) {
9149 json_object_string_add(
9150 json_nexthop_global, "ip",
9151 inet_ntoa(attr->nexthop));
9152
9153 if (path->peer->hostname)
9154 json_object_string_add(
9155 json_nexthop_global, "hostname",
9156 path->peer->hostname);
9157 } else {
9158 if (nexthop_hostname)
9159 vty_out(vty, " %pI4(%s)",
9160 &attr->nexthop,
9161 nexthop_hostname);
9162 else
9163 vty_out(vty, " %pI4",
9164 &attr->nexthop);
9165 }
9166 }
9167
9168 if (json_paths)
9169 json_object_string_add(json_nexthop_global, "afi",
9170 "ipv4");
9171 } else {
9172 if (json_paths) {
9173 json_object_string_add(
9174 json_nexthop_global, "ip",
9175 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
9176 buf, INET6_ADDRSTRLEN));
9177
9178 if (path->peer->hostname)
9179 json_object_string_add(json_nexthop_global,
9180 "hostname",
9181 path->peer->hostname);
9182
9183 json_object_string_add(json_nexthop_global, "afi",
9184 "ipv6");
9185 json_object_string_add(json_nexthop_global, "scope",
9186 "global");
9187 } else {
9188 if (nexthop_hostname)
9189 vty_out(vty, " %pI6(%s)",
9190 &attr->mp_nexthop_global,
9191 nexthop_hostname);
9192 else
9193 vty_out(vty, " %pI6",
9194 &attr->mp_nexthop_global);
9195 }
9196 }
9197
9198 /* Display the IGP cost or 'inaccessible' */
9199 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
9200 if (json_paths)
9201 json_object_boolean_false_add(json_nexthop_global,
9202 "accessible");
9203 else
9204 vty_out(vty, " (inaccessible)");
9205 } else {
9206 if (path->extra && path->extra->igpmetric) {
9207 if (json_paths)
9208 json_object_int_add(json_nexthop_global,
9209 "metric",
9210 path->extra->igpmetric);
9211 else
9212 vty_out(vty, " (metric %u)",
9213 path->extra->igpmetric);
9214 }
9215
9216 /* IGP cost is 0, display this only for json */
9217 else {
9218 if (json_paths)
9219 json_object_int_add(json_nexthop_global,
9220 "metric", 0);
9221 }
9222
9223 if (json_paths)
9224 json_object_boolean_true_add(json_nexthop_global,
9225 "accessible");
9226 }
9227
9228 /* Display peer "from" output */
9229 /* This path was originated locally */
9230 if (path->peer == bgp->peer_self) {
9231
9232 if (safi == SAFI_EVPN
9233 || (bn_p->family == AF_INET
9234 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9235 if (json_paths)
9236 json_object_string_add(json_peer, "peerId",
9237 "0.0.0.0");
9238 else
9239 vty_out(vty, " from 0.0.0.0 ");
9240 } else {
9241 if (json_paths)
9242 json_object_string_add(json_peer, "peerId",
9243 "::");
9244 else
9245 vty_out(vty, " from :: ");
9246 }
9247
9248 if (json_paths)
9249 json_object_string_add(json_peer, "routerId",
9250 inet_ntoa(bgp->router_id));
9251 else
9252 vty_out(vty, "(%s)", inet_ntoa(bgp->router_id));
9253 }
9254
9255 /* We RXed this path from one of our peers */
9256 else {
9257
9258 if (json_paths) {
9259 json_object_string_add(json_peer, "peerId",
9260 sockunion2str(&path->peer->su,
9261 buf,
9262 SU_ADDRSTRLEN));
9263 json_object_string_add(json_peer, "routerId",
9264 inet_ntop(AF_INET,
9265 &path->peer->remote_id,
9266 buf1, sizeof(buf1)));
9267
9268 if (path->peer->hostname)
9269 json_object_string_add(json_peer, "hostname",
9270 path->peer->hostname);
9271
9272 if (path->peer->domainname)
9273 json_object_string_add(json_peer, "domainname",
9274 path->peer->domainname);
9275
9276 if (path->peer->conf_if)
9277 json_object_string_add(json_peer, "interface",
9278 path->peer->conf_if);
9279 } else {
9280 if (path->peer->conf_if) {
9281 if (path->peer->hostname
9282 && CHECK_FLAG(path->peer->bgp->flags,
9283 BGP_FLAG_SHOW_HOSTNAME))
9284 vty_out(vty, " from %s(%s)",
9285 path->peer->hostname,
9286 path->peer->conf_if);
9287 else
9288 vty_out(vty, " from %s",
9289 path->peer->conf_if);
9290 } else {
9291 if (path->peer->hostname
9292 && CHECK_FLAG(path->peer->bgp->flags,
9293 BGP_FLAG_SHOW_HOSTNAME))
9294 vty_out(vty, " from %s(%s)",
9295 path->peer->hostname,
9296 path->peer->host);
9297 else
9298 vty_out(vty, " from %s",
9299 sockunion2str(&path->peer->su,
9300 buf,
9301 SU_ADDRSTRLEN));
9302 }
9303
9304 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
9305 vty_out(vty, " (%s)",
9306 inet_ntoa(attr->originator_id));
9307 else
9308 vty_out(vty, " (%s)",
9309 inet_ntop(AF_INET,
9310 &path->peer->remote_id, buf1,
9311 sizeof(buf1)));
9312 }
9313 }
9314
9315 /*
9316 * Note when vrfid of nexthop is different from that of prefix
9317 */
9318 if (path->extra && path->extra->bgp_orig) {
9319 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9320
9321 if (json_paths) {
9322 const char *vn;
9323
9324 if (path->extra->bgp_orig->inst_type
9325 == BGP_INSTANCE_TYPE_DEFAULT)
9326 vn = VRF_DEFAULT_NAME;
9327 else
9328 vn = path->extra->bgp_orig->name;
9329
9330 json_object_string_add(json_path, "nhVrfName", vn);
9331
9332 if (nexthop_vrfid == VRF_UNKNOWN) {
9333 json_object_int_add(json_path, "nhVrfId", -1);
9334 } else {
9335 json_object_int_add(json_path, "nhVrfId",
9336 (int)nexthop_vrfid);
9337 }
9338 } else {
9339 if (nexthop_vrfid == VRF_UNKNOWN)
9340 vty_out(vty, " vrf ?");
9341 else {
9342 struct vrf *vrf;
9343
9344 vrf = vrf_lookup_by_id(nexthop_vrfid);
9345 vty_out(vty, " vrf %s(%u)",
9346 VRF_LOGNAME(vrf), nexthop_vrfid);
9347 }
9348 }
9349 }
9350
9351 if (nexthop_self) {
9352 if (json_paths) {
9353 json_object_boolean_true_add(json_path,
9354 "announceNexthopSelf");
9355 } else {
9356 vty_out(vty, " announce-nh-self");
9357 }
9358 }
9359
9360 if (!json_paths)
9361 vty_out(vty, "\n");
9362
9363 /* display the link-local nexthop */
9364 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9365 if (json_paths) {
9366 json_nexthop_ll = json_object_new_object();
9367 json_object_string_add(
9368 json_nexthop_ll, "ip",
9369 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
9370 buf, INET6_ADDRSTRLEN));
9371
9372 if (path->peer->hostname)
9373 json_object_string_add(json_nexthop_ll,
9374 "hostname",
9375 path->peer->hostname);
9376
9377 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
9378 json_object_string_add(json_nexthop_ll, "scope",
9379 "link-local");
9380
9381 json_object_boolean_true_add(json_nexthop_ll,
9382 "accessible");
9383
9384 if (!attr->mp_nexthop_prefer_global)
9385 json_object_boolean_true_add(json_nexthop_ll,
9386 "used");
9387 else
9388 json_object_boolean_true_add(
9389 json_nexthop_global, "used");
9390 } else {
9391 vty_out(vty, " (%s) %s\n",
9392 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
9393 buf, INET6_ADDRSTRLEN),
9394 attr->mp_nexthop_prefer_global
9395 ? "(prefer-global)"
9396 : "(used)");
9397 }
9398 }
9399 /* If we do not have a link-local nexthop then we must flag the
9400 global as "used" */
9401 else {
9402 if (json_paths)
9403 json_object_boolean_true_add(json_nexthop_global,
9404 "used");
9405 }
9406
9407 if (safi == SAFI_EVPN &&
9408 bgp_evpn_is_esi_valid(&attr->esi)) {
9409 route_vty_out_detail_es_info(vty, attr, json_path);
9410 }
9411
9412 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
9413 * Int/Ext/Local, Atomic, best */
9414 if (json_paths)
9415 json_object_string_add(json_path, "origin",
9416 bgp_origin_long_str[attr->origin]);
9417 else
9418 vty_out(vty, " Origin %s",
9419 bgp_origin_long_str[attr->origin]);
9420
9421 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
9422 if (json_paths)
9423 json_object_int_add(json_path, "metric", attr->med);
9424 else
9425 vty_out(vty, ", metric %u", attr->med);
9426 }
9427
9428 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
9429 if (json_paths)
9430 json_object_int_add(json_path, "locPrf",
9431 attr->local_pref);
9432 else
9433 vty_out(vty, ", localpref %u", attr->local_pref);
9434 }
9435
9436 if (attr->weight != 0) {
9437 if (json_paths)
9438 json_object_int_add(json_path, "weight", attr->weight);
9439 else
9440 vty_out(vty, ", weight %u", attr->weight);
9441 }
9442
9443 if (attr->tag != 0) {
9444 if (json_paths)
9445 json_object_int_add(json_path, "tag", attr->tag);
9446 else
9447 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
9448 }
9449
9450 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
9451 if (json_paths)
9452 json_object_boolean_false_add(json_path, "valid");
9453 else
9454 vty_out(vty, ", invalid");
9455 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
9456 if (json_paths)
9457 json_object_boolean_true_add(json_path, "valid");
9458 else
9459 vty_out(vty, ", valid");
9460 }
9461
9462 if (path->peer != bgp->peer_self) {
9463 if (path->peer->as == path->peer->local_as) {
9464 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
9465 if (json_paths)
9466 json_object_string_add(
9467 json_peer, "type",
9468 "confed-internal");
9469 else
9470 vty_out(vty, ", confed-internal");
9471 } else {
9472 if (json_paths)
9473 json_object_string_add(
9474 json_peer, "type", "internal");
9475 else
9476 vty_out(vty, ", internal");
9477 }
9478 } else {
9479 if (bgp_confederation_peers_check(bgp,
9480 path->peer->as)) {
9481 if (json_paths)
9482 json_object_string_add(
9483 json_peer, "type",
9484 "confed-external");
9485 else
9486 vty_out(vty, ", confed-external");
9487 } else {
9488 if (json_paths)
9489 json_object_string_add(
9490 json_peer, "type", "external");
9491 else
9492 vty_out(vty, ", external");
9493 }
9494 }
9495 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
9496 if (json_paths) {
9497 json_object_boolean_true_add(json_path, "aggregated");
9498 json_object_boolean_true_add(json_path, "local");
9499 } else {
9500 vty_out(vty, ", aggregated, local");
9501 }
9502 } else if (path->type != ZEBRA_ROUTE_BGP) {
9503 if (json_paths)
9504 json_object_boolean_true_add(json_path, "sourced");
9505 else
9506 vty_out(vty, ", sourced");
9507 } else {
9508 if (json_paths) {
9509 json_object_boolean_true_add(json_path, "sourced");
9510 json_object_boolean_true_add(json_path, "local");
9511 } else {
9512 vty_out(vty, ", sourced, local");
9513 }
9514 }
9515
9516 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
9517 if (json_paths)
9518 json_object_boolean_true_add(json_path,
9519 "atomicAggregate");
9520 else
9521 vty_out(vty, ", atomic-aggregate");
9522 }
9523
9524 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
9525 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
9526 && bgp_path_info_mpath_count(path))) {
9527 if (json_paths)
9528 json_object_boolean_true_add(json_path, "multipath");
9529 else
9530 vty_out(vty, ", multipath");
9531 }
9532
9533 // Mark the bestpath(s)
9534 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
9535 first_as = aspath_get_first_as(attr->aspath);
9536
9537 if (json_paths) {
9538 if (!json_bestpath)
9539 json_bestpath = json_object_new_object();
9540 json_object_int_add(json_bestpath, "bestpathFromAs",
9541 first_as);
9542 } else {
9543 if (first_as)
9544 vty_out(vty, ", bestpath-from-AS %u", first_as);
9545 else
9546 vty_out(vty, ", bestpath-from-AS Local");
9547 }
9548 }
9549
9550 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9551 if (json_paths) {
9552 if (!json_bestpath)
9553 json_bestpath = json_object_new_object();
9554 json_object_boolean_true_add(json_bestpath, "overall");
9555 json_object_string_add(
9556 json_bestpath, "selectionReason",
9557 bgp_path_selection_reason2str(bn->reason));
9558 } else {
9559 vty_out(vty, ", best");
9560 vty_out(vty, " (%s)",
9561 bgp_path_selection_reason2str(bn->reason));
9562 }
9563 }
9564
9565 if (json_bestpath)
9566 json_object_object_add(json_path, "bestpath", json_bestpath);
9567
9568 if (!json_paths)
9569 vty_out(vty, "\n");
9570
9571 /* Line 4 display Community */
9572 if (attr->community) {
9573 if (json_paths) {
9574 if (!attr->community->json)
9575 community_str(attr->community, true);
9576 json_object_lock(attr->community->json);
9577 json_object_object_add(json_path, "community",
9578 attr->community->json);
9579 } else {
9580 vty_out(vty, " Community: %s\n",
9581 attr->community->str);
9582 }
9583 }
9584
9585 /* Line 5 display Extended-community */
9586 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9587 if (json_paths) {
9588 json_ext_community = json_object_new_object();
9589 json_object_string_add(json_ext_community, "string",
9590 attr->ecommunity->str);
9591 json_object_object_add(json_path, "extendedCommunity",
9592 json_ext_community);
9593 } else {
9594 vty_out(vty, " Extended Community: %s\n",
9595 attr->ecommunity->str);
9596 }
9597 }
9598
9599 /* Line 6 display Large community */
9600 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
9601 if (json_paths) {
9602 if (!attr->lcommunity->json)
9603 lcommunity_str(attr->lcommunity, true);
9604 json_object_lock(attr->lcommunity->json);
9605 json_object_object_add(json_path, "largeCommunity",
9606 attr->lcommunity->json);
9607 } else {
9608 vty_out(vty, " Large Community: %s\n",
9609 attr->lcommunity->str);
9610 }
9611 }
9612
9613 /* Line 7 display Originator, Cluster-id */
9614 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
9615 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
9616 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
9617 if (json_paths)
9618 json_object_string_add(
9619 json_path, "originatorId",
9620 inet_ntoa(attr->originator_id));
9621 else
9622 vty_out(vty, " Originator: %s",
9623 inet_ntoa(attr->originator_id));
9624 }
9625
9626 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
9627 int i;
9628
9629 if (json_paths) {
9630 json_cluster_list = json_object_new_object();
9631 json_cluster_list_list =
9632 json_object_new_array();
9633
9634 for (i = 0; i < attr->cluster->length / 4;
9635 i++) {
9636 json_string = json_object_new_string(
9637 inet_ntoa(attr->cluster
9638 ->list[i]));
9639 json_object_array_add(
9640 json_cluster_list_list,
9641 json_string);
9642 }
9643
9644 /*
9645 * struct cluster_list does not have
9646 * "str" variable like aspath and community
9647 * do. Add this someday if someone asks
9648 * for it.
9649 * json_object_string_add(json_cluster_list,
9650 * "string", attr->cluster->str);
9651 */
9652 json_object_object_add(json_cluster_list,
9653 "list",
9654 json_cluster_list_list);
9655 json_object_object_add(json_path, "clusterList",
9656 json_cluster_list);
9657 } else {
9658 vty_out(vty, ", Cluster list: ");
9659
9660 for (i = 0; i < attr->cluster->length / 4;
9661 i++) {
9662 vty_out(vty, "%s ",
9663 inet_ntoa(attr->cluster
9664 ->list[i]));
9665 }
9666 }
9667 }
9668
9669 if (!json_paths)
9670 vty_out(vty, "\n");
9671 }
9672
9673 if (path->extra && path->extra->damp_info)
9674 bgp_damp_info_vty(vty, path, afi, safi, json_path);
9675
9676 /* Remote Label */
9677 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
9678 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
9679 mpls_label_t label = label_pton(&path->extra->label[0]);
9680
9681 if (json_paths)
9682 json_object_int_add(json_path, "remoteLabel", label);
9683 else
9684 vty_out(vty, " Remote label: %d\n", label);
9685 }
9686
9687 /* Remote SID */
9688 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
9689 inet_ntop(AF_INET6, &path->extra->sid, buf, sizeof(buf));
9690 if (json_paths)
9691 json_object_string_add(json_path, "remoteSid", buf);
9692 else
9693 vty_out(vty, " Remote SID: %s\n", buf);
9694 }
9695
9696 /* Label Index */
9697 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
9698 if (json_paths)
9699 json_object_int_add(json_path, "labelIndex",
9700 attr->label_index);
9701 else
9702 vty_out(vty, " Label Index: %d\n",
9703 attr->label_index);
9704 }
9705
9706 /* Line 8 display Addpath IDs */
9707 if (path->addpath_rx_id
9708 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
9709 if (json_paths) {
9710 json_object_int_add(json_path, "addpathRxId",
9711 path->addpath_rx_id);
9712
9713 /* Keep backwards compatibility with the old API
9714 * by putting TX All's ID in the old field
9715 */
9716 json_object_int_add(
9717 json_path, "addpathTxId",
9718 path->tx_addpath
9719 .addpath_tx_id[BGP_ADDPATH_ALL]);
9720
9721 /* ... but create a specific field for each
9722 * strategy
9723 */
9724 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9725 json_object_int_add(
9726 json_path,
9727 bgp_addpath_names(i)->id_json_name,
9728 path->tx_addpath.addpath_tx_id[i]);
9729 }
9730 } else {
9731 vty_out(vty, " AddPath ID: RX %u, ",
9732 path->addpath_rx_id);
9733
9734 route_vty_out_tx_ids(vty, &path->tx_addpath);
9735 }
9736 }
9737
9738 /* If we used addpath to TX a non-bestpath we need to display
9739 * "Advertised to" on a path-by-path basis
9740 */
9741 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
9742 first = 1;
9743
9744 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
9745 addpath_capable =
9746 bgp_addpath_encode_tx(peer, afi, safi);
9747 has_adj = bgp_adj_out_lookup(
9748 peer, path->net,
9749 bgp_addpath_id_for_peer(peer, afi, safi,
9750 &path->tx_addpath));
9751
9752 if ((addpath_capable && has_adj)
9753 || (!addpath_capable && has_adj
9754 && CHECK_FLAG(path->flags,
9755 BGP_PATH_SELECTED))) {
9756 if (json_path && !json_adv_to)
9757 json_adv_to = json_object_new_object();
9758
9759 route_vty_out_advertised_to(
9760 vty, peer, &first,
9761 " Advertised to:", json_adv_to);
9762 }
9763 }
9764
9765 if (json_path) {
9766 if (json_adv_to) {
9767 json_object_object_add(
9768 json_path, "advertisedTo", json_adv_to);
9769 }
9770 } else {
9771 if (!first) {
9772 vty_out(vty, "\n");
9773 }
9774 }
9775 }
9776
9777 /* Line 9 display Uptime */
9778 tbuf = time(NULL) - (bgp_clock() - path->uptime);
9779 if (json_paths) {
9780 json_last_update = json_object_new_object();
9781 json_object_int_add(json_last_update, "epoch", tbuf);
9782 json_object_string_add(json_last_update, "string",
9783 ctime(&tbuf));
9784 json_object_object_add(json_path, "lastUpdate",
9785 json_last_update);
9786 } else
9787 vty_out(vty, " Last update: %s", ctime(&tbuf));
9788
9789 /* Line 10 display PMSI tunnel attribute, if present */
9790 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
9791 const char *str =
9792 lookup_msg(bgp_pmsi_tnltype_str, attr->pmsi_tnl_type,
9793 PMSI_TNLTYPE_STR_DEFAULT);
9794
9795 if (json_paths) {
9796 json_pmsi = json_object_new_object();
9797 json_object_string_add(json_pmsi, "tunnelType", str);
9798 json_object_int_add(json_pmsi, "label",
9799 label2vni(&attr->label));
9800 json_object_object_add(json_path, "pmsi", json_pmsi);
9801 } else
9802 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
9803 str, label2vni(&attr->label));
9804 }
9805
9806 /* We've constructed the json object for this path, add it to the json
9807 * array of paths
9808 */
9809 if (json_paths) {
9810 if (json_nexthop_global || json_nexthop_ll) {
9811 json_nexthops = json_object_new_array();
9812
9813 if (json_nexthop_global)
9814 json_object_array_add(json_nexthops,
9815 json_nexthop_global);
9816
9817 if (json_nexthop_ll)
9818 json_object_array_add(json_nexthops,
9819 json_nexthop_ll);
9820
9821 json_object_object_add(json_path, "nexthops",
9822 json_nexthops);
9823 }
9824
9825 json_object_object_add(json_path, "peer", json_peer);
9826 json_object_array_add(json_paths, json_path);
9827 }
9828 }
9829
9830 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
9831 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
9832 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
9833
9834 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
9835 const char *prefix_list_str, afi_t afi,
9836 safi_t safi, enum bgp_show_type type);
9837 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
9838 const char *filter, afi_t afi, safi_t safi,
9839 enum bgp_show_type type);
9840 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
9841 const char *rmap_str, afi_t afi, safi_t safi,
9842 enum bgp_show_type type);
9843 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
9844 const char *com, int exact, afi_t afi,
9845 safi_t safi);
9846 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
9847 const char *prefix, afi_t afi, safi_t safi,
9848 enum bgp_show_type type);
9849 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
9850 afi_t afi, safi_t safi, enum bgp_show_type type,
9851 bool use_json);
9852 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
9853 const char *comstr, int exact, afi_t afi,
9854 safi_t safi, uint8_t show_flags);
9855
9856
9857 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
9858 struct bgp_table *table, enum bgp_show_type type,
9859 void *output_arg, char *rd, int is_last,
9860 unsigned long *output_cum, unsigned long *total_cum,
9861 unsigned long *json_header_depth, uint8_t show_flags)
9862 {
9863 struct bgp_path_info *pi;
9864 struct bgp_dest *dest;
9865 int header = 1;
9866 int display;
9867 unsigned long output_count = 0;
9868 unsigned long total_count = 0;
9869 struct prefix *p;
9870 json_object *json_paths = NULL;
9871 int first = 1;
9872 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
9873 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
9874 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
9875
9876 if (output_cum && *output_cum != 0)
9877 header = 0;
9878
9879 if (use_json && !*json_header_depth) {
9880 if (all)
9881 *json_header_depth = 1;
9882 else {
9883 vty_out(vty, "{\n");
9884 *json_header_depth = 2;
9885 }
9886
9887 vty_out(vty,
9888 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n"
9889 " \"localAS\": %u,\n \"routes\": { ",
9890 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
9891 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
9892 ? VRF_DEFAULT_NAME
9893 : bgp->name,
9894 table->version, inet_ntoa(bgp->router_id),
9895 bgp->default_local_pref, bgp->as);
9896 if (rd) {
9897 vty_out(vty, " \"routeDistinguishers\" : {");
9898 ++*json_header_depth;
9899 }
9900 }
9901
9902 if (use_json && rd) {
9903 vty_out(vty, " \"%s\" : { ", rd);
9904 }
9905
9906 /* Start processing of routes. */
9907 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
9908 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
9909
9910 pi = bgp_dest_get_bgp_path_info(dest);
9911 if (pi == NULL)
9912 continue;
9913
9914 display = 0;
9915 if (use_json)
9916 json_paths = json_object_new_array();
9917 else
9918 json_paths = NULL;
9919
9920 for (; pi; pi = pi->next) {
9921 total_count++;
9922 if (type == bgp_show_type_flap_statistics
9923 || type == bgp_show_type_flap_neighbor
9924 || type == bgp_show_type_dampend_paths
9925 || type == bgp_show_type_damp_neighbor) {
9926 if (!(pi->extra && pi->extra->damp_info))
9927 continue;
9928 }
9929 if (type == bgp_show_type_regexp) {
9930 regex_t *regex = output_arg;
9931
9932 if (bgp_regexec(regex, pi->attr->aspath)
9933 == REG_NOMATCH)
9934 continue;
9935 }
9936 if (type == bgp_show_type_prefix_list) {
9937 struct prefix_list *plist = output_arg;
9938
9939 if (prefix_list_apply(plist, dest_p)
9940 != PREFIX_PERMIT)
9941 continue;
9942 }
9943 if (type == bgp_show_type_filter_list) {
9944 struct as_list *as_list = output_arg;
9945
9946 if (as_list_apply(as_list, pi->attr->aspath)
9947 != AS_FILTER_PERMIT)
9948 continue;
9949 }
9950 if (type == bgp_show_type_route_map) {
9951 struct route_map *rmap = output_arg;
9952 struct bgp_path_info path;
9953 struct attr dummy_attr;
9954 route_map_result_t ret;
9955
9956 dummy_attr = *pi->attr;
9957
9958 path.peer = pi->peer;
9959 path.attr = &dummy_attr;
9960
9961 ret = route_map_apply(rmap, dest_p, RMAP_BGP,
9962 &path);
9963 if (ret == RMAP_DENYMATCH)
9964 continue;
9965 }
9966 if (type == bgp_show_type_neighbor
9967 || type == bgp_show_type_flap_neighbor
9968 || type == bgp_show_type_damp_neighbor) {
9969 union sockunion *su = output_arg;
9970
9971 if (pi->peer == NULL
9972 || pi->peer->su_remote == NULL
9973 || !sockunion_same(pi->peer->su_remote, su))
9974 continue;
9975 }
9976 if (type == bgp_show_type_cidr_only) {
9977 uint32_t destination;
9978
9979 destination = ntohl(dest_p->u.prefix4.s_addr);
9980 if (IN_CLASSC(destination)
9981 && dest_p->prefixlen == 24)
9982 continue;
9983 if (IN_CLASSB(destination)
9984 && dest_p->prefixlen == 16)
9985 continue;
9986 if (IN_CLASSA(destination)
9987 && dest_p->prefixlen == 8)
9988 continue;
9989 }
9990 if (type == bgp_show_type_prefix_longer) {
9991 p = output_arg;
9992 if (!prefix_match(p, dest_p))
9993 continue;
9994 }
9995 if (type == bgp_show_type_community_all) {
9996 if (!pi->attr->community)
9997 continue;
9998 }
9999 if (type == bgp_show_type_community) {
10000 struct community *com = output_arg;
10001
10002 if (!pi->attr->community
10003 || !community_match(pi->attr->community,
10004 com))
10005 continue;
10006 }
10007 if (type == bgp_show_type_community_exact) {
10008 struct community *com = output_arg;
10009
10010 if (!pi->attr->community
10011 || !community_cmp(pi->attr->community, com))
10012 continue;
10013 }
10014 if (type == bgp_show_type_community_list) {
10015 struct community_list *list = output_arg;
10016
10017 if (!community_list_match(pi->attr->community,
10018 list))
10019 continue;
10020 }
10021 if (type == bgp_show_type_community_list_exact) {
10022 struct community_list *list = output_arg;
10023
10024 if (!community_list_exact_match(
10025 pi->attr->community, list))
10026 continue;
10027 }
10028 if (type == bgp_show_type_lcommunity) {
10029 struct lcommunity *lcom = output_arg;
10030
10031 if (!pi->attr->lcommunity
10032 || !lcommunity_match(pi->attr->lcommunity,
10033 lcom))
10034 continue;
10035 }
10036
10037 if (type == bgp_show_type_lcommunity_exact) {
10038 struct lcommunity *lcom = output_arg;
10039
10040 if (!pi->attr->lcommunity
10041 || !lcommunity_cmp(pi->attr->lcommunity,
10042 lcom))
10043 continue;
10044 }
10045 if (type == bgp_show_type_lcommunity_list) {
10046 struct community_list *list = output_arg;
10047
10048 if (!lcommunity_list_match(pi->attr->lcommunity,
10049 list))
10050 continue;
10051 }
10052 if (type
10053 == bgp_show_type_lcommunity_list_exact) {
10054 struct community_list *list = output_arg;
10055
10056 if (!lcommunity_list_exact_match(
10057 pi->attr->lcommunity, list))
10058 continue;
10059 }
10060 if (type == bgp_show_type_lcommunity_all) {
10061 if (!pi->attr->lcommunity)
10062 continue;
10063 }
10064 if (type == bgp_show_type_dampend_paths
10065 || type == bgp_show_type_damp_neighbor) {
10066 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
10067 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
10068 continue;
10069 }
10070
10071 if (!use_json && header) {
10072 vty_out(vty, "BGP table version is %" PRIu64", local router ID is %s, vrf id ",
10073 table->version,
10074 inet_ntoa(bgp->router_id));
10075 if (bgp->vrf_id == VRF_UNKNOWN)
10076 vty_out(vty, "%s", VRFID_NONE_STR);
10077 else
10078 vty_out(vty, "%u", bgp->vrf_id);
10079 vty_out(vty, "\n");
10080 vty_out(vty, "Default local pref %u, ",
10081 bgp->default_local_pref);
10082 vty_out(vty, "local AS %u\n", bgp->as);
10083 vty_out(vty, BGP_SHOW_SCODE_HEADER);
10084 vty_out(vty, BGP_SHOW_NCODE_HEADER);
10085 vty_out(vty, BGP_SHOW_OCODE_HEADER);
10086 if (type == bgp_show_type_dampend_paths
10087 || type == bgp_show_type_damp_neighbor)
10088 vty_out(vty, BGP_SHOW_DAMP_HEADER);
10089 else if (type == bgp_show_type_flap_statistics
10090 || type == bgp_show_type_flap_neighbor)
10091 vty_out(vty, BGP_SHOW_FLAP_HEADER);
10092 else
10093 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
10094 : BGP_SHOW_HEADER));
10095 header = 0;
10096 }
10097 if (rd != NULL && !display && !output_count) {
10098 if (!use_json)
10099 vty_out(vty,
10100 "Route Distinguisher: %s\n",
10101 rd);
10102 }
10103 if (type == bgp_show_type_dampend_paths
10104 || type == bgp_show_type_damp_neighbor)
10105 damp_route_vty_out(vty, dest_p, pi, display,
10106 AFI_IP, safi, use_json,
10107 json_paths);
10108 else if (type == bgp_show_type_flap_statistics
10109 || type == bgp_show_type_flap_neighbor)
10110 flap_route_vty_out(vty, dest_p, pi, display,
10111 AFI_IP, safi, use_json,
10112 json_paths);
10113 else
10114 route_vty_out(vty, dest_p, pi, display, safi,
10115 json_paths, wide);
10116 display++;
10117 }
10118
10119 if (display) {
10120 output_count++;
10121 if (!use_json)
10122 continue;
10123
10124 /* encode prefix */
10125 if (dest_p->family == AF_FLOWSPEC) {
10126 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
10127
10128
10129 bgp_fs_nlri_get_string(
10130 (unsigned char *)
10131 dest_p->u.prefix_flowspec.ptr,
10132 dest_p->u.prefix_flowspec.prefixlen,
10133 retstr, NLRI_STRING_FORMAT_MIN, NULL,
10134 family2afi(dest_p->u
10135 .prefix_flowspec.family));
10136 if (first)
10137 vty_out(vty, "\"%s/%d\": ", retstr,
10138 dest_p->u.prefix_flowspec
10139 .prefixlen);
10140 else
10141 vty_out(vty, ",\"%s/%d\": ", retstr,
10142 dest_p->u.prefix_flowspec
10143 .prefixlen);
10144 } else {
10145 if (first)
10146 vty_out(vty, "\"%pFX\": ", dest_p);
10147 else
10148 vty_out(vty, ",\"%pFX\": ", dest_p);
10149 }
10150 vty_out(vty, "%s",
10151 json_object_to_json_string_ext(
10152 json_paths, JSON_C_TO_STRING_PRETTY));
10153 json_object_free(json_paths);
10154 json_paths = NULL;
10155 first = 0;
10156 } else
10157 json_object_free(json_paths);
10158 }
10159
10160 if (output_cum) {
10161 output_count += *output_cum;
10162 *output_cum = output_count;
10163 }
10164 if (total_cum) {
10165 total_count += *total_cum;
10166 *total_cum = total_count;
10167 }
10168 if (use_json) {
10169 if (rd) {
10170 vty_out(vty, " }%s ", (is_last ? "" : ","));
10171 }
10172 if (is_last) {
10173 unsigned long i;
10174 for (i = 0; i < *json_header_depth; ++i)
10175 vty_out(vty, " } ");
10176 if (!all)
10177 vty_out(vty, "\n");
10178 }
10179 } else {
10180 if (is_last) {
10181 /* No route is displayed */
10182 if (output_count == 0) {
10183 if (type == bgp_show_type_normal)
10184 vty_out(vty,
10185 "No BGP prefixes displayed, %ld exist\n",
10186 total_count);
10187 } else
10188 vty_out(vty,
10189 "\nDisplayed %ld routes and %ld total paths\n",
10190 output_count, total_count);
10191 }
10192 }
10193
10194 return CMD_SUCCESS;
10195 }
10196
10197 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
10198 struct bgp_table *table, struct prefix_rd *prd_match,
10199 enum bgp_show_type type, void *output_arg, bool use_json)
10200 {
10201 struct bgp_dest *dest, *next;
10202 unsigned long output_cum = 0;
10203 unsigned long total_cum = 0;
10204 unsigned long json_header_depth = 0;
10205 struct bgp_table *itable;
10206 bool show_msg;
10207 uint8_t show_flags = 0;
10208
10209 show_msg = (!use_json && type == bgp_show_type_normal);
10210
10211 if (use_json)
10212 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10213
10214 for (dest = bgp_table_top(table); dest; dest = next) {
10215 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10216
10217 next = bgp_route_next(dest);
10218 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
10219 continue;
10220
10221 itable = bgp_dest_get_bgp_table_info(dest);
10222 if (itable != NULL) {
10223 struct prefix_rd prd;
10224 char rd[RD_ADDRSTRLEN];
10225
10226 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
10227 prefix_rd2str(&prd, rd, sizeof(rd));
10228 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
10229 rd, next == NULL, &output_cum,
10230 &total_cum, &json_header_depth,
10231 show_flags);
10232 if (next == NULL)
10233 show_msg = false;
10234 }
10235 }
10236 if (show_msg) {
10237 if (output_cum == 0)
10238 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
10239 total_cum);
10240 else
10241 vty_out(vty,
10242 "\nDisplayed %ld routes and %ld total paths\n",
10243 output_cum, total_cum);
10244 }
10245 return CMD_SUCCESS;
10246 }
10247 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
10248 enum bgp_show_type type, void *output_arg,
10249 uint8_t show_flags)
10250 {
10251 struct bgp_table *table;
10252 unsigned long json_header_depth = 0;
10253 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10254
10255 if (bgp == NULL) {
10256 bgp = bgp_get_default();
10257 }
10258
10259 if (bgp == NULL) {
10260 if (!use_json)
10261 vty_out(vty, "No BGP process is configured\n");
10262 else
10263 vty_out(vty, "{}\n");
10264 return CMD_WARNING;
10265 }
10266
10267 table = bgp->rib[afi][safi];
10268 /* use MPLS and ENCAP specific shows until they are merged */
10269 if (safi == SAFI_MPLS_VPN) {
10270 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
10271 output_arg, use_json);
10272 }
10273
10274 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
10275 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
10276 output_arg, use_json,
10277 1, NULL, NULL);
10278 }
10279 /* labeled-unicast routes live in the unicast table */
10280 else if (safi == SAFI_LABELED_UNICAST)
10281 safi = SAFI_UNICAST;
10282
10283 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
10284 NULL, NULL, &json_header_depth, show_flags);
10285 }
10286
10287 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
10288 safi_t safi, uint8_t show_flags)
10289 {
10290 struct listnode *node, *nnode;
10291 struct bgp *bgp;
10292 int is_first = 1;
10293 bool route_output = false;
10294 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10295
10296 if (use_json)
10297 vty_out(vty, "{\n");
10298
10299 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
10300 route_output = true;
10301 if (use_json) {
10302 if (!is_first)
10303 vty_out(vty, ",\n");
10304 else
10305 is_first = 0;
10306
10307 vty_out(vty, "\"%s\":",
10308 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
10309 ? VRF_DEFAULT_NAME
10310 : bgp->name);
10311 } else {
10312 vty_out(vty, "\nInstance %s:\n",
10313 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
10314 ? VRF_DEFAULT_NAME
10315 : bgp->name);
10316 }
10317 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
10318 show_flags);
10319 }
10320
10321 if (use_json)
10322 vty_out(vty, "}\n");
10323 else if (!route_output)
10324 vty_out(vty, "%% BGP instance not found\n");
10325 }
10326
10327 /* Header of detailed BGP route information */
10328 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
10329 struct bgp_dest *dest, struct prefix_rd *prd,
10330 afi_t afi, safi_t safi, json_object *json)
10331 {
10332 struct bgp_path_info *pi;
10333 const struct prefix *p;
10334 struct peer *peer;
10335 struct listnode *node, *nnode;
10336 char buf1[RD_ADDRSTRLEN];
10337 char buf2[INET6_ADDRSTRLEN];
10338 char buf3[EVPN_ROUTE_STRLEN];
10339 char prefix_str[BUFSIZ];
10340 int count = 0;
10341 int best = 0;
10342 int suppress = 0;
10343 int accept_own = 0;
10344 int route_filter_translated_v4 = 0;
10345 int route_filter_v4 = 0;
10346 int route_filter_translated_v6 = 0;
10347 int route_filter_v6 = 0;
10348 int llgr_stale = 0;
10349 int no_llgr = 0;
10350 int accept_own_nexthop = 0;
10351 int blackhole = 0;
10352 int no_export = 0;
10353 int no_advertise = 0;
10354 int local_as = 0;
10355 int no_peer = 0;
10356 int first = 1;
10357 int has_valid_label = 0;
10358 mpls_label_t label = 0;
10359 json_object *json_adv_to = NULL;
10360
10361 p = bgp_dest_get_prefix(dest);
10362 has_valid_label = bgp_is_valid_label(&dest->local_label);
10363
10364 if (has_valid_label)
10365 label = label_pton(&dest->local_label);
10366
10367 if (safi == SAFI_EVPN) {
10368
10369 if (!json) {
10370 vty_out(vty, "BGP routing table entry for %s%s%s\n",
10371 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
10372 : "", prd ? ":" : "",
10373 bgp_evpn_route2str((struct prefix_evpn *)p,
10374 buf3, sizeof(buf3)));
10375 } else {
10376 json_object_string_add(json, "rd",
10377 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
10378 "");
10379 bgp_evpn_route2json((struct prefix_evpn *)p, json);
10380 }
10381 } else {
10382 if (!json) {
10383 vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
10384 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
10385 ? prefix_rd2str(prd, buf1,
10386 sizeof(buf1))
10387 : ""),
10388 safi == SAFI_MPLS_VPN ? ":" : "",
10389 inet_ntop(p->family, &p->u.prefix, buf2,
10390 INET6_ADDRSTRLEN),
10391 p->prefixlen);
10392
10393 } else
10394 json_object_string_add(json, "prefix",
10395 prefix2str(p, prefix_str, sizeof(prefix_str)));
10396 }
10397
10398 if (has_valid_label) {
10399 if (json)
10400 json_object_int_add(json, "localLabel", label);
10401 else
10402 vty_out(vty, "Local label: %d\n", label);
10403 }
10404
10405 if (!json)
10406 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
10407 vty_out(vty, "not allocated\n");
10408
10409 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
10410 count++;
10411 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
10412 best = count;
10413 if (pi->extra && pi->extra->suppress)
10414 suppress = 1;
10415
10416 if (pi->attr->community == NULL)
10417 continue;
10418
10419 no_advertise += community_include(
10420 pi->attr->community, COMMUNITY_NO_ADVERTISE);
10421 no_export += community_include(pi->attr->community,
10422 COMMUNITY_NO_EXPORT);
10423 local_as += community_include(pi->attr->community,
10424 COMMUNITY_LOCAL_AS);
10425 accept_own += community_include(pi->attr->community,
10426 COMMUNITY_ACCEPT_OWN);
10427 route_filter_translated_v4 += community_include(
10428 pi->attr->community,
10429 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
10430 route_filter_translated_v6 += community_include(
10431 pi->attr->community,
10432 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
10433 route_filter_v4 += community_include(
10434 pi->attr->community, COMMUNITY_ROUTE_FILTER_v4);
10435 route_filter_v6 += community_include(
10436 pi->attr->community, COMMUNITY_ROUTE_FILTER_v6);
10437 llgr_stale += community_include(pi->attr->community,
10438 COMMUNITY_LLGR_STALE);
10439 no_llgr += community_include(pi->attr->community,
10440 COMMUNITY_NO_LLGR);
10441 accept_own_nexthop +=
10442 community_include(pi->attr->community,
10443 COMMUNITY_ACCEPT_OWN_NEXTHOP);
10444 blackhole += community_include(pi->attr->community,
10445 COMMUNITY_BLACKHOLE);
10446 no_peer += community_include(pi->attr->community,
10447 COMMUNITY_NO_PEER);
10448 }
10449 }
10450
10451 if (!json) {
10452 vty_out(vty, "Paths: (%d available", count);
10453 if (best) {
10454 vty_out(vty, ", best #%d", best);
10455 if (safi == SAFI_UNICAST) {
10456 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
10457 vty_out(vty, ", table %s",
10458 VRF_DEFAULT_NAME);
10459 else
10460 vty_out(vty, ", vrf %s",
10461 bgp->name);
10462 }
10463 } else
10464 vty_out(vty, ", no best path");
10465
10466 if (accept_own)
10467 vty_out(vty,
10468 ", accept own local route exported and imported in different VRF");
10469 else if (route_filter_translated_v4)
10470 vty_out(vty,
10471 ", mark translated RTs for VPNv4 route filtering");
10472 else if (route_filter_v4)
10473 vty_out(vty,
10474 ", attach RT as-is for VPNv4 route filtering");
10475 else if (route_filter_translated_v6)
10476 vty_out(vty,
10477 ", mark translated RTs for VPNv6 route filtering");
10478 else if (route_filter_v6)
10479 vty_out(vty,
10480 ", attach RT as-is for VPNv6 route filtering");
10481 else if (llgr_stale)
10482 vty_out(vty,
10483 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
10484 else if (no_llgr)
10485 vty_out(vty,
10486 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
10487 else if (accept_own_nexthop)
10488 vty_out(vty,
10489 ", accept local nexthop");
10490 else if (blackhole)
10491 vty_out(vty, ", inform peer to blackhole prefix");
10492 else if (no_export)
10493 vty_out(vty, ", not advertised to EBGP peer");
10494 else if (no_advertise)
10495 vty_out(vty, ", not advertised to any peer");
10496 else if (local_as)
10497 vty_out(vty, ", not advertised outside local AS");
10498 else if (no_peer)
10499 vty_out(vty,
10500 ", inform EBGP peer not to advertise to their EBGP peers");
10501
10502 if (suppress)
10503 vty_out(vty,
10504 ", Advertisements suppressed by an aggregate.");
10505 vty_out(vty, ")\n");
10506 }
10507
10508 /* If we are not using addpath then we can display Advertised to and
10509 * that will
10510 * show what peers we advertised the bestpath to. If we are using
10511 * addpath
10512 * though then we must display Advertised to on a path-by-path basis. */
10513 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
10514 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
10515 if (bgp_adj_out_lookup(peer, dest, 0)) {
10516 if (json && !json_adv_to)
10517 json_adv_to = json_object_new_object();
10518
10519 route_vty_out_advertised_to(
10520 vty, peer, &first,
10521 " Advertised to non peer-group peers:\n ",
10522 json_adv_to);
10523 }
10524 }
10525
10526 if (json) {
10527 if (json_adv_to) {
10528 json_object_object_add(json, "advertisedTo",
10529 json_adv_to);
10530 }
10531 } else {
10532 if (first)
10533 vty_out(vty, " Not advertised to any peer");
10534 vty_out(vty, "\n");
10535 }
10536 }
10537 }
10538
10539 static void bgp_show_path_info(struct prefix_rd *pfx_rd,
10540 struct bgp_dest *bgp_node, struct vty *vty,
10541 struct bgp *bgp, afi_t afi, safi_t safi,
10542 json_object *json, enum bgp_path_type pathtype,
10543 int *display)
10544 {
10545 struct bgp_path_info *pi;
10546 int header = 1;
10547 char rdbuf[RD_ADDRSTRLEN];
10548 json_object *json_header = NULL;
10549 json_object *json_paths = NULL;
10550
10551 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
10552
10553 if (json && !json_paths) {
10554 /* Instantiate json_paths only if path is valid */
10555 json_paths = json_object_new_array();
10556 if (pfx_rd) {
10557 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
10558 json_header = json_object_new_object();
10559 } else
10560 json_header = json;
10561 }
10562
10563 if (header) {
10564 route_vty_out_detail_header(
10565 vty, bgp, bgp_node, pfx_rd,
10566 AFI_IP, safi, json_header);
10567 header = 0;
10568 }
10569 (*display)++;
10570
10571 if (pathtype == BGP_PATH_SHOW_ALL
10572 || (pathtype == BGP_PATH_SHOW_BESTPATH
10573 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
10574 || (pathtype == BGP_PATH_SHOW_MULTIPATH
10575 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
10576 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
10577 route_vty_out_detail(vty, bgp, bgp_node,
10578 pi, AFI_IP, safi,
10579 json_paths);
10580 }
10581
10582 if (json && json_paths) {
10583 json_object_object_add(json_header, "paths", json_paths);
10584
10585 if (pfx_rd)
10586 json_object_object_add(json, rdbuf, json_header);
10587 }
10588 }
10589
10590 /* Display specified route of BGP table. */
10591 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
10592 struct bgp_table *rib, const char *ip_str,
10593 afi_t afi, safi_t safi,
10594 struct prefix_rd *prd, int prefix_check,
10595 enum bgp_path_type pathtype, bool use_json)
10596 {
10597 int ret;
10598 int display = 0;
10599 struct prefix match;
10600 struct bgp_dest *dest;
10601 struct bgp_dest *rm;
10602 struct bgp_table *table;
10603 json_object *json = NULL;
10604 json_object *json_paths = NULL;
10605
10606 /* Check IP address argument. */
10607 ret = str2prefix(ip_str, &match);
10608 if (!ret) {
10609 vty_out(vty, "address is malformed\n");
10610 return CMD_WARNING;
10611 }
10612
10613 match.family = afi2family(afi);
10614
10615 if (use_json)
10616 json = json_object_new_object();
10617
10618 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
10619 for (dest = bgp_table_top(rib); dest;
10620 dest = bgp_route_next(dest)) {
10621 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10622
10623 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
10624 continue;
10625 table = bgp_dest_get_bgp_table_info(dest);
10626 if (!table)
10627 continue;
10628
10629 if ((rm = bgp_node_match(table, &match)) == NULL)
10630 continue;
10631
10632 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
10633 if (prefix_check
10634 && rm_p->prefixlen != match.prefixlen) {
10635 bgp_dest_unlock_node(rm);
10636 continue;
10637 }
10638
10639 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
10640 bgp, afi, safi, json, pathtype,
10641 &display);
10642
10643 bgp_dest_unlock_node(rm);
10644 }
10645 } else if (safi == SAFI_EVPN) {
10646 struct bgp_dest *longest_pfx;
10647 bool is_exact_pfxlen_match = false;
10648
10649 for (dest = bgp_table_top(rib); dest;
10650 dest = bgp_route_next(dest)) {
10651 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10652
10653 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
10654 continue;
10655 table = bgp_dest_get_bgp_table_info(dest);
10656 if (!table)
10657 continue;
10658
10659 longest_pfx = NULL;
10660 is_exact_pfxlen_match = false;
10661 /*
10662 * Search through all the prefixes for a match. The
10663 * pfx's are enumerated in ascending order of pfxlens.
10664 * So, the last pfx match is the longest match. Set
10665 * is_exact_pfxlen_match when we get exact pfxlen match
10666 */
10667 for (rm = bgp_table_top(table); rm;
10668 rm = bgp_route_next(rm)) {
10669 const struct prefix *rm_p =
10670 bgp_dest_get_prefix(rm);
10671 /*
10672 * Get prefixlen of the ip-prefix within type5
10673 * evpn route
10674 */
10675 if (evpn_type5_prefix_match(rm_p, &match)
10676 && rm->info) {
10677 longest_pfx = rm;
10678 int type5_pfxlen =
10679 bgp_evpn_get_type5_prefixlen(
10680 rm_p);
10681 if (type5_pfxlen == match.prefixlen) {
10682 is_exact_pfxlen_match = true;
10683 bgp_dest_unlock_node(rm);
10684 break;
10685 }
10686 }
10687 }
10688
10689 if (!longest_pfx)
10690 continue;
10691
10692 if (prefix_check && !is_exact_pfxlen_match)
10693 continue;
10694
10695 rm = longest_pfx;
10696 bgp_dest_lock_node(rm);
10697
10698 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
10699 bgp, afi, safi, json, pathtype,
10700 &display);
10701
10702 bgp_dest_unlock_node(rm);
10703 }
10704 } else if (safi == SAFI_FLOWSPEC) {
10705 if (use_json)
10706 json_paths = json_object_new_array();
10707
10708 display = bgp_flowspec_display_match_per_ip(afi, rib,
10709 &match, prefix_check,
10710 vty,
10711 use_json,
10712 json_paths);
10713 if (use_json && display)
10714 json_object_object_add(json, "paths", json_paths);
10715 } else {
10716 if ((dest = bgp_node_match(rib, &match)) != NULL) {
10717 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10718 if (!prefix_check
10719 || dest_p->prefixlen == match.prefixlen) {
10720 bgp_show_path_info(NULL, dest, vty, bgp, afi,
10721 safi, json, pathtype,
10722 &display);
10723 }
10724
10725 bgp_dest_unlock_node(dest);
10726 }
10727 }
10728
10729 if (use_json) {
10730 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10731 json, JSON_C_TO_STRING_PRETTY |
10732 JSON_C_TO_STRING_NOSLASHESCAPE));
10733 json_object_free(json);
10734 } else {
10735 if (!display) {
10736 vty_out(vty, "%% Network not in table\n");
10737 return CMD_WARNING;
10738 }
10739 }
10740
10741 return CMD_SUCCESS;
10742 }
10743
10744 /* Display specified route of Main RIB */
10745 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
10746 afi_t afi, safi_t safi, struct prefix_rd *prd,
10747 int prefix_check, enum bgp_path_type pathtype,
10748 bool use_json)
10749 {
10750 if (!bgp) {
10751 bgp = bgp_get_default();
10752 if (!bgp) {
10753 if (!use_json)
10754 vty_out(vty, "No BGP process is configured\n");
10755 else
10756 vty_out(vty, "{}\n");
10757 return CMD_WARNING;
10758 }
10759 }
10760
10761 /* labeled-unicast routes live in the unicast table */
10762 if (safi == SAFI_LABELED_UNICAST)
10763 safi = SAFI_UNICAST;
10764
10765 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
10766 afi, safi, prd, prefix_check, pathtype,
10767 use_json);
10768 }
10769
10770 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
10771 struct cmd_token **argv, bool exact, afi_t afi,
10772 safi_t safi, bool uj)
10773 {
10774 struct lcommunity *lcom;
10775 struct buffer *b;
10776 int i;
10777 char *str;
10778 int first = 0;
10779 uint8_t show_flags = 0;
10780
10781 if (uj)
10782 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10783
10784 b = buffer_new(1024);
10785 for (i = 0; i < argc; i++) {
10786 if (first)
10787 buffer_putc(b, ' ');
10788 else {
10789 if (strmatch(argv[i]->text, "AA:BB:CC")) {
10790 first = 1;
10791 buffer_putstr(b, argv[i]->arg);
10792 }
10793 }
10794 }
10795 buffer_putc(b, '\0');
10796
10797 str = buffer_getstr(b);
10798 buffer_free(b);
10799
10800 lcom = lcommunity_str2com(str);
10801 XFREE(MTYPE_TMP, str);
10802 if (!lcom) {
10803 vty_out(vty, "%% Large-community malformed\n");
10804 return CMD_WARNING;
10805 }
10806
10807 return bgp_show(vty, bgp, afi, safi,
10808 (exact ? bgp_show_type_lcommunity_exact
10809 : bgp_show_type_lcommunity),
10810 lcom, show_flags);
10811 }
10812
10813 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
10814 const char *lcom, bool exact, afi_t afi,
10815 safi_t safi, bool uj)
10816 {
10817 struct community_list *list;
10818 uint8_t show_flags = 0;
10819
10820 if (uj)
10821 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10822
10823
10824 list = community_list_lookup(bgp_clist, lcom, 0,
10825 LARGE_COMMUNITY_LIST_MASTER);
10826 if (list == NULL) {
10827 vty_out(vty, "%% %s is not a valid large-community-list name\n",
10828 lcom);
10829 return CMD_WARNING;
10830 }
10831
10832 return bgp_show(vty, bgp, afi, safi,
10833 (exact ? bgp_show_type_lcommunity_list_exact
10834 : bgp_show_type_lcommunity_list),
10835 list, show_flags);
10836 }
10837
10838 DEFUN (show_ip_bgp_large_community_list,
10839 show_ip_bgp_large_community_list_cmd,
10840 "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]",
10841 SHOW_STR
10842 IP_STR
10843 BGP_STR
10844 BGP_INSTANCE_HELP_STR
10845 BGP_AFI_HELP_STR
10846 BGP_SAFI_WITH_LABEL_HELP_STR
10847 "Display routes matching the large-community-list\n"
10848 "large-community-list number\n"
10849 "large-community-list name\n"
10850 "Exact match of the large-communities\n"
10851 JSON_STR)
10852 {
10853 afi_t afi = AFI_IP6;
10854 safi_t safi = SAFI_UNICAST;
10855 int idx = 0;
10856 bool exact_match = 0;
10857 struct bgp *bgp = NULL;
10858 bool uj = use_json(argc, argv);
10859
10860 if (uj)
10861 argc--;
10862
10863 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10864 &bgp, uj);
10865 if (!idx)
10866 return CMD_WARNING;
10867
10868 argv_find(argv, argc, "large-community-list", &idx);
10869
10870 const char *clist_number_or_name = argv[++idx]->arg;
10871
10872 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
10873 exact_match = 1;
10874
10875 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
10876 exact_match, afi, safi, uj);
10877 }
10878 DEFUN (show_ip_bgp_large_community,
10879 show_ip_bgp_large_community_cmd,
10880 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
10881 SHOW_STR
10882 IP_STR
10883 BGP_STR
10884 BGP_INSTANCE_HELP_STR
10885 BGP_AFI_HELP_STR
10886 BGP_SAFI_WITH_LABEL_HELP_STR
10887 "Display routes matching the large-communities\n"
10888 "List of large-community numbers\n"
10889 "Exact match of the large-communities\n"
10890 JSON_STR)
10891 {
10892 afi_t afi = AFI_IP6;
10893 safi_t safi = SAFI_UNICAST;
10894 int idx = 0;
10895 bool exact_match = 0;
10896 struct bgp *bgp = NULL;
10897 bool uj = use_json(argc, argv);
10898 uint8_t show_flags = 0;
10899
10900 if (uj) {
10901 argc--;
10902 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10903 }
10904
10905 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10906 &bgp, uj);
10907 if (!idx)
10908 return CMD_WARNING;
10909
10910 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
10911 if (argv_find(argv, argc, "exact-match", &idx))
10912 exact_match = 1;
10913 return bgp_show_lcommunity(vty, bgp, argc, argv,
10914 exact_match, afi, safi, uj);
10915 } else
10916 return bgp_show(vty, bgp, afi, safi,
10917 bgp_show_type_lcommunity_all, NULL, show_flags);
10918 }
10919
10920 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
10921 safi_t safi, struct json_object *json_array);
10922 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
10923 safi_t safi, struct json_object *json);
10924
10925
10926 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
10927 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
10928 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
10929 "Display number of prefixes for all afi/safi\n" JSON_STR)
10930 {
10931 bool uj = use_json(argc, argv);
10932 struct bgp *bgp = NULL;
10933 safi_t safi = SAFI_UNICAST;
10934 afi_t afi = AFI_IP6;
10935 int idx = 0;
10936 struct json_object *json_all = NULL;
10937 struct json_object *json_afi_safi = NULL;
10938
10939 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10940 &bgp, false);
10941 if (!idx)
10942 return CMD_WARNING;
10943
10944 if (uj)
10945 json_all = json_object_new_object();
10946
10947 FOREACH_AFI_SAFI (afi, safi) {
10948 /*
10949 * So limit output to those afi/safi pairs that
10950 * actually have something interesting in them
10951 */
10952 if (strmatch(get_afi_safi_str(afi, safi, true),
10953 "Unknown")) {
10954 continue;
10955 }
10956 if (uj) {
10957 json_afi_safi = json_object_new_array();
10958 json_object_object_add(
10959 json_all,
10960 get_afi_safi_str(afi, safi, true),
10961 json_afi_safi);
10962 } else {
10963 json_afi_safi = NULL;
10964 }
10965
10966 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
10967 }
10968
10969 if (uj) {
10970 vty_out(vty, "%s",
10971 json_object_to_json_string_ext(
10972 json_all, JSON_C_TO_STRING_PRETTY));
10973 json_object_free(json_all);
10974 }
10975
10976 return CMD_SUCCESS;
10977 }
10978
10979 /* BGP route print out function without JSON */
10980 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
10981 show_ip_bgp_l2vpn_evpn_statistics_cmd,
10982 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
10983 SHOW_STR
10984 IP_STR
10985 BGP_STR
10986 BGP_INSTANCE_HELP_STR
10987 L2VPN_HELP_STR
10988 EVPN_HELP_STR
10989 "BGP RIB advertisement statistics\n"
10990 JSON_STR)
10991 {
10992 afi_t afi = AFI_IP6;
10993 safi_t safi = SAFI_UNICAST;
10994 struct bgp *bgp = NULL;
10995 int idx = 0, ret;
10996 bool uj = use_json(argc, argv);
10997 struct json_object *json_afi_safi = NULL, *json = NULL;
10998
10999 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11000 &bgp, false);
11001 if (!idx)
11002 return CMD_WARNING;
11003
11004 if (uj)
11005 json_afi_safi = json_object_new_array();
11006 else
11007 json_afi_safi = NULL;
11008
11009 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
11010
11011 if (uj) {
11012 json = json_object_new_object();
11013 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
11014 json_afi_safi);
11015 vty_out(vty, "%s", json_object_to_json_string_ext(
11016 json, JSON_C_TO_STRING_PRETTY));
11017 json_object_free(json);
11018 }
11019 return ret;
11020 }
11021
11022 /* BGP route print out function without JSON */
11023 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
11024 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
11025 " [" BGP_SAFI_WITH_LABEL_CMD_STR
11026 "]]\
11027 statistics [json]",
11028 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
11029 BGP_SAFI_WITH_LABEL_HELP_STR
11030 "BGP RIB advertisement statistics\n" JSON_STR)
11031 {
11032 afi_t afi = AFI_IP6;
11033 safi_t safi = SAFI_UNICAST;
11034 struct bgp *bgp = NULL;
11035 int idx = 0, ret;
11036 bool uj = use_json(argc, argv);
11037 struct json_object *json_afi_safi = NULL, *json = NULL;
11038
11039 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11040 &bgp, false);
11041 if (!idx)
11042 return CMD_WARNING;
11043
11044 if (uj)
11045 json_afi_safi = json_object_new_array();
11046 else
11047 json_afi_safi = NULL;
11048
11049 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
11050
11051 if (uj) {
11052 json = json_object_new_object();
11053 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
11054 json_afi_safi);
11055 vty_out(vty, "%s",
11056 json_object_to_json_string_ext(
11057 json, JSON_C_TO_STRING_PRETTY));
11058 json_object_free(json);
11059 }
11060 return ret;
11061 }
11062
11063 /* BGP route print out function without JSON */
11064 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
11065 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
11066 " [" BGP_SAFI_WITH_LABEL_CMD_STR
11067 "]]\
11068 <[all$all] dampening <parameters>\
11069 |route-map WORD\
11070 |prefix-list WORD\
11071 |filter-list WORD\
11072 |community-list <(1-500)|WORD> [exact-match]\
11073 |A.B.C.D/M longer-prefixes\
11074 |X:X::X:X/M longer-prefixes\
11075 >",
11076 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
11077 BGP_SAFI_WITH_LABEL_HELP_STR
11078 "Display the entries for all address families\n"
11079 "Display detailed information about dampening\n"
11080 "Display detail of configured dampening parameters\n"
11081 "Display routes matching the route-map\n"
11082 "A route-map to match on\n"
11083 "Display routes conforming to the prefix-list\n"
11084 "Prefix-list name\n"
11085 "Display routes conforming to the filter-list\n"
11086 "Regular expression access list name\n"
11087 "Display routes matching the community-list\n"
11088 "community-list number\n"
11089 "community-list name\n"
11090 "Exact match of the communities\n"
11091 "IPv4 prefix\n"
11092 "Display route and more specific routes\n"
11093 "IPv6 prefix\n"
11094 "Display route and more specific routes\n")
11095 {
11096 afi_t afi = AFI_IP6;
11097 safi_t safi = SAFI_UNICAST;
11098 int exact_match = 0;
11099 struct bgp *bgp = NULL;
11100 int idx = 0;
11101 uint8_t show_flags = 0;
11102
11103 /* [<ipv4|ipv6> [all]] */
11104 if (all) {
11105 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11106 if (argv_find(argv, argc, "ipv4", &idx))
11107 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
11108
11109 if (argv_find(argv, argc, "ipv6", &idx))
11110 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
11111 }
11112
11113 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11114 &bgp, false);
11115 if (!idx)
11116 return CMD_WARNING;
11117
11118 if (argv_find(argv, argc, "dampening", &idx)) {
11119 if (argv_find(argv, argc, "parameters", &idx))
11120 return bgp_show_dampening_parameters(vty, afi, safi,
11121 show_flags);
11122 }
11123
11124 if (argv_find(argv, argc, "prefix-list", &idx))
11125 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
11126 safi, bgp_show_type_prefix_list);
11127
11128 if (argv_find(argv, argc, "filter-list", &idx))
11129 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
11130 safi, bgp_show_type_filter_list);
11131
11132 if (argv_find(argv, argc, "route-map", &idx))
11133 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
11134 safi, bgp_show_type_route_map);
11135
11136 if (argv_find(argv, argc, "community-list", &idx)) {
11137 const char *clist_number_or_name = argv[++idx]->arg;
11138 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
11139 exact_match = 1;
11140 return bgp_show_community_list(vty, bgp, clist_number_or_name,
11141 exact_match, afi, safi);
11142 }
11143 /* prefix-longer */
11144 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
11145 || argv_find(argv, argc, "X:X::X:X/M", &idx))
11146 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
11147 safi,
11148 bgp_show_type_prefix_longer);
11149
11150 return CMD_WARNING;
11151 }
11152
11153 /* BGP route print out function with JSON */
11154 DEFPY (show_ip_bgp_json,
11155 show_ip_bgp_json_cmd,
11156 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
11157 [all$all]\
11158 [cidr-only\
11159 |dampening <flap-statistics|dampened-paths>\
11160 |community [AA:NN|local-AS|no-advertise|no-export\
11161 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
11162 |accept-own|accept-own-nexthop|route-filter-v6\
11163 |route-filter-v4|route-filter-translated-v6\
11164 |route-filter-translated-v4] [exact-match]\
11165 ] [json$uj | wide$wide]",
11166 SHOW_STR
11167 IP_STR
11168 BGP_STR
11169 BGP_INSTANCE_HELP_STR
11170 BGP_AFI_HELP_STR
11171 BGP_SAFI_WITH_LABEL_HELP_STR
11172 "Display the entries for all address families\n"
11173 "Display only routes with non-natural netmasks\n"
11174 "Display detailed information about dampening\n"
11175 "Display flap statistics of routes\n"
11176 "Display paths suppressed due to dampening\n"
11177 "Display routes matching the communities\n"
11178 COMMUNITY_AANN_STR
11179 "Do not send outside local AS (well-known community)\n"
11180 "Do not advertise to any peer (well-known community)\n"
11181 "Do not export to next AS (well-known community)\n"
11182 "Graceful shutdown (well-known community)\n"
11183 "Do not export to any peer (well-known community)\n"
11184 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
11185 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
11186 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
11187 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
11188 "Should accept VPN route with local nexthop (well-known community)\n"
11189 "RT VPNv6 route filtering (well-known community)\n"
11190 "RT VPNv4 route filtering (well-known community)\n"
11191 "RT translated VPNv6 route filtering (well-known community)\n"
11192 "RT translated VPNv4 route filtering (well-known community)\n"
11193 "Exact match of the communities\n"
11194 JSON_STR
11195 "Increase table width for longer prefixes\n")
11196 {
11197 afi_t afi = AFI_IP6;
11198 safi_t safi = SAFI_UNICAST;
11199 enum bgp_show_type sh_type = bgp_show_type_normal;
11200 struct bgp *bgp = NULL;
11201 int idx = 0;
11202 int exact_match = 0;
11203 char *community = NULL;
11204 bool first = true;
11205 uint8_t show_flags = 0;
11206
11207
11208 if (uj) {
11209 argc--;
11210 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11211 }
11212
11213 /* [<ipv4|ipv6> [all]] */
11214 if (all) {
11215 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11216
11217 if (argv_find(argv, argc, "ipv4", &idx))
11218 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
11219
11220 if (argv_find(argv, argc, "ipv6", &idx))
11221 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
11222 }
11223
11224 if (wide)
11225 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11226
11227 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11228 &bgp, uj);
11229 if (!idx)
11230 return CMD_WARNING;
11231
11232 if (argv_find(argv, argc, "cidr-only", &idx))
11233 sh_type = bgp_show_type_cidr_only;
11234
11235 if (argv_find(argv, argc, "dampening", &idx)) {
11236 if (argv_find(argv, argc, "dampened-paths", &idx))
11237 sh_type = bgp_show_type_dampend_paths;
11238 else if (argv_find(argv, argc, "flap-statistics", &idx))
11239 sh_type = bgp_show_type_flap_statistics;
11240 }
11241
11242 if (argv_find(argv, argc, "community", &idx)) {
11243 char *maybecomm = NULL;
11244
11245 if (idx + 1 < argc) {
11246 if (argv[idx + 1]->type == VARIABLE_TKN)
11247 maybecomm = argv[idx + 1]->arg;
11248 else
11249 maybecomm = argv[idx + 1]->text;
11250 }
11251
11252 if (maybecomm && !strmatch(maybecomm, "json")
11253 && !strmatch(maybecomm, "exact-match"))
11254 community = maybecomm;
11255
11256 if (argv_find(argv, argc, "exact-match", &idx))
11257 exact_match = 1;
11258
11259 if (!community)
11260 sh_type = bgp_show_type_community_all;
11261 }
11262
11263 if (!all) {
11264 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
11265 if (community)
11266 return bgp_show_community(vty, bgp, community,
11267 exact_match, afi, safi,
11268 show_flags);
11269 else
11270 return bgp_show(vty, bgp, afi, safi, sh_type, NULL,
11271 show_flags);
11272 } else {
11273 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
11274 * AFI_IP6 */
11275
11276 if (uj)
11277 vty_out(vty, "{\n");
11278
11279 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
11280 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
11281 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
11282 ? AFI_IP
11283 : AFI_IP6;
11284 FOREACH_SAFI (safi) {
11285 if (strmatch(get_afi_safi_str(afi, safi, true),
11286 "Unknown"))
11287 continue;
11288
11289 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
11290 continue;
11291
11292 if (uj) {
11293 if (first)
11294 first = false;
11295 else
11296 vty_out(vty, ",\n");
11297 vty_out(vty, "\"%s\":{\n",
11298 get_afi_safi_str(afi, safi,
11299 true));
11300 } else
11301 vty_out(vty,
11302 "\nFor address family: %s\n",
11303 get_afi_safi_str(afi, safi,
11304 false));
11305
11306 if (community)
11307 bgp_show_community(vty, bgp, community,
11308 exact_match, afi,
11309 safi, show_flags);
11310 else
11311 bgp_show(vty, bgp, afi, safi, sh_type,
11312 NULL, show_flags);
11313 if (uj)
11314 vty_out(vty, "}\n");
11315 }
11316 } else {
11317 /* show <ip> bgp all: for each AFI and SAFI*/
11318 FOREACH_AFI_SAFI (afi, safi) {
11319 if (strmatch(get_afi_safi_str(afi, safi, true),
11320 "Unknown"))
11321 continue;
11322
11323 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
11324 continue;
11325
11326 if (uj) {
11327 if (first)
11328 first = false;
11329 else
11330 vty_out(vty, ",\n");
11331
11332 vty_out(vty, "\"%s\":{\n",
11333 get_afi_safi_str(afi, safi,
11334 true));
11335 } else
11336 vty_out(vty,
11337 "\nFor address family: %s\n",
11338 get_afi_safi_str(afi, safi,
11339 false));
11340
11341 if (community)
11342 bgp_show_community(vty, bgp, community,
11343 exact_match, afi,
11344 safi, show_flags);
11345 else
11346 bgp_show(vty, bgp, afi, safi, sh_type,
11347 NULL, show_flags);
11348 if (uj)
11349 vty_out(vty, "}\n");
11350 }
11351 }
11352 if (uj)
11353 vty_out(vty, "}\n");
11354 }
11355 return CMD_SUCCESS;
11356 }
11357
11358 DEFUN (show_ip_bgp_route,
11359 show_ip_bgp_route_cmd,
11360 "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]",
11361 SHOW_STR
11362 IP_STR
11363 BGP_STR
11364 BGP_INSTANCE_HELP_STR
11365 BGP_AFI_HELP_STR
11366 BGP_SAFI_WITH_LABEL_HELP_STR
11367 "Network in the BGP routing table to display\n"
11368 "IPv4 prefix\n"
11369 "Network in the BGP routing table to display\n"
11370 "IPv6 prefix\n"
11371 "Display only the bestpath\n"
11372 "Display only multipaths\n"
11373 JSON_STR)
11374 {
11375 int prefix_check = 0;
11376
11377 afi_t afi = AFI_IP6;
11378 safi_t safi = SAFI_UNICAST;
11379 char *prefix = NULL;
11380 struct bgp *bgp = NULL;
11381 enum bgp_path_type path_type;
11382 bool uj = use_json(argc, argv);
11383
11384 int idx = 0;
11385
11386 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11387 &bgp, uj);
11388 if (!idx)
11389 return CMD_WARNING;
11390
11391 if (!bgp) {
11392 vty_out(vty,
11393 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
11394 return CMD_WARNING;
11395 }
11396
11397 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
11398 if (argv_find(argv, argc, "A.B.C.D", &idx)
11399 || argv_find(argv, argc, "X:X::X:X", &idx))
11400 prefix_check = 0;
11401 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
11402 || argv_find(argv, argc, "X:X::X:X/M", &idx))
11403 prefix_check = 1;
11404
11405 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
11406 && afi != AFI_IP6) {
11407 vty_out(vty,
11408 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
11409 return CMD_WARNING;
11410 }
11411 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
11412 && afi != AFI_IP) {
11413 vty_out(vty,
11414 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
11415 return CMD_WARNING;
11416 }
11417
11418 prefix = argv[idx]->arg;
11419
11420 /* [<bestpath|multipath>] */
11421 if (argv_find(argv, argc, "bestpath", &idx))
11422 path_type = BGP_PATH_SHOW_BESTPATH;
11423 else if (argv_find(argv, argc, "multipath", &idx))
11424 path_type = BGP_PATH_SHOW_MULTIPATH;
11425 else
11426 path_type = BGP_PATH_SHOW_ALL;
11427
11428 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
11429 path_type, uj);
11430 }
11431
11432 DEFUN (show_ip_bgp_regexp,
11433 show_ip_bgp_regexp_cmd,
11434 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
11435 SHOW_STR
11436 IP_STR
11437 BGP_STR
11438 BGP_INSTANCE_HELP_STR
11439 BGP_AFI_HELP_STR
11440 BGP_SAFI_WITH_LABEL_HELP_STR
11441 "Display routes matching the AS path regular expression\n"
11442 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
11443 JSON_STR)
11444 {
11445 afi_t afi = AFI_IP6;
11446 safi_t safi = SAFI_UNICAST;
11447 struct bgp *bgp = NULL;
11448 bool uj = use_json(argc, argv);
11449 char *regstr = NULL;
11450
11451 int idx = 0;
11452 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11453 &bgp, false);
11454 if (!idx)
11455 return CMD_WARNING;
11456
11457 // get index of regex
11458 if (argv_find(argv, argc, "REGEX", &idx))
11459 regstr = argv[idx]->arg;
11460
11461 assert(regstr);
11462 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
11463 bgp_show_type_regexp, uj);
11464 }
11465
11466 DEFPY (show_ip_bgp_instance_all,
11467 show_ip_bgp_instance_all_cmd,
11468 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
11469 SHOW_STR
11470 IP_STR
11471 BGP_STR
11472 BGP_INSTANCE_ALL_HELP_STR
11473 BGP_AFI_HELP_STR
11474 BGP_SAFI_WITH_LABEL_HELP_STR
11475 JSON_STR
11476 "Increase table width for longer prefixes\n")
11477 {
11478 afi_t afi = AFI_IP;
11479 safi_t safi = SAFI_UNICAST;
11480 struct bgp *bgp = NULL;
11481 int idx = 0;
11482 uint8_t show_flags = 0;
11483
11484 if (uj) {
11485 argc--;
11486 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11487 }
11488
11489 if (wide)
11490 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11491
11492 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11493 &bgp, uj);
11494 if (!idx)
11495 return CMD_WARNING;
11496
11497 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
11498 return CMD_SUCCESS;
11499 }
11500
11501 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11502 afi_t afi, safi_t safi, enum bgp_show_type type,
11503 bool use_json)
11504 {
11505 regex_t *regex;
11506 int rc;
11507 uint8_t show_flags = 0;
11508
11509 if (use_json)
11510 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11511
11512 if (!config_bgp_aspath_validate(regstr)) {
11513 vty_out(vty, "Invalid character in REGEX %s\n",
11514 regstr);
11515 return CMD_WARNING_CONFIG_FAILED;
11516 }
11517
11518 regex = bgp_regcomp(regstr);
11519 if (!regex) {
11520 vty_out(vty, "Can't compile regexp %s\n", regstr);
11521 return CMD_WARNING;
11522 }
11523
11524 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags);
11525 bgp_regex_free(regex);
11526 return rc;
11527 }
11528
11529 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
11530 const char *prefix_list_str, afi_t afi,
11531 safi_t safi, enum bgp_show_type type)
11532 {
11533 struct prefix_list *plist;
11534 uint8_t show_flags = 0;
11535
11536 plist = prefix_list_lookup(afi, prefix_list_str);
11537 if (plist == NULL) {
11538 vty_out(vty, "%% %s is not a valid prefix-list name\n",
11539 prefix_list_str);
11540 return CMD_WARNING;
11541 }
11542
11543 return bgp_show(vty, bgp, afi, safi, type, plist, show_flags);
11544 }
11545
11546 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
11547 const char *filter, afi_t afi, safi_t safi,
11548 enum bgp_show_type type)
11549 {
11550 struct as_list *as_list;
11551 uint8_t show_flags = 0;
11552
11553 as_list = as_list_lookup(filter);
11554 if (as_list == NULL) {
11555 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
11556 filter);
11557 return CMD_WARNING;
11558 }
11559
11560 return bgp_show(vty, bgp, afi, safi, type, as_list, show_flags);
11561 }
11562
11563 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
11564 const char *rmap_str, afi_t afi, safi_t safi,
11565 enum bgp_show_type type)
11566 {
11567 struct route_map *rmap;
11568 uint8_t show_flags = 0;
11569
11570 rmap = route_map_lookup_by_name(rmap_str);
11571 if (!rmap) {
11572 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
11573 return CMD_WARNING;
11574 }
11575
11576 return bgp_show(vty, bgp, afi, safi, type, rmap, show_flags);
11577 }
11578
11579 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11580 const char *comstr, int exact, afi_t afi,
11581 safi_t safi, uint8_t show_flags)
11582 {
11583 struct community *com;
11584 int ret = 0;
11585
11586 com = community_str2com(comstr);
11587 if (!com) {
11588 vty_out(vty, "%% Community malformed: %s\n", comstr);
11589 return CMD_WARNING;
11590 }
11591
11592 ret = bgp_show(vty, bgp, afi, safi,
11593 (exact ? bgp_show_type_community_exact
11594 : bgp_show_type_community),
11595 com, show_flags);
11596 community_free(&com);
11597
11598 return ret;
11599 }
11600
11601 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
11602 const char *com, int exact, afi_t afi,
11603 safi_t safi)
11604 {
11605 struct community_list *list;
11606 uint8_t show_flags = 0;
11607
11608 list = community_list_lookup(bgp_clist, com, 0, COMMUNITY_LIST_MASTER);
11609 if (list == NULL) {
11610 vty_out(vty, "%% %s is not a valid community-list name\n", com);
11611 return CMD_WARNING;
11612 }
11613
11614 return bgp_show(vty, bgp, afi, safi,
11615 (exact ? bgp_show_type_community_list_exact
11616 : bgp_show_type_community_list),
11617 list, show_flags);
11618 }
11619
11620 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
11621 const char *prefix, afi_t afi, safi_t safi,
11622 enum bgp_show_type type)
11623 {
11624 int ret;
11625 struct prefix *p;
11626 uint8_t show_flags = 0;
11627
11628 p = prefix_new();
11629
11630 ret = str2prefix(prefix, p);
11631 if (!ret) {
11632 vty_out(vty, "%% Malformed Prefix\n");
11633 return CMD_WARNING;
11634 }
11635
11636 ret = bgp_show(vty, bgp, afi, safi, type, p, show_flags);
11637 prefix_free(&p);
11638 return ret;
11639 }
11640
11641 enum bgp_stats {
11642 BGP_STATS_MAXBITLEN = 0,
11643 BGP_STATS_RIB,
11644 BGP_STATS_PREFIXES,
11645 BGP_STATS_TOTPLEN,
11646 BGP_STATS_UNAGGREGATEABLE,
11647 BGP_STATS_MAX_AGGREGATEABLE,
11648 BGP_STATS_AGGREGATES,
11649 BGP_STATS_SPACE,
11650 BGP_STATS_ASPATH_COUNT,
11651 BGP_STATS_ASPATH_MAXHOPS,
11652 BGP_STATS_ASPATH_TOTHOPS,
11653 BGP_STATS_ASPATH_MAXSIZE,
11654 BGP_STATS_ASPATH_TOTSIZE,
11655 BGP_STATS_ASN_HIGHEST,
11656 BGP_STATS_MAX,
11657 };
11658
11659 #define TABLE_STATS_IDX_VTY 0
11660 #define TABLE_STATS_IDX_JSON 1
11661
11662 static const char *table_stats_strs[][2] = {
11663 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
11664 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
11665 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
11666 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
11667 "unaggregateablePrefixes"},
11668 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
11669 "maximumAggregateablePrefixes"},
11670 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
11671 "bgpAggregateAdvertisements"},
11672 [BGP_STATS_SPACE] = {"Address space advertised",
11673 "addressSpaceAdvertised"},
11674 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
11675 "advertisementsWithPaths"},
11676 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
11677 "longestAsPath"},
11678 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
11679 "largestAsPath"},
11680 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
11681 "averageAsPathLengthHops"},
11682 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
11683 "averageAsPathSizeBytes"},
11684 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
11685 [BGP_STATS_MAX] = {NULL, NULL}
11686 };
11687
11688 struct bgp_table_stats {
11689 struct bgp_table *table;
11690 unsigned long long counts[BGP_STATS_MAX];
11691 double total_space;
11692 };
11693
11694 #if 0
11695 #define TALLY_SIGFIG 100000
11696 static unsigned long
11697 ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
11698 {
11699 unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
11700 unsigned long res = (newtot * TALLY_SIGFIG) / count;
11701 unsigned long ret = newtot / count;
11702
11703 if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
11704 return ret + 1;
11705 else
11706 return ret;
11707 }
11708 #endif
11709
11710 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
11711 struct bgp_table_stats *ts, unsigned int space)
11712 {
11713 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
11714 struct bgp_path_info *pi;
11715 const struct prefix *rn_p;
11716
11717 if (dest == top)
11718 return;
11719
11720 if (!bgp_dest_has_bgp_path_info_data(dest))
11721 return;
11722
11723 rn_p = bgp_dest_get_prefix(dest);
11724 ts->counts[BGP_STATS_PREFIXES]++;
11725 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
11726
11727 #if 0
11728 ts->counts[BGP_STATS_AVGPLEN]
11729 = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
11730 ts->counts[BGP_STATS_AVGPLEN],
11731 rn_p->prefixlen);
11732 #endif
11733
11734 /* check if the prefix is included by any other announcements */
11735 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
11736 pdest = bgp_dest_parent_nolock(pdest);
11737
11738 if (pdest == NULL || pdest == top) {
11739 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
11740 /* announced address space */
11741 if (space)
11742 ts->total_space += pow(2.0, space - rn_p->prefixlen);
11743 } else if (bgp_dest_has_bgp_path_info_data(pdest))
11744 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
11745
11746
11747 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11748 ts->counts[BGP_STATS_RIB]++;
11749
11750 if (CHECK_FLAG(pi->attr->flag,
11751 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
11752 ts->counts[BGP_STATS_AGGREGATES]++;
11753
11754 /* as-path stats */
11755 if (pi->attr->aspath) {
11756 unsigned int hops = aspath_count_hops(pi->attr->aspath);
11757 unsigned int size = aspath_size(pi->attr->aspath);
11758 as_t highest = aspath_highest(pi->attr->aspath);
11759
11760 ts->counts[BGP_STATS_ASPATH_COUNT]++;
11761
11762 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
11763 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
11764
11765 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
11766 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
11767
11768 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
11769 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
11770 #if 0
11771 ts->counts[BGP_STATS_ASPATH_AVGHOPS]
11772 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
11773 ts->counts[BGP_STATS_ASPATH_AVGHOPS],
11774 hops);
11775 ts->counts[BGP_STATS_ASPATH_AVGSIZE]
11776 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
11777 ts->counts[BGP_STATS_ASPATH_AVGSIZE],
11778 size);
11779 #endif
11780 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
11781 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
11782 }
11783 }
11784 }
11785
11786 static int bgp_table_stats_walker(struct thread *t)
11787 {
11788 struct bgp_dest *dest, *ndest;
11789 struct bgp_dest *top;
11790 struct bgp_table_stats *ts = THREAD_ARG(t);
11791 unsigned int space = 0;
11792
11793 if (!(top = bgp_table_top(ts->table)))
11794 return 0;
11795
11796 switch (ts->table->afi) {
11797 case AFI_IP:
11798 space = IPV4_MAX_BITLEN;
11799 break;
11800 case AFI_IP6:
11801 space = IPV6_MAX_BITLEN;
11802 break;
11803 default:
11804 return 0;
11805 }
11806
11807 ts->counts[BGP_STATS_MAXBITLEN] = space;
11808
11809 for (dest = top; dest; dest = bgp_route_next(dest)) {
11810 if (ts->table->safi == SAFI_MPLS_VPN
11811 || ts->table->safi == SAFI_ENCAP
11812 || ts->table->safi == SAFI_EVPN) {
11813 struct bgp_table *table;
11814
11815 table = bgp_dest_get_bgp_table_info(dest);
11816 if (!table)
11817 continue;
11818
11819 top = bgp_table_top(table);
11820 for (ndest = bgp_table_top(table); ndest;
11821 ndest = bgp_route_next(ndest))
11822 bgp_table_stats_rn(ndest, top, ts, space);
11823 } else {
11824 bgp_table_stats_rn(dest, top, ts, space);
11825 }
11826 }
11827
11828 return 0;
11829 }
11830
11831 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
11832 struct json_object *json_array)
11833 {
11834 struct listnode *node, *nnode;
11835 struct bgp *bgp;
11836
11837 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
11838 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
11839 }
11840
11841 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
11842 safi_t safi, struct json_object *json_array)
11843 {
11844 struct bgp_table_stats ts;
11845 unsigned int i;
11846 int ret = CMD_SUCCESS;
11847 char temp_buf[20];
11848 struct json_object *json = NULL;
11849
11850 if (json_array)
11851 json = json_object_new_object();
11852
11853 if (!bgp->rib[afi][safi]) {
11854 char warning_msg[50];
11855
11856 snprintf(warning_msg, sizeof(warning_msg),
11857 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
11858 safi);
11859
11860 if (!json)
11861 vty_out(vty, "%s\n", warning_msg);
11862 else
11863 json_object_string_add(json, "warning", warning_msg);
11864
11865 ret = CMD_WARNING;
11866 goto end_table_stats;
11867 }
11868
11869 if (!json)
11870 vty_out(vty, "BGP %s RIB statistics (%s)\n",
11871 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
11872 else
11873 json_object_string_add(json, "instance", bgp->name_pretty);
11874
11875 /* labeled-unicast routes live in the unicast table */
11876 if (safi == SAFI_LABELED_UNICAST)
11877 safi = SAFI_UNICAST;
11878
11879 memset(&ts, 0, sizeof(ts));
11880 ts.table = bgp->rib[afi][safi];
11881 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
11882
11883 for (i = 0; i < BGP_STATS_MAX; i++) {
11884 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
11885 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
11886 continue;
11887
11888 switch (i) {
11889 #if 0
11890 case BGP_STATS_ASPATH_AVGHOPS:
11891 case BGP_STATS_ASPATH_AVGSIZE:
11892 case BGP_STATS_AVGPLEN:
11893 vty_out (vty, "%-30s: ", table_stats_strs[i]);
11894 vty_out (vty, "%12.2f",
11895 (float)ts.counts[i] / (float)TALLY_SIGFIG);
11896 break;
11897 #endif
11898 case BGP_STATS_ASPATH_TOTHOPS:
11899 case BGP_STATS_ASPATH_TOTSIZE:
11900 if (!json) {
11901 snprintf(
11902 temp_buf, sizeof(temp_buf), "%12.2f",
11903 ts.counts[i]
11904 ? (float)ts.counts[i]
11905 / (float)ts.counts
11906 [BGP_STATS_ASPATH_COUNT]
11907 : 0);
11908 vty_out(vty, "%-30s: %s",
11909 table_stats_strs[i]
11910 [TABLE_STATS_IDX_VTY],
11911 temp_buf);
11912 } else {
11913 json_object_double_add(
11914 json,
11915 table_stats_strs[i]
11916 [TABLE_STATS_IDX_JSON],
11917 ts.counts[i]
11918 ? (double)ts.counts[i]
11919 / (double)ts.counts
11920 [BGP_STATS_ASPATH_COUNT]
11921 : 0);
11922 }
11923 break;
11924 case BGP_STATS_TOTPLEN:
11925 if (!json) {
11926 snprintf(
11927 temp_buf, sizeof(temp_buf), "%12.2f",
11928 ts.counts[i]
11929 ? (float)ts.counts[i]
11930 / (float)ts.counts
11931 [BGP_STATS_PREFIXES]
11932 : 0);
11933 vty_out(vty, "%-30s: %s",
11934 table_stats_strs[i]
11935 [TABLE_STATS_IDX_VTY],
11936 temp_buf);
11937 } else {
11938 json_object_double_add(
11939 json,
11940 table_stats_strs[i]
11941 [TABLE_STATS_IDX_JSON],
11942 ts.counts[i]
11943 ? (double)ts.counts[i]
11944 / (double)ts.counts
11945 [BGP_STATS_PREFIXES]
11946 : 0);
11947 }
11948 break;
11949 case BGP_STATS_SPACE:
11950 if (!json) {
11951 snprintf(temp_buf, sizeof(temp_buf), "%12g",
11952 ts.total_space);
11953 vty_out(vty, "%-30s: %s\n",
11954 table_stats_strs[i]
11955 [TABLE_STATS_IDX_VTY],
11956 temp_buf);
11957 } else {
11958 json_object_double_add(
11959 json,
11960 table_stats_strs[i]
11961 [TABLE_STATS_IDX_JSON],
11962 (double)ts.total_space);
11963 }
11964 if (afi == AFI_IP6) {
11965 if (!json) {
11966 snprintf(temp_buf, sizeof(temp_buf),
11967 "%12g",
11968 ts.total_space
11969 * pow(2.0, -128 + 32));
11970 vty_out(vty, "%30s: %s\n",
11971 "/32 equivalent %s\n",
11972 temp_buf);
11973 } else {
11974 json_object_double_add(
11975 json, "/32equivalent",
11976 (double)(ts.total_space
11977 * pow(2.0,
11978 -128 + 32)));
11979 }
11980 if (!json) {
11981 snprintf(temp_buf, sizeof(temp_buf),
11982 "%12g",
11983 ts.total_space
11984 * pow(2.0, -128 + 48));
11985 vty_out(vty, "%30s: %s\n",
11986 "/48 equivalent %s\n",
11987 temp_buf);
11988 } else {
11989 json_object_double_add(
11990 json, "/48equivalent",
11991 (double)(ts.total_space
11992 * pow(2.0,
11993 -128 + 48)));
11994 }
11995 } else {
11996 if (!json) {
11997 snprintf(temp_buf, sizeof(temp_buf),
11998 "%12.2f",
11999 ts.total_space * 100.
12000 * pow(2.0, -32));
12001 vty_out(vty, "%30s: %s\n",
12002 "% announced ", temp_buf);
12003 } else {
12004 json_object_double_add(
12005 json, "%announced",
12006 (double)(ts.total_space * 100.
12007 * pow(2.0, -32)));
12008 }
12009 if (!json) {
12010 snprintf(temp_buf, sizeof(temp_buf),
12011 "%12.2f",
12012 ts.total_space
12013 * pow(2.0, -32 + 8));
12014 vty_out(vty, "%30s: %s\n",
12015 "/8 equivalent ", temp_buf);
12016 } else {
12017 json_object_double_add(
12018 json, "/8equivalent",
12019 (double)(ts.total_space
12020 * pow(2.0, -32 + 8)));
12021 }
12022 if (!json) {
12023 snprintf(temp_buf, sizeof(temp_buf),
12024 "%12.2f",
12025 ts.total_space
12026 * pow(2.0, -32 + 24));
12027 vty_out(vty, "%30s: %s\n",
12028 "/24 equivalent ", temp_buf);
12029 } else {
12030 json_object_double_add(
12031 json, "/24equivalent",
12032 (double)(ts.total_space
12033 * pow(2.0, -32 + 24)));
12034 }
12035 }
12036 break;
12037 default:
12038 if (!json) {
12039 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
12040 ts.counts[i]);
12041 vty_out(vty, "%-30s: %s",
12042 table_stats_strs[i]
12043 [TABLE_STATS_IDX_VTY],
12044 temp_buf);
12045 } else {
12046 json_object_int_add(
12047 json,
12048 table_stats_strs[i]
12049 [TABLE_STATS_IDX_JSON],
12050 ts.counts[i]);
12051 }
12052 }
12053 if (!json)
12054 vty_out(vty, "\n");
12055 }
12056 end_table_stats:
12057 if (json)
12058 json_object_array_add(json_array, json);
12059 return ret;
12060 }
12061
12062 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12063 safi_t safi, struct json_object *json_array)
12064 {
12065 if (!bgp) {
12066 bgp_table_stats_all(vty, afi, safi, json_array);
12067 return CMD_SUCCESS;
12068 }
12069
12070 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
12071 }
12072
12073 enum bgp_pcounts {
12074 PCOUNT_ADJ_IN = 0,
12075 PCOUNT_DAMPED,
12076 PCOUNT_REMOVED,
12077 PCOUNT_HISTORY,
12078 PCOUNT_STALE,
12079 PCOUNT_VALID,
12080 PCOUNT_ALL,
12081 PCOUNT_COUNTED,
12082 PCOUNT_BPATH_SELECTED,
12083 PCOUNT_PFCNT, /* the figure we display to users */
12084 PCOUNT_MAX,
12085 };
12086
12087 static const char *const pcount_strs[] = {
12088 [PCOUNT_ADJ_IN] = "Adj-in",
12089 [PCOUNT_DAMPED] = "Damped",
12090 [PCOUNT_REMOVED] = "Removed",
12091 [PCOUNT_HISTORY] = "History",
12092 [PCOUNT_STALE] = "Stale",
12093 [PCOUNT_VALID] = "Valid",
12094 [PCOUNT_ALL] = "All RIB",
12095 [PCOUNT_COUNTED] = "PfxCt counted",
12096 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
12097 [PCOUNT_PFCNT] = "Useable",
12098 [PCOUNT_MAX] = NULL,
12099 };
12100
12101 struct peer_pcounts {
12102 unsigned int count[PCOUNT_MAX];
12103 const struct peer *peer;
12104 const struct bgp_table *table;
12105 safi_t safi;
12106 };
12107
12108 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
12109 {
12110 const struct bgp_adj_in *ain;
12111 const struct bgp_path_info *pi;
12112 const struct peer *peer = pc->peer;
12113
12114 for (ain = rn->adj_in; ain; ain = ain->next)
12115 if (ain->peer == peer)
12116 pc->count[PCOUNT_ADJ_IN]++;
12117
12118 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
12119
12120 if (pi->peer != peer)
12121 continue;
12122
12123 pc->count[PCOUNT_ALL]++;
12124
12125 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
12126 pc->count[PCOUNT_DAMPED]++;
12127 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
12128 pc->count[PCOUNT_HISTORY]++;
12129 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
12130 pc->count[PCOUNT_REMOVED]++;
12131 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
12132 pc->count[PCOUNT_STALE]++;
12133 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
12134 pc->count[PCOUNT_VALID]++;
12135 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
12136 pc->count[PCOUNT_PFCNT]++;
12137 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12138 pc->count[PCOUNT_BPATH_SELECTED]++;
12139
12140 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
12141 pc->count[PCOUNT_COUNTED]++;
12142 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
12143 flog_err(
12144 EC_LIB_DEVELOPMENT,
12145 "Attempting to count but flags say it is unusable");
12146 } else {
12147 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
12148 flog_err(
12149 EC_LIB_DEVELOPMENT,
12150 "Not counted but flags say we should");
12151 }
12152 }
12153 }
12154
12155 static int bgp_peer_count_walker(struct thread *t)
12156 {
12157 struct bgp_dest *rn, *rm;
12158 const struct bgp_table *table;
12159 struct peer_pcounts *pc = THREAD_ARG(t);
12160
12161 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
12162 || pc->safi == SAFI_EVPN) {
12163 /* Special handling for 2-level routing tables. */
12164 for (rn = bgp_table_top(pc->table); rn;
12165 rn = bgp_route_next(rn)) {
12166 table = bgp_dest_get_bgp_table_info(rn);
12167 if (table != NULL)
12168 for (rm = bgp_table_top(table); rm;
12169 rm = bgp_route_next(rm))
12170 bgp_peer_count_proc(rm, pc);
12171 }
12172 } else
12173 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
12174 bgp_peer_count_proc(rn, pc);
12175
12176 return 0;
12177 }
12178
12179 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
12180 safi_t safi, bool use_json)
12181 {
12182 struct peer_pcounts pcounts = {.peer = peer};
12183 unsigned int i;
12184 json_object *json = NULL;
12185 json_object *json_loop = NULL;
12186
12187 if (use_json) {
12188 json = json_object_new_object();
12189 json_loop = json_object_new_object();
12190 }
12191
12192 if (!peer || !peer->bgp || !peer->afc[afi][safi]
12193 || !peer->bgp->rib[afi][safi]) {
12194 if (use_json) {
12195 json_object_string_add(
12196 json, "warning",
12197 "No such neighbor or address family");
12198 vty_out(vty, "%s\n", json_object_to_json_string(json));
12199 json_object_free(json);
12200 } else
12201 vty_out(vty, "%% No such neighbor or address family\n");
12202
12203 return CMD_WARNING;
12204 }
12205
12206 memset(&pcounts, 0, sizeof(pcounts));
12207 pcounts.peer = peer;
12208 pcounts.table = peer->bgp->rib[afi][safi];
12209 pcounts.safi = safi;
12210
12211 /* in-place call via thread subsystem so as to record execution time
12212 * stats for the thread-walk (i.e. ensure this can't be blamed on
12213 * on just vty_read()).
12214 */
12215 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
12216
12217 if (use_json) {
12218 json_object_string_add(json, "prefixCountsFor", peer->host);
12219 json_object_string_add(json, "multiProtocol",
12220 get_afi_safi_str(afi, safi, true));
12221 json_object_int_add(json, "pfxCounter",
12222 peer->pcount[afi][safi]);
12223
12224 for (i = 0; i < PCOUNT_MAX; i++)
12225 json_object_int_add(json_loop, pcount_strs[i],
12226 pcounts.count[i]);
12227
12228 json_object_object_add(json, "ribTableWalkCounters", json_loop);
12229
12230 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
12231 json_object_string_add(json, "pfxctDriftFor",
12232 peer->host);
12233 json_object_string_add(
12234 json, "recommended",
12235 "Please report this bug, with the above command output");
12236 }
12237 vty_out(vty, "%s\n", json_object_to_json_string_ext(
12238 json, JSON_C_TO_STRING_PRETTY));
12239 json_object_free(json);
12240 } else {
12241
12242 if (peer->hostname
12243 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
12244 vty_out(vty, "Prefix counts for %s/%s, %s\n",
12245 peer->hostname, peer->host,
12246 get_afi_safi_str(afi, safi, false));
12247 } else {
12248 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
12249 get_afi_safi_str(afi, safi, false));
12250 }
12251
12252 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
12253 vty_out(vty, "\nCounts from RIB table walk:\n\n");
12254
12255 for (i = 0; i < PCOUNT_MAX; i++)
12256 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
12257 pcounts.count[i]);
12258
12259 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
12260 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
12261 vty_out(vty,
12262 "Please report this bug, with the above command output\n");
12263 }
12264 }
12265
12266 return CMD_SUCCESS;
12267 }
12268
12269 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
12270 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
12271 "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]",
12272 SHOW_STR
12273 IP_STR
12274 BGP_STR
12275 BGP_INSTANCE_HELP_STR
12276 BGP_AFI_HELP_STR
12277 BGP_SAFI_HELP_STR
12278 "Detailed information on TCP and BGP neighbor connections\n"
12279 "Neighbor to display information about\n"
12280 "Neighbor to display information about\n"
12281 "Neighbor on BGP configured interface\n"
12282 "Display detailed prefix count information\n"
12283 JSON_STR)
12284 {
12285 afi_t afi = AFI_IP6;
12286 safi_t safi = SAFI_UNICAST;
12287 struct peer *peer;
12288 int idx = 0;
12289 struct bgp *bgp = NULL;
12290 bool uj = use_json(argc, argv);
12291
12292 if (uj)
12293 argc--;
12294
12295 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12296 &bgp, uj);
12297 if (!idx)
12298 return CMD_WARNING;
12299
12300 argv_find(argv, argc, "neighbors", &idx);
12301 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
12302 if (!peer)
12303 return CMD_WARNING;
12304
12305 return bgp_peer_counts(vty, peer, afi, safi, uj);
12306 }
12307
12308 #ifdef KEEP_OLD_VPN_COMMANDS
12309 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
12310 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
12311 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
12312 SHOW_STR
12313 IP_STR
12314 BGP_STR
12315 BGP_VPNVX_HELP_STR
12316 "Display information about all VPNv4 NLRIs\n"
12317 "Detailed information on TCP and BGP neighbor connections\n"
12318 "Neighbor to display information about\n"
12319 "Neighbor to display information about\n"
12320 "Neighbor on BGP configured interface\n"
12321 "Display detailed prefix count information\n"
12322 JSON_STR)
12323 {
12324 int idx_peer = 6;
12325 struct peer *peer;
12326 bool uj = use_json(argc, argv);
12327
12328 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
12329 if (!peer)
12330 return CMD_WARNING;
12331
12332 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
12333 }
12334
12335 DEFUN (show_ip_bgp_vpn_all_route_prefix,
12336 show_ip_bgp_vpn_all_route_prefix_cmd,
12337 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
12338 SHOW_STR
12339 IP_STR
12340 BGP_STR
12341 BGP_VPNVX_HELP_STR
12342 "Display information about all VPNv4 NLRIs\n"
12343 "Network in the BGP routing table to display\n"
12344 "Network in the BGP routing table to display\n"
12345 JSON_STR)
12346 {
12347 int idx = 0;
12348 char *network = NULL;
12349 struct bgp *bgp = bgp_get_default();
12350 if (!bgp) {
12351 vty_out(vty, "Can't find default instance\n");
12352 return CMD_WARNING;
12353 }
12354
12355 if (argv_find(argv, argc, "A.B.C.D", &idx))
12356 network = argv[idx]->arg;
12357 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
12358 network = argv[idx]->arg;
12359 else {
12360 vty_out(vty, "Unable to figure out Network\n");
12361 return CMD_WARNING;
12362 }
12363
12364 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
12365 BGP_PATH_SHOW_ALL, use_json(argc, argv));
12366 }
12367 #endif /* KEEP_OLD_VPN_COMMANDS */
12368
12369 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
12370 show_bgp_l2vpn_evpn_route_prefix_cmd,
12371 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
12372 SHOW_STR
12373 BGP_STR
12374 L2VPN_HELP_STR
12375 EVPN_HELP_STR
12376 "Network in the BGP routing table to display\n"
12377 "Network in the BGP routing table to display\n"
12378 "Network in the BGP routing table to display\n"
12379 "Network in the BGP routing table to display\n"
12380 JSON_STR)
12381 {
12382 int idx = 0;
12383 char *network = NULL;
12384 int prefix_check = 0;
12385
12386 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
12387 argv_find(argv, argc, "X:X::X:X", &idx))
12388 network = argv[idx]->arg;
12389 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
12390 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12391 network = argv[idx]->arg;
12392 prefix_check = 1;
12393 } else {
12394 vty_out(vty, "Unable to figure out Network\n");
12395 return CMD_WARNING;
12396 }
12397 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
12398 prefix_check, BGP_PATH_SHOW_ALL,
12399 use_json(argc, argv));
12400 }
12401
12402 static void show_adj_route_header(struct vty *vty, struct bgp *bgp,
12403 struct bgp_table *table, int *header1,
12404 int *header2, json_object *json,
12405 json_object *json_scode,
12406 json_object *json_ocode, bool wide)
12407 {
12408 uint64_t version = table ? table->version : 0;
12409
12410 if (*header1) {
12411 if (json) {
12412 json_object_int_add(json, "bgpTableVersion", version);
12413 json_object_string_add(json, "bgpLocalRouterId",
12414 inet_ntoa(bgp->router_id));
12415 json_object_int_add(json, "defaultLocPrf",
12416 bgp->default_local_pref);
12417 json_object_int_add(json, "localAS", bgp->as);
12418 json_object_object_add(json, "bgpStatusCodes",
12419 json_scode);
12420 json_object_object_add(json, "bgpOriginCodes",
12421 json_ocode);
12422 } else {
12423 vty_out(vty,
12424 "BGP table version is %" PRIu64 ", local router ID is %s, vrf id ",
12425 version, inet_ntoa(bgp->router_id));
12426 if (bgp->vrf_id == VRF_UNKNOWN)
12427 vty_out(vty, "%s", VRFID_NONE_STR);
12428 else
12429 vty_out(vty, "%u", bgp->vrf_id);
12430 vty_out(vty, "\n");
12431 vty_out(vty, "Default local pref %u, ",
12432 bgp->default_local_pref);
12433 vty_out(vty, "local AS %u\n", bgp->as);
12434 vty_out(vty, BGP_SHOW_SCODE_HEADER);
12435 vty_out(vty, BGP_SHOW_NCODE_HEADER);
12436 vty_out(vty, BGP_SHOW_OCODE_HEADER);
12437 }
12438 *header1 = 0;
12439 }
12440 if (*header2) {
12441 if (!json)
12442 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
12443 : BGP_SHOW_HEADER));
12444 *header2 = 0;
12445 }
12446 }
12447
12448 static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
12449 safi_t safi, enum bgp_show_adj_route_type type,
12450 const char *rmap_name, json_object *json,
12451 uint8_t show_flags)
12452 {
12453 struct bgp_table *table;
12454 struct bgp_adj_in *ain;
12455 struct bgp_adj_out *adj;
12456 unsigned long output_count = 0;
12457 unsigned long filtered_count = 0;
12458 struct bgp_dest *dest;
12459 int header1 = 1;
12460 struct bgp *bgp;
12461 int header2 = 1;
12462 struct attr attr;
12463 int ret;
12464 struct update_subgroup *subgrp;
12465 json_object *json_scode = NULL;
12466 json_object *json_ocode = NULL;
12467 json_object *json_ar = NULL;
12468 struct peer_af *paf;
12469 bool route_filtered;
12470 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12471 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12472
12473 if (use_json) {
12474 json_scode = json_object_new_object();
12475 json_ocode = json_object_new_object();
12476 json_ar = json_object_new_object();
12477
12478 json_object_string_add(json_scode, "suppressed", "s");
12479 json_object_string_add(json_scode, "damped", "d");
12480 json_object_string_add(json_scode, "history", "h");
12481 json_object_string_add(json_scode, "valid", "*");
12482 json_object_string_add(json_scode, "best", ">");
12483 json_object_string_add(json_scode, "multipath", "=");
12484 json_object_string_add(json_scode, "internal", "i");
12485 json_object_string_add(json_scode, "ribFailure", "r");
12486 json_object_string_add(json_scode, "stale", "S");
12487 json_object_string_add(json_scode, "removed", "R");
12488
12489 json_object_string_add(json_ocode, "igp", "i");
12490 json_object_string_add(json_ocode, "egp", "e");
12491 json_object_string_add(json_ocode, "incomplete", "?");
12492 }
12493
12494 bgp = peer->bgp;
12495
12496 if (!bgp) {
12497 if (use_json) {
12498 json_object_string_add(json, "alert", "no BGP");
12499 vty_out(vty, "%s\n", json_object_to_json_string(json));
12500 json_object_free(json);
12501 } else
12502 vty_out(vty, "%% No bgp\n");
12503 return;
12504 }
12505
12506 /* labeled-unicast routes live in the unicast table */
12507 if (safi == SAFI_LABELED_UNICAST)
12508 table = bgp->rib[afi][SAFI_UNICAST];
12509 else
12510 table = bgp->rib[afi][safi];
12511
12512 output_count = filtered_count = 0;
12513 subgrp = peer_subgroup(peer, afi, safi);
12514
12515 if (type == bgp_show_adj_route_advertised && subgrp
12516 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
12517 if (use_json) {
12518 json_object_int_add(json, "bgpTableVersion",
12519 table->version);
12520 json_object_string_add(json, "bgpLocalRouterId",
12521 inet_ntoa(bgp->router_id));
12522 json_object_int_add(json, "defaultLocPrf",
12523 bgp->default_local_pref);
12524 json_object_int_add(json, "localAS", bgp->as);
12525 json_object_object_add(json, "bgpStatusCodes",
12526 json_scode);
12527 json_object_object_add(json, "bgpOriginCodes",
12528 json_ocode);
12529 json_object_string_add(
12530 json, "bgpOriginatingDefaultNetwork",
12531 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
12532 } else {
12533 vty_out(vty, "BGP table version is %" PRIu64", local router ID is %s, vrf id ",
12534 table->version, inet_ntoa(bgp->router_id));
12535 if (bgp->vrf_id == VRF_UNKNOWN)
12536 vty_out(vty, "%s", VRFID_NONE_STR);
12537 else
12538 vty_out(vty, "%u", bgp->vrf_id);
12539 vty_out(vty, "\n");
12540 vty_out(vty, "Default local pref %u, ",
12541 bgp->default_local_pref);
12542 vty_out(vty, "local AS %u\n", bgp->as);
12543 vty_out(vty, BGP_SHOW_SCODE_HEADER);
12544 vty_out(vty, BGP_SHOW_NCODE_HEADER);
12545 vty_out(vty, BGP_SHOW_OCODE_HEADER);
12546
12547 vty_out(vty, "Originating default network %s\n\n",
12548 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
12549 }
12550 header1 = 0;
12551 }
12552
12553 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
12554 if (type == bgp_show_adj_route_received
12555 || type == bgp_show_adj_route_filtered) {
12556 for (ain = dest->adj_in; ain; ain = ain->next) {
12557 if (ain->peer != peer)
12558 continue;
12559
12560 show_adj_route_header(
12561 vty, bgp, table, &header1, &header2,
12562 json, json_scode, json_ocode, wide);
12563
12564 attr = *ain->attr;
12565 route_filtered = false;
12566
12567 /* Filter prefix using distribute list,
12568 * filter list or prefix list
12569 */
12570 const struct prefix *rn_p =
12571 bgp_dest_get_prefix(dest);
12572 if ((bgp_input_filter(peer, rn_p, &attr, afi,
12573 safi))
12574 == FILTER_DENY)
12575 route_filtered = true;
12576
12577 /* Filter prefix using route-map */
12578 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
12579 safi, rmap_name, NULL,
12580 0, NULL);
12581
12582 if (type == bgp_show_adj_route_filtered &&
12583 !route_filtered && ret != RMAP_DENY) {
12584 bgp_attr_undup(&attr, ain->attr);
12585 continue;
12586 }
12587
12588 if (type == bgp_show_adj_route_received &&
12589 (route_filtered || ret == RMAP_DENY))
12590 filtered_count++;
12591
12592 route_vty_out_tmp(vty, rn_p, &attr, safi,
12593 use_json, json_ar, wide);
12594 bgp_attr_undup(&attr, ain->attr);
12595 output_count++;
12596 }
12597 } else if (type == bgp_show_adj_route_advertised) {
12598 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
12599 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
12600 if (paf->peer != peer || !adj->attr)
12601 continue;
12602
12603 show_adj_route_header(
12604 vty, bgp, table, &header1,
12605 &header2, json, json_scode,
12606 json_ocode, wide);
12607
12608 const struct prefix *rn_p =
12609 bgp_dest_get_prefix(dest);
12610
12611 attr = *adj->attr;
12612 ret = bgp_output_modifier(
12613 peer, rn_p, &attr, afi, safi,
12614 rmap_name);
12615
12616 if (ret != RMAP_DENY) {
12617 route_vty_out_tmp(
12618 vty, rn_p, &attr, safi,
12619 use_json, json_ar,
12620 wide);
12621 output_count++;
12622 } else {
12623 filtered_count++;
12624 }
12625
12626 bgp_attr_undup(&attr, adj->attr);
12627 }
12628 } else if (type == bgp_show_adj_route_bestpath) {
12629 struct bgp_path_info *pi;
12630
12631 show_adj_route_header(vty, bgp, table, &header1,
12632 &header2, json, json_scode,
12633 json_ocode, wide);
12634
12635 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
12636 pi = pi->next) {
12637 if (pi->peer != peer)
12638 continue;
12639
12640 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12641 continue;
12642
12643 route_vty_out_tmp(vty,
12644 bgp_dest_get_prefix(dest),
12645 pi->attr, safi, use_json,
12646 json_ar, wide);
12647 output_count++;
12648 }
12649 }
12650 }
12651
12652 if (use_json) {
12653 json_object_object_add(json, "advertisedRoutes", json_ar);
12654 json_object_int_add(json, "totalPrefixCounter", output_count);
12655 json_object_int_add(json, "filteredPrefixCounter",
12656 filtered_count);
12657
12658 vty_out(vty, "%s\n", json_object_to_json_string_ext(
12659 json, JSON_C_TO_STRING_PRETTY));
12660
12661 if (!output_count && !filtered_count) {
12662 json_object_free(json_scode);
12663 json_object_free(json_ocode);
12664 }
12665
12666 json_object_free(json);
12667 } else if (output_count > 0) {
12668 if (filtered_count > 0)
12669 vty_out(vty,
12670 "\nTotal number of prefixes %ld (%ld filtered)\n",
12671 output_count, filtered_count);
12672 else
12673 vty_out(vty, "\nTotal number of prefixes %ld\n",
12674 output_count);
12675 }
12676 }
12677
12678 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
12679 safi_t safi, enum bgp_show_adj_route_type type,
12680 const char *rmap_name, uint8_t show_flags)
12681 {
12682 json_object *json = NULL;
12683 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12684
12685 if (use_json)
12686 json = json_object_new_object();
12687
12688 if (!peer || !peer->afc[afi][safi]) {
12689 if (use_json) {
12690 json_object_string_add(
12691 json, "warning",
12692 "No such neighbor or address family");
12693 vty_out(vty, "%s\n", json_object_to_json_string(json));
12694 json_object_free(json);
12695 } else
12696 vty_out(vty, "%% No such neighbor or address family\n");
12697
12698 return CMD_WARNING;
12699 }
12700
12701 if ((type == bgp_show_adj_route_received
12702 || type == bgp_show_adj_route_filtered)
12703 && !CHECK_FLAG(peer->af_flags[afi][safi],
12704 PEER_FLAG_SOFT_RECONFIG)) {
12705 if (use_json) {
12706 json_object_string_add(
12707 json, "warning",
12708 "Inbound soft reconfiguration not enabled");
12709 vty_out(vty, "%s\n", json_object_to_json_string(json));
12710 json_object_free(json);
12711 } else
12712 vty_out(vty,
12713 "%% Inbound soft reconfiguration not enabled\n");
12714
12715 return CMD_WARNING;
12716 }
12717
12718 show_adj_route(vty, peer, afi, safi, type, rmap_name, json, show_flags);
12719
12720 return CMD_SUCCESS;
12721 }
12722
12723 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
12724 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
12725 "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]",
12726 SHOW_STR
12727 IP_STR
12728 BGP_STR
12729 BGP_INSTANCE_HELP_STR
12730 BGP_AFI_HELP_STR
12731 BGP_SAFI_WITH_LABEL_HELP_STR
12732 "Detailed information on TCP and BGP neighbor connections\n"
12733 "Neighbor to display information about\n"
12734 "Neighbor to display information about\n"
12735 "Neighbor on BGP configured interface\n"
12736 "Display the routes selected by best path\n"
12737 JSON_STR
12738 "Increase table width for longer prefixes\n")
12739 {
12740 afi_t afi = AFI_IP6;
12741 safi_t safi = SAFI_UNICAST;
12742 char *rmap_name = NULL;
12743 char *peerstr = NULL;
12744 struct bgp *bgp = NULL;
12745 struct peer *peer;
12746 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
12747 int idx = 0;
12748 uint8_t show_flags = 0;
12749
12750 if (uj)
12751 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12752
12753 if (wide)
12754 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12755
12756 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12757 &bgp, uj);
12758
12759 if (!idx)
12760 return CMD_WARNING;
12761
12762 argv_find(argv, argc, "neighbors", &idx);
12763 peerstr = argv[++idx]->arg;
12764
12765 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
12766 if (!peer)
12767 return CMD_WARNING;
12768
12769 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
12770 show_flags);
12771 }
12772
12773 DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
12774 show_ip_bgp_instance_neighbor_advertised_route_cmd,
12775 "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]",
12776 SHOW_STR
12777 IP_STR
12778 BGP_STR
12779 BGP_INSTANCE_HELP_STR
12780 BGP_AFI_HELP_STR
12781 BGP_SAFI_WITH_LABEL_HELP_STR
12782 "Display the entries for all address families\n"
12783 "Detailed information on TCP and BGP neighbor connections\n"
12784 "Neighbor to display information about\n"
12785 "Neighbor to display information about\n"
12786 "Neighbor on BGP configured interface\n"
12787 "Display the routes advertised to a BGP neighbor\n"
12788 "Display the received routes from neighbor\n"
12789 "Display the filtered routes received from neighbor\n"
12790 "Route-map to modify the attributes\n"
12791 "Name of the route map\n"
12792 JSON_STR
12793 "Increase table width for longer prefixes\n")
12794 {
12795 afi_t afi = AFI_IP6;
12796 safi_t safi = SAFI_UNICAST;
12797 char *rmap_name = NULL;
12798 char *peerstr = NULL;
12799 struct bgp *bgp = NULL;
12800 struct peer *peer;
12801 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
12802 int idx = 0;
12803 bool first = true;
12804 uint8_t show_flags = 0;
12805
12806 if (uj) {
12807 argc--;
12808 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12809 }
12810
12811 if (all) {
12812 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12813 if (argv_find(argv, argc, "ipv4", &idx))
12814 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12815
12816 if (argv_find(argv, argc, "ipv6", &idx))
12817 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12818 }
12819
12820 if (wide)
12821 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12822
12823 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12824 &bgp, uj);
12825 if (!idx)
12826 return CMD_WARNING;
12827
12828 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
12829 argv_find(argv, argc, "neighbors", &idx);
12830 peerstr = argv[++idx]->arg;
12831
12832 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
12833 if (!peer)
12834 return CMD_WARNING;
12835
12836 if (argv_find(argv, argc, "advertised-routes", &idx))
12837 type = bgp_show_adj_route_advertised;
12838 else if (argv_find(argv, argc, "received-routes", &idx))
12839 type = bgp_show_adj_route_received;
12840 else if (argv_find(argv, argc, "filtered-routes", &idx))
12841 type = bgp_show_adj_route_filtered;
12842
12843 if (argv_find(argv, argc, "route-map", &idx))
12844 rmap_name = argv[++idx]->arg;
12845
12846 if (!all)
12847 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
12848 show_flags);
12849 if (uj)
12850 vty_out(vty, "{\n");
12851
12852 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12853 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12854 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
12855 : AFI_IP6;
12856 FOREACH_SAFI (safi) {
12857 if (strmatch(get_afi_safi_str(afi, safi, true),
12858 "Unknown"))
12859 continue;
12860
12861 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
12862 continue;
12863
12864 if (uj) {
12865 if (first)
12866 first = false;
12867 else
12868 vty_out(vty, ",\n");
12869 vty_out(vty, "\"%s\":",
12870 get_afi_safi_str(afi, safi, true));
12871 } else
12872 vty_out(vty, "\nFor address family: %s\n",
12873 get_afi_safi_str(afi, safi, false));
12874
12875 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
12876 show_flags);
12877 }
12878 } else {
12879 FOREACH_AFI_SAFI (afi, safi) {
12880 if (strmatch(get_afi_safi_str(afi, safi, true),
12881 "Unknown"))
12882 continue;
12883
12884 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
12885 continue;
12886
12887 if (uj) {
12888 if (first)
12889 first = false;
12890 else
12891 vty_out(vty, ",\n");
12892 vty_out(vty, "\"%s\":",
12893 get_afi_safi_str(afi, safi, true));
12894 } else
12895 vty_out(vty, "\nFor address family: %s\n",
12896 get_afi_safi_str(afi, safi, false));
12897
12898 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
12899 show_flags);
12900 }
12901 }
12902 if (uj)
12903 vty_out(vty, "}\n");
12904
12905 return CMD_SUCCESS;
12906 }
12907
12908 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
12909 show_ip_bgp_neighbor_received_prefix_filter_cmd,
12910 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
12911 SHOW_STR
12912 IP_STR
12913 BGP_STR
12914 "Address Family\n"
12915 "Address Family\n"
12916 "Address Family modifier\n"
12917 "Detailed information on TCP and BGP neighbor connections\n"
12918 "Neighbor to display information about\n"
12919 "Neighbor to display information about\n"
12920 "Neighbor on BGP configured interface\n"
12921 "Display information received from a BGP neighbor\n"
12922 "Display the prefixlist filter\n"
12923 JSON_STR)
12924 {
12925 afi_t afi = AFI_IP6;
12926 safi_t safi = SAFI_UNICAST;
12927 char *peerstr = NULL;
12928
12929 char name[BUFSIZ];
12930 union sockunion su;
12931 struct peer *peer;
12932 int count, ret;
12933
12934 int idx = 0;
12935
12936 /* show [ip] bgp */
12937 if (argv_find(argv, argc, "ip", &idx))
12938 afi = AFI_IP;
12939 /* [<ipv4|ipv6> [unicast]] */
12940 if (argv_find(argv, argc, "ipv4", &idx))
12941 afi = AFI_IP;
12942 if (argv_find(argv, argc, "ipv6", &idx))
12943 afi = AFI_IP6;
12944 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
12945 argv_find(argv, argc, "neighbors", &idx);
12946 peerstr = argv[++idx]->arg;
12947
12948 bool uj = use_json(argc, argv);
12949
12950 ret = str2sockunion(peerstr, &su);
12951 if (ret < 0) {
12952 peer = peer_lookup_by_conf_if(NULL, peerstr);
12953 if (!peer) {
12954 if (uj)
12955 vty_out(vty, "{}\n");
12956 else
12957 vty_out(vty,
12958 "%% Malformed address or name: %s\n",
12959 peerstr);
12960 return CMD_WARNING;
12961 }
12962 } else {
12963 peer = peer_lookup(NULL, &su);
12964 if (!peer) {
12965 if (uj)
12966 vty_out(vty, "{}\n");
12967 else
12968 vty_out(vty, "No peer\n");
12969 return CMD_WARNING;
12970 }
12971 }
12972
12973 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
12974 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
12975 if (count) {
12976 if (!uj)
12977 vty_out(vty, "Address Family: %s\n",
12978 get_afi_safi_str(afi, safi, false));
12979 prefix_bgp_show_prefix_list(vty, afi, name, uj);
12980 } else {
12981 if (uj)
12982 vty_out(vty, "{}\n");
12983 else
12984 vty_out(vty, "No functional output\n");
12985 }
12986
12987 return CMD_SUCCESS;
12988 }
12989
12990 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
12991 afi_t afi, safi_t safi,
12992 enum bgp_show_type type, bool use_json)
12993 {
12994 uint8_t show_flags = 0;
12995
12996 if (use_json)
12997 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12998
12999 /* labeled-unicast routes live in the unicast table */
13000 if (safi == SAFI_LABELED_UNICAST)
13001 safi = SAFI_UNICAST;
13002
13003 if (!peer || !peer->afc[afi][safi]) {
13004 if (use_json) {
13005 json_object *json_no = NULL;
13006 json_no = json_object_new_object();
13007 json_object_string_add(
13008 json_no, "warning",
13009 "No such neighbor or address family");
13010 vty_out(vty, "%s\n",
13011 json_object_to_json_string(json_no));
13012 json_object_free(json_no);
13013 } else
13014 vty_out(vty, "%% No such neighbor or address family\n");
13015 return CMD_WARNING;
13016 }
13017
13018 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags);
13019 }
13020
13021 DEFUN (show_ip_bgp_flowspec_routes_detailed,
13022 show_ip_bgp_flowspec_routes_detailed_cmd,
13023 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
13024 SHOW_STR
13025 IP_STR
13026 BGP_STR
13027 BGP_INSTANCE_HELP_STR
13028 BGP_AFI_HELP_STR
13029 "SAFI Flowspec\n"
13030 "Detailed information on flowspec entries\n"
13031 JSON_STR)
13032 {
13033 afi_t afi = AFI_IP;
13034 safi_t safi = SAFI_UNICAST;
13035 struct bgp *bgp = NULL;
13036 int idx = 0;
13037 bool uj = use_json(argc, argv);
13038 uint8_t show_flags = 0;
13039
13040 if (uj) {
13041 argc--;
13042 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13043 }
13044
13045 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13046 &bgp, uj);
13047 if (!idx)
13048 return CMD_WARNING;
13049
13050 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
13051 show_flags);
13052 }
13053
13054 DEFUN (show_ip_bgp_neighbor_routes,
13055 show_ip_bgp_neighbor_routes_cmd,
13056 "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]",
13057 SHOW_STR
13058 IP_STR
13059 BGP_STR
13060 BGP_INSTANCE_HELP_STR
13061 BGP_AFI_HELP_STR
13062 BGP_SAFI_WITH_LABEL_HELP_STR
13063 "Detailed information on TCP and BGP neighbor connections\n"
13064 "Neighbor to display information about\n"
13065 "Neighbor to display information about\n"
13066 "Neighbor on BGP configured interface\n"
13067 "Display flap statistics of the routes learned from neighbor\n"
13068 "Display the dampened routes received from neighbor\n"
13069 "Display routes learned from neighbor\n"
13070 JSON_STR)
13071 {
13072 char *peerstr = NULL;
13073 struct bgp *bgp = NULL;
13074 afi_t afi = AFI_IP6;
13075 safi_t safi = SAFI_UNICAST;
13076 struct peer *peer;
13077 enum bgp_show_type sh_type = bgp_show_type_neighbor;
13078 int idx = 0;
13079 bool uj = use_json(argc, argv);
13080
13081 if (uj)
13082 argc--;
13083
13084 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13085 &bgp, uj);
13086 if (!idx)
13087 return CMD_WARNING;
13088
13089 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
13090 argv_find(argv, argc, "neighbors", &idx);
13091 peerstr = argv[++idx]->arg;
13092
13093 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13094 if (!peer)
13095 return CMD_WARNING;
13096
13097 if (argv_find(argv, argc, "flap-statistics", &idx))
13098 sh_type = bgp_show_type_flap_neighbor;
13099 else if (argv_find(argv, argc, "dampened-routes", &idx))
13100 sh_type = bgp_show_type_damp_neighbor;
13101 else if (argv_find(argv, argc, "routes", &idx))
13102 sh_type = bgp_show_type_neighbor;
13103
13104 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
13105 }
13106
13107 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
13108
13109 struct bgp_distance {
13110 /* Distance value for the IP source prefix. */
13111 uint8_t distance;
13112
13113 /* Name of the access-list to be matched. */
13114 char *access_list;
13115 };
13116
13117 DEFUN (show_bgp_afi_vpn_rd_route,
13118 show_bgp_afi_vpn_rd_route_cmd,
13119 "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]",
13120 SHOW_STR
13121 BGP_STR
13122 BGP_AFI_HELP_STR
13123 "Address Family modifier\n"
13124 "Display information for a route distinguisher\n"
13125 "Route Distinguisher\n"
13126 "Network in the BGP routing table to display\n"
13127 "Network in the BGP routing table to display\n"
13128 JSON_STR)
13129 {
13130 int ret;
13131 struct prefix_rd prd;
13132 afi_t afi = AFI_MAX;
13133 int idx = 0;
13134
13135 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
13136 vty_out(vty, "%% Malformed Address Family\n");
13137 return CMD_WARNING;
13138 }
13139
13140 ret = str2prefix_rd(argv[5]->arg, &prd);
13141 if (!ret) {
13142 vty_out(vty, "%% Malformed Route Distinguisher\n");
13143 return CMD_WARNING;
13144 }
13145
13146 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
13147 0, BGP_PATH_SHOW_ALL, use_json(argc, argv));
13148 }
13149
13150 static struct bgp_distance *bgp_distance_new(void)
13151 {
13152 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
13153 }
13154
13155 static void bgp_distance_free(struct bgp_distance *bdistance)
13156 {
13157 XFREE(MTYPE_BGP_DISTANCE, bdistance);
13158 }
13159
13160 static int bgp_distance_set(struct vty *vty, const char *distance_str,
13161 const char *ip_str, const char *access_list_str)
13162 {
13163 int ret;
13164 afi_t afi;
13165 safi_t safi;
13166 struct prefix p;
13167 uint8_t distance;
13168 struct bgp_dest *dest;
13169 struct bgp_distance *bdistance;
13170
13171 afi = bgp_node_afi(vty);
13172 safi = bgp_node_safi(vty);
13173
13174 ret = str2prefix(ip_str, &p);
13175 if (ret == 0) {
13176 vty_out(vty, "Malformed prefix\n");
13177 return CMD_WARNING_CONFIG_FAILED;
13178 }
13179
13180 distance = atoi(distance_str);
13181
13182 /* Get BGP distance node. */
13183 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
13184 bdistance = bgp_dest_get_bgp_distance_info(dest);
13185 if (bdistance)
13186 bgp_dest_unlock_node(dest);
13187 else {
13188 bdistance = bgp_distance_new();
13189 bgp_dest_set_bgp_distance_info(dest, bdistance);
13190 }
13191
13192 /* Set distance value. */
13193 bdistance->distance = distance;
13194
13195 /* Reset access-list configuration. */
13196 XFREE(MTYPE_AS_LIST, bdistance->access_list);
13197 if (access_list_str)
13198 bdistance->access_list =
13199 XSTRDUP(MTYPE_AS_LIST, access_list_str);
13200
13201 return CMD_SUCCESS;
13202 }
13203
13204 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
13205 const char *ip_str, const char *access_list_str)
13206 {
13207 int ret;
13208 afi_t afi;
13209 safi_t safi;
13210 struct prefix p;
13211 int distance;
13212 struct bgp_dest *dest;
13213 struct bgp_distance *bdistance;
13214
13215 afi = bgp_node_afi(vty);
13216 safi = bgp_node_safi(vty);
13217
13218 ret = str2prefix(ip_str, &p);
13219 if (ret == 0) {
13220 vty_out(vty, "Malformed prefix\n");
13221 return CMD_WARNING_CONFIG_FAILED;
13222 }
13223
13224 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
13225 if (!dest) {
13226 vty_out(vty, "Can't find specified prefix\n");
13227 return CMD_WARNING_CONFIG_FAILED;
13228 }
13229
13230 bdistance = bgp_dest_get_bgp_distance_info(dest);
13231 distance = atoi(distance_str);
13232
13233 if (bdistance->distance != distance) {
13234 vty_out(vty, "Distance does not match configured\n");
13235 return CMD_WARNING_CONFIG_FAILED;
13236 }
13237
13238 XFREE(MTYPE_AS_LIST, bdistance->access_list);
13239 bgp_distance_free(bdistance);
13240
13241 bgp_dest_set_bgp_path_info(dest, NULL);
13242 bgp_dest_unlock_node(dest);
13243 bgp_dest_unlock_node(dest);
13244
13245 return CMD_SUCCESS;
13246 }
13247
13248 /* Apply BGP information to distance method. */
13249 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
13250 afi_t afi, safi_t safi, struct bgp *bgp)
13251 {
13252 struct bgp_dest *dest;
13253 struct prefix q;
13254 struct peer *peer;
13255 struct bgp_distance *bdistance;
13256 struct access_list *alist;
13257 struct bgp_static *bgp_static;
13258
13259 if (!bgp)
13260 return 0;
13261
13262 peer = pinfo->peer;
13263
13264 if (pinfo->attr->distance)
13265 return pinfo->attr->distance;
13266
13267 /* Check source address. */
13268 sockunion2hostprefix(&peer->su, &q);
13269 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
13270 if (dest) {
13271 bdistance = bgp_dest_get_bgp_distance_info(dest);
13272 bgp_dest_unlock_node(dest);
13273
13274 if (bdistance->access_list) {
13275 alist = access_list_lookup(afi, bdistance->access_list);
13276 if (alist
13277 && access_list_apply(alist, p) == FILTER_PERMIT)
13278 return bdistance->distance;
13279 } else
13280 return bdistance->distance;
13281 }
13282
13283 /* Backdoor check. */
13284 dest = bgp_node_lookup(bgp->route[afi][safi], p);
13285 if (dest) {
13286 bgp_static = bgp_dest_get_bgp_static_info(dest);
13287 bgp_dest_unlock_node(dest);
13288
13289 if (bgp_static->backdoor) {
13290 if (bgp->distance_local[afi][safi])
13291 return bgp->distance_local[afi][safi];
13292 else
13293 return ZEBRA_IBGP_DISTANCE_DEFAULT;
13294 }
13295 }
13296
13297 if (peer->sort == BGP_PEER_EBGP) {
13298 if (bgp->distance_ebgp[afi][safi])
13299 return bgp->distance_ebgp[afi][safi];
13300 return ZEBRA_EBGP_DISTANCE_DEFAULT;
13301 } else {
13302 if (bgp->distance_ibgp[afi][safi])
13303 return bgp->distance_ibgp[afi][safi];
13304 return ZEBRA_IBGP_DISTANCE_DEFAULT;
13305 }
13306 }
13307
13308 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
13309 * we should tell ZEBRA update the routes for a specific
13310 * AFI/SAFI to reflect changes in RIB.
13311 */
13312 static void bgp_announce_routes_distance_update(struct bgp *bgp,
13313 afi_t update_afi,
13314 safi_t update_safi)
13315 {
13316 afi_t afi;
13317 safi_t safi;
13318
13319 FOREACH_AFI_SAFI (afi, safi) {
13320 if (!bgp_fibupd_safi(safi))
13321 continue;
13322
13323 if (afi != update_afi && safi != update_safi)
13324 continue;
13325
13326 if (BGP_DEBUG(zebra, ZEBRA))
13327 zlog_debug(
13328 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
13329 __func__, afi, safi);
13330 bgp_zebra_announce_table(bgp, afi, safi);
13331 }
13332 }
13333
13334 DEFUN (bgp_distance,
13335 bgp_distance_cmd,
13336 "distance bgp (1-255) (1-255) (1-255)",
13337 "Define an administrative distance\n"
13338 "BGP distance\n"
13339 "Distance for routes external to the AS\n"
13340 "Distance for routes internal to the AS\n"
13341 "Distance for local routes\n")
13342 {
13343 VTY_DECLVAR_CONTEXT(bgp, bgp);
13344 int idx_number = 2;
13345 int idx_number_2 = 3;
13346 int idx_number_3 = 4;
13347 int distance_ebgp = atoi(argv[idx_number]->arg);
13348 int distance_ibgp = atoi(argv[idx_number_2]->arg);
13349 int distance_local = atoi(argv[idx_number_3]->arg);
13350 afi_t afi;
13351 safi_t safi;
13352
13353 afi = bgp_node_afi(vty);
13354 safi = bgp_node_safi(vty);
13355
13356 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
13357 || bgp->distance_ibgp[afi][safi] != distance_ibgp
13358 || bgp->distance_local[afi][safi] != distance_local) {
13359 bgp->distance_ebgp[afi][safi] = distance_ebgp;
13360 bgp->distance_ibgp[afi][safi] = distance_ibgp;
13361 bgp->distance_local[afi][safi] = distance_local;
13362 bgp_announce_routes_distance_update(bgp, afi, safi);
13363 }
13364 return CMD_SUCCESS;
13365 }
13366
13367 DEFUN (no_bgp_distance,
13368 no_bgp_distance_cmd,
13369 "no distance bgp [(1-255) (1-255) (1-255)]",
13370 NO_STR
13371 "Define an administrative distance\n"
13372 "BGP distance\n"
13373 "Distance for routes external to the AS\n"
13374 "Distance for routes internal to the AS\n"
13375 "Distance for local routes\n")
13376 {
13377 VTY_DECLVAR_CONTEXT(bgp, bgp);
13378 afi_t afi;
13379 safi_t safi;
13380
13381 afi = bgp_node_afi(vty);
13382 safi = bgp_node_safi(vty);
13383
13384 if (bgp->distance_ebgp[afi][safi] != 0
13385 || bgp->distance_ibgp[afi][safi] != 0
13386 || bgp->distance_local[afi][safi] != 0) {
13387 bgp->distance_ebgp[afi][safi] = 0;
13388 bgp->distance_ibgp[afi][safi] = 0;
13389 bgp->distance_local[afi][safi] = 0;
13390 bgp_announce_routes_distance_update(bgp, afi, safi);
13391 }
13392 return CMD_SUCCESS;
13393 }
13394
13395
13396 DEFUN (bgp_distance_source,
13397 bgp_distance_source_cmd,
13398 "distance (1-255) A.B.C.D/M",
13399 "Define an administrative distance\n"
13400 "Administrative distance\n"
13401 "IP source prefix\n")
13402 {
13403 int idx_number = 1;
13404 int idx_ipv4_prefixlen = 2;
13405 bgp_distance_set(vty, argv[idx_number]->arg,
13406 argv[idx_ipv4_prefixlen]->arg, NULL);
13407 return CMD_SUCCESS;
13408 }
13409
13410 DEFUN (no_bgp_distance_source,
13411 no_bgp_distance_source_cmd,
13412 "no distance (1-255) A.B.C.D/M",
13413 NO_STR
13414 "Define an administrative distance\n"
13415 "Administrative distance\n"
13416 "IP source prefix\n")
13417 {
13418 int idx_number = 2;
13419 int idx_ipv4_prefixlen = 3;
13420 bgp_distance_unset(vty, argv[idx_number]->arg,
13421 argv[idx_ipv4_prefixlen]->arg, NULL);
13422 return CMD_SUCCESS;
13423 }
13424
13425 DEFUN (bgp_distance_source_access_list,
13426 bgp_distance_source_access_list_cmd,
13427 "distance (1-255) A.B.C.D/M WORD",
13428 "Define an administrative distance\n"
13429 "Administrative distance\n"
13430 "IP source prefix\n"
13431 "Access list name\n")
13432 {
13433 int idx_number = 1;
13434 int idx_ipv4_prefixlen = 2;
13435 int idx_word = 3;
13436 bgp_distance_set(vty, argv[idx_number]->arg,
13437 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
13438 return CMD_SUCCESS;
13439 }
13440
13441 DEFUN (no_bgp_distance_source_access_list,
13442 no_bgp_distance_source_access_list_cmd,
13443 "no distance (1-255) A.B.C.D/M WORD",
13444 NO_STR
13445 "Define an administrative distance\n"
13446 "Administrative distance\n"
13447 "IP source prefix\n"
13448 "Access list name\n")
13449 {
13450 int idx_number = 2;
13451 int idx_ipv4_prefixlen = 3;
13452 int idx_word = 4;
13453 bgp_distance_unset(vty, argv[idx_number]->arg,
13454 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
13455 return CMD_SUCCESS;
13456 }
13457
13458 DEFUN (ipv6_bgp_distance_source,
13459 ipv6_bgp_distance_source_cmd,
13460 "distance (1-255) X:X::X:X/M",
13461 "Define an administrative distance\n"
13462 "Administrative distance\n"
13463 "IP source prefix\n")
13464 {
13465 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
13466 return CMD_SUCCESS;
13467 }
13468
13469 DEFUN (no_ipv6_bgp_distance_source,
13470 no_ipv6_bgp_distance_source_cmd,
13471 "no distance (1-255) X:X::X:X/M",
13472 NO_STR
13473 "Define an administrative distance\n"
13474 "Administrative distance\n"
13475 "IP source prefix\n")
13476 {
13477 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
13478 return CMD_SUCCESS;
13479 }
13480
13481 DEFUN (ipv6_bgp_distance_source_access_list,
13482 ipv6_bgp_distance_source_access_list_cmd,
13483 "distance (1-255) X:X::X:X/M WORD",
13484 "Define an administrative distance\n"
13485 "Administrative distance\n"
13486 "IP source prefix\n"
13487 "Access list name\n")
13488 {
13489 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
13490 return CMD_SUCCESS;
13491 }
13492
13493 DEFUN (no_ipv6_bgp_distance_source_access_list,
13494 no_ipv6_bgp_distance_source_access_list_cmd,
13495 "no distance (1-255) X:X::X:X/M WORD",
13496 NO_STR
13497 "Define an administrative distance\n"
13498 "Administrative distance\n"
13499 "IP source prefix\n"
13500 "Access list name\n")
13501 {
13502 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
13503 return CMD_SUCCESS;
13504 }
13505
13506 DEFUN (bgp_damp_set,
13507 bgp_damp_set_cmd,
13508 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
13509 "BGP Specific commands\n"
13510 "Enable route-flap dampening\n"
13511 "Half-life time for the penalty\n"
13512 "Value to start reusing a route\n"
13513 "Value to start suppressing a route\n"
13514 "Maximum duration to suppress a stable route\n")
13515 {
13516 VTY_DECLVAR_CONTEXT(bgp, bgp);
13517 int idx_half_life = 2;
13518 int idx_reuse = 3;
13519 int idx_suppress = 4;
13520 int idx_max_suppress = 5;
13521 int half = DEFAULT_HALF_LIFE * 60;
13522 int reuse = DEFAULT_REUSE;
13523 int suppress = DEFAULT_SUPPRESS;
13524 int max = 4 * half;
13525
13526 if (argc == 6) {
13527 half = atoi(argv[idx_half_life]->arg) * 60;
13528 reuse = atoi(argv[idx_reuse]->arg);
13529 suppress = atoi(argv[idx_suppress]->arg);
13530 max = atoi(argv[idx_max_suppress]->arg) * 60;
13531 } else if (argc == 3) {
13532 half = atoi(argv[idx_half_life]->arg) * 60;
13533 max = 4 * half;
13534 }
13535
13536 /*
13537 * These can't be 0 but our SA doesn't understand the
13538 * way our cli is constructed
13539 */
13540 assert(reuse);
13541 assert(half);
13542 if (suppress < reuse) {
13543 vty_out(vty,
13544 "Suppress value cannot be less than reuse value \n");
13545 return 0;
13546 }
13547
13548 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
13549 reuse, suppress, max);
13550 }
13551
13552 DEFUN (bgp_damp_unset,
13553 bgp_damp_unset_cmd,
13554 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
13555 NO_STR
13556 "BGP Specific commands\n"
13557 "Enable route-flap dampening\n"
13558 "Half-life time for the penalty\n"
13559 "Value to start reusing a route\n"
13560 "Value to start suppressing a route\n"
13561 "Maximum duration to suppress a stable route\n")
13562 {
13563 VTY_DECLVAR_CONTEXT(bgp, bgp);
13564 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
13565 }
13566
13567 /* Display specified route of BGP table. */
13568 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
13569 const char *ip_str, afi_t afi, safi_t safi,
13570 struct prefix_rd *prd, int prefix_check)
13571 {
13572 int ret;
13573 struct prefix match;
13574 struct bgp_dest *dest;
13575 struct bgp_dest *rm;
13576 struct bgp_path_info *pi;
13577 struct bgp_path_info *pi_temp;
13578 struct bgp *bgp;
13579 struct bgp_table *table;
13580
13581 /* BGP structure lookup. */
13582 if (view_name) {
13583 bgp = bgp_lookup_by_name(view_name);
13584 if (bgp == NULL) {
13585 vty_out(vty, "%% Can't find BGP instance %s\n",
13586 view_name);
13587 return CMD_WARNING;
13588 }
13589 } else {
13590 bgp = bgp_get_default();
13591 if (bgp == NULL) {
13592 vty_out(vty, "%% No BGP process is configured\n");
13593 return CMD_WARNING;
13594 }
13595 }
13596
13597 /* Check IP address argument. */
13598 ret = str2prefix(ip_str, &match);
13599 if (!ret) {
13600 vty_out(vty, "%% address is malformed\n");
13601 return CMD_WARNING;
13602 }
13603
13604 match.family = afi2family(afi);
13605
13606 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13607 || (safi == SAFI_EVPN)) {
13608 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
13609 dest = bgp_route_next(dest)) {
13610 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
13611
13612 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
13613 continue;
13614 table = bgp_dest_get_bgp_table_info(dest);
13615 if (!table)
13616 continue;
13617 if ((rm = bgp_node_match(table, &match)) == NULL)
13618 continue;
13619
13620 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
13621
13622 if (!prefix_check
13623 || rm_p->prefixlen == match.prefixlen) {
13624 pi = bgp_dest_get_bgp_path_info(rm);
13625 while (pi) {
13626 if (pi->extra && pi->extra->damp_info) {
13627 pi_temp = pi->next;
13628 bgp_damp_info_free(
13629 pi->extra->damp_info,
13630 1, afi, safi);
13631 pi = pi_temp;
13632 } else
13633 pi = pi->next;
13634 }
13635 }
13636
13637 bgp_dest_unlock_node(rm);
13638 }
13639 } else {
13640 if ((dest = bgp_node_match(bgp->rib[afi][safi], &match))
13641 != NULL) {
13642 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
13643
13644 if (!prefix_check
13645 || dest_p->prefixlen == match.prefixlen) {
13646 pi = bgp_dest_get_bgp_path_info(dest);
13647 while (pi) {
13648 if (pi->extra && pi->extra->damp_info) {
13649 pi_temp = pi->next;
13650 bgp_damp_info_free(
13651 pi->extra->damp_info,
13652 1, afi, safi);
13653 pi = pi_temp;
13654 } else
13655 pi = pi->next;
13656 }
13657 }
13658
13659 bgp_dest_unlock_node(dest);
13660 }
13661 }
13662
13663 return CMD_SUCCESS;
13664 }
13665
13666 DEFUN (clear_ip_bgp_dampening,
13667 clear_ip_bgp_dampening_cmd,
13668 "clear ip bgp dampening",
13669 CLEAR_STR
13670 IP_STR
13671 BGP_STR
13672 "Clear route flap dampening information\n")
13673 {
13674 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
13675 return CMD_SUCCESS;
13676 }
13677
13678 DEFUN (clear_ip_bgp_dampening_prefix,
13679 clear_ip_bgp_dampening_prefix_cmd,
13680 "clear ip bgp dampening A.B.C.D/M",
13681 CLEAR_STR
13682 IP_STR
13683 BGP_STR
13684 "Clear route flap dampening information\n"
13685 "IPv4 prefix\n")
13686 {
13687 int idx_ipv4_prefixlen = 4;
13688 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
13689 AFI_IP, SAFI_UNICAST, NULL, 1);
13690 }
13691
13692 DEFUN (clear_ip_bgp_dampening_address,
13693 clear_ip_bgp_dampening_address_cmd,
13694 "clear ip bgp dampening A.B.C.D",
13695 CLEAR_STR
13696 IP_STR
13697 BGP_STR
13698 "Clear route flap dampening information\n"
13699 "Network to clear damping information\n")
13700 {
13701 int idx_ipv4 = 4;
13702 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
13703 SAFI_UNICAST, NULL, 0);
13704 }
13705
13706 DEFUN (clear_ip_bgp_dampening_address_mask,
13707 clear_ip_bgp_dampening_address_mask_cmd,
13708 "clear ip bgp dampening A.B.C.D A.B.C.D",
13709 CLEAR_STR
13710 IP_STR
13711 BGP_STR
13712 "Clear route flap dampening information\n"
13713 "Network to clear damping information\n"
13714 "Network mask\n")
13715 {
13716 int idx_ipv4 = 4;
13717 int idx_ipv4_2 = 5;
13718 int ret;
13719 char prefix_str[BUFSIZ];
13720
13721 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
13722 prefix_str);
13723 if (!ret) {
13724 vty_out(vty, "%% Inconsistent address and mask\n");
13725 return CMD_WARNING;
13726 }
13727
13728 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
13729 NULL, 0);
13730 }
13731
13732 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
13733 {
13734 struct vty *vty = arg;
13735 struct peer *peer = bucket->data;
13736 char buf[SU_ADDRSTRLEN];
13737
13738 vty_out(vty, "\tPeer: %s %s\n", peer->host,
13739 sockunion2str(&peer->su, buf, sizeof(buf)));
13740 }
13741
13742 DEFUN (show_bgp_listeners,
13743 show_bgp_listeners_cmd,
13744 "show bgp listeners",
13745 SHOW_STR
13746 BGP_STR
13747 "Display Listen Sockets and who created them\n")
13748 {
13749 bgp_dump_listener_info(vty);
13750
13751 return CMD_SUCCESS;
13752 }
13753
13754 DEFUN (show_bgp_peerhash,
13755 show_bgp_peerhash_cmd,
13756 "show bgp peerhash",
13757 SHOW_STR
13758 BGP_STR
13759 "Display information about the BGP peerhash\n")
13760 {
13761 struct list *instances = bm->bgp;
13762 struct listnode *node;
13763 struct bgp *bgp;
13764
13765 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
13766 vty_out(vty, "BGP: %s\n", bgp->name);
13767 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
13768 vty);
13769 }
13770
13771 return CMD_SUCCESS;
13772 }
13773
13774 /* also used for encap safi */
13775 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
13776 afi_t afi, safi_t safi)
13777 {
13778 struct bgp_dest *pdest;
13779 struct bgp_dest *dest;
13780 struct bgp_table *table;
13781 const struct prefix *p;
13782 const struct prefix_rd *prd;
13783 struct bgp_static *bgp_static;
13784 mpls_label_t label;
13785 char buf[SU_ADDRSTRLEN];
13786 char rdbuf[RD_ADDRSTRLEN];
13787
13788 /* Network configuration. */
13789 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
13790 pdest = bgp_route_next(pdest)) {
13791 table = bgp_dest_get_bgp_table_info(pdest);
13792 if (!table)
13793 continue;
13794
13795 for (dest = bgp_table_top(table); dest;
13796 dest = bgp_route_next(dest)) {
13797 bgp_static = bgp_dest_get_bgp_static_info(dest);
13798 if (bgp_static == NULL)
13799 continue;
13800
13801 p = bgp_dest_get_prefix(dest);
13802 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
13803 pdest);
13804
13805 /* "network" configuration display. */
13806 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
13807 label = decode_label(&bgp_static->label);
13808
13809 vty_out(vty, " network %s/%d rd %s",
13810 inet_ntop(p->family, &p->u.prefix, buf,
13811 SU_ADDRSTRLEN),
13812 p->prefixlen, rdbuf);
13813 if (safi == SAFI_MPLS_VPN)
13814 vty_out(vty, " label %u", label);
13815
13816 if (bgp_static->rmap.name)
13817 vty_out(vty, " route-map %s",
13818 bgp_static->rmap.name);
13819
13820 if (bgp_static->backdoor)
13821 vty_out(vty, " backdoor");
13822
13823 vty_out(vty, "\n");
13824 }
13825 }
13826 }
13827
13828 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
13829 afi_t afi, safi_t safi)
13830 {
13831 struct bgp_dest *pdest;
13832 struct bgp_dest *dest;
13833 struct bgp_table *table;
13834 const struct prefix *p;
13835 const struct prefix_rd *prd;
13836 struct bgp_static *bgp_static;
13837 char buf[PREFIX_STRLEN * 2];
13838 char buf2[SU_ADDRSTRLEN];
13839 char rdbuf[RD_ADDRSTRLEN];
13840 char esi_buf[ESI_BYTES];
13841
13842 /* Network configuration. */
13843 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
13844 pdest = bgp_route_next(pdest)) {
13845 table = bgp_dest_get_bgp_table_info(pdest);
13846 if (!table)
13847 continue;
13848
13849 for (dest = bgp_table_top(table); dest;
13850 dest = bgp_route_next(dest)) {
13851 bgp_static = bgp_dest_get_bgp_static_info(dest);
13852 if (bgp_static == NULL)
13853 continue;
13854
13855 char *macrouter = NULL;
13856
13857 if (bgp_static->router_mac)
13858 macrouter = prefix_mac2str(
13859 bgp_static->router_mac, NULL, 0);
13860 if (bgp_static->eth_s_id)
13861 esi_to_str(bgp_static->eth_s_id,
13862 esi_buf, sizeof(esi_buf));
13863 p = bgp_dest_get_prefix(dest);
13864 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
13865
13866 /* "network" configuration display. */
13867 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
13868 if (p->u.prefix_evpn.route_type == 5) {
13869 char local_buf[PREFIX_STRLEN];
13870 uint8_t family = is_evpn_prefix_ipaddr_v4((
13871 struct prefix_evpn *)p)
13872 ? AF_INET
13873 : AF_INET6;
13874 inet_ntop(family,
13875 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
13876 local_buf, PREFIX_STRLEN);
13877 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
13878 p->u.prefix_evpn.prefix_addr
13879 .ip_prefix_length);
13880 } else {
13881 prefix2str(p, buf, sizeof(buf));
13882 }
13883
13884 if (bgp_static->gatewayIp.family == AF_INET
13885 || bgp_static->gatewayIp.family == AF_INET6)
13886 inet_ntop(bgp_static->gatewayIp.family,
13887 &bgp_static->gatewayIp.u.prefix, buf2,
13888 sizeof(buf2));
13889 vty_out(vty,
13890 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
13891 buf, rdbuf,
13892 p->u.prefix_evpn.prefix_addr.eth_tag,
13893 decode_label(&bgp_static->label), esi_buf, buf2,
13894 macrouter);
13895
13896 XFREE(MTYPE_TMP, macrouter);
13897 }
13898 }
13899 }
13900
13901 /* Configuration of static route announcement and aggregate
13902 information. */
13903 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
13904 safi_t safi)
13905 {
13906 struct bgp_dest *dest;
13907 const struct prefix *p;
13908 struct bgp_static *bgp_static;
13909 struct bgp_aggregate *bgp_aggregate;
13910 char buf[SU_ADDRSTRLEN];
13911
13912 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
13913 bgp_config_write_network_vpn(vty, bgp, afi, safi);
13914 return;
13915 }
13916
13917 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
13918 bgp_config_write_network_evpn(vty, bgp, afi, safi);
13919 return;
13920 }
13921
13922 /* Network configuration. */
13923 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
13924 dest = bgp_route_next(dest)) {
13925 bgp_static = bgp_dest_get_bgp_static_info(dest);
13926 if (bgp_static == NULL)
13927 continue;
13928
13929 p = bgp_dest_get_prefix(dest);
13930
13931 vty_out(vty, " network %s/%d",
13932 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
13933 p->prefixlen);
13934
13935 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
13936 vty_out(vty, " label-index %u",
13937 bgp_static->label_index);
13938
13939 if (bgp_static->rmap.name)
13940 vty_out(vty, " route-map %s", bgp_static->rmap.name);
13941
13942 if (bgp_static->backdoor)
13943 vty_out(vty, " backdoor");
13944
13945 vty_out(vty, "\n");
13946 }
13947
13948 /* Aggregate-address configuration. */
13949 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
13950 dest = bgp_route_next(dest)) {
13951 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
13952 if (bgp_aggregate == NULL)
13953 continue;
13954
13955 p = bgp_dest_get_prefix(dest);
13956
13957 vty_out(vty, " aggregate-address %s/%d",
13958 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
13959 p->prefixlen);
13960
13961 if (bgp_aggregate->as_set)
13962 vty_out(vty, " as-set");
13963
13964 if (bgp_aggregate->summary_only)
13965 vty_out(vty, " summary-only");
13966
13967 if (bgp_aggregate->rmap.name)
13968 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
13969
13970 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
13971 vty_out(vty, " origin %s",
13972 bgp_origin2str(bgp_aggregate->origin));
13973
13974 if (bgp_aggregate->match_med)
13975 vty_out(vty, " matching-MED-only");
13976
13977 vty_out(vty, "\n");
13978 }
13979 }
13980
13981 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
13982 safi_t safi)
13983 {
13984 struct bgp_dest *dest;
13985 struct bgp_distance *bdistance;
13986
13987 /* Distance configuration. */
13988 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
13989 && bgp->distance_local[afi][safi]
13990 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
13991 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
13992 || bgp->distance_local[afi][safi]
13993 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
13994 vty_out(vty, " distance bgp %d %d %d\n",
13995 bgp->distance_ebgp[afi][safi],
13996 bgp->distance_ibgp[afi][safi],
13997 bgp->distance_local[afi][safi]);
13998 }
13999
14000 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
14001 dest = bgp_route_next(dest)) {
14002 bdistance = bgp_dest_get_bgp_distance_info(dest);
14003 if (bdistance != NULL)
14004 vty_out(vty, " distance %d %pRN %s\n",
14005 bdistance->distance, dest,
14006 bdistance->access_list ? bdistance->access_list
14007 : "");
14008 }
14009 }
14010
14011 /* Allocate routing table structure and install commands. */
14012 void bgp_route_init(void)
14013 {
14014 afi_t afi;
14015 safi_t safi;
14016
14017 /* Init BGP distance table. */
14018 FOREACH_AFI_SAFI (afi, safi)
14019 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
14020
14021 /* IPv4 BGP commands. */
14022 install_element(BGP_NODE, &bgp_table_map_cmd);
14023 install_element(BGP_NODE, &bgp_network_cmd);
14024 install_element(BGP_NODE, &no_bgp_table_map_cmd);
14025
14026 install_element(BGP_NODE, &aggregate_addressv4_cmd);
14027
14028 /* IPv4 unicast configuration. */
14029 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
14030 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
14031 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
14032
14033 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
14034
14035 /* IPv4 multicast configuration. */
14036 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
14037 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
14038 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
14039 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
14040
14041 /* IPv4 labeled-unicast configuration. */
14042 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
14043 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
14044
14045 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
14046 install_element(VIEW_NODE, &show_ip_bgp_cmd);
14047 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
14048 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
14049 install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
14050 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
14051 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
14052 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
14053
14054 install_element(VIEW_NODE,
14055 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
14056 install_element(VIEW_NODE,
14057 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
14058 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
14059 install_element(VIEW_NODE,
14060 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
14061 #ifdef KEEP_OLD_VPN_COMMANDS
14062 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
14063 #endif /* KEEP_OLD_VPN_COMMANDS */
14064 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
14065 install_element(VIEW_NODE,
14066 &show_bgp_l2vpn_evpn_route_prefix_cmd);
14067
14068 /* BGP dampening clear commands */
14069 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
14070 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
14071
14072 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
14073 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
14074
14075 /* prefix count */
14076 install_element(ENABLE_NODE,
14077 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
14078 #ifdef KEEP_OLD_VPN_COMMANDS
14079 install_element(ENABLE_NODE,
14080 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
14081 #endif /* KEEP_OLD_VPN_COMMANDS */
14082
14083 /* New config IPv6 BGP commands. */
14084 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
14085 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
14086 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
14087
14088 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
14089
14090 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
14091
14092 /* IPv6 labeled unicast address family. */
14093 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
14094 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
14095
14096 install_element(BGP_NODE, &bgp_distance_cmd);
14097 install_element(BGP_NODE, &no_bgp_distance_cmd);
14098 install_element(BGP_NODE, &bgp_distance_source_cmd);
14099 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
14100 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
14101 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
14102 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
14103 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
14104 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
14105 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
14106 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
14107 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
14108 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
14109 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
14110 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
14111 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
14112 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
14113 install_element(BGP_IPV4M_NODE,
14114 &no_bgp_distance_source_access_list_cmd);
14115 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
14116 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
14117 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
14118 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
14119 install_element(BGP_IPV6_NODE,
14120 &ipv6_bgp_distance_source_access_list_cmd);
14121 install_element(BGP_IPV6_NODE,
14122 &no_ipv6_bgp_distance_source_access_list_cmd);
14123 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
14124 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
14125 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
14126 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
14127 install_element(BGP_IPV6M_NODE,
14128 &ipv6_bgp_distance_source_access_list_cmd);
14129 install_element(BGP_IPV6M_NODE,
14130 &no_ipv6_bgp_distance_source_access_list_cmd);
14131
14132 /* BGP dampening */
14133 install_element(BGP_NODE, &bgp_damp_set_cmd);
14134 install_element(BGP_NODE, &bgp_damp_unset_cmd);
14135 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
14136 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
14137 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
14138 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
14139 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
14140 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
14141 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
14142 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
14143 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
14144 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
14145 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
14146 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
14147
14148 /* Large Communities */
14149 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
14150 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
14151
14152 /* show bgp ipv4 flowspec detailed */
14153 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
14154
14155 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
14156 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
14157 }
14158
14159 void bgp_route_finish(void)
14160 {
14161 afi_t afi;
14162 safi_t safi;
14163
14164 FOREACH_AFI_SAFI (afi, safi) {
14165 bgp_table_unlock(bgp_distance_table[afi][safi]);
14166 bgp_distance_table[afi][safi] = NULL;
14167 }
14168 }