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