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