]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #6962 from mjstapp/fix_zapi_nh_sort
[mirror_frr.git] / bgpd / bgp_route.c
1 /* BGP routing information
2 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 * Copyright (C) 2016 Job Snijders <job@instituut.net>
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <zebra.h>
23 #include <math.h>
24
25 #include "printfrr.h"
26 #include "prefix.h"
27 #include "linklist.h"
28 #include "memory.h"
29 #include "command.h"
30 #include "stream.h"
31 #include "filter.h"
32 #include "log.h"
33 #include "routemap.h"
34 #include "buffer.h"
35 #include "sockunion.h"
36 #include "plist.h"
37 #include "thread.h"
38 #include "workqueue.h"
39 #include "queue.h"
40 #include "memory.h"
41 #include "srv6.h"
42 #include "lib/json.h"
43 #include "lib_errors.h"
44 #include "zclient.h"
45 #include "bgpd/bgpd.h"
46 #include "bgpd/bgp_table.h"
47 #include "bgpd/bgp_route.h"
48 #include "bgpd/bgp_attr.h"
49 #include "bgpd/bgp_debug.h"
50 #include "bgpd/bgp_errors.h"
51 #include "bgpd/bgp_aspath.h"
52 #include "bgpd/bgp_regex.h"
53 #include "bgpd/bgp_community.h"
54 #include "bgpd/bgp_ecommunity.h"
55 #include "bgpd/bgp_lcommunity.h"
56 #include "bgpd/bgp_clist.h"
57 #include "bgpd/bgp_packet.h"
58 #include "bgpd/bgp_filter.h"
59 #include "bgpd/bgp_fsm.h"
60 #include "bgpd/bgp_mplsvpn.h"
61 #include "bgpd/bgp_nexthop.h"
62 #include "bgpd/bgp_damp.h"
63 #include "bgpd/bgp_advertise.h"
64 #include "bgpd/bgp_zebra.h"
65 #include "bgpd/bgp_vty.h"
66 #include "bgpd/bgp_mpath.h"
67 #include "bgpd/bgp_nht.h"
68 #include "bgpd/bgp_updgrp.h"
69 #include "bgpd/bgp_label.h"
70 #include "bgpd/bgp_addpath.h"
71 #include "bgpd/bgp_mac.h"
72 #include "bgpd/bgp_network.h"
73
74 #ifdef ENABLE_BGP_VNC
75 #include "bgpd/rfapi/rfapi_backend.h"
76 #include "bgpd/rfapi/vnc_import_bgp.h"
77 #include "bgpd/rfapi/vnc_export_bgp.h"
78 #endif
79 #include "bgpd/bgp_encap_types.h"
80 #include "bgpd/bgp_encap_tlv.h"
81 #include "bgpd/bgp_evpn.h"
82 #include "bgpd/bgp_evpn_mh.h"
83 #include "bgpd/bgp_evpn_vty.h"
84 #include "bgpd/bgp_flowspec.h"
85 #include "bgpd/bgp_flowspec_util.h"
86 #include "bgpd/bgp_pbr.h"
87
88 #ifndef VTYSH_EXTRACT_PL
89 #include "bgpd/bgp_route_clippy.c"
90 #endif
91
92 /* Extern from bgp_dump.c */
93 extern const char *bgp_origin_str[];
94 extern const char *bgp_origin_long_str[];
95 const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json);
96 /* PMSI strings. */
97 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
98 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
99 static const struct message bgp_pmsi_tnltype_str[] = {
100 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
101 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
102 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
103 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
104 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
105 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
106 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
107 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
108 {0}
109 };
110
111 #define VRFID_NONE_STR "-"
112
113 DEFINE_HOOK(bgp_process,
114 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
115 struct peer *peer, bool withdraw),
116 (bgp, afi, safi, bn, peer, withdraw))
117
118
119 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
120 safi_t safi, const struct prefix *p,
121 struct prefix_rd *prd)
122 {
123 struct bgp_dest *dest;
124 struct bgp_dest *pdest = NULL;
125
126 assert(table);
127
128 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
129 || (safi == SAFI_EVPN)) {
130 pdest = bgp_node_get(table, (struct prefix *)prd);
131
132 if (!bgp_dest_has_bgp_path_info_data(pdest))
133 bgp_dest_set_bgp_table_info(
134 pdest, bgp_table_init(table->bgp, afi, safi));
135 else
136 bgp_dest_unlock_node(pdest);
137 table = bgp_dest_get_bgp_table_info(pdest);
138 }
139
140 dest = bgp_node_get(table, p);
141
142 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
143 || (safi == SAFI_EVPN))
144 dest->pdest = pdest;
145
146 return dest;
147 }
148
149 struct bgp_dest *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
150 safi_t safi, const struct prefix *p,
151 struct prefix_rd *prd)
152 {
153 struct bgp_dest *dest;
154 struct bgp_dest *pdest = NULL;
155
156 if (!table)
157 return NULL;
158
159 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
160 || (safi == SAFI_EVPN)) {
161 pdest = bgp_node_lookup(table, (struct prefix *)prd);
162 if (!pdest)
163 return NULL;
164
165 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
166 bgp_dest_unlock_node(pdest);
167 return NULL;
168 }
169
170 table = bgp_dest_get_bgp_table_info(pdest);
171 }
172
173 dest = bgp_node_lookup(table, p);
174
175 return dest;
176 }
177
178 /* Allocate bgp_path_info_extra */
179 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
180 {
181 struct bgp_path_info_extra *new;
182 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
183 sizeof(struct bgp_path_info_extra));
184 new->label[0] = MPLS_INVALID_LABEL;
185 new->num_labels = 0;
186 new->bgp_fs_pbr = NULL;
187 new->bgp_fs_iprule = NULL;
188 return new;
189 }
190
191 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
192 {
193 struct bgp_path_info_extra *e;
194
195 if (!extra || !*extra)
196 return;
197
198 e = *extra;
199 if (e->damp_info)
200 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
201 e->damp_info->safi);
202
203 e->damp_info = NULL;
204 if (e->parent) {
205 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
206
207 if (bpi->net) {
208 /* FIXME: since multiple e may have the same e->parent
209 * and e->parent->net is holding a refcount for each
210 * of them, we need to do some fudging here.
211 *
212 * WARNING: if bpi->net->lock drops to 0, bpi may be
213 * freed as well (because bpi->net was holding the
214 * last reference to bpi) => write after free!
215 */
216 unsigned refcount;
217
218 bpi = bgp_path_info_lock(bpi);
219 refcount = bpi->net->lock - 1;
220 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
221 if (!refcount)
222 bpi->net = NULL;
223 bgp_path_info_unlock(bpi);
224 }
225 bgp_path_info_unlock(e->parent);
226 e->parent = NULL;
227 }
228
229 if (e->bgp_orig)
230 bgp_unlock(e->bgp_orig);
231
232 if ((*extra)->bgp_fs_iprule)
233 list_delete(&((*extra)->bgp_fs_iprule));
234 if ((*extra)->bgp_fs_pbr)
235 list_delete(&((*extra)->bgp_fs_pbr));
236 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
237 }
238
239 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
240 * allocated if required.
241 */
242 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
243 {
244 if (!pi->extra)
245 pi->extra = bgp_path_info_extra_new();
246 return pi->extra;
247 }
248
249 /* Free bgp route information. */
250 static void bgp_path_info_free(struct bgp_path_info *path)
251 {
252 bgp_attr_unintern(&path->attr);
253
254 bgp_unlink_nexthop(path);
255 bgp_path_info_extra_free(&path->extra);
256 bgp_path_info_mpath_free(&path->mpath);
257 if (path->net)
258 bgp_addpath_free_info_data(&path->tx_addpath,
259 &path->net->tx_addpath);
260
261 peer_unlock(path->peer); /* bgp_path_info peer reference */
262
263 XFREE(MTYPE_BGP_ROUTE, path);
264 }
265
266 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
267 {
268 path->lock++;
269 return path;
270 }
271
272 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
273 {
274 assert(path && path->lock > 0);
275 path->lock--;
276
277 if (path->lock == 0) {
278 #if 0
279 zlog_debug ("%s: unlocked and freeing", __func__);
280 zlog_backtrace (LOG_DEBUG);
281 #endif
282 bgp_path_info_free(path);
283 return NULL;
284 }
285
286 #if 0
287 if (path->lock == 1)
288 {
289 zlog_debug ("%s: unlocked to 1", __func__);
290 zlog_backtrace (LOG_DEBUG);
291 }
292 #endif
293
294 return path;
295 }
296
297 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
298 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
299 {
300 struct peer *peer;
301 struct bgp_path_info *old_pi, *nextpi;
302 bool set_flag = false;
303 struct bgp *bgp = NULL;
304 struct bgp_table *table = NULL;
305 afi_t afi = 0;
306 safi_t safi = 0;
307
308 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
309 * then the route selection is deferred
310 */
311 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
312 return 0;
313
314 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
315 if (BGP_DEBUG(update, UPDATE_OUT))
316 zlog_debug(
317 "Route %pRN is in workqueue and being processed, not deferred.",
318 bgp_dest_to_rnode(dest));
319
320 return 0;
321 }
322
323 table = bgp_dest_table(dest);
324 if (table) {
325 bgp = table->bgp;
326 afi = table->afi;
327 safi = table->safi;
328 }
329
330 for (old_pi = bgp_dest_get_bgp_path_info(dest);
331 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
332 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
333 continue;
334
335 /* Route selection is deferred if there is a stale path which
336 * which indicates peer is in restart mode
337 */
338 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
339 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
340 set_flag = true;
341 } else {
342 /* If the peer is graceful restart capable and peer is
343 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
344 */
345 peer = old_pi->peer;
346 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
347 && BGP_PEER_RESTARTING_MODE(peer)
348 && (old_pi
349 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
350 set_flag = true;
351 }
352 }
353 if (set_flag)
354 break;
355 }
356
357 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
358 * is active
359 */
360 if (set_flag && table) {
361 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
362 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
363 if (dest->rt_node == NULL)
364 dest->rt_node = listnode_add(
365 bgp->gr_info[afi][safi].route_list,
366 dest);
367 if (BGP_DEBUG(update, UPDATE_OUT))
368 zlog_debug("DEFER route %pRN, dest %p, node %p",
369 dest, dest, dest->rt_node);
370 return 0;
371 }
372 }
373 return -1;
374 }
375
376 void bgp_path_info_add(struct bgp_dest *dest, struct bgp_path_info *pi)
377 {
378 struct bgp_path_info *top;
379
380 top = bgp_dest_get_bgp_path_info(dest);
381
382 pi->next = top;
383 pi->prev = NULL;
384 if (top)
385 top->prev = pi;
386 bgp_dest_set_bgp_path_info(dest, pi);
387
388 bgp_path_info_lock(pi);
389 bgp_dest_lock_node(dest);
390 peer_lock(pi->peer); /* bgp_path_info peer reference */
391 bgp_dest_set_defer_flag(dest, false);
392 }
393
394 /* Do the actual removal of info from RIB, for use by bgp_process
395 completion callback *only* */
396 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
397 {
398 if (pi->next)
399 pi->next->prev = pi->prev;
400 if (pi->prev)
401 pi->prev->next = pi->next;
402 else
403 bgp_dest_set_bgp_path_info(dest, pi->next);
404
405 bgp_path_info_mpath_dequeue(pi);
406 bgp_path_info_unlock(pi);
407 bgp_dest_unlock_node(dest);
408 }
409
410 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
411 {
412 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
413 /* set of previous already took care of pcount */
414 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
415 }
416
417 /* undo the effects of a previous call to bgp_path_info_delete; typically
418 called when a route is deleted and then quickly re-added before the
419 deletion has been processed */
420 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
421 {
422 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
423 /* unset of previous already took care of pcount */
424 SET_FLAG(pi->flags, BGP_PATH_VALID);
425 }
426
427 /* Adjust pcount as required */
428 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
429 {
430 struct bgp_table *table;
431
432 assert(dest && bgp_dest_table(dest));
433 assert(pi && pi->peer && pi->peer->bgp);
434
435 table = bgp_dest_table(dest);
436
437 if (pi->peer == pi->peer->bgp->peer_self)
438 return;
439
440 if (!BGP_PATH_COUNTABLE(pi)
441 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
442
443 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
444
445 /* slight hack, but more robust against errors. */
446 if (pi->peer->pcount[table->afi][table->safi])
447 pi->peer->pcount[table->afi][table->safi]--;
448 else
449 flog_err(EC_LIB_DEVELOPMENT,
450 "Asked to decrement 0 prefix count for peer");
451 } else if (BGP_PATH_COUNTABLE(pi)
452 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
453 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
454 pi->peer->pcount[table->afi][table->safi]++;
455 }
456 }
457
458 static int bgp_label_index_differs(struct bgp_path_info *pi1,
459 struct bgp_path_info *pi2)
460 {
461 return (!(pi1->attr->label_index == pi2->attr->label_index));
462 }
463
464 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
465 * This is here primarily to keep prefix-count in check.
466 */
467 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
468 uint32_t flag)
469 {
470 SET_FLAG(pi->flags, flag);
471
472 /* early bath if we know it's not a flag that changes countability state
473 */
474 if (!CHECK_FLAG(flag,
475 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
476 return;
477
478 bgp_pcount_adjust(dest, pi);
479 }
480
481 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
482 uint32_t flag)
483 {
484 UNSET_FLAG(pi->flags, flag);
485
486 /* early bath if we know it's not a flag that changes countability state
487 */
488 if (!CHECK_FLAG(flag,
489 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
490 return;
491
492 bgp_pcount_adjust(dest, pi);
493 }
494
495 /* Get MED value. If MED value is missing and "bgp bestpath
496 missing-as-worst" is specified, treat it as the worst value. */
497 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
498 {
499 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
500 return attr->med;
501 else {
502 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
503 return BGP_MED_MAX;
504 else
505 return 0;
506 }
507 }
508
509 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf)
510 {
511 if (pi->addpath_rx_id)
512 sprintf(buf, "path %s (addpath rxid %d)", pi->peer->host,
513 pi->addpath_rx_id);
514 else
515 sprintf(buf, "path %s", pi->peer->host);
516 }
517
518 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
519 */
520 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
521 struct bgp_path_info *exist, int *paths_eq,
522 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
523 char *pfx_buf, afi_t afi, safi_t safi,
524 enum bgp_path_selection_reason *reason)
525 {
526 struct attr *newattr, *existattr;
527 bgp_peer_sort_t new_sort;
528 bgp_peer_sort_t exist_sort;
529 uint32_t new_pref;
530 uint32_t exist_pref;
531 uint32_t new_med;
532 uint32_t exist_med;
533 uint32_t new_weight;
534 uint32_t exist_weight;
535 uint32_t newm, existm;
536 struct in_addr new_id;
537 struct in_addr exist_id;
538 int new_cluster;
539 int exist_cluster;
540 int internal_as_route;
541 int confed_as_route;
542 int ret = 0;
543 char new_buf[PATH_ADDPATH_STR_BUFFER];
544 char exist_buf[PATH_ADDPATH_STR_BUFFER];
545 uint32_t new_mm_seq;
546 uint32_t exist_mm_seq;
547 int nh_cmp;
548 esi_t *exist_esi;
549 esi_t *new_esi;
550 bool same_esi;
551 bool old_proxy;
552 bool new_proxy;
553
554 *paths_eq = 0;
555
556 /* 0. Null check. */
557 if (new == NULL) {
558 *reason = bgp_path_selection_none;
559 if (debug)
560 zlog_debug("%s: new is NULL", pfx_buf);
561 return 0;
562 }
563
564 if (debug)
565 bgp_path_info_path_with_addpath_rx_str(new, new_buf);
566
567 if (exist == NULL) {
568 *reason = bgp_path_selection_first;
569 if (debug)
570 zlog_debug("%s: %s is the initial bestpath", pfx_buf,
571 new_buf);
572 return 1;
573 }
574
575 if (debug) {
576 bgp_path_info_path_with_addpath_rx_str(exist, exist_buf);
577 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
578 pfx_buf, new_buf, new->flags, exist_buf,
579 exist->flags);
580 }
581
582 newattr = new->attr;
583 existattr = exist->attr;
584
585 /* For EVPN routes, we cannot just go by local vs remote, we have to
586 * look at the MAC mobility sequence number, if present.
587 */
588 if (safi == SAFI_EVPN) {
589 /* This is an error condition described in RFC 7432 Section
590 * 15.2. The RFC
591 * states that in this scenario "the PE MUST alert the operator"
592 * but it
593 * does not state what other action to take. In order to provide
594 * some
595 * consistency in this scenario we are going to prefer the path
596 * with the
597 * sticky flag.
598 */
599 if (newattr->sticky != existattr->sticky) {
600 if (!debug) {
601 prefix2str(
602 bgp_dest_get_prefix(new->net), pfx_buf,
603 sizeof(*pfx_buf) * PREFIX2STR_BUFFER);
604 bgp_path_info_path_with_addpath_rx_str(new,
605 new_buf);
606 bgp_path_info_path_with_addpath_rx_str(
607 exist, exist_buf);
608 }
609
610 if (newattr->sticky && !existattr->sticky) {
611 *reason = bgp_path_selection_evpn_sticky_mac;
612 if (debug)
613 zlog_debug(
614 "%s: %s wins over %s due to sticky MAC flag",
615 pfx_buf, new_buf, exist_buf);
616 return 1;
617 }
618
619 if (!newattr->sticky && existattr->sticky) {
620 *reason = bgp_path_selection_evpn_sticky_mac;
621 if (debug)
622 zlog_debug(
623 "%s: %s loses to %s due to sticky MAC flag",
624 pfx_buf, new_buf, exist_buf);
625 return 0;
626 }
627 }
628
629 new_esi = bgp_evpn_attr_get_esi(newattr);
630 exist_esi = bgp_evpn_attr_get_esi(existattr);
631 if (bgp_evpn_is_esi_valid(new_esi) &&
632 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
633 same_esi = true;
634 } else {
635 same_esi = false;
636 }
637
638 /* If both paths have the same non-zero ES and
639 * one path is local it wins.
640 * PS: Note the local path wins even if the remote
641 * has the higher MM seq. The local path's
642 * MM seq will be fixed up to match the highest
643 * rem seq, subsequently.
644 */
645 if (same_esi) {
646 char esi_buf[ESI_STR_LEN];
647
648 if (bgp_evpn_is_path_local(bgp, new)) {
649 *reason = bgp_path_selection_evpn_local_path;
650 if (debug)
651 zlog_debug(
652 "%s: %s wins over %s as ES %s is same and local",
653 pfx_buf, new_buf, exist_buf,
654 esi_to_str(new_esi, esi_buf,
655 sizeof(esi_buf)));
656 return 1;
657 }
658 if (bgp_evpn_is_path_local(bgp, exist)) {
659 *reason = bgp_path_selection_evpn_local_path;
660 if (debug)
661 zlog_debug(
662 "%s: %s loses to %s as ES %s is same and local",
663 pfx_buf, new_buf, exist_buf,
664 esi_to_str(new_esi, esi_buf,
665 sizeof(esi_buf)));
666 return 0;
667 }
668 }
669
670 new_mm_seq = mac_mobility_seqnum(newattr);
671 exist_mm_seq = mac_mobility_seqnum(existattr);
672
673 if (new_mm_seq > exist_mm_seq) {
674 *reason = bgp_path_selection_evpn_seq;
675 if (debug)
676 zlog_debug(
677 "%s: %s wins over %s due to MM seq %u > %u",
678 pfx_buf, new_buf, exist_buf, new_mm_seq,
679 exist_mm_seq);
680 return 1;
681 }
682
683 if (new_mm_seq < exist_mm_seq) {
684 *reason = bgp_path_selection_evpn_seq;
685 if (debug)
686 zlog_debug(
687 "%s: %s loses to %s due to MM seq %u < %u",
688 pfx_buf, new_buf, exist_buf, new_mm_seq,
689 exist_mm_seq);
690 return 0;
691 }
692
693 /* if the sequence numbers and ESI are the same and one path
694 * is non-proxy it wins (over proxy)
695 */
696 new_proxy = bgp_evpn_attr_is_proxy(newattr);
697 old_proxy = bgp_evpn_attr_is_proxy(existattr);
698 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
699 old_proxy != new_proxy) {
700 if (!new_proxy) {
701 *reason = bgp_path_selection_evpn_non_proxy;
702 if (debug)
703 zlog_debug(
704 "%s: %s wins over %s, same seq/es and non-proxy",
705 pfx_buf, new_buf, exist_buf);
706 return 1;
707 }
708
709 *reason = bgp_path_selection_evpn_non_proxy;
710 if (debug)
711 zlog_debug(
712 "%s: %s loses to %s, same seq/es and non-proxy",
713 pfx_buf, new_buf, exist_buf);
714 return 0;
715 }
716
717 /*
718 * if sequence numbers are the same path with the lowest IP
719 * wins
720 */
721 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
722 if (nh_cmp < 0) {
723 *reason = bgp_path_selection_evpn_lower_ip;
724 if (debug)
725 zlog_debug(
726 "%s: %s wins over %s due to same MM seq %u and lower IP %s",
727 pfx_buf, new_buf, exist_buf, new_mm_seq,
728 inet_ntoa(new->attr->nexthop));
729 return 1;
730 }
731 if (nh_cmp > 0) {
732 *reason = bgp_path_selection_evpn_lower_ip;
733 if (debug)
734 zlog_debug(
735 "%s: %s loses to %s due to same MM seq %u and higher IP %s",
736 pfx_buf, new_buf, exist_buf, new_mm_seq,
737 inet_ntoa(new->attr->nexthop));
738 return 0;
739 }
740 }
741
742 /* 1. Weight check. */
743 new_weight = newattr->weight;
744 exist_weight = existattr->weight;
745
746 if (new_weight > exist_weight) {
747 *reason = bgp_path_selection_weight;
748 if (debug)
749 zlog_debug("%s: %s wins over %s due to weight %d > %d",
750 pfx_buf, new_buf, exist_buf, new_weight,
751 exist_weight);
752 return 1;
753 }
754
755 if (new_weight < exist_weight) {
756 *reason = bgp_path_selection_weight;
757 if (debug)
758 zlog_debug("%s: %s loses to %s due to weight %d < %d",
759 pfx_buf, new_buf, exist_buf, new_weight,
760 exist_weight);
761 return 0;
762 }
763
764 /* 2. Local preference check. */
765 new_pref = exist_pref = bgp->default_local_pref;
766
767 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
768 new_pref = newattr->local_pref;
769 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
770 exist_pref = existattr->local_pref;
771
772 if (new_pref > exist_pref) {
773 *reason = bgp_path_selection_local_pref;
774 if (debug)
775 zlog_debug(
776 "%s: %s wins over %s due to localpref %d > %d",
777 pfx_buf, new_buf, exist_buf, new_pref,
778 exist_pref);
779 return 1;
780 }
781
782 if (new_pref < exist_pref) {
783 *reason = bgp_path_selection_local_pref;
784 if (debug)
785 zlog_debug(
786 "%s: %s loses to %s due to localpref %d < %d",
787 pfx_buf, new_buf, exist_buf, new_pref,
788 exist_pref);
789 return 0;
790 }
791
792 /* 3. Local route check. We prefer:
793 * - BGP_ROUTE_STATIC
794 * - BGP_ROUTE_AGGREGATE
795 * - BGP_ROUTE_REDISTRIBUTE
796 */
797 if (!(new->sub_type == BGP_ROUTE_NORMAL ||
798 new->sub_type == BGP_ROUTE_IMPORTED)) {
799 *reason = bgp_path_selection_local_route;
800 if (debug)
801 zlog_debug(
802 "%s: %s wins over %s due to preferred BGP_ROUTE type",
803 pfx_buf, new_buf, exist_buf);
804 return 1;
805 }
806
807 if (!(exist->sub_type == BGP_ROUTE_NORMAL ||
808 exist->sub_type == BGP_ROUTE_IMPORTED)) {
809 *reason = bgp_path_selection_local_route;
810 if (debug)
811 zlog_debug(
812 "%s: %s loses to %s due to preferred BGP_ROUTE type",
813 pfx_buf, new_buf, exist_buf);
814 return 0;
815 }
816
817 /* 4. AS path length check. */
818 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
819 int exist_hops = aspath_count_hops(existattr->aspath);
820 int exist_confeds = aspath_count_confeds(existattr->aspath);
821
822 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
823 int aspath_hops;
824
825 aspath_hops = aspath_count_hops(newattr->aspath);
826 aspath_hops += aspath_count_confeds(newattr->aspath);
827
828 if (aspath_hops < (exist_hops + exist_confeds)) {
829 *reason = bgp_path_selection_confed_as_path;
830 if (debug)
831 zlog_debug(
832 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
833 pfx_buf, new_buf, exist_buf,
834 aspath_hops,
835 (exist_hops + exist_confeds));
836 return 1;
837 }
838
839 if (aspath_hops > (exist_hops + exist_confeds)) {
840 *reason = bgp_path_selection_confed_as_path;
841 if (debug)
842 zlog_debug(
843 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
844 pfx_buf, new_buf, exist_buf,
845 aspath_hops,
846 (exist_hops + exist_confeds));
847 return 0;
848 }
849 } else {
850 int newhops = aspath_count_hops(newattr->aspath);
851
852 if (newhops < exist_hops) {
853 *reason = bgp_path_selection_as_path;
854 if (debug)
855 zlog_debug(
856 "%s: %s wins over %s due to aspath hopcount %d < %d",
857 pfx_buf, new_buf, exist_buf,
858 newhops, exist_hops);
859 return 1;
860 }
861
862 if (newhops > exist_hops) {
863 *reason = bgp_path_selection_as_path;
864 if (debug)
865 zlog_debug(
866 "%s: %s loses to %s due to aspath hopcount %d > %d",
867 pfx_buf, new_buf, exist_buf,
868 newhops, exist_hops);
869 return 0;
870 }
871 }
872 }
873
874 /* 5. Origin check. */
875 if (newattr->origin < existattr->origin) {
876 *reason = bgp_path_selection_origin;
877 if (debug)
878 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
879 pfx_buf, new_buf, exist_buf,
880 bgp_origin_long_str[newattr->origin],
881 bgp_origin_long_str[existattr->origin]);
882 return 1;
883 }
884
885 if (newattr->origin > existattr->origin) {
886 *reason = bgp_path_selection_origin;
887 if (debug)
888 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
889 pfx_buf, new_buf, exist_buf,
890 bgp_origin_long_str[newattr->origin],
891 bgp_origin_long_str[existattr->origin]);
892 return 0;
893 }
894
895 /* 6. MED check. */
896 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
897 && aspath_count_hops(existattr->aspath) == 0);
898 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
899 && aspath_count_confeds(existattr->aspath) > 0
900 && aspath_count_hops(newattr->aspath) == 0
901 && aspath_count_hops(existattr->aspath) == 0);
902
903 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
904 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
905 || aspath_cmp_left(newattr->aspath, existattr->aspath)
906 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
907 || internal_as_route) {
908 new_med = bgp_med_value(new->attr, bgp);
909 exist_med = bgp_med_value(exist->attr, bgp);
910
911 if (new_med < exist_med) {
912 *reason = bgp_path_selection_med;
913 if (debug)
914 zlog_debug(
915 "%s: %s wins over %s due to MED %d < %d",
916 pfx_buf, new_buf, exist_buf, new_med,
917 exist_med);
918 return 1;
919 }
920
921 if (new_med > exist_med) {
922 *reason = bgp_path_selection_med;
923 if (debug)
924 zlog_debug(
925 "%s: %s loses to %s due to MED %d > %d",
926 pfx_buf, new_buf, exist_buf, new_med,
927 exist_med);
928 return 0;
929 }
930 }
931
932 /* 7. Peer type check. */
933 new_sort = new->peer->sort;
934 exist_sort = exist->peer->sort;
935
936 if (new_sort == BGP_PEER_EBGP
937 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
938 *reason = bgp_path_selection_peer;
939 if (debug)
940 zlog_debug(
941 "%s: %s wins over %s due to eBGP peer > iBGP peer",
942 pfx_buf, new_buf, exist_buf);
943 return 1;
944 }
945
946 if (exist_sort == BGP_PEER_EBGP
947 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
948 *reason = bgp_path_selection_peer;
949 if (debug)
950 zlog_debug(
951 "%s: %s loses to %s due to iBGP peer < eBGP peer",
952 pfx_buf, new_buf, exist_buf);
953 return 0;
954 }
955
956 /* 8. IGP metric check. */
957 newm = existm = 0;
958
959 if (new->extra)
960 newm = new->extra->igpmetric;
961 if (exist->extra)
962 existm = exist->extra->igpmetric;
963
964 if (newm < existm) {
965 if (debug)
966 zlog_debug(
967 "%s: %s wins over %s due to IGP metric %d < %d",
968 pfx_buf, new_buf, exist_buf, newm, existm);
969 ret = 1;
970 }
971
972 if (newm > existm) {
973 if (debug)
974 zlog_debug(
975 "%s: %s loses to %s due to IGP metric %d > %d",
976 pfx_buf, new_buf, exist_buf, newm, existm);
977 ret = 0;
978 }
979
980 /* 9. Same IGP metric. Compare the cluster list length as
981 representative of IGP hops metric. Rewrite the metric value
982 pair (newm, existm) with the cluster list length. Prefer the
983 path with smaller cluster list length. */
984 if (newm == existm) {
985 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP
986 && peer_sort_lookup(exist->peer) == BGP_PEER_IBGP
987 && (mpath_cfg == NULL
988 || CHECK_FLAG(
989 mpath_cfg->ibgp_flags,
990 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN))) {
991 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
992 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
993
994 if (newm < existm) {
995 if (debug)
996 zlog_debug(
997 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
998 pfx_buf, new_buf, exist_buf,
999 newm, existm);
1000 ret = 1;
1001 }
1002
1003 if (newm > existm) {
1004 if (debug)
1005 zlog_debug(
1006 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1007 pfx_buf, new_buf, exist_buf,
1008 newm, existm);
1009 ret = 0;
1010 }
1011 }
1012 }
1013
1014 /* 10. confed-external vs. confed-internal */
1015 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1016 if (new_sort == BGP_PEER_CONFED
1017 && exist_sort == BGP_PEER_IBGP) {
1018 *reason = bgp_path_selection_confed;
1019 if (debug)
1020 zlog_debug(
1021 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1022 pfx_buf, new_buf, exist_buf);
1023 return 1;
1024 }
1025
1026 if (exist_sort == BGP_PEER_CONFED
1027 && new_sort == BGP_PEER_IBGP) {
1028 *reason = bgp_path_selection_confed;
1029 if (debug)
1030 zlog_debug(
1031 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1032 pfx_buf, new_buf, exist_buf);
1033 return 0;
1034 }
1035 }
1036
1037 /* 11. Maximum path check. */
1038 if (newm == existm) {
1039 /* If one path has a label but the other does not, do not treat
1040 * them as equals for multipath
1041 */
1042 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1043 != (exist->extra
1044 && bgp_is_valid_label(&exist->extra->label[0]))) {
1045 if (debug)
1046 zlog_debug(
1047 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1048 pfx_buf, new_buf, exist_buf);
1049 } else if (CHECK_FLAG(bgp->flags,
1050 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1051
1052 /*
1053 * For the two paths, all comparison steps till IGP
1054 * metric
1055 * have succeeded - including AS_PATH hop count. Since
1056 * 'bgp
1057 * bestpath as-path multipath-relax' knob is on, we
1058 * don't need
1059 * an exact match of AS_PATH. Thus, mark the paths are
1060 * equal.
1061 * That will trigger both these paths to get into the
1062 * multipath
1063 * array.
1064 */
1065 *paths_eq = 1;
1066
1067 if (debug)
1068 zlog_debug(
1069 "%s: %s and %s are equal via multipath-relax",
1070 pfx_buf, new_buf, exist_buf);
1071 } else if (new->peer->sort == BGP_PEER_IBGP) {
1072 if (aspath_cmp(new->attr->aspath,
1073 exist->attr->aspath)) {
1074 *paths_eq = 1;
1075
1076 if (debug)
1077 zlog_debug(
1078 "%s: %s and %s are equal via matching aspaths",
1079 pfx_buf, new_buf, exist_buf);
1080 }
1081 } else if (new->peer->as == exist->peer->as) {
1082 *paths_eq = 1;
1083
1084 if (debug)
1085 zlog_debug(
1086 "%s: %s and %s are equal via same remote-as",
1087 pfx_buf, new_buf, exist_buf);
1088 }
1089 } else {
1090 /*
1091 * TODO: If unequal cost ibgp multipath is enabled we can
1092 * mark the paths as equal here instead of returning
1093 */
1094 if (debug) {
1095 if (ret == 1)
1096 zlog_debug(
1097 "%s: %s wins over %s after IGP metric comparison",
1098 pfx_buf, new_buf, exist_buf);
1099 else
1100 zlog_debug(
1101 "%s: %s loses to %s after IGP metric comparison",
1102 pfx_buf, new_buf, exist_buf);
1103 }
1104 *reason = bgp_path_selection_igp_metric;
1105 return ret;
1106 }
1107
1108 /* 12. If both paths are external, prefer the path that was received
1109 first (the oldest one). This step minimizes route-flap, since a
1110 newer path won't displace an older one, even if it was the
1111 preferred route based on the additional decision criteria below. */
1112 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1113 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1114 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1115 *reason = bgp_path_selection_older;
1116 if (debug)
1117 zlog_debug(
1118 "%s: %s wins over %s due to oldest external",
1119 pfx_buf, new_buf, exist_buf);
1120 return 1;
1121 }
1122
1123 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1124 *reason = bgp_path_selection_older;
1125 if (debug)
1126 zlog_debug(
1127 "%s: %s loses to %s due to oldest external",
1128 pfx_buf, new_buf, exist_buf);
1129 return 0;
1130 }
1131 }
1132
1133 /* 13. Router-ID comparision. */
1134 /* If one of the paths is "stale", the corresponding peer router-id will
1135 * be 0 and would always win over the other path. If originator id is
1136 * used for the comparision, it will decide which path is better.
1137 */
1138 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1139 new_id.s_addr = newattr->originator_id.s_addr;
1140 else
1141 new_id.s_addr = new->peer->remote_id.s_addr;
1142 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1143 exist_id.s_addr = existattr->originator_id.s_addr;
1144 else
1145 exist_id.s_addr = exist->peer->remote_id.s_addr;
1146
1147 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1148 *reason = bgp_path_selection_router_id;
1149 if (debug)
1150 zlog_debug(
1151 "%s: %s wins over %s due to Router-ID comparison",
1152 pfx_buf, new_buf, exist_buf);
1153 return 1;
1154 }
1155
1156 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1157 *reason = bgp_path_selection_router_id;
1158 if (debug)
1159 zlog_debug(
1160 "%s: %s loses to %s due to Router-ID comparison",
1161 pfx_buf, new_buf, exist_buf);
1162 return 0;
1163 }
1164
1165 /* 14. Cluster length comparision. */
1166 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1167 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1168
1169 if (new_cluster < exist_cluster) {
1170 *reason = bgp_path_selection_cluster_length;
1171 if (debug)
1172 zlog_debug(
1173 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1174 pfx_buf, new_buf, exist_buf, new_cluster,
1175 exist_cluster);
1176 return 1;
1177 }
1178
1179 if (new_cluster > exist_cluster) {
1180 *reason = bgp_path_selection_cluster_length;
1181 if (debug)
1182 zlog_debug(
1183 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1184 pfx_buf, new_buf, exist_buf, new_cluster,
1185 exist_cluster);
1186 return 0;
1187 }
1188
1189 /* 15. Neighbor address comparision. */
1190 /* Do this only if neither path is "stale" as stale paths do not have
1191 * valid peer information (as the connection may or may not be up).
1192 */
1193 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1194 *reason = bgp_path_selection_stale;
1195 if (debug)
1196 zlog_debug(
1197 "%s: %s wins over %s due to latter path being STALE",
1198 pfx_buf, new_buf, exist_buf);
1199 return 1;
1200 }
1201
1202 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1203 *reason = bgp_path_selection_stale;
1204 if (debug)
1205 zlog_debug(
1206 "%s: %s loses to %s due to former path being STALE",
1207 pfx_buf, new_buf, exist_buf);
1208 return 0;
1209 }
1210
1211 /* locally configured routes to advertise do not have su_remote */
1212 if (new->peer->su_remote == NULL) {
1213 *reason = bgp_path_selection_local_configured;
1214 return 0;
1215 }
1216 if (exist->peer->su_remote == NULL) {
1217 *reason = bgp_path_selection_local_configured;
1218 return 1;
1219 }
1220
1221 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1222
1223 if (ret == 1) {
1224 *reason = bgp_path_selection_neighbor_ip;
1225 if (debug)
1226 zlog_debug(
1227 "%s: %s loses to %s due to Neighor IP comparison",
1228 pfx_buf, new_buf, exist_buf);
1229 return 0;
1230 }
1231
1232 if (ret == -1) {
1233 *reason = bgp_path_selection_neighbor_ip;
1234 if (debug)
1235 zlog_debug(
1236 "%s: %s wins over %s due to Neighor IP comparison",
1237 pfx_buf, new_buf, exist_buf);
1238 return 1;
1239 }
1240
1241 *reason = bgp_path_selection_default;
1242 if (debug)
1243 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1244 pfx_buf, new_buf, exist_buf);
1245
1246 return 1;
1247 }
1248
1249
1250 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1251 struct bgp_path_info *exist, int *paths_eq)
1252 {
1253 enum bgp_path_selection_reason reason;
1254 char pfx_buf[PREFIX2STR_BUFFER];
1255
1256 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1257 AFI_L2VPN, SAFI_EVPN, &reason);
1258 }
1259
1260 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1261 * is preferred, or 0 if they are the same (usually will only occur if
1262 * multipath is enabled
1263 * This version is compatible with */
1264 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1265 struct bgp_path_info *exist, char *pfx_buf,
1266 afi_t afi, safi_t safi,
1267 enum bgp_path_selection_reason *reason)
1268 {
1269 int paths_eq;
1270 int ret;
1271 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1272 afi, safi, reason);
1273
1274 if (paths_eq)
1275 ret = 0;
1276 else {
1277 if (ret == 1)
1278 ret = -1;
1279 else
1280 ret = 1;
1281 }
1282 return ret;
1283 }
1284
1285 static enum filter_type bgp_input_filter(struct peer *peer,
1286 const struct prefix *p,
1287 struct attr *attr, afi_t afi,
1288 safi_t safi)
1289 {
1290 struct bgp_filter *filter;
1291
1292 filter = &peer->filter[afi][safi];
1293
1294 #define FILTER_EXIST_WARN(F, f, filter) \
1295 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1296 zlog_debug("%s: Could not find configured input %s-list %s!", \
1297 peer->host, #f, F##_IN_NAME(filter));
1298
1299 if (DISTRIBUTE_IN_NAME(filter)) {
1300 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1301
1302 if (access_list_apply(DISTRIBUTE_IN(filter), p) == FILTER_DENY)
1303 return FILTER_DENY;
1304 }
1305
1306 if (PREFIX_LIST_IN_NAME(filter)) {
1307 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1308
1309 if (prefix_list_apply(PREFIX_LIST_IN(filter), p) == PREFIX_DENY)
1310 return FILTER_DENY;
1311 }
1312
1313 if (FILTER_LIST_IN_NAME(filter)) {
1314 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1315
1316 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1317 == AS_FILTER_DENY)
1318 return FILTER_DENY;
1319 }
1320
1321 return FILTER_PERMIT;
1322 #undef FILTER_EXIST_WARN
1323 }
1324
1325 static enum filter_type bgp_output_filter(struct peer *peer,
1326 const struct prefix *p,
1327 struct attr *attr, afi_t afi,
1328 safi_t safi)
1329 {
1330 struct bgp_filter *filter;
1331
1332 filter = &peer->filter[afi][safi];
1333
1334 #define FILTER_EXIST_WARN(F, f, filter) \
1335 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1336 zlog_debug("%s: Could not find configured output %s-list %s!", \
1337 peer->host, #f, F##_OUT_NAME(filter));
1338
1339 if (DISTRIBUTE_OUT_NAME(filter)) {
1340 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1341
1342 if (access_list_apply(DISTRIBUTE_OUT(filter), p) == FILTER_DENY)
1343 return FILTER_DENY;
1344 }
1345
1346 if (PREFIX_LIST_OUT_NAME(filter)) {
1347 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1348
1349 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1350 == PREFIX_DENY)
1351 return FILTER_DENY;
1352 }
1353
1354 if (FILTER_LIST_OUT_NAME(filter)) {
1355 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1356
1357 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1358 == AS_FILTER_DENY)
1359 return FILTER_DENY;
1360 }
1361
1362 return FILTER_PERMIT;
1363 #undef FILTER_EXIST_WARN
1364 }
1365
1366 /* If community attribute includes no_export then return 1. */
1367 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1368 {
1369 if (attr->community) {
1370 /* NO_ADVERTISE check. */
1371 if (community_include(attr->community, COMMUNITY_NO_ADVERTISE))
1372 return true;
1373
1374 /* NO_EXPORT check. */
1375 if (peer->sort == BGP_PEER_EBGP
1376 && community_include(attr->community, COMMUNITY_NO_EXPORT))
1377 return true;
1378
1379 /* NO_EXPORT_SUBCONFED check. */
1380 if (peer->sort == BGP_PEER_EBGP
1381 || peer->sort == BGP_PEER_CONFED)
1382 if (community_include(attr->community,
1383 COMMUNITY_NO_EXPORT_SUBCONFED))
1384 return true;
1385 }
1386 return false;
1387 }
1388
1389 /* Route reflection loop check. */
1390 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1391 {
1392 struct in_addr cluster_id;
1393
1394 if (attr->cluster) {
1395 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1396 cluster_id = peer->bgp->cluster_id;
1397 else
1398 cluster_id = peer->bgp->router_id;
1399
1400 if (cluster_loop_check(attr->cluster, cluster_id))
1401 return true;
1402 }
1403 return false;
1404 }
1405
1406 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1407 struct attr *attr, afi_t afi, safi_t safi,
1408 const char *rmap_name, mpls_label_t *label,
1409 uint32_t num_labels, struct bgp_dest *dest)
1410 {
1411 struct bgp_filter *filter;
1412 struct bgp_path_info rmap_path = { 0 };
1413 struct bgp_path_info_extra extra = { 0 };
1414 route_map_result_t ret;
1415 struct route_map *rmap = NULL;
1416
1417 filter = &peer->filter[afi][safi];
1418
1419 /* Apply default weight value. */
1420 if (peer->weight[afi][safi])
1421 attr->weight = peer->weight[afi][safi];
1422
1423 if (rmap_name) {
1424 rmap = route_map_lookup_by_name(rmap_name);
1425
1426 if (rmap == NULL)
1427 return RMAP_DENY;
1428 } else {
1429 if (ROUTE_MAP_IN_NAME(filter)) {
1430 rmap = ROUTE_MAP_IN(filter);
1431
1432 if (rmap == NULL)
1433 return RMAP_DENY;
1434 }
1435 }
1436
1437 /* Route map apply. */
1438 if (rmap) {
1439 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1440 /* Duplicate current value to new strucutre for modification. */
1441 rmap_path.peer = peer;
1442 rmap_path.attr = attr;
1443 rmap_path.extra = &extra;
1444 rmap_path.net = dest;
1445
1446 extra.num_labels = num_labels;
1447 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1448 memcpy(extra.label, label,
1449 num_labels * sizeof(mpls_label_t));
1450
1451 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1452
1453 /* Apply BGP route map to the attribute. */
1454 ret = route_map_apply(rmap, p, RMAP_BGP, &rmap_path);
1455
1456 peer->rmap_type = 0;
1457
1458 if (ret == RMAP_DENYMATCH)
1459 return RMAP_DENY;
1460 }
1461 return RMAP_PERMIT;
1462 }
1463
1464 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1465 struct attr *attr, afi_t afi, safi_t safi,
1466 const char *rmap_name)
1467 {
1468 struct bgp_path_info rmap_path;
1469 route_map_result_t ret;
1470 struct route_map *rmap = NULL;
1471 uint8_t rmap_type;
1472
1473 /*
1474 * So if we get to this point and have no rmap_name
1475 * we want to just show the output as it currently
1476 * exists.
1477 */
1478 if (!rmap_name)
1479 return RMAP_PERMIT;
1480
1481 /* Apply default weight value. */
1482 if (peer->weight[afi][safi])
1483 attr->weight = peer->weight[afi][safi];
1484
1485 rmap = route_map_lookup_by_name(rmap_name);
1486
1487 /*
1488 * If we have a route map name and we do not find
1489 * the routemap that means we have an implicit
1490 * deny.
1491 */
1492 if (rmap == NULL)
1493 return RMAP_DENY;
1494
1495 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1496 /* Route map apply. */
1497 /* Duplicate current value to new strucutre for modification. */
1498 rmap_path.peer = peer;
1499 rmap_path.attr = attr;
1500
1501 rmap_type = peer->rmap_type;
1502 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1503
1504 /* Apply BGP route map to the attribute. */
1505 ret = route_map_apply(rmap, p, RMAP_BGP, &rmap_path);
1506
1507 peer->rmap_type = rmap_type;
1508
1509 if (ret == RMAP_DENYMATCH)
1510 /*
1511 * caller has multiple error paths with bgp_attr_flush()
1512 */
1513 return RMAP_DENY;
1514
1515 return RMAP_PERMIT;
1516 }
1517
1518 /* If this is an EBGP peer with remove-private-AS */
1519 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1520 struct peer *peer, struct attr *attr)
1521 {
1522 if (peer->sort == BGP_PEER_EBGP
1523 && (peer_af_flag_check(peer, afi, safi,
1524 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1525 || peer_af_flag_check(peer, afi, safi,
1526 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1527 || peer_af_flag_check(peer, afi, safi,
1528 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1529 || peer_af_flag_check(peer, afi, safi,
1530 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1531 // Take action on the entire aspath
1532 if (peer_af_flag_check(peer, afi, safi,
1533 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1534 || peer_af_flag_check(peer, afi, safi,
1535 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1536 if (peer_af_flag_check(
1537 peer, afi, safi,
1538 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1539 attr->aspath = aspath_replace_private_asns(
1540 attr->aspath, bgp->as, peer->as);
1541
1542 // The entire aspath consists of private ASNs so create
1543 // an empty aspath
1544 else if (aspath_private_as_check(attr->aspath))
1545 attr->aspath = aspath_empty_get();
1546
1547 // There are some public and some private ASNs, remove
1548 // the private ASNs
1549 else
1550 attr->aspath = aspath_remove_private_asns(
1551 attr->aspath, peer->as);
1552 }
1553
1554 // 'all' was not specified so the entire aspath must be private
1555 // ASNs
1556 // for us to do anything
1557 else if (aspath_private_as_check(attr->aspath)) {
1558 if (peer_af_flag_check(
1559 peer, afi, safi,
1560 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1561 attr->aspath = aspath_replace_private_asns(
1562 attr->aspath, bgp->as, peer->as);
1563 else
1564 attr->aspath = aspath_empty_get();
1565 }
1566 }
1567 }
1568
1569 /* If this is an EBGP peer with as-override */
1570 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1571 struct peer *peer, struct attr *attr)
1572 {
1573 if (peer->sort == BGP_PEER_EBGP
1574 && peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1575 if (aspath_single_asn_check(attr->aspath, peer->as))
1576 attr->aspath = aspath_replace_specific_asn(
1577 attr->aspath, peer->as, bgp->as);
1578 }
1579 }
1580
1581 void bgp_attr_add_gshut_community(struct attr *attr)
1582 {
1583 struct community *old;
1584 struct community *new;
1585 struct community *merge;
1586 struct community *gshut;
1587
1588 old = attr->community;
1589 gshut = community_str2com("graceful-shutdown");
1590
1591 assert(gshut);
1592
1593 if (old) {
1594 merge = community_merge(community_dup(old), gshut);
1595
1596 if (old->refcnt == 0)
1597 community_free(&old);
1598
1599 new = community_uniq_sort(merge);
1600 community_free(&merge);
1601 } else {
1602 new = community_dup(gshut);
1603 }
1604
1605 community_free(&gshut);
1606 attr->community = new;
1607 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
1608
1609 /* When we add the graceful-shutdown community we must also
1610 * lower the local-preference */
1611 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1612 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1613 }
1614
1615
1616 static void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1617 {
1618 if (family == AF_INET) {
1619 attr->nexthop.s_addr = INADDR_ANY;
1620 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1621 }
1622 if (family == AF_INET6)
1623 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1624 if (family == AF_EVPN)
1625 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1626 }
1627
1628 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1629 struct update_subgroup *subgrp,
1630 const struct prefix *p, struct attr *attr)
1631 {
1632 struct bgp_filter *filter;
1633 struct peer *from;
1634 struct peer *peer;
1635 struct peer *onlypeer;
1636 struct bgp *bgp;
1637 struct attr *piattr;
1638 char buf[PREFIX_STRLEN];
1639 route_map_result_t ret;
1640 int transparent;
1641 int reflect;
1642 afi_t afi;
1643 safi_t safi;
1644 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1645 bool nh_reset = false;
1646 uint64_t cum_bw;
1647
1648 if (DISABLE_BGP_ANNOUNCE)
1649 return false;
1650
1651 afi = SUBGRP_AFI(subgrp);
1652 safi = SUBGRP_SAFI(subgrp);
1653 peer = SUBGRP_PEER(subgrp);
1654 onlypeer = NULL;
1655 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1656 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1657
1658 from = pi->peer;
1659 filter = &peer->filter[afi][safi];
1660 bgp = SUBGRP_INST(subgrp);
1661 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
1662 : pi->attr;
1663
1664 #ifdef ENABLE_BGP_VNC
1665 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
1666 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
1667 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
1668
1669 /*
1670 * direct and direct_ext type routes originate internally even
1671 * though they can have peer pointers that reference other
1672 * systems
1673 */
1674 prefix2str(p, buf, PREFIX_STRLEN);
1675 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe",
1676 __func__, buf);
1677 samepeer_safe = 1;
1678 }
1679 #endif
1680
1681 if (((afi == AFI_IP) || (afi == AFI_IP6))
1682 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
1683 && (pi->type == ZEBRA_ROUTE_BGP)
1684 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
1685
1686 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1687
1688 samepeer_safe = 1;
1689 }
1690
1691 /* With addpath we may be asked to TX all kinds of paths so make sure
1692 * pi is valid */
1693 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
1694 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
1695 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
1696 return false;
1697 }
1698
1699 /* If this is not the bestpath then check to see if there is an enabled
1700 * addpath
1701 * feature that requires us to advertise it */
1702 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
1703 if (!bgp_addpath_tx_path(peer->addpath_type[afi][safi], pi)) {
1704 return false;
1705 }
1706 }
1707
1708 /* Aggregate-address suppress check. */
1709 if (pi->extra && pi->extra->suppress)
1710 if (!UNSUPPRESS_MAP_NAME(filter)) {
1711 return false;
1712 }
1713
1714 /*
1715 * If we are doing VRF 2 VRF leaking via the import
1716 * statement, we want to prevent the route going
1717 * off box as that the RT and RD created are localy
1718 * significant and globaly useless.
1719 */
1720 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
1721 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
1722 return false;
1723
1724 /* If it's labeled safi, make sure the route has a valid label. */
1725 if (safi == SAFI_LABELED_UNICAST) {
1726 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
1727 if (!bgp_is_valid_label(&label)) {
1728 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1729 zlog_debug("u%" PRIu64 ":s%" PRIu64" %s/%d is filtered - no label (%p)",
1730 subgrp->update_group->id, subgrp->id,
1731 inet_ntop(p->family, &p->u.prefix,
1732 buf, SU_ADDRSTRLEN),
1733 p->prefixlen, &label);
1734 return false;
1735 }
1736 }
1737
1738 /* Do not send back route to sender. */
1739 if (onlypeer && from == onlypeer) {
1740 return false;
1741 }
1742
1743 /* Do not send the default route in the BGP table if the neighbor is
1744 * configured for default-originate */
1745 if (CHECK_FLAG(peer->af_flags[afi][safi],
1746 PEER_FLAG_DEFAULT_ORIGINATE)) {
1747 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
1748 return false;
1749 else if (p->family == AF_INET6 && p->prefixlen == 0)
1750 return false;
1751 }
1752
1753 /* Transparency check. */
1754 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
1755 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1756 transparent = 1;
1757 else
1758 transparent = 0;
1759
1760 /* If community is not disabled check the no-export and local. */
1761 if (!transparent && bgp_community_filter(peer, piattr)) {
1762 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1763 zlog_debug(
1764 "subgrpannouncecheck: community filter check fail");
1765 return false;
1766 }
1767
1768 /* If the attribute has originator-id and it is same as remote
1769 peer's id. */
1770 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
1771 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
1772 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1773 zlog_debug(
1774 "%s [Update:SEND] %s originator-id is same as remote router-id",
1775 onlypeer->host,
1776 prefix2str(p, buf, sizeof(buf)));
1777 return false;
1778 }
1779
1780 /* ORF prefix-list filter check */
1781 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
1782 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
1783 || CHECK_FLAG(peer->af_cap[afi][safi],
1784 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
1785 if (peer->orf_plist[afi][safi]) {
1786 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
1787 == PREFIX_DENY) {
1788 if (bgp_debug_update(NULL, p,
1789 subgrp->update_group, 0))
1790 zlog_debug(
1791 "%s [Update:SEND] %s is filtered via ORF",
1792 peer->host,
1793 prefix2str(p, buf,
1794 sizeof(buf)));
1795 return false;
1796 }
1797 }
1798
1799 /* Output filter check. */
1800 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
1801 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1802 zlog_debug("%s [Update:SEND] %s is filtered",
1803 peer->host, prefix2str(p, buf, sizeof(buf)));
1804 return false;
1805 }
1806
1807 /* AS path loop check. */
1808 if (onlypeer && onlypeer->as_path_loop_detection
1809 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
1810 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1811 zlog_debug(
1812 "%s [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
1813 onlypeer->host, onlypeer->as);
1814 return false;
1815 }
1816
1817 /* If we're a CONFED we need to loop check the CONFED ID too */
1818 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1819 if (aspath_loop_check(piattr->aspath, bgp->confed_id)) {
1820 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1821 zlog_debug(
1822 "%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
1823 peer->host, bgp->confed_id);
1824 return false;
1825 }
1826 }
1827
1828 /* Route-Reflect check. */
1829 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
1830 reflect = 1;
1831 else
1832 reflect = 0;
1833
1834 /* IBGP reflection check. */
1835 if (reflect && !samepeer_safe) {
1836 /* A route from a Client peer. */
1837 if (CHECK_FLAG(from->af_flags[afi][safi],
1838 PEER_FLAG_REFLECTOR_CLIENT)) {
1839 /* Reflect to all the Non-Client peers and also to the
1840 Client peers other than the originator. Originator
1841 check
1842 is already done. So there is noting to do. */
1843 /* no bgp client-to-client reflection check. */
1844 if (CHECK_FLAG(bgp->flags,
1845 BGP_FLAG_NO_CLIENT_TO_CLIENT))
1846 if (CHECK_FLAG(peer->af_flags[afi][safi],
1847 PEER_FLAG_REFLECTOR_CLIENT))
1848 return false;
1849 } else {
1850 /* A route from a Non-client peer. Reflect to all other
1851 clients. */
1852 if (!CHECK_FLAG(peer->af_flags[afi][safi],
1853 PEER_FLAG_REFLECTOR_CLIENT))
1854 return false;
1855 }
1856 }
1857
1858 /* For modify attribute, copy it to temporary structure. */
1859 *attr = *piattr;
1860
1861 /* If local-preference is not set. */
1862 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
1863 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
1864 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1865 attr->local_pref = bgp->default_local_pref;
1866 }
1867
1868 /* If originator-id is not set and the route is to be reflected,
1869 set the originator id */
1870 if (reflect
1871 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
1872 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
1873 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
1874 }
1875
1876 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
1877 */
1878 if (peer->sort == BGP_PEER_EBGP
1879 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
1880 if (from != bgp->peer_self && !transparent
1881 && !CHECK_FLAG(peer->af_flags[afi][safi],
1882 PEER_FLAG_MED_UNCHANGED))
1883 attr->flag &=
1884 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
1885 }
1886
1887 /* Since the nexthop attribute can vary per peer, it is not explicitly
1888 * set
1889 * in announce check, only certain flags and length (or number of
1890 * nexthops
1891 * -- for IPv6/MP_REACH) are set here in order to guide the update
1892 * formation
1893 * code in setting the nexthop(s) on a per peer basis in
1894 * reformat_peer().
1895 * Typically, the source nexthop in the attribute is preserved but in
1896 * the
1897 * scenarios where we know it will always be overwritten, we reset the
1898 * nexthop to "0" in an attempt to achieve better Update packing. An
1899 * example of this is when a prefix from each of 2 IBGP peers needs to
1900 * be
1901 * announced to an EBGP peer (and they have the same attributes barring
1902 * their nexthop).
1903 */
1904 if (reflect)
1905 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
1906
1907 #define NEXTHOP_IS_V6 \
1908 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
1909 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
1910 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
1911 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1912
1913 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
1914 * if
1915 * the peer (group) is configured to receive link-local nexthop
1916 * unchanged
1917 * and it is available in the prefix OR we're not reflecting the route,
1918 * link-local nexthop address is valid and
1919 * the peer (group) to whom we're going to announce is on a shared
1920 * network
1921 * and this is either a self-originated route or the peer is EBGP.
1922 * By checking if nexthop LL address is valid we are sure that
1923 * we do not announce LL address as `::`.
1924 */
1925 if (NEXTHOP_IS_V6) {
1926 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
1927 if ((CHECK_FLAG(peer->af_flags[afi][safi],
1928 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
1929 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
1930 || (!reflect
1931 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
1932 && peer->shared_network
1933 && (from == bgp->peer_self
1934 || peer->sort == BGP_PEER_EBGP))) {
1935 attr->mp_nexthop_len =
1936 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
1937 }
1938
1939 /* Clear off link-local nexthop in source, whenever it is not
1940 * needed to
1941 * ensure more prefixes share the same attribute for
1942 * announcement.
1943 */
1944 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
1945 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
1946 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
1947 }
1948
1949 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
1950 bgp_peer_as_override(bgp, afi, safi, peer, attr);
1951
1952 /* Route map & unsuppress-map apply. */
1953 if (ROUTE_MAP_OUT_NAME(filter) || (pi->extra && pi->extra->suppress)) {
1954 struct bgp_path_info rmap_path = {0};
1955 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
1956 struct attr dummy_attr = {0};
1957
1958 /* Fill temp path_info */
1959 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
1960 pi, peer, attr);
1961
1962 /* don't confuse inbound and outbound setting */
1963 RESET_FLAG(attr->rmap_change_flags);
1964
1965 /*
1966 * The route reflector is not allowed to modify the attributes
1967 * of the reflected IBGP routes unless explicitly allowed.
1968 */
1969 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
1970 && !CHECK_FLAG(bgp->flags,
1971 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
1972 dummy_attr = *attr;
1973 rmap_path.attr = &dummy_attr;
1974 }
1975
1976 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1977
1978 if (pi->extra && pi->extra->suppress)
1979 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
1980 RMAP_BGP, &rmap_path);
1981 else
1982 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
1983 RMAP_BGP, &rmap_path);
1984
1985 peer->rmap_type = 0;
1986
1987 if (ret == RMAP_DENYMATCH) {
1988 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1989 zlog_debug("%s [Update:SEND] %s is filtered by route-map",
1990 peer->host, prefix2str(p, buf, sizeof(buf)));
1991
1992 bgp_attr_flush(attr);
1993 return false;
1994 }
1995 }
1996
1997 /* RFC 8212 to prevent route leaks.
1998 * This specification intends to improve this situation by requiring the
1999 * explicit configuration of both BGP Import and Export Policies for any
2000 * External BGP (EBGP) session such as customers, peers, or
2001 * confederation boundaries for all enabled address families. Through
2002 * codification of the aforementioned requirement, operators will
2003 * benefit from consistent behavior across different BGP
2004 * implementations.
2005 */
2006 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2007 if (!bgp_outbound_policy_exists(peer, filter))
2008 return false;
2009
2010 /* draft-ietf-idr-deprecate-as-set-confed-set
2011 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2012 * Eventually, This document (if approved) updates RFC 4271
2013 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2014 * and obsoletes RFC 6472.
2015 */
2016 if (peer->bgp->reject_as_sets)
2017 if (aspath_check_as_sets(attr->aspath))
2018 return false;
2019
2020 /* Codification of AS 0 Processing */
2021 if (aspath_check_as_zero(attr->aspath))
2022 return false;
2023
2024 if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
2025 if (peer->sort == BGP_PEER_IBGP
2026 || peer->sort == BGP_PEER_CONFED) {
2027 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2028 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2029 } else {
2030 bgp_attr_add_gshut_community(attr);
2031 }
2032 }
2033
2034 /* After route-map has been applied, we check to see if the nexthop to
2035 * be carried in the attribute (that is used for the announcement) can
2036 * be cleared off or not. We do this in all cases where we would be
2037 * setting the nexthop to "ourselves". For IPv6, we only need to
2038 * consider
2039 * the global nexthop here; the link-local nexthop would have been
2040 * cleared
2041 * already, and if not, it is required by the update formation code.
2042 * Also see earlier comments in this function.
2043 */
2044 /*
2045 * If route-map has performed some operation on the nexthop or the peer
2046 * configuration says to pass it unchanged, we cannot reset the nexthop
2047 * here, so only attempt to do it if these aren't true. Note that the
2048 * route-map handler itself might have cleared the nexthop, if for
2049 * example,
2050 * it is configured as 'peer-address'.
2051 */
2052 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2053 piattr->rmap_change_flags)
2054 && !transparent
2055 && !CHECK_FLAG(peer->af_flags[afi][safi],
2056 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2057 /* We can reset the nexthop, if setting (or forcing) it to
2058 * 'self' */
2059 if (CHECK_FLAG(peer->af_flags[afi][safi],
2060 PEER_FLAG_NEXTHOP_SELF)
2061 || CHECK_FLAG(peer->af_flags[afi][safi],
2062 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2063 if (!reflect
2064 || CHECK_FLAG(peer->af_flags[afi][safi],
2065 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2066 subgroup_announce_reset_nhop(
2067 (peer_cap_enhe(peer, afi, safi)
2068 ? AF_INET6
2069 : p->family),
2070 attr);
2071 nh_reset = true;
2072 }
2073 } else if (peer->sort == BGP_PEER_EBGP) {
2074 /* Can also reset the nexthop if announcing to EBGP, but
2075 * only if
2076 * no peer in the subgroup is on a shared subnet.
2077 * Note: 3rd party nexthop currently implemented for
2078 * IPv4 only.
2079 */
2080 if ((p->family == AF_INET) &&
2081 (!bgp_subgrp_multiaccess_check_v4(
2082 piattr->nexthop,
2083 subgrp, from))) {
2084 subgroup_announce_reset_nhop(
2085 (peer_cap_enhe(peer, afi, safi)
2086 ? AF_INET6
2087 : p->family),
2088 attr);
2089 nh_reset = true;
2090 }
2091
2092 if ((p->family == AF_INET6) &&
2093 (!bgp_subgrp_multiaccess_check_v6(
2094 piattr->mp_nexthop_global,
2095 subgrp, from))) {
2096 subgroup_announce_reset_nhop(
2097 (peer_cap_enhe(peer, afi, safi)
2098 ? AF_INET6
2099 : p->family),
2100 attr);
2101 nh_reset = true;
2102 }
2103
2104
2105
2106 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2107 /*
2108 * This flag is used for leaked vpn-vrf routes
2109 */
2110 int family = p->family;
2111
2112 if (peer_cap_enhe(peer, afi, safi))
2113 family = AF_INET6;
2114
2115 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2116 zlog_debug(
2117 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
2118 __func__, family2str(family));
2119 subgroup_announce_reset_nhop(family, attr);
2120 nh_reset = true;
2121 }
2122 }
2123
2124 /* If IPv6/MP and nexthop does not have any override and happens
2125 * to
2126 * be a link-local address, reset it so that we don't pass along
2127 * the
2128 * source's link-local IPv6 address to recipients who may not be
2129 * on
2130 * the same interface.
2131 */
2132 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2133 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2134 subgroup_announce_reset_nhop(AF_INET6, attr);
2135 nh_reset = true;
2136 }
2137 }
2138
2139 /*
2140 * When the next hop is set to ourselves, if all multipaths have
2141 * link-bandwidth announce the cumulative bandwidth as that makes
2142 * the most sense. However, don't modify if the link-bandwidth has
2143 * been explicitly set by user policy.
2144 */
2145 if (nh_reset &&
2146 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2147 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2148 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2149 attr->ecommunity = ecommunity_replace_linkbw(
2150 bgp->as, attr->ecommunity, cum_bw);
2151
2152 return true;
2153 }
2154
2155 static int bgp_route_select_timer_expire(struct thread *thread)
2156 {
2157 struct afi_safi_info *info;
2158 afi_t afi;
2159 safi_t safi;
2160 struct bgp *bgp;
2161
2162 info = THREAD_ARG(thread);
2163 afi = info->afi;
2164 safi = info->safi;
2165 bgp = info->bgp;
2166
2167 if (BGP_DEBUG(update, UPDATE_OUT))
2168 zlog_debug("afi %d, safi %d : route select timer expired", afi,
2169 safi);
2170
2171 bgp->gr_info[afi][safi].t_route_select = NULL;
2172
2173 XFREE(MTYPE_TMP, info);
2174
2175 /* Best path selection */
2176 return bgp_best_path_select_defer(bgp, afi, safi);
2177 }
2178
2179 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2180 struct bgp_maxpaths_cfg *mpath_cfg,
2181 struct bgp_path_info_pair *result, afi_t afi,
2182 safi_t safi)
2183 {
2184 struct bgp_path_info *new_select;
2185 struct bgp_path_info *old_select;
2186 struct bgp_path_info *pi;
2187 struct bgp_path_info *pi1;
2188 struct bgp_path_info *pi2;
2189 struct bgp_path_info *nextpi = NULL;
2190 int paths_eq, do_mpath, debug;
2191 struct list mp_list;
2192 char pfx_buf[PREFIX2STR_BUFFER];
2193 char path_buf[PATH_ADDPATH_STR_BUFFER];
2194
2195 bgp_mp_list_init(&mp_list);
2196 do_mpath =
2197 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2198
2199 debug = bgp_debug_bestpath(dest);
2200
2201 if (debug)
2202 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2203
2204 dest->reason = bgp_path_selection_none;
2205 /* bgp deterministic-med */
2206 new_select = NULL;
2207 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2208
2209 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2210 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2211 pi1 = pi1->next)
2212 bgp_path_info_unset_flag(dest, pi1,
2213 BGP_PATH_DMED_SELECTED);
2214
2215 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2216 pi1 = pi1->next) {
2217 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2218 continue;
2219 if (BGP_PATH_HOLDDOWN(pi1))
2220 continue;
2221 if (pi1->peer != bgp->peer_self)
2222 if (pi1->peer->status != Established)
2223 continue;
2224
2225 new_select = pi1;
2226 if (pi1->next) {
2227 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2228 if (CHECK_FLAG(pi2->flags,
2229 BGP_PATH_DMED_CHECK))
2230 continue;
2231 if (BGP_PATH_HOLDDOWN(pi2))
2232 continue;
2233 if (pi2->peer != bgp->peer_self
2234 && !CHECK_FLAG(
2235 pi2->peer->sflags,
2236 PEER_STATUS_NSF_WAIT))
2237 if (pi2->peer->status
2238 != Established)
2239 continue;
2240
2241 if (!aspath_cmp_left(pi1->attr->aspath,
2242 pi2->attr->aspath)
2243 && !aspath_cmp_left_confed(
2244 pi1->attr->aspath,
2245 pi2->attr->aspath))
2246 continue;
2247
2248 if (bgp_path_info_cmp(
2249 bgp, pi2, new_select,
2250 &paths_eq, mpath_cfg, debug,
2251 pfx_buf, afi, safi,
2252 &dest->reason)) {
2253 bgp_path_info_unset_flag(
2254 dest, new_select,
2255 BGP_PATH_DMED_SELECTED);
2256 new_select = pi2;
2257 }
2258
2259 bgp_path_info_set_flag(
2260 dest, pi2, BGP_PATH_DMED_CHECK);
2261 }
2262 }
2263 bgp_path_info_set_flag(dest, new_select,
2264 BGP_PATH_DMED_CHECK);
2265 bgp_path_info_set_flag(dest, new_select,
2266 BGP_PATH_DMED_SELECTED);
2267
2268 if (debug) {
2269 bgp_path_info_path_with_addpath_rx_str(
2270 new_select, path_buf);
2271 zlog_debug("%s: %s is the bestpath from AS %u",
2272 pfx_buf, path_buf,
2273 aspath_get_first_as(
2274 new_select->attr->aspath));
2275 }
2276 }
2277 }
2278
2279 /* Check old selected route and new selected route. */
2280 old_select = NULL;
2281 new_select = NULL;
2282 for (pi = bgp_dest_get_bgp_path_info(dest);
2283 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2284 enum bgp_path_selection_reason reason;
2285
2286 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2287 old_select = pi;
2288
2289 if (BGP_PATH_HOLDDOWN(pi)) {
2290 /* reap REMOVED routes, if needs be
2291 * selected route must stay for a while longer though
2292 */
2293 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2294 && (pi != old_select))
2295 bgp_path_info_reap(dest, pi);
2296
2297 if (debug)
2298 zlog_debug("%s: pi %p in holddown", __func__,
2299 pi);
2300
2301 continue;
2302 }
2303
2304 if (pi->peer && pi->peer != bgp->peer_self
2305 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2306 if (pi->peer->status != Established) {
2307
2308 if (debug)
2309 zlog_debug(
2310 "%s: pi %p non self peer %s not estab state",
2311 __func__, pi, pi->peer->host);
2312
2313 continue;
2314 }
2315
2316 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2317 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2318 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2319 if (debug)
2320 zlog_debug("%s: pi %p dmed", __func__, pi);
2321 continue;
2322 }
2323
2324 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2325
2326 reason = dest->reason;
2327 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2328 debug, pfx_buf, afi, safi,
2329 &dest->reason)) {
2330 if (new_select == NULL &&
2331 reason != bgp_path_selection_none)
2332 dest->reason = reason;
2333 new_select = pi;
2334 }
2335 }
2336
2337 /* Now that we know which path is the bestpath see if any of the other
2338 * paths
2339 * qualify as multipaths
2340 */
2341 if (debug) {
2342 if (new_select)
2343 bgp_path_info_path_with_addpath_rx_str(new_select,
2344 path_buf);
2345 else
2346 snprintf(path_buf, sizeof(path_buf), "NONE");
2347 zlog_debug(
2348 "%s: After path selection, newbest is %s oldbest was %s",
2349 pfx_buf, path_buf,
2350 old_select ? old_select->peer->host : "NONE");
2351 }
2352
2353 if (do_mpath && new_select) {
2354 for (pi = bgp_dest_get_bgp_path_info(dest);
2355 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2356
2357 if (debug)
2358 bgp_path_info_path_with_addpath_rx_str(
2359 pi, path_buf);
2360
2361 if (pi == new_select) {
2362 if (debug)
2363 zlog_debug(
2364 "%s: %s is the bestpath, add to the multipath list",
2365 pfx_buf, path_buf);
2366 bgp_mp_list_add(&mp_list, pi);
2367 continue;
2368 }
2369
2370 if (BGP_PATH_HOLDDOWN(pi))
2371 continue;
2372
2373 if (pi->peer && pi->peer != bgp->peer_self
2374 && !CHECK_FLAG(pi->peer->sflags,
2375 PEER_STATUS_NSF_WAIT))
2376 if (pi->peer->status != Established)
2377 continue;
2378
2379 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2380 if (debug)
2381 zlog_debug(
2382 "%s: %s has the same nexthop as the bestpath, skip it",
2383 pfx_buf, path_buf);
2384 continue;
2385 }
2386
2387 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2388 mpath_cfg, debug, pfx_buf, afi, safi,
2389 &dest->reason);
2390
2391 if (paths_eq) {
2392 if (debug)
2393 zlog_debug(
2394 "%s: %s is equivalent to the bestpath, add to the multipath list",
2395 pfx_buf, path_buf);
2396 bgp_mp_list_add(&mp_list, pi);
2397 }
2398 }
2399 }
2400
2401 bgp_path_info_mpath_update(dest, new_select, old_select, &mp_list,
2402 mpath_cfg);
2403 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2404 bgp_mp_list_clear(&mp_list);
2405
2406 bgp_addpath_update_ids(bgp, dest, afi, safi);
2407
2408 result->old = old_select;
2409 result->new = new_select;
2410
2411 return;
2412 }
2413
2414 /*
2415 * A new route/change in bestpath of an existing route. Evaluate the path
2416 * for advertisement to the subgroup.
2417 */
2418 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2419 struct bgp_path_info *selected,
2420 struct bgp_dest *dest,
2421 uint32_t addpath_tx_id)
2422 {
2423 const struct prefix *p;
2424 struct peer *onlypeer;
2425 struct attr attr;
2426 afi_t afi;
2427 safi_t safi;
2428
2429 p = bgp_dest_get_prefix(dest);
2430 afi = SUBGRP_AFI(subgrp);
2431 safi = SUBGRP_SAFI(subgrp);
2432 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2433 : NULL);
2434
2435 if (BGP_DEBUG(update, UPDATE_OUT)) {
2436 char buf_prefix[PREFIX_STRLEN];
2437 prefix2str(p, buf_prefix, sizeof(buf_prefix));
2438 zlog_debug("%s: p=%s, selected=%p", __func__, buf_prefix,
2439 selected);
2440 }
2441
2442 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2443 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2444 PEER_STATUS_ORF_WAIT_REFRESH))
2445 return;
2446
2447 memset(&attr, 0, sizeof(struct attr));
2448 /* It's initialized in bgp_announce_check() */
2449
2450 /* Announcement to the subgroup. If the route is filtered withdraw it.
2451 */
2452 if (selected) {
2453 if (subgroup_announce_check(dest, selected, subgrp, p, &attr))
2454 bgp_adj_out_set_subgroup(dest, subgrp, &attr, selected);
2455 else
2456 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2457 addpath_tx_id);
2458 }
2459
2460 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2461 else {
2462 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2463 }
2464 }
2465
2466 /*
2467 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2468 * This is called at the end of route processing.
2469 */
2470 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2471 {
2472 struct bgp_path_info *pi;
2473
2474 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2475 if (BGP_PATH_HOLDDOWN(pi))
2476 continue;
2477 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2478 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2479 }
2480 }
2481
2482 /*
2483 * Has the route changed from the RIB's perspective? This is invoked only
2484 * if the route selection returns the same best route as earlier - to
2485 * determine if we need to update zebra or not.
2486 */
2487 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2488 {
2489 struct bgp_path_info *mpinfo;
2490
2491 /* If this is multipath, check all selected paths for any nexthop
2492 * change or attribute change. Some attribute changes (e.g., community)
2493 * aren't of relevance to the RIB, but we'll update zebra to ensure
2494 * we handle the case of BGP nexthop change. This is the behavior
2495 * when the best path has an attribute change anyway.
2496 */
2497 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2498 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2499 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2500 return true;
2501
2502 /*
2503 * If this is multipath, check all selected paths for any nexthop change
2504 */
2505 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2506 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2507 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2508 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2509 return true;
2510 }
2511
2512 /* Nothing has changed from the RIB's perspective. */
2513 return false;
2514 }
2515
2516 struct bgp_process_queue {
2517 struct bgp *bgp;
2518 STAILQ_HEAD(, bgp_dest) pqueue;
2519 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2520 unsigned int flags;
2521 unsigned int queued;
2522 };
2523
2524 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
2525 safi_t safi, struct bgp_dest *dest,
2526 struct bgp_path_info *new_select,
2527 struct bgp_path_info *old_select)
2528 {
2529 const struct prefix *p = bgp_dest_get_prefix(dest);
2530
2531 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
2532 return;
2533
2534 if (advertise_type5_routes(bgp, afi) && new_select
2535 && is_route_injectable_into_evpn(new_select)) {
2536
2537 /* apply the route-map */
2538 if (bgp->adv_cmd_rmap[afi][safi].map) {
2539 route_map_result_t ret;
2540 struct bgp_path_info rmap_path;
2541 struct bgp_path_info_extra rmap_path_extra;
2542 struct attr dummy_attr;
2543
2544 dummy_attr = *new_select->attr;
2545
2546 /* Fill temp path_info */
2547 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
2548 new_select, new_select->peer,
2549 &dummy_attr);
2550
2551 RESET_FLAG(dummy_attr.rmap_change_flags);
2552
2553 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
2554 p, RMAP_BGP, &rmap_path);
2555
2556 if (ret == RMAP_DENYMATCH) {
2557 bgp_attr_flush(&dummy_attr);
2558 bgp_evpn_withdraw_type5_route(bgp, p, afi,
2559 safi);
2560 } else
2561 bgp_evpn_advertise_type5_route(
2562 bgp, p, &dummy_attr, afi, safi);
2563 } else {
2564 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
2565 afi, safi);
2566 }
2567 } else if (advertise_type5_routes(bgp, afi) && old_select
2568 && is_route_injectable_into_evpn(old_select))
2569 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
2570 }
2571
2572 /*
2573 * old_select = The old best path
2574 * new_select = the new best path
2575 *
2576 * if (!old_select && new_select)
2577 * We are sending new information on.
2578 *
2579 * if (old_select && new_select) {
2580 * if (new_select != old_select)
2581 * We have a new best path send a change
2582 * else
2583 * We've received a update with new attributes that needs
2584 * to be passed on.
2585 * }
2586 *
2587 * if (old_select && !new_select)
2588 * We have no eligible route that we can announce or the rn
2589 * is being removed.
2590 */
2591 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
2592 afi_t afi, safi_t safi)
2593 {
2594 struct bgp_path_info *new_select;
2595 struct bgp_path_info *old_select;
2596 struct bgp_path_info_pair old_and_new;
2597 int debug = 0;
2598
2599 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
2600 if (dest)
2601 debug = bgp_debug_bestpath(dest);
2602 if (debug)
2603 zlog_debug(
2604 "%s: bgp delete in progress, ignoring event, p=%pRN",
2605 __func__, dest);
2606 return;
2607 }
2608 /* Is it end of initial update? (after startup) */
2609 if (!dest) {
2610 quagga_timestamp(3, bgp->update_delay_zebra_resume_time,
2611 sizeof(bgp->update_delay_zebra_resume_time));
2612
2613 bgp->main_zebra_update_hold = 0;
2614 FOREACH_AFI_SAFI (afi, safi) {
2615 if (bgp_fibupd_safi(safi))
2616 bgp_zebra_announce_table(bgp, afi, safi);
2617 }
2618 bgp->main_peers_update_hold = 0;
2619
2620 bgp_start_routeadv(bgp);
2621 return;
2622 }
2623
2624 const struct prefix *p = bgp_dest_get_prefix(dest);
2625
2626 debug = bgp_debug_bestpath(dest);
2627 if (debug)
2628 zlog_debug("%s: p=%pRN afi=%s, safi=%s start", __func__, dest,
2629 afi2str(afi), safi2str(safi));
2630
2631 /* The best path calculation for the route is deferred if
2632 * BGP_NODE_SELECT_DEFER is set
2633 */
2634 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
2635 if (BGP_DEBUG(update, UPDATE_OUT))
2636 zlog_debug("SELECT_DEFER falg set for route %p", dest);
2637 return;
2638 }
2639
2640 /* Best path selection. */
2641 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
2642 afi, safi);
2643 old_select = old_and_new.old;
2644 new_select = old_and_new.new;
2645
2646 /* Do we need to allocate or free labels?
2647 * Right now, since we only deal with per-prefix labels, it is not
2648 * necessary to do this upon changes to best path. Exceptions:
2649 * - label index has changed -> recalculate resulting label
2650 * - path_info sub_type changed -> switch to/from implicit-null
2651 * - no valid label (due to removed static label binding) -> get new one
2652 */
2653 if (bgp->allocate_mpls_labels[afi][safi]) {
2654 if (new_select) {
2655 if (!old_select
2656 || bgp_label_index_differs(new_select, old_select)
2657 || new_select->sub_type != old_select->sub_type
2658 || !bgp_is_valid_label(&dest->local_label)) {
2659 /* Enforced penultimate hop popping:
2660 * implicit-null for local routes, aggregate
2661 * and redistributed routes
2662 */
2663 if (new_select->sub_type == BGP_ROUTE_STATIC
2664 || new_select->sub_type
2665 == BGP_ROUTE_AGGREGATE
2666 || new_select->sub_type
2667 == BGP_ROUTE_REDISTRIBUTE) {
2668 if (CHECK_FLAG(
2669 dest->flags,
2670 BGP_NODE_REGISTERED_FOR_LABEL))
2671 bgp_unregister_for_label(dest);
2672 label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1,
2673 &dest->local_label);
2674 bgp_set_valid_label(&dest->local_label);
2675 } else
2676 bgp_register_for_label(dest,
2677 new_select);
2678 }
2679 } else if (CHECK_FLAG(dest->flags,
2680 BGP_NODE_REGISTERED_FOR_LABEL)) {
2681 bgp_unregister_for_label(dest);
2682 }
2683 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)) {
2684 bgp_unregister_for_label(dest);
2685 }
2686
2687 if (debug)
2688 zlog_debug(
2689 "%s: p=%pRN afi=%s, safi=%s, old_select=%p, new_select=%p",
2690 __func__, dest, afi2str(afi), safi2str(safi),
2691 old_select, new_select);
2692
2693 /* If best route remains the same and this is not due to user-initiated
2694 * clear, see exactly what needs to be done.
2695 */
2696 if (old_select && old_select == new_select
2697 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
2698 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2699 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
2700 if (bgp_zebra_has_route_changed(old_select)) {
2701 #ifdef ENABLE_BGP_VNC
2702 vnc_import_bgp_add_route(bgp, p, old_select);
2703 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
2704 #endif
2705 if (bgp_fibupd_safi(safi)
2706 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2707
2708 if (new_select->type == ZEBRA_ROUTE_BGP
2709 && (new_select->sub_type == BGP_ROUTE_NORMAL
2710 || new_select->sub_type
2711 == BGP_ROUTE_IMPORTED))
2712
2713 bgp_zebra_announce(dest, p, old_select,
2714 bgp, afi, safi);
2715 }
2716 }
2717
2718 /* If there is a change of interest to peers, reannounce the
2719 * route. */
2720 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2721 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
2722 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
2723 group_announce_route(bgp, afi, safi, dest, new_select);
2724
2725 /* unicast routes must also be annouced to
2726 * labeled-unicast update-groups */
2727 if (safi == SAFI_UNICAST)
2728 group_announce_route(bgp, afi,
2729 SAFI_LABELED_UNICAST, dest,
2730 new_select);
2731
2732 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
2733 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
2734 }
2735
2736 /* advertise/withdraw type-5 routes */
2737 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
2738 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
2739 bgp_process_evpn_route_injection(
2740 bgp, afi, safi, dest, old_select, old_select);
2741
2742 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
2743 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
2744 bgp_zebra_clear_route_change_flags(dest);
2745 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
2746 return;
2747 }
2748
2749 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2750 */
2751 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
2752
2753 /* bestpath has changed; bump version */
2754 if (old_select || new_select) {
2755 bgp_bump_version(dest);
2756
2757 if (!bgp->t_rmap_def_originate_eval) {
2758 bgp_lock(bgp);
2759 thread_add_timer(
2760 bm->master,
2761 update_group_refresh_default_originate_route_map,
2762 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
2763 &bgp->t_rmap_def_originate_eval);
2764 }
2765 }
2766
2767 if (old_select)
2768 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
2769 if (new_select) {
2770 if (debug)
2771 zlog_debug("%s: setting SELECTED flag", __func__);
2772 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
2773 bgp_path_info_unset_flag(dest, new_select,
2774 BGP_PATH_ATTR_CHANGED);
2775 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
2776 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
2777 }
2778
2779 #ifdef ENABLE_BGP_VNC
2780 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
2781 if (old_select != new_select) {
2782 if (old_select) {
2783 vnc_import_bgp_exterior_del_route(bgp, p,
2784 old_select);
2785 vnc_import_bgp_del_route(bgp, p, old_select);
2786 }
2787 if (new_select) {
2788 vnc_import_bgp_exterior_add_route(bgp, p,
2789 new_select);
2790 vnc_import_bgp_add_route(bgp, p, new_select);
2791 }
2792 }
2793 }
2794 #endif
2795
2796 group_announce_route(bgp, afi, safi, dest, new_select);
2797
2798 /* unicast routes must also be annouced to labeled-unicast update-groups
2799 */
2800 if (safi == SAFI_UNICAST)
2801 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
2802 new_select);
2803
2804 /* FIB update. */
2805 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
2806 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2807 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
2808 && (new_select->sub_type == BGP_ROUTE_NORMAL
2809 || new_select->sub_type == BGP_ROUTE_AGGREGATE
2810 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
2811
2812 /* if this is an evpn imported type-5 prefix,
2813 * we need to withdraw the route first to clear
2814 * the nh neigh and the RMAC entry.
2815 */
2816 if (old_select &&
2817 is_route_parent_evpn(old_select))
2818 bgp_zebra_withdraw(p, old_select, bgp, safi);
2819
2820 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
2821 } else {
2822 /* Withdraw the route from the kernel. */
2823 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
2824 && (old_select->sub_type == BGP_ROUTE_NORMAL
2825 || old_select->sub_type == BGP_ROUTE_AGGREGATE
2826 || old_select->sub_type == BGP_ROUTE_IMPORTED))
2827
2828 bgp_zebra_withdraw(p, old_select, bgp, safi);
2829 }
2830 }
2831
2832 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
2833 old_select);
2834
2835 /* Clear any route change flags. */
2836 bgp_zebra_clear_route_change_flags(dest);
2837
2838 /* Reap old select bgp_path_info, if it has been removed */
2839 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
2840 bgp_path_info_reap(dest, old_select);
2841
2842 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
2843 return;
2844 }
2845
2846 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
2847 int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
2848 {
2849 struct bgp_dest *dest;
2850 int cnt = 0;
2851 struct afi_safi_info *thread_info;
2852 struct listnode *node = NULL, *nnode = NULL;
2853
2854 if (bgp->gr_info[afi][safi].t_route_select)
2855 BGP_TIMER_OFF(bgp->gr_info[afi][safi].t_route_select);
2856
2857 if (BGP_DEBUG(update, UPDATE_OUT)) {
2858 zlog_debug("%s: processing route for %s : cnt %d", __func__,
2859 get_afi_safi_str(afi, safi, false),
2860 listcount(bgp->gr_info[afi][safi].route_list));
2861 }
2862
2863 /* Process the route list */
2864 node = listhead(bgp->gr_info[afi][safi].route_list);
2865 while (node) {
2866 dest = listgetdata(node);
2867 nnode = node->next;
2868 list_delete_node(bgp->gr_info[afi][safi].route_list, node);
2869 dest->rt_node = NULL;
2870
2871 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
2872 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
2873 bgp_process_main_one(bgp, dest, afi, safi);
2874 cnt++;
2875 if (cnt >= BGP_MAX_BEST_ROUTE_SELECT)
2876 break;
2877 }
2878 node = nnode;
2879 }
2880
2881 /* Send EOR message when all routes are processed */
2882 if (list_isempty(bgp->gr_info[afi][safi].route_list)) {
2883 bgp_send_delayed_eor(bgp);
2884 /* Send route processing complete message to RIB */
2885 bgp_zebra_update(afi, safi, bgp->vrf_id,
2886 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
2887 return 0;
2888 }
2889
2890 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
2891
2892 thread_info->afi = afi;
2893 thread_info->safi = safi;
2894 thread_info->bgp = bgp;
2895
2896 /* If there are more routes to be processed, start the
2897 * selection timer
2898 */
2899 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
2900 BGP_ROUTE_SELECT_DELAY,
2901 &bgp->gr_info[afi][safi].t_route_select);
2902 return 0;
2903 }
2904
2905 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
2906 {
2907 struct bgp_process_queue *pqnode = data;
2908 struct bgp *bgp = pqnode->bgp;
2909 struct bgp_table *table;
2910 struct bgp_dest *dest;
2911
2912 /* eoiu marker */
2913 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
2914 bgp_process_main_one(bgp, NULL, 0, 0);
2915 /* should always have dedicated wq call */
2916 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
2917 return WQ_SUCCESS;
2918 }
2919
2920 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
2921 dest = STAILQ_FIRST(&pqnode->pqueue);
2922 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
2923 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
2924 table = bgp_dest_table(dest);
2925 /* note, new DESTs may be added as part of processing */
2926 bgp_process_main_one(bgp, dest, table->afi, table->safi);
2927
2928 bgp_dest_unlock_node(dest);
2929 bgp_table_unlock(table);
2930 }
2931
2932 return WQ_SUCCESS;
2933 }
2934
2935 static void bgp_processq_del(struct work_queue *wq, void *data)
2936 {
2937 struct bgp_process_queue *pqnode = data;
2938
2939 bgp_unlock(pqnode->bgp);
2940
2941 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
2942 }
2943
2944 void bgp_process_queue_init(void)
2945 {
2946 if (!bm->process_main_queue)
2947 bm->process_main_queue =
2948 work_queue_new(bm->master, "process_main_queue");
2949
2950 bm->process_main_queue->spec.workfunc = &bgp_process_wq;
2951 bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
2952 bm->process_main_queue->spec.max_retries = 0;
2953 bm->process_main_queue->spec.hold = 50;
2954 /* Use a higher yield value of 50ms for main queue processing */
2955 bm->process_main_queue->spec.yield = 50 * 1000L;
2956 }
2957
2958 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
2959 {
2960 struct bgp_process_queue *pqnode;
2961
2962 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
2963 sizeof(struct bgp_process_queue));
2964
2965 /* unlocked in bgp_processq_del */
2966 pqnode->bgp = bgp_lock(bgp);
2967 STAILQ_INIT(&pqnode->pqueue);
2968
2969 return pqnode;
2970 }
2971
2972 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
2973 {
2974 #define ARBITRARY_PROCESS_QLEN 10000
2975 struct work_queue *wq = bm->process_main_queue;
2976 struct bgp_process_queue *pqnode;
2977 int pqnode_reuse = 0;
2978
2979 /* already scheduled for processing? */
2980 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
2981 return;
2982
2983 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
2984 * the workqueue
2985 */
2986 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
2987 if (BGP_DEBUG(update, UPDATE_OUT))
2988 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
2989 dest);
2990 return;
2991 }
2992
2993 if (wq == NULL)
2994 return;
2995
2996 /* Add route nodes to an existing work queue item until reaching the
2997 limit only if is from the same BGP view and it's not an EOIU marker
2998 */
2999 if (work_queue_item_count(wq)) {
3000 struct work_queue_item *item = work_queue_last_item(wq);
3001 pqnode = item->data;
3002
3003 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3004 || pqnode->bgp != bgp
3005 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3006 pqnode = bgp_processq_alloc(bgp);
3007 else
3008 pqnode_reuse = 1;
3009 } else
3010 pqnode = bgp_processq_alloc(bgp);
3011 /* all unlocked in bgp_process_wq */
3012 bgp_table_lock(bgp_dest_table(dest));
3013
3014 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3015 bgp_dest_lock_node(dest);
3016
3017 /* can't be enqueued twice */
3018 assert(STAILQ_NEXT(dest, pq) == NULL);
3019 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3020 pqnode->queued++;
3021
3022 if (!pqnode_reuse)
3023 work_queue_add(wq, pqnode);
3024
3025 return;
3026 }
3027
3028 void bgp_add_eoiu_mark(struct bgp *bgp)
3029 {
3030 struct bgp_process_queue *pqnode;
3031
3032 if (bm->process_main_queue == NULL)
3033 return;
3034
3035 pqnode = bgp_processq_alloc(bgp);
3036
3037 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3038 work_queue_add(bm->process_main_queue, pqnode);
3039 }
3040
3041 static int bgp_maximum_prefix_restart_timer(struct thread *thread)
3042 {
3043 struct peer *peer;
3044
3045 peer = THREAD_ARG(thread);
3046 peer->t_pmax_restart = NULL;
3047
3048 if (bgp_debug_neighbor_events(peer))
3049 zlog_debug(
3050 "%s Maximum-prefix restart timer expired, restore peering",
3051 peer->host);
3052
3053 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3054 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3055
3056 return 0;
3057 }
3058
3059 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3060 safi_t safi)
3061 {
3062 uint32_t count = 0;
3063 bool filtered = false;
3064 struct bgp_dest *dest;
3065 struct bgp_adj_in *ain;
3066 struct bgp_table *table = peer->bgp->rib[afi][safi];
3067
3068 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3069 for (ain = dest->adj_in; ain; ain = ain->next) {
3070 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3071 struct attr attr = {};
3072
3073 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3074 == FILTER_DENY)
3075 filtered = true;
3076
3077 if (bgp_input_modifier(
3078 peer, rn_p, &attr, afi, safi,
3079 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3080 NULL, 0, NULL)
3081 == RMAP_DENY)
3082 filtered = true;
3083
3084 if (filtered)
3085 count++;
3086
3087 bgp_attr_undup(&attr, ain->attr);
3088 }
3089 }
3090
3091 return count;
3092 }
3093
3094 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3095 int always)
3096 {
3097 iana_afi_t pkt_afi;
3098 iana_safi_t pkt_safi;
3099 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3100 PEER_FLAG_MAX_PREFIX_FORCE))
3101 ? bgp_filtered_routes_count(peer, afi, safi)
3102 + peer->pcount[afi][safi]
3103 : peer->pcount[afi][safi];
3104
3105 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3106 return false;
3107
3108 if (pcount > peer->pmax[afi][safi]) {
3109 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3110 PEER_STATUS_PREFIX_LIMIT)
3111 && !always)
3112 return false;
3113
3114 zlog_info(
3115 "%%MAXPFXEXCEED: No. of %s prefix received from %s %u exceed, limit %u",
3116 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3117 peer->pmax[afi][safi]);
3118 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3119
3120 if (CHECK_FLAG(peer->af_flags[afi][safi],
3121 PEER_FLAG_MAX_PREFIX_WARNING))
3122 return false;
3123
3124 /* Convert AFI, SAFI to values for packet. */
3125 pkt_afi = afi_int2iana(afi);
3126 pkt_safi = safi_int2iana(safi);
3127 {
3128 uint8_t ndata[7];
3129
3130 ndata[0] = (pkt_afi >> 8);
3131 ndata[1] = pkt_afi;
3132 ndata[2] = pkt_safi;
3133 ndata[3] = (peer->pmax[afi][safi] >> 24);
3134 ndata[4] = (peer->pmax[afi][safi] >> 16);
3135 ndata[5] = (peer->pmax[afi][safi] >> 8);
3136 ndata[6] = (peer->pmax[afi][safi]);
3137
3138 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3139 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3140 BGP_NOTIFY_CEASE_MAX_PREFIX,
3141 ndata, 7);
3142 }
3143
3144 /* Dynamic peers will just close their connection. */
3145 if (peer_dynamic_neighbor(peer))
3146 return true;
3147
3148 /* restart timer start */
3149 if (peer->pmax_restart[afi][safi]) {
3150 peer->v_pmax_restart =
3151 peer->pmax_restart[afi][safi] * 60;
3152
3153 if (bgp_debug_neighbor_events(peer))
3154 zlog_debug(
3155 "%s Maximum-prefix restart timer started for %d secs",
3156 peer->host, peer->v_pmax_restart);
3157
3158 BGP_TIMER_ON(peer->t_pmax_restart,
3159 bgp_maximum_prefix_restart_timer,
3160 peer->v_pmax_restart);
3161 }
3162
3163 return true;
3164 } else
3165 UNSET_FLAG(peer->af_sflags[afi][safi],
3166 PEER_STATUS_PREFIX_LIMIT);
3167
3168 if (pcount > (pcount * peer->pmax_threshold[afi][safi] / 100)) {
3169 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3170 PEER_STATUS_PREFIX_THRESHOLD)
3171 && !always)
3172 return false;
3173
3174 zlog_info(
3175 "%%MAXPFX: No. of %s prefix received from %s reaches %u, max %u",
3176 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3177 peer->pmax[afi][safi]);
3178 SET_FLAG(peer->af_sflags[afi][safi],
3179 PEER_STATUS_PREFIX_THRESHOLD);
3180 } else
3181 UNSET_FLAG(peer->af_sflags[afi][safi],
3182 PEER_STATUS_PREFIX_THRESHOLD);
3183 return false;
3184 }
3185
3186 /* Unconditionally remove the route from the RIB, without taking
3187 * damping into consideration (eg, because the session went down)
3188 */
3189 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3190 struct peer *peer, afi_t afi, safi_t safi)
3191 {
3192
3193 struct bgp *bgp = NULL;
3194 bool delete_route = false;
3195
3196 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3197 safi);
3198
3199 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3200 bgp_path_info_delete(dest, pi); /* keep historical info */
3201
3202 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3203 * flag
3204 */
3205 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3206 delete_route = true;
3207 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3208 delete_route = true;
3209 if (delete_route) {
3210 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3211 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3212 bgp = pi->peer->bgp;
3213 if ((dest->rt_node)
3214 && (bgp->gr_info[afi][safi].route_list)) {
3215 list_delete_node(bgp->gr_info[afi][safi]
3216 .route_list,
3217 dest->rt_node);
3218 dest->rt_node = NULL;
3219 }
3220 }
3221 }
3222 }
3223
3224 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3225 bgp_process(peer->bgp, dest, afi, safi);
3226 }
3227
3228 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3229 struct peer *peer, afi_t afi, safi_t safi,
3230 struct prefix_rd *prd)
3231 {
3232 const struct prefix *p = bgp_dest_get_prefix(dest);
3233
3234 /* apply dampening, if result is suppressed, we'll be retaining
3235 * the bgp_path_info in the RIB for historical reference.
3236 */
3237 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3238 && peer->sort == BGP_PEER_EBGP)
3239 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3240 == BGP_DAMP_SUPPRESSED) {
3241 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3242 safi);
3243 return;
3244 }
3245
3246 #ifdef ENABLE_BGP_VNC
3247 if (safi == SAFI_MPLS_VPN) {
3248 struct bgp_dest *pdest = NULL;
3249 struct bgp_table *table = NULL;
3250
3251 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3252 (struct prefix *)prd);
3253 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3254 table = bgp_dest_get_bgp_table_info(pdest);
3255
3256 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3257 peer->bgp, prd, table, p, pi);
3258 }
3259 bgp_dest_unlock_node(pdest);
3260 }
3261 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3262 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3263
3264 vnc_import_bgp_del_route(peer->bgp, p, pi);
3265 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3266 }
3267 }
3268 #endif
3269
3270 /* If this is an EVPN route, process for un-import. */
3271 if (safi == SAFI_EVPN)
3272 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3273
3274 bgp_rib_remove(dest, pi, peer, afi, safi);
3275 }
3276
3277 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3278 struct peer *peer, struct attr *attr,
3279 struct bgp_dest *dest)
3280 {
3281 struct bgp_path_info *new;
3282
3283 /* Make new BGP info. */
3284 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3285 new->type = type;
3286 new->instance = instance;
3287 new->sub_type = sub_type;
3288 new->peer = peer;
3289 new->attr = attr;
3290 new->uptime = bgp_clock();
3291 new->net = dest;
3292 return new;
3293 }
3294
3295 static void overlay_index_update(struct attr *attr,
3296 union gw_addr *gw_ip)
3297 {
3298 if (!attr)
3299 return;
3300 if (gw_ip == NULL) {
3301 memset(&(attr->evpn_overlay.gw_ip), 0, sizeof(union gw_addr));
3302 } else {
3303 memcpy(&(attr->evpn_overlay.gw_ip), gw_ip,
3304 sizeof(union gw_addr));
3305 }
3306 }
3307
3308 static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path,
3309 union gw_addr *gw_ip)
3310 {
3311 union gw_addr *path_gw_ip, *path_gw_ip_remote;
3312 union {
3313 esi_t esi;
3314 union gw_addr ip;
3315 } temp;
3316
3317 if (afi != AFI_L2VPN)
3318 return true;
3319
3320 path_gw_ip = &(path->attr->evpn_overlay.gw_ip);
3321
3322 if (gw_ip == NULL) {
3323 memset(&temp, 0, sizeof(temp));
3324 path_gw_ip_remote = &temp.ip;
3325 } else
3326 path_gw_ip_remote = gw_ip;
3327
3328 return !!memcmp(path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr));
3329 }
3330
3331 /* Check if received nexthop is valid or not. */
3332 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3333 uint8_t type, uint8_t stype, struct attr *attr,
3334 struct bgp_dest *dest)
3335 {
3336 bool ret = false;
3337 bool is_bgp_static_route =
3338 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3339 : false;
3340
3341 /* Only validated for unicast and multicast currently. */
3342 /* Also valid for EVPN where the nexthop is an IP address. */
3343 if (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN)
3344 return false;
3345
3346 /* If NEXT_HOP is present, validate it. */
3347 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3348 if ((attr->nexthop.s_addr == INADDR_ANY && !is_bgp_static_route)
3349 || IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr))
3350 || bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3351 return true;
3352 }
3353
3354 /* If MP_NEXTHOP is present, validate it. */
3355 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3356 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3357 * it is not an IPv6 link-local address.
3358 *
3359 * If we receive an UPDATE with nexthop length set to 32 bytes
3360 * we shouldn't discard an UPDATE if it's set to (::).
3361 * The link-local (2st) is validated along the code path later.
3362 */
3363 if (attr->mp_nexthop_len) {
3364 switch (attr->mp_nexthop_len) {
3365 case BGP_ATTR_NHLEN_IPV4:
3366 case BGP_ATTR_NHLEN_VPNV4:
3367 ret = ((attr->mp_nexthop_global_in.s_addr == INADDR_ANY
3368 && !is_bgp_static_route)
3369 || IPV4_CLASS_DE(
3370 ntohl(attr->mp_nexthop_global_in.s_addr))
3371 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3372 dest));
3373 break;
3374
3375 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3376 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3377 ret = ((IN6_IS_ADDR_UNSPECIFIED(
3378 &attr->mp_nexthop_global)
3379 && !is_bgp_static_route)
3380 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3381 || IN6_IS_ADDR_MULTICAST(
3382 &attr->mp_nexthop_global)
3383 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3384 dest));
3385 break;
3386 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3387 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3388 || IN6_IS_ADDR_MULTICAST(
3389 &attr->mp_nexthop_global)
3390 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3391 dest));
3392 break;
3393
3394 default:
3395 ret = true;
3396 break;
3397 }
3398 }
3399
3400 return ret;
3401 }
3402
3403 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3404 struct attr *attr, afi_t afi, safi_t safi, int type,
3405 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3406 uint32_t num_labels, int soft_reconfig,
3407 struct bgp_route_evpn *evpn)
3408 {
3409 int ret;
3410 int aspath_loop_count = 0;
3411 struct bgp_dest *dest;
3412 struct bgp *bgp;
3413 struct attr new_attr;
3414 struct attr *attr_new;
3415 struct bgp_path_info *pi;
3416 struct bgp_path_info *new;
3417 struct bgp_path_info_extra *extra;
3418 const char *reason;
3419 char pfx_buf[BGP_PRD_PATH_STRLEN];
3420 int connected = 0;
3421 int do_loop_check = 1;
3422 int has_valid_label = 0;
3423 afi_t nh_afi;
3424 uint8_t pi_type = 0;
3425 uint8_t pi_sub_type = 0;
3426
3427 #ifdef ENABLE_BGP_VNC
3428 int vnc_implicit_withdraw = 0;
3429 #endif
3430 int same_attr = 0;
3431
3432 memset(&new_attr, 0, sizeof(struct attr));
3433 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
3434 new_attr.label = MPLS_INVALID_LABEL;
3435
3436 bgp = peer->bgp;
3437 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3438 /* TODO: Check to see if we can get rid of "is_valid_label" */
3439 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3440 has_valid_label = (num_labels > 0) ? 1 : 0;
3441 else
3442 has_valid_label = bgp_is_valid_label(label);
3443
3444 /* When peer's soft reconfiguration enabled. Record input packet in
3445 Adj-RIBs-In. */
3446 if (!soft_reconfig
3447 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3448 && peer != bgp->peer_self)
3449 bgp_adj_in_set(dest, peer, attr, addpath_id);
3450
3451 /* Check previously received route. */
3452 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
3453 if (pi->peer == peer && pi->type == type
3454 && pi->sub_type == sub_type
3455 && pi->addpath_rx_id == addpath_id)
3456 break;
3457
3458 /* AS path local-as loop check. */
3459 if (peer->change_local_as) {
3460 if (peer->allowas_in[afi][safi])
3461 aspath_loop_count = peer->allowas_in[afi][safi];
3462 else if (!CHECK_FLAG(peer->flags,
3463 PEER_FLAG_LOCAL_AS_NO_PREPEND))
3464 aspath_loop_count = 1;
3465
3466 if (aspath_loop_check(attr->aspath, peer->change_local_as)
3467 > aspath_loop_count) {
3468 peer->stat_pfx_aspath_loop++;
3469 reason = "as-path contains our own AS A;";
3470 goto filtered;
3471 }
3472 }
3473
3474 /* If the peer is configured for "allowas-in origin" and the last ASN in
3475 * the
3476 * as-path is our ASN then we do not need to call aspath_loop_check
3477 */
3478 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
3479 if (aspath_get_last_as(attr->aspath) == bgp->as)
3480 do_loop_check = 0;
3481
3482 /* AS path loop check. */
3483 if (do_loop_check) {
3484 if (aspath_loop_check(attr->aspath, bgp->as)
3485 > peer->allowas_in[afi][safi]
3486 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
3487 && aspath_loop_check(attr->aspath, bgp->confed_id)
3488 > peer->allowas_in[afi][safi])) {
3489 peer->stat_pfx_aspath_loop++;
3490 reason = "as-path contains our own AS;";
3491 goto filtered;
3492 }
3493 }
3494
3495 /* Route reflector originator ID check. */
3496 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
3497 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
3498 peer->stat_pfx_originator_loop++;
3499 reason = "originator is us;";
3500 goto filtered;
3501 }
3502
3503 /* Route reflector cluster ID check. */
3504 if (bgp_cluster_filter(peer, attr)) {
3505 peer->stat_pfx_cluster_loop++;
3506 reason = "reflected from the same cluster;";
3507 goto filtered;
3508 }
3509
3510 /* Apply incoming filter. */
3511 if (bgp_input_filter(peer, p, attr, afi, safi) == FILTER_DENY) {
3512 peer->stat_pfx_filter++;
3513 reason = "filter;";
3514 goto filtered;
3515 }
3516
3517 /* RFC 8212 to prevent route leaks.
3518 * This specification intends to improve this situation by requiring the
3519 * explicit configuration of both BGP Import and Export Policies for any
3520 * External BGP (EBGP) session such as customers, peers, or
3521 * confederation boundaries for all enabled address families. Through
3522 * codification of the aforementioned requirement, operators will
3523 * benefit from consistent behavior across different BGP
3524 * implementations.
3525 */
3526 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
3527 if (!bgp_inbound_policy_exists(peer,
3528 &peer->filter[afi][safi])) {
3529 reason = "inbound policy missing";
3530 goto filtered;
3531 }
3532
3533 /* draft-ietf-idr-deprecate-as-set-confed-set
3534 * Filter routes having AS_SET or AS_CONFED_SET in the path.
3535 * Eventually, This document (if approved) updates RFC 4271
3536 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
3537 * and obsoletes RFC 6472.
3538 */
3539 if (peer->bgp->reject_as_sets)
3540 if (aspath_check_as_sets(attr->aspath)) {
3541 reason =
3542 "as-path contains AS_SET or AS_CONFED_SET type;";
3543 goto filtered;
3544 }
3545
3546 new_attr = *attr;
3547
3548 /* Apply incoming route-map.
3549 * NB: new_attr may now contain newly allocated values from route-map
3550 * "set"
3551 * commands, so we need bgp_attr_flush in the error paths, until we
3552 * intern
3553 * the attr (which takes over the memory references) */
3554 if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL, label,
3555 num_labels, dest)
3556 == RMAP_DENY) {
3557 peer->stat_pfx_filter++;
3558 reason = "route-map;";
3559 bgp_attr_flush(&new_attr);
3560 goto filtered;
3561 }
3562
3563 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
3564 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3565 /* remove from RIB previous entry */
3566 bgp_zebra_withdraw(p, pi, bgp, safi);
3567 }
3568
3569 if (peer->sort == BGP_PEER_EBGP) {
3570
3571 /* If we receive the graceful-shutdown community from an eBGP
3572 * peer we must lower local-preference */
3573 if (new_attr.community
3574 && community_include(new_attr.community, COMMUNITY_GSHUT)) {
3575 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
3576 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
3577
3578 /* If graceful-shutdown is configured then add the GSHUT
3579 * community to all paths received from eBGP peers */
3580 } else if (CHECK_FLAG(peer->bgp->flags,
3581 BGP_FLAG_GRACEFUL_SHUTDOWN))
3582 bgp_attr_add_gshut_community(&new_attr);
3583 }
3584
3585 if (pi) {
3586 pi_type = pi->type;
3587 pi_sub_type = pi->sub_type;
3588 }
3589
3590 /* next hop check. */
3591 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
3592 && bgp_update_martian_nexthop(bgp, afi, safi, pi_type, pi_sub_type,
3593 &new_attr, dest)) {
3594 peer->stat_pfx_nh_invalid++;
3595 reason = "martian or self next-hop;";
3596 bgp_attr_flush(&new_attr);
3597 goto filtered;
3598 }
3599
3600 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
3601 peer->stat_pfx_nh_invalid++;
3602 reason = "self mac;";
3603 goto filtered;
3604 }
3605
3606 attr_new = bgp_attr_intern(&new_attr);
3607
3608 /* If maximum prefix count is configured and current prefix
3609 * count exeed it.
3610 */
3611 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0))
3612 return -1;
3613
3614 /* If the update is implicit withdraw. */
3615 if (pi) {
3616 pi->uptime = bgp_clock();
3617 same_attr = attrhash_cmp(pi->attr, attr_new);
3618
3619 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
3620
3621 /* Same attribute comes in. */
3622 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
3623 && attrhash_cmp(pi->attr, attr_new)
3624 && (!has_valid_label
3625 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
3626 num_labels * sizeof(mpls_label_t))
3627 == 0)
3628 && (overlay_index_equal(
3629 afi, pi,
3630 evpn == NULL ? NULL : &evpn->gw_ip))) {
3631 if (CHECK_FLAG(bgp->af_flags[afi][safi],
3632 BGP_CONFIG_DAMPENING)
3633 && peer->sort == BGP_PEER_EBGP
3634 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3635 if (bgp_debug_update(peer, p, NULL, 1)) {
3636 bgp_debug_rdpfxpath2str(
3637 afi, safi, prd, p, label,
3638 num_labels, addpath_id ? 1 : 0,
3639 addpath_id, pfx_buf,
3640 sizeof(pfx_buf));
3641 zlog_debug("%s rcvd %s", peer->host,
3642 pfx_buf);
3643 }
3644
3645 if (bgp_damp_update(pi, dest, afi, safi)
3646 != BGP_DAMP_SUPPRESSED) {
3647 bgp_aggregate_increment(bgp, p, pi, afi,
3648 safi);
3649 bgp_process(bgp, dest, afi, safi);
3650 }
3651 } else /* Duplicate - odd */
3652 {
3653 if (bgp_debug_update(peer, p, NULL, 1)) {
3654 if (!peer->rcvd_attr_printed) {
3655 zlog_debug(
3656 "%s rcvd UPDATE w/ attr: %s",
3657 peer->host,
3658 peer->rcvd_attr_str);
3659 peer->rcvd_attr_printed = 1;
3660 }
3661
3662 bgp_debug_rdpfxpath2str(
3663 afi, safi, prd, p, label,
3664 num_labels, addpath_id ? 1 : 0,
3665 addpath_id, pfx_buf,
3666 sizeof(pfx_buf));
3667 zlog_debug(
3668 "%s rcvd %s...duplicate ignored",
3669 peer->host, pfx_buf);
3670 }
3671
3672 /* graceful restart STALE flag unset. */
3673 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3674 bgp_path_info_unset_flag(
3675 dest, pi, BGP_PATH_STALE);
3676 bgp_dest_set_defer_flag(dest, false);
3677 bgp_process(bgp, dest, afi, safi);
3678 }
3679 }
3680
3681 bgp_dest_unlock_node(dest);
3682 bgp_attr_unintern(&attr_new);
3683
3684 return 0;
3685 }
3686
3687 /* Withdraw/Announce before we fully processed the withdraw */
3688 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
3689 if (bgp_debug_update(peer, p, NULL, 1)) {
3690 bgp_debug_rdpfxpath2str(
3691 afi, safi, prd, p, label, num_labels,
3692 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3693 sizeof(pfx_buf));
3694 zlog_debug(
3695 "%s rcvd %s, flapped quicker than processing",
3696 peer->host, pfx_buf);
3697 }
3698
3699 bgp_path_info_restore(dest, pi);
3700 }
3701
3702 /* Received Logging. */
3703 if (bgp_debug_update(peer, p, NULL, 1)) {
3704 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
3705 num_labels, addpath_id ? 1 : 0,
3706 addpath_id, pfx_buf,
3707 sizeof(pfx_buf));
3708 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3709 }
3710
3711 /* graceful restart STALE flag unset. */
3712 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3713 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
3714 bgp_dest_set_defer_flag(dest, false);
3715 }
3716
3717 /* The attribute is changed. */
3718 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
3719
3720 /* implicit withdraw, decrement aggregate and pcount here.
3721 * only if update is accepted, they'll increment below.
3722 */
3723 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
3724
3725 /* Update bgp route dampening information. */
3726 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3727 && peer->sort == BGP_PEER_EBGP) {
3728 /* This is implicit withdraw so we should update
3729 dampening
3730 information. */
3731 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
3732 bgp_damp_withdraw(pi, dest, afi, safi, 1);
3733 }
3734 #ifdef ENABLE_BGP_VNC
3735 if (safi == SAFI_MPLS_VPN) {
3736 struct bgp_dest *pdest = NULL;
3737 struct bgp_table *table = NULL;
3738
3739 pdest = bgp_node_get(bgp->rib[afi][safi],
3740 (struct prefix *)prd);
3741 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3742 table = bgp_dest_get_bgp_table_info(pdest);
3743
3744 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3745 bgp, prd, table, p, pi);
3746 }
3747 bgp_dest_unlock_node(pdest);
3748 }
3749 if ((afi == AFI_IP || afi == AFI_IP6)
3750 && (safi == SAFI_UNICAST)) {
3751 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3752 /*
3753 * Implicit withdraw case.
3754 */
3755 ++vnc_implicit_withdraw;
3756 vnc_import_bgp_del_route(bgp, p, pi);
3757 vnc_import_bgp_exterior_del_route(bgp, p, pi);
3758 }
3759 }
3760 #endif
3761
3762 /* Special handling for EVPN update of an existing route. If the
3763 * extended community attribute has changed, we need to
3764 * un-import
3765 * the route using its existing extended community. It will be
3766 * subsequently processed for import with the new extended
3767 * community.
3768 */
3769 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
3770 && !same_attr) {
3771 if ((pi->attr->flag
3772 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
3773 && (attr_new->flag
3774 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
3775 int cmp;
3776
3777 cmp = ecommunity_cmp(pi->attr->ecommunity,
3778 attr_new->ecommunity);
3779 if (!cmp) {
3780 if (bgp_debug_update(peer, p, NULL, 1))
3781 zlog_debug(
3782 "Change in EXT-COMM, existing %s new %s",
3783 ecommunity_str(
3784 pi->attr->ecommunity),
3785 ecommunity_str(
3786 attr_new->ecommunity));
3787 if (safi == SAFI_EVPN)
3788 bgp_evpn_unimport_route(
3789 bgp, afi, safi, p, pi);
3790 else /* SAFI_MPLS_VPN */
3791 vpn_leak_to_vrf_withdraw(bgp,
3792 pi);
3793 }
3794 }
3795 }
3796
3797 /* Update to new attribute. */
3798 bgp_attr_unintern(&pi->attr);
3799 pi->attr = attr_new;
3800
3801 /* Update MPLS label */
3802 if (has_valid_label) {
3803 extra = bgp_path_info_extra_get(pi);
3804 if (extra->label != label) {
3805 memcpy(&extra->label, label,
3806 num_labels * sizeof(mpls_label_t));
3807 extra->num_labels = num_labels;
3808 }
3809 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
3810 bgp_set_valid_label(&extra->label[0]);
3811 }
3812
3813 /* Update SRv6 SID */
3814 if (attr->srv6_l3vpn) {
3815 extra = bgp_path_info_extra_get(pi);
3816 if (sid_diff(&extra->sid[0], &attr->srv6_l3vpn->sid)) {
3817 sid_copy(&extra->sid[0],
3818 &attr->srv6_l3vpn->sid);
3819 extra->num_sids = 1;
3820 }
3821 } else if (attr->srv6_vpn) {
3822 extra = bgp_path_info_extra_get(pi);
3823 if (sid_diff(&extra->sid[0], &attr->srv6_vpn->sid)) {
3824 sid_copy(&extra->sid[0], &attr->srv6_vpn->sid);
3825 extra->num_sids = 1;
3826 }
3827 }
3828
3829 #ifdef ENABLE_BGP_VNC
3830 if ((afi == AFI_IP || afi == AFI_IP6)
3831 && (safi == SAFI_UNICAST)) {
3832 if (vnc_implicit_withdraw) {
3833 /*
3834 * Add back the route with its new attributes
3835 * (e.g., nexthop).
3836 * The route is still selected, until the route
3837 * selection
3838 * queued by bgp_process actually runs. We have
3839 * to make this
3840 * update to the VNC side immediately to avoid
3841 * racing against
3842 * configuration changes (e.g., route-map
3843 * changes) which
3844 * trigger re-importation of the entire RIB.
3845 */
3846 vnc_import_bgp_add_route(bgp, p, pi);
3847 vnc_import_bgp_exterior_add_route(bgp, p, pi);
3848 }
3849 }
3850 #endif
3851 /* Update Overlay Index */
3852 if (afi == AFI_L2VPN) {
3853 overlay_index_update(
3854 pi->attr,
3855 evpn == NULL ? NULL : &evpn->gw_ip);
3856 }
3857
3858 /* Update bgp route dampening information. */
3859 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3860 && peer->sort == BGP_PEER_EBGP) {
3861 /* Now we do normal update dampening. */
3862 ret = bgp_damp_update(pi, dest, afi, safi);
3863 if (ret == BGP_DAMP_SUPPRESSED) {
3864 bgp_dest_unlock_node(dest);
3865 return 0;
3866 }
3867 }
3868
3869 /* Nexthop reachability check - for unicast and
3870 * labeled-unicast.. */
3871 if (((afi == AFI_IP || afi == AFI_IP6)
3872 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
3873 || (safi == SAFI_EVPN &&
3874 bgp_evpn_is_prefix_nht_supported(p))) {
3875 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
3876 && peer->ttl == BGP_DEFAULT_TTL
3877 && !CHECK_FLAG(peer->flags,
3878 PEER_FLAG_DISABLE_CONNECTED_CHECK)
3879 && !CHECK_FLAG(bgp->flags,
3880 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
3881 connected = 1;
3882 else
3883 connected = 0;
3884
3885 struct bgp *bgp_nexthop = bgp;
3886
3887 if (pi->extra && pi->extra->bgp_orig)
3888 bgp_nexthop = pi->extra->bgp_orig;
3889
3890 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
3891
3892 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
3893 pi, NULL, connected)
3894 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
3895 bgp_path_info_set_flag(dest, pi,
3896 BGP_PATH_VALID);
3897 else {
3898 if (BGP_DEBUG(nht, NHT)) {
3899 zlog_debug("%s(%pI4): NH unresolved",
3900 __func__,
3901 (in_addr_t *)&attr_new->nexthop);
3902 }
3903 bgp_path_info_unset_flag(dest, pi,
3904 BGP_PATH_VALID);
3905 }
3906 } else
3907 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
3908
3909 #ifdef ENABLE_BGP_VNC
3910 if (safi == SAFI_MPLS_VPN) {
3911 struct bgp_dest *pdest = NULL;
3912 struct bgp_table *table = NULL;
3913
3914 pdest = bgp_node_get(bgp->rib[afi][safi],
3915 (struct prefix *)prd);
3916 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3917 table = bgp_dest_get_bgp_table_info(pdest);
3918
3919 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3920 bgp, prd, table, p, pi);
3921 }
3922 bgp_dest_unlock_node(pdest);
3923 }
3924 #endif
3925
3926 /* If this is an EVPN route and some attribute has changed,
3927 * process
3928 * route for import. If the extended community has changed, we
3929 * would
3930 * have done the un-import earlier and the import would result
3931 * in the
3932 * route getting injected into appropriate L2 VNIs. If it is
3933 * just
3934 * some other attribute change, the import will result in
3935 * updating
3936 * the attributes for the route in the VNI(s).
3937 */
3938 if (safi == SAFI_EVPN && !same_attr &&
3939 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
3940 bgp_evpn_import_route(bgp, afi, safi, p, pi);
3941
3942 /* Process change. */
3943 bgp_aggregate_increment(bgp, p, pi, afi, safi);
3944
3945 bgp_process(bgp, dest, afi, safi);
3946 bgp_dest_unlock_node(dest);
3947
3948 if (SAFI_UNICAST == safi
3949 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
3950 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3951
3952 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
3953 }
3954 if ((SAFI_MPLS_VPN == safi)
3955 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3956
3957 vpn_leak_to_vrf_update(bgp, pi);
3958 }
3959
3960 #ifdef ENABLE_BGP_VNC
3961 if (SAFI_MPLS_VPN == safi) {
3962 mpls_label_t label_decoded = decode_label(label);
3963
3964 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
3965 type, sub_type, &label_decoded);
3966 }
3967 if (SAFI_ENCAP == safi) {
3968 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
3969 type, sub_type, NULL);
3970 }
3971 #endif
3972
3973 return 0;
3974 } // End of implicit withdraw
3975
3976 /* Received Logging. */
3977 if (bgp_debug_update(peer, p, NULL, 1)) {
3978 if (!peer->rcvd_attr_printed) {
3979 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
3980 peer->rcvd_attr_str);
3981 peer->rcvd_attr_printed = 1;
3982 }
3983
3984 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
3985 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3986 sizeof(pfx_buf));
3987 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3988 }
3989
3990 /* Make new BGP info. */
3991 new = info_make(type, sub_type, 0, peer, attr_new, dest);
3992
3993 /* Update MPLS label */
3994 if (has_valid_label) {
3995 extra = bgp_path_info_extra_get(new);
3996 if (extra->label != label) {
3997 memcpy(&extra->label, label,
3998 num_labels * sizeof(mpls_label_t));
3999 extra->num_labels = num_labels;
4000 }
4001 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4002 bgp_set_valid_label(&extra->label[0]);
4003 }
4004
4005 /* Update SRv6 SID */
4006 if (safi == SAFI_MPLS_VPN) {
4007 extra = bgp_path_info_extra_get(new);
4008 if (attr->srv6_l3vpn) {
4009 sid_copy(&extra->sid[0], &attr->srv6_l3vpn->sid);
4010 extra->num_sids = 1;
4011 } else if (attr->srv6_vpn) {
4012 sid_copy(&extra->sid[0], &attr->srv6_vpn->sid);
4013 extra->num_sids = 1;
4014 }
4015 }
4016
4017 /* Update Overlay Index */
4018 if (afi == AFI_L2VPN) {
4019 overlay_index_update(new->attr,
4020 evpn == NULL ? NULL : &evpn->gw_ip);
4021 }
4022 /* Nexthop reachability check. */
4023 if (((afi == AFI_IP || afi == AFI_IP6)
4024 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4025 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4026 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4027 && peer->ttl == BGP_DEFAULT_TTL
4028 && !CHECK_FLAG(peer->flags,
4029 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4030 && !CHECK_FLAG(bgp->flags,
4031 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4032 connected = 1;
4033 else
4034 connected = 0;
4035
4036 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4037
4038 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, new, NULL,
4039 connected)
4040 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4041 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4042 else {
4043 if (BGP_DEBUG(nht, NHT)) {
4044 char buf1[INET6_ADDRSTRLEN];
4045 inet_ntop(AF_INET,
4046 (const void *)&attr_new->nexthop,
4047 buf1, INET6_ADDRSTRLEN);
4048 zlog_debug("%s(%s): NH unresolved", __func__,
4049 buf1);
4050 }
4051 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4052 }
4053 } else
4054 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4055
4056 /* Addpath ID */
4057 new->addpath_rx_id = addpath_id;
4058
4059 /* Increment prefix */
4060 bgp_aggregate_increment(bgp, p, new, afi, safi);
4061
4062 /* Register new BGP information. */
4063 bgp_path_info_add(dest, new);
4064
4065 /* route_node_get lock */
4066 bgp_dest_unlock_node(dest);
4067
4068 #ifdef ENABLE_BGP_VNC
4069 if (safi == SAFI_MPLS_VPN) {
4070 struct bgp_dest *pdest = NULL;
4071 struct bgp_table *table = NULL;
4072
4073 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4074 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4075 table = bgp_dest_get_bgp_table_info(pdest);
4076
4077 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4078 bgp, prd, table, p, new);
4079 }
4080 bgp_dest_unlock_node(pdest);
4081 }
4082 #endif
4083
4084 /* If this is an EVPN route, process for import. */
4085 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4086 bgp_evpn_import_route(bgp, afi, safi, p, new);
4087
4088 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4089
4090 /* Process change. */
4091 bgp_process(bgp, dest, afi, safi);
4092
4093 if (SAFI_UNICAST == safi
4094 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4095 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4096 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4097 }
4098 if ((SAFI_MPLS_VPN == safi)
4099 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4100
4101 vpn_leak_to_vrf_update(bgp, new);
4102 }
4103 #ifdef ENABLE_BGP_VNC
4104 if (SAFI_MPLS_VPN == safi) {
4105 mpls_label_t label_decoded = decode_label(label);
4106
4107 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4108 sub_type, &label_decoded);
4109 }
4110 if (SAFI_ENCAP == safi) {
4111 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4112 sub_type, NULL);
4113 }
4114 #endif
4115
4116 return 0;
4117
4118 /* This BGP update is filtered. Log the reason then update BGP
4119 entry. */
4120 filtered:
4121 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4122
4123 if (bgp_debug_update(peer, p, NULL, 1)) {
4124 if (!peer->rcvd_attr_printed) {
4125 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
4126 peer->rcvd_attr_str);
4127 peer->rcvd_attr_printed = 1;
4128 }
4129
4130 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4131 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4132 sizeof(pfx_buf));
4133 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
4134 peer->host, pfx_buf, reason);
4135 }
4136
4137 if (pi) {
4138 /* If this is an EVPN route, un-import it as it is now filtered.
4139 */
4140 if (safi == SAFI_EVPN)
4141 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4142
4143 if (SAFI_UNICAST == safi
4144 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4145 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4146
4147 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4148 }
4149 if ((SAFI_MPLS_VPN == safi)
4150 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4151
4152 vpn_leak_to_vrf_withdraw(bgp, pi);
4153 }
4154
4155 bgp_rib_remove(dest, pi, peer, afi, safi);
4156 }
4157
4158 bgp_dest_unlock_node(dest);
4159
4160 #ifdef ENABLE_BGP_VNC
4161 /*
4162 * Filtered update is treated as an implicit withdrawal (see
4163 * bgp_rib_remove()
4164 * a few lines above)
4165 */
4166 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4167 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4168 0);
4169 }
4170 #endif
4171
4172 return 0;
4173 }
4174
4175 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4176 struct attr *attr, afi_t afi, safi_t safi, int type,
4177 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4178 uint32_t num_labels, struct bgp_route_evpn *evpn)
4179 {
4180 struct bgp *bgp;
4181 char pfx_buf[BGP_PRD_PATH_STRLEN];
4182 struct bgp_dest *dest;
4183 struct bgp_path_info *pi;
4184
4185 #ifdef ENABLE_BGP_VNC
4186 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4187 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4188 0);
4189 }
4190 #endif
4191
4192 bgp = peer->bgp;
4193
4194 /* Lookup node. */
4195 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4196
4197 /* If peer is soft reconfiguration enabled. Record input packet for
4198 * further calculation.
4199 *
4200 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4201 * routes that are filtered. This tanks out Quagga RS pretty badly due
4202 * to
4203 * the iteration over all RS clients.
4204 * Since we need to remove the entry from adj_in anyway, do that first
4205 * and
4206 * if there was no entry, we don't need to do anything more.
4207 */
4208 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4209 && peer != bgp->peer_self)
4210 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4211 peer->stat_pfx_dup_withdraw++;
4212
4213 if (bgp_debug_update(peer, p, NULL, 1)) {
4214 bgp_debug_rdpfxpath2str(
4215 afi, safi, prd, p, label, num_labels,
4216 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4217 sizeof(pfx_buf));
4218 zlog_debug(
4219 "%s withdrawing route %s not in adj-in",
4220 peer->host, pfx_buf);
4221 }
4222 bgp_dest_unlock_node(dest);
4223 return 0;
4224 }
4225
4226 /* Lookup withdrawn route. */
4227 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4228 if (pi->peer == peer && pi->type == type
4229 && pi->sub_type == sub_type
4230 && pi->addpath_rx_id == addpath_id)
4231 break;
4232
4233 /* Logging. */
4234 if (bgp_debug_update(peer, p, NULL, 1)) {
4235 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4236 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4237 sizeof(pfx_buf));
4238 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
4239 pfx_buf);
4240 }
4241
4242 /* Withdraw specified route from routing table. */
4243 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4244 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4245 if (SAFI_UNICAST == safi
4246 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4247 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4248 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4249 }
4250 if ((SAFI_MPLS_VPN == safi)
4251 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4252
4253 vpn_leak_to_vrf_withdraw(bgp, pi);
4254 }
4255 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4256 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4257 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4258 sizeof(pfx_buf));
4259 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4260 }
4261
4262 /* Unlock bgp_node_get() lock. */
4263 bgp_dest_unlock_node(dest);
4264
4265 return 0;
4266 }
4267
4268 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4269 int withdraw)
4270 {
4271 struct update_subgroup *subgrp;
4272 subgrp = peer_subgroup(peer, afi, safi);
4273 subgroup_default_originate(subgrp, withdraw);
4274 }
4275
4276
4277 /*
4278 * bgp_stop_announce_route_timer
4279 */
4280 void bgp_stop_announce_route_timer(struct peer_af *paf)
4281 {
4282 if (!paf->t_announce_route)
4283 return;
4284
4285 THREAD_TIMER_OFF(paf->t_announce_route);
4286 }
4287
4288 /*
4289 * bgp_announce_route_timer_expired
4290 *
4291 * Callback that is invoked when the route announcement timer for a
4292 * peer_af expires.
4293 */
4294 static int bgp_announce_route_timer_expired(struct thread *t)
4295 {
4296 struct peer_af *paf;
4297 struct peer *peer;
4298
4299 paf = THREAD_ARG(t);
4300 peer = paf->peer;
4301
4302 if (peer->status != Established)
4303 return 0;
4304
4305 if (!peer->afc_nego[paf->afi][paf->safi])
4306 return 0;
4307
4308 peer_af_announce_route(paf, 1);
4309 return 0;
4310 }
4311
4312 /*
4313 * bgp_announce_route
4314 *
4315 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
4316 */
4317 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi)
4318 {
4319 struct peer_af *paf;
4320 struct update_subgroup *subgrp;
4321
4322 paf = peer_af_find(peer, afi, safi);
4323 if (!paf)
4324 return;
4325 subgrp = PAF_SUBGRP(paf);
4326
4327 /*
4328 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
4329 * or a refresh has already been triggered.
4330 */
4331 if (!subgrp || paf->t_announce_route)
4332 return;
4333
4334 /*
4335 * Start a timer to stagger/delay the announce. This serves
4336 * two purposes - announcement can potentially be combined for
4337 * multiple peers and the announcement doesn't happen in the
4338 * vty context.
4339 */
4340 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
4341 (subgrp->peer_count == 1)
4342 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
4343 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
4344 &paf->t_announce_route);
4345 }
4346
4347 /*
4348 * Announce routes from all AF tables to a peer.
4349 *
4350 * This should ONLY be called when there is a need to refresh the
4351 * routes to the peer based on a policy change for this peer alone
4352 * or a route refresh request received from the peer.
4353 * The operation will result in splitting the peer from its existing
4354 * subgroups and putting it in new subgroups.
4355 */
4356 void bgp_announce_route_all(struct peer *peer)
4357 {
4358 afi_t afi;
4359 safi_t safi;
4360
4361 FOREACH_AFI_SAFI (afi, safi)
4362 bgp_announce_route(peer, afi, safi);
4363 }
4364
4365 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
4366 struct bgp_table *table,
4367 struct prefix_rd *prd)
4368 {
4369 int ret;
4370 struct bgp_dest *dest;
4371 struct bgp_adj_in *ain;
4372
4373 if (!table)
4374 table = peer->bgp->rib[afi][safi];
4375
4376 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
4377 for (ain = dest->adj_in; ain; ain = ain->next) {
4378 if (ain->peer != peer)
4379 continue;
4380
4381 struct bgp_path_info *pi;
4382 uint32_t num_labels = 0;
4383 mpls_label_t *label_pnt = NULL;
4384 struct bgp_route_evpn evpn;
4385
4386 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
4387 pi = pi->next)
4388 if (pi->peer == peer)
4389 break;
4390
4391 if (pi && pi->extra)
4392 num_labels = pi->extra->num_labels;
4393 if (num_labels)
4394 label_pnt = &pi->extra->label[0];
4395 if (pi)
4396 memcpy(&evpn, &pi->attr->evpn_overlay,
4397 sizeof(evpn));
4398 else
4399 memset(&evpn, 0, sizeof(evpn));
4400
4401 ret = bgp_update(peer, bgp_dest_get_prefix(dest),
4402 ain->addpath_rx_id, ain->attr, afi,
4403 safi, ZEBRA_ROUTE_BGP,
4404 BGP_ROUTE_NORMAL, prd, label_pnt,
4405 num_labels, 1, &evpn);
4406
4407 if (ret < 0) {
4408 bgp_dest_unlock_node(dest);
4409 return;
4410 }
4411 }
4412 }
4413
4414 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
4415 {
4416 struct bgp_dest *dest;
4417 struct bgp_table *table;
4418
4419 if (peer->status != Established)
4420 return;
4421
4422 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
4423 && (safi != SAFI_EVPN))
4424 bgp_soft_reconfig_table(peer, afi, safi, NULL, NULL);
4425 else
4426 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4427 dest = bgp_route_next(dest)) {
4428 table = bgp_dest_get_bgp_table_info(dest);
4429
4430 if (table == NULL)
4431 continue;
4432
4433 const struct prefix *p = bgp_dest_get_prefix(dest);
4434 struct prefix_rd prd;
4435
4436 prd.family = AF_UNSPEC;
4437 prd.prefixlen = 64;
4438 memcpy(&prd.val, p->u.val, 8);
4439
4440 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
4441 }
4442 }
4443
4444
4445 struct bgp_clear_node_queue {
4446 struct bgp_dest *dest;
4447 };
4448
4449 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
4450 {
4451 struct bgp_clear_node_queue *cnq = data;
4452 struct bgp_dest *dest = cnq->dest;
4453 struct peer *peer = wq->spec.data;
4454 struct bgp_path_info *pi;
4455 struct bgp *bgp;
4456 afi_t afi = bgp_dest_table(dest)->afi;
4457 safi_t safi = bgp_dest_table(dest)->safi;
4458
4459 assert(dest && peer);
4460 bgp = peer->bgp;
4461
4462 /* It is possible that we have multiple paths for a prefix from a peer
4463 * if that peer is using AddPath.
4464 */
4465 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
4466 if (pi->peer != peer)
4467 continue;
4468
4469 /* graceful restart STALE flag set. */
4470 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
4471 && peer->nsf[afi][safi]
4472 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
4473 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
4474 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
4475 else {
4476 /* If this is an EVPN route, process for
4477 * un-import. */
4478 if (safi == SAFI_EVPN)
4479 bgp_evpn_unimport_route(
4480 bgp, afi, safi,
4481 bgp_dest_get_prefix(dest), pi);
4482 /* Handle withdraw for VRF route-leaking and L3VPN */
4483 if (SAFI_UNICAST == safi
4484 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
4485 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4486 vpn_leak_from_vrf_withdraw(bgp_get_default(),
4487 bgp, pi);
4488 }
4489 if (SAFI_MPLS_VPN == safi &&
4490 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4491 vpn_leak_to_vrf_withdraw(bgp, pi);
4492 }
4493
4494 bgp_rib_remove(dest, pi, peer, afi, safi);
4495 }
4496 }
4497 return WQ_SUCCESS;
4498 }
4499
4500 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
4501 {
4502 struct bgp_clear_node_queue *cnq = data;
4503 struct bgp_dest *dest = cnq->dest;
4504 struct bgp_table *table = bgp_dest_table(dest);
4505
4506 bgp_dest_unlock_node(dest);
4507 bgp_table_unlock(table);
4508 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
4509 }
4510
4511 static void bgp_clear_node_complete(struct work_queue *wq)
4512 {
4513 struct peer *peer = wq->spec.data;
4514
4515 /* Tickle FSM to start moving again */
4516 BGP_EVENT_ADD(peer, Clearing_Completed);
4517
4518 peer_unlock(peer); /* bgp_clear_route */
4519 }
4520
4521 static void bgp_clear_node_queue_init(struct peer *peer)
4522 {
4523 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
4524
4525 snprintf(wname, sizeof(wname), "clear %s", peer->host);
4526 #undef CLEAR_QUEUE_NAME_LEN
4527
4528 peer->clear_node_queue = work_queue_new(bm->master, wname);
4529 peer->clear_node_queue->spec.hold = 10;
4530 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
4531 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
4532 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
4533 peer->clear_node_queue->spec.max_retries = 0;
4534
4535 /* we only 'lock' this peer reference when the queue is actually active
4536 */
4537 peer->clear_node_queue->spec.data = peer;
4538 }
4539
4540 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
4541 struct bgp_table *table)
4542 {
4543 struct bgp_dest *dest;
4544 int force = bm->process_main_queue ? 0 : 1;
4545
4546 if (!table)
4547 table = peer->bgp->rib[afi][safi];
4548
4549 /* If still no table => afi/safi isn't configured at all or smth. */
4550 if (!table)
4551 return;
4552
4553 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4554 struct bgp_path_info *pi, *next;
4555 struct bgp_adj_in *ain;
4556 struct bgp_adj_in *ain_next;
4557
4558 /* XXX:TODO: This is suboptimal, every non-empty route_node is
4559 * queued for every clearing peer, regardless of whether it is
4560 * relevant to the peer at hand.
4561 *
4562 * Overview: There are 3 different indices which need to be
4563 * scrubbed, potentially, when a peer is removed:
4564 *
4565 * 1 peer's routes visible via the RIB (ie accepted routes)
4566 * 2 peer's routes visible by the (optional) peer's adj-in index
4567 * 3 other routes visible by the peer's adj-out index
4568 *
4569 * 3 there is no hurry in scrubbing, once the struct peer is
4570 * removed from bgp->peer, we could just GC such deleted peer's
4571 * adj-outs at our leisure.
4572 *
4573 * 1 and 2 must be 'scrubbed' in some way, at least made
4574 * invisible via RIB index before peer session is allowed to be
4575 * brought back up. So one needs to know when such a 'search' is
4576 * complete.
4577 *
4578 * Ideally:
4579 *
4580 * - there'd be a single global queue or a single RIB walker
4581 * - rather than tracking which route_nodes still need to be
4582 * examined on a peer basis, we'd track which peers still
4583 * aren't cleared
4584 *
4585 * Given that our per-peer prefix-counts now should be reliable,
4586 * this may actually be achievable. It doesn't seem to be a huge
4587 * problem at this time,
4588 *
4589 * It is possible that we have multiple paths for a prefix from
4590 * a peer
4591 * if that peer is using AddPath.
4592 */
4593 ain = dest->adj_in;
4594 while (ain) {
4595 ain_next = ain->next;
4596
4597 if (ain->peer == peer) {
4598 bgp_adj_in_remove(dest, ain);
4599 bgp_dest_unlock_node(dest);
4600 }
4601
4602 ain = ain_next;
4603 }
4604
4605 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
4606 next = pi->next;
4607 if (pi->peer != peer)
4608 continue;
4609
4610 if (force)
4611 bgp_path_info_reap(dest, pi);
4612 else {
4613 struct bgp_clear_node_queue *cnq;
4614
4615 /* both unlocked in bgp_clear_node_queue_del */
4616 bgp_table_lock(bgp_dest_table(dest));
4617 bgp_dest_lock_node(dest);
4618 cnq = XCALLOC(
4619 MTYPE_BGP_CLEAR_NODE_QUEUE,
4620 sizeof(struct bgp_clear_node_queue));
4621 cnq->dest = dest;
4622 work_queue_add(peer->clear_node_queue, cnq);
4623 break;
4624 }
4625 }
4626 }
4627 return;
4628 }
4629
4630 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
4631 {
4632 struct bgp_dest *dest;
4633 struct bgp_table *table;
4634
4635 if (peer->clear_node_queue == NULL)
4636 bgp_clear_node_queue_init(peer);
4637
4638 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
4639 * Idle until it receives a Clearing_Completed event. This protects
4640 * against peers which flap faster than we can we clear, which could
4641 * lead to:
4642 *
4643 * a) race with routes from the new session being installed before
4644 * clear_route_node visits the node (to delete the route of that
4645 * peer)
4646 * b) resource exhaustion, clear_route_node likely leads to an entry
4647 * on the process_main queue. Fast-flapping could cause that queue
4648 * to grow and grow.
4649 */
4650
4651 /* lock peer in assumption that clear-node-queue will get nodes; if so,
4652 * the unlock will happen upon work-queue completion; other wise, the
4653 * unlock happens at the end of this function.
4654 */
4655 if (!peer->clear_node_queue->thread)
4656 peer_lock(peer);
4657
4658 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
4659 bgp_clear_route_table(peer, afi, safi, NULL);
4660 else
4661 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4662 dest = bgp_route_next(dest)) {
4663 table = bgp_dest_get_bgp_table_info(dest);
4664 if (!table)
4665 continue;
4666
4667 bgp_clear_route_table(peer, afi, safi, table);
4668 }
4669
4670 /* unlock if no nodes got added to the clear-node-queue. */
4671 if (!peer->clear_node_queue->thread)
4672 peer_unlock(peer);
4673 }
4674
4675 void bgp_clear_route_all(struct peer *peer)
4676 {
4677 afi_t afi;
4678 safi_t safi;
4679
4680 FOREACH_AFI_SAFI (afi, safi)
4681 bgp_clear_route(peer, afi, safi);
4682
4683 #ifdef ENABLE_BGP_VNC
4684 rfapiProcessPeerDown(peer);
4685 #endif
4686 }
4687
4688 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
4689 {
4690 struct bgp_table *table;
4691 struct bgp_dest *dest;
4692 struct bgp_adj_in *ain;
4693 struct bgp_adj_in *ain_next;
4694
4695 table = peer->bgp->rib[afi][safi];
4696
4697 /* It is possible that we have multiple paths for a prefix from a peer
4698 * if that peer is using AddPath.
4699 */
4700 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4701 ain = dest->adj_in;
4702
4703 while (ain) {
4704 ain_next = ain->next;
4705
4706 if (ain->peer == peer) {
4707 bgp_adj_in_remove(dest, ain);
4708 bgp_dest_unlock_node(dest);
4709 }
4710
4711 ain = ain_next;
4712 }
4713 }
4714 }
4715
4716 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
4717 {
4718 struct bgp_dest *dest;
4719 struct bgp_path_info *pi;
4720 struct bgp_table *table;
4721
4722 if (safi == SAFI_MPLS_VPN) {
4723 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4724 dest = bgp_route_next(dest)) {
4725 struct bgp_dest *rm;
4726
4727 /* look for neighbor in tables */
4728 table = bgp_dest_get_bgp_table_info(dest);
4729 if (!table)
4730 continue;
4731
4732 for (rm = bgp_table_top(table); rm;
4733 rm = bgp_route_next(rm))
4734 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
4735 pi = pi->next) {
4736 if (pi->peer != peer)
4737 continue;
4738 if (!CHECK_FLAG(pi->flags,
4739 BGP_PATH_STALE))
4740 break;
4741
4742 bgp_rib_remove(rm, pi, peer, afi, safi);
4743 break;
4744 }
4745 }
4746 } else {
4747 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4748 dest = bgp_route_next(dest))
4749 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
4750 pi = pi->next) {
4751 if (pi->peer != peer)
4752 continue;
4753 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
4754 break;
4755 bgp_rib_remove(dest, pi, peer, afi, safi);
4756 break;
4757 }
4758 }
4759 }
4760
4761 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
4762 {
4763 if (peer->sort == BGP_PEER_IBGP)
4764 return true;
4765
4766 if (peer->sort == BGP_PEER_EBGP
4767 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
4768 || FILTER_LIST_OUT_NAME(filter)
4769 || DISTRIBUTE_OUT_NAME(filter)))
4770 return true;
4771 return false;
4772 }
4773
4774 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
4775 {
4776 if (peer->sort == BGP_PEER_IBGP)
4777 return true;
4778
4779 if (peer->sort == BGP_PEER_EBGP
4780 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
4781 || FILTER_LIST_IN_NAME(filter)
4782 || DISTRIBUTE_IN_NAME(filter)))
4783 return true;
4784 return false;
4785 }
4786
4787 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
4788 safi_t safi)
4789 {
4790 struct bgp_dest *dest;
4791 struct bgp_path_info *pi;
4792 struct bgp_path_info *next;
4793
4794 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
4795 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
4796 const struct prefix *p = bgp_dest_get_prefix(dest);
4797
4798 next = pi->next;
4799
4800 /* Unimport EVPN routes from VRFs */
4801 if (safi == SAFI_EVPN)
4802 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
4803 SAFI_EVPN, p, pi);
4804
4805 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
4806 && pi->type == ZEBRA_ROUTE_BGP
4807 && (pi->sub_type == BGP_ROUTE_NORMAL
4808 || pi->sub_type == BGP_ROUTE_AGGREGATE
4809 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
4810
4811 if (bgp_fibupd_safi(safi))
4812 bgp_zebra_withdraw(p, pi, bgp, safi);
4813 }
4814
4815 bgp_path_info_reap(dest, pi);
4816 }
4817 }
4818
4819 /* Delete all kernel routes. */
4820 void bgp_cleanup_routes(struct bgp *bgp)
4821 {
4822 afi_t afi;
4823 struct bgp_dest *dest;
4824 struct bgp_table *table;
4825
4826 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
4827 if (afi == AFI_L2VPN)
4828 continue;
4829 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
4830 SAFI_UNICAST);
4831 /*
4832 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
4833 */
4834 if (afi != AFI_L2VPN) {
4835 safi_t safi;
4836 safi = SAFI_MPLS_VPN;
4837 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
4838 dest = bgp_route_next(dest)) {
4839 table = bgp_dest_get_bgp_table_info(dest);
4840 if (table != NULL) {
4841 bgp_cleanup_table(bgp, table, safi);
4842 bgp_table_finish(&table);
4843 bgp_dest_set_bgp_table_info(dest, NULL);
4844 bgp_dest_unlock_node(dest);
4845 }
4846 }
4847 safi = SAFI_ENCAP;
4848 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
4849 dest = bgp_route_next(dest)) {
4850 table = bgp_dest_get_bgp_table_info(dest);
4851 if (table != NULL) {
4852 bgp_cleanup_table(bgp, table, safi);
4853 bgp_table_finish(&table);
4854 bgp_dest_set_bgp_table_info(dest, NULL);
4855 bgp_dest_unlock_node(dest);
4856 }
4857 }
4858 }
4859 }
4860 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
4861 dest = bgp_route_next(dest)) {
4862 table = bgp_dest_get_bgp_table_info(dest);
4863 if (table != NULL) {
4864 bgp_cleanup_table(bgp, table, SAFI_EVPN);
4865 bgp_table_finish(&table);
4866 bgp_dest_set_bgp_table_info(dest, NULL);
4867 bgp_dest_unlock_node(dest);
4868 }
4869 }
4870 }
4871
4872 void bgp_reset(void)
4873 {
4874 vty_reset();
4875 bgp_zclient_reset();
4876 access_list_reset();
4877 prefix_list_reset();
4878 }
4879
4880 static int bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
4881 {
4882 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
4883 && CHECK_FLAG(peer->af_cap[afi][safi],
4884 PEER_CAP_ADDPATH_AF_TX_RCV));
4885 }
4886
4887 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
4888 value. */
4889 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
4890 struct bgp_nlri *packet)
4891 {
4892 uint8_t *pnt;
4893 uint8_t *lim;
4894 struct prefix p;
4895 int psize;
4896 int ret;
4897 afi_t afi;
4898 safi_t safi;
4899 int addpath_encoded;
4900 uint32_t addpath_id;
4901
4902 pnt = packet->nlri;
4903 lim = pnt + packet->length;
4904 afi = packet->afi;
4905 safi = packet->safi;
4906 addpath_id = 0;
4907 addpath_encoded = bgp_addpath_encode_rx(peer, afi, safi);
4908
4909 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
4910 syntactic validity. If the field is syntactically incorrect,
4911 then the Error Subcode is set to Invalid Network Field. */
4912 for (; pnt < lim; pnt += psize) {
4913 /* Clear prefix structure. */
4914 memset(&p, 0, sizeof(struct prefix));
4915
4916 if (addpath_encoded) {
4917
4918 /* When packet overflow occurs return immediately. */
4919 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
4920 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
4921
4922 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
4923 addpath_id = ntohl(addpath_id);
4924 pnt += BGP_ADDPATH_ID_LEN;
4925 }
4926
4927 /* Fetch prefix length. */
4928 p.prefixlen = *pnt++;
4929 /* afi/safi validity already verified by caller,
4930 * bgp_update_receive */
4931 p.family = afi2family(afi);
4932
4933 /* Prefix length check. */
4934 if (p.prefixlen > prefix_blen(&p) * 8) {
4935 flog_err(
4936 EC_BGP_UPDATE_RCV,
4937 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
4938 peer->host, p.prefixlen, packet->afi);
4939 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
4940 }
4941
4942 /* Packet size overflow check. */
4943 psize = PSIZE(p.prefixlen);
4944
4945 /* When packet overflow occur return immediately. */
4946 if (pnt + psize > lim) {
4947 flog_err(
4948 EC_BGP_UPDATE_RCV,
4949 "%s [Error] Update packet error (prefix length %d overflows packet)",
4950 peer->host, p.prefixlen);
4951 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
4952 }
4953
4954 /* Defensive coding, double-check the psize fits in a struct
4955 * prefix */
4956 if (psize > (ssize_t)sizeof(p.u)) {
4957 flog_err(
4958 EC_BGP_UPDATE_RCV,
4959 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
4960 peer->host, p.prefixlen, sizeof(p.u));
4961 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
4962 }
4963
4964 /* Fetch prefix from NLRI packet. */
4965 memcpy(p.u.val, pnt, psize);
4966
4967 /* Check address. */
4968 if (afi == AFI_IP && safi == SAFI_UNICAST) {
4969 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
4970 /* From RFC4271 Section 6.3:
4971 *
4972 * If a prefix in the NLRI field is semantically
4973 * incorrect
4974 * (e.g., an unexpected multicast IP address),
4975 * an error SHOULD
4976 * be logged locally, and the prefix SHOULD be
4977 * ignored.
4978 */
4979 flog_err(
4980 EC_BGP_UPDATE_RCV,
4981 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
4982 peer->host, inet_ntoa(p.u.prefix4));
4983 continue;
4984 }
4985 }
4986
4987 /* Check address. */
4988 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
4989 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
4990 char buf[BUFSIZ];
4991
4992 flog_err(
4993 EC_BGP_UPDATE_RCV,
4994 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
4995 peer->host,
4996 inet_ntop(AF_INET6, &p.u.prefix6, buf,
4997 BUFSIZ));
4998
4999 continue;
5000 }
5001 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
5002 char buf[BUFSIZ];
5003
5004 flog_err(
5005 EC_BGP_UPDATE_RCV,
5006 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
5007 peer->host,
5008 inet_ntop(AF_INET6, &p.u.prefix6, buf,
5009 BUFSIZ));
5010
5011 continue;
5012 }
5013 }
5014
5015 /* Normal process. */
5016 if (attr)
5017 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
5018 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
5019 NULL, NULL, 0, 0, NULL);
5020 else
5021 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
5022 safi, ZEBRA_ROUTE_BGP,
5023 BGP_ROUTE_NORMAL, NULL, NULL, 0,
5024 NULL);
5025
5026 /* Do not send BGP notification twice when maximum-prefix count
5027 * overflow. */
5028 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
5029 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
5030
5031 /* Address family configuration mismatch. */
5032 if (ret < 0)
5033 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
5034 }
5035
5036 /* Packet length consistency check. */
5037 if (pnt != lim) {
5038 flog_err(
5039 EC_BGP_UPDATE_RCV,
5040 "%s [Error] Update packet error (prefix length mismatch with total length)",
5041 peer->host);
5042 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5043 }
5044
5045 return BGP_NLRI_PARSE_OK;
5046 }
5047
5048 static struct bgp_static *bgp_static_new(void)
5049 {
5050 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
5051 }
5052
5053 static void bgp_static_free(struct bgp_static *bgp_static)
5054 {
5055 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5056 route_map_counter_decrement(bgp_static->rmap.map);
5057
5058 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
5059 XFREE(MTYPE_BGP_STATIC, bgp_static);
5060 }
5061
5062 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
5063 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
5064 {
5065 struct bgp_dest *dest;
5066 struct bgp_path_info *pi;
5067 struct bgp_path_info *new;
5068 struct bgp_path_info rmap_path;
5069 struct attr attr;
5070 struct attr *attr_new;
5071 route_map_result_t ret;
5072 #ifdef ENABLE_BGP_VNC
5073 int vnc_implicit_withdraw = 0;
5074 #endif
5075
5076 assert(bgp_static);
5077
5078 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5079
5080 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5081
5082 attr.nexthop = bgp_static->igpnexthop;
5083 attr.med = bgp_static->igpmetric;
5084 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5085
5086 if (bgp_static->atomic)
5087 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
5088
5089 /* Store label index, if required. */
5090 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
5091 attr.label_index = bgp_static->label_index;
5092 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
5093 }
5094
5095 /* Apply route-map. */
5096 if (bgp_static->rmap.name) {
5097 struct attr attr_tmp = attr;
5098
5099 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
5100 rmap_path.peer = bgp->peer_self;
5101 rmap_path.attr = &attr_tmp;
5102
5103 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5104
5105 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
5106 &rmap_path);
5107
5108 bgp->peer_self->rmap_type = 0;
5109
5110 if (ret == RMAP_DENYMATCH) {
5111 /* Free uninterned attribute. */
5112 bgp_attr_flush(&attr_tmp);
5113
5114 /* Unintern original. */
5115 aspath_unintern(&attr.aspath);
5116 bgp_static_withdraw(bgp, p, afi, safi);
5117 return;
5118 }
5119
5120 if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN))
5121 bgp_attr_add_gshut_community(&attr_tmp);
5122
5123 attr_new = bgp_attr_intern(&attr_tmp);
5124 } else {
5125
5126 if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN))
5127 bgp_attr_add_gshut_community(&attr);
5128
5129 attr_new = bgp_attr_intern(&attr);
5130 }
5131
5132 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5133 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5134 && pi->sub_type == BGP_ROUTE_STATIC)
5135 break;
5136
5137 if (pi) {
5138 if (attrhash_cmp(pi->attr, attr_new)
5139 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
5140 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
5141 bgp_dest_unlock_node(dest);
5142 bgp_attr_unintern(&attr_new);
5143 aspath_unintern(&attr.aspath);
5144 return;
5145 } else {
5146 /* The attribute is changed. */
5147 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5148
5149 /* Rewrite BGP route information. */
5150 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5151 bgp_path_info_restore(dest, pi);
5152 else
5153 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5154 #ifdef ENABLE_BGP_VNC
5155 if ((afi == AFI_IP || afi == AFI_IP6)
5156 && (safi == SAFI_UNICAST)) {
5157 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
5158 /*
5159 * Implicit withdraw case.
5160 * We have to do this before pi is
5161 * changed
5162 */
5163 ++vnc_implicit_withdraw;
5164 vnc_import_bgp_del_route(bgp, p, pi);
5165 vnc_import_bgp_exterior_del_route(
5166 bgp, p, pi);
5167 }
5168 }
5169 #endif
5170 bgp_attr_unintern(&pi->attr);
5171 pi->attr = attr_new;
5172 pi->uptime = bgp_clock();
5173 #ifdef ENABLE_BGP_VNC
5174 if ((afi == AFI_IP || afi == AFI_IP6)
5175 && (safi == SAFI_UNICAST)) {
5176 if (vnc_implicit_withdraw) {
5177 vnc_import_bgp_add_route(bgp, p, pi);
5178 vnc_import_bgp_exterior_add_route(
5179 bgp, p, pi);
5180 }
5181 }
5182 #endif
5183
5184 /* Nexthop reachability check. */
5185 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5186 && (safi == SAFI_UNICAST
5187 || safi == SAFI_LABELED_UNICAST)) {
5188
5189 struct bgp *bgp_nexthop = bgp;
5190
5191 if (pi->extra && pi->extra->bgp_orig)
5192 bgp_nexthop = pi->extra->bgp_orig;
5193
5194 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
5195 afi, pi, NULL, 0))
5196 bgp_path_info_set_flag(dest, pi,
5197 BGP_PATH_VALID);
5198 else {
5199 if (BGP_DEBUG(nht, NHT)) {
5200 char buf1[INET6_ADDRSTRLEN];
5201 inet_ntop(p->family,
5202 &p->u.prefix, buf1,
5203 INET6_ADDRSTRLEN);
5204 zlog_debug(
5205 "%s(%s): Route not in table, not advertising",
5206 __func__, buf1);
5207 }
5208 bgp_path_info_unset_flag(
5209 dest, pi, BGP_PATH_VALID);
5210 }
5211 } else {
5212 /* Delete the NHT structure if any, if we're
5213 * toggling between
5214 * enabling/disabling import check. We
5215 * deregister the route
5216 * from NHT to avoid overloading NHT and the
5217 * process interaction
5218 */
5219 bgp_unlink_nexthop(pi);
5220 bgp_path_info_set_flag(dest, pi,
5221 BGP_PATH_VALID);
5222 }
5223 /* Process change. */
5224 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5225 bgp_process(bgp, dest, afi, safi);
5226
5227 if (SAFI_UNICAST == safi
5228 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5229 || bgp->inst_type
5230 == BGP_INSTANCE_TYPE_DEFAULT)) {
5231 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
5232 pi);
5233 }
5234
5235 bgp_dest_unlock_node(dest);
5236 aspath_unintern(&attr.aspath);
5237 return;
5238 }
5239 }
5240
5241 /* Make new BGP info. */
5242 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5243 attr_new, dest);
5244 /* Nexthop reachability check. */
5245 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5246 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
5247 if (bgp_find_or_add_nexthop(bgp, bgp, afi, new, NULL, 0))
5248 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5249 else {
5250 if (BGP_DEBUG(nht, NHT)) {
5251 char buf1[INET6_ADDRSTRLEN];
5252 inet_ntop(p->family, &p->u.prefix, buf1,
5253 INET6_ADDRSTRLEN);
5254 zlog_debug(
5255 "%s(%s): Route not in table, not advertising",
5256 __func__, buf1);
5257 }
5258 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
5259 }
5260 } else {
5261 /* Delete the NHT structure if any, if we're toggling between
5262 * enabling/disabling import check. We deregister the route
5263 * from NHT to avoid overloading NHT and the process interaction
5264 */
5265 bgp_unlink_nexthop(new);
5266
5267 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5268 }
5269
5270 /* Aggregate address increment. */
5271 bgp_aggregate_increment(bgp, p, new, afi, safi);
5272
5273 /* Register new BGP information. */
5274 bgp_path_info_add(dest, new);
5275
5276 /* route_node_get lock */
5277 bgp_dest_unlock_node(dest);
5278
5279 /* Process change. */
5280 bgp_process(bgp, dest, afi, safi);
5281
5282 if (SAFI_UNICAST == safi
5283 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5284 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5285 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
5286 }
5287
5288 /* Unintern original. */
5289 aspath_unintern(&attr.aspath);
5290 }
5291
5292 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
5293 safi_t safi)
5294 {
5295 struct bgp_dest *dest;
5296 struct bgp_path_info *pi;
5297
5298 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5299
5300 /* Check selected route and self inserted route. */
5301 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5302 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5303 && pi->sub_type == BGP_ROUTE_STATIC)
5304 break;
5305
5306 /* Withdraw static BGP route from routing table. */
5307 if (pi) {
5308 if (SAFI_UNICAST == safi
5309 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5310 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5311 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5312 }
5313 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5314 bgp_unlink_nexthop(pi);
5315 bgp_path_info_delete(dest, pi);
5316 bgp_process(bgp, dest, afi, safi);
5317 }
5318
5319 /* Unlock bgp_node_lookup. */
5320 bgp_dest_unlock_node(dest);
5321 }
5322
5323 /*
5324 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
5325 */
5326 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
5327 afi_t afi, safi_t safi,
5328 struct prefix_rd *prd)
5329 {
5330 struct bgp_dest *dest;
5331 struct bgp_path_info *pi;
5332
5333 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
5334
5335 /* Check selected route and self inserted route. */
5336 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5337 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5338 && pi->sub_type == BGP_ROUTE_STATIC)
5339 break;
5340
5341 /* Withdraw static BGP route from routing table. */
5342 if (pi) {
5343 #ifdef ENABLE_BGP_VNC
5344 rfapiProcessWithdraw(
5345 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
5346 1); /* Kill, since it is an administrative change */
5347 #endif
5348 if (SAFI_MPLS_VPN == safi
5349 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5350 vpn_leak_to_vrf_withdraw(bgp, pi);
5351 }
5352 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5353 bgp_path_info_delete(dest, pi);
5354 bgp_process(bgp, dest, afi, safi);
5355 }
5356
5357 /* Unlock bgp_node_lookup. */
5358 bgp_dest_unlock_node(dest);
5359 }
5360
5361 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
5362 struct bgp_static *bgp_static, afi_t afi,
5363 safi_t safi)
5364 {
5365 struct bgp_dest *dest;
5366 struct bgp_path_info *new;
5367 struct attr *attr_new;
5368 struct attr attr = {0};
5369 struct bgp_path_info *pi;
5370 #ifdef ENABLE_BGP_VNC
5371 mpls_label_t label = 0;
5372 #endif
5373 uint32_t num_labels = 0;
5374 union gw_addr add;
5375
5376 assert(bgp_static);
5377
5378 if (bgp_static->label != MPLS_INVALID_LABEL)
5379 num_labels = 1;
5380 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
5381 &bgp_static->prd);
5382
5383 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5384
5385 attr.nexthop = bgp_static->igpnexthop;
5386 attr.med = bgp_static->igpmetric;
5387 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5388
5389 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
5390 || (safi == SAFI_ENCAP)) {
5391 if (afi == AFI_IP) {
5392 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
5393 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
5394 }
5395 }
5396 if (afi == AFI_L2VPN) {
5397 if (bgp_static->gatewayIp.family == AF_INET)
5398 add.ipv4.s_addr =
5399 bgp_static->gatewayIp.u.prefix4.s_addr;
5400 else if (bgp_static->gatewayIp.family == AF_INET6)
5401 memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
5402 sizeof(struct in6_addr));
5403 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
5404 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
5405 struct bgp_encap_type_vxlan bet;
5406 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
5407 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
5408 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
5409 }
5410 if (bgp_static->router_mac) {
5411 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
5412 }
5413 }
5414 /* Apply route-map. */
5415 if (bgp_static->rmap.name) {
5416 struct attr attr_tmp = attr;
5417 struct bgp_path_info rmap_path;
5418 route_map_result_t ret;
5419
5420 rmap_path.peer = bgp->peer_self;
5421 rmap_path.attr = &attr_tmp;
5422
5423 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5424
5425 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
5426 &rmap_path);
5427
5428 bgp->peer_self->rmap_type = 0;
5429
5430 if (ret == RMAP_DENYMATCH) {
5431 /* Free uninterned attribute. */
5432 bgp_attr_flush(&attr_tmp);
5433
5434 /* Unintern original. */
5435 aspath_unintern(&attr.aspath);
5436 bgp_static_withdraw_safi(bgp, p, afi, safi,
5437 &bgp_static->prd);
5438 return;
5439 }
5440
5441 attr_new = bgp_attr_intern(&attr_tmp);
5442 } else {
5443 attr_new = bgp_attr_intern(&attr);
5444 }
5445
5446 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5447 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5448 && pi->sub_type == BGP_ROUTE_STATIC)
5449 break;
5450
5451 if (pi) {
5452 memset(&add, 0, sizeof(union gw_addr));
5453 if (attrhash_cmp(pi->attr, attr_new)
5454 && overlay_index_equal(afi, pi, &add)
5455 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
5456 bgp_dest_unlock_node(dest);
5457 bgp_attr_unintern(&attr_new);
5458 aspath_unintern(&attr.aspath);
5459 return;
5460 } else {
5461 /* The attribute is changed. */
5462 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5463
5464 /* Rewrite BGP route information. */
5465 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5466 bgp_path_info_restore(dest, pi);
5467 else
5468 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5469 bgp_attr_unintern(&pi->attr);
5470 pi->attr = attr_new;
5471 pi->uptime = bgp_clock();
5472 #ifdef ENABLE_BGP_VNC
5473 if (pi->extra)
5474 label = decode_label(&pi->extra->label[0]);
5475 #endif
5476
5477 /* Process change. */
5478 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5479 bgp_process(bgp, dest, afi, safi);
5480
5481 if (SAFI_MPLS_VPN == safi
5482 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5483 vpn_leak_to_vrf_update(bgp, pi);
5484 }
5485 #ifdef ENABLE_BGP_VNC
5486 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
5487 pi->attr, afi, safi, pi->type,
5488 pi->sub_type, &label);
5489 #endif
5490 bgp_dest_unlock_node(dest);
5491 aspath_unintern(&attr.aspath);
5492 return;
5493 }
5494 }
5495
5496
5497 /* Make new BGP info. */
5498 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5499 attr_new, dest);
5500 SET_FLAG(new->flags, BGP_PATH_VALID);
5501 new->extra = bgp_path_info_extra_new();
5502 if (num_labels) {
5503 new->extra->label[0] = bgp_static->label;
5504 new->extra->num_labels = num_labels;
5505 }
5506 #ifdef ENABLE_BGP_VNC
5507 label = decode_label(&bgp_static->label);
5508 #endif
5509
5510 /* Aggregate address increment. */
5511 bgp_aggregate_increment(bgp, p, new, afi, safi);
5512
5513 /* Register new BGP information. */
5514 bgp_path_info_add(dest, new);
5515 /* route_node_get lock */
5516 bgp_dest_unlock_node(dest);
5517
5518 /* Process change. */
5519 bgp_process(bgp, dest, afi, safi);
5520
5521 if (SAFI_MPLS_VPN == safi
5522 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5523 vpn_leak_to_vrf_update(bgp, new);
5524 }
5525 #ifdef ENABLE_BGP_VNC
5526 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
5527 safi, new->type, new->sub_type, &label);
5528 #endif
5529
5530 /* Unintern original. */
5531 aspath_unintern(&attr.aspath);
5532 }
5533
5534 /* Configure static BGP network. When user don't run zebra, static
5535 route should be installed as valid. */
5536 static int bgp_static_set(struct vty *vty, const char *negate,
5537 const char *ip_str, afi_t afi, safi_t safi,
5538 const char *rmap, int backdoor, uint32_t label_index)
5539 {
5540 VTY_DECLVAR_CONTEXT(bgp, bgp);
5541 int ret;
5542 struct prefix p;
5543 struct bgp_static *bgp_static;
5544 struct bgp_dest *dest;
5545 uint8_t need_update = 0;
5546
5547 /* Convert IP prefix string to struct prefix. */
5548 ret = str2prefix(ip_str, &p);
5549 if (!ret) {
5550 vty_out(vty, "%% Malformed prefix\n");
5551 return CMD_WARNING_CONFIG_FAILED;
5552 }
5553 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
5554 vty_out(vty, "%% Malformed prefix (link-local address)\n");
5555 return CMD_WARNING_CONFIG_FAILED;
5556 }
5557
5558 apply_mask(&p);
5559
5560 if (negate) {
5561
5562 /* Set BGP static route configuration. */
5563 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
5564
5565 if (!dest) {
5566 vty_out(vty, "%% Can't find static route specified\n");
5567 return CMD_WARNING_CONFIG_FAILED;
5568 }
5569
5570 bgp_static = bgp_dest_get_bgp_static_info(dest);
5571
5572 if ((label_index != BGP_INVALID_LABEL_INDEX)
5573 && (label_index != bgp_static->label_index)) {
5574 vty_out(vty,
5575 "%% label-index doesn't match static route\n");
5576 return CMD_WARNING_CONFIG_FAILED;
5577 }
5578
5579 if ((rmap && bgp_static->rmap.name)
5580 && strcmp(rmap, bgp_static->rmap.name)) {
5581 vty_out(vty,
5582 "%% route-map name doesn't match static route\n");
5583 return CMD_WARNING_CONFIG_FAILED;
5584 }
5585
5586 /* Update BGP RIB. */
5587 if (!bgp_static->backdoor)
5588 bgp_static_withdraw(bgp, &p, afi, safi);
5589
5590 /* Clear configuration. */
5591 bgp_static_free(bgp_static);
5592 bgp_dest_set_bgp_static_info(dest, NULL);
5593 bgp_dest_unlock_node(dest);
5594 bgp_dest_unlock_node(dest);
5595 } else {
5596
5597 /* Set BGP static route configuration. */
5598 dest = bgp_node_get(bgp->route[afi][safi], &p);
5599 bgp_static = bgp_dest_get_bgp_static_info(dest);
5600 if (bgp_static) {
5601 /* Configuration change. */
5602 /* Label index cannot be changed. */
5603 if (bgp_static->label_index != label_index) {
5604 vty_out(vty, "%% cannot change label-index\n");
5605 return CMD_WARNING_CONFIG_FAILED;
5606 }
5607
5608 /* Check previous routes are installed into BGP. */
5609 if (bgp_static->valid
5610 && bgp_static->backdoor != backdoor)
5611 need_update = 1;
5612
5613 bgp_static->backdoor = backdoor;
5614
5615 if (rmap) {
5616 XFREE(MTYPE_ROUTE_MAP_NAME,
5617 bgp_static->rmap.name);
5618 route_map_counter_decrement(
5619 bgp_static->rmap.map);
5620 bgp_static->rmap.name =
5621 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5622 bgp_static->rmap.map =
5623 route_map_lookup_by_name(rmap);
5624 route_map_counter_increment(
5625 bgp_static->rmap.map);
5626 } else {
5627 XFREE(MTYPE_ROUTE_MAP_NAME,
5628 bgp_static->rmap.name);
5629 route_map_counter_decrement(
5630 bgp_static->rmap.map);
5631 bgp_static->rmap.map = NULL;
5632 bgp_static->valid = 0;
5633 }
5634 bgp_dest_unlock_node(dest);
5635 } else {
5636 /* New configuration. */
5637 bgp_static = bgp_static_new();
5638 bgp_static->backdoor = backdoor;
5639 bgp_static->valid = 0;
5640 bgp_static->igpmetric = 0;
5641 bgp_static->igpnexthop.s_addr = INADDR_ANY;
5642 bgp_static->label_index = label_index;
5643
5644 if (rmap) {
5645 XFREE(MTYPE_ROUTE_MAP_NAME,
5646 bgp_static->rmap.name);
5647 route_map_counter_decrement(
5648 bgp_static->rmap.map);
5649 bgp_static->rmap.name =
5650 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5651 bgp_static->rmap.map =
5652 route_map_lookup_by_name(rmap);
5653 route_map_counter_increment(
5654 bgp_static->rmap.map);
5655 }
5656 bgp_dest_set_bgp_static_info(dest, bgp_static);
5657 }
5658
5659 bgp_static->valid = 1;
5660 if (need_update)
5661 bgp_static_withdraw(bgp, &p, afi, safi);
5662
5663 if (!bgp_static->backdoor)
5664 bgp_static_update(bgp, &p, bgp_static, afi, safi);
5665 }
5666
5667 return CMD_SUCCESS;
5668 }
5669
5670 void bgp_static_add(struct bgp *bgp)
5671 {
5672 afi_t afi;
5673 safi_t safi;
5674 struct bgp_dest *dest;
5675 struct bgp_dest *rm;
5676 struct bgp_table *table;
5677 struct bgp_static *bgp_static;
5678
5679 FOREACH_AFI_SAFI (afi, safi)
5680 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
5681 dest = bgp_route_next(dest)) {
5682 if (!bgp_dest_has_bgp_path_info_data(dest))
5683 continue;
5684
5685 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5686 || (safi == SAFI_EVPN)) {
5687 table = bgp_dest_get_bgp_table_info(dest);
5688
5689 for (rm = bgp_table_top(table); rm;
5690 rm = bgp_route_next(rm)) {
5691 bgp_static =
5692 bgp_dest_get_bgp_static_info(
5693 rm);
5694 bgp_static_update_safi(
5695 bgp, bgp_dest_get_prefix(rm),
5696 bgp_static, afi, safi);
5697 }
5698 } else {
5699 bgp_static_update(
5700 bgp, bgp_dest_get_prefix(dest),
5701 bgp_dest_get_bgp_static_info(dest), afi,
5702 safi);
5703 }
5704 }
5705 }
5706
5707 /* Called from bgp_delete(). Delete all static routes from the BGP
5708 instance. */
5709 void bgp_static_delete(struct bgp *bgp)
5710 {
5711 afi_t afi;
5712 safi_t safi;
5713 struct bgp_dest *dest;
5714 struct bgp_dest *rm;
5715 struct bgp_table *table;
5716 struct bgp_static *bgp_static;
5717
5718 FOREACH_AFI_SAFI (afi, safi)
5719 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
5720 dest = bgp_route_next(dest)) {
5721 if (!bgp_dest_has_bgp_path_info_data(dest))
5722 continue;
5723
5724 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5725 || (safi == SAFI_EVPN)) {
5726 table = bgp_dest_get_bgp_table_info(dest);
5727
5728 for (rm = bgp_table_top(table); rm;
5729 rm = bgp_route_next(rm)) {
5730 bgp_static =
5731 bgp_dest_get_bgp_static_info(
5732 rm);
5733 if (!bgp_static)
5734 continue;
5735
5736 bgp_static_withdraw_safi(
5737 bgp, bgp_dest_get_prefix(rm),
5738 AFI_IP, safi,
5739 (struct prefix_rd *)
5740 bgp_dest_get_prefix(
5741 dest));
5742 bgp_static_free(bgp_static);
5743 bgp_dest_set_bgp_static_info(dest,
5744 NULL);
5745 bgp_dest_unlock_node(dest);
5746 }
5747 } else {
5748 bgp_static = bgp_dest_get_bgp_static_info(dest);
5749 bgp_static_withdraw(bgp,
5750 bgp_dest_get_prefix(dest),
5751 afi, safi);
5752 bgp_static_free(bgp_static);
5753 bgp_dest_set_bgp_static_info(dest, NULL);
5754 bgp_dest_unlock_node(dest);
5755 }
5756 }
5757 }
5758
5759 void bgp_static_redo_import_check(struct bgp *bgp)
5760 {
5761 afi_t afi;
5762 safi_t safi;
5763 struct bgp_dest *dest;
5764 struct bgp_dest *rm;
5765 struct bgp_table *table;
5766 struct bgp_static *bgp_static;
5767
5768 /* Use this flag to force reprocessing of the route */
5769 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
5770 FOREACH_AFI_SAFI (afi, safi) {
5771 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
5772 dest = bgp_route_next(dest)) {
5773 if (!bgp_dest_has_bgp_path_info_data(dest))
5774 continue;
5775
5776 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5777 || (safi == SAFI_EVPN)) {
5778 table = bgp_dest_get_bgp_table_info(dest);
5779
5780 for (rm = bgp_table_top(table); rm;
5781 rm = bgp_route_next(rm)) {
5782 bgp_static =
5783 bgp_dest_get_bgp_static_info(
5784 rm);
5785 bgp_static_update_safi(
5786 bgp, bgp_dest_get_prefix(rm),
5787 bgp_static, afi, safi);
5788 }
5789 } else {
5790 bgp_static = bgp_dest_get_bgp_static_info(dest);
5791 bgp_static_update(bgp,
5792 bgp_dest_get_prefix(dest),
5793 bgp_static, afi, safi);
5794 }
5795 }
5796 }
5797 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
5798 }
5799
5800 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
5801 safi_t safi)
5802 {
5803 struct bgp_table *table;
5804 struct bgp_dest *dest;
5805 struct bgp_path_info *pi;
5806
5807 /* Do not install the aggregate route if BGP is in the
5808 * process of termination.
5809 */
5810 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
5811 || (bgp->peer_self == NULL))
5812 return;
5813
5814 table = bgp->rib[afi][safi];
5815 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5816 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5817 if (pi->peer == bgp->peer_self
5818 && ((pi->type == ZEBRA_ROUTE_BGP
5819 && pi->sub_type == BGP_ROUTE_STATIC)
5820 || (pi->type != ZEBRA_ROUTE_BGP
5821 && pi->sub_type
5822 == BGP_ROUTE_REDISTRIBUTE))) {
5823 bgp_aggregate_decrement(
5824 bgp, bgp_dest_get_prefix(dest), pi, afi,
5825 safi);
5826 bgp_unlink_nexthop(pi);
5827 bgp_path_info_delete(dest, pi);
5828 bgp_process(bgp, dest, afi, safi);
5829 }
5830 }
5831 }
5832 }
5833
5834 /*
5835 * Purge all networks and redistributed routes from routing table.
5836 * Invoked upon the instance going down.
5837 */
5838 void bgp_purge_static_redist_routes(struct bgp *bgp)
5839 {
5840 afi_t afi;
5841 safi_t safi;
5842
5843 FOREACH_AFI_SAFI (afi, safi)
5844 bgp_purge_af_static_redist_routes(bgp, afi, safi);
5845 }
5846
5847 /*
5848 * gpz 110624
5849 * Currently this is used to set static routes for VPN and ENCAP.
5850 * I think it can probably be factored with bgp_static_set.
5851 */
5852 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
5853 const char *ip_str, const char *rd_str,
5854 const char *label_str, const char *rmap_str,
5855 int evpn_type, const char *esi, const char *gwip,
5856 const char *ethtag, const char *routermac)
5857 {
5858 VTY_DECLVAR_CONTEXT(bgp, bgp);
5859 int ret;
5860 struct prefix p;
5861 struct prefix_rd prd;
5862 struct bgp_dest *pdest;
5863 struct bgp_dest *dest;
5864 struct bgp_table *table;
5865 struct bgp_static *bgp_static;
5866 mpls_label_t label = MPLS_INVALID_LABEL;
5867 struct prefix gw_ip;
5868
5869 /* validate ip prefix */
5870 ret = str2prefix(ip_str, &p);
5871 if (!ret) {
5872 vty_out(vty, "%% Malformed prefix\n");
5873 return CMD_WARNING_CONFIG_FAILED;
5874 }
5875 apply_mask(&p);
5876 if ((afi == AFI_L2VPN)
5877 && (bgp_build_evpn_prefix(evpn_type,
5878 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5879 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5880 return CMD_WARNING_CONFIG_FAILED;
5881 }
5882
5883 ret = str2prefix_rd(rd_str, &prd);
5884 if (!ret) {
5885 vty_out(vty, "%% Malformed rd\n");
5886 return CMD_WARNING_CONFIG_FAILED;
5887 }
5888
5889 if (label_str) {
5890 unsigned long label_val;
5891 label_val = strtoul(label_str, NULL, 10);
5892 encode_label(label_val, &label);
5893 }
5894
5895 if (safi == SAFI_EVPN) {
5896 if (esi && str2esi(esi, NULL) == 0) {
5897 vty_out(vty, "%% Malformed ESI\n");
5898 return CMD_WARNING_CONFIG_FAILED;
5899 }
5900 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
5901 vty_out(vty, "%% Malformed Router MAC\n");
5902 return CMD_WARNING_CONFIG_FAILED;
5903 }
5904 if (gwip) {
5905 memset(&gw_ip, 0, sizeof(struct prefix));
5906 ret = str2prefix(gwip, &gw_ip);
5907 if (!ret) {
5908 vty_out(vty, "%% Malformed GatewayIp\n");
5909 return CMD_WARNING_CONFIG_FAILED;
5910 }
5911 if ((gw_ip.family == AF_INET
5912 && is_evpn_prefix_ipaddr_v6(
5913 (struct prefix_evpn *)&p))
5914 || (gw_ip.family == AF_INET6
5915 && is_evpn_prefix_ipaddr_v4(
5916 (struct prefix_evpn *)&p))) {
5917 vty_out(vty,
5918 "%% GatewayIp family differs with IP prefix\n");
5919 return CMD_WARNING_CONFIG_FAILED;
5920 }
5921 }
5922 }
5923 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5924 if (!bgp_dest_has_bgp_path_info_data(pdest))
5925 bgp_dest_set_bgp_table_info(pdest,
5926 bgp_table_init(bgp, afi, safi));
5927 table = bgp_dest_get_bgp_table_info(pdest);
5928
5929 dest = bgp_node_get(table, &p);
5930
5931 if (bgp_dest_has_bgp_path_info_data(dest)) {
5932 vty_out(vty, "%% Same network configuration exists\n");
5933 bgp_dest_unlock_node(dest);
5934 } else {
5935 /* New configuration. */
5936 bgp_static = bgp_static_new();
5937 bgp_static->backdoor = 0;
5938 bgp_static->valid = 0;
5939 bgp_static->igpmetric = 0;
5940 bgp_static->igpnexthop.s_addr = INADDR_ANY;
5941 bgp_static->label = label;
5942 bgp_static->prd = prd;
5943
5944 if (rmap_str) {
5945 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5946 route_map_counter_decrement(bgp_static->rmap.map);
5947 bgp_static->rmap.name =
5948 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
5949 bgp_static->rmap.map =
5950 route_map_lookup_by_name(rmap_str);
5951 route_map_counter_increment(bgp_static->rmap.map);
5952 }
5953
5954 if (safi == SAFI_EVPN) {
5955 if (esi) {
5956 bgp_static->eth_s_id =
5957 XCALLOC(MTYPE_ATTR,
5958 sizeof(esi_t));
5959 str2esi(esi, bgp_static->eth_s_id);
5960 }
5961 if (routermac) {
5962 bgp_static->router_mac =
5963 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
5964 (void)prefix_str2mac(routermac,
5965 bgp_static->router_mac);
5966 }
5967 if (gwip)
5968 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
5969 }
5970 bgp_dest_set_bgp_static_info(dest, bgp_static);
5971
5972 bgp_static->valid = 1;
5973 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
5974 }
5975
5976 return CMD_SUCCESS;
5977 }
5978
5979 /* Configure static BGP network. */
5980 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
5981 const char *ip_str, const char *rd_str,
5982 const char *label_str, int evpn_type, const char *esi,
5983 const char *gwip, const char *ethtag)
5984 {
5985 VTY_DECLVAR_CONTEXT(bgp, bgp);
5986 int ret;
5987 struct prefix p;
5988 struct prefix_rd prd;
5989 struct bgp_dest *pdest;
5990 struct bgp_dest *dest;
5991 struct bgp_table *table;
5992 struct bgp_static *bgp_static;
5993 mpls_label_t label = MPLS_INVALID_LABEL;
5994
5995 /* Convert IP prefix string to struct prefix. */
5996 ret = str2prefix(ip_str, &p);
5997 if (!ret) {
5998 vty_out(vty, "%% Malformed prefix\n");
5999 return CMD_WARNING_CONFIG_FAILED;
6000 }
6001 apply_mask(&p);
6002 if ((afi == AFI_L2VPN)
6003 && (bgp_build_evpn_prefix(evpn_type,
6004 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6005 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6006 return CMD_WARNING_CONFIG_FAILED;
6007 }
6008 ret = str2prefix_rd(rd_str, &prd);
6009 if (!ret) {
6010 vty_out(vty, "%% Malformed rd\n");
6011 return CMD_WARNING_CONFIG_FAILED;
6012 }
6013
6014 if (label_str) {
6015 unsigned long label_val;
6016 label_val = strtoul(label_str, NULL, 10);
6017 encode_label(label_val, &label);
6018 }
6019
6020 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6021 if (!bgp_dest_has_bgp_path_info_data(pdest))
6022 bgp_dest_set_bgp_table_info(pdest,
6023 bgp_table_init(bgp, afi, safi));
6024 else
6025 bgp_dest_unlock_node(pdest);
6026 table = bgp_dest_get_bgp_table_info(pdest);
6027
6028 dest = bgp_node_lookup(table, &p);
6029
6030 if (dest) {
6031 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
6032
6033 bgp_static = bgp_dest_get_bgp_static_info(dest);
6034 bgp_static_free(bgp_static);
6035 bgp_dest_set_bgp_static_info(dest, NULL);
6036 bgp_dest_unlock_node(dest);
6037 bgp_dest_unlock_node(dest);
6038 } else
6039 vty_out(vty, "%% Can't find the route\n");
6040
6041 return CMD_SUCCESS;
6042 }
6043
6044 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
6045 const char *rmap_name)
6046 {
6047 VTY_DECLVAR_CONTEXT(bgp, bgp);
6048 struct bgp_rmap *rmap;
6049
6050 rmap = &bgp->table_map[afi][safi];
6051 if (rmap_name) {
6052 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6053 route_map_counter_decrement(rmap->map);
6054 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
6055 rmap->map = route_map_lookup_by_name(rmap_name);
6056 route_map_counter_increment(rmap->map);
6057 } else {
6058 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6059 route_map_counter_decrement(rmap->map);
6060 rmap->map = NULL;
6061 }
6062
6063 if (bgp_fibupd_safi(safi))
6064 bgp_zebra_announce_table(bgp, afi, safi);
6065
6066 return CMD_SUCCESS;
6067 }
6068
6069 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
6070 const char *rmap_name)
6071 {
6072 VTY_DECLVAR_CONTEXT(bgp, bgp);
6073 struct bgp_rmap *rmap;
6074
6075 rmap = &bgp->table_map[afi][safi];
6076 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6077 route_map_counter_decrement(rmap->map);
6078 rmap->map = NULL;
6079
6080 if (bgp_fibupd_safi(safi))
6081 bgp_zebra_announce_table(bgp, afi, safi);
6082
6083 return CMD_SUCCESS;
6084 }
6085
6086 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
6087 safi_t safi)
6088 {
6089 if (bgp->table_map[afi][safi].name) {
6090 vty_out(vty, " table-map %s\n",
6091 bgp->table_map[afi][safi].name);
6092 }
6093 }
6094
6095 DEFUN (bgp_table_map,
6096 bgp_table_map_cmd,
6097 "table-map WORD",
6098 "BGP table to RIB route download filter\n"
6099 "Name of the route map\n")
6100 {
6101 int idx_word = 1;
6102 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6103 argv[idx_word]->arg);
6104 }
6105 DEFUN (no_bgp_table_map,
6106 no_bgp_table_map_cmd,
6107 "no table-map WORD",
6108 NO_STR
6109 "BGP table to RIB route download filter\n"
6110 "Name of the route map\n")
6111 {
6112 int idx_word = 2;
6113 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6114 argv[idx_word]->arg);
6115 }
6116
6117 DEFPY(bgp_network,
6118 bgp_network_cmd,
6119 "[no] network \
6120 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
6121 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
6122 backdoor$backdoor}]",
6123 NO_STR
6124 "Specify a network to announce via BGP\n"
6125 "IPv4 prefix\n"
6126 "Network number\n"
6127 "Network mask\n"
6128 "Network mask\n"
6129 "Route-map to modify the attributes\n"
6130 "Name of the route map\n"
6131 "Label index to associate with the prefix\n"
6132 "Label index value\n"
6133 "Specify a BGP backdoor route\n")
6134 {
6135 char addr_prefix_str[BUFSIZ];
6136
6137 if (address_str) {
6138 int ret;
6139
6140 ret = netmask_str2prefix_str(address_str, netmask_str,
6141 addr_prefix_str);
6142 if (!ret) {
6143 vty_out(vty, "%% Inconsistent address and mask\n");
6144 return CMD_WARNING_CONFIG_FAILED;
6145 }
6146 }
6147
6148 return bgp_static_set(
6149 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
6150 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
6151 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
6152 }
6153
6154 DEFPY(ipv6_bgp_network,
6155 ipv6_bgp_network_cmd,
6156 "[no] network X:X::X:X/M$prefix \
6157 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
6158 NO_STR
6159 "Specify a network to announce via BGP\n"
6160 "IPv6 prefix\n"
6161 "Route-map to modify the attributes\n"
6162 "Name of the route map\n"
6163 "Label index to associate with the prefix\n"
6164 "Label index value\n")
6165 {
6166 return bgp_static_set(
6167 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
6168 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
6169 }
6170
6171 static struct bgp_aggregate *bgp_aggregate_new(void)
6172 {
6173 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
6174 }
6175
6176 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
6177 {
6178 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
6179 route_map_counter_decrement(aggregate->rmap.map);
6180 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
6181 }
6182
6183 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
6184 struct aspath *aspath,
6185 struct community *comm,
6186 struct ecommunity *ecomm,
6187 struct lcommunity *lcomm)
6188 {
6189 static struct aspath *ae = NULL;
6190
6191 if (!ae)
6192 ae = aspath_empty();
6193
6194 if (!pi)
6195 return false;
6196
6197 if (origin != pi->attr->origin)
6198 return false;
6199
6200 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
6201 return false;
6202
6203 if (!community_cmp(pi->attr->community, comm))
6204 return false;
6205
6206 if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
6207 return false;
6208
6209 if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
6210 return false;
6211
6212 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
6213 return false;
6214
6215 return true;
6216 }
6217
6218 static void bgp_aggregate_install(
6219 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
6220 uint8_t origin, struct aspath *aspath, struct community *community,
6221 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
6222 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
6223 {
6224 struct bgp_dest *dest;
6225 struct bgp_table *table;
6226 struct bgp_path_info *pi, *orig, *new;
6227 struct attr *attr;
6228
6229 table = bgp->rib[afi][safi];
6230
6231 dest = bgp_node_get(table, p);
6232
6233 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6234 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6235 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6236 break;
6237
6238 if (aggregate->count > 0) {
6239 /*
6240 * If the aggregate information has not changed
6241 * no need to re-install it again.
6242 */
6243 if (bgp_aggregate_info_same(orig, origin, aspath, community,
6244 ecommunity, lcommunity)) {
6245 bgp_dest_unlock_node(dest);
6246
6247 if (aspath)
6248 aspath_free(aspath);
6249 if (community)
6250 community_free(&community);
6251 if (ecommunity)
6252 ecommunity_free(&ecommunity);
6253 if (lcommunity)
6254 lcommunity_free(&lcommunity);
6255
6256 return;
6257 }
6258
6259 /*
6260 * Mark the old as unusable
6261 */
6262 if (pi)
6263 bgp_path_info_delete(dest, pi);
6264
6265 attr = bgp_attr_aggregate_intern(
6266 bgp, origin, aspath, community, ecommunity, lcommunity,
6267 aggregate, atomic_aggregate, p);
6268
6269 if (!attr) {
6270 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
6271 return;
6272 }
6273
6274 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
6275 bgp->peer_self, attr, dest);
6276
6277 SET_FLAG(new->flags, BGP_PATH_VALID);
6278
6279 bgp_path_info_add(dest, new);
6280 bgp_process(bgp, dest, afi, safi);
6281 } else {
6282 for (pi = orig; pi; pi = pi->next)
6283 if (pi->peer == bgp->peer_self
6284 && pi->type == ZEBRA_ROUTE_BGP
6285 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6286 break;
6287
6288 /* Withdraw static BGP route from routing table. */
6289 if (pi) {
6290 bgp_path_info_delete(dest, pi);
6291 bgp_process(bgp, dest, afi, safi);
6292 }
6293 }
6294
6295 bgp_dest_unlock_node(dest);
6296 }
6297
6298 /* Update an aggregate as routes are added/removed from the BGP table */
6299 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
6300 safi_t safi, struct bgp_aggregate *aggregate)
6301 {
6302 struct bgp_table *table;
6303 struct bgp_dest *top;
6304 struct bgp_dest *dest;
6305 uint8_t origin;
6306 struct aspath *aspath = NULL;
6307 struct community *community = NULL;
6308 struct ecommunity *ecommunity = NULL;
6309 struct lcommunity *lcommunity = NULL;
6310 struct bgp_path_info *pi;
6311 unsigned long match = 0;
6312 uint8_t atomic_aggregate = 0;
6313
6314 /* If the bgp instance is being deleted or self peer is deleted
6315 * then do not create aggregate route
6316 */
6317 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6318 || (bgp->peer_self == NULL))
6319 return;
6320
6321 /* ORIGIN attribute: If at least one route among routes that are
6322 aggregated has ORIGIN with the value INCOMPLETE, then the
6323 aggregated route must have the ORIGIN attribute with the value
6324 INCOMPLETE. Otherwise, if at least one route among routes that
6325 are aggregated has ORIGIN with the value EGP, then the aggregated
6326 route must have the origin attribute with the value EGP. In all
6327 other case the value of the ORIGIN attribute of the aggregated
6328 route is INTERNAL. */
6329 origin = BGP_ORIGIN_IGP;
6330
6331 table = bgp->rib[afi][safi];
6332
6333 top = bgp_node_get(table, p);
6334 for (dest = bgp_node_get(table, p); dest;
6335 dest = bgp_route_next_until(dest, top)) {
6336 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
6337
6338 if (dest_p->prefixlen <= p->prefixlen)
6339 continue;
6340
6341 match = 0;
6342
6343 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6344 if (BGP_PATH_HOLDDOWN(pi))
6345 continue;
6346
6347 if (pi->attr->flag
6348 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
6349 atomic_aggregate = 1;
6350
6351 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6352 continue;
6353
6354 /*
6355 * summary-only aggregate route suppress
6356 * aggregated route announcements.
6357 */
6358 if (aggregate->summary_only) {
6359 (bgp_path_info_extra_get(pi))->suppress++;
6360 bgp_path_info_set_flag(dest, pi,
6361 BGP_PATH_ATTR_CHANGED);
6362 match++;
6363 }
6364
6365 aggregate->count++;
6366
6367 /*
6368 * If at least one route among routes that are
6369 * aggregated has ORIGIN with the value INCOMPLETE,
6370 * then the aggregated route MUST have the ORIGIN
6371 * attribute with the value INCOMPLETE. Otherwise, if
6372 * at least one route among routes that are aggregated
6373 * has ORIGIN with the value EGP, then the aggregated
6374 * route MUST have the ORIGIN attribute with the value
6375 * EGP.
6376 */
6377 switch (pi->attr->origin) {
6378 case BGP_ORIGIN_INCOMPLETE:
6379 aggregate->incomplete_origin_count++;
6380 break;
6381 case BGP_ORIGIN_EGP:
6382 aggregate->egp_origin_count++;
6383 break;
6384 default:
6385 /*Do nothing.
6386 */
6387 break;
6388 }
6389
6390 if (!aggregate->as_set)
6391 continue;
6392
6393 /*
6394 * as-set aggregate route generate origin, as path,
6395 * and community aggregation.
6396 */
6397 /* Compute aggregate route's as-path.
6398 */
6399 bgp_compute_aggregate_aspath_hash(aggregate,
6400 pi->attr->aspath);
6401
6402 /* Compute aggregate route's community.
6403 */
6404 if (pi->attr->community)
6405 bgp_compute_aggregate_community_hash(
6406 aggregate,
6407 pi->attr->community);
6408
6409 /* Compute aggregate route's extended community.
6410 */
6411 if (pi->attr->ecommunity)
6412 bgp_compute_aggregate_ecommunity_hash(
6413 aggregate,
6414 pi->attr->ecommunity);
6415
6416 /* Compute aggregate route's large community.
6417 */
6418 if (pi->attr->lcommunity)
6419 bgp_compute_aggregate_lcommunity_hash(
6420 aggregate,
6421 pi->attr->lcommunity);
6422 }
6423 if (match)
6424 bgp_process(bgp, dest, afi, safi);
6425 }
6426 if (aggregate->as_set) {
6427 bgp_compute_aggregate_aspath_val(aggregate);
6428 bgp_compute_aggregate_community_val(aggregate);
6429 bgp_compute_aggregate_ecommunity_val(aggregate);
6430 bgp_compute_aggregate_lcommunity_val(aggregate);
6431 }
6432
6433
6434 bgp_dest_unlock_node(top);
6435
6436
6437 if (aggregate->incomplete_origin_count > 0)
6438 origin = BGP_ORIGIN_INCOMPLETE;
6439 else if (aggregate->egp_origin_count > 0)
6440 origin = BGP_ORIGIN_EGP;
6441
6442 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
6443 origin = aggregate->origin;
6444
6445 if (aggregate->as_set) {
6446 if (aggregate->aspath)
6447 /* Retrieve aggregate route's as-path.
6448 */
6449 aspath = aspath_dup(aggregate->aspath);
6450
6451 if (aggregate->community)
6452 /* Retrieve aggregate route's community.
6453 */
6454 community = community_dup(aggregate->community);
6455
6456 if (aggregate->ecommunity)
6457 /* Retrieve aggregate route's ecommunity.
6458 */
6459 ecommunity = ecommunity_dup(aggregate->ecommunity);
6460
6461 if (aggregate->lcommunity)
6462 /* Retrieve aggregate route's lcommunity.
6463 */
6464 lcommunity = lcommunity_dup(aggregate->lcommunity);
6465 }
6466
6467 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
6468 ecommunity, lcommunity, atomic_aggregate,
6469 aggregate);
6470 }
6471
6472 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
6473 safi_t safi, struct bgp_aggregate *aggregate)
6474 {
6475 struct bgp_table *table;
6476 struct bgp_dest *top;
6477 struct bgp_dest *dest;
6478 struct bgp_path_info *pi;
6479 unsigned long match;
6480
6481 table = bgp->rib[afi][safi];
6482
6483 /* If routes exists below this node, generate aggregate routes. */
6484 top = bgp_node_get(table, p);
6485 for (dest = bgp_node_get(table, p); dest;
6486 dest = bgp_route_next_until(dest, top)) {
6487 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
6488
6489 if (dest_p->prefixlen <= p->prefixlen)
6490 continue;
6491 match = 0;
6492
6493 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6494 if (BGP_PATH_HOLDDOWN(pi))
6495 continue;
6496
6497 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6498 continue;
6499
6500 if (aggregate->summary_only && pi->extra) {
6501 pi->extra->suppress--;
6502
6503 if (pi->extra->suppress == 0) {
6504 bgp_path_info_set_flag(
6505 dest, pi,
6506 BGP_PATH_ATTR_CHANGED);
6507 match++;
6508 }
6509 }
6510 aggregate->count--;
6511
6512 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
6513 aggregate->incomplete_origin_count--;
6514 else if (pi->attr->origin == BGP_ORIGIN_EGP)
6515 aggregate->egp_origin_count--;
6516
6517 if (aggregate->as_set) {
6518 /* Remove as-path from aggregate.
6519 */
6520 bgp_remove_aspath_from_aggregate_hash(
6521 aggregate,
6522 pi->attr->aspath);
6523
6524 if (pi->attr->community)
6525 /* Remove community from aggregate.
6526 */
6527 bgp_remove_comm_from_aggregate_hash(
6528 aggregate,
6529 pi->attr->community);
6530
6531 if (pi->attr->ecommunity)
6532 /* Remove ecommunity from aggregate.
6533 */
6534 bgp_remove_ecomm_from_aggregate_hash(
6535 aggregate,
6536 pi->attr->ecommunity);
6537
6538 if (pi->attr->lcommunity)
6539 /* Remove lcommunity from aggregate.
6540 */
6541 bgp_remove_lcomm_from_aggregate_hash(
6542 aggregate,
6543 pi->attr->lcommunity);
6544 }
6545 }
6546
6547 /* If this node was suppressed, process the change. */
6548 if (match)
6549 bgp_process(bgp, dest, afi, safi);
6550 }
6551 if (aggregate->as_set) {
6552 aspath_free(aggregate->aspath);
6553 aggregate->aspath = NULL;
6554 if (aggregate->community)
6555 community_free(&aggregate->community);
6556 if (aggregate->ecommunity)
6557 ecommunity_free(&aggregate->ecommunity);
6558 if (aggregate->lcommunity)
6559 lcommunity_free(&aggregate->lcommunity);
6560 }
6561
6562 bgp_dest_unlock_node(top);
6563 }
6564
6565 static void bgp_add_route_to_aggregate(struct bgp *bgp,
6566 const struct prefix *aggr_p,
6567 struct bgp_path_info *pinew, afi_t afi,
6568 safi_t safi,
6569 struct bgp_aggregate *aggregate)
6570 {
6571 uint8_t origin;
6572 struct aspath *aspath = NULL;
6573 uint8_t atomic_aggregate = 0;
6574 struct community *community = NULL;
6575 struct ecommunity *ecommunity = NULL;
6576 struct lcommunity *lcommunity = NULL;
6577
6578 /* ORIGIN attribute: If at least one route among routes that are
6579 * aggregated has ORIGIN with the value INCOMPLETE, then the
6580 * aggregated route must have the ORIGIN attribute with the value
6581 * INCOMPLETE. Otherwise, if at least one route among routes that
6582 * are aggregated has ORIGIN with the value EGP, then the aggregated
6583 * route must have the origin attribute with the value EGP. In all
6584 * other case the value of the ORIGIN attribute of the aggregated
6585 * route is INTERNAL.
6586 */
6587 origin = BGP_ORIGIN_IGP;
6588
6589 aggregate->count++;
6590
6591 if (aggregate->summary_only)
6592 (bgp_path_info_extra_get(pinew))->suppress++;
6593
6594 switch (pinew->attr->origin) {
6595 case BGP_ORIGIN_INCOMPLETE:
6596 aggregate->incomplete_origin_count++;
6597 break;
6598 case BGP_ORIGIN_EGP:
6599 aggregate->egp_origin_count++;
6600 break;
6601 default:
6602 /* Do nothing.
6603 */
6604 break;
6605 }
6606
6607 if (aggregate->incomplete_origin_count > 0)
6608 origin = BGP_ORIGIN_INCOMPLETE;
6609 else if (aggregate->egp_origin_count > 0)
6610 origin = BGP_ORIGIN_EGP;
6611
6612 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
6613 origin = aggregate->origin;
6614
6615 if (aggregate->as_set) {
6616 /* Compute aggregate route's as-path.
6617 */
6618 bgp_compute_aggregate_aspath(aggregate,
6619 pinew->attr->aspath);
6620
6621 /* Compute aggregate route's community.
6622 */
6623 if (pinew->attr->community)
6624 bgp_compute_aggregate_community(
6625 aggregate,
6626 pinew->attr->community);
6627
6628 /* Compute aggregate route's extended community.
6629 */
6630 if (pinew->attr->ecommunity)
6631 bgp_compute_aggregate_ecommunity(
6632 aggregate,
6633 pinew->attr->ecommunity);
6634
6635 /* Compute aggregate route's large community.
6636 */
6637 if (pinew->attr->lcommunity)
6638 bgp_compute_aggregate_lcommunity(
6639 aggregate,
6640 pinew->attr->lcommunity);
6641
6642 /* Retrieve aggregate route's as-path.
6643 */
6644 if (aggregate->aspath)
6645 aspath = aspath_dup(aggregate->aspath);
6646
6647 /* Retrieve aggregate route's community.
6648 */
6649 if (aggregate->community)
6650 community = community_dup(aggregate->community);
6651
6652 /* Retrieve aggregate route's ecommunity.
6653 */
6654 if (aggregate->ecommunity)
6655 ecommunity = ecommunity_dup(aggregate->ecommunity);
6656
6657 /* Retrieve aggregate route's lcommunity.
6658 */
6659 if (aggregate->lcommunity)
6660 lcommunity = lcommunity_dup(aggregate->lcommunity);
6661 }
6662
6663 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
6664 aspath, community, ecommunity,
6665 lcommunity, atomic_aggregate, aggregate);
6666 }
6667
6668 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
6669 safi_t safi,
6670 struct bgp_path_info *pi,
6671 struct bgp_aggregate *aggregate,
6672 const struct prefix *aggr_p)
6673 {
6674 uint8_t origin;
6675 struct aspath *aspath = NULL;
6676 uint8_t atomic_aggregate = 0;
6677 struct community *community = NULL;
6678 struct ecommunity *ecommunity = NULL;
6679 struct lcommunity *lcommunity = NULL;
6680 unsigned long match = 0;
6681
6682 if (BGP_PATH_HOLDDOWN(pi))
6683 return;
6684
6685 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6686 return;
6687
6688 if (aggregate->summary_only
6689 && pi->extra
6690 && pi->extra->suppress > 0) {
6691 pi->extra->suppress--;
6692
6693 if (pi->extra->suppress == 0) {
6694 bgp_path_info_set_flag(pi->net, pi,
6695 BGP_PATH_ATTR_CHANGED);
6696 match++;
6697 }
6698 }
6699
6700 if (aggregate->count > 0)
6701 aggregate->count--;
6702
6703 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
6704 aggregate->incomplete_origin_count--;
6705 else if (pi->attr->origin == BGP_ORIGIN_EGP)
6706 aggregate->egp_origin_count--;
6707
6708 if (aggregate->as_set) {
6709 /* Remove as-path from aggregate.
6710 */
6711 bgp_remove_aspath_from_aggregate(aggregate,
6712 pi->attr->aspath);
6713
6714 if (pi->attr->community)
6715 /* Remove community from aggregate.
6716 */
6717 bgp_remove_community_from_aggregate(
6718 aggregate,
6719 pi->attr->community);
6720
6721 if (pi->attr->ecommunity)
6722 /* Remove ecommunity from aggregate.
6723 */
6724 bgp_remove_ecommunity_from_aggregate(
6725 aggregate,
6726 pi->attr->ecommunity);
6727
6728 if (pi->attr->lcommunity)
6729 /* Remove lcommunity from aggregate.
6730 */
6731 bgp_remove_lcommunity_from_aggregate(
6732 aggregate,
6733 pi->attr->lcommunity);
6734 }
6735
6736 /* If this node was suppressed, process the change. */
6737 if (match)
6738 bgp_process(bgp, pi->net, afi, safi);
6739
6740 origin = BGP_ORIGIN_IGP;
6741 if (aggregate->incomplete_origin_count > 0)
6742 origin = BGP_ORIGIN_INCOMPLETE;
6743 else if (aggregate->egp_origin_count > 0)
6744 origin = BGP_ORIGIN_EGP;
6745
6746 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
6747 origin = aggregate->origin;
6748
6749 if (aggregate->as_set) {
6750 /* Retrieve aggregate route's as-path.
6751 */
6752 if (aggregate->aspath)
6753 aspath = aspath_dup(aggregate->aspath);
6754
6755 /* Retrieve aggregate route's community.
6756 */
6757 if (aggregate->community)
6758 community = community_dup(aggregate->community);
6759
6760 /* Retrieve aggregate route's ecommunity.
6761 */
6762 if (aggregate->ecommunity)
6763 ecommunity = ecommunity_dup(aggregate->ecommunity);
6764
6765 /* Retrieve aggregate route's lcommunity.
6766 */
6767 if (aggregate->lcommunity)
6768 lcommunity = lcommunity_dup(aggregate->lcommunity);
6769 }
6770
6771 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
6772 aspath, community, ecommunity,
6773 lcommunity, atomic_aggregate, aggregate);
6774 }
6775
6776 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
6777 struct bgp_path_info *pi, afi_t afi, safi_t safi)
6778 {
6779 struct bgp_dest *child;
6780 struct bgp_dest *dest;
6781 struct bgp_aggregate *aggregate;
6782 struct bgp_table *table;
6783
6784 table = bgp->aggregate[afi][safi];
6785
6786 /* No aggregates configured. */
6787 if (bgp_table_top_nolock(table) == NULL)
6788 return;
6789
6790 if (p->prefixlen == 0)
6791 return;
6792
6793 if (BGP_PATH_HOLDDOWN(pi))
6794 return;
6795
6796 child = bgp_node_get(table, p);
6797
6798 /* Aggregate address configuration check. */
6799 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
6800 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
6801
6802 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
6803 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
6804 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
6805 aggregate);
6806 }
6807 }
6808 bgp_dest_unlock_node(child);
6809 }
6810
6811 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
6812 struct bgp_path_info *del, afi_t afi, safi_t safi)
6813 {
6814 struct bgp_dest *child;
6815 struct bgp_dest *dest;
6816 struct bgp_aggregate *aggregate;
6817 struct bgp_table *table;
6818
6819 table = bgp->aggregate[afi][safi];
6820
6821 /* No aggregates configured. */
6822 if (bgp_table_top_nolock(table) == NULL)
6823 return;
6824
6825 if (p->prefixlen == 0)
6826 return;
6827
6828 child = bgp_node_get(table, p);
6829
6830 /* Aggregate address configuration check. */
6831 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
6832 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
6833
6834 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
6835 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
6836 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
6837 aggregate, dest_p);
6838 }
6839 }
6840 bgp_dest_unlock_node(child);
6841 }
6842
6843 /* Aggregate route attribute. */
6844 #define AGGREGATE_SUMMARY_ONLY 1
6845 #define AGGREGATE_AS_SET 1
6846 #define AGGREGATE_AS_UNSET 0
6847
6848 static const char *bgp_origin2str(uint8_t origin)
6849 {
6850 switch (origin) {
6851 case BGP_ORIGIN_IGP:
6852 return "igp";
6853 case BGP_ORIGIN_EGP:
6854 return "egp";
6855 case BGP_ORIGIN_INCOMPLETE:
6856 return "incomplete";
6857 }
6858 return "n/a";
6859 }
6860
6861 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
6862 afi_t afi, safi_t safi)
6863 {
6864 VTY_DECLVAR_CONTEXT(bgp, bgp);
6865 int ret;
6866 struct prefix p;
6867 struct bgp_dest *dest;
6868 struct bgp_aggregate *aggregate;
6869
6870 /* Convert string to prefix structure. */
6871 ret = str2prefix(prefix_str, &p);
6872 if (!ret) {
6873 vty_out(vty, "Malformed prefix\n");
6874 return CMD_WARNING_CONFIG_FAILED;
6875 }
6876 apply_mask(&p);
6877
6878 /* Old configuration check. */
6879 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
6880 if (!dest) {
6881 vty_out(vty,
6882 "%% There is no aggregate-address configuration.\n");
6883 return CMD_WARNING_CONFIG_FAILED;
6884 }
6885
6886 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
6887 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
6888 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
6889 NULL, NULL, 0, aggregate);
6890
6891 /* Unlock aggregate address configuration. */
6892 bgp_dest_set_bgp_aggregate_info(dest, NULL);
6893
6894 if (aggregate->community)
6895 community_free(&aggregate->community);
6896
6897 if (aggregate->community_hash) {
6898 /* Delete all communities in the hash.
6899 */
6900 hash_clean(aggregate->community_hash,
6901 bgp_aggr_community_remove);
6902 /* Free up the community_hash.
6903 */
6904 hash_free(aggregate->community_hash);
6905 }
6906
6907 if (aggregate->ecommunity)
6908 ecommunity_free(&aggregate->ecommunity);
6909
6910 if (aggregate->ecommunity_hash) {
6911 /* Delete all ecommunities in the hash.
6912 */
6913 hash_clean(aggregate->ecommunity_hash,
6914 bgp_aggr_ecommunity_remove);
6915 /* Free up the ecommunity_hash.
6916 */
6917 hash_free(aggregate->ecommunity_hash);
6918 }
6919
6920 if (aggregate->lcommunity)
6921 lcommunity_free(&aggregate->lcommunity);
6922
6923 if (aggregate->lcommunity_hash) {
6924 /* Delete all lcommunities in the hash.
6925 */
6926 hash_clean(aggregate->lcommunity_hash,
6927 bgp_aggr_lcommunity_remove);
6928 /* Free up the lcommunity_hash.
6929 */
6930 hash_free(aggregate->lcommunity_hash);
6931 }
6932
6933 if (aggregate->aspath)
6934 aspath_free(aggregate->aspath);
6935
6936 if (aggregate->aspath_hash) {
6937 /* Delete all as-paths in the hash.
6938 */
6939 hash_clean(aggregate->aspath_hash,
6940 bgp_aggr_aspath_remove);
6941 /* Free up the aspath_hash.
6942 */
6943 hash_free(aggregate->aspath_hash);
6944 }
6945
6946 bgp_aggregate_free(aggregate);
6947 bgp_dest_unlock_node(dest);
6948 bgp_dest_unlock_node(dest);
6949
6950 return CMD_SUCCESS;
6951 }
6952
6953 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
6954 safi_t safi, const char *rmap,
6955 uint8_t summary_only, uint8_t as_set,
6956 uint8_t origin)
6957 {
6958 VTY_DECLVAR_CONTEXT(bgp, bgp);
6959 int ret;
6960 struct prefix p;
6961 struct bgp_dest *dest;
6962 struct bgp_aggregate *aggregate;
6963 uint8_t as_set_new = as_set;
6964
6965 /* Convert string to prefix structure. */
6966 ret = str2prefix(prefix_str, &p);
6967 if (!ret) {
6968 vty_out(vty, "Malformed prefix\n");
6969 return CMD_WARNING_CONFIG_FAILED;
6970 }
6971 apply_mask(&p);
6972
6973 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
6974 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
6975 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
6976 prefix_str);
6977 return CMD_WARNING_CONFIG_FAILED;
6978 }
6979
6980 /* Old configuration check. */
6981 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
6982 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
6983
6984 if (aggregate) {
6985 vty_out(vty, "There is already same aggregate network.\n");
6986 /* try to remove the old entry */
6987 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
6988 if (ret) {
6989 vty_out(vty, "Error deleting aggregate.\n");
6990 bgp_dest_unlock_node(dest);
6991 return CMD_WARNING_CONFIG_FAILED;
6992 }
6993 }
6994
6995 /* Make aggregate address structure. */
6996 aggregate = bgp_aggregate_new();
6997 aggregate->summary_only = summary_only;
6998
6999 /* Network operators MUST NOT locally generate any new
7000 * announcements containing AS_SET or AS_CONFED_SET. If they have
7001 * announced routes with AS_SET or AS_CONFED_SET in them, then they
7002 * SHOULD withdraw those routes and re-announce routes for the
7003 * aggregate or component prefixes (i.e., the more-specific routes
7004 * subsumed by the previously aggregated route) without AS_SET
7005 * or AS_CONFED_SET in the updates.
7006 */
7007 if (bgp->reject_as_sets) {
7008 if (as_set == AGGREGATE_AS_SET) {
7009 as_set_new = AGGREGATE_AS_UNSET;
7010 zlog_warn(
7011 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
7012 __func__);
7013 vty_out(vty,
7014 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
7015 }
7016 }
7017
7018 aggregate->as_set = as_set_new;
7019 aggregate->safi = safi;
7020 /* Override ORIGIN attribute if defined.
7021 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
7022 * to IGP which is not what rfc4271 says.
7023 * This enables the same behavior, optionally.
7024 */
7025 aggregate->origin = origin;
7026
7027 if (rmap) {
7028 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7029 route_map_counter_decrement(aggregate->rmap.map);
7030 aggregate->rmap.name =
7031 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
7032 aggregate->rmap.map = route_map_lookup_by_name(rmap);
7033 route_map_counter_increment(aggregate->rmap.map);
7034 }
7035 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
7036
7037 /* Aggregate address insert into BGP routing table. */
7038 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
7039
7040 return CMD_SUCCESS;
7041 }
7042
7043 DEFUN (aggregate_address,
7044 aggregate_address_cmd,
7045 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]",
7046 "Configure BGP aggregate entries\n"
7047 "Aggregate prefix\n"
7048 "Generate AS set path information\n"
7049 "Filter more specific routes from updates\n"
7050 "Filter more specific routes from updates\n"
7051 "Generate AS set path information\n"
7052 "Apply route map to aggregate network\n"
7053 "Name of route map\n"
7054 "BGP origin code\n"
7055 "Remote EGP\n"
7056 "Local IGP\n"
7057 "Unknown heritage\n")
7058 {
7059 int idx = 0;
7060 argv_find(argv, argc, "A.B.C.D/M", &idx);
7061 char *prefix = argv[idx]->arg;
7062 char *rmap = NULL;
7063 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
7064 int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
7065 : AGGREGATE_AS_UNSET;
7066 idx = 0;
7067 int summary_only = argv_find(argv, argc, "summary-only", &idx)
7068 ? AGGREGATE_SUMMARY_ONLY
7069 : 0;
7070
7071 idx = 0;
7072 argv_find(argv, argc, "WORD", &idx);
7073 if (idx)
7074 rmap = argv[idx]->arg;
7075
7076 idx = 0;
7077 if (argv_find(argv, argc, "origin", &idx)) {
7078 if (strncmp(argv[idx + 1]->arg, "igp", 2) == 0)
7079 origin = BGP_ORIGIN_IGP;
7080 if (strncmp(argv[idx + 1]->arg, "egp", 1) == 0)
7081 origin = BGP_ORIGIN_EGP;
7082 if (strncmp(argv[idx + 1]->arg, "incomplete", 2) == 0)
7083 origin = BGP_ORIGIN_INCOMPLETE;
7084 }
7085
7086 return bgp_aggregate_set(vty, prefix, AFI_IP, bgp_node_safi(vty), rmap,
7087 summary_only, as_set, origin);
7088 }
7089
7090 DEFUN (aggregate_address_mask,
7091 aggregate_address_mask_cmd,
7092 "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>]",
7093 "Configure BGP aggregate entries\n"
7094 "Aggregate address\n"
7095 "Aggregate mask\n"
7096 "Generate AS set path information\n"
7097 "Filter more specific routes from updates\n"
7098 "Filter more specific routes from updates\n"
7099 "Generate AS set path information\n"
7100 "Apply route map to aggregate network\n"
7101 "Name of route map\n"
7102 "BGP origin code\n"
7103 "Remote EGP\n"
7104 "Local IGP\n"
7105 "Unknown heritage\n")
7106 {
7107 int idx = 0;
7108 argv_find(argv, argc, "A.B.C.D", &idx);
7109 char *prefix = argv[idx]->arg;
7110 char *mask = argv[idx + 1]->arg;
7111 bool rmap_found;
7112 char *rmap = NULL;
7113 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
7114 int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
7115 : AGGREGATE_AS_UNSET;
7116 idx = 0;
7117 int summary_only = argv_find(argv, argc, "summary-only", &idx)
7118 ? AGGREGATE_SUMMARY_ONLY
7119 : 0;
7120
7121 rmap_found = argv_find(argv, argc, "WORD", &idx);
7122 if (rmap_found)
7123 rmap = argv[idx]->arg;
7124
7125 char prefix_str[BUFSIZ];
7126 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
7127
7128 if (!ret) {
7129 vty_out(vty, "%% Inconsistent address and mask\n");
7130 return CMD_WARNING_CONFIG_FAILED;
7131 }
7132
7133 idx = 0;
7134 if (argv_find(argv, argc, "origin", &idx)) {
7135 if (strncmp(argv[idx + 1]->arg, "igp", 2) == 0)
7136 origin = BGP_ORIGIN_IGP;
7137 if (strncmp(argv[idx + 1]->arg, "egp", 1) == 0)
7138 origin = BGP_ORIGIN_EGP;
7139 if (strncmp(argv[idx + 1]->arg, "incomplete", 2) == 0)
7140 origin = BGP_ORIGIN_INCOMPLETE;
7141 }
7142
7143 return bgp_aggregate_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty),
7144 rmap, summary_only, as_set, origin);
7145 }
7146
7147 DEFUN (no_aggregate_address,
7148 no_aggregate_address_cmd,
7149 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]",
7150 NO_STR
7151 "Configure BGP aggregate entries\n"
7152 "Aggregate prefix\n"
7153 "Generate AS set path information\n"
7154 "Filter more specific routes from updates\n"
7155 "Filter more specific routes from updates\n"
7156 "Generate AS set path information\n"
7157 "Apply route map to aggregate network\n"
7158 "Name of route map\n"
7159 "BGP origin code\n"
7160 "Remote EGP\n"
7161 "Local IGP\n"
7162 "Unknown heritage\n")
7163 {
7164 int idx = 0;
7165 argv_find(argv, argc, "A.B.C.D/M", &idx);
7166 char *prefix = argv[idx]->arg;
7167 return bgp_aggregate_unset(vty, prefix, AFI_IP, bgp_node_safi(vty));
7168 }
7169
7170 DEFUN (no_aggregate_address_mask,
7171 no_aggregate_address_mask_cmd,
7172 "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>]",
7173 NO_STR
7174 "Configure BGP aggregate entries\n"
7175 "Aggregate address\n"
7176 "Aggregate mask\n"
7177 "Generate AS set path information\n"
7178 "Filter more specific routes from updates\n"
7179 "Filter more specific routes from updates\n"
7180 "Generate AS set path information\n"
7181 "Apply route map to aggregate network\n"
7182 "Name of route map\n"
7183 "BGP origin code\n"
7184 "Remote EGP\n"
7185 "Local IGP\n"
7186 "Unknown heritage\n")
7187 {
7188 int idx = 0;
7189 argv_find(argv, argc, "A.B.C.D", &idx);
7190 char *prefix = argv[idx]->arg;
7191 char *mask = argv[idx + 1]->arg;
7192
7193 char prefix_str[BUFSIZ];
7194 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
7195
7196 if (!ret) {
7197 vty_out(vty, "%% Inconsistent address and mask\n");
7198 return CMD_WARNING_CONFIG_FAILED;
7199 }
7200
7201 return bgp_aggregate_unset(vty, prefix_str, AFI_IP, bgp_node_safi(vty));
7202 }
7203
7204 DEFUN (ipv6_aggregate_address,
7205 ipv6_aggregate_address_cmd,
7206 "aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]",
7207 "Configure BGP aggregate entries\n"
7208 "Aggregate prefix\n"
7209 "Generate AS set path information\n"
7210 "Filter more specific routes from updates\n"
7211 "Filter more specific routes from updates\n"
7212 "Generate AS set path information\n"
7213 "Apply route map to aggregate network\n"
7214 "Name of route map\n"
7215 "BGP origin code\n"
7216 "Remote EGP\n"
7217 "Local IGP\n"
7218 "Unknown heritage\n")
7219 {
7220 int idx = 0;
7221 argv_find(argv, argc, "X:X::X:X/M", &idx);
7222 char *prefix = argv[idx]->arg;
7223 char *rmap = NULL;
7224 bool rmap_found;
7225 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
7226 int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
7227 : AGGREGATE_AS_UNSET;
7228
7229 idx = 0;
7230 int sum_only = argv_find(argv, argc, "summary-only", &idx)
7231 ? AGGREGATE_SUMMARY_ONLY
7232 : 0;
7233
7234 rmap_found = argv_find(argv, argc, "WORD", &idx);
7235 if (rmap_found)
7236 rmap = argv[idx]->arg;
7237
7238 idx = 0;
7239 if (argv_find(argv, argc, "origin", &idx)) {
7240 if (strncmp(argv[idx + 1]->arg, "igp", 2) == 0)
7241 origin = BGP_ORIGIN_IGP;
7242 if (strncmp(argv[idx + 1]->arg, "egp", 1) == 0)
7243 origin = BGP_ORIGIN_EGP;
7244 if (strncmp(argv[idx + 1]->arg, "incomplete", 2) == 0)
7245 origin = BGP_ORIGIN_INCOMPLETE;
7246 }
7247
7248 return bgp_aggregate_set(vty, prefix, AFI_IP6, SAFI_UNICAST, rmap,
7249 sum_only, as_set, origin);
7250 }
7251
7252 DEFUN (no_ipv6_aggregate_address,
7253 no_ipv6_aggregate_address_cmd,
7254 "no aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]",
7255 NO_STR
7256 "Configure BGP aggregate entries\n"
7257 "Aggregate prefix\n"
7258 "Generate AS set path information\n"
7259 "Filter more specific routes from updates\n"
7260 "Filter more specific routes from updates\n"
7261 "Generate AS set path information\n"
7262 "Apply route map to aggregate network\n"
7263 "Name of route map\n"
7264 "BGP origin code\n"
7265 "Remote EGP\n"
7266 "Local IGP\n"
7267 "Unknown heritage\n")
7268 {
7269 int idx = 0;
7270 argv_find(argv, argc, "X:X::X:X/M", &idx);
7271 char *prefix = argv[idx]->arg;
7272 return bgp_aggregate_unset(vty, prefix, AFI_IP6, SAFI_UNICAST);
7273 }
7274
7275 /* Redistribute route treatment. */
7276 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
7277 const union g_addr *nexthop, ifindex_t ifindex,
7278 enum nexthop_types_t nhtype, uint32_t metric,
7279 uint8_t type, unsigned short instance,
7280 route_tag_t tag)
7281 {
7282 struct bgp_path_info *new;
7283 struct bgp_path_info *bpi;
7284 struct bgp_path_info rmap_path;
7285 struct bgp_dest *bn;
7286 struct attr attr;
7287 struct attr *new_attr;
7288 afi_t afi;
7289 route_map_result_t ret;
7290 struct bgp_redist *red;
7291
7292 /* Make default attribute. */
7293 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
7294 /*
7295 * This must not be NULL to satisfy Coverity SA
7296 */
7297 assert(attr.aspath);
7298
7299 switch (nhtype) {
7300 case NEXTHOP_TYPE_IFINDEX:
7301 break;
7302 case NEXTHOP_TYPE_IPV4:
7303 case NEXTHOP_TYPE_IPV4_IFINDEX:
7304 attr.nexthop = nexthop->ipv4;
7305 break;
7306 case NEXTHOP_TYPE_IPV6:
7307 case NEXTHOP_TYPE_IPV6_IFINDEX:
7308 attr.mp_nexthop_global = nexthop->ipv6;
7309 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
7310 break;
7311 case NEXTHOP_TYPE_BLACKHOLE:
7312 switch (p->family) {
7313 case AF_INET:
7314 attr.nexthop.s_addr = INADDR_ANY;
7315 break;
7316 case AF_INET6:
7317 memset(&attr.mp_nexthop_global, 0,
7318 sizeof(attr.mp_nexthop_global));
7319 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
7320 break;
7321 }
7322 break;
7323 }
7324 attr.nh_ifindex = ifindex;
7325
7326 attr.med = metric;
7327 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
7328 attr.tag = tag;
7329
7330 afi = family2afi(p->family);
7331
7332 red = bgp_redist_lookup(bgp, afi, type, instance);
7333 if (red) {
7334 struct attr attr_new;
7335
7336 /* Copy attribute for modification. */
7337 attr_new = attr;
7338
7339 if (red->redist_metric_flag)
7340 attr_new.med = red->redist_metric;
7341
7342 /* Apply route-map. */
7343 if (red->rmap.name) {
7344 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
7345 rmap_path.peer = bgp->peer_self;
7346 rmap_path.attr = &attr_new;
7347
7348 SET_FLAG(bgp->peer_self->rmap_type,
7349 PEER_RMAP_TYPE_REDISTRIBUTE);
7350
7351 ret = route_map_apply(red->rmap.map, p, RMAP_BGP,
7352 &rmap_path);
7353
7354 bgp->peer_self->rmap_type = 0;
7355
7356 if (ret == RMAP_DENYMATCH) {
7357 /* Free uninterned attribute. */
7358 bgp_attr_flush(&attr_new);
7359
7360 /* Unintern original. */
7361 aspath_unintern(&attr.aspath);
7362 bgp_redistribute_delete(bgp, p, type, instance);
7363 return;
7364 }
7365 }
7366
7367 if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN))
7368 bgp_attr_add_gshut_community(&attr_new);
7369
7370 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
7371 SAFI_UNICAST, p, NULL);
7372
7373 new_attr = bgp_attr_intern(&attr_new);
7374
7375 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
7376 if (bpi->peer == bgp->peer_self
7377 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
7378 break;
7379
7380 if (bpi) {
7381 /* Ensure the (source route) type is updated. */
7382 bpi->type = type;
7383 if (attrhash_cmp(bpi->attr, new_attr)
7384 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
7385 bgp_attr_unintern(&new_attr);
7386 aspath_unintern(&attr.aspath);
7387 bgp_dest_unlock_node(bn);
7388 return;
7389 } else {
7390 /* The attribute is changed. */
7391 bgp_path_info_set_flag(bn, bpi,
7392 BGP_PATH_ATTR_CHANGED);
7393
7394 /* Rewrite BGP route information. */
7395 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
7396 bgp_path_info_restore(bn, bpi);
7397 else
7398 bgp_aggregate_decrement(
7399 bgp, p, bpi, afi, SAFI_UNICAST);
7400 bgp_attr_unintern(&bpi->attr);
7401 bpi->attr = new_attr;
7402 bpi->uptime = bgp_clock();
7403
7404 /* Process change. */
7405 bgp_aggregate_increment(bgp, p, bpi, afi,
7406 SAFI_UNICAST);
7407 bgp_process(bgp, bn, afi, SAFI_UNICAST);
7408 bgp_dest_unlock_node(bn);
7409 aspath_unintern(&attr.aspath);
7410
7411 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7412 || (bgp->inst_type
7413 == BGP_INSTANCE_TYPE_DEFAULT)) {
7414
7415 vpn_leak_from_vrf_update(
7416 bgp_get_default(), bgp, bpi);
7417 }
7418 return;
7419 }
7420 }
7421
7422 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
7423 bgp->peer_self, new_attr, bn);
7424 SET_FLAG(new->flags, BGP_PATH_VALID);
7425
7426 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
7427 bgp_path_info_add(bn, new);
7428 bgp_dest_unlock_node(bn);
7429 bgp_process(bgp, bn, afi, SAFI_UNICAST);
7430
7431 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7432 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
7433
7434 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
7435 }
7436 }
7437
7438 /* Unintern original. */
7439 aspath_unintern(&attr.aspath);
7440 }
7441
7442 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
7443 unsigned short instance)
7444 {
7445 afi_t afi;
7446 struct bgp_dest *dest;
7447 struct bgp_path_info *pi;
7448 struct bgp_redist *red;
7449
7450 afi = family2afi(p->family);
7451
7452 red = bgp_redist_lookup(bgp, afi, type, instance);
7453 if (red) {
7454 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
7455 SAFI_UNICAST, p, NULL);
7456
7457 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7458 if (pi->peer == bgp->peer_self && pi->type == type)
7459 break;
7460
7461 if (pi) {
7462 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7463 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
7464
7465 vpn_leak_from_vrf_withdraw(bgp_get_default(),
7466 bgp, pi);
7467 }
7468 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
7469 bgp_path_info_delete(dest, pi);
7470 bgp_process(bgp, dest, afi, SAFI_UNICAST);
7471 }
7472 bgp_dest_unlock_node(dest);
7473 }
7474 }
7475
7476 /* Withdraw specified route type's route. */
7477 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
7478 unsigned short instance)
7479 {
7480 struct bgp_dest *dest;
7481 struct bgp_path_info *pi;
7482 struct bgp_table *table;
7483
7484 table = bgp->rib[afi][SAFI_UNICAST];
7485
7486 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
7487 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7488 if (pi->peer == bgp->peer_self && pi->type == type
7489 && pi->instance == instance)
7490 break;
7491
7492 if (pi) {
7493 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7494 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
7495
7496 vpn_leak_from_vrf_withdraw(bgp_get_default(),
7497 bgp, pi);
7498 }
7499 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
7500 pi, afi, SAFI_UNICAST);
7501 bgp_path_info_delete(dest, pi);
7502 bgp_process(bgp, dest, afi, SAFI_UNICAST);
7503 }
7504 }
7505 }
7506
7507 /* Static function to display route. */
7508 static void route_vty_out_route(const struct prefix *p, struct vty *vty,
7509 json_object *json, bool wide)
7510 {
7511 int len = 0;
7512 char buf[BUFSIZ];
7513 char buf2[BUFSIZ];
7514
7515 if (p->family == AF_INET) {
7516 if (!json) {
7517 len = vty_out(
7518 vty, "%s/%d",
7519 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
7520 p->prefixlen);
7521 } else {
7522 json_object_string_add(json, "prefix",
7523 inet_ntop(p->family,
7524 &p->u.prefix, buf,
7525 BUFSIZ));
7526 json_object_int_add(json, "prefixLen", p->prefixlen);
7527 prefix2str(p, buf2, PREFIX_STRLEN);
7528 json_object_string_add(json, "network", buf2);
7529 }
7530 } else if (p->family == AF_ETHERNET) {
7531 prefix2str(p, buf, PREFIX_STRLEN);
7532 len = vty_out(vty, "%s", buf);
7533 } else if (p->family == AF_EVPN) {
7534 if (!json)
7535 len = vty_out(
7536 vty, "%s",
7537 bgp_evpn_route2str((struct prefix_evpn *)p, buf,
7538 BUFSIZ));
7539 else
7540 bgp_evpn_route2json((struct prefix_evpn *)p, json);
7541 } else if (p->family == AF_FLOWSPEC) {
7542 route_vty_out_flowspec(vty, p, NULL,
7543 json ?
7544 NLRI_STRING_FORMAT_JSON_SIMPLE :
7545 NLRI_STRING_FORMAT_MIN, json);
7546 } else {
7547 if (!json)
7548 len = vty_out(
7549 vty, "%s/%d",
7550 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
7551 p->prefixlen);
7552 else {
7553 json_object_string_add(json, "prefix",
7554 inet_ntop(p->family,
7555 &p->u.prefix, buf,
7556 BUFSIZ));
7557 json_object_int_add(json, "prefixLen", p->prefixlen);
7558 prefix2str(p, buf2, PREFIX_STRLEN);
7559 json_object_string_add(json, "network", buf2);
7560 }
7561 }
7562
7563 if (!json) {
7564 len = wide ? (45 - len) : (17 - len);
7565 if (len < 1)
7566 vty_out(vty, "\n%*s", 20, " ");
7567 else
7568 vty_out(vty, "%*s", len, " ");
7569 }
7570 }
7571
7572 enum bgp_display_type {
7573 normal_list,
7574 };
7575
7576 /* Print the short form route status for a bgp_path_info */
7577 static void route_vty_short_status_out(struct vty *vty,
7578 struct bgp_path_info *path,
7579 json_object *json_path)
7580 {
7581 if (json_path) {
7582
7583 /* Route status display. */
7584 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
7585 json_object_boolean_true_add(json_path, "removed");
7586
7587 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
7588 json_object_boolean_true_add(json_path, "stale");
7589
7590 if (path->extra && path->extra->suppress)
7591 json_object_boolean_true_add(json_path, "suppressed");
7592
7593 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
7594 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7595 json_object_boolean_true_add(json_path, "valid");
7596
7597 /* Selected */
7598 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7599 json_object_boolean_true_add(json_path, "history");
7600
7601 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
7602 json_object_boolean_true_add(json_path, "damped");
7603
7604 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
7605 json_object_boolean_true_add(json_path, "bestpath");
7606
7607 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
7608 json_object_boolean_true_add(json_path, "multipath");
7609
7610 /* Internal route. */
7611 if ((path->peer->as)
7612 && (path->peer->as == path->peer->local_as))
7613 json_object_string_add(json_path, "pathFrom",
7614 "internal");
7615 else
7616 json_object_string_add(json_path, "pathFrom",
7617 "external");
7618
7619 return;
7620 }
7621
7622 /* Route status display. */
7623 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
7624 vty_out(vty, "R");
7625 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
7626 vty_out(vty, "S");
7627 else if (path->extra && path->extra->suppress)
7628 vty_out(vty, "s");
7629 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
7630 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7631 vty_out(vty, "*");
7632 else
7633 vty_out(vty, " ");
7634
7635 /* Selected */
7636 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7637 vty_out(vty, "h");
7638 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
7639 vty_out(vty, "d");
7640 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
7641 vty_out(vty, ">");
7642 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
7643 vty_out(vty, "=");
7644 else
7645 vty_out(vty, " ");
7646
7647 /* Internal route. */
7648 if (path->peer && (path->peer->as)
7649 && (path->peer->as == path->peer->local_as))
7650 vty_out(vty, "i");
7651 else
7652 vty_out(vty, " ");
7653 }
7654
7655 static char *bgp_nexthop_hostname(struct peer *peer,
7656 struct bgp_nexthop_cache *bnc)
7657 {
7658 if (peer->hostname
7659 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
7660 return peer->hostname;
7661 return NULL;
7662 }
7663
7664 /* called from terminal list command */
7665 void route_vty_out(struct vty *vty, const struct prefix *p,
7666 struct bgp_path_info *path, int display, safi_t safi,
7667 json_object *json_paths, bool wide)
7668 {
7669 int len;
7670 struct attr *attr = path->attr;
7671 json_object *json_path = NULL;
7672 json_object *json_nexthops = NULL;
7673 json_object *json_nexthop_global = NULL;
7674 json_object *json_nexthop_ll = NULL;
7675 json_object *json_ext_community = NULL;
7676 char vrf_id_str[VRF_NAMSIZ] = {0};
7677 bool nexthop_self =
7678 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
7679 bool nexthop_othervrf = false;
7680 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
7681 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
7682 char *nexthop_hostname =
7683 bgp_nexthop_hostname(path->peer, path->nexthop);
7684 char esi_buf[ESI_STR_LEN];
7685
7686 if (json_paths)
7687 json_path = json_object_new_object();
7688
7689 /* short status lead text */
7690 route_vty_short_status_out(vty, path, json_path);
7691
7692 if (!json_paths) {
7693 /* print prefix and mask */
7694 if (!display)
7695 route_vty_out_route(p, vty, json_path, wide);
7696 else
7697 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
7698 } else {
7699 route_vty_out_route(p, vty, json_path, wide);
7700 }
7701
7702 /*
7703 * If vrf id of nexthop is different from that of prefix,
7704 * set up printable string to append
7705 */
7706 if (path->extra && path->extra->bgp_orig) {
7707 const char *self = "";
7708
7709 if (nexthop_self)
7710 self = "<";
7711
7712 nexthop_othervrf = true;
7713 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
7714
7715 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
7716 snprintf(vrf_id_str, sizeof(vrf_id_str),
7717 "@%s%s", VRFID_NONE_STR, self);
7718 else
7719 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
7720 path->extra->bgp_orig->vrf_id, self);
7721
7722 if (path->extra->bgp_orig->inst_type
7723 != BGP_INSTANCE_TYPE_DEFAULT)
7724
7725 nexthop_vrfname = path->extra->bgp_orig->name;
7726 } else {
7727 const char *self = "";
7728
7729 if (nexthop_self)
7730 self = "<";
7731
7732 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
7733 }
7734
7735 /*
7736 * For ENCAP and EVPN routes, nexthop address family is not
7737 * neccessarily the same as the prefix address family.
7738 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
7739 * EVPN routes are also exchanged with a MP nexthop. Currently,
7740 * this
7741 * is only IPv4, the value will be present in either
7742 * attr->nexthop or
7743 * attr->mp_nexthop_global_in
7744 */
7745 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
7746 char buf[BUFSIZ];
7747 char nexthop[128];
7748 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
7749
7750 switch (af) {
7751 case AF_INET:
7752 snprintf(nexthop, sizeof(nexthop), "%s",
7753 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
7754 BUFSIZ));
7755 break;
7756 case AF_INET6:
7757 snprintf(nexthop, sizeof(nexthop), "%s",
7758 inet_ntop(af, &attr->mp_nexthop_global, buf,
7759 BUFSIZ));
7760 break;
7761 default:
7762 snprintf(nexthop, sizeof(nexthop), "?");
7763 break;
7764 }
7765
7766 if (json_paths) {
7767 json_nexthop_global = json_object_new_object();
7768
7769 json_object_string_add(json_nexthop_global, "ip",
7770 nexthop);
7771
7772 if (path->peer->hostname)
7773 json_object_string_add(json_nexthop_global,
7774 "hostname",
7775 path->peer->hostname);
7776
7777 json_object_string_add(json_nexthop_global, "afi",
7778 (af == AF_INET) ? "ipv4"
7779 : "ipv6");
7780 json_object_boolean_true_add(json_nexthop_global,
7781 "used");
7782 } else {
7783 if (nexthop_hostname)
7784 len = vty_out(vty, "%s(%s)%s", nexthop,
7785 nexthop_hostname, vrf_id_str);
7786 else
7787 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
7788
7789 len = wide ? (41 - len) : (16 - len);
7790 if (len < 1)
7791 vty_out(vty, "\n%*s", 36, " ");
7792 else
7793 vty_out(vty, "%*s", len, " ");
7794 }
7795 } else if (safi == SAFI_EVPN) {
7796 if (json_paths) {
7797 json_nexthop_global = json_object_new_object();
7798
7799 json_object_string_add(json_nexthop_global, "ip",
7800 inet_ntoa(attr->nexthop));
7801
7802 if (path->peer->hostname)
7803 json_object_string_add(json_nexthop_global,
7804 "hostname",
7805 path->peer->hostname);
7806
7807 json_object_string_add(json_nexthop_global, "afi",
7808 "ipv4");
7809 json_object_boolean_true_add(json_nexthop_global,
7810 "used");
7811 } else {
7812 if (nexthop_hostname)
7813 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
7814 nexthop_hostname, vrf_id_str);
7815 else
7816 len = vty_out(vty, "%pI4%s", &attr->nexthop,
7817 vrf_id_str);
7818
7819 len = wide ? (41 - len) : (16 - len);
7820 if (len < 1)
7821 vty_out(vty, "\n%*s", 36, " ");
7822 else
7823 vty_out(vty, "%*s", len, " ");
7824 }
7825 } else if (safi == SAFI_FLOWSPEC) {
7826 if (attr->nexthop.s_addr != INADDR_ANY) {
7827 if (json_paths) {
7828 json_nexthop_global = json_object_new_object();
7829
7830 json_object_string_add(json_nexthop_global,
7831 "afi", "ipv4");
7832 json_object_string_add(
7833 json_nexthop_global, "ip",
7834 inet_ntoa(attr->nexthop));
7835
7836 if (path->peer->hostname)
7837 json_object_string_add(
7838 json_nexthop_global, "hostname",
7839 path->peer->hostname);
7840
7841 json_object_boolean_true_add(
7842 json_nexthop_global,
7843 "used");
7844 } else {
7845 if (nexthop_hostname)
7846 len = vty_out(vty, "%pI4(%s)%s",
7847 &attr->nexthop,
7848 nexthop_hostname,
7849 vrf_id_str);
7850 else
7851 len = vty_out(vty, "%pI4%s",
7852 &attr->nexthop,
7853 vrf_id_str);
7854
7855 len = wide ? (41 - len) : (16 - len);
7856 if (len < 1)
7857 vty_out(vty, "\n%*s", 36, " ");
7858 else
7859 vty_out(vty, "%*s", len, " ");
7860 }
7861 }
7862 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7863 if (json_paths) {
7864 json_nexthop_global = json_object_new_object();
7865
7866 json_object_string_add(json_nexthop_global, "ip",
7867 inet_ntoa(attr->nexthop));
7868
7869 if (path->peer->hostname)
7870 json_object_string_add(json_nexthop_global,
7871 "hostname",
7872 path->peer->hostname);
7873
7874 json_object_string_add(json_nexthop_global, "afi",
7875 "ipv4");
7876 json_object_boolean_true_add(json_nexthop_global,
7877 "used");
7878 } else {
7879 if (nexthop_hostname)
7880 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
7881 nexthop_hostname, vrf_id_str);
7882 else
7883 len = vty_out(vty, "%pI4%s", &attr->nexthop,
7884 vrf_id_str);
7885
7886 len = wide ? (41 - len) : (16 - len);
7887 if (len < 1)
7888 vty_out(vty, "\n%*s", 36, " ");
7889 else
7890 vty_out(vty, "%*s", len, " ");
7891 }
7892 }
7893
7894 /* IPv6 Next Hop */
7895 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7896 char buf[BUFSIZ];
7897
7898 if (json_paths) {
7899 json_nexthop_global = json_object_new_object();
7900 json_object_string_add(
7901 json_nexthop_global, "ip",
7902 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
7903 buf, BUFSIZ));
7904
7905 if (path->peer->hostname)
7906 json_object_string_add(json_nexthop_global,
7907 "hostname",
7908 path->peer->hostname);
7909
7910 json_object_string_add(json_nexthop_global, "afi",
7911 "ipv6");
7912 json_object_string_add(json_nexthop_global, "scope",
7913 "global");
7914
7915 /* We display both LL & GL if both have been
7916 * received */
7917 if ((attr->mp_nexthop_len
7918 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
7919 || (path->peer->conf_if)) {
7920 json_nexthop_ll = json_object_new_object();
7921 json_object_string_add(
7922 json_nexthop_ll, "ip",
7923 inet_ntop(AF_INET6,
7924 &attr->mp_nexthop_local, buf,
7925 BUFSIZ));
7926
7927 if (path->peer->hostname)
7928 json_object_string_add(
7929 json_nexthop_ll, "hostname",
7930 path->peer->hostname);
7931
7932 json_object_string_add(json_nexthop_ll, "afi",
7933 "ipv6");
7934 json_object_string_add(json_nexthop_ll, "scope",
7935 "link-local");
7936
7937 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
7938 &attr->mp_nexthop_local)
7939 != 0)
7940 && !attr->mp_nexthop_prefer_global)
7941 json_object_boolean_true_add(
7942 json_nexthop_ll, "used");
7943 else
7944 json_object_boolean_true_add(
7945 json_nexthop_global, "used");
7946 } else
7947 json_object_boolean_true_add(
7948 json_nexthop_global, "used");
7949 } else {
7950 /* Display LL if LL/Global both in table unless
7951 * prefer-global is set */
7952 if (((attr->mp_nexthop_len
7953 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
7954 && !attr->mp_nexthop_prefer_global)
7955 || (path->peer->conf_if)) {
7956 if (path->peer->conf_if) {
7957 len = vty_out(vty, "%s",
7958 path->peer->conf_if);
7959 /* len of IPv6 addr + max len of def
7960 * ifname */
7961 len = wide ? (41 - len) : (16 - len);
7962
7963 if (len < 1)
7964 vty_out(vty, "\n%*s", 36, " ");
7965 else
7966 vty_out(vty, "%*s", len, " ");
7967 } else {
7968 if (nexthop_hostname)
7969 len = vty_out(
7970 vty, "%pI6(%s)%s",
7971 &attr->mp_nexthop_local,
7972 nexthop_hostname,
7973 vrf_id_str);
7974 else
7975 len = vty_out(
7976 vty, "%pI6%s",
7977 &attr->mp_nexthop_local,
7978 vrf_id_str);
7979
7980 len = wide ? (41 - len) : (16 - len);
7981
7982 if (len < 1)
7983 vty_out(vty, "\n%*s", 36, " ");
7984 else
7985 vty_out(vty, "%*s", len, " ");
7986 }
7987 } else {
7988 if (nexthop_hostname)
7989 len = vty_out(vty, "%pI6(%s)%s",
7990 &attr->mp_nexthop_global,
7991 nexthop_hostname,
7992 vrf_id_str);
7993 else
7994 len = vty_out(vty, "%pI6%s",
7995 &attr->mp_nexthop_global,
7996 vrf_id_str);
7997
7998 len = wide ? (41 - len) : (16 - len);
7999
8000 if (len < 1)
8001 vty_out(vty, "\n%*s", 36, " ");
8002 else
8003 vty_out(vty, "%*s", len, " ");
8004 }
8005 }
8006 }
8007
8008 /* MED/Metric */
8009 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
8010 if (json_paths)
8011 json_object_int_add(json_path, "metric", attr->med);
8012 else if (wide)
8013 vty_out(vty, "%7u", attr->med);
8014 else
8015 vty_out(vty, "%10u", attr->med);
8016 else if (!json_paths) {
8017 if (wide)
8018 vty_out(vty, "%*s", 7, " ");
8019 else
8020 vty_out(vty, "%*s", 10, " ");
8021 }
8022
8023 /* Local Pref */
8024 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
8025 if (json_paths)
8026 json_object_int_add(json_path, "locPrf",
8027 attr->local_pref);
8028 else
8029 vty_out(vty, "%7u", attr->local_pref);
8030 else if (!json_paths)
8031 vty_out(vty, " ");
8032
8033 if (json_paths)
8034 json_object_int_add(json_path, "weight", attr->weight);
8035 else
8036 vty_out(vty, "%7u ", attr->weight);
8037
8038 if (json_paths) {
8039 char buf[BUFSIZ];
8040 json_object_string_add(
8041 json_path, "peerId",
8042 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
8043 }
8044
8045 /* Print aspath */
8046 if (attr->aspath) {
8047 if (json_paths)
8048 json_object_string_add(json_path, "path",
8049 attr->aspath->str);
8050 else
8051 aspath_print_vty(vty, "%s", attr->aspath, " ");
8052 }
8053
8054 /* Print origin */
8055 if (json_paths)
8056 json_object_string_add(json_path, "origin",
8057 bgp_origin_long_str[attr->origin]);
8058 else
8059 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8060
8061 if (json_paths) {
8062 if (bgp_evpn_is_esi_valid(&attr->esi)) {
8063 json_object_string_add(json_path, "esi",
8064 esi_to_str(&attr->esi,
8065 esi_buf, sizeof(esi_buf)));
8066 }
8067 if (safi == SAFI_EVPN &&
8068 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8069 json_ext_community = json_object_new_object();
8070 json_object_string_add(json_ext_community,
8071 "string",
8072 attr->ecommunity->str);
8073 json_object_object_add(json_path,
8074 "extendedCommunity",
8075 json_ext_community);
8076 }
8077
8078 if (nexthop_self)
8079 json_object_boolean_true_add(json_path,
8080 "announceNexthopSelf");
8081 if (nexthop_othervrf) {
8082 json_object_string_add(json_path, "nhVrfName",
8083 nexthop_vrfname);
8084
8085 json_object_int_add(json_path, "nhVrfId",
8086 ((nexthop_vrfid == VRF_UNKNOWN)
8087 ? -1
8088 : (int)nexthop_vrfid));
8089 }
8090 }
8091
8092 if (json_paths) {
8093 if (json_nexthop_global || json_nexthop_ll) {
8094 json_nexthops = json_object_new_array();
8095
8096 if (json_nexthop_global)
8097 json_object_array_add(json_nexthops,
8098 json_nexthop_global);
8099
8100 if (json_nexthop_ll)
8101 json_object_array_add(json_nexthops,
8102 json_nexthop_ll);
8103
8104 json_object_object_add(json_path, "nexthops",
8105 json_nexthops);
8106 }
8107
8108 json_object_array_add(json_paths, json_path);
8109 } else {
8110 vty_out(vty, "\n");
8111
8112 if (safi == SAFI_EVPN) {
8113 if (bgp_evpn_is_esi_valid(&attr->esi)) {
8114 vty_out(vty, "%*s", 20, " ");
8115 vty_out(vty, "ESI:%s\n",
8116 esi_to_str(&attr->esi,
8117 esi_buf, sizeof(esi_buf)));
8118 }
8119 if (attr->flag &
8120 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8121 vty_out(vty, "%*s", 20, " ");
8122 vty_out(vty, "%s\n", attr->ecommunity->str);
8123 }
8124 }
8125
8126 #ifdef ENABLE_BGP_VNC
8127 /* prints an additional line, indented, with VNC info, if
8128 * present */
8129 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
8130 rfapi_vty_out_vncinfo(vty, p, path, safi);
8131 #endif
8132 }
8133 }
8134
8135 /* called from terminal list command */
8136 void route_vty_out_tmp(struct vty *vty, const struct prefix *p,
8137 struct attr *attr, safi_t safi, bool use_json,
8138 json_object *json_ar, bool wide)
8139 {
8140 json_object *json_status = NULL;
8141 json_object *json_net = NULL;
8142 int len;
8143 char buff[BUFSIZ];
8144
8145 /* Route status display. */
8146 if (use_json) {
8147 json_status = json_object_new_object();
8148 json_net = json_object_new_object();
8149 } else {
8150 vty_out(vty, "*");
8151 vty_out(vty, ">");
8152 vty_out(vty, " ");
8153 }
8154
8155 /* print prefix and mask */
8156 if (use_json) {
8157 if (safi == SAFI_EVPN)
8158 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
8159 else if (p->family == AF_INET || p->family == AF_INET6) {
8160 json_object_string_add(
8161 json_net, "addrPrefix",
8162 inet_ntop(p->family, &p->u.prefix, buff,
8163 BUFSIZ));
8164 json_object_int_add(json_net, "prefixLen",
8165 p->prefixlen);
8166 prefix2str(p, buff, PREFIX_STRLEN);
8167 json_object_string_add(json_net, "network", buff);
8168 }
8169 } else
8170 route_vty_out_route(p, vty, NULL, wide);
8171
8172 /* Print attribute */
8173 if (attr) {
8174 if (use_json) {
8175 if (p->family == AF_INET
8176 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8177 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8178 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
8179 json_object_string_add(
8180 json_net, "nextHop",
8181 inet_ntoa(
8182 attr->mp_nexthop_global_in));
8183 else
8184 json_object_string_add(
8185 json_net, "nextHop",
8186 inet_ntoa(attr->nexthop));
8187 } else if (p->family == AF_INET6
8188 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8189 char buf[BUFSIZ];
8190
8191 json_object_string_add(
8192 json_net, "nextHopGlobal",
8193 inet_ntop(AF_INET6,
8194 &attr->mp_nexthop_global, buf,
8195 BUFSIZ));
8196 } else if (p->family == AF_EVPN &&
8197 !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
8198 json_object_string_add(json_net,
8199 "nextHop", inet_ntoa(
8200 attr->mp_nexthop_global_in));
8201
8202 if (attr->flag
8203 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
8204 json_object_int_add(json_net, "metric",
8205 attr->med);
8206
8207 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
8208 json_object_int_add(json_net, "locPrf",
8209 attr->local_pref);
8210
8211 json_object_int_add(json_net, "weight", attr->weight);
8212
8213 /* Print aspath */
8214 if (attr->aspath)
8215 json_object_string_add(json_net, "path",
8216 attr->aspath->str);
8217
8218 /* Print origin */
8219 json_object_string_add(json_net, "bgpOriginCode",
8220 bgp_origin_str[attr->origin]);
8221 } else {
8222 if (p->family == AF_INET
8223 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8224 || safi == SAFI_EVPN
8225 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8226 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8227 || safi == SAFI_EVPN)
8228 vty_out(vty, "%-16s",
8229 inet_ntoa(
8230 attr->mp_nexthop_global_in));
8231 else if (wide)
8232 vty_out(vty, "%-41s",
8233 inet_ntoa(attr->nexthop));
8234 else
8235 vty_out(vty, "%-16s",
8236 inet_ntoa(attr->nexthop));
8237 } else if (p->family == AF_INET6
8238 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8239 char buf[BUFSIZ];
8240
8241 len = vty_out(
8242 vty, "%s",
8243 inet_ntop(AF_INET6,
8244 &attr->mp_nexthop_global, buf,
8245 BUFSIZ));
8246 len = wide ? (41 - len) : (16 - len);
8247 if (len < 1)
8248 vty_out(vty, "\n%*s", 36, " ");
8249 else
8250 vty_out(vty, "%*s", len, " ");
8251 }
8252 if (attr->flag
8253 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
8254 if (wide)
8255 vty_out(vty, "%7u", attr->med);
8256 else
8257 vty_out(vty, "%10u", attr->med);
8258 else if (wide)
8259 vty_out(vty, " ");
8260 else
8261 vty_out(vty, " ");
8262
8263 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
8264 vty_out(vty, "%7u", attr->local_pref);
8265 else
8266 vty_out(vty, " ");
8267
8268 vty_out(vty, "%7u ", attr->weight);
8269
8270 /* Print aspath */
8271 if (attr->aspath)
8272 aspath_print_vty(vty, "%s", attr->aspath, " ");
8273
8274 /* Print origin */
8275 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8276 }
8277 }
8278 if (use_json) {
8279 json_object_boolean_true_add(json_status, "*");
8280 json_object_boolean_true_add(json_status, ">");
8281 json_object_object_add(json_net, "appliedStatusSymbols",
8282 json_status);
8283
8284 prefix2str(p, buff, PREFIX_STRLEN);
8285 json_object_object_add(json_ar, buff, json_net);
8286 } else
8287 vty_out(vty, "\n");
8288 }
8289
8290 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
8291 struct bgp_path_info *path, int display, safi_t safi,
8292 json_object *json)
8293 {
8294 json_object *json_out = NULL;
8295 struct attr *attr;
8296 mpls_label_t label = MPLS_INVALID_LABEL;
8297
8298 if (!path->extra)
8299 return;
8300
8301 if (json)
8302 json_out = json_object_new_object();
8303
8304 /* short status lead text */
8305 route_vty_short_status_out(vty, path, json_out);
8306
8307 /* print prefix and mask */
8308 if (json == NULL) {
8309 if (!display)
8310 route_vty_out_route(p, vty, NULL, false);
8311 else
8312 vty_out(vty, "%*s", 17, " ");
8313 }
8314
8315 /* Print attribute */
8316 attr = path->attr;
8317 if (((p->family == AF_INET)
8318 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
8319 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
8320 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8321 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8322 || safi == SAFI_EVPN) {
8323 if (json)
8324 json_object_string_add(
8325 json_out, "mpNexthopGlobalIn",
8326 inet_ntoa(attr->mp_nexthop_global_in));
8327 else
8328 vty_out(vty, "%-16s",
8329 inet_ntoa(attr->mp_nexthop_global_in));
8330 } else {
8331 if (json)
8332 json_object_string_add(
8333 json_out, "nexthop",
8334 inet_ntoa(attr->nexthop));
8335 else
8336 vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
8337 }
8338 } else if (((p->family == AF_INET6)
8339 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
8340 || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
8341 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8342 char buf_a[512];
8343
8344 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
8345 if (json)
8346 json_object_string_add(
8347 json_out, "mpNexthopGlobalIn",
8348 inet_ntop(AF_INET6,
8349 &attr->mp_nexthop_global,
8350 buf_a, sizeof(buf_a)));
8351 else
8352 vty_out(vty, "%s",
8353 inet_ntop(AF_INET6,
8354 &attr->mp_nexthop_global,
8355 buf_a, sizeof(buf_a)));
8356 } else if (attr->mp_nexthop_len
8357 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
8358 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
8359 &attr->mp_nexthop_global,
8360 &attr->mp_nexthop_local);
8361 if (json)
8362 json_object_string_add(json_out,
8363 "mpNexthopGlobalLocal",
8364 buf_a);
8365 else
8366 vty_out(vty, "%s", buf_a);
8367 }
8368 }
8369
8370 label = decode_label(&path->extra->label[0]);
8371
8372 if (bgp_is_valid_label(&label)) {
8373 if (json) {
8374 json_object_int_add(json_out, "notag", label);
8375 json_object_array_add(json, json_out);
8376 } else {
8377 vty_out(vty, "notag/%d", label);
8378 vty_out(vty, "\n");
8379 }
8380 }
8381 }
8382
8383 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
8384 struct bgp_path_info *path, int display,
8385 json_object *json_paths)
8386 {
8387 struct attr *attr;
8388 char buf[BUFSIZ] = {0};
8389 json_object *json_path = NULL;
8390 json_object *json_nexthop = NULL;
8391 json_object *json_overlay = NULL;
8392
8393 if (!path->extra)
8394 return;
8395
8396 if (json_paths) {
8397 json_path = json_object_new_object();
8398 json_overlay = json_object_new_object();
8399 json_nexthop = json_object_new_object();
8400 }
8401
8402 /* short status lead text */
8403 route_vty_short_status_out(vty, path, json_path);
8404
8405 /* print prefix and mask */
8406 if (!display)
8407 route_vty_out_route(p, vty, json_path, false);
8408 else
8409 vty_out(vty, "%*s", 17, " ");
8410
8411 /* Print attribute */
8412 attr = path->attr;
8413 char buf1[BUFSIZ];
8414 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
8415
8416 switch (af) {
8417 case AF_INET:
8418 inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ);
8419 if (!json_path) {
8420 vty_out(vty, "%-16s", buf);
8421 } else {
8422 json_object_string_add(json_nexthop, "ip", buf);
8423
8424 json_object_string_add(json_nexthop, "afi", "ipv4");
8425
8426 json_object_object_add(json_path, "nexthop",
8427 json_nexthop);
8428 }
8429 break;
8430 case AF_INET6:
8431 inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ);
8432 inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ);
8433 if (!json_path) {
8434 vty_out(vty, "%s(%s)", buf, buf1);
8435 } else {
8436 json_object_string_add(json_nexthop, "ipv6Global", buf);
8437
8438 json_object_string_add(json_nexthop, "ipv6LinkLocal",
8439 buf1);
8440
8441 json_object_string_add(json_nexthop, "afi", "ipv6");
8442
8443 json_object_object_add(json_path, "nexthop",
8444 json_nexthop);
8445 }
8446 break;
8447 default:
8448 if (!json_path) {
8449 vty_out(vty, "?");
8450 } else {
8451 json_object_string_add(json_nexthop, "Error",
8452 "Unsupported address-family");
8453 }
8454 }
8455
8456 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) {
8457 inet_ntop(AF_INET, &(attr->evpn_overlay.gw_ip.ipv4), buf,
8458 BUFSIZ);
8459 } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) {
8460 inet_ntop(AF_INET6, &(attr->evpn_overlay.gw_ip.ipv6), buf,
8461 BUFSIZ);
8462 }
8463
8464 if (!json_path)
8465 vty_out(vty, "/%s", buf);
8466 else
8467 json_object_string_add(json_overlay, "gw", buf);
8468
8469 if (attr->ecommunity) {
8470 char *mac = NULL;
8471 struct ecommunity_val *routermac = ecommunity_lookup(
8472 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
8473 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
8474
8475 if (routermac)
8476 mac = ecom_mac2str((char *)routermac->val);
8477 if (mac) {
8478 if (!json_path) {
8479 vty_out(vty, "/%s", mac);
8480 } else {
8481 json_object_string_add(json_overlay, "rmac",
8482 mac);
8483 }
8484 XFREE(MTYPE_TMP, mac);
8485 }
8486 }
8487
8488 if (!json_path) {
8489 vty_out(vty, "\n");
8490 } else {
8491 json_object_object_add(json_path, "overlay", json_overlay);
8492
8493 json_object_array_add(json_paths, json_path);
8494 }
8495 }
8496
8497 /* dampening route */
8498 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
8499 struct bgp_path_info *path, int display,
8500 afi_t afi, safi_t safi, bool use_json,
8501 json_object *json)
8502 {
8503 struct attr *attr;
8504 int len;
8505 char timebuf[BGP_UPTIME_LEN];
8506
8507 /* short status lead text */
8508 route_vty_short_status_out(vty, path, json);
8509
8510 /* print prefix and mask */
8511 if (!use_json) {
8512 if (!display)
8513 route_vty_out_route(p, vty, NULL, false);
8514 else
8515 vty_out(vty, "%*s", 17, " ");
8516 }
8517
8518 len = vty_out(vty, "%s", path->peer->host);
8519 len = 17 - len;
8520 if (len < 1) {
8521 if (!use_json)
8522 vty_out(vty, "\n%*s", 34, " ");
8523 } else {
8524 if (use_json)
8525 json_object_int_add(json, "peerHost", len);
8526 else
8527 vty_out(vty, "%*s", len, " ");
8528 }
8529
8530 if (use_json)
8531 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
8532 safi, use_json, json);
8533 else
8534 vty_out(vty, "%s ",
8535 bgp_damp_reuse_time_vty(vty, path, timebuf,
8536 BGP_UPTIME_LEN, afi, safi,
8537 use_json, json));
8538
8539 /* Print attribute */
8540 attr = path->attr;
8541
8542 /* Print aspath */
8543 if (attr->aspath) {
8544 if (use_json)
8545 json_object_string_add(json, "asPath",
8546 attr->aspath->str);
8547 else
8548 aspath_print_vty(vty, "%s", attr->aspath, " ");
8549 }
8550
8551 /* Print origin */
8552 if (use_json)
8553 json_object_string_add(json, "origin",
8554 bgp_origin_str[attr->origin]);
8555 else
8556 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8557
8558 if (!use_json)
8559 vty_out(vty, "\n");
8560 }
8561
8562 /* flap route */
8563 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
8564 struct bgp_path_info *path, int display,
8565 afi_t afi, safi_t safi, bool use_json,
8566 json_object *json)
8567 {
8568 struct attr *attr;
8569 struct bgp_damp_info *bdi;
8570 char timebuf[BGP_UPTIME_LEN];
8571 int len;
8572
8573 if (!path->extra)
8574 return;
8575
8576 bdi = path->extra->damp_info;
8577
8578 /* short status lead text */
8579 route_vty_short_status_out(vty, path, json);
8580
8581 /* print prefix and mask */
8582 if (!use_json) {
8583 if (!display)
8584 route_vty_out_route(p, vty, NULL, false);
8585 else
8586 vty_out(vty, "%*s", 17, " ");
8587 }
8588
8589 len = vty_out(vty, "%s", path->peer->host);
8590 len = 16 - len;
8591 if (len < 1) {
8592 if (!use_json)
8593 vty_out(vty, "\n%*s", 33, " ");
8594 } else {
8595 if (use_json)
8596 json_object_int_add(json, "peerHost", len);
8597 else
8598 vty_out(vty, "%*s", len, " ");
8599 }
8600
8601 len = vty_out(vty, "%d", bdi->flap);
8602 len = 5 - len;
8603 if (len < 1) {
8604 if (!use_json)
8605 vty_out(vty, " ");
8606 } else {
8607 if (use_json)
8608 json_object_int_add(json, "bdiFlap", len);
8609 else
8610 vty_out(vty, "%*s", len, " ");
8611 }
8612
8613 if (use_json)
8614 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
8615 json);
8616 else
8617 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
8618 BGP_UPTIME_LEN, 0, NULL));
8619
8620 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
8621 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8622 if (use_json)
8623 bgp_damp_reuse_time_vty(vty, path, timebuf,
8624 BGP_UPTIME_LEN, afi, safi,
8625 use_json, json);
8626 else
8627 vty_out(vty, "%s ",
8628 bgp_damp_reuse_time_vty(vty, path, timebuf,
8629 BGP_UPTIME_LEN, afi,
8630 safi, use_json, json));
8631 } else {
8632 if (!use_json)
8633 vty_out(vty, "%*s ", 8, " ");
8634 }
8635
8636 /* Print attribute */
8637 attr = path->attr;
8638
8639 /* Print aspath */
8640 if (attr->aspath) {
8641 if (use_json)
8642 json_object_string_add(json, "asPath",
8643 attr->aspath->str);
8644 else
8645 aspath_print_vty(vty, "%s", attr->aspath, " ");
8646 }
8647
8648 /* Print origin */
8649 if (use_json)
8650 json_object_string_add(json, "origin",
8651 bgp_origin_str[attr->origin]);
8652 else
8653 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8654
8655 if (!use_json)
8656 vty_out(vty, "\n");
8657 }
8658
8659 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
8660 int *first, const char *header,
8661 json_object *json_adv_to)
8662 {
8663 char buf1[INET6_ADDRSTRLEN];
8664 json_object *json_peer = NULL;
8665
8666 if (json_adv_to) {
8667 /* 'advertised-to' is a dictionary of peers we have advertised
8668 * this
8669 * prefix too. The key is the peer's IP or swpX, the value is
8670 * the
8671 * hostname if we know it and "" if not.
8672 */
8673 json_peer = json_object_new_object();
8674
8675 if (peer->hostname)
8676 json_object_string_add(json_peer, "hostname",
8677 peer->hostname);
8678
8679 if (peer->conf_if)
8680 json_object_object_add(json_adv_to, peer->conf_if,
8681 json_peer);
8682 else
8683 json_object_object_add(
8684 json_adv_to,
8685 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
8686 json_peer);
8687 } else {
8688 if (*first) {
8689 vty_out(vty, "%s", header);
8690 *first = 0;
8691 }
8692
8693 if (peer->hostname
8694 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
8695 if (peer->conf_if)
8696 vty_out(vty, " %s(%s)", peer->hostname,
8697 peer->conf_if);
8698 else
8699 vty_out(vty, " %s(%s)", peer->hostname,
8700 sockunion2str(&peer->su, buf1,
8701 SU_ADDRSTRLEN));
8702 } else {
8703 if (peer->conf_if)
8704 vty_out(vty, " %s", peer->conf_if);
8705 else
8706 vty_out(vty, " %s",
8707 sockunion2str(&peer->su, buf1,
8708 SU_ADDRSTRLEN));
8709 }
8710 }
8711 }
8712
8713 static void route_vty_out_tx_ids(struct vty *vty,
8714 struct bgp_addpath_info_data *d)
8715 {
8716 int i;
8717
8718 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
8719 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
8720 d->addpath_tx_id[i],
8721 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
8722 }
8723 }
8724
8725 static const char *bgp_path_selection_reason2str(
8726 enum bgp_path_selection_reason reason)
8727 {
8728 switch (reason) {
8729 case bgp_path_selection_none:
8730 return "Nothing to Select";
8731 case bgp_path_selection_first:
8732 return "First path received";
8733 case bgp_path_selection_evpn_sticky_mac:
8734 return "EVPN Sticky Mac";
8735 case bgp_path_selection_evpn_seq:
8736 return "EVPN sequence number";
8737 case bgp_path_selection_evpn_lower_ip:
8738 return "EVPN lower IP";
8739 case bgp_path_selection_evpn_local_path:
8740 return "EVPN local ES path";
8741 case bgp_path_selection_evpn_non_proxy:
8742 return "EVPN non proxy";
8743 case bgp_path_selection_weight:
8744 return "Weight";
8745 case bgp_path_selection_local_pref:
8746 return "Local Pref";
8747 case bgp_path_selection_local_route:
8748 return "Local Route";
8749 case bgp_path_selection_confed_as_path:
8750 return "Confederation based AS Path";
8751 case bgp_path_selection_as_path:
8752 return "AS Path";
8753 case bgp_path_selection_origin:
8754 return "Origin";
8755 case bgp_path_selection_med:
8756 return "MED";
8757 case bgp_path_selection_peer:
8758 return "Peer Type";
8759 case bgp_path_selection_confed:
8760 return "Confed Peer Type";
8761 case bgp_path_selection_igp_metric:
8762 return "IGP Metric";
8763 case bgp_path_selection_older:
8764 return "Older Path";
8765 case bgp_path_selection_router_id:
8766 return "Router ID";
8767 case bgp_path_selection_cluster_length:
8768 return "Cluser length";
8769 case bgp_path_selection_stale:
8770 return "Path Staleness";
8771 case bgp_path_selection_local_configured:
8772 return "Locally configured route";
8773 case bgp_path_selection_neighbor_ip:
8774 return "Neighbor IP";
8775 case bgp_path_selection_default:
8776 return "Nothing left to compare";
8777 }
8778 return "Invalid (internal error)";
8779 }
8780
8781 static void route_vty_out_detail_es_info(struct vty *vty,
8782 struct attr *attr, json_object *json_path)
8783 {
8784 char esi_buf[ESI_STR_LEN];
8785 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
8786 bool peer_router = !!CHECK_FLAG(attr->es_flags,
8787 ATTR_ES_PEER_ROUTER);
8788 bool peer_active = !!CHECK_FLAG(attr->es_flags,
8789 ATTR_ES_PEER_ACTIVE);
8790 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
8791 ATTR_ES_PEER_PROXY);
8792
8793 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
8794 if (json_path) {
8795 json_object *json_es_info = NULL;
8796
8797 json_object_string_add(
8798 json_path, "esi",
8799 esi_buf);
8800 if (es_local || bgp_evpn_attr_is_sync(attr)) {
8801 json_es_info = json_object_new_object();
8802 if (es_local)
8803 json_object_boolean_true_add(
8804 json_es_info, "localEs");
8805 if (peer_active)
8806 json_object_boolean_true_add(
8807 json_es_info, "peerActive");
8808 if (peer_proxy)
8809 json_object_boolean_true_add(
8810 json_es_info, "peerProxy");
8811 if (peer_router)
8812 json_object_boolean_true_add(
8813 json_es_info, "peerRouter");
8814 if (attr->mm_sync_seqnum)
8815 json_object_int_add(
8816 json_es_info, "peerSeq",
8817 attr->mm_sync_seqnum);
8818 json_object_object_add(
8819 json_path, "es_info",
8820 json_es_info);
8821 }
8822 } else {
8823 if (bgp_evpn_attr_is_sync(attr))
8824 vty_out(vty,
8825 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
8826 esi_buf,
8827 es_local ? "local-es":"",
8828 peer_proxy ? "proxy " : "",
8829 peer_active ? "active ":"",
8830 peer_router ? "router ":"",
8831 attr->mm_sync_seqnum);
8832 else
8833 vty_out(vty, " ESI %s %s\n",
8834 esi_buf,
8835 es_local ? "local-es":"");
8836 }
8837 }
8838
8839 void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
8840 struct bgp_dest *bn, struct bgp_path_info *path,
8841 afi_t afi, safi_t safi, json_object *json_paths)
8842 {
8843 char buf[INET6_ADDRSTRLEN];
8844 char buf1[BUFSIZ];
8845 char buf2[EVPN_ROUTE_STRLEN];
8846 struct attr *attr = path->attr;
8847 int sockunion_vty_out(struct vty *, union sockunion *);
8848 time_t tbuf;
8849 json_object *json_bestpath = NULL;
8850 json_object *json_cluster_list = NULL;
8851 json_object *json_cluster_list_list = NULL;
8852 json_object *json_ext_community = NULL;
8853 json_object *json_last_update = NULL;
8854 json_object *json_pmsi = NULL;
8855 json_object *json_nexthop_global = NULL;
8856 json_object *json_nexthop_ll = NULL;
8857 json_object *json_nexthops = NULL;
8858 json_object *json_path = NULL;
8859 json_object *json_peer = NULL;
8860 json_object *json_string = NULL;
8861 json_object *json_adv_to = NULL;
8862 int first = 0;
8863 struct listnode *node, *nnode;
8864 struct peer *peer;
8865 int addpath_capable;
8866 int has_adj;
8867 unsigned int first_as;
8868 bool nexthop_self =
8869 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8870 int i;
8871 char *nexthop_hostname =
8872 bgp_nexthop_hostname(path->peer, path->nexthop);
8873
8874 if (json_paths) {
8875 json_path = json_object_new_object();
8876 json_peer = json_object_new_object();
8877 json_nexthop_global = json_object_new_object();
8878 }
8879
8880 if (path->extra) {
8881 char tag_buf[30];
8882
8883 buf2[0] = '\0';
8884 tag_buf[0] = '\0';
8885 if (path->extra && path->extra->num_labels) {
8886 bgp_evpn_label2str(path->extra->label,
8887 path->extra->num_labels, tag_buf,
8888 sizeof(tag_buf));
8889 }
8890 if (safi == SAFI_EVPN) {
8891 if (!json_paths) {
8892 bgp_evpn_route2str(
8893 (struct prefix_evpn *)
8894 bgp_dest_get_prefix(bn),
8895 buf2, sizeof(buf2));
8896 vty_out(vty, " Route %s", buf2);
8897 if (tag_buf[0] != '\0')
8898 vty_out(vty, " VNI %s", tag_buf);
8899 vty_out(vty, "\n");
8900 } else {
8901 if (tag_buf[0])
8902 json_object_string_add(json_path, "VNI",
8903 tag_buf);
8904 }
8905 }
8906
8907 if (path->extra && path->extra->parent && !json_paths) {
8908 struct bgp_path_info *parent_ri;
8909 struct bgp_dest *dest, *pdest;
8910
8911 parent_ri = (struct bgp_path_info *)path->extra->parent;
8912 dest = parent_ri->net;
8913 if (dest && dest->pdest) {
8914 pdest = dest->pdest;
8915 prefix_rd2str(
8916 (struct prefix_rd *)bgp_dest_get_prefix(
8917 pdest),
8918 buf1, sizeof(buf1));
8919 if (is_pi_family_evpn(parent_ri)) {
8920 bgp_evpn_route2str(
8921 (struct prefix_evpn *)
8922 bgp_dest_get_prefix(
8923 dest),
8924 buf2, sizeof(buf2));
8925 vty_out(vty, " Imported from %s:%s, VNI %s\n", buf1, buf2, tag_buf);
8926 } else
8927 vty_out(vty, " Imported from %s:%s\n", buf1, buf2);
8928 }
8929 }
8930 }
8931
8932 /* Line1 display AS-path, Aggregator */
8933 if (attr->aspath) {
8934 if (json_paths) {
8935 if (!attr->aspath->json)
8936 aspath_str_update(attr->aspath, true);
8937 json_object_lock(attr->aspath->json);
8938 json_object_object_add(json_path, "aspath",
8939 attr->aspath->json);
8940 } else {
8941 if (attr->aspath->segments)
8942 aspath_print_vty(vty, " %s", attr->aspath, "");
8943 else
8944 vty_out(vty, " Local");
8945 }
8946 }
8947
8948 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
8949 if (json_paths)
8950 json_object_boolean_true_add(json_path, "removed");
8951 else
8952 vty_out(vty, ", (removed)");
8953 }
8954
8955 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
8956 if (json_paths)
8957 json_object_boolean_true_add(json_path, "stale");
8958 else
8959 vty_out(vty, ", (stale)");
8960 }
8961
8962 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
8963 if (json_paths) {
8964 json_object_int_add(json_path, "aggregatorAs",
8965 attr->aggregator_as);
8966 json_object_string_add(
8967 json_path, "aggregatorId",
8968 inet_ntoa(attr->aggregator_addr));
8969 if (attr->aggregator_as == BGP_AS_ZERO)
8970 json_object_boolean_true_add(
8971 json_path, "aggregatorAsMalformed");
8972 else
8973 json_object_boolean_false_add(
8974 json_path, "aggregatorAsMalformed");
8975 } else {
8976 if (attr->aggregator_as == BGP_AS_ZERO)
8977 vty_out(vty,
8978 ", (aggregated by %u(malformed) %s)",
8979 attr->aggregator_as,
8980 inet_ntoa(attr->aggregator_addr));
8981 else
8982 vty_out(vty, ", (aggregated by %u %s)",
8983 attr->aggregator_as,
8984 inet_ntoa(attr->aggregator_addr));
8985 }
8986 }
8987
8988 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
8989 PEER_FLAG_REFLECTOR_CLIENT)) {
8990 if (json_paths)
8991 json_object_boolean_true_add(json_path,
8992 "rxedFromRrClient");
8993 else
8994 vty_out(vty, ", (Received from a RR-client)");
8995 }
8996
8997 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
8998 PEER_FLAG_RSERVER_CLIENT)) {
8999 if (json_paths)
9000 json_object_boolean_true_add(json_path,
9001 "rxedFromRsClient");
9002 else
9003 vty_out(vty, ", (Received from a RS-client)");
9004 }
9005
9006 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
9007 if (json_paths)
9008 json_object_boolean_true_add(json_path,
9009 "dampeningHistoryEntry");
9010 else
9011 vty_out(vty, ", (history entry)");
9012 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
9013 if (json_paths)
9014 json_object_boolean_true_add(json_path,
9015 "dampeningSuppressed");
9016 else
9017 vty_out(vty, ", (suppressed due to dampening)");
9018 }
9019
9020 if (!json_paths)
9021 vty_out(vty, "\n");
9022
9023 /* Line2 display Next-hop, Neighbor, Router-id */
9024 /* Display the nexthop */
9025 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
9026
9027 if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET
9028 || bn_p->family == AF_EVPN)
9029 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
9030 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9031 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9032 || safi == SAFI_EVPN) {
9033 if (json_paths) {
9034 json_object_string_add(
9035 json_nexthop_global, "ip",
9036 inet_ntoa(attr->mp_nexthop_global_in));
9037
9038 if (path->peer->hostname)
9039 json_object_string_add(
9040 json_nexthop_global, "hostname",
9041 path->peer->hostname);
9042 } else {
9043 if (nexthop_hostname)
9044 vty_out(vty, " %pI4(%s)",
9045 &attr->mp_nexthop_global_in,
9046 nexthop_hostname);
9047 else
9048 vty_out(vty, " %pI4",
9049 &attr->mp_nexthop_global_in);
9050 }
9051 } else {
9052 if (json_paths) {
9053 json_object_string_add(
9054 json_nexthop_global, "ip",
9055 inet_ntoa(attr->nexthop));
9056
9057 if (path->peer->hostname)
9058 json_object_string_add(
9059 json_nexthop_global, "hostname",
9060 path->peer->hostname);
9061 } else {
9062 if (nexthop_hostname)
9063 vty_out(vty, " %pI4(%s)",
9064 &attr->nexthop,
9065 nexthop_hostname);
9066 else
9067 vty_out(vty, " %pI4",
9068 &attr->nexthop);
9069 }
9070 }
9071
9072 if (json_paths)
9073 json_object_string_add(json_nexthop_global, "afi",
9074 "ipv4");
9075 } else {
9076 if (json_paths) {
9077 json_object_string_add(
9078 json_nexthop_global, "ip",
9079 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
9080 buf, INET6_ADDRSTRLEN));
9081
9082 if (path->peer->hostname)
9083 json_object_string_add(json_nexthop_global,
9084 "hostname",
9085 path->peer->hostname);
9086
9087 json_object_string_add(json_nexthop_global, "afi",
9088 "ipv6");
9089 json_object_string_add(json_nexthop_global, "scope",
9090 "global");
9091 } else {
9092 if (nexthop_hostname)
9093 vty_out(vty, " %pI6(%s)",
9094 &attr->mp_nexthop_global,
9095 nexthop_hostname);
9096 else
9097 vty_out(vty, " %pI6",
9098 &attr->mp_nexthop_global);
9099 }
9100 }
9101
9102 /* Display the IGP cost or 'inaccessible' */
9103 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
9104 if (json_paths)
9105 json_object_boolean_false_add(json_nexthop_global,
9106 "accessible");
9107 else
9108 vty_out(vty, " (inaccessible)");
9109 } else {
9110 if (path->extra && path->extra->igpmetric) {
9111 if (json_paths)
9112 json_object_int_add(json_nexthop_global,
9113 "metric",
9114 path->extra->igpmetric);
9115 else
9116 vty_out(vty, " (metric %u)",
9117 path->extra->igpmetric);
9118 }
9119
9120 /* IGP cost is 0, display this only for json */
9121 else {
9122 if (json_paths)
9123 json_object_int_add(json_nexthop_global,
9124 "metric", 0);
9125 }
9126
9127 if (json_paths)
9128 json_object_boolean_true_add(json_nexthop_global,
9129 "accessible");
9130 }
9131
9132 /* Display peer "from" output */
9133 /* This path was originated locally */
9134 if (path->peer == bgp->peer_self) {
9135
9136 if (safi == SAFI_EVPN
9137 || (bn_p->family == AF_INET
9138 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9139 if (json_paths)
9140 json_object_string_add(json_peer, "peerId",
9141 "0.0.0.0");
9142 else
9143 vty_out(vty, " from 0.0.0.0 ");
9144 } else {
9145 if (json_paths)
9146 json_object_string_add(json_peer, "peerId",
9147 "::");
9148 else
9149 vty_out(vty, " from :: ");
9150 }
9151
9152 if (json_paths)
9153 json_object_string_add(json_peer, "routerId",
9154 inet_ntoa(bgp->router_id));
9155 else
9156 vty_out(vty, "(%s)", inet_ntoa(bgp->router_id));
9157 }
9158
9159 /* We RXed this path from one of our peers */
9160 else {
9161
9162 if (json_paths) {
9163 json_object_string_add(json_peer, "peerId",
9164 sockunion2str(&path->peer->su,
9165 buf,
9166 SU_ADDRSTRLEN));
9167 json_object_string_add(json_peer, "routerId",
9168 inet_ntop(AF_INET,
9169 &path->peer->remote_id,
9170 buf1, sizeof(buf1)));
9171
9172 if (path->peer->hostname)
9173 json_object_string_add(json_peer, "hostname",
9174 path->peer->hostname);
9175
9176 if (path->peer->domainname)
9177 json_object_string_add(json_peer, "domainname",
9178 path->peer->domainname);
9179
9180 if (path->peer->conf_if)
9181 json_object_string_add(json_peer, "interface",
9182 path->peer->conf_if);
9183 } else {
9184 if (path->peer->conf_if) {
9185 if (path->peer->hostname
9186 && CHECK_FLAG(path->peer->bgp->flags,
9187 BGP_FLAG_SHOW_HOSTNAME))
9188 vty_out(vty, " from %s(%s)",
9189 path->peer->hostname,
9190 path->peer->conf_if);
9191 else
9192 vty_out(vty, " from %s",
9193 path->peer->conf_if);
9194 } else {
9195 if (path->peer->hostname
9196 && CHECK_FLAG(path->peer->bgp->flags,
9197 BGP_FLAG_SHOW_HOSTNAME))
9198 vty_out(vty, " from %s(%s)",
9199 path->peer->hostname,
9200 path->peer->host);
9201 else
9202 vty_out(vty, " from %s",
9203 sockunion2str(&path->peer->su,
9204 buf,
9205 SU_ADDRSTRLEN));
9206 }
9207
9208 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
9209 vty_out(vty, " (%s)",
9210 inet_ntoa(attr->originator_id));
9211 else
9212 vty_out(vty, " (%s)",
9213 inet_ntop(AF_INET,
9214 &path->peer->remote_id, buf1,
9215 sizeof(buf1)));
9216 }
9217 }
9218
9219 /*
9220 * Note when vrfid of nexthop is different from that of prefix
9221 */
9222 if (path->extra && path->extra->bgp_orig) {
9223 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9224
9225 if (json_paths) {
9226 const char *vn;
9227
9228 if (path->extra->bgp_orig->inst_type
9229 == BGP_INSTANCE_TYPE_DEFAULT)
9230 vn = VRF_DEFAULT_NAME;
9231 else
9232 vn = path->extra->bgp_orig->name;
9233
9234 json_object_string_add(json_path, "nhVrfName", vn);
9235
9236 if (nexthop_vrfid == VRF_UNKNOWN) {
9237 json_object_int_add(json_path, "nhVrfId", -1);
9238 } else {
9239 json_object_int_add(json_path, "nhVrfId",
9240 (int)nexthop_vrfid);
9241 }
9242 } else {
9243 if (nexthop_vrfid == VRF_UNKNOWN)
9244 vty_out(vty, " vrf ?");
9245 else {
9246 struct vrf *vrf;
9247
9248 vrf = vrf_lookup_by_id(nexthop_vrfid);
9249 vty_out(vty, " vrf %s(%u)",
9250 VRF_LOGNAME(vrf), nexthop_vrfid);
9251 }
9252 }
9253 }
9254
9255 if (nexthop_self) {
9256 if (json_paths) {
9257 json_object_boolean_true_add(json_path,
9258 "announceNexthopSelf");
9259 } else {
9260 vty_out(vty, " announce-nh-self");
9261 }
9262 }
9263
9264 if (!json_paths)
9265 vty_out(vty, "\n");
9266
9267 /* display the link-local nexthop */
9268 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9269 if (json_paths) {
9270 json_nexthop_ll = json_object_new_object();
9271 json_object_string_add(
9272 json_nexthop_ll, "ip",
9273 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
9274 buf, INET6_ADDRSTRLEN));
9275
9276 if (path->peer->hostname)
9277 json_object_string_add(json_nexthop_ll,
9278 "hostname",
9279 path->peer->hostname);
9280
9281 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
9282 json_object_string_add(json_nexthop_ll, "scope",
9283 "link-local");
9284
9285 json_object_boolean_true_add(json_nexthop_ll,
9286 "accessible");
9287
9288 if (!attr->mp_nexthop_prefer_global)
9289 json_object_boolean_true_add(json_nexthop_ll,
9290 "used");
9291 else
9292 json_object_boolean_true_add(
9293 json_nexthop_global, "used");
9294 } else {
9295 vty_out(vty, " (%s) %s\n",
9296 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
9297 buf, INET6_ADDRSTRLEN),
9298 attr->mp_nexthop_prefer_global
9299 ? "(prefer-global)"
9300 : "(used)");
9301 }
9302 }
9303 /* If we do not have a link-local nexthop then we must flag the
9304 global as "used" */
9305 else {
9306 if (json_paths)
9307 json_object_boolean_true_add(json_nexthop_global,
9308 "used");
9309 }
9310
9311 if (safi == SAFI_EVPN &&
9312 bgp_evpn_is_esi_valid(&attr->esi)) {
9313 route_vty_out_detail_es_info(vty, attr, json_path);
9314 }
9315
9316 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
9317 * Int/Ext/Local, Atomic, best */
9318 if (json_paths)
9319 json_object_string_add(json_path, "origin",
9320 bgp_origin_long_str[attr->origin]);
9321 else
9322 vty_out(vty, " Origin %s",
9323 bgp_origin_long_str[attr->origin]);
9324
9325 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
9326 if (json_paths)
9327 json_object_int_add(json_path, "metric", attr->med);
9328 else
9329 vty_out(vty, ", metric %u", attr->med);
9330 }
9331
9332 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
9333 if (json_paths)
9334 json_object_int_add(json_path, "locPrf",
9335 attr->local_pref);
9336 else
9337 vty_out(vty, ", localpref %u", attr->local_pref);
9338 }
9339
9340 if (attr->weight != 0) {
9341 if (json_paths)
9342 json_object_int_add(json_path, "weight", attr->weight);
9343 else
9344 vty_out(vty, ", weight %u", attr->weight);
9345 }
9346
9347 if (attr->tag != 0) {
9348 if (json_paths)
9349 json_object_int_add(json_path, "tag", attr->tag);
9350 else
9351 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
9352 }
9353
9354 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
9355 if (json_paths)
9356 json_object_boolean_false_add(json_path, "valid");
9357 else
9358 vty_out(vty, ", invalid");
9359 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
9360 if (json_paths)
9361 json_object_boolean_true_add(json_path, "valid");
9362 else
9363 vty_out(vty, ", valid");
9364 }
9365
9366 if (path->peer != bgp->peer_self) {
9367 if (path->peer->as == path->peer->local_as) {
9368 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
9369 if (json_paths)
9370 json_object_string_add(
9371 json_peer, "type",
9372 "confed-internal");
9373 else
9374 vty_out(vty, ", confed-internal");
9375 } else {
9376 if (json_paths)
9377 json_object_string_add(
9378 json_peer, "type", "internal");
9379 else
9380 vty_out(vty, ", internal");
9381 }
9382 } else {
9383 if (bgp_confederation_peers_check(bgp,
9384 path->peer->as)) {
9385 if (json_paths)
9386 json_object_string_add(
9387 json_peer, "type",
9388 "confed-external");
9389 else
9390 vty_out(vty, ", confed-external");
9391 } else {
9392 if (json_paths)
9393 json_object_string_add(
9394 json_peer, "type", "external");
9395 else
9396 vty_out(vty, ", external");
9397 }
9398 }
9399 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
9400 if (json_paths) {
9401 json_object_boolean_true_add(json_path, "aggregated");
9402 json_object_boolean_true_add(json_path, "local");
9403 } else {
9404 vty_out(vty, ", aggregated, local");
9405 }
9406 } else if (path->type != ZEBRA_ROUTE_BGP) {
9407 if (json_paths)
9408 json_object_boolean_true_add(json_path, "sourced");
9409 else
9410 vty_out(vty, ", sourced");
9411 } else {
9412 if (json_paths) {
9413 json_object_boolean_true_add(json_path, "sourced");
9414 json_object_boolean_true_add(json_path, "local");
9415 } else {
9416 vty_out(vty, ", sourced, local");
9417 }
9418 }
9419
9420 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
9421 if (json_paths)
9422 json_object_boolean_true_add(json_path,
9423 "atomicAggregate");
9424 else
9425 vty_out(vty, ", atomic-aggregate");
9426 }
9427
9428 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
9429 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
9430 && bgp_path_info_mpath_count(path))) {
9431 if (json_paths)
9432 json_object_boolean_true_add(json_path, "multipath");
9433 else
9434 vty_out(vty, ", multipath");
9435 }
9436
9437 // Mark the bestpath(s)
9438 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
9439 first_as = aspath_get_first_as(attr->aspath);
9440
9441 if (json_paths) {
9442 if (!json_bestpath)
9443 json_bestpath = json_object_new_object();
9444 json_object_int_add(json_bestpath, "bestpathFromAs",
9445 first_as);
9446 } else {
9447 if (first_as)
9448 vty_out(vty, ", bestpath-from-AS %u", first_as);
9449 else
9450 vty_out(vty, ", bestpath-from-AS Local");
9451 }
9452 }
9453
9454 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9455 if (json_paths) {
9456 if (!json_bestpath)
9457 json_bestpath = json_object_new_object();
9458 json_object_boolean_true_add(json_bestpath, "overall");
9459 json_object_string_add(
9460 json_bestpath, "selectionReason",
9461 bgp_path_selection_reason2str(bn->reason));
9462 } else {
9463 vty_out(vty, ", best");
9464 vty_out(vty, " (%s)",
9465 bgp_path_selection_reason2str(bn->reason));
9466 }
9467 }
9468
9469 if (json_bestpath)
9470 json_object_object_add(json_path, "bestpath", json_bestpath);
9471
9472 if (!json_paths)
9473 vty_out(vty, "\n");
9474
9475 /* Line 4 display Community */
9476 if (attr->community) {
9477 if (json_paths) {
9478 if (!attr->community->json)
9479 community_str(attr->community, true);
9480 json_object_lock(attr->community->json);
9481 json_object_object_add(json_path, "community",
9482 attr->community->json);
9483 } else {
9484 vty_out(vty, " Community: %s\n",
9485 attr->community->str);
9486 }
9487 }
9488
9489 /* Line 5 display Extended-community */
9490 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9491 if (json_paths) {
9492 json_ext_community = json_object_new_object();
9493 json_object_string_add(json_ext_community, "string",
9494 attr->ecommunity->str);
9495 json_object_object_add(json_path, "extendedCommunity",
9496 json_ext_community);
9497 } else {
9498 vty_out(vty, " Extended Community: %s\n",
9499 attr->ecommunity->str);
9500 }
9501 }
9502
9503 /* Line 6 display Large community */
9504 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
9505 if (json_paths) {
9506 if (!attr->lcommunity->json)
9507 lcommunity_str(attr->lcommunity, true);
9508 json_object_lock(attr->lcommunity->json);
9509 json_object_object_add(json_path, "largeCommunity",
9510 attr->lcommunity->json);
9511 } else {
9512 vty_out(vty, " Large Community: %s\n",
9513 attr->lcommunity->str);
9514 }
9515 }
9516
9517 /* Line 7 display Originator, Cluster-id */
9518 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
9519 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
9520 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
9521 if (json_paths)
9522 json_object_string_add(
9523 json_path, "originatorId",
9524 inet_ntoa(attr->originator_id));
9525 else
9526 vty_out(vty, " Originator: %s",
9527 inet_ntoa(attr->originator_id));
9528 }
9529
9530 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
9531 int i;
9532
9533 if (json_paths) {
9534 json_cluster_list = json_object_new_object();
9535 json_cluster_list_list =
9536 json_object_new_array();
9537
9538 for (i = 0; i < attr->cluster->length / 4;
9539 i++) {
9540 json_string = json_object_new_string(
9541 inet_ntoa(attr->cluster
9542 ->list[i]));
9543 json_object_array_add(
9544 json_cluster_list_list,
9545 json_string);
9546 }
9547
9548 /*
9549 * struct cluster_list does not have
9550 * "str" variable like aspath and community
9551 * do. Add this someday if someone asks
9552 * for it.
9553 * json_object_string_add(json_cluster_list,
9554 * "string", attr->cluster->str);
9555 */
9556 json_object_object_add(json_cluster_list,
9557 "list",
9558 json_cluster_list_list);
9559 json_object_object_add(json_path, "clusterList",
9560 json_cluster_list);
9561 } else {
9562 vty_out(vty, ", Cluster list: ");
9563
9564 for (i = 0; i < attr->cluster->length / 4;
9565 i++) {
9566 vty_out(vty, "%s ",
9567 inet_ntoa(attr->cluster
9568 ->list[i]));
9569 }
9570 }
9571 }
9572
9573 if (!json_paths)
9574 vty_out(vty, "\n");
9575 }
9576
9577 if (path->extra && path->extra->damp_info)
9578 bgp_damp_info_vty(vty, path, afi, safi, json_path);
9579
9580 /* Remote Label */
9581 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
9582 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
9583 mpls_label_t label = label_pton(&path->extra->label[0]);
9584
9585 if (json_paths)
9586 json_object_int_add(json_path, "remoteLabel", label);
9587 else
9588 vty_out(vty, " Remote label: %d\n", label);
9589 }
9590
9591 /* Remote SID */
9592 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
9593 inet_ntop(AF_INET6, &path->extra->sid, buf, sizeof(buf));
9594 if (json_paths)
9595 json_object_string_add(json_path, "remoteSid", buf);
9596 else
9597 vty_out(vty, " Remote SID: %s\n", buf);
9598 }
9599
9600 /* Label Index */
9601 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
9602 if (json_paths)
9603 json_object_int_add(json_path, "labelIndex",
9604 attr->label_index);
9605 else
9606 vty_out(vty, " Label Index: %d\n",
9607 attr->label_index);
9608 }
9609
9610 /* Line 8 display Addpath IDs */
9611 if (path->addpath_rx_id
9612 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
9613 if (json_paths) {
9614 json_object_int_add(json_path, "addpathRxId",
9615 path->addpath_rx_id);
9616
9617 /* Keep backwards compatibility with the old API
9618 * by putting TX All's ID in the old field
9619 */
9620 json_object_int_add(
9621 json_path, "addpathTxId",
9622 path->tx_addpath
9623 .addpath_tx_id[BGP_ADDPATH_ALL]);
9624
9625 /* ... but create a specific field for each
9626 * strategy
9627 */
9628 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9629 json_object_int_add(
9630 json_path,
9631 bgp_addpath_names(i)->id_json_name,
9632 path->tx_addpath.addpath_tx_id[i]);
9633 }
9634 } else {
9635 vty_out(vty, " AddPath ID: RX %u, ",
9636 path->addpath_rx_id);
9637
9638 route_vty_out_tx_ids(vty, &path->tx_addpath);
9639 }
9640 }
9641
9642 /* If we used addpath to TX a non-bestpath we need to display
9643 * "Advertised to" on a path-by-path basis
9644 */
9645 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
9646 first = 1;
9647
9648 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
9649 addpath_capable =
9650 bgp_addpath_encode_tx(peer, afi, safi);
9651 has_adj = bgp_adj_out_lookup(
9652 peer, path->net,
9653 bgp_addpath_id_for_peer(peer, afi, safi,
9654 &path->tx_addpath));
9655
9656 if ((addpath_capable && has_adj)
9657 || (!addpath_capable && has_adj
9658 && CHECK_FLAG(path->flags,
9659 BGP_PATH_SELECTED))) {
9660 if (json_path && !json_adv_to)
9661 json_adv_to = json_object_new_object();
9662
9663 route_vty_out_advertised_to(
9664 vty, peer, &first,
9665 " Advertised to:", json_adv_to);
9666 }
9667 }
9668
9669 if (json_path) {
9670 if (json_adv_to) {
9671 json_object_object_add(
9672 json_path, "advertisedTo", json_adv_to);
9673 }
9674 } else {
9675 if (!first) {
9676 vty_out(vty, "\n");
9677 }
9678 }
9679 }
9680
9681 /* Line 9 display Uptime */
9682 tbuf = time(NULL) - (bgp_clock() - path->uptime);
9683 if (json_paths) {
9684 json_last_update = json_object_new_object();
9685 json_object_int_add(json_last_update, "epoch", tbuf);
9686 json_object_string_add(json_last_update, "string",
9687 ctime(&tbuf));
9688 json_object_object_add(json_path, "lastUpdate",
9689 json_last_update);
9690 } else
9691 vty_out(vty, " Last update: %s", ctime(&tbuf));
9692
9693 /* Line 10 display PMSI tunnel attribute, if present */
9694 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
9695 const char *str =
9696 lookup_msg(bgp_pmsi_tnltype_str, attr->pmsi_tnl_type,
9697 PMSI_TNLTYPE_STR_DEFAULT);
9698
9699 if (json_paths) {
9700 json_pmsi = json_object_new_object();
9701 json_object_string_add(json_pmsi, "tunnelType", str);
9702 json_object_int_add(json_pmsi, "label",
9703 label2vni(&attr->label));
9704 json_object_object_add(json_path, "pmsi", json_pmsi);
9705 } else
9706 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
9707 str, label2vni(&attr->label));
9708 }
9709
9710 /* We've constructed the json object for this path, add it to the json
9711 * array of paths
9712 */
9713 if (json_paths) {
9714 if (json_nexthop_global || json_nexthop_ll) {
9715 json_nexthops = json_object_new_array();
9716
9717 if (json_nexthop_global)
9718 json_object_array_add(json_nexthops,
9719 json_nexthop_global);
9720
9721 if (json_nexthop_ll)
9722 json_object_array_add(json_nexthops,
9723 json_nexthop_ll);
9724
9725 json_object_object_add(json_path, "nexthops",
9726 json_nexthops);
9727 }
9728
9729 json_object_object_add(json_path, "peer", json_peer);
9730 json_object_array_add(json_paths, json_path);
9731 }
9732 }
9733
9734 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
9735 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
9736 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
9737
9738 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
9739 const char *prefix_list_str, afi_t afi,
9740 safi_t safi, enum bgp_show_type type);
9741 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
9742 const char *filter, afi_t afi, safi_t safi,
9743 enum bgp_show_type type);
9744 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
9745 const char *rmap_str, afi_t afi, safi_t safi,
9746 enum bgp_show_type type);
9747 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
9748 const char *com, int exact, afi_t afi,
9749 safi_t safi);
9750 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
9751 const char *prefix, afi_t afi, safi_t safi,
9752 enum bgp_show_type type);
9753 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
9754 afi_t afi, safi_t safi, enum bgp_show_type type,
9755 bool use_json);
9756 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
9757 const char *comstr, int exact, afi_t afi,
9758 safi_t safi, bool use_json);
9759
9760
9761 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
9762 struct bgp_table *table, enum bgp_show_type type,
9763 void *output_arg, bool use_json, char *rd,
9764 int is_last, unsigned long *output_cum,
9765 unsigned long *total_cum,
9766 unsigned long *json_header_depth, bool wide)
9767 {
9768 struct bgp_path_info *pi;
9769 struct bgp_dest *dest;
9770 int header = 1;
9771 int display;
9772 unsigned long output_count = 0;
9773 unsigned long total_count = 0;
9774 struct prefix *p;
9775 json_object *json_paths = NULL;
9776 int first = 1;
9777
9778 if (output_cum && *output_cum != 0)
9779 header = 0;
9780
9781 if (use_json && !*json_header_depth) {
9782 vty_out(vty,
9783 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n"
9784 " \"localAS\": %u,\n \"routes\": { ",
9785 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
9786 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
9787 ? VRF_DEFAULT_NAME
9788 : bgp->name,
9789 table->version, inet_ntoa(bgp->router_id),
9790 bgp->default_local_pref, bgp->as);
9791 *json_header_depth = 2;
9792 if (rd) {
9793 vty_out(vty, " \"routeDistinguishers\" : {");
9794 ++*json_header_depth;
9795 }
9796 }
9797
9798 if (use_json && rd) {
9799 vty_out(vty, " \"%s\" : { ", rd);
9800 }
9801
9802 /* Start processing of routes. */
9803 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
9804 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
9805
9806 pi = bgp_dest_get_bgp_path_info(dest);
9807 if (pi == NULL)
9808 continue;
9809
9810 display = 0;
9811 if (use_json)
9812 json_paths = json_object_new_array();
9813 else
9814 json_paths = NULL;
9815
9816 for (; pi; pi = pi->next) {
9817 total_count++;
9818 if (type == bgp_show_type_flap_statistics
9819 || type == bgp_show_type_flap_neighbor
9820 || type == bgp_show_type_dampend_paths
9821 || type == bgp_show_type_damp_neighbor) {
9822 if (!(pi->extra && pi->extra->damp_info))
9823 continue;
9824 }
9825 if (type == bgp_show_type_regexp) {
9826 regex_t *regex = output_arg;
9827
9828 if (bgp_regexec(regex, pi->attr->aspath)
9829 == REG_NOMATCH)
9830 continue;
9831 }
9832 if (type == bgp_show_type_prefix_list) {
9833 struct prefix_list *plist = output_arg;
9834
9835 if (prefix_list_apply(plist, dest_p)
9836 != PREFIX_PERMIT)
9837 continue;
9838 }
9839 if (type == bgp_show_type_filter_list) {
9840 struct as_list *as_list = output_arg;
9841
9842 if (as_list_apply(as_list, pi->attr->aspath)
9843 != AS_FILTER_PERMIT)
9844 continue;
9845 }
9846 if (type == bgp_show_type_route_map) {
9847 struct route_map *rmap = output_arg;
9848 struct bgp_path_info path;
9849 struct attr dummy_attr;
9850 route_map_result_t ret;
9851
9852 dummy_attr = *pi->attr;
9853
9854 path.peer = pi->peer;
9855 path.attr = &dummy_attr;
9856
9857 ret = route_map_apply(rmap, dest_p, RMAP_BGP,
9858 &path);
9859 if (ret == RMAP_DENYMATCH)
9860 continue;
9861 }
9862 if (type == bgp_show_type_neighbor
9863 || type == bgp_show_type_flap_neighbor
9864 || type == bgp_show_type_damp_neighbor) {
9865 union sockunion *su = output_arg;
9866
9867 if (pi->peer == NULL
9868 || pi->peer->su_remote == NULL
9869 || !sockunion_same(pi->peer->su_remote, su))
9870 continue;
9871 }
9872 if (type == bgp_show_type_cidr_only) {
9873 uint32_t destination;
9874
9875 destination = ntohl(dest_p->u.prefix4.s_addr);
9876 if (IN_CLASSC(destination)
9877 && dest_p->prefixlen == 24)
9878 continue;
9879 if (IN_CLASSB(destination)
9880 && dest_p->prefixlen == 16)
9881 continue;
9882 if (IN_CLASSA(destination)
9883 && dest_p->prefixlen == 8)
9884 continue;
9885 }
9886 if (type == bgp_show_type_prefix_longer) {
9887 p = output_arg;
9888 if (!prefix_match(p, dest_p))
9889 continue;
9890 }
9891 if (type == bgp_show_type_community_all) {
9892 if (!pi->attr->community)
9893 continue;
9894 }
9895 if (type == bgp_show_type_community) {
9896 struct community *com = output_arg;
9897
9898 if (!pi->attr->community
9899 || !community_match(pi->attr->community,
9900 com))
9901 continue;
9902 }
9903 if (type == bgp_show_type_community_exact) {
9904 struct community *com = output_arg;
9905
9906 if (!pi->attr->community
9907 || !community_cmp(pi->attr->community, com))
9908 continue;
9909 }
9910 if (type == bgp_show_type_community_list) {
9911 struct community_list *list = output_arg;
9912
9913 if (!community_list_match(pi->attr->community,
9914 list))
9915 continue;
9916 }
9917 if (type == bgp_show_type_community_list_exact) {
9918 struct community_list *list = output_arg;
9919
9920 if (!community_list_exact_match(
9921 pi->attr->community, list))
9922 continue;
9923 }
9924 if (type == bgp_show_type_lcommunity) {
9925 struct lcommunity *lcom = output_arg;
9926
9927 if (!pi->attr->lcommunity
9928 || !lcommunity_match(pi->attr->lcommunity,
9929 lcom))
9930 continue;
9931 }
9932
9933 if (type == bgp_show_type_lcommunity_exact) {
9934 struct lcommunity *lcom = output_arg;
9935
9936 if (!pi->attr->lcommunity
9937 || !lcommunity_cmp(pi->attr->lcommunity,
9938 lcom))
9939 continue;
9940 }
9941 if (type == bgp_show_type_lcommunity_list) {
9942 struct community_list *list = output_arg;
9943
9944 if (!lcommunity_list_match(pi->attr->lcommunity,
9945 list))
9946 continue;
9947 }
9948 if (type
9949 == bgp_show_type_lcommunity_list_exact) {
9950 struct community_list *list = output_arg;
9951
9952 if (!lcommunity_list_exact_match(
9953 pi->attr->lcommunity, list))
9954 continue;
9955 }
9956 if (type == bgp_show_type_lcommunity_all) {
9957 if (!pi->attr->lcommunity)
9958 continue;
9959 }
9960 if (type == bgp_show_type_dampend_paths
9961 || type == bgp_show_type_damp_neighbor) {
9962 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
9963 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
9964 continue;
9965 }
9966
9967 if (!use_json && header) {
9968 vty_out(vty, "BGP table version is %" PRIu64", local router ID is %s, vrf id ",
9969 table->version,
9970 inet_ntoa(bgp->router_id));
9971 if (bgp->vrf_id == VRF_UNKNOWN)
9972 vty_out(vty, "%s", VRFID_NONE_STR);
9973 else
9974 vty_out(vty, "%u", bgp->vrf_id);
9975 vty_out(vty, "\n");
9976 vty_out(vty, "Default local pref %u, ",
9977 bgp->default_local_pref);
9978 vty_out(vty, "local AS %u\n", bgp->as);
9979 vty_out(vty, BGP_SHOW_SCODE_HEADER);
9980 vty_out(vty, BGP_SHOW_NCODE_HEADER);
9981 vty_out(vty, BGP_SHOW_OCODE_HEADER);
9982 if (type == bgp_show_type_dampend_paths
9983 || type == bgp_show_type_damp_neighbor)
9984 vty_out(vty, BGP_SHOW_DAMP_HEADER);
9985 else if (type == bgp_show_type_flap_statistics
9986 || type == bgp_show_type_flap_neighbor)
9987 vty_out(vty, BGP_SHOW_FLAP_HEADER);
9988 else
9989 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
9990 : BGP_SHOW_HEADER));
9991 header = 0;
9992 }
9993 if (rd != NULL && !display && !output_count) {
9994 if (!use_json)
9995 vty_out(vty,
9996 "Route Distinguisher: %s\n",
9997 rd);
9998 }
9999 if (type == bgp_show_type_dampend_paths
10000 || type == bgp_show_type_damp_neighbor)
10001 damp_route_vty_out(vty, dest_p, pi, display,
10002 AFI_IP, safi, use_json,
10003 json_paths);
10004 else if (type == bgp_show_type_flap_statistics
10005 || type == bgp_show_type_flap_neighbor)
10006 flap_route_vty_out(vty, dest_p, pi, display,
10007 AFI_IP, safi, use_json,
10008 json_paths);
10009 else
10010 route_vty_out(vty, dest_p, pi, display, safi,
10011 json_paths, wide);
10012 display++;
10013 }
10014
10015 if (display) {
10016 output_count++;
10017 if (!use_json)
10018 continue;
10019
10020 /* encode prefix */
10021 if (dest_p->family == AF_FLOWSPEC) {
10022 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
10023
10024 bgp_fs_nlri_get_string(
10025 (unsigned char *)
10026 dest_p->u.prefix_flowspec.ptr,
10027 dest_p->u.prefix_flowspec.prefixlen,
10028 retstr, NLRI_STRING_FORMAT_MIN, NULL);
10029 if (first)
10030 vty_out(vty, "\"%s/%d\": ", retstr,
10031 dest_p->u.prefix_flowspec
10032 .prefixlen);
10033 else
10034 vty_out(vty, ",\"%s/%d\": ", retstr,
10035 dest_p->u.prefix_flowspec
10036 .prefixlen);
10037 } else {
10038 if (first)
10039 vty_out(vty, "\"%pFX\": ", dest_p);
10040 else
10041 vty_out(vty, ",\"%pFX\": ", dest_p);
10042 }
10043 vty_out(vty, "%s",
10044 json_object_to_json_string_ext(
10045 json_paths, JSON_C_TO_STRING_PRETTY));
10046 json_object_free(json_paths);
10047 json_paths = NULL;
10048 first = 0;
10049 } else
10050 json_object_free(json_paths);
10051 }
10052
10053 if (output_cum) {
10054 output_count += *output_cum;
10055 *output_cum = output_count;
10056 }
10057 if (total_cum) {
10058 total_count += *total_cum;
10059 *total_cum = total_count;
10060 }
10061 if (use_json) {
10062 if (rd) {
10063 vty_out(vty, " }%s ", (is_last ? "" : ","));
10064 }
10065 if (is_last) {
10066 unsigned long i;
10067 for (i = 0; i < *json_header_depth; ++i)
10068 vty_out(vty, " } ");
10069 vty_out(vty, "\n");
10070 }
10071 } else {
10072 if (is_last) {
10073 /* No route is displayed */
10074 if (output_count == 0) {
10075 if (type == bgp_show_type_normal)
10076 vty_out(vty,
10077 "No BGP prefixes displayed, %ld exist\n",
10078 total_count);
10079 } else
10080 vty_out(vty,
10081 "\nDisplayed %ld routes and %ld total paths\n",
10082 output_count, total_count);
10083 }
10084 }
10085
10086 return CMD_SUCCESS;
10087 }
10088
10089 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
10090 struct bgp_table *table, struct prefix_rd *prd_match,
10091 enum bgp_show_type type, void *output_arg, bool use_json)
10092 {
10093 struct bgp_dest *dest, *next;
10094 unsigned long output_cum = 0;
10095 unsigned long total_cum = 0;
10096 unsigned long json_header_depth = 0;
10097 struct bgp_table *itable;
10098 bool show_msg;
10099
10100 show_msg = (!use_json && type == bgp_show_type_normal);
10101
10102 for (dest = bgp_table_top(table); dest; dest = next) {
10103 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10104
10105 next = bgp_route_next(dest);
10106 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
10107 continue;
10108
10109 itable = bgp_dest_get_bgp_table_info(dest);
10110 if (itable != NULL) {
10111 struct prefix_rd prd;
10112 char rd[RD_ADDRSTRLEN];
10113
10114 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
10115 prefix_rd2str(&prd, rd, sizeof(rd));
10116 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
10117 use_json, rd, next == NULL, &output_cum,
10118 &total_cum, &json_header_depth, false);
10119 if (next == NULL)
10120 show_msg = false;
10121 }
10122 }
10123 if (show_msg) {
10124 if (output_cum == 0)
10125 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
10126 total_cum);
10127 else
10128 vty_out(vty,
10129 "\nDisplayed %ld routes and %ld total paths\n",
10130 output_cum, total_cum);
10131 }
10132 return CMD_SUCCESS;
10133 }
10134 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
10135 enum bgp_show_type type, void *output_arg, bool use_json,
10136 bool wide)
10137 {
10138 struct bgp_table *table;
10139 unsigned long json_header_depth = 0;
10140
10141 if (bgp == NULL) {
10142 bgp = bgp_get_default();
10143 }
10144
10145 if (bgp == NULL) {
10146 if (!use_json)
10147 vty_out(vty, "No BGP process is configured\n");
10148 else
10149 vty_out(vty, "{}\n");
10150 return CMD_WARNING;
10151 }
10152
10153 table = bgp->rib[afi][safi];
10154 /* use MPLS and ENCAP specific shows until they are merged */
10155 if (safi == SAFI_MPLS_VPN) {
10156 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
10157 output_arg, use_json);
10158 }
10159
10160 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
10161 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
10162 output_arg, use_json,
10163 1, NULL, NULL);
10164 }
10165 /* labeled-unicast routes live in the unicast table */
10166 else if (safi == SAFI_LABELED_UNICAST)
10167 safi = SAFI_UNICAST;
10168
10169 return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json,
10170 NULL, 1, NULL, NULL, &json_header_depth, wide);
10171 }
10172
10173 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
10174 safi_t safi, bool use_json,
10175 bool wide)
10176 {
10177 struct listnode *node, *nnode;
10178 struct bgp *bgp;
10179 int is_first = 1;
10180 bool route_output = false;
10181
10182 if (use_json)
10183 vty_out(vty, "{\n");
10184
10185 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
10186 route_output = true;
10187 if (use_json) {
10188 if (!is_first)
10189 vty_out(vty, ",\n");
10190 else
10191 is_first = 0;
10192
10193 vty_out(vty, "\"%s\":",
10194 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
10195 ? VRF_DEFAULT_NAME
10196 : bgp->name);
10197 } else {
10198 vty_out(vty, "\nInstance %s:\n",
10199 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
10200 ? VRF_DEFAULT_NAME
10201 : bgp->name);
10202 }
10203 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
10204 use_json, wide);
10205 }
10206
10207 if (use_json)
10208 vty_out(vty, "}\n");
10209 else if (!route_output)
10210 vty_out(vty, "%% BGP instance not found\n");
10211 }
10212
10213 /* Header of detailed BGP route information */
10214 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
10215 struct bgp_dest *dest, struct prefix_rd *prd,
10216 afi_t afi, safi_t safi, json_object *json)
10217 {
10218 struct bgp_path_info *pi;
10219 const struct prefix *p;
10220 struct peer *peer;
10221 struct listnode *node, *nnode;
10222 char buf1[RD_ADDRSTRLEN];
10223 char buf2[INET6_ADDRSTRLEN];
10224 char buf3[EVPN_ROUTE_STRLEN];
10225 char prefix_str[BUFSIZ];
10226 int count = 0;
10227 int best = 0;
10228 int suppress = 0;
10229 int accept_own = 0;
10230 int route_filter_translated_v4 = 0;
10231 int route_filter_v4 = 0;
10232 int route_filter_translated_v6 = 0;
10233 int route_filter_v6 = 0;
10234 int llgr_stale = 0;
10235 int no_llgr = 0;
10236 int accept_own_nexthop = 0;
10237 int blackhole = 0;
10238 int no_export = 0;
10239 int no_advertise = 0;
10240 int local_as = 0;
10241 int no_peer = 0;
10242 int first = 1;
10243 int has_valid_label = 0;
10244 mpls_label_t label = 0;
10245 json_object *json_adv_to = NULL;
10246
10247 p = bgp_dest_get_prefix(dest);
10248 has_valid_label = bgp_is_valid_label(&dest->local_label);
10249
10250 if (has_valid_label)
10251 label = label_pton(&dest->local_label);
10252
10253 if (safi == SAFI_EVPN) {
10254
10255 if (!json) {
10256 vty_out(vty, "BGP routing table entry for %s%s%s\n",
10257 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
10258 : "", prd ? ":" : "",
10259 bgp_evpn_route2str((struct prefix_evpn *)p,
10260 buf3, sizeof(buf3)));
10261 } else {
10262 json_object_string_add(json, "rd",
10263 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
10264 "");
10265 bgp_evpn_route2json((struct prefix_evpn *)p, json);
10266 }
10267 } else {
10268 if (!json) {
10269 vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
10270 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
10271 ? prefix_rd2str(prd, buf1,
10272 sizeof(buf1))
10273 : ""),
10274 safi == SAFI_MPLS_VPN ? ":" : "",
10275 inet_ntop(p->family, &p->u.prefix, buf2,
10276 INET6_ADDRSTRLEN),
10277 p->prefixlen);
10278
10279 } else
10280 json_object_string_add(json, "prefix",
10281 prefix2str(p, prefix_str, sizeof(prefix_str)));
10282 }
10283
10284 if (has_valid_label) {
10285 if (json)
10286 json_object_int_add(json, "localLabel", label);
10287 else
10288 vty_out(vty, "Local label: %d\n", label);
10289 }
10290
10291 if (!json)
10292 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
10293 vty_out(vty, "not allocated\n");
10294
10295 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
10296 count++;
10297 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
10298 best = count;
10299 if (pi->extra && pi->extra->suppress)
10300 suppress = 1;
10301
10302 if (pi->attr->community == NULL)
10303 continue;
10304
10305 no_advertise += community_include(
10306 pi->attr->community, COMMUNITY_NO_ADVERTISE);
10307 no_export += community_include(pi->attr->community,
10308 COMMUNITY_NO_EXPORT);
10309 local_as += community_include(pi->attr->community,
10310 COMMUNITY_LOCAL_AS);
10311 accept_own += community_include(pi->attr->community,
10312 COMMUNITY_ACCEPT_OWN);
10313 route_filter_translated_v4 += community_include(
10314 pi->attr->community,
10315 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
10316 route_filter_translated_v6 += community_include(
10317 pi->attr->community,
10318 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
10319 route_filter_v4 += community_include(
10320 pi->attr->community, COMMUNITY_ROUTE_FILTER_v4);
10321 route_filter_v6 += community_include(
10322 pi->attr->community, COMMUNITY_ROUTE_FILTER_v6);
10323 llgr_stale += community_include(pi->attr->community,
10324 COMMUNITY_LLGR_STALE);
10325 no_llgr += community_include(pi->attr->community,
10326 COMMUNITY_NO_LLGR);
10327 accept_own_nexthop +=
10328 community_include(pi->attr->community,
10329 COMMUNITY_ACCEPT_OWN_NEXTHOP);
10330 blackhole += community_include(pi->attr->community,
10331 COMMUNITY_BLACKHOLE);
10332 no_peer += community_include(pi->attr->community,
10333 COMMUNITY_NO_PEER);
10334 }
10335 }
10336
10337 if (!json) {
10338 vty_out(vty, "Paths: (%d available", count);
10339 if (best) {
10340 vty_out(vty, ", best #%d", best);
10341 if (safi == SAFI_UNICAST) {
10342 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
10343 vty_out(vty, ", table %s",
10344 VRF_DEFAULT_NAME);
10345 else
10346 vty_out(vty, ", vrf %s",
10347 bgp->name);
10348 }
10349 } else
10350 vty_out(vty, ", no best path");
10351
10352 if (accept_own)
10353 vty_out(vty,
10354 ", accept own local route exported and imported in different VRF");
10355 else if (route_filter_translated_v4)
10356 vty_out(vty,
10357 ", mark translated RTs for VPNv4 route filtering");
10358 else if (route_filter_v4)
10359 vty_out(vty,
10360 ", attach RT as-is for VPNv4 route filtering");
10361 else if (route_filter_translated_v6)
10362 vty_out(vty,
10363 ", mark translated RTs for VPNv6 route filtering");
10364 else if (route_filter_v6)
10365 vty_out(vty,
10366 ", attach RT as-is for VPNv6 route filtering");
10367 else if (llgr_stale)
10368 vty_out(vty,
10369 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
10370 else if (no_llgr)
10371 vty_out(vty,
10372 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
10373 else if (accept_own_nexthop)
10374 vty_out(vty,
10375 ", accept local nexthop");
10376 else if (blackhole)
10377 vty_out(vty, ", inform peer to blackhole prefix");
10378 else if (no_export)
10379 vty_out(vty, ", not advertised to EBGP peer");
10380 else if (no_advertise)
10381 vty_out(vty, ", not advertised to any peer");
10382 else if (local_as)
10383 vty_out(vty, ", not advertised outside local AS");
10384 else if (no_peer)
10385 vty_out(vty,
10386 ", inform EBGP peer not to advertise to their EBGP peers");
10387
10388 if (suppress)
10389 vty_out(vty,
10390 ", Advertisements suppressed by an aggregate.");
10391 vty_out(vty, ")\n");
10392 }
10393
10394 /* If we are not using addpath then we can display Advertised to and
10395 * that will
10396 * show what peers we advertised the bestpath to. If we are using
10397 * addpath
10398 * though then we must display Advertised to on a path-by-path basis. */
10399 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
10400 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
10401 if (bgp_adj_out_lookup(peer, dest, 0)) {
10402 if (json && !json_adv_to)
10403 json_adv_to = json_object_new_object();
10404
10405 route_vty_out_advertised_to(
10406 vty, peer, &first,
10407 " Advertised to non peer-group peers:\n ",
10408 json_adv_to);
10409 }
10410 }
10411
10412 if (json) {
10413 if (json_adv_to) {
10414 json_object_object_add(json, "advertisedTo",
10415 json_adv_to);
10416 }
10417 } else {
10418 if (first)
10419 vty_out(vty, " Not advertised to any peer");
10420 vty_out(vty, "\n");
10421 }
10422 }
10423 }
10424
10425 static void bgp_show_path_info(struct prefix_rd *pfx_rd,
10426 struct bgp_dest *bgp_node, struct vty *vty,
10427 struct bgp *bgp, afi_t afi, safi_t safi,
10428 json_object *json, enum bgp_path_type pathtype,
10429 int *display)
10430 {
10431 struct bgp_path_info *pi;
10432 int header = 1;
10433 char rdbuf[RD_ADDRSTRLEN];
10434 json_object *json_header = NULL;
10435 json_object *json_paths = NULL;
10436
10437 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
10438
10439 if (json && !json_paths) {
10440 /* Instantiate json_paths only if path is valid */
10441 json_paths = json_object_new_array();
10442 if (pfx_rd) {
10443 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
10444 json_header = json_object_new_object();
10445 } else
10446 json_header = json;
10447 }
10448
10449 if (header) {
10450 route_vty_out_detail_header(
10451 vty, bgp, bgp_node, pfx_rd,
10452 AFI_IP, safi, json_header);
10453 header = 0;
10454 }
10455 (*display)++;
10456
10457 if (pathtype == BGP_PATH_SHOW_ALL
10458 || (pathtype == BGP_PATH_SHOW_BESTPATH
10459 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
10460 || (pathtype == BGP_PATH_SHOW_MULTIPATH
10461 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
10462 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
10463 route_vty_out_detail(vty, bgp, bgp_node,
10464 pi, AFI_IP, safi,
10465 json_paths);
10466 }
10467
10468 if (json && json_paths) {
10469 json_object_object_add(json_header, "paths", json_paths);
10470
10471 if (pfx_rd)
10472 json_object_object_add(json, rdbuf, json_header);
10473 }
10474 }
10475
10476 /* Display specified route of BGP table. */
10477 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
10478 struct bgp_table *rib, const char *ip_str,
10479 afi_t afi, safi_t safi,
10480 struct prefix_rd *prd, int prefix_check,
10481 enum bgp_path_type pathtype, bool use_json)
10482 {
10483 int ret;
10484 int display = 0;
10485 struct prefix match;
10486 struct bgp_dest *dest;
10487 struct bgp_dest *rm;
10488 struct bgp_table *table;
10489 json_object *json = NULL;
10490 json_object *json_paths = NULL;
10491
10492 /* Check IP address argument. */
10493 ret = str2prefix(ip_str, &match);
10494 if (!ret) {
10495 vty_out(vty, "address is malformed\n");
10496 return CMD_WARNING;
10497 }
10498
10499 match.family = afi2family(afi);
10500
10501 if (use_json)
10502 json = json_object_new_object();
10503
10504 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
10505 for (dest = bgp_table_top(rib); dest;
10506 dest = bgp_route_next(dest)) {
10507 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10508
10509 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
10510 continue;
10511 table = bgp_dest_get_bgp_table_info(dest);
10512 if (!table)
10513 continue;
10514
10515 if ((rm = bgp_node_match(table, &match)) == NULL)
10516 continue;
10517
10518 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
10519 if (prefix_check
10520 && rm_p->prefixlen != match.prefixlen) {
10521 bgp_dest_unlock_node(rm);
10522 continue;
10523 }
10524
10525 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
10526 bgp, afi, safi, json, pathtype,
10527 &display);
10528
10529 bgp_dest_unlock_node(rm);
10530 }
10531 } else if (safi == SAFI_EVPN) {
10532 struct bgp_dest *longest_pfx;
10533 bool is_exact_pfxlen_match = false;
10534
10535 for (dest = bgp_table_top(rib); dest;
10536 dest = bgp_route_next(dest)) {
10537 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10538
10539 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
10540 continue;
10541 table = bgp_dest_get_bgp_table_info(dest);
10542 if (!table)
10543 continue;
10544
10545 longest_pfx = NULL;
10546 is_exact_pfxlen_match = false;
10547 /*
10548 * Search through all the prefixes for a match. The
10549 * pfx's are enumerated in ascending order of pfxlens.
10550 * So, the last pfx match is the longest match. Set
10551 * is_exact_pfxlen_match when we get exact pfxlen match
10552 */
10553 for (rm = bgp_table_top(table); rm;
10554 rm = bgp_route_next(rm)) {
10555 const struct prefix *rm_p =
10556 bgp_dest_get_prefix(rm);
10557 /*
10558 * Get prefixlen of the ip-prefix within type5
10559 * evpn route
10560 */
10561 if (evpn_type5_prefix_match(rm_p, &match)
10562 && rm->info) {
10563 longest_pfx = rm;
10564 int type5_pfxlen =
10565 bgp_evpn_get_type5_prefixlen(
10566 rm_p);
10567 if (type5_pfxlen == match.prefixlen) {
10568 is_exact_pfxlen_match = true;
10569 bgp_dest_unlock_node(rm);
10570 break;
10571 }
10572 }
10573 }
10574
10575 if (!longest_pfx)
10576 continue;
10577
10578 if (prefix_check && !is_exact_pfxlen_match)
10579 continue;
10580
10581 rm = longest_pfx;
10582 bgp_dest_lock_node(rm);
10583
10584 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
10585 bgp, afi, safi, json, pathtype,
10586 &display);
10587
10588 bgp_dest_unlock_node(rm);
10589 }
10590 } else if (safi == SAFI_FLOWSPEC) {
10591 if (use_json)
10592 json_paths = json_object_new_array();
10593
10594 display = bgp_flowspec_display_match_per_ip(afi, rib,
10595 &match, prefix_check,
10596 vty,
10597 use_json,
10598 json_paths);
10599 if (use_json && display)
10600 json_object_object_add(json, "paths", json_paths);
10601 } else {
10602 if ((dest = bgp_node_match(rib, &match)) != NULL) {
10603 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10604 if (!prefix_check
10605 || dest_p->prefixlen == match.prefixlen) {
10606 bgp_show_path_info(NULL, dest, vty, bgp, afi,
10607 safi, json, pathtype,
10608 &display);
10609 }
10610
10611 bgp_dest_unlock_node(dest);
10612 }
10613 }
10614
10615 if (use_json) {
10616 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10617 json, JSON_C_TO_STRING_PRETTY |
10618 JSON_C_TO_STRING_NOSLASHESCAPE));
10619 json_object_free(json);
10620 } else {
10621 if (!display) {
10622 vty_out(vty, "%% Network not in table\n");
10623 return CMD_WARNING;
10624 }
10625 }
10626
10627 return CMD_SUCCESS;
10628 }
10629
10630 /* Display specified route of Main RIB */
10631 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
10632 afi_t afi, safi_t safi, struct prefix_rd *prd,
10633 int prefix_check, enum bgp_path_type pathtype,
10634 bool use_json)
10635 {
10636 if (!bgp) {
10637 bgp = bgp_get_default();
10638 if (!bgp) {
10639 if (!use_json)
10640 vty_out(vty, "No BGP process is configured\n");
10641 else
10642 vty_out(vty, "{}\n");
10643 return CMD_WARNING;
10644 }
10645 }
10646
10647 /* labeled-unicast routes live in the unicast table */
10648 if (safi == SAFI_LABELED_UNICAST)
10649 safi = SAFI_UNICAST;
10650
10651 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
10652 afi, safi, prd, prefix_check, pathtype,
10653 use_json);
10654 }
10655
10656 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
10657 struct cmd_token **argv, bool exact, afi_t afi,
10658 safi_t safi, bool uj)
10659 {
10660 struct lcommunity *lcom;
10661 struct buffer *b;
10662 int i;
10663 char *str;
10664 int first = 0;
10665
10666 b = buffer_new(1024);
10667 for (i = 0; i < argc; i++) {
10668 if (first)
10669 buffer_putc(b, ' ');
10670 else {
10671 if (strmatch(argv[i]->text, "AA:BB:CC")) {
10672 first = 1;
10673 buffer_putstr(b, argv[i]->arg);
10674 }
10675 }
10676 }
10677 buffer_putc(b, '\0');
10678
10679 str = buffer_getstr(b);
10680 buffer_free(b);
10681
10682 lcom = lcommunity_str2com(str);
10683 XFREE(MTYPE_TMP, str);
10684 if (!lcom) {
10685 vty_out(vty, "%% Large-community malformed\n");
10686 return CMD_WARNING;
10687 }
10688
10689 return bgp_show(vty, bgp, afi, safi,
10690 (exact ? bgp_show_type_lcommunity_exact
10691 : bgp_show_type_lcommunity),
10692 lcom, uj, false);
10693 }
10694
10695 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
10696 const char *lcom, bool exact, afi_t afi,
10697 safi_t safi, bool uj)
10698 {
10699 struct community_list *list;
10700
10701 list = community_list_lookup(bgp_clist, lcom, 0,
10702 LARGE_COMMUNITY_LIST_MASTER);
10703 if (list == NULL) {
10704 vty_out(vty, "%% %s is not a valid large-community-list name\n",
10705 lcom);
10706 return CMD_WARNING;
10707 }
10708
10709 return bgp_show(vty, bgp, afi, safi,
10710 (exact ? bgp_show_type_lcommunity_list_exact
10711 : bgp_show_type_lcommunity_list),
10712 list, uj, false);
10713 }
10714
10715 DEFUN (show_ip_bgp_large_community_list,
10716 show_ip_bgp_large_community_list_cmd,
10717 "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]",
10718 SHOW_STR
10719 IP_STR
10720 BGP_STR
10721 BGP_INSTANCE_HELP_STR
10722 BGP_AFI_HELP_STR
10723 BGP_SAFI_WITH_LABEL_HELP_STR
10724 "Display routes matching the large-community-list\n"
10725 "large-community-list number\n"
10726 "large-community-list name\n"
10727 "Exact match of the large-communities\n"
10728 JSON_STR)
10729 {
10730 afi_t afi = AFI_IP6;
10731 safi_t safi = SAFI_UNICAST;
10732 int idx = 0;
10733 bool exact_match = 0;
10734 struct bgp *bgp = NULL;
10735 bool uj = use_json(argc, argv);
10736
10737 if (uj)
10738 argc--;
10739
10740 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10741 &bgp, uj);
10742 if (!idx)
10743 return CMD_WARNING;
10744
10745 argv_find(argv, argc, "large-community-list", &idx);
10746
10747 const char *clist_number_or_name = argv[++idx]->arg;
10748
10749 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
10750 exact_match = 1;
10751
10752 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
10753 exact_match, afi, safi, uj);
10754 }
10755 DEFUN (show_ip_bgp_large_community,
10756 show_ip_bgp_large_community_cmd,
10757 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
10758 SHOW_STR
10759 IP_STR
10760 BGP_STR
10761 BGP_INSTANCE_HELP_STR
10762 BGP_AFI_HELP_STR
10763 BGP_SAFI_WITH_LABEL_HELP_STR
10764 "Display routes matching the large-communities\n"
10765 "List of large-community numbers\n"
10766 "Exact match of the large-communities\n"
10767 JSON_STR)
10768 {
10769 afi_t afi = AFI_IP6;
10770 safi_t safi = SAFI_UNICAST;
10771 int idx = 0;
10772 bool exact_match = 0;
10773 struct bgp *bgp = NULL;
10774 bool uj = use_json(argc, argv);
10775
10776 if (uj)
10777 argc--;
10778
10779 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10780 &bgp, uj);
10781 if (!idx)
10782 return CMD_WARNING;
10783
10784 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
10785 if (argv_find(argv, argc, "exact-match", &idx))
10786 exact_match = 1;
10787 return bgp_show_lcommunity(vty, bgp, argc, argv,
10788 exact_match, afi, safi, uj);
10789 } else
10790 return bgp_show(vty, bgp, afi, safi,
10791 bgp_show_type_lcommunity_all, NULL, uj, false);
10792 }
10793
10794 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
10795 safi_t safi, struct json_object *json_array);
10796 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
10797 safi_t safi, struct json_object *json);
10798
10799
10800 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
10801 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
10802 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
10803 "Display number of prefixes for all afi/safi\n" JSON_STR)
10804 {
10805 bool uj = use_json(argc, argv);
10806 struct bgp *bgp = NULL;
10807 safi_t safi = SAFI_UNICAST;
10808 afi_t afi = AFI_IP6;
10809 int idx = 0;
10810 struct json_object *json_all = NULL;
10811 struct json_object *json_afi_safi = NULL;
10812
10813 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10814 &bgp, false);
10815 if (!idx)
10816 return CMD_WARNING;
10817
10818 if (uj)
10819 json_all = json_object_new_object();
10820
10821 FOREACH_AFI_SAFI (afi, safi) {
10822 /*
10823 * So limit output to those afi/safi pairs that
10824 * actually have something interesting in them
10825 */
10826 if (strmatch(get_afi_safi_str(afi, safi, true),
10827 "Unknown")) {
10828 continue;
10829 }
10830 if (uj) {
10831 json_afi_safi = json_object_new_array();
10832 json_object_object_add(
10833 json_all,
10834 get_afi_safi_str(afi, safi, true),
10835 json_afi_safi);
10836 } else {
10837 json_afi_safi = NULL;
10838 }
10839
10840 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
10841 }
10842
10843 if (uj) {
10844 vty_out(vty, "%s",
10845 json_object_to_json_string_ext(
10846 json_all, JSON_C_TO_STRING_PRETTY));
10847 json_object_free(json_all);
10848 }
10849
10850 return CMD_SUCCESS;
10851 }
10852
10853 /* BGP route print out function without JSON */
10854 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
10855 show_ip_bgp_l2vpn_evpn_statistics_cmd,
10856 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
10857 SHOW_STR
10858 IP_STR
10859 BGP_STR
10860 BGP_INSTANCE_HELP_STR
10861 L2VPN_HELP_STR
10862 EVPN_HELP_STR
10863 "BGP RIB advertisement statistics\n"
10864 JSON_STR)
10865 {
10866 afi_t afi = AFI_IP6;
10867 safi_t safi = SAFI_UNICAST;
10868 struct bgp *bgp = NULL;
10869 int idx = 0, ret;
10870 bool uj = use_json(argc, argv);
10871 struct json_object *json_afi_safi = NULL, *json = NULL;
10872
10873 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10874 &bgp, false);
10875 if (!idx)
10876 return CMD_WARNING;
10877
10878 if (uj)
10879 json_afi_safi = json_object_new_array();
10880 else
10881 json_afi_safi = NULL;
10882
10883 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
10884
10885 if (uj) {
10886 json = json_object_new_object();
10887 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
10888 json_afi_safi);
10889 vty_out(vty, "%s", json_object_to_json_string_ext(
10890 json, JSON_C_TO_STRING_PRETTY));
10891 json_object_free(json);
10892 }
10893 return ret;
10894 }
10895
10896 /* BGP route print out function without JSON */
10897 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
10898 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
10899 " [" BGP_SAFI_WITH_LABEL_CMD_STR
10900 "]]\
10901 statistics [json]",
10902 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
10903 BGP_SAFI_WITH_LABEL_HELP_STR
10904 "BGP RIB advertisement statistics\n" JSON_STR)
10905 {
10906 afi_t afi = AFI_IP6;
10907 safi_t safi = SAFI_UNICAST;
10908 struct bgp *bgp = NULL;
10909 int idx = 0, ret;
10910 bool uj = use_json(argc, argv);
10911 struct json_object *json_afi_safi = NULL, *json = NULL;
10912
10913 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10914 &bgp, false);
10915 if (!idx)
10916 return CMD_WARNING;
10917
10918 if (uj)
10919 json_afi_safi = json_object_new_array();
10920 else
10921 json_afi_safi = NULL;
10922
10923 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
10924
10925 if (uj) {
10926 json = json_object_new_object();
10927 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
10928 json_afi_safi);
10929 vty_out(vty, "%s",
10930 json_object_to_json_string_ext(
10931 json, JSON_C_TO_STRING_PRETTY));
10932 json_object_free(json);
10933 }
10934 return ret;
10935 }
10936
10937 /* BGP route print out function without JSON */
10938 DEFUN(show_ip_bgp, show_ip_bgp_cmd,
10939 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
10940 " [" BGP_SAFI_WITH_LABEL_CMD_STR
10941 "]]\
10942 <dampening <parameters>\
10943 |route-map WORD\
10944 |prefix-list WORD\
10945 |filter-list WORD\
10946 |community-list <(1-500)|WORD> [exact-match]\
10947 |A.B.C.D/M longer-prefixes\
10948 |X:X::X:X/M longer-prefixes\
10949 >",
10950 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
10951 BGP_SAFI_WITH_LABEL_HELP_STR
10952 "Display detailed information about dampening\n"
10953 "Display detail of configured dampening parameters\n"
10954 "Display routes matching the route-map\n"
10955 "A route-map to match on\n"
10956 "Display routes conforming to the prefix-list\n"
10957 "Prefix-list name\n"
10958 "Display routes conforming to the filter-list\n"
10959 "Regular expression access list name\n"
10960 "Display routes matching the community-list\n"
10961 "community-list number\n"
10962 "community-list name\n"
10963 "Exact match of the communities\n"
10964 "IPv4 prefix\n"
10965 "Display route and more specific routes\n"
10966 "IPv6 prefix\n"
10967 "Display route and more specific routes\n")
10968 {
10969 afi_t afi = AFI_IP6;
10970 safi_t safi = SAFI_UNICAST;
10971 int exact_match = 0;
10972 struct bgp *bgp = NULL;
10973 int idx = 0;
10974
10975 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10976 &bgp, false);
10977 if (!idx)
10978 return CMD_WARNING;
10979
10980 if (argv_find(argv, argc, "dampening", &idx)) {
10981 if (argv_find(argv, argc, "parameters", &idx))
10982 return bgp_show_dampening_parameters(vty, afi, safi);
10983 }
10984
10985 if (argv_find(argv, argc, "prefix-list", &idx))
10986 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
10987 safi, bgp_show_type_prefix_list);
10988
10989 if (argv_find(argv, argc, "filter-list", &idx))
10990 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
10991 safi, bgp_show_type_filter_list);
10992
10993 if (argv_find(argv, argc, "route-map", &idx))
10994 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
10995 safi, bgp_show_type_route_map);
10996
10997 if (argv_find(argv, argc, "community-list", &idx)) {
10998 const char *clist_number_or_name = argv[++idx]->arg;
10999 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
11000 exact_match = 1;
11001 return bgp_show_community_list(vty, bgp, clist_number_or_name,
11002 exact_match, afi, safi);
11003 }
11004 /* prefix-longer */
11005 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
11006 || argv_find(argv, argc, "X:X::X:X/M", &idx))
11007 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
11008 safi,
11009 bgp_show_type_prefix_longer);
11010
11011 return CMD_WARNING;
11012 }
11013
11014 /* BGP route print out function with JSON */
11015 DEFPY (show_ip_bgp_json,
11016 show_ip_bgp_json_cmd,
11017 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
11018 [cidr-only\
11019 |dampening <flap-statistics|dampened-paths>\
11020 |community [AA:NN|local-AS|no-advertise|no-export\
11021 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
11022 |accept-own|accept-own-nexthop|route-filter-v6\
11023 |route-filter-v4|route-filter-translated-v6\
11024 |route-filter-translated-v4] [exact-match]\
11025 ] [json$uj | wide$wide]",
11026 SHOW_STR
11027 IP_STR
11028 BGP_STR
11029 BGP_INSTANCE_HELP_STR
11030 BGP_AFI_HELP_STR
11031 BGP_SAFI_WITH_LABEL_HELP_STR
11032 "Display only routes with non-natural netmasks\n"
11033 "Display detailed information about dampening\n"
11034 "Display flap statistics of routes\n"
11035 "Display paths suppressed due to dampening\n"
11036 "Display routes matching the communities\n"
11037 COMMUNITY_AANN_STR
11038 "Do not send outside local AS (well-known community)\n"
11039 "Do not advertise to any peer (well-known community)\n"
11040 "Do not export to next AS (well-known community)\n"
11041 "Graceful shutdown (well-known community)\n"
11042 "Do not export to any peer (well-known community)\n"
11043 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
11044 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
11045 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
11046 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
11047 "Should accept VPN route with local nexthop (well-known community)\n"
11048 "RT VPNv6 route filtering (well-known community)\n"
11049 "RT VPNv4 route filtering (well-known community)\n"
11050 "RT translated VPNv6 route filtering (well-known community)\n"
11051 "RT translated VPNv4 route filtering (well-known community)\n"
11052 "Exact match of the communities\n"
11053 JSON_STR
11054 "Increase table width for longer prefixes\n")
11055 {
11056 afi_t afi = AFI_IP6;
11057 safi_t safi = SAFI_UNICAST;
11058 enum bgp_show_type sh_type = bgp_show_type_normal;
11059 struct bgp *bgp = NULL;
11060 int idx = 0;
11061 int exact_match = 0;
11062
11063 if (uj)
11064 argc--;
11065
11066 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11067 &bgp, uj);
11068 if (!idx)
11069 return CMD_WARNING;
11070
11071 if (argv_find(argv, argc, "cidr-only", &idx))
11072 return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only,
11073 NULL, uj, wide);
11074
11075 if (argv_find(argv, argc, "dampening", &idx)) {
11076 if (argv_find(argv, argc, "dampened-paths", &idx))
11077 return bgp_show(vty, bgp, afi, safi,
11078 bgp_show_type_dampend_paths, NULL, uj,
11079 wide);
11080 else if (argv_find(argv, argc, "flap-statistics", &idx))
11081 return bgp_show(vty, bgp, afi, safi,
11082 bgp_show_type_flap_statistics, NULL, uj,
11083 wide);
11084 }
11085
11086 if (argv_find(argv, argc, "community", &idx)) {
11087 char *maybecomm = NULL;
11088 char *community = NULL;
11089
11090 if (idx + 1 < argc) {
11091 if (argv[idx + 1]->type == VARIABLE_TKN)
11092 maybecomm = argv[idx + 1]->arg;
11093 else
11094 maybecomm = argv[idx + 1]->text;
11095 }
11096
11097 if (maybecomm && !strmatch(maybecomm, "json")
11098 && !strmatch(maybecomm, "exact-match"))
11099 community = maybecomm;
11100
11101 if (argv_find(argv, argc, "exact-match", &idx))
11102 exact_match = 1;
11103
11104 if (community)
11105 return bgp_show_community(vty, bgp, community,
11106 exact_match, afi, safi, uj);
11107 else
11108 return (bgp_show(vty, bgp, afi, safi,
11109 bgp_show_type_community_all, NULL, uj,
11110 wide));
11111 }
11112
11113 return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj, wide);
11114 }
11115
11116 DEFUN (show_ip_bgp_route,
11117 show_ip_bgp_route_cmd,
11118 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
11119 SHOW_STR
11120 IP_STR
11121 BGP_STR
11122 BGP_INSTANCE_HELP_STR
11123 BGP_AFI_HELP_STR
11124 BGP_SAFI_WITH_LABEL_HELP_STR
11125 "Network in the BGP routing table to display\n"
11126 "IPv4 prefix\n"
11127 "Network in the BGP routing table to display\n"
11128 "IPv6 prefix\n"
11129 "Display only the bestpath\n"
11130 "Display only multipaths\n"
11131 JSON_STR)
11132 {
11133 int prefix_check = 0;
11134
11135 afi_t afi = AFI_IP6;
11136 safi_t safi = SAFI_UNICAST;
11137 char *prefix = NULL;
11138 struct bgp *bgp = NULL;
11139 enum bgp_path_type path_type;
11140 bool uj = use_json(argc, argv);
11141
11142 int idx = 0;
11143
11144 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11145 &bgp, uj);
11146 if (!idx)
11147 return CMD_WARNING;
11148
11149 if (!bgp) {
11150 vty_out(vty,
11151 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
11152 return CMD_WARNING;
11153 }
11154
11155 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
11156 if (argv_find(argv, argc, "A.B.C.D", &idx)
11157 || argv_find(argv, argc, "X:X::X:X", &idx))
11158 prefix_check = 0;
11159 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
11160 || argv_find(argv, argc, "X:X::X:X/M", &idx))
11161 prefix_check = 1;
11162
11163 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
11164 && afi != AFI_IP6) {
11165 vty_out(vty,
11166 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
11167 return CMD_WARNING;
11168 }
11169 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
11170 && afi != AFI_IP) {
11171 vty_out(vty,
11172 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
11173 return CMD_WARNING;
11174 }
11175
11176 prefix = argv[idx]->arg;
11177
11178 /* [<bestpath|multipath>] */
11179 if (argv_find(argv, argc, "bestpath", &idx))
11180 path_type = BGP_PATH_SHOW_BESTPATH;
11181 else if (argv_find(argv, argc, "multipath", &idx))
11182 path_type = BGP_PATH_SHOW_MULTIPATH;
11183 else
11184 path_type = BGP_PATH_SHOW_ALL;
11185
11186 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
11187 path_type, uj);
11188 }
11189
11190 DEFUN (show_ip_bgp_regexp,
11191 show_ip_bgp_regexp_cmd,
11192 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
11193 SHOW_STR
11194 IP_STR
11195 BGP_STR
11196 BGP_INSTANCE_HELP_STR
11197 BGP_AFI_HELP_STR
11198 BGP_SAFI_WITH_LABEL_HELP_STR
11199 "Display routes matching the AS path regular expression\n"
11200 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
11201 JSON_STR)
11202 {
11203 afi_t afi = AFI_IP6;
11204 safi_t safi = SAFI_UNICAST;
11205 struct bgp *bgp = NULL;
11206 bool uj = use_json(argc, argv);
11207 char *regstr = NULL;
11208
11209 int idx = 0;
11210 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11211 &bgp, false);
11212 if (!idx)
11213 return CMD_WARNING;
11214
11215 // get index of regex
11216 if (argv_find(argv, argc, "REGEX", &idx))
11217 regstr = argv[idx]->arg;
11218
11219 assert(regstr);
11220 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
11221 bgp_show_type_regexp, uj);
11222 }
11223
11224 DEFPY (show_ip_bgp_instance_all,
11225 show_ip_bgp_instance_all_cmd,
11226 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
11227 SHOW_STR
11228 IP_STR
11229 BGP_STR
11230 BGP_INSTANCE_ALL_HELP_STR
11231 BGP_AFI_HELP_STR
11232 BGP_SAFI_WITH_LABEL_HELP_STR
11233 JSON_STR
11234 "Increase table width for longer prefixes\n")
11235 {
11236 afi_t afi = AFI_IP;
11237 safi_t safi = SAFI_UNICAST;
11238 struct bgp *bgp = NULL;
11239 int idx = 0;
11240
11241 if (uj)
11242 argc--;
11243
11244 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11245 &bgp, uj);
11246 if (!idx)
11247 return CMD_WARNING;
11248
11249 bgp_show_all_instances_routes_vty(vty, afi, safi, uj, wide);
11250 return CMD_SUCCESS;
11251 }
11252
11253 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11254 afi_t afi, safi_t safi, enum bgp_show_type type,
11255 bool use_json)
11256 {
11257 regex_t *regex;
11258 int rc;
11259
11260 if (!config_bgp_aspath_validate(regstr)) {
11261 vty_out(vty, "Invalid character in REGEX %s\n",
11262 regstr);
11263 return CMD_WARNING_CONFIG_FAILED;
11264 }
11265
11266 regex = bgp_regcomp(regstr);
11267 if (!regex) {
11268 vty_out(vty, "Can't compile regexp %s\n", regstr);
11269 return CMD_WARNING;
11270 }
11271
11272 rc = bgp_show(vty, bgp, afi, safi, type, regex, use_json, false);
11273 bgp_regex_free(regex);
11274 return rc;
11275 }
11276
11277 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
11278 const char *prefix_list_str, afi_t afi,
11279 safi_t safi, enum bgp_show_type type)
11280 {
11281 struct prefix_list *plist;
11282
11283 plist = prefix_list_lookup(afi, prefix_list_str);
11284 if (plist == NULL) {
11285 vty_out(vty, "%% %s is not a valid prefix-list name\n",
11286 prefix_list_str);
11287 return CMD_WARNING;
11288 }
11289
11290 return bgp_show(vty, bgp, afi, safi, type, plist, 0, false);
11291 }
11292
11293 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
11294 const char *filter, afi_t afi, safi_t safi,
11295 enum bgp_show_type type)
11296 {
11297 struct as_list *as_list;
11298
11299 as_list = as_list_lookup(filter);
11300 if (as_list == NULL) {
11301 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
11302 filter);
11303 return CMD_WARNING;
11304 }
11305
11306 return bgp_show(vty, bgp, afi, safi, type, as_list, 0, false);
11307 }
11308
11309 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
11310 const char *rmap_str, afi_t afi, safi_t safi,
11311 enum bgp_show_type type)
11312 {
11313 struct route_map *rmap;
11314
11315 rmap = route_map_lookup_by_name(rmap_str);
11316 if (!rmap) {
11317 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
11318 return CMD_WARNING;
11319 }
11320
11321 return bgp_show(vty, bgp, afi, safi, type, rmap, 0, false);
11322 }
11323
11324 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11325 const char *comstr, int exact, afi_t afi,
11326 safi_t safi, bool use_json)
11327 {
11328 struct community *com;
11329 int ret = 0;
11330
11331 com = community_str2com(comstr);
11332 if (!com) {
11333 vty_out(vty, "%% Community malformed: %s\n", comstr);
11334 return CMD_WARNING;
11335 }
11336
11337 ret = bgp_show(vty, bgp, afi, safi,
11338 (exact ? bgp_show_type_community_exact
11339 : bgp_show_type_community),
11340 com, use_json, false);
11341 community_free(&com);
11342
11343 return ret;
11344 }
11345
11346 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
11347 const char *com, int exact, afi_t afi,
11348 safi_t safi)
11349 {
11350 struct community_list *list;
11351
11352 list = community_list_lookup(bgp_clist, com, 0, COMMUNITY_LIST_MASTER);
11353 if (list == NULL) {
11354 vty_out(vty, "%% %s is not a valid community-list name\n", com);
11355 return CMD_WARNING;
11356 }
11357
11358 return bgp_show(vty, bgp, afi, safi,
11359 (exact ? bgp_show_type_community_list_exact
11360 : bgp_show_type_community_list),
11361 list, 0, false);
11362 }
11363
11364 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
11365 const char *prefix, afi_t afi, safi_t safi,
11366 enum bgp_show_type type)
11367 {
11368 int ret;
11369 struct prefix *p;
11370
11371 p = prefix_new();
11372
11373 ret = str2prefix(prefix, p);
11374 if (!ret) {
11375 vty_out(vty, "%% Malformed Prefix\n");
11376 return CMD_WARNING;
11377 }
11378
11379 ret = bgp_show(vty, bgp, afi, safi, type, p, 0, false);
11380 prefix_free(&p);
11381 return ret;
11382 }
11383
11384 enum bgp_stats {
11385 BGP_STATS_MAXBITLEN = 0,
11386 BGP_STATS_RIB,
11387 BGP_STATS_PREFIXES,
11388 BGP_STATS_TOTPLEN,
11389 BGP_STATS_UNAGGREGATEABLE,
11390 BGP_STATS_MAX_AGGREGATEABLE,
11391 BGP_STATS_AGGREGATES,
11392 BGP_STATS_SPACE,
11393 BGP_STATS_ASPATH_COUNT,
11394 BGP_STATS_ASPATH_MAXHOPS,
11395 BGP_STATS_ASPATH_TOTHOPS,
11396 BGP_STATS_ASPATH_MAXSIZE,
11397 BGP_STATS_ASPATH_TOTSIZE,
11398 BGP_STATS_ASN_HIGHEST,
11399 BGP_STATS_MAX,
11400 };
11401
11402 #define TABLE_STATS_IDX_VTY 0
11403 #define TABLE_STATS_IDX_JSON 1
11404
11405 static const char *table_stats_strs[][2] = {
11406 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
11407 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
11408 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
11409 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
11410 "unaggregateablePrefixes"},
11411 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
11412 "maximumAggregateablePrefixes"},
11413 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
11414 "bgpAggregateAdvertisements"},
11415 [BGP_STATS_SPACE] = {"Address space advertised",
11416 "addressSpaceAdvertised"},
11417 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
11418 "advertisementsWithPaths"},
11419 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
11420 "longestAsPath"},
11421 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
11422 "largestAsPath"},
11423 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
11424 "averageAsPathLengthHops"},
11425 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
11426 "averageAsPathSizeBytes"},
11427 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
11428 [BGP_STATS_MAX] = {NULL, NULL}
11429 };
11430
11431 struct bgp_table_stats {
11432 struct bgp_table *table;
11433 unsigned long long counts[BGP_STATS_MAX];
11434 double total_space;
11435 };
11436
11437 #if 0
11438 #define TALLY_SIGFIG 100000
11439 static unsigned long
11440 ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
11441 {
11442 unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
11443 unsigned long res = (newtot * TALLY_SIGFIG) / count;
11444 unsigned long ret = newtot / count;
11445
11446 if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
11447 return ret + 1;
11448 else
11449 return ret;
11450 }
11451 #endif
11452
11453 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
11454 struct bgp_table_stats *ts, unsigned int space)
11455 {
11456 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
11457 struct bgp_path_info *pi;
11458 const struct prefix *rn_p;
11459
11460 if (dest == top)
11461 return;
11462
11463 if (!bgp_dest_has_bgp_path_info_data(dest))
11464 return;
11465
11466 rn_p = bgp_dest_get_prefix(dest);
11467 ts->counts[BGP_STATS_PREFIXES]++;
11468 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
11469
11470 #if 0
11471 ts->counts[BGP_STATS_AVGPLEN]
11472 = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
11473 ts->counts[BGP_STATS_AVGPLEN],
11474 rn_p->prefixlen);
11475 #endif
11476
11477 /* check if the prefix is included by any other announcements */
11478 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
11479 pdest = bgp_dest_parent_nolock(pdest);
11480
11481 if (pdest == NULL || pdest == top) {
11482 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
11483 /* announced address space */
11484 if (space)
11485 ts->total_space += pow(2.0, space - rn_p->prefixlen);
11486 } else if (bgp_dest_has_bgp_path_info_data(pdest))
11487 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
11488
11489
11490 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11491 ts->counts[BGP_STATS_RIB]++;
11492
11493 if (CHECK_FLAG(pi->attr->flag,
11494 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
11495 ts->counts[BGP_STATS_AGGREGATES]++;
11496
11497 /* as-path stats */
11498 if (pi->attr->aspath) {
11499 unsigned int hops = aspath_count_hops(pi->attr->aspath);
11500 unsigned int size = aspath_size(pi->attr->aspath);
11501 as_t highest = aspath_highest(pi->attr->aspath);
11502
11503 ts->counts[BGP_STATS_ASPATH_COUNT]++;
11504
11505 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
11506 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
11507
11508 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
11509 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
11510
11511 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
11512 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
11513 #if 0
11514 ts->counts[BGP_STATS_ASPATH_AVGHOPS]
11515 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
11516 ts->counts[BGP_STATS_ASPATH_AVGHOPS],
11517 hops);
11518 ts->counts[BGP_STATS_ASPATH_AVGSIZE]
11519 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
11520 ts->counts[BGP_STATS_ASPATH_AVGSIZE],
11521 size);
11522 #endif
11523 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
11524 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
11525 }
11526 }
11527 }
11528
11529 static int bgp_table_stats_walker(struct thread *t)
11530 {
11531 struct bgp_dest *dest, *ndest;
11532 struct bgp_dest *top;
11533 struct bgp_table_stats *ts = THREAD_ARG(t);
11534 unsigned int space = 0;
11535
11536 if (!(top = bgp_table_top(ts->table)))
11537 return 0;
11538
11539 switch (ts->table->afi) {
11540 case AFI_IP:
11541 space = IPV4_MAX_BITLEN;
11542 break;
11543 case AFI_IP6:
11544 space = IPV6_MAX_BITLEN;
11545 break;
11546 default:
11547 return 0;
11548 }
11549
11550 ts->counts[BGP_STATS_MAXBITLEN] = space;
11551
11552 for (dest = top; dest; dest = bgp_route_next(dest)) {
11553 if (ts->table->safi == SAFI_MPLS_VPN
11554 || ts->table->safi == SAFI_ENCAP
11555 || ts->table->safi == SAFI_EVPN) {
11556 struct bgp_table *table;
11557
11558 table = bgp_dest_get_bgp_table_info(dest);
11559 if (!table)
11560 continue;
11561
11562 top = bgp_table_top(table);
11563 for (ndest = bgp_table_top(table); ndest;
11564 ndest = bgp_route_next(ndest))
11565 bgp_table_stats_rn(ndest, top, ts, space);
11566 } else {
11567 bgp_table_stats_rn(dest, top, ts, space);
11568 }
11569 }
11570
11571 return 0;
11572 }
11573
11574 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
11575 struct json_object *json_array)
11576 {
11577 struct listnode *node, *nnode;
11578 struct bgp *bgp;
11579
11580 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
11581 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
11582 }
11583
11584 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
11585 safi_t safi, struct json_object *json_array)
11586 {
11587 struct bgp_table_stats ts;
11588 unsigned int i;
11589 int ret = CMD_SUCCESS;
11590 char temp_buf[20];
11591 struct json_object *json = NULL;
11592
11593 if (json_array)
11594 json = json_object_new_object();
11595
11596 if (!bgp->rib[afi][safi]) {
11597 char warning_msg[50];
11598
11599 snprintf(warning_msg, sizeof(warning_msg),
11600 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
11601 safi);
11602
11603 if (!json)
11604 vty_out(vty, "%s\n", warning_msg);
11605 else
11606 json_object_string_add(json, "warning", warning_msg);
11607
11608 ret = CMD_WARNING;
11609 goto end_table_stats;
11610 }
11611
11612 if (!json)
11613 vty_out(vty, "BGP %s RIB statistics (%s)\n",
11614 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
11615 else
11616 json_object_string_add(json, "instance", bgp->name_pretty);
11617
11618 /* labeled-unicast routes live in the unicast table */
11619 if (safi == SAFI_LABELED_UNICAST)
11620 safi = SAFI_UNICAST;
11621
11622 memset(&ts, 0, sizeof(ts));
11623 ts.table = bgp->rib[afi][safi];
11624 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
11625
11626 for (i = 0; i < BGP_STATS_MAX; i++) {
11627 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
11628 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
11629 continue;
11630
11631 switch (i) {
11632 #if 0
11633 case BGP_STATS_ASPATH_AVGHOPS:
11634 case BGP_STATS_ASPATH_AVGSIZE:
11635 case BGP_STATS_AVGPLEN:
11636 vty_out (vty, "%-30s: ", table_stats_strs[i]);
11637 vty_out (vty, "%12.2f",
11638 (float)ts.counts[i] / (float)TALLY_SIGFIG);
11639 break;
11640 #endif
11641 case BGP_STATS_ASPATH_TOTHOPS:
11642 case BGP_STATS_ASPATH_TOTSIZE:
11643 if (!json) {
11644 snprintf(
11645 temp_buf, sizeof(temp_buf), "%12.2f",
11646 ts.counts[i]
11647 ? (float)ts.counts[i]
11648 / (float)ts.counts
11649 [BGP_STATS_ASPATH_COUNT]
11650 : 0);
11651 vty_out(vty, "%-30s: %s",
11652 table_stats_strs[i]
11653 [TABLE_STATS_IDX_VTY],
11654 temp_buf);
11655 } else {
11656 json_object_double_add(
11657 json,
11658 table_stats_strs[i]
11659 [TABLE_STATS_IDX_JSON],
11660 ts.counts[i]
11661 ? (double)ts.counts[i]
11662 / (double)ts.counts
11663 [BGP_STATS_ASPATH_COUNT]
11664 : 0);
11665 }
11666 break;
11667 case BGP_STATS_TOTPLEN:
11668 if (!json) {
11669 snprintf(
11670 temp_buf, sizeof(temp_buf), "%12.2f",
11671 ts.counts[i]
11672 ? (float)ts.counts[i]
11673 / (float)ts.counts
11674 [BGP_STATS_PREFIXES]
11675 : 0);
11676 vty_out(vty, "%-30s: %s",
11677 table_stats_strs[i]
11678 [TABLE_STATS_IDX_VTY],
11679 temp_buf);
11680 } else {
11681 json_object_double_add(
11682 json,
11683 table_stats_strs[i]
11684 [TABLE_STATS_IDX_JSON],
11685 ts.counts[i]
11686 ? (double)ts.counts[i]
11687 / (double)ts.counts
11688 [BGP_STATS_PREFIXES]
11689 : 0);
11690 }
11691 break;
11692 case BGP_STATS_SPACE:
11693 if (!json) {
11694 snprintf(temp_buf, sizeof(temp_buf), "%12g",
11695 ts.total_space);
11696 vty_out(vty, "%-30s: %s\n",
11697 table_stats_strs[i]
11698 [TABLE_STATS_IDX_VTY],
11699 temp_buf);
11700 } else {
11701 json_object_double_add(
11702 json,
11703 table_stats_strs[i]
11704 [TABLE_STATS_IDX_JSON],
11705 (double)ts.total_space);
11706 }
11707 if (afi == AFI_IP6) {
11708 if (!json) {
11709 snprintf(temp_buf, sizeof(temp_buf),
11710 "%12g",
11711 ts.total_space
11712 * pow(2.0, -128 + 32));
11713 vty_out(vty, "%30s: %s\n",
11714 "/32 equivalent %s\n",
11715 temp_buf);
11716 } else {
11717 json_object_double_add(
11718 json, "/32equivalent",
11719 (double)(ts.total_space
11720 * pow(2.0,
11721 -128 + 32)));
11722 }
11723 if (!json) {
11724 snprintf(temp_buf, sizeof(temp_buf),
11725 "%12g",
11726 ts.total_space
11727 * pow(2.0, -128 + 48));
11728 vty_out(vty, "%30s: %s\n",
11729 "/48 equivalent %s\n",
11730 temp_buf);
11731 } else {
11732 json_object_double_add(
11733 json, "/48equivalent",
11734 (double)(ts.total_space
11735 * pow(2.0,
11736 -128 + 48)));
11737 }
11738 } else {
11739 if (!json) {
11740 snprintf(temp_buf, sizeof(temp_buf),
11741 "%12.2f",
11742 ts.total_space * 100.
11743 * pow(2.0, -32));
11744 vty_out(vty, "%30s: %s\n",
11745 "% announced ", temp_buf);
11746 } else {
11747 json_object_double_add(
11748 json, "%announced",
11749 (double)(ts.total_space * 100.
11750 * pow(2.0, -32)));
11751 }
11752 if (!json) {
11753 snprintf(temp_buf, sizeof(temp_buf),
11754 "%12.2f",
11755 ts.total_space
11756 * pow(2.0, -32 + 8));
11757 vty_out(vty, "%30s: %s\n",
11758 "/8 equivalent ", temp_buf);
11759 } else {
11760 json_object_double_add(
11761 json, "/8equivalent",
11762 (double)(ts.total_space
11763 * pow(2.0, -32 + 8)));
11764 }
11765 if (!json) {
11766 snprintf(temp_buf, sizeof(temp_buf),
11767 "%12.2f",
11768 ts.total_space
11769 * pow(2.0, -32 + 24));
11770 vty_out(vty, "%30s: %s\n",
11771 "/24 equivalent ", temp_buf);
11772 } else {
11773 json_object_double_add(
11774 json, "/24equivalent",
11775 (double)(ts.total_space
11776 * pow(2.0, -32 + 24)));
11777 }
11778 }
11779 break;
11780 default:
11781 if (!json) {
11782 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
11783 ts.counts[i]);
11784 vty_out(vty, "%-30s: %s",
11785 table_stats_strs[i]
11786 [TABLE_STATS_IDX_VTY],
11787 temp_buf);
11788 } else {
11789 json_object_int_add(
11790 json,
11791 table_stats_strs[i]
11792 [TABLE_STATS_IDX_JSON],
11793 ts.counts[i]);
11794 }
11795 }
11796 if (!json)
11797 vty_out(vty, "\n");
11798 }
11799 end_table_stats:
11800 if (json)
11801 json_object_array_add(json_array, json);
11802 return ret;
11803 }
11804
11805 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
11806 safi_t safi, struct json_object *json_array)
11807 {
11808 if (!bgp) {
11809 bgp_table_stats_all(vty, afi, safi, json_array);
11810 return CMD_SUCCESS;
11811 }
11812
11813 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
11814 }
11815
11816 enum bgp_pcounts {
11817 PCOUNT_ADJ_IN = 0,
11818 PCOUNT_DAMPED,
11819 PCOUNT_REMOVED,
11820 PCOUNT_HISTORY,
11821 PCOUNT_STALE,
11822 PCOUNT_VALID,
11823 PCOUNT_ALL,
11824 PCOUNT_COUNTED,
11825 PCOUNT_BPATH_SELECTED,
11826 PCOUNT_PFCNT, /* the figure we display to users */
11827 PCOUNT_MAX,
11828 };
11829
11830 static const char *const pcount_strs[] = {
11831 [PCOUNT_ADJ_IN] = "Adj-in",
11832 [PCOUNT_DAMPED] = "Damped",
11833 [PCOUNT_REMOVED] = "Removed",
11834 [PCOUNT_HISTORY] = "History",
11835 [PCOUNT_STALE] = "Stale",
11836 [PCOUNT_VALID] = "Valid",
11837 [PCOUNT_ALL] = "All RIB",
11838 [PCOUNT_COUNTED] = "PfxCt counted",
11839 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
11840 [PCOUNT_PFCNT] = "Useable",
11841 [PCOUNT_MAX] = NULL,
11842 };
11843
11844 struct peer_pcounts {
11845 unsigned int count[PCOUNT_MAX];
11846 const struct peer *peer;
11847 const struct bgp_table *table;
11848 safi_t safi;
11849 };
11850
11851 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
11852 {
11853 const struct bgp_adj_in *ain;
11854 const struct bgp_path_info *pi;
11855 const struct peer *peer = pc->peer;
11856
11857 for (ain = rn->adj_in; ain; ain = ain->next)
11858 if (ain->peer == peer)
11859 pc->count[PCOUNT_ADJ_IN]++;
11860
11861 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
11862
11863 if (pi->peer != peer)
11864 continue;
11865
11866 pc->count[PCOUNT_ALL]++;
11867
11868 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
11869 pc->count[PCOUNT_DAMPED]++;
11870 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11871 pc->count[PCOUNT_HISTORY]++;
11872 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
11873 pc->count[PCOUNT_REMOVED]++;
11874 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
11875 pc->count[PCOUNT_STALE]++;
11876 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
11877 pc->count[PCOUNT_VALID]++;
11878 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
11879 pc->count[PCOUNT_PFCNT]++;
11880 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
11881 pc->count[PCOUNT_BPATH_SELECTED]++;
11882
11883 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
11884 pc->count[PCOUNT_COUNTED]++;
11885 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
11886 flog_err(
11887 EC_LIB_DEVELOPMENT,
11888 "Attempting to count but flags say it is unusable");
11889 } else {
11890 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
11891 flog_err(
11892 EC_LIB_DEVELOPMENT,
11893 "Not counted but flags say we should");
11894 }
11895 }
11896 }
11897
11898 static int bgp_peer_count_walker(struct thread *t)
11899 {
11900 struct bgp_dest *rn, *rm;
11901 const struct bgp_table *table;
11902 struct peer_pcounts *pc = THREAD_ARG(t);
11903
11904 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
11905 || pc->safi == SAFI_EVPN) {
11906 /* Special handling for 2-level routing tables. */
11907 for (rn = bgp_table_top(pc->table); rn;
11908 rn = bgp_route_next(rn)) {
11909 table = bgp_dest_get_bgp_table_info(rn);
11910 if (table != NULL)
11911 for (rm = bgp_table_top(table); rm;
11912 rm = bgp_route_next(rm))
11913 bgp_peer_count_proc(rm, pc);
11914 }
11915 } else
11916 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
11917 bgp_peer_count_proc(rn, pc);
11918
11919 return 0;
11920 }
11921
11922 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
11923 safi_t safi, bool use_json)
11924 {
11925 struct peer_pcounts pcounts = {.peer = peer};
11926 unsigned int i;
11927 json_object *json = NULL;
11928 json_object *json_loop = NULL;
11929
11930 if (use_json) {
11931 json = json_object_new_object();
11932 json_loop = json_object_new_object();
11933 }
11934
11935 if (!peer || !peer->bgp || !peer->afc[afi][safi]
11936 || !peer->bgp->rib[afi][safi]) {
11937 if (use_json) {
11938 json_object_string_add(
11939 json, "warning",
11940 "No such neighbor or address family");
11941 vty_out(vty, "%s\n", json_object_to_json_string(json));
11942 json_object_free(json);
11943 } else
11944 vty_out(vty, "%% No such neighbor or address family\n");
11945
11946 return CMD_WARNING;
11947 }
11948
11949 memset(&pcounts, 0, sizeof(pcounts));
11950 pcounts.peer = peer;
11951 pcounts.table = peer->bgp->rib[afi][safi];
11952 pcounts.safi = safi;
11953
11954 /* in-place call via thread subsystem so as to record execution time
11955 * stats for the thread-walk (i.e. ensure this can't be blamed on
11956 * on just vty_read()).
11957 */
11958 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
11959
11960 if (use_json) {
11961 json_object_string_add(json, "prefixCountsFor", peer->host);
11962 json_object_string_add(json, "multiProtocol",
11963 get_afi_safi_str(afi, safi, true));
11964 json_object_int_add(json, "pfxCounter",
11965 peer->pcount[afi][safi]);
11966
11967 for (i = 0; i < PCOUNT_MAX; i++)
11968 json_object_int_add(json_loop, pcount_strs[i],
11969 pcounts.count[i]);
11970
11971 json_object_object_add(json, "ribTableWalkCounters", json_loop);
11972
11973 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
11974 json_object_string_add(json, "pfxctDriftFor",
11975 peer->host);
11976 json_object_string_add(
11977 json, "recommended",
11978 "Please report this bug, with the above command output");
11979 }
11980 vty_out(vty, "%s\n", json_object_to_json_string_ext(
11981 json, JSON_C_TO_STRING_PRETTY));
11982 json_object_free(json);
11983 } else {
11984
11985 if (peer->hostname
11986 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
11987 vty_out(vty, "Prefix counts for %s/%s, %s\n",
11988 peer->hostname, peer->host,
11989 get_afi_safi_str(afi, safi, false));
11990 } else {
11991 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
11992 get_afi_safi_str(afi, safi, false));
11993 }
11994
11995 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
11996 vty_out(vty, "\nCounts from RIB table walk:\n\n");
11997
11998 for (i = 0; i < PCOUNT_MAX; i++)
11999 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
12000 pcounts.count[i]);
12001
12002 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
12003 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
12004 vty_out(vty,
12005 "Please report this bug, with the above command output\n");
12006 }
12007 }
12008
12009 return CMD_SUCCESS;
12010 }
12011
12012 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
12013 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
12014 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
12015 SHOW_STR
12016 IP_STR
12017 BGP_STR
12018 BGP_INSTANCE_HELP_STR
12019 BGP_AFI_HELP_STR
12020 BGP_SAFI_HELP_STR
12021 "Detailed information on TCP and BGP neighbor connections\n"
12022 "Neighbor to display information about\n"
12023 "Neighbor to display information about\n"
12024 "Neighbor on BGP configured interface\n"
12025 "Display detailed prefix count information\n"
12026 JSON_STR)
12027 {
12028 afi_t afi = AFI_IP6;
12029 safi_t safi = SAFI_UNICAST;
12030 struct peer *peer;
12031 int idx = 0;
12032 struct bgp *bgp = NULL;
12033 bool uj = use_json(argc, argv);
12034
12035 if (uj)
12036 argc--;
12037
12038 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12039 &bgp, uj);
12040 if (!idx)
12041 return CMD_WARNING;
12042
12043 argv_find(argv, argc, "neighbors", &idx);
12044 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
12045 if (!peer)
12046 return CMD_WARNING;
12047
12048 return bgp_peer_counts(vty, peer, afi, safi, uj);
12049 }
12050
12051 #ifdef KEEP_OLD_VPN_COMMANDS
12052 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
12053 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
12054 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
12055 SHOW_STR
12056 IP_STR
12057 BGP_STR
12058 BGP_VPNVX_HELP_STR
12059 "Display information about all VPNv4 NLRIs\n"
12060 "Detailed information on TCP and BGP neighbor connections\n"
12061 "Neighbor to display information about\n"
12062 "Neighbor to display information about\n"
12063 "Neighbor on BGP configured interface\n"
12064 "Display detailed prefix count information\n"
12065 JSON_STR)
12066 {
12067 int idx_peer = 6;
12068 struct peer *peer;
12069 bool uj = use_json(argc, argv);
12070
12071 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
12072 if (!peer)
12073 return CMD_WARNING;
12074
12075 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
12076 }
12077
12078 DEFUN (show_ip_bgp_vpn_all_route_prefix,
12079 show_ip_bgp_vpn_all_route_prefix_cmd,
12080 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
12081 SHOW_STR
12082 IP_STR
12083 BGP_STR
12084 BGP_VPNVX_HELP_STR
12085 "Display information about all VPNv4 NLRIs\n"
12086 "Network in the BGP routing table to display\n"
12087 "Network in the BGP routing table to display\n"
12088 JSON_STR)
12089 {
12090 int idx = 0;
12091 char *network = NULL;
12092 struct bgp *bgp = bgp_get_default();
12093 if (!bgp) {
12094 vty_out(vty, "Can't find default instance\n");
12095 return CMD_WARNING;
12096 }
12097
12098 if (argv_find(argv, argc, "A.B.C.D", &idx))
12099 network = argv[idx]->arg;
12100 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
12101 network = argv[idx]->arg;
12102 else {
12103 vty_out(vty, "Unable to figure out Network\n");
12104 return CMD_WARNING;
12105 }
12106
12107 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
12108 BGP_PATH_SHOW_ALL, use_json(argc, argv));
12109 }
12110 #endif /* KEEP_OLD_VPN_COMMANDS */
12111
12112 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
12113 show_bgp_l2vpn_evpn_route_prefix_cmd,
12114 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
12115 SHOW_STR
12116 BGP_STR
12117 L2VPN_HELP_STR
12118 EVPN_HELP_STR
12119 "Network in the BGP routing table to display\n"
12120 "Network in the BGP routing table to display\n"
12121 "Network in the BGP routing table to display\n"
12122 "Network in the BGP routing table to display\n"
12123 JSON_STR)
12124 {
12125 int idx = 0;
12126 char *network = NULL;
12127 int prefix_check = 0;
12128
12129 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
12130 argv_find(argv, argc, "X:X::X:X", &idx))
12131 network = argv[idx]->arg;
12132 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
12133 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12134 network = argv[idx]->arg;
12135 prefix_check = 1;
12136 } else {
12137 vty_out(vty, "Unable to figure out Network\n");
12138 return CMD_WARNING;
12139 }
12140 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
12141 prefix_check, BGP_PATH_SHOW_ALL,
12142 use_json(argc, argv));
12143 }
12144
12145 static void show_adj_route_header(struct vty *vty, struct bgp *bgp,
12146 struct bgp_table *table, int *header1,
12147 int *header2, json_object *json,
12148 json_object *json_scode,
12149 json_object *json_ocode, bool wide)
12150 {
12151 uint64_t version = table ? table->version : 0;
12152
12153 if (*header1) {
12154 if (json) {
12155 json_object_int_add(json, "bgpTableVersion", version);
12156 json_object_string_add(json, "bgpLocalRouterId",
12157 inet_ntoa(bgp->router_id));
12158 json_object_int_add(json, "defaultLocPrf",
12159 bgp->default_local_pref);
12160 json_object_int_add(json, "localAS", bgp->as);
12161 json_object_object_add(json, "bgpStatusCodes",
12162 json_scode);
12163 json_object_object_add(json, "bgpOriginCodes",
12164 json_ocode);
12165 } else {
12166 vty_out(vty,
12167 "BGP table version is %" PRIu64 ", local router ID is %s, vrf id ",
12168 version, inet_ntoa(bgp->router_id));
12169 if (bgp->vrf_id == VRF_UNKNOWN)
12170 vty_out(vty, "%s", VRFID_NONE_STR);
12171 else
12172 vty_out(vty, "%u", bgp->vrf_id);
12173 vty_out(vty, "\n");
12174 vty_out(vty, "Default local pref %u, ",
12175 bgp->default_local_pref);
12176 vty_out(vty, "local AS %u\n", bgp->as);
12177 vty_out(vty, BGP_SHOW_SCODE_HEADER);
12178 vty_out(vty, BGP_SHOW_NCODE_HEADER);
12179 vty_out(vty, BGP_SHOW_OCODE_HEADER);
12180 }
12181 *header1 = 0;
12182 }
12183 if (*header2) {
12184 if (!json)
12185 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
12186 : BGP_SHOW_HEADER));
12187 *header2 = 0;
12188 }
12189 }
12190
12191 static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
12192 safi_t safi, enum bgp_show_adj_route_type type,
12193 const char *rmap_name, bool use_json,
12194 json_object *json, bool wide)
12195 {
12196 struct bgp_table *table;
12197 struct bgp_adj_in *ain;
12198 struct bgp_adj_out *adj;
12199 unsigned long output_count = 0;
12200 unsigned long filtered_count = 0;
12201 struct bgp_dest *dest;
12202 int header1 = 1;
12203 struct bgp *bgp;
12204 int header2 = 1;
12205 struct attr attr;
12206 int ret;
12207 struct update_subgroup *subgrp;
12208 json_object *json_scode = NULL;
12209 json_object *json_ocode = NULL;
12210 json_object *json_ar = NULL;
12211 struct peer_af *paf;
12212 bool route_filtered;
12213
12214 if (use_json) {
12215 json_scode = json_object_new_object();
12216 json_ocode = json_object_new_object();
12217 json_ar = json_object_new_object();
12218
12219 json_object_string_add(json_scode, "suppressed", "s");
12220 json_object_string_add(json_scode, "damped", "d");
12221 json_object_string_add(json_scode, "history", "h");
12222 json_object_string_add(json_scode, "valid", "*");
12223 json_object_string_add(json_scode, "best", ">");
12224 json_object_string_add(json_scode, "multipath", "=");
12225 json_object_string_add(json_scode, "internal", "i");
12226 json_object_string_add(json_scode, "ribFailure", "r");
12227 json_object_string_add(json_scode, "stale", "S");
12228 json_object_string_add(json_scode, "removed", "R");
12229
12230 json_object_string_add(json_ocode, "igp", "i");
12231 json_object_string_add(json_ocode, "egp", "e");
12232 json_object_string_add(json_ocode, "incomplete", "?");
12233 }
12234
12235 bgp = peer->bgp;
12236
12237 if (!bgp) {
12238 if (use_json) {
12239 json_object_string_add(json, "alert", "no BGP");
12240 vty_out(vty, "%s\n", json_object_to_json_string(json));
12241 json_object_free(json);
12242 } else
12243 vty_out(vty, "%% No bgp\n");
12244 return;
12245 }
12246
12247 /* labeled-unicast routes live in the unicast table */
12248 if (safi == SAFI_LABELED_UNICAST)
12249 table = bgp->rib[afi][SAFI_UNICAST];
12250 else
12251 table = bgp->rib[afi][safi];
12252
12253 output_count = filtered_count = 0;
12254 subgrp = peer_subgroup(peer, afi, safi);
12255
12256 if (type == bgp_show_adj_route_advertised && subgrp
12257 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
12258 if (use_json) {
12259 json_object_int_add(json, "bgpTableVersion",
12260 table->version);
12261 json_object_string_add(json, "bgpLocalRouterId",
12262 inet_ntoa(bgp->router_id));
12263 json_object_int_add(json, "defaultLocPrf",
12264 bgp->default_local_pref);
12265 json_object_int_add(json, "localAS", bgp->as);
12266 json_object_object_add(json, "bgpStatusCodes",
12267 json_scode);
12268 json_object_object_add(json, "bgpOriginCodes",
12269 json_ocode);
12270 json_object_string_add(
12271 json, "bgpOriginatingDefaultNetwork",
12272 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
12273 } else {
12274 vty_out(vty, "BGP table version is %" PRIu64", local router ID is %s, vrf id ",
12275 table->version, inet_ntoa(bgp->router_id));
12276 if (bgp->vrf_id == VRF_UNKNOWN)
12277 vty_out(vty, "%s", VRFID_NONE_STR);
12278 else
12279 vty_out(vty, "%u", bgp->vrf_id);
12280 vty_out(vty, "\n");
12281 vty_out(vty, "Default local pref %u, ",
12282 bgp->default_local_pref);
12283 vty_out(vty, "local AS %u\n", bgp->as);
12284 vty_out(vty, BGP_SHOW_SCODE_HEADER);
12285 vty_out(vty, BGP_SHOW_NCODE_HEADER);
12286 vty_out(vty, BGP_SHOW_OCODE_HEADER);
12287
12288 vty_out(vty, "Originating default network %s\n\n",
12289 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
12290 }
12291 header1 = 0;
12292 }
12293
12294 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
12295 if (type == bgp_show_adj_route_received
12296 || type == bgp_show_adj_route_filtered) {
12297 for (ain = dest->adj_in; ain; ain = ain->next) {
12298 if (ain->peer != peer)
12299 continue;
12300
12301 show_adj_route_header(
12302 vty, bgp, table, &header1, &header2,
12303 json, json_scode, json_ocode, wide);
12304
12305 attr = *ain->attr;
12306 route_filtered = false;
12307
12308 /* Filter prefix using distribute list,
12309 * filter list or prefix list
12310 */
12311 const struct prefix *rn_p =
12312 bgp_dest_get_prefix(dest);
12313 if ((bgp_input_filter(peer, rn_p, &attr, afi,
12314 safi))
12315 == FILTER_DENY)
12316 route_filtered = true;
12317
12318 /* Filter prefix using route-map */
12319 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
12320 safi, rmap_name, NULL,
12321 0, NULL);
12322
12323 if (type == bgp_show_adj_route_filtered &&
12324 !route_filtered && ret != RMAP_DENY) {
12325 bgp_attr_undup(&attr, ain->attr);
12326 continue;
12327 }
12328
12329 if (type == bgp_show_adj_route_received &&
12330 (route_filtered || ret == RMAP_DENY))
12331 filtered_count++;
12332
12333 route_vty_out_tmp(vty, rn_p, &attr, safi,
12334 use_json, json_ar, wide);
12335 bgp_attr_undup(&attr, ain->attr);
12336 output_count++;
12337 }
12338 } else if (type == bgp_show_adj_route_advertised) {
12339 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
12340 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
12341 if (paf->peer != peer || !adj->attr)
12342 continue;
12343
12344 show_adj_route_header(
12345 vty, bgp, table, &header1,
12346 &header2, json, json_scode,
12347 json_ocode, wide);
12348
12349 const struct prefix *rn_p =
12350 bgp_dest_get_prefix(dest);
12351
12352 attr = *adj->attr;
12353 ret = bgp_output_modifier(
12354 peer, rn_p, &attr, afi, safi,
12355 rmap_name);
12356
12357 if (ret != RMAP_DENY) {
12358 route_vty_out_tmp(
12359 vty, rn_p, &attr, safi,
12360 use_json, json_ar,
12361 wide);
12362 output_count++;
12363 } else {
12364 filtered_count++;
12365 }
12366
12367 bgp_attr_undup(&attr, adj->attr);
12368 }
12369 } else if (type == bgp_show_adj_route_bestpath) {
12370 struct bgp_path_info *pi;
12371
12372 show_adj_route_header(vty, bgp, table, &header1,
12373 &header2, json, json_scode,
12374 json_ocode, wide);
12375
12376 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
12377 pi = pi->next) {
12378 if (pi->peer != peer)
12379 continue;
12380
12381 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12382 continue;
12383
12384 route_vty_out_tmp(vty,
12385 bgp_dest_get_prefix(dest),
12386 pi->attr, safi, use_json,
12387 json_ar, wide);
12388 output_count++;
12389 }
12390 }
12391 }
12392
12393 if (use_json) {
12394 json_object_object_add(json, "advertisedRoutes", json_ar);
12395 json_object_int_add(json, "totalPrefixCounter", output_count);
12396 json_object_int_add(json, "filteredPrefixCounter",
12397 filtered_count);
12398
12399 vty_out(vty, "%s\n", json_object_to_json_string_ext(
12400 json, JSON_C_TO_STRING_PRETTY));
12401
12402 if (!output_count && !filtered_count) {
12403 json_object_free(json_scode);
12404 json_object_free(json_ocode);
12405 }
12406
12407 json_object_free(json);
12408 } else if (output_count > 0) {
12409 if (filtered_count > 0)
12410 vty_out(vty,
12411 "\nTotal number of prefixes %ld (%ld filtered)\n",
12412 output_count, filtered_count);
12413 else
12414 vty_out(vty, "\nTotal number of prefixes %ld\n",
12415 output_count);
12416 }
12417 }
12418
12419 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
12420 safi_t safi, enum bgp_show_adj_route_type type,
12421 const char *rmap_name, bool use_json, bool wide)
12422 {
12423 json_object *json = NULL;
12424
12425 if (use_json)
12426 json = json_object_new_object();
12427
12428 if (!peer || !peer->afc[afi][safi]) {
12429 if (use_json) {
12430 json_object_string_add(
12431 json, "warning",
12432 "No such neighbor or address family");
12433 vty_out(vty, "%s\n", json_object_to_json_string(json));
12434 json_object_free(json);
12435 } else
12436 vty_out(vty, "%% No such neighbor or address family\n");
12437
12438 return CMD_WARNING;
12439 }
12440
12441 if ((type == bgp_show_adj_route_received
12442 || type == bgp_show_adj_route_filtered)
12443 && !CHECK_FLAG(peer->af_flags[afi][safi],
12444 PEER_FLAG_SOFT_RECONFIG)) {
12445 if (use_json) {
12446 json_object_string_add(
12447 json, "warning",
12448 "Inbound soft reconfiguration not enabled");
12449 vty_out(vty, "%s\n", json_object_to_json_string(json));
12450 json_object_free(json);
12451 } else
12452 vty_out(vty,
12453 "%% Inbound soft reconfiguration not enabled\n");
12454
12455 return CMD_WARNING;
12456 }
12457
12458 show_adj_route(vty, peer, afi, safi, type, rmap_name, use_json, json,
12459 wide);
12460
12461 return CMD_SUCCESS;
12462 }
12463
12464 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
12465 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
12466 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] neighbors <A.B.C.D|X:X::X:X|WORD> bestpath-routes [json$uj | wide$wide]",
12467 SHOW_STR
12468 IP_STR
12469 BGP_STR
12470 BGP_INSTANCE_HELP_STR
12471 BGP_AFI_HELP_STR
12472 BGP_SAFI_WITH_LABEL_HELP_STR
12473 "Detailed information on TCP and BGP neighbor connections\n"
12474 "Neighbor to display information about\n"
12475 "Neighbor to display information about\n"
12476 "Neighbor on BGP configured interface\n"
12477 "Display the routes selected by best path\n"
12478 JSON_STR
12479 "Increase table width for longer prefixes\n")
12480 {
12481 afi_t afi = AFI_IP6;
12482 safi_t safi = SAFI_UNICAST;
12483 char *rmap_name = NULL;
12484 char *peerstr = NULL;
12485 struct bgp *bgp = NULL;
12486 struct peer *peer;
12487 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
12488 int idx = 0;
12489
12490 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12491 &bgp, uj);
12492
12493 if (!idx)
12494 return CMD_WARNING;
12495
12496 argv_find(argv, argc, "neighbors", &idx);
12497 peerstr = argv[++idx]->arg;
12498
12499 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
12500 if (!peer)
12501 return CMD_WARNING;
12502
12503 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, uj, wide);
12504 }
12505
12506 DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
12507 show_ip_bgp_instance_neighbor_advertised_route_cmd,
12508 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map WORD] [json$uj | wide$wide]",
12509 SHOW_STR
12510 IP_STR
12511 BGP_STR
12512 BGP_INSTANCE_HELP_STR
12513 BGP_AFI_HELP_STR
12514 BGP_SAFI_WITH_LABEL_HELP_STR
12515 "Detailed information on TCP and BGP neighbor connections\n"
12516 "Neighbor to display information about\n"
12517 "Neighbor to display information about\n"
12518 "Neighbor on BGP configured interface\n"
12519 "Display the routes advertised to a BGP neighbor\n"
12520 "Display the received routes from neighbor\n"
12521 "Display the filtered routes received from neighbor\n"
12522 "Route-map to modify the attributes\n"
12523 "Name of the route map\n"
12524 JSON_STR
12525 "Increase table width for longer prefixes\n")
12526 {
12527 afi_t afi = AFI_IP6;
12528 safi_t safi = SAFI_UNICAST;
12529 char *rmap_name = NULL;
12530 char *peerstr = NULL;
12531 struct bgp *bgp = NULL;
12532 struct peer *peer;
12533 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
12534 int idx = 0;
12535
12536 if (uj)
12537 argc--;
12538
12539 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12540 &bgp, uj);
12541 if (!idx)
12542 return CMD_WARNING;
12543
12544 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
12545 argv_find(argv, argc, "neighbors", &idx);
12546 peerstr = argv[++idx]->arg;
12547
12548 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
12549 if (!peer)
12550 return CMD_WARNING;
12551
12552 if (argv_find(argv, argc, "advertised-routes", &idx))
12553 type = bgp_show_adj_route_advertised;
12554 else if (argv_find(argv, argc, "received-routes", &idx))
12555 type = bgp_show_adj_route_received;
12556 else if (argv_find(argv, argc, "filtered-routes", &idx))
12557 type = bgp_show_adj_route_filtered;
12558
12559 if (argv_find(argv, argc, "route-map", &idx))
12560 rmap_name = argv[++idx]->arg;
12561
12562 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, uj, wide);
12563 }
12564
12565 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
12566 show_ip_bgp_neighbor_received_prefix_filter_cmd,
12567 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
12568 SHOW_STR
12569 IP_STR
12570 BGP_STR
12571 "Address Family\n"
12572 "Address Family\n"
12573 "Address Family modifier\n"
12574 "Detailed information on TCP and BGP neighbor connections\n"
12575 "Neighbor to display information about\n"
12576 "Neighbor to display information about\n"
12577 "Neighbor on BGP configured interface\n"
12578 "Display information received from a BGP neighbor\n"
12579 "Display the prefixlist filter\n"
12580 JSON_STR)
12581 {
12582 afi_t afi = AFI_IP6;
12583 safi_t safi = SAFI_UNICAST;
12584 char *peerstr = NULL;
12585
12586 char name[BUFSIZ];
12587 union sockunion su;
12588 struct peer *peer;
12589 int count, ret;
12590
12591 int idx = 0;
12592
12593 /* show [ip] bgp */
12594 if (argv_find(argv, argc, "ip", &idx))
12595 afi = AFI_IP;
12596 /* [<ipv4|ipv6> [unicast]] */
12597 if (argv_find(argv, argc, "ipv4", &idx))
12598 afi = AFI_IP;
12599 if (argv_find(argv, argc, "ipv6", &idx))
12600 afi = AFI_IP6;
12601 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
12602 argv_find(argv, argc, "neighbors", &idx);
12603 peerstr = argv[++idx]->arg;
12604
12605 bool uj = use_json(argc, argv);
12606
12607 ret = str2sockunion(peerstr, &su);
12608 if (ret < 0) {
12609 peer = peer_lookup_by_conf_if(NULL, peerstr);
12610 if (!peer) {
12611 if (uj)
12612 vty_out(vty, "{}\n");
12613 else
12614 vty_out(vty,
12615 "%% Malformed address or name: %s\n",
12616 peerstr);
12617 return CMD_WARNING;
12618 }
12619 } else {
12620 peer = peer_lookup(NULL, &su);
12621 if (!peer) {
12622 if (uj)
12623 vty_out(vty, "{}\n");
12624 else
12625 vty_out(vty, "No peer\n");
12626 return CMD_WARNING;
12627 }
12628 }
12629
12630 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
12631 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
12632 if (count) {
12633 if (!uj)
12634 vty_out(vty, "Address Family: %s\n",
12635 get_afi_safi_str(afi, safi, false));
12636 prefix_bgp_show_prefix_list(vty, afi, name, uj);
12637 } else {
12638 if (uj)
12639 vty_out(vty, "{}\n");
12640 else
12641 vty_out(vty, "No functional output\n");
12642 }
12643
12644 return CMD_SUCCESS;
12645 }
12646
12647 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
12648 afi_t afi, safi_t safi,
12649 enum bgp_show_type type, bool use_json)
12650 {
12651 /* labeled-unicast routes live in the unicast table */
12652 if (safi == SAFI_LABELED_UNICAST)
12653 safi = SAFI_UNICAST;
12654
12655 if (!peer || !peer->afc[afi][safi]) {
12656 if (use_json) {
12657 json_object *json_no = NULL;
12658 json_no = json_object_new_object();
12659 json_object_string_add(
12660 json_no, "warning",
12661 "No such neighbor or address family");
12662 vty_out(vty, "%s\n",
12663 json_object_to_json_string(json_no));
12664 json_object_free(json_no);
12665 } else
12666 vty_out(vty, "%% No such neighbor or address family\n");
12667 return CMD_WARNING;
12668 }
12669
12670 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, use_json,
12671 false);
12672 }
12673
12674 DEFUN (show_ip_bgp_flowspec_routes_detailed,
12675 show_ip_bgp_flowspec_routes_detailed_cmd,
12676 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
12677 SHOW_STR
12678 IP_STR
12679 BGP_STR
12680 BGP_INSTANCE_HELP_STR
12681 BGP_AFI_HELP_STR
12682 "SAFI Flowspec\n"
12683 "Detailed information on flowspec entries\n"
12684 JSON_STR)
12685 {
12686 afi_t afi = AFI_IP;
12687 safi_t safi = SAFI_UNICAST;
12688 struct bgp *bgp = NULL;
12689 int idx = 0;
12690 bool uj = use_json(argc, argv);
12691
12692 if (uj)
12693 argc--;
12694
12695 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12696 &bgp, uj);
12697 if (!idx)
12698 return CMD_WARNING;
12699
12700 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL, uj,
12701 false);
12702 }
12703
12704 DEFUN (show_ip_bgp_neighbor_routes,
12705 show_ip_bgp_neighbor_routes_cmd,
12706 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
12707 SHOW_STR
12708 IP_STR
12709 BGP_STR
12710 BGP_INSTANCE_HELP_STR
12711 BGP_AFI_HELP_STR
12712 BGP_SAFI_WITH_LABEL_HELP_STR
12713 "Detailed information on TCP and BGP neighbor connections\n"
12714 "Neighbor to display information about\n"
12715 "Neighbor to display information about\n"
12716 "Neighbor on BGP configured interface\n"
12717 "Display flap statistics of the routes learned from neighbor\n"
12718 "Display the dampened routes received from neighbor\n"
12719 "Display routes learned from neighbor\n"
12720 JSON_STR)
12721 {
12722 char *peerstr = NULL;
12723 struct bgp *bgp = NULL;
12724 afi_t afi = AFI_IP6;
12725 safi_t safi = SAFI_UNICAST;
12726 struct peer *peer;
12727 enum bgp_show_type sh_type = bgp_show_type_neighbor;
12728 int idx = 0;
12729 bool uj = use_json(argc, argv);
12730
12731 if (uj)
12732 argc--;
12733
12734 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12735 &bgp, uj);
12736 if (!idx)
12737 return CMD_WARNING;
12738
12739 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
12740 argv_find(argv, argc, "neighbors", &idx);
12741 peerstr = argv[++idx]->arg;
12742
12743 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
12744 if (!peer)
12745 return CMD_WARNING;
12746
12747 if (argv_find(argv, argc, "flap-statistics", &idx))
12748 sh_type = bgp_show_type_flap_neighbor;
12749 else if (argv_find(argv, argc, "dampened-routes", &idx))
12750 sh_type = bgp_show_type_damp_neighbor;
12751 else if (argv_find(argv, argc, "routes", &idx))
12752 sh_type = bgp_show_type_neighbor;
12753
12754 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
12755 }
12756
12757 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
12758
12759 struct bgp_distance {
12760 /* Distance value for the IP source prefix. */
12761 uint8_t distance;
12762
12763 /* Name of the access-list to be matched. */
12764 char *access_list;
12765 };
12766
12767 DEFUN (show_bgp_afi_vpn_rd_route,
12768 show_bgp_afi_vpn_rd_route_cmd,
12769 "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]",
12770 SHOW_STR
12771 BGP_STR
12772 BGP_AFI_HELP_STR
12773 "Address Family modifier\n"
12774 "Display information for a route distinguisher\n"
12775 "Route Distinguisher\n"
12776 "Network in the BGP routing table to display\n"
12777 "Network in the BGP routing table to display\n"
12778 JSON_STR)
12779 {
12780 int ret;
12781 struct prefix_rd prd;
12782 afi_t afi = AFI_MAX;
12783 int idx = 0;
12784
12785 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
12786 vty_out(vty, "%% Malformed Address Family\n");
12787 return CMD_WARNING;
12788 }
12789
12790 ret = str2prefix_rd(argv[5]->arg, &prd);
12791 if (!ret) {
12792 vty_out(vty, "%% Malformed Route Distinguisher\n");
12793 return CMD_WARNING;
12794 }
12795
12796 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
12797 0, BGP_PATH_SHOW_ALL, use_json(argc, argv));
12798 }
12799
12800 static struct bgp_distance *bgp_distance_new(void)
12801 {
12802 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
12803 }
12804
12805 static void bgp_distance_free(struct bgp_distance *bdistance)
12806 {
12807 XFREE(MTYPE_BGP_DISTANCE, bdistance);
12808 }
12809
12810 static int bgp_distance_set(struct vty *vty, const char *distance_str,
12811 const char *ip_str, const char *access_list_str)
12812 {
12813 int ret;
12814 afi_t afi;
12815 safi_t safi;
12816 struct prefix p;
12817 uint8_t distance;
12818 struct bgp_dest *dest;
12819 struct bgp_distance *bdistance;
12820
12821 afi = bgp_node_afi(vty);
12822 safi = bgp_node_safi(vty);
12823
12824 ret = str2prefix(ip_str, &p);
12825 if (ret == 0) {
12826 vty_out(vty, "Malformed prefix\n");
12827 return CMD_WARNING_CONFIG_FAILED;
12828 }
12829
12830 distance = atoi(distance_str);
12831
12832 /* Get BGP distance node. */
12833 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
12834 bdistance = bgp_dest_get_bgp_distance_info(dest);
12835 if (bdistance)
12836 bgp_dest_unlock_node(dest);
12837 else {
12838 bdistance = bgp_distance_new();
12839 bgp_dest_set_bgp_distance_info(dest, bdistance);
12840 }
12841
12842 /* Set distance value. */
12843 bdistance->distance = distance;
12844
12845 /* Reset access-list configuration. */
12846 XFREE(MTYPE_AS_LIST, bdistance->access_list);
12847 if (access_list_str)
12848 bdistance->access_list =
12849 XSTRDUP(MTYPE_AS_LIST, access_list_str);
12850
12851 return CMD_SUCCESS;
12852 }
12853
12854 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
12855 const char *ip_str, const char *access_list_str)
12856 {
12857 int ret;
12858 afi_t afi;
12859 safi_t safi;
12860 struct prefix p;
12861 int distance;
12862 struct bgp_dest *dest;
12863 struct bgp_distance *bdistance;
12864
12865 afi = bgp_node_afi(vty);
12866 safi = bgp_node_safi(vty);
12867
12868 ret = str2prefix(ip_str, &p);
12869 if (ret == 0) {
12870 vty_out(vty, "Malformed prefix\n");
12871 return CMD_WARNING_CONFIG_FAILED;
12872 }
12873
12874 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
12875 if (!dest) {
12876 vty_out(vty, "Can't find specified prefix\n");
12877 return CMD_WARNING_CONFIG_FAILED;
12878 }
12879
12880 bdistance = bgp_dest_get_bgp_distance_info(dest);
12881 distance = atoi(distance_str);
12882
12883 if (bdistance->distance != distance) {
12884 vty_out(vty, "Distance does not match configured\n");
12885 return CMD_WARNING_CONFIG_FAILED;
12886 }
12887
12888 XFREE(MTYPE_AS_LIST, bdistance->access_list);
12889 bgp_distance_free(bdistance);
12890
12891 bgp_dest_set_bgp_path_info(dest, NULL);
12892 bgp_dest_unlock_node(dest);
12893 bgp_dest_unlock_node(dest);
12894
12895 return CMD_SUCCESS;
12896 }
12897
12898 /* Apply BGP information to distance method. */
12899 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
12900 afi_t afi, safi_t safi, struct bgp *bgp)
12901 {
12902 struct bgp_dest *dest;
12903 struct prefix q;
12904 struct peer *peer;
12905 struct bgp_distance *bdistance;
12906 struct access_list *alist;
12907 struct bgp_static *bgp_static;
12908
12909 if (!bgp)
12910 return 0;
12911
12912 peer = pinfo->peer;
12913
12914 if (pinfo->attr->distance)
12915 return pinfo->attr->distance;
12916
12917 /* Check source address. */
12918 sockunion2hostprefix(&peer->su, &q);
12919 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
12920 if (dest) {
12921 bdistance = bgp_dest_get_bgp_distance_info(dest);
12922 bgp_dest_unlock_node(dest);
12923
12924 if (bdistance->access_list) {
12925 alist = access_list_lookup(afi, bdistance->access_list);
12926 if (alist
12927 && access_list_apply(alist, p) == FILTER_PERMIT)
12928 return bdistance->distance;
12929 } else
12930 return bdistance->distance;
12931 }
12932
12933 /* Backdoor check. */
12934 dest = bgp_node_lookup(bgp->route[afi][safi], p);
12935 if (dest) {
12936 bgp_static = bgp_dest_get_bgp_static_info(dest);
12937 bgp_dest_unlock_node(dest);
12938
12939 if (bgp_static->backdoor) {
12940 if (bgp->distance_local[afi][safi])
12941 return bgp->distance_local[afi][safi];
12942 else
12943 return ZEBRA_IBGP_DISTANCE_DEFAULT;
12944 }
12945 }
12946
12947 if (peer->sort == BGP_PEER_EBGP) {
12948 if (bgp->distance_ebgp[afi][safi])
12949 return bgp->distance_ebgp[afi][safi];
12950 return ZEBRA_EBGP_DISTANCE_DEFAULT;
12951 } else {
12952 if (bgp->distance_ibgp[afi][safi])
12953 return bgp->distance_ibgp[afi][safi];
12954 return ZEBRA_IBGP_DISTANCE_DEFAULT;
12955 }
12956 }
12957
12958 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
12959 * we should tell ZEBRA update the routes for a specific
12960 * AFI/SAFI to reflect changes in RIB.
12961 */
12962 static void bgp_announce_routes_distance_update(struct bgp *bgp,
12963 afi_t update_afi,
12964 safi_t update_safi)
12965 {
12966 afi_t afi;
12967 safi_t safi;
12968
12969 FOREACH_AFI_SAFI (afi, safi) {
12970 if (!bgp_fibupd_safi(safi))
12971 continue;
12972
12973 if (afi != update_afi && safi != update_safi)
12974 continue;
12975
12976 if (BGP_DEBUG(zebra, ZEBRA))
12977 zlog_debug(
12978 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
12979 __func__, afi, safi);
12980 bgp_zebra_announce_table(bgp, afi, safi);
12981 }
12982 }
12983
12984 DEFUN (bgp_distance,
12985 bgp_distance_cmd,
12986 "distance bgp (1-255) (1-255) (1-255)",
12987 "Define an administrative distance\n"
12988 "BGP distance\n"
12989 "Distance for routes external to the AS\n"
12990 "Distance for routes internal to the AS\n"
12991 "Distance for local routes\n")
12992 {
12993 VTY_DECLVAR_CONTEXT(bgp, bgp);
12994 int idx_number = 2;
12995 int idx_number_2 = 3;
12996 int idx_number_3 = 4;
12997 int distance_ebgp = atoi(argv[idx_number]->arg);
12998 int distance_ibgp = atoi(argv[idx_number_2]->arg);
12999 int distance_local = atoi(argv[idx_number_3]->arg);
13000 afi_t afi;
13001 safi_t safi;
13002
13003 afi = bgp_node_afi(vty);
13004 safi = bgp_node_safi(vty);
13005
13006 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
13007 || bgp->distance_ibgp[afi][safi] != distance_ibgp
13008 || bgp->distance_local[afi][safi] != distance_local) {
13009 bgp->distance_ebgp[afi][safi] = distance_ebgp;
13010 bgp->distance_ibgp[afi][safi] = distance_ibgp;
13011 bgp->distance_local[afi][safi] = distance_local;
13012 bgp_announce_routes_distance_update(bgp, afi, safi);
13013 }
13014 return CMD_SUCCESS;
13015 }
13016
13017 DEFUN (no_bgp_distance,
13018 no_bgp_distance_cmd,
13019 "no distance bgp [(1-255) (1-255) (1-255)]",
13020 NO_STR
13021 "Define an administrative distance\n"
13022 "BGP distance\n"
13023 "Distance for routes external to the AS\n"
13024 "Distance for routes internal to the AS\n"
13025 "Distance for local routes\n")
13026 {
13027 VTY_DECLVAR_CONTEXT(bgp, bgp);
13028 afi_t afi;
13029 safi_t safi;
13030
13031 afi = bgp_node_afi(vty);
13032 safi = bgp_node_safi(vty);
13033
13034 if (bgp->distance_ebgp[afi][safi] != 0
13035 || bgp->distance_ibgp[afi][safi] != 0
13036 || bgp->distance_local[afi][safi] != 0) {
13037 bgp->distance_ebgp[afi][safi] = 0;
13038 bgp->distance_ibgp[afi][safi] = 0;
13039 bgp->distance_local[afi][safi] = 0;
13040 bgp_announce_routes_distance_update(bgp, afi, safi);
13041 }
13042 return CMD_SUCCESS;
13043 }
13044
13045
13046 DEFUN (bgp_distance_source,
13047 bgp_distance_source_cmd,
13048 "distance (1-255) A.B.C.D/M",
13049 "Define an administrative distance\n"
13050 "Administrative distance\n"
13051 "IP source prefix\n")
13052 {
13053 int idx_number = 1;
13054 int idx_ipv4_prefixlen = 2;
13055 bgp_distance_set(vty, argv[idx_number]->arg,
13056 argv[idx_ipv4_prefixlen]->arg, NULL);
13057 return CMD_SUCCESS;
13058 }
13059
13060 DEFUN (no_bgp_distance_source,
13061 no_bgp_distance_source_cmd,
13062 "no distance (1-255) A.B.C.D/M",
13063 NO_STR
13064 "Define an administrative distance\n"
13065 "Administrative distance\n"
13066 "IP source prefix\n")
13067 {
13068 int idx_number = 2;
13069 int idx_ipv4_prefixlen = 3;
13070 bgp_distance_unset(vty, argv[idx_number]->arg,
13071 argv[idx_ipv4_prefixlen]->arg, NULL);
13072 return CMD_SUCCESS;
13073 }
13074
13075 DEFUN (bgp_distance_source_access_list,
13076 bgp_distance_source_access_list_cmd,
13077 "distance (1-255) A.B.C.D/M WORD",
13078 "Define an administrative distance\n"
13079 "Administrative distance\n"
13080 "IP source prefix\n"
13081 "Access list name\n")
13082 {
13083 int idx_number = 1;
13084 int idx_ipv4_prefixlen = 2;
13085 int idx_word = 3;
13086 bgp_distance_set(vty, argv[idx_number]->arg,
13087 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
13088 return CMD_SUCCESS;
13089 }
13090
13091 DEFUN (no_bgp_distance_source_access_list,
13092 no_bgp_distance_source_access_list_cmd,
13093 "no distance (1-255) A.B.C.D/M WORD",
13094 NO_STR
13095 "Define an administrative distance\n"
13096 "Administrative distance\n"
13097 "IP source prefix\n"
13098 "Access list name\n")
13099 {
13100 int idx_number = 2;
13101 int idx_ipv4_prefixlen = 3;
13102 int idx_word = 4;
13103 bgp_distance_unset(vty, argv[idx_number]->arg,
13104 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
13105 return CMD_SUCCESS;
13106 }
13107
13108 DEFUN (ipv6_bgp_distance_source,
13109 ipv6_bgp_distance_source_cmd,
13110 "distance (1-255) X:X::X:X/M",
13111 "Define an administrative distance\n"
13112 "Administrative distance\n"
13113 "IP source prefix\n")
13114 {
13115 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
13116 return CMD_SUCCESS;
13117 }
13118
13119 DEFUN (no_ipv6_bgp_distance_source,
13120 no_ipv6_bgp_distance_source_cmd,
13121 "no distance (1-255) X:X::X:X/M",
13122 NO_STR
13123 "Define an administrative distance\n"
13124 "Administrative distance\n"
13125 "IP source prefix\n")
13126 {
13127 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
13128 return CMD_SUCCESS;
13129 }
13130
13131 DEFUN (ipv6_bgp_distance_source_access_list,
13132 ipv6_bgp_distance_source_access_list_cmd,
13133 "distance (1-255) X:X::X:X/M WORD",
13134 "Define an administrative distance\n"
13135 "Administrative distance\n"
13136 "IP source prefix\n"
13137 "Access list name\n")
13138 {
13139 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
13140 return CMD_SUCCESS;
13141 }
13142
13143 DEFUN (no_ipv6_bgp_distance_source_access_list,
13144 no_ipv6_bgp_distance_source_access_list_cmd,
13145 "no distance (1-255) X:X::X:X/M WORD",
13146 NO_STR
13147 "Define an administrative distance\n"
13148 "Administrative distance\n"
13149 "IP source prefix\n"
13150 "Access list name\n")
13151 {
13152 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
13153 return CMD_SUCCESS;
13154 }
13155
13156 DEFUN (bgp_damp_set,
13157 bgp_damp_set_cmd,
13158 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
13159 "BGP Specific commands\n"
13160 "Enable route-flap dampening\n"
13161 "Half-life time for the penalty\n"
13162 "Value to start reusing a route\n"
13163 "Value to start suppressing a route\n"
13164 "Maximum duration to suppress a stable route\n")
13165 {
13166 VTY_DECLVAR_CONTEXT(bgp, bgp);
13167 int idx_half_life = 2;
13168 int idx_reuse = 3;
13169 int idx_suppress = 4;
13170 int idx_max_suppress = 5;
13171 int half = DEFAULT_HALF_LIFE * 60;
13172 int reuse = DEFAULT_REUSE;
13173 int suppress = DEFAULT_SUPPRESS;
13174 int max = 4 * half;
13175
13176 if (argc == 6) {
13177 half = atoi(argv[idx_half_life]->arg) * 60;
13178 reuse = atoi(argv[idx_reuse]->arg);
13179 suppress = atoi(argv[idx_suppress]->arg);
13180 max = atoi(argv[idx_max_suppress]->arg) * 60;
13181 } else if (argc == 3) {
13182 half = atoi(argv[idx_half_life]->arg) * 60;
13183 max = 4 * half;
13184 }
13185
13186 /*
13187 * These can't be 0 but our SA doesn't understand the
13188 * way our cli is constructed
13189 */
13190 assert(reuse);
13191 assert(half);
13192 if (suppress < reuse) {
13193 vty_out(vty,
13194 "Suppress value cannot be less than reuse value \n");
13195 return 0;
13196 }
13197
13198 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
13199 reuse, suppress, max);
13200 }
13201
13202 DEFUN (bgp_damp_unset,
13203 bgp_damp_unset_cmd,
13204 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
13205 NO_STR
13206 "BGP Specific commands\n"
13207 "Enable route-flap dampening\n"
13208 "Half-life time for the penalty\n"
13209 "Value to start reusing a route\n"
13210 "Value to start suppressing a route\n"
13211 "Maximum duration to suppress a stable route\n")
13212 {
13213 VTY_DECLVAR_CONTEXT(bgp, bgp);
13214 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
13215 }
13216
13217 /* Display specified route of BGP table. */
13218 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
13219 const char *ip_str, afi_t afi, safi_t safi,
13220 struct prefix_rd *prd, int prefix_check)
13221 {
13222 int ret;
13223 struct prefix match;
13224 struct bgp_dest *dest;
13225 struct bgp_dest *rm;
13226 struct bgp_path_info *pi;
13227 struct bgp_path_info *pi_temp;
13228 struct bgp *bgp;
13229 struct bgp_table *table;
13230
13231 /* BGP structure lookup. */
13232 if (view_name) {
13233 bgp = bgp_lookup_by_name(view_name);
13234 if (bgp == NULL) {
13235 vty_out(vty, "%% Can't find BGP instance %s\n",
13236 view_name);
13237 return CMD_WARNING;
13238 }
13239 } else {
13240 bgp = bgp_get_default();
13241 if (bgp == NULL) {
13242 vty_out(vty, "%% No BGP process is configured\n");
13243 return CMD_WARNING;
13244 }
13245 }
13246
13247 /* Check IP address argument. */
13248 ret = str2prefix(ip_str, &match);
13249 if (!ret) {
13250 vty_out(vty, "%% address is malformed\n");
13251 return CMD_WARNING;
13252 }
13253
13254 match.family = afi2family(afi);
13255
13256 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13257 || (safi == SAFI_EVPN)) {
13258 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
13259 dest = bgp_route_next(dest)) {
13260 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
13261
13262 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
13263 continue;
13264 table = bgp_dest_get_bgp_table_info(dest);
13265 if (!table)
13266 continue;
13267 if ((rm = bgp_node_match(table, &match)) == NULL)
13268 continue;
13269
13270 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
13271
13272 if (!prefix_check
13273 || rm_p->prefixlen == match.prefixlen) {
13274 pi = bgp_dest_get_bgp_path_info(rm);
13275 while (pi) {
13276 if (pi->extra && pi->extra->damp_info) {
13277 pi_temp = pi->next;
13278 bgp_damp_info_free(
13279 pi->extra->damp_info,
13280 1, afi, safi);
13281 pi = pi_temp;
13282 } else
13283 pi = pi->next;
13284 }
13285 }
13286
13287 bgp_dest_unlock_node(rm);
13288 }
13289 } else {
13290 if ((dest = bgp_node_match(bgp->rib[afi][safi], &match))
13291 != NULL) {
13292 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
13293
13294 if (!prefix_check
13295 || dest_p->prefixlen == match.prefixlen) {
13296 pi = bgp_dest_get_bgp_path_info(dest);
13297 while (pi) {
13298 if (pi->extra && pi->extra->damp_info) {
13299 pi_temp = pi->next;
13300 bgp_damp_info_free(
13301 pi->extra->damp_info,
13302 1, afi, safi);
13303 pi = pi_temp;
13304 } else
13305 pi = pi->next;
13306 }
13307 }
13308
13309 bgp_dest_unlock_node(dest);
13310 }
13311 }
13312
13313 return CMD_SUCCESS;
13314 }
13315
13316 DEFUN (clear_ip_bgp_dampening,
13317 clear_ip_bgp_dampening_cmd,
13318 "clear ip bgp dampening",
13319 CLEAR_STR
13320 IP_STR
13321 BGP_STR
13322 "Clear route flap dampening information\n")
13323 {
13324 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
13325 return CMD_SUCCESS;
13326 }
13327
13328 DEFUN (clear_ip_bgp_dampening_prefix,
13329 clear_ip_bgp_dampening_prefix_cmd,
13330 "clear ip bgp dampening A.B.C.D/M",
13331 CLEAR_STR
13332 IP_STR
13333 BGP_STR
13334 "Clear route flap dampening information\n"
13335 "IPv4 prefix\n")
13336 {
13337 int idx_ipv4_prefixlen = 4;
13338 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
13339 AFI_IP, SAFI_UNICAST, NULL, 1);
13340 }
13341
13342 DEFUN (clear_ip_bgp_dampening_address,
13343 clear_ip_bgp_dampening_address_cmd,
13344 "clear ip bgp dampening A.B.C.D",
13345 CLEAR_STR
13346 IP_STR
13347 BGP_STR
13348 "Clear route flap dampening information\n"
13349 "Network to clear damping information\n")
13350 {
13351 int idx_ipv4 = 4;
13352 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
13353 SAFI_UNICAST, NULL, 0);
13354 }
13355
13356 DEFUN (clear_ip_bgp_dampening_address_mask,
13357 clear_ip_bgp_dampening_address_mask_cmd,
13358 "clear ip bgp dampening A.B.C.D A.B.C.D",
13359 CLEAR_STR
13360 IP_STR
13361 BGP_STR
13362 "Clear route flap dampening information\n"
13363 "Network to clear damping information\n"
13364 "Network mask\n")
13365 {
13366 int idx_ipv4 = 4;
13367 int idx_ipv4_2 = 5;
13368 int ret;
13369 char prefix_str[BUFSIZ];
13370
13371 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
13372 prefix_str);
13373 if (!ret) {
13374 vty_out(vty, "%% Inconsistent address and mask\n");
13375 return CMD_WARNING;
13376 }
13377
13378 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
13379 NULL, 0);
13380 }
13381
13382 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
13383 {
13384 struct vty *vty = arg;
13385 struct peer *peer = bucket->data;
13386 char buf[SU_ADDRSTRLEN];
13387
13388 vty_out(vty, "\tPeer: %s %s\n", peer->host,
13389 sockunion2str(&peer->su, buf, sizeof(buf)));
13390 }
13391
13392 DEFUN (show_bgp_listeners,
13393 show_bgp_listeners_cmd,
13394 "show bgp listeners",
13395 SHOW_STR
13396 BGP_STR
13397 "Display Listen Sockets and who created them\n")
13398 {
13399 bgp_dump_listener_info(vty);
13400
13401 return CMD_SUCCESS;
13402 }
13403
13404 DEFUN (show_bgp_peerhash,
13405 show_bgp_peerhash_cmd,
13406 "show bgp peerhash",
13407 SHOW_STR
13408 BGP_STR
13409 "Display information about the BGP peerhash\n")
13410 {
13411 struct list *instances = bm->bgp;
13412 struct listnode *node;
13413 struct bgp *bgp;
13414
13415 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
13416 vty_out(vty, "BGP: %s\n", bgp->name);
13417 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
13418 vty);
13419 }
13420
13421 return CMD_SUCCESS;
13422 }
13423
13424 /* also used for encap safi */
13425 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
13426 afi_t afi, safi_t safi)
13427 {
13428 struct bgp_dest *pdest;
13429 struct bgp_dest *dest;
13430 struct bgp_table *table;
13431 const struct prefix *p;
13432 const struct prefix_rd *prd;
13433 struct bgp_static *bgp_static;
13434 mpls_label_t label;
13435 char buf[SU_ADDRSTRLEN];
13436 char rdbuf[RD_ADDRSTRLEN];
13437
13438 /* Network configuration. */
13439 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
13440 pdest = bgp_route_next(pdest)) {
13441 table = bgp_dest_get_bgp_table_info(pdest);
13442 if (!table)
13443 continue;
13444
13445 for (dest = bgp_table_top(table); dest;
13446 dest = bgp_route_next(dest)) {
13447 bgp_static = bgp_dest_get_bgp_static_info(dest);
13448 if (bgp_static == NULL)
13449 continue;
13450
13451 p = bgp_dest_get_prefix(dest);
13452 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
13453 pdest);
13454
13455 /* "network" configuration display. */
13456 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
13457 label = decode_label(&bgp_static->label);
13458
13459 vty_out(vty, " network %s/%d rd %s",
13460 inet_ntop(p->family, &p->u.prefix, buf,
13461 SU_ADDRSTRLEN),
13462 p->prefixlen, rdbuf);
13463 if (safi == SAFI_MPLS_VPN)
13464 vty_out(vty, " label %u", label);
13465
13466 if (bgp_static->rmap.name)
13467 vty_out(vty, " route-map %s",
13468 bgp_static->rmap.name);
13469
13470 if (bgp_static->backdoor)
13471 vty_out(vty, " backdoor");
13472
13473 vty_out(vty, "\n");
13474 }
13475 }
13476 }
13477
13478 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
13479 afi_t afi, safi_t safi)
13480 {
13481 struct bgp_dest *pdest;
13482 struct bgp_dest *dest;
13483 struct bgp_table *table;
13484 const struct prefix *p;
13485 const struct prefix_rd *prd;
13486 struct bgp_static *bgp_static;
13487 char buf[PREFIX_STRLEN * 2];
13488 char buf2[SU_ADDRSTRLEN];
13489 char rdbuf[RD_ADDRSTRLEN];
13490 char esi_buf[ESI_BYTES];
13491
13492 /* Network configuration. */
13493 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
13494 pdest = bgp_route_next(pdest)) {
13495 table = bgp_dest_get_bgp_table_info(pdest);
13496 if (!table)
13497 continue;
13498
13499 for (dest = bgp_table_top(table); dest;
13500 dest = bgp_route_next(dest)) {
13501 bgp_static = bgp_dest_get_bgp_static_info(dest);
13502 if (bgp_static == NULL)
13503 continue;
13504
13505 char *macrouter = NULL;
13506
13507 if (bgp_static->router_mac)
13508 macrouter = prefix_mac2str(
13509 bgp_static->router_mac, NULL, 0);
13510 if (bgp_static->eth_s_id)
13511 esi_to_str(bgp_static->eth_s_id,
13512 esi_buf, sizeof(esi_buf));
13513 p = bgp_dest_get_prefix(dest);
13514 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
13515
13516 /* "network" configuration display. */
13517 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
13518 if (p->u.prefix_evpn.route_type == 5) {
13519 char local_buf[PREFIX_STRLEN];
13520 uint8_t family = is_evpn_prefix_ipaddr_v4((
13521 struct prefix_evpn *)p)
13522 ? AF_INET
13523 : AF_INET6;
13524 inet_ntop(family,
13525 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
13526 local_buf, PREFIX_STRLEN);
13527 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
13528 p->u.prefix_evpn.prefix_addr
13529 .ip_prefix_length);
13530 } else {
13531 prefix2str(p, buf, sizeof(buf));
13532 }
13533
13534 if (bgp_static->gatewayIp.family == AF_INET
13535 || bgp_static->gatewayIp.family == AF_INET6)
13536 inet_ntop(bgp_static->gatewayIp.family,
13537 &bgp_static->gatewayIp.u.prefix, buf2,
13538 sizeof(buf2));
13539 vty_out(vty,
13540 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
13541 buf, rdbuf,
13542 p->u.prefix_evpn.prefix_addr.eth_tag,
13543 decode_label(&bgp_static->label), esi_buf, buf2,
13544 macrouter);
13545
13546 XFREE(MTYPE_TMP, macrouter);
13547 }
13548 }
13549 }
13550
13551 /* Configuration of static route announcement and aggregate
13552 information. */
13553 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
13554 safi_t safi)
13555 {
13556 struct bgp_dest *dest;
13557 const struct prefix *p;
13558 struct bgp_static *bgp_static;
13559 struct bgp_aggregate *bgp_aggregate;
13560 char buf[SU_ADDRSTRLEN];
13561
13562 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
13563 bgp_config_write_network_vpn(vty, bgp, afi, safi);
13564 return;
13565 }
13566
13567 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
13568 bgp_config_write_network_evpn(vty, bgp, afi, safi);
13569 return;
13570 }
13571
13572 /* Network configuration. */
13573 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
13574 dest = bgp_route_next(dest)) {
13575 bgp_static = bgp_dest_get_bgp_static_info(dest);
13576 if (bgp_static == NULL)
13577 continue;
13578
13579 p = bgp_dest_get_prefix(dest);
13580
13581 vty_out(vty, " network %s/%d",
13582 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
13583 p->prefixlen);
13584
13585 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
13586 vty_out(vty, " label-index %u",
13587 bgp_static->label_index);
13588
13589 if (bgp_static->rmap.name)
13590 vty_out(vty, " route-map %s", bgp_static->rmap.name);
13591
13592 if (bgp_static->backdoor)
13593 vty_out(vty, " backdoor");
13594
13595 vty_out(vty, "\n");
13596 }
13597
13598 /* Aggregate-address configuration. */
13599 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
13600 dest = bgp_route_next(dest)) {
13601 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
13602 if (bgp_aggregate == NULL)
13603 continue;
13604
13605 p = bgp_dest_get_prefix(dest);
13606
13607 vty_out(vty, " aggregate-address %s/%d",
13608 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
13609 p->prefixlen);
13610
13611 if (bgp_aggregate->as_set)
13612 vty_out(vty, " as-set");
13613
13614 if (bgp_aggregate->summary_only)
13615 vty_out(vty, " summary-only");
13616
13617 if (bgp_aggregate->rmap.name)
13618 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
13619
13620 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
13621 vty_out(vty, " origin %s",
13622 bgp_origin2str(bgp_aggregate->origin));
13623
13624 vty_out(vty, "\n");
13625 }
13626 }
13627
13628 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
13629 safi_t safi)
13630 {
13631 struct bgp_dest *dest;
13632 struct bgp_distance *bdistance;
13633
13634 /* Distance configuration. */
13635 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
13636 && bgp->distance_local[afi][safi]
13637 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
13638 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
13639 || bgp->distance_local[afi][safi]
13640 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
13641 vty_out(vty, " distance bgp %d %d %d\n",
13642 bgp->distance_ebgp[afi][safi],
13643 bgp->distance_ibgp[afi][safi],
13644 bgp->distance_local[afi][safi]);
13645 }
13646
13647 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
13648 dest = bgp_route_next(dest)) {
13649 bdistance = bgp_dest_get_bgp_distance_info(dest);
13650 if (bdistance != NULL)
13651 vty_out(vty, " distance %d %pRN %s\n",
13652 bdistance->distance, dest,
13653 bdistance->access_list ? bdistance->access_list
13654 : "");
13655 }
13656 }
13657
13658 /* Allocate routing table structure and install commands. */
13659 void bgp_route_init(void)
13660 {
13661 afi_t afi;
13662 safi_t safi;
13663
13664 /* Init BGP distance table. */
13665 FOREACH_AFI_SAFI (afi, safi)
13666 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
13667
13668 /* IPv4 BGP commands. */
13669 install_element(BGP_NODE, &bgp_table_map_cmd);
13670 install_element(BGP_NODE, &bgp_network_cmd);
13671 install_element(BGP_NODE, &no_bgp_table_map_cmd);
13672
13673 install_element(BGP_NODE, &aggregate_address_cmd);
13674 install_element(BGP_NODE, &aggregate_address_mask_cmd);
13675 install_element(BGP_NODE, &no_aggregate_address_cmd);
13676 install_element(BGP_NODE, &no_aggregate_address_mask_cmd);
13677
13678 /* IPv4 unicast configuration. */
13679 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
13680 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
13681 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
13682
13683 install_element(BGP_IPV4_NODE, &aggregate_address_cmd);
13684 install_element(BGP_IPV4_NODE, &aggregate_address_mask_cmd);
13685 install_element(BGP_IPV4_NODE, &no_aggregate_address_cmd);
13686 install_element(BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
13687
13688 /* IPv4 multicast configuration. */
13689 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
13690 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
13691 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
13692 install_element(BGP_IPV4M_NODE, &aggregate_address_cmd);
13693 install_element(BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
13694 install_element(BGP_IPV4M_NODE, &no_aggregate_address_cmd);
13695 install_element(BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
13696
13697 /* IPv4 labeled-unicast configuration. */
13698 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
13699 install_element(BGP_IPV4L_NODE, &aggregate_address_cmd);
13700 install_element(BGP_IPV4L_NODE, &aggregate_address_mask_cmd);
13701 install_element(BGP_IPV4L_NODE, &no_aggregate_address_cmd);
13702 install_element(BGP_IPV4L_NODE, &no_aggregate_address_mask_cmd);
13703
13704 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
13705 install_element(VIEW_NODE, &show_ip_bgp_cmd);
13706 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
13707 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
13708 install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
13709 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
13710 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
13711 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
13712
13713 install_element(VIEW_NODE,
13714 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
13715 install_element(VIEW_NODE,
13716 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
13717 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
13718 install_element(VIEW_NODE,
13719 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
13720 #ifdef KEEP_OLD_VPN_COMMANDS
13721 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
13722 #endif /* KEEP_OLD_VPN_COMMANDS */
13723 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
13724 install_element(VIEW_NODE,
13725 &show_bgp_l2vpn_evpn_route_prefix_cmd);
13726
13727 /* BGP dampening clear commands */
13728 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
13729 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
13730
13731 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
13732 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
13733
13734 /* prefix count */
13735 install_element(ENABLE_NODE,
13736 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
13737 #ifdef KEEP_OLD_VPN_COMMANDS
13738 install_element(ENABLE_NODE,
13739 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
13740 #endif /* KEEP_OLD_VPN_COMMANDS */
13741
13742 /* New config IPv6 BGP commands. */
13743 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
13744 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
13745 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
13746
13747 install_element(BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
13748 install_element(BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
13749
13750 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
13751
13752 /* IPv6 labeled unicast address family. */
13753 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
13754 install_element(BGP_IPV6L_NODE, &ipv6_aggregate_address_cmd);
13755 install_element(BGP_IPV6L_NODE, &no_ipv6_aggregate_address_cmd);
13756
13757 install_element(BGP_NODE, &bgp_distance_cmd);
13758 install_element(BGP_NODE, &no_bgp_distance_cmd);
13759 install_element(BGP_NODE, &bgp_distance_source_cmd);
13760 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
13761 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
13762 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
13763 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
13764 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
13765 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
13766 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
13767 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
13768 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
13769 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
13770 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
13771 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
13772 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
13773 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
13774 install_element(BGP_IPV4M_NODE,
13775 &no_bgp_distance_source_access_list_cmd);
13776 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
13777 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
13778 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
13779 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
13780 install_element(BGP_IPV6_NODE,
13781 &ipv6_bgp_distance_source_access_list_cmd);
13782 install_element(BGP_IPV6_NODE,
13783 &no_ipv6_bgp_distance_source_access_list_cmd);
13784 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
13785 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
13786 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
13787 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
13788 install_element(BGP_IPV6M_NODE,
13789 &ipv6_bgp_distance_source_access_list_cmd);
13790 install_element(BGP_IPV6M_NODE,
13791 &no_ipv6_bgp_distance_source_access_list_cmd);
13792
13793 /* BGP dampening */
13794 install_element(BGP_NODE, &bgp_damp_set_cmd);
13795 install_element(BGP_NODE, &bgp_damp_unset_cmd);
13796 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
13797 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
13798 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
13799 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
13800 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
13801 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
13802 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
13803 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
13804 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
13805 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
13806 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
13807 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
13808
13809 /* Large Communities */
13810 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
13811 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
13812
13813 /* show bgp ipv4 flowspec detailed */
13814 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
13815
13816 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
13817 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
13818 }
13819
13820 void bgp_route_finish(void)
13821 {
13822 afi_t afi;
13823 safi_t safi;
13824
13825 FOREACH_AFI_SAFI (afi, safi) {
13826 bgp_table_unlock(bgp_distance_table[afi][safi]);
13827 bgp_distance_table[afi][safi] = NULL;
13828 }
13829 }