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