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