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