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