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