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