]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
bgpd: Code to remove the bottleneck in aggregation.
[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 if (bgp_static->eth_s_id)
4421 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
4422 XFREE(MTYPE_BGP_STATIC, bgp_static);
4423 }
4424
4425 void bgp_static_update(struct bgp *bgp, struct prefix *p,
4426 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
4427 {
4428 struct bgp_node *rn;
4429 struct bgp_path_info *pi;
4430 struct bgp_path_info *new;
4431 struct bgp_path_info rmap_path;
4432 struct attr attr;
4433 struct attr *attr_new;
4434 int ret;
4435 #if ENABLE_BGP_VNC
4436 int vnc_implicit_withdraw = 0;
4437 #endif
4438
4439 assert(bgp_static);
4440 if (!bgp_static)
4441 return;
4442
4443 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
4444
4445 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
4446
4447 attr.nexthop = bgp_static->igpnexthop;
4448 attr.med = bgp_static->igpmetric;
4449 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
4450
4451 if (bgp_static->atomic)
4452 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
4453
4454 /* Store label index, if required. */
4455 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
4456 attr.label_index = bgp_static->label_index;
4457 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
4458 }
4459
4460 /* Apply route-map. */
4461 if (bgp_static->rmap.name) {
4462 struct attr attr_tmp = attr;
4463
4464 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
4465 rmap_path.peer = bgp->peer_self;
4466 rmap_path.attr = &attr_tmp;
4467
4468 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
4469
4470 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
4471 &rmap_path);
4472
4473 bgp->peer_self->rmap_type = 0;
4474
4475 if (ret == RMAP_DENYMATCH) {
4476 /* Free uninterned attribute. */
4477 bgp_attr_flush(&attr_tmp);
4478
4479 /* Unintern original. */
4480 aspath_unintern(&attr.aspath);
4481 bgp_static_withdraw(bgp, p, afi, safi);
4482 return;
4483 }
4484
4485 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
4486 bgp_attr_add_gshut_community(&attr_tmp);
4487
4488 attr_new = bgp_attr_intern(&attr_tmp);
4489 } else {
4490
4491 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
4492 bgp_attr_add_gshut_community(&attr);
4493
4494 attr_new = bgp_attr_intern(&attr);
4495 }
4496
4497 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4498 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4499 && pi->sub_type == BGP_ROUTE_STATIC)
4500 break;
4501
4502 if (pi) {
4503 if (attrhash_cmp(pi->attr, attr_new)
4504 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4505 && !bgp_flag_check(bgp, BGP_FLAG_FORCE_STATIC_PROCESS)) {
4506 bgp_unlock_node(rn);
4507 bgp_attr_unintern(&attr_new);
4508 aspath_unintern(&attr.aspath);
4509 return;
4510 } else {
4511 /* The attribute is changed. */
4512 bgp_path_info_set_flag(rn, pi, BGP_PATH_ATTR_CHANGED);
4513
4514 /* Rewrite BGP route information. */
4515 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
4516 bgp_path_info_restore(rn, pi);
4517 else
4518 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4519 #if ENABLE_BGP_VNC
4520 if ((afi == AFI_IP || afi == AFI_IP6)
4521 && (safi == SAFI_UNICAST)) {
4522 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4523 /*
4524 * Implicit withdraw case.
4525 * We have to do this before pi is
4526 * changed
4527 */
4528 ++vnc_implicit_withdraw;
4529 vnc_import_bgp_del_route(bgp, p, pi);
4530 vnc_import_bgp_exterior_del_route(
4531 bgp, p, pi);
4532 }
4533 }
4534 #endif
4535 bgp_attr_unintern(&pi->attr);
4536 pi->attr = attr_new;
4537 pi->uptime = bgp_clock();
4538 #if ENABLE_BGP_VNC
4539 if ((afi == AFI_IP || afi == AFI_IP6)
4540 && (safi == SAFI_UNICAST)) {
4541 if (vnc_implicit_withdraw) {
4542 vnc_import_bgp_add_route(bgp, p, pi);
4543 vnc_import_bgp_exterior_add_route(
4544 bgp, p, pi);
4545 }
4546 }
4547 #endif
4548
4549 /* Nexthop reachability check. */
4550 if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
4551 && (safi == SAFI_UNICAST
4552 || safi == SAFI_LABELED_UNICAST)) {
4553
4554 struct bgp *bgp_nexthop = bgp;
4555
4556 if (pi->extra && pi->extra->bgp_orig)
4557 bgp_nexthop = pi->extra->bgp_orig;
4558
4559 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
4560 afi, pi, NULL, 0))
4561 bgp_path_info_set_flag(rn, pi,
4562 BGP_PATH_VALID);
4563 else {
4564 if (BGP_DEBUG(nht, NHT)) {
4565 char buf1[INET6_ADDRSTRLEN];
4566 inet_ntop(p->family,
4567 &p->u.prefix, buf1,
4568 INET6_ADDRSTRLEN);
4569 zlog_debug(
4570 "%s(%s): Route not in table, not advertising",
4571 __FUNCTION__, buf1);
4572 }
4573 bgp_path_info_unset_flag(
4574 rn, pi, BGP_PATH_VALID);
4575 }
4576 } else {
4577 /* Delete the NHT structure if any, if we're
4578 * toggling between
4579 * enabling/disabling import check. We
4580 * deregister the route
4581 * from NHT to avoid overloading NHT and the
4582 * process interaction
4583 */
4584 bgp_unlink_nexthop(pi);
4585 bgp_path_info_set_flag(rn, pi, BGP_PATH_VALID);
4586 }
4587 /* Process change. */
4588 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4589 bgp_process(bgp, rn, afi, safi);
4590
4591 if (SAFI_UNICAST == safi
4592 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4593 || bgp->inst_type
4594 == BGP_INSTANCE_TYPE_DEFAULT)) {
4595 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
4596 pi);
4597 }
4598
4599 bgp_unlock_node(rn);
4600 aspath_unintern(&attr.aspath);
4601 return;
4602 }
4603 }
4604
4605 /* Make new BGP info. */
4606 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
4607 attr_new, rn);
4608 /* Nexthop reachability check. */
4609 if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
4610 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
4611 if (bgp_find_or_add_nexthop(bgp, bgp, afi, new, NULL, 0))
4612 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
4613 else {
4614 if (BGP_DEBUG(nht, NHT)) {
4615 char buf1[INET6_ADDRSTRLEN];
4616 inet_ntop(p->family, &p->u.prefix, buf1,
4617 INET6_ADDRSTRLEN);
4618 zlog_debug(
4619 "%s(%s): Route not in table, not advertising",
4620 __FUNCTION__, buf1);
4621 }
4622 bgp_path_info_unset_flag(rn, new, BGP_PATH_VALID);
4623 }
4624 } else {
4625 /* Delete the NHT structure if any, if we're toggling between
4626 * enabling/disabling import check. We deregister the route
4627 * from NHT to avoid overloading NHT and the process interaction
4628 */
4629 bgp_unlink_nexthop(new);
4630
4631 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
4632 }
4633
4634 /* Aggregate address increment. */
4635 bgp_aggregate_increment(bgp, p, new, afi, safi);
4636
4637 /* Register new BGP information. */
4638 bgp_path_info_add(rn, new);
4639
4640 /* route_node_get lock */
4641 bgp_unlock_node(rn);
4642
4643 /* Process change. */
4644 bgp_process(bgp, rn, afi, safi);
4645
4646 if (SAFI_UNICAST == safi
4647 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4648 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4649 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4650 }
4651
4652 /* Unintern original. */
4653 aspath_unintern(&attr.aspath);
4654 }
4655
4656 void bgp_static_withdraw(struct bgp *bgp, struct prefix *p, afi_t afi,
4657 safi_t safi)
4658 {
4659 struct bgp_node *rn;
4660 struct bgp_path_info *pi;
4661
4662 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
4663
4664 /* Check selected route and self inserted route. */
4665 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4666 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4667 && pi->sub_type == BGP_ROUTE_STATIC)
4668 break;
4669
4670 /* Withdraw static BGP route from routing table. */
4671 if (pi) {
4672 if (SAFI_UNICAST == safi
4673 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4674 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4675 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4676 }
4677 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4678 bgp_unlink_nexthop(pi);
4679 bgp_path_info_delete(rn, pi);
4680 bgp_process(bgp, rn, afi, safi);
4681 }
4682
4683 /* Unlock bgp_node_lookup. */
4684 bgp_unlock_node(rn);
4685 }
4686
4687 /*
4688 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4689 */
4690 static void bgp_static_withdraw_safi(struct bgp *bgp, struct prefix *p,
4691 afi_t afi, safi_t safi,
4692 struct prefix_rd *prd)
4693 {
4694 struct bgp_node *rn;
4695 struct bgp_path_info *pi;
4696
4697 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4698
4699 /* Check selected route and self inserted route. */
4700 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4701 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4702 && pi->sub_type == BGP_ROUTE_STATIC)
4703 break;
4704
4705 /* Withdraw static BGP route from routing table. */
4706 if (pi) {
4707 #if ENABLE_BGP_VNC
4708 rfapiProcessWithdraw(
4709 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
4710 1); /* Kill, since it is an administrative change */
4711 #endif
4712 if (SAFI_MPLS_VPN == safi
4713 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4714 vpn_leak_to_vrf_withdraw(bgp, pi);
4715 }
4716 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4717 bgp_path_info_delete(rn, pi);
4718 bgp_process(bgp, rn, afi, safi);
4719 }
4720
4721 /* Unlock bgp_node_lookup. */
4722 bgp_unlock_node(rn);
4723 }
4724
4725 static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p,
4726 struct bgp_static *bgp_static, afi_t afi,
4727 safi_t safi)
4728 {
4729 struct bgp_node *rn;
4730 struct bgp_path_info *new;
4731 struct attr *attr_new;
4732 struct attr attr = {0};
4733 struct bgp_path_info *pi;
4734 #if ENABLE_BGP_VNC
4735 mpls_label_t label = 0;
4736 #endif
4737 uint32_t num_labels = 0;
4738 union gw_addr add;
4739
4740 assert(bgp_static);
4741
4742 if (bgp_static->label != MPLS_INVALID_LABEL)
4743 num_labels = 1;
4744 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
4745 &bgp_static->prd);
4746
4747 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
4748
4749 attr.nexthop = bgp_static->igpnexthop;
4750 attr.med = bgp_static->igpmetric;
4751 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
4752
4753 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
4754 || (safi == SAFI_ENCAP)) {
4755 if (afi == AFI_IP) {
4756 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
4757 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
4758 }
4759 }
4760 if (afi == AFI_L2VPN) {
4761 if (bgp_static->gatewayIp.family == AF_INET)
4762 add.ipv4.s_addr =
4763 bgp_static->gatewayIp.u.prefix4.s_addr;
4764 else if (bgp_static->gatewayIp.family == AF_INET6)
4765 memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
4766 sizeof(struct in6_addr));
4767 overlay_index_update(&attr, bgp_static->eth_s_id, &add);
4768 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
4769 struct bgp_encap_type_vxlan bet;
4770 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
4771 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
4772 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
4773 }
4774 if (bgp_static->router_mac) {
4775 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
4776 }
4777 }
4778 /* Apply route-map. */
4779 if (bgp_static->rmap.name) {
4780 struct attr attr_tmp = attr;
4781 struct bgp_path_info rmap_path;
4782 int ret;
4783
4784 rmap_path.peer = bgp->peer_self;
4785 rmap_path.attr = &attr_tmp;
4786
4787 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
4788
4789 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
4790 &rmap_path);
4791
4792 bgp->peer_self->rmap_type = 0;
4793
4794 if (ret == RMAP_DENYMATCH) {
4795 /* Free uninterned attribute. */
4796 bgp_attr_flush(&attr_tmp);
4797
4798 /* Unintern original. */
4799 aspath_unintern(&attr.aspath);
4800 bgp_static_withdraw_safi(bgp, p, afi, safi,
4801 &bgp_static->prd);
4802 return;
4803 }
4804
4805 attr_new = bgp_attr_intern(&attr_tmp);
4806 } else {
4807 attr_new = bgp_attr_intern(&attr);
4808 }
4809
4810 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4811 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4812 && pi->sub_type == BGP_ROUTE_STATIC)
4813 break;
4814
4815 if (pi) {
4816 memset(&add, 0, sizeof(union gw_addr));
4817 if (attrhash_cmp(pi->attr, attr_new)
4818 && overlay_index_equal(afi, pi, bgp_static->eth_s_id, &add)
4819 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4820 bgp_unlock_node(rn);
4821 bgp_attr_unintern(&attr_new);
4822 aspath_unintern(&attr.aspath);
4823 return;
4824 } else {
4825 /* The attribute is changed. */
4826 bgp_path_info_set_flag(rn, pi, BGP_PATH_ATTR_CHANGED);
4827
4828 /* Rewrite BGP route information. */
4829 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
4830 bgp_path_info_restore(rn, pi);
4831 else
4832 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4833 bgp_attr_unintern(&pi->attr);
4834 pi->attr = attr_new;
4835 pi->uptime = bgp_clock();
4836 #if ENABLE_BGP_VNC
4837 if (pi->extra)
4838 label = decode_label(&pi->extra->label[0]);
4839 #endif
4840
4841 /* Process change. */
4842 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4843 bgp_process(bgp, rn, afi, safi);
4844
4845 if (SAFI_MPLS_VPN == safi
4846 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4847 vpn_leak_to_vrf_update(bgp, pi);
4848 }
4849 #if ENABLE_BGP_VNC
4850 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
4851 pi->attr, afi, safi, pi->type,
4852 pi->sub_type, &label);
4853 #endif
4854 bgp_unlock_node(rn);
4855 aspath_unintern(&attr.aspath);
4856 return;
4857 }
4858 }
4859
4860
4861 /* Make new BGP info. */
4862 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
4863 attr_new, rn);
4864 SET_FLAG(new->flags, BGP_PATH_VALID);
4865 new->extra = bgp_path_info_extra_new();
4866 if (num_labels) {
4867 new->extra->label[0] = bgp_static->label;
4868 new->extra->num_labels = num_labels;
4869 }
4870 #if ENABLE_BGP_VNC
4871 label = decode_label(&bgp_static->label);
4872 #endif
4873
4874 /* Aggregate address increment. */
4875 bgp_aggregate_increment(bgp, p, new, afi, safi);
4876
4877 /* Register new BGP information. */
4878 bgp_path_info_add(rn, new);
4879 /* route_node_get lock */
4880 bgp_unlock_node(rn);
4881
4882 /* Process change. */
4883 bgp_process(bgp, rn, afi, safi);
4884
4885 if (SAFI_MPLS_VPN == safi
4886 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4887 vpn_leak_to_vrf_update(bgp, new);
4888 }
4889 #if ENABLE_BGP_VNC
4890 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
4891 safi, new->type, new->sub_type, &label);
4892 #endif
4893
4894 /* Unintern original. */
4895 aspath_unintern(&attr.aspath);
4896 }
4897
4898 /* Configure static BGP network. When user don't run zebra, static
4899 route should be installed as valid. */
4900 static int bgp_static_set(struct vty *vty, const char *negate,
4901 const char *ip_str, afi_t afi, safi_t safi,
4902 const char *rmap, int backdoor, uint32_t label_index)
4903 {
4904 VTY_DECLVAR_CONTEXT(bgp, bgp);
4905 int ret;
4906 struct prefix p;
4907 struct bgp_static *bgp_static;
4908 struct bgp_node *rn;
4909 uint8_t need_update = 0;
4910
4911 /* Convert IP prefix string to struct prefix. */
4912 ret = str2prefix(ip_str, &p);
4913 if (!ret) {
4914 vty_out(vty, "%% Malformed prefix\n");
4915 return CMD_WARNING_CONFIG_FAILED;
4916 }
4917 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
4918 vty_out(vty, "%% Malformed prefix (link-local address)\n");
4919 return CMD_WARNING_CONFIG_FAILED;
4920 }
4921
4922 apply_mask(&p);
4923
4924 if (negate) {
4925
4926 /* Set BGP static route configuration. */
4927 rn = bgp_node_lookup(bgp->route[afi][safi], &p);
4928
4929 if (!rn) {
4930 vty_out(vty, "%% Can't find static route specified\n");
4931 return CMD_WARNING_CONFIG_FAILED;
4932 }
4933
4934 bgp_static = bgp_node_get_bgp_static_info(rn);
4935
4936 if ((label_index != BGP_INVALID_LABEL_INDEX)
4937 && (label_index != bgp_static->label_index)) {
4938 vty_out(vty,
4939 "%% label-index doesn't match static route\n");
4940 return CMD_WARNING_CONFIG_FAILED;
4941 }
4942
4943 if ((rmap && bgp_static->rmap.name)
4944 && strcmp(rmap, bgp_static->rmap.name)) {
4945 vty_out(vty,
4946 "%% route-map name doesn't match static route\n");
4947 return CMD_WARNING_CONFIG_FAILED;
4948 }
4949
4950 /* Update BGP RIB. */
4951 if (!bgp_static->backdoor)
4952 bgp_static_withdraw(bgp, &p, afi, safi);
4953
4954 /* Clear configuration. */
4955 bgp_static_free(bgp_static);
4956 bgp_node_set_bgp_static_info(rn, NULL);
4957 bgp_unlock_node(rn);
4958 bgp_unlock_node(rn);
4959 } else {
4960
4961 /* Set BGP static route configuration. */
4962 rn = bgp_node_get(bgp->route[afi][safi], &p);
4963
4964 bgp_static = bgp_node_get_bgp_static_info(rn);
4965 if (bgp_static) {
4966 /* Configuration change. */
4967 /* Label index cannot be changed. */
4968 if (bgp_static->label_index != label_index) {
4969 vty_out(vty, "%% cannot change label-index\n");
4970 return CMD_WARNING_CONFIG_FAILED;
4971 }
4972
4973 /* Check previous routes are installed into BGP. */
4974 if (bgp_static->valid
4975 && bgp_static->backdoor != backdoor)
4976 need_update = 1;
4977
4978 bgp_static->backdoor = backdoor;
4979
4980 if (rmap) {
4981 if (bgp_static->rmap.name)
4982 XFREE(MTYPE_ROUTE_MAP_NAME,
4983 bgp_static->rmap.name);
4984 bgp_static->rmap.name =
4985 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
4986 bgp_static->rmap.map =
4987 route_map_lookup_by_name(rmap);
4988 } else {
4989 if (bgp_static->rmap.name)
4990 XFREE(MTYPE_ROUTE_MAP_NAME,
4991 bgp_static->rmap.name);
4992 bgp_static->rmap.name = NULL;
4993 bgp_static->rmap.map = NULL;
4994 bgp_static->valid = 0;
4995 }
4996 bgp_unlock_node(rn);
4997 } else {
4998 /* New configuration. */
4999 bgp_static = bgp_static_new();
5000 bgp_static->backdoor = backdoor;
5001 bgp_static->valid = 0;
5002 bgp_static->igpmetric = 0;
5003 bgp_static->igpnexthop.s_addr = 0;
5004 bgp_static->label_index = label_index;
5005
5006 if (rmap) {
5007 if (bgp_static->rmap.name)
5008 XFREE(MTYPE_ROUTE_MAP_NAME,
5009 bgp_static->rmap.name);
5010 bgp_static->rmap.name =
5011 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5012 bgp_static->rmap.map =
5013 route_map_lookup_by_name(rmap);
5014 }
5015 bgp_node_set_bgp_static_info(rn, bgp_static);
5016 }
5017
5018 bgp_static->valid = 1;
5019 if (need_update)
5020 bgp_static_withdraw(bgp, &p, afi, safi);
5021
5022 if (!bgp_static->backdoor)
5023 bgp_static_update(bgp, &p, bgp_static, afi, safi);
5024 }
5025
5026 return CMD_SUCCESS;
5027 }
5028
5029 void bgp_static_add(struct bgp *bgp)
5030 {
5031 afi_t afi;
5032 safi_t safi;
5033 struct bgp_node *rn;
5034 struct bgp_node *rm;
5035 struct bgp_table *table;
5036 struct bgp_static *bgp_static;
5037
5038 FOREACH_AFI_SAFI (afi, safi)
5039 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5040 rn = bgp_route_next(rn)) {
5041 if (!bgp_node_has_bgp_path_info_data(rn))
5042 continue;
5043
5044 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5045 || (safi == SAFI_EVPN)) {
5046 table = bgp_node_get_bgp_table_info(rn);
5047
5048 for (rm = bgp_table_top(table); rm;
5049 rm = bgp_route_next(rm)) {
5050 bgp_static =
5051 bgp_node_get_bgp_static_info(
5052 rm);
5053 bgp_static_update_safi(bgp, &rm->p,
5054 bgp_static, afi,
5055 safi);
5056 }
5057 } else {
5058 bgp_static_update(
5059 bgp, &rn->p,
5060 bgp_node_get_bgp_static_info(rn), afi,
5061 safi);
5062 }
5063 }
5064 }
5065
5066 /* Called from bgp_delete(). Delete all static routes from the BGP
5067 instance. */
5068 void bgp_static_delete(struct bgp *bgp)
5069 {
5070 afi_t afi;
5071 safi_t safi;
5072 struct bgp_node *rn;
5073 struct bgp_node *rm;
5074 struct bgp_table *table;
5075 struct bgp_static *bgp_static;
5076
5077 FOREACH_AFI_SAFI (afi, safi)
5078 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5079 rn = bgp_route_next(rn)) {
5080 if (!bgp_node_has_bgp_path_info_data(rn))
5081 continue;
5082
5083 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5084 || (safi == SAFI_EVPN)) {
5085 table = bgp_node_get_bgp_table_info(rn);
5086
5087 for (rm = bgp_table_top(table); rm;
5088 rm = bgp_route_next(rm)) {
5089 bgp_static =
5090 bgp_node_get_bgp_static_info(
5091 rm);
5092 if (!bgp_static)
5093 continue;
5094
5095 bgp_static_withdraw_safi(
5096 bgp, &rm->p, AFI_IP, safi,
5097 (struct prefix_rd *)&rn->p);
5098 bgp_static_free(bgp_static);
5099 bgp_node_set_bgp_static_info(rn, NULL);
5100 bgp_unlock_node(rn);
5101 }
5102 } else {
5103 bgp_static = bgp_node_get_bgp_static_info(rn);
5104 bgp_static_withdraw(bgp, &rn->p, afi, safi);
5105 bgp_static_free(bgp_static);
5106 bgp_node_set_bgp_static_info(rn, NULL);
5107 bgp_unlock_node(rn);
5108 }
5109 }
5110 }
5111
5112 void bgp_static_redo_import_check(struct bgp *bgp)
5113 {
5114 afi_t afi;
5115 safi_t safi;
5116 struct bgp_node *rn;
5117 struct bgp_node *rm;
5118 struct bgp_table *table;
5119 struct bgp_static *bgp_static;
5120
5121 /* Use this flag to force reprocessing of the route */
5122 bgp_flag_set(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
5123 FOREACH_AFI_SAFI (afi, safi) {
5124 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5125 rn = bgp_route_next(rn)) {
5126 if (!bgp_node_has_bgp_path_info_data(rn))
5127 continue;
5128
5129 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5130 || (safi == SAFI_EVPN)) {
5131 table = bgp_node_get_bgp_table_info(rn);
5132
5133 for (rm = bgp_table_top(table); rm;
5134 rm = bgp_route_next(rm)) {
5135 bgp_static =
5136 bgp_node_get_bgp_static_info(
5137 rm);
5138 bgp_static_update_safi(bgp, &rm->p,
5139 bgp_static, afi,
5140 safi);
5141 }
5142 } else {
5143 bgp_static = bgp_node_get_bgp_static_info(rn);
5144 bgp_static_update(bgp, &rn->p, bgp_static, afi,
5145 safi);
5146 }
5147 }
5148 }
5149 bgp_flag_unset(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
5150 }
5151
5152 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
5153 safi_t safi)
5154 {
5155 struct bgp_table *table;
5156 struct bgp_node *rn;
5157 struct bgp_path_info *pi;
5158
5159 table = bgp->rib[afi][safi];
5160 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
5161 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
5162 if (pi->peer == bgp->peer_self
5163 && ((pi->type == ZEBRA_ROUTE_BGP
5164 && pi->sub_type == BGP_ROUTE_STATIC)
5165 || (pi->type != ZEBRA_ROUTE_BGP
5166 && pi->sub_type
5167 == BGP_ROUTE_REDISTRIBUTE))) {
5168 bgp_aggregate_decrement(bgp, &rn->p, pi, afi,
5169 safi);
5170 bgp_unlink_nexthop(pi);
5171 bgp_path_info_delete(rn, pi);
5172 bgp_process(bgp, rn, afi, safi);
5173 }
5174 }
5175 }
5176 }
5177
5178 /*
5179 * Purge all networks and redistributed routes from routing table.
5180 * Invoked upon the instance going down.
5181 */
5182 void bgp_purge_static_redist_routes(struct bgp *bgp)
5183 {
5184 afi_t afi;
5185 safi_t safi;
5186
5187 FOREACH_AFI_SAFI (afi, safi)
5188 bgp_purge_af_static_redist_routes(bgp, afi, safi);
5189 }
5190
5191 /*
5192 * gpz 110624
5193 * Currently this is used to set static routes for VPN and ENCAP.
5194 * I think it can probably be factored with bgp_static_set.
5195 */
5196 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
5197 const char *ip_str, const char *rd_str,
5198 const char *label_str, const char *rmap_str,
5199 int evpn_type, const char *esi, const char *gwip,
5200 const char *ethtag, const char *routermac)
5201 {
5202 VTY_DECLVAR_CONTEXT(bgp, bgp);
5203 int ret;
5204 struct prefix p;
5205 struct prefix_rd prd;
5206 struct bgp_node *prn;
5207 struct bgp_node *rn;
5208 struct bgp_table *table;
5209 struct bgp_static *bgp_static;
5210 mpls_label_t label = MPLS_INVALID_LABEL;
5211 struct prefix gw_ip;
5212
5213 /* validate ip prefix */
5214 ret = str2prefix(ip_str, &p);
5215 if (!ret) {
5216 vty_out(vty, "%% Malformed prefix\n");
5217 return CMD_WARNING_CONFIG_FAILED;
5218 }
5219 apply_mask(&p);
5220 if ((afi == AFI_L2VPN)
5221 && (bgp_build_evpn_prefix(evpn_type,
5222 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5223 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5224 return CMD_WARNING_CONFIG_FAILED;
5225 }
5226
5227 ret = str2prefix_rd(rd_str, &prd);
5228 if (!ret) {
5229 vty_out(vty, "%% Malformed rd\n");
5230 return CMD_WARNING_CONFIG_FAILED;
5231 }
5232
5233 if (label_str) {
5234 unsigned long label_val;
5235 label_val = strtoul(label_str, NULL, 10);
5236 encode_label(label_val, &label);
5237 }
5238
5239 if (safi == SAFI_EVPN) {
5240 if (esi && str2esi(esi, NULL) == 0) {
5241 vty_out(vty, "%% Malformed ESI\n");
5242 return CMD_WARNING_CONFIG_FAILED;
5243 }
5244 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
5245 vty_out(vty, "%% Malformed Router MAC\n");
5246 return CMD_WARNING_CONFIG_FAILED;
5247 }
5248 if (gwip) {
5249 memset(&gw_ip, 0, sizeof(struct prefix));
5250 ret = str2prefix(gwip, &gw_ip);
5251 if (!ret) {
5252 vty_out(vty, "%% Malformed GatewayIp\n");
5253 return CMD_WARNING_CONFIG_FAILED;
5254 }
5255 if ((gw_ip.family == AF_INET
5256 && is_evpn_prefix_ipaddr_v6(
5257 (struct prefix_evpn *)&p))
5258 || (gw_ip.family == AF_INET6
5259 && is_evpn_prefix_ipaddr_v4(
5260 (struct prefix_evpn *)&p))) {
5261 vty_out(vty,
5262 "%% GatewayIp family differs with IP prefix\n");
5263 return CMD_WARNING_CONFIG_FAILED;
5264 }
5265 }
5266 }
5267 prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5268 if (!bgp_node_has_bgp_path_info_data(prn))
5269 bgp_node_set_bgp_table_info(prn,
5270 bgp_table_init(bgp, afi, safi));
5271 table = bgp_node_get_bgp_table_info(prn);
5272
5273 rn = bgp_node_get(table, &p);
5274
5275 if (bgp_node_has_bgp_path_info_data(rn)) {
5276 vty_out(vty, "%% Same network configuration exists\n");
5277 bgp_unlock_node(rn);
5278 } else {
5279 /* New configuration. */
5280 bgp_static = bgp_static_new();
5281 bgp_static->backdoor = 0;
5282 bgp_static->valid = 0;
5283 bgp_static->igpmetric = 0;
5284 bgp_static->igpnexthop.s_addr = 0;
5285 bgp_static->label = label;
5286 bgp_static->prd = prd;
5287
5288 if (rmap_str) {
5289 if (bgp_static->rmap.name)
5290 XFREE(MTYPE_ROUTE_MAP_NAME,
5291 bgp_static->rmap.name);
5292 bgp_static->rmap.name =
5293 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
5294 bgp_static->rmap.map =
5295 route_map_lookup_by_name(rmap_str);
5296 }
5297
5298 if (safi == SAFI_EVPN) {
5299 if (esi) {
5300 bgp_static->eth_s_id =
5301 XCALLOC(MTYPE_ATTR,
5302 sizeof(struct eth_segment_id));
5303 str2esi(esi, bgp_static->eth_s_id);
5304 }
5305 if (routermac) {
5306 bgp_static->router_mac =
5307 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
5308 (void)prefix_str2mac(routermac,
5309 bgp_static->router_mac);
5310 }
5311 if (gwip)
5312 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
5313 }
5314 bgp_node_set_bgp_static_info(rn, bgp_static);
5315
5316 bgp_static->valid = 1;
5317 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
5318 }
5319
5320 return CMD_SUCCESS;
5321 }
5322
5323 /* Configure static BGP network. */
5324 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
5325 const char *ip_str, const char *rd_str,
5326 const char *label_str, int evpn_type, const char *esi,
5327 const char *gwip, const char *ethtag)
5328 {
5329 VTY_DECLVAR_CONTEXT(bgp, bgp);
5330 int ret;
5331 struct prefix p;
5332 struct prefix_rd prd;
5333 struct bgp_node *prn;
5334 struct bgp_node *rn;
5335 struct bgp_table *table;
5336 struct bgp_static *bgp_static;
5337 mpls_label_t label = MPLS_INVALID_LABEL;
5338
5339 /* Convert IP prefix string to struct prefix. */
5340 ret = str2prefix(ip_str, &p);
5341 if (!ret) {
5342 vty_out(vty, "%% Malformed prefix\n");
5343 return CMD_WARNING_CONFIG_FAILED;
5344 }
5345 apply_mask(&p);
5346 if ((afi == AFI_L2VPN)
5347 && (bgp_build_evpn_prefix(evpn_type,
5348 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5349 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5350 return CMD_WARNING_CONFIG_FAILED;
5351 }
5352 ret = str2prefix_rd(rd_str, &prd);
5353 if (!ret) {
5354 vty_out(vty, "%% Malformed rd\n");
5355 return CMD_WARNING_CONFIG_FAILED;
5356 }
5357
5358 if (label_str) {
5359 unsigned long label_val;
5360 label_val = strtoul(label_str, NULL, 10);
5361 encode_label(label_val, &label);
5362 }
5363
5364 prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5365 if (!bgp_node_has_bgp_path_info_data(prn))
5366 bgp_node_set_bgp_table_info(prn,
5367 bgp_table_init(bgp, afi, safi));
5368 else
5369 bgp_unlock_node(prn);
5370 table = bgp_node_get_bgp_table_info(prn);
5371
5372 rn = bgp_node_lookup(table, &p);
5373
5374 if (rn) {
5375 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
5376
5377 bgp_static = bgp_node_get_bgp_static_info(rn);
5378 bgp_static_free(bgp_static);
5379 bgp_node_set_bgp_static_info(rn, NULL);
5380 bgp_unlock_node(rn);
5381 bgp_unlock_node(rn);
5382 } else
5383 vty_out(vty, "%% Can't find the route\n");
5384
5385 return CMD_SUCCESS;
5386 }
5387
5388 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
5389 const char *rmap_name)
5390 {
5391 VTY_DECLVAR_CONTEXT(bgp, bgp);
5392 struct bgp_rmap *rmap;
5393
5394 rmap = &bgp->table_map[afi][safi];
5395 if (rmap_name) {
5396 if (rmap->name)
5397 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5398 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
5399 rmap->map = route_map_lookup_by_name(rmap_name);
5400 } else {
5401 if (rmap->name)
5402 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5403 rmap->name = NULL;
5404 rmap->map = NULL;
5405 }
5406
5407 if (bgp_fibupd_safi(safi))
5408 bgp_zebra_announce_table(bgp, afi, safi);
5409
5410 return CMD_SUCCESS;
5411 }
5412
5413 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
5414 const char *rmap_name)
5415 {
5416 VTY_DECLVAR_CONTEXT(bgp, bgp);
5417 struct bgp_rmap *rmap;
5418
5419 rmap = &bgp->table_map[afi][safi];
5420 if (rmap->name)
5421 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5422 rmap->name = NULL;
5423 rmap->map = NULL;
5424
5425 if (bgp_fibupd_safi(safi))
5426 bgp_zebra_announce_table(bgp, afi, safi);
5427
5428 return CMD_SUCCESS;
5429 }
5430
5431 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
5432 safi_t safi)
5433 {
5434 if (bgp->table_map[afi][safi].name) {
5435 vty_out(vty, " table-map %s\n",
5436 bgp->table_map[afi][safi].name);
5437 }
5438 }
5439
5440 DEFUN (bgp_table_map,
5441 bgp_table_map_cmd,
5442 "table-map WORD",
5443 "BGP table to RIB route download filter\n"
5444 "Name of the route map\n")
5445 {
5446 int idx_word = 1;
5447 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
5448 argv[idx_word]->arg);
5449 }
5450 DEFUN (no_bgp_table_map,
5451 no_bgp_table_map_cmd,
5452 "no table-map WORD",
5453 NO_STR
5454 "BGP table to RIB route download filter\n"
5455 "Name of the route map\n")
5456 {
5457 int idx_word = 2;
5458 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
5459 argv[idx_word]->arg);
5460 }
5461
5462 DEFPY(bgp_network,
5463 bgp_network_cmd,
5464 "[no] network \
5465 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
5466 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
5467 backdoor$backdoor}]",
5468 NO_STR
5469 "Specify a network to announce via BGP\n"
5470 "IPv4 prefix\n"
5471 "Network number\n"
5472 "Network mask\n"
5473 "Network mask\n"
5474 "Route-map to modify the attributes\n"
5475 "Name of the route map\n"
5476 "Label index to associate with the prefix\n"
5477 "Label index value\n"
5478 "Specify a BGP backdoor route\n")
5479 {
5480 char addr_prefix_str[BUFSIZ];
5481
5482 if (address_str) {
5483 int ret;
5484
5485 ret = netmask_str2prefix_str(address_str, netmask_str,
5486 addr_prefix_str);
5487 if (!ret) {
5488 vty_out(vty, "%% Inconsistent address and mask\n");
5489 return CMD_WARNING_CONFIG_FAILED;
5490 }
5491 }
5492
5493 return bgp_static_set(
5494 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
5495 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
5496 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
5497 }
5498
5499 DEFPY(ipv6_bgp_network,
5500 ipv6_bgp_network_cmd,
5501 "[no] network X:X::X:X/M$prefix \
5502 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
5503 NO_STR
5504 "Specify a network to announce via BGP\n"
5505 "IPv6 prefix\n"
5506 "Route-map to modify the attributes\n"
5507 "Name of the route map\n"
5508 "Label index to associate with the prefix\n"
5509 "Label index value\n")
5510 {
5511 return bgp_static_set(
5512 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
5513 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
5514 }
5515
5516 static struct bgp_aggregate *bgp_aggregate_new(void)
5517 {
5518 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
5519 }
5520
5521 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
5522 {
5523 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
5524 }
5525
5526 static int bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
5527 struct aspath *aspath,
5528 struct community *comm,
5529 struct ecommunity *ecomm,
5530 struct lcommunity *lcomm)
5531 {
5532 static struct aspath *ae = NULL;
5533
5534 if (!ae)
5535 ae = aspath_empty();
5536
5537 if (!pi)
5538 return 0;
5539
5540 if (origin != pi->attr->origin)
5541 return 0;
5542
5543 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
5544 return 0;
5545
5546 if (!community_cmp(pi->attr->community, comm))
5547 return 0;
5548
5549 if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
5550 return 0;
5551
5552 if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
5553 return 0;
5554
5555 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
5556 return 0;
5557
5558 return 1;
5559 }
5560
5561 static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
5562 struct prefix *p, uint8_t origin,
5563 struct aspath *aspath,
5564 struct community *community,
5565 struct ecommunity *ecommunity,
5566 struct lcommunity *lcommunity,
5567 uint8_t atomic_aggregate,
5568 struct bgp_aggregate *aggregate)
5569 {
5570 struct bgp_node *rn;
5571 struct bgp_table *table;
5572 struct bgp_path_info *pi, *orig, *new;
5573
5574 table = bgp->rib[afi][safi];
5575
5576 rn = bgp_node_get(table, p);
5577
5578 for (orig = pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
5579 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5580 && pi->sub_type == BGP_ROUTE_AGGREGATE)
5581 break;
5582
5583 if (aggregate->count > 0) {
5584 /*
5585 * If the aggregate information has not changed
5586 * no need to re-install it again.
5587 */
5588 if (bgp_aggregate_info_same(orig, origin, aspath, community,
5589 ecommunity, lcommunity)) {
5590 bgp_unlock_node(rn);
5591
5592 if (aspath)
5593 aspath_free(aspath);
5594 if (community)
5595 community_free(&community);
5596 if (ecommunity)
5597 ecommunity_free(&ecommunity);
5598 if (lcommunity)
5599 lcommunity_free(&lcommunity);
5600
5601 return;
5602 }
5603
5604 /*
5605 * Mark the old as unusable
5606 */
5607 if (pi)
5608 bgp_path_info_delete(rn, pi);
5609
5610 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
5611 bgp->peer_self,
5612 bgp_attr_aggregate_intern(bgp, origin, aspath,
5613 community, ecommunity,
5614 lcommunity,
5615 aggregate->as_set,
5616 atomic_aggregate),
5617 rn);
5618 SET_FLAG(new->flags, BGP_PATH_VALID);
5619
5620 bgp_path_info_add(rn, new);
5621 bgp_process(bgp, rn, afi, safi);
5622 } else {
5623 for (pi = orig; pi; pi = pi->next)
5624 if (pi->peer == bgp->peer_self
5625 && pi->type == ZEBRA_ROUTE_BGP
5626 && pi->sub_type == BGP_ROUTE_AGGREGATE)
5627 break;
5628
5629 /* Withdraw static BGP route from routing table. */
5630 if (pi) {
5631 bgp_path_info_delete(rn, pi);
5632 bgp_process(bgp, rn, afi, safi);
5633 }
5634 }
5635
5636 bgp_unlock_node(rn);
5637 }
5638
5639 /* Update an aggregate as routes are added/removed from the BGP table */
5640 static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
5641 afi_t afi, safi_t safi,
5642 struct bgp_aggregate *aggregate)
5643 {
5644 struct bgp_table *table;
5645 struct bgp_node *top;
5646 struct bgp_node *rn;
5647 uint8_t origin;
5648 struct aspath *aspath = NULL;
5649 struct community *community = NULL;
5650 struct ecommunity *ecommunity = NULL;
5651 struct lcommunity *lcommunity = NULL;
5652 struct bgp_path_info *pi;
5653 unsigned long match = 0;
5654 uint8_t atomic_aggregate = 0;
5655
5656 /* ORIGIN attribute: If at least one route among routes that are
5657 aggregated has ORIGIN with the value INCOMPLETE, then the
5658 aggregated route must have the ORIGIN attribute with the value
5659 INCOMPLETE. Otherwise, if at least one route among routes that
5660 are aggregated has ORIGIN with the value EGP, then the aggregated
5661 route must have the origin attribute with the value EGP. In all
5662 other case the value of the ORIGIN attribute of the aggregated
5663 route is INTERNAL. */
5664 origin = BGP_ORIGIN_IGP;
5665
5666 table = bgp->rib[afi][safi];
5667
5668 top = bgp_node_get(table, p);
5669 for (rn = bgp_node_get(table, p); rn;
5670 rn = bgp_route_next_until(rn, top)) {
5671 if (rn->p.prefixlen <= p->prefixlen)
5672 continue;
5673
5674 match = 0;
5675
5676 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
5677 if (BGP_PATH_HOLDDOWN(pi))
5678 continue;
5679
5680 if (pi->attr->flag
5681 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
5682 atomic_aggregate = 1;
5683
5684 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
5685 continue;
5686
5687 /*
5688 * summary-only aggregate route suppress
5689 * aggregated route announcements.
5690 */
5691 if (aggregate->summary_only) {
5692 (bgp_path_info_extra_get(pi))->suppress++;
5693 bgp_path_info_set_flag(rn, pi,
5694 BGP_PATH_ATTR_CHANGED);
5695 match++;
5696 }
5697
5698 aggregate->count++;
5699
5700 /*
5701 * If at least one route among routes that are
5702 * aggregated has ORIGIN with the value INCOMPLETE,
5703 * then the aggregated route MUST have the ORIGIN
5704 * attribute with the value INCOMPLETE. Otherwise, if
5705 * at least one route among routes that are aggregated
5706 * has ORIGIN with the value EGP, then the aggregated
5707 * route MUST have the ORIGIN attribute with the value
5708 * EGP.
5709 */
5710 switch (pi->attr->origin) {
5711 case BGP_ORIGIN_INCOMPLETE:
5712 aggregate->incomplete_origin_count++;
5713 break;
5714 case BGP_ORIGIN_EGP:
5715 aggregate->egp_origin_count++;
5716 break;
5717 default:
5718 /*Do nothing.
5719 */
5720 break;
5721 }
5722
5723 if (!aggregate->as_set)
5724 continue;
5725
5726 /*
5727 * as-set aggregate route generate origin, as path,
5728 * and community aggregation.
5729 */
5730 /* Compute aggregate route's as-path.
5731 */
5732 bgp_compute_aggregate_aspath(aggregate,
5733 pi->attr->aspath);
5734
5735 /* Compute aggregate route's community.
5736 */
5737 if (pi->attr->community)
5738 bgp_compute_aggregate_community(
5739 aggregate,
5740 pi->attr->community);
5741
5742 /* Compute aggregate route's extended community.
5743 */
5744 if (pi->attr->ecommunity)
5745 bgp_compute_aggregate_ecommunity(
5746 aggregate,
5747 pi->attr->ecommunity);
5748
5749 /* Compute aggregate route's large community.
5750 */
5751 if (pi->attr->lcommunity)
5752 bgp_compute_aggregate_lcommunity(
5753 aggregate,
5754 pi->attr->lcommunity);
5755 }
5756 if (match)
5757 bgp_process(bgp, rn, afi, safi);
5758 }
5759 bgp_unlock_node(top);
5760
5761
5762 if (aggregate->incomplete_origin_count > 0)
5763 origin = BGP_ORIGIN_INCOMPLETE;
5764 else if (aggregate->egp_origin_count > 0)
5765 origin = BGP_ORIGIN_EGP;
5766
5767 if (aggregate->as_set) {
5768 if (aggregate->aspath)
5769 /* Retrieve aggregate route's as-path.
5770 */
5771 aspath = aspath_dup(aggregate->aspath);
5772
5773 if (aggregate->community)
5774 /* Retrieve aggregate route's community.
5775 */
5776 community = community_dup(aggregate->community);
5777
5778 if (aggregate->ecommunity)
5779 /* Retrieve aggregate route's ecommunity.
5780 */
5781 ecommunity = ecommunity_dup(aggregate->ecommunity);
5782
5783 if (aggregate->lcommunity)
5784 /* Retrieve aggregate route's lcommunity.
5785 */
5786 lcommunity = lcommunity_dup(aggregate->lcommunity);
5787 }
5788
5789 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
5790 ecommunity, lcommunity, atomic_aggregate,
5791 aggregate);
5792 }
5793
5794 static void bgp_aggregate_delete(struct bgp *bgp, struct prefix *p, afi_t afi,
5795 safi_t safi, struct bgp_aggregate *aggregate)
5796 {
5797 struct bgp_table *table;
5798 struct bgp_node *top;
5799 struct bgp_node *rn;
5800 struct bgp_path_info *pi;
5801 unsigned long match;
5802
5803 table = bgp->rib[afi][safi];
5804
5805 /* If routes exists below this node, generate aggregate routes. */
5806 top = bgp_node_get(table, p);
5807 for (rn = bgp_node_get(table, p); rn;
5808 rn = bgp_route_next_until(rn, top)) {
5809 if (rn->p.prefixlen <= p->prefixlen)
5810 continue;
5811 match = 0;
5812
5813 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
5814 if (BGP_PATH_HOLDDOWN(pi))
5815 continue;
5816
5817 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
5818 continue;
5819
5820 if (aggregate->summary_only && pi->extra) {
5821 pi->extra->suppress--;
5822
5823 if (pi->extra->suppress == 0) {
5824 bgp_path_info_set_flag(
5825 rn, pi, BGP_PATH_ATTR_CHANGED);
5826 match++;
5827 }
5828 }
5829 aggregate->count--;
5830
5831 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
5832 aggregate->incomplete_origin_count--;
5833 else if (pi->attr->origin == BGP_ORIGIN_EGP)
5834 aggregate->egp_origin_count--;
5835
5836 if (aggregate->as_set) {
5837 /* Remove as-path from aggregate.
5838 */
5839 bgp_remove_aspath_from_aggregate(
5840 aggregate,
5841 pi->attr->aspath);
5842
5843 if (pi->attr->community)
5844 /* Remove community from aggregate.
5845 */
5846 bgp_remove_community_from_aggregate(
5847 aggregate,
5848 pi->attr->community);
5849
5850 if (pi->attr->ecommunity)
5851 /* Remove ecommunity from aggregate.
5852 */
5853 bgp_remove_ecommunity_from_aggregate(
5854 aggregate,
5855 pi->attr->ecommunity);
5856
5857 if (pi->attr->lcommunity)
5858 /* Remove lcommunity from aggregate.
5859 */
5860 bgp_remove_lcommunity_from_aggregate(
5861 aggregate,
5862 pi->attr->lcommunity);
5863 }
5864
5865 }
5866
5867 /* If this node was suppressed, process the change. */
5868 if (match)
5869 bgp_process(bgp, rn, afi, safi);
5870 }
5871 bgp_unlock_node(top);
5872 }
5873
5874 static void bgp_add_route_to_aggregate(struct bgp *bgp, struct prefix *aggr_p,
5875 struct bgp_path_info *pinew, afi_t afi,
5876 safi_t safi,
5877 struct bgp_aggregate *aggregate)
5878 {
5879 uint8_t origin;
5880 struct aspath *aspath = NULL;
5881 uint8_t atomic_aggregate = 0;
5882 struct community *community = NULL;
5883 struct ecommunity *ecommunity = NULL;
5884 struct lcommunity *lcommunity = NULL;
5885
5886 /* ORIGIN attribute: If at least one route among routes that are
5887 * aggregated has ORIGIN with the value INCOMPLETE, then the
5888 * aggregated route must have the ORIGIN attribute with the value
5889 * INCOMPLETE. Otherwise, if at least one route among routes that
5890 * are aggregated has ORIGIN with the value EGP, then the aggregated
5891 * route must have the origin attribute with the value EGP. In all
5892 * other case the value of the ORIGIN attribute of the aggregated
5893 * route is INTERNAL.
5894 */
5895 origin = BGP_ORIGIN_IGP;
5896
5897 aggregate->count++;
5898
5899 if (aggregate->summary_only)
5900 (bgp_path_info_extra_get(pinew))->suppress++;
5901
5902 switch (pinew->attr->origin) {
5903 case BGP_ORIGIN_INCOMPLETE:
5904 aggregate->incomplete_origin_count++;
5905 break;
5906 case BGP_ORIGIN_EGP:
5907 aggregate->egp_origin_count++;
5908 break;
5909 default:
5910 /* Do nothing.
5911 */
5912 break;
5913 }
5914
5915 if (aggregate->incomplete_origin_count > 0)
5916 origin = BGP_ORIGIN_INCOMPLETE;
5917 else if (aggregate->egp_origin_count > 0)
5918 origin = BGP_ORIGIN_EGP;
5919
5920 if (aggregate->as_set) {
5921 /* Compute aggregate route's as-path.
5922 */
5923 bgp_compute_aggregate_aspath(aggregate,
5924 pinew->attr->aspath);
5925
5926 /* Compute aggregate route's community.
5927 */
5928 if (pinew->attr->community)
5929 bgp_compute_aggregate_community(
5930 aggregate,
5931 pinew->attr->community);
5932
5933 /* Compute aggregate route's extended community.
5934 */
5935 if (pinew->attr->ecommunity)
5936 bgp_compute_aggregate_ecommunity(
5937 aggregate,
5938 pinew->attr->ecommunity);
5939
5940 /* Compute aggregate route's large community.
5941 */
5942 if (pinew->attr->lcommunity)
5943 bgp_compute_aggregate_lcommunity(
5944 aggregate,
5945 pinew->attr->lcommunity);
5946
5947 /* Retrieve aggregate route's as-path.
5948 */
5949 if (aggregate->aspath)
5950 aspath = aspath_dup(aggregate->aspath);
5951
5952 /* Retrieve aggregate route's community.
5953 */
5954 if (aggregate->community)
5955 community = community_dup(aggregate->community);
5956
5957 /* Retrieve aggregate route's ecommunity.
5958 */
5959 if (aggregate->ecommunity)
5960 ecommunity = ecommunity_dup(aggregate->ecommunity);
5961
5962 /* Retrieve aggregate route's lcommunity.
5963 */
5964 if (aggregate->lcommunity)
5965 lcommunity = lcommunity_dup(aggregate->lcommunity);
5966 }
5967
5968 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
5969 aspath, community, ecommunity,
5970 lcommunity, atomic_aggregate, aggregate);
5971 }
5972
5973 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
5974 safi_t safi,
5975 struct bgp_path_info *pi,
5976 struct bgp_aggregate *aggregate,
5977 struct prefix *aggr_p)
5978 {
5979 uint8_t origin;
5980 struct aspath *aspath = NULL;
5981 uint8_t atomic_aggregate = 0;
5982 struct community *community = NULL;
5983 struct ecommunity *ecommunity = NULL;
5984 struct lcommunity *lcommunity = NULL;
5985 unsigned long match = 0;
5986
5987 if (BGP_PATH_HOLDDOWN(pi))
5988 return;
5989
5990 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
5991 return;
5992
5993 if (aggregate->summary_only
5994 && pi->extra
5995 && pi->extra->suppress > 0) {
5996 pi->extra->suppress--;
5997
5998 if (pi->extra->suppress == 0) {
5999 bgp_path_info_set_flag(pi->net, pi,
6000 BGP_PATH_ATTR_CHANGED);
6001 match++;
6002 }
6003 }
6004
6005 if (aggregate->count > 0)
6006 aggregate->count--;
6007
6008 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
6009 aggregate->incomplete_origin_count--;
6010 else if (pi->attr->origin == BGP_ORIGIN_EGP)
6011 aggregate->egp_origin_count--;
6012
6013 if (aggregate->as_set) {
6014 /* Remove as-path from aggregate.
6015 */
6016 bgp_remove_aspath_from_aggregate(aggregate,
6017 pi->attr->aspath);
6018
6019 if (pi->attr->community)
6020 /* Remove community from aggregate.
6021 */
6022 bgp_remove_community_from_aggregate(
6023 aggregate,
6024 pi->attr->community);
6025
6026 if (pi->attr->ecommunity)
6027 /* Remove ecommunity from aggregate.
6028 */
6029 bgp_remove_ecommunity_from_aggregate(
6030 aggregate,
6031 pi->attr->ecommunity);
6032
6033 if (pi->attr->lcommunity)
6034 /* Remove lcommunity from aggregate.
6035 */
6036 bgp_remove_lcommunity_from_aggregate(
6037 aggregate,
6038 pi->attr->lcommunity);
6039 }
6040
6041 /* If this node was suppressed, process the change. */
6042 if (match)
6043 bgp_process(bgp, pi->net, afi, safi);
6044
6045 origin = BGP_ORIGIN_IGP;
6046 if (aggregate->incomplete_origin_count > 0)
6047 origin = BGP_ORIGIN_INCOMPLETE;
6048 else if (aggregate->egp_origin_count > 0)
6049 origin = BGP_ORIGIN_EGP;
6050
6051 if (aggregate->as_set) {
6052 /* Retrieve aggregate route's as-path.
6053 */
6054 if (aggregate->aspath)
6055 aspath = aspath_dup(aggregate->aspath);
6056
6057 /* Retrieve aggregate route's community.
6058 */
6059 if (aggregate->community)
6060 community = community_dup(aggregate->community);
6061
6062 /* Retrieve aggregate route's ecommunity.
6063 */
6064 if (aggregate->ecommunity)
6065 ecommunity = ecommunity_dup(aggregate->ecommunity);
6066
6067 /* Retrieve aggregate route's lcommunity.
6068 */
6069 if (aggregate->lcommunity)
6070 lcommunity = lcommunity_dup(aggregate->lcommunity);
6071 }
6072
6073 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
6074 aspath, community, ecommunity,
6075 lcommunity, atomic_aggregate, aggregate);
6076 }
6077
6078 void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p,
6079 struct bgp_path_info *pi, afi_t afi, safi_t safi)
6080 {
6081 struct bgp_node *child;
6082 struct bgp_node *rn;
6083 struct bgp_aggregate *aggregate;
6084 struct bgp_table *table;
6085
6086 table = bgp->aggregate[afi][safi];
6087
6088 /* No aggregates configured. */
6089 if (bgp_table_top_nolock(table) == NULL)
6090 return;
6091
6092 if (p->prefixlen == 0)
6093 return;
6094
6095 if (BGP_PATH_HOLDDOWN(pi))
6096 return;
6097
6098 child = bgp_node_get(table, p);
6099
6100 /* Aggregate address configuration check. */
6101 for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
6102 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6103 if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
6104 bgp_add_route_to_aggregate(bgp, &rn->p, pi, afi,
6105 safi, aggregate);
6106 }
6107 }
6108 bgp_unlock_node(child);
6109 }
6110
6111 void bgp_aggregate_decrement(struct bgp *bgp, struct prefix *p,
6112 struct bgp_path_info *del, afi_t afi, safi_t safi)
6113 {
6114 struct bgp_node *child;
6115 struct bgp_node *rn;
6116 struct bgp_aggregate *aggregate;
6117 struct bgp_table *table;
6118
6119 table = bgp->aggregate[afi][safi];
6120
6121 /* No aggregates configured. */
6122 if (bgp_table_top_nolock(table) == NULL)
6123 return;
6124
6125 if (p->prefixlen == 0)
6126 return;
6127
6128 child = bgp_node_get(table, p);
6129
6130 /* Aggregate address configuration check. */
6131 for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
6132 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6133 if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
6134 bgp_remove_route_from_aggregate(bgp, afi, safi,
6135 del, aggregate, &rn->p);
6136 }
6137 }
6138 bgp_unlock_node(child);
6139 }
6140
6141 /* Aggregate route attribute. */
6142 #define AGGREGATE_SUMMARY_ONLY 1
6143 #define AGGREGATE_AS_SET 1
6144
6145 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
6146 afi_t afi, safi_t safi)
6147 {
6148 VTY_DECLVAR_CONTEXT(bgp, bgp);
6149 int ret;
6150 struct prefix p;
6151 struct bgp_node *rn;
6152 struct bgp_aggregate *aggregate;
6153
6154 /* Convert string to prefix structure. */
6155 ret = str2prefix(prefix_str, &p);
6156 if (!ret) {
6157 vty_out(vty, "Malformed prefix\n");
6158 return CMD_WARNING_CONFIG_FAILED;
6159 }
6160 apply_mask(&p);
6161
6162 /* Old configuration check. */
6163 rn = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
6164 if (!rn) {
6165 vty_out(vty,
6166 "%% There is no aggregate-address configuration.\n");
6167 return CMD_WARNING_CONFIG_FAILED;
6168 }
6169
6170 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6171 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
6172 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
6173 NULL, NULL, 0, aggregate);
6174
6175 /* Unlock aggregate address configuration. */
6176 bgp_node_set_bgp_aggregate_info(rn, NULL);
6177
6178 if (aggregate->community)
6179 community_free(&aggregate->community);
6180
6181 if (aggregate->community_hash) {
6182 /* Delete all communities in the hash.
6183 */
6184 hash_clean(aggregate->community_hash,
6185 bgp_aggr_community_remove);
6186 /* Free up the community_hash.
6187 */
6188 hash_free(aggregate->community_hash);
6189 }
6190
6191 if (aggregate->ecommunity)
6192 ecommunity_free(&aggregate->ecommunity);
6193
6194 if (aggregate->ecommunity_hash) {
6195 /* Delete all ecommunities in the hash.
6196 */
6197 hash_clean(aggregate->ecommunity_hash,
6198 bgp_aggr_ecommunity_remove);
6199 /* Free up the ecommunity_hash.
6200 */
6201 hash_free(aggregate->ecommunity_hash);
6202 }
6203
6204 if (aggregate->lcommunity)
6205 lcommunity_free(&aggregate->lcommunity);
6206
6207 if (aggregate->lcommunity_hash) {
6208 /* Delete all lcommunities in the hash.
6209 */
6210 hash_clean(aggregate->lcommunity_hash,
6211 bgp_aggr_lcommunity_remove);
6212 /* Free up the lcommunity_hash.
6213 */
6214 hash_free(aggregate->lcommunity_hash);
6215 }
6216
6217 if (aggregate->aspath)
6218 aspath_free(aggregate->aspath);
6219
6220 if (aggregate->aspath_hash) {
6221 /* Delete all as-paths in the hash.
6222 */
6223 hash_clean(aggregate->aspath_hash,
6224 bgp_aggr_aspath_remove);
6225 /* Free up the aspath_hash.
6226 */
6227 hash_free(aggregate->aspath_hash);
6228 }
6229
6230 bgp_aggregate_free(aggregate);
6231 bgp_unlock_node(rn);
6232 bgp_unlock_node(rn);
6233
6234 return CMD_SUCCESS;
6235 }
6236
6237 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
6238 safi_t safi, uint8_t summary_only, uint8_t as_set)
6239 {
6240 VTY_DECLVAR_CONTEXT(bgp, bgp);
6241 int ret;
6242 struct prefix p;
6243 struct bgp_node *rn;
6244 struct bgp_aggregate *aggregate;
6245
6246 /* Convert string to prefix structure. */
6247 ret = str2prefix(prefix_str, &p);
6248 if (!ret) {
6249 vty_out(vty, "Malformed prefix\n");
6250 return CMD_WARNING_CONFIG_FAILED;
6251 }
6252 apply_mask(&p);
6253
6254 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
6255 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
6256 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
6257 prefix_str);
6258 return CMD_WARNING_CONFIG_FAILED;
6259 }
6260
6261 /* Old configuration check. */
6262 rn = bgp_node_get(bgp->aggregate[afi][safi], &p);
6263
6264 if (bgp_node_has_bgp_path_info_data(rn)) {
6265 vty_out(vty, "There is already same aggregate network.\n");
6266 /* try to remove the old entry */
6267 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
6268 if (ret) {
6269 vty_out(vty, "Error deleting aggregate.\n");
6270 bgp_unlock_node(rn);
6271 return CMD_WARNING_CONFIG_FAILED;
6272 }
6273 }
6274
6275 /* Make aggregate address structure. */
6276 aggregate = bgp_aggregate_new();
6277 aggregate->summary_only = summary_only;
6278 aggregate->as_set = as_set;
6279 aggregate->safi = safi;
6280 bgp_node_set_bgp_aggregate_info(rn, aggregate);
6281
6282 /* Aggregate address insert into BGP routing table. */
6283 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
6284
6285 return CMD_SUCCESS;
6286 }
6287
6288 DEFUN (aggregate_address,
6289 aggregate_address_cmd,
6290 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
6291 "Configure BGP aggregate entries\n"
6292 "Aggregate prefix\n"
6293 "Generate AS set path information\n"
6294 "Filter more specific routes from updates\n"
6295 "Filter more specific routes from updates\n"
6296 "Generate AS set path information\n")
6297 {
6298 int idx = 0;
6299 argv_find(argv, argc, "A.B.C.D/M", &idx);
6300 char *prefix = argv[idx]->arg;
6301 int as_set =
6302 argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
6303 idx = 0;
6304 int summary_only = argv_find(argv, argc, "summary-only", &idx)
6305 ? AGGREGATE_SUMMARY_ONLY
6306 : 0;
6307
6308 return bgp_aggregate_set(vty, prefix, AFI_IP, bgp_node_safi(vty),
6309 summary_only, as_set);
6310 }
6311
6312 DEFUN (aggregate_address_mask,
6313 aggregate_address_mask_cmd,
6314 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
6315 "Configure BGP aggregate entries\n"
6316 "Aggregate address\n"
6317 "Aggregate mask\n"
6318 "Generate AS set path information\n"
6319 "Filter more specific routes from updates\n"
6320 "Filter more specific routes from updates\n"
6321 "Generate AS set path information\n")
6322 {
6323 int idx = 0;
6324 argv_find(argv, argc, "A.B.C.D", &idx);
6325 char *prefix = argv[idx]->arg;
6326 char *mask = argv[idx + 1]->arg;
6327 int as_set =
6328 argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
6329 idx = 0;
6330 int summary_only = argv_find(argv, argc, "summary-only", &idx)
6331 ? AGGREGATE_SUMMARY_ONLY
6332 : 0;
6333
6334 char prefix_str[BUFSIZ];
6335 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
6336
6337 if (!ret) {
6338 vty_out(vty, "%% Inconsistent address and mask\n");
6339 return CMD_WARNING_CONFIG_FAILED;
6340 }
6341
6342 return bgp_aggregate_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty),
6343 summary_only, as_set);
6344 }
6345
6346 DEFUN (no_aggregate_address,
6347 no_aggregate_address_cmd,
6348 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
6349 NO_STR
6350 "Configure BGP aggregate entries\n"
6351 "Aggregate prefix\n"
6352 "Generate AS set path information\n"
6353 "Filter more specific routes from updates\n"
6354 "Filter more specific routes from updates\n"
6355 "Generate AS set path information\n")
6356 {
6357 int idx = 0;
6358 argv_find(argv, argc, "A.B.C.D/M", &idx);
6359 char *prefix = argv[idx]->arg;
6360 return bgp_aggregate_unset(vty, prefix, AFI_IP, bgp_node_safi(vty));
6361 }
6362
6363 DEFUN (no_aggregate_address_mask,
6364 no_aggregate_address_mask_cmd,
6365 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
6366 NO_STR
6367 "Configure BGP aggregate entries\n"
6368 "Aggregate address\n"
6369 "Aggregate mask\n"
6370 "Generate AS set path information\n"
6371 "Filter more specific routes from updates\n"
6372 "Filter more specific routes from updates\n"
6373 "Generate AS set path information\n")
6374 {
6375 int idx = 0;
6376 argv_find(argv, argc, "A.B.C.D", &idx);
6377 char *prefix = argv[idx]->arg;
6378 char *mask = argv[idx + 1]->arg;
6379
6380 char prefix_str[BUFSIZ];
6381 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
6382
6383 if (!ret) {
6384 vty_out(vty, "%% Inconsistent address and mask\n");
6385 return CMD_WARNING_CONFIG_FAILED;
6386 }
6387
6388 return bgp_aggregate_unset(vty, prefix_str, AFI_IP, bgp_node_safi(vty));
6389 }
6390
6391 DEFUN (ipv6_aggregate_address,
6392 ipv6_aggregate_address_cmd,
6393 "aggregate-address X:X::X:X/M [summary-only]",
6394 "Configure BGP aggregate entries\n"
6395 "Aggregate prefix\n"
6396 "Filter more specific routes from updates\n")
6397 {
6398 int idx = 0;
6399 argv_find(argv, argc, "X:X::X:X/M", &idx);
6400 char *prefix = argv[idx]->arg;
6401 int sum_only = argv_find(argv, argc, "summary-only", &idx)
6402 ? AGGREGATE_SUMMARY_ONLY
6403 : 0;
6404 return bgp_aggregate_set(vty, prefix, AFI_IP6, SAFI_UNICAST, sum_only,
6405 0);
6406 }
6407
6408 DEFUN (no_ipv6_aggregate_address,
6409 no_ipv6_aggregate_address_cmd,
6410 "no aggregate-address X:X::X:X/M [summary-only]",
6411 NO_STR
6412 "Configure BGP aggregate entries\n"
6413 "Aggregate prefix\n"
6414 "Filter more specific routes from updates\n")
6415 {
6416 int idx = 0;
6417 argv_find(argv, argc, "X:X::X:X/M", &idx);
6418 char *prefix = argv[idx]->arg;
6419 return bgp_aggregate_unset(vty, prefix, AFI_IP6, SAFI_UNICAST);
6420 }
6421
6422 /* Redistribute route treatment. */
6423 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
6424 const union g_addr *nexthop, ifindex_t ifindex,
6425 enum nexthop_types_t nhtype, uint32_t metric,
6426 uint8_t type, unsigned short instance,
6427 route_tag_t tag)
6428 {
6429 struct bgp_path_info *new;
6430 struct bgp_path_info *bpi;
6431 struct bgp_path_info rmap_path;
6432 struct bgp_node *bn;
6433 struct attr attr;
6434 struct attr *new_attr;
6435 afi_t afi;
6436 int ret;
6437 struct bgp_redist *red;
6438
6439 /* Make default attribute. */
6440 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
6441
6442 switch (nhtype) {
6443 case NEXTHOP_TYPE_IFINDEX:
6444 break;
6445 case NEXTHOP_TYPE_IPV4:
6446 case NEXTHOP_TYPE_IPV4_IFINDEX:
6447 attr.nexthop = nexthop->ipv4;
6448 break;
6449 case NEXTHOP_TYPE_IPV6:
6450 case NEXTHOP_TYPE_IPV6_IFINDEX:
6451 attr.mp_nexthop_global = nexthop->ipv6;
6452 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
6453 break;
6454 case NEXTHOP_TYPE_BLACKHOLE:
6455 switch (p->family) {
6456 case AF_INET:
6457 attr.nexthop.s_addr = INADDR_ANY;
6458 break;
6459 case AF_INET6:
6460 memset(&attr.mp_nexthop_global, 0,
6461 sizeof(attr.mp_nexthop_global));
6462 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
6463 break;
6464 }
6465 break;
6466 }
6467 attr.nh_ifindex = ifindex;
6468
6469 attr.med = metric;
6470 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6471 attr.tag = tag;
6472
6473 afi = family2afi(p->family);
6474
6475 red = bgp_redist_lookup(bgp, afi, type, instance);
6476 if (red) {
6477 struct attr attr_new;
6478
6479 /* Copy attribute for modification. */
6480 bgp_attr_dup(&attr_new, &attr);
6481
6482 if (red->redist_metric_flag)
6483 attr_new.med = red->redist_metric;
6484
6485 /* Apply route-map. */
6486 if (red->rmap.name) {
6487 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
6488 rmap_path.peer = bgp->peer_self;
6489 rmap_path.attr = &attr_new;
6490
6491 SET_FLAG(bgp->peer_self->rmap_type,
6492 PEER_RMAP_TYPE_REDISTRIBUTE);
6493
6494 ret = route_map_apply(red->rmap.map, p, RMAP_BGP,
6495 &rmap_path);
6496
6497 bgp->peer_self->rmap_type = 0;
6498
6499 if (ret == RMAP_DENYMATCH) {
6500 /* Free uninterned attribute. */
6501 bgp_attr_flush(&attr_new);
6502
6503 /* Unintern original. */
6504 aspath_unintern(&attr.aspath);
6505 bgp_redistribute_delete(bgp, p, type, instance);
6506 return;
6507 }
6508 }
6509
6510 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
6511 bgp_attr_add_gshut_community(&attr_new);
6512
6513 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
6514 SAFI_UNICAST, p, NULL);
6515
6516 new_attr = bgp_attr_intern(&attr_new);
6517
6518 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
6519 bpi = bpi->next)
6520 if (bpi->peer == bgp->peer_self
6521 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
6522 break;
6523
6524 if (bpi) {
6525 /* Ensure the (source route) type is updated. */
6526 bpi->type = type;
6527 if (attrhash_cmp(bpi->attr, new_attr)
6528 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
6529 bgp_attr_unintern(&new_attr);
6530 aspath_unintern(&attr.aspath);
6531 bgp_unlock_node(bn);
6532 return;
6533 } else {
6534 /* The attribute is changed. */
6535 bgp_path_info_set_flag(bn, bpi,
6536 BGP_PATH_ATTR_CHANGED);
6537
6538 /* Rewrite BGP route information. */
6539 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
6540 bgp_path_info_restore(bn, bpi);
6541 else
6542 bgp_aggregate_decrement(
6543 bgp, p, bpi, afi, SAFI_UNICAST);
6544 bgp_attr_unintern(&bpi->attr);
6545 bpi->attr = new_attr;
6546 bpi->uptime = bgp_clock();
6547
6548 /* Process change. */
6549 bgp_aggregate_increment(bgp, p, bpi, afi,
6550 SAFI_UNICAST);
6551 bgp_process(bgp, bn, afi, SAFI_UNICAST);
6552 bgp_unlock_node(bn);
6553 aspath_unintern(&attr.aspath);
6554
6555 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6556 || (bgp->inst_type
6557 == BGP_INSTANCE_TYPE_DEFAULT)) {
6558
6559 vpn_leak_from_vrf_update(
6560 bgp_get_default(), bgp, bpi);
6561 }
6562 return;
6563 }
6564 }
6565
6566 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
6567 bgp->peer_self, new_attr, bn);
6568 SET_FLAG(new->flags, BGP_PATH_VALID);
6569
6570 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
6571 bgp_path_info_add(bn, new);
6572 bgp_unlock_node(bn);
6573 bgp_process(bgp, bn, afi, SAFI_UNICAST);
6574
6575 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6576 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6577
6578 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6579 }
6580 }
6581
6582 /* Unintern original. */
6583 aspath_unintern(&attr.aspath);
6584 }
6585
6586 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
6587 unsigned short instance)
6588 {
6589 afi_t afi;
6590 struct bgp_node *rn;
6591 struct bgp_path_info *pi;
6592 struct bgp_redist *red;
6593
6594 afi = family2afi(p->family);
6595
6596 red = bgp_redist_lookup(bgp, afi, type, instance);
6597 if (red) {
6598 rn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
6599 SAFI_UNICAST, p, NULL);
6600
6601 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
6602 if (pi->peer == bgp->peer_self && pi->type == type)
6603 break;
6604
6605 if (pi) {
6606 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6607 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6608
6609 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6610 bgp, pi);
6611 }
6612 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
6613 bgp_path_info_delete(rn, pi);
6614 bgp_process(bgp, rn, afi, SAFI_UNICAST);
6615 }
6616 bgp_unlock_node(rn);
6617 }
6618 }
6619
6620 /* Withdraw specified route type's route. */
6621 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
6622 unsigned short instance)
6623 {
6624 struct bgp_node *rn;
6625 struct bgp_path_info *pi;
6626 struct bgp_table *table;
6627
6628 table = bgp->rib[afi][SAFI_UNICAST];
6629
6630 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
6631 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
6632 if (pi->peer == bgp->peer_self && pi->type == type
6633 && pi->instance == instance)
6634 break;
6635
6636 if (pi) {
6637 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6638 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6639
6640 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6641 bgp, pi);
6642 }
6643 bgp_aggregate_decrement(bgp, &rn->p, pi, afi,
6644 SAFI_UNICAST);
6645 bgp_path_info_delete(rn, pi);
6646 bgp_process(bgp, rn, afi, SAFI_UNICAST);
6647 }
6648 }
6649 }
6650
6651 /* Static function to display route. */
6652 static void route_vty_out_route(struct prefix *p, struct vty *vty,
6653 json_object *json)
6654 {
6655 int len = 0;
6656 char buf[BUFSIZ];
6657 char buf2[BUFSIZ];
6658
6659 if (p->family == AF_INET) {
6660 if (!json) {
6661 len = vty_out(
6662 vty, "%s/%d",
6663 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
6664 p->prefixlen);
6665 } else {
6666 json_object_string_add(json, "prefix",
6667 inet_ntop(p->family,
6668 &p->u.prefix, buf,
6669 BUFSIZ));
6670 json_object_int_add(json, "prefixLen", p->prefixlen);
6671 prefix2str(p, buf2, PREFIX_STRLEN);
6672 json_object_string_add(json, "network", buf2);
6673 }
6674 } else if (p->family == AF_ETHERNET) {
6675 prefix2str(p, buf, PREFIX_STRLEN);
6676 len = vty_out(vty, "%s", buf);
6677 } else if (p->family == AF_EVPN) {
6678 if (!json)
6679 len = vty_out(
6680 vty, "%s",
6681 bgp_evpn_route2str((struct prefix_evpn *)p, buf,
6682 BUFSIZ));
6683 else
6684 bgp_evpn_route2json((struct prefix_evpn *)p, json);
6685 } else if (p->family == AF_FLOWSPEC) {
6686 route_vty_out_flowspec(vty, p, NULL,
6687 json ?
6688 NLRI_STRING_FORMAT_JSON_SIMPLE :
6689 NLRI_STRING_FORMAT_MIN, json);
6690 } else {
6691 if (!json)
6692 len = vty_out(
6693 vty, "%s/%d",
6694 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
6695 p->prefixlen);
6696 else {
6697 json_object_string_add(json, "prefix",
6698 inet_ntop(p->family,
6699 &p->u.prefix, buf,
6700 BUFSIZ));
6701 json_object_int_add(json, "prefixLen", p->prefixlen);
6702 prefix2str(p, buf2, PREFIX_STRLEN);
6703 json_object_string_add(json, "network", buf2);
6704 }
6705 }
6706
6707 if (!json) {
6708 len = 17 - len;
6709 if (len < 1)
6710 vty_out(vty, "\n%*s", 20, " ");
6711 else
6712 vty_out(vty, "%*s", len, " ");
6713 }
6714 }
6715
6716 enum bgp_display_type {
6717 normal_list,
6718 };
6719
6720 /* Print the short form route status for a bgp_path_info */
6721 static void route_vty_short_status_out(struct vty *vty,
6722 struct bgp_path_info *path,
6723 json_object *json_path)
6724 {
6725 if (json_path) {
6726
6727 /* Route status display. */
6728 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
6729 json_object_boolean_true_add(json_path, "removed");
6730
6731 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
6732 json_object_boolean_true_add(json_path, "stale");
6733
6734 if (path->extra && path->extra->suppress)
6735 json_object_boolean_true_add(json_path, "suppressed");
6736
6737 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
6738 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
6739 json_object_boolean_true_add(json_path, "valid");
6740
6741 /* Selected */
6742 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
6743 json_object_boolean_true_add(json_path, "history");
6744
6745 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
6746 json_object_boolean_true_add(json_path, "damped");
6747
6748 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
6749 json_object_boolean_true_add(json_path, "bestpath");
6750
6751 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
6752 json_object_boolean_true_add(json_path, "multipath");
6753
6754 /* Internal route. */
6755 if ((path->peer->as)
6756 && (path->peer->as == path->peer->local_as))
6757 json_object_string_add(json_path, "pathFrom",
6758 "internal");
6759 else
6760 json_object_string_add(json_path, "pathFrom",
6761 "external");
6762
6763 return;
6764 }
6765
6766 /* Route status display. */
6767 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
6768 vty_out(vty, "R");
6769 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
6770 vty_out(vty, "S");
6771 else if (path->extra && path->extra->suppress)
6772 vty_out(vty, "s");
6773 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
6774 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
6775 vty_out(vty, "*");
6776 else
6777 vty_out(vty, " ");
6778
6779 /* Selected */
6780 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
6781 vty_out(vty, "h");
6782 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
6783 vty_out(vty, "d");
6784 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
6785 vty_out(vty, ">");
6786 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
6787 vty_out(vty, "=");
6788 else
6789 vty_out(vty, " ");
6790
6791 /* Internal route. */
6792 if (path->peer && (path->peer->as)
6793 && (path->peer->as == path->peer->local_as))
6794 vty_out(vty, "i");
6795 else
6796 vty_out(vty, " ");
6797 }
6798
6799 /* called from terminal list command */
6800 void route_vty_out(struct vty *vty, struct prefix *p,
6801 struct bgp_path_info *path, int display, safi_t safi,
6802 json_object *json_paths)
6803 {
6804 struct attr *attr;
6805 json_object *json_path = NULL;
6806 json_object *json_nexthops = NULL;
6807 json_object *json_nexthop_global = NULL;
6808 json_object *json_nexthop_ll = NULL;
6809 char vrf_id_str[VRF_NAMSIZ] = {0};
6810 bool nexthop_self =
6811 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
6812 bool nexthop_othervrf = false;
6813 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
6814 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
6815
6816 if (json_paths)
6817 json_path = json_object_new_object();
6818
6819 /* short status lead text */
6820 route_vty_short_status_out(vty, path, json_path);
6821
6822 if (!json_paths) {
6823 /* print prefix and mask */
6824 if (!display)
6825 route_vty_out_route(p, vty, json_path);
6826 else
6827 vty_out(vty, "%*s", 17, " ");
6828 } else {
6829 route_vty_out_route(p, vty, json_path);
6830 }
6831
6832 /* Print attribute */
6833 attr = path->attr;
6834 if (!attr) {
6835 if (json_paths)
6836 json_object_array_add(json_paths, json_path);
6837 else
6838 vty_out(vty, "\n");
6839
6840 return;
6841 }
6842
6843 /*
6844 * If vrf id of nexthop is different from that of prefix,
6845 * set up printable string to append
6846 */
6847 if (path->extra && path->extra->bgp_orig) {
6848 const char *self = "";
6849
6850 if (nexthop_self)
6851 self = "<";
6852
6853 nexthop_othervrf = true;
6854 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
6855
6856 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
6857 snprintf(vrf_id_str, sizeof(vrf_id_str),
6858 "@%s%s", VRFID_NONE_STR, self);
6859 else
6860 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
6861 path->extra->bgp_orig->vrf_id, self);
6862
6863 if (path->extra->bgp_orig->inst_type
6864 != BGP_INSTANCE_TYPE_DEFAULT)
6865
6866 nexthop_vrfname = path->extra->bgp_orig->name;
6867 } else {
6868 const char *self = "";
6869
6870 if (nexthop_self)
6871 self = "<";
6872
6873 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
6874 }
6875
6876 /*
6877 * For ENCAP and EVPN routes, nexthop address family is not
6878 * neccessarily the same as the prefix address family.
6879 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6880 * EVPN routes are also exchanged with a MP nexthop. Currently,
6881 * this
6882 * is only IPv4, the value will be present in either
6883 * attr->nexthop or
6884 * attr->mp_nexthop_global_in
6885 */
6886 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
6887 char buf[BUFSIZ];
6888 char nexthop[128];
6889 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
6890
6891 switch (af) {
6892 case AF_INET:
6893 sprintf(nexthop, "%s",
6894 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
6895 BUFSIZ));
6896 break;
6897 case AF_INET6:
6898 sprintf(nexthop, "%s",
6899 inet_ntop(af, &attr->mp_nexthop_global, buf,
6900 BUFSIZ));
6901 break;
6902 default:
6903 sprintf(nexthop, "?");
6904 break;
6905 }
6906
6907 if (json_paths) {
6908 json_nexthop_global = json_object_new_object();
6909
6910 json_object_string_add(json_nexthop_global, "afi",
6911 (af == AF_INET) ? "ip" : "ipv6");
6912 json_object_string_add(json_nexthop_global,
6913 (af == AF_INET) ? "ip" : "ipv6",
6914 nexthop);
6915 json_object_boolean_true_add(json_nexthop_global,
6916 "used");
6917 } else
6918 vty_out(vty, "%s%s", nexthop, vrf_id_str);
6919 } else if (safi == SAFI_EVPN) {
6920 if (json_paths) {
6921 json_nexthop_global = json_object_new_object();
6922
6923 json_object_string_add(json_nexthop_global, "ip",
6924 inet_ntoa(attr->nexthop));
6925 json_object_string_add(json_nexthop_global, "afi",
6926 "ipv4");
6927 json_object_boolean_true_add(json_nexthop_global,
6928 "used");
6929 } else
6930 vty_out(vty, "%-16s%s", inet_ntoa(attr->nexthop),
6931 vrf_id_str);
6932 } else if (safi == SAFI_FLOWSPEC) {
6933 if (attr->nexthop.s_addr != 0) {
6934 if (json_paths) {
6935 json_nexthop_global = json_object_new_object();
6936 json_object_string_add(
6937 json_nexthop_global, "ip",
6938 inet_ntoa(attr->nexthop));
6939 json_object_string_add(json_nexthop_global,
6940 "afi", "ipv4");
6941 json_object_boolean_true_add(
6942 json_nexthop_global,
6943 "used");
6944 } else {
6945 vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
6946 }
6947 }
6948 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
6949 if (json_paths) {
6950 json_nexthop_global = json_object_new_object();
6951
6952 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
6953 json_object_string_add(
6954 json_nexthop_global, "ip",
6955 inet_ntoa(attr->mp_nexthop_global_in));
6956 else
6957 json_object_string_add(
6958 json_nexthop_global, "ip",
6959 inet_ntoa(attr->nexthop));
6960
6961 json_object_string_add(json_nexthop_global, "afi",
6962 "ipv4");
6963 json_object_boolean_true_add(json_nexthop_global,
6964 "used");
6965 } else {
6966 char buf[BUFSIZ];
6967
6968 snprintf(buf, sizeof(buf), "%s%s",
6969 inet_ntoa(attr->nexthop), vrf_id_str);
6970 vty_out(vty, "%-16s", buf);
6971 }
6972 }
6973
6974 /* IPv6 Next Hop */
6975 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
6976 int len;
6977 char buf[BUFSIZ];
6978
6979 if (json_paths) {
6980 json_nexthop_global = json_object_new_object();
6981 json_object_string_add(
6982 json_nexthop_global, "ip",
6983 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
6984 buf, BUFSIZ));
6985 json_object_string_add(json_nexthop_global, "afi",
6986 "ipv6");
6987 json_object_string_add(json_nexthop_global, "scope",
6988 "global");
6989
6990 /* We display both LL & GL if both have been
6991 * received */
6992 if ((attr->mp_nexthop_len == 32)
6993 || (path->peer->conf_if)) {
6994 json_nexthop_ll = json_object_new_object();
6995 json_object_string_add(
6996 json_nexthop_ll, "ip",
6997 inet_ntop(AF_INET6,
6998 &attr->mp_nexthop_local, buf,
6999 BUFSIZ));
7000 json_object_string_add(json_nexthop_ll, "afi",
7001 "ipv6");
7002 json_object_string_add(json_nexthop_ll, "scope",
7003 "link-local");
7004
7005 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
7006 &attr->mp_nexthop_local)
7007 != 0)
7008 && !attr->mp_nexthop_prefer_global)
7009 json_object_boolean_true_add(
7010 json_nexthop_ll, "used");
7011 else
7012 json_object_boolean_true_add(
7013 json_nexthop_global, "used");
7014 } else
7015 json_object_boolean_true_add(
7016 json_nexthop_global, "used");
7017 } else {
7018 /* Display LL if LL/Global both in table unless
7019 * prefer-global is set */
7020 if (((attr->mp_nexthop_len == 32)
7021 && !attr->mp_nexthop_prefer_global)
7022 || (path->peer->conf_if)) {
7023 if (path->peer->conf_if) {
7024 len = vty_out(vty, "%s",
7025 path->peer->conf_if);
7026 len = 16 - len; /* len of IPv6
7027 addr + max
7028 len of def
7029 ifname */
7030
7031 if (len < 1)
7032 vty_out(vty, "\n%*s", 36, " ");
7033 else
7034 vty_out(vty, "%*s", len, " ");
7035 } else {
7036 len = vty_out(
7037 vty, "%s%s",
7038 inet_ntop(
7039 AF_INET6,
7040 &attr->mp_nexthop_local,
7041 buf, BUFSIZ),
7042 vrf_id_str);
7043 len = 16 - len;
7044
7045 if (len < 1)
7046 vty_out(vty, "\n%*s", 36, " ");
7047 else
7048 vty_out(vty, "%*s", len, " ");
7049 }
7050 } else {
7051 len = vty_out(
7052 vty, "%s%s",
7053 inet_ntop(AF_INET6,
7054 &attr->mp_nexthop_global, buf,
7055 BUFSIZ),
7056 vrf_id_str);
7057 len = 16 - len;
7058
7059 if (len < 1)
7060 vty_out(vty, "\n%*s", 36, " ");
7061 else
7062 vty_out(vty, "%*s", len, " ");
7063 }
7064 }
7065 }
7066
7067 /* MED/Metric */
7068 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7069 if (json_paths) {
7070
7071 /*
7072 * Adding "metric" field to match with corresponding
7073 * CLI. "med" will be deprecated in future.
7074 */
7075 json_object_int_add(json_path, "med", attr->med);
7076 json_object_int_add(json_path, "metric", attr->med);
7077 } else
7078 vty_out(vty, "%10u", attr->med);
7079 else if (!json_paths)
7080 vty_out(vty, " ");
7081
7082 /* Local Pref */
7083 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
7084 if (json_paths) {
7085
7086 /*
7087 * Adding "locPrf" field to match with corresponding
7088 * CLI. "localPref" will be deprecated in future.
7089 */
7090 json_object_int_add(json_path, "localpref",
7091 attr->local_pref);
7092 json_object_int_add(json_path, "locPrf",
7093 attr->local_pref);
7094 } else
7095 vty_out(vty, "%7u", attr->local_pref);
7096 else if (!json_paths)
7097 vty_out(vty, " ");
7098
7099 if (json_paths)
7100 json_object_int_add(json_path, "weight", attr->weight);
7101 else
7102 vty_out(vty, "%7u ", attr->weight);
7103
7104 if (json_paths) {
7105 char buf[BUFSIZ];
7106 json_object_string_add(
7107 json_path, "peerId",
7108 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
7109 }
7110
7111 /* Print aspath */
7112 if (attr->aspath) {
7113 if (json_paths) {
7114
7115 /*
7116 * Adding "path" field to match with corresponding
7117 * CLI. "aspath" will be deprecated in future.
7118 */
7119 json_object_string_add(json_path, "aspath",
7120 attr->aspath->str);
7121 json_object_string_add(json_path, "path",
7122 attr->aspath->str);
7123 } else
7124 aspath_print_vty(vty, "%s", attr->aspath, " ");
7125 }
7126
7127 /* Print origin */
7128 if (json_paths)
7129 json_object_string_add(json_path, "origin",
7130 bgp_origin_long_str[attr->origin]);
7131 else
7132 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7133
7134 if (json_paths) {
7135 if (nexthop_self)
7136 json_object_boolean_true_add(json_path,
7137 "announceNexthopSelf");
7138 if (nexthop_othervrf) {
7139 json_object_string_add(json_path, "nhVrfName",
7140 nexthop_vrfname);
7141
7142 json_object_int_add(json_path, "nhVrfId",
7143 ((nexthop_vrfid == VRF_UNKNOWN)
7144 ? -1
7145 : (int)nexthop_vrfid));
7146 }
7147 }
7148
7149 if (json_paths) {
7150 if (json_nexthop_global || json_nexthop_ll) {
7151 json_nexthops = json_object_new_array();
7152
7153 if (json_nexthop_global)
7154 json_object_array_add(json_nexthops,
7155 json_nexthop_global);
7156
7157 if (json_nexthop_ll)
7158 json_object_array_add(json_nexthops,
7159 json_nexthop_ll);
7160
7161 json_object_object_add(json_path, "nexthops",
7162 json_nexthops);
7163 }
7164
7165 json_object_array_add(json_paths, json_path);
7166 } else {
7167 vty_out(vty, "\n");
7168 #if ENABLE_BGP_VNC
7169 /* prints an additional line, indented, with VNC info, if
7170 * present */
7171 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
7172 rfapi_vty_out_vncinfo(vty, p, path, safi);
7173 #endif
7174 }
7175 }
7176
7177 /* called from terminal list command */
7178 void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
7179 safi_t safi, bool use_json, json_object *json_ar)
7180 {
7181 json_object *json_status = NULL;
7182 json_object *json_net = NULL;
7183 char buff[BUFSIZ];
7184 char buf2[BUFSIZ];
7185 /* Route status display. */
7186 if (use_json) {
7187 json_status = json_object_new_object();
7188 json_net = json_object_new_object();
7189 } else {
7190 vty_out(vty, "*");
7191 vty_out(vty, ">");
7192 vty_out(vty, " ");
7193 }
7194
7195 /* print prefix and mask */
7196 if (use_json) {
7197 json_object_string_add(
7198 json_net, "addrPrefix",
7199 inet_ntop(p->family, &p->u.prefix, buff, BUFSIZ));
7200 json_object_int_add(json_net, "prefixLen", p->prefixlen);
7201 prefix2str(p, buf2, PREFIX_STRLEN);
7202 json_object_string_add(json_net, "network", buf2);
7203 } else
7204 route_vty_out_route(p, vty, NULL);
7205
7206 /* Print attribute */
7207 if (attr) {
7208 if (use_json) {
7209 if (p->family == AF_INET
7210 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7211 || safi == SAFI_EVPN
7212 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7213 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7214 || safi == SAFI_EVPN)
7215 json_object_string_add(
7216 json_net, "nextHop",
7217 inet_ntoa(
7218 attr->mp_nexthop_global_in));
7219 else
7220 json_object_string_add(
7221 json_net, "nextHop",
7222 inet_ntoa(attr->nexthop));
7223 } else if (p->family == AF_INET6
7224 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7225 char buf[BUFSIZ];
7226
7227 json_object_string_add(
7228 json_net, "nextHopGlobal",
7229 inet_ntop(AF_INET6,
7230 &attr->mp_nexthop_global, buf,
7231 BUFSIZ));
7232 }
7233
7234 if (attr->flag
7235 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7236 json_object_int_add(json_net, "metric",
7237 attr->med);
7238
7239 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
7240
7241 /*
7242 * Adding "locPrf" field to match with
7243 * corresponding CLI. "localPref" will be
7244 * deprecated in future.
7245 */
7246 json_object_int_add(json_net, "localPref",
7247 attr->local_pref);
7248 json_object_int_add(json_net, "locPrf",
7249 attr->local_pref);
7250 }
7251
7252 json_object_int_add(json_net, "weight", attr->weight);
7253
7254 /* Print aspath */
7255 if (attr->aspath) {
7256
7257 /*
7258 * Adding "path" field to match with
7259 * corresponding CLI. "localPref" will be
7260 * deprecated in future.
7261 */
7262 json_object_string_add(json_net, "asPath",
7263 attr->aspath->str);
7264 json_object_string_add(json_net, "path",
7265 attr->aspath->str);
7266 }
7267
7268 /* Print origin */
7269 json_object_string_add(json_net, "bgpOriginCode",
7270 bgp_origin_str[attr->origin]);
7271 } else {
7272 if (p->family == AF_INET
7273 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7274 || safi == SAFI_EVPN
7275 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7276 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7277 || safi == SAFI_EVPN)
7278 vty_out(vty, "%-16s",
7279 inet_ntoa(
7280 attr->mp_nexthop_global_in));
7281 else
7282 vty_out(vty, "%-16s",
7283 inet_ntoa(attr->nexthop));
7284 } else if (p->family == AF_INET6
7285 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7286 int len;
7287 char buf[BUFSIZ];
7288
7289 len = vty_out(
7290 vty, "%s",
7291 inet_ntop(AF_INET6,
7292 &attr->mp_nexthop_global, buf,
7293 BUFSIZ));
7294 len = 16 - len;
7295 if (len < 1)
7296 vty_out(vty, "\n%*s", 36, " ");
7297 else
7298 vty_out(vty, "%*s", len, " ");
7299 }
7300 if (attr->flag
7301 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7302 vty_out(vty, "%10u", attr->med);
7303 else
7304 vty_out(vty, " ");
7305
7306 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
7307 vty_out(vty, "%7u", attr->local_pref);
7308 else
7309 vty_out(vty, " ");
7310
7311 vty_out(vty, "%7u ", attr->weight);
7312
7313 /* Print aspath */
7314 if (attr->aspath)
7315 aspath_print_vty(vty, "%s", attr->aspath, " ");
7316
7317 /* Print origin */
7318 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7319 }
7320 }
7321 if (use_json) {
7322 json_object_boolean_true_add(json_status, "*");
7323 json_object_boolean_true_add(json_status, ">");
7324 json_object_object_add(json_net, "appliedStatusSymbols",
7325 json_status);
7326 char buf_cut[BUFSIZ];
7327 json_object_object_add(
7328 json_ar,
7329 inet_ntop(p->family, &p->u.prefix, buf_cut, BUFSIZ),
7330 json_net);
7331 } else
7332 vty_out(vty, "\n");
7333 }
7334
7335 void route_vty_out_tag(struct vty *vty, struct prefix *p,
7336 struct bgp_path_info *path, int display, safi_t safi,
7337 json_object *json)
7338 {
7339 json_object *json_out = NULL;
7340 struct attr *attr;
7341 mpls_label_t label = MPLS_INVALID_LABEL;
7342
7343 if (!path->extra)
7344 return;
7345
7346 if (json)
7347 json_out = json_object_new_object();
7348
7349 /* short status lead text */
7350 route_vty_short_status_out(vty, path, json_out);
7351
7352 /* print prefix and mask */
7353 if (json == NULL) {
7354 if (!display)
7355 route_vty_out_route(p, vty, NULL);
7356 else
7357 vty_out(vty, "%*s", 17, " ");
7358 }
7359
7360 /* Print attribute */
7361 attr = path->attr;
7362 if (attr) {
7363 if (((p->family == AF_INET)
7364 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
7365 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7366 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7367 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7368 || safi == SAFI_EVPN) {
7369 if (json)
7370 json_object_string_add(
7371 json_out, "mpNexthopGlobalIn",
7372 inet_ntoa(
7373 attr->mp_nexthop_global_in));
7374 else
7375 vty_out(vty, "%-16s",
7376 inet_ntoa(
7377 attr->mp_nexthop_global_in));
7378 } else {
7379 if (json)
7380 json_object_string_add(
7381 json_out, "nexthop",
7382 inet_ntoa(attr->nexthop));
7383 else
7384 vty_out(vty, "%-16s",
7385 inet_ntoa(attr->nexthop));
7386 }
7387 } else if (((p->family == AF_INET6)
7388 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
7389 || (safi == SAFI_EVPN
7390 && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7391 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7392 char buf_a[512];
7393 char buf_b[512];
7394 char buf_c[BUFSIZ];
7395 if (attr->mp_nexthop_len
7396 == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
7397 if (json)
7398 json_object_string_add(
7399 json_out, "mpNexthopGlobalIn",
7400 inet_ntop(
7401 AF_INET6,
7402 &attr->mp_nexthop_global,
7403 buf_a, sizeof(buf_a)));
7404 else
7405 vty_out(vty, "%s",
7406 inet_ntop(
7407 AF_INET6,
7408 &attr->mp_nexthop_global,
7409 buf_a, sizeof(buf_a)));
7410 } else if (attr->mp_nexthop_len
7411 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
7412 if (json) {
7413 inet_ntop(AF_INET6,
7414 &attr->mp_nexthop_global,
7415 buf_a, sizeof(buf_a));
7416 inet_ntop(AF_INET6,
7417 &attr->mp_nexthop_local,
7418 buf_b, sizeof(buf_b));
7419 sprintf(buf_c, "%s(%s)", buf_a, buf_b);
7420 json_object_string_add(
7421 json_out,
7422 "mpNexthopGlobalLocal", buf_c);
7423 } else
7424 vty_out(vty, "%s(%s)",
7425 inet_ntop(
7426 AF_INET6,
7427 &attr->mp_nexthop_global,
7428 buf_a, sizeof(buf_a)),
7429 inet_ntop(
7430 AF_INET6,
7431 &attr->mp_nexthop_local,
7432 buf_b, sizeof(buf_b)));
7433 }
7434 }
7435 }
7436
7437 label = decode_label(&path->extra->label[0]);
7438
7439 if (bgp_is_valid_label(&label)) {
7440 if (json) {
7441 json_object_int_add(json_out, "notag", label);
7442 json_object_array_add(json, json_out);
7443 } else {
7444 vty_out(vty, "notag/%d", label);
7445 vty_out(vty, "\n");
7446 }
7447 }
7448 }
7449
7450 void route_vty_out_overlay(struct vty *vty, struct prefix *p,
7451 struct bgp_path_info *path, int display,
7452 json_object *json_paths)
7453 {
7454 struct attr *attr;
7455 char buf[BUFSIZ];
7456 json_object *json_path = NULL;
7457
7458 if (json_paths)
7459 json_path = json_object_new_object();
7460
7461 if (!path->extra)
7462 return;
7463
7464 /* short status lead text */
7465 route_vty_short_status_out(vty, path, json_path);
7466
7467 /* print prefix and mask */
7468 if (!display)
7469 route_vty_out_route(p, vty, NULL);
7470 else
7471 vty_out(vty, "%*s", 17, " ");
7472
7473 /* Print attribute */
7474 attr = path->attr;
7475 if (attr) {
7476 char buf1[BUFSIZ];
7477 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
7478
7479 switch (af) {
7480 case AF_INET:
7481 vty_out(vty, "%-16s",
7482 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
7483 BUFSIZ));
7484 break;
7485 case AF_INET6:
7486 vty_out(vty, "%s(%s)",
7487 inet_ntop(af, &attr->mp_nexthop_global, buf,
7488 BUFSIZ),
7489 inet_ntop(af, &attr->mp_nexthop_local, buf1,
7490 BUFSIZ));
7491 break;
7492 default:
7493 vty_out(vty, "?");
7494 }
7495
7496 char *str = esi2str(&(attr->evpn_overlay.eth_s_id));
7497
7498 vty_out(vty, "%s", str);
7499 XFREE(MTYPE_TMP, str);
7500
7501 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) {
7502 vty_out(vty, "/%s",
7503 inet_ntoa(attr->evpn_overlay.gw_ip.ipv4));
7504 } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) {
7505 vty_out(vty, "/%s",
7506 inet_ntop(AF_INET6,
7507 &(attr->evpn_overlay.gw_ip.ipv6), buf,
7508 BUFSIZ));
7509 }
7510 if (attr->ecommunity) {
7511 char *mac = NULL;
7512 struct ecommunity_val *routermac = ecommunity_lookup(
7513 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
7514 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
7515 if (routermac)
7516 mac = ecom_mac2str((char *)routermac->val);
7517 if (mac) {
7518 vty_out(vty, "/%s", (char *)mac);
7519 XFREE(MTYPE_TMP, mac);
7520 }
7521 }
7522 vty_out(vty, "\n");
7523 }
7524
7525 }
7526
7527 /* dampening route */
7528 static void damp_route_vty_out(struct vty *vty, struct prefix *p,
7529 struct bgp_path_info *path, int display,
7530 safi_t safi, bool use_json, json_object *json)
7531 {
7532 struct attr *attr;
7533 int len;
7534 char timebuf[BGP_UPTIME_LEN];
7535
7536 /* short status lead text */
7537 route_vty_short_status_out(vty, path, json);
7538
7539 /* print prefix and mask */
7540 if (!use_json) {
7541 if (!display)
7542 route_vty_out_route(p, vty, NULL);
7543 else
7544 vty_out(vty, "%*s", 17, " ");
7545 }
7546
7547 len = vty_out(vty, "%s", path->peer->host);
7548 len = 17 - len;
7549 if (len < 1) {
7550 if (!use_json)
7551 vty_out(vty, "\n%*s", 34, " ");
7552 } else {
7553 if (use_json)
7554 json_object_int_add(json, "peerHost", len);
7555 else
7556 vty_out(vty, "%*s", len, " ");
7557 }
7558
7559 if (use_json)
7560 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN,
7561 use_json, json);
7562 else
7563 vty_out(vty, "%s ",
7564 bgp_damp_reuse_time_vty(vty, path, timebuf,
7565 BGP_UPTIME_LEN, use_json,
7566 json));
7567
7568 /* Print attribute */
7569 attr = path->attr;
7570 if (attr) {
7571 /* Print aspath */
7572 if (attr->aspath) {
7573 if (use_json)
7574 json_object_string_add(json, "asPath",
7575 attr->aspath->str);
7576 else
7577 aspath_print_vty(vty, "%s", attr->aspath, " ");
7578 }
7579
7580 /* Print origin */
7581 if (use_json)
7582 json_object_string_add(json, "origin",
7583 bgp_origin_str[attr->origin]);
7584 else
7585 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7586 }
7587 if (!use_json)
7588 vty_out(vty, "\n");
7589 }
7590
7591 /* flap route */
7592 static void flap_route_vty_out(struct vty *vty, struct prefix *p,
7593 struct bgp_path_info *path, int display,
7594 safi_t safi, bool use_json, json_object *json)
7595 {
7596 struct attr *attr;
7597 struct bgp_damp_info *bdi;
7598 char timebuf[BGP_UPTIME_LEN];
7599 int len;
7600
7601 if (!path->extra)
7602 return;
7603
7604 bdi = path->extra->damp_info;
7605
7606 /* short status lead text */
7607 route_vty_short_status_out(vty, path, json);
7608
7609 /* print prefix and mask */
7610 if (!use_json) {
7611 if (!display)
7612 route_vty_out_route(p, vty, NULL);
7613 else
7614 vty_out(vty, "%*s", 17, " ");
7615 }
7616
7617 len = vty_out(vty, "%s", path->peer->host);
7618 len = 16 - len;
7619 if (len < 1) {
7620 if (!use_json)
7621 vty_out(vty, "\n%*s", 33, " ");
7622 } else {
7623 if (use_json)
7624 json_object_int_add(json, "peerHost", len);
7625 else
7626 vty_out(vty, "%*s", len, " ");
7627 }
7628
7629 len = vty_out(vty, "%d", bdi->flap);
7630 len = 5 - len;
7631 if (len < 1) {
7632 if (!use_json)
7633 vty_out(vty, " ");
7634 } else {
7635 if (use_json)
7636 json_object_int_add(json, "bdiFlap", len);
7637 else
7638 vty_out(vty, "%*s", len, " ");
7639 }
7640
7641 if (use_json)
7642 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
7643 json);
7644 else
7645 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
7646 BGP_UPTIME_LEN, 0, NULL));
7647
7648 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
7649 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
7650 if (use_json)
7651 bgp_damp_reuse_time_vty(vty, path, timebuf,
7652 BGP_UPTIME_LEN, use_json, json);
7653 else
7654 vty_out(vty, "%s ",
7655 bgp_damp_reuse_time_vty(vty, path, timebuf,
7656 BGP_UPTIME_LEN,
7657 use_json, json));
7658 } else {
7659 if (!use_json)
7660 vty_out(vty, "%*s ", 8, " ");
7661 }
7662
7663 /* Print attribute */
7664 attr = path->attr;
7665 if (attr) {
7666 /* Print aspath */
7667 if (attr->aspath) {
7668 if (use_json)
7669 json_object_string_add(json, "asPath",
7670 attr->aspath->str);
7671 else
7672 aspath_print_vty(vty, "%s", attr->aspath, " ");
7673 }
7674
7675 /* Print origin */
7676 if (use_json)
7677 json_object_string_add(json, "origin",
7678 bgp_origin_str[attr->origin]);
7679 else
7680 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7681 }
7682 if (!use_json)
7683 vty_out(vty, "\n");
7684 }
7685
7686 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
7687 int *first, const char *header,
7688 json_object *json_adv_to)
7689 {
7690 char buf1[INET6_ADDRSTRLEN];
7691 json_object *json_peer = NULL;
7692
7693 if (json_adv_to) {
7694 /* 'advertised-to' is a dictionary of peers we have advertised
7695 * this
7696 * prefix too. The key is the peer's IP or swpX, the value is
7697 * the
7698 * hostname if we know it and "" if not.
7699 */
7700 json_peer = json_object_new_object();
7701
7702 if (peer->hostname)
7703 json_object_string_add(json_peer, "hostname",
7704 peer->hostname);
7705
7706 if (peer->conf_if)
7707 json_object_object_add(json_adv_to, peer->conf_if,
7708 json_peer);
7709 else
7710 json_object_object_add(
7711 json_adv_to,
7712 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
7713 json_peer);
7714 } else {
7715 if (*first) {
7716 vty_out(vty, "%s", header);
7717 *first = 0;
7718 }
7719
7720 if (peer->hostname
7721 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
7722 if (peer->conf_if)
7723 vty_out(vty, " %s(%s)", peer->hostname,
7724 peer->conf_if);
7725 else
7726 vty_out(vty, " %s(%s)", peer->hostname,
7727 sockunion2str(&peer->su, buf1,
7728 SU_ADDRSTRLEN));
7729 } else {
7730 if (peer->conf_if)
7731 vty_out(vty, " %s", peer->conf_if);
7732 else
7733 vty_out(vty, " %s",
7734 sockunion2str(&peer->su, buf1,
7735 SU_ADDRSTRLEN));
7736 }
7737 }
7738 }
7739
7740 static void route_vty_out_tx_ids(struct vty *vty,
7741 struct bgp_addpath_info_data *d)
7742 {
7743 int i;
7744
7745 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
7746 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
7747 d->addpath_tx_id[i],
7748 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
7749 }
7750 }
7751
7752 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
7753 struct bgp_path_info *path, afi_t afi, safi_t safi,
7754 json_object *json_paths)
7755 {
7756 char buf[INET6_ADDRSTRLEN];
7757 char buf1[BUFSIZ];
7758 char buf2[EVPN_ROUTE_STRLEN];
7759 struct attr *attr;
7760 int sockunion_vty_out(struct vty *, union sockunion *);
7761 time_t tbuf;
7762 json_object *json_bestpath = NULL;
7763 json_object *json_cluster_list = NULL;
7764 json_object *json_cluster_list_list = NULL;
7765 json_object *json_ext_community = NULL;
7766 json_object *json_last_update = NULL;
7767 json_object *json_pmsi = NULL;
7768 json_object *json_nexthop_global = NULL;
7769 json_object *json_nexthop_ll = NULL;
7770 json_object *json_nexthops = NULL;
7771 json_object *json_path = NULL;
7772 json_object *json_peer = NULL;
7773 json_object *json_string = NULL;
7774 json_object *json_adv_to = NULL;
7775 int first = 0;
7776 struct listnode *node, *nnode;
7777 struct peer *peer;
7778 int addpath_capable;
7779 int has_adj;
7780 unsigned int first_as;
7781 bool nexthop_self =
7782 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
7783 int i;
7784
7785 if (json_paths) {
7786 json_path = json_object_new_object();
7787 json_peer = json_object_new_object();
7788 json_nexthop_global = json_object_new_object();
7789 }
7790
7791 if (!json_paths && safi == SAFI_EVPN) {
7792 char tag_buf[30];
7793
7794 bgp_evpn_route2str((struct prefix_evpn *)p, buf2, sizeof(buf2));
7795 vty_out(vty, " Route %s", buf2);
7796 tag_buf[0] = '\0';
7797 if (path->extra && path->extra->num_labels) {
7798 bgp_evpn_label2str(path->extra->label,
7799 path->extra->num_labels, tag_buf,
7800 sizeof(tag_buf));
7801 vty_out(vty, " VNI %s", tag_buf);
7802 }
7803 vty_out(vty, "\n");
7804 if (path->extra && path->extra->parent) {
7805 struct bgp_path_info *parent_ri;
7806 struct bgp_node *rn, *prn;
7807
7808 parent_ri = (struct bgp_path_info *)path->extra->parent;
7809 rn = parent_ri->net;
7810 if (rn && rn->prn) {
7811 prn = rn->prn;
7812 vty_out(vty, " Imported from %s:%s\n",
7813 prefix_rd2str(
7814 (struct prefix_rd *)&prn->p,
7815 buf1, sizeof(buf1)),
7816 buf2);
7817 }
7818 }
7819 }
7820
7821 attr = path->attr;
7822
7823 if (attr) {
7824 /* Line1 display AS-path, Aggregator */
7825 if (attr->aspath) {
7826 if (json_paths) {
7827 if (!attr->aspath->json)
7828 aspath_str_update(attr->aspath, true);
7829 json_object_lock(attr->aspath->json);
7830 json_object_object_add(json_path, "aspath",
7831 attr->aspath->json);
7832 } else {
7833 if (attr->aspath->segments)
7834 aspath_print_vty(vty, " %s",
7835 attr->aspath, "");
7836 else
7837 vty_out(vty, " Local");
7838 }
7839 }
7840
7841 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
7842 if (json_paths)
7843 json_object_boolean_true_add(json_path,
7844 "removed");
7845 else
7846 vty_out(vty, ", (removed)");
7847 }
7848
7849 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
7850 if (json_paths)
7851 json_object_boolean_true_add(json_path,
7852 "stale");
7853 else
7854 vty_out(vty, ", (stale)");
7855 }
7856
7857 if (CHECK_FLAG(attr->flag,
7858 ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
7859 if (json_paths) {
7860 json_object_int_add(json_path, "aggregatorAs",
7861 attr->aggregator_as);
7862 json_object_string_add(
7863 json_path, "aggregatorId",
7864 inet_ntoa(attr->aggregator_addr));
7865 } else {
7866 vty_out(vty, ", (aggregated by %u %s)",
7867 attr->aggregator_as,
7868 inet_ntoa(attr->aggregator_addr));
7869 }
7870 }
7871
7872 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
7873 PEER_FLAG_REFLECTOR_CLIENT)) {
7874 if (json_paths)
7875 json_object_boolean_true_add(
7876 json_path, "rxedFromRrClient");
7877 else
7878 vty_out(vty, ", (Received from a RR-client)");
7879 }
7880
7881 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
7882 PEER_FLAG_RSERVER_CLIENT)) {
7883 if (json_paths)
7884 json_object_boolean_true_add(
7885 json_path, "rxedFromRsClient");
7886 else
7887 vty_out(vty, ", (Received from a RS-client)");
7888 }
7889
7890 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
7891 if (json_paths)
7892 json_object_boolean_true_add(
7893 json_path, "dampeningHistoryEntry");
7894 else
7895 vty_out(vty, ", (history entry)");
7896 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
7897 if (json_paths)
7898 json_object_boolean_true_add(
7899 json_path, "dampeningSuppressed");
7900 else
7901 vty_out(vty, ", (suppressed due to dampening)");
7902 }
7903
7904 if (!json_paths)
7905 vty_out(vty, "\n");
7906
7907 /* Line2 display Next-hop, Neighbor, Router-id */
7908 /* Display the nexthop */
7909 if ((p->family == AF_INET || p->family == AF_ETHERNET
7910 || p->family == AF_EVPN)
7911 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7912 || safi == SAFI_EVPN
7913 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7914 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7915 || safi == SAFI_EVPN) {
7916 if (json_paths)
7917 json_object_string_add(
7918 json_nexthop_global, "ip",
7919 inet_ntoa(
7920 attr->mp_nexthop_global_in));
7921 else
7922 vty_out(vty, " %s",
7923 inet_ntoa(
7924 attr->mp_nexthop_global_in));
7925 } else {
7926 if (json_paths)
7927 json_object_string_add(
7928 json_nexthop_global, "ip",
7929 inet_ntoa(attr->nexthop));
7930 else
7931 vty_out(vty, " %s",
7932 inet_ntoa(attr->nexthop));
7933 }
7934
7935 if (json_paths)
7936 json_object_string_add(json_nexthop_global,
7937 "afi", "ipv4");
7938 } else {
7939 if (json_paths) {
7940 json_object_string_add(
7941 json_nexthop_global, "ip",
7942 inet_ntop(AF_INET6,
7943 &attr->mp_nexthop_global, buf,
7944 INET6_ADDRSTRLEN));
7945 json_object_string_add(json_nexthop_global,
7946 "afi", "ipv6");
7947 json_object_string_add(json_nexthop_global,
7948 "scope", "global");
7949 } else {
7950 vty_out(vty, " %s",
7951 inet_ntop(AF_INET6,
7952 &attr->mp_nexthop_global, buf,
7953 INET6_ADDRSTRLEN));
7954 }
7955 }
7956
7957 /* Display the IGP cost or 'inaccessible' */
7958 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
7959 if (json_paths)
7960 json_object_boolean_false_add(
7961 json_nexthop_global, "accessible");
7962 else
7963 vty_out(vty, " (inaccessible)");
7964 } else {
7965 if (path->extra && path->extra->igpmetric) {
7966 if (json_paths)
7967 json_object_int_add(
7968 json_nexthop_global, "metric",
7969 path->extra->igpmetric);
7970 else
7971 vty_out(vty, " (metric %u)",
7972 path->extra->igpmetric);
7973 }
7974
7975 /* IGP cost is 0, display this only for json */
7976 else {
7977 if (json_paths)
7978 json_object_int_add(json_nexthop_global,
7979 "metric", 0);
7980 }
7981
7982 if (json_paths)
7983 json_object_boolean_true_add(
7984 json_nexthop_global, "accessible");
7985 }
7986
7987 /* Display peer "from" output */
7988 /* This path was originated locally */
7989 if (path->peer == bgp->peer_self) {
7990
7991 if (safi == SAFI_EVPN
7992 || (p->family == AF_INET
7993 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7994 if (json_paths)
7995 json_object_string_add(
7996 json_peer, "peerId", "0.0.0.0");
7997 else
7998 vty_out(vty, " from 0.0.0.0 ");
7999 } else {
8000 if (json_paths)
8001 json_object_string_add(json_peer,
8002 "peerId", "::");
8003 else
8004 vty_out(vty, " from :: ");
8005 }
8006
8007 if (json_paths)
8008 json_object_string_add(
8009 json_peer, "routerId",
8010 inet_ntoa(bgp->router_id));
8011 else
8012 vty_out(vty, "(%s)", inet_ntoa(bgp->router_id));
8013 }
8014
8015 /* We RXed this path from one of our peers */
8016 else {
8017
8018 if (json_paths) {
8019 json_object_string_add(
8020 json_peer, "peerId",
8021 sockunion2str(&path->peer->su, buf,
8022 SU_ADDRSTRLEN));
8023 json_object_string_add(
8024 json_peer, "routerId",
8025 inet_ntop(AF_INET,
8026 &path->peer->remote_id, buf1,
8027 sizeof(buf1)));
8028
8029 if (path->peer->hostname)
8030 json_object_string_add(
8031 json_peer, "hostname",
8032 path->peer->hostname);
8033
8034 if (path->peer->domainname)
8035 json_object_string_add(
8036 json_peer, "domainname",
8037 path->peer->domainname);
8038
8039 if (path->peer->conf_if)
8040 json_object_string_add(
8041 json_peer, "interface",
8042 path->peer->conf_if);
8043 } else {
8044 if (path->peer->conf_if) {
8045 if (path->peer->hostname
8046 && bgp_flag_check(
8047 path->peer->bgp,
8048 BGP_FLAG_SHOW_HOSTNAME))
8049 vty_out(vty, " from %s(%s)",
8050 path->peer->hostname,
8051 path->peer->conf_if);
8052 else
8053 vty_out(vty, " from %s",
8054 path->peer->conf_if);
8055 } else {
8056 if (path->peer->hostname
8057 && bgp_flag_check(
8058 path->peer->bgp,
8059 BGP_FLAG_SHOW_HOSTNAME))
8060 vty_out(vty, " from %s(%s)",
8061 path->peer->hostname,
8062 path->peer->host);
8063 else
8064 vty_out(vty, " from %s",
8065 sockunion2str(
8066 &path->peer->su,
8067 buf,
8068 SU_ADDRSTRLEN));
8069 }
8070
8071 if (attr->flag
8072 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
8073 vty_out(vty, " (%s)",
8074 inet_ntoa(attr->originator_id));
8075 else
8076 vty_out(vty, " (%s)",
8077 inet_ntop(
8078 AF_INET,
8079 &path->peer->remote_id,
8080 buf1, sizeof(buf1)));
8081 }
8082 }
8083
8084 /*
8085 * Note when vrfid of nexthop is different from that of prefix
8086 */
8087 if (path->extra && path->extra->bgp_orig) {
8088 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
8089
8090 if (json_paths) {
8091 const char *vn;
8092
8093 if (path->extra->bgp_orig->inst_type
8094 == BGP_INSTANCE_TYPE_DEFAULT)
8095
8096 vn = VRF_DEFAULT_NAME;
8097 else
8098 vn = path->extra->bgp_orig->name;
8099
8100 json_object_string_add(json_path, "nhVrfName",
8101 vn);
8102
8103 if (nexthop_vrfid == VRF_UNKNOWN) {
8104 json_object_int_add(json_path,
8105 "nhVrfId", -1);
8106 } else {
8107 json_object_int_add(json_path,
8108 "nhVrfId", (int)nexthop_vrfid);
8109 }
8110 } else {
8111 if (nexthop_vrfid == VRF_UNKNOWN)
8112 vty_out(vty, " vrf ?");
8113 else
8114 vty_out(vty, " vrf %u", nexthop_vrfid);
8115 }
8116 }
8117
8118 if (nexthop_self) {
8119 if (json_paths) {
8120 json_object_boolean_true_add(json_path,
8121 "announceNexthopSelf");
8122 } else {
8123 vty_out(vty, " announce-nh-self");
8124 }
8125 }
8126
8127 if (!json_paths)
8128 vty_out(vty, "\n");
8129
8130 /* display the link-local nexthop */
8131 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
8132 if (json_paths) {
8133 json_nexthop_ll = json_object_new_object();
8134 json_object_string_add(
8135 json_nexthop_ll, "ip",
8136 inet_ntop(AF_INET6,
8137 &attr->mp_nexthop_local, buf,
8138 INET6_ADDRSTRLEN));
8139 json_object_string_add(json_nexthop_ll, "afi",
8140 "ipv6");
8141 json_object_string_add(json_nexthop_ll, "scope",
8142 "link-local");
8143
8144 json_object_boolean_true_add(json_nexthop_ll,
8145 "accessible");
8146
8147 if (!attr->mp_nexthop_prefer_global)
8148 json_object_boolean_true_add(
8149 json_nexthop_ll, "used");
8150 else
8151 json_object_boolean_true_add(
8152 json_nexthop_global, "used");
8153 } else {
8154 vty_out(vty, " (%s) %s\n",
8155 inet_ntop(AF_INET6,
8156 &attr->mp_nexthop_local, buf,
8157 INET6_ADDRSTRLEN),
8158 attr->mp_nexthop_prefer_global
8159 ? "(prefer-global)"
8160 : "(used)");
8161 }
8162 }
8163 /* If we do not have a link-local nexthop then we must flag the
8164 global as "used" */
8165 else {
8166 if (json_paths)
8167 json_object_boolean_true_add(
8168 json_nexthop_global, "used");
8169 }
8170
8171 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
8172 * Int/Ext/Local, Atomic, best */
8173 if (json_paths)
8174 json_object_string_add(
8175 json_path, "origin",
8176 bgp_origin_long_str[attr->origin]);
8177 else
8178 vty_out(vty, " Origin %s",
8179 bgp_origin_long_str[attr->origin]);
8180
8181 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
8182 if (json_paths) {
8183
8184 /*
8185 * Adding "metric" field to match with
8186 * corresponding CLI. "med" will be
8187 * deprecated in future.
8188 */
8189 json_object_int_add(json_path, "med",
8190 attr->med);
8191 json_object_int_add(json_path, "metric",
8192 attr->med);
8193 } else
8194 vty_out(vty, ", metric %u", attr->med);
8195 }
8196
8197 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
8198 if (json_paths)
8199 json_object_int_add(json_path, "localpref",
8200 attr->local_pref);
8201 else
8202 vty_out(vty, ", localpref %u",
8203 attr->local_pref);
8204 }
8205
8206 if (attr->weight != 0) {
8207 if (json_paths)
8208 json_object_int_add(json_path, "weight",
8209 attr->weight);
8210 else
8211 vty_out(vty, ", weight %u", attr->weight);
8212 }
8213
8214 if (attr->tag != 0) {
8215 if (json_paths)
8216 json_object_int_add(json_path, "tag",
8217 attr->tag);
8218 else
8219 vty_out(vty, ", tag %" ROUTE_TAG_PRI,
8220 attr->tag);
8221 }
8222
8223 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
8224 if (json_paths)
8225 json_object_boolean_false_add(json_path,
8226 "valid");
8227 else
8228 vty_out(vty, ", invalid");
8229 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8230 if (json_paths)
8231 json_object_boolean_true_add(json_path,
8232 "valid");
8233 else
8234 vty_out(vty, ", valid");
8235 }
8236
8237 if (path->peer != bgp->peer_self) {
8238 if (path->peer->as == path->peer->local_as) {
8239 if (CHECK_FLAG(bgp->config,
8240 BGP_CONFIG_CONFEDERATION)) {
8241 if (json_paths)
8242 json_object_string_add(
8243 json_peer, "type",
8244 "confed-internal");
8245 else
8246 vty_out(vty,
8247 ", confed-internal");
8248 } else {
8249 if (json_paths)
8250 json_object_string_add(
8251 json_peer, "type",
8252 "internal");
8253 else
8254 vty_out(vty, ", internal");
8255 }
8256 } else {
8257 if (bgp_confederation_peers_check(
8258 bgp, path->peer->as)) {
8259 if (json_paths)
8260 json_object_string_add(
8261 json_peer, "type",
8262 "confed-external");
8263 else
8264 vty_out(vty,
8265 ", confed-external");
8266 } else {
8267 if (json_paths)
8268 json_object_string_add(
8269 json_peer, "type",
8270 "external");
8271 else
8272 vty_out(vty, ", external");
8273 }
8274 }
8275 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
8276 if (json_paths) {
8277 json_object_boolean_true_add(json_path,
8278 "aggregated");
8279 json_object_boolean_true_add(json_path,
8280 "local");
8281 } else {
8282 vty_out(vty, ", aggregated, local");
8283 }
8284 } else if (path->type != ZEBRA_ROUTE_BGP) {
8285 if (json_paths)
8286 json_object_boolean_true_add(json_path,
8287 "sourced");
8288 else
8289 vty_out(vty, ", sourced");
8290 } else {
8291 if (json_paths) {
8292 json_object_boolean_true_add(json_path,
8293 "sourced");
8294 json_object_boolean_true_add(json_path,
8295 "local");
8296 } else {
8297 vty_out(vty, ", sourced, local");
8298 }
8299 }
8300
8301 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
8302 if (json_paths)
8303 json_object_boolean_true_add(json_path,
8304 "atomicAggregate");
8305 else
8306 vty_out(vty, ", atomic-aggregate");
8307 }
8308
8309 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
8310 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
8311 && bgp_path_info_mpath_count(path))) {
8312 if (json_paths)
8313 json_object_boolean_true_add(json_path,
8314 "multipath");
8315 else
8316 vty_out(vty, ", multipath");
8317 }
8318
8319 // Mark the bestpath(s)
8320 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
8321 first_as = aspath_get_first_as(attr->aspath);
8322
8323 if (json_paths) {
8324 if (!json_bestpath)
8325 json_bestpath =
8326 json_object_new_object();
8327 json_object_int_add(json_bestpath,
8328 "bestpathFromAs", first_as);
8329 } else {
8330 if (first_as)
8331 vty_out(vty, ", bestpath-from-AS %u",
8332 first_as);
8333 else
8334 vty_out(vty,
8335 ", bestpath-from-AS Local");
8336 }
8337 }
8338
8339 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
8340 if (json_paths) {
8341 if (!json_bestpath)
8342 json_bestpath =
8343 json_object_new_object();
8344 json_object_boolean_true_add(json_bestpath,
8345 "overall");
8346 } else
8347 vty_out(vty, ", best");
8348 }
8349
8350 if (json_bestpath)
8351 json_object_object_add(json_path, "bestpath",
8352 json_bestpath);
8353
8354 if (!json_paths)
8355 vty_out(vty, "\n");
8356
8357 /* Line 4 display Community */
8358 if (attr->community) {
8359 if (json_paths) {
8360 if (!attr->community->json)
8361 community_str(attr->community, true);
8362 json_object_lock(attr->community->json);
8363 json_object_object_add(json_path, "community",
8364 attr->community->json);
8365 } else {
8366 vty_out(vty, " Community: %s\n",
8367 attr->community->str);
8368 }
8369 }
8370
8371 /* Line 5 display Extended-community */
8372 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8373 if (json_paths) {
8374 json_ext_community = json_object_new_object();
8375 json_object_string_add(json_ext_community,
8376 "string",
8377 attr->ecommunity->str);
8378 json_object_object_add(json_path,
8379 "extendedCommunity",
8380 json_ext_community);
8381 } else {
8382 vty_out(vty, " Extended Community: %s\n",
8383 attr->ecommunity->str);
8384 }
8385 }
8386
8387 /* Line 6 display Large community */
8388 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
8389 if (json_paths) {
8390 if (!attr->lcommunity->json)
8391 lcommunity_str(attr->lcommunity, true);
8392 json_object_lock(attr->lcommunity->json);
8393 json_object_object_add(json_path,
8394 "largeCommunity",
8395 attr->lcommunity->json);
8396 } else {
8397 vty_out(vty, " Large Community: %s\n",
8398 attr->lcommunity->str);
8399 }
8400 }
8401
8402 /* Line 7 display Originator, Cluster-id */
8403 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
8404 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
8405 if (attr->flag
8406 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
8407 if (json_paths)
8408 json_object_string_add(
8409 json_path, "originatorId",
8410 inet_ntoa(attr->originator_id));
8411 else
8412 vty_out(vty, " Originator: %s",
8413 inet_ntoa(attr->originator_id));
8414 }
8415
8416 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
8417 int i;
8418
8419 if (json_paths) {
8420 json_cluster_list =
8421 json_object_new_object();
8422 json_cluster_list_list =
8423 json_object_new_array();
8424
8425 for (i = 0;
8426 i < attr->cluster->length / 4;
8427 i++) {
8428 json_string = json_object_new_string(
8429 inet_ntoa(
8430 attr->cluster->list
8431 [i]));
8432 json_object_array_add(
8433 json_cluster_list_list,
8434 json_string);
8435 }
8436
8437 /* struct cluster_list does not have
8438 "str" variable like
8439 * aspath and community do. Add this
8440 someday if someone
8441 * asks for it.
8442 json_object_string_add(json_cluster_list,
8443 "string", attr->cluster->str);
8444 */
8445 json_object_object_add(
8446 json_cluster_list, "list",
8447 json_cluster_list_list);
8448 json_object_object_add(
8449 json_path, "clusterList",
8450 json_cluster_list);
8451 } else {
8452 vty_out(vty, ", Cluster list: ");
8453
8454 for (i = 0;
8455 i < attr->cluster->length / 4;
8456 i++) {
8457 vty_out(vty, "%s ",
8458 inet_ntoa(
8459 attr->cluster->list
8460 [i]));
8461 }
8462 }
8463 }
8464
8465 if (!json_paths)
8466 vty_out(vty, "\n");
8467 }
8468
8469 if (path->extra && path->extra->damp_info)
8470 bgp_damp_info_vty(vty, path, json_path);
8471
8472 /* Remote Label */
8473 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
8474 && safi != SAFI_EVPN) {
8475 mpls_label_t label = label_pton(&path->extra->label[0]);
8476
8477 if (json_paths)
8478 json_object_int_add(json_path, "remoteLabel",
8479 label);
8480 else
8481 vty_out(vty, " Remote label: %d\n", label);
8482 }
8483
8484 /* Label Index */
8485 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
8486 if (json_paths)
8487 json_object_int_add(json_path, "labelIndex",
8488 attr->label_index);
8489 else
8490 vty_out(vty, " Label Index: %d\n",
8491 attr->label_index);
8492 }
8493
8494 /* Line 8 display Addpath IDs */
8495 if (path->addpath_rx_id
8496 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
8497 if (json_paths) {
8498 json_object_int_add(json_path, "addpathRxId",
8499 path->addpath_rx_id);
8500
8501 /* Keep backwards compatibility with the old API
8502 * by putting TX All's ID in the old field
8503 */
8504 json_object_int_add(
8505 json_path, "addpathTxId",
8506 path->tx_addpath.addpath_tx_id
8507 [BGP_ADDPATH_ALL]);
8508
8509 /* ... but create a specific field for each
8510 * strategy
8511 */
8512 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
8513 json_object_int_add(
8514 json_path,
8515 bgp_addpath_names(i)
8516 ->id_json_name,
8517 path->tx_addpath
8518 .addpath_tx_id[i]);
8519 }
8520 } else {
8521 vty_out(vty, " AddPath ID: RX %u, ",
8522 path->addpath_rx_id);
8523
8524 route_vty_out_tx_ids(vty, &path->tx_addpath);
8525 }
8526 }
8527
8528 /* If we used addpath to TX a non-bestpath we need to display
8529 * "Advertised to" on a path-by-path basis
8530 */
8531 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
8532 first = 1;
8533
8534 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
8535 addpath_capable =
8536 bgp_addpath_encode_tx(peer, afi, safi);
8537 has_adj = bgp_adj_out_lookup(
8538 peer, path->net,
8539 bgp_addpath_id_for_peer(
8540 peer, afi, safi,
8541 &path->tx_addpath));
8542
8543 if ((addpath_capable && has_adj)
8544 || (!addpath_capable && has_adj
8545 && CHECK_FLAG(path->flags,
8546 BGP_PATH_SELECTED))) {
8547 if (json_path && !json_adv_to)
8548 json_adv_to =
8549 json_object_new_object();
8550
8551 route_vty_out_advertised_to(
8552 vty, peer, &first,
8553 " Advertised to:",
8554 json_adv_to);
8555 }
8556 }
8557
8558 if (json_path) {
8559 if (json_adv_to) {
8560 json_object_object_add(json_path,
8561 "advertisedTo",
8562 json_adv_to);
8563 }
8564 } else {
8565 if (!first) {
8566 vty_out(vty, "\n");
8567 }
8568 }
8569 }
8570
8571 /* Line 9 display Uptime */
8572 tbuf = time(NULL) - (bgp_clock() - path->uptime);
8573 if (json_paths) {
8574 json_last_update = json_object_new_object();
8575 json_object_int_add(json_last_update, "epoch", tbuf);
8576 json_object_string_add(json_last_update, "string",
8577 ctime(&tbuf));
8578 json_object_object_add(json_path, "lastUpdate",
8579 json_last_update);
8580 } else
8581 vty_out(vty, " Last update: %s", ctime(&tbuf));
8582
8583 /* Line 10 display PMSI tunnel attribute, if present */
8584 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
8585 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
8586 attr->pmsi_tnl_type,
8587 PMSI_TNLTYPE_STR_DEFAULT);
8588
8589 if (json_paths) {
8590 json_pmsi = json_object_new_object();
8591 json_object_string_add(json_pmsi,
8592 "tunnelType", str);
8593 json_object_object_add(json_path, "pmsi",
8594 json_pmsi);
8595 } else
8596 vty_out(vty, " PMSI Tunnel Type: %s\n",
8597 str);
8598 }
8599
8600 }
8601
8602 /* We've constructed the json object for this path, add it to the json
8603 * array of paths
8604 */
8605 if (json_paths) {
8606 if (json_nexthop_global || json_nexthop_ll) {
8607 json_nexthops = json_object_new_array();
8608
8609 if (json_nexthop_global)
8610 json_object_array_add(json_nexthops,
8611 json_nexthop_global);
8612
8613 if (json_nexthop_ll)
8614 json_object_array_add(json_nexthops,
8615 json_nexthop_ll);
8616
8617 json_object_object_add(json_path, "nexthops",
8618 json_nexthops);
8619 }
8620
8621 json_object_object_add(json_path, "peer", json_peer);
8622 json_object_array_add(json_paths, json_path);
8623 } else
8624 vty_out(vty, "\n");
8625 }
8626
8627 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
8628 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
8629 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
8630
8631 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
8632 const char *prefix_list_str, afi_t afi,
8633 safi_t safi, enum bgp_show_type type);
8634 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
8635 const char *filter, afi_t afi, safi_t safi,
8636 enum bgp_show_type type);
8637 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
8638 const char *rmap_str, afi_t afi, safi_t safi,
8639 enum bgp_show_type type);
8640 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
8641 const char *com, int exact, afi_t afi,
8642 safi_t safi);
8643 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
8644 const char *prefix, afi_t afi, safi_t safi,
8645 enum bgp_show_type type);
8646 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
8647 afi_t afi, safi_t safi, enum bgp_show_type type);
8648 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
8649 const char *comstr, int exact, afi_t afi,
8650 safi_t safi, bool use_json);
8651
8652
8653 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
8654 struct bgp_table *table, enum bgp_show_type type,
8655 void *output_arg, bool use_json, char *rd,
8656 int is_last, unsigned long *output_cum,
8657 unsigned long *total_cum,
8658 unsigned long *json_header_depth)
8659 {
8660 struct bgp_path_info *pi;
8661 struct bgp_node *rn;
8662 int header = 1;
8663 int display;
8664 unsigned long output_count = 0;
8665 unsigned long total_count = 0;
8666 struct prefix *p;
8667 char buf2[BUFSIZ];
8668 json_object *json_paths = NULL;
8669 int first = 1;
8670
8671 if (output_cum && *output_cum != 0)
8672 header = 0;
8673
8674 if (use_json && !*json_header_depth) {
8675 vty_out(vty,
8676 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
8677 ",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n"
8678 " \"localAS\": %u,\n \"routes\": { ",
8679 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
8680 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
8681 ? VRF_DEFAULT_NAME
8682 : bgp->name,
8683 table->version, inet_ntoa(bgp->router_id),
8684 bgp->default_local_pref, bgp->as);
8685 *json_header_depth = 2;
8686 if (rd) {
8687 vty_out(vty, " \"routeDistinguishers\" : {");
8688 ++*json_header_depth;
8689 }
8690 }
8691
8692 if (use_json && rd) {
8693 vty_out(vty, " \"%s\" : { ", rd);
8694 }
8695
8696 /* Start processing of routes. */
8697 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
8698 pi = bgp_node_get_bgp_path_info(rn);
8699 if (pi == NULL)
8700 continue;
8701
8702 display = 0;
8703 if (use_json)
8704 json_paths = json_object_new_array();
8705 else
8706 json_paths = NULL;
8707
8708 for (; pi; pi = pi->next) {
8709 total_count++;
8710 if (type == bgp_show_type_flap_statistics
8711 || type == bgp_show_type_flap_neighbor
8712 || type == bgp_show_type_dampend_paths
8713 || type == bgp_show_type_damp_neighbor) {
8714 if (!(pi->extra && pi->extra->damp_info))
8715 continue;
8716 }
8717 if (type == bgp_show_type_regexp) {
8718 regex_t *regex = output_arg;
8719
8720 if (bgp_regexec(regex, pi->attr->aspath)
8721 == REG_NOMATCH)
8722 continue;
8723 }
8724 if (type == bgp_show_type_prefix_list) {
8725 struct prefix_list *plist = output_arg;
8726
8727 if (prefix_list_apply(plist, &rn->p)
8728 != PREFIX_PERMIT)
8729 continue;
8730 }
8731 if (type == bgp_show_type_filter_list) {
8732 struct as_list *as_list = output_arg;
8733
8734 if (as_list_apply(as_list, pi->attr->aspath)
8735 != AS_FILTER_PERMIT)
8736 continue;
8737 }
8738 if (type == bgp_show_type_route_map) {
8739 struct route_map *rmap = output_arg;
8740 struct bgp_path_info path;
8741 struct attr dummy_attr;
8742 int ret;
8743
8744 bgp_attr_dup(&dummy_attr, pi->attr);
8745
8746 path.peer = pi->peer;
8747 path.attr = &dummy_attr;
8748
8749 ret = route_map_apply(rmap, &rn->p, RMAP_BGP,
8750 &path);
8751 if (ret == RMAP_DENYMATCH)
8752 continue;
8753 }
8754 if (type == bgp_show_type_neighbor
8755 || type == bgp_show_type_flap_neighbor
8756 || type == bgp_show_type_damp_neighbor) {
8757 union sockunion *su = output_arg;
8758
8759 if (pi->peer == NULL
8760 || pi->peer->su_remote == NULL
8761 || !sockunion_same(pi->peer->su_remote, su))
8762 continue;
8763 }
8764 if (type == bgp_show_type_cidr_only) {
8765 uint32_t destination;
8766
8767 destination = ntohl(rn->p.u.prefix4.s_addr);
8768 if (IN_CLASSC(destination)
8769 && rn->p.prefixlen == 24)
8770 continue;
8771 if (IN_CLASSB(destination)
8772 && rn->p.prefixlen == 16)
8773 continue;
8774 if (IN_CLASSA(destination)
8775 && rn->p.prefixlen == 8)
8776 continue;
8777 }
8778 if (type == bgp_show_type_prefix_longer) {
8779 p = output_arg;
8780 if (!prefix_match(p, &rn->p))
8781 continue;
8782 }
8783 if (type == bgp_show_type_community_all) {
8784 if (!pi->attr->community)
8785 continue;
8786 }
8787 if (type == bgp_show_type_community) {
8788 struct community *com = output_arg;
8789
8790 if (!pi->attr->community
8791 || !community_match(pi->attr->community,
8792 com))
8793 continue;
8794 }
8795 if (type == bgp_show_type_community_exact) {
8796 struct community *com = output_arg;
8797
8798 if (!pi->attr->community
8799 || !community_cmp(pi->attr->community, com))
8800 continue;
8801 }
8802 if (type == bgp_show_type_community_list) {
8803 struct community_list *list = output_arg;
8804
8805 if (!community_list_match(pi->attr->community,
8806 list))
8807 continue;
8808 }
8809 if (type == bgp_show_type_community_list_exact) {
8810 struct community_list *list = output_arg;
8811
8812 if (!community_list_exact_match(
8813 pi->attr->community, list))
8814 continue;
8815 }
8816 if (type == bgp_show_type_lcommunity) {
8817 struct lcommunity *lcom = output_arg;
8818
8819 if (!pi->attr->lcommunity
8820 || !lcommunity_match(pi->attr->lcommunity,
8821 lcom))
8822 continue;
8823 }
8824 if (type == bgp_show_type_lcommunity_list) {
8825 struct community_list *list = output_arg;
8826
8827 if (!lcommunity_list_match(pi->attr->lcommunity,
8828 list))
8829 continue;
8830 }
8831 if (type == bgp_show_type_lcommunity_all) {
8832 if (!pi->attr->lcommunity)
8833 continue;
8834 }
8835 if (type == bgp_show_type_dampend_paths
8836 || type == bgp_show_type_damp_neighbor) {
8837 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
8838 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
8839 continue;
8840 }
8841
8842 if (!use_json && header) {
8843 vty_out(vty, "BGP table version is %" PRIu64
8844 ", local router ID is %s, vrf id ",
8845 table->version,
8846 inet_ntoa(bgp->router_id));
8847 if (bgp->vrf_id == VRF_UNKNOWN)
8848 vty_out(vty, "%s", VRFID_NONE_STR);
8849 else
8850 vty_out(vty, "%u", bgp->vrf_id);
8851 vty_out(vty, "\n");
8852 vty_out(vty, "Default local pref %u, ",
8853 bgp->default_local_pref);
8854 vty_out(vty, "local AS %u\n", bgp->as);
8855 vty_out(vty, BGP_SHOW_SCODE_HEADER);
8856 vty_out(vty, BGP_SHOW_NCODE_HEADER);
8857 vty_out(vty, BGP_SHOW_OCODE_HEADER);
8858 if (type == bgp_show_type_dampend_paths
8859 || type == bgp_show_type_damp_neighbor)
8860 vty_out(vty, BGP_SHOW_DAMP_HEADER);
8861 else if (type == bgp_show_type_flap_statistics
8862 || type == bgp_show_type_flap_neighbor)
8863 vty_out(vty, BGP_SHOW_FLAP_HEADER);
8864 else
8865 vty_out(vty, BGP_SHOW_HEADER);
8866 header = 0;
8867 }
8868 if (rd != NULL && !display && !output_count) {
8869 if (!use_json)
8870 vty_out(vty,
8871 "Route Distinguisher: %s\n",
8872 rd);
8873 }
8874 if (type == bgp_show_type_dampend_paths
8875 || type == bgp_show_type_damp_neighbor)
8876 damp_route_vty_out(vty, &rn->p, pi, display,
8877 safi, use_json, json_paths);
8878 else if (type == bgp_show_type_flap_statistics
8879 || type == bgp_show_type_flap_neighbor)
8880 flap_route_vty_out(vty, &rn->p, pi, display,
8881 safi, use_json, json_paths);
8882 else
8883 route_vty_out(vty, &rn->p, pi, display, safi,
8884 json_paths);
8885 display++;
8886 }
8887
8888 if (display) {
8889 output_count++;
8890 if (!use_json)
8891 continue;
8892
8893 p = &rn->p;
8894 /* encode prefix */
8895 if (p->family == AF_FLOWSPEC) {
8896 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
8897
8898 bgp_fs_nlri_get_string((unsigned char *)
8899 p->u.prefix_flowspec.ptr,
8900 p->u.prefix_flowspec
8901 .prefixlen,
8902 retstr,
8903 NLRI_STRING_FORMAT_MIN,
8904 NULL);
8905 if (first)
8906 vty_out(vty, "\"%s/%d\": ",
8907 retstr,
8908 p->u.prefix_flowspec.prefixlen);
8909 else
8910 vty_out(vty, ",\"%s/%d\": ",
8911 retstr,
8912 p->u.prefix_flowspec.prefixlen);
8913 } else {
8914 prefix2str(p, buf2, sizeof(buf2));
8915 if (first)
8916 vty_out(vty, "\"%s\": ", buf2);
8917 else
8918 vty_out(vty, ",\"%s\": ", buf2);
8919 }
8920 vty_out(vty, "%s",
8921 json_object_to_json_string(json_paths));
8922 json_object_free(json_paths);
8923 json_paths = NULL;
8924 first = 0;
8925 }
8926 }
8927
8928 if (output_cum) {
8929 output_count += *output_cum;
8930 *output_cum = output_count;
8931 }
8932 if (total_cum) {
8933 total_count += *total_cum;
8934 *total_cum = total_count;
8935 }
8936 if (use_json) {
8937 if (rd) {
8938 vty_out(vty, " }%s ", (is_last ? "" : ","));
8939 }
8940 if (is_last) {
8941 unsigned long i;
8942 for (i = 0; i < *json_header_depth; ++i)
8943 vty_out(vty, " } ");
8944 }
8945 } else {
8946 if (is_last) {
8947 /* No route is displayed */
8948 if (output_count == 0) {
8949 if (type == bgp_show_type_normal)
8950 vty_out(vty,
8951 "No BGP prefixes displayed, %ld exist\n",
8952 total_count);
8953 } else
8954 vty_out(vty,
8955 "\nDisplayed %ld routes and %ld total paths\n",
8956 output_count, total_count);
8957 }
8958 }
8959
8960 return CMD_SUCCESS;
8961 }
8962
8963 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
8964 struct bgp_table *table, struct prefix_rd *prd_match,
8965 enum bgp_show_type type, void *output_arg, bool use_json)
8966 {
8967 struct bgp_node *rn, *next;
8968 unsigned long output_cum = 0;
8969 unsigned long total_cum = 0;
8970 unsigned long json_header_depth = 0;
8971 struct bgp_table *itable;
8972 bool show_msg;
8973
8974 show_msg = (!use_json && type == bgp_show_type_normal);
8975
8976 for (rn = bgp_table_top(table); rn; rn = next) {
8977 next = bgp_route_next(rn);
8978 if (prd_match && memcmp(rn->p.u.val, prd_match->val, 8) != 0)
8979 continue;
8980
8981 itable = bgp_node_get_bgp_table_info(rn);
8982 if (itable != NULL) {
8983 struct prefix_rd prd;
8984 char rd[RD_ADDRSTRLEN];
8985
8986 memcpy(&prd, &(rn->p), sizeof(struct prefix_rd));
8987 prefix_rd2str(&prd, rd, sizeof(rd));
8988 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
8989 use_json, rd, next == NULL, &output_cum,
8990 &total_cum, &json_header_depth);
8991 if (next == NULL)
8992 show_msg = false;
8993 }
8994 }
8995 if (show_msg) {
8996 if (output_cum == 0)
8997 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
8998 total_cum);
8999 else
9000 vty_out(vty,
9001 "\nDisplayed %ld routes and %ld total paths\n",
9002 output_cum, total_cum);
9003 }
9004 return CMD_SUCCESS;
9005 }
9006 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
9007 enum bgp_show_type type, void *output_arg, bool use_json)
9008 {
9009 struct bgp_table *table;
9010 unsigned long json_header_depth = 0;
9011
9012 if (bgp == NULL) {
9013 bgp = bgp_get_default();
9014 }
9015
9016 if (bgp == NULL) {
9017 if (!use_json)
9018 vty_out(vty, "No BGP process is configured\n");
9019 else
9020 vty_out(vty, "{}\n");
9021 return CMD_WARNING;
9022 }
9023
9024 table = bgp->rib[afi][safi];
9025 /* use MPLS and ENCAP specific shows until they are merged */
9026 if (safi == SAFI_MPLS_VPN) {
9027 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
9028 output_arg, use_json);
9029 }
9030
9031 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
9032 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
9033 output_arg, use_json,
9034 1, NULL, NULL);
9035 }
9036 /* labeled-unicast routes live in the unicast table */
9037 else if (safi == SAFI_LABELED_UNICAST)
9038 safi = SAFI_UNICAST;
9039
9040 return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json,
9041 NULL, 1, NULL, NULL, &json_header_depth);
9042 }
9043
9044 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
9045 safi_t safi, bool use_json)
9046 {
9047 struct listnode *node, *nnode;
9048 struct bgp *bgp;
9049 int is_first = 1;
9050 bool route_output = false;
9051
9052 if (use_json)
9053 vty_out(vty, "{\n");
9054
9055 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
9056 route_output = true;
9057 if (use_json) {
9058 if (!is_first)
9059 vty_out(vty, ",\n");
9060 else
9061 is_first = 0;
9062
9063 vty_out(vty, "\"%s\":",
9064 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9065 ? VRF_DEFAULT_NAME
9066 : bgp->name);
9067 } else {
9068 vty_out(vty, "\nInstance %s:\n",
9069 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9070 ? VRF_DEFAULT_NAME
9071 : bgp->name);
9072 }
9073 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
9074 use_json);
9075 }
9076
9077 if (use_json)
9078 vty_out(vty, "}\n");
9079 else if (!route_output)
9080 vty_out(vty, "%% BGP instance not found\n");
9081 }
9082
9083 /* Header of detailed BGP route information */
9084 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
9085 struct bgp_node *rn, struct prefix_rd *prd,
9086 afi_t afi, safi_t safi, json_object *json)
9087 {
9088 struct bgp_path_info *pi;
9089 struct prefix *p;
9090 struct peer *peer;
9091 struct listnode *node, *nnode;
9092 char buf1[RD_ADDRSTRLEN];
9093 char buf2[INET6_ADDRSTRLEN];
9094 char buf3[EVPN_ROUTE_STRLEN];
9095 char prefix_str[BUFSIZ];
9096 int count = 0;
9097 int best = 0;
9098 int suppress = 0;
9099 int accept_own = 0;
9100 int route_filter_translated_v4 = 0;
9101 int route_filter_v4 = 0;
9102 int route_filter_translated_v6 = 0;
9103 int route_filter_v6 = 0;
9104 int llgr_stale = 0;
9105 int no_llgr = 0;
9106 int accept_own_nexthop = 0;
9107 int blackhole = 0;
9108 int no_export = 0;
9109 int no_advertise = 0;
9110 int local_as = 0;
9111 int no_peer = 0;
9112 int first = 1;
9113 int has_valid_label = 0;
9114 mpls_label_t label = 0;
9115 json_object *json_adv_to = NULL;
9116
9117 p = &rn->p;
9118 has_valid_label = bgp_is_valid_label(&rn->local_label);
9119
9120 if (has_valid_label)
9121 label = label_pton(&rn->local_label);
9122
9123 if (json) {
9124 if (has_valid_label)
9125 json_object_int_add(json, "localLabel", label);
9126
9127 json_object_string_add(
9128 json, "prefix",
9129 prefix2str(p, prefix_str, sizeof(prefix_str)));
9130 } else {
9131 if (safi == SAFI_EVPN)
9132 vty_out(vty, "BGP routing table entry for %s%s%s\n",
9133 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
9134 : "",
9135 prd ? ":" : "",
9136 bgp_evpn_route2str((struct prefix_evpn *)p,
9137 buf3, sizeof(buf3)));
9138 else
9139 vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
9140 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9141 ? prefix_rd2str(prd, buf1,
9142 sizeof(buf1))
9143 : ""),
9144 safi == SAFI_MPLS_VPN ? ":" : "",
9145 inet_ntop(p->family, &p->u.prefix, buf2,
9146 INET6_ADDRSTRLEN),
9147 p->prefixlen);
9148
9149 if (has_valid_label)
9150 vty_out(vty, "Local label: %d\n", label);
9151 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
9152 vty_out(vty, "not allocated\n");
9153 }
9154
9155 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
9156 count++;
9157 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
9158 best = count;
9159 if (pi->extra && pi->extra->suppress)
9160 suppress = 1;
9161
9162 if (pi->attr->community == NULL)
9163 continue;
9164
9165 no_advertise += community_include(
9166 pi->attr->community, COMMUNITY_NO_ADVERTISE);
9167 no_export += community_include(pi->attr->community,
9168 COMMUNITY_NO_EXPORT);
9169 local_as += community_include(pi->attr->community,
9170 COMMUNITY_LOCAL_AS);
9171 accept_own += community_include(pi->attr->community,
9172 COMMUNITY_ACCEPT_OWN);
9173 route_filter_translated_v4 += community_include(
9174 pi->attr->community,
9175 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
9176 route_filter_translated_v6 += community_include(
9177 pi->attr->community,
9178 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
9179 route_filter_v4 += community_include(
9180 pi->attr->community, COMMUNITY_ROUTE_FILTER_v4);
9181 route_filter_v6 += community_include(
9182 pi->attr->community, COMMUNITY_ROUTE_FILTER_v6);
9183 llgr_stale += community_include(pi->attr->community,
9184 COMMUNITY_LLGR_STALE);
9185 no_llgr += community_include(pi->attr->community,
9186 COMMUNITY_NO_LLGR);
9187 accept_own_nexthop +=
9188 community_include(pi->attr->community,
9189 COMMUNITY_ACCEPT_OWN_NEXTHOP);
9190 blackhole += community_include(pi->attr->community,
9191 COMMUNITY_BLACKHOLE);
9192 no_peer += community_include(pi->attr->community,
9193 COMMUNITY_NO_PEER);
9194 }
9195 }
9196
9197 if (!json) {
9198 vty_out(vty, "Paths: (%d available", count);
9199 if (best) {
9200 vty_out(vty, ", best #%d", best);
9201 if (safi == SAFI_UNICAST)
9202 vty_out(vty, ", table %s",
9203 (bgp->inst_type
9204 == BGP_INSTANCE_TYPE_DEFAULT)
9205 ? VRF_DEFAULT_NAME
9206 : bgp->name);
9207 } else
9208 vty_out(vty, ", no best path");
9209
9210 if (accept_own)
9211 vty_out(vty,
9212 ", accept own local route exported and imported in different VRF");
9213 else if (route_filter_translated_v4)
9214 vty_out(vty,
9215 ", mark translated RTs for VPNv4 route filtering");
9216 else if (route_filter_v4)
9217 vty_out(vty,
9218 ", attach RT as-is for VPNv4 route filtering");
9219 else if (route_filter_translated_v6)
9220 vty_out(vty,
9221 ", mark translated RTs for VPNv6 route filtering");
9222 else if (route_filter_v6)
9223 vty_out(vty,
9224 ", attach RT as-is for VPNv6 route filtering");
9225 else if (llgr_stale)
9226 vty_out(vty,
9227 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
9228 else if (no_llgr)
9229 vty_out(vty,
9230 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
9231 else if (accept_own_nexthop)
9232 vty_out(vty,
9233 ", accept local nexthop");
9234 else if (blackhole)
9235 vty_out(vty, ", inform peer to blackhole prefix");
9236 else if (no_export)
9237 vty_out(vty, ", not advertised to EBGP peer");
9238 else if (no_advertise)
9239 vty_out(vty, ", not advertised to any peer");
9240 else if (local_as)
9241 vty_out(vty, ", not advertised outside local AS");
9242 else if (no_peer)
9243 vty_out(vty,
9244 ", inform EBGP peer not to advertise to their EBGP peers");
9245
9246 if (suppress)
9247 vty_out(vty,
9248 ", Advertisements suppressed by an aggregate.");
9249 vty_out(vty, ")\n");
9250 }
9251
9252 /* If we are not using addpath then we can display Advertised to and
9253 * that will
9254 * show what peers we advertised the bestpath to. If we are using
9255 * addpath
9256 * though then we must display Advertised to on a path-by-path basis. */
9257 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
9258 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
9259 if (bgp_adj_out_lookup(peer, rn, 0)) {
9260 if (json && !json_adv_to)
9261 json_adv_to = json_object_new_object();
9262
9263 route_vty_out_advertised_to(
9264 vty, peer, &first,
9265 " Advertised to non peer-group peers:\n ",
9266 json_adv_to);
9267 }
9268 }
9269
9270 if (json) {
9271 if (json_adv_to) {
9272 json_object_object_add(json, "advertisedTo",
9273 json_adv_to);
9274 }
9275 } else {
9276 if (first)
9277 vty_out(vty, " Not advertised to any peer");
9278 vty_out(vty, "\n");
9279 }
9280 }
9281 }
9282
9283 /* Display specified route of BGP table. */
9284 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
9285 struct bgp_table *rib, const char *ip_str,
9286 afi_t afi, safi_t safi,
9287 struct prefix_rd *prd, int prefix_check,
9288 enum bgp_path_type pathtype, bool use_json)
9289 {
9290 int ret;
9291 int header;
9292 int display = 0;
9293 struct prefix match;
9294 struct bgp_node *rn;
9295 struct bgp_node *rm;
9296 struct bgp_path_info *pi;
9297 struct bgp_table *table;
9298 json_object *json = NULL;
9299 json_object *json_paths = NULL;
9300
9301 /* Check IP address argument. */
9302 ret = str2prefix(ip_str, &match);
9303 if (!ret) {
9304 vty_out(vty, "address is malformed\n");
9305 return CMD_WARNING;
9306 }
9307
9308 match.family = afi2family(afi);
9309
9310 if (use_json) {
9311 json = json_object_new_object();
9312 json_paths = json_object_new_array();
9313 }
9314
9315 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
9316 for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
9317 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
9318 continue;
9319 table = bgp_node_get_bgp_table_info(rn);
9320 if (!table)
9321 continue;
9322
9323 header = 1;
9324
9325 if ((rm = bgp_node_match(table, &match)) == NULL)
9326 continue;
9327
9328 if (prefix_check
9329 && rm->p.prefixlen != match.prefixlen) {
9330 bgp_unlock_node(rm);
9331 continue;
9332 }
9333
9334 for (pi = bgp_node_get_bgp_path_info(rm); pi;
9335 pi = pi->next) {
9336 if (header) {
9337 route_vty_out_detail_header(
9338 vty, bgp, rm,
9339 (struct prefix_rd *)&rn->p,
9340 AFI_IP, safi, json);
9341 header = 0;
9342 }
9343 display++;
9344
9345 if (pathtype == BGP_PATH_SHOW_ALL
9346 || (pathtype == BGP_PATH_SHOW_BESTPATH
9347 && CHECK_FLAG(pi->flags,
9348 BGP_PATH_SELECTED))
9349 || (pathtype == BGP_PATH_SHOW_MULTIPATH
9350 && (CHECK_FLAG(pi->flags,
9351 BGP_PATH_MULTIPATH)
9352 || CHECK_FLAG(pi->flags,
9353 BGP_PATH_SELECTED))))
9354 route_vty_out_detail(vty, bgp, &rm->p,
9355 pi, AFI_IP, safi,
9356 json_paths);
9357 }
9358
9359 bgp_unlock_node(rm);
9360 }
9361 } else if (safi == SAFI_FLOWSPEC) {
9362 display = bgp_flowspec_display_match_per_ip(afi, rib,
9363 &match, prefix_check,
9364 vty,
9365 use_json,
9366 json_paths);
9367 } else {
9368 header = 1;
9369
9370 if ((rn = bgp_node_match(rib, &match)) != NULL) {
9371 if (!prefix_check
9372 || rn->p.prefixlen == match.prefixlen) {
9373 for (pi = bgp_node_get_bgp_path_info(rn); pi;
9374 pi = pi->next) {
9375 if (header) {
9376 route_vty_out_detail_header(
9377 vty, bgp, rn, NULL, afi,
9378 safi, json);
9379 header = 0;
9380 }
9381 display++;
9382
9383 if (pathtype == BGP_PATH_SHOW_ALL
9384 || (pathtype
9385 == BGP_PATH_SHOW_BESTPATH
9386 && CHECK_FLAG(
9387 pi->flags,
9388 BGP_PATH_SELECTED))
9389 || (pathtype
9390 == BGP_PATH_SHOW_MULTIPATH
9391 && (CHECK_FLAG(
9392 pi->flags,
9393 BGP_PATH_MULTIPATH)
9394 || CHECK_FLAG(
9395 pi->flags,
9396 BGP_PATH_SELECTED))))
9397 route_vty_out_detail(
9398 vty, bgp, &rn->p, pi,
9399 afi, safi, json_paths);
9400 }
9401 }
9402
9403 bgp_unlock_node(rn);
9404 }
9405 }
9406
9407 if (use_json) {
9408 if (display)
9409 json_object_object_add(json, "paths", json_paths);
9410
9411 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9412 json, JSON_C_TO_STRING_PRETTY));
9413 json_object_free(json);
9414 } else {
9415 if (!display) {
9416 vty_out(vty, "%% Network not in table\n");
9417 return CMD_WARNING;
9418 }
9419 }
9420
9421 return CMD_SUCCESS;
9422 }
9423
9424 /* Display specified route of Main RIB */
9425 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
9426 afi_t afi, safi_t safi, struct prefix_rd *prd,
9427 int prefix_check, enum bgp_path_type pathtype,
9428 bool use_json)
9429 {
9430 if (!bgp) {
9431 bgp = bgp_get_default();
9432 if (!bgp) {
9433 if (!use_json)
9434 vty_out(vty, "No BGP process is configured\n");
9435 else
9436 vty_out(vty, "{}\n");
9437 return CMD_WARNING;
9438 }
9439 }
9440
9441 /* labeled-unicast routes live in the unicast table */
9442 if (safi == SAFI_LABELED_UNICAST)
9443 safi = SAFI_UNICAST;
9444
9445 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
9446 afi, safi, prd, prefix_check, pathtype,
9447 use_json);
9448 }
9449
9450 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
9451 struct cmd_token **argv, afi_t afi, safi_t safi,
9452 bool uj)
9453 {
9454 struct lcommunity *lcom;
9455 struct buffer *b;
9456 int i;
9457 char *str;
9458 int first = 0;
9459
9460 b = buffer_new(1024);
9461 for (i = 0; i < argc; i++) {
9462 if (first)
9463 buffer_putc(b, ' ');
9464 else {
9465 if (strmatch(argv[i]->text, "AA:BB:CC")) {
9466 first = 1;
9467 buffer_putstr(b, argv[i]->arg);
9468 }
9469 }
9470 }
9471 buffer_putc(b, '\0');
9472
9473 str = buffer_getstr(b);
9474 buffer_free(b);
9475
9476 lcom = lcommunity_str2com(str);
9477 XFREE(MTYPE_TMP, str);
9478 if (!lcom) {
9479 vty_out(vty, "%% Large-community malformed\n");
9480 return CMD_WARNING;
9481 }
9482
9483 return bgp_show(vty, bgp, afi, safi, bgp_show_type_lcommunity, lcom,
9484 uj);
9485 }
9486
9487 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
9488 const char *lcom, afi_t afi, safi_t safi,
9489 bool uj)
9490 {
9491 struct community_list *list;
9492
9493 list = community_list_lookup(bgp_clist, lcom, 0,
9494 LARGE_COMMUNITY_LIST_MASTER);
9495 if (list == NULL) {
9496 vty_out(vty, "%% %s is not a valid large-community-list name\n",
9497 lcom);
9498 return CMD_WARNING;
9499 }
9500
9501 return bgp_show(vty, bgp, afi, safi, bgp_show_type_lcommunity_list,
9502 list, uj);
9503 }
9504
9505 DEFUN (show_ip_bgp_large_community_list,
9506 show_ip_bgp_large_community_list_cmd,
9507 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community-list <(1-500)|WORD> [json]",
9508 SHOW_STR
9509 IP_STR
9510 BGP_STR
9511 BGP_INSTANCE_HELP_STR
9512 BGP_AFI_HELP_STR
9513 BGP_SAFI_WITH_LABEL_HELP_STR
9514 "Display routes matching the large-community-list\n"
9515 "large-community-list number\n"
9516 "large-community-list name\n"
9517 JSON_STR)
9518 {
9519 char *vrf = NULL;
9520 afi_t afi = AFI_IP6;
9521 safi_t safi = SAFI_UNICAST;
9522 int idx = 0;
9523
9524 if (argv_find(argv, argc, "ip", &idx))
9525 afi = AFI_IP;
9526 if (argv_find(argv, argc, "view", &idx)
9527 || argv_find(argv, argc, "vrf", &idx))
9528 vrf = argv[++idx]->arg;
9529 if (argv_find(argv, argc, "ipv4", &idx)
9530 || argv_find(argv, argc, "ipv6", &idx)) {
9531 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
9532 if (argv_find(argv, argc, "unicast", &idx)
9533 || argv_find(argv, argc, "multicast", &idx))
9534 safi = bgp_vty_safi_from_str(argv[idx]->text);
9535 }
9536
9537 bool uj = use_json(argc, argv);
9538
9539 struct bgp *bgp = bgp_lookup_by_name(vrf);
9540 if (bgp == NULL) {
9541 vty_out(vty, "Can't find BGP instance %s\n", vrf);
9542 return CMD_WARNING;
9543 }
9544
9545 argv_find(argv, argc, "large-community-list", &idx);
9546 return bgp_show_lcommunity_list(vty, bgp, argv[idx + 1]->arg, afi, safi,
9547 uj);
9548 }
9549 DEFUN (show_ip_bgp_large_community,
9550 show_ip_bgp_large_community_cmd,
9551 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [AA:BB:CC] [json]",
9552 SHOW_STR
9553 IP_STR
9554 BGP_STR
9555 BGP_INSTANCE_HELP_STR
9556 BGP_AFI_HELP_STR
9557 BGP_SAFI_WITH_LABEL_HELP_STR
9558 "Display routes matching the large-communities\n"
9559 "List of large-community numbers\n"
9560 JSON_STR)
9561 {
9562 char *vrf = NULL;
9563 afi_t afi = AFI_IP6;
9564 safi_t safi = SAFI_UNICAST;
9565 int idx = 0;
9566
9567 if (argv_find(argv, argc, "ip", &idx))
9568 afi = AFI_IP;
9569 if (argv_find(argv, argc, "view", &idx)
9570 || argv_find(argv, argc, "vrf", &idx))
9571 vrf = argv[++idx]->arg;
9572 if (argv_find(argv, argc, "ipv4", &idx)
9573 || argv_find(argv, argc, "ipv6", &idx)) {
9574 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
9575 if (argv_find(argv, argc, "unicast", &idx)
9576 || argv_find(argv, argc, "multicast", &idx))
9577 safi = bgp_vty_safi_from_str(argv[idx]->text);
9578 }
9579
9580 bool uj = use_json(argc, argv);
9581
9582 struct bgp *bgp = bgp_lookup_by_name(vrf);
9583 if (bgp == NULL) {
9584 vty_out(vty, "Can't find BGP instance %s\n", vrf);
9585 return CMD_WARNING;
9586 }
9587
9588 if (argv_find(argv, argc, "AA:BB:CC", &idx))
9589 return bgp_show_lcommunity(vty, bgp, argc, argv, afi, safi, uj);
9590 else
9591 return bgp_show(vty, bgp, afi, safi,
9592 bgp_show_type_lcommunity_all, NULL, uj);
9593 }
9594
9595 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
9596 safi_t safi);
9597
9598
9599 /* BGP route print out function without JSON */
9600 DEFUN (show_ip_bgp,
9601 show_ip_bgp_cmd,
9602 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
9603 <dampening <parameters>\
9604 |route-map WORD\
9605 |prefix-list WORD\
9606 |filter-list WORD\
9607 |statistics\
9608 |community-list <(1-500)|WORD> [exact-match]\
9609 |A.B.C.D/M longer-prefixes\
9610 |X:X::X:X/M longer-prefixes\
9611 >",
9612 SHOW_STR
9613 IP_STR
9614 BGP_STR
9615 BGP_INSTANCE_HELP_STR
9616 BGP_AFI_HELP_STR
9617 BGP_SAFI_WITH_LABEL_HELP_STR
9618 "Display detailed information about dampening\n"
9619 "Display detail of configured dampening parameters\n"
9620 "Display routes matching the route-map\n"
9621 "A route-map to match on\n"
9622 "Display routes conforming to the prefix-list\n"
9623 "Prefix-list name\n"
9624 "Display routes conforming to the filter-list\n"
9625 "Regular expression access list name\n"
9626 "BGP RIB advertisement statistics\n"
9627 "Display routes matching the community-list\n"
9628 "community-list number\n"
9629 "community-list name\n"
9630 "Exact match of the communities\n"
9631 "IPv4 prefix\n"
9632 "Display route and more specific routes\n"
9633 "IPv6 prefix\n"
9634 "Display route and more specific routes\n")
9635 {
9636 afi_t afi = AFI_IP6;
9637 safi_t safi = SAFI_UNICAST;
9638 int exact_match = 0;
9639 struct bgp *bgp = NULL;
9640 int idx = 0;
9641
9642 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9643 &bgp, false);
9644 if (!idx)
9645 return CMD_WARNING;
9646
9647 if (argv_find(argv, argc, "dampening", &idx)) {
9648 if (argv_find(argv, argc, "parameters", &idx))
9649 return bgp_show_dampening_parameters(vty, afi, safi);
9650 }
9651
9652 if (argv_find(argv, argc, "prefix-list", &idx))
9653 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
9654 safi, bgp_show_type_prefix_list);
9655
9656 if (argv_find(argv, argc, "filter-list", &idx))
9657 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
9658 safi, bgp_show_type_filter_list);
9659
9660 if (argv_find(argv, argc, "statistics", &idx))
9661 return bgp_table_stats(vty, bgp, afi, safi);
9662
9663 if (argv_find(argv, argc, "route-map", &idx))
9664 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
9665 safi, bgp_show_type_route_map);
9666
9667 if (argv_find(argv, argc, "community-list", &idx)) {
9668 const char *clist_number_or_name = argv[++idx]->arg;
9669 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
9670 exact_match = 1;
9671 return bgp_show_community_list(vty, bgp, clist_number_or_name,
9672 exact_match, afi, safi);
9673 }
9674 /* prefix-longer */
9675 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
9676 || argv_find(argv, argc, "X:X::X:X/M", &idx))
9677 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
9678 safi,
9679 bgp_show_type_prefix_longer);
9680
9681 return CMD_WARNING;
9682 }
9683
9684 /* BGP route print out function with JSON */
9685 DEFUN (show_ip_bgp_json,
9686 show_ip_bgp_json_cmd,
9687 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
9688 [cidr-only\
9689 |dampening <flap-statistics|dampened-paths>\
9690 |community [AA:NN|local-AS|no-advertise|no-export\
9691 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
9692 |accept-own|accept-own-nexthop|route-filter-v6\
9693 |route-filter-v4|route-filter-translated-v6\
9694 |route-filter-translated-v4] [exact-match]\
9695 ] [json]",
9696 SHOW_STR
9697 IP_STR
9698 BGP_STR
9699 BGP_INSTANCE_HELP_STR
9700 BGP_AFI_HELP_STR
9701 BGP_SAFI_WITH_LABEL_HELP_STR
9702 "Display only routes with non-natural netmasks\n"
9703 "Display detailed information about dampening\n"
9704 "Display flap statistics of routes\n"
9705 "Display paths suppressed due to dampening\n"
9706 "Display routes matching the communities\n"
9707 COMMUNITY_AANN_STR
9708 "Do not send outside local AS (well-known community)\n"
9709 "Do not advertise to any peer (well-known community)\n"
9710 "Do not export to next AS (well-known community)\n"
9711 "Graceful shutdown (well-known community)\n"
9712 "Do not export to any peer (well-known community)\n"
9713 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
9714 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
9715 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
9716 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
9717 "Should accept VPN route with local nexthop (well-known community)\n"
9718 "RT VPNv6 route filtering (well-known community)\n"
9719 "RT VPNv4 route filtering (well-known community)\n"
9720 "RT translated VPNv6 route filtering (well-known community)\n"
9721 "RT translated VPNv4 route filtering (well-known community)\n"
9722 "Exact match of the communities\n"
9723 JSON_STR)
9724 {
9725 afi_t afi = AFI_IP6;
9726 safi_t safi = SAFI_UNICAST;
9727 enum bgp_show_type sh_type = bgp_show_type_normal;
9728 struct bgp *bgp = NULL;
9729 int idx = 0;
9730 int exact_match = 0;
9731 bool uj = use_json(argc, argv);
9732
9733 if (uj)
9734 argc--;
9735
9736 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9737 &bgp, uj);
9738 if (!idx)
9739 return CMD_WARNING;
9740
9741 if (argv_find(argv, argc, "cidr-only", &idx))
9742 return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only,
9743 NULL, uj);
9744
9745 if (argv_find(argv, argc, "dampening", &idx)) {
9746 if (argv_find(argv, argc, "dampened-paths", &idx))
9747 return bgp_show(vty, bgp, afi, safi,
9748 bgp_show_type_dampend_paths, NULL, uj);
9749 else if (argv_find(argv, argc, "flap-statistics", &idx))
9750 return bgp_show(vty, bgp, afi, safi,
9751 bgp_show_type_flap_statistics, NULL,
9752 uj);
9753 }
9754
9755 if (argv_find(argv, argc, "community", &idx)) {
9756 char *maybecomm = NULL;
9757 char *community = NULL;
9758
9759 if (idx + 1 < argc) {
9760 if (argv[idx + 1]->type == VARIABLE_TKN)
9761 maybecomm = argv[idx + 1]->arg;
9762 else
9763 maybecomm = argv[idx + 1]->text;
9764 }
9765
9766 if (maybecomm && !strmatch(maybecomm, "json")
9767 && !strmatch(maybecomm, "exact-match"))
9768 community = maybecomm;
9769
9770 if (argv_find(argv, argc, "exact-match", &idx))
9771 exact_match = 1;
9772
9773 if (community)
9774 return bgp_show_community(vty, bgp, community,
9775 exact_match, afi, safi, uj);
9776 else
9777 return (bgp_show(vty, bgp, afi, safi,
9778 bgp_show_type_community_all, NULL,
9779 uj));
9780 }
9781
9782 return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
9783 }
9784
9785 DEFUN (show_ip_bgp_route,
9786 show_ip_bgp_route_cmd,
9787 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]"
9788 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
9789 SHOW_STR
9790 IP_STR
9791 BGP_STR
9792 BGP_INSTANCE_HELP_STR
9793 BGP_AFI_HELP_STR
9794 BGP_SAFI_WITH_LABEL_HELP_STR
9795 "Network in the BGP routing table to display\n"
9796 "IPv4 prefix\n"
9797 "Network in the BGP routing table to display\n"
9798 "IPv6 prefix\n"
9799 "Display only the bestpath\n"
9800 "Display only multipaths\n"
9801 JSON_STR)
9802 {
9803 int prefix_check = 0;
9804
9805 afi_t afi = AFI_IP6;
9806 safi_t safi = SAFI_UNICAST;
9807 char *prefix = NULL;
9808 struct bgp *bgp = NULL;
9809 enum bgp_path_type path_type;
9810 bool uj = use_json(argc, argv);
9811
9812 int idx = 0;
9813
9814 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9815 &bgp, uj);
9816 if (!idx)
9817 return CMD_WARNING;
9818
9819 if (!bgp) {
9820 vty_out(vty,
9821 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
9822 return CMD_WARNING;
9823 }
9824
9825 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
9826 if (argv_find(argv, argc, "A.B.C.D", &idx)
9827 || argv_find(argv, argc, "X:X::X:X", &idx))
9828 prefix_check = 0;
9829 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
9830 || argv_find(argv, argc, "X:X::X:X/M", &idx))
9831 prefix_check = 1;
9832
9833 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
9834 && afi != AFI_IP6) {
9835 vty_out(vty,
9836 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
9837 return CMD_WARNING;
9838 }
9839 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
9840 && afi != AFI_IP) {
9841 vty_out(vty,
9842 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
9843 return CMD_WARNING;
9844 }
9845
9846 prefix = argv[idx]->arg;
9847
9848 /* [<bestpath|multipath>] */
9849 if (argv_find(argv, argc, "bestpath", &idx))
9850 path_type = BGP_PATH_SHOW_BESTPATH;
9851 else if (argv_find(argv, argc, "multipath", &idx))
9852 path_type = BGP_PATH_SHOW_MULTIPATH;
9853 else
9854 path_type = BGP_PATH_SHOW_ALL;
9855
9856 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
9857 path_type, uj);
9858 }
9859
9860 DEFUN (show_ip_bgp_regexp,
9861 show_ip_bgp_regexp_cmd,
9862 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX...",
9863 SHOW_STR
9864 IP_STR
9865 BGP_STR
9866 BGP_INSTANCE_HELP_STR
9867 BGP_AFI_HELP_STR
9868 BGP_SAFI_WITH_LABEL_HELP_STR
9869 "Display routes matching the AS path regular expression\n"
9870 "A regular-expression to match the BGP AS paths\n")
9871 {
9872 afi_t afi = AFI_IP6;
9873 safi_t safi = SAFI_UNICAST;
9874 struct bgp *bgp = NULL;
9875
9876 int idx = 0;
9877 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9878 &bgp, false);
9879 if (!idx)
9880 return CMD_WARNING;
9881
9882 // get index of regex
9883 argv_find(argv, argc, "regexp", &idx);
9884 idx++;
9885
9886 char *regstr = argv_concat(argv, argc, idx);
9887 int rc = bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
9888 bgp_show_type_regexp);
9889 XFREE(MTYPE_TMP, regstr);
9890 return rc;
9891 }
9892
9893 DEFUN (show_ip_bgp_instance_all,
9894 show_ip_bgp_instance_all_cmd,
9895 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json]",
9896 SHOW_STR
9897 IP_STR
9898 BGP_STR
9899 BGP_INSTANCE_ALL_HELP_STR
9900 BGP_AFI_HELP_STR
9901 BGP_SAFI_WITH_LABEL_HELP_STR
9902 JSON_STR)
9903 {
9904 afi_t afi = AFI_IP;
9905 safi_t safi = SAFI_UNICAST;
9906 struct bgp *bgp = NULL;
9907 int idx = 0;
9908 bool uj = use_json(argc, argv);
9909
9910 if (uj)
9911 argc--;
9912
9913 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
9914 &bgp, uj);
9915 if (!idx)
9916 return CMD_WARNING;
9917
9918 bgp_show_all_instances_routes_vty(vty, afi, safi, uj);
9919 return CMD_SUCCESS;
9920 }
9921
9922 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
9923 afi_t afi, safi_t safi, enum bgp_show_type type)
9924 {
9925 regex_t *regex;
9926 int rc;
9927
9928 regex = bgp_regcomp(regstr);
9929 if (!regex) {
9930 vty_out(vty, "Can't compile regexp %s\n", regstr);
9931 return CMD_WARNING;
9932 }
9933
9934 rc = bgp_show(vty, bgp, afi, safi, type, regex, 0);
9935 bgp_regex_free(regex);
9936 return rc;
9937 }
9938
9939 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
9940 const char *prefix_list_str, afi_t afi,
9941 safi_t safi, enum bgp_show_type type)
9942 {
9943 struct prefix_list *plist;
9944
9945 plist = prefix_list_lookup(afi, prefix_list_str);
9946 if (plist == NULL) {
9947 vty_out(vty, "%% %s is not a valid prefix-list name\n",
9948 prefix_list_str);
9949 return CMD_WARNING;
9950 }
9951
9952 return bgp_show(vty, bgp, afi, safi, type, plist, 0);
9953 }
9954
9955 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
9956 const char *filter, afi_t afi, safi_t safi,
9957 enum bgp_show_type type)
9958 {
9959 struct as_list *as_list;
9960
9961 as_list = as_list_lookup(filter);
9962 if (as_list == NULL) {
9963 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
9964 filter);
9965 return CMD_WARNING;
9966 }
9967
9968 return bgp_show(vty, bgp, afi, safi, type, as_list, 0);
9969 }
9970
9971 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
9972 const char *rmap_str, afi_t afi, safi_t safi,
9973 enum bgp_show_type type)
9974 {
9975 struct route_map *rmap;
9976
9977 rmap = route_map_lookup_by_name(rmap_str);
9978 if (!rmap) {
9979 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
9980 return CMD_WARNING;
9981 }
9982
9983 return bgp_show(vty, bgp, afi, safi, type, rmap, 0);
9984 }
9985
9986 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
9987 const char *comstr, int exact, afi_t afi,
9988 safi_t safi, bool use_json)
9989 {
9990 struct community *com;
9991 int ret = 0;
9992
9993 com = community_str2com(comstr);
9994 if (!com) {
9995 vty_out(vty, "%% Community malformed: %s\n", comstr);
9996 return CMD_WARNING;
9997 }
9998
9999 ret = bgp_show(vty, bgp, afi, safi,
10000 (exact ? bgp_show_type_community_exact
10001 : bgp_show_type_community),
10002 com, use_json);
10003 community_free(&com);
10004
10005 return ret;
10006 }
10007
10008 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
10009 const char *com, int exact, afi_t afi,
10010 safi_t safi)
10011 {
10012 struct community_list *list;
10013
10014 list = community_list_lookup(bgp_clist, com, 0, COMMUNITY_LIST_MASTER);
10015 if (list == NULL) {
10016 vty_out(vty, "%% %s is not a valid community-list name\n", com);
10017 return CMD_WARNING;
10018 }
10019
10020 return bgp_show(vty, bgp, afi, safi,
10021 (exact ? bgp_show_type_community_list_exact
10022 : bgp_show_type_community_list),
10023 list, 0);
10024 }
10025
10026 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
10027 const char *prefix, afi_t afi, safi_t safi,
10028 enum bgp_show_type type)
10029 {
10030 int ret;
10031 struct prefix *p;
10032
10033 p = prefix_new();
10034
10035 ret = str2prefix(prefix, p);
10036 if (!ret) {
10037 vty_out(vty, "%% Malformed Prefix\n");
10038 return CMD_WARNING;
10039 }
10040
10041 ret = bgp_show(vty, bgp, afi, safi, type, p, 0);
10042 prefix_free(p);
10043 return ret;
10044 }
10045
10046 static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
10047 const char *ip_str, bool use_json)
10048 {
10049 int ret;
10050 struct peer *peer;
10051 union sockunion su;
10052
10053 /* Get peer sockunion. */
10054 ret = str2sockunion(ip_str, &su);
10055 if (ret < 0) {
10056 peer = peer_lookup_by_conf_if(bgp, ip_str);
10057 if (!peer) {
10058 peer = peer_lookup_by_hostname(bgp, ip_str);
10059
10060 if (!peer) {
10061 if (use_json) {
10062 json_object *json_no = NULL;
10063 json_no = json_object_new_object();
10064 json_object_string_add(
10065 json_no,
10066 "malformedAddressOrName",
10067 ip_str);
10068 vty_out(vty, "%s\n",
10069 json_object_to_json_string_ext(
10070 json_no,
10071 JSON_C_TO_STRING_PRETTY));
10072 json_object_free(json_no);
10073 } else
10074 vty_out(vty,
10075 "%% Malformed address or name: %s\n",
10076 ip_str);
10077 return NULL;
10078 }
10079 }
10080 return peer;
10081 }
10082
10083 /* Peer structure lookup. */
10084 peer = peer_lookup(bgp, &su);
10085 if (!peer) {
10086 if (use_json) {
10087 json_object *json_no = NULL;
10088 json_no = json_object_new_object();
10089 json_object_string_add(json_no, "warning",
10090 "No such neighbor in this view/vrf");
10091 vty_out(vty, "%s\n",
10092 json_object_to_json_string_ext(
10093 json_no, JSON_C_TO_STRING_PRETTY));
10094 json_object_free(json_no);
10095 } else
10096 vty_out(vty, "No such neighbor in this view/vrf\n");
10097 return NULL;
10098 }
10099
10100 return peer;
10101 }
10102
10103 enum bgp_stats {
10104 BGP_STATS_MAXBITLEN = 0,
10105 BGP_STATS_RIB,
10106 BGP_STATS_PREFIXES,
10107 BGP_STATS_TOTPLEN,
10108 BGP_STATS_UNAGGREGATEABLE,
10109 BGP_STATS_MAX_AGGREGATEABLE,
10110 BGP_STATS_AGGREGATES,
10111 BGP_STATS_SPACE,
10112 BGP_STATS_ASPATH_COUNT,
10113 BGP_STATS_ASPATH_MAXHOPS,
10114 BGP_STATS_ASPATH_TOTHOPS,
10115 BGP_STATS_ASPATH_MAXSIZE,
10116 BGP_STATS_ASPATH_TOTSIZE,
10117 BGP_STATS_ASN_HIGHEST,
10118 BGP_STATS_MAX,
10119 };
10120
10121 static const char *table_stats_strs[] = {
10122 [BGP_STATS_PREFIXES] = "Total Prefixes",
10123 [BGP_STATS_TOTPLEN] = "Average prefix length",
10124 [BGP_STATS_RIB] = "Total Advertisements",
10125 [BGP_STATS_UNAGGREGATEABLE] = "Unaggregateable prefixes",
10126 [BGP_STATS_MAX_AGGREGATEABLE] =
10127 "Maximum aggregateable prefixes",
10128 [BGP_STATS_AGGREGATES] = "BGP Aggregate advertisements",
10129 [BGP_STATS_SPACE] = "Address space advertised",
10130 [BGP_STATS_ASPATH_COUNT] = "Advertisements with paths",
10131 [BGP_STATS_ASPATH_MAXHOPS] = "Longest AS-Path (hops)",
10132 [BGP_STATS_ASPATH_MAXSIZE] = "Largest AS-Path (bytes)",
10133 [BGP_STATS_ASPATH_TOTHOPS] = "Average AS-Path length (hops)",
10134 [BGP_STATS_ASPATH_TOTSIZE] = "Average AS-Path size (bytes)",
10135 [BGP_STATS_ASN_HIGHEST] = "Highest public ASN",
10136 [BGP_STATS_MAX] = NULL,
10137 };
10138
10139 struct bgp_table_stats {
10140 struct bgp_table *table;
10141 unsigned long long counts[BGP_STATS_MAX];
10142 double total_space;
10143 };
10144
10145 #if 0
10146 #define TALLY_SIGFIG 100000
10147 static unsigned long
10148 ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
10149 {
10150 unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
10151 unsigned long res = (newtot * TALLY_SIGFIG) / count;
10152 unsigned long ret = newtot / count;
10153
10154 if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
10155 return ret + 1;
10156 else
10157 return ret;
10158 }
10159 #endif
10160
10161 static int bgp_table_stats_walker(struct thread *t)
10162 {
10163 struct bgp_node *rn;
10164 struct bgp_node *top;
10165 struct bgp_table_stats *ts = THREAD_ARG(t);
10166 unsigned int space = 0;
10167
10168 if (!(top = bgp_table_top(ts->table)))
10169 return 0;
10170
10171 switch (top->p.family) {
10172 case AF_INET:
10173 space = IPV4_MAX_BITLEN;
10174 break;
10175 case AF_INET6:
10176 space = IPV6_MAX_BITLEN;
10177 break;
10178 }
10179
10180 ts->counts[BGP_STATS_MAXBITLEN] = space;
10181
10182 for (rn = top; rn; rn = bgp_route_next(rn)) {
10183 struct bgp_path_info *pi;
10184 struct bgp_node *prn = bgp_node_parent_nolock(rn);
10185 unsigned int pinum = 0;
10186
10187 if (rn == top)
10188 continue;
10189
10190 if (!bgp_node_has_bgp_path_info_data(rn))
10191 continue;
10192
10193 ts->counts[BGP_STATS_PREFIXES]++;
10194 ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
10195
10196 #if 0
10197 ts->counts[BGP_STATS_AVGPLEN]
10198 = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
10199 ts->counts[BGP_STATS_AVGPLEN],
10200 rn->p.prefixlen);
10201 #endif
10202
10203 /* check if the prefix is included by any other announcements */
10204 while (prn && !bgp_node_has_bgp_path_info_data(prn))
10205 prn = bgp_node_parent_nolock(prn);
10206
10207 if (prn == NULL || prn == top) {
10208 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
10209 /* announced address space */
10210 if (space)
10211 ts->total_space +=
10212 pow(2.0, space - rn->p.prefixlen);
10213 } else if (bgp_node_has_bgp_path_info_data(prn))
10214 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
10215
10216 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
10217 pinum++;
10218 ts->counts[BGP_STATS_RIB]++;
10219
10220 if (pi->attr
10221 && (CHECK_FLAG(pi->attr->flag,
10222 ATTR_FLAG_BIT(
10223 BGP_ATTR_ATOMIC_AGGREGATE))))
10224 ts->counts[BGP_STATS_AGGREGATES]++;
10225
10226 /* as-path stats */
10227 if (pi->attr && pi->attr->aspath) {
10228 unsigned int hops =
10229 aspath_count_hops(pi->attr->aspath);
10230 unsigned int size =
10231 aspath_size(pi->attr->aspath);
10232 as_t highest = aspath_highest(pi->attr->aspath);
10233
10234 ts->counts[BGP_STATS_ASPATH_COUNT]++;
10235
10236 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
10237 ts->counts[BGP_STATS_ASPATH_MAXHOPS] =
10238 hops;
10239
10240 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
10241 ts->counts[BGP_STATS_ASPATH_MAXSIZE] =
10242 size;
10243
10244 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
10245 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
10246 #if 0
10247 ts->counts[BGP_STATS_ASPATH_AVGHOPS]
10248 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
10249 ts->counts[BGP_STATS_ASPATH_AVGHOPS],
10250 hops);
10251 ts->counts[BGP_STATS_ASPATH_AVGSIZE]
10252 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
10253 ts->counts[BGP_STATS_ASPATH_AVGSIZE],
10254 size);
10255 #endif
10256 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
10257 ts->counts[BGP_STATS_ASN_HIGHEST] =
10258 highest;
10259 }
10260 }
10261 }
10262 return 0;
10263 }
10264
10265 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
10266 safi_t safi)
10267 {
10268 struct bgp_table_stats ts;
10269 unsigned int i;
10270
10271 if (!bgp->rib[afi][safi]) {
10272 vty_out(vty, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
10273 afi, safi);
10274 return CMD_WARNING;
10275 }
10276
10277 vty_out(vty, "BGP %s RIB statistics\n", afi_safi_print(afi, safi));
10278
10279 /* labeled-unicast routes live in the unicast table */
10280 if (safi == SAFI_LABELED_UNICAST)
10281 safi = SAFI_UNICAST;
10282
10283 memset(&ts, 0, sizeof(ts));
10284 ts.table = bgp->rib[afi][safi];
10285 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
10286
10287 for (i = 0; i < BGP_STATS_MAX; i++) {
10288 if (!table_stats_strs[i])
10289 continue;
10290
10291 switch (i) {
10292 #if 0
10293 case BGP_STATS_ASPATH_AVGHOPS:
10294 case BGP_STATS_ASPATH_AVGSIZE:
10295 case BGP_STATS_AVGPLEN:
10296 vty_out (vty, "%-30s: ", table_stats_strs[i]);
10297 vty_out (vty, "%12.2f",
10298 (float)ts.counts[i] / (float)TALLY_SIGFIG);
10299 break;
10300 #endif
10301 case BGP_STATS_ASPATH_TOTHOPS:
10302 case BGP_STATS_ASPATH_TOTSIZE:
10303 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10304 vty_out(vty, "%12.2f",
10305 ts.counts[i]
10306 ? (float)ts.counts[i]
10307 / (float)ts.counts
10308 [BGP_STATS_ASPATH_COUNT]
10309 : 0);
10310 break;
10311 case BGP_STATS_TOTPLEN:
10312 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10313 vty_out(vty, "%12.2f",
10314 ts.counts[i]
10315 ? (float)ts.counts[i]
10316 / (float)ts.counts
10317 [BGP_STATS_PREFIXES]
10318 : 0);
10319 break;
10320 case BGP_STATS_SPACE:
10321 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10322 vty_out(vty, "%12g\n", ts.total_space);
10323
10324 if (afi == AFI_IP6) {
10325 vty_out(vty, "%30s: ", "/32 equivalent ");
10326 vty_out(vty, "%12g\n",
10327 ts.total_space * pow(2.0, -128 + 32));
10328 vty_out(vty, "%30s: ", "/48 equivalent ");
10329 vty_out(vty, "%12g\n",
10330 ts.total_space * pow(2.0, -128 + 48));
10331 } else {
10332 vty_out(vty, "%30s: ", "% announced ");
10333 vty_out(vty, "%12.2f\n",
10334 ts.total_space * 100. * pow(2.0, -32));
10335 vty_out(vty, "%30s: ", "/8 equivalent ");
10336 vty_out(vty, "%12.2f\n",
10337 ts.total_space * pow(2.0, -32 + 8));
10338 vty_out(vty, "%30s: ", "/24 equivalent ");
10339 vty_out(vty, "%12.2f\n",
10340 ts.total_space * pow(2.0, -32 + 24));
10341 }
10342 break;
10343 default:
10344 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10345 vty_out(vty, "%12llu", ts.counts[i]);
10346 }
10347
10348 vty_out(vty, "\n");
10349 }
10350 return CMD_SUCCESS;
10351 }
10352
10353 enum bgp_pcounts {
10354 PCOUNT_ADJ_IN = 0,
10355 PCOUNT_DAMPED,
10356 PCOUNT_REMOVED,
10357 PCOUNT_HISTORY,
10358 PCOUNT_STALE,
10359 PCOUNT_VALID,
10360 PCOUNT_ALL,
10361 PCOUNT_COUNTED,
10362 PCOUNT_PFCNT, /* the figure we display to users */
10363 PCOUNT_MAX,
10364 };
10365
10366 static const char *pcount_strs[] = {
10367 [PCOUNT_ADJ_IN] = "Adj-in",
10368 [PCOUNT_DAMPED] = "Damped",
10369 [PCOUNT_REMOVED] = "Removed",
10370 [PCOUNT_HISTORY] = "History",
10371 [PCOUNT_STALE] = "Stale",
10372 [PCOUNT_VALID] = "Valid",
10373 [PCOUNT_ALL] = "All RIB",
10374 [PCOUNT_COUNTED] = "PfxCt counted",
10375 [PCOUNT_PFCNT] = "Useable",
10376 [PCOUNT_MAX] = NULL,
10377 };
10378
10379 struct peer_pcounts {
10380 unsigned int count[PCOUNT_MAX];
10381 const struct peer *peer;
10382 const struct bgp_table *table;
10383 };
10384
10385 static int bgp_peer_count_walker(struct thread *t)
10386 {
10387 struct bgp_node *rn;
10388 struct peer_pcounts *pc = THREAD_ARG(t);
10389 const struct peer *peer = pc->peer;
10390
10391 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn)) {
10392 struct bgp_adj_in *ain;
10393 struct bgp_path_info *pi;
10394
10395 for (ain = rn->adj_in; ain; ain = ain->next)
10396 if (ain->peer == peer)
10397 pc->count[PCOUNT_ADJ_IN]++;
10398
10399 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
10400
10401 if (pi->peer != peer)
10402 continue;
10403
10404 pc->count[PCOUNT_ALL]++;
10405
10406 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
10407 pc->count[PCOUNT_DAMPED]++;
10408 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
10409 pc->count[PCOUNT_HISTORY]++;
10410 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
10411 pc->count[PCOUNT_REMOVED]++;
10412 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
10413 pc->count[PCOUNT_STALE]++;
10414 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
10415 pc->count[PCOUNT_VALID]++;
10416 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
10417 pc->count[PCOUNT_PFCNT]++;
10418
10419 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
10420 pc->count[PCOUNT_COUNTED]++;
10421 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
10422 flog_err(
10423 EC_LIB_DEVELOPMENT,
10424 "Attempting to count but flags say it is unusable");
10425 } else {
10426 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
10427 flog_err(
10428 EC_LIB_DEVELOPMENT,
10429 "Not counted but flags say we should");
10430 }
10431 }
10432 }
10433 return 0;
10434 }
10435
10436 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
10437 safi_t safi, bool use_json)
10438 {
10439 struct peer_pcounts pcounts = {.peer = peer};
10440 unsigned int i;
10441 json_object *json = NULL;
10442 json_object *json_loop = NULL;
10443
10444 if (use_json) {
10445 json = json_object_new_object();
10446 json_loop = json_object_new_object();
10447 }
10448
10449 if (!peer || !peer->bgp || !peer->afc[afi][safi]
10450 || !peer->bgp->rib[afi][safi]) {
10451 if (use_json) {
10452 json_object_string_add(
10453 json, "warning",
10454 "No such neighbor or address family");
10455 vty_out(vty, "%s\n", json_object_to_json_string(json));
10456 json_object_free(json);
10457 } else
10458 vty_out(vty, "%% No such neighbor or address family\n");
10459
10460 return CMD_WARNING;
10461 }
10462
10463 memset(&pcounts, 0, sizeof(pcounts));
10464 pcounts.peer = peer;
10465 pcounts.table = peer->bgp->rib[afi][safi];
10466
10467 /* in-place call via thread subsystem so as to record execution time
10468 * stats for the thread-walk (i.e. ensure this can't be blamed on
10469 * on just vty_read()).
10470 */
10471 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
10472
10473 if (use_json) {
10474 json_object_string_add(json, "prefixCountsFor", peer->host);
10475 json_object_string_add(json, "multiProtocol",
10476 afi_safi_print(afi, safi));
10477 json_object_int_add(json, "pfxCounter",
10478 peer->pcount[afi][safi]);
10479
10480 for (i = 0; i < PCOUNT_MAX; i++)
10481 json_object_int_add(json_loop, pcount_strs[i],
10482 pcounts.count[i]);
10483
10484 json_object_object_add(json, "ribTableWalkCounters", json_loop);
10485
10486 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
10487 json_object_string_add(json, "pfxctDriftFor",
10488 peer->host);
10489 json_object_string_add(
10490 json, "recommended",
10491 "Please report this bug, with the above command output");
10492 }
10493 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10494 json, JSON_C_TO_STRING_PRETTY));
10495 json_object_free(json);
10496 } else {
10497
10498 if (peer->hostname
10499 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
10500 vty_out(vty, "Prefix counts for %s/%s, %s\n",
10501 peer->hostname, peer->host,
10502 afi_safi_print(afi, safi));
10503 } else {
10504 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
10505 afi_safi_print(afi, safi));
10506 }
10507
10508 vty_out(vty, "PfxCt: %ld\n", peer->pcount[afi][safi]);
10509 vty_out(vty, "\nCounts from RIB table walk:\n\n");
10510
10511 for (i = 0; i < PCOUNT_MAX; i++)
10512 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
10513 pcounts.count[i]);
10514
10515 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
10516 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
10517 vty_out(vty,
10518 "Please report this bug, with the above command output\n");
10519 }
10520 }
10521
10522 return CMD_SUCCESS;
10523 }
10524
10525 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
10526 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
10527 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] "
10528 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
10529 SHOW_STR
10530 IP_STR
10531 BGP_STR
10532 BGP_INSTANCE_HELP_STR
10533 BGP_AFI_HELP_STR
10534 BGP_SAFI_HELP_STR
10535 "Detailed information on TCP and BGP neighbor connections\n"
10536 "Neighbor to display information about\n"
10537 "Neighbor to display information about\n"
10538 "Neighbor on BGP configured interface\n"
10539 "Display detailed prefix count information\n"
10540 JSON_STR)
10541 {
10542 afi_t afi = AFI_IP6;
10543 safi_t safi = SAFI_UNICAST;
10544 struct peer *peer;
10545 int idx = 0;
10546 struct bgp *bgp = NULL;
10547 bool uj = use_json(argc, argv);
10548
10549 if (uj)
10550 argc--;
10551
10552 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10553 &bgp, uj);
10554 if (!idx)
10555 return CMD_WARNING;
10556
10557 argv_find(argv, argc, "neighbors", &idx);
10558 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
10559 if (!peer)
10560 return CMD_WARNING;
10561
10562 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_UNICAST, uj);
10563 }
10564
10565 #ifdef KEEP_OLD_VPN_COMMANDS
10566 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
10567 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
10568 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
10569 SHOW_STR
10570 IP_STR
10571 BGP_STR
10572 BGP_VPNVX_HELP_STR
10573 "Display information about all VPNv4 NLRIs\n"
10574 "Detailed information on TCP and BGP neighbor connections\n"
10575 "Neighbor to display information about\n"
10576 "Neighbor to display information about\n"
10577 "Neighbor on BGP configured interface\n"
10578 "Display detailed prefix count information\n"
10579 JSON_STR)
10580 {
10581 int idx_peer = 6;
10582 struct peer *peer;
10583 bool uj = use_json(argc, argv);
10584
10585 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
10586 if (!peer)
10587 return CMD_WARNING;
10588
10589 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
10590 }
10591
10592 DEFUN (show_ip_bgp_vpn_all_route_prefix,
10593 show_ip_bgp_vpn_all_route_prefix_cmd,
10594 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
10595 SHOW_STR
10596 IP_STR
10597 BGP_STR
10598 BGP_VPNVX_HELP_STR
10599 "Display information about all VPNv4 NLRIs\n"
10600 "Network in the BGP routing table to display\n"
10601 "Network in the BGP routing table to display\n"
10602 JSON_STR)
10603 {
10604 int idx = 0;
10605 char *network = NULL;
10606 struct bgp *bgp = bgp_get_default();
10607 if (!bgp) {
10608 vty_out(vty, "Can't find default instance\n");
10609 return CMD_WARNING;
10610 }
10611
10612 if (argv_find(argv, argc, "A.B.C.D", &idx))
10613 network = argv[idx]->arg;
10614 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
10615 network = argv[idx]->arg;
10616 else {
10617 vty_out(vty, "Unable to figure out Network\n");
10618 return CMD_WARNING;
10619 }
10620
10621 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
10622 BGP_PATH_SHOW_ALL, use_json(argc, argv));
10623 }
10624 #endif /* KEEP_OLD_VPN_COMMANDS */
10625
10626 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix,
10627 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd,
10628 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
10629 SHOW_STR
10630 IP_STR
10631 BGP_STR
10632 L2VPN_HELP_STR
10633 EVPN_HELP_STR
10634 "Display information about all EVPN NLRIs\n"
10635 "Network in the BGP routing table to display\n"
10636 "Network in the BGP routing table to display\n"
10637 JSON_STR)
10638 {
10639 int idx = 0;
10640 char *network = NULL;
10641
10642 if (argv_find(argv, argc, "A.B.C.D", &idx))
10643 network = argv[idx]->arg;
10644 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
10645 network = argv[idx]->arg;
10646 else {
10647 vty_out(vty, "Unable to figure out Network\n");
10648 return CMD_WARNING;
10649 }
10650 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL, 0,
10651 BGP_PATH_SHOW_ALL, use_json(argc, argv));
10652 }
10653
10654 static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
10655 safi_t safi, enum bgp_show_adj_route_type type,
10656 const char *rmap_name, bool use_json,
10657 json_object *json)
10658 {
10659 struct bgp_table *table;
10660 struct bgp_adj_in *ain;
10661 struct bgp_adj_out *adj;
10662 unsigned long output_count;
10663 unsigned long filtered_count;
10664 struct bgp_node *rn;
10665 int header1 = 1;
10666 struct bgp *bgp;
10667 int header2 = 1;
10668 struct attr attr;
10669 int ret;
10670 struct update_subgroup *subgrp;
10671 json_object *json_scode = NULL;
10672 json_object *json_ocode = NULL;
10673 json_object *json_ar = NULL;
10674 struct peer_af *paf;
10675 bool route_filtered;
10676
10677 if (use_json) {
10678 json_scode = json_object_new_object();
10679 json_ocode = json_object_new_object();
10680 json_ar = json_object_new_object();
10681
10682 json_object_string_add(json_scode, "suppressed", "s");
10683 json_object_string_add(json_scode, "damped", "d");
10684 json_object_string_add(json_scode, "history", "h");
10685 json_object_string_add(json_scode, "valid", "*");
10686 json_object_string_add(json_scode, "best", ">");
10687 json_object_string_add(json_scode, "multipath", "=");
10688 json_object_string_add(json_scode, "internal", "i");
10689 json_object_string_add(json_scode, "ribFailure", "r");
10690 json_object_string_add(json_scode, "stale", "S");
10691 json_object_string_add(json_scode, "removed", "R");
10692
10693 json_object_string_add(json_ocode, "igp", "i");
10694 json_object_string_add(json_ocode, "egp", "e");
10695 json_object_string_add(json_ocode, "incomplete", "?");
10696 }
10697
10698 bgp = peer->bgp;
10699
10700 if (!bgp) {
10701 if (use_json) {
10702 json_object_string_add(json, "alert", "no BGP");
10703 vty_out(vty, "%s\n", json_object_to_json_string(json));
10704 json_object_free(json);
10705 } else
10706 vty_out(vty, "%% No bgp\n");
10707 return;
10708 }
10709
10710 table = bgp->rib[afi][safi];
10711
10712 output_count = filtered_count = 0;
10713 subgrp = peer_subgroup(peer, afi, safi);
10714
10715 if (type == bgp_show_adj_route_advertised && subgrp
10716 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
10717 if (use_json) {
10718 json_object_int_add(json, "bgpTableVersion",
10719 table->version);
10720 json_object_string_add(json, "bgpLocalRouterId",
10721 inet_ntoa(bgp->router_id));
10722 json_object_int_add(json, "defaultLocPrf",
10723 bgp->default_local_pref);
10724 json_object_int_add(json, "localAS", bgp->as);
10725 json_object_object_add(json, "bgpStatusCodes",
10726 json_scode);
10727 json_object_object_add(json, "bgpOriginCodes",
10728 json_ocode);
10729 json_object_string_add(
10730 json, "bgpOriginatingDefaultNetwork",
10731 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
10732 } else {
10733 vty_out(vty, "BGP table version is %" PRIu64
10734 ", local router ID is %s, vrf id ",
10735 table->version, inet_ntoa(bgp->router_id));
10736 if (bgp->vrf_id == VRF_UNKNOWN)
10737 vty_out(vty, "%s", VRFID_NONE_STR);
10738 else
10739 vty_out(vty, "%u", bgp->vrf_id);
10740 vty_out(vty, "\n");
10741 vty_out(vty, "Default local pref %u, ",
10742 bgp->default_local_pref);
10743 vty_out(vty, "local AS %u\n", bgp->as);
10744 vty_out(vty, BGP_SHOW_SCODE_HEADER);
10745 vty_out(vty, BGP_SHOW_NCODE_HEADER);
10746 vty_out(vty, BGP_SHOW_OCODE_HEADER);
10747
10748 vty_out(vty, "Originating default network %s\n\n",
10749 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
10750 }
10751 header1 = 0;
10752 }
10753
10754 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
10755 if (type == bgp_show_adj_route_received
10756 || type == bgp_show_adj_route_filtered) {
10757 for (ain = rn->adj_in; ain; ain = ain->next) {
10758 if (ain->peer != peer || !ain->attr)
10759 continue;
10760
10761 if (header1) {
10762 if (use_json) {
10763 json_object_int_add(
10764 json, "bgpTableVersion",
10765 0);
10766 json_object_string_add(
10767 json,
10768 "bgpLocalRouterId",
10769 inet_ntoa(
10770 bgp->router_id));
10771 json_object_int_add(json,
10772 "defaultLocPrf",
10773 bgp->default_local_pref);
10774 json_object_int_add(json,
10775 "localAS", bgp->as);
10776 json_object_object_add(
10777 json, "bgpStatusCodes",
10778 json_scode);
10779 json_object_object_add(
10780 json, "bgpOriginCodes",
10781 json_ocode);
10782 } else {
10783 vty_out(vty,
10784 "BGP table version is 0, local router ID is %s, vrf id ",
10785 inet_ntoa(
10786 bgp->router_id));
10787 if (bgp->vrf_id == VRF_UNKNOWN)
10788 vty_out(vty, "%s",
10789 VRFID_NONE_STR);
10790 else
10791 vty_out(vty, "%u",
10792 bgp->vrf_id);
10793 vty_out(vty, "\n");
10794 vty_out(vty,
10795 "Default local pref %u, ",
10796 bgp->default_local_pref);
10797 vty_out(vty, "local AS %u\n",
10798 bgp->as);
10799 vty_out(vty,
10800 BGP_SHOW_SCODE_HEADER);
10801 vty_out(vty,
10802 BGP_SHOW_NCODE_HEADER);
10803 vty_out(vty,
10804 BGP_SHOW_OCODE_HEADER);
10805 }
10806 header1 = 0;
10807 }
10808 if (header2) {
10809 if (!use_json)
10810 vty_out(vty, BGP_SHOW_HEADER);
10811 header2 = 0;
10812 }
10813
10814 bgp_attr_dup(&attr, ain->attr);
10815 route_filtered = false;
10816
10817 /* Filter prefix using distribute list,
10818 * filter list or prefix list
10819 */
10820 if ((bgp_input_filter(peer, &rn->p, &attr, afi,
10821 safi)) == FILTER_DENY)
10822 route_filtered = true;
10823
10824 /* Filter prefix using route-map */
10825 ret = bgp_input_modifier(peer, &rn->p, &attr,
10826 afi, safi, rmap_name);
10827
10828 if (type == bgp_show_adj_route_filtered &&
10829 !route_filtered && ret != RMAP_DENY) {
10830 bgp_attr_undup(&attr, ain->attr);
10831 continue;
10832 }
10833
10834 if (type == bgp_show_adj_route_received &&
10835 (route_filtered || ret == RMAP_DENY))
10836 filtered_count++;
10837
10838 route_vty_out_tmp(vty, &rn->p, &attr, safi,
10839 use_json, json_ar);
10840 bgp_attr_undup(&attr, ain->attr);
10841 output_count++;
10842 }
10843 } else if (type == bgp_show_adj_route_advertised) {
10844 RB_FOREACH (adj, bgp_adj_out_rb, &rn->adj_out)
10845 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
10846 if (paf->peer != peer || !adj->attr)
10847 continue;
10848
10849 if (header1) {
10850 if (use_json) {
10851 json_object_int_add(
10852 json,
10853 "bgpTableVersion",
10854 table->version);
10855 json_object_string_add(
10856 json,
10857 "bgpLocalRouterId",
10858 inet_ntoa(
10859 bgp->router_id));
10860 json_object_int_add(
10861 json, "defaultLocPrf",
10862 bgp->default_local_pref
10863 );
10864 json_object_int_add(
10865 json, "localAS",
10866 bgp->as);
10867 json_object_object_add(
10868 json,
10869 "bgpStatusCodes",
10870 json_scode);
10871 json_object_object_add(
10872 json,
10873 "bgpOriginCodes",
10874 json_ocode);
10875 } else {
10876 vty_out(vty,
10877 "BGP table version is %" PRIu64
10878 ", local router ID is %s, vrf id ",
10879 table->version,
10880 inet_ntoa(
10881 bgp->router_id));
10882 if (bgp->vrf_id ==
10883 VRF_UNKNOWN)
10884 vty_out(vty,
10885 "%s",
10886 VRFID_NONE_STR);
10887 else
10888 vty_out(vty,
10889 "%u",
10890 bgp->vrf_id);
10891 vty_out(vty, "\n");
10892 vty_out(vty,
10893 "Default local pref %u, ",
10894 bgp->default_local_pref
10895 );
10896 vty_out(vty,
10897 "local AS %u\n",
10898 bgp->as);
10899 vty_out(vty,
10900 BGP_SHOW_SCODE_HEADER);
10901 vty_out(vty,
10902 BGP_SHOW_NCODE_HEADER);
10903 vty_out(vty,
10904 BGP_SHOW_OCODE_HEADER);
10905 }
10906 header1 = 0;
10907 }
10908 if (header2) {
10909 if (!use_json)
10910 vty_out(vty,
10911 BGP_SHOW_HEADER);
10912 header2 = 0;
10913 }
10914
10915 bgp_attr_dup(&attr, adj->attr);
10916 ret = bgp_output_modifier(
10917 peer, &rn->p, &attr, afi, safi,
10918 rmap_name);
10919
10920 if (ret != RMAP_DENY) {
10921 route_vty_out_tmp(vty, &rn->p,
10922 &attr, safi,
10923 use_json,
10924 json_ar);
10925 output_count++;
10926 } else {
10927 filtered_count++;
10928 }
10929
10930 bgp_attr_undup(&attr, adj->attr);
10931 }
10932 }
10933 }
10934
10935 if (use_json) {
10936 json_object_object_add(json, "advertisedRoutes", json_ar);
10937 json_object_int_add(json, "totalPrefixCounter", output_count);
10938 json_object_int_add(json, "filteredPrefixCounter",
10939 filtered_count);
10940
10941 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10942 json, JSON_C_TO_STRING_PRETTY));
10943 json_object_free(json);
10944 } else if (output_count > 0) {
10945 if (filtered_count > 0)
10946 vty_out(vty,
10947 "\nTotal number of prefixes %ld (%ld filtered)\n",
10948 output_count, filtered_count);
10949 else
10950 vty_out(vty, "\nTotal number of prefixes %ld\n",
10951 output_count);
10952 }
10953 }
10954
10955 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
10956 safi_t safi, enum bgp_show_adj_route_type type,
10957 const char *rmap_name, bool use_json)
10958 {
10959 json_object *json = NULL;
10960
10961 if (use_json)
10962 json = json_object_new_object();
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_string_add(
10971 json, "warning",
10972 "No such neighbor or address family");
10973 vty_out(vty, "%s\n", json_object_to_json_string(json));
10974 json_object_free(json);
10975 } else
10976 vty_out(vty, "%% No such neighbor or address family\n");
10977
10978 return CMD_WARNING;
10979 }
10980
10981 if ((type == bgp_show_adj_route_received
10982 || type == bgp_show_adj_route_filtered)
10983 && !CHECK_FLAG(peer->af_flags[afi][safi],
10984 PEER_FLAG_SOFT_RECONFIG)) {
10985 if (use_json) {
10986 json_object_string_add(
10987 json, "warning",
10988 "Inbound soft reconfiguration not enabled");
10989 vty_out(vty, "%s\n", json_object_to_json_string(json));
10990 json_object_free(json);
10991 } else
10992 vty_out(vty,
10993 "%% Inbound soft reconfiguration not enabled\n");
10994
10995 return CMD_WARNING;
10996 }
10997
10998 show_adj_route(vty, peer, afi, safi, type, rmap_name, use_json, json);
10999
11000 return CMD_SUCCESS;
11001 }
11002
11003 DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
11004 show_ip_bgp_instance_neighbor_advertised_route_cmd,
11005 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
11006 "neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map WORD] [json]",
11007 SHOW_STR
11008 IP_STR
11009 BGP_STR
11010 BGP_INSTANCE_HELP_STR
11011 BGP_AFI_HELP_STR
11012 BGP_SAFI_WITH_LABEL_HELP_STR
11013 "Detailed information on TCP and BGP neighbor connections\n"
11014 "Neighbor to display information about\n"
11015 "Neighbor to display information about\n"
11016 "Neighbor on BGP configured interface\n"
11017 "Display the routes advertised to a BGP neighbor\n"
11018 "Display the received routes from neighbor\n"
11019 "Display the filtered routes received from neighbor\n"
11020 "Route-map to modify the attributes\n"
11021 "Name of the route map\n"
11022 JSON_STR)
11023 {
11024 afi_t afi = AFI_IP6;
11025 safi_t safi = SAFI_UNICAST;
11026 char *rmap_name = NULL;
11027 char *peerstr = NULL;
11028 struct bgp *bgp = NULL;
11029 struct peer *peer;
11030 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
11031 int idx = 0;
11032 bool uj = use_json(argc, argv);
11033
11034 if (uj)
11035 argc--;
11036
11037 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11038 &bgp, uj);
11039 if (!idx)
11040 return CMD_WARNING;
11041
11042 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11043 argv_find(argv, argc, "neighbors", &idx);
11044 peerstr = argv[++idx]->arg;
11045
11046 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
11047 if (!peer)
11048 return CMD_WARNING;
11049
11050 if (argv_find(argv, argc, "advertised-routes", &idx))
11051 type = bgp_show_adj_route_advertised;
11052 else if (argv_find(argv, argc, "received-routes", &idx))
11053 type = bgp_show_adj_route_received;
11054 else if (argv_find(argv, argc, "filtered-routes", &idx))
11055 type = bgp_show_adj_route_filtered;
11056
11057 if (argv_find(argv, argc, "route-map", &idx))
11058 rmap_name = argv[++idx]->arg;
11059
11060 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, uj);
11061 }
11062
11063 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
11064 show_ip_bgp_neighbor_received_prefix_filter_cmd,
11065 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
11066 SHOW_STR
11067 IP_STR
11068 BGP_STR
11069 "Address Family\n"
11070 "Address Family\n"
11071 "Address Family modifier\n"
11072 "Detailed information on TCP and BGP neighbor connections\n"
11073 "Neighbor to display information about\n"
11074 "Neighbor to display information about\n"
11075 "Neighbor on BGP configured interface\n"
11076 "Display information received from a BGP neighbor\n"
11077 "Display the prefixlist filter\n"
11078 JSON_STR)
11079 {
11080 afi_t afi = AFI_IP6;
11081 safi_t safi = SAFI_UNICAST;
11082 char *peerstr = NULL;
11083
11084 char name[BUFSIZ];
11085 union sockunion su;
11086 struct peer *peer;
11087 int count, ret;
11088
11089 int idx = 0;
11090
11091 /* show [ip] bgp */
11092 if (argv_find(argv, argc, "ip", &idx))
11093 afi = AFI_IP;
11094 /* [<ipv4|ipv6> [unicast]] */
11095 if (argv_find(argv, argc, "ipv4", &idx))
11096 afi = AFI_IP;
11097 if (argv_find(argv, argc, "ipv6", &idx))
11098 afi = AFI_IP6;
11099 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11100 argv_find(argv, argc, "neighbors", &idx);
11101 peerstr = argv[++idx]->arg;
11102
11103 bool uj = use_json(argc, argv);
11104
11105 ret = str2sockunion(peerstr, &su);
11106 if (ret < 0) {
11107 peer = peer_lookup_by_conf_if(NULL, peerstr);
11108 if (!peer) {
11109 if (uj)
11110 vty_out(vty, "{}\n");
11111 else
11112 vty_out(vty,
11113 "%% Malformed address or name: %s\n",
11114 peerstr);
11115 return CMD_WARNING;
11116 }
11117 } else {
11118 peer = peer_lookup(NULL, &su);
11119 if (!peer) {
11120 if (uj)
11121 vty_out(vty, "{}\n");
11122 else
11123 vty_out(vty, "No peer\n");
11124 return CMD_WARNING;
11125 }
11126 }
11127
11128 sprintf(name, "%s.%d.%d", peer->host, afi, safi);
11129 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
11130 if (count) {
11131 if (!uj)
11132 vty_out(vty, "Address Family: %s\n",
11133 afi_safi_print(afi, safi));
11134 prefix_bgp_show_prefix_list(vty, afi, name, uj);
11135 } else {
11136 if (uj)
11137 vty_out(vty, "{}\n");
11138 else
11139 vty_out(vty, "No functional output\n");
11140 }
11141
11142 return CMD_SUCCESS;
11143 }
11144
11145 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
11146 afi_t afi, safi_t safi,
11147 enum bgp_show_type type, bool use_json)
11148 {
11149 /* labeled-unicast routes live in the unicast table */
11150 if (safi == SAFI_LABELED_UNICAST)
11151 safi = SAFI_UNICAST;
11152
11153 if (!peer || !peer->afc[afi][safi]) {
11154 if (use_json) {
11155 json_object *json_no = NULL;
11156 json_no = json_object_new_object();
11157 json_object_string_add(
11158 json_no, "warning",
11159 "No such neighbor or address family");
11160 vty_out(vty, "%s\n",
11161 json_object_to_json_string(json_no));
11162 json_object_free(json_no);
11163 } else
11164 vty_out(vty, "%% No such neighbor or address family\n");
11165 return CMD_WARNING;
11166 }
11167
11168 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, use_json);
11169 }
11170
11171 DEFUN (show_ip_bgp_flowspec_routes_detailed,
11172 show_ip_bgp_flowspec_routes_detailed_cmd,
11173 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
11174 SHOW_STR
11175 IP_STR
11176 BGP_STR
11177 BGP_INSTANCE_HELP_STR
11178 BGP_AFI_HELP_STR
11179 "SAFI Flowspec\n"
11180 "Detailed information on flowspec entries\n"
11181 JSON_STR)
11182 {
11183 afi_t afi = AFI_IP;
11184 safi_t safi = SAFI_UNICAST;
11185 struct bgp *bgp = NULL;
11186 int idx = 0;
11187 bool uj = use_json(argc, argv);
11188
11189 if (uj)
11190 argc--;
11191
11192 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11193 &bgp, uj);
11194 if (!idx)
11195 return CMD_WARNING;
11196
11197 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL, uj);
11198 }
11199
11200 DEFUN (show_ip_bgp_neighbor_routes,
11201 show_ip_bgp_neighbor_routes_cmd,
11202 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
11203 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
11204 SHOW_STR
11205 IP_STR
11206 BGP_STR
11207 BGP_INSTANCE_HELP_STR
11208 BGP_AFI_HELP_STR
11209 BGP_SAFI_WITH_LABEL_HELP_STR
11210 "Detailed information on TCP and BGP neighbor connections\n"
11211 "Neighbor to display information about\n"
11212 "Neighbor to display information about\n"
11213 "Neighbor on BGP configured interface\n"
11214 "Display flap statistics of the routes learned from neighbor\n"
11215 "Display the dampened routes received from neighbor\n"
11216 "Display routes learned from neighbor\n"
11217 JSON_STR)
11218 {
11219 char *peerstr = NULL;
11220 struct bgp *bgp = NULL;
11221 afi_t afi = AFI_IP6;
11222 safi_t safi = SAFI_UNICAST;
11223 struct peer *peer;
11224 enum bgp_show_type sh_type = bgp_show_type_neighbor;
11225 int idx = 0;
11226 bool uj = use_json(argc, argv);
11227
11228 if (uj)
11229 argc--;
11230
11231 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11232 &bgp, uj);
11233 if (!idx)
11234 return CMD_WARNING;
11235
11236 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11237 argv_find(argv, argc, "neighbors", &idx);
11238 peerstr = argv[++idx]->arg;
11239
11240 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
11241 if (!peer)
11242 return CMD_WARNING;
11243
11244 if (argv_find(argv, argc, "flap-statistics", &idx))
11245 sh_type = bgp_show_type_flap_neighbor;
11246 else if (argv_find(argv, argc, "dampened-routes", &idx))
11247 sh_type = bgp_show_type_damp_neighbor;
11248 else if (argv_find(argv, argc, "routes", &idx))
11249 sh_type = bgp_show_type_neighbor;
11250
11251 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
11252 }
11253
11254 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
11255
11256 struct bgp_distance {
11257 /* Distance value for the IP source prefix. */
11258 uint8_t distance;
11259
11260 /* Name of the access-list to be matched. */
11261 char *access_list;
11262 };
11263
11264 DEFUN (show_bgp_afi_vpn_rd_route,
11265 show_bgp_afi_vpn_rd_route_cmd,
11266 "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]",
11267 SHOW_STR
11268 BGP_STR
11269 BGP_AFI_HELP_STR
11270 "Address Family modifier\n"
11271 "Display information for a route distinguisher\n"
11272 "Route Distinguisher\n"
11273 "Network in the BGP routing table to display\n"
11274 "Network in the BGP routing table to display\n"
11275 JSON_STR)
11276 {
11277 int ret;
11278 struct prefix_rd prd;
11279 afi_t afi = AFI_MAX;
11280 int idx = 0;
11281
11282 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
11283 vty_out(vty, "%% Malformed Address Family\n");
11284 return CMD_WARNING;
11285 }
11286
11287 ret = str2prefix_rd(argv[5]->arg, &prd);
11288 if (!ret) {
11289 vty_out(vty, "%% Malformed Route Distinguisher\n");
11290 return CMD_WARNING;
11291 }
11292
11293 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
11294 0, BGP_PATH_SHOW_ALL, use_json(argc, argv));
11295 }
11296
11297 static struct bgp_distance *bgp_distance_new(void)
11298 {
11299 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
11300 }
11301
11302 static void bgp_distance_free(struct bgp_distance *bdistance)
11303 {
11304 XFREE(MTYPE_BGP_DISTANCE, bdistance);
11305 }
11306
11307 static int bgp_distance_set(struct vty *vty, const char *distance_str,
11308 const char *ip_str, const char *access_list_str)
11309 {
11310 int ret;
11311 afi_t afi;
11312 safi_t safi;
11313 struct prefix p;
11314 uint8_t distance;
11315 struct bgp_node *rn;
11316 struct bgp_distance *bdistance;
11317
11318 afi = bgp_node_afi(vty);
11319 safi = bgp_node_safi(vty);
11320
11321 ret = str2prefix(ip_str, &p);
11322 if (ret == 0) {
11323 vty_out(vty, "Malformed prefix\n");
11324 return CMD_WARNING_CONFIG_FAILED;
11325 }
11326
11327 distance = atoi(distance_str);
11328
11329 /* Get BGP distance node. */
11330 rn = bgp_node_get(bgp_distance_table[afi][safi], (struct prefix *)&p);
11331 bdistance = bgp_node_get_bgp_distance_info(rn);
11332 if (bdistance)
11333 bgp_unlock_node(rn);
11334 else {
11335 bdistance = bgp_distance_new();
11336 bgp_node_set_bgp_distance_info(rn, bdistance);
11337 }
11338
11339 /* Set distance value. */
11340 bdistance->distance = distance;
11341
11342 /* Reset access-list configuration. */
11343 if (bdistance->access_list) {
11344 XFREE(MTYPE_AS_LIST, bdistance->access_list);
11345 bdistance->access_list = NULL;
11346 }
11347 if (access_list_str)
11348 bdistance->access_list =
11349 XSTRDUP(MTYPE_AS_LIST, access_list_str);
11350
11351 return CMD_SUCCESS;
11352 }
11353
11354 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
11355 const char *ip_str, const char *access_list_str)
11356 {
11357 int ret;
11358 afi_t afi;
11359 safi_t safi;
11360 struct prefix p;
11361 int distance;
11362 struct bgp_node *rn;
11363 struct bgp_distance *bdistance;
11364
11365 afi = bgp_node_afi(vty);
11366 safi = bgp_node_safi(vty);
11367
11368 ret = str2prefix(ip_str, &p);
11369 if (ret == 0) {
11370 vty_out(vty, "Malformed prefix\n");
11371 return CMD_WARNING_CONFIG_FAILED;
11372 }
11373
11374 rn = bgp_node_lookup(bgp_distance_table[afi][safi],
11375 (struct prefix *)&p);
11376 if (!rn) {
11377 vty_out(vty, "Can't find specified prefix\n");
11378 return CMD_WARNING_CONFIG_FAILED;
11379 }
11380
11381 bdistance = bgp_node_get_bgp_distance_info(rn);
11382 distance = atoi(distance_str);
11383
11384 if (bdistance->distance != distance) {
11385 vty_out(vty, "Distance does not match configured\n");
11386 return CMD_WARNING_CONFIG_FAILED;
11387 }
11388
11389 if (bdistance->access_list)
11390 XFREE(MTYPE_AS_LIST, bdistance->access_list);
11391 bgp_distance_free(bdistance);
11392
11393 bgp_node_set_bgp_path_info(rn, NULL);
11394 bgp_unlock_node(rn);
11395 bgp_unlock_node(rn);
11396
11397 return CMD_SUCCESS;
11398 }
11399
11400 /* Apply BGP information to distance method. */
11401 uint8_t bgp_distance_apply(struct prefix *p, struct bgp_path_info *pinfo,
11402 afi_t afi, safi_t safi, struct bgp *bgp)
11403 {
11404 struct bgp_node *rn;
11405 struct prefix q;
11406 struct peer *peer;
11407 struct bgp_distance *bdistance;
11408 struct access_list *alist;
11409 struct bgp_static *bgp_static;
11410
11411 if (!bgp)
11412 return 0;
11413
11414 peer = pinfo->peer;
11415
11416 /* Check source address. */
11417 sockunion2hostprefix(&peer->su, &q);
11418 rn = bgp_node_match(bgp_distance_table[afi][safi], &q);
11419 if (rn) {
11420 bdistance = bgp_node_get_bgp_distance_info(rn);
11421 bgp_unlock_node(rn);
11422
11423 if (bdistance->access_list) {
11424 alist = access_list_lookup(afi, bdistance->access_list);
11425 if (alist
11426 && access_list_apply(alist, p) == FILTER_PERMIT)
11427 return bdistance->distance;
11428 } else
11429 return bdistance->distance;
11430 }
11431
11432 /* Backdoor check. */
11433 rn = bgp_node_lookup(bgp->route[afi][safi], p);
11434 if (rn) {
11435 bgp_static = bgp_node_get_bgp_static_info(rn);
11436 bgp_unlock_node(rn);
11437
11438 if (bgp_static->backdoor) {
11439 if (bgp->distance_local[afi][safi])
11440 return bgp->distance_local[afi][safi];
11441 else
11442 return ZEBRA_IBGP_DISTANCE_DEFAULT;
11443 }
11444 }
11445
11446 if (peer->sort == BGP_PEER_EBGP) {
11447 if (bgp->distance_ebgp[afi][safi])
11448 return bgp->distance_ebgp[afi][safi];
11449 return ZEBRA_EBGP_DISTANCE_DEFAULT;
11450 } else {
11451 if (bgp->distance_ibgp[afi][safi])
11452 return bgp->distance_ibgp[afi][safi];
11453 return ZEBRA_IBGP_DISTANCE_DEFAULT;
11454 }
11455 }
11456
11457 DEFUN (bgp_distance,
11458 bgp_distance_cmd,
11459 "distance bgp (1-255) (1-255) (1-255)",
11460 "Define an administrative distance\n"
11461 "BGP distance\n"
11462 "Distance for routes external to the AS\n"
11463 "Distance for routes internal to the AS\n"
11464 "Distance for local routes\n")
11465 {
11466 VTY_DECLVAR_CONTEXT(bgp, bgp);
11467 int idx_number = 2;
11468 int idx_number_2 = 3;
11469 int idx_number_3 = 4;
11470 afi_t afi;
11471 safi_t safi;
11472
11473 afi = bgp_node_afi(vty);
11474 safi = bgp_node_safi(vty);
11475
11476 bgp->distance_ebgp[afi][safi] = atoi(argv[idx_number]->arg);
11477 bgp->distance_ibgp[afi][safi] = atoi(argv[idx_number_2]->arg);
11478 bgp->distance_local[afi][safi] = atoi(argv[idx_number_3]->arg);
11479 return CMD_SUCCESS;
11480 }
11481
11482 DEFUN (no_bgp_distance,
11483 no_bgp_distance_cmd,
11484 "no distance bgp [(1-255) (1-255) (1-255)]",
11485 NO_STR
11486 "Define an administrative distance\n"
11487 "BGP distance\n"
11488 "Distance for routes external to the AS\n"
11489 "Distance for routes internal to the AS\n"
11490 "Distance for local routes\n")
11491 {
11492 VTY_DECLVAR_CONTEXT(bgp, bgp);
11493 afi_t afi;
11494 safi_t safi;
11495
11496 afi = bgp_node_afi(vty);
11497 safi = bgp_node_safi(vty);
11498
11499 bgp->distance_ebgp[afi][safi] = 0;
11500 bgp->distance_ibgp[afi][safi] = 0;
11501 bgp->distance_local[afi][safi] = 0;
11502 return CMD_SUCCESS;
11503 }
11504
11505
11506 DEFUN (bgp_distance_source,
11507 bgp_distance_source_cmd,
11508 "distance (1-255) A.B.C.D/M",
11509 "Define an administrative distance\n"
11510 "Administrative distance\n"
11511 "IP source prefix\n")
11512 {
11513 int idx_number = 1;
11514 int idx_ipv4_prefixlen = 2;
11515 bgp_distance_set(vty, argv[idx_number]->arg,
11516 argv[idx_ipv4_prefixlen]->arg, NULL);
11517 return CMD_SUCCESS;
11518 }
11519
11520 DEFUN (no_bgp_distance_source,
11521 no_bgp_distance_source_cmd,
11522 "no distance (1-255) A.B.C.D/M",
11523 NO_STR
11524 "Define an administrative distance\n"
11525 "Administrative distance\n"
11526 "IP source prefix\n")
11527 {
11528 int idx_number = 2;
11529 int idx_ipv4_prefixlen = 3;
11530 bgp_distance_unset(vty, argv[idx_number]->arg,
11531 argv[idx_ipv4_prefixlen]->arg, NULL);
11532 return CMD_SUCCESS;
11533 }
11534
11535 DEFUN (bgp_distance_source_access_list,
11536 bgp_distance_source_access_list_cmd,
11537 "distance (1-255) A.B.C.D/M WORD",
11538 "Define an administrative distance\n"
11539 "Administrative distance\n"
11540 "IP source prefix\n"
11541 "Access list name\n")
11542 {
11543 int idx_number = 1;
11544 int idx_ipv4_prefixlen = 2;
11545 int idx_word = 3;
11546 bgp_distance_set(vty, argv[idx_number]->arg,
11547 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
11548 return CMD_SUCCESS;
11549 }
11550
11551 DEFUN (no_bgp_distance_source_access_list,
11552 no_bgp_distance_source_access_list_cmd,
11553 "no distance (1-255) A.B.C.D/M WORD",
11554 NO_STR
11555 "Define an administrative distance\n"
11556 "Administrative distance\n"
11557 "IP source prefix\n"
11558 "Access list name\n")
11559 {
11560 int idx_number = 2;
11561 int idx_ipv4_prefixlen = 3;
11562 int idx_word = 4;
11563 bgp_distance_unset(vty, argv[idx_number]->arg,
11564 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
11565 return CMD_SUCCESS;
11566 }
11567
11568 DEFUN (ipv6_bgp_distance_source,
11569 ipv6_bgp_distance_source_cmd,
11570 "distance (1-255) X:X::X:X/M",
11571 "Define an administrative distance\n"
11572 "Administrative distance\n"
11573 "IP source prefix\n")
11574 {
11575 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
11576 return CMD_SUCCESS;
11577 }
11578
11579 DEFUN (no_ipv6_bgp_distance_source,
11580 no_ipv6_bgp_distance_source_cmd,
11581 "no distance (1-255) X:X::X:X/M",
11582 NO_STR
11583 "Define an administrative distance\n"
11584 "Administrative distance\n"
11585 "IP source prefix\n")
11586 {
11587 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
11588 return CMD_SUCCESS;
11589 }
11590
11591 DEFUN (ipv6_bgp_distance_source_access_list,
11592 ipv6_bgp_distance_source_access_list_cmd,
11593 "distance (1-255) X:X::X:X/M WORD",
11594 "Define an administrative distance\n"
11595 "Administrative distance\n"
11596 "IP source prefix\n"
11597 "Access list name\n")
11598 {
11599 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
11600 return CMD_SUCCESS;
11601 }
11602
11603 DEFUN (no_ipv6_bgp_distance_source_access_list,
11604 no_ipv6_bgp_distance_source_access_list_cmd,
11605 "no distance (1-255) X:X::X:X/M WORD",
11606 NO_STR
11607 "Define an administrative distance\n"
11608 "Administrative distance\n"
11609 "IP source prefix\n"
11610 "Access list name\n")
11611 {
11612 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
11613 return CMD_SUCCESS;
11614 }
11615
11616 DEFUN (bgp_damp_set,
11617 bgp_damp_set_cmd,
11618 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
11619 "BGP Specific commands\n"
11620 "Enable route-flap dampening\n"
11621 "Half-life time for the penalty\n"
11622 "Value to start reusing a route\n"
11623 "Value to start suppressing a route\n"
11624 "Maximum duration to suppress a stable route\n")
11625 {
11626 VTY_DECLVAR_CONTEXT(bgp, bgp);
11627 int idx_half_life = 2;
11628 int idx_reuse = 3;
11629 int idx_suppress = 4;
11630 int idx_max_suppress = 5;
11631 int half = DEFAULT_HALF_LIFE * 60;
11632 int reuse = DEFAULT_REUSE;
11633 int suppress = DEFAULT_SUPPRESS;
11634 int max = 4 * half;
11635
11636 if (argc == 6) {
11637 half = atoi(argv[idx_half_life]->arg) * 60;
11638 reuse = atoi(argv[idx_reuse]->arg);
11639 suppress = atoi(argv[idx_suppress]->arg);
11640 max = atoi(argv[idx_max_suppress]->arg) * 60;
11641 } else if (argc == 3) {
11642 half = atoi(argv[idx_half_life]->arg) * 60;
11643 max = 4 * half;
11644 }
11645
11646 if (suppress < reuse) {
11647 vty_out(vty,
11648 "Suppress value cannot be less than reuse value \n");
11649 return 0;
11650 }
11651
11652 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
11653 reuse, suppress, max);
11654 }
11655
11656 DEFUN (bgp_damp_unset,
11657 bgp_damp_unset_cmd,
11658 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
11659 NO_STR
11660 "BGP Specific commands\n"
11661 "Enable route-flap dampening\n"
11662 "Half-life time for the penalty\n"
11663 "Value to start reusing a route\n"
11664 "Value to start suppressing a route\n"
11665 "Maximum duration to suppress a stable route\n")
11666 {
11667 VTY_DECLVAR_CONTEXT(bgp, bgp);
11668 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
11669 }
11670
11671 /* Display specified route of BGP table. */
11672 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
11673 const char *ip_str, afi_t afi, safi_t safi,
11674 struct prefix_rd *prd, int prefix_check)
11675 {
11676 int ret;
11677 struct prefix match;
11678 struct bgp_node *rn;
11679 struct bgp_node *rm;
11680 struct bgp_path_info *pi;
11681 struct bgp_path_info *pi_temp;
11682 struct bgp *bgp;
11683 struct bgp_table *table;
11684
11685 /* BGP structure lookup. */
11686 if (view_name) {
11687 bgp = bgp_lookup_by_name(view_name);
11688 if (bgp == NULL) {
11689 vty_out(vty, "%% Can't find BGP instance %s\n",
11690 view_name);
11691 return CMD_WARNING;
11692 }
11693 } else {
11694 bgp = bgp_get_default();
11695 if (bgp == NULL) {
11696 vty_out(vty, "%% No BGP process is configured\n");
11697 return CMD_WARNING;
11698 }
11699 }
11700
11701 /* Check IP address argument. */
11702 ret = str2prefix(ip_str, &match);
11703 if (!ret) {
11704 vty_out(vty, "%% address is malformed\n");
11705 return CMD_WARNING;
11706 }
11707
11708 match.family = afi2family(afi);
11709
11710 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
11711 || (safi == SAFI_EVPN)) {
11712 for (rn = bgp_table_top(bgp->rib[AFI_IP][safi]); rn;
11713 rn = bgp_route_next(rn)) {
11714 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
11715 continue;
11716 table = bgp_node_get_bgp_table_info(rn);
11717 if (!table)
11718 continue;
11719 if ((rm = bgp_node_match(table, &match)) == NULL)
11720 continue;
11721
11722 if (!prefix_check
11723 || rm->p.prefixlen == match.prefixlen) {
11724 pi = bgp_node_get_bgp_path_info(rm);
11725 while (pi) {
11726 if (pi->extra && pi->extra->damp_info) {
11727 pi_temp = pi->next;
11728 bgp_damp_info_free(
11729 pi->extra->damp_info,
11730 1);
11731 pi = pi_temp;
11732 } else
11733 pi = pi->next;
11734 }
11735 }
11736
11737 bgp_unlock_node(rm);
11738 }
11739 } else {
11740 if ((rn = bgp_node_match(bgp->rib[afi][safi], &match))
11741 != NULL) {
11742 if (!prefix_check
11743 || rn->p.prefixlen == match.prefixlen) {
11744 pi = bgp_node_get_bgp_path_info(rn);
11745 while (pi) {
11746 if (pi->extra && pi->extra->damp_info) {
11747 pi_temp = pi->next;
11748 bgp_damp_info_free(
11749 pi->extra->damp_info,
11750 1);
11751 pi = pi_temp;
11752 } else
11753 pi = pi->next;
11754 }
11755 }
11756
11757 bgp_unlock_node(rn);
11758 }
11759 }
11760
11761 return CMD_SUCCESS;
11762 }
11763
11764 DEFUN (clear_ip_bgp_dampening,
11765 clear_ip_bgp_dampening_cmd,
11766 "clear ip bgp dampening",
11767 CLEAR_STR
11768 IP_STR
11769 BGP_STR
11770 "Clear route flap dampening information\n")
11771 {
11772 bgp_damp_info_clean();
11773 return CMD_SUCCESS;
11774 }
11775
11776 DEFUN (clear_ip_bgp_dampening_prefix,
11777 clear_ip_bgp_dampening_prefix_cmd,
11778 "clear ip bgp dampening A.B.C.D/M",
11779 CLEAR_STR
11780 IP_STR
11781 BGP_STR
11782 "Clear route flap dampening information\n"
11783 "IPv4 prefix\n")
11784 {
11785 int idx_ipv4_prefixlen = 4;
11786 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
11787 AFI_IP, SAFI_UNICAST, NULL, 1);
11788 }
11789
11790 DEFUN (clear_ip_bgp_dampening_address,
11791 clear_ip_bgp_dampening_address_cmd,
11792 "clear ip bgp dampening A.B.C.D",
11793 CLEAR_STR
11794 IP_STR
11795 BGP_STR
11796 "Clear route flap dampening information\n"
11797 "Network to clear damping information\n")
11798 {
11799 int idx_ipv4 = 4;
11800 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
11801 SAFI_UNICAST, NULL, 0);
11802 }
11803
11804 DEFUN (clear_ip_bgp_dampening_address_mask,
11805 clear_ip_bgp_dampening_address_mask_cmd,
11806 "clear ip bgp dampening A.B.C.D A.B.C.D",
11807 CLEAR_STR
11808 IP_STR
11809 BGP_STR
11810 "Clear route flap dampening information\n"
11811 "Network to clear damping information\n"
11812 "Network mask\n")
11813 {
11814 int idx_ipv4 = 4;
11815 int idx_ipv4_2 = 5;
11816 int ret;
11817 char prefix_str[BUFSIZ];
11818
11819 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
11820 prefix_str);
11821 if (!ret) {
11822 vty_out(vty, "%% Inconsistent address and mask\n");
11823 return CMD_WARNING;
11824 }
11825
11826 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
11827 NULL, 0);
11828 }
11829
11830 static void show_bgp_peerhash_entry(struct hash_backet *backet, void *arg)
11831 {
11832 struct vty *vty = arg;
11833 struct peer *peer = backet->data;
11834 char buf[SU_ADDRSTRLEN];
11835
11836 vty_out(vty, "\tPeer: %s %s\n", peer->host,
11837 sockunion2str(&peer->su, buf, sizeof(buf)));
11838 }
11839
11840 DEFUN (show_bgp_peerhash,
11841 show_bgp_peerhash_cmd,
11842 "show bgp peerhash",
11843 SHOW_STR
11844 BGP_STR
11845 "Display information about the BGP peerhash\n")
11846 {
11847 struct list *instances = bm->bgp;
11848 struct listnode *node;
11849 struct bgp *bgp;
11850
11851 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
11852 vty_out(vty, "BGP: %s\n", bgp->name);
11853 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
11854 vty);
11855 }
11856
11857 return CMD_SUCCESS;
11858 }
11859
11860 /* also used for encap safi */
11861 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
11862 afi_t afi, safi_t safi)
11863 {
11864 struct bgp_node *prn;
11865 struct bgp_node *rn;
11866 struct bgp_table *table;
11867 struct prefix *p;
11868 struct prefix_rd *prd;
11869 struct bgp_static *bgp_static;
11870 mpls_label_t label;
11871 char buf[SU_ADDRSTRLEN];
11872 char rdbuf[RD_ADDRSTRLEN];
11873
11874 /* Network configuration. */
11875 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
11876 prn = bgp_route_next(prn)) {
11877 table = bgp_node_get_bgp_table_info(prn);
11878 if (!table)
11879 continue;
11880
11881 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
11882 bgp_static = bgp_node_get_bgp_static_info(rn);
11883 if (bgp_static == NULL)
11884 continue;
11885
11886 p = &rn->p;
11887 prd = (struct prefix_rd *)&prn->p;
11888
11889 /* "network" configuration display. */
11890 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
11891 label = decode_label(&bgp_static->label);
11892
11893 vty_out(vty, " network %s/%d rd %s",
11894 inet_ntop(p->family, &p->u.prefix, buf,
11895 SU_ADDRSTRLEN),
11896 p->prefixlen, rdbuf);
11897 if (safi == SAFI_MPLS_VPN)
11898 vty_out(vty, " label %u", label);
11899
11900 if (bgp_static->rmap.name)
11901 vty_out(vty, " route-map %s",
11902 bgp_static->rmap.name);
11903
11904 if (bgp_static->backdoor)
11905 vty_out(vty, " backdoor");
11906
11907 vty_out(vty, "\n");
11908 }
11909 }
11910 }
11911
11912 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
11913 afi_t afi, safi_t safi)
11914 {
11915 struct bgp_node *prn;
11916 struct bgp_node *rn;
11917 struct bgp_table *table;
11918 struct prefix *p;
11919 struct prefix_rd *prd;
11920 struct bgp_static *bgp_static;
11921 char buf[PREFIX_STRLEN * 2];
11922 char buf2[SU_ADDRSTRLEN];
11923 char rdbuf[RD_ADDRSTRLEN];
11924
11925 /* Network configuration. */
11926 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
11927 prn = bgp_route_next(prn)) {
11928 table = bgp_node_get_bgp_table_info(prn);
11929 if (!table)
11930 continue;
11931
11932 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
11933 bgp_static = bgp_node_get_bgp_static_info(rn);
11934 if (bgp_static == NULL)
11935 continue;
11936
11937 char *macrouter = NULL;
11938 char *esi = NULL;
11939
11940 if (bgp_static->router_mac)
11941 macrouter = prefix_mac2str(
11942 bgp_static->router_mac, NULL, 0);
11943 if (bgp_static->eth_s_id)
11944 esi = esi2str(bgp_static->eth_s_id);
11945 p = &rn->p;
11946 prd = (struct prefix_rd *)&prn->p;
11947
11948 /* "network" configuration display. */
11949 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
11950 if (p->u.prefix_evpn.route_type == 5) {
11951 char local_buf[PREFIX_STRLEN];
11952 uint8_t family = is_evpn_prefix_ipaddr_v4((
11953 struct prefix_evpn *)p)
11954 ? AF_INET
11955 : AF_INET6;
11956 inet_ntop(family,
11957 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
11958 local_buf, PREFIX_STRLEN);
11959 sprintf(buf, "%s/%u", local_buf,
11960 p->u.prefix_evpn.prefix_addr.ip_prefix_length);
11961 } else {
11962 prefix2str(p, buf, sizeof(buf));
11963 }
11964
11965 if (bgp_static->gatewayIp.family == AF_INET
11966 || bgp_static->gatewayIp.family == AF_INET6)
11967 inet_ntop(bgp_static->gatewayIp.family,
11968 &bgp_static->gatewayIp.u.prefix, buf2,
11969 sizeof(buf2));
11970 vty_out(vty,
11971 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
11972 buf, rdbuf,
11973 p->u.prefix_evpn.prefix_addr.eth_tag,
11974 decode_label(&bgp_static->label), esi, buf2,
11975 macrouter);
11976
11977 if (macrouter)
11978 XFREE(MTYPE_TMP, macrouter);
11979 if (esi)
11980 XFREE(MTYPE_TMP, esi);
11981 }
11982 }
11983 }
11984
11985 /* Configuration of static route announcement and aggregate
11986 information. */
11987 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
11988 safi_t safi)
11989 {
11990 struct bgp_node *rn;
11991 struct prefix *p;
11992 struct bgp_static *bgp_static;
11993 struct bgp_aggregate *bgp_aggregate;
11994 char buf[SU_ADDRSTRLEN];
11995
11996 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
11997 bgp_config_write_network_vpn(vty, bgp, afi, safi);
11998 return;
11999 }
12000
12001 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
12002 bgp_config_write_network_evpn(vty, bgp, afi, safi);
12003 return;
12004 }
12005
12006 /* Network configuration. */
12007 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
12008 rn = bgp_route_next(rn)) {
12009 bgp_static = bgp_node_get_bgp_static_info(rn);
12010 if (bgp_static == NULL)
12011 continue;
12012
12013 p = &rn->p;
12014
12015 /* "network" configuration display. */
12016 if (bgp_option_check(BGP_OPT_CONFIG_CISCO) && afi == AFI_IP) {
12017 uint32_t destination;
12018 struct in_addr netmask;
12019
12020 destination = ntohl(p->u.prefix4.s_addr);
12021 masklen2ip(p->prefixlen, &netmask);
12022 vty_out(vty, " network %s",
12023 inet_ntop(p->family, &p->u.prefix, buf,
12024 SU_ADDRSTRLEN));
12025
12026 if ((IN_CLASSC(destination) && p->prefixlen == 24)
12027 || (IN_CLASSB(destination) && p->prefixlen == 16)
12028 || (IN_CLASSA(destination) && p->prefixlen == 8)
12029 || p->u.prefix4.s_addr == 0) {
12030 /* Natural mask is not display. */
12031 } else
12032 vty_out(vty, " mask %s", inet_ntoa(netmask));
12033 } else {
12034 vty_out(vty, " network %s/%d",
12035 inet_ntop(p->family, &p->u.prefix, buf,
12036 SU_ADDRSTRLEN),
12037 p->prefixlen);
12038 }
12039
12040 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
12041 vty_out(vty, " label-index %u",
12042 bgp_static->label_index);
12043
12044 if (bgp_static->rmap.name)
12045 vty_out(vty, " route-map %s", bgp_static->rmap.name);
12046
12047 if (bgp_static->backdoor)
12048 vty_out(vty, " backdoor");
12049
12050 vty_out(vty, "\n");
12051 }
12052
12053 /* Aggregate-address configuration. */
12054 for (rn = bgp_table_top(bgp->aggregate[afi][safi]); rn;
12055 rn = bgp_route_next(rn)) {
12056 bgp_aggregate = bgp_node_get_bgp_aggregate_info(rn);
12057 if (bgp_aggregate == NULL)
12058 continue;
12059
12060 p = &rn->p;
12061
12062 if (bgp_option_check(BGP_OPT_CONFIG_CISCO) && afi == AFI_IP) {
12063 struct in_addr netmask;
12064
12065 masklen2ip(p->prefixlen, &netmask);
12066 vty_out(vty, " aggregate-address %s %s",
12067 inet_ntop(p->family, &p->u.prefix, buf,
12068 SU_ADDRSTRLEN),
12069 inet_ntoa(netmask));
12070 } else {
12071 vty_out(vty, " aggregate-address %s/%d",
12072 inet_ntop(p->family, &p->u.prefix, buf,
12073 SU_ADDRSTRLEN),
12074 p->prefixlen);
12075 }
12076
12077 if (bgp_aggregate->as_set)
12078 vty_out(vty, " as-set");
12079
12080 if (bgp_aggregate->summary_only)
12081 vty_out(vty, " summary-only");
12082
12083 vty_out(vty, "\n");
12084 }
12085 }
12086
12087 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
12088 safi_t safi)
12089 {
12090 struct bgp_node *rn;
12091 struct bgp_distance *bdistance;
12092
12093 /* Distance configuration. */
12094 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
12095 && bgp->distance_local[afi][safi]
12096 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
12097 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
12098 || bgp->distance_local[afi][safi]
12099 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
12100 vty_out(vty, " distance bgp %d %d %d\n",
12101 bgp->distance_ebgp[afi][safi],
12102 bgp->distance_ibgp[afi][safi],
12103 bgp->distance_local[afi][safi]);
12104 }
12105
12106 for (rn = bgp_table_top(bgp_distance_table[afi][safi]); rn;
12107 rn = bgp_route_next(rn)) {
12108 bdistance = bgp_node_get_bgp_distance_info(rn);
12109 if (bdistance != NULL) {
12110 char buf[PREFIX_STRLEN];
12111
12112 vty_out(vty, " distance %d %s %s\n",
12113 bdistance->distance,
12114 prefix2str(&rn->p, buf, sizeof(buf)),
12115 bdistance->access_list ? bdistance->access_list
12116 : "");
12117 }
12118 }
12119 }
12120
12121 /* Allocate routing table structure and install commands. */
12122 void bgp_route_init(void)
12123 {
12124 afi_t afi;
12125 safi_t safi;
12126
12127 /* Init BGP distance table. */
12128 FOREACH_AFI_SAFI (afi, safi)
12129 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
12130
12131 /* IPv4 BGP commands. */
12132 install_element(BGP_NODE, &bgp_table_map_cmd);
12133 install_element(BGP_NODE, &bgp_network_cmd);
12134 install_element(BGP_NODE, &no_bgp_table_map_cmd);
12135
12136 install_element(BGP_NODE, &aggregate_address_cmd);
12137 install_element(BGP_NODE, &aggregate_address_mask_cmd);
12138 install_element(BGP_NODE, &no_aggregate_address_cmd);
12139 install_element(BGP_NODE, &no_aggregate_address_mask_cmd);
12140
12141 /* IPv4 unicast configuration. */
12142 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
12143 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
12144 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
12145
12146 install_element(BGP_IPV4_NODE, &aggregate_address_cmd);
12147 install_element(BGP_IPV4_NODE, &aggregate_address_mask_cmd);
12148 install_element(BGP_IPV4_NODE, &no_aggregate_address_cmd);
12149 install_element(BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
12150
12151 /* IPv4 multicast configuration. */
12152 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
12153 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
12154 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
12155 install_element(BGP_IPV4M_NODE, &aggregate_address_cmd);
12156 install_element(BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
12157 install_element(BGP_IPV4M_NODE, &no_aggregate_address_cmd);
12158 install_element(BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
12159
12160 /* IPv4 labeled-unicast configuration. */
12161 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
12162 install_element(VIEW_NODE, &show_ip_bgp_cmd);
12163 install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
12164 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
12165 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
12166
12167 install_element(VIEW_NODE,
12168 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
12169 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
12170 install_element(VIEW_NODE,
12171 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
12172 #ifdef KEEP_OLD_VPN_COMMANDS
12173 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
12174 #endif /* KEEP_OLD_VPN_COMMANDS */
12175 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
12176 install_element(VIEW_NODE,
12177 &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd);
12178
12179 /* BGP dampening clear commands */
12180 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
12181 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
12182
12183 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
12184 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
12185
12186 /* prefix count */
12187 install_element(ENABLE_NODE,
12188 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
12189 #ifdef KEEP_OLD_VPN_COMMANDS
12190 install_element(ENABLE_NODE,
12191 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
12192 #endif /* KEEP_OLD_VPN_COMMANDS */
12193
12194 /* New config IPv6 BGP commands. */
12195 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
12196 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
12197 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
12198
12199 install_element(BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
12200 install_element(BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
12201
12202 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
12203
12204 install_element(BGP_NODE, &bgp_distance_cmd);
12205 install_element(BGP_NODE, &no_bgp_distance_cmd);
12206 install_element(BGP_NODE, &bgp_distance_source_cmd);
12207 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
12208 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
12209 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
12210 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
12211 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
12212 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
12213 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
12214 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
12215 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
12216 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
12217 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
12218 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
12219 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
12220 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
12221 install_element(BGP_IPV4M_NODE,
12222 &no_bgp_distance_source_access_list_cmd);
12223 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
12224 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
12225 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
12226 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
12227 install_element(BGP_IPV6_NODE,
12228 &ipv6_bgp_distance_source_access_list_cmd);
12229 install_element(BGP_IPV6_NODE,
12230 &no_ipv6_bgp_distance_source_access_list_cmd);
12231 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
12232 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
12233 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
12234 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
12235 install_element(BGP_IPV6M_NODE,
12236 &ipv6_bgp_distance_source_access_list_cmd);
12237 install_element(BGP_IPV6M_NODE,
12238 &no_ipv6_bgp_distance_source_access_list_cmd);
12239
12240 install_element(BGP_NODE, &bgp_damp_set_cmd);
12241 install_element(BGP_NODE, &bgp_damp_unset_cmd);
12242 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
12243 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
12244
12245 /* IPv4 Multicast Mode */
12246 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
12247 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
12248
12249 /* Large Communities */
12250 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
12251 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
12252
12253 /* show bgp ipv4 flowspec detailed */
12254 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
12255
12256 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
12257 }
12258
12259 void bgp_route_finish(void)
12260 {
12261 afi_t afi;
12262 safi_t safi;
12263
12264 FOREACH_AFI_SAFI (afi, safi) {
12265 bgp_table_unlock(bgp_distance_table[afi][safi]);
12266 bgp_distance_table[afi][safi] = NULL;
12267 }
12268 }