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