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