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