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