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