]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #5589 from ton31337/fix/send_fsm_error_notification_where_needed
[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_IBGP)
4361 return 1;
4362
4363 if (peer->sort == BGP_PEER_EBGP
4364 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
4365 || FILTER_LIST_OUT_NAME(filter)
4366 || DISTRIBUTE_OUT_NAME(filter)))
4367 return 1;
4368 return 0;
4369 }
4370
4371 int bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
4372 {
4373 if (peer->sort == BGP_PEER_IBGP)
4374 return 1;
4375
4376 if (peer->sort == BGP_PEER_EBGP
4377 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
4378 || FILTER_LIST_IN_NAME(filter)
4379 || DISTRIBUTE_IN_NAME(filter)))
4380 return 1;
4381 return 0;
4382 }
4383
4384 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
4385 safi_t safi)
4386 {
4387 struct bgp_node *rn;
4388 struct bgp_path_info *pi;
4389 struct bgp_path_info *next;
4390
4391 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
4392 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = next) {
4393 next = pi->next;
4394
4395 /* Unimport EVPN routes from VRFs */
4396 if (safi == SAFI_EVPN)
4397 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
4398 SAFI_EVPN,
4399 &rn->p, pi);
4400
4401 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
4402 && pi->type == ZEBRA_ROUTE_BGP
4403 && (pi->sub_type == BGP_ROUTE_NORMAL
4404 || pi->sub_type == BGP_ROUTE_AGGREGATE
4405 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
4406
4407 if (bgp_fibupd_safi(safi))
4408 bgp_zebra_withdraw(&rn->p, pi, bgp,
4409 safi);
4410 bgp_path_info_reap(rn, pi);
4411 }
4412 }
4413 }
4414
4415 /* Delete all kernel routes. */
4416 void bgp_cleanup_routes(struct bgp *bgp)
4417 {
4418 afi_t afi;
4419 struct bgp_node *rn;
4420 struct bgp_table *table;
4421
4422 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
4423 if (afi == AFI_L2VPN)
4424 continue;
4425 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
4426 SAFI_UNICAST);
4427 /*
4428 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
4429 */
4430 if (afi != AFI_L2VPN) {
4431 safi_t safi;
4432 safi = SAFI_MPLS_VPN;
4433 for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
4434 rn = bgp_route_next(rn)) {
4435 table = bgp_node_get_bgp_table_info(rn);
4436 if (table != NULL) {
4437 bgp_cleanup_table(bgp, table, safi);
4438 bgp_table_finish(&table);
4439 bgp_node_set_bgp_table_info(rn, NULL);
4440 bgp_unlock_node(rn);
4441 }
4442 }
4443 safi = SAFI_ENCAP;
4444 for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
4445 rn = bgp_route_next(rn)) {
4446 table = bgp_node_get_bgp_table_info(rn);
4447 if (table != NULL) {
4448 bgp_cleanup_table(bgp, table, safi);
4449 bgp_table_finish(&table);
4450 bgp_node_set_bgp_table_info(rn, NULL);
4451 bgp_unlock_node(rn);
4452 }
4453 }
4454 }
4455 }
4456 for (rn = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); rn;
4457 rn = bgp_route_next(rn)) {
4458 table = bgp_node_get_bgp_table_info(rn);
4459 if (table != NULL) {
4460 bgp_cleanup_table(bgp, table, SAFI_EVPN);
4461 bgp_table_finish(&table);
4462 bgp_node_set_bgp_table_info(rn, NULL);
4463 bgp_unlock_node(rn);
4464 }
4465 }
4466 }
4467
4468 void bgp_reset(void)
4469 {
4470 vty_reset();
4471 bgp_zclient_reset();
4472 access_list_reset();
4473 prefix_list_reset();
4474 }
4475
4476 static int bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
4477 {
4478 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
4479 && CHECK_FLAG(peer->af_cap[afi][safi],
4480 PEER_CAP_ADDPATH_AF_TX_RCV));
4481 }
4482
4483 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
4484 value. */
4485 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
4486 struct bgp_nlri *packet)
4487 {
4488 uint8_t *pnt;
4489 uint8_t *lim;
4490 struct prefix p;
4491 int psize;
4492 int ret;
4493 afi_t afi;
4494 safi_t safi;
4495 int addpath_encoded;
4496 uint32_t addpath_id;
4497
4498 pnt = packet->nlri;
4499 lim = pnt + packet->length;
4500 afi = packet->afi;
4501 safi = packet->safi;
4502 addpath_id = 0;
4503 addpath_encoded = bgp_addpath_encode_rx(peer, afi, safi);
4504
4505 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
4506 syntactic validity. If the field is syntactically incorrect,
4507 then the Error Subcode is set to Invalid Network Field. */
4508 for (; pnt < lim; pnt += psize) {
4509 /* Clear prefix structure. */
4510 memset(&p, 0, sizeof(struct prefix));
4511
4512 if (addpath_encoded) {
4513
4514 /* When packet overflow occurs return immediately. */
4515 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
4516 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
4517
4518 addpath_id = ntohl(*((uint32_t *)pnt));
4519 pnt += BGP_ADDPATH_ID_LEN;
4520 }
4521
4522 /* Fetch prefix length. */
4523 p.prefixlen = *pnt++;
4524 /* afi/safi validity already verified by caller,
4525 * bgp_update_receive */
4526 p.family = afi2family(afi);
4527
4528 /* Prefix length check. */
4529 if (p.prefixlen > prefix_blen(&p) * 8) {
4530 flog_err(
4531 EC_BGP_UPDATE_RCV,
4532 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
4533 peer->host, p.prefixlen, packet->afi);
4534 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
4535 }
4536
4537 /* Packet size overflow check. */
4538 psize = PSIZE(p.prefixlen);
4539
4540 /* When packet overflow occur return immediately. */
4541 if (pnt + psize > lim) {
4542 flog_err(
4543 EC_BGP_UPDATE_RCV,
4544 "%s [Error] Update packet error (prefix length %d overflows packet)",
4545 peer->host, p.prefixlen);
4546 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
4547 }
4548
4549 /* Defensive coding, double-check the psize fits in a struct
4550 * prefix */
4551 if (psize > (ssize_t)sizeof(p.u)) {
4552 flog_err(
4553 EC_BGP_UPDATE_RCV,
4554 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
4555 peer->host, p.prefixlen, sizeof(p.u));
4556 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
4557 }
4558
4559 /* Fetch prefix from NLRI packet. */
4560 memcpy(p.u.val, pnt, psize);
4561
4562 /* Check address. */
4563 if (afi == AFI_IP && safi == SAFI_UNICAST) {
4564 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
4565 /* From RFC4271 Section 6.3:
4566 *
4567 * If a prefix in the NLRI field is semantically
4568 * incorrect
4569 * (e.g., an unexpected multicast IP address),
4570 * an error SHOULD
4571 * be logged locally, and the prefix SHOULD be
4572 * ignored.
4573 */
4574 flog_err(
4575 EC_BGP_UPDATE_RCV,
4576 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
4577 peer->host, inet_ntoa(p.u.prefix4));
4578 continue;
4579 }
4580 }
4581
4582 /* Check address. */
4583 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
4584 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
4585 char buf[BUFSIZ];
4586
4587 flog_err(
4588 EC_BGP_UPDATE_RCV,
4589 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
4590 peer->host,
4591 inet_ntop(AF_INET6, &p.u.prefix6, buf,
4592 BUFSIZ));
4593
4594 continue;
4595 }
4596 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
4597 char buf[BUFSIZ];
4598
4599 flog_err(
4600 EC_BGP_UPDATE_RCV,
4601 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
4602 peer->host,
4603 inet_ntop(AF_INET6, &p.u.prefix6, buf,
4604 BUFSIZ));
4605
4606 continue;
4607 }
4608 }
4609
4610 /* Normal process. */
4611 if (attr)
4612 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
4613 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
4614 NULL, NULL, 0, 0, NULL);
4615 else
4616 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
4617 safi, ZEBRA_ROUTE_BGP,
4618 BGP_ROUTE_NORMAL, NULL, NULL, 0,
4619 NULL);
4620
4621 /* Do not send BGP notification twice when maximum-prefix count
4622 * overflow. */
4623 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
4624 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
4625
4626 /* Address family configuration mismatch. */
4627 if (ret < 0)
4628 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
4629 }
4630
4631 /* Packet length consistency check. */
4632 if (pnt != lim) {
4633 flog_err(
4634 EC_BGP_UPDATE_RCV,
4635 "%s [Error] Update packet error (prefix length mismatch with total length)",
4636 peer->host);
4637 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
4638 }
4639
4640 return BGP_NLRI_PARSE_OK;
4641 }
4642
4643 static struct bgp_static *bgp_static_new(void)
4644 {
4645 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
4646 }
4647
4648 static void bgp_static_free(struct bgp_static *bgp_static)
4649 {
4650 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
4651 route_map_counter_decrement(bgp_static->rmap.map);
4652
4653 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
4654 XFREE(MTYPE_BGP_STATIC, bgp_static);
4655 }
4656
4657 void bgp_static_update(struct bgp *bgp, struct prefix *p,
4658 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
4659 {
4660 struct bgp_node *rn;
4661 struct bgp_path_info *pi;
4662 struct bgp_path_info *new;
4663 struct bgp_path_info rmap_path;
4664 struct attr attr;
4665 struct attr *attr_new;
4666 route_map_result_t ret;
4667 #if ENABLE_BGP_VNC
4668 int vnc_implicit_withdraw = 0;
4669 #endif
4670
4671 assert(bgp_static);
4672 if (!bgp_static)
4673 return;
4674
4675 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
4676
4677 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
4678
4679 attr.nexthop = bgp_static->igpnexthop;
4680 attr.med = bgp_static->igpmetric;
4681 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
4682
4683 if (bgp_static->atomic)
4684 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
4685
4686 /* Store label index, if required. */
4687 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
4688 attr.label_index = bgp_static->label_index;
4689 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
4690 }
4691
4692 /* Apply route-map. */
4693 if (bgp_static->rmap.name) {
4694 struct attr attr_tmp = attr;
4695
4696 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
4697 rmap_path.peer = bgp->peer_self;
4698 rmap_path.attr = &attr_tmp;
4699
4700 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
4701
4702 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
4703 &rmap_path);
4704
4705 bgp->peer_self->rmap_type = 0;
4706
4707 if (ret == RMAP_DENYMATCH) {
4708 /* Free uninterned attribute. */
4709 bgp_attr_flush(&attr_tmp);
4710
4711 /* Unintern original. */
4712 aspath_unintern(&attr.aspath);
4713 bgp_static_withdraw(bgp, p, afi, safi);
4714 return;
4715 }
4716
4717 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
4718 bgp_attr_add_gshut_community(&attr_tmp);
4719
4720 attr_new = bgp_attr_intern(&attr_tmp);
4721 } else {
4722
4723 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
4724 bgp_attr_add_gshut_community(&attr);
4725
4726 attr_new = bgp_attr_intern(&attr);
4727 }
4728
4729 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4730 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4731 && pi->sub_type == BGP_ROUTE_STATIC)
4732 break;
4733
4734 if (pi) {
4735 if (attrhash_cmp(pi->attr, attr_new)
4736 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4737 && !bgp_flag_check(bgp, BGP_FLAG_FORCE_STATIC_PROCESS)) {
4738 bgp_unlock_node(rn);
4739 bgp_attr_unintern(&attr_new);
4740 aspath_unintern(&attr.aspath);
4741 return;
4742 } else {
4743 /* The attribute is changed. */
4744 bgp_path_info_set_flag(rn, pi, BGP_PATH_ATTR_CHANGED);
4745
4746 /* Rewrite BGP route information. */
4747 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
4748 bgp_path_info_restore(rn, pi);
4749 else
4750 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4751 #if ENABLE_BGP_VNC
4752 if ((afi == AFI_IP || afi == AFI_IP6)
4753 && (safi == SAFI_UNICAST)) {
4754 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4755 /*
4756 * Implicit withdraw case.
4757 * We have to do this before pi is
4758 * changed
4759 */
4760 ++vnc_implicit_withdraw;
4761 vnc_import_bgp_del_route(bgp, p, pi);
4762 vnc_import_bgp_exterior_del_route(
4763 bgp, p, pi);
4764 }
4765 }
4766 #endif
4767 bgp_attr_unintern(&pi->attr);
4768 pi->attr = attr_new;
4769 pi->uptime = bgp_clock();
4770 #if ENABLE_BGP_VNC
4771 if ((afi == AFI_IP || afi == AFI_IP6)
4772 && (safi == SAFI_UNICAST)) {
4773 if (vnc_implicit_withdraw) {
4774 vnc_import_bgp_add_route(bgp, p, pi);
4775 vnc_import_bgp_exterior_add_route(
4776 bgp, p, pi);
4777 }
4778 }
4779 #endif
4780
4781 /* Nexthop reachability check. */
4782 if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
4783 && (safi == SAFI_UNICAST
4784 || safi == SAFI_LABELED_UNICAST)) {
4785
4786 struct bgp *bgp_nexthop = bgp;
4787
4788 if (pi->extra && pi->extra->bgp_orig)
4789 bgp_nexthop = pi->extra->bgp_orig;
4790
4791 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
4792 afi, pi, NULL, 0))
4793 bgp_path_info_set_flag(rn, pi,
4794 BGP_PATH_VALID);
4795 else {
4796 if (BGP_DEBUG(nht, NHT)) {
4797 char buf1[INET6_ADDRSTRLEN];
4798 inet_ntop(p->family,
4799 &p->u.prefix, buf1,
4800 INET6_ADDRSTRLEN);
4801 zlog_debug(
4802 "%s(%s): Route not in table, not advertising",
4803 __FUNCTION__, buf1);
4804 }
4805 bgp_path_info_unset_flag(
4806 rn, pi, BGP_PATH_VALID);
4807 }
4808 } else {
4809 /* Delete the NHT structure if any, if we're
4810 * toggling between
4811 * enabling/disabling import check. We
4812 * deregister the route
4813 * from NHT to avoid overloading NHT and the
4814 * process interaction
4815 */
4816 bgp_unlink_nexthop(pi);
4817 bgp_path_info_set_flag(rn, pi, BGP_PATH_VALID);
4818 }
4819 /* Process change. */
4820 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4821 bgp_process(bgp, rn, afi, safi);
4822
4823 if (SAFI_UNICAST == safi
4824 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4825 || bgp->inst_type
4826 == BGP_INSTANCE_TYPE_DEFAULT)) {
4827 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
4828 pi);
4829 }
4830
4831 bgp_unlock_node(rn);
4832 aspath_unintern(&attr.aspath);
4833 return;
4834 }
4835 }
4836
4837 /* Make new BGP info. */
4838 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
4839 attr_new, rn);
4840 /* Nexthop reachability check. */
4841 if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
4842 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
4843 if (bgp_find_or_add_nexthop(bgp, bgp, afi, new, NULL, 0))
4844 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
4845 else {
4846 if (BGP_DEBUG(nht, NHT)) {
4847 char buf1[INET6_ADDRSTRLEN];
4848 inet_ntop(p->family, &p->u.prefix, buf1,
4849 INET6_ADDRSTRLEN);
4850 zlog_debug(
4851 "%s(%s): Route not in table, not advertising",
4852 __FUNCTION__, buf1);
4853 }
4854 bgp_path_info_unset_flag(rn, new, BGP_PATH_VALID);
4855 }
4856 } else {
4857 /* Delete the NHT structure if any, if we're toggling between
4858 * enabling/disabling import check. We deregister the route
4859 * from NHT to avoid overloading NHT and the process interaction
4860 */
4861 bgp_unlink_nexthop(new);
4862
4863 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
4864 }
4865
4866 /* Aggregate address increment. */
4867 bgp_aggregate_increment(bgp, p, new, afi, safi);
4868
4869 /* Register new BGP information. */
4870 bgp_path_info_add(rn, new);
4871
4872 /* route_node_get lock */
4873 bgp_unlock_node(rn);
4874
4875 /* Process change. */
4876 bgp_process(bgp, rn, afi, safi);
4877
4878 if (SAFI_UNICAST == safi
4879 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4880 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4881 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4882 }
4883
4884 /* Unintern original. */
4885 aspath_unintern(&attr.aspath);
4886 }
4887
4888 void bgp_static_withdraw(struct bgp *bgp, struct prefix *p, afi_t afi,
4889 safi_t safi)
4890 {
4891 struct bgp_node *rn;
4892 struct bgp_path_info *pi;
4893
4894 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
4895
4896 /* Check selected route and self inserted route. */
4897 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4898 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4899 && pi->sub_type == BGP_ROUTE_STATIC)
4900 break;
4901
4902 /* Withdraw static BGP route from routing table. */
4903 if (pi) {
4904 if (SAFI_UNICAST == safi
4905 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4906 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4907 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4908 }
4909 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4910 bgp_unlink_nexthop(pi);
4911 bgp_path_info_delete(rn, pi);
4912 bgp_process(bgp, rn, afi, safi);
4913 }
4914
4915 /* Unlock bgp_node_lookup. */
4916 bgp_unlock_node(rn);
4917 }
4918
4919 /*
4920 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4921 */
4922 static void bgp_static_withdraw_safi(struct bgp *bgp, struct prefix *p,
4923 afi_t afi, safi_t safi,
4924 struct prefix_rd *prd)
4925 {
4926 struct bgp_node *rn;
4927 struct bgp_path_info *pi;
4928
4929 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4930
4931 /* Check selected route and self inserted route. */
4932 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4933 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4934 && pi->sub_type == BGP_ROUTE_STATIC)
4935 break;
4936
4937 /* Withdraw static BGP route from routing table. */
4938 if (pi) {
4939 #if ENABLE_BGP_VNC
4940 rfapiProcessWithdraw(
4941 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
4942 1); /* Kill, since it is an administrative change */
4943 #endif
4944 if (SAFI_MPLS_VPN == safi
4945 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4946 vpn_leak_to_vrf_withdraw(bgp, pi);
4947 }
4948 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4949 bgp_path_info_delete(rn, pi);
4950 bgp_process(bgp, rn, afi, safi);
4951 }
4952
4953 /* Unlock bgp_node_lookup. */
4954 bgp_unlock_node(rn);
4955 }
4956
4957 static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p,
4958 struct bgp_static *bgp_static, afi_t afi,
4959 safi_t safi)
4960 {
4961 struct bgp_node *rn;
4962 struct bgp_path_info *new;
4963 struct attr *attr_new;
4964 struct attr attr = {0};
4965 struct bgp_path_info *pi;
4966 #if ENABLE_BGP_VNC
4967 mpls_label_t label = 0;
4968 #endif
4969 uint32_t num_labels = 0;
4970 union gw_addr add;
4971
4972 assert(bgp_static);
4973
4974 if (bgp_static->label != MPLS_INVALID_LABEL)
4975 num_labels = 1;
4976 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
4977 &bgp_static->prd);
4978
4979 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
4980
4981 attr.nexthop = bgp_static->igpnexthop;
4982 attr.med = bgp_static->igpmetric;
4983 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
4984
4985 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
4986 || (safi == SAFI_ENCAP)) {
4987 if (afi == AFI_IP) {
4988 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
4989 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
4990 }
4991 }
4992 if (afi == AFI_L2VPN) {
4993 if (bgp_static->gatewayIp.family == AF_INET)
4994 add.ipv4.s_addr =
4995 bgp_static->gatewayIp.u.prefix4.s_addr;
4996 else if (bgp_static->gatewayIp.family == AF_INET6)
4997 memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
4998 sizeof(struct in6_addr));
4999 overlay_index_update(&attr, bgp_static->eth_s_id, &add);
5000 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
5001 struct bgp_encap_type_vxlan bet;
5002 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
5003 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
5004 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
5005 }
5006 if (bgp_static->router_mac) {
5007 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
5008 }
5009 }
5010 /* Apply route-map. */
5011 if (bgp_static->rmap.name) {
5012 struct attr attr_tmp = attr;
5013 struct bgp_path_info rmap_path;
5014 route_map_result_t ret;
5015
5016 rmap_path.peer = bgp->peer_self;
5017 rmap_path.attr = &attr_tmp;
5018
5019 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5020
5021 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
5022 &rmap_path);
5023
5024 bgp->peer_self->rmap_type = 0;
5025
5026 if (ret == RMAP_DENYMATCH) {
5027 /* Free uninterned attribute. */
5028 bgp_attr_flush(&attr_tmp);
5029
5030 /* Unintern original. */
5031 aspath_unintern(&attr.aspath);
5032 bgp_static_withdraw_safi(bgp, p, afi, safi,
5033 &bgp_static->prd);
5034 return;
5035 }
5036
5037 attr_new = bgp_attr_intern(&attr_tmp);
5038 } else {
5039 attr_new = bgp_attr_intern(&attr);
5040 }
5041
5042 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
5043 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5044 && pi->sub_type == BGP_ROUTE_STATIC)
5045 break;
5046
5047 if (pi) {
5048 memset(&add, 0, sizeof(union gw_addr));
5049 if (attrhash_cmp(pi->attr, attr_new)
5050 && overlay_index_equal(afi, pi, bgp_static->eth_s_id, &add)
5051 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
5052 bgp_unlock_node(rn);
5053 bgp_attr_unintern(&attr_new);
5054 aspath_unintern(&attr.aspath);
5055 return;
5056 } else {
5057 /* The attribute is changed. */
5058 bgp_path_info_set_flag(rn, pi, BGP_PATH_ATTR_CHANGED);
5059
5060 /* Rewrite BGP route information. */
5061 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5062 bgp_path_info_restore(rn, pi);
5063 else
5064 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5065 bgp_attr_unintern(&pi->attr);
5066 pi->attr = attr_new;
5067 pi->uptime = bgp_clock();
5068 #if ENABLE_BGP_VNC
5069 if (pi->extra)
5070 label = decode_label(&pi->extra->label[0]);
5071 #endif
5072
5073 /* Process change. */
5074 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5075 bgp_process(bgp, rn, afi, safi);
5076
5077 if (SAFI_MPLS_VPN == safi
5078 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5079 vpn_leak_to_vrf_update(bgp, pi);
5080 }
5081 #if ENABLE_BGP_VNC
5082 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
5083 pi->attr, afi, safi, pi->type,
5084 pi->sub_type, &label);
5085 #endif
5086 bgp_unlock_node(rn);
5087 aspath_unintern(&attr.aspath);
5088 return;
5089 }
5090 }
5091
5092
5093 /* Make new BGP info. */
5094 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5095 attr_new, rn);
5096 SET_FLAG(new->flags, BGP_PATH_VALID);
5097 new->extra = bgp_path_info_extra_new();
5098 if (num_labels) {
5099 new->extra->label[0] = bgp_static->label;
5100 new->extra->num_labels = num_labels;
5101 }
5102 #if ENABLE_BGP_VNC
5103 label = decode_label(&bgp_static->label);
5104 #endif
5105
5106 /* Aggregate address increment. */
5107 bgp_aggregate_increment(bgp, p, new, afi, safi);
5108
5109 /* Register new BGP information. */
5110 bgp_path_info_add(rn, new);
5111 /* route_node_get lock */
5112 bgp_unlock_node(rn);
5113
5114 /* Process change. */
5115 bgp_process(bgp, rn, afi, safi);
5116
5117 if (SAFI_MPLS_VPN == safi
5118 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5119 vpn_leak_to_vrf_update(bgp, new);
5120 }
5121 #if ENABLE_BGP_VNC
5122 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
5123 safi, new->type, new->sub_type, &label);
5124 #endif
5125
5126 /* Unintern original. */
5127 aspath_unintern(&attr.aspath);
5128 }
5129
5130 /* Configure static BGP network. When user don't run zebra, static
5131 route should be installed as valid. */
5132 static int bgp_static_set(struct vty *vty, const char *negate,
5133 const char *ip_str, afi_t afi, safi_t safi,
5134 const char *rmap, int backdoor, uint32_t label_index)
5135 {
5136 VTY_DECLVAR_CONTEXT(bgp, bgp);
5137 int ret;
5138 struct prefix p;
5139 struct bgp_static *bgp_static;
5140 struct bgp_node *rn;
5141 uint8_t need_update = 0;
5142
5143 /* Convert IP prefix string to struct prefix. */
5144 ret = str2prefix(ip_str, &p);
5145 if (!ret) {
5146 vty_out(vty, "%% Malformed prefix\n");
5147 return CMD_WARNING_CONFIG_FAILED;
5148 }
5149 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
5150 vty_out(vty, "%% Malformed prefix (link-local address)\n");
5151 return CMD_WARNING_CONFIG_FAILED;
5152 }
5153
5154 apply_mask(&p);
5155
5156 if (negate) {
5157
5158 /* Set BGP static route configuration. */
5159 rn = bgp_node_lookup(bgp->route[afi][safi], &p);
5160
5161 if (!rn) {
5162 vty_out(vty, "%% Can't find static route specified\n");
5163 return CMD_WARNING_CONFIG_FAILED;
5164 }
5165
5166 bgp_static = bgp_node_get_bgp_static_info(rn);
5167
5168 if ((label_index != BGP_INVALID_LABEL_INDEX)
5169 && (label_index != bgp_static->label_index)) {
5170 vty_out(vty,
5171 "%% label-index doesn't match static route\n");
5172 return CMD_WARNING_CONFIG_FAILED;
5173 }
5174
5175 if ((rmap && bgp_static->rmap.name)
5176 && strcmp(rmap, bgp_static->rmap.name)) {
5177 vty_out(vty,
5178 "%% route-map name doesn't match static route\n");
5179 return CMD_WARNING_CONFIG_FAILED;
5180 }
5181
5182 /* Update BGP RIB. */
5183 if (!bgp_static->backdoor)
5184 bgp_static_withdraw(bgp, &p, afi, safi);
5185
5186 /* Clear configuration. */
5187 bgp_static_free(bgp_static);
5188 bgp_node_set_bgp_static_info(rn, NULL);
5189 bgp_unlock_node(rn);
5190 bgp_unlock_node(rn);
5191 } else {
5192
5193 /* Set BGP static route configuration. */
5194 rn = bgp_node_get(bgp->route[afi][safi], &p);
5195
5196 bgp_static = bgp_node_get_bgp_static_info(rn);
5197 if (bgp_static) {
5198 /* Configuration change. */
5199 /* Label index cannot be changed. */
5200 if (bgp_static->label_index != label_index) {
5201 vty_out(vty, "%% cannot change label-index\n");
5202 return CMD_WARNING_CONFIG_FAILED;
5203 }
5204
5205 /* Check previous routes are installed into BGP. */
5206 if (bgp_static->valid
5207 && bgp_static->backdoor != backdoor)
5208 need_update = 1;
5209
5210 bgp_static->backdoor = backdoor;
5211
5212 if (rmap) {
5213 XFREE(MTYPE_ROUTE_MAP_NAME,
5214 bgp_static->rmap.name);
5215 route_map_counter_decrement(
5216 bgp_static->rmap.map);
5217 bgp_static->rmap.name =
5218 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5219 bgp_static->rmap.map =
5220 route_map_lookup_by_name(rmap);
5221 route_map_counter_increment(
5222 bgp_static->rmap.map);
5223 } else {
5224 XFREE(MTYPE_ROUTE_MAP_NAME,
5225 bgp_static->rmap.name);
5226 route_map_counter_decrement(
5227 bgp_static->rmap.map);
5228 bgp_static->rmap.name = NULL;
5229 bgp_static->rmap.map = NULL;
5230 bgp_static->valid = 0;
5231 }
5232 bgp_unlock_node(rn);
5233 } else {
5234 /* New configuration. */
5235 bgp_static = bgp_static_new();
5236 bgp_static->backdoor = backdoor;
5237 bgp_static->valid = 0;
5238 bgp_static->igpmetric = 0;
5239 bgp_static->igpnexthop.s_addr = 0;
5240 bgp_static->label_index = label_index;
5241
5242 if (rmap) {
5243 XFREE(MTYPE_ROUTE_MAP_NAME,
5244 bgp_static->rmap.name);
5245 route_map_counter_decrement(
5246 bgp_static->rmap.map);
5247 bgp_static->rmap.name =
5248 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5249 bgp_static->rmap.map =
5250 route_map_lookup_by_name(rmap);
5251 route_map_counter_increment(
5252 bgp_static->rmap.map);
5253 }
5254 bgp_node_set_bgp_static_info(rn, bgp_static);
5255 }
5256
5257 bgp_static->valid = 1;
5258 if (need_update)
5259 bgp_static_withdraw(bgp, &p, afi, safi);
5260
5261 if (!bgp_static->backdoor)
5262 bgp_static_update(bgp, &p, bgp_static, afi, safi);
5263 }
5264
5265 return CMD_SUCCESS;
5266 }
5267
5268 void bgp_static_add(struct bgp *bgp)
5269 {
5270 afi_t afi;
5271 safi_t safi;
5272 struct bgp_node *rn;
5273 struct bgp_node *rm;
5274 struct bgp_table *table;
5275 struct bgp_static *bgp_static;
5276
5277 FOREACH_AFI_SAFI (afi, safi)
5278 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5279 rn = bgp_route_next(rn)) {
5280 if (!bgp_node_has_bgp_path_info_data(rn))
5281 continue;
5282
5283 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5284 || (safi == SAFI_EVPN)) {
5285 table = bgp_node_get_bgp_table_info(rn);
5286
5287 for (rm = bgp_table_top(table); rm;
5288 rm = bgp_route_next(rm)) {
5289 bgp_static =
5290 bgp_node_get_bgp_static_info(
5291 rm);
5292 bgp_static_update_safi(bgp, &rm->p,
5293 bgp_static, afi,
5294 safi);
5295 }
5296 } else {
5297 bgp_static_update(
5298 bgp, &rn->p,
5299 bgp_node_get_bgp_static_info(rn), afi,
5300 safi);
5301 }
5302 }
5303 }
5304
5305 /* Called from bgp_delete(). Delete all static routes from the BGP
5306 instance. */
5307 void bgp_static_delete(struct bgp *bgp)
5308 {
5309 afi_t afi;
5310 safi_t safi;
5311 struct bgp_node *rn;
5312 struct bgp_node *rm;
5313 struct bgp_table *table;
5314 struct bgp_static *bgp_static;
5315
5316 FOREACH_AFI_SAFI (afi, safi)
5317 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5318 rn = bgp_route_next(rn)) {
5319 if (!bgp_node_has_bgp_path_info_data(rn))
5320 continue;
5321
5322 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5323 || (safi == SAFI_EVPN)) {
5324 table = bgp_node_get_bgp_table_info(rn);
5325
5326 for (rm = bgp_table_top(table); rm;
5327 rm = bgp_route_next(rm)) {
5328 bgp_static =
5329 bgp_node_get_bgp_static_info(
5330 rm);
5331 if (!bgp_static)
5332 continue;
5333
5334 bgp_static_withdraw_safi(
5335 bgp, &rm->p, AFI_IP, safi,
5336 (struct prefix_rd *)&rn->p);
5337 bgp_static_free(bgp_static);
5338 bgp_node_set_bgp_static_info(rn, NULL);
5339 bgp_unlock_node(rn);
5340 }
5341 } else {
5342 bgp_static = bgp_node_get_bgp_static_info(rn);
5343 bgp_static_withdraw(bgp, &rn->p, afi, safi);
5344 bgp_static_free(bgp_static);
5345 bgp_node_set_bgp_static_info(rn, NULL);
5346 bgp_unlock_node(rn);
5347 }
5348 }
5349 }
5350
5351 void bgp_static_redo_import_check(struct bgp *bgp)
5352 {
5353 afi_t afi;
5354 safi_t safi;
5355 struct bgp_node *rn;
5356 struct bgp_node *rm;
5357 struct bgp_table *table;
5358 struct bgp_static *bgp_static;
5359
5360 /* Use this flag to force reprocessing of the route */
5361 bgp_flag_set(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
5362 FOREACH_AFI_SAFI (afi, safi) {
5363 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5364 rn = bgp_route_next(rn)) {
5365 if (!bgp_node_has_bgp_path_info_data(rn))
5366 continue;
5367
5368 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5369 || (safi == SAFI_EVPN)) {
5370 table = bgp_node_get_bgp_table_info(rn);
5371
5372 for (rm = bgp_table_top(table); rm;
5373 rm = bgp_route_next(rm)) {
5374 bgp_static =
5375 bgp_node_get_bgp_static_info(
5376 rm);
5377 bgp_static_update_safi(bgp, &rm->p,
5378 bgp_static, afi,
5379 safi);
5380 }
5381 } else {
5382 bgp_static = bgp_node_get_bgp_static_info(rn);
5383 bgp_static_update(bgp, &rn->p, bgp_static, afi,
5384 safi);
5385 }
5386 }
5387 }
5388 bgp_flag_unset(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
5389 }
5390
5391 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
5392 safi_t safi)
5393 {
5394 struct bgp_table *table;
5395 struct bgp_node *rn;
5396 struct bgp_path_info *pi;
5397
5398 /* Do not install the aggregate route if BGP is in the
5399 * process of termination.
5400 */
5401 if (bgp_flag_check(bgp, BGP_FLAG_DELETE_IN_PROGRESS) ||
5402 (bgp->peer_self == NULL))
5403 return;
5404
5405 table = bgp->rib[afi][safi];
5406 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
5407 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
5408 if (pi->peer == bgp->peer_self
5409 && ((pi->type == ZEBRA_ROUTE_BGP
5410 && pi->sub_type == BGP_ROUTE_STATIC)
5411 || (pi->type != ZEBRA_ROUTE_BGP
5412 && pi->sub_type
5413 == BGP_ROUTE_REDISTRIBUTE))) {
5414 bgp_aggregate_decrement(bgp, &rn->p, pi, afi,
5415 safi);
5416 bgp_unlink_nexthop(pi);
5417 bgp_path_info_delete(rn, pi);
5418 bgp_process(bgp, rn, afi, safi);
5419 }
5420 }
5421 }
5422 }
5423
5424 /*
5425 * Purge all networks and redistributed routes from routing table.
5426 * Invoked upon the instance going down.
5427 */
5428 void bgp_purge_static_redist_routes(struct bgp *bgp)
5429 {
5430 afi_t afi;
5431 safi_t safi;
5432
5433 FOREACH_AFI_SAFI (afi, safi)
5434 bgp_purge_af_static_redist_routes(bgp, afi, safi);
5435 }
5436
5437 /*
5438 * gpz 110624
5439 * Currently this is used to set static routes for VPN and ENCAP.
5440 * I think it can probably be factored with bgp_static_set.
5441 */
5442 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
5443 const char *ip_str, const char *rd_str,
5444 const char *label_str, const char *rmap_str,
5445 int evpn_type, const char *esi, const char *gwip,
5446 const char *ethtag, const char *routermac)
5447 {
5448 VTY_DECLVAR_CONTEXT(bgp, bgp);
5449 int ret;
5450 struct prefix p;
5451 struct prefix_rd prd;
5452 struct bgp_node *prn;
5453 struct bgp_node *rn;
5454 struct bgp_table *table;
5455 struct bgp_static *bgp_static;
5456 mpls_label_t label = MPLS_INVALID_LABEL;
5457 struct prefix gw_ip;
5458
5459 /* validate ip prefix */
5460 ret = str2prefix(ip_str, &p);
5461 if (!ret) {
5462 vty_out(vty, "%% Malformed prefix\n");
5463 return CMD_WARNING_CONFIG_FAILED;
5464 }
5465 apply_mask(&p);
5466 if ((afi == AFI_L2VPN)
5467 && (bgp_build_evpn_prefix(evpn_type,
5468 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5469 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5470 return CMD_WARNING_CONFIG_FAILED;
5471 }
5472
5473 ret = str2prefix_rd(rd_str, &prd);
5474 if (!ret) {
5475 vty_out(vty, "%% Malformed rd\n");
5476 return CMD_WARNING_CONFIG_FAILED;
5477 }
5478
5479 if (label_str) {
5480 unsigned long label_val;
5481 label_val = strtoul(label_str, NULL, 10);
5482 encode_label(label_val, &label);
5483 }
5484
5485 if (safi == SAFI_EVPN) {
5486 if (esi && str2esi(esi, NULL) == 0) {
5487 vty_out(vty, "%% Malformed ESI\n");
5488 return CMD_WARNING_CONFIG_FAILED;
5489 }
5490 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
5491 vty_out(vty, "%% Malformed Router MAC\n");
5492 return CMD_WARNING_CONFIG_FAILED;
5493 }
5494 if (gwip) {
5495 memset(&gw_ip, 0, sizeof(struct prefix));
5496 ret = str2prefix(gwip, &gw_ip);
5497 if (!ret) {
5498 vty_out(vty, "%% Malformed GatewayIp\n");
5499 return CMD_WARNING_CONFIG_FAILED;
5500 }
5501 if ((gw_ip.family == AF_INET
5502 && is_evpn_prefix_ipaddr_v6(
5503 (struct prefix_evpn *)&p))
5504 || (gw_ip.family == AF_INET6
5505 && is_evpn_prefix_ipaddr_v4(
5506 (struct prefix_evpn *)&p))) {
5507 vty_out(vty,
5508 "%% GatewayIp family differs with IP prefix\n");
5509 return CMD_WARNING_CONFIG_FAILED;
5510 }
5511 }
5512 }
5513 prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5514 if (!bgp_node_has_bgp_path_info_data(prn))
5515 bgp_node_set_bgp_table_info(prn,
5516 bgp_table_init(bgp, afi, safi));
5517 table = bgp_node_get_bgp_table_info(prn);
5518
5519 rn = bgp_node_get(table, &p);
5520
5521 if (bgp_node_has_bgp_path_info_data(rn)) {
5522 vty_out(vty, "%% Same network configuration exists\n");
5523 bgp_unlock_node(rn);
5524 } else {
5525 /* New configuration. */
5526 bgp_static = bgp_static_new();
5527 bgp_static->backdoor = 0;
5528 bgp_static->valid = 0;
5529 bgp_static->igpmetric = 0;
5530 bgp_static->igpnexthop.s_addr = 0;
5531 bgp_static->label = label;
5532 bgp_static->prd = prd;
5533
5534 if (rmap_str) {
5535 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5536 route_map_counter_decrement(bgp_static->rmap.map);
5537 bgp_static->rmap.name =
5538 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
5539 bgp_static->rmap.map =
5540 route_map_lookup_by_name(rmap_str);
5541 route_map_counter_increment(bgp_static->rmap.map);
5542 }
5543
5544 if (safi == SAFI_EVPN) {
5545 if (esi) {
5546 bgp_static->eth_s_id =
5547 XCALLOC(MTYPE_ATTR,
5548 sizeof(struct eth_segment_id));
5549 str2esi(esi, bgp_static->eth_s_id);
5550 }
5551 if (routermac) {
5552 bgp_static->router_mac =
5553 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
5554 (void)prefix_str2mac(routermac,
5555 bgp_static->router_mac);
5556 }
5557 if (gwip)
5558 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
5559 }
5560 bgp_node_set_bgp_static_info(rn, bgp_static);
5561
5562 bgp_static->valid = 1;
5563 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
5564 }
5565
5566 return CMD_SUCCESS;
5567 }
5568
5569 /* Configure static BGP network. */
5570 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
5571 const char *ip_str, const char *rd_str,
5572 const char *label_str, int evpn_type, const char *esi,
5573 const char *gwip, const char *ethtag)
5574 {
5575 VTY_DECLVAR_CONTEXT(bgp, bgp);
5576 int ret;
5577 struct prefix p;
5578 struct prefix_rd prd;
5579 struct bgp_node *prn;
5580 struct bgp_node *rn;
5581 struct bgp_table *table;
5582 struct bgp_static *bgp_static;
5583 mpls_label_t label = MPLS_INVALID_LABEL;
5584
5585 /* Convert IP prefix string to struct prefix. */
5586 ret = str2prefix(ip_str, &p);
5587 if (!ret) {
5588 vty_out(vty, "%% Malformed prefix\n");
5589 return CMD_WARNING_CONFIG_FAILED;
5590 }
5591 apply_mask(&p);
5592 if ((afi == AFI_L2VPN)
5593 && (bgp_build_evpn_prefix(evpn_type,
5594 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5595 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5596 return CMD_WARNING_CONFIG_FAILED;
5597 }
5598 ret = str2prefix_rd(rd_str, &prd);
5599 if (!ret) {
5600 vty_out(vty, "%% Malformed rd\n");
5601 return CMD_WARNING_CONFIG_FAILED;
5602 }
5603
5604 if (label_str) {
5605 unsigned long label_val;
5606 label_val = strtoul(label_str, NULL, 10);
5607 encode_label(label_val, &label);
5608 }
5609
5610 prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5611 if (!bgp_node_has_bgp_path_info_data(prn))
5612 bgp_node_set_bgp_table_info(prn,
5613 bgp_table_init(bgp, afi, safi));
5614 else
5615 bgp_unlock_node(prn);
5616 table = bgp_node_get_bgp_table_info(prn);
5617
5618 rn = bgp_node_lookup(table, &p);
5619
5620 if (rn) {
5621 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
5622
5623 bgp_static = bgp_node_get_bgp_static_info(rn);
5624 bgp_static_free(bgp_static);
5625 bgp_node_set_bgp_static_info(rn, NULL);
5626 bgp_unlock_node(rn);
5627 bgp_unlock_node(rn);
5628 } else
5629 vty_out(vty, "%% Can't find the route\n");
5630
5631 return CMD_SUCCESS;
5632 }
5633
5634 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
5635 const char *rmap_name)
5636 {
5637 VTY_DECLVAR_CONTEXT(bgp, bgp);
5638 struct bgp_rmap *rmap;
5639
5640 rmap = &bgp->table_map[afi][safi];
5641 if (rmap_name) {
5642 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5643 route_map_counter_decrement(rmap->map);
5644 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
5645 rmap->map = route_map_lookup_by_name(rmap_name);
5646 route_map_counter_increment(rmap->map);
5647 } else {
5648 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5649 route_map_counter_decrement(rmap->map);
5650 rmap->name = NULL;
5651 rmap->map = NULL;
5652 }
5653
5654 if (bgp_fibupd_safi(safi))
5655 bgp_zebra_announce_table(bgp, afi, safi);
5656
5657 return CMD_SUCCESS;
5658 }
5659
5660 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
5661 const char *rmap_name)
5662 {
5663 VTY_DECLVAR_CONTEXT(bgp, bgp);
5664 struct bgp_rmap *rmap;
5665
5666 rmap = &bgp->table_map[afi][safi];
5667 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5668 route_map_counter_decrement(rmap->map);
5669 rmap->name = NULL;
5670 rmap->map = NULL;
5671
5672 if (bgp_fibupd_safi(safi))
5673 bgp_zebra_announce_table(bgp, afi, safi);
5674
5675 return CMD_SUCCESS;
5676 }
5677
5678 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
5679 safi_t safi)
5680 {
5681 if (bgp->table_map[afi][safi].name) {
5682 vty_out(vty, " table-map %s\n",
5683 bgp->table_map[afi][safi].name);
5684 }
5685 }
5686
5687 DEFUN (bgp_table_map,
5688 bgp_table_map_cmd,
5689 "table-map WORD",
5690 "BGP table to RIB route download filter\n"
5691 "Name of the route map\n")
5692 {
5693 int idx_word = 1;
5694 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
5695 argv[idx_word]->arg);
5696 }
5697 DEFUN (no_bgp_table_map,
5698 no_bgp_table_map_cmd,
5699 "no table-map WORD",
5700 NO_STR
5701 "BGP table to RIB route download filter\n"
5702 "Name of the route map\n")
5703 {
5704 int idx_word = 2;
5705 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
5706 argv[idx_word]->arg);
5707 }
5708
5709 DEFPY(bgp_network,
5710 bgp_network_cmd,
5711 "[no] network \
5712 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
5713 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
5714 backdoor$backdoor}]",
5715 NO_STR
5716 "Specify a network to announce via BGP\n"
5717 "IPv4 prefix\n"
5718 "Network number\n"
5719 "Network mask\n"
5720 "Network mask\n"
5721 "Route-map to modify the attributes\n"
5722 "Name of the route map\n"
5723 "Label index to associate with the prefix\n"
5724 "Label index value\n"
5725 "Specify a BGP backdoor route\n")
5726 {
5727 char addr_prefix_str[BUFSIZ];
5728
5729 if (address_str) {
5730 int ret;
5731
5732 ret = netmask_str2prefix_str(address_str, netmask_str,
5733 addr_prefix_str);
5734 if (!ret) {
5735 vty_out(vty, "%% Inconsistent address and mask\n");
5736 return CMD_WARNING_CONFIG_FAILED;
5737 }
5738 }
5739
5740 return bgp_static_set(
5741 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
5742 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
5743 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
5744 }
5745
5746 DEFPY(ipv6_bgp_network,
5747 ipv6_bgp_network_cmd,
5748 "[no] network X:X::X:X/M$prefix \
5749 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
5750 NO_STR
5751 "Specify a network to announce via BGP\n"
5752 "IPv6 prefix\n"
5753 "Route-map to modify the attributes\n"
5754 "Name of the route map\n"
5755 "Label index to associate with the prefix\n"
5756 "Label index value\n")
5757 {
5758 return bgp_static_set(
5759 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
5760 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
5761 }
5762
5763 static struct bgp_aggregate *bgp_aggregate_new(void)
5764 {
5765 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
5766 }
5767
5768 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
5769 {
5770 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
5771 route_map_counter_decrement(aggregate->rmap.map);
5772 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
5773 }
5774
5775 static int bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
5776 struct aspath *aspath,
5777 struct community *comm,
5778 struct ecommunity *ecomm,
5779 struct lcommunity *lcomm)
5780 {
5781 static struct aspath *ae = NULL;
5782
5783 if (!ae)
5784 ae = aspath_empty();
5785
5786 if (!pi)
5787 return 0;
5788
5789 if (origin != pi->attr->origin)
5790 return 0;
5791
5792 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
5793 return 0;
5794
5795 if (!community_cmp(pi->attr->community, comm))
5796 return 0;
5797
5798 if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
5799 return 0;
5800
5801 if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
5802 return 0;
5803
5804 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
5805 return 0;
5806
5807 return 1;
5808 }
5809
5810 static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
5811 struct prefix *p, uint8_t origin,
5812 struct aspath *aspath,
5813 struct community *community,
5814 struct ecommunity *ecommunity,
5815 struct lcommunity *lcommunity,
5816 uint8_t atomic_aggregate,
5817 struct bgp_aggregate *aggregate)
5818 {
5819 struct bgp_node *rn;
5820 struct bgp_table *table;
5821 struct bgp_path_info *pi, *orig, *new;
5822 struct attr *attr;
5823
5824 table = bgp->rib[afi][safi];
5825
5826 rn = bgp_node_get(table, p);
5827
5828 for (orig = pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
5829 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5830 && pi->sub_type == BGP_ROUTE_AGGREGATE)
5831 break;
5832
5833 if (aggregate->count > 0) {
5834 /*
5835 * If the aggregate information has not changed
5836 * no need to re-install it again.
5837 */
5838 if (bgp_aggregate_info_same(orig, origin, aspath, community,
5839 ecommunity, lcommunity)) {
5840 bgp_unlock_node(rn);
5841
5842 if (aspath)
5843 aspath_free(aspath);
5844 if (community)
5845 community_free(&community);
5846 if (ecommunity)
5847 ecommunity_free(&ecommunity);
5848 if (lcommunity)
5849 lcommunity_free(&lcommunity);
5850
5851 return;
5852 }
5853
5854 /*
5855 * Mark the old as unusable
5856 */
5857 if (pi)
5858 bgp_path_info_delete(rn, pi);
5859
5860 attr = bgp_attr_aggregate_intern(
5861 bgp, origin, aspath, community, ecommunity, lcommunity,
5862 aggregate, atomic_aggregate, p);
5863
5864 if (!attr) {
5865 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
5866 return;
5867 }
5868
5869 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
5870 bgp->peer_self, attr, rn);
5871
5872 SET_FLAG(new->flags, BGP_PATH_VALID);
5873
5874 bgp_path_info_add(rn, new);
5875 bgp_process(bgp, rn, afi, safi);
5876 } else {
5877 for (pi = orig; pi; pi = pi->next)
5878 if (pi->peer == bgp->peer_self
5879 && pi->type == ZEBRA_ROUTE_BGP
5880 && pi->sub_type == BGP_ROUTE_AGGREGATE)
5881 break;
5882
5883 /* Withdraw static BGP route from routing table. */
5884 if (pi) {
5885 bgp_path_info_delete(rn, pi);
5886 bgp_process(bgp, rn, afi, safi);
5887 }
5888 }
5889
5890 bgp_unlock_node(rn);
5891 }
5892
5893 /* Update an aggregate as routes are added/removed from the BGP table */
5894 void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
5895 afi_t afi, safi_t safi,
5896 struct bgp_aggregate *aggregate)
5897 {
5898 struct bgp_table *table;
5899 struct bgp_node *top;
5900 struct bgp_node *rn;
5901 uint8_t origin;
5902 struct aspath *aspath = NULL;
5903 struct community *community = NULL;
5904 struct ecommunity *ecommunity = NULL;
5905 struct lcommunity *lcommunity = NULL;
5906 struct bgp_path_info *pi;
5907 unsigned long match = 0;
5908 uint8_t atomic_aggregate = 0;
5909
5910 /* If the bgp instance is being deleted or self peer is deleted
5911 * then do not create aggregate route
5912 */
5913 if (bgp_flag_check(bgp, BGP_FLAG_DELETE_IN_PROGRESS) ||
5914 (bgp->peer_self == NULL))
5915 return;
5916
5917 /* ORIGIN attribute: If at least one route among routes that are
5918 aggregated has ORIGIN with the value INCOMPLETE, then the
5919 aggregated route must have the ORIGIN attribute with the value
5920 INCOMPLETE. Otherwise, if at least one route among routes that
5921 are aggregated has ORIGIN with the value EGP, then the aggregated
5922 route must have the origin attribute with the value EGP. In all
5923 other case the value of the ORIGIN attribute of the aggregated
5924 route is INTERNAL. */
5925 origin = BGP_ORIGIN_IGP;
5926
5927 table = bgp->rib[afi][safi];
5928
5929 top = bgp_node_get(table, p);
5930 for (rn = bgp_node_get(table, p); rn;
5931 rn = bgp_route_next_until(rn, top)) {
5932 if (rn->p.prefixlen <= p->prefixlen)
5933 continue;
5934
5935 match = 0;
5936
5937 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
5938 if (BGP_PATH_HOLDDOWN(pi))
5939 continue;
5940
5941 if (pi->attr->flag
5942 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
5943 atomic_aggregate = 1;
5944
5945 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
5946 continue;
5947
5948 /*
5949 * summary-only aggregate route suppress
5950 * aggregated route announcements.
5951 */
5952 if (aggregate->summary_only) {
5953 (bgp_path_info_extra_get(pi))->suppress++;
5954 bgp_path_info_set_flag(rn, pi,
5955 BGP_PATH_ATTR_CHANGED);
5956 match++;
5957 }
5958
5959 aggregate->count++;
5960
5961 /*
5962 * If at least one route among routes that are
5963 * aggregated has ORIGIN with the value INCOMPLETE,
5964 * then the aggregated route MUST have the ORIGIN
5965 * attribute with the value INCOMPLETE. Otherwise, if
5966 * at least one route among routes that are aggregated
5967 * has ORIGIN with the value EGP, then the aggregated
5968 * route MUST have the ORIGIN attribute with the value
5969 * EGP.
5970 */
5971 switch (pi->attr->origin) {
5972 case BGP_ORIGIN_INCOMPLETE:
5973 aggregate->incomplete_origin_count++;
5974 break;
5975 case BGP_ORIGIN_EGP:
5976 aggregate->egp_origin_count++;
5977 break;
5978 default:
5979 /*Do nothing.
5980 */
5981 break;
5982 }
5983
5984 if (!aggregate->as_set)
5985 continue;
5986
5987 /*
5988 * as-set aggregate route generate origin, as path,
5989 * and community aggregation.
5990 */
5991 /* Compute aggregate route's as-path.
5992 */
5993 bgp_compute_aggregate_aspath_hash(aggregate,
5994 pi->attr->aspath);
5995
5996 /* Compute aggregate route's community.
5997 */
5998 if (pi->attr->community)
5999 bgp_compute_aggregate_community_hash(
6000 aggregate,
6001 pi->attr->community);
6002
6003 /* Compute aggregate route's extended community.
6004 */
6005 if (pi->attr->ecommunity)
6006 bgp_compute_aggregate_ecommunity_hash(
6007 aggregate,
6008 pi->attr->ecommunity);
6009
6010 /* Compute aggregate route's large community.
6011 */
6012 if (pi->attr->lcommunity)
6013 bgp_compute_aggregate_lcommunity_hash(
6014 aggregate,
6015 pi->attr->lcommunity);
6016 }
6017 if (match)
6018 bgp_process(bgp, rn, afi, safi);
6019 }
6020 if (aggregate->as_set) {
6021 bgp_compute_aggregate_aspath_val(aggregate);
6022 bgp_compute_aggregate_community_val(aggregate);
6023 bgp_compute_aggregate_ecommunity_val(aggregate);
6024 bgp_compute_aggregate_lcommunity_val(aggregate);
6025 }
6026
6027
6028 bgp_unlock_node(top);
6029
6030
6031 if (aggregate->incomplete_origin_count > 0)
6032 origin = BGP_ORIGIN_INCOMPLETE;
6033 else if (aggregate->egp_origin_count > 0)
6034 origin = BGP_ORIGIN_EGP;
6035
6036 if (aggregate->as_set) {
6037 if (aggregate->aspath)
6038 /* Retrieve aggregate route's as-path.
6039 */
6040 aspath = aspath_dup(aggregate->aspath);
6041
6042 if (aggregate->community)
6043 /* Retrieve aggregate route's community.
6044 */
6045 community = community_dup(aggregate->community);
6046
6047 if (aggregate->ecommunity)
6048 /* Retrieve aggregate route's ecommunity.
6049 */
6050 ecommunity = ecommunity_dup(aggregate->ecommunity);
6051
6052 if (aggregate->lcommunity)
6053 /* Retrieve aggregate route's lcommunity.
6054 */
6055 lcommunity = lcommunity_dup(aggregate->lcommunity);
6056 }
6057
6058 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
6059 ecommunity, lcommunity, atomic_aggregate,
6060 aggregate);
6061 }
6062
6063 void bgp_aggregate_delete(struct bgp *bgp, struct prefix *p, afi_t afi,
6064 safi_t safi, struct bgp_aggregate *aggregate)
6065 {
6066 struct bgp_table *table;
6067 struct bgp_node *top;
6068 struct bgp_node *rn;
6069 struct bgp_path_info *pi;
6070 unsigned long match;
6071
6072 table = bgp->rib[afi][safi];
6073
6074 /* If routes exists below this node, generate aggregate routes. */
6075 top = bgp_node_get(table, p);
6076 for (rn = bgp_node_get(table, p); rn;
6077 rn = bgp_route_next_until(rn, top)) {
6078 if (rn->p.prefixlen <= p->prefixlen)
6079 continue;
6080 match = 0;
6081
6082 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
6083 if (BGP_PATH_HOLDDOWN(pi))
6084 continue;
6085
6086 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6087 continue;
6088
6089 if (aggregate->summary_only && pi->extra) {
6090 pi->extra->suppress--;
6091
6092 if (pi->extra->suppress == 0) {
6093 bgp_path_info_set_flag(
6094 rn, pi, BGP_PATH_ATTR_CHANGED);
6095 match++;
6096 }
6097 }
6098 aggregate->count--;
6099
6100 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
6101 aggregate->incomplete_origin_count--;
6102 else if (pi->attr->origin == BGP_ORIGIN_EGP)
6103 aggregate->egp_origin_count--;
6104
6105 if (aggregate->as_set) {
6106 /* Remove as-path from aggregate.
6107 */
6108 bgp_remove_aspath_from_aggregate_hash(
6109 aggregate,
6110 pi->attr->aspath);
6111
6112 if (pi->attr->community)
6113 /* Remove community from aggregate.
6114 */
6115 bgp_remove_comm_from_aggregate_hash(
6116 aggregate,
6117 pi->attr->community);
6118
6119 if (pi->attr->ecommunity)
6120 /* Remove ecommunity from aggregate.
6121 */
6122 bgp_remove_ecomm_from_aggregate_hash(
6123 aggregate,
6124 pi->attr->ecommunity);
6125
6126 if (pi->attr->lcommunity)
6127 /* Remove lcommunity from aggregate.
6128 */
6129 bgp_remove_lcomm_from_aggregate_hash(
6130 aggregate,
6131 pi->attr->lcommunity);
6132 }
6133
6134 }
6135
6136 /* If this node was suppressed, process the change. */
6137 if (match)
6138 bgp_process(bgp, rn, afi, safi);
6139 }
6140 if (aggregate->as_set) {
6141 aspath_free(aggregate->aspath);
6142 aggregate->aspath = NULL;
6143 if (aggregate->community)
6144 community_free(&aggregate->community);
6145 if (aggregate->ecommunity)
6146 ecommunity_free(&aggregate->ecommunity);
6147 if (aggregate->lcommunity)
6148 lcommunity_free(&aggregate->lcommunity);
6149 }
6150
6151 bgp_unlock_node(top);
6152 }
6153
6154 static void bgp_add_route_to_aggregate(struct bgp *bgp, struct prefix *aggr_p,
6155 struct bgp_path_info *pinew, afi_t afi,
6156 safi_t safi,
6157 struct bgp_aggregate *aggregate)
6158 {
6159 uint8_t origin;
6160 struct aspath *aspath = NULL;
6161 uint8_t atomic_aggregate = 0;
6162 struct community *community = NULL;
6163 struct ecommunity *ecommunity = NULL;
6164 struct lcommunity *lcommunity = NULL;
6165
6166 /* ORIGIN attribute: If at least one route among routes that are
6167 * aggregated has ORIGIN with the value INCOMPLETE, then the
6168 * aggregated route must have the ORIGIN attribute with the value
6169 * INCOMPLETE. Otherwise, if at least one route among routes that
6170 * are aggregated has ORIGIN with the value EGP, then the aggregated
6171 * route must have the origin attribute with the value EGP. In all
6172 * other case the value of the ORIGIN attribute of the aggregated
6173 * route is INTERNAL.
6174 */
6175 origin = BGP_ORIGIN_IGP;
6176
6177 aggregate->count++;
6178
6179 if (aggregate->summary_only)
6180 (bgp_path_info_extra_get(pinew))->suppress++;
6181
6182 switch (pinew->attr->origin) {
6183 case BGP_ORIGIN_INCOMPLETE:
6184 aggregate->incomplete_origin_count++;
6185 break;
6186 case BGP_ORIGIN_EGP:
6187 aggregate->egp_origin_count++;
6188 break;
6189 default:
6190 /* Do nothing.
6191 */
6192 break;
6193 }
6194
6195 if (aggregate->incomplete_origin_count > 0)
6196 origin = BGP_ORIGIN_INCOMPLETE;
6197 else if (aggregate->egp_origin_count > 0)
6198 origin = BGP_ORIGIN_EGP;
6199
6200 if (aggregate->as_set) {
6201 /* Compute aggregate route's as-path.
6202 */
6203 bgp_compute_aggregate_aspath(aggregate,
6204 pinew->attr->aspath);
6205
6206 /* Compute aggregate route's community.
6207 */
6208 if (pinew->attr->community)
6209 bgp_compute_aggregate_community(
6210 aggregate,
6211 pinew->attr->community);
6212
6213 /* Compute aggregate route's extended community.
6214 */
6215 if (pinew->attr->ecommunity)
6216 bgp_compute_aggregate_ecommunity(
6217 aggregate,
6218 pinew->attr->ecommunity);
6219
6220 /* Compute aggregate route's large community.
6221 */
6222 if (pinew->attr->lcommunity)
6223 bgp_compute_aggregate_lcommunity(
6224 aggregate,
6225 pinew->attr->lcommunity);
6226
6227 /* Retrieve aggregate route's as-path.
6228 */
6229 if (aggregate->aspath)
6230 aspath = aspath_dup(aggregate->aspath);
6231
6232 /* Retrieve aggregate route's community.
6233 */
6234 if (aggregate->community)
6235 community = community_dup(aggregate->community);
6236
6237 /* Retrieve aggregate route's ecommunity.
6238 */
6239 if (aggregate->ecommunity)
6240 ecommunity = ecommunity_dup(aggregate->ecommunity);
6241
6242 /* Retrieve aggregate route's lcommunity.
6243 */
6244 if (aggregate->lcommunity)
6245 lcommunity = lcommunity_dup(aggregate->lcommunity);
6246 }
6247
6248 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
6249 aspath, community, ecommunity,
6250 lcommunity, atomic_aggregate, aggregate);
6251 }
6252
6253 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
6254 safi_t safi,
6255 struct bgp_path_info *pi,
6256 struct bgp_aggregate *aggregate,
6257 struct prefix *aggr_p)
6258 {
6259 uint8_t origin;
6260 struct aspath *aspath = NULL;
6261 uint8_t atomic_aggregate = 0;
6262 struct community *community = NULL;
6263 struct ecommunity *ecommunity = NULL;
6264 struct lcommunity *lcommunity = NULL;
6265 unsigned long match = 0;
6266
6267 if (BGP_PATH_HOLDDOWN(pi))
6268 return;
6269
6270 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6271 return;
6272
6273 if (aggregate->summary_only
6274 && pi->extra
6275 && pi->extra->suppress > 0) {
6276 pi->extra->suppress--;
6277
6278 if (pi->extra->suppress == 0) {
6279 bgp_path_info_set_flag(pi->net, pi,
6280 BGP_PATH_ATTR_CHANGED);
6281 match++;
6282 }
6283 }
6284
6285 if (aggregate->count > 0)
6286 aggregate->count--;
6287
6288 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
6289 aggregate->incomplete_origin_count--;
6290 else if (pi->attr->origin == BGP_ORIGIN_EGP)
6291 aggregate->egp_origin_count--;
6292
6293 if (aggregate->as_set) {
6294 /* Remove as-path from aggregate.
6295 */
6296 bgp_remove_aspath_from_aggregate(aggregate,
6297 pi->attr->aspath);
6298
6299 if (pi->attr->community)
6300 /* Remove community from aggregate.
6301 */
6302 bgp_remove_community_from_aggregate(
6303 aggregate,
6304 pi->attr->community);
6305
6306 if (pi->attr->ecommunity)
6307 /* Remove ecommunity from aggregate.
6308 */
6309 bgp_remove_ecommunity_from_aggregate(
6310 aggregate,
6311 pi->attr->ecommunity);
6312
6313 if (pi->attr->lcommunity)
6314 /* Remove lcommunity from aggregate.
6315 */
6316 bgp_remove_lcommunity_from_aggregate(
6317 aggregate,
6318 pi->attr->lcommunity);
6319 }
6320
6321 /* If this node was suppressed, process the change. */
6322 if (match)
6323 bgp_process(bgp, pi->net, afi, safi);
6324
6325 origin = BGP_ORIGIN_IGP;
6326 if (aggregate->incomplete_origin_count > 0)
6327 origin = BGP_ORIGIN_INCOMPLETE;
6328 else if (aggregate->egp_origin_count > 0)
6329 origin = BGP_ORIGIN_EGP;
6330
6331 if (aggregate->as_set) {
6332 /* Retrieve aggregate route's as-path.
6333 */
6334 if (aggregate->aspath)
6335 aspath = aspath_dup(aggregate->aspath);
6336
6337 /* Retrieve aggregate route's community.
6338 */
6339 if (aggregate->community)
6340 community = community_dup(aggregate->community);
6341
6342 /* Retrieve aggregate route's ecommunity.
6343 */
6344 if (aggregate->ecommunity)
6345 ecommunity = ecommunity_dup(aggregate->ecommunity);
6346
6347 /* Retrieve aggregate route's lcommunity.
6348 */
6349 if (aggregate->lcommunity)
6350 lcommunity = lcommunity_dup(aggregate->lcommunity);
6351 }
6352
6353 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
6354 aspath, community, ecommunity,
6355 lcommunity, atomic_aggregate, aggregate);
6356 }
6357
6358 void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p,
6359 struct bgp_path_info *pi, afi_t afi, safi_t safi)
6360 {
6361 struct bgp_node *child;
6362 struct bgp_node *rn;
6363 struct bgp_aggregate *aggregate;
6364 struct bgp_table *table;
6365
6366 table = bgp->aggregate[afi][safi];
6367
6368 /* No aggregates configured. */
6369 if (bgp_table_top_nolock(table) == NULL)
6370 return;
6371
6372 if (p->prefixlen == 0)
6373 return;
6374
6375 if (BGP_PATH_HOLDDOWN(pi))
6376 return;
6377
6378 child = bgp_node_get(table, p);
6379
6380 /* Aggregate address configuration check. */
6381 for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
6382 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6383 if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
6384 bgp_add_route_to_aggregate(bgp, &rn->p, pi, afi,
6385 safi, aggregate);
6386 }
6387 }
6388 bgp_unlock_node(child);
6389 }
6390
6391 void bgp_aggregate_decrement(struct bgp *bgp, struct prefix *p,
6392 struct bgp_path_info *del, afi_t afi, safi_t safi)
6393 {
6394 struct bgp_node *child;
6395 struct bgp_node *rn;
6396 struct bgp_aggregate *aggregate;
6397 struct bgp_table *table;
6398
6399 table = bgp->aggregate[afi][safi];
6400
6401 /* No aggregates configured. */
6402 if (bgp_table_top_nolock(table) == NULL)
6403 return;
6404
6405 if (p->prefixlen == 0)
6406 return;
6407
6408 child = bgp_node_get(table, p);
6409
6410 /* Aggregate address configuration check. */
6411 for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
6412 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6413 if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
6414 bgp_remove_route_from_aggregate(bgp, afi, safi,
6415 del, aggregate, &rn->p);
6416 }
6417 }
6418 bgp_unlock_node(child);
6419 }
6420
6421 /* Aggregate route attribute. */
6422 #define AGGREGATE_SUMMARY_ONLY 1
6423 #define AGGREGATE_AS_SET 1
6424 #define AGGREGATE_AS_UNSET 0
6425
6426 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
6427 afi_t afi, safi_t safi)
6428 {
6429 VTY_DECLVAR_CONTEXT(bgp, bgp);
6430 int ret;
6431 struct prefix p;
6432 struct bgp_node *rn;
6433 struct bgp_aggregate *aggregate;
6434
6435 /* Convert string to prefix structure. */
6436 ret = str2prefix(prefix_str, &p);
6437 if (!ret) {
6438 vty_out(vty, "Malformed prefix\n");
6439 return CMD_WARNING_CONFIG_FAILED;
6440 }
6441 apply_mask(&p);
6442
6443 /* Old configuration check. */
6444 rn = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
6445 if (!rn) {
6446 vty_out(vty,
6447 "%% There is no aggregate-address configuration.\n");
6448 return CMD_WARNING_CONFIG_FAILED;
6449 }
6450
6451 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6452 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
6453 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
6454 NULL, NULL, 0, aggregate);
6455
6456 /* Unlock aggregate address configuration. */
6457 bgp_node_set_bgp_aggregate_info(rn, NULL);
6458
6459 if (aggregate->community)
6460 community_free(&aggregate->community);
6461
6462 if (aggregate->community_hash) {
6463 /* Delete all communities in the hash.
6464 */
6465 hash_clean(aggregate->community_hash,
6466 bgp_aggr_community_remove);
6467 /* Free up the community_hash.
6468 */
6469 hash_free(aggregate->community_hash);
6470 }
6471
6472 if (aggregate->ecommunity)
6473 ecommunity_free(&aggregate->ecommunity);
6474
6475 if (aggregate->ecommunity_hash) {
6476 /* Delete all ecommunities in the hash.
6477 */
6478 hash_clean(aggregate->ecommunity_hash,
6479 bgp_aggr_ecommunity_remove);
6480 /* Free up the ecommunity_hash.
6481 */
6482 hash_free(aggregate->ecommunity_hash);
6483 }
6484
6485 if (aggregate->lcommunity)
6486 lcommunity_free(&aggregate->lcommunity);
6487
6488 if (aggregate->lcommunity_hash) {
6489 /* Delete all lcommunities in the hash.
6490 */
6491 hash_clean(aggregate->lcommunity_hash,
6492 bgp_aggr_lcommunity_remove);
6493 /* Free up the lcommunity_hash.
6494 */
6495 hash_free(aggregate->lcommunity_hash);
6496 }
6497
6498 if (aggregate->aspath)
6499 aspath_free(aggregate->aspath);
6500
6501 if (aggregate->aspath_hash) {
6502 /* Delete all as-paths in the hash.
6503 */
6504 hash_clean(aggregate->aspath_hash,
6505 bgp_aggr_aspath_remove);
6506 /* Free up the aspath_hash.
6507 */
6508 hash_free(aggregate->aspath_hash);
6509 }
6510
6511 bgp_aggregate_free(aggregate);
6512 bgp_unlock_node(rn);
6513 bgp_unlock_node(rn);
6514
6515 return CMD_SUCCESS;
6516 }
6517
6518 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
6519 safi_t safi, const char *rmap, uint8_t summary_only,
6520 uint8_t as_set)
6521 {
6522 VTY_DECLVAR_CONTEXT(bgp, bgp);
6523 int ret;
6524 struct prefix p;
6525 struct bgp_node *rn;
6526 struct bgp_aggregate *aggregate;
6527 uint8_t as_set_new = as_set;
6528
6529 /* Convert string to prefix structure. */
6530 ret = str2prefix(prefix_str, &p);
6531 if (!ret) {
6532 vty_out(vty, "Malformed prefix\n");
6533 return CMD_WARNING_CONFIG_FAILED;
6534 }
6535 apply_mask(&p);
6536
6537 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
6538 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
6539 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
6540 prefix_str);
6541 return CMD_WARNING_CONFIG_FAILED;
6542 }
6543
6544 /* Old configuration check. */
6545 rn = bgp_node_get(bgp->aggregate[afi][safi], &p);
6546 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6547
6548 if (aggregate) {
6549 vty_out(vty, "There is already same aggregate network.\n");
6550 /* try to remove the old entry */
6551 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
6552 if (ret) {
6553 vty_out(vty, "Error deleting aggregate.\n");
6554 bgp_unlock_node(rn);
6555 return CMD_WARNING_CONFIG_FAILED;
6556 }
6557 }
6558
6559 /* Make aggregate address structure. */
6560 aggregate = bgp_aggregate_new();
6561 aggregate->summary_only = summary_only;
6562
6563 /* Network operators MUST NOT locally generate any new
6564 * announcements containing AS_SET or AS_CONFED_SET. If they have
6565 * announced routes with AS_SET or AS_CONFED_SET in them, then they
6566 * SHOULD withdraw those routes and re-announce routes for the
6567 * aggregate or component prefixes (i.e., the more-specific routes
6568 * subsumed by the previously aggregated route) without AS_SET
6569 * or AS_CONFED_SET in the updates.
6570 */
6571 if (bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED) {
6572 if (as_set == AGGREGATE_AS_SET) {
6573 as_set_new = AGGREGATE_AS_UNSET;
6574 zlog_warn(
6575 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.\n",
6576 __func__);
6577 vty_out(vty,
6578 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
6579 }
6580 }
6581
6582 aggregate->as_set = as_set_new;
6583 aggregate->safi = safi;
6584
6585 if (rmap) {
6586 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
6587 route_map_counter_decrement(aggregate->rmap.map);
6588 aggregate->rmap.name =
6589 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6590 aggregate->rmap.map = route_map_lookup_by_name(rmap);
6591 route_map_counter_increment(aggregate->rmap.map);
6592 }
6593 bgp_node_set_bgp_aggregate_info(rn, aggregate);
6594
6595 /* Aggregate address insert into BGP routing table. */
6596 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
6597
6598 return CMD_SUCCESS;
6599 }
6600
6601 DEFUN (aggregate_address,
6602 aggregate_address_cmd,
6603 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6604 "Configure BGP aggregate entries\n"
6605 "Aggregate prefix\n"
6606 "Generate AS set path information\n"
6607 "Filter more specific routes from updates\n"
6608 "Filter more specific routes from updates\n"
6609 "Generate AS set path information\n"
6610 "Apply route map to aggregate network\n"
6611 "Name of route map\n")
6612 {
6613 int idx = 0;
6614 argv_find(argv, argc, "A.B.C.D/M", &idx);
6615 char *prefix = argv[idx]->arg;
6616 char *rmap = NULL;
6617 int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
6618 : AGGREGATE_AS_UNSET;
6619 idx = 0;
6620 int summary_only = argv_find(argv, argc, "summary-only", &idx)
6621 ? AGGREGATE_SUMMARY_ONLY
6622 : 0;
6623
6624 idx = 0;
6625 argv_find(argv, argc, "WORD", &idx);
6626 if (idx)
6627 rmap = argv[idx]->arg;
6628
6629 return bgp_aggregate_set(vty, prefix, AFI_IP, bgp_node_safi(vty),
6630 rmap, summary_only, as_set);
6631 }
6632
6633 DEFUN (aggregate_address_mask,
6634 aggregate_address_mask_cmd,
6635 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6636 "Configure BGP aggregate entries\n"
6637 "Aggregate address\n"
6638 "Aggregate mask\n"
6639 "Generate AS set path information\n"
6640 "Filter more specific routes from updates\n"
6641 "Filter more specific routes from updates\n"
6642 "Generate AS set path information\n"
6643 "Apply route map to aggregate network\n"
6644 "Name of route map\n")
6645 {
6646 int idx = 0;
6647 argv_find(argv, argc, "A.B.C.D", &idx);
6648 char *prefix = argv[idx]->arg;
6649 char *mask = argv[idx + 1]->arg;
6650 bool rmap_found;
6651 char *rmap = NULL;
6652 int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
6653 : AGGREGATE_AS_UNSET;
6654 idx = 0;
6655 int summary_only = argv_find(argv, argc, "summary-only", &idx)
6656 ? AGGREGATE_SUMMARY_ONLY
6657 : 0;
6658
6659 rmap_found = argv_find(argv, argc, "WORD", &idx);
6660 if (rmap_found)
6661 rmap = argv[idx]->arg;
6662
6663 char prefix_str[BUFSIZ];
6664 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
6665
6666 if (!ret) {
6667 vty_out(vty, "%% Inconsistent address and mask\n");
6668 return CMD_WARNING_CONFIG_FAILED;
6669 }
6670
6671 return bgp_aggregate_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty),
6672 rmap, summary_only, as_set);
6673 }
6674
6675 DEFUN (no_aggregate_address,
6676 no_aggregate_address_cmd,
6677 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6678 NO_STR
6679 "Configure BGP aggregate entries\n"
6680 "Aggregate prefix\n"
6681 "Generate AS set path information\n"
6682 "Filter more specific routes from updates\n"
6683 "Filter more specific routes from updates\n"
6684 "Generate AS set path information\n"
6685 "Apply route map to aggregate network\n"
6686 "Name of route map\n")
6687 {
6688 int idx = 0;
6689 argv_find(argv, argc, "A.B.C.D/M", &idx);
6690 char *prefix = argv[idx]->arg;
6691 return bgp_aggregate_unset(vty, prefix, AFI_IP, bgp_node_safi(vty));
6692 }
6693
6694 DEFUN (no_aggregate_address_mask,
6695 no_aggregate_address_mask_cmd,
6696 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6697 NO_STR
6698 "Configure BGP aggregate entries\n"
6699 "Aggregate address\n"
6700 "Aggregate mask\n"
6701 "Generate AS set path information\n"
6702 "Filter more specific routes from updates\n"
6703 "Filter more specific routes from updates\n"
6704 "Generate AS set path information\n"
6705 "Apply route map to aggregate network\n"
6706 "Name of route map\n")
6707 {
6708 int idx = 0;
6709 argv_find(argv, argc, "A.B.C.D", &idx);
6710 char *prefix = argv[idx]->arg;
6711 char *mask = argv[idx + 1]->arg;
6712
6713 char prefix_str[BUFSIZ];
6714 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
6715
6716 if (!ret) {
6717 vty_out(vty, "%% Inconsistent address and mask\n");
6718 return CMD_WARNING_CONFIG_FAILED;
6719 }
6720
6721 return bgp_aggregate_unset(vty, prefix_str, AFI_IP, bgp_node_safi(vty));
6722 }
6723
6724 DEFUN (ipv6_aggregate_address,
6725 ipv6_aggregate_address_cmd,
6726 "aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6727 "Configure BGP aggregate entries\n"
6728 "Aggregate prefix\n"
6729 "Generate AS set path information\n"
6730 "Filter more specific routes from updates\n"
6731 "Filter more specific routes from updates\n"
6732 "Generate AS set path information\n"
6733 "Apply route map to aggregate network\n"
6734 "Name of route map\n")
6735 {
6736 int idx = 0;
6737 argv_find(argv, argc, "X:X::X:X/M", &idx);
6738 char *prefix = argv[idx]->arg;
6739 char *rmap = NULL;
6740 bool rmap_found;
6741 int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
6742 : AGGREGATE_AS_UNSET;
6743
6744 idx = 0;
6745 int sum_only = argv_find(argv, argc, "summary-only", &idx)
6746 ? AGGREGATE_SUMMARY_ONLY
6747 : 0;
6748
6749 rmap_found = argv_find(argv, argc, "WORD", &idx);
6750 if (rmap_found)
6751 rmap = argv[idx]->arg;
6752
6753 return bgp_aggregate_set(vty, prefix, AFI_IP6, SAFI_UNICAST, rmap,
6754 sum_only, as_set);
6755 }
6756
6757 DEFUN (no_ipv6_aggregate_address,
6758 no_ipv6_aggregate_address_cmd,
6759 "no aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6760 NO_STR
6761 "Configure BGP aggregate entries\n"
6762 "Aggregate prefix\n"
6763 "Generate AS set path information\n"
6764 "Filter more specific routes from updates\n"
6765 "Filter more specific routes from updates\n"
6766 "Generate AS set path information\n"
6767 "Apply route map to aggregate network\n"
6768 "Name of route map\n")
6769 {
6770 int idx = 0;
6771 argv_find(argv, argc, "X:X::X:X/M", &idx);
6772 char *prefix = argv[idx]->arg;
6773 return bgp_aggregate_unset(vty, prefix, AFI_IP6, SAFI_UNICAST);
6774 }
6775
6776 /* Redistribute route treatment. */
6777 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
6778 const union g_addr *nexthop, ifindex_t ifindex,
6779 enum nexthop_types_t nhtype, uint32_t metric,
6780 uint8_t type, unsigned short instance,
6781 route_tag_t tag)
6782 {
6783 struct bgp_path_info *new;
6784 struct bgp_path_info *bpi;
6785 struct bgp_path_info rmap_path;
6786 struct bgp_node *bn;
6787 struct attr attr;
6788 struct attr *new_attr;
6789 afi_t afi;
6790 route_map_result_t ret;
6791 struct bgp_redist *red;
6792
6793 /* Make default attribute. */
6794 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
6795 /*
6796 * This must not be NULL to satisfy Coverity SA
6797 */
6798 assert(attr.aspath);
6799
6800 switch (nhtype) {
6801 case NEXTHOP_TYPE_IFINDEX:
6802 break;
6803 case NEXTHOP_TYPE_IPV4:
6804 case NEXTHOP_TYPE_IPV4_IFINDEX:
6805 attr.nexthop = nexthop->ipv4;
6806 break;
6807 case NEXTHOP_TYPE_IPV6:
6808 case NEXTHOP_TYPE_IPV6_IFINDEX:
6809 attr.mp_nexthop_global = nexthop->ipv6;
6810 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
6811 break;
6812 case NEXTHOP_TYPE_BLACKHOLE:
6813 switch (p->family) {
6814 case AF_INET:
6815 attr.nexthop.s_addr = INADDR_ANY;
6816 break;
6817 case AF_INET6:
6818 memset(&attr.mp_nexthop_global, 0,
6819 sizeof(attr.mp_nexthop_global));
6820 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
6821 break;
6822 }
6823 break;
6824 }
6825 attr.nh_ifindex = ifindex;
6826
6827 attr.med = metric;
6828 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6829 attr.tag = tag;
6830
6831 afi = family2afi(p->family);
6832
6833 red = bgp_redist_lookup(bgp, afi, type, instance);
6834 if (red) {
6835 struct attr attr_new;
6836
6837 /* Copy attribute for modification. */
6838 attr_new = attr;
6839
6840 if (red->redist_metric_flag)
6841 attr_new.med = red->redist_metric;
6842
6843 /* Apply route-map. */
6844 if (red->rmap.name) {
6845 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
6846 rmap_path.peer = bgp->peer_self;
6847 rmap_path.attr = &attr_new;
6848
6849 SET_FLAG(bgp->peer_self->rmap_type,
6850 PEER_RMAP_TYPE_REDISTRIBUTE);
6851
6852 ret = route_map_apply(red->rmap.map, p, RMAP_BGP,
6853 &rmap_path);
6854
6855 bgp->peer_self->rmap_type = 0;
6856
6857 if (ret == RMAP_DENYMATCH) {
6858 /* Free uninterned attribute. */
6859 bgp_attr_flush(&attr_new);
6860
6861 /* Unintern original. */
6862 aspath_unintern(&attr.aspath);
6863 bgp_redistribute_delete(bgp, p, type, instance);
6864 return;
6865 }
6866 }
6867
6868 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
6869 bgp_attr_add_gshut_community(&attr_new);
6870
6871 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
6872 SAFI_UNICAST, p, NULL);
6873
6874 new_attr = bgp_attr_intern(&attr_new);
6875
6876 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
6877 bpi = bpi->next)
6878 if (bpi->peer == bgp->peer_self
6879 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
6880 break;
6881
6882 if (bpi) {
6883 /* Ensure the (source route) type is updated. */
6884 bpi->type = type;
6885 if (attrhash_cmp(bpi->attr, new_attr)
6886 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
6887 bgp_attr_unintern(&new_attr);
6888 aspath_unintern(&attr.aspath);
6889 bgp_unlock_node(bn);
6890 return;
6891 } else {
6892 /* The attribute is changed. */
6893 bgp_path_info_set_flag(bn, bpi,
6894 BGP_PATH_ATTR_CHANGED);
6895
6896 /* Rewrite BGP route information. */
6897 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
6898 bgp_path_info_restore(bn, bpi);
6899 else
6900 bgp_aggregate_decrement(
6901 bgp, p, bpi, afi, SAFI_UNICAST);
6902 bgp_attr_unintern(&bpi->attr);
6903 bpi->attr = new_attr;
6904 bpi->uptime = bgp_clock();
6905
6906 /* Process change. */
6907 bgp_aggregate_increment(bgp, p, bpi, afi,
6908 SAFI_UNICAST);
6909 bgp_process(bgp, bn, afi, SAFI_UNICAST);
6910 bgp_unlock_node(bn);
6911 aspath_unintern(&attr.aspath);
6912
6913 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6914 || (bgp->inst_type
6915 == BGP_INSTANCE_TYPE_DEFAULT)) {
6916
6917 vpn_leak_from_vrf_update(
6918 bgp_get_default(), bgp, bpi);
6919 }
6920 return;
6921 }
6922 }
6923
6924 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
6925 bgp->peer_self, new_attr, bn);
6926 SET_FLAG(new->flags, BGP_PATH_VALID);
6927
6928 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
6929 bgp_path_info_add(bn, new);
6930 bgp_unlock_node(bn);
6931 bgp_process(bgp, bn, afi, SAFI_UNICAST);
6932
6933 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6934 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6935
6936 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6937 }
6938 }
6939
6940 /* Unintern original. */
6941 aspath_unintern(&attr.aspath);
6942 }
6943
6944 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
6945 unsigned short instance)
6946 {
6947 afi_t afi;
6948 struct bgp_node *rn;
6949 struct bgp_path_info *pi;
6950 struct bgp_redist *red;
6951
6952 afi = family2afi(p->family);
6953
6954 red = bgp_redist_lookup(bgp, afi, type, instance);
6955 if (red) {
6956 rn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
6957 SAFI_UNICAST, p, NULL);
6958
6959 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
6960 if (pi->peer == bgp->peer_self && pi->type == type)
6961 break;
6962
6963 if (pi) {
6964 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6965 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6966
6967 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6968 bgp, pi);
6969 }
6970 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
6971 bgp_path_info_delete(rn, pi);
6972 bgp_process(bgp, rn, afi, SAFI_UNICAST);
6973 }
6974 bgp_unlock_node(rn);
6975 }
6976 }
6977
6978 /* Withdraw specified route type's route. */
6979 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
6980 unsigned short instance)
6981 {
6982 struct bgp_node *rn;
6983 struct bgp_path_info *pi;
6984 struct bgp_table *table;
6985
6986 table = bgp->rib[afi][SAFI_UNICAST];
6987
6988 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
6989 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
6990 if (pi->peer == bgp->peer_self && pi->type == type
6991 && pi->instance == instance)
6992 break;
6993
6994 if (pi) {
6995 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
6996 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6997
6998 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6999 bgp, pi);
7000 }
7001 bgp_aggregate_decrement(bgp, &rn->p, pi, afi,
7002 SAFI_UNICAST);
7003 bgp_path_info_delete(rn, pi);
7004 bgp_process(bgp, rn, afi, SAFI_UNICAST);
7005 }
7006 }
7007 }
7008
7009 /* Static function to display route. */
7010 static void route_vty_out_route(struct prefix *p, struct vty *vty,
7011 json_object *json)
7012 {
7013 int len = 0;
7014 char buf[BUFSIZ];
7015 char buf2[BUFSIZ];
7016
7017 if (p->family == AF_INET) {
7018 if (!json) {
7019 len = vty_out(
7020 vty, "%s/%d",
7021 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
7022 p->prefixlen);
7023 } else {
7024 json_object_string_add(json, "prefix",
7025 inet_ntop(p->family,
7026 &p->u.prefix, buf,
7027 BUFSIZ));
7028 json_object_int_add(json, "prefixLen", p->prefixlen);
7029 prefix2str(p, buf2, PREFIX_STRLEN);
7030 json_object_string_add(json, "network", buf2);
7031 }
7032 } else if (p->family == AF_ETHERNET) {
7033 prefix2str(p, buf, PREFIX_STRLEN);
7034 len = vty_out(vty, "%s", buf);
7035 } else if (p->family == AF_EVPN) {
7036 if (!json)
7037 len = vty_out(
7038 vty, "%s",
7039 bgp_evpn_route2str((struct prefix_evpn *)p, buf,
7040 BUFSIZ));
7041 else
7042 bgp_evpn_route2json((struct prefix_evpn *)p, json);
7043 } else if (p->family == AF_FLOWSPEC) {
7044 route_vty_out_flowspec(vty, p, NULL,
7045 json ?
7046 NLRI_STRING_FORMAT_JSON_SIMPLE :
7047 NLRI_STRING_FORMAT_MIN, json);
7048 } else {
7049 if (!json)
7050 len = vty_out(
7051 vty, "%s/%d",
7052 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
7053 p->prefixlen);
7054 else {
7055 json_object_string_add(json, "prefix",
7056 inet_ntop(p->family,
7057 &p->u.prefix, buf,
7058 BUFSIZ));
7059 json_object_int_add(json, "prefixLen", p->prefixlen);
7060 prefix2str(p, buf2, PREFIX_STRLEN);
7061 json_object_string_add(json, "network", buf2);
7062 }
7063 }
7064
7065 if (!json) {
7066 len = 17 - len;
7067 if (len < 1)
7068 vty_out(vty, "\n%*s", 20, " ");
7069 else
7070 vty_out(vty, "%*s", len, " ");
7071 }
7072 }
7073
7074 enum bgp_display_type {
7075 normal_list,
7076 };
7077
7078 /* Print the short form route status for a bgp_path_info */
7079 static void route_vty_short_status_out(struct vty *vty,
7080 struct bgp_path_info *path,
7081 json_object *json_path)
7082 {
7083 if (json_path) {
7084
7085 /* Route status display. */
7086 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
7087 json_object_boolean_true_add(json_path, "removed");
7088
7089 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
7090 json_object_boolean_true_add(json_path, "stale");
7091
7092 if (path->extra && path->extra->suppress)
7093 json_object_boolean_true_add(json_path, "suppressed");
7094
7095 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
7096 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7097 json_object_boolean_true_add(json_path, "valid");
7098
7099 /* Selected */
7100 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7101 json_object_boolean_true_add(json_path, "history");
7102
7103 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
7104 json_object_boolean_true_add(json_path, "damped");
7105
7106 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
7107 json_object_boolean_true_add(json_path, "bestpath");
7108
7109 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
7110 json_object_boolean_true_add(json_path, "multipath");
7111
7112 /* Internal route. */
7113 if ((path->peer->as)
7114 && (path->peer->as == path->peer->local_as))
7115 json_object_string_add(json_path, "pathFrom",
7116 "internal");
7117 else
7118 json_object_string_add(json_path, "pathFrom",
7119 "external");
7120
7121 return;
7122 }
7123
7124 /* Route status display. */
7125 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
7126 vty_out(vty, "R");
7127 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
7128 vty_out(vty, "S");
7129 else if (path->extra && path->extra->suppress)
7130 vty_out(vty, "s");
7131 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
7132 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7133 vty_out(vty, "*");
7134 else
7135 vty_out(vty, " ");
7136
7137 /* Selected */
7138 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7139 vty_out(vty, "h");
7140 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
7141 vty_out(vty, "d");
7142 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
7143 vty_out(vty, ">");
7144 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
7145 vty_out(vty, "=");
7146 else
7147 vty_out(vty, " ");
7148
7149 /* Internal route. */
7150 if (path->peer && (path->peer->as)
7151 && (path->peer->as == path->peer->local_as))
7152 vty_out(vty, "i");
7153 else
7154 vty_out(vty, " ");
7155 }
7156
7157 static char *bgp_nexthop_hostname(struct peer *peer, struct attr *attr)
7158 {
7159 if (peer->hostname && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)
7160 && !(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))
7161 return peer->hostname;
7162 return NULL;
7163 }
7164
7165 /* called from terminal list command */
7166 void route_vty_out(struct vty *vty, struct prefix *p,
7167 struct bgp_path_info *path, int display, safi_t safi,
7168 json_object *json_paths)
7169 {
7170 struct attr *attr = path->attr;
7171 json_object *json_path = NULL;
7172 json_object *json_nexthops = NULL;
7173 json_object *json_nexthop_global = NULL;
7174 json_object *json_nexthop_ll = NULL;
7175 json_object *json_ext_community = NULL;
7176 char vrf_id_str[VRF_NAMSIZ] = {0};
7177 bool nexthop_self =
7178 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
7179 bool nexthop_othervrf = false;
7180 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
7181 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
7182 char *nexthop_hostname = bgp_nexthop_hostname(path->peer, attr);
7183
7184 if (json_paths)
7185 json_path = json_object_new_object();
7186
7187 /* short status lead text */
7188 route_vty_short_status_out(vty, path, json_path);
7189
7190 if (!json_paths) {
7191 /* print prefix and mask */
7192 if (!display)
7193 route_vty_out_route(p, vty, json_path);
7194 else
7195 vty_out(vty, "%*s", 17, " ");
7196 } else {
7197 route_vty_out_route(p, vty, json_path);
7198 }
7199
7200 /*
7201 * If vrf id of nexthop is different from that of prefix,
7202 * set up printable string to append
7203 */
7204 if (path->extra && path->extra->bgp_orig) {
7205 const char *self = "";
7206
7207 if (nexthop_self)
7208 self = "<";
7209
7210 nexthop_othervrf = true;
7211 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
7212
7213 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
7214 snprintf(vrf_id_str, sizeof(vrf_id_str),
7215 "@%s%s", VRFID_NONE_STR, self);
7216 else
7217 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
7218 path->extra->bgp_orig->vrf_id, self);
7219
7220 if (path->extra->bgp_orig->inst_type
7221 != BGP_INSTANCE_TYPE_DEFAULT)
7222
7223 nexthop_vrfname = path->extra->bgp_orig->name;
7224 } else {
7225 const char *self = "";
7226
7227 if (nexthop_self)
7228 self = "<";
7229
7230 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
7231 }
7232
7233 /*
7234 * For ENCAP and EVPN routes, nexthop address family is not
7235 * neccessarily the same as the prefix address family.
7236 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
7237 * EVPN routes are also exchanged with a MP nexthop. Currently,
7238 * this
7239 * is only IPv4, the value will be present in either
7240 * attr->nexthop or
7241 * attr->mp_nexthop_global_in
7242 */
7243 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
7244 char buf[BUFSIZ];
7245 char nexthop[128];
7246 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
7247
7248 switch (af) {
7249 case AF_INET:
7250 sprintf(nexthop, "%s",
7251 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
7252 BUFSIZ));
7253 break;
7254 case AF_INET6:
7255 sprintf(nexthop, "%s",
7256 inet_ntop(af, &attr->mp_nexthop_global, buf,
7257 BUFSIZ));
7258 break;
7259 default:
7260 sprintf(nexthop, "?");
7261 break;
7262 }
7263
7264 if (json_paths) {
7265 json_nexthop_global = json_object_new_object();
7266
7267 json_object_string_add(json_nexthop_global, "ip",
7268 nexthop);
7269
7270 if (nexthop_hostname)
7271 json_object_string_add(json_nexthop_global,
7272 "hostname",
7273 nexthop_hostname);
7274
7275 json_object_string_add(json_nexthop_global, "afi",
7276 (af == AF_INET) ? "ipv4"
7277 : "ipv6");
7278 json_object_boolean_true_add(json_nexthop_global,
7279 "used");
7280 } else
7281 vty_out(vty, "%s%s",
7282 nexthop_hostname ? nexthop_hostname : nexthop,
7283 vrf_id_str);
7284 } else if (safi == SAFI_EVPN) {
7285 if (json_paths) {
7286 json_nexthop_global = json_object_new_object();
7287
7288 json_object_string_add(json_nexthop_global, "ip",
7289 inet_ntoa(attr->nexthop));
7290
7291 if (nexthop_hostname)
7292 json_object_string_add(json_nexthop_global,
7293 "hostname",
7294 nexthop_hostname);
7295
7296 json_object_string_add(json_nexthop_global, "afi",
7297 "ipv4");
7298 json_object_boolean_true_add(json_nexthop_global,
7299 "used");
7300 } else
7301 vty_out(vty, "%-16s%s",
7302 nexthop_hostname ? nexthop_hostname
7303 : inet_ntoa(attr->nexthop),
7304 vrf_id_str);
7305 } else if (safi == SAFI_FLOWSPEC) {
7306 if (attr->nexthop.s_addr != 0) {
7307 if (json_paths) {
7308 json_nexthop_global = json_object_new_object();
7309
7310 json_object_string_add(json_nexthop_global,
7311 "afi", "ipv4");
7312 json_object_string_add(
7313 json_nexthop_global, "ip",
7314 inet_ntoa(attr->nexthop));
7315
7316 if (nexthop_hostname)
7317 json_object_string_add(
7318 json_nexthop_global, "hostname",
7319 nexthop_hostname);
7320
7321 json_object_boolean_true_add(
7322 json_nexthop_global,
7323 "used");
7324 } else {
7325 vty_out(vty, "%-16s",
7326 nexthop_hostname
7327 ? nexthop_hostname
7328 : inet_ntoa(attr->nexthop));
7329 }
7330 }
7331 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7332 if (json_paths) {
7333 json_nexthop_global = json_object_new_object();
7334
7335 json_object_string_add(json_nexthop_global, "ip",
7336 inet_ntoa(attr->nexthop));
7337
7338 if (nexthop_hostname)
7339 json_object_string_add(json_nexthop_global,
7340 "hostname",
7341 nexthop_hostname);
7342
7343 json_object_string_add(json_nexthop_global, "afi",
7344 "ipv4");
7345 json_object_boolean_true_add(json_nexthop_global,
7346 "used");
7347 } else {
7348 char buf[BUFSIZ];
7349
7350 snprintf(buf, sizeof(buf), "%s%s",
7351 nexthop_hostname ? nexthop_hostname
7352 : inet_ntoa(attr->nexthop),
7353 vrf_id_str);
7354 vty_out(vty, "%-16s", buf);
7355 }
7356 }
7357
7358 /* IPv6 Next Hop */
7359 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7360 int len;
7361 char buf[BUFSIZ];
7362
7363 if (json_paths) {
7364 json_nexthop_global = json_object_new_object();
7365 json_object_string_add(
7366 json_nexthop_global, "ip",
7367 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
7368 buf, BUFSIZ));
7369
7370 if (nexthop_hostname)
7371 json_object_string_add(json_nexthop_global,
7372 "hostname",
7373 nexthop_hostname);
7374
7375 json_object_string_add(json_nexthop_global, "afi",
7376 "ipv6");
7377 json_object_string_add(json_nexthop_global, "scope",
7378 "global");
7379
7380 /* We display both LL & GL if both have been
7381 * received */
7382 if ((attr->mp_nexthop_len
7383 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
7384 || (path->peer->conf_if)) {
7385 json_nexthop_ll = json_object_new_object();
7386 json_object_string_add(
7387 json_nexthop_ll, "ip",
7388 inet_ntop(AF_INET6,
7389 &attr->mp_nexthop_local, buf,
7390 BUFSIZ));
7391
7392 if (nexthop_hostname)
7393 json_object_string_add(
7394 json_nexthop_ll, "hostname",
7395 nexthop_hostname);
7396
7397 json_object_string_add(json_nexthop_ll, "afi",
7398 "ipv6");
7399 json_object_string_add(json_nexthop_ll, "scope",
7400 "link-local");
7401
7402 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
7403 &attr->mp_nexthop_local)
7404 != 0)
7405 && !attr->mp_nexthop_prefer_global)
7406 json_object_boolean_true_add(
7407 json_nexthop_ll, "used");
7408 else
7409 json_object_boolean_true_add(
7410 json_nexthop_global, "used");
7411 } else
7412 json_object_boolean_true_add(
7413 json_nexthop_global, "used");
7414 } else {
7415 /* Display LL if LL/Global both in table unless
7416 * prefer-global is set */
7417 if (((attr->mp_nexthop_len
7418 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
7419 && !attr->mp_nexthop_prefer_global)
7420 || (path->peer->conf_if)) {
7421 if (path->peer->conf_if) {
7422 len = vty_out(vty, "%s",
7423 path->peer->conf_if);
7424 len = 16 - len; /* len of IPv6
7425 addr + max
7426 len of def
7427 ifname */
7428
7429 if (len < 1)
7430 vty_out(vty, "\n%*s", 36, " ");
7431 else
7432 vty_out(vty, "%*s", len, " ");
7433 } else {
7434 len = vty_out(
7435 vty, "%s%s",
7436 nexthop_hostname
7437 ? nexthop_hostname
7438 : inet_ntop(
7439 AF_INET6,
7440 &attr->mp_nexthop_local,
7441 buf, BUFSIZ),
7442 vrf_id_str);
7443 len = 16 - len;
7444
7445 if (len < 1)
7446 vty_out(vty, "\n%*s", 36, " ");
7447 else
7448 vty_out(vty, "%*s", len, " ");
7449 }
7450 } else {
7451 len = vty_out(
7452 vty, "%s%s",
7453 nexthop_hostname
7454 ? nexthop_hostname
7455 : inet_ntop(
7456 AF_INET6,
7457 &attr->mp_nexthop_global,
7458 buf, BUFSIZ),
7459 vrf_id_str);
7460 len = 16 - len;
7461
7462 if (len < 1)
7463 vty_out(vty, "\n%*s", 36, " ");
7464 else
7465 vty_out(vty, "%*s", len, " ");
7466 }
7467 }
7468 }
7469
7470 /* MED/Metric */
7471 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7472 if (json_paths) {
7473
7474 /*
7475 * Adding "metric" field to match with corresponding
7476 * CLI. "med" will be deprecated in future.
7477 */
7478 json_object_int_add(json_path, "med", attr->med);
7479 json_object_int_add(json_path, "metric", attr->med);
7480 } else
7481 vty_out(vty, "%10u", attr->med);
7482 else if (!json_paths)
7483 vty_out(vty, " ");
7484
7485 /* Local Pref */
7486 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
7487 if (json_paths) {
7488
7489 /*
7490 * Adding "locPrf" field to match with corresponding
7491 * CLI. "localPref" will be deprecated in future.
7492 */
7493 json_object_int_add(json_path, "localpref",
7494 attr->local_pref);
7495 json_object_int_add(json_path, "locPrf",
7496 attr->local_pref);
7497 } else
7498 vty_out(vty, "%7u", attr->local_pref);
7499 else if (!json_paths)
7500 vty_out(vty, " ");
7501
7502 if (json_paths)
7503 json_object_int_add(json_path, "weight", attr->weight);
7504 else
7505 vty_out(vty, "%7u ", attr->weight);
7506
7507 if (json_paths) {
7508 char buf[BUFSIZ];
7509 json_object_string_add(
7510 json_path, "peerId",
7511 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
7512 }
7513
7514 /* Print aspath */
7515 if (attr->aspath) {
7516 if (json_paths) {
7517
7518 /*
7519 * Adding "path" field to match with corresponding
7520 * CLI. "aspath" will be deprecated in future.
7521 */
7522 json_object_string_add(json_path, "aspath",
7523 attr->aspath->str);
7524 json_object_string_add(json_path, "path",
7525 attr->aspath->str);
7526 } else
7527 aspath_print_vty(vty, "%s", attr->aspath, " ");
7528 }
7529
7530 /* Print origin */
7531 if (json_paths)
7532 json_object_string_add(json_path, "origin",
7533 bgp_origin_long_str[attr->origin]);
7534 else
7535 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7536
7537 if (json_paths) {
7538 if (safi == SAFI_EVPN &&
7539 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
7540 json_ext_community = json_object_new_object();
7541 json_object_string_add(json_ext_community,
7542 "string",
7543 attr->ecommunity->str);
7544 json_object_object_add(json_path,
7545 "extendedCommunity",
7546 json_ext_community);
7547 }
7548
7549 if (nexthop_self)
7550 json_object_boolean_true_add(json_path,
7551 "announceNexthopSelf");
7552 if (nexthop_othervrf) {
7553 json_object_string_add(json_path, "nhVrfName",
7554 nexthop_vrfname);
7555
7556 json_object_int_add(json_path, "nhVrfId",
7557 ((nexthop_vrfid == VRF_UNKNOWN)
7558 ? -1
7559 : (int)nexthop_vrfid));
7560 }
7561 }
7562
7563 if (json_paths) {
7564 if (json_nexthop_global || json_nexthop_ll) {
7565 json_nexthops = json_object_new_array();
7566
7567 if (json_nexthop_global)
7568 json_object_array_add(json_nexthops,
7569 json_nexthop_global);
7570
7571 if (json_nexthop_ll)
7572 json_object_array_add(json_nexthops,
7573 json_nexthop_ll);
7574
7575 json_object_object_add(json_path, "nexthops",
7576 json_nexthops);
7577 }
7578
7579 json_object_array_add(json_paths, json_path);
7580 } else {
7581 vty_out(vty, "\n");
7582
7583 if (safi == SAFI_EVPN &&
7584 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
7585 vty_out(vty, "%*s", 20, " ");
7586 vty_out(vty, "%s\n", attr->ecommunity->str);
7587 }
7588
7589 #if ENABLE_BGP_VNC
7590 /* prints an additional line, indented, with VNC info, if
7591 * present */
7592 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
7593 rfapi_vty_out_vncinfo(vty, p, path, safi);
7594 #endif
7595 }
7596 }
7597
7598 /* called from terminal list command */
7599 void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
7600 safi_t safi, bool use_json, json_object *json_ar)
7601 {
7602 json_object *json_status = NULL;
7603 json_object *json_net = NULL;
7604 char buff[BUFSIZ];
7605
7606 /* Route status display. */
7607 if (use_json) {
7608 json_status = json_object_new_object();
7609 json_net = json_object_new_object();
7610 } else {
7611 vty_out(vty, "*");
7612 vty_out(vty, ">");
7613 vty_out(vty, " ");
7614 }
7615
7616 /* print prefix and mask */
7617 if (use_json) {
7618 if (safi == SAFI_EVPN)
7619 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
7620 else if (p->family == AF_INET || p->family == AF_INET6) {
7621 json_object_string_add(
7622 json_net, "addrPrefix",
7623 inet_ntop(p->family, &p->u.prefix, buff,
7624 BUFSIZ));
7625 json_object_int_add(json_net, "prefixLen",
7626 p->prefixlen);
7627 prefix2str(p, buff, PREFIX_STRLEN);
7628 json_object_string_add(json_net, "network", buff);
7629 }
7630 } else
7631 route_vty_out_route(p, vty, NULL);
7632
7633 /* Print attribute */
7634 if (attr) {
7635 if (use_json) {
7636 if (p->family == AF_INET
7637 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7638 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7639 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
7640 json_object_string_add(
7641 json_net, "nextHop",
7642 inet_ntoa(
7643 attr->mp_nexthop_global_in));
7644 else
7645 json_object_string_add(
7646 json_net, "nextHop",
7647 inet_ntoa(attr->nexthop));
7648 } else if (p->family == AF_INET6
7649 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7650 char buf[BUFSIZ];
7651
7652 json_object_string_add(
7653 json_net, "nextHopGlobal",
7654 inet_ntop(AF_INET6,
7655 &attr->mp_nexthop_global, buf,
7656 BUFSIZ));
7657 } else if (p->family == AF_EVPN &&
7658 !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7659 json_object_string_add(json_net,
7660 "nextHop", inet_ntoa(
7661 attr->mp_nexthop_global_in));
7662
7663 if (attr->flag
7664 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7665 json_object_int_add(json_net, "metric",
7666 attr->med);
7667
7668 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
7669
7670 /*
7671 * Adding "locPrf" field to match with
7672 * corresponding CLI. "localPref" will be
7673 * deprecated in future.
7674 */
7675 json_object_int_add(json_net, "localPref",
7676 attr->local_pref);
7677 json_object_int_add(json_net, "locPrf",
7678 attr->local_pref);
7679 }
7680
7681 json_object_int_add(json_net, "weight", attr->weight);
7682
7683 /* Print aspath */
7684 if (attr->aspath) {
7685
7686 /*
7687 * Adding "path" field to match with
7688 * corresponding CLI. "localPref" will be
7689 * deprecated in future.
7690 */
7691 json_object_string_add(json_net, "asPath",
7692 attr->aspath->str);
7693 json_object_string_add(json_net, "path",
7694 attr->aspath->str);
7695 }
7696
7697 /* Print origin */
7698 json_object_string_add(json_net, "bgpOriginCode",
7699 bgp_origin_str[attr->origin]);
7700 } else {
7701 if (p->family == AF_INET
7702 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7703 || safi == SAFI_EVPN
7704 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7705 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7706 || safi == SAFI_EVPN)
7707 vty_out(vty, "%-16s",
7708 inet_ntoa(
7709 attr->mp_nexthop_global_in));
7710 else
7711 vty_out(vty, "%-16s",
7712 inet_ntoa(attr->nexthop));
7713 } else if (p->family == AF_INET6
7714 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7715 int len;
7716 char buf[BUFSIZ];
7717
7718 len = vty_out(
7719 vty, "%s",
7720 inet_ntop(AF_INET6,
7721 &attr->mp_nexthop_global, buf,
7722 BUFSIZ));
7723 len = 16 - len;
7724 if (len < 1)
7725 vty_out(vty, "\n%*s", 36, " ");
7726 else
7727 vty_out(vty, "%*s", len, " ");
7728 }
7729 if (attr->flag
7730 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7731 vty_out(vty, "%10u", attr->med);
7732 else
7733 vty_out(vty, " ");
7734
7735 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
7736 vty_out(vty, "%7u", attr->local_pref);
7737 else
7738 vty_out(vty, " ");
7739
7740 vty_out(vty, "%7u ", attr->weight);
7741
7742 /* Print aspath */
7743 if (attr->aspath)
7744 aspath_print_vty(vty, "%s", attr->aspath, " ");
7745
7746 /* Print origin */
7747 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7748 }
7749 }
7750 if (use_json) {
7751 json_object_boolean_true_add(json_status, "*");
7752 json_object_boolean_true_add(json_status, ">");
7753 json_object_object_add(json_net, "appliedStatusSymbols",
7754 json_status);
7755
7756 prefix2str(p, buff, PREFIX_STRLEN);
7757 json_object_object_add(json_ar, buff, json_net);
7758 } else
7759 vty_out(vty, "\n");
7760 }
7761
7762 void route_vty_out_tag(struct vty *vty, struct prefix *p,
7763 struct bgp_path_info *path, int display, safi_t safi,
7764 json_object *json)
7765 {
7766 json_object *json_out = NULL;
7767 struct attr *attr;
7768 mpls_label_t label = MPLS_INVALID_LABEL;
7769
7770 if (!path->extra)
7771 return;
7772
7773 if (json)
7774 json_out = json_object_new_object();
7775
7776 /* short status lead text */
7777 route_vty_short_status_out(vty, path, json_out);
7778
7779 /* print prefix and mask */
7780 if (json == NULL) {
7781 if (!display)
7782 route_vty_out_route(p, vty, NULL);
7783 else
7784 vty_out(vty, "%*s", 17, " ");
7785 }
7786
7787 /* Print attribute */
7788 attr = path->attr;
7789 if (((p->family == AF_INET)
7790 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
7791 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7792 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7793 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7794 || safi == SAFI_EVPN) {
7795 if (json)
7796 json_object_string_add(
7797 json_out, "mpNexthopGlobalIn",
7798 inet_ntoa(attr->mp_nexthop_global_in));
7799 else
7800 vty_out(vty, "%-16s",
7801 inet_ntoa(attr->mp_nexthop_global_in));
7802 } else {
7803 if (json)
7804 json_object_string_add(
7805 json_out, "nexthop",
7806 inet_ntoa(attr->nexthop));
7807 else
7808 vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
7809 }
7810 } else if (((p->family == AF_INET6)
7811 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
7812 || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7813 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7814 char buf_a[512];
7815
7816 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
7817 if (json)
7818 json_object_string_add(
7819 json_out, "mpNexthopGlobalIn",
7820 inet_ntop(AF_INET6,
7821 &attr->mp_nexthop_global,
7822 buf_a, sizeof(buf_a)));
7823 else
7824 vty_out(vty, "%s",
7825 inet_ntop(AF_INET6,
7826 &attr->mp_nexthop_global,
7827 buf_a, sizeof(buf_a)));
7828 } else if (attr->mp_nexthop_len
7829 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
7830 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
7831 &attr->mp_nexthop_global,
7832 &attr->mp_nexthop_local);
7833 if (json)
7834 json_object_string_add(json_out,
7835 "mpNexthopGlobalLocal",
7836 buf_a);
7837 else
7838 vty_out(vty, "%s", buf_a);
7839 }
7840 }
7841
7842 label = decode_label(&path->extra->label[0]);
7843
7844 if (bgp_is_valid_label(&label)) {
7845 if (json) {
7846 json_object_int_add(json_out, "notag", label);
7847 json_object_array_add(json, json_out);
7848 } else {
7849 vty_out(vty, "notag/%d", label);
7850 vty_out(vty, "\n");
7851 }
7852 }
7853 }
7854
7855 void route_vty_out_overlay(struct vty *vty, struct prefix *p,
7856 struct bgp_path_info *path, int display,
7857 json_object *json_paths)
7858 {
7859 struct attr *attr;
7860 char buf[BUFSIZ] = {0};
7861 json_object *json_path = NULL;
7862 json_object *json_nexthop = NULL;
7863 json_object *json_overlay = NULL;
7864
7865 if (!path->extra)
7866 return;
7867
7868 if (json_paths) {
7869 json_path = json_object_new_object();
7870 json_overlay = json_object_new_object();
7871 json_nexthop = json_object_new_object();
7872 }
7873
7874 /* short status lead text */
7875 route_vty_short_status_out(vty, path, json_path);
7876
7877 /* print prefix and mask */
7878 if (!display)
7879 route_vty_out_route(p, vty, json_path);
7880 else
7881 vty_out(vty, "%*s", 17, " ");
7882
7883 /* Print attribute */
7884 attr = path->attr;
7885 char buf1[BUFSIZ];
7886 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
7887
7888 switch (af) {
7889 case AF_INET:
7890 inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ);
7891 if (!json_path) {
7892 vty_out(vty, "%-16s", buf);
7893 } else {
7894 json_object_string_add(json_nexthop, "ip", buf);
7895
7896 json_object_string_add(json_nexthop, "afi", "ipv4");
7897
7898 json_object_object_add(json_path, "nexthop",
7899 json_nexthop);
7900 }
7901 break;
7902 case AF_INET6:
7903 inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ);
7904 inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ);
7905 if (!json_path) {
7906 vty_out(vty, "%s(%s)", buf, buf1);
7907 } else {
7908 json_object_string_add(json_nexthop, "ipv6Global", buf);
7909
7910 json_object_string_add(json_nexthop, "ipv6LinkLocal",
7911 buf1);
7912
7913 json_object_string_add(json_nexthop, "afi", "ipv6");
7914
7915 json_object_object_add(json_path, "nexthop",
7916 json_nexthop);
7917 }
7918 break;
7919 default:
7920 if (!json_path) {
7921 vty_out(vty, "?");
7922 } else {
7923 json_object_string_add(json_nexthop, "Error",
7924 "Unsupported address-family");
7925 }
7926 }
7927
7928 char *str = esi2str(&(attr->evpn_overlay.eth_s_id));
7929
7930 if (!json_path)
7931 vty_out(vty, "%s", str);
7932 else
7933 json_object_string_add(json_overlay, "esi", str);
7934
7935 XFREE(MTYPE_TMP, str);
7936
7937 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) {
7938 inet_ntop(AF_INET, &(attr->evpn_overlay.gw_ip.ipv4), buf,
7939 BUFSIZ);
7940 } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) {
7941 inet_ntop(AF_INET6, &(attr->evpn_overlay.gw_ip.ipv6), buf,
7942 BUFSIZ);
7943 }
7944
7945 if (!json_path)
7946 vty_out(vty, "/%s", buf);
7947 else
7948 json_object_string_add(json_overlay, "gw", buf);
7949
7950 if (attr->ecommunity) {
7951 char *mac = NULL;
7952 struct ecommunity_val *routermac = ecommunity_lookup(
7953 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
7954 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
7955
7956 if (routermac)
7957 mac = ecom_mac2str((char *)routermac->val);
7958 if (mac) {
7959 if (!json_path) {
7960 vty_out(vty, "/%s", (char *)mac);
7961 } else {
7962 json_object_string_add(json_overlay, "rmac",
7963 mac);
7964 }
7965 XFREE(MTYPE_TMP, mac);
7966 }
7967 }
7968
7969 if (!json_path) {
7970 vty_out(vty, "\n");
7971 } else {
7972 json_object_object_add(json_path, "overlay", json_overlay);
7973
7974 json_object_array_add(json_paths, json_path);
7975 }
7976 }
7977
7978 /* dampening route */
7979 static void damp_route_vty_out(struct vty *vty, struct prefix *p,
7980 struct bgp_path_info *path, int display, afi_t afi,
7981 safi_t safi, bool use_json, json_object *json)
7982 {
7983 struct attr *attr;
7984 int len;
7985 char timebuf[BGP_UPTIME_LEN];
7986
7987 /* short status lead text */
7988 route_vty_short_status_out(vty, path, json);
7989
7990 /* print prefix and mask */
7991 if (!use_json) {
7992 if (!display)
7993 route_vty_out_route(p, vty, NULL);
7994 else
7995 vty_out(vty, "%*s", 17, " ");
7996 }
7997
7998 len = vty_out(vty, "%s", path->peer->host);
7999 len = 17 - len;
8000 if (len < 1) {
8001 if (!use_json)
8002 vty_out(vty, "\n%*s", 34, " ");
8003 } else {
8004 if (use_json)
8005 json_object_int_add(json, "peerHost", len);
8006 else
8007 vty_out(vty, "%*s", len, " ");
8008 }
8009
8010 if (use_json)
8011 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
8012 safi, use_json, json);
8013 else
8014 vty_out(vty, "%s ",
8015 bgp_damp_reuse_time_vty(vty, path, timebuf,
8016 BGP_UPTIME_LEN, afi, safi,
8017 use_json, json));
8018
8019 /* Print attribute */
8020 attr = path->attr;
8021
8022 /* Print aspath */
8023 if (attr->aspath) {
8024 if (use_json)
8025 json_object_string_add(json, "asPath",
8026 attr->aspath->str);
8027 else
8028 aspath_print_vty(vty, "%s", attr->aspath, " ");
8029 }
8030
8031 /* Print origin */
8032 if (use_json)
8033 json_object_string_add(json, "origin",
8034 bgp_origin_str[attr->origin]);
8035 else
8036 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8037
8038 if (!use_json)
8039 vty_out(vty, "\n");
8040 }
8041
8042 /* flap route */
8043 static void flap_route_vty_out(struct vty *vty, struct prefix *p,
8044 struct bgp_path_info *path, int display, afi_t afi,
8045 safi_t safi, bool use_json, json_object *json)
8046 {
8047 struct attr *attr;
8048 struct bgp_damp_info *bdi;
8049 char timebuf[BGP_UPTIME_LEN];
8050 int len;
8051
8052 if (!path->extra)
8053 return;
8054
8055 bdi = path->extra->damp_info;
8056
8057 /* short status lead text */
8058 route_vty_short_status_out(vty, path, json);
8059
8060 /* print prefix and mask */
8061 if (!use_json) {
8062 if (!display)
8063 route_vty_out_route(p, vty, NULL);
8064 else
8065 vty_out(vty, "%*s", 17, " ");
8066 }
8067
8068 len = vty_out(vty, "%s", path->peer->host);
8069 len = 16 - len;
8070 if (len < 1) {
8071 if (!use_json)
8072 vty_out(vty, "\n%*s", 33, " ");
8073 } else {
8074 if (use_json)
8075 json_object_int_add(json, "peerHost", len);
8076 else
8077 vty_out(vty, "%*s", len, " ");
8078 }
8079
8080 len = vty_out(vty, "%d", bdi->flap);
8081 len = 5 - len;
8082 if (len < 1) {
8083 if (!use_json)
8084 vty_out(vty, " ");
8085 } else {
8086 if (use_json)
8087 json_object_int_add(json, "bdiFlap", len);
8088 else
8089 vty_out(vty, "%*s", len, " ");
8090 }
8091
8092 if (use_json)
8093 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
8094 json);
8095 else
8096 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
8097 BGP_UPTIME_LEN, 0, NULL));
8098
8099 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
8100 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8101 if (use_json)
8102 bgp_damp_reuse_time_vty(vty, path, timebuf,
8103 BGP_UPTIME_LEN, afi, safi,
8104 use_json, json);
8105 else
8106 vty_out(vty, "%s ",
8107 bgp_damp_reuse_time_vty(vty, path, timebuf,
8108 BGP_UPTIME_LEN, afi,
8109 safi, use_json, json));
8110 } else {
8111 if (!use_json)
8112 vty_out(vty, "%*s ", 8, " ");
8113 }
8114
8115 /* Print attribute */
8116 attr = path->attr;
8117
8118 /* Print aspath */
8119 if (attr->aspath) {
8120 if (use_json)
8121 json_object_string_add(json, "asPath",
8122 attr->aspath->str);
8123 else
8124 aspath_print_vty(vty, "%s", attr->aspath, " ");
8125 }
8126
8127 /* Print origin */
8128 if (use_json)
8129 json_object_string_add(json, "origin",
8130 bgp_origin_str[attr->origin]);
8131 else
8132 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8133
8134 if (!use_json)
8135 vty_out(vty, "\n");
8136 }
8137
8138 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
8139 int *first, const char *header,
8140 json_object *json_adv_to)
8141 {
8142 char buf1[INET6_ADDRSTRLEN];
8143 json_object *json_peer = NULL;
8144
8145 if (json_adv_to) {
8146 /* 'advertised-to' is a dictionary of peers we have advertised
8147 * this
8148 * prefix too. The key is the peer's IP or swpX, the value is
8149 * the
8150 * hostname if we know it and "" if not.
8151 */
8152 json_peer = json_object_new_object();
8153
8154 if (peer->hostname)
8155 json_object_string_add(json_peer, "hostname",
8156 peer->hostname);
8157
8158 if (peer->conf_if)
8159 json_object_object_add(json_adv_to, peer->conf_if,
8160 json_peer);
8161 else
8162 json_object_object_add(
8163 json_adv_to,
8164 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
8165 json_peer);
8166 } else {
8167 if (*first) {
8168 vty_out(vty, "%s", header);
8169 *first = 0;
8170 }
8171
8172 if (peer->hostname
8173 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
8174 if (peer->conf_if)
8175 vty_out(vty, " %s(%s)", peer->hostname,
8176 peer->conf_if);
8177 else
8178 vty_out(vty, " %s(%s)", peer->hostname,
8179 sockunion2str(&peer->su, buf1,
8180 SU_ADDRSTRLEN));
8181 } else {
8182 if (peer->conf_if)
8183 vty_out(vty, " %s", peer->conf_if);
8184 else
8185 vty_out(vty, " %s",
8186 sockunion2str(&peer->su, buf1,
8187 SU_ADDRSTRLEN));
8188 }
8189 }
8190 }
8191
8192 static void route_vty_out_tx_ids(struct vty *vty,
8193 struct bgp_addpath_info_data *d)
8194 {
8195 int i;
8196
8197 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
8198 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
8199 d->addpath_tx_id[i],
8200 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
8201 }
8202 }
8203
8204 static const char *bgp_path_selection_reason2str(
8205 enum bgp_path_selection_reason reason)
8206 {
8207 switch (reason) {
8208 case bgp_path_selection_none:
8209 return "Nothing to Select";
8210 break;
8211 case bgp_path_selection_first:
8212 return "First path received";
8213 break;
8214 case bgp_path_selection_evpn_sticky_mac:
8215 return "EVPN Sticky Mac";
8216 break;
8217 case bgp_path_selection_evpn_seq:
8218 return "EVPN sequence number";
8219 break;
8220 case bgp_path_selection_evpn_lower_ip:
8221 return "EVPN lower IP";
8222 break;
8223 case bgp_path_selection_weight:
8224 return "Weight";
8225 break;
8226 case bgp_path_selection_local_pref:
8227 return "Local Pref";
8228 break;
8229 case bgp_path_selection_local_route:
8230 return "Local Route";
8231 break;
8232 case bgp_path_selection_confed_as_path:
8233 return "Confederation based AS Path";
8234 break;
8235 case bgp_path_selection_as_path:
8236 return "AS Path";
8237 break;
8238 case bgp_path_selection_origin:
8239 return "Origin";
8240 break;
8241 case bgp_path_selection_med:
8242 return "MED";
8243 break;
8244 case bgp_path_selection_peer:
8245 return "Peer Type";
8246 break;
8247 case bgp_path_selection_confed:
8248 return "Confed Peer Type";
8249 break;
8250 case bgp_path_selection_igp_metric:
8251 return "IGP Metric";
8252 break;
8253 case bgp_path_selection_older:
8254 return "Older Path";
8255 break;
8256 case bgp_path_selection_router_id:
8257 return "Router ID";
8258 break;
8259 case bgp_path_selection_cluster_length:
8260 return "Cluser length";
8261 break;
8262 case bgp_path_selection_stale:
8263 return "Path Staleness";
8264 break;
8265 case bgp_path_selection_local_configured:
8266 return "Locally configured route";
8267 break;
8268 case bgp_path_selection_neighbor_ip:
8269 return "Neighbor IP";
8270 break;
8271 case bgp_path_selection_default:
8272 return "Nothing left to compare";
8273 break;
8274 }
8275 return "Invalid (internal error)";
8276 }
8277
8278 void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
8279 struct bgp_node *bn, struct bgp_path_info *path,
8280 afi_t afi, safi_t safi, json_object *json_paths)
8281 {
8282 char buf[INET6_ADDRSTRLEN];
8283 char buf1[BUFSIZ];
8284 char buf2[EVPN_ROUTE_STRLEN];
8285 struct attr *attr = path->attr;
8286 int sockunion_vty_out(struct vty *, union sockunion *);
8287 time_t tbuf;
8288 json_object *json_bestpath = NULL;
8289 json_object *json_cluster_list = NULL;
8290 json_object *json_cluster_list_list = NULL;
8291 json_object *json_ext_community = NULL;
8292 json_object *json_last_update = NULL;
8293 json_object *json_pmsi = NULL;
8294 json_object *json_nexthop_global = NULL;
8295 json_object *json_nexthop_ll = NULL;
8296 json_object *json_nexthops = NULL;
8297 json_object *json_path = NULL;
8298 json_object *json_peer = NULL;
8299 json_object *json_string = NULL;
8300 json_object *json_adv_to = NULL;
8301 int first = 0;
8302 struct listnode *node, *nnode;
8303 struct peer *peer;
8304 int addpath_capable;
8305 int has_adj;
8306 unsigned int first_as;
8307 bool nexthop_self =
8308 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8309 int i;
8310 char *nexthop_hostname = bgp_nexthop_hostname(path->peer, attr);
8311
8312 if (json_paths) {
8313 json_path = json_object_new_object();
8314 json_peer = json_object_new_object();
8315 json_nexthop_global = json_object_new_object();
8316 }
8317
8318 if (path->extra) {
8319 char tag_buf[30];
8320
8321 buf2[0] = '\0';
8322 tag_buf[0] = '\0';
8323 if (path->extra && path->extra->num_labels) {
8324 bgp_evpn_label2str(path->extra->label,
8325 path->extra->num_labels, tag_buf,
8326 sizeof(tag_buf));
8327 }
8328 if (safi == SAFI_EVPN) {
8329 if (!json_paths) {
8330 bgp_evpn_route2str((struct prefix_evpn *)&bn->p,
8331 buf2, sizeof(buf2));
8332 vty_out(vty, " Route %s", buf2);
8333 if (tag_buf[0] != '\0')
8334 vty_out(vty, " VNI %s", tag_buf);
8335 vty_out(vty, "\n");
8336 } else {
8337 if (tag_buf[0])
8338 json_object_string_add(json_path, "VNI",
8339 tag_buf);
8340 }
8341 }
8342
8343 if (path->extra && path->extra->parent && !json_paths) {
8344 struct bgp_path_info *parent_ri;
8345 struct bgp_node *rn, *prn;
8346
8347 parent_ri = (struct bgp_path_info *)path->extra->parent;
8348 rn = parent_ri->net;
8349 if (rn && rn->prn) {
8350 prn = rn->prn;
8351 prefix_rd2str((struct prefix_rd *)&prn->p,
8352 buf1, sizeof(buf1));
8353 if (is_pi_family_evpn(parent_ri)) {
8354 bgp_evpn_route2str((struct prefix_evpn *)&rn->p,
8355 buf2, sizeof(buf2));
8356 vty_out(vty, " Imported from %s:%s, VNI %s\n", buf1, buf2, tag_buf);
8357 } else
8358 vty_out(vty, " Imported from %s:%s\n", buf1, buf2);
8359 }
8360 }
8361 }
8362
8363 /* Line1 display AS-path, Aggregator */
8364 if (attr->aspath) {
8365 if (json_paths) {
8366 if (!attr->aspath->json)
8367 aspath_str_update(attr->aspath, true);
8368 json_object_lock(attr->aspath->json);
8369 json_object_object_add(json_path, "aspath",
8370 attr->aspath->json);
8371 } else {
8372 if (attr->aspath->segments)
8373 aspath_print_vty(vty, " %s", attr->aspath, "");
8374 else
8375 vty_out(vty, " Local");
8376 }
8377 }
8378
8379 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
8380 if (json_paths)
8381 json_object_boolean_true_add(json_path, "removed");
8382 else
8383 vty_out(vty, ", (removed)");
8384 }
8385
8386 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
8387 if (json_paths)
8388 json_object_boolean_true_add(json_path, "stale");
8389 else
8390 vty_out(vty, ", (stale)");
8391 }
8392
8393 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
8394 if (json_paths) {
8395 json_object_int_add(json_path, "aggregatorAs",
8396 attr->aggregator_as);
8397 json_object_string_add(
8398 json_path, "aggregatorId",
8399 inet_ntoa(attr->aggregator_addr));
8400 } else {
8401 vty_out(vty, ", (aggregated by %u %s)",
8402 attr->aggregator_as,
8403 inet_ntoa(attr->aggregator_addr));
8404 }
8405 }
8406
8407 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
8408 PEER_FLAG_REFLECTOR_CLIENT)) {
8409 if (json_paths)
8410 json_object_boolean_true_add(json_path,
8411 "rxedFromRrClient");
8412 else
8413 vty_out(vty, ", (Received from a RR-client)");
8414 }
8415
8416 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
8417 PEER_FLAG_RSERVER_CLIENT)) {
8418 if (json_paths)
8419 json_object_boolean_true_add(json_path,
8420 "rxedFromRsClient");
8421 else
8422 vty_out(vty, ", (Received from a RS-client)");
8423 }
8424
8425 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8426 if (json_paths)
8427 json_object_boolean_true_add(json_path,
8428 "dampeningHistoryEntry");
8429 else
8430 vty_out(vty, ", (history entry)");
8431 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
8432 if (json_paths)
8433 json_object_boolean_true_add(json_path,
8434 "dampeningSuppressed");
8435 else
8436 vty_out(vty, ", (suppressed due to dampening)");
8437 }
8438
8439 if (!json_paths)
8440 vty_out(vty, "\n");
8441
8442 /* Line2 display Next-hop, Neighbor, Router-id */
8443 /* Display the nexthop */
8444 if ((bn->p.family == AF_INET || bn->p.family == AF_ETHERNET
8445 || bn->p.family == AF_EVPN)
8446 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
8447 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8448 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8449 || safi == SAFI_EVPN) {
8450 if (json_paths) {
8451 json_object_string_add(
8452 json_nexthop_global, "ip",
8453 inet_ntoa(attr->mp_nexthop_global_in));
8454
8455 if (nexthop_hostname)
8456 json_object_string_add(
8457 json_nexthop_global, "hostname",
8458 nexthop_hostname);
8459 } else
8460 vty_out(vty, " %s",
8461 nexthop_hostname
8462 ? nexthop_hostname
8463 : inet_ntoa(
8464 attr->mp_nexthop_global_in));
8465 } else {
8466 if (json_paths) {
8467 json_object_string_add(
8468 json_nexthop_global, "ip",
8469 inet_ntoa(attr->nexthop));
8470
8471 if (nexthop_hostname)
8472 json_object_string_add(
8473 json_nexthop_global, "hostname",
8474 nexthop_hostname);
8475 } else
8476 vty_out(vty, " %s",
8477 nexthop_hostname
8478 ? nexthop_hostname
8479 : inet_ntoa(attr->nexthop));
8480 }
8481
8482 if (json_paths)
8483 json_object_string_add(json_nexthop_global, "afi",
8484 "ipv4");
8485 } else {
8486 if (json_paths) {
8487 json_object_string_add(
8488 json_nexthop_global, "ip",
8489 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
8490 buf, INET6_ADDRSTRLEN));
8491
8492 if (nexthop_hostname)
8493 json_object_string_add(json_nexthop_global,
8494 "hostname",
8495 nexthop_hostname);
8496
8497 json_object_string_add(json_nexthop_global, "afi",
8498 "ipv6");
8499 json_object_string_add(json_nexthop_global, "scope",
8500 "global");
8501 } else {
8502 vty_out(vty, " %s",
8503 nexthop_hostname
8504 ? nexthop_hostname
8505 : inet_ntop(AF_INET6,
8506 &attr->mp_nexthop_global,
8507 buf, INET6_ADDRSTRLEN));
8508 }
8509 }
8510
8511 /* Display the IGP cost or 'inaccessible' */
8512 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
8513 if (json_paths)
8514 json_object_boolean_false_add(json_nexthop_global,
8515 "accessible");
8516 else
8517 vty_out(vty, " (inaccessible)");
8518 } else {
8519 if (path->extra && path->extra->igpmetric) {
8520 if (json_paths)
8521 json_object_int_add(json_nexthop_global,
8522 "metric",
8523 path->extra->igpmetric);
8524 else
8525 vty_out(vty, " (metric %u)",
8526 path->extra->igpmetric);
8527 }
8528
8529 /* IGP cost is 0, display this only for json */
8530 else {
8531 if (json_paths)
8532 json_object_int_add(json_nexthop_global,
8533 "metric", 0);
8534 }
8535
8536 if (json_paths)
8537 json_object_boolean_true_add(json_nexthop_global,
8538 "accessible");
8539 }
8540
8541 /* Display peer "from" output */
8542 /* This path was originated locally */
8543 if (path->peer == bgp->peer_self) {
8544
8545 if (safi == SAFI_EVPN
8546 || (bn->p.family == AF_INET
8547 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8548 if (json_paths)
8549 json_object_string_add(json_peer, "peerId",
8550 "0.0.0.0");
8551 else
8552 vty_out(vty, " from 0.0.0.0 ");
8553 } else {
8554 if (json_paths)
8555 json_object_string_add(json_peer, "peerId",
8556 "::");
8557 else
8558 vty_out(vty, " from :: ");
8559 }
8560
8561 if (json_paths)
8562 json_object_string_add(json_peer, "routerId",
8563 inet_ntoa(bgp->router_id));
8564 else
8565 vty_out(vty, "(%s)", inet_ntoa(bgp->router_id));
8566 }
8567
8568 /* We RXed this path from one of our peers */
8569 else {
8570
8571 if (json_paths) {
8572 json_object_string_add(json_peer, "peerId",
8573 sockunion2str(&path->peer->su,
8574 buf,
8575 SU_ADDRSTRLEN));
8576 json_object_string_add(json_peer, "routerId",
8577 inet_ntop(AF_INET,
8578 &path->peer->remote_id,
8579 buf1, sizeof(buf1)));
8580
8581 if (path->peer->hostname)
8582 json_object_string_add(json_peer, "hostname",
8583 path->peer->hostname);
8584
8585 if (path->peer->domainname)
8586 json_object_string_add(json_peer, "domainname",
8587 path->peer->domainname);
8588
8589 if (path->peer->conf_if)
8590 json_object_string_add(json_peer, "interface",
8591 path->peer->conf_if);
8592 } else {
8593 if (path->peer->conf_if) {
8594 if (path->peer->hostname
8595 && bgp_flag_check(path->peer->bgp,
8596 BGP_FLAG_SHOW_HOSTNAME))
8597 vty_out(vty, " from %s(%s)",
8598 path->peer->hostname,
8599 path->peer->conf_if);
8600 else
8601 vty_out(vty, " from %s",
8602 path->peer->conf_if);
8603 } else {
8604 if (path->peer->hostname
8605 && bgp_flag_check(path->peer->bgp,
8606 BGP_FLAG_SHOW_HOSTNAME))
8607 vty_out(vty, " from %s(%s)",
8608 path->peer->hostname,
8609 path->peer->host);
8610 else
8611 vty_out(vty, " from %s",
8612 sockunion2str(&path->peer->su,
8613 buf,
8614 SU_ADDRSTRLEN));
8615 }
8616
8617 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
8618 vty_out(vty, " (%s)",
8619 inet_ntoa(attr->originator_id));
8620 else
8621 vty_out(vty, " (%s)",
8622 inet_ntop(AF_INET,
8623 &path->peer->remote_id, buf1,
8624 sizeof(buf1)));
8625 }
8626 }
8627
8628 /*
8629 * Note when vrfid of nexthop is different from that of prefix
8630 */
8631 if (path->extra && path->extra->bgp_orig) {
8632 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
8633
8634 if (json_paths) {
8635 const char *vn;
8636
8637 if (path->extra->bgp_orig->inst_type
8638 == BGP_INSTANCE_TYPE_DEFAULT)
8639 vn = VRF_DEFAULT_NAME;
8640 else
8641 vn = path->extra->bgp_orig->name;
8642
8643 json_object_string_add(json_path, "nhVrfName", vn);
8644
8645 if (nexthop_vrfid == VRF_UNKNOWN) {
8646 json_object_int_add(json_path, "nhVrfId", -1);
8647 } else {
8648 json_object_int_add(json_path, "nhVrfId",
8649 (int)nexthop_vrfid);
8650 }
8651 } else {
8652 if (nexthop_vrfid == VRF_UNKNOWN)
8653 vty_out(vty, " vrf ?");
8654 else
8655 vty_out(vty, " vrf %u", nexthop_vrfid);
8656 }
8657 }
8658
8659 if (nexthop_self) {
8660 if (json_paths) {
8661 json_object_boolean_true_add(json_path,
8662 "announceNexthopSelf");
8663 } else {
8664 vty_out(vty, " announce-nh-self");
8665 }
8666 }
8667
8668 if (!json_paths)
8669 vty_out(vty, "\n");
8670
8671 /* display the link-local nexthop */
8672 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
8673 if (json_paths) {
8674 json_nexthop_ll = json_object_new_object();
8675 json_object_string_add(
8676 json_nexthop_ll, "ip",
8677 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
8678 buf, INET6_ADDRSTRLEN));
8679
8680 if (nexthop_hostname)
8681 json_object_string_add(json_nexthop_ll,
8682 "hostname",
8683 nexthop_hostname);
8684
8685 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
8686 json_object_string_add(json_nexthop_ll, "scope",
8687 "link-local");
8688
8689 json_object_boolean_true_add(json_nexthop_ll,
8690 "accessible");
8691
8692 if (!attr->mp_nexthop_prefer_global)
8693 json_object_boolean_true_add(json_nexthop_ll,
8694 "used");
8695 else
8696 json_object_boolean_true_add(
8697 json_nexthop_global, "used");
8698 } else {
8699 vty_out(vty, " (%s) %s\n",
8700 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
8701 buf, INET6_ADDRSTRLEN),
8702 attr->mp_nexthop_prefer_global
8703 ? "(prefer-global)"
8704 : "(used)");
8705 }
8706 }
8707 /* If we do not have a link-local nexthop then we must flag the
8708 global as "used" */
8709 else {
8710 if (json_paths)
8711 json_object_boolean_true_add(json_nexthop_global,
8712 "used");
8713 }
8714
8715 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
8716 * Int/Ext/Local, Atomic, best */
8717 if (json_paths)
8718 json_object_string_add(json_path, "origin",
8719 bgp_origin_long_str[attr->origin]);
8720 else
8721 vty_out(vty, " Origin %s",
8722 bgp_origin_long_str[attr->origin]);
8723
8724 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
8725 if (json_paths) {
8726 /*
8727 * Adding "metric" field to match with
8728 * corresponding CLI. "med" will be
8729 * deprecated in future.
8730 */
8731 json_object_int_add(json_path, "med", attr->med);
8732 json_object_int_add(json_path, "metric", attr->med);
8733 } else
8734 vty_out(vty, ", metric %u", attr->med);
8735 }
8736
8737 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
8738 if (json_paths)
8739 json_object_int_add(json_path, "localpref",
8740 attr->local_pref);
8741 else
8742 vty_out(vty, ", localpref %u", attr->local_pref);
8743 }
8744
8745 if (attr->weight != 0) {
8746 if (json_paths)
8747 json_object_int_add(json_path, "weight", attr->weight);
8748 else
8749 vty_out(vty, ", weight %u", attr->weight);
8750 }
8751
8752 if (attr->tag != 0) {
8753 if (json_paths)
8754 json_object_int_add(json_path, "tag", attr->tag);
8755 else
8756 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
8757 }
8758
8759 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
8760 if (json_paths)
8761 json_object_boolean_false_add(json_path, "valid");
8762 else
8763 vty_out(vty, ", invalid");
8764 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8765 if (json_paths)
8766 json_object_boolean_true_add(json_path, "valid");
8767 else
8768 vty_out(vty, ", valid");
8769 }
8770
8771 if (path->peer != bgp->peer_self) {
8772 if (path->peer->as == path->peer->local_as) {
8773 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
8774 if (json_paths)
8775 json_object_string_add(
8776 json_peer, "type",
8777 "confed-internal");
8778 else
8779 vty_out(vty, ", confed-internal");
8780 } else {
8781 if (json_paths)
8782 json_object_string_add(
8783 json_peer, "type", "internal");
8784 else
8785 vty_out(vty, ", internal");
8786 }
8787 } else {
8788 if (bgp_confederation_peers_check(bgp,
8789 path->peer->as)) {
8790 if (json_paths)
8791 json_object_string_add(
8792 json_peer, "type",
8793 "confed-external");
8794 else
8795 vty_out(vty, ", confed-external");
8796 } else {
8797 if (json_paths)
8798 json_object_string_add(
8799 json_peer, "type", "external");
8800 else
8801 vty_out(vty, ", external");
8802 }
8803 }
8804 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
8805 if (json_paths) {
8806 json_object_boolean_true_add(json_path, "aggregated");
8807 json_object_boolean_true_add(json_path, "local");
8808 } else {
8809 vty_out(vty, ", aggregated, local");
8810 }
8811 } else if (path->type != ZEBRA_ROUTE_BGP) {
8812 if (json_paths)
8813 json_object_boolean_true_add(json_path, "sourced");
8814 else
8815 vty_out(vty, ", sourced");
8816 } else {
8817 if (json_paths) {
8818 json_object_boolean_true_add(json_path, "sourced");
8819 json_object_boolean_true_add(json_path, "local");
8820 } else {
8821 vty_out(vty, ", sourced, local");
8822 }
8823 }
8824
8825 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
8826 if (json_paths)
8827 json_object_boolean_true_add(json_path,
8828 "atomicAggregate");
8829 else
8830 vty_out(vty, ", atomic-aggregate");
8831 }
8832
8833 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
8834 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
8835 && bgp_path_info_mpath_count(path))) {
8836 if (json_paths)
8837 json_object_boolean_true_add(json_path, "multipath");
8838 else
8839 vty_out(vty, ", multipath");
8840 }
8841
8842 // Mark the bestpath(s)
8843 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
8844 first_as = aspath_get_first_as(attr->aspath);
8845
8846 if (json_paths) {
8847 if (!json_bestpath)
8848 json_bestpath = json_object_new_object();
8849 json_object_int_add(json_bestpath, "bestpathFromAs",
8850 first_as);
8851 } else {
8852 if (first_as)
8853 vty_out(vty, ", bestpath-from-AS %u", first_as);
8854 else
8855 vty_out(vty, ", bestpath-from-AS Local");
8856 }
8857 }
8858
8859 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
8860 if (json_paths) {
8861 if (!json_bestpath)
8862 json_bestpath = json_object_new_object();
8863 json_object_boolean_true_add(json_bestpath, "overall");
8864 json_object_string_add(
8865 json_bestpath, "selectionReason",
8866 bgp_path_selection_reason2str(bn->reason));
8867 } else {
8868 vty_out(vty, ", best");
8869 vty_out(vty, " (%s)",
8870 bgp_path_selection_reason2str(bn->reason));
8871 }
8872 }
8873
8874 if (json_bestpath)
8875 json_object_object_add(json_path, "bestpath", json_bestpath);
8876
8877 if (!json_paths)
8878 vty_out(vty, "\n");
8879
8880 /* Line 4 display Community */
8881 if (attr->community) {
8882 if (json_paths) {
8883 if (!attr->community->json)
8884 community_str(attr->community, true);
8885 json_object_lock(attr->community->json);
8886 json_object_object_add(json_path, "community",
8887 attr->community->json);
8888 } else {
8889 vty_out(vty, " Community: %s\n",
8890 attr->community->str);
8891 }
8892 }
8893
8894 /* Line 5 display Extended-community */
8895 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8896 if (json_paths) {
8897 json_ext_community = json_object_new_object();
8898 json_object_string_add(json_ext_community, "string",
8899 attr->ecommunity->str);
8900 json_object_object_add(json_path, "extendedCommunity",
8901 json_ext_community);
8902 } else {
8903 vty_out(vty, " Extended Community: %s\n",
8904 attr->ecommunity->str);
8905 }
8906 }
8907
8908 /* Line 6 display Large community */
8909 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
8910 if (json_paths) {
8911 if (!attr->lcommunity->json)
8912 lcommunity_str(attr->lcommunity, true);
8913 json_object_lock(attr->lcommunity->json);
8914 json_object_object_add(json_path, "largeCommunity",
8915 attr->lcommunity->json);
8916 } else {
8917 vty_out(vty, " Large Community: %s\n",
8918 attr->lcommunity->str);
8919 }
8920 }
8921
8922 /* Line 7 display Originator, Cluster-id */
8923 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
8924 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
8925 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
8926 if (json_paths)
8927 json_object_string_add(
8928 json_path, "originatorId",
8929 inet_ntoa(attr->originator_id));
8930 else
8931 vty_out(vty, " Originator: %s",
8932 inet_ntoa(attr->originator_id));
8933 }
8934
8935 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
8936 int i;
8937
8938 if (json_paths) {
8939 json_cluster_list = json_object_new_object();
8940 json_cluster_list_list =
8941 json_object_new_array();
8942
8943 for (i = 0; i < attr->cluster->length / 4;
8944 i++) {
8945 json_string = json_object_new_string(
8946 inet_ntoa(attr->cluster
8947 ->list[i]));
8948 json_object_array_add(
8949 json_cluster_list_list,
8950 json_string);
8951 }
8952
8953 /*
8954 * struct cluster_list does not have
8955 * "str" variable like aspath and community
8956 * do. Add this someday if someone asks
8957 * for it.
8958 * json_object_string_add(json_cluster_list,
8959 * "string", attr->cluster->str);
8960 */
8961 json_object_object_add(json_cluster_list,
8962 "list",
8963 json_cluster_list_list);
8964 json_object_object_add(json_path, "clusterList",
8965 json_cluster_list);
8966 } else {
8967 vty_out(vty, ", Cluster list: ");
8968
8969 for (i = 0; i < attr->cluster->length / 4;
8970 i++) {
8971 vty_out(vty, "%s ",
8972 inet_ntoa(attr->cluster
8973 ->list[i]));
8974 }
8975 }
8976 }
8977
8978 if (!json_paths)
8979 vty_out(vty, "\n");
8980 }
8981
8982 if (path->extra && path->extra->damp_info)
8983 bgp_damp_info_vty(vty, path, afi, safi, json_path);
8984
8985 /* Remote Label */
8986 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
8987 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
8988 mpls_label_t label = label_pton(&path->extra->label[0]);
8989
8990 if (json_paths)
8991 json_object_int_add(json_path, "remoteLabel", label);
8992 else
8993 vty_out(vty, " Remote label: %d\n", label);
8994 }
8995
8996 /* Label Index */
8997 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
8998 if (json_paths)
8999 json_object_int_add(json_path, "labelIndex",
9000 attr->label_index);
9001 else
9002 vty_out(vty, " Label Index: %d\n",
9003 attr->label_index);
9004 }
9005
9006 /* Line 8 display Addpath IDs */
9007 if (path->addpath_rx_id
9008 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
9009 if (json_paths) {
9010 json_object_int_add(json_path, "addpathRxId",
9011 path->addpath_rx_id);
9012
9013 /* Keep backwards compatibility with the old API
9014 * by putting TX All's ID in the old field
9015 */
9016 json_object_int_add(
9017 json_path, "addpathTxId",
9018 path->tx_addpath
9019 .addpath_tx_id[BGP_ADDPATH_ALL]);
9020
9021 /* ... but create a specific field for each
9022 * strategy
9023 */
9024 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9025 json_object_int_add(
9026 json_path,
9027 bgp_addpath_names(i)->id_json_name,
9028 path->tx_addpath.addpath_tx_id[i]);
9029 }
9030 } else {
9031 vty_out(vty, " AddPath ID: RX %u, ",
9032 path->addpath_rx_id);
9033
9034 route_vty_out_tx_ids(vty, &path->tx_addpath);
9035 }
9036 }
9037
9038 /* If we used addpath to TX a non-bestpath we need to display
9039 * "Advertised to" on a path-by-path basis
9040 */
9041 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
9042 first = 1;
9043
9044 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
9045 addpath_capable =
9046 bgp_addpath_encode_tx(peer, afi, safi);
9047 has_adj = bgp_adj_out_lookup(
9048 peer, path->net,
9049 bgp_addpath_id_for_peer(peer, afi, safi,
9050 &path->tx_addpath));
9051
9052 if ((addpath_capable && has_adj)
9053 || (!addpath_capable && has_adj
9054 && CHECK_FLAG(path->flags,
9055 BGP_PATH_SELECTED))) {
9056 if (json_path && !json_adv_to)
9057 json_adv_to = json_object_new_object();
9058
9059 route_vty_out_advertised_to(
9060 vty, peer, &first,
9061 " Advertised to:", json_adv_to);
9062 }
9063 }
9064
9065 if (json_path) {
9066 if (json_adv_to) {
9067 json_object_object_add(
9068 json_path, "advertisedTo", json_adv_to);
9069 }
9070 } else {
9071 if (!first) {
9072 vty_out(vty, "\n");
9073 }
9074 }
9075 }
9076
9077 /* Line 9 display Uptime */
9078 tbuf = time(NULL) - (bgp_clock() - path->uptime);
9079 if (json_paths) {
9080 json_last_update = json_object_new_object();
9081 json_object_int_add(json_last_update, "epoch", tbuf);
9082 json_object_string_add(json_last_update, "string",
9083 ctime(&tbuf));
9084 json_object_object_add(json_path, "lastUpdate",
9085 json_last_update);
9086 } else
9087 vty_out(vty, " Last update: %s", ctime(&tbuf));
9088
9089 /* Line 10 display PMSI tunnel attribute, if present */
9090 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
9091 const char *str =
9092 lookup_msg(bgp_pmsi_tnltype_str, attr->pmsi_tnl_type,
9093 PMSI_TNLTYPE_STR_DEFAULT);
9094
9095 if (json_paths) {
9096 json_pmsi = json_object_new_object();
9097 json_object_string_add(json_pmsi, "tunnelType", str);
9098 json_object_int_add(json_pmsi, "label",
9099 label2vni(&attr->label));
9100 json_object_object_add(json_path, "pmsi", json_pmsi);
9101 } else
9102 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
9103 str, label2vni(&attr->label));
9104 }
9105
9106 /* We've constructed the json object for this path, add it to the json
9107 * array of paths
9108 */
9109 if (json_paths) {
9110 if (json_nexthop_global || json_nexthop_ll) {
9111 json_nexthops = json_object_new_array();
9112
9113 if (json_nexthop_global)
9114 json_object_array_add(json_nexthops,
9115 json_nexthop_global);
9116
9117 if (json_nexthop_ll)
9118 json_object_array_add(json_nexthops,
9119 json_nexthop_ll);
9120
9121 json_object_object_add(json_path, "nexthops",
9122 json_nexthops);
9123 }
9124
9125 json_object_object_add(json_path, "peer", json_peer);
9126 json_object_array_add(json_paths, json_path);
9127 }
9128 }
9129
9130 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
9131 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
9132 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
9133
9134 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
9135 const char *prefix_list_str, afi_t afi,
9136 safi_t safi, enum bgp_show_type type);
9137 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
9138 const char *filter, afi_t afi, safi_t safi,
9139 enum bgp_show_type type);
9140 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
9141 const char *rmap_str, afi_t afi, safi_t safi,
9142 enum bgp_show_type type);
9143 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
9144 const char *com, int exact, afi_t afi,
9145 safi_t safi);
9146 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
9147 const char *prefix, afi_t afi, safi_t safi,
9148 enum bgp_show_type type);
9149 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
9150 afi_t afi, safi_t safi, enum bgp_show_type type);
9151 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
9152 const char *comstr, int exact, afi_t afi,
9153 safi_t safi, bool use_json);
9154
9155
9156 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
9157 struct bgp_table *table, enum bgp_show_type type,
9158 void *output_arg, bool use_json, char *rd,
9159 int is_last, unsigned long *output_cum,
9160 unsigned long *total_cum,
9161 unsigned long *json_header_depth)
9162 {
9163 struct bgp_path_info *pi;
9164 struct bgp_node *rn;
9165 int header = 1;
9166 int display;
9167 unsigned long output_count = 0;
9168 unsigned long total_count = 0;
9169 struct prefix *p;
9170 char buf2[BUFSIZ];
9171 json_object *json_paths = NULL;
9172 int first = 1;
9173
9174 if (output_cum && *output_cum != 0)
9175 header = 0;
9176
9177 if (use_json && !*json_header_depth) {
9178 vty_out(vty,
9179 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
9180 ",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n"
9181 " \"localAS\": %u,\n \"routes\": { ",
9182 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
9183 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
9184 ? VRF_DEFAULT_NAME
9185 : bgp->name,
9186 table->version, inet_ntoa(bgp->router_id),
9187 bgp->default_local_pref, bgp->as);
9188 *json_header_depth = 2;
9189 if (rd) {
9190 vty_out(vty, " \"routeDistinguishers\" : {");
9191 ++*json_header_depth;
9192 }
9193 }
9194
9195 if (use_json && rd) {
9196 vty_out(vty, " \"%s\" : { ", rd);
9197 }
9198
9199 /* Start processing of routes. */
9200 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
9201 pi = bgp_node_get_bgp_path_info(rn);
9202 if (pi == NULL)
9203 continue;
9204
9205 display = 0;
9206 if (use_json)
9207 json_paths = json_object_new_array();
9208 else
9209 json_paths = NULL;
9210
9211 for (; pi; pi = pi->next) {
9212 total_count++;
9213 if (type == bgp_show_type_flap_statistics
9214 || type == bgp_show_type_flap_neighbor
9215 || type == bgp_show_type_dampend_paths
9216 || type == bgp_show_type_damp_neighbor) {
9217 if (!(pi->extra && pi->extra->damp_info))
9218 continue;
9219 }
9220 if (type == bgp_show_type_regexp) {
9221 regex_t *regex = output_arg;
9222
9223 if (bgp_regexec(regex, pi->attr->aspath)
9224 == REG_NOMATCH)
9225 continue;
9226 }
9227 if (type == bgp_show_type_prefix_list) {
9228 struct prefix_list *plist = output_arg;
9229
9230 if (prefix_list_apply(plist, &rn->p)
9231 != PREFIX_PERMIT)
9232 continue;
9233 }
9234 if (type == bgp_show_type_filter_list) {
9235 struct as_list *as_list = output_arg;
9236
9237 if (as_list_apply(as_list, pi->attr->aspath)
9238 != AS_FILTER_PERMIT)
9239 continue;
9240 }
9241 if (type == bgp_show_type_route_map) {
9242 struct route_map *rmap = output_arg;
9243 struct bgp_path_info path;
9244 struct attr dummy_attr;
9245 route_map_result_t ret;
9246
9247 dummy_attr = *pi->attr;
9248
9249 path.peer = pi->peer;
9250 path.attr = &dummy_attr;
9251
9252 ret = route_map_apply(rmap, &rn->p, RMAP_BGP,
9253 &path);
9254 if (ret == RMAP_DENYMATCH)
9255 continue;
9256 }
9257 if (type == bgp_show_type_neighbor
9258 || type == bgp_show_type_flap_neighbor
9259 || type == bgp_show_type_damp_neighbor) {
9260 union sockunion *su = output_arg;
9261
9262 if (pi->peer == NULL
9263 || pi->peer->su_remote == NULL
9264 || !sockunion_same(pi->peer->su_remote, su))
9265 continue;
9266 }
9267 if (type == bgp_show_type_cidr_only) {
9268 uint32_t destination;
9269
9270 destination = ntohl(rn->p.u.prefix4.s_addr);
9271 if (IN_CLASSC(destination)
9272 && rn->p.prefixlen == 24)
9273 continue;
9274 if (IN_CLASSB(destination)
9275 && rn->p.prefixlen == 16)
9276 continue;
9277 if (IN_CLASSA(destination)
9278 && rn->p.prefixlen == 8)
9279 continue;
9280 }
9281 if (type == bgp_show_type_prefix_longer) {
9282 p = output_arg;
9283 if (!prefix_match(p, &rn->p))
9284 continue;
9285 }
9286 if (type == bgp_show_type_community_all) {
9287 if (!pi->attr->community)
9288 continue;
9289 }
9290 if (type == bgp_show_type_community) {
9291 struct community *com = output_arg;
9292
9293 if (!pi->attr->community
9294 || !community_match(pi->attr->community,
9295 com))
9296 continue;
9297 }
9298 if (type == bgp_show_type_community_exact) {
9299 struct community *com = output_arg;
9300
9301 if (!pi->attr->community
9302 || !community_cmp(pi->attr->community, com))
9303 continue;
9304 }
9305 if (type == bgp_show_type_community_list) {
9306 struct community_list *list = output_arg;
9307
9308 if (!community_list_match(pi->attr->community,
9309 list))
9310 continue;
9311 }
9312 if (type == bgp_show_type_community_list_exact) {
9313 struct community_list *list = output_arg;
9314
9315 if (!community_list_exact_match(
9316 pi->attr->community, list))
9317 continue;
9318 }
9319 if (type == bgp_show_type_lcommunity) {
9320 struct lcommunity *lcom = output_arg;
9321
9322 if (!pi->attr->lcommunity
9323 || !lcommunity_match(pi->attr->lcommunity,
9324 lcom))
9325 continue;
9326 }
9327
9328 if (type == bgp_show_type_lcommunity_exact) {
9329 struct lcommunity *lcom = output_arg;
9330
9331 if (!pi->attr->lcommunity
9332 || !lcommunity_cmp(pi->attr->lcommunity,
9333 lcom))
9334 continue;
9335 }
9336 if (type == bgp_show_type_lcommunity_list) {
9337 struct community_list *list = output_arg;
9338
9339 if (!lcommunity_list_match(pi->attr->lcommunity,
9340 list))
9341 continue;
9342 }
9343 if (type
9344 == bgp_show_type_lcommunity_list_exact) {
9345 struct community_list *list = output_arg;
9346
9347 if (!lcommunity_list_exact_match(
9348 pi->attr->lcommunity, list))
9349 continue;
9350 }
9351 if (type == bgp_show_type_lcommunity_all) {
9352 if (!pi->attr->lcommunity)
9353 continue;
9354 }
9355 if (type == bgp_show_type_dampend_paths
9356 || type == bgp_show_type_damp_neighbor) {
9357 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
9358 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
9359 continue;
9360 }
9361
9362 if (!use_json && header) {
9363 vty_out(vty, "BGP table version is %" PRIu64
9364 ", local router ID is %s, vrf id ",
9365 table->version,
9366 inet_ntoa(bgp->router_id));
9367 if (bgp->vrf_id == VRF_UNKNOWN)
9368 vty_out(vty, "%s", VRFID_NONE_STR);
9369 else
9370 vty_out(vty, "%u", bgp->vrf_id);
9371 vty_out(vty, "\n");
9372 vty_out(vty, "Default local pref %u, ",
9373 bgp->default_local_pref);
9374 vty_out(vty, "local AS %u\n", bgp->as);
9375 vty_out(vty, BGP_SHOW_SCODE_HEADER);
9376 vty_out(vty, BGP_SHOW_NCODE_HEADER);
9377 vty_out(vty, BGP_SHOW_OCODE_HEADER);
9378 if (type == bgp_show_type_dampend_paths
9379 || type == bgp_show_type_damp_neighbor)
9380 vty_out(vty, BGP_SHOW_DAMP_HEADER);
9381 else if (type == bgp_show_type_flap_statistics
9382 || type == bgp_show_type_flap_neighbor)
9383 vty_out(vty, BGP_SHOW_FLAP_HEADER);
9384 else
9385 vty_out(vty, BGP_SHOW_HEADER);
9386 header = 0;
9387 }
9388 if (rd != NULL && !display && !output_count) {
9389 if (!use_json)
9390 vty_out(vty,
9391 "Route Distinguisher: %s\n",
9392 rd);
9393 }
9394 if (type == bgp_show_type_dampend_paths
9395 || type == bgp_show_type_damp_neighbor)
9396 damp_route_vty_out(vty, &rn->p, pi, display, AFI_IP,
9397 safi, use_json, json_paths);
9398 else if (type == bgp_show_type_flap_statistics
9399 || type == bgp_show_type_flap_neighbor)
9400 flap_route_vty_out(vty, &rn->p, pi, display, AFI_IP,
9401 safi, use_json, json_paths);
9402 else
9403 route_vty_out(vty, &rn->p, pi, display, safi,
9404 json_paths);
9405 display++;
9406 }
9407
9408 if (display) {
9409 output_count++;
9410 if (!use_json)
9411 continue;
9412
9413 p = &rn->p;
9414 /* encode prefix */
9415 if (p->family == AF_FLOWSPEC) {
9416 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
9417
9418 bgp_fs_nlri_get_string((unsigned char *)
9419 p->u.prefix_flowspec.ptr,
9420 p->u.prefix_flowspec
9421 .prefixlen,
9422 retstr,
9423 NLRI_STRING_FORMAT_MIN,
9424 NULL);
9425 if (first)
9426 vty_out(vty, "\"%s/%d\": ",
9427 retstr,
9428 p->u.prefix_flowspec.prefixlen);
9429 else
9430 vty_out(vty, ",\"%s/%d\": ",
9431 retstr,
9432 p->u.prefix_flowspec.prefixlen);
9433 } else {
9434 prefix2str(p, buf2, sizeof(buf2));
9435 if (first)
9436 vty_out(vty, "\"%s\": ", buf2);
9437 else
9438 vty_out(vty, ",\"%s\": ", buf2);
9439 }
9440 vty_out(vty, "%s",
9441 json_object_to_json_string(json_paths));
9442 json_object_free(json_paths);
9443 json_paths = NULL;
9444 first = 0;
9445 } else
9446 json_object_free(json_paths);
9447 }
9448
9449 if (output_cum) {
9450 output_count += *output_cum;
9451 *output_cum = output_count;
9452 }
9453 if (total_cum) {
9454 total_count += *total_cum;
9455 *total_cum = total_count;
9456 }
9457 if (use_json) {
9458 if (rd) {
9459 vty_out(vty, " }%s ", (is_last ? "" : ","));
9460 }
9461 if (is_last) {
9462 unsigned long i;
9463 for (i = 0; i < *json_header_depth; ++i)
9464 vty_out(vty, " } ");
9465 vty_out(vty, "\n");
9466 }
9467 } else {
9468 if (is_last) {
9469 /* No route is displayed */
9470 if (output_count == 0) {
9471 if (type == bgp_show_type_normal)
9472 vty_out(vty,
9473 "No BGP prefixes displayed, %ld exist\n",
9474 total_count);
9475 } else
9476 vty_out(vty,
9477 "\nDisplayed %ld routes and %ld total paths\n",
9478 output_count, total_count);
9479 }
9480 }
9481
9482 return CMD_SUCCESS;
9483 }
9484
9485 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
9486 struct bgp_table *table, struct prefix_rd *prd_match,
9487 enum bgp_show_type type, void *output_arg, bool use_json)
9488 {
9489 struct bgp_node *rn, *next;
9490 unsigned long output_cum = 0;
9491 unsigned long total_cum = 0;
9492 unsigned long json_header_depth = 0;
9493 struct bgp_table *itable;
9494 bool show_msg;
9495
9496 show_msg = (!use_json && type == bgp_show_type_normal);
9497
9498 for (rn = bgp_table_top(table); rn; rn = next) {
9499 next = bgp_route_next(rn);
9500 if (prd_match && memcmp(rn->p.u.val, prd_match->val, 8) != 0)
9501 continue;
9502
9503 itable = bgp_node_get_bgp_table_info(rn);
9504 if (itable != NULL) {
9505 struct prefix_rd prd;
9506 char rd[RD_ADDRSTRLEN];
9507
9508 memcpy(&prd, &(rn->p), sizeof(struct prefix_rd));
9509 prefix_rd2str(&prd, rd, sizeof(rd));
9510 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
9511 use_json, rd, next == NULL, &output_cum,
9512 &total_cum, &json_header_depth);
9513 if (next == NULL)
9514 show_msg = false;
9515 }
9516 }
9517 if (show_msg) {
9518 if (output_cum == 0)
9519 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
9520 total_cum);
9521 else
9522 vty_out(vty,
9523 "\nDisplayed %ld routes and %ld total paths\n",
9524 output_cum, total_cum);
9525 }
9526 return CMD_SUCCESS;
9527 }
9528 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
9529 enum bgp_show_type type, void *output_arg, bool use_json)
9530 {
9531 struct bgp_table *table;
9532 unsigned long json_header_depth = 0;
9533
9534 if (bgp == NULL) {
9535 bgp = bgp_get_default();
9536 }
9537
9538 if (bgp == NULL) {
9539 if (!use_json)
9540 vty_out(vty, "No BGP process is configured\n");
9541 else
9542 vty_out(vty, "{}\n");
9543 return CMD_WARNING;
9544 }
9545
9546 table = bgp->rib[afi][safi];
9547 /* use MPLS and ENCAP specific shows until they are merged */
9548 if (safi == SAFI_MPLS_VPN) {
9549 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
9550 output_arg, use_json);
9551 }
9552
9553 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
9554 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
9555 output_arg, use_json,
9556 1, NULL, NULL);
9557 }
9558 /* labeled-unicast routes live in the unicast table */
9559 else if (safi == SAFI_LABELED_UNICAST)
9560 safi = SAFI_UNICAST;
9561
9562 return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json,
9563 NULL, 1, NULL, NULL, &json_header_depth);
9564 }
9565
9566 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
9567 safi_t safi, bool use_json)
9568 {
9569 struct listnode *node, *nnode;
9570 struct bgp *bgp;
9571 int is_first = 1;
9572 bool route_output = false;
9573
9574 if (use_json)
9575 vty_out(vty, "{\n");
9576
9577 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
9578 route_output = true;
9579 if (use_json) {
9580 if (!is_first)
9581 vty_out(vty, ",\n");
9582 else
9583 is_first = 0;
9584
9585 vty_out(vty, "\"%s\":",
9586 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9587 ? VRF_DEFAULT_NAME
9588 : bgp->name);
9589 } else {
9590 vty_out(vty, "\nInstance %s:\n",
9591 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9592 ? VRF_DEFAULT_NAME
9593 : bgp->name);
9594 }
9595 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
9596 use_json);
9597 }
9598
9599 if (use_json)
9600 vty_out(vty, "}\n");
9601 else if (!route_output)
9602 vty_out(vty, "%% BGP instance not found\n");
9603 }
9604
9605 /* Header of detailed BGP route information */
9606 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
9607 struct bgp_node *rn, struct prefix_rd *prd,
9608 afi_t afi, safi_t safi, json_object *json)
9609 {
9610 struct bgp_path_info *pi;
9611 struct prefix *p;
9612 struct peer *peer;
9613 struct listnode *node, *nnode;
9614 char buf1[RD_ADDRSTRLEN];
9615 char buf2[INET6_ADDRSTRLEN];
9616 char buf3[EVPN_ROUTE_STRLEN];
9617 char prefix_str[BUFSIZ];
9618 int count = 0;
9619 int best = 0;
9620 int suppress = 0;
9621 int accept_own = 0;
9622 int route_filter_translated_v4 = 0;
9623 int route_filter_v4 = 0;
9624 int route_filter_translated_v6 = 0;
9625 int route_filter_v6 = 0;
9626 int llgr_stale = 0;
9627 int no_llgr = 0;
9628 int accept_own_nexthop = 0;
9629 int blackhole = 0;
9630 int no_export = 0;
9631 int no_advertise = 0;
9632 int local_as = 0;
9633 int no_peer = 0;
9634 int first = 1;
9635 int has_valid_label = 0;
9636 mpls_label_t label = 0;
9637 json_object *json_adv_to = NULL;
9638
9639 p = &rn->p;
9640 has_valid_label = bgp_is_valid_label(&rn->local_label);
9641
9642 if (has_valid_label)
9643 label = label_pton(&rn->local_label);
9644
9645 if (safi == SAFI_EVPN) {
9646
9647 if (!json) {
9648 vty_out(vty, "BGP routing table entry for %s%s%s\n",
9649 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
9650 : "", prd ? ":" : "",
9651 bgp_evpn_route2str((struct prefix_evpn *)p,
9652 buf3, sizeof(buf3)));
9653 } else {
9654 json_object_string_add(json, "rd",
9655 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
9656 "");
9657 bgp_evpn_route2json((struct prefix_evpn *)p, json);
9658 }
9659 } else {
9660 if (!json) {
9661 vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
9662 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9663 ? prefix_rd2str(prd, buf1,
9664 sizeof(buf1))
9665 : ""),
9666 safi == SAFI_MPLS_VPN ? ":" : "",
9667 inet_ntop(p->family, &p->u.prefix, buf2,
9668 INET6_ADDRSTRLEN),
9669 p->prefixlen);
9670
9671 } else
9672 json_object_string_add(json, "prefix",
9673 prefix2str(p, prefix_str, sizeof(prefix_str)));
9674 }
9675
9676 if (has_valid_label) {
9677 if (json)
9678 json_object_int_add(json, "localLabel", label);
9679 else
9680 vty_out(vty, "Local label: %d\n", label);
9681 }
9682
9683 if (!json)
9684 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
9685 vty_out(vty, "not allocated\n");
9686
9687 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
9688 count++;
9689 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
9690 best = count;
9691 if (pi->extra && pi->extra->suppress)
9692 suppress = 1;
9693
9694 if (pi->attr->community == NULL)
9695 continue;
9696
9697 no_advertise += community_include(
9698 pi->attr->community, COMMUNITY_NO_ADVERTISE);
9699 no_export += community_include(pi->attr->community,
9700 COMMUNITY_NO_EXPORT);
9701 local_as += community_include(pi->attr->community,
9702 COMMUNITY_LOCAL_AS);
9703 accept_own += community_include(pi->attr->community,
9704 COMMUNITY_ACCEPT_OWN);
9705 route_filter_translated_v4 += community_include(
9706 pi->attr->community,
9707 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
9708 route_filter_translated_v6 += community_include(
9709 pi->attr->community,
9710 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
9711 route_filter_v4 += community_include(
9712 pi->attr->community, COMMUNITY_ROUTE_FILTER_v4);
9713 route_filter_v6 += community_include(
9714 pi->attr->community, COMMUNITY_ROUTE_FILTER_v6);
9715 llgr_stale += community_include(pi->attr->community,
9716 COMMUNITY_LLGR_STALE);
9717 no_llgr += community_include(pi->attr->community,
9718 COMMUNITY_NO_LLGR);
9719 accept_own_nexthop +=
9720 community_include(pi->attr->community,
9721 COMMUNITY_ACCEPT_OWN_NEXTHOP);
9722 blackhole += community_include(pi->attr->community,
9723 COMMUNITY_BLACKHOLE);
9724 no_peer += community_include(pi->attr->community,
9725 COMMUNITY_NO_PEER);
9726 }
9727 }
9728
9729 if (!json) {
9730 vty_out(vty, "Paths: (%d available", count);
9731 if (best) {
9732 vty_out(vty, ", best #%d", best);
9733 if (safi == SAFI_UNICAST) {
9734 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9735 vty_out(vty, ", table %s",
9736 VRF_DEFAULT_NAME);
9737 else
9738 vty_out(vty, ", vrf %s",
9739 bgp->name);
9740 }
9741 } else
9742 vty_out(vty, ", no best path");
9743
9744 if (accept_own)
9745 vty_out(vty,
9746 ", accept own local route exported and imported in different VRF");
9747 else if (route_filter_translated_v4)
9748 vty_out(vty,
9749 ", mark translated RTs for VPNv4 route filtering");
9750 else if (route_filter_v4)
9751 vty_out(vty,
9752 ", attach RT as-is for VPNv4 route filtering");
9753 else if (route_filter_translated_v6)
9754 vty_out(vty,
9755 ", mark translated RTs for VPNv6 route filtering");
9756 else if (route_filter_v6)
9757 vty_out(vty,
9758 ", attach RT as-is for VPNv6 route filtering");
9759 else if (llgr_stale)
9760 vty_out(vty,
9761 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
9762 else if (no_llgr)
9763 vty_out(vty,
9764 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
9765 else if (accept_own_nexthop)
9766 vty_out(vty,
9767 ", accept local nexthop");
9768 else if (blackhole)
9769 vty_out(vty, ", inform peer to blackhole prefix");
9770 else if (no_export)
9771 vty_out(vty, ", not advertised to EBGP peer");
9772 else if (no_advertise)
9773 vty_out(vty, ", not advertised to any peer");
9774 else if (local_as)
9775 vty_out(vty, ", not advertised outside local AS");
9776 else if (no_peer)
9777 vty_out(vty,
9778 ", inform EBGP peer not to advertise to their EBGP peers");
9779
9780 if (suppress)
9781 vty_out(vty,
9782 ", Advertisements suppressed by an aggregate.");
9783 vty_out(vty, ")\n");
9784 }
9785
9786 /* If we are not using addpath then we can display Advertised to and
9787 * that will
9788 * show what peers we advertised the bestpath to. If we are using
9789 * addpath
9790 * though then we must display Advertised to on a path-by-path basis. */
9791 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
9792 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
9793 if (bgp_adj_out_lookup(peer, rn, 0)) {
9794 if (json && !json_adv_to)
9795 json_adv_to = json_object_new_object();
9796
9797 route_vty_out_advertised_to(
9798 vty, peer, &first,
9799 " Advertised to non peer-group peers:\n ",
9800 json_adv_to);
9801 }
9802 }
9803
9804 if (json) {
9805 if (json_adv_to) {
9806 json_object_object_add(json, "advertisedTo",
9807 json_adv_to);
9808 }
9809 } else {
9810 if (first)
9811 vty_out(vty, " Not advertised to any peer");
9812 vty_out(vty, "\n");
9813 }
9814 }
9815 }
9816
9817 static void bgp_show_path_info(struct prefix_rd *pfx_rd,
9818 struct bgp_node *bgp_node, struct vty *vty,
9819 struct bgp *bgp, afi_t afi,
9820 safi_t safi, json_object *json,
9821 enum bgp_path_type pathtype, int *display)
9822 {
9823 struct bgp_path_info *pi;
9824 int header = 1;
9825 char rdbuf[RD_ADDRSTRLEN];
9826 json_object *json_header = NULL;
9827 json_object *json_paths = NULL;
9828
9829 for (pi = bgp_node_get_bgp_path_info(bgp_node); pi;
9830 pi = pi->next) {
9831
9832 if (json && !json_paths) {
9833 /* Instantiate json_paths only if path is valid */
9834 json_paths = json_object_new_array();
9835 if (pfx_rd) {
9836 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
9837 json_header = json_object_new_object();
9838 } else
9839 json_header = json;
9840 }
9841
9842 if (header) {
9843 route_vty_out_detail_header(
9844 vty, bgp, bgp_node, pfx_rd,
9845 AFI_IP, safi, json_header);
9846 header = 0;
9847 }
9848 (*display)++;
9849
9850 if (pathtype == BGP_PATH_SHOW_ALL
9851 || (pathtype == BGP_PATH_SHOW_BESTPATH
9852 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
9853 || (pathtype == BGP_PATH_SHOW_MULTIPATH
9854 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
9855 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
9856 route_vty_out_detail(vty, bgp, bgp_node,
9857 pi, AFI_IP, safi,
9858 json_paths);
9859 }
9860
9861 if (json && json_paths) {
9862 json_object_object_add(json_header, "paths", json_paths);
9863
9864 if (pfx_rd)
9865 json_object_object_add(json, rdbuf, json_header);
9866 }
9867 }
9868
9869 /* Display specified route of BGP table. */
9870 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
9871 struct bgp_table *rib, const char *ip_str,
9872 afi_t afi, safi_t safi,
9873 struct prefix_rd *prd, int prefix_check,
9874 enum bgp_path_type pathtype, bool use_json)
9875 {
9876 int ret;
9877 int display = 0;
9878 struct prefix match;
9879 struct bgp_node *rn;
9880 struct bgp_node *rm;
9881 struct bgp_table *table;
9882 json_object *json = NULL;
9883 json_object *json_paths = NULL;
9884
9885 /* Check IP address argument. */
9886 ret = str2prefix(ip_str, &match);
9887 if (!ret) {
9888 vty_out(vty, "address is malformed\n");
9889 return CMD_WARNING;
9890 }
9891
9892 match.family = afi2family(afi);
9893
9894 if (use_json)
9895 json = json_object_new_object();
9896
9897 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
9898 for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
9899 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
9900 continue;
9901 table = bgp_node_get_bgp_table_info(rn);
9902 if (!table)
9903 continue;
9904
9905 if ((rm = bgp_node_match(table, &match)) == NULL)
9906 continue;
9907
9908 if (prefix_check
9909 && rm->p.prefixlen != match.prefixlen) {
9910 bgp_unlock_node(rm);
9911 continue;
9912 }
9913
9914 bgp_show_path_info((struct prefix_rd *)&rn->p, rm,
9915 vty, bgp, afi, safi, json,
9916 pathtype, &display);
9917
9918 bgp_unlock_node(rm);
9919 }
9920 } else if (safi == SAFI_EVPN) {
9921 struct bgp_node *longest_pfx;
9922 bool is_exact_pfxlen_match = FALSE;
9923
9924 for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
9925 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
9926 continue;
9927 table = bgp_node_get_bgp_table_info(rn);
9928 if (!table)
9929 continue;
9930
9931 longest_pfx = NULL;
9932 is_exact_pfxlen_match = FALSE;
9933 /*
9934 * Search through all the prefixes for a match. The
9935 * pfx's are enumerated in ascending order of pfxlens.
9936 * So, the last pfx match is the longest match. Set
9937 * is_exact_pfxlen_match when we get exact pfxlen match
9938 */
9939 for (rm = bgp_table_top(table); rm;
9940 rm = bgp_route_next(rm)) {
9941 /*
9942 * Get prefixlen of the ip-prefix within type5
9943 * evpn route
9944 */
9945 if (evpn_type5_prefix_match(&rm->p,
9946 &match) && rm->info) {
9947 longest_pfx = rm;
9948 int type5_pfxlen =
9949 bgp_evpn_get_type5_prefixlen(&rm->p);
9950 if (type5_pfxlen == match.prefixlen) {
9951 is_exact_pfxlen_match = TRUE;
9952 bgp_unlock_node(rm);
9953 break;
9954 }
9955 }
9956 }
9957
9958 if (!longest_pfx)
9959 continue;
9960
9961 if (prefix_check && !is_exact_pfxlen_match)
9962 continue;
9963
9964 rm = longest_pfx;
9965 bgp_lock_node(rm);
9966
9967 bgp_show_path_info((struct prefix_rd *)&rn->p, rm,
9968 vty, bgp, afi, safi, json,
9969 pathtype, &display);
9970
9971 bgp_unlock_node(rm);
9972 }
9973 } else if (safi == SAFI_FLOWSPEC) {
9974 if (use_json)
9975 json_paths = json_object_new_array();
9976
9977 display = bgp_flowspec_display_match_per_ip(afi, rib,
9978 &match, prefix_check,
9979 vty,
9980 use_json,
9981 json_paths);
9982 if (use_json && display)
9983 json_object_object_add(json, "paths", json_paths);
9984 } else {
9985 if ((rn = bgp_node_match(rib, &match)) != NULL) {
9986 if (!prefix_check
9987 || rn->p.prefixlen == match.prefixlen) {
9988 bgp_show_path_info(NULL, rn, vty, bgp, afi,
9989 safi, json,
9990 pathtype, &display);
9991 }
9992
9993 bgp_unlock_node(rn);
9994 }
9995 }
9996
9997 if (use_json) {
9998 vty_out(vty, "%s\n", json_object_to_json_string_ext(
9999 json, JSON_C_TO_STRING_PRETTY |
10000 JSON_C_TO_STRING_NOSLASHESCAPE));
10001 json_object_free(json);
10002 } else {
10003 if (!display) {
10004 vty_out(vty, "%% Network not in table\n");
10005 return CMD_WARNING;
10006 }
10007 }
10008
10009 return CMD_SUCCESS;
10010 }
10011
10012 /* Display specified route of Main RIB */
10013 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
10014 afi_t afi, safi_t safi, struct prefix_rd *prd,
10015 int prefix_check, enum bgp_path_type pathtype,
10016 bool use_json)
10017 {
10018 if (!bgp) {
10019 bgp = bgp_get_default();
10020 if (!bgp) {
10021 if (!use_json)
10022 vty_out(vty, "No BGP process is configured\n");
10023 else
10024 vty_out(vty, "{}\n");
10025 return CMD_WARNING;
10026 }
10027 }
10028
10029 /* labeled-unicast routes live in the unicast table */
10030 if (safi == SAFI_LABELED_UNICAST)
10031 safi = SAFI_UNICAST;
10032
10033 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
10034 afi, safi, prd, prefix_check, pathtype,
10035 use_json);
10036 }
10037
10038 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
10039 struct cmd_token **argv, bool exact, afi_t afi,
10040 safi_t safi, bool uj)
10041 {
10042 struct lcommunity *lcom;
10043 struct buffer *b;
10044 int i;
10045 char *str;
10046 int first = 0;
10047
10048 b = buffer_new(1024);
10049 for (i = 0; i < argc; i++) {
10050 if (first)
10051 buffer_putc(b, ' ');
10052 else {
10053 if (strmatch(argv[i]->text, "AA:BB:CC")) {
10054 first = 1;
10055 buffer_putstr(b, argv[i]->arg);
10056 }
10057 }
10058 }
10059 buffer_putc(b, '\0');
10060
10061 str = buffer_getstr(b);
10062 buffer_free(b);
10063
10064 lcom = lcommunity_str2com(str);
10065 XFREE(MTYPE_TMP, str);
10066 if (!lcom) {
10067 vty_out(vty, "%% Large-community malformed\n");
10068 return CMD_WARNING;
10069 }
10070
10071 return bgp_show(vty, bgp, afi, safi,
10072 (exact ? bgp_show_type_lcommunity_exact
10073 : bgp_show_type_lcommunity),
10074 lcom, uj);
10075 }
10076
10077 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
10078 const char *lcom, bool exact, afi_t afi,
10079 safi_t safi, bool uj)
10080 {
10081 struct community_list *list;
10082
10083 list = community_list_lookup(bgp_clist, lcom, 0,
10084 LARGE_COMMUNITY_LIST_MASTER);
10085 if (list == NULL) {
10086 vty_out(vty, "%% %s is not a valid large-community-list name\n",
10087 lcom);
10088 return CMD_WARNING;
10089 }
10090
10091 return bgp_show(vty, bgp, afi, safi,
10092 (exact ? bgp_show_type_lcommunity_list_exact
10093 : bgp_show_type_lcommunity_list),
10094 list, uj);
10095 }
10096
10097 DEFUN (show_ip_bgp_large_community_list,
10098 show_ip_bgp_large_community_list_cmd,
10099 "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]",
10100 SHOW_STR
10101 IP_STR
10102 BGP_STR
10103 BGP_INSTANCE_HELP_STR
10104 BGP_AFI_HELP_STR
10105 BGP_SAFI_WITH_LABEL_HELP_STR
10106 "Display routes matching the large-community-list\n"
10107 "large-community-list number\n"
10108 "large-community-list name\n"
10109 "Exact match of the large-communities\n"
10110 JSON_STR)
10111 {
10112 char *vrf = NULL;
10113 afi_t afi = AFI_IP6;
10114 safi_t safi = SAFI_UNICAST;
10115 int idx = 0;
10116 bool exact_match = 0;
10117
10118 if (argv_find(argv, argc, "ip", &idx))
10119 afi = AFI_IP;
10120 if (argv_find(argv, argc, "view", &idx)
10121 || argv_find(argv, argc, "vrf", &idx))
10122 vrf = argv[++idx]->arg;
10123 if (argv_find(argv, argc, "ipv4", &idx)
10124 || argv_find(argv, argc, "ipv6", &idx)) {
10125 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
10126 if (argv_find(argv, argc, "unicast", &idx)
10127 || argv_find(argv, argc, "multicast", &idx))
10128 safi = bgp_vty_safi_from_str(argv[idx]->text);
10129 }
10130
10131 bool uj = use_json(argc, argv);
10132
10133 struct bgp *bgp = bgp_lookup_by_name(vrf);
10134 if (bgp == NULL) {
10135 vty_out(vty, "Can't find BGP instance %s\n", vrf);
10136 return CMD_WARNING;
10137 }
10138
10139 argv_find(argv, argc, "large-community-list", &idx);
10140
10141 const char *clist_number_or_name = argv[++idx]->arg;
10142
10143 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
10144 exact_match = 1;
10145
10146 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
10147 exact_match, afi, safi, uj);
10148 }
10149 DEFUN (show_ip_bgp_large_community,
10150 show_ip_bgp_large_community_cmd,
10151 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
10152 SHOW_STR
10153 IP_STR
10154 BGP_STR
10155 BGP_INSTANCE_HELP_STR
10156 BGP_AFI_HELP_STR
10157 BGP_SAFI_WITH_LABEL_HELP_STR
10158 "Display routes matching the large-communities\n"
10159 "List of large-community numbers\n"
10160 "Exact match of the large-communities\n"
10161 JSON_STR)
10162 {
10163 char *vrf = NULL;
10164 afi_t afi = AFI_IP6;
10165 safi_t safi = SAFI_UNICAST;
10166 int idx = 0;
10167 bool exact_match = 0;
10168
10169 if (argv_find(argv, argc, "ip", &idx))
10170 afi = AFI_IP;
10171 if (argv_find(argv, argc, "view", &idx)
10172 || argv_find(argv, argc, "vrf", &idx))
10173 vrf = argv[++idx]->arg;
10174 if (argv_find(argv, argc, "ipv4", &idx)
10175 || argv_find(argv, argc, "ipv6", &idx)) {
10176 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
10177 if (argv_find(argv, argc, "unicast", &idx)
10178 || argv_find(argv, argc, "multicast", &idx))
10179 safi = bgp_vty_safi_from_str(argv[idx]->text);
10180 }
10181
10182 bool uj = use_json(argc, argv);
10183
10184 struct bgp *bgp = bgp_lookup_by_name(vrf);
10185 if (bgp == NULL) {
10186 vty_out(vty, "Can't find BGP instance %s\n", vrf);
10187 return CMD_WARNING;
10188 }
10189
10190 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
10191 if (argv_find(argv, argc, "exact-match", &idx))
10192 exact_match = 1;
10193 return bgp_show_lcommunity(vty, bgp, argc, argv,
10194 exact_match, afi, safi, uj);
10195 } else
10196 return bgp_show(vty, bgp, afi, safi,
10197 bgp_show_type_lcommunity_all, NULL, uj);
10198 }
10199
10200 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
10201 safi_t safi);
10202
10203
10204 /* BGP route print out function without JSON */
10205 DEFUN (show_ip_bgp,
10206 show_ip_bgp_cmd,
10207 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
10208 <dampening <parameters>\
10209 |route-map WORD\
10210 |prefix-list WORD\
10211 |filter-list WORD\
10212 |statistics\
10213 |community-list <(1-500)|WORD> [exact-match]\
10214 |A.B.C.D/M longer-prefixes\
10215 |X:X::X:X/M longer-prefixes\
10216 >",
10217 SHOW_STR
10218 IP_STR
10219 BGP_STR
10220 BGP_INSTANCE_HELP_STR
10221 BGP_AFI_HELP_STR
10222 BGP_SAFI_WITH_LABEL_HELP_STR
10223 "Display detailed information about dampening\n"
10224 "Display detail of configured dampening parameters\n"
10225 "Display routes matching the route-map\n"
10226 "A route-map to match on\n"
10227 "Display routes conforming to the prefix-list\n"
10228 "Prefix-list name\n"
10229 "Display routes conforming to the filter-list\n"
10230 "Regular expression access list name\n"
10231 "BGP RIB advertisement statistics\n"
10232 "Display routes matching the community-list\n"
10233 "community-list number\n"
10234 "community-list name\n"
10235 "Exact match of the communities\n"
10236 "IPv4 prefix\n"
10237 "Display route and more specific routes\n"
10238 "IPv6 prefix\n"
10239 "Display route and more specific routes\n")
10240 {
10241 afi_t afi = AFI_IP6;
10242 safi_t safi = SAFI_UNICAST;
10243 int exact_match = 0;
10244 struct bgp *bgp = NULL;
10245 int idx = 0;
10246
10247 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10248 &bgp, false);
10249 if (!idx)
10250 return CMD_WARNING;
10251
10252 if (argv_find(argv, argc, "dampening", &idx)) {
10253 if (argv_find(argv, argc, "parameters", &idx))
10254 return bgp_show_dampening_parameters(vty, afi, safi);
10255 }
10256
10257 if (argv_find(argv, argc, "prefix-list", &idx))
10258 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
10259 safi, bgp_show_type_prefix_list);
10260
10261 if (argv_find(argv, argc, "filter-list", &idx))
10262 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
10263 safi, bgp_show_type_filter_list);
10264
10265 if (argv_find(argv, argc, "statistics", &idx))
10266 return bgp_table_stats(vty, bgp, afi, safi);
10267
10268 if (argv_find(argv, argc, "route-map", &idx))
10269 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
10270 safi, bgp_show_type_route_map);
10271
10272 if (argv_find(argv, argc, "community-list", &idx)) {
10273 const char *clist_number_or_name = argv[++idx]->arg;
10274 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
10275 exact_match = 1;
10276 return bgp_show_community_list(vty, bgp, clist_number_or_name,
10277 exact_match, afi, safi);
10278 }
10279 /* prefix-longer */
10280 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
10281 || argv_find(argv, argc, "X:X::X:X/M", &idx))
10282 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
10283 safi,
10284 bgp_show_type_prefix_longer);
10285
10286 return CMD_WARNING;
10287 }
10288
10289 /* BGP route print out function with JSON */
10290 DEFUN (show_ip_bgp_json,
10291 show_ip_bgp_json_cmd,
10292 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
10293 [cidr-only\
10294 |dampening <flap-statistics|dampened-paths>\
10295 |community [AA:NN|local-AS|no-advertise|no-export\
10296 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
10297 |accept-own|accept-own-nexthop|route-filter-v6\
10298 |route-filter-v4|route-filter-translated-v6\
10299 |route-filter-translated-v4] [exact-match]\
10300 ] [json]",
10301 SHOW_STR
10302 IP_STR
10303 BGP_STR
10304 BGP_INSTANCE_HELP_STR
10305 BGP_AFI_HELP_STR
10306 BGP_SAFI_WITH_LABEL_HELP_STR
10307 "Display only routes with non-natural netmasks\n"
10308 "Display detailed information about dampening\n"
10309 "Display flap statistics of routes\n"
10310 "Display paths suppressed due to dampening\n"
10311 "Display routes matching the communities\n"
10312 COMMUNITY_AANN_STR
10313 "Do not send outside local AS (well-known community)\n"
10314 "Do not advertise to any peer (well-known community)\n"
10315 "Do not export to next AS (well-known community)\n"
10316 "Graceful shutdown (well-known community)\n"
10317 "Do not export to any peer (well-known community)\n"
10318 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
10319 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
10320 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
10321 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
10322 "Should accept VPN route with local nexthop (well-known community)\n"
10323 "RT VPNv6 route filtering (well-known community)\n"
10324 "RT VPNv4 route filtering (well-known community)\n"
10325 "RT translated VPNv6 route filtering (well-known community)\n"
10326 "RT translated VPNv4 route filtering (well-known community)\n"
10327 "Exact match of the communities\n"
10328 JSON_STR)
10329 {
10330 afi_t afi = AFI_IP6;
10331 safi_t safi = SAFI_UNICAST;
10332 enum bgp_show_type sh_type = bgp_show_type_normal;
10333 struct bgp *bgp = NULL;
10334 int idx = 0;
10335 int exact_match = 0;
10336 bool uj = use_json(argc, argv);
10337
10338 if (uj)
10339 argc--;
10340
10341 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10342 &bgp, uj);
10343 if (!idx)
10344 return CMD_WARNING;
10345
10346 if (argv_find(argv, argc, "cidr-only", &idx))
10347 return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only,
10348 NULL, uj);
10349
10350 if (argv_find(argv, argc, "dampening", &idx)) {
10351 if (argv_find(argv, argc, "dampened-paths", &idx))
10352 return bgp_show(vty, bgp, afi, safi,
10353 bgp_show_type_dampend_paths, NULL, uj);
10354 else if (argv_find(argv, argc, "flap-statistics", &idx))
10355 return bgp_show(vty, bgp, afi, safi,
10356 bgp_show_type_flap_statistics, NULL,
10357 uj);
10358 }
10359
10360 if (argv_find(argv, argc, "community", &idx)) {
10361 char *maybecomm = NULL;
10362 char *community = NULL;
10363
10364 if (idx + 1 < argc) {
10365 if (argv[idx + 1]->type == VARIABLE_TKN)
10366 maybecomm = argv[idx + 1]->arg;
10367 else
10368 maybecomm = argv[idx + 1]->text;
10369 }
10370
10371 if (maybecomm && !strmatch(maybecomm, "json")
10372 && !strmatch(maybecomm, "exact-match"))
10373 community = maybecomm;
10374
10375 if (argv_find(argv, argc, "exact-match", &idx))
10376 exact_match = 1;
10377
10378 if (community)
10379 return bgp_show_community(vty, bgp, community,
10380 exact_match, afi, safi, uj);
10381 else
10382 return (bgp_show(vty, bgp, afi, safi,
10383 bgp_show_type_community_all, NULL,
10384 uj));
10385 }
10386
10387 return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
10388 }
10389
10390 DEFUN (show_ip_bgp_route,
10391 show_ip_bgp_route_cmd,
10392 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]"
10393 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
10394 SHOW_STR
10395 IP_STR
10396 BGP_STR
10397 BGP_INSTANCE_HELP_STR
10398 BGP_AFI_HELP_STR
10399 BGP_SAFI_WITH_LABEL_HELP_STR
10400 "Network in the BGP routing table to display\n"
10401 "IPv4 prefix\n"
10402 "Network in the BGP routing table to display\n"
10403 "IPv6 prefix\n"
10404 "Display only the bestpath\n"
10405 "Display only multipaths\n"
10406 JSON_STR)
10407 {
10408 int prefix_check = 0;
10409
10410 afi_t afi = AFI_IP6;
10411 safi_t safi = SAFI_UNICAST;
10412 char *prefix = NULL;
10413 struct bgp *bgp = NULL;
10414 enum bgp_path_type path_type;
10415 bool uj = use_json(argc, argv);
10416
10417 int idx = 0;
10418
10419 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10420 &bgp, uj);
10421 if (!idx)
10422 return CMD_WARNING;
10423
10424 if (!bgp) {
10425 vty_out(vty,
10426 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
10427 return CMD_WARNING;
10428 }
10429
10430 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
10431 if (argv_find(argv, argc, "A.B.C.D", &idx)
10432 || argv_find(argv, argc, "X:X::X:X", &idx))
10433 prefix_check = 0;
10434 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
10435 || argv_find(argv, argc, "X:X::X:X/M", &idx))
10436 prefix_check = 1;
10437
10438 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
10439 && afi != AFI_IP6) {
10440 vty_out(vty,
10441 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
10442 return CMD_WARNING;
10443 }
10444 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
10445 && afi != AFI_IP) {
10446 vty_out(vty,
10447 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
10448 return CMD_WARNING;
10449 }
10450
10451 prefix = argv[idx]->arg;
10452
10453 /* [<bestpath|multipath>] */
10454 if (argv_find(argv, argc, "bestpath", &idx))
10455 path_type = BGP_PATH_SHOW_BESTPATH;
10456 else if (argv_find(argv, argc, "multipath", &idx))
10457 path_type = BGP_PATH_SHOW_MULTIPATH;
10458 else
10459 path_type = BGP_PATH_SHOW_ALL;
10460
10461 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
10462 path_type, uj);
10463 }
10464
10465 DEFUN (show_ip_bgp_regexp,
10466 show_ip_bgp_regexp_cmd,
10467 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX...",
10468 SHOW_STR
10469 IP_STR
10470 BGP_STR
10471 BGP_INSTANCE_HELP_STR
10472 BGP_AFI_HELP_STR
10473 BGP_SAFI_WITH_LABEL_HELP_STR
10474 "Display routes matching the AS path regular expression\n"
10475 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n")
10476 {
10477 afi_t afi = AFI_IP6;
10478 safi_t safi = SAFI_UNICAST;
10479 struct bgp *bgp = NULL;
10480
10481 int idx = 0;
10482 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10483 &bgp, false);
10484 if (!idx)
10485 return CMD_WARNING;
10486
10487 // get index of regex
10488 argv_find(argv, argc, "regexp", &idx);
10489 idx++;
10490
10491 char *regstr = argv_concat(argv, argc, idx);
10492 int rc = bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
10493 bgp_show_type_regexp);
10494 XFREE(MTYPE_TMP, regstr);
10495 return rc;
10496 }
10497
10498 DEFUN (show_ip_bgp_instance_all,
10499 show_ip_bgp_instance_all_cmd,
10500 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json]",
10501 SHOW_STR
10502 IP_STR
10503 BGP_STR
10504 BGP_INSTANCE_ALL_HELP_STR
10505 BGP_AFI_HELP_STR
10506 BGP_SAFI_WITH_LABEL_HELP_STR
10507 JSON_STR)
10508 {
10509 afi_t afi = AFI_IP;
10510 safi_t safi = SAFI_UNICAST;
10511 struct bgp *bgp = NULL;
10512 int idx = 0;
10513 bool uj = use_json(argc, argv);
10514
10515 if (uj)
10516 argc--;
10517
10518 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10519 &bgp, uj);
10520 if (!idx)
10521 return CMD_WARNING;
10522
10523 bgp_show_all_instances_routes_vty(vty, afi, safi, uj);
10524 return CMD_SUCCESS;
10525 }
10526
10527 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
10528 afi_t afi, safi_t safi, enum bgp_show_type type)
10529 {
10530 regex_t *regex;
10531 int rc;
10532
10533 if (!config_bgp_aspath_validate(regstr)) {
10534 vty_out(vty, "Invalid character in as-path access-list %s\n",
10535 regstr);
10536 return CMD_WARNING_CONFIG_FAILED;
10537 }
10538
10539 regex = bgp_regcomp(regstr);
10540 if (!regex) {
10541 vty_out(vty, "Can't compile regexp %s\n", regstr);
10542 return CMD_WARNING;
10543 }
10544
10545 rc = bgp_show(vty, bgp, afi, safi, type, regex, 0);
10546 bgp_regex_free(regex);
10547 return rc;
10548 }
10549
10550 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
10551 const char *prefix_list_str, afi_t afi,
10552 safi_t safi, enum bgp_show_type type)
10553 {
10554 struct prefix_list *plist;
10555
10556 plist = prefix_list_lookup(afi, prefix_list_str);
10557 if (plist == NULL) {
10558 vty_out(vty, "%% %s is not a valid prefix-list name\n",
10559 prefix_list_str);
10560 return CMD_WARNING;
10561 }
10562
10563 return bgp_show(vty, bgp, afi, safi, type, plist, 0);
10564 }
10565
10566 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
10567 const char *filter, afi_t afi, safi_t safi,
10568 enum bgp_show_type type)
10569 {
10570 struct as_list *as_list;
10571
10572 as_list = as_list_lookup(filter);
10573 if (as_list == NULL) {
10574 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
10575 filter);
10576 return CMD_WARNING;
10577 }
10578
10579 return bgp_show(vty, bgp, afi, safi, type, as_list, 0);
10580 }
10581
10582 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
10583 const char *rmap_str, afi_t afi, safi_t safi,
10584 enum bgp_show_type type)
10585 {
10586 struct route_map *rmap;
10587
10588 rmap = route_map_lookup_by_name(rmap_str);
10589 if (!rmap) {
10590 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
10591 return CMD_WARNING;
10592 }
10593
10594 return bgp_show(vty, bgp, afi, safi, type, rmap, 0);
10595 }
10596
10597 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
10598 const char *comstr, int exact, afi_t afi,
10599 safi_t safi, bool use_json)
10600 {
10601 struct community *com;
10602 int ret = 0;
10603
10604 com = community_str2com(comstr);
10605 if (!com) {
10606 vty_out(vty, "%% Community malformed: %s\n", comstr);
10607 return CMD_WARNING;
10608 }
10609
10610 ret = bgp_show(vty, bgp, afi, safi,
10611 (exact ? bgp_show_type_community_exact
10612 : bgp_show_type_community),
10613 com, use_json);
10614 community_free(&com);
10615
10616 return ret;
10617 }
10618
10619 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
10620 const char *com, int exact, afi_t afi,
10621 safi_t safi)
10622 {
10623 struct community_list *list;
10624
10625 list = community_list_lookup(bgp_clist, com, 0, COMMUNITY_LIST_MASTER);
10626 if (list == NULL) {
10627 vty_out(vty, "%% %s is not a valid community-list name\n", com);
10628 return CMD_WARNING;
10629 }
10630
10631 return bgp_show(vty, bgp, afi, safi,
10632 (exact ? bgp_show_type_community_list_exact
10633 : bgp_show_type_community_list),
10634 list, 0);
10635 }
10636
10637 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
10638 const char *prefix, afi_t afi, safi_t safi,
10639 enum bgp_show_type type)
10640 {
10641 int ret;
10642 struct prefix *p;
10643
10644 p = prefix_new();
10645
10646 ret = str2prefix(prefix, p);
10647 if (!ret) {
10648 vty_out(vty, "%% Malformed Prefix\n");
10649 return CMD_WARNING;
10650 }
10651
10652 ret = bgp_show(vty, bgp, afi, safi, type, p, 0);
10653 prefix_free(&p);
10654 return ret;
10655 }
10656
10657 enum bgp_stats {
10658 BGP_STATS_MAXBITLEN = 0,
10659 BGP_STATS_RIB,
10660 BGP_STATS_PREFIXES,
10661 BGP_STATS_TOTPLEN,
10662 BGP_STATS_UNAGGREGATEABLE,
10663 BGP_STATS_MAX_AGGREGATEABLE,
10664 BGP_STATS_AGGREGATES,
10665 BGP_STATS_SPACE,
10666 BGP_STATS_ASPATH_COUNT,
10667 BGP_STATS_ASPATH_MAXHOPS,
10668 BGP_STATS_ASPATH_TOTHOPS,
10669 BGP_STATS_ASPATH_MAXSIZE,
10670 BGP_STATS_ASPATH_TOTSIZE,
10671 BGP_STATS_ASN_HIGHEST,
10672 BGP_STATS_MAX,
10673 };
10674
10675 static const char *const table_stats_strs[] = {
10676 [BGP_STATS_PREFIXES] = "Total Prefixes",
10677 [BGP_STATS_TOTPLEN] = "Average prefix length",
10678 [BGP_STATS_RIB] = "Total Advertisements",
10679 [BGP_STATS_UNAGGREGATEABLE] = "Unaggregateable prefixes",
10680 [BGP_STATS_MAX_AGGREGATEABLE] =
10681 "Maximum aggregateable prefixes",
10682 [BGP_STATS_AGGREGATES] = "BGP Aggregate advertisements",
10683 [BGP_STATS_SPACE] = "Address space advertised",
10684 [BGP_STATS_ASPATH_COUNT] = "Advertisements with paths",
10685 [BGP_STATS_ASPATH_MAXHOPS] = "Longest AS-Path (hops)",
10686 [BGP_STATS_ASPATH_MAXSIZE] = "Largest AS-Path (bytes)",
10687 [BGP_STATS_ASPATH_TOTHOPS] = "Average AS-Path length (hops)",
10688 [BGP_STATS_ASPATH_TOTSIZE] = "Average AS-Path size (bytes)",
10689 [BGP_STATS_ASN_HIGHEST] = "Highest public ASN",
10690 [BGP_STATS_MAX] = NULL,
10691 };
10692
10693 struct bgp_table_stats {
10694 struct bgp_table *table;
10695 unsigned long long counts[BGP_STATS_MAX];
10696 double total_space;
10697 };
10698
10699 #if 0
10700 #define TALLY_SIGFIG 100000
10701 static unsigned long
10702 ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
10703 {
10704 unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
10705 unsigned long res = (newtot * TALLY_SIGFIG) / count;
10706 unsigned long ret = newtot / count;
10707
10708 if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
10709 return ret + 1;
10710 else
10711 return ret;
10712 }
10713 #endif
10714
10715 static void bgp_table_stats_rn(struct bgp_node *rn, struct bgp_node *top,
10716 struct bgp_table_stats *ts, unsigned int space)
10717 {
10718 struct bgp_node *prn = bgp_node_parent_nolock(rn);
10719 struct bgp_path_info *pi;
10720
10721 if (rn == top)
10722 return;
10723
10724 if (!bgp_node_has_bgp_path_info_data(rn))
10725 return;
10726
10727 ts->counts[BGP_STATS_PREFIXES]++;
10728 ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
10729
10730 #if 0
10731 ts->counts[BGP_STATS_AVGPLEN]
10732 = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
10733 ts->counts[BGP_STATS_AVGPLEN],
10734 rn->p.prefixlen);
10735 #endif
10736
10737 /* check if the prefix is included by any other announcements */
10738 while (prn && !bgp_node_has_bgp_path_info_data(prn))
10739 prn = bgp_node_parent_nolock(prn);
10740
10741 if (prn == NULL || prn == top) {
10742 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
10743 /* announced address space */
10744 if (space)
10745 ts->total_space += pow(2.0, space - rn->p.prefixlen);
10746 } else if (bgp_node_has_bgp_path_info_data(prn))
10747 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
10748
10749
10750 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
10751 ts->counts[BGP_STATS_RIB]++;
10752
10753 if (CHECK_FLAG(pi->attr->flag,
10754 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
10755 ts->counts[BGP_STATS_AGGREGATES]++;
10756
10757 /* as-path stats */
10758 if (pi->attr->aspath) {
10759 unsigned int hops = aspath_count_hops(pi->attr->aspath);
10760 unsigned int size = aspath_size(pi->attr->aspath);
10761 as_t highest = aspath_highest(pi->attr->aspath);
10762
10763 ts->counts[BGP_STATS_ASPATH_COUNT]++;
10764
10765 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
10766 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
10767
10768 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
10769 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
10770
10771 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
10772 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
10773 #if 0
10774 ts->counts[BGP_STATS_ASPATH_AVGHOPS]
10775 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
10776 ts->counts[BGP_STATS_ASPATH_AVGHOPS],
10777 hops);
10778 ts->counts[BGP_STATS_ASPATH_AVGSIZE]
10779 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
10780 ts->counts[BGP_STATS_ASPATH_AVGSIZE],
10781 size);
10782 #endif
10783 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
10784 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
10785 }
10786 }
10787 }
10788
10789 static int bgp_table_stats_walker(struct thread *t)
10790 {
10791 struct bgp_node *rn, *nrn;
10792 struct bgp_node *top;
10793 struct bgp_table_stats *ts = THREAD_ARG(t);
10794 unsigned int space = 0;
10795
10796 if (!(top = bgp_table_top(ts->table)))
10797 return 0;
10798
10799 switch (ts->table->afi) {
10800 case AFI_IP:
10801 space = IPV4_MAX_BITLEN;
10802 break;
10803 case AFI_IP6:
10804 space = IPV6_MAX_BITLEN;
10805 break;
10806 default:
10807 return 0;
10808 }
10809
10810 ts->counts[BGP_STATS_MAXBITLEN] = space;
10811
10812 for (rn = top; rn; rn = bgp_route_next(rn)) {
10813 if (ts->table->safi == SAFI_MPLS_VPN) {
10814 struct bgp_table *table;
10815
10816 table = bgp_node_get_bgp_table_info(rn);
10817 if (!table)
10818 continue;
10819
10820 top = bgp_table_top(table);
10821 for (nrn = bgp_table_top(table); nrn;
10822 nrn = bgp_route_next(nrn))
10823 bgp_table_stats_rn(nrn, top, ts, space);
10824 } else {
10825 bgp_table_stats_rn(rn, top, ts, space);
10826 }
10827 }
10828
10829 return 0;
10830 }
10831
10832 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
10833 safi_t safi)
10834 {
10835 struct bgp_table_stats ts;
10836 unsigned int i;
10837
10838 if (!bgp->rib[afi][safi]) {
10839 vty_out(vty, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
10840 afi, safi);
10841 return CMD_WARNING;
10842 }
10843
10844 vty_out(vty, "BGP %s RIB statistics\n", get_afi_safi_str(afi, safi, false));
10845
10846 /* labeled-unicast routes live in the unicast table */
10847 if (safi == SAFI_LABELED_UNICAST)
10848 safi = SAFI_UNICAST;
10849
10850 memset(&ts, 0, sizeof(ts));
10851 ts.table = bgp->rib[afi][safi];
10852 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
10853
10854 for (i = 0; i < BGP_STATS_MAX; i++) {
10855 if (!table_stats_strs[i])
10856 continue;
10857
10858 switch (i) {
10859 #if 0
10860 case BGP_STATS_ASPATH_AVGHOPS:
10861 case BGP_STATS_ASPATH_AVGSIZE:
10862 case BGP_STATS_AVGPLEN:
10863 vty_out (vty, "%-30s: ", table_stats_strs[i]);
10864 vty_out (vty, "%12.2f",
10865 (float)ts.counts[i] / (float)TALLY_SIGFIG);
10866 break;
10867 #endif
10868 case BGP_STATS_ASPATH_TOTHOPS:
10869 case BGP_STATS_ASPATH_TOTSIZE:
10870 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10871 vty_out(vty, "%12.2f",
10872 ts.counts[i]
10873 ? (float)ts.counts[i]
10874 / (float)ts.counts
10875 [BGP_STATS_ASPATH_COUNT]
10876 : 0);
10877 break;
10878 case BGP_STATS_TOTPLEN:
10879 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10880 vty_out(vty, "%12.2f",
10881 ts.counts[i]
10882 ? (float)ts.counts[i]
10883 / (float)ts.counts
10884 [BGP_STATS_PREFIXES]
10885 : 0);
10886 break;
10887 case BGP_STATS_SPACE:
10888 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10889 vty_out(vty, "%12g\n", ts.total_space);
10890
10891 if (afi == AFI_IP6) {
10892 vty_out(vty, "%30s: ", "/32 equivalent ");
10893 vty_out(vty, "%12g\n",
10894 ts.total_space * pow(2.0, -128 + 32));
10895 vty_out(vty, "%30s: ", "/48 equivalent ");
10896 vty_out(vty, "%12g\n",
10897 ts.total_space * pow(2.0, -128 + 48));
10898 } else {
10899 vty_out(vty, "%30s: ", "% announced ");
10900 vty_out(vty, "%12.2f\n",
10901 ts.total_space * 100. * pow(2.0, -32));
10902 vty_out(vty, "%30s: ", "/8 equivalent ");
10903 vty_out(vty, "%12.2f\n",
10904 ts.total_space * pow(2.0, -32 + 8));
10905 vty_out(vty, "%30s: ", "/24 equivalent ");
10906 vty_out(vty, "%12.2f\n",
10907 ts.total_space * pow(2.0, -32 + 24));
10908 }
10909 break;
10910 default:
10911 vty_out(vty, "%-30s: ", table_stats_strs[i]);
10912 vty_out(vty, "%12llu", ts.counts[i]);
10913 }
10914
10915 vty_out(vty, "\n");
10916 }
10917 return CMD_SUCCESS;
10918 }
10919
10920 enum bgp_pcounts {
10921 PCOUNT_ADJ_IN = 0,
10922 PCOUNT_DAMPED,
10923 PCOUNT_REMOVED,
10924 PCOUNT_HISTORY,
10925 PCOUNT_STALE,
10926 PCOUNT_VALID,
10927 PCOUNT_ALL,
10928 PCOUNT_COUNTED,
10929 PCOUNT_PFCNT, /* the figure we display to users */
10930 PCOUNT_MAX,
10931 };
10932
10933 static const char *const pcount_strs[] = {
10934 [PCOUNT_ADJ_IN] = "Adj-in",
10935 [PCOUNT_DAMPED] = "Damped",
10936 [PCOUNT_REMOVED] = "Removed",
10937 [PCOUNT_HISTORY] = "History",
10938 [PCOUNT_STALE] = "Stale",
10939 [PCOUNT_VALID] = "Valid",
10940 [PCOUNT_ALL] = "All RIB",
10941 [PCOUNT_COUNTED] = "PfxCt counted",
10942 [PCOUNT_PFCNT] = "Useable",
10943 [PCOUNT_MAX] = NULL,
10944 };
10945
10946 struct peer_pcounts {
10947 unsigned int count[PCOUNT_MAX];
10948 const struct peer *peer;
10949 const struct bgp_table *table;
10950 safi_t safi;
10951 };
10952
10953 static void bgp_peer_count_proc(struct bgp_node *rn,
10954 struct peer_pcounts *pc)
10955 {
10956 const struct bgp_adj_in *ain;
10957 const struct bgp_path_info *pi;
10958 const struct peer *peer = pc->peer;
10959
10960 for (ain = rn->adj_in; ain; ain = ain->next)
10961 if (ain->peer == peer)
10962 pc->count[PCOUNT_ADJ_IN]++;
10963
10964 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
10965
10966 if (pi->peer != peer)
10967 continue;
10968
10969 pc->count[PCOUNT_ALL]++;
10970
10971 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
10972 pc->count[PCOUNT_DAMPED]++;
10973 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
10974 pc->count[PCOUNT_HISTORY]++;
10975 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
10976 pc->count[PCOUNT_REMOVED]++;
10977 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
10978 pc->count[PCOUNT_STALE]++;
10979 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
10980 pc->count[PCOUNT_VALID]++;
10981 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
10982 pc->count[PCOUNT_PFCNT]++;
10983
10984 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
10985 pc->count[PCOUNT_COUNTED]++;
10986 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
10987 flog_err(
10988 EC_LIB_DEVELOPMENT,
10989 "Attempting to count but flags say it is unusable");
10990 } else {
10991 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
10992 flog_err(
10993 EC_LIB_DEVELOPMENT,
10994 "Not counted but flags say we should");
10995 }
10996 }
10997 }
10998
10999 static int bgp_peer_count_walker(struct thread *t)
11000 {
11001 struct bgp_node *rn, *rm;
11002 const struct bgp_table *table;
11003 struct peer_pcounts *pc = THREAD_ARG(t);
11004
11005 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
11006 || pc->safi == SAFI_EVPN) {
11007 /* Special handling for 2-level routing tables. */
11008 for (rn = bgp_table_top(pc->table); rn;
11009 rn = bgp_route_next(rn)) {
11010 table = bgp_node_get_bgp_table_info(rn);
11011 if (table != NULL)
11012 for (rm = bgp_table_top(table); rm;
11013 rm = bgp_route_next(rm))
11014 bgp_peer_count_proc(rm, pc);
11015 }
11016 } else
11017 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
11018 bgp_peer_count_proc(rn, pc);
11019
11020 return 0;
11021 }
11022
11023 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
11024 safi_t safi, bool use_json)
11025 {
11026 struct peer_pcounts pcounts = {.peer = peer};
11027 unsigned int i;
11028 json_object *json = NULL;
11029 json_object *json_loop = NULL;
11030
11031 if (use_json) {
11032 json = json_object_new_object();
11033 json_loop = json_object_new_object();
11034 }
11035
11036 if (!peer || !peer->bgp || !peer->afc[afi][safi]
11037 || !peer->bgp->rib[afi][safi]) {
11038 if (use_json) {
11039 json_object_string_add(
11040 json, "warning",
11041 "No such neighbor or address family");
11042 vty_out(vty, "%s\n", json_object_to_json_string(json));
11043 json_object_free(json);
11044 } else
11045 vty_out(vty, "%% No such neighbor or address family\n");
11046
11047 return CMD_WARNING;
11048 }
11049
11050 memset(&pcounts, 0, sizeof(pcounts));
11051 pcounts.peer = peer;
11052 pcounts.table = peer->bgp->rib[afi][safi];
11053 pcounts.safi = safi;
11054
11055 /* in-place call via thread subsystem so as to record execution time
11056 * stats for the thread-walk (i.e. ensure this can't be blamed on
11057 * on just vty_read()).
11058 */
11059 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
11060
11061 if (use_json) {
11062 json_object_string_add(json, "prefixCountsFor", peer->host);
11063 json_object_string_add(json, "multiProtocol",
11064 get_afi_safi_str(afi, safi, true));
11065 json_object_int_add(json, "pfxCounter",
11066 peer->pcount[afi][safi]);
11067
11068 for (i = 0; i < PCOUNT_MAX; i++)
11069 json_object_int_add(json_loop, pcount_strs[i],
11070 pcounts.count[i]);
11071
11072 json_object_object_add(json, "ribTableWalkCounters", json_loop);
11073
11074 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
11075 json_object_string_add(json, "pfxctDriftFor",
11076 peer->host);
11077 json_object_string_add(
11078 json, "recommended",
11079 "Please report this bug, with the above command output");
11080 }
11081 vty_out(vty, "%s\n", json_object_to_json_string_ext(
11082 json, JSON_C_TO_STRING_PRETTY));
11083 json_object_free(json);
11084 } else {
11085
11086 if (peer->hostname
11087 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
11088 vty_out(vty, "Prefix counts for %s/%s, %s\n",
11089 peer->hostname, peer->host,
11090 get_afi_safi_str(afi, safi, false));
11091 } else {
11092 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
11093 get_afi_safi_str(afi, safi, false));
11094 }
11095
11096 vty_out(vty, "PfxCt: %" PRIu32 "\n", peer->pcount[afi][safi]);
11097 vty_out(vty, "\nCounts from RIB table walk:\n\n");
11098
11099 for (i = 0; i < PCOUNT_MAX; i++)
11100 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
11101 pcounts.count[i]);
11102
11103 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
11104 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
11105 vty_out(vty,
11106 "Please report this bug, with the above command output\n");
11107 }
11108 }
11109
11110 return CMD_SUCCESS;
11111 }
11112
11113 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
11114 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
11115 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] "
11116 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
11117 SHOW_STR
11118 IP_STR
11119 BGP_STR
11120 BGP_INSTANCE_HELP_STR
11121 BGP_AFI_HELP_STR
11122 BGP_SAFI_HELP_STR
11123 "Detailed information on TCP and BGP neighbor connections\n"
11124 "Neighbor to display information about\n"
11125 "Neighbor to display information about\n"
11126 "Neighbor on BGP configured interface\n"
11127 "Display detailed prefix count information\n"
11128 JSON_STR)
11129 {
11130 afi_t afi = AFI_IP6;
11131 safi_t safi = SAFI_UNICAST;
11132 struct peer *peer;
11133 int idx = 0;
11134 struct bgp *bgp = NULL;
11135 bool uj = use_json(argc, argv);
11136
11137 if (uj)
11138 argc--;
11139
11140 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11141 &bgp, uj);
11142 if (!idx)
11143 return CMD_WARNING;
11144
11145 argv_find(argv, argc, "neighbors", &idx);
11146 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
11147 if (!peer)
11148 return CMD_WARNING;
11149
11150 return bgp_peer_counts(vty, peer, afi, safi, uj);
11151 }
11152
11153 #ifdef KEEP_OLD_VPN_COMMANDS
11154 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
11155 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
11156 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
11157 SHOW_STR
11158 IP_STR
11159 BGP_STR
11160 BGP_VPNVX_HELP_STR
11161 "Display information about all VPNv4 NLRIs\n"
11162 "Detailed information on TCP and BGP neighbor connections\n"
11163 "Neighbor to display information about\n"
11164 "Neighbor to display information about\n"
11165 "Neighbor on BGP configured interface\n"
11166 "Display detailed prefix count information\n"
11167 JSON_STR)
11168 {
11169 int idx_peer = 6;
11170 struct peer *peer;
11171 bool uj = use_json(argc, argv);
11172
11173 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
11174 if (!peer)
11175 return CMD_WARNING;
11176
11177 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
11178 }
11179
11180 DEFUN (show_ip_bgp_vpn_all_route_prefix,
11181 show_ip_bgp_vpn_all_route_prefix_cmd,
11182 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
11183 SHOW_STR
11184 IP_STR
11185 BGP_STR
11186 BGP_VPNVX_HELP_STR
11187 "Display information about all VPNv4 NLRIs\n"
11188 "Network in the BGP routing table to display\n"
11189 "Network in the BGP routing table to display\n"
11190 JSON_STR)
11191 {
11192 int idx = 0;
11193 char *network = NULL;
11194 struct bgp *bgp = bgp_get_default();
11195 if (!bgp) {
11196 vty_out(vty, "Can't find default instance\n");
11197 return CMD_WARNING;
11198 }
11199
11200 if (argv_find(argv, argc, "A.B.C.D", &idx))
11201 network = argv[idx]->arg;
11202 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
11203 network = argv[idx]->arg;
11204 else {
11205 vty_out(vty, "Unable to figure out Network\n");
11206 return CMD_WARNING;
11207 }
11208
11209 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
11210 BGP_PATH_SHOW_ALL, use_json(argc, argv));
11211 }
11212 #endif /* KEEP_OLD_VPN_COMMANDS */
11213
11214 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
11215 show_bgp_l2vpn_evpn_route_prefix_cmd,
11216 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
11217 SHOW_STR
11218 BGP_STR
11219 L2VPN_HELP_STR
11220 EVPN_HELP_STR
11221 "Network in the BGP routing table to display\n"
11222 "Network in the BGP routing table to display\n"
11223 "Network in the BGP routing table to display\n"
11224 "Network in the BGP routing table to display\n"
11225 JSON_STR)
11226 {
11227 int idx = 0;
11228 char *network = NULL;
11229 int prefix_check = 0;
11230
11231 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
11232 argv_find(argv, argc, "X:X::X:X", &idx))
11233 network = argv[idx]->arg;
11234 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
11235 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
11236 network = argv[idx]->arg;
11237 prefix_check = 1;
11238 } else {
11239 vty_out(vty, "Unable to figure out Network\n");
11240 return CMD_WARNING;
11241 }
11242 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
11243 prefix_check, BGP_PATH_SHOW_ALL,
11244 use_json(argc, argv));
11245 }
11246
11247 static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
11248 safi_t safi, enum bgp_show_adj_route_type type,
11249 const char *rmap_name, bool use_json,
11250 json_object *json)
11251 {
11252 struct bgp_table *table;
11253 struct bgp_adj_in *ain;
11254 struct bgp_adj_out *adj;
11255 unsigned long output_count;
11256 unsigned long filtered_count;
11257 struct bgp_node *rn;
11258 int header1 = 1;
11259 struct bgp *bgp;
11260 int header2 = 1;
11261 struct attr attr;
11262 int ret;
11263 struct update_subgroup *subgrp;
11264 json_object *json_scode = NULL;
11265 json_object *json_ocode = NULL;
11266 json_object *json_ar = NULL;
11267 struct peer_af *paf;
11268 bool route_filtered;
11269
11270 if (use_json) {
11271 json_scode = json_object_new_object();
11272 json_ocode = json_object_new_object();
11273 json_ar = json_object_new_object();
11274
11275 json_object_string_add(json_scode, "suppressed", "s");
11276 json_object_string_add(json_scode, "damped", "d");
11277 json_object_string_add(json_scode, "history", "h");
11278 json_object_string_add(json_scode, "valid", "*");
11279 json_object_string_add(json_scode, "best", ">");
11280 json_object_string_add(json_scode, "multipath", "=");
11281 json_object_string_add(json_scode, "internal", "i");
11282 json_object_string_add(json_scode, "ribFailure", "r");
11283 json_object_string_add(json_scode, "stale", "S");
11284 json_object_string_add(json_scode, "removed", "R");
11285
11286 json_object_string_add(json_ocode, "igp", "i");
11287 json_object_string_add(json_ocode, "egp", "e");
11288 json_object_string_add(json_ocode, "incomplete", "?");
11289 }
11290
11291 bgp = peer->bgp;
11292
11293 if (!bgp) {
11294 if (use_json) {
11295 json_object_string_add(json, "alert", "no BGP");
11296 vty_out(vty, "%s\n", json_object_to_json_string(json));
11297 json_object_free(json);
11298 } else
11299 vty_out(vty, "%% No bgp\n");
11300 return;
11301 }
11302
11303 /* labeled-unicast routes live in the unicast table */
11304 if (safi == SAFI_LABELED_UNICAST)
11305 table = bgp->rib[afi][SAFI_UNICAST];
11306 else
11307 table = bgp->rib[afi][safi];
11308
11309 output_count = filtered_count = 0;
11310 subgrp = peer_subgroup(peer, afi, safi);
11311
11312 if (type == bgp_show_adj_route_advertised && subgrp
11313 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
11314 if (use_json) {
11315 json_object_int_add(json, "bgpTableVersion",
11316 table->version);
11317 json_object_string_add(json, "bgpLocalRouterId",
11318 inet_ntoa(bgp->router_id));
11319 json_object_int_add(json, "defaultLocPrf",
11320 bgp->default_local_pref);
11321 json_object_int_add(json, "localAS", bgp->as);
11322 json_object_object_add(json, "bgpStatusCodes",
11323 json_scode);
11324 json_object_object_add(json, "bgpOriginCodes",
11325 json_ocode);
11326 json_object_string_add(
11327 json, "bgpOriginatingDefaultNetwork",
11328 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
11329 } else {
11330 vty_out(vty, "BGP table version is %" PRIu64
11331 ", local router ID is %s, vrf id ",
11332 table->version, inet_ntoa(bgp->router_id));
11333 if (bgp->vrf_id == VRF_UNKNOWN)
11334 vty_out(vty, "%s", VRFID_NONE_STR);
11335 else
11336 vty_out(vty, "%u", bgp->vrf_id);
11337 vty_out(vty, "\n");
11338 vty_out(vty, "Default local pref %u, ",
11339 bgp->default_local_pref);
11340 vty_out(vty, "local AS %u\n", bgp->as);
11341 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11342 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11343 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11344
11345 vty_out(vty, "Originating default network %s\n\n",
11346 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
11347 }
11348 header1 = 0;
11349 }
11350
11351 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
11352 if (type == bgp_show_adj_route_received
11353 || type == bgp_show_adj_route_filtered) {
11354 for (ain = rn->adj_in; ain; ain = ain->next) {
11355 if (ain->peer != peer)
11356 continue;
11357
11358 if (header1) {
11359 if (use_json) {
11360 json_object_int_add(
11361 json, "bgpTableVersion",
11362 0);
11363 json_object_string_add(
11364 json,
11365 "bgpLocalRouterId",
11366 inet_ntoa(
11367 bgp->router_id));
11368 json_object_int_add(json,
11369 "defaultLocPrf",
11370 bgp->default_local_pref);
11371 json_object_int_add(json,
11372 "localAS", bgp->as);
11373 json_object_object_add(
11374 json, "bgpStatusCodes",
11375 json_scode);
11376 json_object_object_add(
11377 json, "bgpOriginCodes",
11378 json_ocode);
11379 } else {
11380 vty_out(vty,
11381 "BGP table version is 0, local router ID is %s, vrf id ",
11382 inet_ntoa(
11383 bgp->router_id));
11384 if (bgp->vrf_id == VRF_UNKNOWN)
11385 vty_out(vty, "%s",
11386 VRFID_NONE_STR);
11387 else
11388 vty_out(vty, "%u",
11389 bgp->vrf_id);
11390 vty_out(vty, "\n");
11391 vty_out(vty,
11392 "Default local pref %u, ",
11393 bgp->default_local_pref);
11394 vty_out(vty, "local AS %u\n",
11395 bgp->as);
11396 vty_out(vty,
11397 BGP_SHOW_SCODE_HEADER);
11398 vty_out(vty,
11399 BGP_SHOW_NCODE_HEADER);
11400 vty_out(vty,
11401 BGP_SHOW_OCODE_HEADER);
11402 }
11403 header1 = 0;
11404 }
11405 if (header2) {
11406 if (!use_json)
11407 vty_out(vty, BGP_SHOW_HEADER);
11408 header2 = 0;
11409 }
11410
11411 attr = *ain->attr;
11412 route_filtered = false;
11413
11414 /* Filter prefix using distribute list,
11415 * filter list or prefix list
11416 */
11417 if ((bgp_input_filter(peer, &rn->p, &attr, afi,
11418 safi)) == FILTER_DENY)
11419 route_filtered = true;
11420
11421 /* Filter prefix using route-map */
11422 ret = bgp_input_modifier(peer, &rn->p, &attr,
11423 afi, safi, rmap_name, NULL, 0,
11424 NULL);
11425
11426 if (type == bgp_show_adj_route_filtered &&
11427 !route_filtered && ret != RMAP_DENY) {
11428 bgp_attr_undup(&attr, ain->attr);
11429 continue;
11430 }
11431
11432 if (type == bgp_show_adj_route_received &&
11433 (route_filtered || ret == RMAP_DENY))
11434 filtered_count++;
11435
11436 route_vty_out_tmp(vty, &rn->p, &attr, safi,
11437 use_json, json_ar);
11438 bgp_attr_undup(&attr, ain->attr);
11439 output_count++;
11440 }
11441 } else if (type == bgp_show_adj_route_advertised) {
11442 RB_FOREACH (adj, bgp_adj_out_rb, &rn->adj_out)
11443 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
11444 if (paf->peer != peer || !adj->attr)
11445 continue;
11446
11447 if (header1) {
11448 if (use_json) {
11449 json_object_int_add(
11450 json,
11451 "bgpTableVersion",
11452 table->version);
11453 json_object_string_add(
11454 json,
11455 "bgpLocalRouterId",
11456 inet_ntoa(
11457 bgp->router_id));
11458 json_object_int_add(
11459 json, "defaultLocPrf",
11460 bgp->default_local_pref
11461 );
11462 json_object_int_add(
11463 json, "localAS",
11464 bgp->as);
11465 json_object_object_add(
11466 json,
11467 "bgpStatusCodes",
11468 json_scode);
11469 json_object_object_add(
11470 json,
11471 "bgpOriginCodes",
11472 json_ocode);
11473 } else {
11474 vty_out(vty,
11475 "BGP table version is %" PRIu64
11476 ", local router ID is %s, vrf id ",
11477 table->version,
11478 inet_ntoa(
11479 bgp->router_id));
11480 if (bgp->vrf_id ==
11481 VRF_UNKNOWN)
11482 vty_out(vty,
11483 "%s",
11484 VRFID_NONE_STR);
11485 else
11486 vty_out(vty,
11487 "%u",
11488 bgp->vrf_id);
11489 vty_out(vty, "\n");
11490 vty_out(vty,
11491 "Default local pref %u, ",
11492 bgp->default_local_pref
11493 );
11494 vty_out(vty,
11495 "local AS %u\n",
11496 bgp->as);
11497 vty_out(vty,
11498 BGP_SHOW_SCODE_HEADER);
11499 vty_out(vty,
11500 BGP_SHOW_NCODE_HEADER);
11501 vty_out(vty,
11502 BGP_SHOW_OCODE_HEADER);
11503 }
11504 header1 = 0;
11505 }
11506 if (header2) {
11507 if (!use_json)
11508 vty_out(vty,
11509 BGP_SHOW_HEADER);
11510 header2 = 0;
11511 }
11512
11513 attr = *adj->attr;
11514 ret = bgp_output_modifier(
11515 peer, &rn->p, &attr, afi, safi,
11516 rmap_name);
11517
11518 if (ret != RMAP_DENY) {
11519 route_vty_out_tmp(vty, &rn->p,
11520 &attr, safi,
11521 use_json,
11522 json_ar);
11523 output_count++;
11524 } else {
11525 filtered_count++;
11526 }
11527
11528 bgp_attr_undup(&attr, adj->attr);
11529 }
11530 }
11531 }
11532
11533 if (use_json) {
11534 json_object_object_add(json, "advertisedRoutes", json_ar);
11535 json_object_int_add(json, "totalPrefixCounter", output_count);
11536 json_object_int_add(json, "filteredPrefixCounter",
11537 filtered_count);
11538
11539 vty_out(vty, "%s\n", json_object_to_json_string_ext(
11540 json, JSON_C_TO_STRING_PRETTY));
11541 json_object_free(json);
11542 } else if (output_count > 0) {
11543 if (filtered_count > 0)
11544 vty_out(vty,
11545 "\nTotal number of prefixes %ld (%ld filtered)\n",
11546 output_count, filtered_count);
11547 else
11548 vty_out(vty, "\nTotal number of prefixes %ld\n",
11549 output_count);
11550 }
11551 }
11552
11553 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
11554 safi_t safi, enum bgp_show_adj_route_type type,
11555 const char *rmap_name, bool use_json)
11556 {
11557 json_object *json = NULL;
11558
11559 if (use_json)
11560 json = json_object_new_object();
11561
11562 if (!peer || !peer->afc[afi][safi]) {
11563 if (use_json) {
11564 json_object_string_add(
11565 json, "warning",
11566 "No such neighbor or address family");
11567 vty_out(vty, "%s\n", json_object_to_json_string(json));
11568 json_object_free(json);
11569 } else
11570 vty_out(vty, "%% No such neighbor or address family\n");
11571
11572 return CMD_WARNING;
11573 }
11574
11575 if ((type == bgp_show_adj_route_received
11576 || type == bgp_show_adj_route_filtered)
11577 && !CHECK_FLAG(peer->af_flags[afi][safi],
11578 PEER_FLAG_SOFT_RECONFIG)) {
11579 if (use_json) {
11580 json_object_string_add(
11581 json, "warning",
11582 "Inbound soft reconfiguration not enabled");
11583 vty_out(vty, "%s\n", json_object_to_json_string(json));
11584 json_object_free(json);
11585 } else
11586 vty_out(vty,
11587 "%% Inbound soft reconfiguration not enabled\n");
11588
11589 return CMD_WARNING;
11590 }
11591
11592 show_adj_route(vty, peer, afi, safi, type, rmap_name, use_json, json);
11593
11594 return CMD_SUCCESS;
11595 }
11596
11597 DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
11598 show_ip_bgp_instance_neighbor_advertised_route_cmd,
11599 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
11600 "neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map WORD] [json]",
11601 SHOW_STR
11602 IP_STR
11603 BGP_STR
11604 BGP_INSTANCE_HELP_STR
11605 BGP_AFI_HELP_STR
11606 BGP_SAFI_WITH_LABEL_HELP_STR
11607 "Detailed information on TCP and BGP neighbor connections\n"
11608 "Neighbor to display information about\n"
11609 "Neighbor to display information about\n"
11610 "Neighbor on BGP configured interface\n"
11611 "Display the routes advertised to a BGP neighbor\n"
11612 "Display the received routes from neighbor\n"
11613 "Display the filtered routes received from neighbor\n"
11614 "Route-map to modify the attributes\n"
11615 "Name of the route map\n"
11616 JSON_STR)
11617 {
11618 afi_t afi = AFI_IP6;
11619 safi_t safi = SAFI_UNICAST;
11620 char *rmap_name = NULL;
11621 char *peerstr = NULL;
11622 struct bgp *bgp = NULL;
11623 struct peer *peer;
11624 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
11625 int idx = 0;
11626 bool uj = use_json(argc, argv);
11627
11628 if (uj)
11629 argc--;
11630
11631 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11632 &bgp, uj);
11633 if (!idx)
11634 return CMD_WARNING;
11635
11636 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11637 argv_find(argv, argc, "neighbors", &idx);
11638 peerstr = argv[++idx]->arg;
11639
11640 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
11641 if (!peer)
11642 return CMD_WARNING;
11643
11644 if (argv_find(argv, argc, "advertised-routes", &idx))
11645 type = bgp_show_adj_route_advertised;
11646 else if (argv_find(argv, argc, "received-routes", &idx))
11647 type = bgp_show_adj_route_received;
11648 else if (argv_find(argv, argc, "filtered-routes", &idx))
11649 type = bgp_show_adj_route_filtered;
11650
11651 if (argv_find(argv, argc, "route-map", &idx))
11652 rmap_name = argv[++idx]->arg;
11653
11654 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, uj);
11655 }
11656
11657 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
11658 show_ip_bgp_neighbor_received_prefix_filter_cmd,
11659 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
11660 SHOW_STR
11661 IP_STR
11662 BGP_STR
11663 "Address Family\n"
11664 "Address Family\n"
11665 "Address Family modifier\n"
11666 "Detailed information on TCP and BGP neighbor connections\n"
11667 "Neighbor to display information about\n"
11668 "Neighbor to display information about\n"
11669 "Neighbor on BGP configured interface\n"
11670 "Display information received from a BGP neighbor\n"
11671 "Display the prefixlist filter\n"
11672 JSON_STR)
11673 {
11674 afi_t afi = AFI_IP6;
11675 safi_t safi = SAFI_UNICAST;
11676 char *peerstr = NULL;
11677
11678 char name[BUFSIZ];
11679 union sockunion su;
11680 struct peer *peer;
11681 int count, ret;
11682
11683 int idx = 0;
11684
11685 /* show [ip] bgp */
11686 if (argv_find(argv, argc, "ip", &idx))
11687 afi = AFI_IP;
11688 /* [<ipv4|ipv6> [unicast]] */
11689 if (argv_find(argv, argc, "ipv4", &idx))
11690 afi = AFI_IP;
11691 if (argv_find(argv, argc, "ipv6", &idx))
11692 afi = AFI_IP6;
11693 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11694 argv_find(argv, argc, "neighbors", &idx);
11695 peerstr = argv[++idx]->arg;
11696
11697 bool uj = use_json(argc, argv);
11698
11699 ret = str2sockunion(peerstr, &su);
11700 if (ret < 0) {
11701 peer = peer_lookup_by_conf_if(NULL, peerstr);
11702 if (!peer) {
11703 if (uj)
11704 vty_out(vty, "{}\n");
11705 else
11706 vty_out(vty,
11707 "%% Malformed address or name: %s\n",
11708 peerstr);
11709 return CMD_WARNING;
11710 }
11711 } else {
11712 peer = peer_lookup(NULL, &su);
11713 if (!peer) {
11714 if (uj)
11715 vty_out(vty, "{}\n");
11716 else
11717 vty_out(vty, "No peer\n");
11718 return CMD_WARNING;
11719 }
11720 }
11721
11722 sprintf(name, "%s.%d.%d", peer->host, afi, safi);
11723 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
11724 if (count) {
11725 if (!uj)
11726 vty_out(vty, "Address Family: %s\n",
11727 get_afi_safi_str(afi, safi, false));
11728 prefix_bgp_show_prefix_list(vty, afi, name, uj);
11729 } else {
11730 if (uj)
11731 vty_out(vty, "{}\n");
11732 else
11733 vty_out(vty, "No functional output\n");
11734 }
11735
11736 return CMD_SUCCESS;
11737 }
11738
11739 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
11740 afi_t afi, safi_t safi,
11741 enum bgp_show_type type, bool use_json)
11742 {
11743 /* labeled-unicast routes live in the unicast table */
11744 if (safi == SAFI_LABELED_UNICAST)
11745 safi = SAFI_UNICAST;
11746
11747 if (!peer || !peer->afc[afi][safi]) {
11748 if (use_json) {
11749 json_object *json_no = NULL;
11750 json_no = json_object_new_object();
11751 json_object_string_add(
11752 json_no, "warning",
11753 "No such neighbor or address family");
11754 vty_out(vty, "%s\n",
11755 json_object_to_json_string(json_no));
11756 json_object_free(json_no);
11757 } else
11758 vty_out(vty, "%% No such neighbor or address family\n");
11759 return CMD_WARNING;
11760 }
11761
11762 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, use_json);
11763 }
11764
11765 DEFUN (show_ip_bgp_flowspec_routes_detailed,
11766 show_ip_bgp_flowspec_routes_detailed_cmd,
11767 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
11768 SHOW_STR
11769 IP_STR
11770 BGP_STR
11771 BGP_INSTANCE_HELP_STR
11772 BGP_AFI_HELP_STR
11773 "SAFI Flowspec\n"
11774 "Detailed information on flowspec entries\n"
11775 JSON_STR)
11776 {
11777 afi_t afi = AFI_IP;
11778 safi_t safi = SAFI_UNICAST;
11779 struct bgp *bgp = NULL;
11780 int idx = 0;
11781 bool uj = use_json(argc, argv);
11782
11783 if (uj)
11784 argc--;
11785
11786 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11787 &bgp, uj);
11788 if (!idx)
11789 return CMD_WARNING;
11790
11791 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL, uj);
11792 }
11793
11794 DEFUN (show_ip_bgp_neighbor_routes,
11795 show_ip_bgp_neighbor_routes_cmd,
11796 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
11797 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
11798 SHOW_STR
11799 IP_STR
11800 BGP_STR
11801 BGP_INSTANCE_HELP_STR
11802 BGP_AFI_HELP_STR
11803 BGP_SAFI_WITH_LABEL_HELP_STR
11804 "Detailed information on TCP and BGP neighbor connections\n"
11805 "Neighbor to display information about\n"
11806 "Neighbor to display information about\n"
11807 "Neighbor on BGP configured interface\n"
11808 "Display flap statistics of the routes learned from neighbor\n"
11809 "Display the dampened routes received from neighbor\n"
11810 "Display routes learned from neighbor\n"
11811 JSON_STR)
11812 {
11813 char *peerstr = NULL;
11814 struct bgp *bgp = NULL;
11815 afi_t afi = AFI_IP6;
11816 safi_t safi = SAFI_UNICAST;
11817 struct peer *peer;
11818 enum bgp_show_type sh_type = bgp_show_type_neighbor;
11819 int idx = 0;
11820 bool uj = use_json(argc, argv);
11821
11822 if (uj)
11823 argc--;
11824
11825 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11826 &bgp, uj);
11827 if (!idx)
11828 return CMD_WARNING;
11829
11830 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11831 argv_find(argv, argc, "neighbors", &idx);
11832 peerstr = argv[++idx]->arg;
11833
11834 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
11835 if (!peer)
11836 return CMD_WARNING;
11837
11838 if (argv_find(argv, argc, "flap-statistics", &idx))
11839 sh_type = bgp_show_type_flap_neighbor;
11840 else if (argv_find(argv, argc, "dampened-routes", &idx))
11841 sh_type = bgp_show_type_damp_neighbor;
11842 else if (argv_find(argv, argc, "routes", &idx))
11843 sh_type = bgp_show_type_neighbor;
11844
11845 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
11846 }
11847
11848 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
11849
11850 struct bgp_distance {
11851 /* Distance value for the IP source prefix. */
11852 uint8_t distance;
11853
11854 /* Name of the access-list to be matched. */
11855 char *access_list;
11856 };
11857
11858 DEFUN (show_bgp_afi_vpn_rd_route,
11859 show_bgp_afi_vpn_rd_route_cmd,
11860 "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]",
11861 SHOW_STR
11862 BGP_STR
11863 BGP_AFI_HELP_STR
11864 "Address Family modifier\n"
11865 "Display information for a route distinguisher\n"
11866 "Route Distinguisher\n"
11867 "Network in the BGP routing table to display\n"
11868 "Network in the BGP routing table to display\n"
11869 JSON_STR)
11870 {
11871 int ret;
11872 struct prefix_rd prd;
11873 afi_t afi = AFI_MAX;
11874 int idx = 0;
11875
11876 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
11877 vty_out(vty, "%% Malformed Address Family\n");
11878 return CMD_WARNING;
11879 }
11880
11881 ret = str2prefix_rd(argv[5]->arg, &prd);
11882 if (!ret) {
11883 vty_out(vty, "%% Malformed Route Distinguisher\n");
11884 return CMD_WARNING;
11885 }
11886
11887 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
11888 0, BGP_PATH_SHOW_ALL, use_json(argc, argv));
11889 }
11890
11891 static struct bgp_distance *bgp_distance_new(void)
11892 {
11893 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
11894 }
11895
11896 static void bgp_distance_free(struct bgp_distance *bdistance)
11897 {
11898 XFREE(MTYPE_BGP_DISTANCE, bdistance);
11899 }
11900
11901 static int bgp_distance_set(struct vty *vty, const char *distance_str,
11902 const char *ip_str, const char *access_list_str)
11903 {
11904 int ret;
11905 afi_t afi;
11906 safi_t safi;
11907 struct prefix p;
11908 uint8_t distance;
11909 struct bgp_node *rn;
11910 struct bgp_distance *bdistance;
11911
11912 afi = bgp_node_afi(vty);
11913 safi = bgp_node_safi(vty);
11914
11915 ret = str2prefix(ip_str, &p);
11916 if (ret == 0) {
11917 vty_out(vty, "Malformed prefix\n");
11918 return CMD_WARNING_CONFIG_FAILED;
11919 }
11920
11921 distance = atoi(distance_str);
11922
11923 /* Get BGP distance node. */
11924 rn = bgp_node_get(bgp_distance_table[afi][safi], (struct prefix *)&p);
11925 bdistance = bgp_node_get_bgp_distance_info(rn);
11926 if (bdistance)
11927 bgp_unlock_node(rn);
11928 else {
11929 bdistance = bgp_distance_new();
11930 bgp_node_set_bgp_distance_info(rn, bdistance);
11931 }
11932
11933 /* Set distance value. */
11934 bdistance->distance = distance;
11935
11936 /* Reset access-list configuration. */
11937 if (bdistance->access_list) {
11938 XFREE(MTYPE_AS_LIST, bdistance->access_list);
11939 bdistance->access_list = NULL;
11940 }
11941 if (access_list_str)
11942 bdistance->access_list =
11943 XSTRDUP(MTYPE_AS_LIST, access_list_str);
11944
11945 return CMD_SUCCESS;
11946 }
11947
11948 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
11949 const char *ip_str, const char *access_list_str)
11950 {
11951 int ret;
11952 afi_t afi;
11953 safi_t safi;
11954 struct prefix p;
11955 int distance;
11956 struct bgp_node *rn;
11957 struct bgp_distance *bdistance;
11958
11959 afi = bgp_node_afi(vty);
11960 safi = bgp_node_safi(vty);
11961
11962 ret = str2prefix(ip_str, &p);
11963 if (ret == 0) {
11964 vty_out(vty, "Malformed prefix\n");
11965 return CMD_WARNING_CONFIG_FAILED;
11966 }
11967
11968 rn = bgp_node_lookup(bgp_distance_table[afi][safi],
11969 (struct prefix *)&p);
11970 if (!rn) {
11971 vty_out(vty, "Can't find specified prefix\n");
11972 return CMD_WARNING_CONFIG_FAILED;
11973 }
11974
11975 bdistance = bgp_node_get_bgp_distance_info(rn);
11976 distance = atoi(distance_str);
11977
11978 if (bdistance->distance != distance) {
11979 vty_out(vty, "Distance does not match configured\n");
11980 return CMD_WARNING_CONFIG_FAILED;
11981 }
11982
11983 XFREE(MTYPE_AS_LIST, bdistance->access_list);
11984 bgp_distance_free(bdistance);
11985
11986 bgp_node_set_bgp_path_info(rn, NULL);
11987 bgp_unlock_node(rn);
11988 bgp_unlock_node(rn);
11989
11990 return CMD_SUCCESS;
11991 }
11992
11993 /* Apply BGP information to distance method. */
11994 uint8_t bgp_distance_apply(struct prefix *p, struct bgp_path_info *pinfo,
11995 afi_t afi, safi_t safi, struct bgp *bgp)
11996 {
11997 struct bgp_node *rn;
11998 struct prefix q;
11999 struct peer *peer;
12000 struct bgp_distance *bdistance;
12001 struct access_list *alist;
12002 struct bgp_static *bgp_static;
12003
12004 if (!bgp)
12005 return 0;
12006
12007 peer = pinfo->peer;
12008
12009 if (pinfo->attr->distance)
12010 return pinfo->attr->distance;
12011
12012 /* Check source address. */
12013 sockunion2hostprefix(&peer->su, &q);
12014 rn = bgp_node_match(bgp_distance_table[afi][safi], &q);
12015 if (rn) {
12016 bdistance = bgp_node_get_bgp_distance_info(rn);
12017 bgp_unlock_node(rn);
12018
12019 if (bdistance->access_list) {
12020 alist = access_list_lookup(afi, bdistance->access_list);
12021 if (alist
12022 && access_list_apply(alist, p) == FILTER_PERMIT)
12023 return bdistance->distance;
12024 } else
12025 return bdistance->distance;
12026 }
12027
12028 /* Backdoor check. */
12029 rn = bgp_node_lookup(bgp->route[afi][safi], p);
12030 if (rn) {
12031 bgp_static = bgp_node_get_bgp_static_info(rn);
12032 bgp_unlock_node(rn);
12033
12034 if (bgp_static->backdoor) {
12035 if (bgp->distance_local[afi][safi])
12036 return bgp->distance_local[afi][safi];
12037 else
12038 return ZEBRA_IBGP_DISTANCE_DEFAULT;
12039 }
12040 }
12041
12042 if (peer->sort == BGP_PEER_EBGP) {
12043 if (bgp->distance_ebgp[afi][safi])
12044 return bgp->distance_ebgp[afi][safi];
12045 return ZEBRA_EBGP_DISTANCE_DEFAULT;
12046 } else {
12047 if (bgp->distance_ibgp[afi][safi])
12048 return bgp->distance_ibgp[afi][safi];
12049 return ZEBRA_IBGP_DISTANCE_DEFAULT;
12050 }
12051 }
12052
12053 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
12054 * we should tell ZEBRA update the routes for a specific
12055 * AFI/SAFI to reflect changes in RIB.
12056 */
12057 static void bgp_announce_routes_distance_update(struct bgp *bgp,
12058 afi_t update_afi,
12059 safi_t update_safi)
12060 {
12061 afi_t afi;
12062 safi_t safi;
12063
12064 FOREACH_AFI_SAFI (afi, safi) {
12065 if (!bgp_fibupd_safi(safi))
12066 continue;
12067
12068 if (afi != update_afi && safi != update_safi)
12069 continue;
12070
12071 if (BGP_DEBUG(zebra, ZEBRA))
12072 zlog_debug(
12073 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
12074 __func__, afi, safi);
12075 bgp_zebra_announce_table(bgp, afi, safi);
12076 }
12077 }
12078
12079 DEFUN (bgp_distance,
12080 bgp_distance_cmd,
12081 "distance bgp (1-255) (1-255) (1-255)",
12082 "Define an administrative distance\n"
12083 "BGP distance\n"
12084 "Distance for routes external to the AS\n"
12085 "Distance for routes internal to the AS\n"
12086 "Distance for local routes\n")
12087 {
12088 VTY_DECLVAR_CONTEXT(bgp, bgp);
12089 int idx_number = 2;
12090 int idx_number_2 = 3;
12091 int idx_number_3 = 4;
12092 int distance_ebgp = atoi(argv[idx_number]->arg);
12093 int distance_ibgp = atoi(argv[idx_number_2]->arg);
12094 int distance_local = atoi(argv[idx_number_3]->arg);
12095 afi_t afi;
12096 safi_t safi;
12097
12098 afi = bgp_node_afi(vty);
12099 safi = bgp_node_safi(vty);
12100
12101 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
12102 || bgp->distance_ibgp[afi][safi] != distance_ibgp
12103 || bgp->distance_local[afi][safi] != distance_local) {
12104 bgp->distance_ebgp[afi][safi] = distance_ebgp;
12105 bgp->distance_ibgp[afi][safi] = distance_ibgp;
12106 bgp->distance_local[afi][safi] = distance_local;
12107 bgp_announce_routes_distance_update(bgp, afi, safi);
12108 }
12109 return CMD_SUCCESS;
12110 }
12111
12112 DEFUN (no_bgp_distance,
12113 no_bgp_distance_cmd,
12114 "no distance bgp [(1-255) (1-255) (1-255)]",
12115 NO_STR
12116 "Define an administrative distance\n"
12117 "BGP distance\n"
12118 "Distance for routes external to the AS\n"
12119 "Distance for routes internal to the AS\n"
12120 "Distance for local routes\n")
12121 {
12122 VTY_DECLVAR_CONTEXT(bgp, bgp);
12123 afi_t afi;
12124 safi_t safi;
12125
12126 afi = bgp_node_afi(vty);
12127 safi = bgp_node_safi(vty);
12128
12129 if (bgp->distance_ebgp[afi][safi] != 0
12130 || bgp->distance_ibgp[afi][safi] != 0
12131 || bgp->distance_local[afi][safi] != 0) {
12132 bgp->distance_ebgp[afi][safi] = 0;
12133 bgp->distance_ibgp[afi][safi] = 0;
12134 bgp->distance_local[afi][safi] = 0;
12135 bgp_announce_routes_distance_update(bgp, afi, safi);
12136 }
12137 return CMD_SUCCESS;
12138 }
12139
12140
12141 DEFUN (bgp_distance_source,
12142 bgp_distance_source_cmd,
12143 "distance (1-255) A.B.C.D/M",
12144 "Define an administrative distance\n"
12145 "Administrative distance\n"
12146 "IP source prefix\n")
12147 {
12148 int idx_number = 1;
12149 int idx_ipv4_prefixlen = 2;
12150 bgp_distance_set(vty, argv[idx_number]->arg,
12151 argv[idx_ipv4_prefixlen]->arg, NULL);
12152 return CMD_SUCCESS;
12153 }
12154
12155 DEFUN (no_bgp_distance_source,
12156 no_bgp_distance_source_cmd,
12157 "no distance (1-255) A.B.C.D/M",
12158 NO_STR
12159 "Define an administrative distance\n"
12160 "Administrative distance\n"
12161 "IP source prefix\n")
12162 {
12163 int idx_number = 2;
12164 int idx_ipv4_prefixlen = 3;
12165 bgp_distance_unset(vty, argv[idx_number]->arg,
12166 argv[idx_ipv4_prefixlen]->arg, NULL);
12167 return CMD_SUCCESS;
12168 }
12169
12170 DEFUN (bgp_distance_source_access_list,
12171 bgp_distance_source_access_list_cmd,
12172 "distance (1-255) A.B.C.D/M WORD",
12173 "Define an administrative distance\n"
12174 "Administrative distance\n"
12175 "IP source prefix\n"
12176 "Access list name\n")
12177 {
12178 int idx_number = 1;
12179 int idx_ipv4_prefixlen = 2;
12180 int idx_word = 3;
12181 bgp_distance_set(vty, argv[idx_number]->arg,
12182 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
12183 return CMD_SUCCESS;
12184 }
12185
12186 DEFUN (no_bgp_distance_source_access_list,
12187 no_bgp_distance_source_access_list_cmd,
12188 "no distance (1-255) A.B.C.D/M WORD",
12189 NO_STR
12190 "Define an administrative distance\n"
12191 "Administrative distance\n"
12192 "IP source prefix\n"
12193 "Access list name\n")
12194 {
12195 int idx_number = 2;
12196 int idx_ipv4_prefixlen = 3;
12197 int idx_word = 4;
12198 bgp_distance_unset(vty, argv[idx_number]->arg,
12199 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
12200 return CMD_SUCCESS;
12201 }
12202
12203 DEFUN (ipv6_bgp_distance_source,
12204 ipv6_bgp_distance_source_cmd,
12205 "distance (1-255) X:X::X:X/M",
12206 "Define an administrative distance\n"
12207 "Administrative distance\n"
12208 "IP source prefix\n")
12209 {
12210 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
12211 return CMD_SUCCESS;
12212 }
12213
12214 DEFUN (no_ipv6_bgp_distance_source,
12215 no_ipv6_bgp_distance_source_cmd,
12216 "no distance (1-255) X:X::X:X/M",
12217 NO_STR
12218 "Define an administrative distance\n"
12219 "Administrative distance\n"
12220 "IP source prefix\n")
12221 {
12222 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
12223 return CMD_SUCCESS;
12224 }
12225
12226 DEFUN (ipv6_bgp_distance_source_access_list,
12227 ipv6_bgp_distance_source_access_list_cmd,
12228 "distance (1-255) X:X::X:X/M WORD",
12229 "Define an administrative distance\n"
12230 "Administrative distance\n"
12231 "IP source prefix\n"
12232 "Access list name\n")
12233 {
12234 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
12235 return CMD_SUCCESS;
12236 }
12237
12238 DEFUN (no_ipv6_bgp_distance_source_access_list,
12239 no_ipv6_bgp_distance_source_access_list_cmd,
12240 "no distance (1-255) X:X::X:X/M WORD",
12241 NO_STR
12242 "Define an administrative distance\n"
12243 "Administrative distance\n"
12244 "IP source prefix\n"
12245 "Access list name\n")
12246 {
12247 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
12248 return CMD_SUCCESS;
12249 }
12250
12251 DEFUN (bgp_damp_set,
12252 bgp_damp_set_cmd,
12253 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
12254 "BGP Specific commands\n"
12255 "Enable route-flap dampening\n"
12256 "Half-life time for the penalty\n"
12257 "Value to start reusing a route\n"
12258 "Value to start suppressing a route\n"
12259 "Maximum duration to suppress a stable route\n")
12260 {
12261 VTY_DECLVAR_CONTEXT(bgp, bgp);
12262 int idx_half_life = 2;
12263 int idx_reuse = 3;
12264 int idx_suppress = 4;
12265 int idx_max_suppress = 5;
12266 int half = DEFAULT_HALF_LIFE * 60;
12267 int reuse = DEFAULT_REUSE;
12268 int suppress = DEFAULT_SUPPRESS;
12269 int max = 4 * half;
12270
12271 if (argc == 6) {
12272 half = atoi(argv[idx_half_life]->arg) * 60;
12273 reuse = atoi(argv[idx_reuse]->arg);
12274 suppress = atoi(argv[idx_suppress]->arg);
12275 max = atoi(argv[idx_max_suppress]->arg) * 60;
12276 } else if (argc == 3) {
12277 half = atoi(argv[idx_half_life]->arg) * 60;
12278 max = 4 * half;
12279 }
12280
12281 /*
12282 * These can't be 0 but our SA doesn't understand the
12283 * way our cli is constructed
12284 */
12285 assert(reuse);
12286 assert(half);
12287 if (suppress < reuse) {
12288 vty_out(vty,
12289 "Suppress value cannot be less than reuse value \n");
12290 return 0;
12291 }
12292
12293 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
12294 reuse, suppress, max);
12295 }
12296
12297 DEFUN (bgp_damp_unset,
12298 bgp_damp_unset_cmd,
12299 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
12300 NO_STR
12301 "BGP Specific commands\n"
12302 "Enable route-flap dampening\n"
12303 "Half-life time for the penalty\n"
12304 "Value to start reusing a route\n"
12305 "Value to start suppressing a route\n"
12306 "Maximum duration to suppress a stable route\n")
12307 {
12308 VTY_DECLVAR_CONTEXT(bgp, bgp);
12309 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
12310 }
12311
12312 /* Display specified route of BGP table. */
12313 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
12314 const char *ip_str, afi_t afi, safi_t safi,
12315 struct prefix_rd *prd, int prefix_check)
12316 {
12317 int ret;
12318 struct prefix match;
12319 struct bgp_node *rn;
12320 struct bgp_node *rm;
12321 struct bgp_path_info *pi;
12322 struct bgp_path_info *pi_temp;
12323 struct bgp *bgp;
12324 struct bgp_table *table;
12325
12326 /* BGP structure lookup. */
12327 if (view_name) {
12328 bgp = bgp_lookup_by_name(view_name);
12329 if (bgp == NULL) {
12330 vty_out(vty, "%% Can't find BGP instance %s\n",
12331 view_name);
12332 return CMD_WARNING;
12333 }
12334 } else {
12335 bgp = bgp_get_default();
12336 if (bgp == NULL) {
12337 vty_out(vty, "%% No BGP process is configured\n");
12338 return CMD_WARNING;
12339 }
12340 }
12341
12342 /* Check IP address argument. */
12343 ret = str2prefix(ip_str, &match);
12344 if (!ret) {
12345 vty_out(vty, "%% address is malformed\n");
12346 return CMD_WARNING;
12347 }
12348
12349 match.family = afi2family(afi);
12350
12351 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
12352 || (safi == SAFI_EVPN)) {
12353 for (rn = bgp_table_top(bgp->rib[AFI_IP][safi]); rn;
12354 rn = bgp_route_next(rn)) {
12355 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
12356 continue;
12357 table = bgp_node_get_bgp_table_info(rn);
12358 if (!table)
12359 continue;
12360 if ((rm = bgp_node_match(table, &match)) == NULL)
12361 continue;
12362
12363 if (!prefix_check
12364 || rm->p.prefixlen == match.prefixlen) {
12365 pi = bgp_node_get_bgp_path_info(rm);
12366 while (pi) {
12367 if (pi->extra && pi->extra->damp_info) {
12368 pi_temp = pi->next;
12369 bgp_damp_info_free(
12370 pi->extra->damp_info,
12371 1, afi, safi);
12372 pi = pi_temp;
12373 } else
12374 pi = pi->next;
12375 }
12376 }
12377
12378 bgp_unlock_node(rm);
12379 }
12380 } else {
12381 if ((rn = bgp_node_match(bgp->rib[afi][safi], &match))
12382 != NULL) {
12383 if (!prefix_check
12384 || rn->p.prefixlen == match.prefixlen) {
12385 pi = bgp_node_get_bgp_path_info(rn);
12386 while (pi) {
12387 if (pi->extra && pi->extra->damp_info) {
12388 pi_temp = pi->next;
12389 bgp_damp_info_free(
12390 pi->extra->damp_info,
12391 1, afi, safi);
12392 pi = pi_temp;
12393 } else
12394 pi = pi->next;
12395 }
12396 }
12397
12398 bgp_unlock_node(rn);
12399 }
12400 }
12401
12402 return CMD_SUCCESS;
12403 }
12404
12405 DEFUN (clear_ip_bgp_dampening,
12406 clear_ip_bgp_dampening_cmd,
12407 "clear ip bgp dampening",
12408 CLEAR_STR
12409 IP_STR
12410 BGP_STR
12411 "Clear route flap dampening information\n")
12412 {
12413 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
12414 return CMD_SUCCESS;
12415 }
12416
12417 DEFUN (clear_ip_bgp_dampening_prefix,
12418 clear_ip_bgp_dampening_prefix_cmd,
12419 "clear ip bgp dampening A.B.C.D/M",
12420 CLEAR_STR
12421 IP_STR
12422 BGP_STR
12423 "Clear route flap dampening information\n"
12424 "IPv4 prefix\n")
12425 {
12426 int idx_ipv4_prefixlen = 4;
12427 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
12428 AFI_IP, SAFI_UNICAST, NULL, 1);
12429 }
12430
12431 DEFUN (clear_ip_bgp_dampening_address,
12432 clear_ip_bgp_dampening_address_cmd,
12433 "clear ip bgp dampening A.B.C.D",
12434 CLEAR_STR
12435 IP_STR
12436 BGP_STR
12437 "Clear route flap dampening information\n"
12438 "Network to clear damping information\n")
12439 {
12440 int idx_ipv4 = 4;
12441 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
12442 SAFI_UNICAST, NULL, 0);
12443 }
12444
12445 DEFUN (clear_ip_bgp_dampening_address_mask,
12446 clear_ip_bgp_dampening_address_mask_cmd,
12447 "clear ip bgp dampening A.B.C.D A.B.C.D",
12448 CLEAR_STR
12449 IP_STR
12450 BGP_STR
12451 "Clear route flap dampening information\n"
12452 "Network to clear damping information\n"
12453 "Network mask\n")
12454 {
12455 int idx_ipv4 = 4;
12456 int idx_ipv4_2 = 5;
12457 int ret;
12458 char prefix_str[BUFSIZ];
12459
12460 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
12461 prefix_str);
12462 if (!ret) {
12463 vty_out(vty, "%% Inconsistent address and mask\n");
12464 return CMD_WARNING;
12465 }
12466
12467 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
12468 NULL, 0);
12469 }
12470
12471 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
12472 {
12473 struct vty *vty = arg;
12474 struct peer *peer = bucket->data;
12475 char buf[SU_ADDRSTRLEN];
12476
12477 vty_out(vty, "\tPeer: %s %s\n", peer->host,
12478 sockunion2str(&peer->su, buf, sizeof(buf)));
12479 }
12480
12481 DEFUN (show_bgp_peerhash,
12482 show_bgp_peerhash_cmd,
12483 "show bgp peerhash",
12484 SHOW_STR
12485 BGP_STR
12486 "Display information about the BGP peerhash\n")
12487 {
12488 struct list *instances = bm->bgp;
12489 struct listnode *node;
12490 struct bgp *bgp;
12491
12492 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
12493 vty_out(vty, "BGP: %s\n", bgp->name);
12494 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
12495 vty);
12496 }
12497
12498 return CMD_SUCCESS;
12499 }
12500
12501 /* also used for encap safi */
12502 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
12503 afi_t afi, safi_t safi)
12504 {
12505 struct bgp_node *prn;
12506 struct bgp_node *rn;
12507 struct bgp_table *table;
12508 struct prefix *p;
12509 struct prefix_rd *prd;
12510 struct bgp_static *bgp_static;
12511 mpls_label_t label;
12512 char buf[SU_ADDRSTRLEN];
12513 char rdbuf[RD_ADDRSTRLEN];
12514
12515 /* Network configuration. */
12516 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
12517 prn = bgp_route_next(prn)) {
12518 table = bgp_node_get_bgp_table_info(prn);
12519 if (!table)
12520 continue;
12521
12522 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
12523 bgp_static = bgp_node_get_bgp_static_info(rn);
12524 if (bgp_static == NULL)
12525 continue;
12526
12527 p = &rn->p;
12528 prd = (struct prefix_rd *)&prn->p;
12529
12530 /* "network" configuration display. */
12531 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
12532 label = decode_label(&bgp_static->label);
12533
12534 vty_out(vty, " network %s/%d rd %s",
12535 inet_ntop(p->family, &p->u.prefix, buf,
12536 SU_ADDRSTRLEN),
12537 p->prefixlen, rdbuf);
12538 if (safi == SAFI_MPLS_VPN)
12539 vty_out(vty, " label %u", label);
12540
12541 if (bgp_static->rmap.name)
12542 vty_out(vty, " route-map %s",
12543 bgp_static->rmap.name);
12544
12545 if (bgp_static->backdoor)
12546 vty_out(vty, " backdoor");
12547
12548 vty_out(vty, "\n");
12549 }
12550 }
12551 }
12552
12553 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
12554 afi_t afi, safi_t safi)
12555 {
12556 struct bgp_node *prn;
12557 struct bgp_node *rn;
12558 struct bgp_table *table;
12559 struct prefix *p;
12560 struct prefix_rd *prd;
12561 struct bgp_static *bgp_static;
12562 char buf[PREFIX_STRLEN * 2];
12563 char buf2[SU_ADDRSTRLEN];
12564 char rdbuf[RD_ADDRSTRLEN];
12565
12566 /* Network configuration. */
12567 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
12568 prn = bgp_route_next(prn)) {
12569 table = bgp_node_get_bgp_table_info(prn);
12570 if (!table)
12571 continue;
12572
12573 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
12574 bgp_static = bgp_node_get_bgp_static_info(rn);
12575 if (bgp_static == NULL)
12576 continue;
12577
12578 char *macrouter = NULL;
12579 char *esi = NULL;
12580
12581 if (bgp_static->router_mac)
12582 macrouter = prefix_mac2str(
12583 bgp_static->router_mac, NULL, 0);
12584 if (bgp_static->eth_s_id)
12585 esi = esi2str(bgp_static->eth_s_id);
12586 p = &rn->p;
12587 prd = (struct prefix_rd *)&prn->p;
12588
12589 /* "network" configuration display. */
12590 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
12591 if (p->u.prefix_evpn.route_type == 5) {
12592 char local_buf[PREFIX_STRLEN];
12593 uint8_t family = is_evpn_prefix_ipaddr_v4((
12594 struct prefix_evpn *)p)
12595 ? AF_INET
12596 : AF_INET6;
12597 inet_ntop(family,
12598 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
12599 local_buf, PREFIX_STRLEN);
12600 sprintf(buf, "%s/%u", local_buf,
12601 p->u.prefix_evpn.prefix_addr.ip_prefix_length);
12602 } else {
12603 prefix2str(p, buf, sizeof(buf));
12604 }
12605
12606 if (bgp_static->gatewayIp.family == AF_INET
12607 || bgp_static->gatewayIp.family == AF_INET6)
12608 inet_ntop(bgp_static->gatewayIp.family,
12609 &bgp_static->gatewayIp.u.prefix, buf2,
12610 sizeof(buf2));
12611 vty_out(vty,
12612 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
12613 buf, rdbuf,
12614 p->u.prefix_evpn.prefix_addr.eth_tag,
12615 decode_label(&bgp_static->label), esi, buf2,
12616 macrouter);
12617
12618 XFREE(MTYPE_TMP, macrouter);
12619 XFREE(MTYPE_TMP, esi);
12620 }
12621 }
12622 }
12623
12624 /* Configuration of static route announcement and aggregate
12625 information. */
12626 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
12627 safi_t safi)
12628 {
12629 struct bgp_node *rn;
12630 struct prefix *p;
12631 struct bgp_static *bgp_static;
12632 struct bgp_aggregate *bgp_aggregate;
12633 char buf[SU_ADDRSTRLEN];
12634
12635 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
12636 bgp_config_write_network_vpn(vty, bgp, afi, safi);
12637 return;
12638 }
12639
12640 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
12641 bgp_config_write_network_evpn(vty, bgp, afi, safi);
12642 return;
12643 }
12644
12645 /* Network configuration. */
12646 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
12647 rn = bgp_route_next(rn)) {
12648 bgp_static = bgp_node_get_bgp_static_info(rn);
12649 if (bgp_static == NULL)
12650 continue;
12651
12652 p = &rn->p;
12653
12654 vty_out(vty, " network %s/%d",
12655 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
12656 p->prefixlen);
12657
12658 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
12659 vty_out(vty, " label-index %u",
12660 bgp_static->label_index);
12661
12662 if (bgp_static->rmap.name)
12663 vty_out(vty, " route-map %s", bgp_static->rmap.name);
12664
12665 if (bgp_static->backdoor)
12666 vty_out(vty, " backdoor");
12667
12668 vty_out(vty, "\n");
12669 }
12670
12671 /* Aggregate-address configuration. */
12672 for (rn = bgp_table_top(bgp->aggregate[afi][safi]); rn;
12673 rn = bgp_route_next(rn)) {
12674 bgp_aggregate = bgp_node_get_bgp_aggregate_info(rn);
12675 if (bgp_aggregate == NULL)
12676 continue;
12677
12678 p = &rn->p;
12679
12680 vty_out(vty, " aggregate-address %s/%d",
12681 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
12682 p->prefixlen);
12683
12684 if (bgp_aggregate->as_set)
12685 vty_out(vty, " as-set");
12686
12687 if (bgp_aggregate->summary_only)
12688 vty_out(vty, " summary-only");
12689
12690 if (bgp_aggregate->rmap.name)
12691 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
12692
12693 vty_out(vty, "\n");
12694 }
12695 }
12696
12697 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
12698 safi_t safi)
12699 {
12700 struct bgp_node *rn;
12701 struct bgp_distance *bdistance;
12702
12703 /* Distance configuration. */
12704 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
12705 && bgp->distance_local[afi][safi]
12706 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
12707 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
12708 || bgp->distance_local[afi][safi]
12709 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
12710 vty_out(vty, " distance bgp %d %d %d\n",
12711 bgp->distance_ebgp[afi][safi],
12712 bgp->distance_ibgp[afi][safi],
12713 bgp->distance_local[afi][safi]);
12714 }
12715
12716 for (rn = bgp_table_top(bgp_distance_table[afi][safi]); rn;
12717 rn = bgp_route_next(rn)) {
12718 bdistance = bgp_node_get_bgp_distance_info(rn);
12719 if (bdistance != NULL) {
12720 char buf[PREFIX_STRLEN];
12721
12722 vty_out(vty, " distance %d %s %s\n",
12723 bdistance->distance,
12724 prefix2str(&rn->p, buf, sizeof(buf)),
12725 bdistance->access_list ? bdistance->access_list
12726 : "");
12727 }
12728 }
12729 }
12730
12731 /* Allocate routing table structure and install commands. */
12732 void bgp_route_init(void)
12733 {
12734 afi_t afi;
12735 safi_t safi;
12736
12737 /* Init BGP distance table. */
12738 FOREACH_AFI_SAFI (afi, safi)
12739 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
12740
12741 /* IPv4 BGP commands. */
12742 install_element(BGP_NODE, &bgp_table_map_cmd);
12743 install_element(BGP_NODE, &bgp_network_cmd);
12744 install_element(BGP_NODE, &no_bgp_table_map_cmd);
12745
12746 install_element(BGP_NODE, &aggregate_address_cmd);
12747 install_element(BGP_NODE, &aggregate_address_mask_cmd);
12748 install_element(BGP_NODE, &no_aggregate_address_cmd);
12749 install_element(BGP_NODE, &no_aggregate_address_mask_cmd);
12750
12751 /* IPv4 unicast configuration. */
12752 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
12753 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
12754 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
12755
12756 install_element(BGP_IPV4_NODE, &aggregate_address_cmd);
12757 install_element(BGP_IPV4_NODE, &aggregate_address_mask_cmd);
12758 install_element(BGP_IPV4_NODE, &no_aggregate_address_cmd);
12759 install_element(BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
12760
12761 /* IPv4 multicast configuration. */
12762 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
12763 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
12764 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
12765 install_element(BGP_IPV4M_NODE, &aggregate_address_cmd);
12766 install_element(BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
12767 install_element(BGP_IPV4M_NODE, &no_aggregate_address_cmd);
12768 install_element(BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
12769
12770 /* IPv4 labeled-unicast configuration. */
12771 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
12772 install_element(VIEW_NODE, &show_ip_bgp_cmd);
12773 install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
12774 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
12775 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
12776
12777 install_element(VIEW_NODE,
12778 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
12779 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
12780 install_element(VIEW_NODE,
12781 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
12782 #ifdef KEEP_OLD_VPN_COMMANDS
12783 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
12784 #endif /* KEEP_OLD_VPN_COMMANDS */
12785 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
12786 install_element(VIEW_NODE,
12787 &show_bgp_l2vpn_evpn_route_prefix_cmd);
12788
12789 /* BGP dampening clear commands */
12790 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
12791 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
12792
12793 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
12794 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
12795
12796 /* prefix count */
12797 install_element(ENABLE_NODE,
12798 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
12799 #ifdef KEEP_OLD_VPN_COMMANDS
12800 install_element(ENABLE_NODE,
12801 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
12802 #endif /* KEEP_OLD_VPN_COMMANDS */
12803
12804 /* New config IPv6 BGP commands. */
12805 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
12806 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
12807 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
12808
12809 install_element(BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
12810 install_element(BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
12811
12812 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
12813
12814 install_element(BGP_NODE, &bgp_distance_cmd);
12815 install_element(BGP_NODE, &no_bgp_distance_cmd);
12816 install_element(BGP_NODE, &bgp_distance_source_cmd);
12817 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
12818 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
12819 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
12820 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
12821 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
12822 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
12823 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
12824 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
12825 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
12826 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
12827 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
12828 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
12829 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
12830 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
12831 install_element(BGP_IPV4M_NODE,
12832 &no_bgp_distance_source_access_list_cmd);
12833 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
12834 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
12835 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
12836 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
12837 install_element(BGP_IPV6_NODE,
12838 &ipv6_bgp_distance_source_access_list_cmd);
12839 install_element(BGP_IPV6_NODE,
12840 &no_ipv6_bgp_distance_source_access_list_cmd);
12841 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
12842 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
12843 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
12844 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
12845 install_element(BGP_IPV6M_NODE,
12846 &ipv6_bgp_distance_source_access_list_cmd);
12847 install_element(BGP_IPV6M_NODE,
12848 &no_ipv6_bgp_distance_source_access_list_cmd);
12849
12850 install_element(BGP_NODE, &bgp_damp_set_cmd);
12851 install_element(BGP_NODE, &bgp_damp_unset_cmd);
12852 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
12853 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
12854
12855 /* IPv4 Multicast Mode */
12856 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
12857 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
12858
12859 /* Large Communities */
12860 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
12861 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
12862
12863 /* show bgp ipv4 flowspec detailed */
12864 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
12865
12866 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
12867 }
12868
12869 void bgp_route_finish(void)
12870 {
12871 afi_t afi;
12872 safi_t safi;
12873
12874 FOREACH_AFI_SAFI (afi, safi) {
12875 bgp_table_unlock(bgp_distance_table[afi][safi]);
12876 bgp_distance_table[afi][safi] = NULL;
12877 }
12878 }