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