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