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