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