]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #5514 from Jafaral/nhrp-docs
[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_hostname(struct peer *peer, struct attr *attr)
7152 {
7153 if (peer->hostname && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)
7154 && !(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))
7155 return peer->hostname;
7156 return NULL;
7157 }
7158
7159 /* called from terminal list command */
7160 void route_vty_out(struct vty *vty, struct prefix *p,
7161 struct bgp_path_info *path, int display, safi_t safi,
7162 json_object *json_paths)
7163 {
7164 struct attr *attr = path->attr;
7165 json_object *json_path = NULL;
7166 json_object *json_nexthops = NULL;
7167 json_object *json_nexthop_global = NULL;
7168 json_object *json_nexthop_ll = NULL;
7169 json_object *json_ext_community = NULL;
7170 char vrf_id_str[VRF_NAMSIZ] = {0};
7171 bool nexthop_self =
7172 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
7173 bool nexthop_othervrf = false;
7174 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
7175 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
7176 char *nexthop_hostname = bgp_nexthop_hostname(path->peer, attr);
7177
7178 if (json_paths)
7179 json_path = json_object_new_object();
7180
7181 /* short status lead text */
7182 route_vty_short_status_out(vty, path, json_path);
7183
7184 if (!json_paths) {
7185 /* print prefix and mask */
7186 if (!display)
7187 route_vty_out_route(p, vty, json_path);
7188 else
7189 vty_out(vty, "%*s", 17, " ");
7190 } else {
7191 route_vty_out_route(p, vty, json_path);
7192 }
7193
7194 /*
7195 * If vrf id of nexthop is different from that of prefix,
7196 * set up printable string to append
7197 */
7198 if (path->extra && path->extra->bgp_orig) {
7199 const char *self = "";
7200
7201 if (nexthop_self)
7202 self = "<";
7203
7204 nexthop_othervrf = true;
7205 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
7206
7207 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
7208 snprintf(vrf_id_str, sizeof(vrf_id_str),
7209 "@%s%s", VRFID_NONE_STR, self);
7210 else
7211 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
7212 path->extra->bgp_orig->vrf_id, self);
7213
7214 if (path->extra->bgp_orig->inst_type
7215 != BGP_INSTANCE_TYPE_DEFAULT)
7216
7217 nexthop_vrfname = path->extra->bgp_orig->name;
7218 } else {
7219 const char *self = "";
7220
7221 if (nexthop_self)
7222 self = "<";
7223
7224 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
7225 }
7226
7227 /*
7228 * For ENCAP and EVPN routes, nexthop address family is not
7229 * neccessarily the same as the prefix address family.
7230 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
7231 * EVPN routes are also exchanged with a MP nexthop. Currently,
7232 * this
7233 * is only IPv4, the value will be present in either
7234 * attr->nexthop or
7235 * attr->mp_nexthop_global_in
7236 */
7237 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
7238 char buf[BUFSIZ];
7239 char nexthop[128];
7240 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
7241
7242 switch (af) {
7243 case AF_INET:
7244 sprintf(nexthop, "%s",
7245 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
7246 BUFSIZ));
7247 break;
7248 case AF_INET6:
7249 sprintf(nexthop, "%s",
7250 inet_ntop(af, &attr->mp_nexthop_global, buf,
7251 BUFSIZ));
7252 break;
7253 default:
7254 sprintf(nexthop, "?");
7255 break;
7256 }
7257
7258 if (json_paths) {
7259 json_nexthop_global = json_object_new_object();
7260
7261 json_object_string_add(json_nexthop_global, "ip",
7262 nexthop);
7263
7264 if (nexthop_hostname)
7265 json_object_string_add(json_nexthop_global,
7266 "hostname",
7267 nexthop_hostname);
7268
7269 json_object_string_add(json_nexthop_global, "afi",
7270 (af == AF_INET) ? "ipv4"
7271 : "ipv6");
7272 json_object_boolean_true_add(json_nexthop_global,
7273 "used");
7274 } else
7275 vty_out(vty, "%s%s",
7276 nexthop_hostname ? nexthop_hostname : 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(json_nexthop_global, "ip",
7283 inet_ntoa(attr->nexthop));
7284
7285 if (nexthop_hostname)
7286 json_object_string_add(json_nexthop_global,
7287 "hostname",
7288 nexthop_hostname);
7289
7290 json_object_string_add(json_nexthop_global, "afi",
7291 "ipv4");
7292 json_object_boolean_true_add(json_nexthop_global,
7293 "used");
7294 } else
7295 vty_out(vty, "%-16s%s",
7296 nexthop_hostname ? nexthop_hostname
7297 : inet_ntoa(attr->nexthop),
7298 vrf_id_str);
7299 } else if (safi == SAFI_FLOWSPEC) {
7300 if (attr->nexthop.s_addr != 0) {
7301 if (json_paths) {
7302 json_nexthop_global = json_object_new_object();
7303
7304 json_object_string_add(json_nexthop_global,
7305 "afi", "ipv4");
7306 json_object_string_add(
7307 json_nexthop_global, "ip",
7308 inet_ntoa(attr->nexthop));
7309
7310 if (nexthop_hostname)
7311 json_object_string_add(
7312 json_nexthop_global, "hostname",
7313 nexthop_hostname);
7314
7315 json_object_boolean_true_add(
7316 json_nexthop_global,
7317 "used");
7318 } else {
7319 vty_out(vty, "%-16s",
7320 nexthop_hostname
7321 ? nexthop_hostname
7322 : inet_ntoa(attr->nexthop));
7323 }
7324 }
7325 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7326 if (json_paths) {
7327 json_nexthop_global = json_object_new_object();
7328
7329 json_object_string_add(json_nexthop_global, "ip",
7330 inet_ntoa(attr->nexthop));
7331
7332 if (nexthop_hostname)
7333 json_object_string_add(json_nexthop_global,
7334 "hostname",
7335 nexthop_hostname);
7336
7337 json_object_string_add(json_nexthop_global, "afi",
7338 "ipv4");
7339 json_object_boolean_true_add(json_nexthop_global,
7340 "used");
7341 } else {
7342 char buf[BUFSIZ];
7343
7344 snprintf(buf, sizeof(buf), "%s%s",
7345 nexthop_hostname ? nexthop_hostname
7346 : inet_ntoa(attr->nexthop),
7347 vrf_id_str);
7348 vty_out(vty, "%-16s", buf);
7349 }
7350 }
7351
7352 /* IPv6 Next Hop */
7353 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7354 int len;
7355 char buf[BUFSIZ];
7356
7357 if (json_paths) {
7358 json_nexthop_global = json_object_new_object();
7359 json_object_string_add(
7360 json_nexthop_global, "ip",
7361 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
7362 buf, BUFSIZ));
7363
7364 if (nexthop_hostname)
7365 json_object_string_add(json_nexthop_global,
7366 "hostname",
7367 nexthop_hostname);
7368
7369 json_object_string_add(json_nexthop_global, "afi",
7370 "ipv6");
7371 json_object_string_add(json_nexthop_global, "scope",
7372 "global");
7373
7374 /* We display both LL & GL if both have been
7375 * received */
7376 if ((attr->mp_nexthop_len
7377 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
7378 || (path->peer->conf_if)) {
7379 json_nexthop_ll = json_object_new_object();
7380 json_object_string_add(
7381 json_nexthop_ll, "ip",
7382 inet_ntop(AF_INET6,
7383 &attr->mp_nexthop_local, buf,
7384 BUFSIZ));
7385
7386 if (nexthop_hostname)
7387 json_object_string_add(
7388 json_nexthop_ll, "hostname",
7389 nexthop_hostname);
7390
7391 json_object_string_add(json_nexthop_ll, "afi",
7392 "ipv6");
7393 json_object_string_add(json_nexthop_ll, "scope",
7394 "link-local");
7395
7396 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
7397 &attr->mp_nexthop_local)
7398 != 0)
7399 && !attr->mp_nexthop_prefer_global)
7400 json_object_boolean_true_add(
7401 json_nexthop_ll, "used");
7402 else
7403 json_object_boolean_true_add(
7404 json_nexthop_global, "used");
7405 } else
7406 json_object_boolean_true_add(
7407 json_nexthop_global, "used");
7408 } else {
7409 /* Display LL if LL/Global both in table unless
7410 * prefer-global is set */
7411 if (((attr->mp_nexthop_len
7412 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
7413 && !attr->mp_nexthop_prefer_global)
7414 || (path->peer->conf_if)) {
7415 if (path->peer->conf_if) {
7416 len = vty_out(vty, "%s",
7417 path->peer->conf_if);
7418 len = 16 - len; /* len of IPv6
7419 addr + max
7420 len of def
7421 ifname */
7422
7423 if (len < 1)
7424 vty_out(vty, "\n%*s", 36, " ");
7425 else
7426 vty_out(vty, "%*s", len, " ");
7427 } else {
7428 len = vty_out(
7429 vty, "%s%s",
7430 nexthop_hostname
7431 ? nexthop_hostname
7432 : inet_ntop(
7433 AF_INET6,
7434 &attr->mp_nexthop_local,
7435 buf, BUFSIZ),
7436 vrf_id_str);
7437 len = 16 - len;
7438
7439 if (len < 1)
7440 vty_out(vty, "\n%*s", 36, " ");
7441 else
7442 vty_out(vty, "%*s", len, " ");
7443 }
7444 } else {
7445 len = vty_out(
7446 vty, "%s%s",
7447 nexthop_hostname
7448 ? nexthop_hostname
7449 : inet_ntop(
7450 AF_INET6,
7451 &attr->mp_nexthop_global,
7452 buf, BUFSIZ),
7453 vrf_id_str);
7454 len = 16 - len;
7455
7456 if (len < 1)
7457 vty_out(vty, "\n%*s", 36, " ");
7458 else
7459 vty_out(vty, "%*s", len, " ");
7460 }
7461 }
7462 }
7463
7464 /* MED/Metric */
7465 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7466 if (json_paths) {
7467
7468 /*
7469 * Adding "metric" field to match with corresponding
7470 * CLI. "med" will be deprecated in future.
7471 */
7472 json_object_int_add(json_path, "med", attr->med);
7473 json_object_int_add(json_path, "metric", attr->med);
7474 } else
7475 vty_out(vty, "%10u", attr->med);
7476 else if (!json_paths)
7477 vty_out(vty, " ");
7478
7479 /* Local Pref */
7480 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
7481 if (json_paths) {
7482
7483 /*
7484 * Adding "locPrf" field to match with corresponding
7485 * CLI. "localPref" will be deprecated in future.
7486 */
7487 json_object_int_add(json_path, "localpref",
7488 attr->local_pref);
7489 json_object_int_add(json_path, "locPrf",
7490 attr->local_pref);
7491 } else
7492 vty_out(vty, "%7u", attr->local_pref);
7493 else if (!json_paths)
7494 vty_out(vty, " ");
7495
7496 if (json_paths)
7497 json_object_int_add(json_path, "weight", attr->weight);
7498 else
7499 vty_out(vty, "%7u ", attr->weight);
7500
7501 if (json_paths) {
7502 char buf[BUFSIZ];
7503 json_object_string_add(
7504 json_path, "peerId",
7505 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
7506 }
7507
7508 /* Print aspath */
7509 if (attr->aspath) {
7510 if (json_paths) {
7511
7512 /*
7513 * Adding "path" field to match with corresponding
7514 * CLI. "aspath" will be deprecated in future.
7515 */
7516 json_object_string_add(json_path, "aspath",
7517 attr->aspath->str);
7518 json_object_string_add(json_path, "path",
7519 attr->aspath->str);
7520 } else
7521 aspath_print_vty(vty, "%s", attr->aspath, " ");
7522 }
7523
7524 /* Print origin */
7525 if (json_paths)
7526 json_object_string_add(json_path, "origin",
7527 bgp_origin_long_str[attr->origin]);
7528 else
7529 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7530
7531 if (json_paths) {
7532 if (safi == SAFI_EVPN &&
7533 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
7534 json_ext_community = json_object_new_object();
7535 json_object_string_add(json_ext_community,
7536 "string",
7537 attr->ecommunity->str);
7538 json_object_object_add(json_path,
7539 "extendedCommunity",
7540 json_ext_community);
7541 }
7542
7543 if (nexthop_self)
7544 json_object_boolean_true_add(json_path,
7545 "announceNexthopSelf");
7546 if (nexthop_othervrf) {
7547 json_object_string_add(json_path, "nhVrfName",
7548 nexthop_vrfname);
7549
7550 json_object_int_add(json_path, "nhVrfId",
7551 ((nexthop_vrfid == VRF_UNKNOWN)
7552 ? -1
7553 : (int)nexthop_vrfid));
7554 }
7555 }
7556
7557 if (json_paths) {
7558 if (json_nexthop_global || json_nexthop_ll) {
7559 json_nexthops = json_object_new_array();
7560
7561 if (json_nexthop_global)
7562 json_object_array_add(json_nexthops,
7563 json_nexthop_global);
7564
7565 if (json_nexthop_ll)
7566 json_object_array_add(json_nexthops,
7567 json_nexthop_ll);
7568
7569 json_object_object_add(json_path, "nexthops",
7570 json_nexthops);
7571 }
7572
7573 json_object_array_add(json_paths, json_path);
7574 } else {
7575 vty_out(vty, "\n");
7576
7577 if (safi == SAFI_EVPN &&
7578 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
7579 vty_out(vty, "%*s", 20, " ");
7580 vty_out(vty, "%s\n", attr->ecommunity->str);
7581 }
7582
7583 #if ENABLE_BGP_VNC
7584 /* prints an additional line, indented, with VNC info, if
7585 * present */
7586 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
7587 rfapi_vty_out_vncinfo(vty, p, path, safi);
7588 #endif
7589 }
7590 }
7591
7592 /* called from terminal list command */
7593 void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
7594 safi_t safi, bool use_json, json_object *json_ar)
7595 {
7596 json_object *json_status = NULL;
7597 json_object *json_net = NULL;
7598 char buff[BUFSIZ];
7599
7600 /* Route status display. */
7601 if (use_json) {
7602 json_status = json_object_new_object();
7603 json_net = json_object_new_object();
7604 } else {
7605 vty_out(vty, "*");
7606 vty_out(vty, ">");
7607 vty_out(vty, " ");
7608 }
7609
7610 /* print prefix and mask */
7611 if (use_json) {
7612 if (safi == SAFI_EVPN)
7613 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
7614 else if (p->family == AF_INET || p->family == AF_INET6) {
7615 json_object_string_add(
7616 json_net, "addrPrefix",
7617 inet_ntop(p->family, &p->u.prefix, buff,
7618 BUFSIZ));
7619 json_object_int_add(json_net, "prefixLen",
7620 p->prefixlen);
7621 prefix2str(p, buff, PREFIX_STRLEN);
7622 json_object_string_add(json_net, "network", buff);
7623 }
7624 } else
7625 route_vty_out_route(p, vty, NULL);
7626
7627 /* Print attribute */
7628 if (attr) {
7629 if (use_json) {
7630 if (p->family == AF_INET
7631 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7632 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7633 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
7634 json_object_string_add(
7635 json_net, "nextHop",
7636 inet_ntoa(
7637 attr->mp_nexthop_global_in));
7638 else
7639 json_object_string_add(
7640 json_net, "nextHop",
7641 inet_ntoa(attr->nexthop));
7642 } else if (p->family == AF_INET6
7643 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7644 char buf[BUFSIZ];
7645
7646 json_object_string_add(
7647 json_net, "nextHopGlobal",
7648 inet_ntop(AF_INET6,
7649 &attr->mp_nexthop_global, buf,
7650 BUFSIZ));
7651 } else if (p->family == AF_EVPN &&
7652 !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7653 json_object_string_add(json_net,
7654 "nextHop", inet_ntoa(
7655 attr->mp_nexthop_global_in));
7656
7657 if (attr->flag
7658 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7659 json_object_int_add(json_net, "metric",
7660 attr->med);
7661
7662 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
7663
7664 /*
7665 * Adding "locPrf" field to match with
7666 * corresponding CLI. "localPref" will be
7667 * deprecated in future.
7668 */
7669 json_object_int_add(json_net, "localPref",
7670 attr->local_pref);
7671 json_object_int_add(json_net, "locPrf",
7672 attr->local_pref);
7673 }
7674
7675 json_object_int_add(json_net, "weight", attr->weight);
7676
7677 /* Print aspath */
7678 if (attr->aspath) {
7679
7680 /*
7681 * Adding "path" field to match with
7682 * corresponding CLI. "localPref" will be
7683 * deprecated in future.
7684 */
7685 json_object_string_add(json_net, "asPath",
7686 attr->aspath->str);
7687 json_object_string_add(json_net, "path",
7688 attr->aspath->str);
7689 }
7690
7691 /* Print origin */
7692 json_object_string_add(json_net, "bgpOriginCode",
7693 bgp_origin_str[attr->origin]);
7694 } else {
7695 if (p->family == AF_INET
7696 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7697 || safi == SAFI_EVPN
7698 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7699 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7700 || safi == SAFI_EVPN)
7701 vty_out(vty, "%-16s",
7702 inet_ntoa(
7703 attr->mp_nexthop_global_in));
7704 else
7705 vty_out(vty, "%-16s",
7706 inet_ntoa(attr->nexthop));
7707 } else if (p->family == AF_INET6
7708 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7709 int len;
7710 char buf[BUFSIZ];
7711
7712 len = vty_out(
7713 vty, "%s",
7714 inet_ntop(AF_INET6,
7715 &attr->mp_nexthop_global, buf,
7716 BUFSIZ));
7717 len = 16 - len;
7718 if (len < 1)
7719 vty_out(vty, "\n%*s", 36, " ");
7720 else
7721 vty_out(vty, "%*s", len, " ");
7722 }
7723 if (attr->flag
7724 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7725 vty_out(vty, "%10u", attr->med);
7726 else
7727 vty_out(vty, " ");
7728
7729 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
7730 vty_out(vty, "%7u", attr->local_pref);
7731 else
7732 vty_out(vty, " ");
7733
7734 vty_out(vty, "%7u ", attr->weight);
7735
7736 /* Print aspath */
7737 if (attr->aspath)
7738 aspath_print_vty(vty, "%s", attr->aspath, " ");
7739
7740 /* Print origin */
7741 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7742 }
7743 }
7744 if (use_json) {
7745 json_object_boolean_true_add(json_status, "*");
7746 json_object_boolean_true_add(json_status, ">");
7747 json_object_object_add(json_net, "appliedStatusSymbols",
7748 json_status);
7749
7750 prefix2str(p, buff, PREFIX_STRLEN);
7751 json_object_object_add(json_ar, buff, json_net);
7752 } else
7753 vty_out(vty, "\n");
7754 }
7755
7756 void route_vty_out_tag(struct vty *vty, struct prefix *p,
7757 struct bgp_path_info *path, int display, safi_t safi,
7758 json_object *json)
7759 {
7760 json_object *json_out = NULL;
7761 struct attr *attr;
7762 mpls_label_t label = MPLS_INVALID_LABEL;
7763
7764 if (!path->extra)
7765 return;
7766
7767 if (json)
7768 json_out = json_object_new_object();
7769
7770 /* short status lead text */
7771 route_vty_short_status_out(vty, path, json_out);
7772
7773 /* print prefix and mask */
7774 if (json == NULL) {
7775 if (!display)
7776 route_vty_out_route(p, vty, NULL);
7777 else
7778 vty_out(vty, "%*s", 17, " ");
7779 }
7780
7781 /* Print attribute */
7782 attr = path->attr;
7783 if (((p->family == AF_INET)
7784 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
7785 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7786 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7787 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7788 || safi == SAFI_EVPN) {
7789 if (json)
7790 json_object_string_add(
7791 json_out, "mpNexthopGlobalIn",
7792 inet_ntoa(attr->mp_nexthop_global_in));
7793 else
7794 vty_out(vty, "%-16s",
7795 inet_ntoa(attr->mp_nexthop_global_in));
7796 } else {
7797 if (json)
7798 json_object_string_add(
7799 json_out, "nexthop",
7800 inet_ntoa(attr->nexthop));
7801 else
7802 vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
7803 }
7804 } else if (((p->family == AF_INET6)
7805 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
7806 || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7807 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7808 char buf_a[512];
7809
7810 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
7811 if (json)
7812 json_object_string_add(
7813 json_out, "mpNexthopGlobalIn",
7814 inet_ntop(AF_INET6,
7815 &attr->mp_nexthop_global,
7816 buf_a, sizeof(buf_a)));
7817 else
7818 vty_out(vty, "%s",
7819 inet_ntop(AF_INET6,
7820 &attr->mp_nexthop_global,
7821 buf_a, sizeof(buf_a)));
7822 } else if (attr->mp_nexthop_len
7823 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
7824 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
7825 &attr->mp_nexthop_global,
7826 &attr->mp_nexthop_local);
7827 if (json)
7828 json_object_string_add(json_out,
7829 "mpNexthopGlobalLocal",
7830 buf_a);
7831 else
7832 vty_out(vty, "%s", buf_a);
7833 }
7834 }
7835
7836 label = decode_label(&path->extra->label[0]);
7837
7838 if (bgp_is_valid_label(&label)) {
7839 if (json) {
7840 json_object_int_add(json_out, "notag", label);
7841 json_object_array_add(json, json_out);
7842 } else {
7843 vty_out(vty, "notag/%d", label);
7844 vty_out(vty, "\n");
7845 }
7846 }
7847 }
7848
7849 void route_vty_out_overlay(struct vty *vty, struct prefix *p,
7850 struct bgp_path_info *path, int display,
7851 json_object *json_paths)
7852 {
7853 struct attr *attr;
7854 char buf[BUFSIZ] = {0};
7855 json_object *json_path = NULL;
7856 json_object *json_nexthop = NULL;
7857 json_object *json_overlay = NULL;
7858
7859 if (!path->extra)
7860 return;
7861
7862 if (json_paths) {
7863 json_path = json_object_new_object();
7864 json_overlay = json_object_new_object();
7865 json_nexthop = json_object_new_object();
7866 }
7867
7868 /* short status lead text */
7869 route_vty_short_status_out(vty, path, json_path);
7870
7871 /* print prefix and mask */
7872 if (!display)
7873 route_vty_out_route(p, vty, json_path);
7874 else
7875 vty_out(vty, "%*s", 17, " ");
7876
7877 /* Print attribute */
7878 attr = path->attr;
7879 char buf1[BUFSIZ];
7880 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
7881
7882 switch (af) {
7883 case AF_INET:
7884 inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ);
7885 if (!json_path) {
7886 vty_out(vty, "%-16s", buf);
7887 } else {
7888 json_object_string_add(json_nexthop, "ip", buf);
7889
7890 json_object_string_add(json_nexthop, "afi", "ipv4");
7891
7892 json_object_object_add(json_path, "nexthop",
7893 json_nexthop);
7894 }
7895 break;
7896 case AF_INET6:
7897 inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ);
7898 inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ);
7899 if (!json_path) {
7900 vty_out(vty, "%s(%s)", buf, buf1);
7901 } else {
7902 json_object_string_add(json_nexthop, "ipv6Global", buf);
7903
7904 json_object_string_add(json_nexthop, "ipv6LinkLocal",
7905 buf1);
7906
7907 json_object_string_add(json_nexthop, "afi", "ipv6");
7908
7909 json_object_object_add(json_path, "nexthop",
7910 json_nexthop);
7911 }
7912 break;
7913 default:
7914 if (!json_path) {
7915 vty_out(vty, "?");
7916 } else {
7917 json_object_string_add(json_nexthop, "Error",
7918 "Unsupported address-family");
7919 }
7920 }
7921
7922 char *str = esi2str(&(attr->evpn_overlay.eth_s_id));
7923
7924 if (!json_path)
7925 vty_out(vty, "%s", str);
7926 else
7927 json_object_string_add(json_overlay, "esi", str);
7928
7929 XFREE(MTYPE_TMP, str);
7930
7931 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) {
7932 inet_ntop(AF_INET, &(attr->evpn_overlay.gw_ip.ipv4), buf,
7933 BUFSIZ);
7934 } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) {
7935 inet_ntop(AF_INET6, &(attr->evpn_overlay.gw_ip.ipv6), buf,
7936 BUFSIZ);
7937 }
7938
7939 if (!json_path)
7940 vty_out(vty, "/%s", buf);
7941 else
7942 json_object_string_add(json_overlay, "gw", buf);
7943
7944 if (attr->ecommunity) {
7945 char *mac = NULL;
7946 struct ecommunity_val *routermac = ecommunity_lookup(
7947 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
7948 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
7949
7950 if (routermac)
7951 mac = ecom_mac2str((char *)routermac->val);
7952 if (mac) {
7953 if (!json_path) {
7954 vty_out(vty, "/%s", (char *)mac);
7955 } else {
7956 json_object_string_add(json_overlay, "rmac",
7957 mac);
7958 }
7959 XFREE(MTYPE_TMP, mac);
7960 }
7961 }
7962
7963 if (!json_path) {
7964 vty_out(vty, "\n");
7965 } else {
7966 json_object_object_add(json_path, "overlay", json_overlay);
7967
7968 json_object_array_add(json_paths, json_path);
7969 }
7970 }
7971
7972 /* dampening route */
7973 static void damp_route_vty_out(struct vty *vty, struct prefix *p,
7974 struct bgp_path_info *path, int display, afi_t afi,
7975 safi_t safi, bool use_json, json_object *json)
7976 {
7977 struct attr *attr;
7978 int len;
7979 char timebuf[BGP_UPTIME_LEN];
7980
7981 /* short status lead text */
7982 route_vty_short_status_out(vty, path, json);
7983
7984 /* print prefix and mask */
7985 if (!use_json) {
7986 if (!display)
7987 route_vty_out_route(p, vty, NULL);
7988 else
7989 vty_out(vty, "%*s", 17, " ");
7990 }
7991
7992 len = vty_out(vty, "%s", path->peer->host);
7993 len = 17 - len;
7994 if (len < 1) {
7995 if (!use_json)
7996 vty_out(vty, "\n%*s", 34, " ");
7997 } else {
7998 if (use_json)
7999 json_object_int_add(json, "peerHost", len);
8000 else
8001 vty_out(vty, "%*s", len, " ");
8002 }
8003
8004 if (use_json)
8005 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
8006 safi, use_json, json);
8007 else
8008 vty_out(vty, "%s ",
8009 bgp_damp_reuse_time_vty(vty, path, timebuf,
8010 BGP_UPTIME_LEN, afi, safi,
8011 use_json, json));
8012
8013 /* Print attribute */
8014 attr = path->attr;
8015
8016 /* Print aspath */
8017 if (attr->aspath) {
8018 if (use_json)
8019 json_object_string_add(json, "asPath",
8020 attr->aspath->str);
8021 else
8022 aspath_print_vty(vty, "%s", attr->aspath, " ");
8023 }
8024
8025 /* Print origin */
8026 if (use_json)
8027 json_object_string_add(json, "origin",
8028 bgp_origin_str[attr->origin]);
8029 else
8030 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8031
8032 if (!use_json)
8033 vty_out(vty, "\n");
8034 }
8035
8036 /* flap route */
8037 static void flap_route_vty_out(struct vty *vty, struct prefix *p,
8038 struct bgp_path_info *path, int display, afi_t afi,
8039 safi_t safi, bool use_json, json_object *json)
8040 {
8041 struct attr *attr;
8042 struct bgp_damp_info *bdi;
8043 char timebuf[BGP_UPTIME_LEN];
8044 int len;
8045
8046 if (!path->extra)
8047 return;
8048
8049 bdi = path->extra->damp_info;
8050
8051 /* short status lead text */
8052 route_vty_short_status_out(vty, path, json);
8053
8054 /* print prefix and mask */
8055 if (!use_json) {
8056 if (!display)
8057 route_vty_out_route(p, vty, NULL);
8058 else
8059 vty_out(vty, "%*s", 17, " ");
8060 }
8061
8062 len = vty_out(vty, "%s", path->peer->host);
8063 len = 16 - len;
8064 if (len < 1) {
8065 if (!use_json)
8066 vty_out(vty, "\n%*s", 33, " ");
8067 } else {
8068 if (use_json)
8069 json_object_int_add(json, "peerHost", len);
8070 else
8071 vty_out(vty, "%*s", len, " ");
8072 }
8073
8074 len = vty_out(vty, "%d", bdi->flap);
8075 len = 5 - len;
8076 if (len < 1) {
8077 if (!use_json)
8078 vty_out(vty, " ");
8079 } else {
8080 if (use_json)
8081 json_object_int_add(json, "bdiFlap", len);
8082 else
8083 vty_out(vty, "%*s", len, " ");
8084 }
8085
8086 if (use_json)
8087 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
8088 json);
8089 else
8090 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
8091 BGP_UPTIME_LEN, 0, NULL));
8092
8093 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
8094 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8095 if (use_json)
8096 bgp_damp_reuse_time_vty(vty, path, timebuf,
8097 BGP_UPTIME_LEN, afi, safi,
8098 use_json, json);
8099 else
8100 vty_out(vty, "%s ",
8101 bgp_damp_reuse_time_vty(vty, path, timebuf,
8102 BGP_UPTIME_LEN, afi,
8103 safi, use_json, json));
8104 } else {
8105 if (!use_json)
8106 vty_out(vty, "%*s ", 8, " ");
8107 }
8108
8109 /* Print attribute */
8110 attr = path->attr;
8111
8112 /* Print aspath */
8113 if (attr->aspath) {
8114 if (use_json)
8115 json_object_string_add(json, "asPath",
8116 attr->aspath->str);
8117 else
8118 aspath_print_vty(vty, "%s", attr->aspath, " ");
8119 }
8120
8121 /* Print origin */
8122 if (use_json)
8123 json_object_string_add(json, "origin",
8124 bgp_origin_str[attr->origin]);
8125 else
8126 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8127
8128 if (!use_json)
8129 vty_out(vty, "\n");
8130 }
8131
8132 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
8133 int *first, const char *header,
8134 json_object *json_adv_to)
8135 {
8136 char buf1[INET6_ADDRSTRLEN];
8137 json_object *json_peer = NULL;
8138
8139 if (json_adv_to) {
8140 /* 'advertised-to' is a dictionary of peers we have advertised
8141 * this
8142 * prefix too. The key is the peer's IP or swpX, the value is
8143 * the
8144 * hostname if we know it and "" if not.
8145 */
8146 json_peer = json_object_new_object();
8147
8148 if (peer->hostname)
8149 json_object_string_add(json_peer, "hostname",
8150 peer->hostname);
8151
8152 if (peer->conf_if)
8153 json_object_object_add(json_adv_to, peer->conf_if,
8154 json_peer);
8155 else
8156 json_object_object_add(
8157 json_adv_to,
8158 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
8159 json_peer);
8160 } else {
8161 if (*first) {
8162 vty_out(vty, "%s", header);
8163 *first = 0;
8164 }
8165
8166 if (peer->hostname
8167 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
8168 if (peer->conf_if)
8169 vty_out(vty, " %s(%s)", peer->hostname,
8170 peer->conf_if);
8171 else
8172 vty_out(vty, " %s(%s)", peer->hostname,
8173 sockunion2str(&peer->su, buf1,
8174 SU_ADDRSTRLEN));
8175 } else {
8176 if (peer->conf_if)
8177 vty_out(vty, " %s", peer->conf_if);
8178 else
8179 vty_out(vty, " %s",
8180 sockunion2str(&peer->su, buf1,
8181 SU_ADDRSTRLEN));
8182 }
8183 }
8184 }
8185
8186 static void route_vty_out_tx_ids(struct vty *vty,
8187 struct bgp_addpath_info_data *d)
8188 {
8189 int i;
8190
8191 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
8192 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
8193 d->addpath_tx_id[i],
8194 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
8195 }
8196 }
8197
8198 static const char *bgp_path_selection_reason2str(
8199 enum bgp_path_selection_reason reason)
8200 {
8201 switch (reason) {
8202 case bgp_path_selection_none:
8203 return "Nothing to Select";
8204 break;
8205 case bgp_path_selection_first:
8206 return "First path received";
8207 break;
8208 case bgp_path_selection_evpn_sticky_mac:
8209 return "EVPN Sticky Mac";
8210 break;
8211 case bgp_path_selection_evpn_seq:
8212 return "EVPN sequence number";
8213 break;
8214 case bgp_path_selection_evpn_lower_ip:
8215 return "EVPN lower IP";
8216 break;
8217 case bgp_path_selection_weight:
8218 return "Weight";
8219 break;
8220 case bgp_path_selection_local_pref:
8221 return "Local Pref";
8222 break;
8223 case bgp_path_selection_local_route:
8224 return "Local Route";
8225 break;
8226 case bgp_path_selection_confed_as_path:
8227 return "Confederation based AS Path";
8228 break;
8229 case bgp_path_selection_as_path:
8230 return "AS Path";
8231 break;
8232 case bgp_path_selection_origin:
8233 return "Origin";
8234 break;
8235 case bgp_path_selection_med:
8236 return "MED";
8237 break;
8238 case bgp_path_selection_peer:
8239 return "Peer Type";
8240 break;
8241 case bgp_path_selection_confed:
8242 return "Confed Peer Type";
8243 break;
8244 case bgp_path_selection_igp_metric:
8245 return "IGP Metric";
8246 break;
8247 case bgp_path_selection_older:
8248 return "Older Path";
8249 break;
8250 case bgp_path_selection_router_id:
8251 return "Router ID";
8252 break;
8253 case bgp_path_selection_cluster_length:
8254 return "Cluser length";
8255 break;
8256 case bgp_path_selection_stale:
8257 return "Path Staleness";
8258 break;
8259 case bgp_path_selection_local_configured:
8260 return "Locally configured route";
8261 break;
8262 case bgp_path_selection_neighbor_ip:
8263 return "Neighbor IP";
8264 break;
8265 case bgp_path_selection_default:
8266 return "Nothing left to compare";
8267 break;
8268 }
8269 return "Invalid (internal error)";
8270 }
8271
8272 void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
8273 struct bgp_node *bn, struct bgp_path_info *path,
8274 afi_t afi, safi_t safi, json_object *json_paths)
8275 {
8276 char buf[INET6_ADDRSTRLEN];
8277 char buf1[BUFSIZ];
8278 char buf2[EVPN_ROUTE_STRLEN];
8279 struct attr *attr = path->attr;
8280 int sockunion_vty_out(struct vty *, union sockunion *);
8281 time_t tbuf;
8282 json_object *json_bestpath = NULL;
8283 json_object *json_cluster_list = NULL;
8284 json_object *json_cluster_list_list = NULL;
8285 json_object *json_ext_community = NULL;
8286 json_object *json_last_update = NULL;
8287 json_object *json_pmsi = NULL;
8288 json_object *json_nexthop_global = NULL;
8289 json_object *json_nexthop_ll = NULL;
8290 json_object *json_nexthops = NULL;
8291 json_object *json_path = NULL;
8292 json_object *json_peer = NULL;
8293 json_object *json_string = NULL;
8294 json_object *json_adv_to = NULL;
8295 int first = 0;
8296 struct listnode *node, *nnode;
8297 struct peer *peer;
8298 int addpath_capable;
8299 int has_adj;
8300 unsigned int first_as;
8301 bool nexthop_self =
8302 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8303 int i;
8304 char *nexthop_hostname = bgp_nexthop_hostname(path->peer, attr);
8305
8306 if (json_paths) {
8307 json_path = json_object_new_object();
8308 json_peer = json_object_new_object();
8309 json_nexthop_global = json_object_new_object();
8310 }
8311
8312 if (path->extra) {
8313 char tag_buf[30];
8314
8315 buf2[0] = '\0';
8316 tag_buf[0] = '\0';
8317 if (path->extra && path->extra->num_labels) {
8318 bgp_evpn_label2str(path->extra->label,
8319 path->extra->num_labels, tag_buf,
8320 sizeof(tag_buf));
8321 }
8322 if (safi == SAFI_EVPN) {
8323 if (!json_paths) {
8324 bgp_evpn_route2str((struct prefix_evpn *)&bn->p,
8325 buf2, sizeof(buf2));
8326 vty_out(vty, " Route %s", buf2);
8327 if (tag_buf[0] != '\0')
8328 vty_out(vty, " VNI %s", tag_buf);
8329 vty_out(vty, "\n");
8330 } else {
8331 if (tag_buf[0])
8332 json_object_string_add(json_path, "VNI",
8333 tag_buf);
8334 }
8335 }
8336
8337 if (path->extra && path->extra->parent && !json_paths) {
8338 struct bgp_path_info *parent_ri;
8339 struct bgp_node *rn, *prn;
8340
8341 parent_ri = (struct bgp_path_info *)path->extra->parent;
8342 rn = parent_ri->net;
8343 if (rn && rn->prn) {
8344 prn = rn->prn;
8345 prefix_rd2str((struct prefix_rd *)&prn->p,
8346 buf1, sizeof(buf1));
8347 if (is_pi_family_evpn(parent_ri)) {
8348 bgp_evpn_route2str((struct prefix_evpn *)&rn->p,
8349 buf2, sizeof(buf2));
8350 vty_out(vty, " Imported from %s:%s, VNI %s\n", buf1, buf2, tag_buf);
8351 } else
8352 vty_out(vty, " Imported from %s:%s\n", buf1, buf2);
8353 }
8354 }
8355 }
8356
8357 /* Line1 display AS-path, Aggregator */
8358 if (attr->aspath) {
8359 if (json_paths) {
8360 if (!attr->aspath->json)
8361 aspath_str_update(attr->aspath, true);
8362 json_object_lock(attr->aspath->json);
8363 json_object_object_add(json_path, "aspath",
8364 attr->aspath->json);
8365 } else {
8366 if (attr->aspath->segments)
8367 aspath_print_vty(vty, " %s", attr->aspath, "");
8368 else
8369 vty_out(vty, " Local");
8370 }
8371 }
8372
8373 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
8374 if (json_paths)
8375 json_object_boolean_true_add(json_path, "removed");
8376 else
8377 vty_out(vty, ", (removed)");
8378 }
8379
8380 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
8381 if (json_paths)
8382 json_object_boolean_true_add(json_path, "stale");
8383 else
8384 vty_out(vty, ", (stale)");
8385 }
8386
8387 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
8388 if (json_paths) {
8389 json_object_int_add(json_path, "aggregatorAs",
8390 attr->aggregator_as);
8391 json_object_string_add(
8392 json_path, "aggregatorId",
8393 inet_ntoa(attr->aggregator_addr));
8394 } else {
8395 vty_out(vty, ", (aggregated by %u %s)",
8396 attr->aggregator_as,
8397 inet_ntoa(attr->aggregator_addr));
8398 }
8399 }
8400
8401 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
8402 PEER_FLAG_REFLECTOR_CLIENT)) {
8403 if (json_paths)
8404 json_object_boolean_true_add(json_path,
8405 "rxedFromRrClient");
8406 else
8407 vty_out(vty, ", (Received from a RR-client)");
8408 }
8409
8410 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
8411 PEER_FLAG_RSERVER_CLIENT)) {
8412 if (json_paths)
8413 json_object_boolean_true_add(json_path,
8414 "rxedFromRsClient");
8415 else
8416 vty_out(vty, ", (Received from a RS-client)");
8417 }
8418
8419 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8420 if (json_paths)
8421 json_object_boolean_true_add(json_path,
8422 "dampeningHistoryEntry");
8423 else
8424 vty_out(vty, ", (history entry)");
8425 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
8426 if (json_paths)
8427 json_object_boolean_true_add(json_path,
8428 "dampeningSuppressed");
8429 else
8430 vty_out(vty, ", (suppressed due to dampening)");
8431 }
8432
8433 if (!json_paths)
8434 vty_out(vty, "\n");
8435
8436 /* Line2 display Next-hop, Neighbor, Router-id */
8437 /* Display the nexthop */
8438 if ((bn->p.family == AF_INET || bn->p.family == AF_ETHERNET
8439 || bn->p.family == AF_EVPN)
8440 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
8441 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8442 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8443 || safi == SAFI_EVPN) {
8444 if (json_paths) {
8445 json_object_string_add(
8446 json_nexthop_global, "ip",
8447 inet_ntoa(attr->mp_nexthop_global_in));
8448
8449 if (nexthop_hostname)
8450 json_object_string_add(
8451 json_nexthop_global, "hostname",
8452 nexthop_hostname);
8453 } else
8454 vty_out(vty, " %s",
8455 nexthop_hostname
8456 ? nexthop_hostname
8457 : inet_ntoa(
8458 attr->mp_nexthop_global_in));
8459 } else {
8460 if (json_paths) {
8461 json_object_string_add(
8462 json_nexthop_global, "ip",
8463 inet_ntoa(attr->nexthop));
8464
8465 if (nexthop_hostname)
8466 json_object_string_add(
8467 json_nexthop_global, "hostname",
8468 nexthop_hostname);
8469 } else
8470 vty_out(vty, " %s",
8471 nexthop_hostname
8472 ? nexthop_hostname
8473 : inet_ntoa(attr->nexthop));
8474 }
8475
8476 if (json_paths)
8477 json_object_string_add(json_nexthop_global, "afi",
8478 "ipv4");
8479 } else {
8480 if (json_paths) {
8481 json_object_string_add(
8482 json_nexthop_global, "ip",
8483 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
8484 buf, INET6_ADDRSTRLEN));
8485
8486 if (nexthop_hostname)
8487 json_object_string_add(json_nexthop_global,
8488 "hostname",
8489 nexthop_hostname);
8490
8491 json_object_string_add(json_nexthop_global, "afi",
8492 "ipv6");
8493 json_object_string_add(json_nexthop_global, "scope",
8494 "global");
8495 } else {
8496 vty_out(vty, " %s",
8497 nexthop_hostname
8498 ? nexthop_hostname
8499 : inet_ntop(AF_INET6,
8500 &attr->mp_nexthop_global,
8501 buf, INET6_ADDRSTRLEN));
8502 }
8503 }
8504
8505 /* Display the IGP cost or 'inaccessible' */
8506 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
8507 if (json_paths)
8508 json_object_boolean_false_add(json_nexthop_global,
8509 "accessible");
8510 else
8511 vty_out(vty, " (inaccessible)");
8512 } else {
8513 if (path->extra && path->extra->igpmetric) {
8514 if (json_paths)
8515 json_object_int_add(json_nexthop_global,
8516 "metric",
8517 path->extra->igpmetric);
8518 else
8519 vty_out(vty, " (metric %u)",
8520 path->extra->igpmetric);
8521 }
8522
8523 /* IGP cost is 0, display this only for json */
8524 else {
8525 if (json_paths)
8526 json_object_int_add(json_nexthop_global,
8527 "metric", 0);
8528 }
8529
8530 if (json_paths)
8531 json_object_boolean_true_add(json_nexthop_global,
8532 "accessible");
8533 }
8534
8535 /* Display peer "from" output */
8536 /* This path was originated locally */
8537 if (path->peer == bgp->peer_self) {
8538
8539 if (safi == SAFI_EVPN
8540 || (bn->p.family == AF_INET
8541 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8542 if (json_paths)
8543 json_object_string_add(json_peer, "peerId",
8544 "0.0.0.0");
8545 else
8546 vty_out(vty, " from 0.0.0.0 ");
8547 } else {
8548 if (json_paths)
8549 json_object_string_add(json_peer, "peerId",
8550 "::");
8551 else
8552 vty_out(vty, " from :: ");
8553 }
8554
8555 if (json_paths)
8556 json_object_string_add(json_peer, "routerId",
8557 inet_ntoa(bgp->router_id));
8558 else
8559 vty_out(vty, "(%s)", inet_ntoa(bgp->router_id));
8560 }
8561
8562 /* We RXed this path from one of our peers */
8563 else {
8564
8565 if (json_paths) {
8566 json_object_string_add(json_peer, "peerId",
8567 sockunion2str(&path->peer->su,
8568 buf,
8569 SU_ADDRSTRLEN));
8570 json_object_string_add(json_peer, "routerId",
8571 inet_ntop(AF_INET,
8572 &path->peer->remote_id,
8573 buf1, sizeof(buf1)));
8574
8575 if (path->peer->hostname)
8576 json_object_string_add(json_peer, "hostname",
8577 path->peer->hostname);
8578
8579 if (path->peer->domainname)
8580 json_object_string_add(json_peer, "domainname",
8581 path->peer->domainname);
8582
8583 if (path->peer->conf_if)
8584 json_object_string_add(json_peer, "interface",
8585 path->peer->conf_if);
8586 } else {
8587 if (path->peer->conf_if) {
8588 if (path->peer->hostname
8589 && bgp_flag_check(path->peer->bgp,
8590 BGP_FLAG_SHOW_HOSTNAME))
8591 vty_out(vty, " from %s(%s)",
8592 path->peer->hostname,
8593 path->peer->conf_if);
8594 else
8595 vty_out(vty, " from %s",
8596 path->peer->conf_if);
8597 } else {
8598 if (path->peer->hostname
8599 && bgp_flag_check(path->peer->bgp,
8600 BGP_FLAG_SHOW_HOSTNAME))
8601 vty_out(vty, " from %s(%s)",
8602 path->peer->hostname,
8603 path->peer->host);
8604 else
8605 vty_out(vty, " from %s",
8606 sockunion2str(&path->peer->su,
8607 buf,
8608 SU_ADDRSTRLEN));
8609 }
8610
8611 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
8612 vty_out(vty, " (%s)",
8613 inet_ntoa(attr->originator_id));
8614 else
8615 vty_out(vty, " (%s)",
8616 inet_ntop(AF_INET,
8617 &path->peer->remote_id, buf1,
8618 sizeof(buf1)));
8619 }
8620 }
8621
8622 /*
8623 * Note when vrfid of nexthop is different from that of prefix
8624 */
8625 if (path->extra && path->extra->bgp_orig) {
8626 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
8627
8628 if (json_paths) {
8629 const char *vn;
8630
8631 if (path->extra->bgp_orig->inst_type
8632 == BGP_INSTANCE_TYPE_DEFAULT)
8633 vn = VRF_DEFAULT_NAME;
8634 else
8635 vn = path->extra->bgp_orig->name;
8636
8637 json_object_string_add(json_path, "nhVrfName", vn);
8638
8639 if (nexthop_vrfid == VRF_UNKNOWN) {
8640 json_object_int_add(json_path, "nhVrfId", -1);
8641 } else {
8642 json_object_int_add(json_path, "nhVrfId",
8643 (int)nexthop_vrfid);
8644 }
8645 } else {
8646 if (nexthop_vrfid == VRF_UNKNOWN)
8647 vty_out(vty, " vrf ?");
8648 else
8649 vty_out(vty, " vrf %u", nexthop_vrfid);
8650 }
8651 }
8652
8653 if (nexthop_self) {
8654 if (json_paths) {
8655 json_object_boolean_true_add(json_path,
8656 "announceNexthopSelf");
8657 } else {
8658 vty_out(vty, " announce-nh-self");
8659 }
8660 }
8661
8662 if (!json_paths)
8663 vty_out(vty, "\n");
8664
8665 /* display the link-local nexthop */
8666 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
8667 if (json_paths) {
8668 json_nexthop_ll = json_object_new_object();
8669 json_object_string_add(
8670 json_nexthop_ll, "ip",
8671 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
8672 buf, INET6_ADDRSTRLEN));
8673
8674 if (nexthop_hostname)
8675 json_object_string_add(json_nexthop_ll,
8676 "hostname",
8677 nexthop_hostname);
8678
8679 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
8680 json_object_string_add(json_nexthop_ll, "scope",
8681 "link-local");
8682
8683 json_object_boolean_true_add(json_nexthop_ll,
8684 "accessible");
8685
8686 if (!attr->mp_nexthop_prefer_global)
8687 json_object_boolean_true_add(json_nexthop_ll,
8688 "used");
8689 else
8690 json_object_boolean_true_add(
8691 json_nexthop_global, "used");
8692 } else {
8693 vty_out(vty, " (%s) %s\n",
8694 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
8695 buf, INET6_ADDRSTRLEN),
8696 attr->mp_nexthop_prefer_global
8697 ? "(prefer-global)"
8698 : "(used)");
8699 }
8700 }
8701 /* If we do not have a link-local nexthop then we must flag the
8702 global as "used" */
8703 else {
8704 if (json_paths)
8705 json_object_boolean_true_add(json_nexthop_global,
8706 "used");
8707 }
8708
8709 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
8710 * Int/Ext/Local, Atomic, best */
8711 if (json_paths)
8712 json_object_string_add(json_path, "origin",
8713 bgp_origin_long_str[attr->origin]);
8714 else
8715 vty_out(vty, " Origin %s",
8716 bgp_origin_long_str[attr->origin]);
8717
8718 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
8719 if (json_paths) {
8720 /*
8721 * Adding "metric" field to match with
8722 * corresponding CLI. "med" will be
8723 * deprecated in future.
8724 */
8725 json_object_int_add(json_path, "med", attr->med);
8726 json_object_int_add(json_path, "metric", attr->med);
8727 } else
8728 vty_out(vty, ", metric %u", attr->med);
8729 }
8730
8731 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
8732 if (json_paths)
8733 json_object_int_add(json_path, "localpref",
8734 attr->local_pref);
8735 else
8736 vty_out(vty, ", localpref %u", attr->local_pref);
8737 }
8738
8739 if (attr->weight != 0) {
8740 if (json_paths)
8741 json_object_int_add(json_path, "weight", attr->weight);
8742 else
8743 vty_out(vty, ", weight %u", attr->weight);
8744 }
8745
8746 if (attr->tag != 0) {
8747 if (json_paths)
8748 json_object_int_add(json_path, "tag", attr->tag);
8749 else
8750 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
8751 }
8752
8753 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
8754 if (json_paths)
8755 json_object_boolean_false_add(json_path, "valid");
8756 else
8757 vty_out(vty, ", invalid");
8758 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8759 if (json_paths)
8760 json_object_boolean_true_add(json_path, "valid");
8761 else
8762 vty_out(vty, ", valid");
8763 }
8764
8765 if (path->peer != bgp->peer_self) {
8766 if (path->peer->as == path->peer->local_as) {
8767 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
8768 if (json_paths)
8769 json_object_string_add(
8770 json_peer, "type",
8771 "confed-internal");
8772 else
8773 vty_out(vty, ", confed-internal");
8774 } else {
8775 if (json_paths)
8776 json_object_string_add(
8777 json_peer, "type", "internal");
8778 else
8779 vty_out(vty, ", internal");
8780 }
8781 } else {
8782 if (bgp_confederation_peers_check(bgp,
8783 path->peer->as)) {
8784 if (json_paths)
8785 json_object_string_add(
8786 json_peer, "type",
8787 "confed-external");
8788 else
8789 vty_out(vty, ", confed-external");
8790 } else {
8791 if (json_paths)
8792 json_object_string_add(
8793 json_peer, "type", "external");
8794 else
8795 vty_out(vty, ", external");
8796 }
8797 }
8798 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
8799 if (json_paths) {
8800 json_object_boolean_true_add(json_path, "aggregated");
8801 json_object_boolean_true_add(json_path, "local");
8802 } else {
8803 vty_out(vty, ", aggregated, local");
8804 }
8805 } else if (path->type != ZEBRA_ROUTE_BGP) {
8806 if (json_paths)
8807 json_object_boolean_true_add(json_path, "sourced");
8808 else
8809 vty_out(vty, ", sourced");
8810 } else {
8811 if (json_paths) {
8812 json_object_boolean_true_add(json_path, "sourced");
8813 json_object_boolean_true_add(json_path, "local");
8814 } else {
8815 vty_out(vty, ", sourced, local");
8816 }
8817 }
8818
8819 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
8820 if (json_paths)
8821 json_object_boolean_true_add(json_path,
8822 "atomicAggregate");
8823 else
8824 vty_out(vty, ", atomic-aggregate");
8825 }
8826
8827 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
8828 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
8829 && bgp_path_info_mpath_count(path))) {
8830 if (json_paths)
8831 json_object_boolean_true_add(json_path, "multipath");
8832 else
8833 vty_out(vty, ", multipath");
8834 }
8835
8836 // Mark the bestpath(s)
8837 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
8838 first_as = aspath_get_first_as(attr->aspath);
8839
8840 if (json_paths) {
8841 if (!json_bestpath)
8842 json_bestpath = json_object_new_object();
8843 json_object_int_add(json_bestpath, "bestpathFromAs",
8844 first_as);
8845 } else {
8846 if (first_as)
8847 vty_out(vty, ", bestpath-from-AS %u", first_as);
8848 else
8849 vty_out(vty, ", bestpath-from-AS Local");
8850 }
8851 }
8852
8853 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
8854 if (json_paths) {
8855 if (!json_bestpath)
8856 json_bestpath = json_object_new_object();
8857 json_object_boolean_true_add(json_bestpath, "overall");
8858 json_object_string_add(
8859 json_bestpath, "selectionReason",
8860 bgp_path_selection_reason2str(bn->reason));
8861 } else {
8862 vty_out(vty, ", best");
8863 vty_out(vty, " (%s)",
8864 bgp_path_selection_reason2str(bn->reason));
8865 }
8866 }
8867
8868 if (json_bestpath)
8869 json_object_object_add(json_path, "bestpath", json_bestpath);
8870
8871 if (!json_paths)
8872 vty_out(vty, "\n");
8873
8874 /* Line 4 display Community */
8875 if (attr->community) {
8876 if (json_paths) {
8877 if (!attr->community->json)
8878 community_str(attr->community, true);
8879 json_object_lock(attr->community->json);
8880 json_object_object_add(json_path, "community",
8881 attr->community->json);
8882 } else {
8883 vty_out(vty, " Community: %s\n",
8884 attr->community->str);
8885 }
8886 }
8887
8888 /* Line 5 display Extended-community */
8889 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8890 if (json_paths) {
8891 json_ext_community = json_object_new_object();
8892 json_object_string_add(json_ext_community, "string",
8893 attr->ecommunity->str);
8894 json_object_object_add(json_path, "extendedCommunity",
8895 json_ext_community);
8896 } else {
8897 vty_out(vty, " Extended Community: %s\n",
8898 attr->ecommunity->str);
8899 }
8900 }
8901
8902 /* Line 6 display Large community */
8903 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
8904 if (json_paths) {
8905 if (!attr->lcommunity->json)
8906 lcommunity_str(attr->lcommunity, true);
8907 json_object_lock(attr->lcommunity->json);
8908 json_object_object_add(json_path, "largeCommunity",
8909 attr->lcommunity->json);
8910 } else {
8911 vty_out(vty, " Large Community: %s\n",
8912 attr->lcommunity->str);
8913 }
8914 }
8915
8916 /* Line 7 display Originator, Cluster-id */
8917 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
8918 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
8919 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
8920 if (json_paths)
8921 json_object_string_add(
8922 json_path, "originatorId",
8923 inet_ntoa(attr->originator_id));
8924 else
8925 vty_out(vty, " Originator: %s",
8926 inet_ntoa(attr->originator_id));
8927 }
8928
8929 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
8930 int i;
8931
8932 if (json_paths) {
8933 json_cluster_list = json_object_new_object();
8934 json_cluster_list_list =
8935 json_object_new_array();
8936
8937 for (i = 0; i < attr->cluster->length / 4;
8938 i++) {
8939 json_string = json_object_new_string(
8940 inet_ntoa(attr->cluster
8941 ->list[i]));
8942 json_object_array_add(
8943 json_cluster_list_list,
8944 json_string);
8945 }
8946
8947 /*
8948 * struct cluster_list does not have
8949 * "str" variable like aspath and community
8950 * do. Add this someday if someone asks
8951 * for it.
8952 * json_object_string_add(json_cluster_list,
8953 * "string", attr->cluster->str);
8954 */
8955 json_object_object_add(json_cluster_list,
8956 "list",
8957 json_cluster_list_list);
8958 json_object_object_add(json_path, "clusterList",
8959 json_cluster_list);
8960 } else {
8961 vty_out(vty, ", Cluster list: ");
8962
8963 for (i = 0; i < attr->cluster->length / 4;
8964 i++) {
8965 vty_out(vty, "%s ",
8966 inet_ntoa(attr->cluster
8967 ->list[i]));
8968 }
8969 }
8970 }
8971
8972 if (!json_paths)
8973 vty_out(vty, "\n");
8974 }
8975
8976 if (path->extra && path->extra->damp_info)
8977 bgp_damp_info_vty(vty, path, afi, safi, json_path);
8978
8979 /* Remote Label */
8980 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
8981 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
8982 mpls_label_t label = label_pton(&path->extra->label[0]);
8983
8984 if (json_paths)
8985 json_object_int_add(json_path, "remoteLabel", label);
8986 else
8987 vty_out(vty, " Remote label: %d\n", label);
8988 }
8989
8990 /* Label Index */
8991 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
8992 if (json_paths)
8993 json_object_int_add(json_path, "labelIndex",
8994 attr->label_index);
8995 else
8996 vty_out(vty, " Label Index: %d\n",
8997 attr->label_index);
8998 }
8999
9000 /* Line 8 display Addpath IDs */
9001 if (path->addpath_rx_id
9002 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
9003 if (json_paths) {
9004 json_object_int_add(json_path, "addpathRxId",
9005 path->addpath_rx_id);
9006
9007 /* Keep backwards compatibility with the old API
9008 * by putting TX All's ID in the old field
9009 */
9010 json_object_int_add(
9011 json_path, "addpathTxId",
9012 path->tx_addpath
9013 .addpath_tx_id[BGP_ADDPATH_ALL]);
9014
9015 /* ... but create a specific field for each
9016 * strategy
9017 */
9018 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9019 json_object_int_add(
9020 json_path,
9021 bgp_addpath_names(i)->id_json_name,
9022 path->tx_addpath.addpath_tx_id[i]);
9023 }
9024 } else {
9025 vty_out(vty, " AddPath ID: RX %u, ",
9026 path->addpath_rx_id);
9027
9028 route_vty_out_tx_ids(vty, &path->tx_addpath);
9029 }
9030 }
9031
9032 /* If we used addpath to TX a non-bestpath we need to display
9033 * "Advertised to" on a path-by-path basis
9034 */
9035 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
9036 first = 1;
9037
9038 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
9039 addpath_capable =
9040 bgp_addpath_encode_tx(peer, afi, safi);
9041 has_adj = bgp_adj_out_lookup(
9042 peer, path->net,
9043 bgp_addpath_id_for_peer(peer, afi, safi,
9044 &path->tx_addpath));
9045
9046 if ((addpath_capable && has_adj)
9047 || (!addpath_capable && has_adj
9048 && CHECK_FLAG(path->flags,
9049 BGP_PATH_SELECTED))) {
9050 if (json_path && !json_adv_to)
9051 json_adv_to = json_object_new_object();
9052
9053 route_vty_out_advertised_to(
9054 vty, peer, &first,
9055 " Advertised to:", json_adv_to);
9056 }
9057 }
9058
9059 if (json_path) {
9060 if (json_adv_to) {
9061 json_object_object_add(
9062 json_path, "advertisedTo", json_adv_to);
9063 }
9064 } else {
9065 if (!first) {
9066 vty_out(vty, "\n");
9067 }
9068 }
9069 }
9070
9071 /* Line 9 display Uptime */
9072 tbuf = time(NULL) - (bgp_clock() - path->uptime);
9073 if (json_paths) {
9074 json_last_update = json_object_new_object();
9075 json_object_int_add(json_last_update, "epoch", tbuf);
9076 json_object_string_add(json_last_update, "string",
9077 ctime(&tbuf));
9078 json_object_object_add(json_path, "lastUpdate",
9079 json_last_update);
9080 } else
9081 vty_out(vty, " Last update: %s", ctime(&tbuf));
9082
9083 /* Line 10 display PMSI tunnel attribute, if present */
9084 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
9085 const char *str =
9086 lookup_msg(bgp_pmsi_tnltype_str, attr->pmsi_tnl_type,
9087 PMSI_TNLTYPE_STR_DEFAULT);
9088
9089 if (json_paths) {
9090 json_pmsi = json_object_new_object();
9091 json_object_string_add(json_pmsi, "tunnelType", str);
9092 json_object_int_add(json_pmsi, "label",
9093 label2vni(&attr->label));
9094 json_object_object_add(json_path, "pmsi", json_pmsi);
9095 } else
9096 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
9097 str, label2vni(&attr->label));
9098 }
9099
9100 /* We've constructed the json object for this path, add it to the json
9101 * array of paths
9102 */
9103 if (json_paths) {
9104 if (json_nexthop_global || json_nexthop_ll) {
9105 json_nexthops = json_object_new_array();
9106
9107 if (json_nexthop_global)
9108 json_object_array_add(json_nexthops,
9109 json_nexthop_global);
9110
9111 if (json_nexthop_ll)
9112 json_object_array_add(json_nexthops,
9113 json_nexthop_ll);
9114
9115 json_object_object_add(json_path, "nexthops",
9116 json_nexthops);
9117 }
9118
9119 json_object_object_add(json_path, "peer", json_peer);
9120 json_object_array_add(json_paths, json_path);
9121 }
9122 }
9123
9124 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
9125 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
9126 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
9127
9128 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
9129 const char *prefix_list_str, afi_t afi,
9130 safi_t safi, enum bgp_show_type type);
9131 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
9132 const char *filter, afi_t afi, safi_t safi,
9133 enum bgp_show_type type);
9134 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
9135 const char *rmap_str, afi_t afi, safi_t safi,
9136 enum bgp_show_type type);
9137 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
9138 const char *com, int exact, afi_t afi,
9139 safi_t safi);
9140 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
9141 const char *prefix, afi_t afi, safi_t safi,
9142 enum bgp_show_type type);
9143 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
9144 afi_t afi, safi_t safi, enum bgp_show_type type);
9145 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
9146 const char *comstr, int exact, afi_t afi,
9147 safi_t safi, bool use_json);
9148
9149
9150 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
9151 struct bgp_table *table, enum bgp_show_type type,
9152 void *output_arg, bool use_json, char *rd,
9153 int is_last, unsigned long *output_cum,
9154 unsigned long *total_cum,
9155 unsigned long *json_header_depth)
9156 {
9157 struct bgp_path_info *pi;
9158 struct bgp_node *rn;
9159 int header = 1;
9160 int display;
9161 unsigned long output_count = 0;
9162 unsigned long total_count = 0;
9163 struct prefix *p;
9164 char buf2[BUFSIZ];
9165 json_object *json_paths = NULL;
9166 int first = 1;
9167
9168 if (output_cum && *output_cum != 0)
9169 header = 0;
9170
9171 if (use_json && !*json_header_depth) {
9172 vty_out(vty,
9173 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
9174 ",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n"
9175 " \"localAS\": %u,\n \"routes\": { ",
9176 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
9177 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
9178 ? VRF_DEFAULT_NAME
9179 : bgp->name,
9180 table->version, inet_ntoa(bgp->router_id),
9181 bgp->default_local_pref, bgp->as);
9182 *json_header_depth = 2;
9183 if (rd) {
9184 vty_out(vty, " \"routeDistinguishers\" : {");
9185 ++*json_header_depth;
9186 }
9187 }
9188
9189 if (use_json && rd) {
9190 vty_out(vty, " \"%s\" : { ", rd);
9191 }
9192
9193 /* Start processing of routes. */
9194 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
9195 pi = bgp_node_get_bgp_path_info(rn);
9196 if (pi == NULL)
9197 continue;
9198
9199 display = 0;
9200 if (use_json)
9201 json_paths = json_object_new_array();
9202 else
9203 json_paths = NULL;
9204
9205 for (; pi; pi = pi->next) {
9206 total_count++;
9207 if (type == bgp_show_type_flap_statistics
9208 || type == bgp_show_type_flap_neighbor
9209 || type == bgp_show_type_dampend_paths
9210 || type == bgp_show_type_damp_neighbor) {
9211 if (!(pi->extra && pi->extra->damp_info))
9212 continue;
9213 }
9214 if (type == bgp_show_type_regexp) {
9215 regex_t *regex = output_arg;
9216
9217 if (bgp_regexec(regex, pi->attr->aspath)
9218 == REG_NOMATCH)
9219 continue;
9220 }
9221 if (type == bgp_show_type_prefix_list) {
9222 struct prefix_list *plist = output_arg;
9223
9224 if (prefix_list_apply(plist, &rn->p)
9225 != PREFIX_PERMIT)
9226 continue;
9227 }
9228 if (type == bgp_show_type_filter_list) {
9229 struct as_list *as_list = output_arg;
9230
9231 if (as_list_apply(as_list, pi->attr->aspath)
9232 != AS_FILTER_PERMIT)
9233 continue;
9234 }
9235 if (type == bgp_show_type_route_map) {
9236 struct route_map *rmap = output_arg;
9237 struct bgp_path_info path;
9238 struct attr dummy_attr;
9239 route_map_result_t ret;
9240
9241 dummy_attr = *pi->attr;
9242
9243 path.peer = pi->peer;
9244 path.attr = &dummy_attr;
9245
9246 ret = route_map_apply(rmap, &rn->p, RMAP_BGP,
9247 &path);
9248 if (ret == RMAP_DENYMATCH)
9249 continue;
9250 }
9251 if (type == bgp_show_type_neighbor
9252 || type == bgp_show_type_flap_neighbor
9253 || type == bgp_show_type_damp_neighbor) {
9254 union sockunion *su = output_arg;
9255
9256 if (pi->peer == NULL
9257 || pi->peer->su_remote == NULL
9258 || !sockunion_same(pi->peer->su_remote, su))
9259 continue;
9260 }
9261 if (type == bgp_show_type_cidr_only) {
9262 uint32_t destination;
9263
9264 destination = ntohl(rn->p.u.prefix4.s_addr);
9265 if (IN_CLASSC(destination)
9266 && rn->p.prefixlen == 24)
9267 continue;
9268 if (IN_CLASSB(destination)
9269 && rn->p.prefixlen == 16)
9270 continue;
9271 if (IN_CLASSA(destination)
9272 && rn->p.prefixlen == 8)
9273 continue;
9274 }
9275 if (type == bgp_show_type_prefix_longer) {
9276 p = output_arg;
9277 if (!prefix_match(p, &rn->p))
9278 continue;
9279 }
9280 if (type == bgp_show_type_community_all) {
9281 if (!pi->attr->community)
9282 continue;
9283 }
9284 if (type == bgp_show_type_community) {
9285 struct community *com = output_arg;
9286
9287 if (!pi->attr->community
9288 || !community_match(pi->attr->community,
9289 com))
9290 continue;
9291 }
9292 if (type == bgp_show_type_community_exact) {
9293 struct community *com = output_arg;
9294
9295 if (!pi->attr->community
9296 || !community_cmp(pi->attr->community, com))
9297 continue;
9298 }
9299 if (type == bgp_show_type_community_list) {
9300 struct community_list *list = output_arg;
9301
9302 if (!community_list_match(pi->attr->community,
9303 list))
9304 continue;
9305 }
9306 if (type == bgp_show_type_community_list_exact) {
9307 struct community_list *list = output_arg;
9308
9309 if (!community_list_exact_match(
9310 pi->attr->community, list))
9311 continue;
9312 }
9313 if (type == bgp_show_type_lcommunity) {
9314 struct lcommunity *lcom = output_arg;
9315
9316 if (!pi->attr->lcommunity
9317 || !lcommunity_match(pi->attr->lcommunity,
9318 lcom))
9319 continue;
9320 }
9321
9322 if (type == bgp_show_type_lcommunity_exact) {
9323 struct lcommunity *lcom = output_arg;
9324
9325 if (!pi->attr->lcommunity
9326 || !lcommunity_cmp(pi->attr->lcommunity,
9327 lcom))
9328 continue;
9329 }
9330 if (type == bgp_show_type_lcommunity_list) {
9331 struct community_list *list = output_arg;
9332
9333 if (!lcommunity_list_match(pi->attr->lcommunity,
9334 list))
9335 continue;
9336 }
9337 if (type
9338 == bgp_show_type_lcommunity_list_exact) {
9339 struct community_list *list = output_arg;
9340
9341 if (!lcommunity_list_exact_match(
9342 pi->attr->lcommunity, list))
9343 continue;
9344 }
9345 if (type == bgp_show_type_lcommunity_all) {
9346 if (!pi->attr->lcommunity)
9347 continue;
9348 }
9349 if (type == bgp_show_type_dampend_paths
9350 || type == bgp_show_type_damp_neighbor) {
9351 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
9352 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
9353 continue;
9354 }
9355
9356 if (!use_json && header) {
9357 vty_out(vty, "BGP table version is %" PRIu64
9358 ", local router ID is %s, vrf id ",
9359 table->version,
9360 inet_ntoa(bgp->router_id));
9361 if (bgp->vrf_id == VRF_UNKNOWN)
9362 vty_out(vty, "%s", VRFID_NONE_STR);
9363 else
9364 vty_out(vty, "%u", bgp->vrf_id);
9365 vty_out(vty, "\n");
9366 vty_out(vty, "Default local pref %u, ",
9367 bgp->default_local_pref);
9368 vty_out(vty, "local AS %u\n", bgp->as);
9369 vty_out(vty, BGP_SHOW_SCODE_HEADER);
9370 vty_out(vty, BGP_SHOW_NCODE_HEADER);
9371 vty_out(vty, BGP_SHOW_OCODE_HEADER);
9372 if (type == bgp_show_type_dampend_paths
9373 || type == bgp_show_type_damp_neighbor)
9374 vty_out(vty, BGP_SHOW_DAMP_HEADER);
9375 else if (type == bgp_show_type_flap_statistics
9376 || type == bgp_show_type_flap_neighbor)
9377 vty_out(vty, BGP_SHOW_FLAP_HEADER);
9378 else
9379 vty_out(vty, BGP_SHOW_HEADER);
9380 header = 0;
9381 }
9382 if (rd != NULL && !display && !output_count) {
9383 if (!use_json)
9384 vty_out(vty,
9385 "Route Distinguisher: %s\n",
9386 rd);
9387 }
9388 if (type == bgp_show_type_dampend_paths
9389 || type == bgp_show_type_damp_neighbor)
9390 damp_route_vty_out(vty, &rn->p, pi, display, AFI_IP,
9391 safi, use_json, json_paths);
9392 else if (type == bgp_show_type_flap_statistics
9393 || type == bgp_show_type_flap_neighbor)
9394 flap_route_vty_out(vty, &rn->p, pi, display, AFI_IP,
9395 safi, use_json, json_paths);
9396 else
9397 route_vty_out(vty, &rn->p, pi, display, safi,
9398 json_paths);
9399 display++;
9400 }
9401
9402 if (display) {
9403 output_count++;
9404 if (!use_json)
9405 continue;
9406
9407 p = &rn->p;
9408 /* encode prefix */
9409 if (p->family == AF_FLOWSPEC) {
9410 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
9411
9412 bgp_fs_nlri_get_string((unsigned char *)
9413 p->u.prefix_flowspec.ptr,
9414 p->u.prefix_flowspec
9415 .prefixlen,
9416 retstr,
9417 NLRI_STRING_FORMAT_MIN,
9418 NULL);
9419 if (first)
9420 vty_out(vty, "\"%s/%d\": ",
9421 retstr,
9422 p->u.prefix_flowspec.prefixlen);
9423 else
9424 vty_out(vty, ",\"%s/%d\": ",
9425 retstr,
9426 p->u.prefix_flowspec.prefixlen);
9427 } else {
9428 prefix2str(p, buf2, sizeof(buf2));
9429 if (first)
9430 vty_out(vty, "\"%s\": ", buf2);
9431 else
9432 vty_out(vty, ",\"%s\": ", buf2);
9433 }
9434 vty_out(vty, "%s",
9435 json_object_to_json_string(json_paths));
9436 json_object_free(json_paths);
9437 json_paths = NULL;
9438 first = 0;
9439 } else
9440 json_object_free(json_paths);
9441 }
9442
9443 if (output_cum) {
9444 output_count += *output_cum;
9445 *output_cum = output_count;
9446 }
9447 if (total_cum) {
9448 total_count += *total_cum;
9449 *total_cum = total_count;
9450 }
9451 if (use_json) {
9452 if (rd) {
9453 vty_out(vty, " }%s ", (is_last ? "" : ","));
9454 }
9455 if (is_last) {
9456 unsigned long i;
9457 for (i = 0; i < *json_header_depth; ++i)
9458 vty_out(vty, " } ");
9459 vty_out(vty, "\n");
9460 }
9461 } else {
9462 if (is_last) {
9463 /* No route is displayed */
9464 if (output_count == 0) {
9465 if (type == bgp_show_type_normal)
9466 vty_out(vty,
9467 "No BGP prefixes displayed, %ld exist\n",
9468 total_count);
9469 } else
9470 vty_out(vty,
9471 "\nDisplayed %ld routes and %ld total paths\n",
9472 output_count, total_count);
9473 }
9474 }
9475
9476 return CMD_SUCCESS;
9477 }
9478
9479 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
9480 struct bgp_table *table, struct prefix_rd *prd_match,
9481 enum bgp_show_type type, void *output_arg, bool use_json)
9482 {
9483 struct bgp_node *rn, *next;
9484 unsigned long output_cum = 0;
9485 unsigned long total_cum = 0;
9486 unsigned long json_header_depth = 0;
9487 struct bgp_table *itable;
9488 bool show_msg;
9489
9490 show_msg = (!use_json && type == bgp_show_type_normal);
9491
9492 for (rn = bgp_table_top(table); rn; rn = next) {
9493 next = bgp_route_next(rn);
9494 if (prd_match && memcmp(rn->p.u.val, prd_match->val, 8) != 0)
9495 continue;
9496
9497 itable = bgp_node_get_bgp_table_info(rn);
9498 if (itable != NULL) {
9499 struct prefix_rd prd;
9500 char rd[RD_ADDRSTRLEN];
9501
9502 memcpy(&prd, &(rn->p), sizeof(struct prefix_rd));
9503 prefix_rd2str(&prd, rd, sizeof(rd));
9504 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
9505 use_json, rd, next == NULL, &output_cum,
9506 &total_cum, &json_header_depth);
9507 if (next == NULL)
9508 show_msg = false;
9509 }
9510 }
9511 if (show_msg) {
9512 if (output_cum == 0)
9513 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
9514 total_cum);
9515 else
9516 vty_out(vty,
9517 "\nDisplayed %ld routes and %ld total paths\n",
9518 output_cum, total_cum);
9519 }
9520 return CMD_SUCCESS;
9521 }
9522 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
9523 enum bgp_show_type type, void *output_arg, bool use_json)
9524 {
9525 struct bgp_table *table;
9526 unsigned long json_header_depth = 0;
9527
9528 if (bgp == NULL) {
9529 bgp = bgp_get_default();
9530 }
9531
9532 if (bgp == NULL) {
9533 if (!use_json)
9534 vty_out(vty, "No BGP process is configured\n");
9535 else
9536 vty_out(vty, "{}\n");
9537 return CMD_WARNING;
9538 }
9539
9540 table = bgp->rib[afi][safi];
9541 /* use MPLS and ENCAP specific shows until they are merged */
9542 if (safi == SAFI_MPLS_VPN) {
9543 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
9544 output_arg, use_json);
9545 }
9546
9547 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
9548 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
9549 output_arg, use_json,
9550 1, NULL, NULL);
9551 }
9552 /* labeled-unicast routes live in the unicast table */
9553 else if (safi == SAFI_LABELED_UNICAST)
9554 safi = SAFI_UNICAST;
9555
9556 return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json,
9557 NULL, 1, NULL, NULL, &json_header_depth);
9558 }
9559
9560 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
9561 safi_t safi, bool use_json)
9562 {
9563 struct listnode *node, *nnode;
9564 struct bgp *bgp;
9565 int is_first = 1;
9566 bool route_output = false;
9567
9568 if (use_json)
9569 vty_out(vty, "{\n");
9570
9571 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
9572 route_output = true;
9573 if (use_json) {
9574 if (!is_first)
9575 vty_out(vty, ",\n");
9576 else
9577 is_first = 0;
9578
9579 vty_out(vty, "\"%s\":",
9580 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9581 ? VRF_DEFAULT_NAME
9582 : bgp->name);
9583 } else {
9584 vty_out(vty, "\nInstance %s:\n",
9585 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9586 ? VRF_DEFAULT_NAME
9587 : bgp->name);
9588 }
9589 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
9590 use_json);
9591 }
9592
9593 if (use_json)
9594 vty_out(vty, "}\n");
9595 else if (!route_output)
9596 vty_out(vty, "%% BGP instance not found\n");
9597 }
9598
9599 /* Header of detailed BGP route information */
9600 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
9601 struct bgp_node *rn, struct prefix_rd *prd,
9602 afi_t afi, safi_t safi, json_object *json)
9603 {
9604 struct bgp_path_info *pi;
9605 struct prefix *p;
9606 struct peer *peer;
9607 struct listnode *node, *nnode;
9608 char buf1[RD_ADDRSTRLEN];
9609 char buf2[INET6_ADDRSTRLEN];
9610 char buf3[EVPN_ROUTE_STRLEN];
9611 char prefix_str[BUFSIZ];
9612 int count = 0;
9613 int best = 0;
9614 int suppress = 0;
9615 int accept_own = 0;
9616 int route_filter_translated_v4 = 0;
9617 int route_filter_v4 = 0;
9618 int route_filter_translated_v6 = 0;
9619 int route_filter_v6 = 0;
9620 int llgr_stale = 0;
9621 int no_llgr = 0;
9622 int accept_own_nexthop = 0;
9623 int blackhole = 0;
9624 int no_export = 0;
9625 int no_advertise = 0;
9626 int local_as = 0;
9627 int no_peer = 0;
9628 int first = 1;
9629 int has_valid_label = 0;
9630 mpls_label_t label = 0;
9631 json_object *json_adv_to = NULL;
9632
9633 p = &rn->p;
9634 has_valid_label = bgp_is_valid_label(&rn->local_label);
9635
9636 if (has_valid_label)
9637 label = label_pton(&rn->local_label);
9638
9639 if (safi == SAFI_EVPN) {
9640
9641 if (!json) {
9642 vty_out(vty, "BGP routing table entry for %s%s%s\n",
9643 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
9644 : "", prd ? ":" : "",
9645 bgp_evpn_route2str((struct prefix_evpn *)p,
9646 buf3, sizeof(buf3)));
9647 } else {
9648 json_object_string_add(json, "rd",
9649 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
9650 "");
9651 bgp_evpn_route2json((struct prefix_evpn *)p, json);
9652 }
9653 } else {
9654 if (!json) {
9655 vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
9656 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9657 ? prefix_rd2str(prd, buf1,
9658 sizeof(buf1))
9659 : ""),
9660 safi == SAFI_MPLS_VPN ? ":" : "",
9661 inet_ntop(p->family, &p->u.prefix, buf2,
9662 INET6_ADDRSTRLEN),
9663 p->prefixlen);
9664
9665 } else
9666 json_object_string_add(json, "prefix",
9667 prefix2str(p, prefix_str, sizeof(prefix_str)));
9668 }
9669
9670 if (has_valid_label) {
9671 if (json)
9672 json_object_int_add(json, "localLabel", label);
9673 else
9674 vty_out(vty, "Local label: %d\n", label);
9675 }
9676
9677 if (!json)
9678 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
9679 vty_out(vty, "not allocated\n");
9680
9681 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
9682 count++;
9683 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
9684 best = count;
9685 if (pi->extra && pi->extra->suppress)
9686 suppress = 1;
9687
9688 if (pi->attr->community == NULL)
9689 continue;
9690
9691 no_advertise += community_include(
9692 pi->attr->community, COMMUNITY_NO_ADVERTISE);
9693 no_export += community_include(pi->attr->community,
9694 COMMUNITY_NO_EXPORT);
9695 local_as += community_include(pi->attr->community,
9696 COMMUNITY_LOCAL_AS);
9697 accept_own += community_include(pi->attr->community,
9698 COMMUNITY_ACCEPT_OWN);
9699 route_filter_translated_v4 += community_include(
9700 pi->attr->community,
9701 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
9702 route_filter_translated_v6 += community_include(
9703 pi->attr->community,
9704 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
9705 route_filter_v4 += community_include(
9706 pi->attr->community, COMMUNITY_ROUTE_FILTER_v4);
9707 route_filter_v6 += community_include(
9708 pi->attr->community, COMMUNITY_ROUTE_FILTER_v6);
9709 llgr_stale += community_include(pi->attr->community,
9710 COMMUNITY_LLGR_STALE);
9711 no_llgr += community_include(pi->attr->community,
9712 COMMUNITY_NO_LLGR);
9713 accept_own_nexthop +=
9714 community_include(pi->attr->community,
9715 COMMUNITY_ACCEPT_OWN_NEXTHOP);
9716 blackhole += community_include(pi->attr->community,
9717 COMMUNITY_BLACKHOLE);
9718 no_peer += community_include(pi->attr->community,
9719 COMMUNITY_NO_PEER);
9720 }
9721 }
9722
9723 if (!json) {
9724 vty_out(vty, "Paths: (%d available", count);
9725 if (best) {
9726 vty_out(vty, ", best #%d", best);
9727 if (safi == SAFI_UNICAST) {
9728 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9729 vty_out(vty, ", table %s",
9730 VRF_DEFAULT_NAME);
9731 else
9732 vty_out(vty, ", vrf %s",
9733 bgp->name);
9734 }
9735 } else
9736 vty_out(vty, ", no best path");
9737
9738 if (accept_own)
9739 vty_out(vty,
9740 ", accept own local route exported and imported in different VRF");
9741 else if (route_filter_translated_v4)
9742 vty_out(vty,
9743 ", mark translated RTs for VPNv4 route filtering");
9744 else if (route_filter_v4)
9745 vty_out(vty,
9746 ", attach RT as-is for VPNv4 route filtering");
9747 else if (route_filter_translated_v6)
9748 vty_out(vty,
9749 ", mark translated RTs for VPNv6 route filtering");
9750 else if (route_filter_v6)
9751 vty_out(vty,
9752 ", attach RT as-is for VPNv6 route filtering");
9753 else if (llgr_stale)
9754 vty_out(vty,
9755 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
9756 else if (no_llgr)
9757 vty_out(vty,
9758 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
9759 else if (accept_own_nexthop)
9760 vty_out(vty,
9761 ", accept local nexthop");
9762 else if (blackhole)
9763 vty_out(vty, ", inform peer to blackhole prefix");
9764 else if (no_export)
9765 vty_out(vty, ", not advertised to EBGP peer");
9766 else if (no_advertise)
9767 vty_out(vty, ", not advertised to any peer");
9768 else if (local_as)
9769 vty_out(vty, ", not advertised outside local AS");
9770 else if (no_peer)
9771 vty_out(vty,
9772 ", inform EBGP peer not to advertise to their EBGP peers");
9773
9774 if (suppress)
9775 vty_out(vty,
9776 ", Advertisements suppressed by an aggregate.");
9777 vty_out(vty, ")\n");
9778 }
9779
9780 /* If we are not using addpath then we can display Advertised to and
9781 * that will
9782 * show what peers we advertised the bestpath to. If we are using
9783 * addpath
9784 * though then we must display Advertised to on a path-by-path basis. */
9785 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
9786 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
9787 if (bgp_adj_out_lookup(peer, rn, 0)) {
9788 if (json && !json_adv_to)
9789 json_adv_to = json_object_new_object();
9790
9791 route_vty_out_advertised_to(
9792 vty, peer, &first,
9793 " Advertised to non peer-group peers:\n ",
9794 json_adv_to);
9795 }
9796 }
9797
9798 if (json) {
9799 if (json_adv_to) {
9800 json_object_object_add(json, "advertisedTo",
9801 json_adv_to);
9802 }
9803 } else {
9804 if (first)
9805 vty_out(vty, " Not advertised to any peer");
9806 vty_out(vty, "\n");
9807 }
9808 }
9809 }
9810
9811 static void bgp_show_path_info(struct prefix_rd *pfx_rd,
9812 struct bgp_node *bgp_node, struct vty *vty,
9813 struct bgp *bgp, afi_t afi,
9814 safi_t safi, json_object *json,
9815 enum bgp_path_type pathtype, int *display)
9816 {
9817 struct bgp_path_info *pi;
9818 int header = 1;
9819 char rdbuf[RD_ADDRSTRLEN];
9820 json_object *json_header = NULL;
9821 json_object *json_paths = NULL;
9822
9823 for (pi = bgp_node_get_bgp_path_info(bgp_node); pi;
9824 pi = pi->next) {
9825
9826 if (json && !json_paths) {
9827 /* Instantiate json_paths only if path is valid */
9828 json_paths = json_object_new_array();
9829 if (pfx_rd) {
9830 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
9831 json_header = json_object_new_object();
9832 } else
9833 json_header = json;
9834 }
9835
9836 if (header) {
9837 route_vty_out_detail_header(
9838 vty, bgp, bgp_node, pfx_rd,
9839 AFI_IP, safi, json_header);
9840 header = 0;
9841 }
9842 (*display)++;
9843
9844 if (pathtype == BGP_PATH_SHOW_ALL
9845 || (pathtype == BGP_PATH_SHOW_BESTPATH
9846 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
9847 || (pathtype == BGP_PATH_SHOW_MULTIPATH
9848 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
9849 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
9850 route_vty_out_detail(vty, bgp, bgp_node,
9851 pi, AFI_IP, safi,
9852 json_paths);
9853 }
9854
9855 if (json && json_paths) {
9856 json_object_object_add(json_header, "paths", json_paths);
9857
9858 if (pfx_rd)
9859 json_object_object_add(json, rdbuf, json_header);
9860 }
9861 }
9862
9863 /* Display specified route of BGP table. */
9864 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
9865 struct bgp_table *rib, const char *ip_str,
9866 afi_t afi, safi_t safi,
9867 struct prefix_rd *prd, int prefix_check,
9868 enum bgp_path_type pathtype, bool use_json)
9869 {
9870 int ret;
9871 int display = 0;
9872 struct prefix match;
9873 struct bgp_node *rn;
9874 struct bgp_node *rm;
9875 struct bgp_table *table;
9876 json_object *json = NULL;
9877 json_object *json_paths = NULL;
9878
9879 /* Check IP address argument. */
9880 ret = str2prefix(ip_str, &match);
9881 if (!ret) {
9882 vty_out(vty, "address is malformed\n");
9883 return CMD_WARNING;
9884 }
9885
9886 match.family = afi2family(afi);
9887
9888 if (use_json)
9889 json = json_object_new_object();
9890
9891 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
9892 for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
9893 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
9894 continue;
9895 table = bgp_node_get_bgp_table_info(rn);
9896 if (!table)
9897 continue;
9898
9899 if ((rm = bgp_node_match(table, &match)) == NULL)
9900 continue;
9901
9902 if (prefix_check
9903 && rm->p.prefixlen != match.prefixlen) {
9904 bgp_unlock_node(rm);
9905 continue;
9906 }
9907
9908 bgp_show_path_info((struct prefix_rd *)&rn->p, rm,
9909 vty, bgp, afi, safi, json,
9910 pathtype, &display);
9911
9912 bgp_unlock_node(rm);
9913 }
9914 } else if (safi == SAFI_EVPN) {
9915 struct bgp_node *longest_pfx;
9916 bool is_exact_pfxlen_match = FALSE;
9917
9918 for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
9919 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
9920 continue;
9921 table = bgp_node_get_bgp_table_info(rn);
9922 if (!table)
9923 continue;
9924
9925 longest_pfx = NULL;
9926 is_exact_pfxlen_match = FALSE;
9927 /*
9928 * Search through all the prefixes for a match. The
9929 * pfx's are enumerated in ascending order of pfxlens.
9930 * So, the last pfx match is the longest match. Set
9931 * is_exact_pfxlen_match when we get exact pfxlen match
9932 */
9933 for (rm = bgp_table_top(table); rm;
9934 rm = bgp_route_next(rm)) {
9935 /*
9936 * Get prefixlen of the ip-prefix within type5
9937 * evpn route
9938 */
9939 if (evpn_type5_prefix_match(&rm->p,
9940 &match) && rm->info) {
9941 longest_pfx = rm;
9942 int type5_pfxlen =
9943 bgp_evpn_get_type5_prefixlen(&rm->p);
9944 if (type5_pfxlen == match.prefixlen) {
9945 is_exact_pfxlen_match = TRUE;
9946 bgp_unlock_node(rm);
9947 break;
9948 }
9949 }
9950 }
9951
9952 if (!longest_pfx)
9953 continue;
9954
9955 if (prefix_check && !is_exact_pfxlen_match)
9956 continue;
9957
9958 rm = longest_pfx;
9959 bgp_lock_node(rm);
9960
9961 bgp_show_path_info((struct prefix_rd *)&rn->p, rm,
9962 vty, bgp, afi, safi, json,
9963 pathtype, &display);
9964
9965 bgp_unlock_node(rm);
9966 }
9967 } else if (safi == SAFI_FLOWSPEC) {
9968 if (use_json)
9969 json_paths = json_object_new_array();
9970
9971 display = bgp_flowspec_display_match_per_ip(afi, rib,
9972 &match, prefix_check,
9973 vty,
9974 use_json,
9975 json_paths);
9976 if (use_json && display)
9977 json_object_object_add(json, "paths", json_paths);
9978 } else {
9979 if ((rn = bgp_node_match(rib, &match)) != NULL) {
9980 if (!prefix_check
9981 || rn->p.prefixlen == match.prefixlen) {
9982 bgp_show_path_info(NULL, rn, vty, bgp, afi,
9983 safi, json,
9984 pathtype, &display);
9985 }
9986
9987 bgp_unlock_node(rn);
9988 }
9989 }
9990
9991 if (use_json) {
9992 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9993 json, JSON_C_TO_STRING_PRETTY |
9994 JSON_C_TO_STRING_NOSLASHESCAPE));
9995 json_object_free(json);
9996 } else {
9997 if (!display) {
9998 vty_out(vty, "%% Network not in table\n");
9999 return CMD_WARNING;
10000 }
10001 }
10002
10003 return CMD_SUCCESS;
10004 }
10005
10006 /* Display specified route of Main RIB */
10007 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
10008 afi_t afi, safi_t safi, struct prefix_rd *prd,
10009 int prefix_check, enum bgp_path_type pathtype,
10010 bool use_json)
10011 {
10012 if (!bgp) {
10013 bgp = bgp_get_default();
10014 if (!bgp) {
10015 if (!use_json)
10016 vty_out(vty, "No BGP process is configured\n");
10017 else
10018 vty_out(vty, "{}\n");
10019 return CMD_WARNING;
10020 }
10021 }
10022
10023 /* labeled-unicast routes live in the unicast table */
10024 if (safi == SAFI_LABELED_UNICAST)
10025 safi = SAFI_UNICAST;
10026
10027 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
10028 afi, safi, prd, prefix_check, pathtype,
10029 use_json);
10030 }
10031
10032 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
10033 struct cmd_token **argv, bool exact, afi_t afi,
10034 safi_t safi, bool uj)
10035 {
10036 struct lcommunity *lcom;
10037 struct buffer *b;
10038 int i;
10039 char *str;
10040 int first = 0;
10041
10042 b = buffer_new(1024);
10043 for (i = 0; i < argc; i++) {
10044 if (first)
10045 buffer_putc(b, ' ');
10046 else {
10047 if (strmatch(argv[i]->text, "AA:BB:CC")) {
10048 first = 1;
10049 buffer_putstr(b, argv[i]->arg);
10050 }
10051 }
10052 }
10053 buffer_putc(b, '\0');
10054
10055 str = buffer_getstr(b);
10056 buffer_free(b);
10057
10058 lcom = lcommunity_str2com(str);
10059 XFREE(MTYPE_TMP, str);
10060 if (!lcom) {
10061 vty_out(vty, "%% Large-community malformed\n");
10062 return CMD_WARNING;
10063 }
10064
10065 return bgp_show(vty, bgp, afi, safi,
10066 (exact ? bgp_show_type_lcommunity_exact
10067 : bgp_show_type_lcommunity),
10068 lcom, uj);
10069 }
10070
10071 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
10072 const char *lcom, bool exact, afi_t afi,
10073 safi_t safi, bool uj)
10074 {
10075 struct community_list *list;
10076
10077 list = community_list_lookup(bgp_clist, lcom, 0,
10078 LARGE_COMMUNITY_LIST_MASTER);
10079 if (list == NULL) {
10080 vty_out(vty, "%% %s is not a valid large-community-list name\n",
10081 lcom);
10082 return CMD_WARNING;
10083 }
10084
10085 return bgp_show(vty, bgp, afi, safi,
10086 (exact ? bgp_show_type_lcommunity_list_exact
10087 : bgp_show_type_lcommunity_list),
10088 list, uj);
10089 }
10090
10091 DEFUN (show_ip_bgp_large_community_list,
10092 show_ip_bgp_large_community_list_cmd,
10093 "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]",
10094 SHOW_STR
10095 IP_STR
10096 BGP_STR
10097 BGP_INSTANCE_HELP_STR
10098 BGP_AFI_HELP_STR
10099 BGP_SAFI_WITH_LABEL_HELP_STR
10100 "Display routes matching the large-community-list\n"
10101 "large-community-list number\n"
10102 "large-community-list name\n"
10103 "Exact match of the large-communities\n"
10104 JSON_STR)
10105 {
10106 char *vrf = NULL;
10107 afi_t afi = AFI_IP6;
10108 safi_t safi = SAFI_UNICAST;
10109 int idx = 0;
10110 bool exact_match = 0;
10111
10112 if (argv_find(argv, argc, "ip", &idx))
10113 afi = AFI_IP;
10114 if (argv_find(argv, argc, "view", &idx)
10115 || argv_find(argv, argc, "vrf", &idx))
10116 vrf = argv[++idx]->arg;
10117 if (argv_find(argv, argc, "ipv4", &idx)
10118 || argv_find(argv, argc, "ipv6", &idx)) {
10119 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
10120 if (argv_find(argv, argc, "unicast", &idx)
10121 || argv_find(argv, argc, "multicast", &idx))
10122 safi = bgp_vty_safi_from_str(argv[idx]->text);
10123 }
10124
10125 bool uj = use_json(argc, argv);
10126
10127 struct bgp *bgp = bgp_lookup_by_name(vrf);
10128 if (bgp == NULL) {
10129 vty_out(vty, "Can't find BGP instance %s\n", vrf);
10130 return CMD_WARNING;
10131 }
10132
10133 argv_find(argv, argc, "large-community-list", &idx);
10134
10135 const char *clist_number_or_name = argv[++idx]->arg;
10136
10137 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
10138 exact_match = 1;
10139
10140 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
10141 exact_match, afi, safi, uj);
10142 }
10143 DEFUN (show_ip_bgp_large_community,
10144 show_ip_bgp_large_community_cmd,
10145 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
10146 SHOW_STR
10147 IP_STR
10148 BGP_STR
10149 BGP_INSTANCE_HELP_STR
10150 BGP_AFI_HELP_STR
10151 BGP_SAFI_WITH_LABEL_HELP_STR
10152 "Display routes matching the large-communities\n"
10153 "List of large-community numbers\n"
10154 "Exact match of the large-communities\n"
10155 JSON_STR)
10156 {
10157 char *vrf = NULL;
10158 afi_t afi = AFI_IP6;
10159 safi_t safi = SAFI_UNICAST;
10160 int idx = 0;
10161 bool exact_match = 0;
10162
10163 if (argv_find(argv, argc, "ip", &idx))
10164 afi = AFI_IP;
10165 if (argv_find(argv, argc, "view", &idx)
10166 || argv_find(argv, argc, "vrf", &idx))
10167 vrf = argv[++idx]->arg;
10168 if (argv_find(argv, argc, "ipv4", &idx)
10169 || argv_find(argv, argc, "ipv6", &idx)) {
10170 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
10171 if (argv_find(argv, argc, "unicast", &idx)
10172 || argv_find(argv, argc, "multicast", &idx))
10173 safi = bgp_vty_safi_from_str(argv[idx]->text);
10174 }
10175
10176 bool uj = use_json(argc, argv);
10177
10178 struct bgp *bgp = bgp_lookup_by_name(vrf);
10179 if (bgp == NULL) {
10180 vty_out(vty, "Can't find BGP instance %s\n", vrf);
10181 return CMD_WARNING;
10182 }
10183
10184 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
10185 if (argv_find(argv, argc, "exact-match", &idx))
10186 exact_match = 1;
10187 return bgp_show_lcommunity(vty, bgp, argc, argv,
10188 exact_match, afi, safi, uj);
10189 } else
10190 return bgp_show(vty, bgp, afi, safi,
10191 bgp_show_type_lcommunity_all, NULL, uj);
10192 }
10193
10194 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
10195 safi_t safi);
10196
10197
10198 /* BGP route print out function without JSON */
10199 DEFUN (show_ip_bgp,
10200 show_ip_bgp_cmd,
10201 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
10202 <dampening <parameters>\
10203 |route-map WORD\
10204 |prefix-list WORD\
10205 |filter-list WORD\
10206 |statistics\
10207 |community-list <(1-500)|WORD> [exact-match]\
10208 |A.B.C.D/M longer-prefixes\
10209 |X:X::X:X/M longer-prefixes\
10210 >",
10211 SHOW_STR
10212 IP_STR
10213 BGP_STR
10214 BGP_INSTANCE_HELP_STR
10215 BGP_AFI_HELP_STR
10216 BGP_SAFI_WITH_LABEL_HELP_STR
10217 "Display detailed information about dampening\n"
10218 "Display detail of configured dampening parameters\n"
10219 "Display routes matching the route-map\n"
10220 "A route-map to match on\n"
10221 "Display routes conforming to the prefix-list\n"
10222 "Prefix-list name\n"
10223 "Display routes conforming to the filter-list\n"
10224 "Regular expression access list name\n"
10225 "BGP RIB advertisement statistics\n"
10226 "Display routes matching the community-list\n"
10227 "community-list number\n"
10228 "community-list name\n"
10229 "Exact match of the communities\n"
10230 "IPv4 prefix\n"
10231 "Display route and more specific routes\n"
10232 "IPv6 prefix\n"
10233 "Display route and more specific routes\n")
10234 {
10235 afi_t afi = AFI_IP6;
10236 safi_t safi = SAFI_UNICAST;
10237 int exact_match = 0;
10238 struct bgp *bgp = NULL;
10239 int idx = 0;
10240
10241 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10242 &bgp, false);
10243 if (!idx)
10244 return CMD_WARNING;
10245
10246 if (argv_find(argv, argc, "dampening", &idx)) {
10247 if (argv_find(argv, argc, "parameters", &idx))
10248 return bgp_show_dampening_parameters(vty, afi, safi);
10249 }
10250
10251 if (argv_find(argv, argc, "prefix-list", &idx))
10252 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
10253 safi, bgp_show_type_prefix_list);
10254
10255 if (argv_find(argv, argc, "filter-list", &idx))
10256 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
10257 safi, bgp_show_type_filter_list);
10258
10259 if (argv_find(argv, argc, "statistics", &idx))
10260 return bgp_table_stats(vty, bgp, afi, safi);
10261
10262 if (argv_find(argv, argc, "route-map", &idx))
10263 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
10264 safi, bgp_show_type_route_map);
10265
10266 if (argv_find(argv, argc, "community-list", &idx)) {
10267 const char *clist_number_or_name = argv[++idx]->arg;
10268 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
10269 exact_match = 1;
10270 return bgp_show_community_list(vty, bgp, clist_number_or_name,
10271 exact_match, afi, safi);
10272 }
10273 /* prefix-longer */
10274 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
10275 || argv_find(argv, argc, "X:X::X:X/M", &idx))
10276 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
10277 safi,
10278 bgp_show_type_prefix_longer);
10279
10280 return CMD_WARNING;
10281 }
10282
10283 /* BGP route print out function with JSON */
10284 DEFUN (show_ip_bgp_json,
10285 show_ip_bgp_json_cmd,
10286 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
10287 [cidr-only\
10288 |dampening <flap-statistics|dampened-paths>\
10289 |community [AA:NN|local-AS|no-advertise|no-export\
10290 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
10291 |accept-own|accept-own-nexthop|route-filter-v6\
10292 |route-filter-v4|route-filter-translated-v6\
10293 |route-filter-translated-v4] [exact-match]\
10294 ] [json]",
10295 SHOW_STR
10296 IP_STR
10297 BGP_STR
10298 BGP_INSTANCE_HELP_STR
10299 BGP_AFI_HELP_STR
10300 BGP_SAFI_WITH_LABEL_HELP_STR
10301 "Display only routes with non-natural netmasks\n"
10302 "Display detailed information about dampening\n"
10303 "Display flap statistics of routes\n"
10304 "Display paths suppressed due to dampening\n"
10305 "Display routes matching the communities\n"
10306 COMMUNITY_AANN_STR
10307 "Do not send outside local AS (well-known community)\n"
10308 "Do not advertise to any peer (well-known community)\n"
10309 "Do not export to next AS (well-known community)\n"
10310 "Graceful shutdown (well-known community)\n"
10311 "Do not export to any peer (well-known community)\n"
10312 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
10313 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
10314 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
10315 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
10316 "Should accept VPN route with local nexthop (well-known community)\n"
10317 "RT VPNv6 route filtering (well-known community)\n"
10318 "RT VPNv4 route filtering (well-known community)\n"
10319 "RT translated VPNv6 route filtering (well-known community)\n"
10320 "RT translated VPNv4 route filtering (well-known community)\n"
10321 "Exact match of the communities\n"
10322 JSON_STR)
10323 {
10324 afi_t afi = AFI_IP6;
10325 safi_t safi = SAFI_UNICAST;
10326 enum bgp_show_type sh_type = bgp_show_type_normal;
10327 struct bgp *bgp = NULL;
10328 int idx = 0;
10329 int exact_match = 0;
10330 bool uj = use_json(argc, argv);
10331
10332 if (uj)
10333 argc--;
10334
10335 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10336 &bgp, uj);
10337 if (!idx)
10338 return CMD_WARNING;
10339
10340 if (argv_find(argv, argc, "cidr-only", &idx))
10341 return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only,
10342 NULL, uj);
10343
10344 if (argv_find(argv, argc, "dampening", &idx)) {
10345 if (argv_find(argv, argc, "dampened-paths", &idx))
10346 return bgp_show(vty, bgp, afi, safi,
10347 bgp_show_type_dampend_paths, NULL, uj);
10348 else if (argv_find(argv, argc, "flap-statistics", &idx))
10349 return bgp_show(vty, bgp, afi, safi,
10350 bgp_show_type_flap_statistics, NULL,
10351 uj);
10352 }
10353
10354 if (argv_find(argv, argc, "community", &idx)) {
10355 char *maybecomm = NULL;
10356 char *community = NULL;
10357
10358 if (idx + 1 < argc) {
10359 if (argv[idx + 1]->type == VARIABLE_TKN)
10360 maybecomm = argv[idx + 1]->arg;
10361 else
10362 maybecomm = argv[idx + 1]->text;
10363 }
10364
10365 if (maybecomm && !strmatch(maybecomm, "json")
10366 && !strmatch(maybecomm, "exact-match"))
10367 community = maybecomm;
10368
10369 if (argv_find(argv, argc, "exact-match", &idx))
10370 exact_match = 1;
10371
10372 if (community)
10373 return bgp_show_community(vty, bgp, community,
10374 exact_match, afi, safi, uj);
10375 else
10376 return (bgp_show(vty, bgp, afi, safi,
10377 bgp_show_type_community_all, NULL,
10378 uj));
10379 }
10380
10381 return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
10382 }
10383
10384 DEFUN (show_ip_bgp_route,
10385 show_ip_bgp_route_cmd,
10386 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]"
10387 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
10388 SHOW_STR
10389 IP_STR
10390 BGP_STR
10391 BGP_INSTANCE_HELP_STR
10392 BGP_AFI_HELP_STR
10393 BGP_SAFI_WITH_LABEL_HELP_STR
10394 "Network in the BGP routing table to display\n"
10395 "IPv4 prefix\n"
10396 "Network in the BGP routing table to display\n"
10397 "IPv6 prefix\n"
10398 "Display only the bestpath\n"
10399 "Display only multipaths\n"
10400 JSON_STR)
10401 {
10402 int prefix_check = 0;
10403
10404 afi_t afi = AFI_IP6;
10405 safi_t safi = SAFI_UNICAST;
10406 char *prefix = NULL;
10407 struct bgp *bgp = NULL;
10408 enum bgp_path_type path_type;
10409 bool uj = use_json(argc, argv);
10410
10411 int idx = 0;
10412
10413 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10414 &bgp, uj);
10415 if (!idx)
10416 return CMD_WARNING;
10417
10418 if (!bgp) {
10419 vty_out(vty,
10420 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
10421 return CMD_WARNING;
10422 }
10423
10424 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
10425 if (argv_find(argv, argc, "A.B.C.D", &idx)
10426 || argv_find(argv, argc, "X:X::X:X", &idx))
10427 prefix_check = 0;
10428 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
10429 || argv_find(argv, argc, "X:X::X:X/M", &idx))
10430 prefix_check = 1;
10431
10432 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
10433 && afi != AFI_IP6) {
10434 vty_out(vty,
10435 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
10436 return CMD_WARNING;
10437 }
10438 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
10439 && afi != AFI_IP) {
10440 vty_out(vty,
10441 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
10442 return CMD_WARNING;
10443 }
10444
10445 prefix = argv[idx]->arg;
10446
10447 /* [<bestpath|multipath>] */
10448 if (argv_find(argv, argc, "bestpath", &idx))
10449 path_type = BGP_PATH_SHOW_BESTPATH;
10450 else if (argv_find(argv, argc, "multipath", &idx))
10451 path_type = BGP_PATH_SHOW_MULTIPATH;
10452 else
10453 path_type = BGP_PATH_SHOW_ALL;
10454
10455 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
10456 path_type, uj);
10457 }
10458
10459 DEFUN (show_ip_bgp_regexp,
10460 show_ip_bgp_regexp_cmd,
10461 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX...",
10462 SHOW_STR
10463 IP_STR
10464 BGP_STR
10465 BGP_INSTANCE_HELP_STR
10466 BGP_AFI_HELP_STR
10467 BGP_SAFI_WITH_LABEL_HELP_STR
10468 "Display routes matching the AS path regular expression\n"
10469 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n")
10470 {
10471 afi_t afi = AFI_IP6;
10472 safi_t safi = SAFI_UNICAST;
10473 struct bgp *bgp = NULL;
10474
10475 int idx = 0;
10476 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10477 &bgp, false);
10478 if (!idx)
10479 return CMD_WARNING;
10480
10481 // get index of regex
10482 argv_find(argv, argc, "regexp", &idx);
10483 idx++;
10484
10485 char *regstr = argv_concat(argv, argc, idx);
10486 int rc = bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
10487 bgp_show_type_regexp);
10488 XFREE(MTYPE_TMP, regstr);
10489 return rc;
10490 }
10491
10492 DEFUN (show_ip_bgp_instance_all,
10493 show_ip_bgp_instance_all_cmd,
10494 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json]",
10495 SHOW_STR
10496 IP_STR
10497 BGP_STR
10498 BGP_INSTANCE_ALL_HELP_STR
10499 BGP_AFI_HELP_STR
10500 BGP_SAFI_WITH_LABEL_HELP_STR
10501 JSON_STR)
10502 {
10503 afi_t afi = AFI_IP;
10504 safi_t safi = SAFI_UNICAST;
10505 struct bgp *bgp = NULL;
10506 int idx = 0;
10507 bool uj = use_json(argc, argv);
10508
10509 if (uj)
10510 argc--;
10511
10512 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10513 &bgp, uj);
10514 if (!idx)
10515 return CMD_WARNING;
10516
10517 bgp_show_all_instances_routes_vty(vty, afi, safi, uj);
10518 return CMD_SUCCESS;
10519 }
10520
10521 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
10522 afi_t afi, safi_t safi, enum bgp_show_type type)
10523 {
10524 regex_t *regex;
10525 int rc;
10526
10527 if (!config_bgp_aspath_validate(regstr)) {
10528 vty_out(vty, "Invalid character in as-path access-list %s\n",
10529 regstr);
10530 return CMD_WARNING_CONFIG_FAILED;
10531 }
10532
10533 regex = bgp_regcomp(regstr);
10534 if (!regex) {
10535 vty_out(vty, "Can't compile regexp %s\n", regstr);
10536 return CMD_WARNING;
10537 }
10538
10539 rc = bgp_show(vty, bgp, afi, safi, type, regex, 0);
10540 bgp_regex_free(regex);
10541 return rc;
10542 }
10543
10544 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
10545 const char *prefix_list_str, afi_t afi,
10546 safi_t safi, enum bgp_show_type type)
10547 {
10548 struct prefix_list *plist;
10549
10550 plist = prefix_list_lookup(afi, prefix_list_str);
10551 if (plist == NULL) {
10552 vty_out(vty, "%% %s is not a valid prefix-list name\n",
10553 prefix_list_str);
10554 return CMD_WARNING;
10555 }
10556
10557 return bgp_show(vty, bgp, afi, safi, type, plist, 0);
10558 }
10559
10560 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
10561 const char *filter, afi_t afi, safi_t safi,
10562 enum bgp_show_type type)
10563 {
10564 struct as_list *as_list;
10565
10566 as_list = as_list_lookup(filter);
10567 if (as_list == NULL) {
10568 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
10569 filter);
10570 return CMD_WARNING;
10571 }
10572
10573 return bgp_show(vty, bgp, afi, safi, type, as_list, 0);
10574 }
10575
10576 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
10577 const char *rmap_str, afi_t afi, safi_t safi,
10578 enum bgp_show_type type)
10579 {
10580 struct route_map *rmap;
10581
10582 rmap = route_map_lookup_by_name(rmap_str);
10583 if (!rmap) {
10584 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
10585 return CMD_WARNING;
10586 }
10587
10588 return bgp_show(vty, bgp, afi, safi, type, rmap, 0);
10589 }
10590
10591 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
10592 const char *comstr, int exact, afi_t afi,
10593 safi_t safi, bool use_json)
10594 {
10595 struct community *com;
10596 int ret = 0;
10597
10598 com = community_str2com(comstr);
10599 if (!com) {
10600 vty_out(vty, "%% Community malformed: %s\n", comstr);
10601 return CMD_WARNING;
10602 }
10603
10604 ret = bgp_show(vty, bgp, afi, safi,
10605 (exact ? bgp_show_type_community_exact
10606 : bgp_show_type_community),
10607 com, use_json);
10608 community_free(&com);
10609
10610 return ret;
10611 }
10612
10613 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
10614 const char *com, int exact, afi_t afi,
10615 safi_t safi)
10616 {
10617 struct community_list *list;
10618
10619 list = community_list_lookup(bgp_clist, com, 0, COMMUNITY_LIST_MASTER);
10620 if (list == NULL) {
10621 vty_out(vty, "%% %s is not a valid community-list name\n", com);
10622 return CMD_WARNING;
10623 }
10624
10625 return bgp_show(vty, bgp, afi, safi,
10626 (exact ? bgp_show_type_community_list_exact
10627 : bgp_show_type_community_list),
10628 list, 0);
10629 }
10630
10631 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
10632 const char *prefix, afi_t afi, safi_t safi,
10633 enum bgp_show_type type)
10634 {
10635 int ret;
10636 struct prefix *p;
10637
10638 p = prefix_new();
10639
10640 ret = str2prefix(prefix, p);
10641 if (!ret) {
10642 vty_out(vty, "%% Malformed Prefix\n");
10643 return CMD_WARNING;
10644 }
10645
10646 ret = bgp_show(vty, bgp, afi, safi, type, p, 0);
10647 prefix_free(&p);
10648 return ret;
10649 }
10650
10651 enum bgp_stats {
10652 BGP_STATS_MAXBITLEN = 0,
10653 BGP_STATS_RIB,
10654 BGP_STATS_PREFIXES,
10655 BGP_STATS_TOTPLEN,
10656 BGP_STATS_UNAGGREGATEABLE,
10657 BGP_STATS_MAX_AGGREGATEABLE,
10658 BGP_STATS_AGGREGATES,
10659 BGP_STATS_SPACE,
10660 BGP_STATS_ASPATH_COUNT,
10661 BGP_STATS_ASPATH_MAXHOPS,
10662 BGP_STATS_ASPATH_TOTHOPS,
10663 BGP_STATS_ASPATH_MAXSIZE,
10664 BGP_STATS_ASPATH_TOTSIZE,
10665 BGP_STATS_ASN_HIGHEST,
10666 BGP_STATS_MAX,
10667 };
10668
10669 static const char *const table_stats_strs[] = {
10670 [BGP_STATS_PREFIXES] = "Total Prefixes",
10671 [BGP_STATS_TOTPLEN] = "Average prefix length",
10672 [BGP_STATS_RIB] = "Total Advertisements",
10673 [BGP_STATS_UNAGGREGATEABLE] = "Unaggregateable prefixes",
10674 [BGP_STATS_MAX_AGGREGATEABLE] =
10675 "Maximum aggregateable prefixes",
10676 [BGP_STATS_AGGREGATES] = "BGP Aggregate advertisements",
10677 [BGP_STATS_SPACE] = "Address space advertised",
10678 [BGP_STATS_ASPATH_COUNT] = "Advertisements with paths",
10679 [BGP_STATS_ASPATH_MAXHOPS] = "Longest AS-Path (hops)",
10680 [BGP_STATS_ASPATH_MAXSIZE] = "Largest AS-Path (bytes)",
10681 [BGP_STATS_ASPATH_TOTHOPS] = "Average AS-Path length (hops)",
10682 [BGP_STATS_ASPATH_TOTSIZE] = "Average AS-Path size (bytes)",
10683 [BGP_STATS_ASN_HIGHEST] = "Highest public ASN",
10684 [BGP_STATS_MAX] = NULL,
10685 };
10686
10687 struct bgp_table_stats {
10688 struct bgp_table *table;
10689 unsigned long long counts[BGP_STATS_MAX];
10690 double total_space;
10691 };
10692
10693 #if 0
10694 #define TALLY_SIGFIG 100000
10695 static unsigned long
10696 ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
10697 {
10698 unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
10699 unsigned long res = (newtot * TALLY_SIGFIG) / count;
10700 unsigned long ret = newtot / count;
10701
10702 if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
10703 return ret + 1;
10704 else
10705 return ret;
10706 }
10707 #endif
10708
10709 static void bgp_table_stats_rn(struct bgp_node *rn, struct bgp_node *top,
10710 struct bgp_table_stats *ts, unsigned int space)
10711 {
10712 struct bgp_node *prn = bgp_node_parent_nolock(rn);
10713 struct bgp_path_info *pi;
10714
10715 if (rn == top)
10716 return;
10717
10718 if (!bgp_node_has_bgp_path_info_data(rn))
10719 return;
10720
10721 ts->counts[BGP_STATS_PREFIXES]++;
10722 ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
10723
10724 #if 0
10725 ts->counts[BGP_STATS_AVGPLEN]
10726 = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
10727 ts->counts[BGP_STATS_AVGPLEN],
10728 rn->p.prefixlen);
10729 #endif
10730
10731 /* check if the prefix is included by any other announcements */
10732 while (prn && !bgp_node_has_bgp_path_info_data(prn))
10733 prn = bgp_node_parent_nolock(prn);
10734
10735 if (prn == NULL || prn == top) {
10736 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
10737 /* announced address space */
10738 if (space)
10739 ts->total_space += pow(2.0, space - rn->p.prefixlen);
10740 } else if (bgp_node_has_bgp_path_info_data(prn))
10741 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
10742
10743
10744 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
10745 ts->counts[BGP_STATS_RIB]++;
10746
10747 if (CHECK_FLAG(pi->attr->flag,
10748 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
10749 ts->counts[BGP_STATS_AGGREGATES]++;
10750
10751 /* as-path stats */
10752 if (pi->attr->aspath) {
10753 unsigned int hops = aspath_count_hops(pi->attr->aspath);
10754 unsigned int size = aspath_size(pi->attr->aspath);
10755 as_t highest = aspath_highest(pi->attr->aspath);
10756
10757 ts->counts[BGP_STATS_ASPATH_COUNT]++;
10758
10759 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
10760 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
10761
10762 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
10763 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
10764
10765 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
10766 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
10767 #if 0
10768 ts->counts[BGP_STATS_ASPATH_AVGHOPS]
10769 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
10770 ts->counts[BGP_STATS_ASPATH_AVGHOPS],
10771 hops);
10772 ts->counts[BGP_STATS_ASPATH_AVGSIZE]
10773 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
10774 ts->counts[BGP_STATS_ASPATH_AVGSIZE],
10775 size);
10776 #endif
10777 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
10778 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
10779 }
10780 }
10781 }
10782
10783 static int bgp_table_stats_walker(struct thread *t)
10784 {
10785 struct bgp_node *rn, *nrn;
10786 struct bgp_node *top;
10787 struct bgp_table_stats *ts = THREAD_ARG(t);
10788 unsigned int space = 0;
10789
10790 if (!(top = bgp_table_top(ts->table)))
10791 return 0;
10792
10793 switch (ts->table->afi) {
10794 case AFI_IP:
10795 space = IPV4_MAX_BITLEN;
10796 break;
10797 case AFI_IP6:
10798 space = IPV6_MAX_BITLEN;
10799 break;
10800 default:
10801 return 0;
10802 }
10803
10804 ts->counts[BGP_STATS_MAXBITLEN] = space;
10805
10806 for (rn = top; rn; rn = bgp_route_next(rn)) {
10807 if (ts->table->safi == SAFI_MPLS_VPN) {
10808 struct bgp_table *table;
10809
10810 table = bgp_node_get_bgp_table_info(rn);
10811 if (!table)
10812 continue;
10813
10814 top = bgp_table_top(table);
10815 for (nrn = bgp_table_top(table); nrn;
10816 nrn = bgp_route_next(nrn))
10817 bgp_table_stats_rn(nrn, top, ts, space);
10818 } else {
10819 bgp_table_stats_rn(rn, top, ts, space);
10820 }
10821 }
10822
10823 return 0;
10824 }
10825
10826 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
10827 safi_t safi)
10828 {
10829 struct bgp_table_stats ts;
10830 unsigned int i;
10831
10832 if (!bgp->rib[afi][safi]) {
10833 vty_out(vty, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
10834 afi, safi);
10835 return CMD_WARNING;
10836 }
10837
10838 vty_out(vty, "BGP %s RIB statistics\n", get_afi_safi_str(afi, safi, false));
10839
10840 /* labeled-unicast routes live in the unicast table */
10841 if (safi == SAFI_LABELED_UNICAST)
10842 safi = SAFI_UNICAST;
10843
10844 memset(&ts, 0, sizeof(ts));
10845 ts.table = bgp->rib[afi][safi];
10846 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
10847
10848 for (i = 0; i < BGP_STATS_MAX; i++) {
10849 if (!table_stats_strs[i])
10850 continue;
10851
10852 switch (i) {
10853 #if 0
10854 case BGP_STATS_ASPATH_AVGHOPS:
10855 case BGP_STATS_ASPATH_AVGSIZE:
10856 case BGP_STATS_AVGPLEN:
10857 vty_out (vty, "%-30s: ", table_stats_strs[i]);
10858 vty_out (vty, "%12.2f",
10859 (float)ts.counts[i] / (float)TALLY_SIGFIG);
10860 break;
10861 #endif
10862 case BGP_STATS_ASPATH_TOTHOPS:
10863 case BGP_STATS_ASPATH_TOTSIZE:
10864 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10865 vty_out(vty, "%12.2f",
10866 ts.counts[i]
10867 ? (float)ts.counts[i]
10868 / (float)ts.counts
10869 [BGP_STATS_ASPATH_COUNT]
10870 : 0);
10871 break;
10872 case BGP_STATS_TOTPLEN:
10873 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10874 vty_out(vty, "%12.2f",
10875 ts.counts[i]
10876 ? (float)ts.counts[i]
10877 / (float)ts.counts
10878 [BGP_STATS_PREFIXES]
10879 : 0);
10880 break;
10881 case BGP_STATS_SPACE:
10882 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10883 vty_out(vty, "%12g\n", ts.total_space);
10884
10885 if (afi == AFI_IP6) {
10886 vty_out(vty, "%30s: ", "/32 equivalent ");
10887 vty_out(vty, "%12g\n",
10888 ts.total_space * pow(2.0, -128 + 32));
10889 vty_out(vty, "%30s: ", "/48 equivalent ");
10890 vty_out(vty, "%12g\n",
10891 ts.total_space * pow(2.0, -128 + 48));
10892 } else {
10893 vty_out(vty, "%30s: ", "% announced ");
10894 vty_out(vty, "%12.2f\n",
10895 ts.total_space * 100. * pow(2.0, -32));
10896 vty_out(vty, "%30s: ", "/8 equivalent ");
10897 vty_out(vty, "%12.2f\n",
10898 ts.total_space * pow(2.0, -32 + 8));
10899 vty_out(vty, "%30s: ", "/24 equivalent ");
10900 vty_out(vty, "%12.2f\n",
10901 ts.total_space * pow(2.0, -32 + 24));
10902 }
10903 break;
10904 default:
10905 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10906 vty_out(vty, "%12llu", ts.counts[i]);
10907 }
10908
10909 vty_out(vty, "\n");
10910 }
10911 return CMD_SUCCESS;
10912 }
10913
10914 enum bgp_pcounts {
10915 PCOUNT_ADJ_IN = 0,
10916 PCOUNT_DAMPED,
10917 PCOUNT_REMOVED,
10918 PCOUNT_HISTORY,
10919 PCOUNT_STALE,
10920 PCOUNT_VALID,
10921 PCOUNT_ALL,
10922 PCOUNT_COUNTED,
10923 PCOUNT_PFCNT, /* the figure we display to users */
10924 PCOUNT_MAX,
10925 };
10926
10927 static const char *const pcount_strs[] = {
10928 [PCOUNT_ADJ_IN] = "Adj-in",
10929 [PCOUNT_DAMPED] = "Damped",
10930 [PCOUNT_REMOVED] = "Removed",
10931 [PCOUNT_HISTORY] = "History",
10932 [PCOUNT_STALE] = "Stale",
10933 [PCOUNT_VALID] = "Valid",
10934 [PCOUNT_ALL] = "All RIB",
10935 [PCOUNT_COUNTED] = "PfxCt counted",
10936 [PCOUNT_PFCNT] = "Useable",
10937 [PCOUNT_MAX] = NULL,
10938 };
10939
10940 struct peer_pcounts {
10941 unsigned int count[PCOUNT_MAX];
10942 const struct peer *peer;
10943 const struct bgp_table *table;
10944 safi_t safi;
10945 };
10946
10947 static void bgp_peer_count_proc(struct bgp_node *rn,
10948 struct peer_pcounts *pc)
10949 {
10950 const struct bgp_adj_in *ain;
10951 const struct bgp_path_info *pi;
10952 const struct peer *peer = pc->peer;
10953
10954 for (ain = rn->adj_in; ain; ain = ain->next)
10955 if (ain->peer == peer)
10956 pc->count[PCOUNT_ADJ_IN]++;
10957
10958 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
10959
10960 if (pi->peer != peer)
10961 continue;
10962
10963 pc->count[PCOUNT_ALL]++;
10964
10965 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
10966 pc->count[PCOUNT_DAMPED]++;
10967 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
10968 pc->count[PCOUNT_HISTORY]++;
10969 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
10970 pc->count[PCOUNT_REMOVED]++;
10971 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
10972 pc->count[PCOUNT_STALE]++;
10973 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
10974 pc->count[PCOUNT_VALID]++;
10975 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
10976 pc->count[PCOUNT_PFCNT]++;
10977
10978 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
10979 pc->count[PCOUNT_COUNTED]++;
10980 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
10981 flog_err(
10982 EC_LIB_DEVELOPMENT,
10983 "Attempting to count but flags say it is unusable");
10984 } else {
10985 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
10986 flog_err(
10987 EC_LIB_DEVELOPMENT,
10988 "Not counted but flags say we should");
10989 }
10990 }
10991 }
10992
10993 static int bgp_peer_count_walker(struct thread *t)
10994 {
10995 struct bgp_node *rn, *rm;
10996 const struct bgp_table *table;
10997 struct peer_pcounts *pc = THREAD_ARG(t);
10998
10999 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
11000 || pc->safi == SAFI_EVPN) {
11001 /* Special handling for 2-level routing tables. */
11002 for (rn = bgp_table_top(pc->table); rn;
11003 rn = bgp_route_next(rn)) {
11004 table = bgp_node_get_bgp_table_info(rn);
11005 if (table != NULL)
11006 for (rm = bgp_table_top(table); rm;
11007 rm = bgp_route_next(rm))
11008 bgp_peer_count_proc(rm, pc);
11009 }
11010 } else
11011 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
11012 bgp_peer_count_proc(rn, pc);
11013
11014 return 0;
11015 }
11016
11017 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
11018 safi_t safi, bool use_json)
11019 {
11020 struct peer_pcounts pcounts = {.peer = peer};
11021 unsigned int i;
11022 json_object *json = NULL;
11023 json_object *json_loop = NULL;
11024
11025 if (use_json) {
11026 json = json_object_new_object();
11027 json_loop = json_object_new_object();
11028 }
11029
11030 if (!peer || !peer->bgp || !peer->afc[afi][safi]
11031 || !peer->bgp->rib[afi][safi]) {
11032 if (use_json) {
11033 json_object_string_add(
11034 json, "warning",
11035 "No such neighbor or address family");
11036 vty_out(vty, "%s\n", json_object_to_json_string(json));
11037 json_object_free(json);
11038 } else
11039 vty_out(vty, "%% No such neighbor or address family\n");
11040
11041 return CMD_WARNING;
11042 }
11043
11044 memset(&pcounts, 0, sizeof(pcounts));
11045 pcounts.peer = peer;
11046 pcounts.table = peer->bgp->rib[afi][safi];
11047 pcounts.safi = safi;
11048
11049 /* in-place call via thread subsystem so as to record execution time
11050 * stats for the thread-walk (i.e. ensure this can't be blamed on
11051 * on just vty_read()).
11052 */
11053 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
11054
11055 if (use_json) {
11056 json_object_string_add(json, "prefixCountsFor", peer->host);
11057 json_object_string_add(json, "multiProtocol",
11058 get_afi_safi_str(afi, safi, true));
11059 json_object_int_add(json, "pfxCounter",
11060 peer->pcount[afi][safi]);
11061
11062 for (i = 0; i < PCOUNT_MAX; i++)
11063 json_object_int_add(json_loop, pcount_strs[i],
11064 pcounts.count[i]);
11065
11066 json_object_object_add(json, "ribTableWalkCounters", json_loop);
11067
11068 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
11069 json_object_string_add(json, "pfxctDriftFor",
11070 peer->host);
11071 json_object_string_add(
11072 json, "recommended",
11073 "Please report this bug, with the above command output");
11074 }
11075 vty_out(vty, "%s\n", json_object_to_json_string_ext(
11076 json, JSON_C_TO_STRING_PRETTY));
11077 json_object_free(json);
11078 } else {
11079
11080 if (peer->hostname
11081 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
11082 vty_out(vty, "Prefix counts for %s/%s, %s\n",
11083 peer->hostname, peer->host,
11084 get_afi_safi_str(afi, safi, false));
11085 } else {
11086 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
11087 get_afi_safi_str(afi, safi, false));
11088 }
11089
11090 vty_out(vty, "PfxCt: %" PRIu32 "\n", peer->pcount[afi][safi]);
11091 vty_out(vty, "\nCounts from RIB table walk:\n\n");
11092
11093 for (i = 0; i < PCOUNT_MAX; i++)
11094 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
11095 pcounts.count[i]);
11096
11097 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
11098 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
11099 vty_out(vty,
11100 "Please report this bug, with the above command output\n");
11101 }
11102 }
11103
11104 return CMD_SUCCESS;
11105 }
11106
11107 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
11108 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
11109 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] "
11110 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
11111 SHOW_STR
11112 IP_STR
11113 BGP_STR
11114 BGP_INSTANCE_HELP_STR
11115 BGP_AFI_HELP_STR
11116 BGP_SAFI_HELP_STR
11117 "Detailed information on TCP and BGP neighbor connections\n"
11118 "Neighbor to display information about\n"
11119 "Neighbor to display information about\n"
11120 "Neighbor on BGP configured interface\n"
11121 "Display detailed prefix count information\n"
11122 JSON_STR)
11123 {
11124 afi_t afi = AFI_IP6;
11125 safi_t safi = SAFI_UNICAST;
11126 struct peer *peer;
11127 int idx = 0;
11128 struct bgp *bgp = NULL;
11129 bool uj = use_json(argc, argv);
11130
11131 if (uj)
11132 argc--;
11133
11134 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11135 &bgp, uj);
11136 if (!idx)
11137 return CMD_WARNING;
11138
11139 argv_find(argv, argc, "neighbors", &idx);
11140 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
11141 if (!peer)
11142 return CMD_WARNING;
11143
11144 return bgp_peer_counts(vty, peer, afi, safi, uj);
11145 }
11146
11147 #ifdef KEEP_OLD_VPN_COMMANDS
11148 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
11149 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
11150 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
11151 SHOW_STR
11152 IP_STR
11153 BGP_STR
11154 BGP_VPNVX_HELP_STR
11155 "Display information about all VPNv4 NLRIs\n"
11156 "Detailed information on TCP and BGP neighbor connections\n"
11157 "Neighbor to display information about\n"
11158 "Neighbor to display information about\n"
11159 "Neighbor on BGP configured interface\n"
11160 "Display detailed prefix count information\n"
11161 JSON_STR)
11162 {
11163 int idx_peer = 6;
11164 struct peer *peer;
11165 bool uj = use_json(argc, argv);
11166
11167 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
11168 if (!peer)
11169 return CMD_WARNING;
11170
11171 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
11172 }
11173
11174 DEFUN (show_ip_bgp_vpn_all_route_prefix,
11175 show_ip_bgp_vpn_all_route_prefix_cmd,
11176 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
11177 SHOW_STR
11178 IP_STR
11179 BGP_STR
11180 BGP_VPNVX_HELP_STR
11181 "Display information about all VPNv4 NLRIs\n"
11182 "Network in the BGP routing table to display\n"
11183 "Network in the BGP routing table to display\n"
11184 JSON_STR)
11185 {
11186 int idx = 0;
11187 char *network = NULL;
11188 struct bgp *bgp = bgp_get_default();
11189 if (!bgp) {
11190 vty_out(vty, "Can't find default instance\n");
11191 return CMD_WARNING;
11192 }
11193
11194 if (argv_find(argv, argc, "A.B.C.D", &idx))
11195 network = argv[idx]->arg;
11196 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
11197 network = argv[idx]->arg;
11198 else {
11199 vty_out(vty, "Unable to figure out Network\n");
11200 return CMD_WARNING;
11201 }
11202
11203 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
11204 BGP_PATH_SHOW_ALL, use_json(argc, argv));
11205 }
11206 #endif /* KEEP_OLD_VPN_COMMANDS */
11207
11208 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
11209 show_bgp_l2vpn_evpn_route_prefix_cmd,
11210 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
11211 SHOW_STR
11212 BGP_STR
11213 L2VPN_HELP_STR
11214 EVPN_HELP_STR
11215 "Network in the BGP routing table to display\n"
11216 "Network in the BGP routing table to display\n"
11217 "Network in the BGP routing table to display\n"
11218 "Network in the BGP routing table to display\n"
11219 JSON_STR)
11220 {
11221 int idx = 0;
11222 char *network = NULL;
11223 int prefix_check = 0;
11224
11225 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
11226 argv_find(argv, argc, "X:X::X:X", &idx))
11227 network = argv[idx]->arg;
11228 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
11229 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
11230 network = argv[idx]->arg;
11231 prefix_check = 1;
11232 } else {
11233 vty_out(vty, "Unable to figure out Network\n");
11234 return CMD_WARNING;
11235 }
11236 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
11237 prefix_check, BGP_PATH_SHOW_ALL,
11238 use_json(argc, argv));
11239 }
11240
11241 static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
11242 safi_t safi, enum bgp_show_adj_route_type type,
11243 const char *rmap_name, bool use_json,
11244 json_object *json)
11245 {
11246 struct bgp_table *table;
11247 struct bgp_adj_in *ain;
11248 struct bgp_adj_out *adj;
11249 unsigned long output_count;
11250 unsigned long filtered_count;
11251 struct bgp_node *rn;
11252 int header1 = 1;
11253 struct bgp *bgp;
11254 int header2 = 1;
11255 struct attr attr;
11256 int ret;
11257 struct update_subgroup *subgrp;
11258 json_object *json_scode = NULL;
11259 json_object *json_ocode = NULL;
11260 json_object *json_ar = NULL;
11261 struct peer_af *paf;
11262 bool route_filtered;
11263
11264 if (use_json) {
11265 json_scode = json_object_new_object();
11266 json_ocode = json_object_new_object();
11267 json_ar = json_object_new_object();
11268
11269 json_object_string_add(json_scode, "suppressed", "s");
11270 json_object_string_add(json_scode, "damped", "d");
11271 json_object_string_add(json_scode, "history", "h");
11272 json_object_string_add(json_scode, "valid", "*");
11273 json_object_string_add(json_scode, "best", ">");
11274 json_object_string_add(json_scode, "multipath", "=");
11275 json_object_string_add(json_scode, "internal", "i");
11276 json_object_string_add(json_scode, "ribFailure", "r");
11277 json_object_string_add(json_scode, "stale", "S");
11278 json_object_string_add(json_scode, "removed", "R");
11279
11280 json_object_string_add(json_ocode, "igp", "i");
11281 json_object_string_add(json_ocode, "egp", "e");
11282 json_object_string_add(json_ocode, "incomplete", "?");
11283 }
11284
11285 bgp = peer->bgp;
11286
11287 if (!bgp) {
11288 if (use_json) {
11289 json_object_string_add(json, "alert", "no BGP");
11290 vty_out(vty, "%s\n", json_object_to_json_string(json));
11291 json_object_free(json);
11292 } else
11293 vty_out(vty, "%% No bgp\n");
11294 return;
11295 }
11296
11297 /* labeled-unicast routes live in the unicast table */
11298 if (safi == SAFI_LABELED_UNICAST)
11299 table = bgp->rib[afi][SAFI_UNICAST];
11300 else
11301 table = bgp->rib[afi][safi];
11302
11303 output_count = filtered_count = 0;
11304 subgrp = peer_subgroup(peer, afi, safi);
11305
11306 if (type == bgp_show_adj_route_advertised && subgrp
11307 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
11308 if (use_json) {
11309 json_object_int_add(json, "bgpTableVersion",
11310 table->version);
11311 json_object_string_add(json, "bgpLocalRouterId",
11312 inet_ntoa(bgp->router_id));
11313 json_object_int_add(json, "defaultLocPrf",
11314 bgp->default_local_pref);
11315 json_object_int_add(json, "localAS", bgp->as);
11316 json_object_object_add(json, "bgpStatusCodes",
11317 json_scode);
11318 json_object_object_add(json, "bgpOriginCodes",
11319 json_ocode);
11320 json_object_string_add(
11321 json, "bgpOriginatingDefaultNetwork",
11322 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
11323 } else {
11324 vty_out(vty, "BGP table version is %" PRIu64
11325 ", local router ID is %s, vrf id ",
11326 table->version, inet_ntoa(bgp->router_id));
11327 if (bgp->vrf_id == VRF_UNKNOWN)
11328 vty_out(vty, "%s", VRFID_NONE_STR);
11329 else
11330 vty_out(vty, "%u", bgp->vrf_id);
11331 vty_out(vty, "\n");
11332 vty_out(vty, "Default local pref %u, ",
11333 bgp->default_local_pref);
11334 vty_out(vty, "local AS %u\n", bgp->as);
11335 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11336 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11337 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11338
11339 vty_out(vty, "Originating default network %s\n\n",
11340 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
11341 }
11342 header1 = 0;
11343 }
11344
11345 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
11346 if (type == bgp_show_adj_route_received
11347 || type == bgp_show_adj_route_filtered) {
11348 for (ain = rn->adj_in; ain; ain = ain->next) {
11349 if (ain->peer != peer)
11350 continue;
11351
11352 if (header1) {
11353 if (use_json) {
11354 json_object_int_add(
11355 json, "bgpTableVersion",
11356 0);
11357 json_object_string_add(
11358 json,
11359 "bgpLocalRouterId",
11360 inet_ntoa(
11361 bgp->router_id));
11362 json_object_int_add(json,
11363 "defaultLocPrf",
11364 bgp->default_local_pref);
11365 json_object_int_add(json,
11366 "localAS", bgp->as);
11367 json_object_object_add(
11368 json, "bgpStatusCodes",
11369 json_scode);
11370 json_object_object_add(
11371 json, "bgpOriginCodes",
11372 json_ocode);
11373 } else {
11374 vty_out(vty,
11375 "BGP table version is 0, local router ID is %s, vrf id ",
11376 inet_ntoa(
11377 bgp->router_id));
11378 if (bgp->vrf_id == VRF_UNKNOWN)
11379 vty_out(vty, "%s",
11380 VRFID_NONE_STR);
11381 else
11382 vty_out(vty, "%u",
11383 bgp->vrf_id);
11384 vty_out(vty, "\n");
11385 vty_out(vty,
11386 "Default local pref %u, ",
11387 bgp->default_local_pref);
11388 vty_out(vty, "local AS %u\n",
11389 bgp->as);
11390 vty_out(vty,
11391 BGP_SHOW_SCODE_HEADER);
11392 vty_out(vty,
11393 BGP_SHOW_NCODE_HEADER);
11394 vty_out(vty,
11395 BGP_SHOW_OCODE_HEADER);
11396 }
11397 header1 = 0;
11398 }
11399 if (header2) {
11400 if (!use_json)
11401 vty_out(vty, BGP_SHOW_HEADER);
11402 header2 = 0;
11403 }
11404
11405 attr = *ain->attr;
11406 route_filtered = false;
11407
11408 /* Filter prefix using distribute list,
11409 * filter list or prefix list
11410 */
11411 if ((bgp_input_filter(peer, &rn->p, &attr, afi,
11412 safi)) == FILTER_DENY)
11413 route_filtered = true;
11414
11415 /* Filter prefix using route-map */
11416 ret = bgp_input_modifier(peer, &rn->p, &attr,
11417 afi, safi, rmap_name, NULL, 0,
11418 NULL);
11419
11420 if (type == bgp_show_adj_route_filtered &&
11421 !route_filtered && ret != RMAP_DENY) {
11422 bgp_attr_undup(&attr, ain->attr);
11423 continue;
11424 }
11425
11426 if (type == bgp_show_adj_route_received &&
11427 (route_filtered || ret == RMAP_DENY))
11428 filtered_count++;
11429
11430 route_vty_out_tmp(vty, &rn->p, &attr, safi,
11431 use_json, json_ar);
11432 bgp_attr_undup(&attr, ain->attr);
11433 output_count++;
11434 }
11435 } else if (type == bgp_show_adj_route_advertised) {
11436 RB_FOREACH (adj, bgp_adj_out_rb, &rn->adj_out)
11437 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
11438 if (paf->peer != peer || !adj->attr)
11439 continue;
11440
11441 if (header1) {
11442 if (use_json) {
11443 json_object_int_add(
11444 json,
11445 "bgpTableVersion",
11446 table->version);
11447 json_object_string_add(
11448 json,
11449 "bgpLocalRouterId",
11450 inet_ntoa(
11451 bgp->router_id));
11452 json_object_int_add(
11453 json, "defaultLocPrf",
11454 bgp->default_local_pref
11455 );
11456 json_object_int_add(
11457 json, "localAS",
11458 bgp->as);
11459 json_object_object_add(
11460 json,
11461 "bgpStatusCodes",
11462 json_scode);
11463 json_object_object_add(
11464 json,
11465 "bgpOriginCodes",
11466 json_ocode);
11467 } else {
11468 vty_out(vty,
11469 "BGP table version is %" PRIu64
11470 ", local router ID is %s, vrf id ",
11471 table->version,
11472 inet_ntoa(
11473 bgp->router_id));
11474 if (bgp->vrf_id ==
11475 VRF_UNKNOWN)
11476 vty_out(vty,
11477 "%s",
11478 VRFID_NONE_STR);
11479 else
11480 vty_out(vty,
11481 "%u",
11482 bgp->vrf_id);
11483 vty_out(vty, "\n");
11484 vty_out(vty,
11485 "Default local pref %u, ",
11486 bgp->default_local_pref
11487 );
11488 vty_out(vty,
11489 "local AS %u\n",
11490 bgp->as);
11491 vty_out(vty,
11492 BGP_SHOW_SCODE_HEADER);
11493 vty_out(vty,
11494 BGP_SHOW_NCODE_HEADER);
11495 vty_out(vty,
11496 BGP_SHOW_OCODE_HEADER);
11497 }
11498 header1 = 0;
11499 }
11500 if (header2) {
11501 if (!use_json)
11502 vty_out(vty,
11503 BGP_SHOW_HEADER);
11504 header2 = 0;
11505 }
11506
11507 attr = *adj->attr;
11508 ret = bgp_output_modifier(
11509 peer, &rn->p, &attr, afi, safi,
11510 rmap_name);
11511
11512 if (ret != RMAP_DENY) {
11513 route_vty_out_tmp(vty, &rn->p,
11514 &attr, safi,
11515 use_json,
11516 json_ar);
11517 output_count++;
11518 } else {
11519 filtered_count++;
11520 }
11521
11522 bgp_attr_undup(&attr, adj->attr);
11523 }
11524 }
11525 }
11526
11527 if (use_json) {
11528 json_object_object_add(json, "advertisedRoutes", json_ar);
11529 json_object_int_add(json, "totalPrefixCounter", output_count);
11530 json_object_int_add(json, "filteredPrefixCounter",
11531 filtered_count);
11532
11533 vty_out(vty, "%s\n", json_object_to_json_string_ext(
11534 json, JSON_C_TO_STRING_PRETTY));
11535 json_object_free(json);
11536 } else if (output_count > 0) {
11537 if (filtered_count > 0)
11538 vty_out(vty,
11539 "\nTotal number of prefixes %ld (%ld filtered)\n",
11540 output_count, filtered_count);
11541 else
11542 vty_out(vty, "\nTotal number of prefixes %ld\n",
11543 output_count);
11544 }
11545 }
11546
11547 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
11548 safi_t safi, enum bgp_show_adj_route_type type,
11549 const char *rmap_name, bool use_json)
11550 {
11551 json_object *json = NULL;
11552
11553 if (use_json)
11554 json = json_object_new_object();
11555
11556 if (!peer || !peer->afc[afi][safi]) {
11557 if (use_json) {
11558 json_object_string_add(
11559 json, "warning",
11560 "No such neighbor or address family");
11561 vty_out(vty, "%s\n", json_object_to_json_string(json));
11562 json_object_free(json);
11563 } else
11564 vty_out(vty, "%% No such neighbor or address family\n");
11565
11566 return CMD_WARNING;
11567 }
11568
11569 if ((type == bgp_show_adj_route_received
11570 || type == bgp_show_adj_route_filtered)
11571 && !CHECK_FLAG(peer->af_flags[afi][safi],
11572 PEER_FLAG_SOFT_RECONFIG)) {
11573 if (use_json) {
11574 json_object_string_add(
11575 json, "warning",
11576 "Inbound soft reconfiguration not enabled");
11577 vty_out(vty, "%s\n", json_object_to_json_string(json));
11578 json_object_free(json);
11579 } else
11580 vty_out(vty,
11581 "%% Inbound soft reconfiguration not enabled\n");
11582
11583 return CMD_WARNING;
11584 }
11585
11586 show_adj_route(vty, peer, afi, safi, type, rmap_name, use_json, json);
11587
11588 return CMD_SUCCESS;
11589 }
11590
11591 DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
11592 show_ip_bgp_instance_neighbor_advertised_route_cmd,
11593 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
11594 "neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map WORD] [json]",
11595 SHOW_STR
11596 IP_STR
11597 BGP_STR
11598 BGP_INSTANCE_HELP_STR
11599 BGP_AFI_HELP_STR
11600 BGP_SAFI_WITH_LABEL_HELP_STR
11601 "Detailed information on TCP and BGP neighbor connections\n"
11602 "Neighbor to display information about\n"
11603 "Neighbor to display information about\n"
11604 "Neighbor on BGP configured interface\n"
11605 "Display the routes advertised to a BGP neighbor\n"
11606 "Display the received routes from neighbor\n"
11607 "Display the filtered routes received from neighbor\n"
11608 "Route-map to modify the attributes\n"
11609 "Name of the route map\n"
11610 JSON_STR)
11611 {
11612 afi_t afi = AFI_IP6;
11613 safi_t safi = SAFI_UNICAST;
11614 char *rmap_name = NULL;
11615 char *peerstr = NULL;
11616 struct bgp *bgp = NULL;
11617 struct peer *peer;
11618 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
11619 int idx = 0;
11620 bool uj = use_json(argc, argv);
11621
11622 if (uj)
11623 argc--;
11624
11625 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11626 &bgp, uj);
11627 if (!idx)
11628 return CMD_WARNING;
11629
11630 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11631 argv_find(argv, argc, "neighbors", &idx);
11632 peerstr = argv[++idx]->arg;
11633
11634 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
11635 if (!peer)
11636 return CMD_WARNING;
11637
11638 if (argv_find(argv, argc, "advertised-routes", &idx))
11639 type = bgp_show_adj_route_advertised;
11640 else if (argv_find(argv, argc, "received-routes", &idx))
11641 type = bgp_show_adj_route_received;
11642 else if (argv_find(argv, argc, "filtered-routes", &idx))
11643 type = bgp_show_adj_route_filtered;
11644
11645 if (argv_find(argv, argc, "route-map", &idx))
11646 rmap_name = argv[++idx]->arg;
11647
11648 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, uj);
11649 }
11650
11651 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
11652 show_ip_bgp_neighbor_received_prefix_filter_cmd,
11653 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
11654 SHOW_STR
11655 IP_STR
11656 BGP_STR
11657 "Address Family\n"
11658 "Address Family\n"
11659 "Address Family modifier\n"
11660 "Detailed information on TCP and BGP neighbor connections\n"
11661 "Neighbor to display information about\n"
11662 "Neighbor to display information about\n"
11663 "Neighbor on BGP configured interface\n"
11664 "Display information received from a BGP neighbor\n"
11665 "Display the prefixlist filter\n"
11666 JSON_STR)
11667 {
11668 afi_t afi = AFI_IP6;
11669 safi_t safi = SAFI_UNICAST;
11670 char *peerstr = NULL;
11671
11672 char name[BUFSIZ];
11673 union sockunion su;
11674 struct peer *peer;
11675 int count, ret;
11676
11677 int idx = 0;
11678
11679 /* show [ip] bgp */
11680 if (argv_find(argv, argc, "ip", &idx))
11681 afi = AFI_IP;
11682 /* [<ipv4|ipv6> [unicast]] */
11683 if (argv_find(argv, argc, "ipv4", &idx))
11684 afi = AFI_IP;
11685 if (argv_find(argv, argc, "ipv6", &idx))
11686 afi = AFI_IP6;
11687 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11688 argv_find(argv, argc, "neighbors", &idx);
11689 peerstr = argv[++idx]->arg;
11690
11691 bool uj = use_json(argc, argv);
11692
11693 ret = str2sockunion(peerstr, &su);
11694 if (ret < 0) {
11695 peer = peer_lookup_by_conf_if(NULL, peerstr);
11696 if (!peer) {
11697 if (uj)
11698 vty_out(vty, "{}\n");
11699 else
11700 vty_out(vty,
11701 "%% Malformed address or name: %s\n",
11702 peerstr);
11703 return CMD_WARNING;
11704 }
11705 } else {
11706 peer = peer_lookup(NULL, &su);
11707 if (!peer) {
11708 if (uj)
11709 vty_out(vty, "{}\n");
11710 else
11711 vty_out(vty, "No peer\n");
11712 return CMD_WARNING;
11713 }
11714 }
11715
11716 sprintf(name, "%s.%d.%d", peer->host, afi, safi);
11717 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
11718 if (count) {
11719 if (!uj)
11720 vty_out(vty, "Address Family: %s\n",
11721 get_afi_safi_str(afi, safi, false));
11722 prefix_bgp_show_prefix_list(vty, afi, name, uj);
11723 } else {
11724 if (uj)
11725 vty_out(vty, "{}\n");
11726 else
11727 vty_out(vty, "No functional output\n");
11728 }
11729
11730 return CMD_SUCCESS;
11731 }
11732
11733 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
11734 afi_t afi, safi_t safi,
11735 enum bgp_show_type type, bool use_json)
11736 {
11737 /* labeled-unicast routes live in the unicast table */
11738 if (safi == SAFI_LABELED_UNICAST)
11739 safi = SAFI_UNICAST;
11740
11741 if (!peer || !peer->afc[afi][safi]) {
11742 if (use_json) {
11743 json_object *json_no = NULL;
11744 json_no = json_object_new_object();
11745 json_object_string_add(
11746 json_no, "warning",
11747 "No such neighbor or address family");
11748 vty_out(vty, "%s\n",
11749 json_object_to_json_string(json_no));
11750 json_object_free(json_no);
11751 } else
11752 vty_out(vty, "%% No such neighbor or address family\n");
11753 return CMD_WARNING;
11754 }
11755
11756 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, use_json);
11757 }
11758
11759 DEFUN (show_ip_bgp_flowspec_routes_detailed,
11760 show_ip_bgp_flowspec_routes_detailed_cmd,
11761 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
11762 SHOW_STR
11763 IP_STR
11764 BGP_STR
11765 BGP_INSTANCE_HELP_STR
11766 BGP_AFI_HELP_STR
11767 "SAFI Flowspec\n"
11768 "Detailed information on flowspec entries\n"
11769 JSON_STR)
11770 {
11771 afi_t afi = AFI_IP;
11772 safi_t safi = SAFI_UNICAST;
11773 struct bgp *bgp = NULL;
11774 int idx = 0;
11775 bool uj = use_json(argc, argv);
11776
11777 if (uj)
11778 argc--;
11779
11780 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11781 &bgp, uj);
11782 if (!idx)
11783 return CMD_WARNING;
11784
11785 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL, uj);
11786 }
11787
11788 DEFUN (show_ip_bgp_neighbor_routes,
11789 show_ip_bgp_neighbor_routes_cmd,
11790 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
11791 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
11792 SHOW_STR
11793 IP_STR
11794 BGP_STR
11795 BGP_INSTANCE_HELP_STR
11796 BGP_AFI_HELP_STR
11797 BGP_SAFI_WITH_LABEL_HELP_STR
11798 "Detailed information on TCP and BGP neighbor connections\n"
11799 "Neighbor to display information about\n"
11800 "Neighbor to display information about\n"
11801 "Neighbor on BGP configured interface\n"
11802 "Display flap statistics of the routes learned from neighbor\n"
11803 "Display the dampened routes received from neighbor\n"
11804 "Display routes learned from neighbor\n"
11805 JSON_STR)
11806 {
11807 char *peerstr = NULL;
11808 struct bgp *bgp = NULL;
11809 afi_t afi = AFI_IP6;
11810 safi_t safi = SAFI_UNICAST;
11811 struct peer *peer;
11812 enum bgp_show_type sh_type = bgp_show_type_neighbor;
11813 int idx = 0;
11814 bool uj = use_json(argc, argv);
11815
11816 if (uj)
11817 argc--;
11818
11819 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11820 &bgp, uj);
11821 if (!idx)
11822 return CMD_WARNING;
11823
11824 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11825 argv_find(argv, argc, "neighbors", &idx);
11826 peerstr = argv[++idx]->arg;
11827
11828 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
11829 if (!peer)
11830 return CMD_WARNING;
11831
11832 if (argv_find(argv, argc, "flap-statistics", &idx))
11833 sh_type = bgp_show_type_flap_neighbor;
11834 else if (argv_find(argv, argc, "dampened-routes", &idx))
11835 sh_type = bgp_show_type_damp_neighbor;
11836 else if (argv_find(argv, argc, "routes", &idx))
11837 sh_type = bgp_show_type_neighbor;
11838
11839 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
11840 }
11841
11842 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
11843
11844 struct bgp_distance {
11845 /* Distance value for the IP source prefix. */
11846 uint8_t distance;
11847
11848 /* Name of the access-list to be matched. */
11849 char *access_list;
11850 };
11851
11852 DEFUN (show_bgp_afi_vpn_rd_route,
11853 show_bgp_afi_vpn_rd_route_cmd,
11854 "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]",
11855 SHOW_STR
11856 BGP_STR
11857 BGP_AFI_HELP_STR
11858 "Address Family modifier\n"
11859 "Display information for a route distinguisher\n"
11860 "Route Distinguisher\n"
11861 "Network in the BGP routing table to display\n"
11862 "Network in the BGP routing table to display\n"
11863 JSON_STR)
11864 {
11865 int ret;
11866 struct prefix_rd prd;
11867 afi_t afi = AFI_MAX;
11868 int idx = 0;
11869
11870 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
11871 vty_out(vty, "%% Malformed Address Family\n");
11872 return CMD_WARNING;
11873 }
11874
11875 ret = str2prefix_rd(argv[5]->arg, &prd);
11876 if (!ret) {
11877 vty_out(vty, "%% Malformed Route Distinguisher\n");
11878 return CMD_WARNING;
11879 }
11880
11881 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
11882 0, BGP_PATH_SHOW_ALL, use_json(argc, argv));
11883 }
11884
11885 static struct bgp_distance *bgp_distance_new(void)
11886 {
11887 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
11888 }
11889
11890 static void bgp_distance_free(struct bgp_distance *bdistance)
11891 {
11892 XFREE(MTYPE_BGP_DISTANCE, bdistance);
11893 }
11894
11895 static int bgp_distance_set(struct vty *vty, const char *distance_str,
11896 const char *ip_str, const char *access_list_str)
11897 {
11898 int ret;
11899 afi_t afi;
11900 safi_t safi;
11901 struct prefix p;
11902 uint8_t distance;
11903 struct bgp_node *rn;
11904 struct bgp_distance *bdistance;
11905
11906 afi = bgp_node_afi(vty);
11907 safi = bgp_node_safi(vty);
11908
11909 ret = str2prefix(ip_str, &p);
11910 if (ret == 0) {
11911 vty_out(vty, "Malformed prefix\n");
11912 return CMD_WARNING_CONFIG_FAILED;
11913 }
11914
11915 distance = atoi(distance_str);
11916
11917 /* Get BGP distance node. */
11918 rn = bgp_node_get(bgp_distance_table[afi][safi], (struct prefix *)&p);
11919 bdistance = bgp_node_get_bgp_distance_info(rn);
11920 if (bdistance)
11921 bgp_unlock_node(rn);
11922 else {
11923 bdistance = bgp_distance_new();
11924 bgp_node_set_bgp_distance_info(rn, bdistance);
11925 }
11926
11927 /* Set distance value. */
11928 bdistance->distance = distance;
11929
11930 /* Reset access-list configuration. */
11931 if (bdistance->access_list) {
11932 XFREE(MTYPE_AS_LIST, bdistance->access_list);
11933 bdistance->access_list = NULL;
11934 }
11935 if (access_list_str)
11936 bdistance->access_list =
11937 XSTRDUP(MTYPE_AS_LIST, access_list_str);
11938
11939 return CMD_SUCCESS;
11940 }
11941
11942 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
11943 const char *ip_str, const char *access_list_str)
11944 {
11945 int ret;
11946 afi_t afi;
11947 safi_t safi;
11948 struct prefix p;
11949 int distance;
11950 struct bgp_node *rn;
11951 struct bgp_distance *bdistance;
11952
11953 afi = bgp_node_afi(vty);
11954 safi = bgp_node_safi(vty);
11955
11956 ret = str2prefix(ip_str, &p);
11957 if (ret == 0) {
11958 vty_out(vty, "Malformed prefix\n");
11959 return CMD_WARNING_CONFIG_FAILED;
11960 }
11961
11962 rn = bgp_node_lookup(bgp_distance_table[afi][safi],
11963 (struct prefix *)&p);
11964 if (!rn) {
11965 vty_out(vty, "Can't find specified prefix\n");
11966 return CMD_WARNING_CONFIG_FAILED;
11967 }
11968
11969 bdistance = bgp_node_get_bgp_distance_info(rn);
11970 distance = atoi(distance_str);
11971
11972 if (bdistance->distance != distance) {
11973 vty_out(vty, "Distance does not match configured\n");
11974 return CMD_WARNING_CONFIG_FAILED;
11975 }
11976
11977 XFREE(MTYPE_AS_LIST, bdistance->access_list);
11978 bgp_distance_free(bdistance);
11979
11980 bgp_node_set_bgp_path_info(rn, NULL);
11981 bgp_unlock_node(rn);
11982 bgp_unlock_node(rn);
11983
11984 return CMD_SUCCESS;
11985 }
11986
11987 /* Apply BGP information to distance method. */
11988 uint8_t bgp_distance_apply(struct prefix *p, struct bgp_path_info *pinfo,
11989 afi_t afi, safi_t safi, struct bgp *bgp)
11990 {
11991 struct bgp_node *rn;
11992 struct prefix q;
11993 struct peer *peer;
11994 struct bgp_distance *bdistance;
11995 struct access_list *alist;
11996 struct bgp_static *bgp_static;
11997
11998 if (!bgp)
11999 return 0;
12000
12001 peer = pinfo->peer;
12002
12003 if (pinfo->attr->distance)
12004 return pinfo->attr->distance;
12005
12006 /* Check source address. */
12007 sockunion2hostprefix(&peer->su, &q);
12008 rn = bgp_node_match(bgp_distance_table[afi][safi], &q);
12009 if (rn) {
12010 bdistance = bgp_node_get_bgp_distance_info(rn);
12011 bgp_unlock_node(rn);
12012
12013 if (bdistance->access_list) {
12014 alist = access_list_lookup(afi, bdistance->access_list);
12015 if (alist
12016 && access_list_apply(alist, p) == FILTER_PERMIT)
12017 return bdistance->distance;
12018 } else
12019 return bdistance->distance;
12020 }
12021
12022 /* Backdoor check. */
12023 rn = bgp_node_lookup(bgp->route[afi][safi], p);
12024 if (rn) {
12025 bgp_static = bgp_node_get_bgp_static_info(rn);
12026 bgp_unlock_node(rn);
12027
12028 if (bgp_static->backdoor) {
12029 if (bgp->distance_local[afi][safi])
12030 return bgp->distance_local[afi][safi];
12031 else
12032 return ZEBRA_IBGP_DISTANCE_DEFAULT;
12033 }
12034 }
12035
12036 if (peer->sort == BGP_PEER_EBGP) {
12037 if (bgp->distance_ebgp[afi][safi])
12038 return bgp->distance_ebgp[afi][safi];
12039 return ZEBRA_EBGP_DISTANCE_DEFAULT;
12040 } else {
12041 if (bgp->distance_ibgp[afi][safi])
12042 return bgp->distance_ibgp[afi][safi];
12043 return ZEBRA_IBGP_DISTANCE_DEFAULT;
12044 }
12045 }
12046
12047 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
12048 * we should tell ZEBRA update the routes for a specific
12049 * AFI/SAFI to reflect changes in RIB.
12050 */
12051 static void bgp_announce_routes_distance_update(struct bgp *bgp,
12052 afi_t update_afi,
12053 safi_t update_safi)
12054 {
12055 afi_t afi;
12056 safi_t safi;
12057
12058 FOREACH_AFI_SAFI (afi, safi) {
12059 if (!bgp_fibupd_safi(safi))
12060 continue;
12061
12062 if (afi != update_afi && safi != update_safi)
12063 continue;
12064
12065 if (BGP_DEBUG(zebra, ZEBRA))
12066 zlog_debug(
12067 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
12068 __func__, afi, safi);
12069 bgp_zebra_announce_table(bgp, afi, safi);
12070 }
12071 }
12072
12073 DEFUN (bgp_distance,
12074 bgp_distance_cmd,
12075 "distance bgp (1-255) (1-255) (1-255)",
12076 "Define an administrative distance\n"
12077 "BGP distance\n"
12078 "Distance for routes external to the AS\n"
12079 "Distance for routes internal to the AS\n"
12080 "Distance for local routes\n")
12081 {
12082 VTY_DECLVAR_CONTEXT(bgp, bgp);
12083 int idx_number = 2;
12084 int idx_number_2 = 3;
12085 int idx_number_3 = 4;
12086 int distance_ebgp = atoi(argv[idx_number]->arg);
12087 int distance_ibgp = atoi(argv[idx_number_2]->arg);
12088 int distance_local = atoi(argv[idx_number_3]->arg);
12089 afi_t afi;
12090 safi_t safi;
12091
12092 afi = bgp_node_afi(vty);
12093 safi = bgp_node_safi(vty);
12094
12095 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
12096 || bgp->distance_ibgp[afi][safi] != distance_ibgp
12097 || bgp->distance_local[afi][safi] != distance_local) {
12098 bgp->distance_ebgp[afi][safi] = distance_ebgp;
12099 bgp->distance_ibgp[afi][safi] = distance_ibgp;
12100 bgp->distance_local[afi][safi] = distance_local;
12101 bgp_announce_routes_distance_update(bgp, afi, safi);
12102 }
12103 return CMD_SUCCESS;
12104 }
12105
12106 DEFUN (no_bgp_distance,
12107 no_bgp_distance_cmd,
12108 "no distance bgp [(1-255) (1-255) (1-255)]",
12109 NO_STR
12110 "Define an administrative distance\n"
12111 "BGP distance\n"
12112 "Distance for routes external to the AS\n"
12113 "Distance for routes internal to the AS\n"
12114 "Distance for local routes\n")
12115 {
12116 VTY_DECLVAR_CONTEXT(bgp, bgp);
12117 afi_t afi;
12118 safi_t safi;
12119
12120 afi = bgp_node_afi(vty);
12121 safi = bgp_node_safi(vty);
12122
12123 if (bgp->distance_ebgp[afi][safi] != 0
12124 || bgp->distance_ibgp[afi][safi] != 0
12125 || bgp->distance_local[afi][safi] != 0) {
12126 bgp->distance_ebgp[afi][safi] = 0;
12127 bgp->distance_ibgp[afi][safi] = 0;
12128 bgp->distance_local[afi][safi] = 0;
12129 bgp_announce_routes_distance_update(bgp, afi, safi);
12130 }
12131 return CMD_SUCCESS;
12132 }
12133
12134
12135 DEFUN (bgp_distance_source,
12136 bgp_distance_source_cmd,
12137 "distance (1-255) A.B.C.D/M",
12138 "Define an administrative distance\n"
12139 "Administrative distance\n"
12140 "IP source prefix\n")
12141 {
12142 int idx_number = 1;
12143 int idx_ipv4_prefixlen = 2;
12144 bgp_distance_set(vty, argv[idx_number]->arg,
12145 argv[idx_ipv4_prefixlen]->arg, NULL);
12146 return CMD_SUCCESS;
12147 }
12148
12149 DEFUN (no_bgp_distance_source,
12150 no_bgp_distance_source_cmd,
12151 "no distance (1-255) A.B.C.D/M",
12152 NO_STR
12153 "Define an administrative distance\n"
12154 "Administrative distance\n"
12155 "IP source prefix\n")
12156 {
12157 int idx_number = 2;
12158 int idx_ipv4_prefixlen = 3;
12159 bgp_distance_unset(vty, argv[idx_number]->arg,
12160 argv[idx_ipv4_prefixlen]->arg, NULL);
12161 return CMD_SUCCESS;
12162 }
12163
12164 DEFUN (bgp_distance_source_access_list,
12165 bgp_distance_source_access_list_cmd,
12166 "distance (1-255) A.B.C.D/M WORD",
12167 "Define an administrative distance\n"
12168 "Administrative distance\n"
12169 "IP source prefix\n"
12170 "Access list name\n")
12171 {
12172 int idx_number = 1;
12173 int idx_ipv4_prefixlen = 2;
12174 int idx_word = 3;
12175 bgp_distance_set(vty, argv[idx_number]->arg,
12176 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
12177 return CMD_SUCCESS;
12178 }
12179
12180 DEFUN (no_bgp_distance_source_access_list,
12181 no_bgp_distance_source_access_list_cmd,
12182 "no distance (1-255) A.B.C.D/M WORD",
12183 NO_STR
12184 "Define an administrative distance\n"
12185 "Administrative distance\n"
12186 "IP source prefix\n"
12187 "Access list name\n")
12188 {
12189 int idx_number = 2;
12190 int idx_ipv4_prefixlen = 3;
12191 int idx_word = 4;
12192 bgp_distance_unset(vty, argv[idx_number]->arg,
12193 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
12194 return CMD_SUCCESS;
12195 }
12196
12197 DEFUN (ipv6_bgp_distance_source,
12198 ipv6_bgp_distance_source_cmd,
12199 "distance (1-255) X:X::X:X/M",
12200 "Define an administrative distance\n"
12201 "Administrative distance\n"
12202 "IP source prefix\n")
12203 {
12204 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
12205 return CMD_SUCCESS;
12206 }
12207
12208 DEFUN (no_ipv6_bgp_distance_source,
12209 no_ipv6_bgp_distance_source_cmd,
12210 "no distance (1-255) X:X::X:X/M",
12211 NO_STR
12212 "Define an administrative distance\n"
12213 "Administrative distance\n"
12214 "IP source prefix\n")
12215 {
12216 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
12217 return CMD_SUCCESS;
12218 }
12219
12220 DEFUN (ipv6_bgp_distance_source_access_list,
12221 ipv6_bgp_distance_source_access_list_cmd,
12222 "distance (1-255) X:X::X:X/M WORD",
12223 "Define an administrative distance\n"
12224 "Administrative distance\n"
12225 "IP source prefix\n"
12226 "Access list name\n")
12227 {
12228 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
12229 return CMD_SUCCESS;
12230 }
12231
12232 DEFUN (no_ipv6_bgp_distance_source_access_list,
12233 no_ipv6_bgp_distance_source_access_list_cmd,
12234 "no distance (1-255) X:X::X:X/M WORD",
12235 NO_STR
12236 "Define an administrative distance\n"
12237 "Administrative distance\n"
12238 "IP source prefix\n"
12239 "Access list name\n")
12240 {
12241 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
12242 return CMD_SUCCESS;
12243 }
12244
12245 DEFUN (bgp_damp_set,
12246 bgp_damp_set_cmd,
12247 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
12248 "BGP Specific commands\n"
12249 "Enable route-flap dampening\n"
12250 "Half-life time for the penalty\n"
12251 "Value to start reusing a route\n"
12252 "Value to start suppressing a route\n"
12253 "Maximum duration to suppress a stable route\n")
12254 {
12255 VTY_DECLVAR_CONTEXT(bgp, bgp);
12256 int idx_half_life = 2;
12257 int idx_reuse = 3;
12258 int idx_suppress = 4;
12259 int idx_max_suppress = 5;
12260 int half = DEFAULT_HALF_LIFE * 60;
12261 int reuse = DEFAULT_REUSE;
12262 int suppress = DEFAULT_SUPPRESS;
12263 int max = 4 * half;
12264
12265 if (argc == 6) {
12266 half = atoi(argv[idx_half_life]->arg) * 60;
12267 reuse = atoi(argv[idx_reuse]->arg);
12268 suppress = atoi(argv[idx_suppress]->arg);
12269 max = atoi(argv[idx_max_suppress]->arg) * 60;
12270 } else if (argc == 3) {
12271 half = atoi(argv[idx_half_life]->arg) * 60;
12272 max = 4 * half;
12273 }
12274
12275 /*
12276 * These can't be 0 but our SA doesn't understand the
12277 * way our cli is constructed
12278 */
12279 assert(reuse);
12280 assert(half);
12281 if (suppress < reuse) {
12282 vty_out(vty,
12283 "Suppress value cannot be less than reuse value \n");
12284 return 0;
12285 }
12286
12287 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
12288 reuse, suppress, max);
12289 }
12290
12291 DEFUN (bgp_damp_unset,
12292 bgp_damp_unset_cmd,
12293 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
12294 NO_STR
12295 "BGP Specific commands\n"
12296 "Enable route-flap dampening\n"
12297 "Half-life time for the penalty\n"
12298 "Value to start reusing a route\n"
12299 "Value to start suppressing a route\n"
12300 "Maximum duration to suppress a stable route\n")
12301 {
12302 VTY_DECLVAR_CONTEXT(bgp, bgp);
12303 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
12304 }
12305
12306 /* Display specified route of BGP table. */
12307 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
12308 const char *ip_str, afi_t afi, safi_t safi,
12309 struct prefix_rd *prd, int prefix_check)
12310 {
12311 int ret;
12312 struct prefix match;
12313 struct bgp_node *rn;
12314 struct bgp_node *rm;
12315 struct bgp_path_info *pi;
12316 struct bgp_path_info *pi_temp;
12317 struct bgp *bgp;
12318 struct bgp_table *table;
12319
12320 /* BGP structure lookup. */
12321 if (view_name) {
12322 bgp = bgp_lookup_by_name(view_name);
12323 if (bgp == NULL) {
12324 vty_out(vty, "%% Can't find BGP instance %s\n",
12325 view_name);
12326 return CMD_WARNING;
12327 }
12328 } else {
12329 bgp = bgp_get_default();
12330 if (bgp == NULL) {
12331 vty_out(vty, "%% No BGP process is configured\n");
12332 return CMD_WARNING;
12333 }
12334 }
12335
12336 /* Check IP address argument. */
12337 ret = str2prefix(ip_str, &match);
12338 if (!ret) {
12339 vty_out(vty, "%% address is malformed\n");
12340 return CMD_WARNING;
12341 }
12342
12343 match.family = afi2family(afi);
12344
12345 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
12346 || (safi == SAFI_EVPN)) {
12347 for (rn = bgp_table_top(bgp->rib[AFI_IP][safi]); rn;
12348 rn = bgp_route_next(rn)) {
12349 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
12350 continue;
12351 table = bgp_node_get_bgp_table_info(rn);
12352 if (!table)
12353 continue;
12354 if ((rm = bgp_node_match(table, &match)) == NULL)
12355 continue;
12356
12357 if (!prefix_check
12358 || rm->p.prefixlen == match.prefixlen) {
12359 pi = bgp_node_get_bgp_path_info(rm);
12360 while (pi) {
12361 if (pi->extra && pi->extra->damp_info) {
12362 pi_temp = pi->next;
12363 bgp_damp_info_free(
12364 pi->extra->damp_info,
12365 1, afi, safi);
12366 pi = pi_temp;
12367 } else
12368 pi = pi->next;
12369 }
12370 }
12371
12372 bgp_unlock_node(rm);
12373 }
12374 } else {
12375 if ((rn = bgp_node_match(bgp->rib[afi][safi], &match))
12376 != NULL) {
12377 if (!prefix_check
12378 || rn->p.prefixlen == match.prefixlen) {
12379 pi = bgp_node_get_bgp_path_info(rn);
12380 while (pi) {
12381 if (pi->extra && pi->extra->damp_info) {
12382 pi_temp = pi->next;
12383 bgp_damp_info_free(
12384 pi->extra->damp_info,
12385 1, afi, safi);
12386 pi = pi_temp;
12387 } else
12388 pi = pi->next;
12389 }
12390 }
12391
12392 bgp_unlock_node(rn);
12393 }
12394 }
12395
12396 return CMD_SUCCESS;
12397 }
12398
12399 DEFUN (clear_ip_bgp_dampening,
12400 clear_ip_bgp_dampening_cmd,
12401 "clear ip bgp dampening",
12402 CLEAR_STR
12403 IP_STR
12404 BGP_STR
12405 "Clear route flap dampening information\n")
12406 {
12407 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
12408 return CMD_SUCCESS;
12409 }
12410
12411 DEFUN (clear_ip_bgp_dampening_prefix,
12412 clear_ip_bgp_dampening_prefix_cmd,
12413 "clear ip bgp dampening A.B.C.D/M",
12414 CLEAR_STR
12415 IP_STR
12416 BGP_STR
12417 "Clear route flap dampening information\n"
12418 "IPv4 prefix\n")
12419 {
12420 int idx_ipv4_prefixlen = 4;
12421 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
12422 AFI_IP, SAFI_UNICAST, NULL, 1);
12423 }
12424
12425 DEFUN (clear_ip_bgp_dampening_address,
12426 clear_ip_bgp_dampening_address_cmd,
12427 "clear ip bgp dampening A.B.C.D",
12428 CLEAR_STR
12429 IP_STR
12430 BGP_STR
12431 "Clear route flap dampening information\n"
12432 "Network to clear damping information\n")
12433 {
12434 int idx_ipv4 = 4;
12435 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
12436 SAFI_UNICAST, NULL, 0);
12437 }
12438
12439 DEFUN (clear_ip_bgp_dampening_address_mask,
12440 clear_ip_bgp_dampening_address_mask_cmd,
12441 "clear ip bgp dampening A.B.C.D A.B.C.D",
12442 CLEAR_STR
12443 IP_STR
12444 BGP_STR
12445 "Clear route flap dampening information\n"
12446 "Network to clear damping information\n"
12447 "Network mask\n")
12448 {
12449 int idx_ipv4 = 4;
12450 int idx_ipv4_2 = 5;
12451 int ret;
12452 char prefix_str[BUFSIZ];
12453
12454 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
12455 prefix_str);
12456 if (!ret) {
12457 vty_out(vty, "%% Inconsistent address and mask\n");
12458 return CMD_WARNING;
12459 }
12460
12461 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
12462 NULL, 0);
12463 }
12464
12465 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
12466 {
12467 struct vty *vty = arg;
12468 struct peer *peer = bucket->data;
12469 char buf[SU_ADDRSTRLEN];
12470
12471 vty_out(vty, "\tPeer: %s %s\n", peer->host,
12472 sockunion2str(&peer->su, buf, sizeof(buf)));
12473 }
12474
12475 DEFUN (show_bgp_peerhash,
12476 show_bgp_peerhash_cmd,
12477 "show bgp peerhash",
12478 SHOW_STR
12479 BGP_STR
12480 "Display information about the BGP peerhash\n")
12481 {
12482 struct list *instances = bm->bgp;
12483 struct listnode *node;
12484 struct bgp *bgp;
12485
12486 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
12487 vty_out(vty, "BGP: %s\n", bgp->name);
12488 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
12489 vty);
12490 }
12491
12492 return CMD_SUCCESS;
12493 }
12494
12495 /* also used for encap safi */
12496 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
12497 afi_t afi, safi_t safi)
12498 {
12499 struct bgp_node *prn;
12500 struct bgp_node *rn;
12501 struct bgp_table *table;
12502 struct prefix *p;
12503 struct prefix_rd *prd;
12504 struct bgp_static *bgp_static;
12505 mpls_label_t label;
12506 char buf[SU_ADDRSTRLEN];
12507 char rdbuf[RD_ADDRSTRLEN];
12508
12509 /* Network configuration. */
12510 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
12511 prn = bgp_route_next(prn)) {
12512 table = bgp_node_get_bgp_table_info(prn);
12513 if (!table)
12514 continue;
12515
12516 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
12517 bgp_static = bgp_node_get_bgp_static_info(rn);
12518 if (bgp_static == NULL)
12519 continue;
12520
12521 p = &rn->p;
12522 prd = (struct prefix_rd *)&prn->p;
12523
12524 /* "network" configuration display. */
12525 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
12526 label = decode_label(&bgp_static->label);
12527
12528 vty_out(vty, " network %s/%d rd %s",
12529 inet_ntop(p->family, &p->u.prefix, buf,
12530 SU_ADDRSTRLEN),
12531 p->prefixlen, rdbuf);
12532 if (safi == SAFI_MPLS_VPN)
12533 vty_out(vty, " label %u", label);
12534
12535 if (bgp_static->rmap.name)
12536 vty_out(vty, " route-map %s",
12537 bgp_static->rmap.name);
12538
12539 if (bgp_static->backdoor)
12540 vty_out(vty, " backdoor");
12541
12542 vty_out(vty, "\n");
12543 }
12544 }
12545 }
12546
12547 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
12548 afi_t afi, safi_t safi)
12549 {
12550 struct bgp_node *prn;
12551 struct bgp_node *rn;
12552 struct bgp_table *table;
12553 struct prefix *p;
12554 struct prefix_rd *prd;
12555 struct bgp_static *bgp_static;
12556 char buf[PREFIX_STRLEN * 2];
12557 char buf2[SU_ADDRSTRLEN];
12558 char rdbuf[RD_ADDRSTRLEN];
12559
12560 /* Network configuration. */
12561 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
12562 prn = bgp_route_next(prn)) {
12563 table = bgp_node_get_bgp_table_info(prn);
12564 if (!table)
12565 continue;
12566
12567 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
12568 bgp_static = bgp_node_get_bgp_static_info(rn);
12569 if (bgp_static == NULL)
12570 continue;
12571
12572 char *macrouter = NULL;
12573 char *esi = NULL;
12574
12575 if (bgp_static->router_mac)
12576 macrouter = prefix_mac2str(
12577 bgp_static->router_mac, NULL, 0);
12578 if (bgp_static->eth_s_id)
12579 esi = esi2str(bgp_static->eth_s_id);
12580 p = &rn->p;
12581 prd = (struct prefix_rd *)&prn->p;
12582
12583 /* "network" configuration display. */
12584 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
12585 if (p->u.prefix_evpn.route_type == 5) {
12586 char local_buf[PREFIX_STRLEN];
12587 uint8_t family = is_evpn_prefix_ipaddr_v4((
12588 struct prefix_evpn *)p)
12589 ? AF_INET
12590 : AF_INET6;
12591 inet_ntop(family,
12592 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
12593 local_buf, PREFIX_STRLEN);
12594 sprintf(buf, "%s/%u", local_buf,
12595 p->u.prefix_evpn.prefix_addr.ip_prefix_length);
12596 } else {
12597 prefix2str(p, buf, sizeof(buf));
12598 }
12599
12600 if (bgp_static->gatewayIp.family == AF_INET
12601 || bgp_static->gatewayIp.family == AF_INET6)
12602 inet_ntop(bgp_static->gatewayIp.family,
12603 &bgp_static->gatewayIp.u.prefix, buf2,
12604 sizeof(buf2));
12605 vty_out(vty,
12606 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
12607 buf, rdbuf,
12608 p->u.prefix_evpn.prefix_addr.eth_tag,
12609 decode_label(&bgp_static->label), esi, buf2,
12610 macrouter);
12611
12612 XFREE(MTYPE_TMP, macrouter);
12613 XFREE(MTYPE_TMP, esi);
12614 }
12615 }
12616 }
12617
12618 /* Configuration of static route announcement and aggregate
12619 information. */
12620 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
12621 safi_t safi)
12622 {
12623 struct bgp_node *rn;
12624 struct prefix *p;
12625 struct bgp_static *bgp_static;
12626 struct bgp_aggregate *bgp_aggregate;
12627 char buf[SU_ADDRSTRLEN];
12628
12629 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
12630 bgp_config_write_network_vpn(vty, bgp, afi, safi);
12631 return;
12632 }
12633
12634 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
12635 bgp_config_write_network_evpn(vty, bgp, afi, safi);
12636 return;
12637 }
12638
12639 /* Network configuration. */
12640 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
12641 rn = bgp_route_next(rn)) {
12642 bgp_static = bgp_node_get_bgp_static_info(rn);
12643 if (bgp_static == NULL)
12644 continue;
12645
12646 p = &rn->p;
12647
12648 vty_out(vty, " network %s/%d",
12649 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
12650 p->prefixlen);
12651
12652 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
12653 vty_out(vty, " label-index %u",
12654 bgp_static->label_index);
12655
12656 if (bgp_static->rmap.name)
12657 vty_out(vty, " route-map %s", bgp_static->rmap.name);
12658
12659 if (bgp_static->backdoor)
12660 vty_out(vty, " backdoor");
12661
12662 vty_out(vty, "\n");
12663 }
12664
12665 /* Aggregate-address configuration. */
12666 for (rn = bgp_table_top(bgp->aggregate[afi][safi]); rn;
12667 rn = bgp_route_next(rn)) {
12668 bgp_aggregate = bgp_node_get_bgp_aggregate_info(rn);
12669 if (bgp_aggregate == NULL)
12670 continue;
12671
12672 p = &rn->p;
12673
12674 vty_out(vty, " aggregate-address %s/%d",
12675 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
12676 p->prefixlen);
12677
12678 if (bgp_aggregate->as_set)
12679 vty_out(vty, " as-set");
12680
12681 if (bgp_aggregate->summary_only)
12682 vty_out(vty, " summary-only");
12683
12684 if (bgp_aggregate->rmap.name)
12685 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
12686
12687 vty_out(vty, "\n");
12688 }
12689 }
12690
12691 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
12692 safi_t safi)
12693 {
12694 struct bgp_node *rn;
12695 struct bgp_distance *bdistance;
12696
12697 /* Distance configuration. */
12698 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
12699 && bgp->distance_local[afi][safi]
12700 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
12701 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
12702 || bgp->distance_local[afi][safi]
12703 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
12704 vty_out(vty, " distance bgp %d %d %d\n",
12705 bgp->distance_ebgp[afi][safi],
12706 bgp->distance_ibgp[afi][safi],
12707 bgp->distance_local[afi][safi]);
12708 }
12709
12710 for (rn = bgp_table_top(bgp_distance_table[afi][safi]); rn;
12711 rn = bgp_route_next(rn)) {
12712 bdistance = bgp_node_get_bgp_distance_info(rn);
12713 if (bdistance != NULL) {
12714 char buf[PREFIX_STRLEN];
12715
12716 vty_out(vty, " distance %d %s %s\n",
12717 bdistance->distance,
12718 prefix2str(&rn->p, buf, sizeof(buf)),
12719 bdistance->access_list ? bdistance->access_list
12720 : "");
12721 }
12722 }
12723 }
12724
12725 /* Allocate routing table structure and install commands. */
12726 void bgp_route_init(void)
12727 {
12728 afi_t afi;
12729 safi_t safi;
12730
12731 /* Init BGP distance table. */
12732 FOREACH_AFI_SAFI (afi, safi)
12733 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
12734
12735 /* IPv4 BGP commands. */
12736 install_element(BGP_NODE, &bgp_table_map_cmd);
12737 install_element(BGP_NODE, &bgp_network_cmd);
12738 install_element(BGP_NODE, &no_bgp_table_map_cmd);
12739
12740 install_element(BGP_NODE, &aggregate_address_cmd);
12741 install_element(BGP_NODE, &aggregate_address_mask_cmd);
12742 install_element(BGP_NODE, &no_aggregate_address_cmd);
12743 install_element(BGP_NODE, &no_aggregate_address_mask_cmd);
12744
12745 /* IPv4 unicast configuration. */
12746 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
12747 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
12748 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
12749
12750 install_element(BGP_IPV4_NODE, &aggregate_address_cmd);
12751 install_element(BGP_IPV4_NODE, &aggregate_address_mask_cmd);
12752 install_element(BGP_IPV4_NODE, &no_aggregate_address_cmd);
12753 install_element(BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
12754
12755 /* IPv4 multicast configuration. */
12756 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
12757 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
12758 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
12759 install_element(BGP_IPV4M_NODE, &aggregate_address_cmd);
12760 install_element(BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
12761 install_element(BGP_IPV4M_NODE, &no_aggregate_address_cmd);
12762 install_element(BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
12763
12764 /* IPv4 labeled-unicast configuration. */
12765 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
12766 install_element(VIEW_NODE, &show_ip_bgp_cmd);
12767 install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
12768 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
12769 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
12770
12771 install_element(VIEW_NODE,
12772 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
12773 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
12774 install_element(VIEW_NODE,
12775 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
12776 #ifdef KEEP_OLD_VPN_COMMANDS
12777 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
12778 #endif /* KEEP_OLD_VPN_COMMANDS */
12779 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
12780 install_element(VIEW_NODE,
12781 &show_bgp_l2vpn_evpn_route_prefix_cmd);
12782
12783 /* BGP dampening clear commands */
12784 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
12785 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
12786
12787 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
12788 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
12789
12790 /* prefix count */
12791 install_element(ENABLE_NODE,
12792 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
12793 #ifdef KEEP_OLD_VPN_COMMANDS
12794 install_element(ENABLE_NODE,
12795 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
12796 #endif /* KEEP_OLD_VPN_COMMANDS */
12797
12798 /* New config IPv6 BGP commands. */
12799 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
12800 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
12801 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
12802
12803 install_element(BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
12804 install_element(BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
12805
12806 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
12807
12808 install_element(BGP_NODE, &bgp_distance_cmd);
12809 install_element(BGP_NODE, &no_bgp_distance_cmd);
12810 install_element(BGP_NODE, &bgp_distance_source_cmd);
12811 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
12812 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
12813 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
12814 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
12815 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
12816 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
12817 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
12818 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
12819 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
12820 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
12821 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
12822 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
12823 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
12824 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
12825 install_element(BGP_IPV4M_NODE,
12826 &no_bgp_distance_source_access_list_cmd);
12827 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
12828 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
12829 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
12830 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
12831 install_element(BGP_IPV6_NODE,
12832 &ipv6_bgp_distance_source_access_list_cmd);
12833 install_element(BGP_IPV6_NODE,
12834 &no_ipv6_bgp_distance_source_access_list_cmd);
12835 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
12836 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
12837 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
12838 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
12839 install_element(BGP_IPV6M_NODE,
12840 &ipv6_bgp_distance_source_access_list_cmd);
12841 install_element(BGP_IPV6M_NODE,
12842 &no_ipv6_bgp_distance_source_access_list_cmd);
12843
12844 install_element(BGP_NODE, &bgp_damp_set_cmd);
12845 install_element(BGP_NODE, &bgp_damp_unset_cmd);
12846 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
12847 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
12848
12849 /* IPv4 Multicast Mode */
12850 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
12851 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
12852
12853 /* Large Communities */
12854 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
12855 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
12856
12857 /* show bgp ipv4 flowspec detailed */
12858 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
12859
12860 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
12861 }
12862
12863 void bgp_route_finish(void)
12864 {
12865 afi_t afi;
12866 safi_t safi;
12867
12868 FOREACH_AFI_SAFI (afi, safi) {
12869 bgp_table_unlock(bgp_distance_table[afi][safi]);
12870 bgp_distance_table[afi][safi] = NULL;
12871 }
12872 }