]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
*: remove null check before XFREE
[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 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
4468 route_map_counter_decrement(bgp_static->rmap.map);
4469
4470 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
4471 XFREE(MTYPE_BGP_STATIC, bgp_static);
4472 }
4473
4474 void bgp_static_update(struct bgp *bgp, struct prefix *p,
4475 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
4476 {
4477 struct bgp_node *rn;
4478 struct bgp_path_info *pi;
4479 struct bgp_path_info *new;
4480 struct bgp_path_info rmap_path;
4481 struct attr attr;
4482 struct attr *attr_new;
4483 int ret;
4484 #if ENABLE_BGP_VNC
4485 int vnc_implicit_withdraw = 0;
4486 #endif
4487
4488 assert(bgp_static);
4489 if (!bgp_static)
4490 return;
4491
4492 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
4493
4494 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
4495
4496 attr.nexthop = bgp_static->igpnexthop;
4497 attr.med = bgp_static->igpmetric;
4498 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
4499
4500 if (bgp_static->atomic)
4501 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
4502
4503 /* Store label index, if required. */
4504 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
4505 attr.label_index = bgp_static->label_index;
4506 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
4507 }
4508
4509 /* Apply route-map. */
4510 if (bgp_static->rmap.name) {
4511 struct attr attr_tmp = attr;
4512
4513 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
4514 rmap_path.peer = bgp->peer_self;
4515 rmap_path.attr = &attr_tmp;
4516
4517 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
4518
4519 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
4520 &rmap_path);
4521
4522 bgp->peer_self->rmap_type = 0;
4523
4524 if (ret == RMAP_DENYMATCH) {
4525 /* Free uninterned attribute. */
4526 bgp_attr_flush(&attr_tmp);
4527
4528 /* Unintern original. */
4529 aspath_unintern(&attr.aspath);
4530 bgp_static_withdraw(bgp, p, afi, safi);
4531 return;
4532 }
4533
4534 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
4535 bgp_attr_add_gshut_community(&attr_tmp);
4536
4537 attr_new = bgp_attr_intern(&attr_tmp);
4538 } else {
4539
4540 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
4541 bgp_attr_add_gshut_community(&attr);
4542
4543 attr_new = bgp_attr_intern(&attr);
4544 }
4545
4546 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4547 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4548 && pi->sub_type == BGP_ROUTE_STATIC)
4549 break;
4550
4551 if (pi) {
4552 if (attrhash_cmp(pi->attr, attr_new)
4553 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4554 && !bgp_flag_check(bgp, BGP_FLAG_FORCE_STATIC_PROCESS)) {
4555 bgp_unlock_node(rn);
4556 bgp_attr_unintern(&attr_new);
4557 aspath_unintern(&attr.aspath);
4558 return;
4559 } else {
4560 /* The attribute is changed. */
4561 bgp_path_info_set_flag(rn, pi, BGP_PATH_ATTR_CHANGED);
4562
4563 /* Rewrite BGP route information. */
4564 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
4565 bgp_path_info_restore(rn, pi);
4566 else
4567 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4568 #if ENABLE_BGP_VNC
4569 if ((afi == AFI_IP || afi == AFI_IP6)
4570 && (safi == SAFI_UNICAST)) {
4571 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4572 /*
4573 * Implicit withdraw case.
4574 * We have to do this before pi is
4575 * changed
4576 */
4577 ++vnc_implicit_withdraw;
4578 vnc_import_bgp_del_route(bgp, p, pi);
4579 vnc_import_bgp_exterior_del_route(
4580 bgp, p, pi);
4581 }
4582 }
4583 #endif
4584 bgp_attr_unintern(&pi->attr);
4585 pi->attr = attr_new;
4586 pi->uptime = bgp_clock();
4587 #if ENABLE_BGP_VNC
4588 if ((afi == AFI_IP || afi == AFI_IP6)
4589 && (safi == SAFI_UNICAST)) {
4590 if (vnc_implicit_withdraw) {
4591 vnc_import_bgp_add_route(bgp, p, pi);
4592 vnc_import_bgp_exterior_add_route(
4593 bgp, p, pi);
4594 }
4595 }
4596 #endif
4597
4598 /* Nexthop reachability check. */
4599 if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
4600 && (safi == SAFI_UNICAST
4601 || safi == SAFI_LABELED_UNICAST)) {
4602
4603 struct bgp *bgp_nexthop = bgp;
4604
4605 if (pi->extra && pi->extra->bgp_orig)
4606 bgp_nexthop = pi->extra->bgp_orig;
4607
4608 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
4609 afi, pi, NULL, 0))
4610 bgp_path_info_set_flag(rn, pi,
4611 BGP_PATH_VALID);
4612 else {
4613 if (BGP_DEBUG(nht, NHT)) {
4614 char buf1[INET6_ADDRSTRLEN];
4615 inet_ntop(p->family,
4616 &p->u.prefix, buf1,
4617 INET6_ADDRSTRLEN);
4618 zlog_debug(
4619 "%s(%s): Route not in table, not advertising",
4620 __FUNCTION__, buf1);
4621 }
4622 bgp_path_info_unset_flag(
4623 rn, pi, BGP_PATH_VALID);
4624 }
4625 } else {
4626 /* Delete the NHT structure if any, if we're
4627 * toggling between
4628 * enabling/disabling import check. We
4629 * deregister the route
4630 * from NHT to avoid overloading NHT and the
4631 * process interaction
4632 */
4633 bgp_unlink_nexthop(pi);
4634 bgp_path_info_set_flag(rn, pi, BGP_PATH_VALID);
4635 }
4636 /* Process change. */
4637 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4638 bgp_process(bgp, rn, afi, safi);
4639
4640 if (SAFI_UNICAST == safi
4641 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4642 || bgp->inst_type
4643 == BGP_INSTANCE_TYPE_DEFAULT)) {
4644 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
4645 pi);
4646 }
4647
4648 bgp_unlock_node(rn);
4649 aspath_unintern(&attr.aspath);
4650 return;
4651 }
4652 }
4653
4654 /* Make new BGP info. */
4655 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
4656 attr_new, rn);
4657 /* Nexthop reachability check. */
4658 if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
4659 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
4660 if (bgp_find_or_add_nexthop(bgp, bgp, afi, new, NULL, 0))
4661 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
4662 else {
4663 if (BGP_DEBUG(nht, NHT)) {
4664 char buf1[INET6_ADDRSTRLEN];
4665 inet_ntop(p->family, &p->u.prefix, buf1,
4666 INET6_ADDRSTRLEN);
4667 zlog_debug(
4668 "%s(%s): Route not in table, not advertising",
4669 __FUNCTION__, buf1);
4670 }
4671 bgp_path_info_unset_flag(rn, new, BGP_PATH_VALID);
4672 }
4673 } else {
4674 /* Delete the NHT structure if any, if we're toggling between
4675 * enabling/disabling import check. We deregister the route
4676 * from NHT to avoid overloading NHT and the process interaction
4677 */
4678 bgp_unlink_nexthop(new);
4679
4680 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
4681 }
4682
4683 /* Aggregate address increment. */
4684 bgp_aggregate_increment(bgp, p, new, afi, safi);
4685
4686 /* Register new BGP information. */
4687 bgp_path_info_add(rn, new);
4688
4689 /* route_node_get lock */
4690 bgp_unlock_node(rn);
4691
4692 /* Process change. */
4693 bgp_process(bgp, rn, afi, safi);
4694
4695 if (SAFI_UNICAST == safi
4696 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4697 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4698 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4699 }
4700
4701 /* Unintern original. */
4702 aspath_unintern(&attr.aspath);
4703 }
4704
4705 void bgp_static_withdraw(struct bgp *bgp, struct prefix *p, afi_t afi,
4706 safi_t safi)
4707 {
4708 struct bgp_node *rn;
4709 struct bgp_path_info *pi;
4710
4711 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
4712
4713 /* Check selected route and self inserted route. */
4714 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4715 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4716 && pi->sub_type == BGP_ROUTE_STATIC)
4717 break;
4718
4719 /* Withdraw static BGP route from routing table. */
4720 if (pi) {
4721 if (SAFI_UNICAST == safi
4722 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4723 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4724 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4725 }
4726 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4727 bgp_unlink_nexthop(pi);
4728 bgp_path_info_delete(rn, pi);
4729 bgp_process(bgp, rn, afi, safi);
4730 }
4731
4732 /* Unlock bgp_node_lookup. */
4733 bgp_unlock_node(rn);
4734 }
4735
4736 /*
4737 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4738 */
4739 static void bgp_static_withdraw_safi(struct bgp *bgp, struct prefix *p,
4740 afi_t afi, safi_t safi,
4741 struct prefix_rd *prd)
4742 {
4743 struct bgp_node *rn;
4744 struct bgp_path_info *pi;
4745
4746 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4747
4748 /* Check selected route and self inserted route. */
4749 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4750 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4751 && pi->sub_type == BGP_ROUTE_STATIC)
4752 break;
4753
4754 /* Withdraw static BGP route from routing table. */
4755 if (pi) {
4756 #if ENABLE_BGP_VNC
4757 rfapiProcessWithdraw(
4758 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
4759 1); /* Kill, since it is an administrative change */
4760 #endif
4761 if (SAFI_MPLS_VPN == safi
4762 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4763 vpn_leak_to_vrf_withdraw(bgp, pi);
4764 }
4765 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4766 bgp_path_info_delete(rn, pi);
4767 bgp_process(bgp, rn, afi, safi);
4768 }
4769
4770 /* Unlock bgp_node_lookup. */
4771 bgp_unlock_node(rn);
4772 }
4773
4774 static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p,
4775 struct bgp_static *bgp_static, afi_t afi,
4776 safi_t safi)
4777 {
4778 struct bgp_node *rn;
4779 struct bgp_path_info *new;
4780 struct attr *attr_new;
4781 struct attr attr = {0};
4782 struct bgp_path_info *pi;
4783 #if ENABLE_BGP_VNC
4784 mpls_label_t label = 0;
4785 #endif
4786 uint32_t num_labels = 0;
4787 union gw_addr add;
4788
4789 assert(bgp_static);
4790
4791 if (bgp_static->label != MPLS_INVALID_LABEL)
4792 num_labels = 1;
4793 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
4794 &bgp_static->prd);
4795
4796 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
4797
4798 attr.nexthop = bgp_static->igpnexthop;
4799 attr.med = bgp_static->igpmetric;
4800 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
4801
4802 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
4803 || (safi == SAFI_ENCAP)) {
4804 if (afi == AFI_IP) {
4805 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
4806 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
4807 }
4808 }
4809 if (afi == AFI_L2VPN) {
4810 if (bgp_static->gatewayIp.family == AF_INET)
4811 add.ipv4.s_addr =
4812 bgp_static->gatewayIp.u.prefix4.s_addr;
4813 else if (bgp_static->gatewayIp.family == AF_INET6)
4814 memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
4815 sizeof(struct in6_addr));
4816 overlay_index_update(&attr, bgp_static->eth_s_id, &add);
4817 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
4818 struct bgp_encap_type_vxlan bet;
4819 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
4820 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
4821 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
4822 }
4823 if (bgp_static->router_mac) {
4824 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
4825 }
4826 }
4827 /* Apply route-map. */
4828 if (bgp_static->rmap.name) {
4829 struct attr attr_tmp = attr;
4830 struct bgp_path_info rmap_path;
4831 int ret;
4832
4833 rmap_path.peer = bgp->peer_self;
4834 rmap_path.attr = &attr_tmp;
4835
4836 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
4837
4838 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
4839 &rmap_path);
4840
4841 bgp->peer_self->rmap_type = 0;
4842
4843 if (ret == RMAP_DENYMATCH) {
4844 /* Free uninterned attribute. */
4845 bgp_attr_flush(&attr_tmp);
4846
4847 /* Unintern original. */
4848 aspath_unintern(&attr.aspath);
4849 bgp_static_withdraw_safi(bgp, p, afi, safi,
4850 &bgp_static->prd);
4851 return;
4852 }
4853
4854 attr_new = bgp_attr_intern(&attr_tmp);
4855 } else {
4856 attr_new = bgp_attr_intern(&attr);
4857 }
4858
4859 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4860 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4861 && pi->sub_type == BGP_ROUTE_STATIC)
4862 break;
4863
4864 if (pi) {
4865 memset(&add, 0, sizeof(union gw_addr));
4866 if (attrhash_cmp(pi->attr, attr_new)
4867 && overlay_index_equal(afi, pi, bgp_static->eth_s_id, &add)
4868 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4869 bgp_unlock_node(rn);
4870 bgp_attr_unintern(&attr_new);
4871 aspath_unintern(&attr.aspath);
4872 return;
4873 } else {
4874 /* The attribute is changed. */
4875 bgp_path_info_set_flag(rn, pi, BGP_PATH_ATTR_CHANGED);
4876
4877 /* Rewrite BGP route information. */
4878 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
4879 bgp_path_info_restore(rn, pi);
4880 else
4881 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4882 bgp_attr_unintern(&pi->attr);
4883 pi->attr = attr_new;
4884 pi->uptime = bgp_clock();
4885 #if ENABLE_BGP_VNC
4886 if (pi->extra)
4887 label = decode_label(&pi->extra->label[0]);
4888 #endif
4889
4890 /* Process change. */
4891 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4892 bgp_process(bgp, rn, afi, safi);
4893
4894 if (SAFI_MPLS_VPN == safi
4895 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4896 vpn_leak_to_vrf_update(bgp, pi);
4897 }
4898 #if ENABLE_BGP_VNC
4899 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
4900 pi->attr, afi, safi, pi->type,
4901 pi->sub_type, &label);
4902 #endif
4903 bgp_unlock_node(rn);
4904 aspath_unintern(&attr.aspath);
4905 return;
4906 }
4907 }
4908
4909
4910 /* Make new BGP info. */
4911 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
4912 attr_new, rn);
4913 SET_FLAG(new->flags, BGP_PATH_VALID);
4914 new->extra = bgp_path_info_extra_new();
4915 if (num_labels) {
4916 new->extra->label[0] = bgp_static->label;
4917 new->extra->num_labels = num_labels;
4918 }
4919 #if ENABLE_BGP_VNC
4920 label = decode_label(&bgp_static->label);
4921 #endif
4922
4923 /* Aggregate address increment. */
4924 bgp_aggregate_increment(bgp, p, new, afi, safi);
4925
4926 /* Register new BGP information. */
4927 bgp_path_info_add(rn, new);
4928 /* route_node_get lock */
4929 bgp_unlock_node(rn);
4930
4931 /* Process change. */
4932 bgp_process(bgp, rn, afi, safi);
4933
4934 if (SAFI_MPLS_VPN == safi
4935 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4936 vpn_leak_to_vrf_update(bgp, new);
4937 }
4938 #if ENABLE_BGP_VNC
4939 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
4940 safi, new->type, new->sub_type, &label);
4941 #endif
4942
4943 /* Unintern original. */
4944 aspath_unintern(&attr.aspath);
4945 }
4946
4947 /* Configure static BGP network. When user don't run zebra, static
4948 route should be installed as valid. */
4949 static int bgp_static_set(struct vty *vty, const char *negate,
4950 const char *ip_str, afi_t afi, safi_t safi,
4951 const char *rmap, int backdoor, uint32_t label_index)
4952 {
4953 VTY_DECLVAR_CONTEXT(bgp, bgp);
4954 int ret;
4955 struct prefix p;
4956 struct bgp_static *bgp_static;
4957 struct bgp_node *rn;
4958 uint8_t need_update = 0;
4959
4960 /* Convert IP prefix string to struct prefix. */
4961 ret = str2prefix(ip_str, &p);
4962 if (!ret) {
4963 vty_out(vty, "%% Malformed prefix\n");
4964 return CMD_WARNING_CONFIG_FAILED;
4965 }
4966 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
4967 vty_out(vty, "%% Malformed prefix (link-local address)\n");
4968 return CMD_WARNING_CONFIG_FAILED;
4969 }
4970
4971 apply_mask(&p);
4972
4973 if (negate) {
4974
4975 /* Set BGP static route configuration. */
4976 rn = bgp_node_lookup(bgp->route[afi][safi], &p);
4977
4978 if (!rn) {
4979 vty_out(vty, "%% Can't find static route specified\n");
4980 return CMD_WARNING_CONFIG_FAILED;
4981 }
4982
4983 bgp_static = bgp_node_get_bgp_static_info(rn);
4984
4985 if ((label_index != BGP_INVALID_LABEL_INDEX)
4986 && (label_index != bgp_static->label_index)) {
4987 vty_out(vty,
4988 "%% label-index doesn't match static route\n");
4989 return CMD_WARNING_CONFIG_FAILED;
4990 }
4991
4992 if ((rmap && bgp_static->rmap.name)
4993 && strcmp(rmap, bgp_static->rmap.name)) {
4994 vty_out(vty,
4995 "%% route-map name doesn't match static route\n");
4996 return CMD_WARNING_CONFIG_FAILED;
4997 }
4998
4999 /* Update BGP RIB. */
5000 if (!bgp_static->backdoor)
5001 bgp_static_withdraw(bgp, &p, afi, safi);
5002
5003 /* Clear configuration. */
5004 bgp_static_free(bgp_static);
5005 bgp_node_set_bgp_static_info(rn, NULL);
5006 bgp_unlock_node(rn);
5007 bgp_unlock_node(rn);
5008 } else {
5009
5010 /* Set BGP static route configuration. */
5011 rn = bgp_node_get(bgp->route[afi][safi], &p);
5012
5013 bgp_static = bgp_node_get_bgp_static_info(rn);
5014 if (bgp_static) {
5015 /* Configuration change. */
5016 /* Label index cannot be changed. */
5017 if (bgp_static->label_index != label_index) {
5018 vty_out(vty, "%% cannot change label-index\n");
5019 return CMD_WARNING_CONFIG_FAILED;
5020 }
5021
5022 /* Check previous routes are installed into BGP. */
5023 if (bgp_static->valid
5024 && bgp_static->backdoor != backdoor)
5025 need_update = 1;
5026
5027 bgp_static->backdoor = backdoor;
5028
5029 if (rmap) {
5030 XFREE(MTYPE_ROUTE_MAP_NAME,
5031 bgp_static->rmap.name);
5032 route_map_counter_decrement(
5033 bgp_static->rmap.map);
5034 bgp_static->rmap.name =
5035 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5036 bgp_static->rmap.map =
5037 route_map_lookup_by_name(rmap);
5038 route_map_counter_increment(
5039 bgp_static->rmap.map);
5040 } else {
5041 XFREE(MTYPE_ROUTE_MAP_NAME,
5042 bgp_static->rmap.name);
5043 route_map_counter_decrement(
5044 bgp_static->rmap.map);
5045 bgp_static->rmap.name = NULL;
5046 bgp_static->rmap.map = NULL;
5047 bgp_static->valid = 0;
5048 }
5049 bgp_unlock_node(rn);
5050 } else {
5051 /* New configuration. */
5052 bgp_static = bgp_static_new();
5053 bgp_static->backdoor = backdoor;
5054 bgp_static->valid = 0;
5055 bgp_static->igpmetric = 0;
5056 bgp_static->igpnexthop.s_addr = 0;
5057 bgp_static->label_index = label_index;
5058
5059 if (rmap) {
5060 XFREE(MTYPE_ROUTE_MAP_NAME,
5061 bgp_static->rmap.name);
5062 route_map_counter_decrement(
5063 bgp_static->rmap.map);
5064 bgp_static->rmap.name =
5065 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5066 bgp_static->rmap.map =
5067 route_map_lookup_by_name(rmap);
5068 route_map_counter_increment(
5069 bgp_static->rmap.map);
5070 }
5071 bgp_node_set_bgp_static_info(rn, bgp_static);
5072 }
5073
5074 bgp_static->valid = 1;
5075 if (need_update)
5076 bgp_static_withdraw(bgp, &p, afi, safi);
5077
5078 if (!bgp_static->backdoor)
5079 bgp_static_update(bgp, &p, bgp_static, afi, safi);
5080 }
5081
5082 return CMD_SUCCESS;
5083 }
5084
5085 void bgp_static_add(struct bgp *bgp)
5086 {
5087 afi_t afi;
5088 safi_t safi;
5089 struct bgp_node *rn;
5090 struct bgp_node *rm;
5091 struct bgp_table *table;
5092 struct bgp_static *bgp_static;
5093
5094 FOREACH_AFI_SAFI (afi, safi)
5095 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5096 rn = bgp_route_next(rn)) {
5097 if (!bgp_node_has_bgp_path_info_data(rn))
5098 continue;
5099
5100 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5101 || (safi == SAFI_EVPN)) {
5102 table = bgp_node_get_bgp_table_info(rn);
5103
5104 for (rm = bgp_table_top(table); rm;
5105 rm = bgp_route_next(rm)) {
5106 bgp_static =
5107 bgp_node_get_bgp_static_info(
5108 rm);
5109 bgp_static_update_safi(bgp, &rm->p,
5110 bgp_static, afi,
5111 safi);
5112 }
5113 } else {
5114 bgp_static_update(
5115 bgp, &rn->p,
5116 bgp_node_get_bgp_static_info(rn), afi,
5117 safi);
5118 }
5119 }
5120 }
5121
5122 /* Called from bgp_delete(). Delete all static routes from the BGP
5123 instance. */
5124 void bgp_static_delete(struct bgp *bgp)
5125 {
5126 afi_t afi;
5127 safi_t safi;
5128 struct bgp_node *rn;
5129 struct bgp_node *rm;
5130 struct bgp_table *table;
5131 struct bgp_static *bgp_static;
5132
5133 FOREACH_AFI_SAFI (afi, safi)
5134 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5135 rn = bgp_route_next(rn)) {
5136 if (!bgp_node_has_bgp_path_info_data(rn))
5137 continue;
5138
5139 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5140 || (safi == SAFI_EVPN)) {
5141 table = bgp_node_get_bgp_table_info(rn);
5142
5143 for (rm = bgp_table_top(table); rm;
5144 rm = bgp_route_next(rm)) {
5145 bgp_static =
5146 bgp_node_get_bgp_static_info(
5147 rm);
5148 if (!bgp_static)
5149 continue;
5150
5151 bgp_static_withdraw_safi(
5152 bgp, &rm->p, AFI_IP, safi,
5153 (struct prefix_rd *)&rn->p);
5154 bgp_static_free(bgp_static);
5155 bgp_node_set_bgp_static_info(rn, NULL);
5156 bgp_unlock_node(rn);
5157 }
5158 } else {
5159 bgp_static = bgp_node_get_bgp_static_info(rn);
5160 bgp_static_withdraw(bgp, &rn->p, afi, safi);
5161 bgp_static_free(bgp_static);
5162 bgp_node_set_bgp_static_info(rn, NULL);
5163 bgp_unlock_node(rn);
5164 }
5165 }
5166 }
5167
5168 void bgp_static_redo_import_check(struct bgp *bgp)
5169 {
5170 afi_t afi;
5171 safi_t safi;
5172 struct bgp_node *rn;
5173 struct bgp_node *rm;
5174 struct bgp_table *table;
5175 struct bgp_static *bgp_static;
5176
5177 /* Use this flag to force reprocessing of the route */
5178 bgp_flag_set(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
5179 FOREACH_AFI_SAFI (afi, safi) {
5180 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5181 rn = bgp_route_next(rn)) {
5182 if (!bgp_node_has_bgp_path_info_data(rn))
5183 continue;
5184
5185 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5186 || (safi == SAFI_EVPN)) {
5187 table = bgp_node_get_bgp_table_info(rn);
5188
5189 for (rm = bgp_table_top(table); rm;
5190 rm = bgp_route_next(rm)) {
5191 bgp_static =
5192 bgp_node_get_bgp_static_info(
5193 rm);
5194 bgp_static_update_safi(bgp, &rm->p,
5195 bgp_static, afi,
5196 safi);
5197 }
5198 } else {
5199 bgp_static = bgp_node_get_bgp_static_info(rn);
5200 bgp_static_update(bgp, &rn->p, bgp_static, afi,
5201 safi);
5202 }
5203 }
5204 }
5205 bgp_flag_unset(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
5206 }
5207
5208 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
5209 safi_t safi)
5210 {
5211 struct bgp_table *table;
5212 struct bgp_node *rn;
5213 struct bgp_path_info *pi;
5214
5215 table = bgp->rib[afi][safi];
5216 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
5217 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
5218 if (pi->peer == bgp->peer_self
5219 && ((pi->type == ZEBRA_ROUTE_BGP
5220 && pi->sub_type == BGP_ROUTE_STATIC)
5221 || (pi->type != ZEBRA_ROUTE_BGP
5222 && pi->sub_type
5223 == BGP_ROUTE_REDISTRIBUTE))) {
5224 bgp_aggregate_decrement(bgp, &rn->p, pi, afi,
5225 safi);
5226 bgp_unlink_nexthop(pi);
5227 bgp_path_info_delete(rn, pi);
5228 bgp_process(bgp, rn, afi, safi);
5229 }
5230 }
5231 }
5232 }
5233
5234 /*
5235 * Purge all networks and redistributed routes from routing table.
5236 * Invoked upon the instance going down.
5237 */
5238 void bgp_purge_static_redist_routes(struct bgp *bgp)
5239 {
5240 afi_t afi;
5241 safi_t safi;
5242
5243 FOREACH_AFI_SAFI (afi, safi)
5244 bgp_purge_af_static_redist_routes(bgp, afi, safi);
5245 }
5246
5247 /*
5248 * gpz 110624
5249 * Currently this is used to set static routes for VPN and ENCAP.
5250 * I think it can probably be factored with bgp_static_set.
5251 */
5252 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
5253 const char *ip_str, const char *rd_str,
5254 const char *label_str, const char *rmap_str,
5255 int evpn_type, const char *esi, const char *gwip,
5256 const char *ethtag, const char *routermac)
5257 {
5258 VTY_DECLVAR_CONTEXT(bgp, bgp);
5259 int ret;
5260 struct prefix p;
5261 struct prefix_rd prd;
5262 struct bgp_node *prn;
5263 struct bgp_node *rn;
5264 struct bgp_table *table;
5265 struct bgp_static *bgp_static;
5266 mpls_label_t label = MPLS_INVALID_LABEL;
5267 struct prefix gw_ip;
5268
5269 /* validate ip prefix */
5270 ret = str2prefix(ip_str, &p);
5271 if (!ret) {
5272 vty_out(vty, "%% Malformed prefix\n");
5273 return CMD_WARNING_CONFIG_FAILED;
5274 }
5275 apply_mask(&p);
5276 if ((afi == AFI_L2VPN)
5277 && (bgp_build_evpn_prefix(evpn_type,
5278 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5279 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5280 return CMD_WARNING_CONFIG_FAILED;
5281 }
5282
5283 ret = str2prefix_rd(rd_str, &prd);
5284 if (!ret) {
5285 vty_out(vty, "%% Malformed rd\n");
5286 return CMD_WARNING_CONFIG_FAILED;
5287 }
5288
5289 if (label_str) {
5290 unsigned long label_val;
5291 label_val = strtoul(label_str, NULL, 10);
5292 encode_label(label_val, &label);
5293 }
5294
5295 if (safi == SAFI_EVPN) {
5296 if (esi && str2esi(esi, NULL) == 0) {
5297 vty_out(vty, "%% Malformed ESI\n");
5298 return CMD_WARNING_CONFIG_FAILED;
5299 }
5300 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
5301 vty_out(vty, "%% Malformed Router MAC\n");
5302 return CMD_WARNING_CONFIG_FAILED;
5303 }
5304 if (gwip) {
5305 memset(&gw_ip, 0, sizeof(struct prefix));
5306 ret = str2prefix(gwip, &gw_ip);
5307 if (!ret) {
5308 vty_out(vty, "%% Malformed GatewayIp\n");
5309 return CMD_WARNING_CONFIG_FAILED;
5310 }
5311 if ((gw_ip.family == AF_INET
5312 && is_evpn_prefix_ipaddr_v6(
5313 (struct prefix_evpn *)&p))
5314 || (gw_ip.family == AF_INET6
5315 && is_evpn_prefix_ipaddr_v4(
5316 (struct prefix_evpn *)&p))) {
5317 vty_out(vty,
5318 "%% GatewayIp family differs with IP prefix\n");
5319 return CMD_WARNING_CONFIG_FAILED;
5320 }
5321 }
5322 }
5323 prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5324 if (!bgp_node_has_bgp_path_info_data(prn))
5325 bgp_node_set_bgp_table_info(prn,
5326 bgp_table_init(bgp, afi, safi));
5327 table = bgp_node_get_bgp_table_info(prn);
5328
5329 rn = bgp_node_get(table, &p);
5330
5331 if (bgp_node_has_bgp_path_info_data(rn)) {
5332 vty_out(vty, "%% Same network configuration exists\n");
5333 bgp_unlock_node(rn);
5334 } else {
5335 /* New configuration. */
5336 bgp_static = bgp_static_new();
5337 bgp_static->backdoor = 0;
5338 bgp_static->valid = 0;
5339 bgp_static->igpmetric = 0;
5340 bgp_static->igpnexthop.s_addr = 0;
5341 bgp_static->label = label;
5342 bgp_static->prd = prd;
5343
5344 if (rmap_str) {
5345 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5346 route_map_counter_decrement(bgp_static->rmap.map);
5347 bgp_static->rmap.name =
5348 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
5349 bgp_static->rmap.map =
5350 route_map_lookup_by_name(rmap_str);
5351 route_map_counter_increment(bgp_static->rmap.map);
5352 }
5353
5354 if (safi == SAFI_EVPN) {
5355 if (esi) {
5356 bgp_static->eth_s_id =
5357 XCALLOC(MTYPE_ATTR,
5358 sizeof(struct eth_segment_id));
5359 str2esi(esi, bgp_static->eth_s_id);
5360 }
5361 if (routermac) {
5362 bgp_static->router_mac =
5363 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
5364 (void)prefix_str2mac(routermac,
5365 bgp_static->router_mac);
5366 }
5367 if (gwip)
5368 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
5369 }
5370 bgp_node_set_bgp_static_info(rn, bgp_static);
5371
5372 bgp_static->valid = 1;
5373 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
5374 }
5375
5376 return CMD_SUCCESS;
5377 }
5378
5379 /* Configure static BGP network. */
5380 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
5381 const char *ip_str, const char *rd_str,
5382 const char *label_str, int evpn_type, const char *esi,
5383 const char *gwip, const char *ethtag)
5384 {
5385 VTY_DECLVAR_CONTEXT(bgp, bgp);
5386 int ret;
5387 struct prefix p;
5388 struct prefix_rd prd;
5389 struct bgp_node *prn;
5390 struct bgp_node *rn;
5391 struct bgp_table *table;
5392 struct bgp_static *bgp_static;
5393 mpls_label_t label = MPLS_INVALID_LABEL;
5394
5395 /* Convert IP prefix string to struct prefix. */
5396 ret = str2prefix(ip_str, &p);
5397 if (!ret) {
5398 vty_out(vty, "%% Malformed prefix\n");
5399 return CMD_WARNING_CONFIG_FAILED;
5400 }
5401 apply_mask(&p);
5402 if ((afi == AFI_L2VPN)
5403 && (bgp_build_evpn_prefix(evpn_type,
5404 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5405 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5406 return CMD_WARNING_CONFIG_FAILED;
5407 }
5408 ret = str2prefix_rd(rd_str, &prd);
5409 if (!ret) {
5410 vty_out(vty, "%% Malformed rd\n");
5411 return CMD_WARNING_CONFIG_FAILED;
5412 }
5413
5414 if (label_str) {
5415 unsigned long label_val;
5416 label_val = strtoul(label_str, NULL, 10);
5417 encode_label(label_val, &label);
5418 }
5419
5420 prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5421 if (!bgp_node_has_bgp_path_info_data(prn))
5422 bgp_node_set_bgp_table_info(prn,
5423 bgp_table_init(bgp, afi, safi));
5424 else
5425 bgp_unlock_node(prn);
5426 table = bgp_node_get_bgp_table_info(prn);
5427
5428 rn = bgp_node_lookup(table, &p);
5429
5430 if (rn) {
5431 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
5432
5433 bgp_static = bgp_node_get_bgp_static_info(rn);
5434 bgp_static_free(bgp_static);
5435 bgp_node_set_bgp_static_info(rn, NULL);
5436 bgp_unlock_node(rn);
5437 bgp_unlock_node(rn);
5438 } else
5439 vty_out(vty, "%% Can't find the route\n");
5440
5441 return CMD_SUCCESS;
5442 }
5443
5444 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
5445 const char *rmap_name)
5446 {
5447 VTY_DECLVAR_CONTEXT(bgp, bgp);
5448 struct bgp_rmap *rmap;
5449
5450 rmap = &bgp->table_map[afi][safi];
5451 if (rmap_name) {
5452 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5453 route_map_counter_decrement(rmap->map);
5454 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
5455 rmap->map = route_map_lookup_by_name(rmap_name);
5456 route_map_counter_increment(rmap->map);
5457 } else {
5458 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5459 route_map_counter_decrement(rmap->map);
5460 rmap->name = NULL;
5461 rmap->map = NULL;
5462 }
5463
5464 if (bgp_fibupd_safi(safi))
5465 bgp_zebra_announce_table(bgp, afi, safi);
5466
5467 return CMD_SUCCESS;
5468 }
5469
5470 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
5471 const char *rmap_name)
5472 {
5473 VTY_DECLVAR_CONTEXT(bgp, bgp);
5474 struct bgp_rmap *rmap;
5475
5476 rmap = &bgp->table_map[afi][safi];
5477 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5478 route_map_counter_decrement(rmap->map);
5479 rmap->name = NULL;
5480 rmap->map = NULL;
5481
5482 if (bgp_fibupd_safi(safi))
5483 bgp_zebra_announce_table(bgp, afi, safi);
5484
5485 return CMD_SUCCESS;
5486 }
5487
5488 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
5489 safi_t safi)
5490 {
5491 if (bgp->table_map[afi][safi].name) {
5492 vty_out(vty, " table-map %s\n",
5493 bgp->table_map[afi][safi].name);
5494 }
5495 }
5496
5497 DEFUN (bgp_table_map,
5498 bgp_table_map_cmd,
5499 "table-map WORD",
5500 "BGP table to RIB route download filter\n"
5501 "Name of the route map\n")
5502 {
5503 int idx_word = 1;
5504 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
5505 argv[idx_word]->arg);
5506 }
5507 DEFUN (no_bgp_table_map,
5508 no_bgp_table_map_cmd,
5509 "no table-map WORD",
5510 NO_STR
5511 "BGP table to RIB route download filter\n"
5512 "Name of the route map\n")
5513 {
5514 int idx_word = 2;
5515 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
5516 argv[idx_word]->arg);
5517 }
5518
5519 DEFPY(bgp_network,
5520 bgp_network_cmd,
5521 "[no] network \
5522 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
5523 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
5524 backdoor$backdoor}]",
5525 NO_STR
5526 "Specify a network to announce via BGP\n"
5527 "IPv4 prefix\n"
5528 "Network number\n"
5529 "Network mask\n"
5530 "Network mask\n"
5531 "Route-map to modify the attributes\n"
5532 "Name of the route map\n"
5533 "Label index to associate with the prefix\n"
5534 "Label index value\n"
5535 "Specify a BGP backdoor route\n")
5536 {
5537 char addr_prefix_str[BUFSIZ];
5538
5539 if (address_str) {
5540 int ret;
5541
5542 ret = netmask_str2prefix_str(address_str, netmask_str,
5543 addr_prefix_str);
5544 if (!ret) {
5545 vty_out(vty, "%% Inconsistent address and mask\n");
5546 return CMD_WARNING_CONFIG_FAILED;
5547 }
5548 }
5549
5550 return bgp_static_set(
5551 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
5552 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
5553 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
5554 }
5555
5556 DEFPY(ipv6_bgp_network,
5557 ipv6_bgp_network_cmd,
5558 "[no] network X:X::X:X/M$prefix \
5559 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
5560 NO_STR
5561 "Specify a network to announce via BGP\n"
5562 "IPv6 prefix\n"
5563 "Route-map to modify the attributes\n"
5564 "Name of the route map\n"
5565 "Label index to associate with the prefix\n"
5566 "Label index value\n")
5567 {
5568 return bgp_static_set(
5569 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
5570 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
5571 }
5572
5573 /* Aggreagete address:
5574
5575 advertise-map Set condition to advertise attribute
5576 as-set Generate AS set path information
5577 attribute-map Set attributes of aggregate
5578 route-map Set parameters of aggregate
5579 summary-only Filter more specific routes from updates
5580 suppress-map Conditionally filter more specific routes from updates
5581 <cr>
5582 */
5583 struct bgp_aggregate {
5584 /* Summary-only flag. */
5585 uint8_t summary_only;
5586
5587 /* AS set generation. */
5588 uint8_t as_set;
5589
5590 /* Route-map for aggregated route. */
5591 struct route_map *map;
5592
5593 /* Suppress-count. */
5594 unsigned long count;
5595
5596 /* SAFI configuration. */
5597 safi_t safi;
5598 };
5599
5600 static struct bgp_aggregate *bgp_aggregate_new(void)
5601 {
5602 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
5603 }
5604
5605 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
5606 {
5607 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
5608 }
5609
5610 static int bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
5611 struct aspath *aspath,
5612 struct community *comm,
5613 struct ecommunity *ecomm,
5614 struct lcommunity *lcomm)
5615 {
5616 static struct aspath *ae = NULL;
5617
5618 if (!ae)
5619 ae = aspath_empty();
5620
5621 if (!pi)
5622 return 0;
5623
5624 if (origin != pi->attr->origin)
5625 return 0;
5626
5627 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
5628 return 0;
5629
5630 if (!community_cmp(pi->attr->community, comm))
5631 return 0;
5632
5633 if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
5634 return 0;
5635
5636 if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
5637 return 0;
5638
5639 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
5640 return 0;
5641
5642 return 1;
5643 }
5644
5645 static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
5646 struct prefix *p, uint8_t origin,
5647 struct aspath *aspath,
5648 struct community *community,
5649 struct ecommunity *ecommunity,
5650 struct lcommunity *lcommunity,
5651 uint8_t atomic_aggregate,
5652 struct bgp_aggregate *aggregate)
5653 {
5654 struct bgp_node *rn;
5655 struct bgp_table *table;
5656 struct bgp_path_info *pi, *orig, *new;
5657
5658 table = bgp->rib[afi][safi];
5659
5660 rn = bgp_node_get(table, p);
5661
5662 for (orig = pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
5663 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5664 && pi->sub_type == BGP_ROUTE_AGGREGATE)
5665 break;
5666
5667 if (aggregate->count > 0) {
5668 /*
5669 * If the aggregate information has not changed
5670 * no need to re-install it again.
5671 */
5672 if (bgp_aggregate_info_same(orig, origin, aspath, community,
5673 ecommunity, lcommunity)) {
5674 bgp_unlock_node(rn);
5675
5676 if (aspath)
5677 aspath_free(aspath);
5678 if (community)
5679 community_free(&community);
5680 if (ecommunity)
5681 ecommunity_free(&ecommunity);
5682 if (lcommunity)
5683 lcommunity_free(&lcommunity);
5684
5685 return;
5686 }
5687
5688 /*
5689 * Mark the old as unusable
5690 */
5691 if (pi)
5692 bgp_path_info_delete(rn, pi);
5693
5694 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
5695 bgp->peer_self,
5696 bgp_attr_aggregate_intern(bgp, origin, aspath,
5697 community, ecommunity,
5698 lcommunity,
5699 aggregate->as_set,
5700 atomic_aggregate),
5701 rn);
5702 SET_FLAG(new->flags, BGP_PATH_VALID);
5703
5704 bgp_path_info_add(rn, new);
5705 bgp_process(bgp, rn, afi, safi);
5706 } else {
5707 for (pi = orig; pi; pi = pi->next)
5708 if (pi->peer == bgp->peer_self
5709 && pi->type == ZEBRA_ROUTE_BGP
5710 && pi->sub_type == BGP_ROUTE_AGGREGATE)
5711 break;
5712
5713 /* Withdraw static BGP route from routing table. */
5714 if (pi) {
5715 bgp_path_info_delete(rn, pi);
5716 bgp_process(bgp, rn, afi, safi);
5717 }
5718 }
5719
5720 bgp_unlock_node(rn);
5721 }
5722
5723 /* Update an aggregate as routes are added/removed from the BGP table */
5724 static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
5725 struct bgp_path_info *pinew, afi_t afi,
5726 safi_t safi, struct bgp_path_info *del,
5727 struct bgp_aggregate *aggregate)
5728 {
5729 struct bgp_table *table;
5730 struct bgp_node *top;
5731 struct bgp_node *rn;
5732 uint8_t origin;
5733 struct aspath *aspath = NULL;
5734 struct aspath *asmerge = NULL;
5735 struct community *community = NULL;
5736 struct community *commerge = NULL;
5737 struct ecommunity *ecommunity = NULL;
5738 struct ecommunity *ecommerge = NULL;
5739 struct lcommunity *lcommunity = NULL;
5740 struct lcommunity *lcommerge = NULL;
5741 struct bgp_path_info *pi;
5742 unsigned long match = 0;
5743 uint8_t atomic_aggregate = 0;
5744
5745 /* ORIGIN attribute: If at least one route among routes that are
5746 aggregated has ORIGIN with the value INCOMPLETE, then the
5747 aggregated route must have the ORIGIN attribute with the value
5748 INCOMPLETE. Otherwise, if at least one route among routes that
5749 are aggregated has ORIGIN with the value EGP, then the aggregated
5750 route must have the origin attribute with the value EGP. In all
5751 other case the value of the ORIGIN attribute of the aggregated
5752 route is INTERNAL. */
5753 origin = BGP_ORIGIN_IGP;
5754
5755 table = bgp->rib[afi][safi];
5756
5757 top = bgp_node_get(table, p);
5758 for (rn = bgp_node_get(table, p); rn;
5759 rn = bgp_route_next_until(rn, top)) {
5760 if (rn->p.prefixlen <= p->prefixlen)
5761 continue;
5762
5763 match = 0;
5764
5765 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
5766 if (BGP_PATH_HOLDDOWN(pi))
5767 continue;
5768
5769 if (del && pi == del)
5770 continue;
5771
5772 if (pi->attr->flag
5773 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
5774 atomic_aggregate = 1;
5775
5776 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
5777 continue;
5778
5779 /*
5780 * summary-only aggregate route suppress
5781 * aggregated route announcements.
5782 */
5783 if (aggregate->summary_only) {
5784 (bgp_path_info_extra_get(pi))->suppress++;
5785 bgp_path_info_set_flag(rn, pi,
5786 BGP_PATH_ATTR_CHANGED);
5787 match++;
5788 }
5789
5790 aggregate->count++;
5791
5792 /*
5793 * If at least one route among routes that are
5794 * aggregated has ORIGIN with the value INCOMPLETE,
5795 * then the aggregated route MUST have the ORIGIN
5796 * attribute with the value INCOMPLETE. Otherwise, if
5797 * at least one route among routes that are aggregated
5798 * has ORIGIN with the value EGP, then the aggregated
5799 * route MUST have the ORIGIN attribute with the value
5800 * EGP.
5801 */
5802 if (origin < pi->attr->origin)
5803 origin = pi->attr->origin;
5804
5805 if (!aggregate->as_set)
5806 continue;
5807
5808 /*
5809 * as-set aggregate route generate origin, as path,
5810 * and community aggregation.
5811 */
5812 if (aspath) {
5813 asmerge = aspath_aggregate(aspath,
5814 pi->attr->aspath);
5815 aspath_free(aspath);
5816 aspath = asmerge;
5817 } else
5818 aspath = aspath_dup(pi->attr->aspath);
5819
5820 if (pi->attr->community) {
5821 if (community) {
5822 commerge = community_merge(
5823 community, pi->attr->community);
5824 community =
5825 community_uniq_sort(commerge);
5826 community_free(&commerge);
5827 } else
5828 community = community_dup(
5829 pi->attr->community);
5830 }
5831
5832 if (pi->attr->ecommunity) {
5833 if (ecommunity) {
5834 ecommerge = ecommunity_merge(
5835 ecommunity,
5836 pi->attr->ecommunity);
5837 ecommunity =
5838 ecommunity_uniq_sort(ecommerge);
5839 ecommunity_free(&ecommerge);
5840 } else
5841 ecommunity = ecommunity_dup(
5842 pi->attr->ecommunity);
5843 }
5844
5845 if (pi->attr->lcommunity) {
5846 if (lcommunity) {
5847 lcommerge = lcommunity_merge(
5848 lcommunity,
5849 pi->attr->lcommunity);
5850 lcommunity =
5851 lcommunity_uniq_sort(lcommerge);
5852 lcommunity_free(&lcommerge);
5853 } else
5854 lcommunity = lcommunity_dup(
5855 pi->attr->lcommunity);
5856 }
5857 }
5858 if (match)
5859 bgp_process(bgp, rn, afi, safi);
5860 }
5861 bgp_unlock_node(top);
5862
5863 if (pinew) {
5864 aggregate->count++;
5865
5866 if (aggregate->summary_only)
5867 (bgp_path_info_extra_get(pinew))->suppress++;
5868
5869 if (origin < pinew->attr->origin)
5870 origin = pinew->attr->origin;
5871
5872 if (aggregate->as_set) {
5873 if (aspath) {
5874 asmerge = aspath_aggregate(aspath,
5875 pinew->attr->aspath);
5876 aspath_free(aspath);
5877 aspath = asmerge;
5878 } else
5879 aspath = aspath_dup(pinew->attr->aspath);
5880
5881 if (pinew->attr->community) {
5882 if (community) {
5883 commerge = community_merge(
5884 community,
5885 pinew->attr->community);
5886 community =
5887 community_uniq_sort(commerge);
5888 community_free(&commerge);
5889 } else
5890 community = community_dup(
5891 pinew->attr->community);
5892 }
5893
5894 if (pinew->attr->ecommunity) {
5895 if (ecommunity) {
5896 ecommerge = ecommunity_merge(
5897 ecommunity,
5898 pinew->attr->ecommunity);
5899 ecommunity =
5900 ecommunity_uniq_sort(ecommerge);
5901 ecommunity_free(&ecommerge);
5902 } else
5903 ecommunity = ecommunity_dup(
5904 pinew->attr->ecommunity);
5905 }
5906
5907 if (pinew->attr->lcommunity) {
5908 if (lcommunity) {
5909 lcommerge = lcommunity_merge(
5910 lcommunity,
5911 pinew->attr->lcommunity);
5912 lcommunity =
5913 lcommunity_uniq_sort(lcommerge);
5914 lcommunity_free(&lcommerge);
5915 } else
5916 lcommunity = lcommunity_dup(
5917 pinew->attr->lcommunity);
5918 }
5919 }
5920 }
5921
5922 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
5923 ecommunity, lcommunity, atomic_aggregate,
5924 aggregate);
5925
5926 if (aggregate->count == 0) {
5927 if (aspath)
5928 aspath_free(aspath);
5929 if (community)
5930 community_free(&community);
5931 if (ecommunity)
5932 ecommunity_free(&ecommunity);
5933 if (lcommunity)
5934 lcommunity_free(&lcommunity);
5935 }
5936 }
5937
5938 static void bgp_aggregate_delete(struct bgp *bgp, struct prefix *p, afi_t afi,
5939 safi_t safi, struct bgp_aggregate *aggregate)
5940 {
5941 struct bgp_table *table;
5942 struct bgp_node *top;
5943 struct bgp_node *rn;
5944 struct bgp_path_info *pi;
5945 unsigned long match;
5946
5947 table = bgp->rib[afi][safi];
5948
5949 /* If routes exists below this node, generate aggregate routes. */
5950 top = bgp_node_get(table, p);
5951 for (rn = bgp_node_get(table, p); rn;
5952 rn = bgp_route_next_until(rn, top)) {
5953 if (rn->p.prefixlen <= p->prefixlen)
5954 continue;
5955 match = 0;
5956
5957 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
5958 if (BGP_PATH_HOLDDOWN(pi))
5959 continue;
5960
5961 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
5962 continue;
5963
5964 if (aggregate->summary_only && pi->extra) {
5965 pi->extra->suppress--;
5966
5967 if (pi->extra->suppress == 0) {
5968 bgp_path_info_set_flag(
5969 rn, pi, BGP_PATH_ATTR_CHANGED);
5970 match++;
5971 }
5972 }
5973 aggregate->count--;
5974 }
5975
5976 /* If this node was suppressed, process the change. */
5977 if (match)
5978 bgp_process(bgp, rn, afi, safi);
5979 }
5980 bgp_unlock_node(top);
5981 }
5982
5983 void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p,
5984 struct bgp_path_info *pi, afi_t afi, safi_t safi)
5985 {
5986 struct bgp_node *child;
5987 struct bgp_node *rn;
5988 struct bgp_aggregate *aggregate;
5989 struct bgp_table *table;
5990
5991 table = bgp->aggregate[afi][safi];
5992
5993 /* No aggregates configured. */
5994 if (bgp_table_top_nolock(table) == NULL)
5995 return;
5996
5997 if (p->prefixlen == 0)
5998 return;
5999
6000 if (BGP_PATH_HOLDDOWN(pi))
6001 return;
6002
6003 child = bgp_node_get(table, p);
6004
6005 /* Aggregate address configuration check. */
6006 for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
6007 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6008 if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
6009 bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
6010 bgp_aggregate_route(bgp, &rn->p, pi, afi, safi, NULL,
6011 aggregate);
6012 }
6013 }
6014 bgp_unlock_node(child);
6015 }
6016
6017 void bgp_aggregate_decrement(struct bgp *bgp, struct prefix *p,
6018 struct bgp_path_info *del, afi_t afi, safi_t safi)
6019 {
6020 struct bgp_node *child;
6021 struct bgp_node *rn;
6022 struct bgp_aggregate *aggregate;
6023 struct bgp_table *table;
6024
6025 table = bgp->aggregate[afi][safi];
6026
6027 /* No aggregates configured. */
6028 if (bgp_table_top_nolock(table) == NULL)
6029 return;
6030
6031 if (p->prefixlen == 0)
6032 return;
6033
6034 child = bgp_node_get(table, p);
6035
6036 /* Aggregate address configuration check. */
6037 for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
6038 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6039 if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
6040 bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
6041 bgp_aggregate_route(bgp, &rn->p, NULL, afi, safi, del,
6042 aggregate);
6043 }
6044 }
6045 bgp_unlock_node(child);
6046 }
6047
6048 /* Aggregate route attribute. */
6049 #define AGGREGATE_SUMMARY_ONLY 1
6050 #define AGGREGATE_AS_SET 1
6051
6052 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
6053 afi_t afi, safi_t safi)
6054 {
6055 VTY_DECLVAR_CONTEXT(bgp, bgp);
6056 int ret;
6057 struct prefix p;
6058 struct bgp_node *rn;
6059 struct bgp_aggregate *aggregate;
6060
6061 /* Convert string to prefix structure. */
6062 ret = str2prefix(prefix_str, &p);
6063 if (!ret) {
6064 vty_out(vty, "Malformed prefix\n");
6065 return CMD_WARNING_CONFIG_FAILED;
6066 }
6067 apply_mask(&p);
6068
6069 /* Old configuration check. */
6070 rn = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
6071 if (!rn) {
6072 vty_out(vty,
6073 "%% There is no aggregate-address configuration.\n");
6074 return CMD_WARNING_CONFIG_FAILED;
6075 }
6076
6077 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6078 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
6079 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
6080 NULL, NULL, 0, aggregate);
6081
6082 /* Unlock aggregate address configuration. */
6083 bgp_node_set_bgp_aggregate_info(rn, NULL);
6084 bgp_aggregate_free(aggregate);
6085 bgp_unlock_node(rn);
6086 bgp_unlock_node(rn);
6087
6088 return CMD_SUCCESS;
6089 }
6090
6091 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
6092 safi_t safi, uint8_t summary_only, uint8_t as_set)
6093 {
6094 VTY_DECLVAR_CONTEXT(bgp, bgp);
6095 int ret;
6096 struct prefix p;
6097 struct bgp_node *rn;
6098 struct bgp_aggregate *aggregate;
6099
6100 /* Convert string to prefix structure. */
6101 ret = str2prefix(prefix_str, &p);
6102 if (!ret) {
6103 vty_out(vty, "Malformed prefix\n");
6104 return CMD_WARNING_CONFIG_FAILED;
6105 }
6106 apply_mask(&p);
6107
6108 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
6109 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
6110 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
6111 prefix_str);
6112 return CMD_WARNING_CONFIG_FAILED;
6113 }
6114
6115 /* Old configuration check. */
6116 rn = bgp_node_get(bgp->aggregate[afi][safi], &p);
6117
6118 if (bgp_node_has_bgp_path_info_data(rn)) {
6119 vty_out(vty, "There is already same aggregate network.\n");
6120 /* try to remove the old entry */
6121 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
6122 if (ret) {
6123 vty_out(vty, "Error deleting aggregate.\n");
6124 bgp_unlock_node(rn);
6125 return CMD_WARNING_CONFIG_FAILED;
6126 }
6127 }
6128
6129 /* Make aggregate address structure. */
6130 aggregate = bgp_aggregate_new();
6131 aggregate->summary_only = summary_only;
6132 aggregate->as_set = as_set;
6133 aggregate->safi = safi;
6134 bgp_node_set_bgp_aggregate_info(rn, aggregate);
6135
6136 /* Aggregate address insert into BGP routing table. */
6137 bgp_aggregate_route(bgp, &p, NULL, afi, safi, NULL, aggregate);
6138
6139 return CMD_SUCCESS;
6140 }
6141
6142 DEFUN (aggregate_address,
6143 aggregate_address_cmd,
6144 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
6145 "Configure BGP aggregate entries\n"
6146 "Aggregate prefix\n"
6147 "Generate AS set path information\n"
6148 "Filter more specific routes from updates\n"
6149 "Filter more specific routes from updates\n"
6150 "Generate AS set path information\n")
6151 {
6152 int idx = 0;
6153 argv_find(argv, argc, "A.B.C.D/M", &idx);
6154 char *prefix = argv[idx]->arg;
6155 int as_set =
6156 argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
6157 idx = 0;
6158 int summary_only = argv_find(argv, argc, "summary-only", &idx)
6159 ? AGGREGATE_SUMMARY_ONLY
6160 : 0;
6161
6162 return bgp_aggregate_set(vty, prefix, AFI_IP, bgp_node_safi(vty),
6163 summary_only, as_set);
6164 }
6165
6166 DEFUN (aggregate_address_mask,
6167 aggregate_address_mask_cmd,
6168 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
6169 "Configure BGP aggregate entries\n"
6170 "Aggregate address\n"
6171 "Aggregate mask\n"
6172 "Generate AS set path information\n"
6173 "Filter more specific routes from updates\n"
6174 "Filter more specific routes from updates\n"
6175 "Generate AS set path information\n")
6176 {
6177 int idx = 0;
6178 argv_find(argv, argc, "A.B.C.D", &idx);
6179 char *prefix = argv[idx]->arg;
6180 char *mask = argv[idx + 1]->arg;
6181 int as_set =
6182 argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
6183 idx = 0;
6184 int summary_only = argv_find(argv, argc, "summary-only", &idx)
6185 ? AGGREGATE_SUMMARY_ONLY
6186 : 0;
6187
6188 char prefix_str[BUFSIZ];
6189 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
6190
6191 if (!ret) {
6192 vty_out(vty, "%% Inconsistent address and mask\n");
6193 return CMD_WARNING_CONFIG_FAILED;
6194 }
6195
6196 return bgp_aggregate_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty),
6197 summary_only, as_set);
6198 }
6199
6200 DEFUN (no_aggregate_address,
6201 no_aggregate_address_cmd,
6202 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
6203 NO_STR
6204 "Configure BGP aggregate entries\n"
6205 "Aggregate prefix\n"
6206 "Generate AS set path information\n"
6207 "Filter more specific routes from updates\n"
6208 "Filter more specific routes from updates\n"
6209 "Generate AS set path information\n")
6210 {
6211 int idx = 0;
6212 argv_find(argv, argc, "A.B.C.D/M", &idx);
6213 char *prefix = argv[idx]->arg;
6214 return bgp_aggregate_unset(vty, prefix, AFI_IP, bgp_node_safi(vty));
6215 }
6216
6217 DEFUN (no_aggregate_address_mask,
6218 no_aggregate_address_mask_cmd,
6219 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
6220 NO_STR
6221 "Configure BGP aggregate entries\n"
6222 "Aggregate address\n"
6223 "Aggregate mask\n"
6224 "Generate AS set path information\n"
6225 "Filter more specific routes from updates\n"
6226 "Filter more specific routes from updates\n"
6227 "Generate AS set path information\n")
6228 {
6229 int idx = 0;
6230 argv_find(argv, argc, "A.B.C.D", &idx);
6231 char *prefix = argv[idx]->arg;
6232 char *mask = argv[idx + 1]->arg;
6233
6234 char prefix_str[BUFSIZ];
6235 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
6236
6237 if (!ret) {
6238 vty_out(vty, "%% Inconsistent address and mask\n");
6239 return CMD_WARNING_CONFIG_FAILED;
6240 }
6241
6242 return bgp_aggregate_unset(vty, prefix_str, AFI_IP, bgp_node_safi(vty));
6243 }
6244
6245 DEFUN (ipv6_aggregate_address,
6246 ipv6_aggregate_address_cmd,
6247 "aggregate-address X:X::X:X/M [summary-only]",
6248 "Configure BGP aggregate entries\n"
6249 "Aggregate prefix\n"
6250 "Filter more specific routes from updates\n")
6251 {
6252 int idx = 0;
6253 argv_find(argv, argc, "X:X::X:X/M", &idx);
6254 char *prefix = argv[idx]->arg;
6255 int sum_only = argv_find(argv, argc, "summary-only", &idx)
6256 ? AGGREGATE_SUMMARY_ONLY
6257 : 0;
6258 return bgp_aggregate_set(vty, prefix, AFI_IP6, SAFI_UNICAST, sum_only,
6259 0);
6260 }
6261
6262 DEFUN (no_ipv6_aggregate_address,
6263 no_ipv6_aggregate_address_cmd,
6264 "no aggregate-address X:X::X:X/M [summary-only]",
6265 NO_STR
6266 "Configure BGP aggregate entries\n"
6267 "Aggregate prefix\n"
6268 "Filter more specific routes from updates\n")
6269 {
6270 int idx = 0;
6271 argv_find(argv, argc, "X:X::X:X/M", &idx);
6272 char *prefix = argv[idx]->arg;
6273 return bgp_aggregate_unset(vty, prefix, AFI_IP6, SAFI_UNICAST);
6274 }
6275
6276 /* Redistribute route treatment. */
6277 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
6278 const union g_addr *nexthop, ifindex_t ifindex,
6279 enum nexthop_types_t nhtype, uint32_t metric,
6280 uint8_t type, unsigned short instance,
6281 route_tag_t tag)
6282 {
6283 struct bgp_path_info *new;
6284 struct bgp_path_info *bpi;
6285 struct bgp_path_info rmap_path;
6286 struct bgp_node *bn;
6287 struct attr attr;
6288 struct attr *new_attr;
6289 afi_t afi;
6290 int ret;
6291 struct bgp_redist *red;
6292
6293 /* Make default attribute. */
6294 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
6295
6296 switch (nhtype) {
6297 case NEXTHOP_TYPE_IFINDEX:
6298 break;
6299 case NEXTHOP_TYPE_IPV4:
6300 case NEXTHOP_TYPE_IPV4_IFINDEX:
6301 attr.nexthop = nexthop->ipv4;
6302 break;
6303 case NEXTHOP_TYPE_IPV6:
6304 case NEXTHOP_TYPE_IPV6_IFINDEX:
6305 attr.mp_nexthop_global = nexthop->ipv6;
6306 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
6307 break;
6308 case NEXTHOP_TYPE_BLACKHOLE:
6309 switch (p->family) {
6310 case AF_INET:
6311 attr.nexthop.s_addr = INADDR_ANY;
6312 break;
6313 case AF_INET6:
6314 memset(&attr.mp_nexthop_global, 0,
6315 sizeof(attr.mp_nexthop_global));
6316 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
6317 break;
6318 }
6319 break;
6320 }
6321 attr.nh_ifindex = ifindex;
6322
6323 attr.med = metric;
6324 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6325 attr.tag = tag;
6326
6327 afi = family2afi(p->family);
6328
6329 red = bgp_redist_lookup(bgp, afi, type, instance);
6330 if (red) {
6331 struct attr attr_new;
6332
6333 /* Copy attribute for modification. */
6334 bgp_attr_dup(&attr_new, &attr);
6335
6336 if (red->redist_metric_flag)
6337 attr_new.med = red->redist_metric;
6338
6339 /* Apply route-map. */
6340 if (red->rmap.name) {
6341 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
6342 rmap_path.peer = bgp->peer_self;
6343 rmap_path.attr = &attr_new;
6344
6345 SET_FLAG(bgp->peer_self->rmap_type,
6346 PEER_RMAP_TYPE_REDISTRIBUTE);
6347
6348 ret = route_map_apply(red->rmap.map, p, RMAP_BGP,
6349 &rmap_path);
6350
6351 bgp->peer_self->rmap_type = 0;
6352
6353 if (ret == RMAP_DENYMATCH) {
6354 /* Free uninterned attribute. */
6355 bgp_attr_flush(&attr_new);
6356
6357 /* Unintern original. */
6358 aspath_unintern(&attr.aspath);
6359 bgp_redistribute_delete(bgp, p, type, instance);
6360 return;
6361 }
6362 }
6363
6364 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
6365 bgp_attr_add_gshut_community(&attr_new);
6366
6367 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
6368 SAFI_UNICAST, p, NULL);
6369
6370 new_attr = bgp_attr_intern(&attr_new);
6371
6372 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
6373 bpi = bpi->next)
6374 if (bpi->peer == bgp->peer_self
6375 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
6376 break;
6377
6378 if (bpi) {
6379 /* Ensure the (source route) type is updated. */
6380 bpi->type = type;
6381 if (attrhash_cmp(bpi->attr, new_attr)
6382 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
6383 bgp_attr_unintern(&new_attr);
6384 aspath_unintern(&attr.aspath);
6385 bgp_unlock_node(bn);
6386 return;
6387 } else {
6388 /* The attribute is changed. */
6389 bgp_path_info_set_flag(bn, bpi,
6390 BGP_PATH_ATTR_CHANGED);
6391
6392 /* Rewrite BGP route information. */
6393 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
6394 bgp_path_info_restore(bn, bpi);
6395 else
6396 bgp_aggregate_decrement(
6397 bgp, p, bpi, afi, SAFI_UNICAST);
6398 bgp_attr_unintern(&bpi->attr);
6399 bpi->attr = new_attr;
6400 bpi->uptime = bgp_clock();
6401
6402 /* Process change. */
6403 bgp_aggregate_increment(bgp, p, bpi, afi,
6404 SAFI_UNICAST);
6405 bgp_process(bgp, bn, afi, SAFI_UNICAST);
6406 bgp_unlock_node(bn);
6407 aspath_unintern(&attr.aspath);
6408
6409 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6410 || (bgp->inst_type
6411 == BGP_INSTANCE_TYPE_DEFAULT)) {
6412
6413 vpn_leak_from_vrf_update(
6414 bgp_get_default(), bgp, bpi);
6415 }
6416 return;
6417 }
6418 }
6419
6420 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
6421 bgp->peer_self, new_attr, bn);
6422 SET_FLAG(new->flags, BGP_PATH_VALID);
6423
6424 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
6425 bgp_path_info_add(bn, new);
6426 bgp_unlock_node(bn);
6427 bgp_process(bgp, bn, afi, SAFI_UNICAST);
6428
6429 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6430 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6431
6432 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6433 }
6434 }
6435
6436 /* Unintern original. */
6437 aspath_unintern(&attr.aspath);
6438 }
6439
6440 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
6441 unsigned short instance)
6442 {
6443 afi_t afi;
6444 struct bgp_node *rn;
6445 struct bgp_path_info *pi;
6446 struct bgp_redist *red;
6447
6448 afi = family2afi(p->family);
6449
6450 red = bgp_redist_lookup(bgp, afi, type, instance);
6451 if (red) {
6452 rn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
6453 SAFI_UNICAST, p, NULL);
6454
6455 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
6456 if (pi->peer == bgp->peer_self && pi->type == type)
6457 break;
6458
6459 if (pi) {
6460 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6461 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6462
6463 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6464 bgp, pi);
6465 }
6466 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
6467 bgp_path_info_delete(rn, pi);
6468 bgp_process(bgp, rn, afi, SAFI_UNICAST);
6469 }
6470 bgp_unlock_node(rn);
6471 }
6472 }
6473
6474 /* Withdraw specified route type's route. */
6475 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
6476 unsigned short instance)
6477 {
6478 struct bgp_node *rn;
6479 struct bgp_path_info *pi;
6480 struct bgp_table *table;
6481
6482 table = bgp->rib[afi][SAFI_UNICAST];
6483
6484 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
6485 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
6486 if (pi->peer == bgp->peer_self && pi->type == type
6487 && pi->instance == instance)
6488 break;
6489
6490 if (pi) {
6491 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6492 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6493
6494 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6495 bgp, pi);
6496 }
6497 bgp_aggregate_decrement(bgp, &rn->p, pi, afi,
6498 SAFI_UNICAST);
6499 bgp_path_info_delete(rn, pi);
6500 bgp_process(bgp, rn, afi, SAFI_UNICAST);
6501 }
6502 }
6503 }
6504
6505 /* Static function to display route. */
6506 static void route_vty_out_route(struct prefix *p, struct vty *vty,
6507 json_object *json)
6508 {
6509 int len = 0;
6510 char buf[BUFSIZ];
6511 char buf2[BUFSIZ];
6512
6513 if (p->family == AF_INET) {
6514 if (!json) {
6515 len = vty_out(
6516 vty, "%s/%d",
6517 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
6518 p->prefixlen);
6519 } else {
6520 json_object_string_add(json, "prefix",
6521 inet_ntop(p->family,
6522 &p->u.prefix, buf,
6523 BUFSIZ));
6524 json_object_int_add(json, "prefixLen", p->prefixlen);
6525 prefix2str(p, buf2, PREFIX_STRLEN);
6526 json_object_string_add(json, "network", buf2);
6527 }
6528 } else if (p->family == AF_ETHERNET) {
6529 prefix2str(p, buf, PREFIX_STRLEN);
6530 len = vty_out(vty, "%s", buf);
6531 } else if (p->family == AF_EVPN) {
6532 if (!json)
6533 len = vty_out(
6534 vty, "%s",
6535 bgp_evpn_route2str((struct prefix_evpn *)p, buf,
6536 BUFSIZ));
6537 else
6538 bgp_evpn_route2json((struct prefix_evpn *)p, json);
6539 } else if (p->family == AF_FLOWSPEC) {
6540 route_vty_out_flowspec(vty, p, NULL,
6541 json ?
6542 NLRI_STRING_FORMAT_JSON_SIMPLE :
6543 NLRI_STRING_FORMAT_MIN, json);
6544 } else {
6545 if (!json)
6546 len = vty_out(
6547 vty, "%s/%d",
6548 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
6549 p->prefixlen);
6550 else {
6551 json_object_string_add(json, "prefix",
6552 inet_ntop(p->family,
6553 &p->u.prefix, buf,
6554 BUFSIZ));
6555 json_object_int_add(json, "prefixLen", p->prefixlen);
6556 prefix2str(p, buf2, PREFIX_STRLEN);
6557 json_object_string_add(json, "network", buf2);
6558 }
6559 }
6560
6561 if (!json) {
6562 len = 17 - len;
6563 if (len < 1)
6564 vty_out(vty, "\n%*s", 20, " ");
6565 else
6566 vty_out(vty, "%*s", len, " ");
6567 }
6568 }
6569
6570 enum bgp_display_type {
6571 normal_list,
6572 };
6573
6574 /* Print the short form route status for a bgp_path_info */
6575 static void route_vty_short_status_out(struct vty *vty,
6576 struct bgp_path_info *path,
6577 json_object *json_path)
6578 {
6579 if (json_path) {
6580
6581 /* Route status display. */
6582 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
6583 json_object_boolean_true_add(json_path, "removed");
6584
6585 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
6586 json_object_boolean_true_add(json_path, "stale");
6587
6588 if (path->extra && path->extra->suppress)
6589 json_object_boolean_true_add(json_path, "suppressed");
6590
6591 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
6592 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
6593 json_object_boolean_true_add(json_path, "valid");
6594
6595 /* Selected */
6596 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
6597 json_object_boolean_true_add(json_path, "history");
6598
6599 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
6600 json_object_boolean_true_add(json_path, "damped");
6601
6602 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
6603 json_object_boolean_true_add(json_path, "bestpath");
6604
6605 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
6606 json_object_boolean_true_add(json_path, "multipath");
6607
6608 /* Internal route. */
6609 if ((path->peer->as)
6610 && (path->peer->as == path->peer->local_as))
6611 json_object_string_add(json_path, "pathFrom",
6612 "internal");
6613 else
6614 json_object_string_add(json_path, "pathFrom",
6615 "external");
6616
6617 return;
6618 }
6619
6620 /* Route status display. */
6621 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
6622 vty_out(vty, "R");
6623 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
6624 vty_out(vty, "S");
6625 else if (path->extra && path->extra->suppress)
6626 vty_out(vty, "s");
6627 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
6628 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
6629 vty_out(vty, "*");
6630 else
6631 vty_out(vty, " ");
6632
6633 /* Selected */
6634 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
6635 vty_out(vty, "h");
6636 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
6637 vty_out(vty, "d");
6638 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
6639 vty_out(vty, ">");
6640 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
6641 vty_out(vty, "=");
6642 else
6643 vty_out(vty, " ");
6644
6645 /* Internal route. */
6646 if (path->peer && (path->peer->as)
6647 && (path->peer->as == path->peer->local_as))
6648 vty_out(vty, "i");
6649 else
6650 vty_out(vty, " ");
6651 }
6652
6653 /* called from terminal list command */
6654 void route_vty_out(struct vty *vty, struct prefix *p,
6655 struct bgp_path_info *path, int display, safi_t safi,
6656 json_object *json_paths)
6657 {
6658 struct attr *attr;
6659 json_object *json_path = NULL;
6660 json_object *json_nexthops = NULL;
6661 json_object *json_nexthop_global = NULL;
6662 json_object *json_nexthop_ll = NULL;
6663 char vrf_id_str[VRF_NAMSIZ] = {0};
6664 bool nexthop_self =
6665 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
6666 bool nexthop_othervrf = false;
6667 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
6668 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
6669
6670 if (json_paths)
6671 json_path = json_object_new_object();
6672
6673 /* short status lead text */
6674 route_vty_short_status_out(vty, path, json_path);
6675
6676 if (!json_paths) {
6677 /* print prefix and mask */
6678 if (!display)
6679 route_vty_out_route(p, vty, json_path);
6680 else
6681 vty_out(vty, "%*s", 17, " ");
6682 } else {
6683 route_vty_out_route(p, vty, json_path);
6684 }
6685
6686 /* Print attribute */
6687 attr = path->attr;
6688 if (!attr) {
6689 if (json_paths)
6690 json_object_array_add(json_paths, json_path);
6691 else
6692 vty_out(vty, "\n");
6693
6694 return;
6695 }
6696
6697 /*
6698 * If vrf id of nexthop is different from that of prefix,
6699 * set up printable string to append
6700 */
6701 if (path->extra && path->extra->bgp_orig) {
6702 const char *self = "";
6703
6704 if (nexthop_self)
6705 self = "<";
6706
6707 nexthop_othervrf = true;
6708 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
6709
6710 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
6711 snprintf(vrf_id_str, sizeof(vrf_id_str),
6712 "@%s%s", VRFID_NONE_STR, self);
6713 else
6714 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
6715 path->extra->bgp_orig->vrf_id, self);
6716
6717 if (path->extra->bgp_orig->inst_type
6718 != BGP_INSTANCE_TYPE_DEFAULT)
6719
6720 nexthop_vrfname = path->extra->bgp_orig->name;
6721 } else {
6722 const char *self = "";
6723
6724 if (nexthop_self)
6725 self = "<";
6726
6727 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
6728 }
6729
6730 /*
6731 * For ENCAP and EVPN routes, nexthop address family is not
6732 * neccessarily the same as the prefix address family.
6733 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6734 * EVPN routes are also exchanged with a MP nexthop. Currently,
6735 * this
6736 * is only IPv4, the value will be present in either
6737 * attr->nexthop or
6738 * attr->mp_nexthop_global_in
6739 */
6740 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
6741 char buf[BUFSIZ];
6742 char nexthop[128];
6743 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
6744
6745 switch (af) {
6746 case AF_INET:
6747 sprintf(nexthop, "%s",
6748 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
6749 BUFSIZ));
6750 break;
6751 case AF_INET6:
6752 sprintf(nexthop, "%s",
6753 inet_ntop(af, &attr->mp_nexthop_global, buf,
6754 BUFSIZ));
6755 break;
6756 default:
6757 sprintf(nexthop, "?");
6758 break;
6759 }
6760
6761 if (json_paths) {
6762 json_nexthop_global = json_object_new_object();
6763
6764 json_object_string_add(json_nexthop_global, "afi",
6765 (af == AF_INET) ? "ip" : "ipv6");
6766 json_object_string_add(json_nexthop_global,
6767 (af == AF_INET) ? "ip" : "ipv6",
6768 nexthop);
6769 json_object_boolean_true_add(json_nexthop_global,
6770 "used");
6771 } else
6772 vty_out(vty, "%s%s", nexthop, vrf_id_str);
6773 } else if (safi == SAFI_EVPN) {
6774 if (json_paths) {
6775 json_nexthop_global = json_object_new_object();
6776
6777 json_object_string_add(json_nexthop_global, "ip",
6778 inet_ntoa(attr->nexthop));
6779 json_object_string_add(json_nexthop_global, "afi",
6780 "ipv4");
6781 json_object_boolean_true_add(json_nexthop_global,
6782 "used");
6783 } else
6784 vty_out(vty, "%-16s%s", inet_ntoa(attr->nexthop),
6785 vrf_id_str);
6786 } else if (safi == SAFI_FLOWSPEC) {
6787 if (attr->nexthop.s_addr != 0) {
6788 if (json_paths) {
6789 json_nexthop_global = json_object_new_object();
6790 json_object_string_add(
6791 json_nexthop_global, "ip",
6792 inet_ntoa(attr->nexthop));
6793 json_object_string_add(json_nexthop_global,
6794 "afi", "ipv4");
6795 json_object_boolean_true_add(
6796 json_nexthop_global,
6797 "used");
6798 } else {
6799 vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
6800 }
6801 }
6802 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
6803 if (json_paths) {
6804 json_nexthop_global = json_object_new_object();
6805
6806 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
6807 json_object_string_add(
6808 json_nexthop_global, "ip",
6809 inet_ntoa(attr->mp_nexthop_global_in));
6810 else
6811 json_object_string_add(
6812 json_nexthop_global, "ip",
6813 inet_ntoa(attr->nexthop));
6814
6815 json_object_string_add(json_nexthop_global, "afi",
6816 "ipv4");
6817 json_object_boolean_true_add(json_nexthop_global,
6818 "used");
6819 } else {
6820 char buf[BUFSIZ];
6821
6822 snprintf(buf, sizeof(buf), "%s%s",
6823 inet_ntoa(attr->nexthop), vrf_id_str);
6824 vty_out(vty, "%-16s", buf);
6825 }
6826 }
6827
6828 /* IPv6 Next Hop */
6829 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
6830 int len;
6831 char buf[BUFSIZ];
6832
6833 if (json_paths) {
6834 json_nexthop_global = json_object_new_object();
6835 json_object_string_add(
6836 json_nexthop_global, "ip",
6837 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
6838 buf, BUFSIZ));
6839 json_object_string_add(json_nexthop_global, "afi",
6840 "ipv6");
6841 json_object_string_add(json_nexthop_global, "scope",
6842 "global");
6843
6844 /* We display both LL & GL if both have been
6845 * received */
6846 if ((attr->mp_nexthop_len == 32)
6847 || (path->peer->conf_if)) {
6848 json_nexthop_ll = json_object_new_object();
6849 json_object_string_add(
6850 json_nexthop_ll, "ip",
6851 inet_ntop(AF_INET6,
6852 &attr->mp_nexthop_local, buf,
6853 BUFSIZ));
6854 json_object_string_add(json_nexthop_ll, "afi",
6855 "ipv6");
6856 json_object_string_add(json_nexthop_ll, "scope",
6857 "link-local");
6858
6859 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
6860 &attr->mp_nexthop_local)
6861 != 0)
6862 && !attr->mp_nexthop_prefer_global)
6863 json_object_boolean_true_add(
6864 json_nexthop_ll, "used");
6865 else
6866 json_object_boolean_true_add(
6867 json_nexthop_global, "used");
6868 } else
6869 json_object_boolean_true_add(
6870 json_nexthop_global, "used");
6871 } else {
6872 /* Display LL if LL/Global both in table unless
6873 * prefer-global is set */
6874 if (((attr->mp_nexthop_len == 32)
6875 && !attr->mp_nexthop_prefer_global)
6876 || (path->peer->conf_if)) {
6877 if (path->peer->conf_if) {
6878 len = vty_out(vty, "%s",
6879 path->peer->conf_if);
6880 len = 16 - len; /* len of IPv6
6881 addr + max
6882 len of def
6883 ifname */
6884
6885 if (len < 1)
6886 vty_out(vty, "\n%*s", 36, " ");
6887 else
6888 vty_out(vty, "%*s", len, " ");
6889 } else {
6890 len = vty_out(
6891 vty, "%s%s",
6892 inet_ntop(
6893 AF_INET6,
6894 &attr->mp_nexthop_local,
6895 buf, BUFSIZ),
6896 vrf_id_str);
6897 len = 16 - len;
6898
6899 if (len < 1)
6900 vty_out(vty, "\n%*s", 36, " ");
6901 else
6902 vty_out(vty, "%*s", len, " ");
6903 }
6904 } else {
6905 len = vty_out(
6906 vty, "%s%s",
6907 inet_ntop(AF_INET6,
6908 &attr->mp_nexthop_global, buf,
6909 BUFSIZ),
6910 vrf_id_str);
6911 len = 16 - len;
6912
6913 if (len < 1)
6914 vty_out(vty, "\n%*s", 36, " ");
6915 else
6916 vty_out(vty, "%*s", len, " ");
6917 }
6918 }
6919 }
6920
6921 /* MED/Metric */
6922 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
6923 if (json_paths) {
6924
6925 /*
6926 * Adding "metric" field to match with corresponding
6927 * CLI. "med" will be deprecated in future.
6928 */
6929 json_object_int_add(json_path, "med", attr->med);
6930 json_object_int_add(json_path, "metric", attr->med);
6931 } else
6932 vty_out(vty, "%10u", attr->med);
6933 else if (!json_paths)
6934 vty_out(vty, " ");
6935
6936 /* Local Pref */
6937 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
6938 if (json_paths) {
6939
6940 /*
6941 * Adding "locPrf" field to match with corresponding
6942 * CLI. "localPref" will be deprecated in future.
6943 */
6944 json_object_int_add(json_path, "localpref",
6945 attr->local_pref);
6946 json_object_int_add(json_path, "locPrf",
6947 attr->local_pref);
6948 } else
6949 vty_out(vty, "%7u", attr->local_pref);
6950 else if (!json_paths)
6951 vty_out(vty, " ");
6952
6953 if (json_paths)
6954 json_object_int_add(json_path, "weight", attr->weight);
6955 else
6956 vty_out(vty, "%7u ", attr->weight);
6957
6958 if (json_paths) {
6959 char buf[BUFSIZ];
6960 json_object_string_add(
6961 json_path, "peerId",
6962 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
6963 }
6964
6965 /* Print aspath */
6966 if (attr->aspath) {
6967 if (json_paths) {
6968
6969 /*
6970 * Adding "path" field to match with corresponding
6971 * CLI. "aspath" will be deprecated in future.
6972 */
6973 json_object_string_add(json_path, "aspath",
6974 attr->aspath->str);
6975 json_object_string_add(json_path, "path",
6976 attr->aspath->str);
6977 } else
6978 aspath_print_vty(vty, "%s", attr->aspath, " ");
6979 }
6980
6981 /* Print origin */
6982 if (json_paths)
6983 json_object_string_add(json_path, "origin",
6984 bgp_origin_long_str[attr->origin]);
6985 else
6986 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
6987
6988 if (json_paths) {
6989 if (nexthop_self)
6990 json_object_boolean_true_add(json_path,
6991 "announceNexthopSelf");
6992 if (nexthop_othervrf) {
6993 json_object_string_add(json_path, "nhVrfName",
6994 nexthop_vrfname);
6995
6996 json_object_int_add(json_path, "nhVrfId",
6997 ((nexthop_vrfid == VRF_UNKNOWN)
6998 ? -1
6999 : (int)nexthop_vrfid));
7000 }
7001 }
7002
7003 if (json_paths) {
7004 if (json_nexthop_global || json_nexthop_ll) {
7005 json_nexthops = json_object_new_array();
7006
7007 if (json_nexthop_global)
7008 json_object_array_add(json_nexthops,
7009 json_nexthop_global);
7010
7011 if (json_nexthop_ll)
7012 json_object_array_add(json_nexthops,
7013 json_nexthop_ll);
7014
7015 json_object_object_add(json_path, "nexthops",
7016 json_nexthops);
7017 }
7018
7019 json_object_array_add(json_paths, json_path);
7020 } else {
7021 vty_out(vty, "\n");
7022 #if ENABLE_BGP_VNC
7023 /* prints an additional line, indented, with VNC info, if
7024 * present */
7025 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
7026 rfapi_vty_out_vncinfo(vty, p, path, safi);
7027 #endif
7028 }
7029 }
7030
7031 /* called from terminal list command */
7032 void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
7033 safi_t safi, bool use_json, json_object *json_ar)
7034 {
7035 json_object *json_status = NULL;
7036 json_object *json_net = NULL;
7037 char buff[BUFSIZ];
7038 char buf2[BUFSIZ];
7039 /* Route status display. */
7040 if (use_json) {
7041 json_status = json_object_new_object();
7042 json_net = json_object_new_object();
7043 } else {
7044 vty_out(vty, "*");
7045 vty_out(vty, ">");
7046 vty_out(vty, " ");
7047 }
7048
7049 /* print prefix and mask */
7050 if (use_json) {
7051 json_object_string_add(
7052 json_net, "addrPrefix",
7053 inet_ntop(p->family, &p->u.prefix, buff, BUFSIZ));
7054 json_object_int_add(json_net, "prefixLen", p->prefixlen);
7055 prefix2str(p, buf2, PREFIX_STRLEN);
7056 json_object_string_add(json_net, "network", buf2);
7057 } else
7058 route_vty_out_route(p, vty, NULL);
7059
7060 /* Print attribute */
7061 if (attr) {
7062 if (use_json) {
7063 if (p->family == AF_INET
7064 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7065 || safi == SAFI_EVPN
7066 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7067 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7068 || safi == SAFI_EVPN)
7069 json_object_string_add(
7070 json_net, "nextHop",
7071 inet_ntoa(
7072 attr->mp_nexthop_global_in));
7073 else
7074 json_object_string_add(
7075 json_net, "nextHop",
7076 inet_ntoa(attr->nexthop));
7077 } else if (p->family == AF_INET6
7078 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7079 char buf[BUFSIZ];
7080
7081 json_object_string_add(
7082 json_net, "nextHopGlobal",
7083 inet_ntop(AF_INET6,
7084 &attr->mp_nexthop_global, buf,
7085 BUFSIZ));
7086 }
7087
7088 if (attr->flag
7089 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7090 json_object_int_add(json_net, "metric",
7091 attr->med);
7092
7093 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
7094
7095 /*
7096 * Adding "locPrf" field to match with
7097 * corresponding CLI. "localPref" will be
7098 * deprecated in future.
7099 */
7100 json_object_int_add(json_net, "localPref",
7101 attr->local_pref);
7102 json_object_int_add(json_net, "locPrf",
7103 attr->local_pref);
7104 }
7105
7106 json_object_int_add(json_net, "weight", attr->weight);
7107
7108 /* Print aspath */
7109 if (attr->aspath) {
7110
7111 /*
7112 * Adding "path" field to match with
7113 * corresponding CLI. "localPref" will be
7114 * deprecated in future.
7115 */
7116 json_object_string_add(json_net, "asPath",
7117 attr->aspath->str);
7118 json_object_string_add(json_net, "path",
7119 attr->aspath->str);
7120 }
7121
7122 /* Print origin */
7123 json_object_string_add(json_net, "bgpOriginCode",
7124 bgp_origin_str[attr->origin]);
7125 } else {
7126 if (p->family == AF_INET
7127 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7128 || safi == SAFI_EVPN
7129 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7130 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7131 || safi == SAFI_EVPN)
7132 vty_out(vty, "%-16s",
7133 inet_ntoa(
7134 attr->mp_nexthop_global_in));
7135 else
7136 vty_out(vty, "%-16s",
7137 inet_ntoa(attr->nexthop));
7138 } else if (p->family == AF_INET6
7139 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7140 int len;
7141 char buf[BUFSIZ];
7142
7143 len = vty_out(
7144 vty, "%s",
7145 inet_ntop(AF_INET6,
7146 &attr->mp_nexthop_global, buf,
7147 BUFSIZ));
7148 len = 16 - len;
7149 if (len < 1)
7150 vty_out(vty, "\n%*s", 36, " ");
7151 else
7152 vty_out(vty, "%*s", len, " ");
7153 }
7154 if (attr->flag
7155 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7156 vty_out(vty, "%10u", attr->med);
7157 else
7158 vty_out(vty, " ");
7159
7160 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
7161 vty_out(vty, "%7u", attr->local_pref);
7162 else
7163 vty_out(vty, " ");
7164
7165 vty_out(vty, "%7u ", attr->weight);
7166
7167 /* Print aspath */
7168 if (attr->aspath)
7169 aspath_print_vty(vty, "%s", attr->aspath, " ");
7170
7171 /* Print origin */
7172 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7173 }
7174 }
7175 if (use_json) {
7176 json_object_boolean_true_add(json_status, "*");
7177 json_object_boolean_true_add(json_status, ">");
7178 json_object_object_add(json_net, "appliedStatusSymbols",
7179 json_status);
7180 char buf_cut[BUFSIZ];
7181 json_object_object_add(
7182 json_ar,
7183 inet_ntop(p->family, &p->u.prefix, buf_cut, BUFSIZ),
7184 json_net);
7185 } else
7186 vty_out(vty, "\n");
7187 }
7188
7189 void route_vty_out_tag(struct vty *vty, struct prefix *p,
7190 struct bgp_path_info *path, int display, safi_t safi,
7191 json_object *json)
7192 {
7193 json_object *json_out = NULL;
7194 struct attr *attr;
7195 mpls_label_t label = MPLS_INVALID_LABEL;
7196
7197 if (!path->extra)
7198 return;
7199
7200 if (json)
7201 json_out = json_object_new_object();
7202
7203 /* short status lead text */
7204 route_vty_short_status_out(vty, path, json_out);
7205
7206 /* print prefix and mask */
7207 if (json == NULL) {
7208 if (!display)
7209 route_vty_out_route(p, vty, NULL);
7210 else
7211 vty_out(vty, "%*s", 17, " ");
7212 }
7213
7214 /* Print attribute */
7215 attr = path->attr;
7216 if (attr) {
7217 if (((p->family == AF_INET)
7218 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
7219 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7220 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7221 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7222 || safi == SAFI_EVPN) {
7223 if (json)
7224 json_object_string_add(
7225 json_out, "mpNexthopGlobalIn",
7226 inet_ntoa(
7227 attr->mp_nexthop_global_in));
7228 else
7229 vty_out(vty, "%-16s",
7230 inet_ntoa(
7231 attr->mp_nexthop_global_in));
7232 } else {
7233 if (json)
7234 json_object_string_add(
7235 json_out, "nexthop",
7236 inet_ntoa(attr->nexthop));
7237 else
7238 vty_out(vty, "%-16s",
7239 inet_ntoa(attr->nexthop));
7240 }
7241 } else if (((p->family == AF_INET6)
7242 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
7243 || (safi == SAFI_EVPN
7244 && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7245 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7246 char buf_a[512];
7247 char buf_b[512];
7248 char buf_c[BUFSIZ];
7249 if (attr->mp_nexthop_len
7250 == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
7251 if (json)
7252 json_object_string_add(
7253 json_out, "mpNexthopGlobalIn",
7254 inet_ntop(
7255 AF_INET6,
7256 &attr->mp_nexthop_global,
7257 buf_a, sizeof(buf_a)));
7258 else
7259 vty_out(vty, "%s",
7260 inet_ntop(
7261 AF_INET6,
7262 &attr->mp_nexthop_global,
7263 buf_a, sizeof(buf_a)));
7264 } else if (attr->mp_nexthop_len
7265 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
7266 if (json) {
7267 inet_ntop(AF_INET6,
7268 &attr->mp_nexthop_global,
7269 buf_a, sizeof(buf_a));
7270 inet_ntop(AF_INET6,
7271 &attr->mp_nexthop_local,
7272 buf_b, sizeof(buf_b));
7273 sprintf(buf_c, "%s(%s)", buf_a, buf_b);
7274 json_object_string_add(
7275 json_out,
7276 "mpNexthopGlobalLocal", buf_c);
7277 } else
7278 vty_out(vty, "%s(%s)",
7279 inet_ntop(
7280 AF_INET6,
7281 &attr->mp_nexthop_global,
7282 buf_a, sizeof(buf_a)),
7283 inet_ntop(
7284 AF_INET6,
7285 &attr->mp_nexthop_local,
7286 buf_b, sizeof(buf_b)));
7287 }
7288 }
7289 }
7290
7291 label = decode_label(&path->extra->label[0]);
7292
7293 if (bgp_is_valid_label(&label)) {
7294 if (json) {
7295 json_object_int_add(json_out, "notag", label);
7296 json_object_array_add(json, json_out);
7297 } else {
7298 vty_out(vty, "notag/%d", label);
7299 vty_out(vty, "\n");
7300 }
7301 }
7302 }
7303
7304 void route_vty_out_overlay(struct vty *vty, struct prefix *p,
7305 struct bgp_path_info *path, int display,
7306 json_object *json_paths)
7307 {
7308 struct attr *attr;
7309 char buf[BUFSIZ];
7310 json_object *json_path = NULL;
7311
7312 if (json_paths)
7313 json_path = json_object_new_object();
7314
7315 if (!path->extra)
7316 return;
7317
7318 /* short status lead text */
7319 route_vty_short_status_out(vty, path, json_path);
7320
7321 /* print prefix and mask */
7322 if (!display)
7323 route_vty_out_route(p, vty, NULL);
7324 else
7325 vty_out(vty, "%*s", 17, " ");
7326
7327 /* Print attribute */
7328 attr = path->attr;
7329 if (attr) {
7330 char buf1[BUFSIZ];
7331 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
7332
7333 switch (af) {
7334 case AF_INET:
7335 vty_out(vty, "%-16s",
7336 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
7337 BUFSIZ));
7338 break;
7339 case AF_INET6:
7340 vty_out(vty, "%s(%s)",
7341 inet_ntop(af, &attr->mp_nexthop_global, buf,
7342 BUFSIZ),
7343 inet_ntop(af, &attr->mp_nexthop_local, buf1,
7344 BUFSIZ));
7345 break;
7346 default:
7347 vty_out(vty, "?");
7348 }
7349
7350 char *str = esi2str(&(attr->evpn_overlay.eth_s_id));
7351
7352 vty_out(vty, "%s", str);
7353 XFREE(MTYPE_TMP, str);
7354
7355 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) {
7356 vty_out(vty, "/%s",
7357 inet_ntoa(attr->evpn_overlay.gw_ip.ipv4));
7358 } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) {
7359 vty_out(vty, "/%s",
7360 inet_ntop(AF_INET6,
7361 &(attr->evpn_overlay.gw_ip.ipv6), buf,
7362 BUFSIZ));
7363 }
7364 if (attr->ecommunity) {
7365 char *mac = NULL;
7366 struct ecommunity_val *routermac = ecommunity_lookup(
7367 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
7368 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
7369 if (routermac)
7370 mac = ecom_mac2str((char *)routermac->val);
7371 if (mac) {
7372 vty_out(vty, "/%s", (char *)mac);
7373 XFREE(MTYPE_TMP, mac);
7374 }
7375 }
7376 vty_out(vty, "\n");
7377 }
7378
7379 }
7380
7381 /* dampening route */
7382 static void damp_route_vty_out(struct vty *vty, struct prefix *p,
7383 struct bgp_path_info *path, int display,
7384 safi_t safi, bool use_json, json_object *json)
7385 {
7386 struct attr *attr;
7387 int len;
7388 char timebuf[BGP_UPTIME_LEN];
7389
7390 /* short status lead text */
7391 route_vty_short_status_out(vty, path, json);
7392
7393 /* print prefix and mask */
7394 if (!use_json) {
7395 if (!display)
7396 route_vty_out_route(p, vty, NULL);
7397 else
7398 vty_out(vty, "%*s", 17, " ");
7399 }
7400
7401 len = vty_out(vty, "%s", path->peer->host);
7402 len = 17 - len;
7403 if (len < 1) {
7404 if (!use_json)
7405 vty_out(vty, "\n%*s", 34, " ");
7406 } else {
7407 if (use_json)
7408 json_object_int_add(json, "peerHost", len);
7409 else
7410 vty_out(vty, "%*s", len, " ");
7411 }
7412
7413 if (use_json)
7414 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN,
7415 use_json, json);
7416 else
7417 vty_out(vty, "%s ",
7418 bgp_damp_reuse_time_vty(vty, path, timebuf,
7419 BGP_UPTIME_LEN, use_json,
7420 json));
7421
7422 /* Print attribute */
7423 attr = path->attr;
7424 if (attr) {
7425 /* Print aspath */
7426 if (attr->aspath) {
7427 if (use_json)
7428 json_object_string_add(json, "asPath",
7429 attr->aspath->str);
7430 else
7431 aspath_print_vty(vty, "%s", attr->aspath, " ");
7432 }
7433
7434 /* Print origin */
7435 if (use_json)
7436 json_object_string_add(json, "origin",
7437 bgp_origin_str[attr->origin]);
7438 else
7439 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7440 }
7441 if (!use_json)
7442 vty_out(vty, "\n");
7443 }
7444
7445 /* flap route */
7446 static void flap_route_vty_out(struct vty *vty, struct prefix *p,
7447 struct bgp_path_info *path, int display,
7448 safi_t safi, bool use_json, json_object *json)
7449 {
7450 struct attr *attr;
7451 struct bgp_damp_info *bdi;
7452 char timebuf[BGP_UPTIME_LEN];
7453 int len;
7454
7455 if (!path->extra)
7456 return;
7457
7458 bdi = path->extra->damp_info;
7459
7460 /* short status lead text */
7461 route_vty_short_status_out(vty, path, json);
7462
7463 /* print prefix and mask */
7464 if (!use_json) {
7465 if (!display)
7466 route_vty_out_route(p, vty, NULL);
7467 else
7468 vty_out(vty, "%*s", 17, " ");
7469 }
7470
7471 len = vty_out(vty, "%s", path->peer->host);
7472 len = 16 - len;
7473 if (len < 1) {
7474 if (!use_json)
7475 vty_out(vty, "\n%*s", 33, " ");
7476 } else {
7477 if (use_json)
7478 json_object_int_add(json, "peerHost", len);
7479 else
7480 vty_out(vty, "%*s", len, " ");
7481 }
7482
7483 len = vty_out(vty, "%d", bdi->flap);
7484 len = 5 - len;
7485 if (len < 1) {
7486 if (!use_json)
7487 vty_out(vty, " ");
7488 } else {
7489 if (use_json)
7490 json_object_int_add(json, "bdiFlap", len);
7491 else
7492 vty_out(vty, "%*s", len, " ");
7493 }
7494
7495 if (use_json)
7496 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
7497 json);
7498 else
7499 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
7500 BGP_UPTIME_LEN, 0, NULL));
7501
7502 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
7503 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
7504 if (use_json)
7505 bgp_damp_reuse_time_vty(vty, path, timebuf,
7506 BGP_UPTIME_LEN, use_json, json);
7507 else
7508 vty_out(vty, "%s ",
7509 bgp_damp_reuse_time_vty(vty, path, timebuf,
7510 BGP_UPTIME_LEN,
7511 use_json, json));
7512 } else {
7513 if (!use_json)
7514 vty_out(vty, "%*s ", 8, " ");
7515 }
7516
7517 /* Print attribute */
7518 attr = path->attr;
7519 if (attr) {
7520 /* Print aspath */
7521 if (attr->aspath) {
7522 if (use_json)
7523 json_object_string_add(json, "asPath",
7524 attr->aspath->str);
7525 else
7526 aspath_print_vty(vty, "%s", attr->aspath, " ");
7527 }
7528
7529 /* Print origin */
7530 if (use_json)
7531 json_object_string_add(json, "origin",
7532 bgp_origin_str[attr->origin]);
7533 else
7534 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7535 }
7536 if (!use_json)
7537 vty_out(vty, "\n");
7538 }
7539
7540 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
7541 int *first, const char *header,
7542 json_object *json_adv_to)
7543 {
7544 char buf1[INET6_ADDRSTRLEN];
7545 json_object *json_peer = NULL;
7546
7547 if (json_adv_to) {
7548 /* 'advertised-to' is a dictionary of peers we have advertised
7549 * this
7550 * prefix too. The key is the peer's IP or swpX, the value is
7551 * the
7552 * hostname if we know it and "" if not.
7553 */
7554 json_peer = json_object_new_object();
7555
7556 if (peer->hostname)
7557 json_object_string_add(json_peer, "hostname",
7558 peer->hostname);
7559
7560 if (peer->conf_if)
7561 json_object_object_add(json_adv_to, peer->conf_if,
7562 json_peer);
7563 else
7564 json_object_object_add(
7565 json_adv_to,
7566 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
7567 json_peer);
7568 } else {
7569 if (*first) {
7570 vty_out(vty, "%s", header);
7571 *first = 0;
7572 }
7573
7574 if (peer->hostname
7575 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
7576 if (peer->conf_if)
7577 vty_out(vty, " %s(%s)", peer->hostname,
7578 peer->conf_if);
7579 else
7580 vty_out(vty, " %s(%s)", peer->hostname,
7581 sockunion2str(&peer->su, buf1,
7582 SU_ADDRSTRLEN));
7583 } else {
7584 if (peer->conf_if)
7585 vty_out(vty, " %s", peer->conf_if);
7586 else
7587 vty_out(vty, " %s",
7588 sockunion2str(&peer->su, buf1,
7589 SU_ADDRSTRLEN));
7590 }
7591 }
7592 }
7593
7594 static void route_vty_out_tx_ids(struct vty *vty,
7595 struct bgp_addpath_info_data *d)
7596 {
7597 int i;
7598
7599 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
7600 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
7601 d->addpath_tx_id[i],
7602 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
7603 }
7604 }
7605
7606 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
7607 struct bgp_path_info *path, afi_t afi, safi_t safi,
7608 json_object *json_paths)
7609 {
7610 char buf[INET6_ADDRSTRLEN];
7611 char buf1[BUFSIZ];
7612 char buf2[EVPN_ROUTE_STRLEN];
7613 struct attr *attr;
7614 int sockunion_vty_out(struct vty *, union sockunion *);
7615 time_t tbuf;
7616 json_object *json_bestpath = NULL;
7617 json_object *json_cluster_list = NULL;
7618 json_object *json_cluster_list_list = NULL;
7619 json_object *json_ext_community = NULL;
7620 json_object *json_last_update = NULL;
7621 json_object *json_pmsi = NULL;
7622 json_object *json_nexthop_global = NULL;
7623 json_object *json_nexthop_ll = NULL;
7624 json_object *json_nexthops = NULL;
7625 json_object *json_path = NULL;
7626 json_object *json_peer = NULL;
7627 json_object *json_string = NULL;
7628 json_object *json_adv_to = NULL;
7629 int first = 0;
7630 struct listnode *node, *nnode;
7631 struct peer *peer;
7632 int addpath_capable;
7633 int has_adj;
7634 unsigned int first_as;
7635 bool nexthop_self =
7636 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
7637 int i;
7638
7639 if (json_paths) {
7640 json_path = json_object_new_object();
7641 json_peer = json_object_new_object();
7642 json_nexthop_global = json_object_new_object();
7643 }
7644
7645 if (!json_paths && safi == SAFI_EVPN) {
7646 char tag_buf[30];
7647
7648 bgp_evpn_route2str((struct prefix_evpn *)p, buf2, sizeof(buf2));
7649 vty_out(vty, " Route %s", buf2);
7650 tag_buf[0] = '\0';
7651 if (path->extra && path->extra->num_labels) {
7652 bgp_evpn_label2str(path->extra->label,
7653 path->extra->num_labels, tag_buf,
7654 sizeof(tag_buf));
7655 vty_out(vty, " VNI %s", tag_buf);
7656 }
7657 vty_out(vty, "\n");
7658 if (path->extra && path->extra->parent) {
7659 struct bgp_path_info *parent_ri;
7660 struct bgp_node *rn, *prn;
7661
7662 parent_ri = (struct bgp_path_info *)path->extra->parent;
7663 rn = parent_ri->net;
7664 if (rn && rn->prn) {
7665 prn = rn->prn;
7666 vty_out(vty, " Imported from %s:%s\n",
7667 prefix_rd2str(
7668 (struct prefix_rd *)&prn->p,
7669 buf1, sizeof(buf1)),
7670 buf2);
7671 }
7672 }
7673 }
7674
7675 attr = path->attr;
7676
7677 if (attr) {
7678 /* Line1 display AS-path, Aggregator */
7679 if (attr->aspath) {
7680 if (json_paths) {
7681 if (!attr->aspath->json)
7682 aspath_str_update(attr->aspath, true);
7683 json_object_lock(attr->aspath->json);
7684 json_object_object_add(json_path, "aspath",
7685 attr->aspath->json);
7686 } else {
7687 if (attr->aspath->segments)
7688 aspath_print_vty(vty, " %s",
7689 attr->aspath, "");
7690 else
7691 vty_out(vty, " Local");
7692 }
7693 }
7694
7695 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
7696 if (json_paths)
7697 json_object_boolean_true_add(json_path,
7698 "removed");
7699 else
7700 vty_out(vty, ", (removed)");
7701 }
7702
7703 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
7704 if (json_paths)
7705 json_object_boolean_true_add(json_path,
7706 "stale");
7707 else
7708 vty_out(vty, ", (stale)");
7709 }
7710
7711 if (CHECK_FLAG(attr->flag,
7712 ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
7713 if (json_paths) {
7714 json_object_int_add(json_path, "aggregatorAs",
7715 attr->aggregator_as);
7716 json_object_string_add(
7717 json_path, "aggregatorId",
7718 inet_ntoa(attr->aggregator_addr));
7719 } else {
7720 vty_out(vty, ", (aggregated by %u %s)",
7721 attr->aggregator_as,
7722 inet_ntoa(attr->aggregator_addr));
7723 }
7724 }
7725
7726 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
7727 PEER_FLAG_REFLECTOR_CLIENT)) {
7728 if (json_paths)
7729 json_object_boolean_true_add(
7730 json_path, "rxedFromRrClient");
7731 else
7732 vty_out(vty, ", (Received from a RR-client)");
7733 }
7734
7735 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
7736 PEER_FLAG_RSERVER_CLIENT)) {
7737 if (json_paths)
7738 json_object_boolean_true_add(
7739 json_path, "rxedFromRsClient");
7740 else
7741 vty_out(vty, ", (Received from a RS-client)");
7742 }
7743
7744 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
7745 if (json_paths)
7746 json_object_boolean_true_add(
7747 json_path, "dampeningHistoryEntry");
7748 else
7749 vty_out(vty, ", (history entry)");
7750 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
7751 if (json_paths)
7752 json_object_boolean_true_add(
7753 json_path, "dampeningSuppressed");
7754 else
7755 vty_out(vty, ", (suppressed due to dampening)");
7756 }
7757
7758 if (!json_paths)
7759 vty_out(vty, "\n");
7760
7761 /* Line2 display Next-hop, Neighbor, Router-id */
7762 /* Display the nexthop */
7763 if ((p->family == AF_INET || p->family == AF_ETHERNET
7764 || p->family == AF_EVPN)
7765 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7766 || safi == SAFI_EVPN
7767 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7768 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7769 || safi == SAFI_EVPN) {
7770 if (json_paths)
7771 json_object_string_add(
7772 json_nexthop_global, "ip",
7773 inet_ntoa(
7774 attr->mp_nexthop_global_in));
7775 else
7776 vty_out(vty, " %s",
7777 inet_ntoa(
7778 attr->mp_nexthop_global_in));
7779 } else {
7780 if (json_paths)
7781 json_object_string_add(
7782 json_nexthop_global, "ip",
7783 inet_ntoa(attr->nexthop));
7784 else
7785 vty_out(vty, " %s",
7786 inet_ntoa(attr->nexthop));
7787 }
7788
7789 if (json_paths)
7790 json_object_string_add(json_nexthop_global,
7791 "afi", "ipv4");
7792 } else {
7793 if (json_paths) {
7794 json_object_string_add(
7795 json_nexthop_global, "ip",
7796 inet_ntop(AF_INET6,
7797 &attr->mp_nexthop_global, buf,
7798 INET6_ADDRSTRLEN));
7799 json_object_string_add(json_nexthop_global,
7800 "afi", "ipv6");
7801 json_object_string_add(json_nexthop_global,
7802 "scope", "global");
7803 } else {
7804 vty_out(vty, " %s",
7805 inet_ntop(AF_INET6,
7806 &attr->mp_nexthop_global, buf,
7807 INET6_ADDRSTRLEN));
7808 }
7809 }
7810
7811 /* Display the IGP cost or 'inaccessible' */
7812 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
7813 if (json_paths)
7814 json_object_boolean_false_add(
7815 json_nexthop_global, "accessible");
7816 else
7817 vty_out(vty, " (inaccessible)");
7818 } else {
7819 if (path->extra && path->extra->igpmetric) {
7820 if (json_paths)
7821 json_object_int_add(
7822 json_nexthop_global, "metric",
7823 path->extra->igpmetric);
7824 else
7825 vty_out(vty, " (metric %u)",
7826 path->extra->igpmetric);
7827 }
7828
7829 /* IGP cost is 0, display this only for json */
7830 else {
7831 if (json_paths)
7832 json_object_int_add(json_nexthop_global,
7833 "metric", 0);
7834 }
7835
7836 if (json_paths)
7837 json_object_boolean_true_add(
7838 json_nexthop_global, "accessible");
7839 }
7840
7841 /* Display peer "from" output */
7842 /* This path was originated locally */
7843 if (path->peer == bgp->peer_self) {
7844
7845 if (safi == SAFI_EVPN
7846 || (p->family == AF_INET
7847 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7848 if (json_paths)
7849 json_object_string_add(
7850 json_peer, "peerId", "0.0.0.0");
7851 else
7852 vty_out(vty, " from 0.0.0.0 ");
7853 } else {
7854 if (json_paths)
7855 json_object_string_add(json_peer,
7856 "peerId", "::");
7857 else
7858 vty_out(vty, " from :: ");
7859 }
7860
7861 if (json_paths)
7862 json_object_string_add(
7863 json_peer, "routerId",
7864 inet_ntoa(bgp->router_id));
7865 else
7866 vty_out(vty, "(%s)", inet_ntoa(bgp->router_id));
7867 }
7868
7869 /* We RXed this path from one of our peers */
7870 else {
7871
7872 if (json_paths) {
7873 json_object_string_add(
7874 json_peer, "peerId",
7875 sockunion2str(&path->peer->su, buf,
7876 SU_ADDRSTRLEN));
7877 json_object_string_add(
7878 json_peer, "routerId",
7879 inet_ntop(AF_INET,
7880 &path->peer->remote_id, buf1,
7881 sizeof(buf1)));
7882
7883 if (path->peer->hostname)
7884 json_object_string_add(
7885 json_peer, "hostname",
7886 path->peer->hostname);
7887
7888 if (path->peer->domainname)
7889 json_object_string_add(
7890 json_peer, "domainname",
7891 path->peer->domainname);
7892
7893 if (path->peer->conf_if)
7894 json_object_string_add(
7895 json_peer, "interface",
7896 path->peer->conf_if);
7897 } else {
7898 if (path->peer->conf_if) {
7899 if (path->peer->hostname
7900 && bgp_flag_check(
7901 path->peer->bgp,
7902 BGP_FLAG_SHOW_HOSTNAME))
7903 vty_out(vty, " from %s(%s)",
7904 path->peer->hostname,
7905 path->peer->conf_if);
7906 else
7907 vty_out(vty, " from %s",
7908 path->peer->conf_if);
7909 } else {
7910 if (path->peer->hostname
7911 && bgp_flag_check(
7912 path->peer->bgp,
7913 BGP_FLAG_SHOW_HOSTNAME))
7914 vty_out(vty, " from %s(%s)",
7915 path->peer->hostname,
7916 path->peer->host);
7917 else
7918 vty_out(vty, " from %s",
7919 sockunion2str(
7920 &path->peer->su,
7921 buf,
7922 SU_ADDRSTRLEN));
7923 }
7924
7925 if (attr->flag
7926 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
7927 vty_out(vty, " (%s)",
7928 inet_ntoa(attr->originator_id));
7929 else
7930 vty_out(vty, " (%s)",
7931 inet_ntop(
7932 AF_INET,
7933 &path->peer->remote_id,
7934 buf1, sizeof(buf1)));
7935 }
7936 }
7937
7938 /*
7939 * Note when vrfid of nexthop is different from that of prefix
7940 */
7941 if (path->extra && path->extra->bgp_orig) {
7942 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
7943
7944 if (json_paths) {
7945 const char *vn;
7946
7947 if (path->extra->bgp_orig->inst_type
7948 == BGP_INSTANCE_TYPE_DEFAULT)
7949
7950 vn = VRF_DEFAULT_NAME;
7951 else
7952 vn = path->extra->bgp_orig->name;
7953
7954 json_object_string_add(json_path, "nhVrfName",
7955 vn);
7956
7957 if (nexthop_vrfid == VRF_UNKNOWN) {
7958 json_object_int_add(json_path,
7959 "nhVrfId", -1);
7960 } else {
7961 json_object_int_add(json_path,
7962 "nhVrfId", (int)nexthop_vrfid);
7963 }
7964 } else {
7965 if (nexthop_vrfid == VRF_UNKNOWN)
7966 vty_out(vty, " vrf ?");
7967 else
7968 vty_out(vty, " vrf %u", nexthop_vrfid);
7969 }
7970 }
7971
7972 if (nexthop_self) {
7973 if (json_paths) {
7974 json_object_boolean_true_add(json_path,
7975 "announceNexthopSelf");
7976 } else {
7977 vty_out(vty, " announce-nh-self");
7978 }
7979 }
7980
7981 if (!json_paths)
7982 vty_out(vty, "\n");
7983
7984 /* display the link-local nexthop */
7985 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
7986 if (json_paths) {
7987 json_nexthop_ll = json_object_new_object();
7988 json_object_string_add(
7989 json_nexthop_ll, "ip",
7990 inet_ntop(AF_INET6,
7991 &attr->mp_nexthop_local, buf,
7992 INET6_ADDRSTRLEN));
7993 json_object_string_add(json_nexthop_ll, "afi",
7994 "ipv6");
7995 json_object_string_add(json_nexthop_ll, "scope",
7996 "link-local");
7997
7998 json_object_boolean_true_add(json_nexthop_ll,
7999 "accessible");
8000
8001 if (!attr->mp_nexthop_prefer_global)
8002 json_object_boolean_true_add(
8003 json_nexthop_ll, "used");
8004 else
8005 json_object_boolean_true_add(
8006 json_nexthop_global, "used");
8007 } else {
8008 vty_out(vty, " (%s) %s\n",
8009 inet_ntop(AF_INET6,
8010 &attr->mp_nexthop_local, buf,
8011 INET6_ADDRSTRLEN),
8012 attr->mp_nexthop_prefer_global
8013 ? "(prefer-global)"
8014 : "(used)");
8015 }
8016 }
8017 /* If we do not have a link-local nexthop then we must flag the
8018 global as "used" */
8019 else {
8020 if (json_paths)
8021 json_object_boolean_true_add(
8022 json_nexthop_global, "used");
8023 }
8024
8025 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
8026 * Int/Ext/Local, Atomic, best */
8027 if (json_paths)
8028 json_object_string_add(
8029 json_path, "origin",
8030 bgp_origin_long_str[attr->origin]);
8031 else
8032 vty_out(vty, " Origin %s",
8033 bgp_origin_long_str[attr->origin]);
8034
8035 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
8036 if (json_paths) {
8037
8038 /*
8039 * Adding "metric" field to match with
8040 * corresponding CLI. "med" will be
8041 * deprecated in future.
8042 */
8043 json_object_int_add(json_path, "med",
8044 attr->med);
8045 json_object_int_add(json_path, "metric",
8046 attr->med);
8047 } else
8048 vty_out(vty, ", metric %u", attr->med);
8049 }
8050
8051 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
8052 if (json_paths)
8053 json_object_int_add(json_path, "localpref",
8054 attr->local_pref);
8055 else
8056 vty_out(vty, ", localpref %u",
8057 attr->local_pref);
8058 }
8059
8060 if (attr->weight != 0) {
8061 if (json_paths)
8062 json_object_int_add(json_path, "weight",
8063 attr->weight);
8064 else
8065 vty_out(vty, ", weight %u", attr->weight);
8066 }
8067
8068 if (attr->tag != 0) {
8069 if (json_paths)
8070 json_object_int_add(json_path, "tag",
8071 attr->tag);
8072 else
8073 vty_out(vty, ", tag %" ROUTE_TAG_PRI,
8074 attr->tag);
8075 }
8076
8077 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
8078 if (json_paths)
8079 json_object_boolean_false_add(json_path,
8080 "valid");
8081 else
8082 vty_out(vty, ", invalid");
8083 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8084 if (json_paths)
8085 json_object_boolean_true_add(json_path,
8086 "valid");
8087 else
8088 vty_out(vty, ", valid");
8089 }
8090
8091 if (path->peer != bgp->peer_self) {
8092 if (path->peer->as == path->peer->local_as) {
8093 if (CHECK_FLAG(bgp->config,
8094 BGP_CONFIG_CONFEDERATION)) {
8095 if (json_paths)
8096 json_object_string_add(
8097 json_peer, "type",
8098 "confed-internal");
8099 else
8100 vty_out(vty,
8101 ", confed-internal");
8102 } else {
8103 if (json_paths)
8104 json_object_string_add(
8105 json_peer, "type",
8106 "internal");
8107 else
8108 vty_out(vty, ", internal");
8109 }
8110 } else {
8111 if (bgp_confederation_peers_check(
8112 bgp, path->peer->as)) {
8113 if (json_paths)
8114 json_object_string_add(
8115 json_peer, "type",
8116 "confed-external");
8117 else
8118 vty_out(vty,
8119 ", confed-external");
8120 } else {
8121 if (json_paths)
8122 json_object_string_add(
8123 json_peer, "type",
8124 "external");
8125 else
8126 vty_out(vty, ", external");
8127 }
8128 }
8129 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
8130 if (json_paths) {
8131 json_object_boolean_true_add(json_path,
8132 "aggregated");
8133 json_object_boolean_true_add(json_path,
8134 "local");
8135 } else {
8136 vty_out(vty, ", aggregated, local");
8137 }
8138 } else if (path->type != ZEBRA_ROUTE_BGP) {
8139 if (json_paths)
8140 json_object_boolean_true_add(json_path,
8141 "sourced");
8142 else
8143 vty_out(vty, ", sourced");
8144 } else {
8145 if (json_paths) {
8146 json_object_boolean_true_add(json_path,
8147 "sourced");
8148 json_object_boolean_true_add(json_path,
8149 "local");
8150 } else {
8151 vty_out(vty, ", sourced, local");
8152 }
8153 }
8154
8155 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
8156 if (json_paths)
8157 json_object_boolean_true_add(json_path,
8158 "atomicAggregate");
8159 else
8160 vty_out(vty, ", atomic-aggregate");
8161 }
8162
8163 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
8164 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
8165 && bgp_path_info_mpath_count(path))) {
8166 if (json_paths)
8167 json_object_boolean_true_add(json_path,
8168 "multipath");
8169 else
8170 vty_out(vty, ", multipath");
8171 }
8172
8173 // Mark the bestpath(s)
8174 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
8175 first_as = aspath_get_first_as(attr->aspath);
8176
8177 if (json_paths) {
8178 if (!json_bestpath)
8179 json_bestpath =
8180 json_object_new_object();
8181 json_object_int_add(json_bestpath,
8182 "bestpathFromAs", first_as);
8183 } else {
8184 if (first_as)
8185 vty_out(vty, ", bestpath-from-AS %u",
8186 first_as);
8187 else
8188 vty_out(vty,
8189 ", bestpath-from-AS Local");
8190 }
8191 }
8192
8193 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
8194 if (json_paths) {
8195 if (!json_bestpath)
8196 json_bestpath =
8197 json_object_new_object();
8198 json_object_boolean_true_add(json_bestpath,
8199 "overall");
8200 } else
8201 vty_out(vty, ", best");
8202 }
8203
8204 if (json_bestpath)
8205 json_object_object_add(json_path, "bestpath",
8206 json_bestpath);
8207
8208 if (!json_paths)
8209 vty_out(vty, "\n");
8210
8211 /* Line 4 display Community */
8212 if (attr->community) {
8213 if (json_paths) {
8214 if (!attr->community->json)
8215 community_str(attr->community, true);
8216 json_object_lock(attr->community->json);
8217 json_object_object_add(json_path, "community",
8218 attr->community->json);
8219 } else {
8220 vty_out(vty, " Community: %s\n",
8221 attr->community->str);
8222 }
8223 }
8224
8225 /* Line 5 display Extended-community */
8226 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8227 if (json_paths) {
8228 json_ext_community = json_object_new_object();
8229 json_object_string_add(json_ext_community,
8230 "string",
8231 attr->ecommunity->str);
8232 json_object_object_add(json_path,
8233 "extendedCommunity",
8234 json_ext_community);
8235 } else {
8236 vty_out(vty, " Extended Community: %s\n",
8237 attr->ecommunity->str);
8238 }
8239 }
8240
8241 /* Line 6 display Large community */
8242 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
8243 if (json_paths) {
8244 if (!attr->lcommunity->json)
8245 lcommunity_str(attr->lcommunity, true);
8246 json_object_lock(attr->lcommunity->json);
8247 json_object_object_add(json_path,
8248 "largeCommunity",
8249 attr->lcommunity->json);
8250 } else {
8251 vty_out(vty, " Large Community: %s\n",
8252 attr->lcommunity->str);
8253 }
8254 }
8255
8256 /* Line 7 display Originator, Cluster-id */
8257 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
8258 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
8259 if (attr->flag
8260 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
8261 if (json_paths)
8262 json_object_string_add(
8263 json_path, "originatorId",
8264 inet_ntoa(attr->originator_id));
8265 else
8266 vty_out(vty, " Originator: %s",
8267 inet_ntoa(attr->originator_id));
8268 }
8269
8270 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
8271 int i;
8272
8273 if (json_paths) {
8274 json_cluster_list =
8275 json_object_new_object();
8276 json_cluster_list_list =
8277 json_object_new_array();
8278
8279 for (i = 0;
8280 i < attr->cluster->length / 4;
8281 i++) {
8282 json_string = json_object_new_string(
8283 inet_ntoa(
8284 attr->cluster->list
8285 [i]));
8286 json_object_array_add(
8287 json_cluster_list_list,
8288 json_string);
8289 }
8290
8291 /* struct cluster_list does not have
8292 "str" variable like
8293 * aspath and community do. Add this
8294 someday if someone
8295 * asks for it.
8296 json_object_string_add(json_cluster_list,
8297 "string", attr->cluster->str);
8298 */
8299 json_object_object_add(
8300 json_cluster_list, "list",
8301 json_cluster_list_list);
8302 json_object_object_add(
8303 json_path, "clusterList",
8304 json_cluster_list);
8305 } else {
8306 vty_out(vty, ", Cluster list: ");
8307
8308 for (i = 0;
8309 i < attr->cluster->length / 4;
8310 i++) {
8311 vty_out(vty, "%s ",
8312 inet_ntoa(
8313 attr->cluster->list
8314 [i]));
8315 }
8316 }
8317 }
8318
8319 if (!json_paths)
8320 vty_out(vty, "\n");
8321 }
8322
8323 if (path->extra && path->extra->damp_info)
8324 bgp_damp_info_vty(vty, path, json_path);
8325
8326 /* Remote Label */
8327 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
8328 && safi != SAFI_EVPN) {
8329 mpls_label_t label = label_pton(&path->extra->label[0]);
8330
8331 if (json_paths)
8332 json_object_int_add(json_path, "remoteLabel",
8333 label);
8334 else
8335 vty_out(vty, " Remote label: %d\n", label);
8336 }
8337
8338 /* Label Index */
8339 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
8340 if (json_paths)
8341 json_object_int_add(json_path, "labelIndex",
8342 attr->label_index);
8343 else
8344 vty_out(vty, " Label Index: %d\n",
8345 attr->label_index);
8346 }
8347
8348 /* Line 8 display Addpath IDs */
8349 if (path->addpath_rx_id
8350 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
8351 if (json_paths) {
8352 json_object_int_add(json_path, "addpathRxId",
8353 path->addpath_rx_id);
8354
8355 /* Keep backwards compatibility with the old API
8356 * by putting TX All's ID in the old field
8357 */
8358 json_object_int_add(
8359 json_path, "addpathTxId",
8360 path->tx_addpath.addpath_tx_id
8361 [BGP_ADDPATH_ALL]);
8362
8363 /* ... but create a specific field for each
8364 * strategy
8365 */
8366 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
8367 json_object_int_add(
8368 json_path,
8369 bgp_addpath_names(i)
8370 ->id_json_name,
8371 path->tx_addpath
8372 .addpath_tx_id[i]);
8373 }
8374 } else {
8375 vty_out(vty, " AddPath ID: RX %u, ",
8376 path->addpath_rx_id);
8377
8378 route_vty_out_tx_ids(vty, &path->tx_addpath);
8379 }
8380 }
8381
8382 /* If we used addpath to TX a non-bestpath we need to display
8383 * "Advertised to" on a path-by-path basis
8384 */
8385 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
8386 first = 1;
8387
8388 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
8389 addpath_capable =
8390 bgp_addpath_encode_tx(peer, afi, safi);
8391 has_adj = bgp_adj_out_lookup(
8392 peer, path->net,
8393 bgp_addpath_id_for_peer(
8394 peer, afi, safi,
8395 &path->tx_addpath));
8396
8397 if ((addpath_capable && has_adj)
8398 || (!addpath_capable && has_adj
8399 && CHECK_FLAG(path->flags,
8400 BGP_PATH_SELECTED))) {
8401 if (json_path && !json_adv_to)
8402 json_adv_to =
8403 json_object_new_object();
8404
8405 route_vty_out_advertised_to(
8406 vty, peer, &first,
8407 " Advertised to:",
8408 json_adv_to);
8409 }
8410 }
8411
8412 if (json_path) {
8413 if (json_adv_to) {
8414 json_object_object_add(json_path,
8415 "advertisedTo",
8416 json_adv_to);
8417 }
8418 } else {
8419 if (!first) {
8420 vty_out(vty, "\n");
8421 }
8422 }
8423 }
8424
8425 /* Line 9 display Uptime */
8426 tbuf = time(NULL) - (bgp_clock() - path->uptime);
8427 if (json_paths) {
8428 json_last_update = json_object_new_object();
8429 json_object_int_add(json_last_update, "epoch", tbuf);
8430 json_object_string_add(json_last_update, "string",
8431 ctime(&tbuf));
8432 json_object_object_add(json_path, "lastUpdate",
8433 json_last_update);
8434 } else
8435 vty_out(vty, " Last update: %s", ctime(&tbuf));
8436
8437 /* Line 10 display PMSI tunnel attribute, if present */
8438 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
8439 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
8440 attr->pmsi_tnl_type,
8441 PMSI_TNLTYPE_STR_DEFAULT);
8442
8443 if (json_paths) {
8444 json_pmsi = json_object_new_object();
8445 json_object_string_add(json_pmsi,
8446 "tunnelType", str);
8447 json_object_int_add(json_pmsi,
8448 "label",
8449 label2vni(&attr->label));
8450 json_object_object_add(json_path, "pmsi",
8451 json_pmsi);
8452 } else
8453 vty_out(vty,
8454 " PMSI Tunnel Type: %s, label: %d\n",
8455 str, label2vni(&attr->label));
8456 }
8457
8458 }
8459
8460 /* We've constructed the json object for this path, add it to the json
8461 * array of paths
8462 */
8463 if (json_paths) {
8464 if (json_nexthop_global || json_nexthop_ll) {
8465 json_nexthops = json_object_new_array();
8466
8467 if (json_nexthop_global)
8468 json_object_array_add(json_nexthops,
8469 json_nexthop_global);
8470
8471 if (json_nexthop_ll)
8472 json_object_array_add(json_nexthops,
8473 json_nexthop_ll);
8474
8475 json_object_object_add(json_path, "nexthops",
8476 json_nexthops);
8477 }
8478
8479 json_object_object_add(json_path, "peer", json_peer);
8480 json_object_array_add(json_paths, json_path);
8481 } else
8482 vty_out(vty, "\n");
8483 }
8484
8485 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
8486 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
8487 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
8488
8489 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
8490 const char *prefix_list_str, afi_t afi,
8491 safi_t safi, enum bgp_show_type type);
8492 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
8493 const char *filter, afi_t afi, safi_t safi,
8494 enum bgp_show_type type);
8495 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
8496 const char *rmap_str, afi_t afi, safi_t safi,
8497 enum bgp_show_type type);
8498 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
8499 const char *com, int exact, afi_t afi,
8500 safi_t safi);
8501 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
8502 const char *prefix, afi_t afi, safi_t safi,
8503 enum bgp_show_type type);
8504 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
8505 afi_t afi, safi_t safi, enum bgp_show_type type);
8506 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
8507 const char *comstr, int exact, afi_t afi,
8508 safi_t safi, bool use_json);
8509
8510
8511 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
8512 struct bgp_table *table, enum bgp_show_type type,
8513 void *output_arg, bool use_json, char *rd,
8514 int is_last, unsigned long *output_cum,
8515 unsigned long *total_cum,
8516 unsigned long *json_header_depth)
8517 {
8518 struct bgp_path_info *pi;
8519 struct bgp_node *rn;
8520 int header = 1;
8521 int display;
8522 unsigned long output_count = 0;
8523 unsigned long total_count = 0;
8524 struct prefix *p;
8525 char buf2[BUFSIZ];
8526 json_object *json_paths = NULL;
8527 int first = 1;
8528
8529 if (output_cum && *output_cum != 0)
8530 header = 0;
8531
8532 if (use_json && !*json_header_depth) {
8533 vty_out(vty,
8534 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
8535 ",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n"
8536 " \"localAS\": %u,\n \"routes\": { ",
8537 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
8538 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
8539 ? VRF_DEFAULT_NAME
8540 : bgp->name,
8541 table->version, inet_ntoa(bgp->router_id),
8542 bgp->default_local_pref, bgp->as);
8543 *json_header_depth = 2;
8544 if (rd) {
8545 vty_out(vty, " \"routeDistinguishers\" : {");
8546 ++*json_header_depth;
8547 }
8548 }
8549
8550 if (use_json && rd) {
8551 vty_out(vty, " \"%s\" : { ", rd);
8552 }
8553
8554 /* Start processing of routes. */
8555 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
8556 pi = bgp_node_get_bgp_path_info(rn);
8557 if (pi == NULL)
8558 continue;
8559
8560 display = 0;
8561 if (use_json)
8562 json_paths = json_object_new_array();
8563 else
8564 json_paths = NULL;
8565
8566 for (; pi; pi = pi->next) {
8567 total_count++;
8568 if (type == bgp_show_type_flap_statistics
8569 || type == bgp_show_type_flap_neighbor
8570 || type == bgp_show_type_dampend_paths
8571 || type == bgp_show_type_damp_neighbor) {
8572 if (!(pi->extra && pi->extra->damp_info))
8573 continue;
8574 }
8575 if (type == bgp_show_type_regexp) {
8576 regex_t *regex = output_arg;
8577
8578 if (bgp_regexec(regex, pi->attr->aspath)
8579 == REG_NOMATCH)
8580 continue;
8581 }
8582 if (type == bgp_show_type_prefix_list) {
8583 struct prefix_list *plist = output_arg;
8584
8585 if (prefix_list_apply(plist, &rn->p)
8586 != PREFIX_PERMIT)
8587 continue;
8588 }
8589 if (type == bgp_show_type_filter_list) {
8590 struct as_list *as_list = output_arg;
8591
8592 if (as_list_apply(as_list, pi->attr->aspath)
8593 != AS_FILTER_PERMIT)
8594 continue;
8595 }
8596 if (type == bgp_show_type_route_map) {
8597 struct route_map *rmap = output_arg;
8598 struct bgp_path_info path;
8599 struct attr dummy_attr;
8600 int ret;
8601
8602 bgp_attr_dup(&dummy_attr, pi->attr);
8603
8604 path.peer = pi->peer;
8605 path.attr = &dummy_attr;
8606
8607 ret = route_map_apply(rmap, &rn->p, RMAP_BGP,
8608 &path);
8609 if (ret == RMAP_DENYMATCH)
8610 continue;
8611 }
8612 if (type == bgp_show_type_neighbor
8613 || type == bgp_show_type_flap_neighbor
8614 || type == bgp_show_type_damp_neighbor) {
8615 union sockunion *su = output_arg;
8616
8617 if (pi->peer == NULL
8618 || pi->peer->su_remote == NULL
8619 || !sockunion_same(pi->peer->su_remote, su))
8620 continue;
8621 }
8622 if (type == bgp_show_type_cidr_only) {
8623 uint32_t destination;
8624
8625 destination = ntohl(rn->p.u.prefix4.s_addr);
8626 if (IN_CLASSC(destination)
8627 && rn->p.prefixlen == 24)
8628 continue;
8629 if (IN_CLASSB(destination)
8630 && rn->p.prefixlen == 16)
8631 continue;
8632 if (IN_CLASSA(destination)
8633 && rn->p.prefixlen == 8)
8634 continue;
8635 }
8636 if (type == bgp_show_type_prefix_longer) {
8637 p = output_arg;
8638 if (!prefix_match(p, &rn->p))
8639 continue;
8640 }
8641 if (type == bgp_show_type_community_all) {
8642 if (!pi->attr->community)
8643 continue;
8644 }
8645 if (type == bgp_show_type_community) {
8646 struct community *com = output_arg;
8647
8648 if (!pi->attr->community
8649 || !community_match(pi->attr->community,
8650 com))
8651 continue;
8652 }
8653 if (type == bgp_show_type_community_exact) {
8654 struct community *com = output_arg;
8655
8656 if (!pi->attr->community
8657 || !community_cmp(pi->attr->community, com))
8658 continue;
8659 }
8660 if (type == bgp_show_type_community_list) {
8661 struct community_list *list = output_arg;
8662
8663 if (!community_list_match(pi->attr->community,
8664 list))
8665 continue;
8666 }
8667 if (type == bgp_show_type_community_list_exact) {
8668 struct community_list *list = output_arg;
8669
8670 if (!community_list_exact_match(
8671 pi->attr->community, list))
8672 continue;
8673 }
8674 if (type == bgp_show_type_lcommunity) {
8675 struct lcommunity *lcom = output_arg;
8676
8677 if (!pi->attr->lcommunity
8678 || !lcommunity_match(pi->attr->lcommunity,
8679 lcom))
8680 continue;
8681 }
8682 if (type == bgp_show_type_lcommunity_list) {
8683 struct community_list *list = output_arg;
8684
8685 if (!lcommunity_list_match(pi->attr->lcommunity,
8686 list))
8687 continue;
8688 }
8689 if (type == bgp_show_type_lcommunity_all) {
8690 if (!pi->attr->lcommunity)
8691 continue;
8692 }
8693 if (type == bgp_show_type_dampend_paths
8694 || type == bgp_show_type_damp_neighbor) {
8695 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
8696 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
8697 continue;
8698 }
8699
8700 if (!use_json && header) {
8701 vty_out(vty, "BGP table version is %" PRIu64
8702 ", local router ID is %s, vrf id ",
8703 table->version,
8704 inet_ntoa(bgp->router_id));
8705 if (bgp->vrf_id == VRF_UNKNOWN)
8706 vty_out(vty, "%s", VRFID_NONE_STR);
8707 else
8708 vty_out(vty, "%u", bgp->vrf_id);
8709 vty_out(vty, "\n");
8710 vty_out(vty, "Default local pref %u, ",
8711 bgp->default_local_pref);
8712 vty_out(vty, "local AS %u\n", bgp->as);
8713 vty_out(vty, BGP_SHOW_SCODE_HEADER);
8714 vty_out(vty, BGP_SHOW_NCODE_HEADER);
8715 vty_out(vty, BGP_SHOW_OCODE_HEADER);
8716 if (type == bgp_show_type_dampend_paths
8717 || type == bgp_show_type_damp_neighbor)
8718 vty_out(vty, BGP_SHOW_DAMP_HEADER);
8719 else if (type == bgp_show_type_flap_statistics
8720 || type == bgp_show_type_flap_neighbor)
8721 vty_out(vty, BGP_SHOW_FLAP_HEADER);
8722 else
8723 vty_out(vty, BGP_SHOW_HEADER);
8724 header = 0;
8725 }
8726 if (rd != NULL && !display && !output_count) {
8727 if (!use_json)
8728 vty_out(vty,
8729 "Route Distinguisher: %s\n",
8730 rd);
8731 }
8732 if (type == bgp_show_type_dampend_paths
8733 || type == bgp_show_type_damp_neighbor)
8734 damp_route_vty_out(vty, &rn->p, pi, display,
8735 safi, use_json, json_paths);
8736 else if (type == bgp_show_type_flap_statistics
8737 || type == bgp_show_type_flap_neighbor)
8738 flap_route_vty_out(vty, &rn->p, pi, display,
8739 safi, use_json, json_paths);
8740 else
8741 route_vty_out(vty, &rn->p, pi, display, safi,
8742 json_paths);
8743 display++;
8744 }
8745
8746 if (display) {
8747 output_count++;
8748 if (!use_json)
8749 continue;
8750
8751 p = &rn->p;
8752 /* encode prefix */
8753 if (p->family == AF_FLOWSPEC) {
8754 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
8755
8756 bgp_fs_nlri_get_string((unsigned char *)
8757 p->u.prefix_flowspec.ptr,
8758 p->u.prefix_flowspec
8759 .prefixlen,
8760 retstr,
8761 NLRI_STRING_FORMAT_MIN,
8762 NULL);
8763 if (first)
8764 vty_out(vty, "\"%s/%d\": ",
8765 retstr,
8766 p->u.prefix_flowspec.prefixlen);
8767 else
8768 vty_out(vty, ",\"%s/%d\": ",
8769 retstr,
8770 p->u.prefix_flowspec.prefixlen);
8771 } else {
8772 prefix2str(p, buf2, sizeof(buf2));
8773 if (first)
8774 vty_out(vty, "\"%s\": ", buf2);
8775 else
8776 vty_out(vty, ",\"%s\": ", buf2);
8777 }
8778 vty_out(vty, "%s",
8779 json_object_to_json_string(json_paths));
8780 json_object_free(json_paths);
8781 json_paths = NULL;
8782 first = 0;
8783 }
8784 }
8785
8786 if (output_cum) {
8787 output_count += *output_cum;
8788 *output_cum = output_count;
8789 }
8790 if (total_cum) {
8791 total_count += *total_cum;
8792 *total_cum = total_count;
8793 }
8794 if (use_json) {
8795 if (rd) {
8796 vty_out(vty, " }%s ", (is_last ? "" : ","));
8797 }
8798 if (is_last) {
8799 unsigned long i;
8800 for (i = 0; i < *json_header_depth; ++i)
8801 vty_out(vty, " } ");
8802 }
8803 } else {
8804 if (is_last) {
8805 /* No route is displayed */
8806 if (output_count == 0) {
8807 if (type == bgp_show_type_normal)
8808 vty_out(vty,
8809 "No BGP prefixes displayed, %ld exist\n",
8810 total_count);
8811 } else
8812 vty_out(vty,
8813 "\nDisplayed %ld routes and %ld total paths\n",
8814 output_count, total_count);
8815 }
8816 }
8817
8818 return CMD_SUCCESS;
8819 }
8820
8821 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
8822 struct bgp_table *table, struct prefix_rd *prd_match,
8823 enum bgp_show_type type, void *output_arg, bool use_json)
8824 {
8825 struct bgp_node *rn, *next;
8826 unsigned long output_cum = 0;
8827 unsigned long total_cum = 0;
8828 unsigned long json_header_depth = 0;
8829 struct bgp_table *itable;
8830 bool show_msg;
8831
8832 show_msg = (!use_json && type == bgp_show_type_normal);
8833
8834 for (rn = bgp_table_top(table); rn; rn = next) {
8835 next = bgp_route_next(rn);
8836 if (prd_match && memcmp(rn->p.u.val, prd_match->val, 8) != 0)
8837 continue;
8838
8839 itable = bgp_node_get_bgp_table_info(rn);
8840 if (itable != NULL) {
8841 struct prefix_rd prd;
8842 char rd[RD_ADDRSTRLEN];
8843
8844 memcpy(&prd, &(rn->p), sizeof(struct prefix_rd));
8845 prefix_rd2str(&prd, rd, sizeof(rd));
8846 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
8847 use_json, rd, next == NULL, &output_cum,
8848 &total_cum, &json_header_depth);
8849 if (next == NULL)
8850 show_msg = false;
8851 }
8852 }
8853 if (show_msg) {
8854 if (output_cum == 0)
8855 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
8856 total_cum);
8857 else
8858 vty_out(vty,
8859 "\nDisplayed %ld routes and %ld total paths\n",
8860 output_cum, total_cum);
8861 }
8862 return CMD_SUCCESS;
8863 }
8864 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
8865 enum bgp_show_type type, void *output_arg, bool use_json)
8866 {
8867 struct bgp_table *table;
8868 unsigned long json_header_depth = 0;
8869
8870 if (bgp == NULL) {
8871 bgp = bgp_get_default();
8872 }
8873
8874 if (bgp == NULL) {
8875 if (!use_json)
8876 vty_out(vty, "No BGP process is configured\n");
8877 else
8878 vty_out(vty, "{}\n");
8879 return CMD_WARNING;
8880 }
8881
8882 table = bgp->rib[afi][safi];
8883 /* use MPLS and ENCAP specific shows until they are merged */
8884 if (safi == SAFI_MPLS_VPN) {
8885 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
8886 output_arg, use_json);
8887 }
8888
8889 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
8890 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
8891 output_arg, use_json,
8892 1, NULL, NULL);
8893 }
8894 /* labeled-unicast routes live in the unicast table */
8895 else if (safi == SAFI_LABELED_UNICAST)
8896 safi = SAFI_UNICAST;
8897
8898 return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json,
8899 NULL, 1, NULL, NULL, &json_header_depth);
8900 }
8901
8902 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
8903 safi_t safi, bool use_json)
8904 {
8905 struct listnode *node, *nnode;
8906 struct bgp *bgp;
8907 int is_first = 1;
8908 bool route_output = false;
8909
8910 if (use_json)
8911 vty_out(vty, "{\n");
8912
8913 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
8914 route_output = true;
8915 if (use_json) {
8916 if (!is_first)
8917 vty_out(vty, ",\n");
8918 else
8919 is_first = 0;
8920
8921 vty_out(vty, "\"%s\":",
8922 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
8923 ? VRF_DEFAULT_NAME
8924 : bgp->name);
8925 } else {
8926 vty_out(vty, "\nInstance %s:\n",
8927 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
8928 ? VRF_DEFAULT_NAME
8929 : bgp->name);
8930 }
8931 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
8932 use_json);
8933 }
8934
8935 if (use_json)
8936 vty_out(vty, "}\n");
8937 else if (!route_output)
8938 vty_out(vty, "%% BGP instance not found\n");
8939 }
8940
8941 /* Header of detailed BGP route information */
8942 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
8943 struct bgp_node *rn, struct prefix_rd *prd,
8944 afi_t afi, safi_t safi, json_object *json)
8945 {
8946 struct bgp_path_info *pi;
8947 struct prefix *p;
8948 struct peer *peer;
8949 struct listnode *node, *nnode;
8950 char buf1[RD_ADDRSTRLEN];
8951 char buf2[INET6_ADDRSTRLEN];
8952 char buf3[EVPN_ROUTE_STRLEN];
8953 char prefix_str[BUFSIZ];
8954 int count = 0;
8955 int best = 0;
8956 int suppress = 0;
8957 int accept_own = 0;
8958 int route_filter_translated_v4 = 0;
8959 int route_filter_v4 = 0;
8960 int route_filter_translated_v6 = 0;
8961 int route_filter_v6 = 0;
8962 int llgr_stale = 0;
8963 int no_llgr = 0;
8964 int accept_own_nexthop = 0;
8965 int blackhole = 0;
8966 int no_export = 0;
8967 int no_advertise = 0;
8968 int local_as = 0;
8969 int no_peer = 0;
8970 int first = 1;
8971 int has_valid_label = 0;
8972 mpls_label_t label = 0;
8973 json_object *json_adv_to = NULL;
8974
8975 p = &rn->p;
8976 has_valid_label = bgp_is_valid_label(&rn->local_label);
8977
8978 if (has_valid_label)
8979 label = label_pton(&rn->local_label);
8980
8981 if (json) {
8982 if (has_valid_label)
8983 json_object_int_add(json, "localLabel", label);
8984
8985 json_object_string_add(
8986 json, "prefix",
8987 prefix2str(p, prefix_str, sizeof(prefix_str)));
8988 } else {
8989 if (safi == SAFI_EVPN)
8990 vty_out(vty, "BGP routing table entry for %s%s%s\n",
8991 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
8992 : "",
8993 prd ? ":" : "",
8994 bgp_evpn_route2str((struct prefix_evpn *)p,
8995 buf3, sizeof(buf3)));
8996 else
8997 vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
8998 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
8999 ? prefix_rd2str(prd, buf1,
9000 sizeof(buf1))
9001 : ""),
9002 safi == SAFI_MPLS_VPN ? ":" : "",
9003 inet_ntop(p->family, &p->u.prefix, buf2,
9004 INET6_ADDRSTRLEN),
9005 p->prefixlen);
9006
9007 if (has_valid_label)
9008 vty_out(vty, "Local label: %d\n", label);
9009 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
9010 vty_out(vty, "not allocated\n");
9011 }
9012
9013 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
9014 count++;
9015 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
9016 best = count;
9017 if (pi->extra && pi->extra->suppress)
9018 suppress = 1;
9019
9020 if (pi->attr->community == NULL)
9021 continue;
9022
9023 no_advertise += community_include(
9024 pi->attr->community, COMMUNITY_NO_ADVERTISE);
9025 no_export += community_include(pi->attr->community,
9026 COMMUNITY_NO_EXPORT);
9027 local_as += community_include(pi->attr->community,
9028 COMMUNITY_LOCAL_AS);
9029 accept_own += community_include(pi->attr->community,
9030 COMMUNITY_ACCEPT_OWN);
9031 route_filter_translated_v4 += community_include(
9032 pi->attr->community,
9033 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
9034 route_filter_translated_v6 += community_include(
9035 pi->attr->community,
9036 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
9037 route_filter_v4 += community_include(
9038 pi->attr->community, COMMUNITY_ROUTE_FILTER_v4);
9039 route_filter_v6 += community_include(
9040 pi->attr->community, COMMUNITY_ROUTE_FILTER_v6);
9041 llgr_stale += community_include(pi->attr->community,
9042 COMMUNITY_LLGR_STALE);
9043 no_llgr += community_include(pi->attr->community,
9044 COMMUNITY_NO_LLGR);
9045 accept_own_nexthop +=
9046 community_include(pi->attr->community,
9047 COMMUNITY_ACCEPT_OWN_NEXTHOP);
9048 blackhole += community_include(pi->attr->community,
9049 COMMUNITY_BLACKHOLE);
9050 no_peer += community_include(pi->attr->community,
9051 COMMUNITY_NO_PEER);
9052 }
9053 }
9054
9055 if (!json) {
9056 vty_out(vty, "Paths: (%d available", count);
9057 if (best) {
9058 vty_out(vty, ", best #%d", best);
9059 if (safi == SAFI_UNICAST)
9060 vty_out(vty, ", table %s",
9061 (bgp->inst_type
9062 == BGP_INSTANCE_TYPE_DEFAULT)
9063 ? VRF_DEFAULT_NAME
9064 : bgp->name);
9065 } else
9066 vty_out(vty, ", no best path");
9067
9068 if (accept_own)
9069 vty_out(vty,
9070 ", accept own local route exported and imported in different VRF");
9071 else if (route_filter_translated_v4)
9072 vty_out(vty,
9073 ", mark translated RTs for VPNv4 route filtering");
9074 else if (route_filter_v4)
9075 vty_out(vty,
9076 ", attach RT as-is for VPNv4 route filtering");
9077 else if (route_filter_translated_v6)
9078 vty_out(vty,
9079 ", mark translated RTs for VPNv6 route filtering");
9080 else if (route_filter_v6)
9081 vty_out(vty,
9082 ", attach RT as-is for VPNv6 route filtering");
9083 else if (llgr_stale)
9084 vty_out(vty,
9085 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
9086 else if (no_llgr)
9087 vty_out(vty,
9088 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
9089 else if (accept_own_nexthop)
9090 vty_out(vty,
9091 ", accept local nexthop");
9092 else if (blackhole)
9093 vty_out(vty, ", inform peer to blackhole prefix");
9094 else if (no_export)
9095 vty_out(vty, ", not advertised to EBGP peer");
9096 else if (no_advertise)
9097 vty_out(vty, ", not advertised to any peer");
9098 else if (local_as)
9099 vty_out(vty, ", not advertised outside local AS");
9100 else if (no_peer)
9101 vty_out(vty,
9102 ", inform EBGP peer not to advertise to their EBGP peers");
9103
9104 if (suppress)
9105 vty_out(vty,
9106 ", Advertisements suppressed by an aggregate.");
9107 vty_out(vty, ")\n");
9108 }
9109
9110 /* If we are not using addpath then we can display Advertised to and
9111 * that will
9112 * show what peers we advertised the bestpath to. If we are using
9113 * addpath
9114 * though then we must display Advertised to on a path-by-path basis. */
9115 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
9116 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
9117 if (bgp_adj_out_lookup(peer, rn, 0)) {
9118 if (json && !json_adv_to)
9119 json_adv_to = json_object_new_object();
9120
9121 route_vty_out_advertised_to(
9122 vty, peer, &first,
9123 " Advertised to non peer-group peers:\n ",
9124 json_adv_to);
9125 }
9126 }
9127
9128 if (json) {
9129 if (json_adv_to) {
9130 json_object_object_add(json, "advertisedTo",
9131 json_adv_to);
9132 }
9133 } else {
9134 if (first)
9135 vty_out(vty, " Not advertised to any peer");
9136 vty_out(vty, "\n");
9137 }
9138 }
9139 }
9140
9141 /* Display specified route of BGP table. */
9142 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
9143 struct bgp_table *rib, const char *ip_str,
9144 afi_t afi, safi_t safi,
9145 struct prefix_rd *prd, int prefix_check,
9146 enum bgp_path_type pathtype, bool use_json)
9147 {
9148 int ret;
9149 int header;
9150 int display = 0;
9151 struct prefix match;
9152 struct bgp_node *rn;
9153 struct bgp_node *rm;
9154 struct bgp_path_info *pi;
9155 struct bgp_table *table;
9156 json_object *json = NULL;
9157 json_object *json_paths = NULL;
9158
9159 /* Check IP address argument. */
9160 ret = str2prefix(ip_str, &match);
9161 if (!ret) {
9162 vty_out(vty, "address is malformed\n");
9163 return CMD_WARNING;
9164 }
9165
9166 match.family = afi2family(afi);
9167
9168 if (use_json) {
9169 json = json_object_new_object();
9170 json_paths = json_object_new_array();
9171 }
9172
9173 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
9174 for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
9175 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
9176 continue;
9177 table = bgp_node_get_bgp_table_info(rn);
9178 if (!table)
9179 continue;
9180
9181 header = 1;
9182
9183 if ((rm = bgp_node_match(table, &match)) == NULL)
9184 continue;
9185
9186 if (prefix_check
9187 && rm->p.prefixlen != match.prefixlen) {
9188 bgp_unlock_node(rm);
9189 continue;
9190 }
9191
9192 for (pi = bgp_node_get_bgp_path_info(rm); pi;
9193 pi = pi->next) {
9194 if (header) {
9195 route_vty_out_detail_header(
9196 vty, bgp, rm,
9197 (struct prefix_rd *)&rn->p,
9198 AFI_IP, safi, json);
9199 header = 0;
9200 }
9201 display++;
9202
9203 if (pathtype == BGP_PATH_SHOW_ALL
9204 || (pathtype == BGP_PATH_SHOW_BESTPATH
9205 && CHECK_FLAG(pi->flags,
9206 BGP_PATH_SELECTED))
9207 || (pathtype == BGP_PATH_SHOW_MULTIPATH
9208 && (CHECK_FLAG(pi->flags,
9209 BGP_PATH_MULTIPATH)
9210 || CHECK_FLAG(pi->flags,
9211 BGP_PATH_SELECTED))))
9212 route_vty_out_detail(vty, bgp, &rm->p,
9213 pi, AFI_IP, safi,
9214 json_paths);
9215 }
9216
9217 bgp_unlock_node(rm);
9218 }
9219 } else if (safi == SAFI_FLOWSPEC) {
9220 display = bgp_flowspec_display_match_per_ip(afi, rib,
9221 &match, prefix_check,
9222 vty,
9223 use_json,
9224 json_paths);
9225 } else {
9226 header = 1;
9227
9228 if ((rn = bgp_node_match(rib, &match)) != NULL) {
9229 if (!prefix_check
9230 || rn->p.prefixlen == match.prefixlen) {
9231 for (pi = bgp_node_get_bgp_path_info(rn); pi;
9232 pi = pi->next) {
9233 if (header) {
9234 route_vty_out_detail_header(
9235 vty, bgp, rn, NULL, afi,
9236 safi, json);
9237 header = 0;
9238 }
9239 display++;
9240
9241 if (pathtype == BGP_PATH_SHOW_ALL
9242 || (pathtype
9243 == BGP_PATH_SHOW_BESTPATH
9244 && CHECK_FLAG(
9245 pi->flags,
9246 BGP_PATH_SELECTED))
9247 || (pathtype
9248 == BGP_PATH_SHOW_MULTIPATH
9249 && (CHECK_FLAG(
9250 pi->flags,
9251 BGP_PATH_MULTIPATH)
9252 || CHECK_FLAG(
9253 pi->flags,
9254 BGP_PATH_SELECTED))))
9255 route_vty_out_detail(
9256 vty, bgp, &rn->p, pi,
9257 afi, safi, json_paths);
9258 }
9259 }
9260
9261 bgp_unlock_node(rn);
9262 }
9263 }
9264
9265 if (use_json) {
9266 if (display)
9267 json_object_object_add(json, "paths", json_paths);
9268
9269 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9270 json, JSON_C_TO_STRING_PRETTY));
9271 json_object_free(json);
9272 } else {
9273 if (!display) {
9274 vty_out(vty, "%% Network not in table\n");
9275 return CMD_WARNING;
9276 }
9277 }
9278
9279 return CMD_SUCCESS;
9280 }
9281
9282 /* Display specified route of Main RIB */
9283 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
9284 afi_t afi, safi_t safi, struct prefix_rd *prd,
9285 int prefix_check, enum bgp_path_type pathtype,
9286 bool use_json)
9287 {
9288 if (!bgp) {
9289 bgp = bgp_get_default();
9290 if (!bgp) {
9291 if (!use_json)
9292 vty_out(vty, "No BGP process is configured\n");
9293 else
9294 vty_out(vty, "{}\n");
9295 return CMD_WARNING;
9296 }
9297 }
9298
9299 /* labeled-unicast routes live in the unicast table */
9300 if (safi == SAFI_LABELED_UNICAST)
9301 safi = SAFI_UNICAST;
9302
9303 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
9304 afi, safi, prd, prefix_check, pathtype,
9305 use_json);
9306 }
9307
9308 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
9309 struct cmd_token **argv, afi_t afi, safi_t safi,
9310 bool uj)
9311 {
9312 struct lcommunity *lcom;
9313 struct buffer *b;
9314 int i;
9315 char *str;
9316 int first = 0;
9317
9318 b = buffer_new(1024);
9319 for (i = 0; i < argc; i++) {
9320 if (first)
9321 buffer_putc(b, ' ');
9322 else {
9323 if (strmatch(argv[i]->text, "AA:BB:CC")) {
9324 first = 1;
9325 buffer_putstr(b, argv[i]->arg);
9326 }
9327 }
9328 }
9329 buffer_putc(b, '\0');
9330
9331 str = buffer_getstr(b);
9332 buffer_free(b);
9333
9334 lcom = lcommunity_str2com(str);
9335 XFREE(MTYPE_TMP, str);
9336 if (!lcom) {
9337 vty_out(vty, "%% Large-community malformed\n");
9338 return CMD_WARNING;
9339 }
9340
9341 return bgp_show(vty, bgp, afi, safi, bgp_show_type_lcommunity, lcom,
9342 uj);
9343 }
9344
9345 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
9346 const char *lcom, afi_t afi, safi_t safi,
9347 bool uj)
9348 {
9349 struct community_list *list;
9350
9351 list = community_list_lookup(bgp_clist, lcom, 0,
9352 LARGE_COMMUNITY_LIST_MASTER);
9353 if (list == NULL) {
9354 vty_out(vty, "%% %s is not a valid large-community-list name\n",
9355 lcom);
9356 return CMD_WARNING;
9357 }
9358
9359 return bgp_show(vty, bgp, afi, safi, bgp_show_type_lcommunity_list,
9360 list, uj);
9361 }
9362
9363 DEFUN (show_ip_bgp_large_community_list,
9364 show_ip_bgp_large_community_list_cmd,
9365 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community-list <(1-500)|WORD> [json]",
9366 SHOW_STR
9367 IP_STR
9368 BGP_STR
9369 BGP_INSTANCE_HELP_STR
9370 BGP_AFI_HELP_STR
9371 BGP_SAFI_WITH_LABEL_HELP_STR
9372 "Display routes matching the large-community-list\n"
9373 "large-community-list number\n"
9374 "large-community-list name\n"
9375 JSON_STR)
9376 {
9377 char *vrf = NULL;
9378 afi_t afi = AFI_IP6;
9379 safi_t safi = SAFI_UNICAST;
9380 int idx = 0;
9381
9382 if (argv_find(argv, argc, "ip", &idx))
9383 afi = AFI_IP;
9384 if (argv_find(argv, argc, "view", &idx)
9385 || argv_find(argv, argc, "vrf", &idx))
9386 vrf = argv[++idx]->arg;
9387 if (argv_find(argv, argc, "ipv4", &idx)
9388 || argv_find(argv, argc, "ipv6", &idx)) {
9389 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
9390 if (argv_find(argv, argc, "unicast", &idx)
9391 || argv_find(argv, argc, "multicast", &idx))
9392 safi = bgp_vty_safi_from_str(argv[idx]->text);
9393 }
9394
9395 bool uj = use_json(argc, argv);
9396
9397 struct bgp *bgp = bgp_lookup_by_name(vrf);
9398 if (bgp == NULL) {
9399 vty_out(vty, "Can't find BGP instance %s\n", vrf);
9400 return CMD_WARNING;
9401 }
9402
9403 argv_find(argv, argc, "large-community-list", &idx);
9404 return bgp_show_lcommunity_list(vty, bgp, argv[idx + 1]->arg, afi, safi,
9405 uj);
9406 }
9407 DEFUN (show_ip_bgp_large_community,
9408 show_ip_bgp_large_community_cmd,
9409 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [AA:BB:CC] [json]",
9410 SHOW_STR
9411 IP_STR
9412 BGP_STR
9413 BGP_INSTANCE_HELP_STR
9414 BGP_AFI_HELP_STR
9415 BGP_SAFI_WITH_LABEL_HELP_STR
9416 "Display routes matching the large-communities\n"
9417 "List of large-community numbers\n"
9418 JSON_STR)
9419 {
9420 char *vrf = NULL;
9421 afi_t afi = AFI_IP6;
9422 safi_t safi = SAFI_UNICAST;
9423 int idx = 0;
9424
9425 if (argv_find(argv, argc, "ip", &idx))
9426 afi = AFI_IP;
9427 if (argv_find(argv, argc, "view", &idx)
9428 || argv_find(argv, argc, "vrf", &idx))
9429 vrf = argv[++idx]->arg;
9430 if (argv_find(argv, argc, "ipv4", &idx)
9431 || argv_find(argv, argc, "ipv6", &idx)) {
9432 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
9433 if (argv_find(argv, argc, "unicast", &idx)
9434 || argv_find(argv, argc, "multicast", &idx))
9435 safi = bgp_vty_safi_from_str(argv[idx]->text);
9436 }
9437
9438 bool uj = use_json(argc, argv);
9439
9440 struct bgp *bgp = bgp_lookup_by_name(vrf);
9441 if (bgp == NULL) {
9442 vty_out(vty, "Can't find BGP instance %s\n", vrf);
9443 return CMD_WARNING;
9444 }
9445
9446 if (argv_find(argv, argc, "AA:BB:CC", &idx))
9447 return bgp_show_lcommunity(vty, bgp, argc, argv, afi, safi, uj);
9448 else
9449 return bgp_show(vty, bgp, afi, safi,
9450 bgp_show_type_lcommunity_all, NULL, uj);
9451 }
9452
9453 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
9454 safi_t safi);
9455
9456
9457 /* BGP route print out function without JSON */
9458 DEFUN (show_ip_bgp,
9459 show_ip_bgp_cmd,
9460 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
9461 <dampening <parameters>\
9462 |route-map WORD\
9463 |prefix-list WORD\
9464 |filter-list WORD\
9465 |statistics\
9466 |community-list <(1-500)|WORD> [exact-match]\
9467 |A.B.C.D/M longer-prefixes\
9468 |X:X::X:X/M longer-prefixes\
9469 >",
9470 SHOW_STR
9471 IP_STR
9472 BGP_STR
9473 BGP_INSTANCE_HELP_STR
9474 BGP_AFI_HELP_STR
9475 BGP_SAFI_WITH_LABEL_HELP_STR
9476 "Display detailed information about dampening\n"
9477 "Display detail of configured dampening parameters\n"
9478 "Display routes matching the route-map\n"
9479 "A route-map to match on\n"
9480 "Display routes conforming to the prefix-list\n"
9481 "Prefix-list name\n"
9482 "Display routes conforming to the filter-list\n"
9483 "Regular expression access list name\n"
9484 "BGP RIB advertisement statistics\n"
9485 "Display routes matching the community-list\n"
9486 "community-list number\n"
9487 "community-list name\n"
9488 "Exact match of the communities\n"
9489 "IPv4 prefix\n"
9490 "Display route and more specific routes\n"
9491 "IPv6 prefix\n"
9492 "Display route and more specific routes\n")
9493 {
9494 afi_t afi = AFI_IP6;
9495 safi_t safi = SAFI_UNICAST;
9496 int exact_match = 0;
9497 struct bgp *bgp = NULL;
9498 int idx = 0;
9499
9500 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9501 &bgp, false);
9502 if (!idx)
9503 return CMD_WARNING;
9504
9505 if (argv_find(argv, argc, "dampening", &idx)) {
9506 if (argv_find(argv, argc, "parameters", &idx))
9507 return bgp_show_dampening_parameters(vty, afi, safi);
9508 }
9509
9510 if (argv_find(argv, argc, "prefix-list", &idx))
9511 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
9512 safi, bgp_show_type_prefix_list);
9513
9514 if (argv_find(argv, argc, "filter-list", &idx))
9515 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
9516 safi, bgp_show_type_filter_list);
9517
9518 if (argv_find(argv, argc, "statistics", &idx))
9519 return bgp_table_stats(vty, bgp, afi, safi);
9520
9521 if (argv_find(argv, argc, "route-map", &idx))
9522 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
9523 safi, bgp_show_type_route_map);
9524
9525 if (argv_find(argv, argc, "community-list", &idx)) {
9526 const char *clist_number_or_name = argv[++idx]->arg;
9527 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
9528 exact_match = 1;
9529 return bgp_show_community_list(vty, bgp, clist_number_or_name,
9530 exact_match, afi, safi);
9531 }
9532 /* prefix-longer */
9533 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
9534 || argv_find(argv, argc, "X:X::X:X/M", &idx))
9535 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
9536 safi,
9537 bgp_show_type_prefix_longer);
9538
9539 return CMD_WARNING;
9540 }
9541
9542 /* BGP route print out function with JSON */
9543 DEFUN (show_ip_bgp_json,
9544 show_ip_bgp_json_cmd,
9545 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
9546 [cidr-only\
9547 |dampening <flap-statistics|dampened-paths>\
9548 |community [AA:NN|local-AS|no-advertise|no-export\
9549 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
9550 |accept-own|accept-own-nexthop|route-filter-v6\
9551 |route-filter-v4|route-filter-translated-v6\
9552 |route-filter-translated-v4] [exact-match]\
9553 ] [json]",
9554 SHOW_STR
9555 IP_STR
9556 BGP_STR
9557 BGP_INSTANCE_HELP_STR
9558 BGP_AFI_HELP_STR
9559 BGP_SAFI_WITH_LABEL_HELP_STR
9560 "Display only routes with non-natural netmasks\n"
9561 "Display detailed information about dampening\n"
9562 "Display flap statistics of routes\n"
9563 "Display paths suppressed due to dampening\n"
9564 "Display routes matching the communities\n"
9565 COMMUNITY_AANN_STR
9566 "Do not send outside local AS (well-known community)\n"
9567 "Do not advertise to any peer (well-known community)\n"
9568 "Do not export to next AS (well-known community)\n"
9569 "Graceful shutdown (well-known community)\n"
9570 "Do not export to any peer (well-known community)\n"
9571 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
9572 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
9573 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
9574 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
9575 "Should accept VPN route with local nexthop (well-known community)\n"
9576 "RT VPNv6 route filtering (well-known community)\n"
9577 "RT VPNv4 route filtering (well-known community)\n"
9578 "RT translated VPNv6 route filtering (well-known community)\n"
9579 "RT translated VPNv4 route filtering (well-known community)\n"
9580 "Exact match of the communities\n"
9581 JSON_STR)
9582 {
9583 afi_t afi = AFI_IP6;
9584 safi_t safi = SAFI_UNICAST;
9585 enum bgp_show_type sh_type = bgp_show_type_normal;
9586 struct bgp *bgp = NULL;
9587 int idx = 0;
9588 int exact_match = 0;
9589 bool uj = use_json(argc, argv);
9590
9591 if (uj)
9592 argc--;
9593
9594 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9595 &bgp, uj);
9596 if (!idx)
9597 return CMD_WARNING;
9598
9599 if (argv_find(argv, argc, "cidr-only", &idx))
9600 return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only,
9601 NULL, uj);
9602
9603 if (argv_find(argv, argc, "dampening", &idx)) {
9604 if (argv_find(argv, argc, "dampened-paths", &idx))
9605 return bgp_show(vty, bgp, afi, safi,
9606 bgp_show_type_dampend_paths, NULL, uj);
9607 else if (argv_find(argv, argc, "flap-statistics", &idx))
9608 return bgp_show(vty, bgp, afi, safi,
9609 bgp_show_type_flap_statistics, NULL,
9610 uj);
9611 }
9612
9613 if (argv_find(argv, argc, "community", &idx)) {
9614 char *maybecomm = NULL;
9615 char *community = NULL;
9616
9617 if (idx + 1 < argc) {
9618 if (argv[idx + 1]->type == VARIABLE_TKN)
9619 maybecomm = argv[idx + 1]->arg;
9620 else
9621 maybecomm = argv[idx + 1]->text;
9622 }
9623
9624 if (maybecomm && !strmatch(maybecomm, "json")
9625 && !strmatch(maybecomm, "exact-match"))
9626 community = maybecomm;
9627
9628 if (argv_find(argv, argc, "exact-match", &idx))
9629 exact_match = 1;
9630
9631 if (community)
9632 return bgp_show_community(vty, bgp, community,
9633 exact_match, afi, safi, uj);
9634 else
9635 return (bgp_show(vty, bgp, afi, safi,
9636 bgp_show_type_community_all, NULL,
9637 uj));
9638 }
9639
9640 return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
9641 }
9642
9643 DEFUN (show_ip_bgp_route,
9644 show_ip_bgp_route_cmd,
9645 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]"
9646 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
9647 SHOW_STR
9648 IP_STR
9649 BGP_STR
9650 BGP_INSTANCE_HELP_STR
9651 BGP_AFI_HELP_STR
9652 BGP_SAFI_WITH_LABEL_HELP_STR
9653 "Network in the BGP routing table to display\n"
9654 "IPv4 prefix\n"
9655 "Network in the BGP routing table to display\n"
9656 "IPv6 prefix\n"
9657 "Display only the bestpath\n"
9658 "Display only multipaths\n"
9659 JSON_STR)
9660 {
9661 int prefix_check = 0;
9662
9663 afi_t afi = AFI_IP6;
9664 safi_t safi = SAFI_UNICAST;
9665 char *prefix = NULL;
9666 struct bgp *bgp = NULL;
9667 enum bgp_path_type path_type;
9668 bool uj = use_json(argc, argv);
9669
9670 int idx = 0;
9671
9672 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9673 &bgp, uj);
9674 if (!idx)
9675 return CMD_WARNING;
9676
9677 if (!bgp) {
9678 vty_out(vty,
9679 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
9680 return CMD_WARNING;
9681 }
9682
9683 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
9684 if (argv_find(argv, argc, "A.B.C.D", &idx)
9685 || argv_find(argv, argc, "X:X::X:X", &idx))
9686 prefix_check = 0;
9687 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
9688 || argv_find(argv, argc, "X:X::X:X/M", &idx))
9689 prefix_check = 1;
9690
9691 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
9692 && afi != AFI_IP6) {
9693 vty_out(vty,
9694 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
9695 return CMD_WARNING;
9696 }
9697 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
9698 && afi != AFI_IP) {
9699 vty_out(vty,
9700 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
9701 return CMD_WARNING;
9702 }
9703
9704 prefix = argv[idx]->arg;
9705
9706 /* [<bestpath|multipath>] */
9707 if (argv_find(argv, argc, "bestpath", &idx))
9708 path_type = BGP_PATH_SHOW_BESTPATH;
9709 else if (argv_find(argv, argc, "multipath", &idx))
9710 path_type = BGP_PATH_SHOW_MULTIPATH;
9711 else
9712 path_type = BGP_PATH_SHOW_ALL;
9713
9714 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
9715 path_type, uj);
9716 }
9717
9718 DEFUN (show_ip_bgp_regexp,
9719 show_ip_bgp_regexp_cmd,
9720 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX...",
9721 SHOW_STR
9722 IP_STR
9723 BGP_STR
9724 BGP_INSTANCE_HELP_STR
9725 BGP_AFI_HELP_STR
9726 BGP_SAFI_WITH_LABEL_HELP_STR
9727 "Display routes matching the AS path regular expression\n"
9728 "A regular-expression to match the BGP AS paths\n")
9729 {
9730 afi_t afi = AFI_IP6;
9731 safi_t safi = SAFI_UNICAST;
9732 struct bgp *bgp = NULL;
9733
9734 int idx = 0;
9735 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9736 &bgp, false);
9737 if (!idx)
9738 return CMD_WARNING;
9739
9740 // get index of regex
9741 argv_find(argv, argc, "regexp", &idx);
9742 idx++;
9743
9744 char *regstr = argv_concat(argv, argc, idx);
9745 int rc = bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
9746 bgp_show_type_regexp);
9747 XFREE(MTYPE_TMP, regstr);
9748 return rc;
9749 }
9750
9751 DEFUN (show_ip_bgp_instance_all,
9752 show_ip_bgp_instance_all_cmd,
9753 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json]",
9754 SHOW_STR
9755 IP_STR
9756 BGP_STR
9757 BGP_INSTANCE_ALL_HELP_STR
9758 BGP_AFI_HELP_STR
9759 BGP_SAFI_WITH_LABEL_HELP_STR
9760 JSON_STR)
9761 {
9762 afi_t afi = AFI_IP;
9763 safi_t safi = SAFI_UNICAST;
9764 struct bgp *bgp = NULL;
9765 int idx = 0;
9766 bool uj = use_json(argc, argv);
9767
9768 if (uj)
9769 argc--;
9770
9771 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9772 &bgp, uj);
9773 if (!idx)
9774 return CMD_WARNING;
9775
9776 bgp_show_all_instances_routes_vty(vty, afi, safi, uj);
9777 return CMD_SUCCESS;
9778 }
9779
9780 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
9781 afi_t afi, safi_t safi, enum bgp_show_type type)
9782 {
9783 regex_t *regex;
9784 int rc;
9785
9786 regex = bgp_regcomp(regstr);
9787 if (!regex) {
9788 vty_out(vty, "Can't compile regexp %s\n", regstr);
9789 return CMD_WARNING;
9790 }
9791
9792 rc = bgp_show(vty, bgp, afi, safi, type, regex, 0);
9793 bgp_regex_free(regex);
9794 return rc;
9795 }
9796
9797 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
9798 const char *prefix_list_str, afi_t afi,
9799 safi_t safi, enum bgp_show_type type)
9800 {
9801 struct prefix_list *plist;
9802
9803 plist = prefix_list_lookup(afi, prefix_list_str);
9804 if (plist == NULL) {
9805 vty_out(vty, "%% %s is not a valid prefix-list name\n",
9806 prefix_list_str);
9807 return CMD_WARNING;
9808 }
9809
9810 return bgp_show(vty, bgp, afi, safi, type, plist, 0);
9811 }
9812
9813 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
9814 const char *filter, afi_t afi, safi_t safi,
9815 enum bgp_show_type type)
9816 {
9817 struct as_list *as_list;
9818
9819 as_list = as_list_lookup(filter);
9820 if (as_list == NULL) {
9821 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
9822 filter);
9823 return CMD_WARNING;
9824 }
9825
9826 return bgp_show(vty, bgp, afi, safi, type, as_list, 0);
9827 }
9828
9829 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
9830 const char *rmap_str, afi_t afi, safi_t safi,
9831 enum bgp_show_type type)
9832 {
9833 struct route_map *rmap;
9834
9835 rmap = route_map_lookup_by_name(rmap_str);
9836 if (!rmap) {
9837 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
9838 return CMD_WARNING;
9839 }
9840
9841 return bgp_show(vty, bgp, afi, safi, type, rmap, 0);
9842 }
9843
9844 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
9845 const char *comstr, int exact, afi_t afi,
9846 safi_t safi, bool use_json)
9847 {
9848 struct community *com;
9849 int ret = 0;
9850
9851 com = community_str2com(comstr);
9852 if (!com) {
9853 vty_out(vty, "%% Community malformed: %s\n", comstr);
9854 return CMD_WARNING;
9855 }
9856
9857 ret = bgp_show(vty, bgp, afi, safi,
9858 (exact ? bgp_show_type_community_exact
9859 : bgp_show_type_community),
9860 com, use_json);
9861 community_free(&com);
9862
9863 return ret;
9864 }
9865
9866 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
9867 const char *com, int exact, afi_t afi,
9868 safi_t safi)
9869 {
9870 struct community_list *list;
9871
9872 list = community_list_lookup(bgp_clist, com, 0, COMMUNITY_LIST_MASTER);
9873 if (list == NULL) {
9874 vty_out(vty, "%% %s is not a valid community-list name\n", com);
9875 return CMD_WARNING;
9876 }
9877
9878 return bgp_show(vty, bgp, afi, safi,
9879 (exact ? bgp_show_type_community_list_exact
9880 : bgp_show_type_community_list),
9881 list, 0);
9882 }
9883
9884 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
9885 const char *prefix, afi_t afi, safi_t safi,
9886 enum bgp_show_type type)
9887 {
9888 int ret;
9889 struct prefix *p;
9890
9891 p = prefix_new();
9892
9893 ret = str2prefix(prefix, p);
9894 if (!ret) {
9895 vty_out(vty, "%% Malformed Prefix\n");
9896 return CMD_WARNING;
9897 }
9898
9899 ret = bgp_show(vty, bgp, afi, safi, type, p, 0);
9900 prefix_free(p);
9901 return ret;
9902 }
9903
9904 static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
9905 const char *ip_str, bool use_json)
9906 {
9907 int ret;
9908 struct peer *peer;
9909 union sockunion su;
9910
9911 /* Get peer sockunion. */
9912 ret = str2sockunion(ip_str, &su);
9913 if (ret < 0) {
9914 peer = peer_lookup_by_conf_if(bgp, ip_str);
9915 if (!peer) {
9916 peer = peer_lookup_by_hostname(bgp, ip_str);
9917
9918 if (!peer) {
9919 if (use_json) {
9920 json_object *json_no = NULL;
9921 json_no = json_object_new_object();
9922 json_object_string_add(
9923 json_no,
9924 "malformedAddressOrName",
9925 ip_str);
9926 vty_out(vty, "%s\n",
9927 json_object_to_json_string_ext(
9928 json_no,
9929 JSON_C_TO_STRING_PRETTY));
9930 json_object_free(json_no);
9931 } else
9932 vty_out(vty,
9933 "%% Malformed address or name: %s\n",
9934 ip_str);
9935 return NULL;
9936 }
9937 }
9938 return peer;
9939 }
9940
9941 /* Peer structure lookup. */
9942 peer = peer_lookup(bgp, &su);
9943 if (!peer) {
9944 if (use_json) {
9945 json_object *json_no = NULL;
9946 json_no = json_object_new_object();
9947 json_object_string_add(json_no, "warning",
9948 "No such neighbor in this view/vrf");
9949 vty_out(vty, "%s\n",
9950 json_object_to_json_string_ext(
9951 json_no, JSON_C_TO_STRING_PRETTY));
9952 json_object_free(json_no);
9953 } else
9954 vty_out(vty, "No such neighbor in this view/vrf\n");
9955 return NULL;
9956 }
9957
9958 return peer;
9959 }
9960
9961 enum bgp_stats {
9962 BGP_STATS_MAXBITLEN = 0,
9963 BGP_STATS_RIB,
9964 BGP_STATS_PREFIXES,
9965 BGP_STATS_TOTPLEN,
9966 BGP_STATS_UNAGGREGATEABLE,
9967 BGP_STATS_MAX_AGGREGATEABLE,
9968 BGP_STATS_AGGREGATES,
9969 BGP_STATS_SPACE,
9970 BGP_STATS_ASPATH_COUNT,
9971 BGP_STATS_ASPATH_MAXHOPS,
9972 BGP_STATS_ASPATH_TOTHOPS,
9973 BGP_STATS_ASPATH_MAXSIZE,
9974 BGP_STATS_ASPATH_TOTSIZE,
9975 BGP_STATS_ASN_HIGHEST,
9976 BGP_STATS_MAX,
9977 };
9978
9979 static const char *table_stats_strs[] = {
9980 [BGP_STATS_PREFIXES] = "Total Prefixes",
9981 [BGP_STATS_TOTPLEN] = "Average prefix length",
9982 [BGP_STATS_RIB] = "Total Advertisements",
9983 [BGP_STATS_UNAGGREGATEABLE] = "Unaggregateable prefixes",
9984 [BGP_STATS_MAX_AGGREGATEABLE] =
9985 "Maximum aggregateable prefixes",
9986 [BGP_STATS_AGGREGATES] = "BGP Aggregate advertisements",
9987 [BGP_STATS_SPACE] = "Address space advertised",
9988 [BGP_STATS_ASPATH_COUNT] = "Advertisements with paths",
9989 [BGP_STATS_ASPATH_MAXHOPS] = "Longest AS-Path (hops)",
9990 [BGP_STATS_ASPATH_MAXSIZE] = "Largest AS-Path (bytes)",
9991 [BGP_STATS_ASPATH_TOTHOPS] = "Average AS-Path length (hops)",
9992 [BGP_STATS_ASPATH_TOTSIZE] = "Average AS-Path size (bytes)",
9993 [BGP_STATS_ASN_HIGHEST] = "Highest public ASN",
9994 [BGP_STATS_MAX] = NULL,
9995 };
9996
9997 struct bgp_table_stats {
9998 struct bgp_table *table;
9999 unsigned long long counts[BGP_STATS_MAX];
10000 double total_space;
10001 };
10002
10003 #if 0
10004 #define TALLY_SIGFIG 100000
10005 static unsigned long
10006 ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
10007 {
10008 unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
10009 unsigned long res = (newtot * TALLY_SIGFIG) / count;
10010 unsigned long ret = newtot / count;
10011
10012 if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
10013 return ret + 1;
10014 else
10015 return ret;
10016 }
10017 #endif
10018
10019 static int bgp_table_stats_walker(struct thread *t)
10020 {
10021 struct bgp_node *rn;
10022 struct bgp_node *top;
10023 struct bgp_table_stats *ts = THREAD_ARG(t);
10024 unsigned int space = 0;
10025
10026 if (!(top = bgp_table_top(ts->table)))
10027 return 0;
10028
10029 switch (top->p.family) {
10030 case AF_INET:
10031 space = IPV4_MAX_BITLEN;
10032 break;
10033 case AF_INET6:
10034 space = IPV6_MAX_BITLEN;
10035 break;
10036 }
10037
10038 ts->counts[BGP_STATS_MAXBITLEN] = space;
10039
10040 for (rn = top; rn; rn = bgp_route_next(rn)) {
10041 struct bgp_path_info *pi;
10042 struct bgp_node *prn = bgp_node_parent_nolock(rn);
10043 unsigned int pinum = 0;
10044
10045 if (rn == top)
10046 continue;
10047
10048 if (!bgp_node_has_bgp_path_info_data(rn))
10049 continue;
10050
10051 ts->counts[BGP_STATS_PREFIXES]++;
10052 ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
10053
10054 #if 0
10055 ts->counts[BGP_STATS_AVGPLEN]
10056 = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
10057 ts->counts[BGP_STATS_AVGPLEN],
10058 rn->p.prefixlen);
10059 #endif
10060
10061 /* check if the prefix is included by any other announcements */
10062 while (prn && !bgp_node_has_bgp_path_info_data(prn))
10063 prn = bgp_node_parent_nolock(prn);
10064
10065 if (prn == NULL || prn == top) {
10066 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
10067 /* announced address space */
10068 if (space)
10069 ts->total_space +=
10070 pow(2.0, space - rn->p.prefixlen);
10071 } else if (bgp_node_has_bgp_path_info_data(prn))
10072 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
10073
10074 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
10075 pinum++;
10076 ts->counts[BGP_STATS_RIB]++;
10077
10078 if (pi->attr
10079 && (CHECK_FLAG(pi->attr->flag,
10080 ATTR_FLAG_BIT(
10081 BGP_ATTR_ATOMIC_AGGREGATE))))
10082 ts->counts[BGP_STATS_AGGREGATES]++;
10083
10084 /* as-path stats */
10085 if (pi->attr && pi->attr->aspath) {
10086 unsigned int hops =
10087 aspath_count_hops(pi->attr->aspath);
10088 unsigned int size =
10089 aspath_size(pi->attr->aspath);
10090 as_t highest = aspath_highest(pi->attr->aspath);
10091
10092 ts->counts[BGP_STATS_ASPATH_COUNT]++;
10093
10094 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
10095 ts->counts[BGP_STATS_ASPATH_MAXHOPS] =
10096 hops;
10097
10098 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
10099 ts->counts[BGP_STATS_ASPATH_MAXSIZE] =
10100 size;
10101
10102 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
10103 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
10104 #if 0
10105 ts->counts[BGP_STATS_ASPATH_AVGHOPS]
10106 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
10107 ts->counts[BGP_STATS_ASPATH_AVGHOPS],
10108 hops);
10109 ts->counts[BGP_STATS_ASPATH_AVGSIZE]
10110 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
10111 ts->counts[BGP_STATS_ASPATH_AVGSIZE],
10112 size);
10113 #endif
10114 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
10115 ts->counts[BGP_STATS_ASN_HIGHEST] =
10116 highest;
10117 }
10118 }
10119 }
10120 return 0;
10121 }
10122
10123 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
10124 safi_t safi)
10125 {
10126 struct bgp_table_stats ts;
10127 unsigned int i;
10128
10129 if (!bgp->rib[afi][safi]) {
10130 vty_out(vty, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
10131 afi, safi);
10132 return CMD_WARNING;
10133 }
10134
10135 vty_out(vty, "BGP %s RIB statistics\n", afi_safi_print(afi, safi));
10136
10137 /* labeled-unicast routes live in the unicast table */
10138 if (safi == SAFI_LABELED_UNICAST)
10139 safi = SAFI_UNICAST;
10140
10141 memset(&ts, 0, sizeof(ts));
10142 ts.table = bgp->rib[afi][safi];
10143 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
10144
10145 for (i = 0; i < BGP_STATS_MAX; i++) {
10146 if (!table_stats_strs[i])
10147 continue;
10148
10149 switch (i) {
10150 #if 0
10151 case BGP_STATS_ASPATH_AVGHOPS:
10152 case BGP_STATS_ASPATH_AVGSIZE:
10153 case BGP_STATS_AVGPLEN:
10154 vty_out (vty, "%-30s: ", table_stats_strs[i]);
10155 vty_out (vty, "%12.2f",
10156 (float)ts.counts[i] / (float)TALLY_SIGFIG);
10157 break;
10158 #endif
10159 case BGP_STATS_ASPATH_TOTHOPS:
10160 case BGP_STATS_ASPATH_TOTSIZE:
10161 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10162 vty_out(vty, "%12.2f",
10163 ts.counts[i]
10164 ? (float)ts.counts[i]
10165 / (float)ts.counts
10166 [BGP_STATS_ASPATH_COUNT]
10167 : 0);
10168 break;
10169 case BGP_STATS_TOTPLEN:
10170 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10171 vty_out(vty, "%12.2f",
10172 ts.counts[i]
10173 ? (float)ts.counts[i]
10174 / (float)ts.counts
10175 [BGP_STATS_PREFIXES]
10176 : 0);
10177 break;
10178 case BGP_STATS_SPACE:
10179 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10180 vty_out(vty, "%12g\n", ts.total_space);
10181
10182 if (afi == AFI_IP6) {
10183 vty_out(vty, "%30s: ", "/32 equivalent ");
10184 vty_out(vty, "%12g\n",
10185 ts.total_space * pow(2.0, -128 + 32));
10186 vty_out(vty, "%30s: ", "/48 equivalent ");
10187 vty_out(vty, "%12g\n",
10188 ts.total_space * pow(2.0, -128 + 48));
10189 } else {
10190 vty_out(vty, "%30s: ", "% announced ");
10191 vty_out(vty, "%12.2f\n",
10192 ts.total_space * 100. * pow(2.0, -32));
10193 vty_out(vty, "%30s: ", "/8 equivalent ");
10194 vty_out(vty, "%12.2f\n",
10195 ts.total_space * pow(2.0, -32 + 8));
10196 vty_out(vty, "%30s: ", "/24 equivalent ");
10197 vty_out(vty, "%12.2f\n",
10198 ts.total_space * pow(2.0, -32 + 24));
10199 }
10200 break;
10201 default:
10202 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10203 vty_out(vty, "%12llu", ts.counts[i]);
10204 }
10205
10206 vty_out(vty, "\n");
10207 }
10208 return CMD_SUCCESS;
10209 }
10210
10211 enum bgp_pcounts {
10212 PCOUNT_ADJ_IN = 0,
10213 PCOUNT_DAMPED,
10214 PCOUNT_REMOVED,
10215 PCOUNT_HISTORY,
10216 PCOUNT_STALE,
10217 PCOUNT_VALID,
10218 PCOUNT_ALL,
10219 PCOUNT_COUNTED,
10220 PCOUNT_PFCNT, /* the figure we display to users */
10221 PCOUNT_MAX,
10222 };
10223
10224 static const char *pcount_strs[] = {
10225 [PCOUNT_ADJ_IN] = "Adj-in",
10226 [PCOUNT_DAMPED] = "Damped",
10227 [PCOUNT_REMOVED] = "Removed",
10228 [PCOUNT_HISTORY] = "History",
10229 [PCOUNT_STALE] = "Stale",
10230 [PCOUNT_VALID] = "Valid",
10231 [PCOUNT_ALL] = "All RIB",
10232 [PCOUNT_COUNTED] = "PfxCt counted",
10233 [PCOUNT_PFCNT] = "Useable",
10234 [PCOUNT_MAX] = NULL,
10235 };
10236
10237 struct peer_pcounts {
10238 unsigned int count[PCOUNT_MAX];
10239 const struct peer *peer;
10240 const struct bgp_table *table;
10241 };
10242
10243 static int bgp_peer_count_walker(struct thread *t)
10244 {
10245 struct bgp_node *rn;
10246 struct peer_pcounts *pc = THREAD_ARG(t);
10247 const struct peer *peer = pc->peer;
10248
10249 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn)) {
10250 struct bgp_adj_in *ain;
10251 struct bgp_path_info *pi;
10252
10253 for (ain = rn->adj_in; ain; ain = ain->next)
10254 if (ain->peer == peer)
10255 pc->count[PCOUNT_ADJ_IN]++;
10256
10257 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
10258
10259 if (pi->peer != peer)
10260 continue;
10261
10262 pc->count[PCOUNT_ALL]++;
10263
10264 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
10265 pc->count[PCOUNT_DAMPED]++;
10266 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
10267 pc->count[PCOUNT_HISTORY]++;
10268 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
10269 pc->count[PCOUNT_REMOVED]++;
10270 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
10271 pc->count[PCOUNT_STALE]++;
10272 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
10273 pc->count[PCOUNT_VALID]++;
10274 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
10275 pc->count[PCOUNT_PFCNT]++;
10276
10277 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
10278 pc->count[PCOUNT_COUNTED]++;
10279 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
10280 flog_err(
10281 EC_LIB_DEVELOPMENT,
10282 "Attempting to count but flags say it is unusable");
10283 } else {
10284 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
10285 flog_err(
10286 EC_LIB_DEVELOPMENT,
10287 "Not counted but flags say we should");
10288 }
10289 }
10290 }
10291 return 0;
10292 }
10293
10294 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
10295 safi_t safi, bool use_json)
10296 {
10297 struct peer_pcounts pcounts = {.peer = peer};
10298 unsigned int i;
10299 json_object *json = NULL;
10300 json_object *json_loop = NULL;
10301
10302 if (use_json) {
10303 json = json_object_new_object();
10304 json_loop = json_object_new_object();
10305 }
10306
10307 if (!peer || !peer->bgp || !peer->afc[afi][safi]
10308 || !peer->bgp->rib[afi][safi]) {
10309 if (use_json) {
10310 json_object_string_add(
10311 json, "warning",
10312 "No such neighbor or address family");
10313 vty_out(vty, "%s\n", json_object_to_json_string(json));
10314 json_object_free(json);
10315 } else
10316 vty_out(vty, "%% No such neighbor or address family\n");
10317
10318 return CMD_WARNING;
10319 }
10320
10321 memset(&pcounts, 0, sizeof(pcounts));
10322 pcounts.peer = peer;
10323 pcounts.table = peer->bgp->rib[afi][safi];
10324
10325 /* in-place call via thread subsystem so as to record execution time
10326 * stats for the thread-walk (i.e. ensure this can't be blamed on
10327 * on just vty_read()).
10328 */
10329 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
10330
10331 if (use_json) {
10332 json_object_string_add(json, "prefixCountsFor", peer->host);
10333 json_object_string_add(json, "multiProtocol",
10334 afi_safi_print(afi, safi));
10335 json_object_int_add(json, "pfxCounter",
10336 peer->pcount[afi][safi]);
10337
10338 for (i = 0; i < PCOUNT_MAX; i++)
10339 json_object_int_add(json_loop, pcount_strs[i],
10340 pcounts.count[i]);
10341
10342 json_object_object_add(json, "ribTableWalkCounters", json_loop);
10343
10344 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
10345 json_object_string_add(json, "pfxctDriftFor",
10346 peer->host);
10347 json_object_string_add(
10348 json, "recommended",
10349 "Please report this bug, with the above command output");
10350 }
10351 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10352 json, JSON_C_TO_STRING_PRETTY));
10353 json_object_free(json);
10354 } else {
10355
10356 if (peer->hostname
10357 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
10358 vty_out(vty, "Prefix counts for %s/%s, %s\n",
10359 peer->hostname, peer->host,
10360 afi_safi_print(afi, safi));
10361 } else {
10362 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
10363 afi_safi_print(afi, safi));
10364 }
10365
10366 vty_out(vty, "PfxCt: %ld\n", peer->pcount[afi][safi]);
10367 vty_out(vty, "\nCounts from RIB table walk:\n\n");
10368
10369 for (i = 0; i < PCOUNT_MAX; i++)
10370 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
10371 pcounts.count[i]);
10372
10373 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
10374 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
10375 vty_out(vty,
10376 "Please report this bug, with the above command output\n");
10377 }
10378 }
10379
10380 return CMD_SUCCESS;
10381 }
10382
10383 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
10384 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
10385 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] "
10386 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
10387 SHOW_STR
10388 IP_STR
10389 BGP_STR
10390 BGP_INSTANCE_HELP_STR
10391 BGP_AFI_HELP_STR
10392 BGP_SAFI_HELP_STR
10393 "Detailed information on TCP and BGP neighbor connections\n"
10394 "Neighbor to display information about\n"
10395 "Neighbor to display information about\n"
10396 "Neighbor on BGP configured interface\n"
10397 "Display detailed prefix count information\n"
10398 JSON_STR)
10399 {
10400 afi_t afi = AFI_IP6;
10401 safi_t safi = SAFI_UNICAST;
10402 struct peer *peer;
10403 int idx = 0;
10404 struct bgp *bgp = NULL;
10405 bool uj = use_json(argc, argv);
10406
10407 if (uj)
10408 argc--;
10409
10410 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10411 &bgp, uj);
10412 if (!idx)
10413 return CMD_WARNING;
10414
10415 argv_find(argv, argc, "neighbors", &idx);
10416 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
10417 if (!peer)
10418 return CMD_WARNING;
10419
10420 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_UNICAST, uj);
10421 }
10422
10423 #ifdef KEEP_OLD_VPN_COMMANDS
10424 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
10425 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
10426 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
10427 SHOW_STR
10428 IP_STR
10429 BGP_STR
10430 BGP_VPNVX_HELP_STR
10431 "Display information about all VPNv4 NLRIs\n"
10432 "Detailed information on TCP and BGP neighbor connections\n"
10433 "Neighbor to display information about\n"
10434 "Neighbor to display information about\n"
10435 "Neighbor on BGP configured interface\n"
10436 "Display detailed prefix count information\n"
10437 JSON_STR)
10438 {
10439 int idx_peer = 6;
10440 struct peer *peer;
10441 bool uj = use_json(argc, argv);
10442
10443 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
10444 if (!peer)
10445 return CMD_WARNING;
10446
10447 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
10448 }
10449
10450 DEFUN (show_ip_bgp_vpn_all_route_prefix,
10451 show_ip_bgp_vpn_all_route_prefix_cmd,
10452 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
10453 SHOW_STR
10454 IP_STR
10455 BGP_STR
10456 BGP_VPNVX_HELP_STR
10457 "Display information about all VPNv4 NLRIs\n"
10458 "Network in the BGP routing table to display\n"
10459 "Network in the BGP routing table to display\n"
10460 JSON_STR)
10461 {
10462 int idx = 0;
10463 char *network = NULL;
10464 struct bgp *bgp = bgp_get_default();
10465 if (!bgp) {
10466 vty_out(vty, "Can't find default instance\n");
10467 return CMD_WARNING;
10468 }
10469
10470 if (argv_find(argv, argc, "A.B.C.D", &idx))
10471 network = argv[idx]->arg;
10472 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
10473 network = argv[idx]->arg;
10474 else {
10475 vty_out(vty, "Unable to figure out Network\n");
10476 return CMD_WARNING;
10477 }
10478
10479 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
10480 BGP_PATH_SHOW_ALL, use_json(argc, argv));
10481 }
10482 #endif /* KEEP_OLD_VPN_COMMANDS */
10483
10484 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix,
10485 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd,
10486 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
10487 SHOW_STR
10488 IP_STR
10489 BGP_STR
10490 L2VPN_HELP_STR
10491 EVPN_HELP_STR
10492 "Display information about all EVPN NLRIs\n"
10493 "Network in the BGP routing table to display\n"
10494 "Network in the BGP routing table to display\n"
10495 JSON_STR)
10496 {
10497 int idx = 0;
10498 char *network = NULL;
10499
10500 if (argv_find(argv, argc, "A.B.C.D", &idx))
10501 network = argv[idx]->arg;
10502 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
10503 network = argv[idx]->arg;
10504 else {
10505 vty_out(vty, "Unable to figure out Network\n");
10506 return CMD_WARNING;
10507 }
10508 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL, 0,
10509 BGP_PATH_SHOW_ALL, use_json(argc, argv));
10510 }
10511
10512 static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
10513 safi_t safi, enum bgp_show_adj_route_type type,
10514 const char *rmap_name, bool use_json,
10515 json_object *json)
10516 {
10517 struct bgp_table *table;
10518 struct bgp_adj_in *ain;
10519 struct bgp_adj_out *adj;
10520 unsigned long output_count;
10521 unsigned long filtered_count;
10522 struct bgp_node *rn;
10523 int header1 = 1;
10524 struct bgp *bgp;
10525 int header2 = 1;
10526 struct attr attr;
10527 int ret;
10528 struct update_subgroup *subgrp;
10529 json_object *json_scode = NULL;
10530 json_object *json_ocode = NULL;
10531 json_object *json_ar = NULL;
10532 struct peer_af *paf;
10533 bool route_filtered;
10534
10535 if (use_json) {
10536 json_scode = json_object_new_object();
10537 json_ocode = json_object_new_object();
10538 json_ar = json_object_new_object();
10539
10540 json_object_string_add(json_scode, "suppressed", "s");
10541 json_object_string_add(json_scode, "damped", "d");
10542 json_object_string_add(json_scode, "history", "h");
10543 json_object_string_add(json_scode, "valid", "*");
10544 json_object_string_add(json_scode, "best", ">");
10545 json_object_string_add(json_scode, "multipath", "=");
10546 json_object_string_add(json_scode, "internal", "i");
10547 json_object_string_add(json_scode, "ribFailure", "r");
10548 json_object_string_add(json_scode, "stale", "S");
10549 json_object_string_add(json_scode, "removed", "R");
10550
10551 json_object_string_add(json_ocode, "igp", "i");
10552 json_object_string_add(json_ocode, "egp", "e");
10553 json_object_string_add(json_ocode, "incomplete", "?");
10554 }
10555
10556 bgp = peer->bgp;
10557
10558 if (!bgp) {
10559 if (use_json) {
10560 json_object_string_add(json, "alert", "no BGP");
10561 vty_out(vty, "%s\n", json_object_to_json_string(json));
10562 json_object_free(json);
10563 } else
10564 vty_out(vty, "%% No bgp\n");
10565 return;
10566 }
10567
10568 table = bgp->rib[afi][safi];
10569
10570 output_count = filtered_count = 0;
10571 subgrp = peer_subgroup(peer, afi, safi);
10572
10573 if (type == bgp_show_adj_route_advertised && subgrp
10574 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
10575 if (use_json) {
10576 json_object_int_add(json, "bgpTableVersion",
10577 table->version);
10578 json_object_string_add(json, "bgpLocalRouterId",
10579 inet_ntoa(bgp->router_id));
10580 json_object_int_add(json, "defaultLocPrf",
10581 bgp->default_local_pref);
10582 json_object_int_add(json, "localAS", bgp->as);
10583 json_object_object_add(json, "bgpStatusCodes",
10584 json_scode);
10585 json_object_object_add(json, "bgpOriginCodes",
10586 json_ocode);
10587 json_object_string_add(
10588 json, "bgpOriginatingDefaultNetwork",
10589 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
10590 } else {
10591 vty_out(vty, "BGP table version is %" PRIu64
10592 ", local router ID is %s, vrf id ",
10593 table->version, inet_ntoa(bgp->router_id));
10594 if (bgp->vrf_id == VRF_UNKNOWN)
10595 vty_out(vty, "%s", VRFID_NONE_STR);
10596 else
10597 vty_out(vty, "%u", bgp->vrf_id);
10598 vty_out(vty, "\n");
10599 vty_out(vty, "Default local pref %u, ",
10600 bgp->default_local_pref);
10601 vty_out(vty, "local AS %u\n", bgp->as);
10602 vty_out(vty, BGP_SHOW_SCODE_HEADER);
10603 vty_out(vty, BGP_SHOW_NCODE_HEADER);
10604 vty_out(vty, BGP_SHOW_OCODE_HEADER);
10605
10606 vty_out(vty, "Originating default network %s\n\n",
10607 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
10608 }
10609 header1 = 0;
10610 }
10611
10612 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
10613 if (type == bgp_show_adj_route_received
10614 || type == bgp_show_adj_route_filtered) {
10615 for (ain = rn->adj_in; ain; ain = ain->next) {
10616 if (ain->peer != peer || !ain->attr)
10617 continue;
10618
10619 if (header1) {
10620 if (use_json) {
10621 json_object_int_add(
10622 json, "bgpTableVersion",
10623 0);
10624 json_object_string_add(
10625 json,
10626 "bgpLocalRouterId",
10627 inet_ntoa(
10628 bgp->router_id));
10629 json_object_int_add(json,
10630 "defaultLocPrf",
10631 bgp->default_local_pref);
10632 json_object_int_add(json,
10633 "localAS", bgp->as);
10634 json_object_object_add(
10635 json, "bgpStatusCodes",
10636 json_scode);
10637 json_object_object_add(
10638 json, "bgpOriginCodes",
10639 json_ocode);
10640 } else {
10641 vty_out(vty,
10642 "BGP table version is 0, local router ID is %s, vrf id ",
10643 inet_ntoa(
10644 bgp->router_id));
10645 if (bgp->vrf_id == VRF_UNKNOWN)
10646 vty_out(vty, "%s",
10647 VRFID_NONE_STR);
10648 else
10649 vty_out(vty, "%u",
10650 bgp->vrf_id);
10651 vty_out(vty, "\n");
10652 vty_out(vty,
10653 "Default local pref %u, ",
10654 bgp->default_local_pref);
10655 vty_out(vty, "local AS %u\n",
10656 bgp->as);
10657 vty_out(vty,
10658 BGP_SHOW_SCODE_HEADER);
10659 vty_out(vty,
10660 BGP_SHOW_NCODE_HEADER);
10661 vty_out(vty,
10662 BGP_SHOW_OCODE_HEADER);
10663 }
10664 header1 = 0;
10665 }
10666 if (header2) {
10667 if (!use_json)
10668 vty_out(vty, BGP_SHOW_HEADER);
10669 header2 = 0;
10670 }
10671
10672 bgp_attr_dup(&attr, ain->attr);
10673 route_filtered = false;
10674
10675 /* Filter prefix using distribute list,
10676 * filter list or prefix list
10677 */
10678 if ((bgp_input_filter(peer, &rn->p, &attr, afi,
10679 safi)) == FILTER_DENY)
10680 route_filtered = true;
10681
10682 /* Filter prefix using route-map */
10683 ret = bgp_input_modifier(peer, &rn->p, &attr,
10684 afi, safi, rmap_name);
10685
10686 if (type == bgp_show_adj_route_filtered &&
10687 !route_filtered && ret != RMAP_DENY) {
10688 bgp_attr_undup(&attr, ain->attr);
10689 continue;
10690 }
10691
10692 if (type == bgp_show_adj_route_received &&
10693 (route_filtered || ret == RMAP_DENY))
10694 filtered_count++;
10695
10696 route_vty_out_tmp(vty, &rn->p, &attr, safi,
10697 use_json, json_ar);
10698 bgp_attr_undup(&attr, ain->attr);
10699 output_count++;
10700 }
10701 } else if (type == bgp_show_adj_route_advertised) {
10702 RB_FOREACH (adj, bgp_adj_out_rb, &rn->adj_out)
10703 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
10704 if (paf->peer != peer || !adj->attr)
10705 continue;
10706
10707 if (header1) {
10708 if (use_json) {
10709 json_object_int_add(
10710 json,
10711 "bgpTableVersion",
10712 table->version);
10713 json_object_string_add(
10714 json,
10715 "bgpLocalRouterId",
10716 inet_ntoa(
10717 bgp->router_id));
10718 json_object_int_add(
10719 json, "defaultLocPrf",
10720 bgp->default_local_pref
10721 );
10722 json_object_int_add(
10723 json, "localAS",
10724 bgp->as);
10725 json_object_object_add(
10726 json,
10727 "bgpStatusCodes",
10728 json_scode);
10729 json_object_object_add(
10730 json,
10731 "bgpOriginCodes",
10732 json_ocode);
10733 } else {
10734 vty_out(vty,
10735 "BGP table version is %" PRIu64
10736 ", local router ID is %s, vrf id ",
10737 table->version,
10738 inet_ntoa(
10739 bgp->router_id));
10740 if (bgp->vrf_id ==
10741 VRF_UNKNOWN)
10742 vty_out(vty,
10743 "%s",
10744 VRFID_NONE_STR);
10745 else
10746 vty_out(vty,
10747 "%u",
10748 bgp->vrf_id);
10749 vty_out(vty, "\n");
10750 vty_out(vty,
10751 "Default local pref %u, ",
10752 bgp->default_local_pref
10753 );
10754 vty_out(vty,
10755 "local AS %u\n",
10756 bgp->as);
10757 vty_out(vty,
10758 BGP_SHOW_SCODE_HEADER);
10759 vty_out(vty,
10760 BGP_SHOW_NCODE_HEADER);
10761 vty_out(vty,
10762 BGP_SHOW_OCODE_HEADER);
10763 }
10764 header1 = 0;
10765 }
10766 if (header2) {
10767 if (!use_json)
10768 vty_out(vty,
10769 BGP_SHOW_HEADER);
10770 header2 = 0;
10771 }
10772
10773 bgp_attr_dup(&attr, adj->attr);
10774 ret = bgp_output_modifier(
10775 peer, &rn->p, &attr, afi, safi,
10776 rmap_name);
10777
10778 if (ret != RMAP_DENY) {
10779 route_vty_out_tmp(vty, &rn->p,
10780 &attr, safi,
10781 use_json,
10782 json_ar);
10783 output_count++;
10784 } else {
10785 filtered_count++;
10786 }
10787
10788 bgp_attr_undup(&attr, adj->attr);
10789 }
10790 }
10791 }
10792
10793 if (use_json) {
10794 json_object_object_add(json, "advertisedRoutes", json_ar);
10795 json_object_int_add(json, "totalPrefixCounter", output_count);
10796 json_object_int_add(json, "filteredPrefixCounter",
10797 filtered_count);
10798
10799 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10800 json, JSON_C_TO_STRING_PRETTY));
10801 json_object_free(json);
10802 } else if (output_count > 0) {
10803 if (filtered_count > 0)
10804 vty_out(vty,
10805 "\nTotal number of prefixes %ld (%ld filtered)\n",
10806 output_count, filtered_count);
10807 else
10808 vty_out(vty, "\nTotal number of prefixes %ld\n",
10809 output_count);
10810 }
10811 }
10812
10813 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
10814 safi_t safi, enum bgp_show_adj_route_type type,
10815 const char *rmap_name, bool use_json)
10816 {
10817 json_object *json = NULL;
10818
10819 if (use_json)
10820 json = json_object_new_object();
10821
10822 /* labeled-unicast routes live in the unicast table */
10823 if (safi == SAFI_LABELED_UNICAST)
10824 safi = SAFI_UNICAST;
10825
10826 if (!peer || !peer->afc[afi][safi]) {
10827 if (use_json) {
10828 json_object_string_add(
10829 json, "warning",
10830 "No such neighbor or address family");
10831 vty_out(vty, "%s\n", json_object_to_json_string(json));
10832 json_object_free(json);
10833 } else
10834 vty_out(vty, "%% No such neighbor or address family\n");
10835
10836 return CMD_WARNING;
10837 }
10838
10839 if ((type == bgp_show_adj_route_received
10840 || type == bgp_show_adj_route_filtered)
10841 && !CHECK_FLAG(peer->af_flags[afi][safi],
10842 PEER_FLAG_SOFT_RECONFIG)) {
10843 if (use_json) {
10844 json_object_string_add(
10845 json, "warning",
10846 "Inbound soft reconfiguration not enabled");
10847 vty_out(vty, "%s\n", json_object_to_json_string(json));
10848 json_object_free(json);
10849 } else
10850 vty_out(vty,
10851 "%% Inbound soft reconfiguration not enabled\n");
10852
10853 return CMD_WARNING;
10854 }
10855
10856 show_adj_route(vty, peer, afi, safi, type, rmap_name, use_json, json);
10857
10858 return CMD_SUCCESS;
10859 }
10860
10861 DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
10862 show_ip_bgp_instance_neighbor_advertised_route_cmd,
10863 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
10864 "neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map WORD] [json]",
10865 SHOW_STR
10866 IP_STR
10867 BGP_STR
10868 BGP_INSTANCE_HELP_STR
10869 BGP_AFI_HELP_STR
10870 BGP_SAFI_WITH_LABEL_HELP_STR
10871 "Detailed information on TCP and BGP neighbor connections\n"
10872 "Neighbor to display information about\n"
10873 "Neighbor to display information about\n"
10874 "Neighbor on BGP configured interface\n"
10875 "Display the routes advertised to a BGP neighbor\n"
10876 "Display the received routes from neighbor\n"
10877 "Display the filtered routes received from neighbor\n"
10878 "Route-map to modify the attributes\n"
10879 "Name of the route map\n"
10880 JSON_STR)
10881 {
10882 afi_t afi = AFI_IP6;
10883 safi_t safi = SAFI_UNICAST;
10884 char *rmap_name = NULL;
10885 char *peerstr = NULL;
10886 struct bgp *bgp = NULL;
10887 struct peer *peer;
10888 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
10889 int idx = 0;
10890 bool uj = use_json(argc, argv);
10891
10892 if (uj)
10893 argc--;
10894
10895 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10896 &bgp, uj);
10897 if (!idx)
10898 return CMD_WARNING;
10899
10900 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10901 argv_find(argv, argc, "neighbors", &idx);
10902 peerstr = argv[++idx]->arg;
10903
10904 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
10905 if (!peer)
10906 return CMD_WARNING;
10907
10908 if (argv_find(argv, argc, "advertised-routes", &idx))
10909 type = bgp_show_adj_route_advertised;
10910 else if (argv_find(argv, argc, "received-routes", &idx))
10911 type = bgp_show_adj_route_received;
10912 else if (argv_find(argv, argc, "filtered-routes", &idx))
10913 type = bgp_show_adj_route_filtered;
10914
10915 if (argv_find(argv, argc, "route-map", &idx))
10916 rmap_name = argv[++idx]->arg;
10917
10918 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, uj);
10919 }
10920
10921 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
10922 show_ip_bgp_neighbor_received_prefix_filter_cmd,
10923 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
10924 SHOW_STR
10925 IP_STR
10926 BGP_STR
10927 "Address Family\n"
10928 "Address Family\n"
10929 "Address Family modifier\n"
10930 "Detailed information on TCP and BGP neighbor connections\n"
10931 "Neighbor to display information about\n"
10932 "Neighbor to display information about\n"
10933 "Neighbor on BGP configured interface\n"
10934 "Display information received from a BGP neighbor\n"
10935 "Display the prefixlist filter\n"
10936 JSON_STR)
10937 {
10938 afi_t afi = AFI_IP6;
10939 safi_t safi = SAFI_UNICAST;
10940 char *peerstr = NULL;
10941
10942 char name[BUFSIZ];
10943 union sockunion su;
10944 struct peer *peer;
10945 int count, ret;
10946
10947 int idx = 0;
10948
10949 /* show [ip] bgp */
10950 if (argv_find(argv, argc, "ip", &idx))
10951 afi = AFI_IP;
10952 /* [<ipv4|ipv6> [unicast]] */
10953 if (argv_find(argv, argc, "ipv4", &idx))
10954 afi = AFI_IP;
10955 if (argv_find(argv, argc, "ipv6", &idx))
10956 afi = AFI_IP6;
10957 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10958 argv_find(argv, argc, "neighbors", &idx);
10959 peerstr = argv[++idx]->arg;
10960
10961 bool uj = use_json(argc, argv);
10962
10963 ret = str2sockunion(peerstr, &su);
10964 if (ret < 0) {
10965 peer = peer_lookup_by_conf_if(NULL, peerstr);
10966 if (!peer) {
10967 if (uj)
10968 vty_out(vty, "{}\n");
10969 else
10970 vty_out(vty,
10971 "%% Malformed address or name: %s\n",
10972 peerstr);
10973 return CMD_WARNING;
10974 }
10975 } else {
10976 peer = peer_lookup(NULL, &su);
10977 if (!peer) {
10978 if (uj)
10979 vty_out(vty, "{}\n");
10980 else
10981 vty_out(vty, "No peer\n");
10982 return CMD_WARNING;
10983 }
10984 }
10985
10986 sprintf(name, "%s.%d.%d", peer->host, afi, safi);
10987 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
10988 if (count) {
10989 if (!uj)
10990 vty_out(vty, "Address Family: %s\n",
10991 afi_safi_print(afi, safi));
10992 prefix_bgp_show_prefix_list(vty, afi, name, uj);
10993 } else {
10994 if (uj)
10995 vty_out(vty, "{}\n");
10996 else
10997 vty_out(vty, "No functional output\n");
10998 }
10999
11000 return CMD_SUCCESS;
11001 }
11002
11003 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
11004 afi_t afi, safi_t safi,
11005 enum bgp_show_type type, bool use_json)
11006 {
11007 /* labeled-unicast routes live in the unicast table */
11008 if (safi == SAFI_LABELED_UNICAST)
11009 safi = SAFI_UNICAST;
11010
11011 if (!peer || !peer->afc[afi][safi]) {
11012 if (use_json) {
11013 json_object *json_no = NULL;
11014 json_no = json_object_new_object();
11015 json_object_string_add(
11016 json_no, "warning",
11017 "No such neighbor or address family");
11018 vty_out(vty, "%s\n",
11019 json_object_to_json_string(json_no));
11020 json_object_free(json_no);
11021 } else
11022 vty_out(vty, "%% No such neighbor or address family\n");
11023 return CMD_WARNING;
11024 }
11025
11026 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, use_json);
11027 }
11028
11029 DEFUN (show_ip_bgp_flowspec_routes_detailed,
11030 show_ip_bgp_flowspec_routes_detailed_cmd,
11031 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
11032 SHOW_STR
11033 IP_STR
11034 BGP_STR
11035 BGP_INSTANCE_HELP_STR
11036 BGP_AFI_HELP_STR
11037 "SAFI Flowspec\n"
11038 "Detailed information on flowspec entries\n"
11039 JSON_STR)
11040 {
11041 afi_t afi = AFI_IP;
11042 safi_t safi = SAFI_UNICAST;
11043 struct bgp *bgp = NULL;
11044 int idx = 0;
11045 bool uj = use_json(argc, argv);
11046
11047 if (uj)
11048 argc--;
11049
11050 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11051 &bgp, uj);
11052 if (!idx)
11053 return CMD_WARNING;
11054
11055 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL, uj);
11056 }
11057
11058 DEFUN (show_ip_bgp_neighbor_routes,
11059 show_ip_bgp_neighbor_routes_cmd,
11060 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
11061 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
11062 SHOW_STR
11063 IP_STR
11064 BGP_STR
11065 BGP_INSTANCE_HELP_STR
11066 BGP_AFI_HELP_STR
11067 BGP_SAFI_WITH_LABEL_HELP_STR
11068 "Detailed information on TCP and BGP neighbor connections\n"
11069 "Neighbor to display information about\n"
11070 "Neighbor to display information about\n"
11071 "Neighbor on BGP configured interface\n"
11072 "Display flap statistics of the routes learned from neighbor\n"
11073 "Display the dampened routes received from neighbor\n"
11074 "Display routes learned from neighbor\n"
11075 JSON_STR)
11076 {
11077 char *peerstr = NULL;
11078 struct bgp *bgp = NULL;
11079 afi_t afi = AFI_IP6;
11080 safi_t safi = SAFI_UNICAST;
11081 struct peer *peer;
11082 enum bgp_show_type sh_type = bgp_show_type_neighbor;
11083 int idx = 0;
11084 bool uj = use_json(argc, argv);
11085
11086 if (uj)
11087 argc--;
11088
11089 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11090 &bgp, uj);
11091 if (!idx)
11092 return CMD_WARNING;
11093
11094 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11095 argv_find(argv, argc, "neighbors", &idx);
11096 peerstr = argv[++idx]->arg;
11097
11098 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
11099 if (!peer)
11100 return CMD_WARNING;
11101
11102 if (argv_find(argv, argc, "flap-statistics", &idx))
11103 sh_type = bgp_show_type_flap_neighbor;
11104 else if (argv_find(argv, argc, "dampened-routes", &idx))
11105 sh_type = bgp_show_type_damp_neighbor;
11106 else if (argv_find(argv, argc, "routes", &idx))
11107 sh_type = bgp_show_type_neighbor;
11108
11109 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
11110 }
11111
11112 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
11113
11114 struct bgp_distance {
11115 /* Distance value for the IP source prefix. */
11116 uint8_t distance;
11117
11118 /* Name of the access-list to be matched. */
11119 char *access_list;
11120 };
11121
11122 DEFUN (show_bgp_afi_vpn_rd_route,
11123 show_bgp_afi_vpn_rd_route_cmd,
11124 "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]",
11125 SHOW_STR
11126 BGP_STR
11127 BGP_AFI_HELP_STR
11128 "Address Family modifier\n"
11129 "Display information for a route distinguisher\n"
11130 "Route Distinguisher\n"
11131 "Network in the BGP routing table to display\n"
11132 "Network in the BGP routing table to display\n"
11133 JSON_STR)
11134 {
11135 int ret;
11136 struct prefix_rd prd;
11137 afi_t afi = AFI_MAX;
11138 int idx = 0;
11139
11140 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
11141 vty_out(vty, "%% Malformed Address Family\n");
11142 return CMD_WARNING;
11143 }
11144
11145 ret = str2prefix_rd(argv[5]->arg, &prd);
11146 if (!ret) {
11147 vty_out(vty, "%% Malformed Route Distinguisher\n");
11148 return CMD_WARNING;
11149 }
11150
11151 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
11152 0, BGP_PATH_SHOW_ALL, use_json(argc, argv));
11153 }
11154
11155 static struct bgp_distance *bgp_distance_new(void)
11156 {
11157 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
11158 }
11159
11160 static void bgp_distance_free(struct bgp_distance *bdistance)
11161 {
11162 XFREE(MTYPE_BGP_DISTANCE, bdistance);
11163 }
11164
11165 static int bgp_distance_set(struct vty *vty, const char *distance_str,
11166 const char *ip_str, const char *access_list_str)
11167 {
11168 int ret;
11169 afi_t afi;
11170 safi_t safi;
11171 struct prefix p;
11172 uint8_t distance;
11173 struct bgp_node *rn;
11174 struct bgp_distance *bdistance;
11175
11176 afi = bgp_node_afi(vty);
11177 safi = bgp_node_safi(vty);
11178
11179 ret = str2prefix(ip_str, &p);
11180 if (ret == 0) {
11181 vty_out(vty, "Malformed prefix\n");
11182 return CMD_WARNING_CONFIG_FAILED;
11183 }
11184
11185 distance = atoi(distance_str);
11186
11187 /* Get BGP distance node. */
11188 rn = bgp_node_get(bgp_distance_table[afi][safi], (struct prefix *)&p);
11189 bdistance = bgp_node_get_bgp_distance_info(rn);
11190 if (bdistance)
11191 bgp_unlock_node(rn);
11192 else {
11193 bdistance = bgp_distance_new();
11194 bgp_node_set_bgp_distance_info(rn, bdistance);
11195 }
11196
11197 /* Set distance value. */
11198 bdistance->distance = distance;
11199
11200 /* Reset access-list configuration. */
11201 if (bdistance->access_list) {
11202 XFREE(MTYPE_AS_LIST, bdistance->access_list);
11203 bdistance->access_list = NULL;
11204 }
11205 if (access_list_str)
11206 bdistance->access_list =
11207 XSTRDUP(MTYPE_AS_LIST, access_list_str);
11208
11209 return CMD_SUCCESS;
11210 }
11211
11212 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
11213 const char *ip_str, const char *access_list_str)
11214 {
11215 int ret;
11216 afi_t afi;
11217 safi_t safi;
11218 struct prefix p;
11219 int distance;
11220 struct bgp_node *rn;
11221 struct bgp_distance *bdistance;
11222
11223 afi = bgp_node_afi(vty);
11224 safi = bgp_node_safi(vty);
11225
11226 ret = str2prefix(ip_str, &p);
11227 if (ret == 0) {
11228 vty_out(vty, "Malformed prefix\n");
11229 return CMD_WARNING_CONFIG_FAILED;
11230 }
11231
11232 rn = bgp_node_lookup(bgp_distance_table[afi][safi],
11233 (struct prefix *)&p);
11234 if (!rn) {
11235 vty_out(vty, "Can't find specified prefix\n");
11236 return CMD_WARNING_CONFIG_FAILED;
11237 }
11238
11239 bdistance = bgp_node_get_bgp_distance_info(rn);
11240 distance = atoi(distance_str);
11241
11242 if (bdistance->distance != distance) {
11243 vty_out(vty, "Distance does not match configured\n");
11244 return CMD_WARNING_CONFIG_FAILED;
11245 }
11246
11247 XFREE(MTYPE_AS_LIST, bdistance->access_list);
11248 bgp_distance_free(bdistance);
11249
11250 bgp_node_set_bgp_path_info(rn, NULL);
11251 bgp_unlock_node(rn);
11252 bgp_unlock_node(rn);
11253
11254 return CMD_SUCCESS;
11255 }
11256
11257 /* Apply BGP information to distance method. */
11258 uint8_t bgp_distance_apply(struct prefix *p, struct bgp_path_info *pinfo,
11259 afi_t afi, safi_t safi, struct bgp *bgp)
11260 {
11261 struct bgp_node *rn;
11262 struct prefix q;
11263 struct peer *peer;
11264 struct bgp_distance *bdistance;
11265 struct access_list *alist;
11266 struct bgp_static *bgp_static;
11267
11268 if (!bgp)
11269 return 0;
11270
11271 peer = pinfo->peer;
11272
11273 /* Check source address. */
11274 sockunion2hostprefix(&peer->su, &q);
11275 rn = bgp_node_match(bgp_distance_table[afi][safi], &q);
11276 if (rn) {
11277 bdistance = bgp_node_get_bgp_distance_info(rn);
11278 bgp_unlock_node(rn);
11279
11280 if (bdistance->access_list) {
11281 alist = access_list_lookup(afi, bdistance->access_list);
11282 if (alist
11283 && access_list_apply(alist, p) == FILTER_PERMIT)
11284 return bdistance->distance;
11285 } else
11286 return bdistance->distance;
11287 }
11288
11289 /* Backdoor check. */
11290 rn = bgp_node_lookup(bgp->route[afi][safi], p);
11291 if (rn) {
11292 bgp_static = bgp_node_get_bgp_static_info(rn);
11293 bgp_unlock_node(rn);
11294
11295 if (bgp_static->backdoor) {
11296 if (bgp->distance_local[afi][safi])
11297 return bgp->distance_local[afi][safi];
11298 else
11299 return ZEBRA_IBGP_DISTANCE_DEFAULT;
11300 }
11301 }
11302
11303 if (peer->sort == BGP_PEER_EBGP) {
11304 if (bgp->distance_ebgp[afi][safi])
11305 return bgp->distance_ebgp[afi][safi];
11306 return ZEBRA_EBGP_DISTANCE_DEFAULT;
11307 } else {
11308 if (bgp->distance_ibgp[afi][safi])
11309 return bgp->distance_ibgp[afi][safi];
11310 return ZEBRA_IBGP_DISTANCE_DEFAULT;
11311 }
11312 }
11313
11314 DEFUN (bgp_distance,
11315 bgp_distance_cmd,
11316 "distance bgp (1-255) (1-255) (1-255)",
11317 "Define an administrative distance\n"
11318 "BGP distance\n"
11319 "Distance for routes external to the AS\n"
11320 "Distance for routes internal to the AS\n"
11321 "Distance for local routes\n")
11322 {
11323 VTY_DECLVAR_CONTEXT(bgp, bgp);
11324 int idx_number = 2;
11325 int idx_number_2 = 3;
11326 int idx_number_3 = 4;
11327 afi_t afi;
11328 safi_t safi;
11329
11330 afi = bgp_node_afi(vty);
11331 safi = bgp_node_safi(vty);
11332
11333 bgp->distance_ebgp[afi][safi] = atoi(argv[idx_number]->arg);
11334 bgp->distance_ibgp[afi][safi] = atoi(argv[idx_number_2]->arg);
11335 bgp->distance_local[afi][safi] = atoi(argv[idx_number_3]->arg);
11336 return CMD_SUCCESS;
11337 }
11338
11339 DEFUN (no_bgp_distance,
11340 no_bgp_distance_cmd,
11341 "no distance bgp [(1-255) (1-255) (1-255)]",
11342 NO_STR
11343 "Define an administrative distance\n"
11344 "BGP distance\n"
11345 "Distance for routes external to the AS\n"
11346 "Distance for routes internal to the AS\n"
11347 "Distance for local routes\n")
11348 {
11349 VTY_DECLVAR_CONTEXT(bgp, bgp);
11350 afi_t afi;
11351 safi_t safi;
11352
11353 afi = bgp_node_afi(vty);
11354 safi = bgp_node_safi(vty);
11355
11356 bgp->distance_ebgp[afi][safi] = 0;
11357 bgp->distance_ibgp[afi][safi] = 0;
11358 bgp->distance_local[afi][safi] = 0;
11359 return CMD_SUCCESS;
11360 }
11361
11362
11363 DEFUN (bgp_distance_source,
11364 bgp_distance_source_cmd,
11365 "distance (1-255) A.B.C.D/M",
11366 "Define an administrative distance\n"
11367 "Administrative distance\n"
11368 "IP source prefix\n")
11369 {
11370 int idx_number = 1;
11371 int idx_ipv4_prefixlen = 2;
11372 bgp_distance_set(vty, argv[idx_number]->arg,
11373 argv[idx_ipv4_prefixlen]->arg, NULL);
11374 return CMD_SUCCESS;
11375 }
11376
11377 DEFUN (no_bgp_distance_source,
11378 no_bgp_distance_source_cmd,
11379 "no distance (1-255) A.B.C.D/M",
11380 NO_STR
11381 "Define an administrative distance\n"
11382 "Administrative distance\n"
11383 "IP source prefix\n")
11384 {
11385 int idx_number = 2;
11386 int idx_ipv4_prefixlen = 3;
11387 bgp_distance_unset(vty, argv[idx_number]->arg,
11388 argv[idx_ipv4_prefixlen]->arg, NULL);
11389 return CMD_SUCCESS;
11390 }
11391
11392 DEFUN (bgp_distance_source_access_list,
11393 bgp_distance_source_access_list_cmd,
11394 "distance (1-255) A.B.C.D/M WORD",
11395 "Define an administrative distance\n"
11396 "Administrative distance\n"
11397 "IP source prefix\n"
11398 "Access list name\n")
11399 {
11400 int idx_number = 1;
11401 int idx_ipv4_prefixlen = 2;
11402 int idx_word = 3;
11403 bgp_distance_set(vty, argv[idx_number]->arg,
11404 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
11405 return CMD_SUCCESS;
11406 }
11407
11408 DEFUN (no_bgp_distance_source_access_list,
11409 no_bgp_distance_source_access_list_cmd,
11410 "no distance (1-255) A.B.C.D/M WORD",
11411 NO_STR
11412 "Define an administrative distance\n"
11413 "Administrative distance\n"
11414 "IP source prefix\n"
11415 "Access list name\n")
11416 {
11417 int idx_number = 2;
11418 int idx_ipv4_prefixlen = 3;
11419 int idx_word = 4;
11420 bgp_distance_unset(vty, argv[idx_number]->arg,
11421 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
11422 return CMD_SUCCESS;
11423 }
11424
11425 DEFUN (ipv6_bgp_distance_source,
11426 ipv6_bgp_distance_source_cmd,
11427 "distance (1-255) X:X::X:X/M",
11428 "Define an administrative distance\n"
11429 "Administrative distance\n"
11430 "IP source prefix\n")
11431 {
11432 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
11433 return CMD_SUCCESS;
11434 }
11435
11436 DEFUN (no_ipv6_bgp_distance_source,
11437 no_ipv6_bgp_distance_source_cmd,
11438 "no distance (1-255) X:X::X:X/M",
11439 NO_STR
11440 "Define an administrative distance\n"
11441 "Administrative distance\n"
11442 "IP source prefix\n")
11443 {
11444 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
11445 return CMD_SUCCESS;
11446 }
11447
11448 DEFUN (ipv6_bgp_distance_source_access_list,
11449 ipv6_bgp_distance_source_access_list_cmd,
11450 "distance (1-255) X:X::X:X/M WORD",
11451 "Define an administrative distance\n"
11452 "Administrative distance\n"
11453 "IP source prefix\n"
11454 "Access list name\n")
11455 {
11456 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
11457 return CMD_SUCCESS;
11458 }
11459
11460 DEFUN (no_ipv6_bgp_distance_source_access_list,
11461 no_ipv6_bgp_distance_source_access_list_cmd,
11462 "no distance (1-255) X:X::X:X/M WORD",
11463 NO_STR
11464 "Define an administrative distance\n"
11465 "Administrative distance\n"
11466 "IP source prefix\n"
11467 "Access list name\n")
11468 {
11469 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
11470 return CMD_SUCCESS;
11471 }
11472
11473 DEFUN (bgp_damp_set,
11474 bgp_damp_set_cmd,
11475 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
11476 "BGP Specific commands\n"
11477 "Enable route-flap dampening\n"
11478 "Half-life time for the penalty\n"
11479 "Value to start reusing a route\n"
11480 "Value to start suppressing a route\n"
11481 "Maximum duration to suppress a stable route\n")
11482 {
11483 VTY_DECLVAR_CONTEXT(bgp, bgp);
11484 int idx_half_life = 2;
11485 int idx_reuse = 3;
11486 int idx_suppress = 4;
11487 int idx_max_suppress = 5;
11488 int half = DEFAULT_HALF_LIFE * 60;
11489 int reuse = DEFAULT_REUSE;
11490 int suppress = DEFAULT_SUPPRESS;
11491 int max = 4 * half;
11492
11493 if (argc == 6) {
11494 half = atoi(argv[idx_half_life]->arg) * 60;
11495 reuse = atoi(argv[idx_reuse]->arg);
11496 suppress = atoi(argv[idx_suppress]->arg);
11497 max = atoi(argv[idx_max_suppress]->arg) * 60;
11498 } else if (argc == 3) {
11499 half = atoi(argv[idx_half_life]->arg) * 60;
11500 max = 4 * half;
11501 }
11502
11503 if (suppress < reuse) {
11504 vty_out(vty,
11505 "Suppress value cannot be less than reuse value \n");
11506 return 0;
11507 }
11508
11509 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
11510 reuse, suppress, max);
11511 }
11512
11513 DEFUN (bgp_damp_unset,
11514 bgp_damp_unset_cmd,
11515 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
11516 NO_STR
11517 "BGP Specific commands\n"
11518 "Enable route-flap dampening\n"
11519 "Half-life time for the penalty\n"
11520 "Value to start reusing a route\n"
11521 "Value to start suppressing a route\n"
11522 "Maximum duration to suppress a stable route\n")
11523 {
11524 VTY_DECLVAR_CONTEXT(bgp, bgp);
11525 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
11526 }
11527
11528 /* Display specified route of BGP table. */
11529 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
11530 const char *ip_str, afi_t afi, safi_t safi,
11531 struct prefix_rd *prd, int prefix_check)
11532 {
11533 int ret;
11534 struct prefix match;
11535 struct bgp_node *rn;
11536 struct bgp_node *rm;
11537 struct bgp_path_info *pi;
11538 struct bgp_path_info *pi_temp;
11539 struct bgp *bgp;
11540 struct bgp_table *table;
11541
11542 /* BGP structure lookup. */
11543 if (view_name) {
11544 bgp = bgp_lookup_by_name(view_name);
11545 if (bgp == NULL) {
11546 vty_out(vty, "%% Can't find BGP instance %s\n",
11547 view_name);
11548 return CMD_WARNING;
11549 }
11550 } else {
11551 bgp = bgp_get_default();
11552 if (bgp == NULL) {
11553 vty_out(vty, "%% No BGP process is configured\n");
11554 return CMD_WARNING;
11555 }
11556 }
11557
11558 /* Check IP address argument. */
11559 ret = str2prefix(ip_str, &match);
11560 if (!ret) {
11561 vty_out(vty, "%% address is malformed\n");
11562 return CMD_WARNING;
11563 }
11564
11565 match.family = afi2family(afi);
11566
11567 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
11568 || (safi == SAFI_EVPN)) {
11569 for (rn = bgp_table_top(bgp->rib[AFI_IP][safi]); rn;
11570 rn = bgp_route_next(rn)) {
11571 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
11572 continue;
11573 table = bgp_node_get_bgp_table_info(rn);
11574 if (!table)
11575 continue;
11576 if ((rm = bgp_node_match(table, &match)) == NULL)
11577 continue;
11578
11579 if (!prefix_check
11580 || rm->p.prefixlen == match.prefixlen) {
11581 pi = bgp_node_get_bgp_path_info(rm);
11582 while (pi) {
11583 if (pi->extra && pi->extra->damp_info) {
11584 pi_temp = pi->next;
11585 bgp_damp_info_free(
11586 pi->extra->damp_info,
11587 1);
11588 pi = pi_temp;
11589 } else
11590 pi = pi->next;
11591 }
11592 }
11593
11594 bgp_unlock_node(rm);
11595 }
11596 } else {
11597 if ((rn = bgp_node_match(bgp->rib[afi][safi], &match))
11598 != NULL) {
11599 if (!prefix_check
11600 || rn->p.prefixlen == match.prefixlen) {
11601 pi = bgp_node_get_bgp_path_info(rn);
11602 while (pi) {
11603 if (pi->extra && pi->extra->damp_info) {
11604 pi_temp = pi->next;
11605 bgp_damp_info_free(
11606 pi->extra->damp_info,
11607 1);
11608 pi = pi_temp;
11609 } else
11610 pi = pi->next;
11611 }
11612 }
11613
11614 bgp_unlock_node(rn);
11615 }
11616 }
11617
11618 return CMD_SUCCESS;
11619 }
11620
11621 DEFUN (clear_ip_bgp_dampening,
11622 clear_ip_bgp_dampening_cmd,
11623 "clear ip bgp dampening",
11624 CLEAR_STR
11625 IP_STR
11626 BGP_STR
11627 "Clear route flap dampening information\n")
11628 {
11629 bgp_damp_info_clean();
11630 return CMD_SUCCESS;
11631 }
11632
11633 DEFUN (clear_ip_bgp_dampening_prefix,
11634 clear_ip_bgp_dampening_prefix_cmd,
11635 "clear ip bgp dampening A.B.C.D/M",
11636 CLEAR_STR
11637 IP_STR
11638 BGP_STR
11639 "Clear route flap dampening information\n"
11640 "IPv4 prefix\n")
11641 {
11642 int idx_ipv4_prefixlen = 4;
11643 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
11644 AFI_IP, SAFI_UNICAST, NULL, 1);
11645 }
11646
11647 DEFUN (clear_ip_bgp_dampening_address,
11648 clear_ip_bgp_dampening_address_cmd,
11649 "clear ip bgp dampening A.B.C.D",
11650 CLEAR_STR
11651 IP_STR
11652 BGP_STR
11653 "Clear route flap dampening information\n"
11654 "Network to clear damping information\n")
11655 {
11656 int idx_ipv4 = 4;
11657 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
11658 SAFI_UNICAST, NULL, 0);
11659 }
11660
11661 DEFUN (clear_ip_bgp_dampening_address_mask,
11662 clear_ip_bgp_dampening_address_mask_cmd,
11663 "clear ip bgp dampening A.B.C.D A.B.C.D",
11664 CLEAR_STR
11665 IP_STR
11666 BGP_STR
11667 "Clear route flap dampening information\n"
11668 "Network to clear damping information\n"
11669 "Network mask\n")
11670 {
11671 int idx_ipv4 = 4;
11672 int idx_ipv4_2 = 5;
11673 int ret;
11674 char prefix_str[BUFSIZ];
11675
11676 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
11677 prefix_str);
11678 if (!ret) {
11679 vty_out(vty, "%% Inconsistent address and mask\n");
11680 return CMD_WARNING;
11681 }
11682
11683 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
11684 NULL, 0);
11685 }
11686
11687 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
11688 {
11689 struct vty *vty = arg;
11690 struct peer *peer = bucket->data;
11691 char buf[SU_ADDRSTRLEN];
11692
11693 vty_out(vty, "\tPeer: %s %s\n", peer->host,
11694 sockunion2str(&peer->su, buf, sizeof(buf)));
11695 }
11696
11697 DEFUN (show_bgp_peerhash,
11698 show_bgp_peerhash_cmd,
11699 "show bgp peerhash",
11700 SHOW_STR
11701 BGP_STR
11702 "Display information about the BGP peerhash\n")
11703 {
11704 struct list *instances = bm->bgp;
11705 struct listnode *node;
11706 struct bgp *bgp;
11707
11708 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
11709 vty_out(vty, "BGP: %s\n", bgp->name);
11710 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
11711 vty);
11712 }
11713
11714 return CMD_SUCCESS;
11715 }
11716
11717 /* also used for encap safi */
11718 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
11719 afi_t afi, safi_t safi)
11720 {
11721 struct bgp_node *prn;
11722 struct bgp_node *rn;
11723 struct bgp_table *table;
11724 struct prefix *p;
11725 struct prefix_rd *prd;
11726 struct bgp_static *bgp_static;
11727 mpls_label_t label;
11728 char buf[SU_ADDRSTRLEN];
11729 char rdbuf[RD_ADDRSTRLEN];
11730
11731 /* Network configuration. */
11732 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
11733 prn = bgp_route_next(prn)) {
11734 table = bgp_node_get_bgp_table_info(prn);
11735 if (!table)
11736 continue;
11737
11738 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
11739 bgp_static = bgp_node_get_bgp_static_info(rn);
11740 if (bgp_static == NULL)
11741 continue;
11742
11743 p = &rn->p;
11744 prd = (struct prefix_rd *)&prn->p;
11745
11746 /* "network" configuration display. */
11747 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
11748 label = decode_label(&bgp_static->label);
11749
11750 vty_out(vty, " network %s/%d rd %s",
11751 inet_ntop(p->family, &p->u.prefix, buf,
11752 SU_ADDRSTRLEN),
11753 p->prefixlen, rdbuf);
11754 if (safi == SAFI_MPLS_VPN)
11755 vty_out(vty, " label %u", label);
11756
11757 if (bgp_static->rmap.name)
11758 vty_out(vty, " route-map %s",
11759 bgp_static->rmap.name);
11760
11761 if (bgp_static->backdoor)
11762 vty_out(vty, " backdoor");
11763
11764 vty_out(vty, "\n");
11765 }
11766 }
11767 }
11768
11769 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
11770 afi_t afi, safi_t safi)
11771 {
11772 struct bgp_node *prn;
11773 struct bgp_node *rn;
11774 struct bgp_table *table;
11775 struct prefix *p;
11776 struct prefix_rd *prd;
11777 struct bgp_static *bgp_static;
11778 char buf[PREFIX_STRLEN * 2];
11779 char buf2[SU_ADDRSTRLEN];
11780 char rdbuf[RD_ADDRSTRLEN];
11781
11782 /* Network configuration. */
11783 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
11784 prn = bgp_route_next(prn)) {
11785 table = bgp_node_get_bgp_table_info(prn);
11786 if (!table)
11787 continue;
11788
11789 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
11790 bgp_static = bgp_node_get_bgp_static_info(rn);
11791 if (bgp_static == NULL)
11792 continue;
11793
11794 char *macrouter = NULL;
11795 char *esi = NULL;
11796
11797 if (bgp_static->router_mac)
11798 macrouter = prefix_mac2str(
11799 bgp_static->router_mac, NULL, 0);
11800 if (bgp_static->eth_s_id)
11801 esi = esi2str(bgp_static->eth_s_id);
11802 p = &rn->p;
11803 prd = (struct prefix_rd *)&prn->p;
11804
11805 /* "network" configuration display. */
11806 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
11807 if (p->u.prefix_evpn.route_type == 5) {
11808 char local_buf[PREFIX_STRLEN];
11809 uint8_t family = is_evpn_prefix_ipaddr_v4((
11810 struct prefix_evpn *)p)
11811 ? AF_INET
11812 : AF_INET6;
11813 inet_ntop(family,
11814 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
11815 local_buf, PREFIX_STRLEN);
11816 sprintf(buf, "%s/%u", local_buf,
11817 p->u.prefix_evpn.prefix_addr.ip_prefix_length);
11818 } else {
11819 prefix2str(p, buf, sizeof(buf));
11820 }
11821
11822 if (bgp_static->gatewayIp.family == AF_INET
11823 || bgp_static->gatewayIp.family == AF_INET6)
11824 inet_ntop(bgp_static->gatewayIp.family,
11825 &bgp_static->gatewayIp.u.prefix, buf2,
11826 sizeof(buf2));
11827 vty_out(vty,
11828 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
11829 buf, rdbuf,
11830 p->u.prefix_evpn.prefix_addr.eth_tag,
11831 decode_label(&bgp_static->label), esi, buf2,
11832 macrouter);
11833
11834 XFREE(MTYPE_TMP, macrouter);
11835 XFREE(MTYPE_TMP, esi);
11836 }
11837 }
11838 }
11839
11840 /* Configuration of static route announcement and aggregate
11841 information. */
11842 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
11843 safi_t safi)
11844 {
11845 struct bgp_node *rn;
11846 struct prefix *p;
11847 struct bgp_static *bgp_static;
11848 struct bgp_aggregate *bgp_aggregate;
11849 char buf[SU_ADDRSTRLEN];
11850
11851 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
11852 bgp_config_write_network_vpn(vty, bgp, afi, safi);
11853 return;
11854 }
11855
11856 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
11857 bgp_config_write_network_evpn(vty, bgp, afi, safi);
11858 return;
11859 }
11860
11861 /* Network configuration. */
11862 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
11863 rn = bgp_route_next(rn)) {
11864 bgp_static = bgp_node_get_bgp_static_info(rn);
11865 if (bgp_static == NULL)
11866 continue;
11867
11868 p = &rn->p;
11869
11870 /* "network" configuration display. */
11871 if (bgp_option_check(BGP_OPT_CONFIG_CISCO) && afi == AFI_IP) {
11872 uint32_t destination;
11873 struct in_addr netmask;
11874
11875 destination = ntohl(p->u.prefix4.s_addr);
11876 masklen2ip(p->prefixlen, &netmask);
11877 vty_out(vty, " network %s",
11878 inet_ntop(p->family, &p->u.prefix, buf,
11879 SU_ADDRSTRLEN));
11880
11881 if ((IN_CLASSC(destination) && p->prefixlen == 24)
11882 || (IN_CLASSB(destination) && p->prefixlen == 16)
11883 || (IN_CLASSA(destination) && p->prefixlen == 8)
11884 || p->u.prefix4.s_addr == 0) {
11885 /* Natural mask is not display. */
11886 } else
11887 vty_out(vty, " mask %s", inet_ntoa(netmask));
11888 } else {
11889 vty_out(vty, " network %s/%d",
11890 inet_ntop(p->family, &p->u.prefix, buf,
11891 SU_ADDRSTRLEN),
11892 p->prefixlen);
11893 }
11894
11895 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
11896 vty_out(vty, " label-index %u",
11897 bgp_static->label_index);
11898
11899 if (bgp_static->rmap.name)
11900 vty_out(vty, " route-map %s", bgp_static->rmap.name);
11901
11902 if (bgp_static->backdoor)
11903 vty_out(vty, " backdoor");
11904
11905 vty_out(vty, "\n");
11906 }
11907
11908 /* Aggregate-address configuration. */
11909 for (rn = bgp_table_top(bgp->aggregate[afi][safi]); rn;
11910 rn = bgp_route_next(rn)) {
11911 bgp_aggregate = bgp_node_get_bgp_aggregate_info(rn);
11912 if (bgp_aggregate == NULL)
11913 continue;
11914
11915 p = &rn->p;
11916
11917 if (bgp_option_check(BGP_OPT_CONFIG_CISCO) && afi == AFI_IP) {
11918 struct in_addr netmask;
11919
11920 masklen2ip(p->prefixlen, &netmask);
11921 vty_out(vty, " aggregate-address %s %s",
11922 inet_ntop(p->family, &p->u.prefix, buf,
11923 SU_ADDRSTRLEN),
11924 inet_ntoa(netmask));
11925 } else {
11926 vty_out(vty, " aggregate-address %s/%d",
11927 inet_ntop(p->family, &p->u.prefix, buf,
11928 SU_ADDRSTRLEN),
11929 p->prefixlen);
11930 }
11931
11932 if (bgp_aggregate->as_set)
11933 vty_out(vty, " as-set");
11934
11935 if (bgp_aggregate->summary_only)
11936 vty_out(vty, " summary-only");
11937
11938 vty_out(vty, "\n");
11939 }
11940 }
11941
11942 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
11943 safi_t safi)
11944 {
11945 struct bgp_node *rn;
11946 struct bgp_distance *bdistance;
11947
11948 /* Distance configuration. */
11949 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
11950 && bgp->distance_local[afi][safi]
11951 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
11952 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
11953 || bgp->distance_local[afi][safi]
11954 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
11955 vty_out(vty, " distance bgp %d %d %d\n",
11956 bgp->distance_ebgp[afi][safi],
11957 bgp->distance_ibgp[afi][safi],
11958 bgp->distance_local[afi][safi]);
11959 }
11960
11961 for (rn = bgp_table_top(bgp_distance_table[afi][safi]); rn;
11962 rn = bgp_route_next(rn)) {
11963 bdistance = bgp_node_get_bgp_distance_info(rn);
11964 if (bdistance != NULL) {
11965 char buf[PREFIX_STRLEN];
11966
11967 vty_out(vty, " distance %d %s %s\n",
11968 bdistance->distance,
11969 prefix2str(&rn->p, buf, sizeof(buf)),
11970 bdistance->access_list ? bdistance->access_list
11971 : "");
11972 }
11973 }
11974 }
11975
11976 /* Allocate routing table structure and install commands. */
11977 void bgp_route_init(void)
11978 {
11979 afi_t afi;
11980 safi_t safi;
11981
11982 /* Init BGP distance table. */
11983 FOREACH_AFI_SAFI (afi, safi)
11984 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
11985
11986 /* IPv4 BGP commands. */
11987 install_element(BGP_NODE, &bgp_table_map_cmd);
11988 install_element(BGP_NODE, &bgp_network_cmd);
11989 install_element(BGP_NODE, &no_bgp_table_map_cmd);
11990
11991 install_element(BGP_NODE, &aggregate_address_cmd);
11992 install_element(BGP_NODE, &aggregate_address_mask_cmd);
11993 install_element(BGP_NODE, &no_aggregate_address_cmd);
11994 install_element(BGP_NODE, &no_aggregate_address_mask_cmd);
11995
11996 /* IPv4 unicast configuration. */
11997 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
11998 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
11999 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
12000
12001 install_element(BGP_IPV4_NODE, &aggregate_address_cmd);
12002 install_element(BGP_IPV4_NODE, &aggregate_address_mask_cmd);
12003 install_element(BGP_IPV4_NODE, &no_aggregate_address_cmd);
12004 install_element(BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
12005
12006 /* IPv4 multicast configuration. */
12007 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
12008 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
12009 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
12010 install_element(BGP_IPV4M_NODE, &aggregate_address_cmd);
12011 install_element(BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
12012 install_element(BGP_IPV4M_NODE, &no_aggregate_address_cmd);
12013 install_element(BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
12014
12015 /* IPv4 labeled-unicast configuration. */
12016 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
12017 install_element(VIEW_NODE, &show_ip_bgp_cmd);
12018 install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
12019 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
12020 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
12021
12022 install_element(VIEW_NODE,
12023 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
12024 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
12025 install_element(VIEW_NODE,
12026 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
12027 #ifdef KEEP_OLD_VPN_COMMANDS
12028 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
12029 #endif /* KEEP_OLD_VPN_COMMANDS */
12030 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
12031 install_element(VIEW_NODE,
12032 &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd);
12033
12034 /* BGP dampening clear commands */
12035 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
12036 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
12037
12038 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
12039 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
12040
12041 /* prefix count */
12042 install_element(ENABLE_NODE,
12043 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
12044 #ifdef KEEP_OLD_VPN_COMMANDS
12045 install_element(ENABLE_NODE,
12046 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
12047 #endif /* KEEP_OLD_VPN_COMMANDS */
12048
12049 /* New config IPv6 BGP commands. */
12050 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
12051 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
12052 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
12053
12054 install_element(BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
12055 install_element(BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
12056
12057 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
12058
12059 install_element(BGP_NODE, &bgp_distance_cmd);
12060 install_element(BGP_NODE, &no_bgp_distance_cmd);
12061 install_element(BGP_NODE, &bgp_distance_source_cmd);
12062 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
12063 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
12064 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
12065 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
12066 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
12067 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
12068 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
12069 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
12070 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
12071 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
12072 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
12073 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
12074 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
12075 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
12076 install_element(BGP_IPV4M_NODE,
12077 &no_bgp_distance_source_access_list_cmd);
12078 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
12079 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
12080 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
12081 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
12082 install_element(BGP_IPV6_NODE,
12083 &ipv6_bgp_distance_source_access_list_cmd);
12084 install_element(BGP_IPV6_NODE,
12085 &no_ipv6_bgp_distance_source_access_list_cmd);
12086 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
12087 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
12088 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
12089 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
12090 install_element(BGP_IPV6M_NODE,
12091 &ipv6_bgp_distance_source_access_list_cmd);
12092 install_element(BGP_IPV6M_NODE,
12093 &no_ipv6_bgp_distance_source_access_list_cmd);
12094
12095 install_element(BGP_NODE, &bgp_damp_set_cmd);
12096 install_element(BGP_NODE, &bgp_damp_unset_cmd);
12097 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
12098 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
12099
12100 /* IPv4 Multicast Mode */
12101 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
12102 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
12103
12104 /* Large Communities */
12105 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
12106 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
12107
12108 /* show bgp ipv4 flowspec detailed */
12109 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
12110
12111 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
12112 }
12113
12114 void bgp_route_finish(void)
12115 {
12116 afi_t afi;
12117 safi_t safi;
12118
12119 FOREACH_AFI_SAFI (afi, safi) {
12120 bgp_table_unlock(bgp_distance_table[afi][safi]);
12121 bgp_distance_table[afi][safi] = NULL;
12122 }
12123 }