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