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