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