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