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