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