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