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