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