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