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