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