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