]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
bgpd: Tell Coverity SA that regex cannot be NULL here
[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))
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 && table) {
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("SELECT_DEFER falg 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
2766 thread_info->afi = afi;
2767 thread_info->safi = safi;
2768 thread_info->bgp = bgp;
2769
2770 /* If there are more routes to be processed, start the
2771 * selection timer
2772 */
2773 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
2774 BGP_ROUTE_SELECT_DELAY,
2775 &bgp->gr_info[afi][safi].t_route_select);
2776 return 0;
2777 }
2778
2779 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
2780 {
2781 struct bgp_process_queue *pqnode = data;
2782 struct bgp *bgp = pqnode->bgp;
2783 struct bgp_table *table;
2784 struct bgp_node *rn;
2785
2786 /* eoiu marker */
2787 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
2788 bgp_process_main_one(bgp, NULL, 0, 0);
2789 /* should always have dedicated wq call */
2790 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
2791 return WQ_SUCCESS;
2792 }
2793
2794 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
2795 rn = STAILQ_FIRST(&pqnode->pqueue);
2796 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
2797 STAILQ_NEXT(rn, pq) = NULL; /* complete unlink */
2798 table = bgp_node_table(rn);
2799 /* note, new RNs may be added as part of processing */
2800 bgp_process_main_one(bgp, rn, table->afi, table->safi);
2801
2802 bgp_unlock_node(rn);
2803 bgp_table_unlock(table);
2804 }
2805
2806 return WQ_SUCCESS;
2807 }
2808
2809 static void bgp_processq_del(struct work_queue *wq, void *data)
2810 {
2811 struct bgp_process_queue *pqnode = data;
2812
2813 bgp_unlock(pqnode->bgp);
2814
2815 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
2816 }
2817
2818 void bgp_process_queue_init(void)
2819 {
2820 if (!bm->process_main_queue)
2821 bm->process_main_queue =
2822 work_queue_new(bm->master, "process_main_queue");
2823
2824 bm->process_main_queue->spec.workfunc = &bgp_process_wq;
2825 bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
2826 bm->process_main_queue->spec.max_retries = 0;
2827 bm->process_main_queue->spec.hold = 50;
2828 /* Use a higher yield value of 50ms for main queue processing */
2829 bm->process_main_queue->spec.yield = 50 * 1000L;
2830 }
2831
2832 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
2833 {
2834 struct bgp_process_queue *pqnode;
2835
2836 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
2837 sizeof(struct bgp_process_queue));
2838
2839 /* unlocked in bgp_processq_del */
2840 pqnode->bgp = bgp_lock(bgp);
2841 STAILQ_INIT(&pqnode->pqueue);
2842
2843 return pqnode;
2844 }
2845
2846 void bgp_process(struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi)
2847 {
2848 #define ARBITRARY_PROCESS_QLEN 10000
2849 struct work_queue *wq = bm->process_main_queue;
2850 struct bgp_process_queue *pqnode;
2851 int pqnode_reuse = 0;
2852
2853 /* already scheduled for processing? */
2854 if (CHECK_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED))
2855 return;
2856
2857 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
2858 * the workqueue
2859 */
2860 if (CHECK_FLAG(rn->flags, BGP_NODE_SELECT_DEFER)) {
2861 if (BGP_DEBUG(update, UPDATE_OUT))
2862 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
2863 rn);
2864 return;
2865 }
2866
2867 if (wq == NULL)
2868 return;
2869
2870 /* Add route nodes to an existing work queue item until reaching the
2871 limit only if is from the same BGP view and it's not an EOIU marker
2872 */
2873 if (work_queue_item_count(wq)) {
2874 struct work_queue_item *item = work_queue_last_item(wq);
2875 pqnode = item->data;
2876
2877 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
2878 || pqnode->bgp != bgp
2879 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
2880 pqnode = bgp_processq_alloc(bgp);
2881 else
2882 pqnode_reuse = 1;
2883 } else
2884 pqnode = bgp_processq_alloc(bgp);
2885 /* all unlocked in bgp_process_wq */
2886 bgp_table_lock(bgp_node_table(rn));
2887
2888 SET_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED);
2889 bgp_lock_node(rn);
2890
2891 /* can't be enqueued twice */
2892 assert(STAILQ_NEXT(rn, pq) == NULL);
2893 STAILQ_INSERT_TAIL(&pqnode->pqueue, rn, pq);
2894 pqnode->queued++;
2895
2896 if (!pqnode_reuse)
2897 work_queue_add(wq, pqnode);
2898
2899 return;
2900 }
2901
2902 void bgp_add_eoiu_mark(struct bgp *bgp)
2903 {
2904 struct bgp_process_queue *pqnode;
2905
2906 if (bm->process_main_queue == NULL)
2907 return;
2908
2909 pqnode = bgp_processq_alloc(bgp);
2910
2911 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
2912 work_queue_add(bm->process_main_queue, pqnode);
2913 }
2914
2915 static int bgp_maximum_prefix_restart_timer(struct thread *thread)
2916 {
2917 struct peer *peer;
2918
2919 peer = THREAD_ARG(thread);
2920 peer->t_pmax_restart = NULL;
2921
2922 if (bgp_debug_neighbor_events(peer))
2923 zlog_debug(
2924 "%s Maximum-prefix restart timer expired, restore peering",
2925 peer->host);
2926
2927 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
2928 zlog_debug("%s: %s peer_clear failed",
2929 __PRETTY_FUNCTION__, peer->host);
2930
2931 return 0;
2932 }
2933
2934 int bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
2935 int always)
2936 {
2937 iana_afi_t pkt_afi;
2938 iana_safi_t pkt_safi;
2939
2940 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
2941 return 0;
2942
2943 if (peer->pcount[afi][safi] > peer->pmax[afi][safi]) {
2944 if (CHECK_FLAG(peer->af_sflags[afi][safi],
2945 PEER_STATUS_PREFIX_LIMIT)
2946 && !always)
2947 return 0;
2948
2949 zlog_info(
2950 "%%MAXPFXEXCEED: No. of %s prefix received from %s %" PRIu32
2951 " exceed, limit %" PRIu32,
2952 get_afi_safi_str(afi, safi, false), peer->host,
2953 peer->pcount[afi][safi], peer->pmax[afi][safi]);
2954 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
2955
2956 if (CHECK_FLAG(peer->af_flags[afi][safi],
2957 PEER_FLAG_MAX_PREFIX_WARNING))
2958 return 0;
2959
2960 /* Convert AFI, SAFI to values for packet. */
2961 pkt_afi = afi_int2iana(afi);
2962 pkt_safi = safi_int2iana(safi);
2963 {
2964 uint8_t ndata[7];
2965
2966 ndata[0] = (pkt_afi >> 8);
2967 ndata[1] = pkt_afi;
2968 ndata[2] = pkt_safi;
2969 ndata[3] = (peer->pmax[afi][safi] >> 24);
2970 ndata[4] = (peer->pmax[afi][safi] >> 16);
2971 ndata[5] = (peer->pmax[afi][safi] >> 8);
2972 ndata[6] = (peer->pmax[afi][safi]);
2973
2974 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
2975 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
2976 BGP_NOTIFY_CEASE_MAX_PREFIX,
2977 ndata, 7);
2978 }
2979
2980 /* Dynamic peers will just close their connection. */
2981 if (peer_dynamic_neighbor(peer))
2982 return 1;
2983
2984 /* restart timer start */
2985 if (peer->pmax_restart[afi][safi]) {
2986 peer->v_pmax_restart =
2987 peer->pmax_restart[afi][safi] * 60;
2988
2989 if (bgp_debug_neighbor_events(peer))
2990 zlog_debug(
2991 "%s Maximum-prefix restart timer started for %d secs",
2992 peer->host, peer->v_pmax_restart);
2993
2994 BGP_TIMER_ON(peer->t_pmax_restart,
2995 bgp_maximum_prefix_restart_timer,
2996 peer->v_pmax_restart);
2997 }
2998
2999 return 1;
3000 } else
3001 UNSET_FLAG(peer->af_sflags[afi][safi],
3002 PEER_STATUS_PREFIX_LIMIT);
3003
3004 if (peer->pcount[afi][safi]
3005 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3006 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3007 PEER_STATUS_PREFIX_THRESHOLD)
3008 && !always)
3009 return 0;
3010
3011 zlog_info(
3012 "%%MAXPFX: No. of %s prefix received from %s reaches %" PRIu32
3013 ", max %" PRIu32,
3014 get_afi_safi_str(afi, safi, false), peer->host,
3015 peer->pcount[afi][safi], peer->pmax[afi][safi]);
3016 SET_FLAG(peer->af_sflags[afi][safi],
3017 PEER_STATUS_PREFIX_THRESHOLD);
3018 } else
3019 UNSET_FLAG(peer->af_sflags[afi][safi],
3020 PEER_STATUS_PREFIX_THRESHOLD);
3021 return 0;
3022 }
3023
3024 /* Unconditionally remove the route from the RIB, without taking
3025 * damping into consideration (eg, because the session went down)
3026 */
3027 void bgp_rib_remove(struct bgp_node *rn, struct bgp_path_info *pi,
3028 struct peer *peer, afi_t afi, safi_t safi)
3029 {
3030
3031 struct bgp *bgp = NULL;
3032 bool delete_route = false;
3033
3034 bgp_aggregate_decrement(peer->bgp, &rn->p, pi, afi, safi);
3035
3036 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3037 bgp_path_info_delete(rn, pi); /* keep historical info */
3038
3039 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3040 * flag
3041 */
3042 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3043 delete_route = true;
3044 else
3045 if (bgp_node_set_defer_flag(rn, true) < 0)
3046 delete_route = true;
3047 if (delete_route) {
3048 if (CHECK_FLAG(rn->flags, BGP_NODE_SELECT_DEFER)) {
3049 UNSET_FLAG(rn->flags, BGP_NODE_SELECT_DEFER);
3050 bgp = pi->peer->bgp;
3051 if ((rn->rt_node) &&
3052 (bgp->gr_info[afi][safi]
3053 .route_list)) {
3054 list_delete_node(
3055 bgp->gr_info[afi][safi]
3056 .route_list,
3057 rn->rt_node);
3058 rn->rt_node = NULL;
3059 }
3060 }
3061 }
3062 }
3063
3064 hook_call(bgp_process, peer->bgp, afi, safi, rn, peer, true);
3065 bgp_process(peer->bgp, rn, afi, safi);
3066 }
3067
3068 static void bgp_rib_withdraw(struct bgp_node *rn, struct bgp_path_info *pi,
3069 struct peer *peer, afi_t afi, safi_t safi,
3070 struct prefix_rd *prd)
3071 {
3072 /* apply dampening, if result is suppressed, we'll be retaining
3073 * the bgp_path_info in the RIB for historical reference.
3074 */
3075 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3076 && peer->sort == BGP_PEER_EBGP)
3077 if ((bgp_damp_withdraw(pi, rn, afi, safi, 0))
3078 == BGP_DAMP_SUPPRESSED) {
3079 bgp_aggregate_decrement(peer->bgp, &rn->p, pi, afi,
3080 safi);
3081 return;
3082 }
3083
3084 #if ENABLE_BGP_VNC
3085 if (safi == SAFI_MPLS_VPN) {
3086 struct bgp_node *prn = NULL;
3087 struct bgp_table *table = NULL;
3088
3089 prn = bgp_node_get(peer->bgp->rib[afi][safi],
3090 (struct prefix *)prd);
3091 if (bgp_node_has_bgp_path_info_data(prn)) {
3092 table = bgp_node_get_bgp_table_info(prn);
3093
3094 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3095 peer->bgp, prd, table, &rn->p, pi);
3096 }
3097 bgp_unlock_node(prn);
3098 }
3099 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3100 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3101
3102 vnc_import_bgp_del_route(peer->bgp, &rn->p, pi);
3103 vnc_import_bgp_exterior_del_route(peer->bgp, &rn->p,
3104 pi);
3105 }
3106 }
3107 #endif
3108
3109 /* If this is an EVPN route, process for un-import. */
3110 if (safi == SAFI_EVPN)
3111 bgp_evpn_unimport_route(peer->bgp, afi, safi, &rn->p, pi);
3112
3113 bgp_rib_remove(rn, pi, peer, afi, safi);
3114 }
3115
3116 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3117 struct peer *peer, struct attr *attr,
3118 struct bgp_node *rn)
3119 {
3120 struct bgp_path_info *new;
3121
3122 /* Make new BGP info. */
3123 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3124 new->type = type;
3125 new->instance = instance;
3126 new->sub_type = sub_type;
3127 new->peer = peer;
3128 new->attr = attr;
3129 new->uptime = bgp_clock();
3130 new->net = rn;
3131 return new;
3132 }
3133
3134 static void overlay_index_update(struct attr *attr,
3135 struct eth_segment_id *eth_s_id,
3136 union gw_addr *gw_ip)
3137 {
3138 if (!attr)
3139 return;
3140
3141 if (eth_s_id == NULL) {
3142 memset(&(attr->evpn_overlay.eth_s_id), 0,
3143 sizeof(struct eth_segment_id));
3144 } else {
3145 memcpy(&(attr->evpn_overlay.eth_s_id), eth_s_id,
3146 sizeof(struct eth_segment_id));
3147 }
3148 if (gw_ip == NULL) {
3149 memset(&(attr->evpn_overlay.gw_ip), 0, sizeof(union gw_addr));
3150 } else {
3151 memcpy(&(attr->evpn_overlay.gw_ip), gw_ip,
3152 sizeof(union gw_addr));
3153 }
3154 }
3155
3156 static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path,
3157 struct eth_segment_id *eth_s_id,
3158 union gw_addr *gw_ip)
3159 {
3160 struct eth_segment_id *path_eth_s_id, *path_eth_s_id_remote;
3161 union gw_addr *path_gw_ip, *path_gw_ip_remote;
3162 union {
3163 struct eth_segment_id esi;
3164 union gw_addr ip;
3165 } temp;
3166
3167 if (afi != AFI_L2VPN)
3168 return true;
3169
3170 path_eth_s_id = &(path->attr->evpn_overlay.eth_s_id);
3171 path_gw_ip = &(path->attr->evpn_overlay.gw_ip);
3172
3173 if (gw_ip == NULL) {
3174 memset(&temp, 0, sizeof(temp));
3175 path_gw_ip_remote = &temp.ip;
3176 } else
3177 path_gw_ip_remote = gw_ip;
3178
3179 if (eth_s_id == NULL) {
3180 memset(&temp, 0, sizeof(temp));
3181 path_eth_s_id_remote = &temp.esi;
3182 } else
3183 path_eth_s_id_remote = eth_s_id;
3184
3185 if (!memcmp(path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr)))
3186 return false;
3187
3188 return !memcmp(path_eth_s_id, path_eth_s_id_remote,
3189 sizeof(struct eth_segment_id));
3190 }
3191
3192 /* Check if received nexthop is valid or not. */
3193 static int bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3194 uint8_t type, uint8_t stype,
3195 struct attr *attr, struct bgp_node *rn)
3196 {
3197 int ret = 0;
3198
3199 /* Only validated for unicast and multicast currently. */
3200 /* Also valid for EVPN where the nexthop is an IP address. */
3201 if (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN)
3202 return 0;
3203
3204 /* If NEXT_HOP is present, validate it. */
3205 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3206 if (attr->nexthop.s_addr == 0
3207 || IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr))
3208 || bgp_nexthop_self(bgp, afi, type, stype,
3209 attr, rn))
3210 return 1;
3211 }
3212
3213 /* If MP_NEXTHOP is present, validate it. */
3214 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3215 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3216 * it is not an IPv6 link-local address.
3217 */
3218 if (attr->mp_nexthop_len) {
3219 switch (attr->mp_nexthop_len) {
3220 case BGP_ATTR_NHLEN_IPV4:
3221 case BGP_ATTR_NHLEN_VPNV4:
3222 ret = (attr->mp_nexthop_global_in.s_addr == 0
3223 || IPV4_CLASS_DE(ntohl(
3224 attr->mp_nexthop_global_in.s_addr))
3225 || bgp_nexthop_self(bgp, afi, type, stype,
3226 attr, rn));
3227 break;
3228
3229 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3230 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3231 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3232 ret = (IN6_IS_ADDR_UNSPECIFIED(&attr->mp_nexthop_global)
3233 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3234 || IN6_IS_ADDR_MULTICAST(
3235 &attr->mp_nexthop_global)
3236 || bgp_nexthop_self(bgp, afi, type, stype,
3237 attr, rn));
3238 break;
3239
3240 default:
3241 ret = 1;
3242 break;
3243 }
3244 }
3245
3246 return ret;
3247 }
3248
3249 int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
3250 struct attr *attr, afi_t afi, safi_t safi, int type,
3251 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3252 uint32_t num_labels, int soft_reconfig,
3253 struct bgp_route_evpn *evpn)
3254 {
3255 int ret;
3256 int aspath_loop_count = 0;
3257 struct bgp_node *rn;
3258 struct bgp *bgp;
3259 struct attr new_attr;
3260 struct attr *attr_new;
3261 struct bgp_path_info *pi;
3262 struct bgp_path_info *new;
3263 struct bgp_path_info_extra *extra;
3264 const char *reason;
3265 char pfx_buf[BGP_PRD_PATH_STRLEN];
3266 int connected = 0;
3267 int do_loop_check = 1;
3268 int has_valid_label = 0;
3269 afi_t nh_afi;
3270 uint8_t pi_type = 0;
3271 uint8_t pi_sub_type = 0;
3272
3273 #if ENABLE_BGP_VNC
3274 int vnc_implicit_withdraw = 0;
3275 #endif
3276 int same_attr = 0;
3277
3278 memset(&new_attr, 0, sizeof(struct attr));
3279 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
3280 new_attr.label = MPLS_INVALID_LABEL;
3281
3282 bgp = peer->bgp;
3283 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3284 /* TODO: Check to see if we can get rid of "is_valid_label" */
3285 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3286 has_valid_label = (num_labels > 0) ? 1 : 0;
3287 else
3288 has_valid_label = bgp_is_valid_label(label);
3289
3290 /* When peer's soft reconfiguration enabled. Record input packet in
3291 Adj-RIBs-In. */
3292 if (!soft_reconfig
3293 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3294 && peer != bgp->peer_self)
3295 bgp_adj_in_set(rn, peer, attr, addpath_id);
3296
3297 /* Check previously received route. */
3298 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
3299 if (pi->peer == peer && pi->type == type
3300 && pi->sub_type == sub_type
3301 && pi->addpath_rx_id == addpath_id)
3302 break;
3303
3304 /* AS path local-as loop check. */
3305 if (peer->change_local_as) {
3306 if (peer->allowas_in[afi][safi])
3307 aspath_loop_count = peer->allowas_in[afi][safi];
3308 else if (!CHECK_FLAG(peer->flags,
3309 PEER_FLAG_LOCAL_AS_NO_PREPEND))
3310 aspath_loop_count = 1;
3311
3312 if (aspath_loop_check(attr->aspath, peer->change_local_as)
3313 > aspath_loop_count) {
3314 peer->stat_pfx_aspath_loop++;
3315 reason = "as-path contains our own AS;";
3316 goto filtered;
3317 }
3318 }
3319
3320 /* If the peer is configured for "allowas-in origin" and the last ASN in
3321 * the
3322 * as-path is our ASN then we do not need to call aspath_loop_check
3323 */
3324 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
3325 if (aspath_get_last_as(attr->aspath) == bgp->as)
3326 do_loop_check = 0;
3327
3328 /* AS path loop check. */
3329 if (do_loop_check) {
3330 if (aspath_loop_check(attr->aspath, bgp->as)
3331 > peer->allowas_in[afi][safi]
3332 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
3333 && aspath_loop_check(attr->aspath, bgp->confed_id)
3334 > peer->allowas_in[afi][safi])) {
3335 peer->stat_pfx_aspath_loop++;
3336 reason = "as-path contains our own AS;";
3337 goto filtered;
3338 }
3339 }
3340
3341 /* Route reflector originator ID check. */
3342 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
3343 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
3344 peer->stat_pfx_originator_loop++;
3345 reason = "originator is us;";
3346 goto filtered;
3347 }
3348
3349 /* Route reflector cluster ID check. */
3350 if (bgp_cluster_filter(peer, attr)) {
3351 peer->stat_pfx_cluster_loop++;
3352 reason = "reflected from the same cluster;";
3353 goto filtered;
3354 }
3355
3356 /* Apply incoming filter. */
3357 if (bgp_input_filter(peer, p, attr, afi, safi) == FILTER_DENY) {
3358 peer->stat_pfx_filter++;
3359 reason = "filter;";
3360 goto filtered;
3361 }
3362
3363 /* RFC 8212 to prevent route leaks.
3364 * This specification intends to improve this situation by requiring the
3365 * explicit configuration of both BGP Import and Export Policies for any
3366 * External BGP (EBGP) session such as customers, peers, or
3367 * confederation boundaries for all enabled address families. Through
3368 * codification of the aforementioned requirement, operators will
3369 * benefit from consistent behavior across different BGP
3370 * implementations.
3371 */
3372 if (peer->bgp->ebgp_requires_policy == DEFAULT_EBGP_POLICY_ENABLED)
3373 if (!bgp_inbound_policy_exists(peer,
3374 &peer->filter[afi][safi])) {
3375 reason = "inbound policy missing";
3376 goto filtered;
3377 }
3378
3379 /* draft-ietf-idr-deprecate-as-set-confed-set
3380 * Filter routes having AS_SET or AS_CONFED_SET in the path.
3381 * Eventually, This document (if approved) updates RFC 4271
3382 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
3383 * and obsoletes RFC 6472.
3384 */
3385 if (peer->bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED)
3386 if (aspath_check_as_sets(attr->aspath)) {
3387 reason =
3388 "as-path contains AS_SET or AS_CONFED_SET type;";
3389 goto filtered;
3390 }
3391
3392 new_attr = *attr;
3393
3394 /* Apply incoming route-map.
3395 * NB: new_attr may now contain newly allocated values from route-map
3396 * "set"
3397 * commands, so we need bgp_attr_flush in the error paths, until we
3398 * intern
3399 * the attr (which takes over the memory references) */
3400 if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL,
3401 label, num_labels, rn) == RMAP_DENY) {
3402 peer->stat_pfx_filter++;
3403 reason = "route-map;";
3404 bgp_attr_flush(&new_attr);
3405 goto filtered;
3406 }
3407
3408 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
3409 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3410 /* remove from RIB previous entry */
3411 bgp_zebra_withdraw(p, pi, bgp, safi);
3412 }
3413
3414 if (peer->sort == BGP_PEER_EBGP) {
3415
3416 /* If we receive the graceful-shutdown community from an eBGP
3417 * peer we must lower local-preference */
3418 if (new_attr.community
3419 && community_include(new_attr.community, COMMUNITY_GSHUT)) {
3420 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
3421 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
3422
3423 /* If graceful-shutdown is configured then add the GSHUT
3424 * community to all paths received from eBGP peers */
3425 } else if (bgp_flag_check(peer->bgp,
3426 BGP_FLAG_GRACEFUL_SHUTDOWN)) {
3427 bgp_attr_add_gshut_community(&new_attr);
3428 }
3429 }
3430
3431 if (pi) {
3432 pi_type = pi->type;
3433 pi_sub_type = pi->sub_type;
3434 }
3435
3436 /* next hop check. */
3437 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
3438 && bgp_update_martian_nexthop(bgp, afi, safi, pi_type,
3439 pi_sub_type, &new_attr, rn)) {
3440 peer->stat_pfx_nh_invalid++;
3441 reason = "martian or self next-hop;";
3442 bgp_attr_flush(&new_attr);
3443 goto filtered;
3444 }
3445
3446 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
3447 peer->stat_pfx_nh_invalid++;
3448 reason = "self mac;";
3449 goto filtered;
3450 }
3451
3452 attr_new = bgp_attr_intern(&new_attr);
3453
3454 /* If the update is implicit withdraw. */
3455 if (pi) {
3456 pi->uptime = bgp_clock();
3457 same_attr = attrhash_cmp(pi->attr, attr_new);
3458
3459 hook_call(bgp_process, bgp, afi, safi, rn, peer, true);
3460
3461 /* Same attribute comes in. */
3462 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
3463 && attrhash_cmp(pi->attr, attr_new)
3464 && (!has_valid_label
3465 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
3466 num_labels * sizeof(mpls_label_t))
3467 == 0)
3468 && (overlay_index_equal(
3469 afi, pi, evpn == NULL ? NULL : &evpn->eth_s_id,
3470 evpn == NULL ? NULL : &evpn->gw_ip))) {
3471 if (CHECK_FLAG(bgp->af_flags[afi][safi],
3472 BGP_CONFIG_DAMPENING)
3473 && peer->sort == BGP_PEER_EBGP
3474 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3475 if (bgp_debug_update(peer, p, NULL, 1)) {
3476 bgp_debug_rdpfxpath2str(
3477 afi, safi, prd, p, label,
3478 num_labels, addpath_id ? 1 : 0,
3479 addpath_id, pfx_buf,
3480 sizeof(pfx_buf));
3481 zlog_debug("%s rcvd %s", peer->host,
3482 pfx_buf);
3483 }
3484
3485 if (bgp_damp_update(pi, rn, afi, safi)
3486 != BGP_DAMP_SUPPRESSED) {
3487 bgp_aggregate_increment(bgp, p, pi, afi,
3488 safi);
3489 bgp_process(bgp, rn, afi, safi);
3490 }
3491 } else /* Duplicate - odd */
3492 {
3493 if (bgp_debug_update(peer, p, NULL, 1)) {
3494 if (!peer->rcvd_attr_printed) {
3495 zlog_debug(
3496 "%s rcvd UPDATE w/ attr: %s",
3497 peer->host,
3498 peer->rcvd_attr_str);
3499 peer->rcvd_attr_printed = 1;
3500 }
3501
3502 bgp_debug_rdpfxpath2str(
3503 afi, safi, prd, p, label,
3504 num_labels, addpath_id ? 1 : 0,
3505 addpath_id, pfx_buf,
3506 sizeof(pfx_buf));
3507 zlog_debug(
3508 "%s rcvd %s...duplicate ignored",
3509 peer->host, pfx_buf);
3510 }
3511
3512 /* graceful restart STALE flag unset. */
3513 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3514 bgp_path_info_unset_flag(
3515 rn, pi, BGP_PATH_STALE);
3516 bgp_node_set_defer_flag(rn, false);
3517 bgp_process(bgp, rn, afi, safi);
3518 }
3519 }
3520
3521 bgp_unlock_node(rn);
3522 bgp_attr_unintern(&attr_new);
3523
3524 return 0;
3525 }
3526
3527 /* Withdraw/Announce before we fully processed the withdraw */
3528 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
3529 if (bgp_debug_update(peer, p, NULL, 1)) {
3530 bgp_debug_rdpfxpath2str(
3531 afi, safi, prd, p, label, num_labels,
3532 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3533 sizeof(pfx_buf));
3534 zlog_debug(
3535 "%s rcvd %s, flapped quicker than processing",
3536 peer->host, pfx_buf);
3537 }
3538
3539 bgp_path_info_restore(rn, pi);
3540 }
3541
3542 /* Received Logging. */
3543 if (bgp_debug_update(peer, p, NULL, 1)) {
3544 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
3545 num_labels, addpath_id ? 1 : 0,
3546 addpath_id, pfx_buf,
3547 sizeof(pfx_buf));
3548 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3549 }
3550
3551 /* graceful restart STALE flag unset. */
3552 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3553 bgp_path_info_unset_flag(rn, pi, BGP_PATH_STALE);
3554 bgp_node_set_defer_flag(rn, false);
3555 }
3556
3557 /* The attribute is changed. */
3558 bgp_path_info_set_flag(rn, pi, BGP_PATH_ATTR_CHANGED);
3559
3560 /* implicit withdraw, decrement aggregate and pcount here.
3561 * only if update is accepted, they'll increment below.
3562 */
3563 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
3564
3565 /* Update bgp route dampening information. */
3566 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3567 && peer->sort == BGP_PEER_EBGP) {
3568 /* This is implicit withdraw so we should update
3569 dampening
3570 information. */
3571 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
3572 bgp_damp_withdraw(pi, rn, afi, safi, 1);
3573 }
3574 #if ENABLE_BGP_VNC
3575 if (safi == SAFI_MPLS_VPN) {
3576 struct bgp_node *prn = NULL;
3577 struct bgp_table *table = NULL;
3578
3579 prn = bgp_node_get(bgp->rib[afi][safi],
3580 (struct prefix *)prd);
3581 if (bgp_node_has_bgp_path_info_data(prn)) {
3582 table = bgp_node_get_bgp_table_info(prn);
3583
3584 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3585 bgp, prd, table, p, pi);
3586 }
3587 bgp_unlock_node(prn);
3588 }
3589 if ((afi == AFI_IP || afi == AFI_IP6)
3590 && (safi == SAFI_UNICAST)) {
3591 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3592 /*
3593 * Implicit withdraw case.
3594 */
3595 ++vnc_implicit_withdraw;
3596 vnc_import_bgp_del_route(bgp, p, pi);
3597 vnc_import_bgp_exterior_del_route(bgp, p, pi);
3598 }
3599 }
3600 #endif
3601
3602 /* Special handling for EVPN update of an existing route. If the
3603 * extended community attribute has changed, we need to
3604 * un-import
3605 * the route using its existing extended community. It will be
3606 * subsequently processed for import with the new extended
3607 * community.
3608 */
3609 if (safi == SAFI_EVPN && !same_attr) {
3610 if ((pi->attr->flag
3611 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
3612 && (attr_new->flag
3613 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
3614 int cmp;
3615
3616 cmp = ecommunity_cmp(pi->attr->ecommunity,
3617 attr_new->ecommunity);
3618 if (!cmp) {
3619 if (bgp_debug_update(peer, p, NULL, 1))
3620 zlog_debug(
3621 "Change in EXT-COMM, existing %s new %s",
3622 ecommunity_str(
3623 pi->attr->ecommunity),
3624 ecommunity_str(
3625 attr_new->ecommunity));
3626 bgp_evpn_unimport_route(bgp, afi, safi,
3627 p, pi);
3628 }
3629 }
3630 }
3631
3632 /* Update to new attribute. */
3633 bgp_attr_unintern(&pi->attr);
3634 pi->attr = attr_new;
3635
3636 /* Update MPLS label */
3637 if (has_valid_label) {
3638 extra = bgp_path_info_extra_get(pi);
3639 if (extra->label != label) {
3640 memcpy(&extra->label, label,
3641 num_labels * sizeof(mpls_label_t));
3642 extra->num_labels = num_labels;
3643 }
3644 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
3645 bgp_set_valid_label(&extra->label[0]);
3646 }
3647
3648 #if ENABLE_BGP_VNC
3649 if ((afi == AFI_IP || afi == AFI_IP6)
3650 && (safi == SAFI_UNICAST)) {
3651 if (vnc_implicit_withdraw) {
3652 /*
3653 * Add back the route with its new attributes
3654 * (e.g., nexthop).
3655 * The route is still selected, until the route
3656 * selection
3657 * queued by bgp_process actually runs. We have
3658 * to make this
3659 * update to the VNC side immediately to avoid
3660 * racing against
3661 * configuration changes (e.g., route-map
3662 * changes) which
3663 * trigger re-importation of the entire RIB.
3664 */
3665 vnc_import_bgp_add_route(bgp, p, pi);
3666 vnc_import_bgp_exterior_add_route(bgp, p, pi);
3667 }
3668 }
3669 #endif
3670 /* Update Overlay Index */
3671 if (afi == AFI_L2VPN) {
3672 overlay_index_update(
3673 pi->attr, evpn == NULL ? NULL : &evpn->eth_s_id,
3674 evpn == NULL ? NULL : &evpn->gw_ip);
3675 }
3676
3677 /* Update bgp route dampening information. */
3678 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3679 && peer->sort == BGP_PEER_EBGP) {
3680 /* Now we do normal update dampening. */
3681 ret = bgp_damp_update(pi, rn, afi, safi);
3682 if (ret == BGP_DAMP_SUPPRESSED) {
3683 bgp_unlock_node(rn);
3684 return 0;
3685 }
3686 }
3687
3688 /* Nexthop reachability check - for unicast and
3689 * labeled-unicast.. */
3690 if (((afi == AFI_IP || afi == AFI_IP6)
3691 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
3692 || (safi == SAFI_EVPN &&
3693 bgp_evpn_is_prefix_nht_supported(p))) {
3694 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
3695 && peer->ttl == BGP_DEFAULT_TTL
3696 && !CHECK_FLAG(peer->flags,
3697 PEER_FLAG_DISABLE_CONNECTED_CHECK)
3698 && !bgp_flag_check(
3699 bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
3700 connected = 1;
3701 else
3702 connected = 0;
3703
3704 struct bgp *bgp_nexthop = bgp;
3705
3706 if (pi->extra && pi->extra->bgp_orig)
3707 bgp_nexthop = pi->extra->bgp_orig;
3708
3709 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
3710
3711 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
3712 pi, NULL, connected)
3713 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
3714 bgp_path_info_set_flag(rn, pi, BGP_PATH_VALID);
3715 else {
3716 if (BGP_DEBUG(nht, NHT)) {
3717 char buf1[INET6_ADDRSTRLEN];
3718 inet_ntop(AF_INET,
3719 (const void *)&attr_new
3720 ->nexthop,
3721 buf1, INET6_ADDRSTRLEN);
3722 zlog_debug("%s(%s): NH unresolved",
3723 __FUNCTION__, buf1);
3724 }
3725 bgp_path_info_unset_flag(rn, pi,
3726 BGP_PATH_VALID);
3727 }
3728 } else
3729 bgp_path_info_set_flag(rn, pi, BGP_PATH_VALID);
3730
3731 #if ENABLE_BGP_VNC
3732 if (safi == SAFI_MPLS_VPN) {
3733 struct bgp_node *prn = NULL;
3734 struct bgp_table *table = NULL;
3735
3736 prn = bgp_node_get(bgp->rib[afi][safi],
3737 (struct prefix *)prd);
3738 if (bgp_node_has_bgp_path_info_data(prn)) {
3739 table = bgp_node_get_bgp_table_info(prn);
3740
3741 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3742 bgp, prd, table, p, pi);
3743 }
3744 bgp_unlock_node(prn);
3745 }
3746 #endif
3747
3748 /* If this is an EVPN route and some attribute has changed,
3749 * process
3750 * route for import. If the extended community has changed, we
3751 * would
3752 * have done the un-import earlier and the import would result
3753 * in the
3754 * route getting injected into appropriate L2 VNIs. If it is
3755 * just
3756 * some other attribute change, the import will result in
3757 * updating
3758 * the attributes for the route in the VNI(s).
3759 */
3760 if (safi == SAFI_EVPN && !same_attr &&
3761 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
3762 bgp_evpn_import_route(bgp, afi, safi, p, pi);
3763
3764 /* Process change. */
3765 bgp_aggregate_increment(bgp, p, pi, afi, safi);
3766
3767 bgp_process(bgp, rn, afi, safi);
3768 bgp_unlock_node(rn);
3769
3770 if (SAFI_UNICAST == safi
3771 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
3772 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3773
3774 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
3775 }
3776 if ((SAFI_MPLS_VPN == safi)
3777 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3778
3779 vpn_leak_to_vrf_update(bgp, pi);
3780 }
3781
3782 #if ENABLE_BGP_VNC
3783 if (SAFI_MPLS_VPN == safi) {
3784 mpls_label_t label_decoded = decode_label(label);
3785
3786 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
3787 type, sub_type, &label_decoded);
3788 }
3789 if (SAFI_ENCAP == safi) {
3790 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
3791 type, sub_type, NULL);
3792 }
3793 #endif
3794
3795 return 0;
3796 } // End of implicit withdraw
3797
3798 /* Received Logging. */
3799 if (bgp_debug_update(peer, p, NULL, 1)) {
3800 if (!peer->rcvd_attr_printed) {
3801 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
3802 peer->rcvd_attr_str);
3803 peer->rcvd_attr_printed = 1;
3804 }
3805
3806 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
3807 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3808 sizeof(pfx_buf));
3809 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3810 }
3811
3812 /* Make new BGP info. */
3813 new = info_make(type, sub_type, 0, peer, attr_new, rn);
3814
3815 /* Update MPLS label */
3816 if (has_valid_label) {
3817 extra = bgp_path_info_extra_get(new);
3818 if (extra->label != label) {
3819 memcpy(&extra->label, label,
3820 num_labels * sizeof(mpls_label_t));
3821 extra->num_labels = num_labels;
3822 }
3823 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
3824 bgp_set_valid_label(&extra->label[0]);
3825 }
3826
3827 /* Update Overlay Index */
3828 if (afi == AFI_L2VPN) {
3829 overlay_index_update(new->attr,
3830 evpn == NULL ? NULL : &evpn->eth_s_id,
3831 evpn == NULL ? NULL : &evpn->gw_ip);
3832 }
3833 /* Nexthop reachability check. */
3834 if (((afi == AFI_IP || afi == AFI_IP6)
3835 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
3836 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
3837 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
3838 && peer->ttl == BGP_DEFAULT_TTL
3839 && !CHECK_FLAG(peer->flags,
3840 PEER_FLAG_DISABLE_CONNECTED_CHECK)
3841 && !bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
3842 connected = 1;
3843 else
3844 connected = 0;
3845
3846 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
3847
3848 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, new, NULL,
3849 connected)
3850 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
3851 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
3852 else {
3853 if (BGP_DEBUG(nht, NHT)) {
3854 char buf1[INET6_ADDRSTRLEN];
3855 inet_ntop(AF_INET,
3856 (const void *)&attr_new->nexthop,
3857 buf1, INET6_ADDRSTRLEN);
3858 zlog_debug("%s(%s): NH unresolved",
3859 __FUNCTION__, buf1);
3860 }
3861 bgp_path_info_unset_flag(rn, new, BGP_PATH_VALID);
3862 }
3863 } else
3864 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
3865
3866 /* Addpath ID */
3867 new->addpath_rx_id = addpath_id;
3868
3869 /* Increment prefix */
3870 bgp_aggregate_increment(bgp, p, new, afi, safi);
3871
3872 /* Register new BGP information. */
3873 bgp_path_info_add(rn, new);
3874
3875 /* route_node_get lock */
3876 bgp_unlock_node(rn);
3877
3878 #if ENABLE_BGP_VNC
3879 if (safi == SAFI_MPLS_VPN) {
3880 struct bgp_node *prn = NULL;
3881 struct bgp_table *table = NULL;
3882
3883 prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
3884 if (bgp_node_has_bgp_path_info_data(prn)) {
3885 table = bgp_node_get_bgp_table_info(prn);
3886
3887 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3888 bgp, prd, table, p, new);
3889 }
3890 bgp_unlock_node(prn);
3891 }
3892 #endif
3893
3894 /* If maximum prefix count is configured and current prefix
3895 count exeed it. */
3896 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0))
3897 return -1;
3898
3899 /* If this is an EVPN route, process for import. */
3900 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
3901 bgp_evpn_import_route(bgp, afi, safi, p, new);
3902
3903 hook_call(bgp_process, bgp, afi, safi, rn, peer, false);
3904
3905 /* Process change. */
3906 bgp_process(bgp, rn, afi, safi);
3907
3908 if (SAFI_UNICAST == safi
3909 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
3910 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3911 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
3912 }
3913 if ((SAFI_MPLS_VPN == safi)
3914 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3915
3916 vpn_leak_to_vrf_update(bgp, new);
3917 }
3918 #if ENABLE_BGP_VNC
3919 if (SAFI_MPLS_VPN == safi) {
3920 mpls_label_t label_decoded = decode_label(label);
3921
3922 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
3923 sub_type, &label_decoded);
3924 }
3925 if (SAFI_ENCAP == safi) {
3926 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
3927 sub_type, NULL);
3928 }
3929 #endif
3930
3931 return 0;
3932
3933 /* This BGP update is filtered. Log the reason then update BGP
3934 entry. */
3935 filtered:
3936 hook_call(bgp_process, bgp, afi, safi, rn, peer, true);
3937
3938 if (bgp_debug_update(peer, p, NULL, 1)) {
3939 if (!peer->rcvd_attr_printed) {
3940 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
3941 peer->rcvd_attr_str);
3942 peer->rcvd_attr_printed = 1;
3943 }
3944
3945 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
3946 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3947 sizeof(pfx_buf));
3948 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
3949 peer->host, pfx_buf, reason);
3950 }
3951
3952 if (pi) {
3953 /* If this is an EVPN route, un-import it as it is now filtered.
3954 */
3955 if (safi == SAFI_EVPN)
3956 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
3957
3958 if (SAFI_UNICAST == safi
3959 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
3960 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3961
3962 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
3963 }
3964 if ((SAFI_MPLS_VPN == safi)
3965 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3966
3967 vpn_leak_to_vrf_withdraw(bgp, pi);
3968 }
3969
3970 bgp_rib_remove(rn, pi, peer, afi, safi);
3971 }
3972
3973 bgp_unlock_node(rn);
3974
3975 #if ENABLE_BGP_VNC
3976 /*
3977 * Filtered update is treated as an implicit withdrawal (see
3978 * bgp_rib_remove()
3979 * a few lines above)
3980 */
3981 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
3982 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
3983 0);
3984 }
3985 #endif
3986
3987 return 0;
3988 }
3989
3990 int bgp_withdraw(struct peer *peer, struct prefix *p, uint32_t addpath_id,
3991 struct attr *attr, afi_t afi, safi_t safi, int type,
3992 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3993 uint32_t num_labels, struct bgp_route_evpn *evpn)
3994 {
3995 struct bgp *bgp;
3996 char pfx_buf[BGP_PRD_PATH_STRLEN];
3997 struct bgp_node *rn;
3998 struct bgp_path_info *pi;
3999
4000 #if ENABLE_BGP_VNC
4001 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4002 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4003 0);
4004 }
4005 #endif
4006
4007 bgp = peer->bgp;
4008
4009 /* Lookup node. */
4010 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4011
4012 /* If peer is soft reconfiguration enabled. Record input packet for
4013 * further calculation.
4014 *
4015 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4016 * routes that are filtered. This tanks out Quagga RS pretty badly due
4017 * to
4018 * the iteration over all RS clients.
4019 * Since we need to remove the entry from adj_in anyway, do that first
4020 * and
4021 * if there was no entry, we don't need to do anything more.
4022 */
4023 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4024 && peer != bgp->peer_self)
4025 if (!bgp_adj_in_unset(rn, peer, addpath_id)) {
4026 peer->stat_pfx_dup_withdraw++;
4027
4028 if (bgp_debug_update(peer, p, NULL, 1)) {
4029 bgp_debug_rdpfxpath2str(
4030 afi, safi, prd, p, label, num_labels,
4031 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4032 sizeof(pfx_buf));
4033 zlog_debug(
4034 "%s withdrawing route %s not in adj-in",
4035 peer->host, pfx_buf);
4036 }
4037 bgp_unlock_node(rn);
4038 return 0;
4039 }
4040
4041 /* Lookup withdrawn route. */
4042 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4043 if (pi->peer == peer && pi->type == type
4044 && pi->sub_type == sub_type
4045 && pi->addpath_rx_id == addpath_id)
4046 break;
4047
4048 /* Logging. */
4049 if (bgp_debug_update(peer, p, NULL, 1)) {
4050 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4051 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4052 sizeof(pfx_buf));
4053 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
4054 pfx_buf);
4055 }
4056
4057 /* Withdraw specified route from routing table. */
4058 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4059 bgp_rib_withdraw(rn, pi, peer, afi, safi, prd);
4060 if (SAFI_UNICAST == safi
4061 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4062 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4063 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4064 }
4065 if ((SAFI_MPLS_VPN == safi)
4066 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4067
4068 vpn_leak_to_vrf_withdraw(bgp, pi);
4069 }
4070 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4071 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4072 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4073 sizeof(pfx_buf));
4074 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4075 }
4076
4077 /* Unlock bgp_node_get() lock. */
4078 bgp_unlock_node(rn);
4079
4080 return 0;
4081 }
4082
4083 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4084 int withdraw)
4085 {
4086 struct update_subgroup *subgrp;
4087 subgrp = peer_subgroup(peer, afi, safi);
4088 subgroup_default_originate(subgrp, withdraw);
4089 }
4090
4091
4092 /*
4093 * bgp_stop_announce_route_timer
4094 */
4095 void bgp_stop_announce_route_timer(struct peer_af *paf)
4096 {
4097 if (!paf->t_announce_route)
4098 return;
4099
4100 THREAD_TIMER_OFF(paf->t_announce_route);
4101 }
4102
4103 /*
4104 * bgp_announce_route_timer_expired
4105 *
4106 * Callback that is invoked when the route announcement timer for a
4107 * peer_af expires.
4108 */
4109 static int bgp_announce_route_timer_expired(struct thread *t)
4110 {
4111 struct peer_af *paf;
4112 struct peer *peer;
4113
4114 paf = THREAD_ARG(t);
4115 peer = paf->peer;
4116
4117 if (peer->status != Established)
4118 return 0;
4119
4120 if (!peer->afc_nego[paf->afi][paf->safi])
4121 return 0;
4122
4123 peer_af_announce_route(paf, 1);
4124 return 0;
4125 }
4126
4127 /*
4128 * bgp_announce_route
4129 *
4130 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
4131 */
4132 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi)
4133 {
4134 struct peer_af *paf;
4135 struct update_subgroup *subgrp;
4136
4137 paf = peer_af_find(peer, afi, safi);
4138 if (!paf)
4139 return;
4140 subgrp = PAF_SUBGRP(paf);
4141
4142 /*
4143 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
4144 * or a refresh has already been triggered.
4145 */
4146 if (!subgrp || paf->t_announce_route)
4147 return;
4148
4149 /*
4150 * Start a timer to stagger/delay the announce. This serves
4151 * two purposes - announcement can potentially be combined for
4152 * multiple peers and the announcement doesn't happen in the
4153 * vty context.
4154 */
4155 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
4156 (subgrp->peer_count == 1)
4157 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
4158 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
4159 &paf->t_announce_route);
4160 }
4161
4162 /*
4163 * Announce routes from all AF tables to a peer.
4164 *
4165 * This should ONLY be called when there is a need to refresh the
4166 * routes to the peer based on a policy change for this peer alone
4167 * or a route refresh request received from the peer.
4168 * The operation will result in splitting the peer from its existing
4169 * subgroups and putting it in new subgroups.
4170 */
4171 void bgp_announce_route_all(struct peer *peer)
4172 {
4173 afi_t afi;
4174 safi_t safi;
4175
4176 FOREACH_AFI_SAFI (afi, safi)
4177 bgp_announce_route(peer, afi, safi);
4178 }
4179
4180 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
4181 struct bgp_table *table,
4182 struct prefix_rd *prd)
4183 {
4184 int ret;
4185 struct bgp_node *rn;
4186 struct bgp_adj_in *ain;
4187
4188 if (!table)
4189 table = peer->bgp->rib[afi][safi];
4190
4191 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
4192 for (ain = rn->adj_in; ain; ain = ain->next) {
4193 if (ain->peer != peer)
4194 continue;
4195
4196 struct bgp_path_info *pi;
4197 uint32_t num_labels = 0;
4198 mpls_label_t *label_pnt = NULL;
4199 struct bgp_route_evpn evpn;
4200
4201 for (pi = bgp_node_get_bgp_path_info(rn); pi;
4202 pi = pi->next)
4203 if (pi->peer == peer)
4204 break;
4205
4206 if (pi && pi->extra)
4207 num_labels = pi->extra->num_labels;
4208 if (num_labels)
4209 label_pnt = &pi->extra->label[0];
4210 if (pi)
4211 memcpy(&evpn, &pi->attr->evpn_overlay,
4212 sizeof(evpn));
4213 else
4214 memset(&evpn, 0, sizeof(evpn));
4215
4216 ret = bgp_update(peer, &rn->p, ain->addpath_rx_id,
4217 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
4218 BGP_ROUTE_NORMAL, prd, label_pnt,
4219 num_labels, 1, &evpn);
4220
4221 if (ret < 0) {
4222 bgp_unlock_node(rn);
4223 return;
4224 }
4225 }
4226 }
4227
4228 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
4229 {
4230 struct bgp_node *rn;
4231 struct bgp_table *table;
4232
4233 if (peer->status != Established)
4234 return;
4235
4236 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
4237 && (safi != SAFI_EVPN))
4238 bgp_soft_reconfig_table(peer, afi, safi, NULL, NULL);
4239 else
4240 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
4241 rn = bgp_route_next(rn)) {
4242 table = bgp_node_get_bgp_table_info(rn);
4243 if (table != NULL) {
4244 struct prefix_rd prd;
4245
4246 prd.family = AF_UNSPEC;
4247 prd.prefixlen = 64;
4248 memcpy(&prd.val, rn->p.u.val, 8);
4249
4250 bgp_soft_reconfig_table(peer, afi, safi, table,
4251 &prd);
4252 }
4253 }
4254 }
4255
4256
4257 struct bgp_clear_node_queue {
4258 struct bgp_node *rn;
4259 };
4260
4261 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
4262 {
4263 struct bgp_clear_node_queue *cnq = data;
4264 struct bgp_node *rn = cnq->rn;
4265 struct peer *peer = wq->spec.data;
4266 struct bgp_path_info *pi;
4267 struct bgp *bgp;
4268 afi_t afi = bgp_node_table(rn)->afi;
4269 safi_t safi = bgp_node_table(rn)->safi;
4270
4271 assert(rn && peer);
4272 bgp = peer->bgp;
4273
4274 /* It is possible that we have multiple paths for a prefix from a peer
4275 * if that peer is using AddPath.
4276 */
4277 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
4278 if (pi->peer != peer)
4279 continue;
4280
4281 /* graceful restart STALE flag set. */
4282 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
4283 && peer->nsf[afi][safi]
4284 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
4285 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
4286 bgp_path_info_set_flag(rn, pi, BGP_PATH_STALE);
4287 else {
4288 /* If this is an EVPN route, process for
4289 * un-import. */
4290 if (safi == SAFI_EVPN)
4291 bgp_evpn_unimport_route(bgp, afi, safi, &rn->p,
4292 pi);
4293 /* Handle withdraw for VRF route-leaking and L3VPN */
4294 if (SAFI_UNICAST == safi
4295 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
4296 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4297 vpn_leak_from_vrf_withdraw(bgp_get_default(),
4298 bgp, pi);
4299 }
4300 if (SAFI_MPLS_VPN == safi &&
4301 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4302 vpn_leak_to_vrf_withdraw(bgp, pi);
4303 }
4304
4305 bgp_rib_remove(rn, pi, peer, afi, safi);
4306 }
4307 }
4308 return WQ_SUCCESS;
4309 }
4310
4311 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
4312 {
4313 struct bgp_clear_node_queue *cnq = data;
4314 struct bgp_node *rn = cnq->rn;
4315 struct bgp_table *table = bgp_node_table(rn);
4316
4317 bgp_unlock_node(rn);
4318 bgp_table_unlock(table);
4319 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
4320 }
4321
4322 static void bgp_clear_node_complete(struct work_queue *wq)
4323 {
4324 struct peer *peer = wq->spec.data;
4325
4326 /* Tickle FSM to start moving again */
4327 BGP_EVENT_ADD(peer, Clearing_Completed);
4328
4329 peer_unlock(peer); /* bgp_clear_route */
4330 }
4331
4332 static void bgp_clear_node_queue_init(struct peer *peer)
4333 {
4334 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
4335
4336 snprintf(wname, sizeof(wname), "clear %s", peer->host);
4337 #undef CLEAR_QUEUE_NAME_LEN
4338
4339 peer->clear_node_queue = work_queue_new(bm->master, wname);
4340 peer->clear_node_queue->spec.hold = 10;
4341 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
4342 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
4343 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
4344 peer->clear_node_queue->spec.max_retries = 0;
4345
4346 /* we only 'lock' this peer reference when the queue is actually active
4347 */
4348 peer->clear_node_queue->spec.data = peer;
4349 }
4350
4351 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
4352 struct bgp_table *table)
4353 {
4354 struct bgp_node *rn;
4355 int force = bm->process_main_queue ? 0 : 1;
4356
4357 if (!table)
4358 table = peer->bgp->rib[afi][safi];
4359
4360 /* If still no table => afi/safi isn't configured at all or smth. */
4361 if (!table)
4362 return;
4363
4364 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
4365 struct bgp_path_info *pi, *next;
4366 struct bgp_adj_in *ain;
4367 struct bgp_adj_in *ain_next;
4368
4369 /* XXX:TODO: This is suboptimal, every non-empty route_node is
4370 * queued for every clearing peer, regardless of whether it is
4371 * relevant to the peer at hand.
4372 *
4373 * Overview: There are 3 different indices which need to be
4374 * scrubbed, potentially, when a peer is removed:
4375 *
4376 * 1 peer's routes visible via the RIB (ie accepted routes)
4377 * 2 peer's routes visible by the (optional) peer's adj-in index
4378 * 3 other routes visible by the peer's adj-out index
4379 *
4380 * 3 there is no hurry in scrubbing, once the struct peer is
4381 * removed from bgp->peer, we could just GC such deleted peer's
4382 * adj-outs at our leisure.
4383 *
4384 * 1 and 2 must be 'scrubbed' in some way, at least made
4385 * invisible via RIB index before peer session is allowed to be
4386 * brought back up. So one needs to know when such a 'search' is
4387 * complete.
4388 *
4389 * Ideally:
4390 *
4391 * - there'd be a single global queue or a single RIB walker
4392 * - rather than tracking which route_nodes still need to be
4393 * examined on a peer basis, we'd track which peers still
4394 * aren't cleared
4395 *
4396 * Given that our per-peer prefix-counts now should be reliable,
4397 * this may actually be achievable. It doesn't seem to be a huge
4398 * problem at this time,
4399 *
4400 * It is possible that we have multiple paths for a prefix from
4401 * a peer
4402 * if that peer is using AddPath.
4403 */
4404 ain = rn->adj_in;
4405 while (ain) {
4406 ain_next = ain->next;
4407
4408 if (ain->peer == peer) {
4409 bgp_adj_in_remove(rn, ain);
4410 bgp_unlock_node(rn);
4411 }
4412
4413 ain = ain_next;
4414 }
4415
4416 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = next) {
4417 next = pi->next;
4418 if (pi->peer != peer)
4419 continue;
4420
4421 if (force)
4422 bgp_path_info_reap(rn, pi);
4423 else {
4424 struct bgp_clear_node_queue *cnq;
4425
4426 /* both unlocked in bgp_clear_node_queue_del */
4427 bgp_table_lock(bgp_node_table(rn));
4428 bgp_lock_node(rn);
4429 cnq = XCALLOC(
4430 MTYPE_BGP_CLEAR_NODE_QUEUE,
4431 sizeof(struct bgp_clear_node_queue));
4432 cnq->rn = rn;
4433 work_queue_add(peer->clear_node_queue, cnq);
4434 break;
4435 }
4436 }
4437 }
4438 return;
4439 }
4440
4441 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
4442 {
4443 struct bgp_node *rn;
4444 struct bgp_table *table;
4445
4446 if (peer->clear_node_queue == NULL)
4447 bgp_clear_node_queue_init(peer);
4448
4449 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
4450 * Idle until it receives a Clearing_Completed event. This protects
4451 * against peers which flap faster than we can we clear, which could
4452 * lead to:
4453 *
4454 * a) race with routes from the new session being installed before
4455 * clear_route_node visits the node (to delete the route of that
4456 * peer)
4457 * b) resource exhaustion, clear_route_node likely leads to an entry
4458 * on the process_main queue. Fast-flapping could cause that queue
4459 * to grow and grow.
4460 */
4461
4462 /* lock peer in assumption that clear-node-queue will get nodes; if so,
4463 * the unlock will happen upon work-queue completion; other wise, the
4464 * unlock happens at the end of this function.
4465 */
4466 if (!peer->clear_node_queue->thread)
4467 peer_lock(peer);
4468
4469 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
4470 bgp_clear_route_table(peer, afi, safi, NULL);
4471 else
4472 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
4473 rn = bgp_route_next(rn)) {
4474 table = bgp_node_get_bgp_table_info(rn);
4475 if (!table)
4476 continue;
4477
4478 bgp_clear_route_table(peer, afi, safi, table);
4479 }
4480
4481 /* unlock if no nodes got added to the clear-node-queue. */
4482 if (!peer->clear_node_queue->thread)
4483 peer_unlock(peer);
4484 }
4485
4486 void bgp_clear_route_all(struct peer *peer)
4487 {
4488 afi_t afi;
4489 safi_t safi;
4490
4491 FOREACH_AFI_SAFI (afi, safi)
4492 bgp_clear_route(peer, afi, safi);
4493
4494 #if ENABLE_BGP_VNC
4495 rfapiProcessPeerDown(peer);
4496 #endif
4497 }
4498
4499 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
4500 {
4501 struct bgp_table *table;
4502 struct bgp_node *rn;
4503 struct bgp_adj_in *ain;
4504 struct bgp_adj_in *ain_next;
4505
4506 table = peer->bgp->rib[afi][safi];
4507
4508 /* It is possible that we have multiple paths for a prefix from a peer
4509 * if that peer is using AddPath.
4510 */
4511 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
4512 ain = rn->adj_in;
4513
4514 while (ain) {
4515 ain_next = ain->next;
4516
4517 if (ain->peer == peer) {
4518 bgp_adj_in_remove(rn, ain);
4519 bgp_unlock_node(rn);
4520 }
4521
4522 ain = ain_next;
4523 }
4524 }
4525 }
4526
4527 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
4528 {
4529 struct bgp_node *rn;
4530 struct bgp_path_info *pi;
4531 struct bgp_table *table;
4532
4533 if (safi == SAFI_MPLS_VPN) {
4534 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
4535 rn = bgp_route_next(rn)) {
4536 struct bgp_node *rm;
4537
4538 /* look for neighbor in tables */
4539 table = bgp_node_get_bgp_table_info(rn);
4540 if (!table)
4541 continue;
4542
4543 for (rm = bgp_table_top(table); rm;
4544 rm = bgp_route_next(rm))
4545 for (pi = bgp_node_get_bgp_path_info(rm); pi;
4546 pi = pi->next) {
4547 if (pi->peer != peer)
4548 continue;
4549 if (!CHECK_FLAG(pi->flags,
4550 BGP_PATH_STALE))
4551 break;
4552
4553 bgp_rib_remove(rm, pi, peer, afi, safi);
4554 break;
4555 }
4556 }
4557 } else {
4558 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
4559 rn = bgp_route_next(rn))
4560 for (pi = bgp_node_get_bgp_path_info(rn); pi;
4561 pi = pi->next) {
4562 if (pi->peer != peer)
4563 continue;
4564 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
4565 break;
4566 bgp_rib_remove(rn, pi, peer, afi, safi);
4567 break;
4568 }
4569 }
4570 }
4571
4572 int bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
4573 {
4574 if (peer->sort == BGP_PEER_IBGP)
4575 return 1;
4576
4577 if (peer->sort == BGP_PEER_EBGP
4578 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
4579 || FILTER_LIST_OUT_NAME(filter)
4580 || DISTRIBUTE_OUT_NAME(filter)))
4581 return 1;
4582 return 0;
4583 }
4584
4585 int bgp_inbound_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_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
4592 || FILTER_LIST_IN_NAME(filter)
4593 || DISTRIBUTE_IN_NAME(filter)))
4594 return 1;
4595 return 0;
4596 }
4597
4598 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
4599 safi_t safi)
4600 {
4601 struct bgp_node *rn;
4602 struct bgp_path_info *pi;
4603 struct bgp_path_info *next;
4604
4605 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
4606 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = next) {
4607 next = pi->next;
4608
4609 /* Unimport EVPN routes from VRFs */
4610 if (safi == SAFI_EVPN)
4611 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
4612 SAFI_EVPN,
4613 &rn->p, pi);
4614
4615 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
4616 && pi->type == ZEBRA_ROUTE_BGP
4617 && (pi->sub_type == BGP_ROUTE_NORMAL
4618 || pi->sub_type == BGP_ROUTE_AGGREGATE
4619 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
4620
4621 if (bgp_fibupd_safi(safi))
4622 bgp_zebra_withdraw(&rn->p, pi, bgp,
4623 safi);
4624 bgp_path_info_reap(rn, pi);
4625 }
4626 }
4627 }
4628
4629 /* Delete all kernel routes. */
4630 void bgp_cleanup_routes(struct bgp *bgp)
4631 {
4632 afi_t afi;
4633 struct bgp_node *rn;
4634 struct bgp_table *table;
4635
4636 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
4637 if (afi == AFI_L2VPN)
4638 continue;
4639 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
4640 SAFI_UNICAST);
4641 /*
4642 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
4643 */
4644 if (afi != AFI_L2VPN) {
4645 safi_t safi;
4646 safi = SAFI_MPLS_VPN;
4647 for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
4648 rn = bgp_route_next(rn)) {
4649 table = bgp_node_get_bgp_table_info(rn);
4650 if (table != NULL) {
4651 bgp_cleanup_table(bgp, table, safi);
4652 bgp_table_finish(&table);
4653 bgp_node_set_bgp_table_info(rn, NULL);
4654 bgp_unlock_node(rn);
4655 }
4656 }
4657 safi = SAFI_ENCAP;
4658 for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
4659 rn = bgp_route_next(rn)) {
4660 table = bgp_node_get_bgp_table_info(rn);
4661 if (table != NULL) {
4662 bgp_cleanup_table(bgp, table, safi);
4663 bgp_table_finish(&table);
4664 bgp_node_set_bgp_table_info(rn, NULL);
4665 bgp_unlock_node(rn);
4666 }
4667 }
4668 }
4669 }
4670 for (rn = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); rn;
4671 rn = bgp_route_next(rn)) {
4672 table = bgp_node_get_bgp_table_info(rn);
4673 if (table != NULL) {
4674 bgp_cleanup_table(bgp, table, SAFI_EVPN);
4675 bgp_table_finish(&table);
4676 bgp_node_set_bgp_table_info(rn, NULL);
4677 bgp_unlock_node(rn);
4678 }
4679 }
4680 }
4681
4682 void bgp_reset(void)
4683 {
4684 vty_reset();
4685 bgp_zclient_reset();
4686 access_list_reset();
4687 prefix_list_reset();
4688 }
4689
4690 static int bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
4691 {
4692 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
4693 && CHECK_FLAG(peer->af_cap[afi][safi],
4694 PEER_CAP_ADDPATH_AF_TX_RCV));
4695 }
4696
4697 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
4698 value. */
4699 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
4700 struct bgp_nlri *packet)
4701 {
4702 uint8_t *pnt;
4703 uint8_t *lim;
4704 struct prefix p;
4705 int psize;
4706 int ret;
4707 afi_t afi;
4708 safi_t safi;
4709 int addpath_encoded;
4710 uint32_t addpath_id;
4711
4712 pnt = packet->nlri;
4713 lim = pnt + packet->length;
4714 afi = packet->afi;
4715 safi = packet->safi;
4716 addpath_id = 0;
4717 addpath_encoded = bgp_addpath_encode_rx(peer, afi, safi);
4718
4719 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
4720 syntactic validity. If the field is syntactically incorrect,
4721 then the Error Subcode is set to Invalid Network Field. */
4722 for (; pnt < lim; pnt += psize) {
4723 /* Clear prefix structure. */
4724 memset(&p, 0, sizeof(struct prefix));
4725
4726 if (addpath_encoded) {
4727
4728 /* When packet overflow occurs return immediately. */
4729 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
4730 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
4731
4732 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
4733 addpath_id = ntohl(addpath_id);
4734 pnt += BGP_ADDPATH_ID_LEN;
4735 }
4736
4737 /* Fetch prefix length. */
4738 p.prefixlen = *pnt++;
4739 /* afi/safi validity already verified by caller,
4740 * bgp_update_receive */
4741 p.family = afi2family(afi);
4742
4743 /* Prefix length check. */
4744 if (p.prefixlen > prefix_blen(&p) * 8) {
4745 flog_err(
4746 EC_BGP_UPDATE_RCV,
4747 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
4748 peer->host, p.prefixlen, packet->afi);
4749 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
4750 }
4751
4752 /* Packet size overflow check. */
4753 psize = PSIZE(p.prefixlen);
4754
4755 /* When packet overflow occur return immediately. */
4756 if (pnt + psize > lim) {
4757 flog_err(
4758 EC_BGP_UPDATE_RCV,
4759 "%s [Error] Update packet error (prefix length %d overflows packet)",
4760 peer->host, p.prefixlen);
4761 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
4762 }
4763
4764 /* Defensive coding, double-check the psize fits in a struct
4765 * prefix */
4766 if (psize > (ssize_t)sizeof(p.u)) {
4767 flog_err(
4768 EC_BGP_UPDATE_RCV,
4769 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
4770 peer->host, p.prefixlen, sizeof(p.u));
4771 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
4772 }
4773
4774 /* Fetch prefix from NLRI packet. */
4775 memcpy(p.u.val, pnt, psize);
4776
4777 /* Check address. */
4778 if (afi == AFI_IP && safi == SAFI_UNICAST) {
4779 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
4780 /* From RFC4271 Section 6.3:
4781 *
4782 * If a prefix in the NLRI field is semantically
4783 * incorrect
4784 * (e.g., an unexpected multicast IP address),
4785 * an error SHOULD
4786 * be logged locally, and the prefix SHOULD be
4787 * ignored.
4788 */
4789 flog_err(
4790 EC_BGP_UPDATE_RCV,
4791 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
4792 peer->host, inet_ntoa(p.u.prefix4));
4793 continue;
4794 }
4795 }
4796
4797 /* Check address. */
4798 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
4799 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
4800 char buf[BUFSIZ];
4801
4802 flog_err(
4803 EC_BGP_UPDATE_RCV,
4804 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
4805 peer->host,
4806 inet_ntop(AF_INET6, &p.u.prefix6, buf,
4807 BUFSIZ));
4808
4809 continue;
4810 }
4811 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
4812 char buf[BUFSIZ];
4813
4814 flog_err(
4815 EC_BGP_UPDATE_RCV,
4816 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
4817 peer->host,
4818 inet_ntop(AF_INET6, &p.u.prefix6, buf,
4819 BUFSIZ));
4820
4821 continue;
4822 }
4823 }
4824
4825 /* Normal process. */
4826 if (attr)
4827 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
4828 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
4829 NULL, NULL, 0, 0, NULL);
4830 else
4831 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
4832 safi, ZEBRA_ROUTE_BGP,
4833 BGP_ROUTE_NORMAL, NULL, NULL, 0,
4834 NULL);
4835
4836 /* Do not send BGP notification twice when maximum-prefix count
4837 * overflow. */
4838 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
4839 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
4840
4841 /* Address family configuration mismatch. */
4842 if (ret < 0)
4843 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
4844 }
4845
4846 /* Packet length consistency check. */
4847 if (pnt != lim) {
4848 flog_err(
4849 EC_BGP_UPDATE_RCV,
4850 "%s [Error] Update packet error (prefix length mismatch with total length)",
4851 peer->host);
4852 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
4853 }
4854
4855 return BGP_NLRI_PARSE_OK;
4856 }
4857
4858 static struct bgp_static *bgp_static_new(void)
4859 {
4860 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
4861 }
4862
4863 static void bgp_static_free(struct bgp_static *bgp_static)
4864 {
4865 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
4866 route_map_counter_decrement(bgp_static->rmap.map);
4867
4868 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
4869 XFREE(MTYPE_BGP_STATIC, bgp_static);
4870 }
4871
4872 void bgp_static_update(struct bgp *bgp, struct prefix *p,
4873 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
4874 {
4875 struct bgp_node *rn;
4876 struct bgp_path_info *pi;
4877 struct bgp_path_info *new;
4878 struct bgp_path_info rmap_path;
4879 struct attr attr;
4880 struct attr *attr_new;
4881 route_map_result_t ret;
4882 #if ENABLE_BGP_VNC
4883 int vnc_implicit_withdraw = 0;
4884 #endif
4885
4886 assert(bgp_static);
4887 if (!bgp_static)
4888 return;
4889
4890 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
4891
4892 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
4893
4894 attr.nexthop = bgp_static->igpnexthop;
4895 attr.med = bgp_static->igpmetric;
4896 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
4897
4898 if (bgp_static->atomic)
4899 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
4900
4901 /* Store label index, if required. */
4902 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
4903 attr.label_index = bgp_static->label_index;
4904 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
4905 }
4906
4907 /* Apply route-map. */
4908 if (bgp_static->rmap.name) {
4909 struct attr attr_tmp = attr;
4910
4911 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
4912 rmap_path.peer = bgp->peer_self;
4913 rmap_path.attr = &attr_tmp;
4914
4915 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
4916
4917 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
4918 &rmap_path);
4919
4920 bgp->peer_self->rmap_type = 0;
4921
4922 if (ret == RMAP_DENYMATCH) {
4923 /* Free uninterned attribute. */
4924 bgp_attr_flush(&attr_tmp);
4925
4926 /* Unintern original. */
4927 aspath_unintern(&attr.aspath);
4928 bgp_static_withdraw(bgp, p, afi, safi);
4929 return;
4930 }
4931
4932 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
4933 bgp_attr_add_gshut_community(&attr_tmp);
4934
4935 attr_new = bgp_attr_intern(&attr_tmp);
4936 } else {
4937
4938 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
4939 bgp_attr_add_gshut_community(&attr);
4940
4941 attr_new = bgp_attr_intern(&attr);
4942 }
4943
4944 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4945 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4946 && pi->sub_type == BGP_ROUTE_STATIC)
4947 break;
4948
4949 if (pi) {
4950 if (attrhash_cmp(pi->attr, attr_new)
4951 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4952 && !bgp_flag_check(bgp, BGP_FLAG_FORCE_STATIC_PROCESS)) {
4953 bgp_unlock_node(rn);
4954 bgp_attr_unintern(&attr_new);
4955 aspath_unintern(&attr.aspath);
4956 return;
4957 } else {
4958 /* The attribute is changed. */
4959 bgp_path_info_set_flag(rn, pi, BGP_PATH_ATTR_CHANGED);
4960
4961 /* Rewrite BGP route information. */
4962 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
4963 bgp_path_info_restore(rn, pi);
4964 else
4965 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4966 #if ENABLE_BGP_VNC
4967 if ((afi == AFI_IP || afi == AFI_IP6)
4968 && (safi == SAFI_UNICAST)) {
4969 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4970 /*
4971 * Implicit withdraw case.
4972 * We have to do this before pi is
4973 * changed
4974 */
4975 ++vnc_implicit_withdraw;
4976 vnc_import_bgp_del_route(bgp, p, pi);
4977 vnc_import_bgp_exterior_del_route(
4978 bgp, p, pi);
4979 }
4980 }
4981 #endif
4982 bgp_attr_unintern(&pi->attr);
4983 pi->attr = attr_new;
4984 pi->uptime = bgp_clock();
4985 #if ENABLE_BGP_VNC
4986 if ((afi == AFI_IP || afi == AFI_IP6)
4987 && (safi == SAFI_UNICAST)) {
4988 if (vnc_implicit_withdraw) {
4989 vnc_import_bgp_add_route(bgp, p, pi);
4990 vnc_import_bgp_exterior_add_route(
4991 bgp, p, pi);
4992 }
4993 }
4994 #endif
4995
4996 /* Nexthop reachability check. */
4997 if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
4998 && (safi == SAFI_UNICAST
4999 || safi == SAFI_LABELED_UNICAST)) {
5000
5001 struct bgp *bgp_nexthop = bgp;
5002
5003 if (pi->extra && pi->extra->bgp_orig)
5004 bgp_nexthop = pi->extra->bgp_orig;
5005
5006 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
5007 afi, pi, NULL, 0))
5008 bgp_path_info_set_flag(rn, pi,
5009 BGP_PATH_VALID);
5010 else {
5011 if (BGP_DEBUG(nht, NHT)) {
5012 char buf1[INET6_ADDRSTRLEN];
5013 inet_ntop(p->family,
5014 &p->u.prefix, buf1,
5015 INET6_ADDRSTRLEN);
5016 zlog_debug(
5017 "%s(%s): Route not in table, not advertising",
5018 __FUNCTION__, buf1);
5019 }
5020 bgp_path_info_unset_flag(
5021 rn, pi, BGP_PATH_VALID);
5022 }
5023 } else {
5024 /* Delete the NHT structure if any, if we're
5025 * toggling between
5026 * enabling/disabling import check. We
5027 * deregister the route
5028 * from NHT to avoid overloading NHT and the
5029 * process interaction
5030 */
5031 bgp_unlink_nexthop(pi);
5032 bgp_path_info_set_flag(rn, pi, BGP_PATH_VALID);
5033 }
5034 /* Process change. */
5035 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5036 bgp_process(bgp, rn, afi, safi);
5037
5038 if (SAFI_UNICAST == safi
5039 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5040 || bgp->inst_type
5041 == BGP_INSTANCE_TYPE_DEFAULT)) {
5042 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
5043 pi);
5044 }
5045
5046 bgp_unlock_node(rn);
5047 aspath_unintern(&attr.aspath);
5048 return;
5049 }
5050 }
5051
5052 /* Make new BGP info. */
5053 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5054 attr_new, rn);
5055 /* Nexthop reachability check. */
5056 if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)
5057 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
5058 if (bgp_find_or_add_nexthop(bgp, bgp, afi, new, NULL, 0))
5059 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
5060 else {
5061 if (BGP_DEBUG(nht, NHT)) {
5062 char buf1[INET6_ADDRSTRLEN];
5063 inet_ntop(p->family, &p->u.prefix, buf1,
5064 INET6_ADDRSTRLEN);
5065 zlog_debug(
5066 "%s(%s): Route not in table, not advertising",
5067 __FUNCTION__, buf1);
5068 }
5069 bgp_path_info_unset_flag(rn, new, BGP_PATH_VALID);
5070 }
5071 } else {
5072 /* Delete the NHT structure if any, if we're toggling between
5073 * enabling/disabling import check. We deregister the route
5074 * from NHT to avoid overloading NHT and the process interaction
5075 */
5076 bgp_unlink_nexthop(new);
5077
5078 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
5079 }
5080
5081 /* Aggregate address increment. */
5082 bgp_aggregate_increment(bgp, p, new, afi, safi);
5083
5084 /* Register new BGP information. */
5085 bgp_path_info_add(rn, new);
5086
5087 /* route_node_get lock */
5088 bgp_unlock_node(rn);
5089
5090 /* Process change. */
5091 bgp_process(bgp, rn, afi, safi);
5092
5093 if (SAFI_UNICAST == safi
5094 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5095 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5096 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
5097 }
5098
5099 /* Unintern original. */
5100 aspath_unintern(&attr.aspath);
5101 }
5102
5103 void bgp_static_withdraw(struct bgp *bgp, struct prefix *p, afi_t afi,
5104 safi_t safi)
5105 {
5106 struct bgp_node *rn;
5107 struct bgp_path_info *pi;
5108
5109 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5110
5111 /* Check selected route and self inserted route. */
5112 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
5113 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5114 && pi->sub_type == BGP_ROUTE_STATIC)
5115 break;
5116
5117 /* Withdraw static BGP route from routing table. */
5118 if (pi) {
5119 if (SAFI_UNICAST == safi
5120 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5121 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5122 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5123 }
5124 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5125 bgp_unlink_nexthop(pi);
5126 bgp_path_info_delete(rn, pi);
5127 bgp_process(bgp, rn, afi, safi);
5128 }
5129
5130 /* Unlock bgp_node_lookup. */
5131 bgp_unlock_node(rn);
5132 }
5133
5134 /*
5135 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
5136 */
5137 static void bgp_static_withdraw_safi(struct bgp *bgp, struct prefix *p,
5138 afi_t afi, safi_t safi,
5139 struct prefix_rd *prd)
5140 {
5141 struct bgp_node *rn;
5142 struct bgp_path_info *pi;
5143
5144 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
5145
5146 /* Check selected route and self inserted route. */
5147 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
5148 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5149 && pi->sub_type == BGP_ROUTE_STATIC)
5150 break;
5151
5152 /* Withdraw static BGP route from routing table. */
5153 if (pi) {
5154 #if ENABLE_BGP_VNC
5155 rfapiProcessWithdraw(
5156 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
5157 1); /* Kill, since it is an administrative change */
5158 #endif
5159 if (SAFI_MPLS_VPN == safi
5160 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5161 vpn_leak_to_vrf_withdraw(bgp, pi);
5162 }
5163 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5164 bgp_path_info_delete(rn, pi);
5165 bgp_process(bgp, rn, afi, safi);
5166 }
5167
5168 /* Unlock bgp_node_lookup. */
5169 bgp_unlock_node(rn);
5170 }
5171
5172 static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p,
5173 struct bgp_static *bgp_static, afi_t afi,
5174 safi_t safi)
5175 {
5176 struct bgp_node *rn;
5177 struct bgp_path_info *new;
5178 struct attr *attr_new;
5179 struct attr attr = {0};
5180 struct bgp_path_info *pi;
5181 #if ENABLE_BGP_VNC
5182 mpls_label_t label = 0;
5183 #endif
5184 uint32_t num_labels = 0;
5185 union gw_addr add;
5186
5187 assert(bgp_static);
5188
5189 if (bgp_static->label != MPLS_INVALID_LABEL)
5190 num_labels = 1;
5191 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
5192 &bgp_static->prd);
5193
5194 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5195
5196 attr.nexthop = bgp_static->igpnexthop;
5197 attr.med = bgp_static->igpmetric;
5198 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5199
5200 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
5201 || (safi == SAFI_ENCAP)) {
5202 if (afi == AFI_IP) {
5203 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
5204 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
5205 }
5206 }
5207 if (afi == AFI_L2VPN) {
5208 if (bgp_static->gatewayIp.family == AF_INET)
5209 add.ipv4.s_addr =
5210 bgp_static->gatewayIp.u.prefix4.s_addr;
5211 else if (bgp_static->gatewayIp.family == AF_INET6)
5212 memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
5213 sizeof(struct in6_addr));
5214 overlay_index_update(&attr, bgp_static->eth_s_id, &add);
5215 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
5216 struct bgp_encap_type_vxlan bet;
5217 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
5218 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
5219 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
5220 }
5221 if (bgp_static->router_mac) {
5222 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
5223 }
5224 }
5225 /* Apply route-map. */
5226 if (bgp_static->rmap.name) {
5227 struct attr attr_tmp = attr;
5228 struct bgp_path_info rmap_path;
5229 route_map_result_t ret;
5230
5231 rmap_path.peer = bgp->peer_self;
5232 rmap_path.attr = &attr_tmp;
5233
5234 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5235
5236 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
5237 &rmap_path);
5238
5239 bgp->peer_self->rmap_type = 0;
5240
5241 if (ret == RMAP_DENYMATCH) {
5242 /* Free uninterned attribute. */
5243 bgp_attr_flush(&attr_tmp);
5244
5245 /* Unintern original. */
5246 aspath_unintern(&attr.aspath);
5247 bgp_static_withdraw_safi(bgp, p, afi, safi,
5248 &bgp_static->prd);
5249 return;
5250 }
5251
5252 attr_new = bgp_attr_intern(&attr_tmp);
5253 } else {
5254 attr_new = bgp_attr_intern(&attr);
5255 }
5256
5257 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
5258 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5259 && pi->sub_type == BGP_ROUTE_STATIC)
5260 break;
5261
5262 if (pi) {
5263 memset(&add, 0, sizeof(union gw_addr));
5264 if (attrhash_cmp(pi->attr, attr_new)
5265 && overlay_index_equal(afi, pi, bgp_static->eth_s_id, &add)
5266 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
5267 bgp_unlock_node(rn);
5268 bgp_attr_unintern(&attr_new);
5269 aspath_unintern(&attr.aspath);
5270 return;
5271 } else {
5272 /* The attribute is changed. */
5273 bgp_path_info_set_flag(rn, pi, BGP_PATH_ATTR_CHANGED);
5274
5275 /* Rewrite BGP route information. */
5276 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5277 bgp_path_info_restore(rn, pi);
5278 else
5279 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5280 bgp_attr_unintern(&pi->attr);
5281 pi->attr = attr_new;
5282 pi->uptime = bgp_clock();
5283 #if ENABLE_BGP_VNC
5284 if (pi->extra)
5285 label = decode_label(&pi->extra->label[0]);
5286 #endif
5287
5288 /* Process change. */
5289 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5290 bgp_process(bgp, rn, afi, safi);
5291
5292 if (SAFI_MPLS_VPN == safi
5293 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5294 vpn_leak_to_vrf_update(bgp, pi);
5295 }
5296 #if ENABLE_BGP_VNC
5297 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
5298 pi->attr, afi, safi, pi->type,
5299 pi->sub_type, &label);
5300 #endif
5301 bgp_unlock_node(rn);
5302 aspath_unintern(&attr.aspath);
5303 return;
5304 }
5305 }
5306
5307
5308 /* Make new BGP info. */
5309 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5310 attr_new, rn);
5311 SET_FLAG(new->flags, BGP_PATH_VALID);
5312 new->extra = bgp_path_info_extra_new();
5313 if (num_labels) {
5314 new->extra->label[0] = bgp_static->label;
5315 new->extra->num_labels = num_labels;
5316 }
5317 #if ENABLE_BGP_VNC
5318 label = decode_label(&bgp_static->label);
5319 #endif
5320
5321 /* Aggregate address increment. */
5322 bgp_aggregate_increment(bgp, p, new, afi, safi);
5323
5324 /* Register new BGP information. */
5325 bgp_path_info_add(rn, new);
5326 /* route_node_get lock */
5327 bgp_unlock_node(rn);
5328
5329 /* Process change. */
5330 bgp_process(bgp, rn, afi, safi);
5331
5332 if (SAFI_MPLS_VPN == safi
5333 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5334 vpn_leak_to_vrf_update(bgp, new);
5335 }
5336 #if ENABLE_BGP_VNC
5337 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
5338 safi, new->type, new->sub_type, &label);
5339 #endif
5340
5341 /* Unintern original. */
5342 aspath_unintern(&attr.aspath);
5343 }
5344
5345 /* Configure static BGP network. When user don't run zebra, static
5346 route should be installed as valid. */
5347 static int bgp_static_set(struct vty *vty, const char *negate,
5348 const char *ip_str, afi_t afi, safi_t safi,
5349 const char *rmap, int backdoor, uint32_t label_index)
5350 {
5351 VTY_DECLVAR_CONTEXT(bgp, bgp);
5352 int ret;
5353 struct prefix p;
5354 struct bgp_static *bgp_static;
5355 struct bgp_node *rn;
5356 uint8_t need_update = 0;
5357
5358 /* Convert IP prefix string to struct prefix. */
5359 ret = str2prefix(ip_str, &p);
5360 if (!ret) {
5361 vty_out(vty, "%% Malformed prefix\n");
5362 return CMD_WARNING_CONFIG_FAILED;
5363 }
5364 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
5365 vty_out(vty, "%% Malformed prefix (link-local address)\n");
5366 return CMD_WARNING_CONFIG_FAILED;
5367 }
5368
5369 apply_mask(&p);
5370
5371 if (negate) {
5372
5373 /* Set BGP static route configuration. */
5374 rn = bgp_node_lookup(bgp->route[afi][safi], &p);
5375
5376 if (!rn) {
5377 vty_out(vty, "%% Can't find static route specified\n");
5378 return CMD_WARNING_CONFIG_FAILED;
5379 }
5380
5381 bgp_static = bgp_node_get_bgp_static_info(rn);
5382
5383 if ((label_index != BGP_INVALID_LABEL_INDEX)
5384 && (label_index != bgp_static->label_index)) {
5385 vty_out(vty,
5386 "%% label-index doesn't match static route\n");
5387 return CMD_WARNING_CONFIG_FAILED;
5388 }
5389
5390 if ((rmap && bgp_static->rmap.name)
5391 && strcmp(rmap, bgp_static->rmap.name)) {
5392 vty_out(vty,
5393 "%% route-map name doesn't match static route\n");
5394 return CMD_WARNING_CONFIG_FAILED;
5395 }
5396
5397 /* Update BGP RIB. */
5398 if (!bgp_static->backdoor)
5399 bgp_static_withdraw(bgp, &p, afi, safi);
5400
5401 /* Clear configuration. */
5402 bgp_static_free(bgp_static);
5403 bgp_node_set_bgp_static_info(rn, NULL);
5404 bgp_unlock_node(rn);
5405 bgp_unlock_node(rn);
5406 } else {
5407
5408 /* Set BGP static route configuration. */
5409 rn = bgp_node_get(bgp->route[afi][safi], &p);
5410
5411 bgp_static = bgp_node_get_bgp_static_info(rn);
5412 if (bgp_static) {
5413 /* Configuration change. */
5414 /* Label index cannot be changed. */
5415 if (bgp_static->label_index != label_index) {
5416 vty_out(vty, "%% cannot change label-index\n");
5417 return CMD_WARNING_CONFIG_FAILED;
5418 }
5419
5420 /* Check previous routes are installed into BGP. */
5421 if (bgp_static->valid
5422 && bgp_static->backdoor != backdoor)
5423 need_update = 1;
5424
5425 bgp_static->backdoor = backdoor;
5426
5427 if (rmap) {
5428 XFREE(MTYPE_ROUTE_MAP_NAME,
5429 bgp_static->rmap.name);
5430 route_map_counter_decrement(
5431 bgp_static->rmap.map);
5432 bgp_static->rmap.name =
5433 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5434 bgp_static->rmap.map =
5435 route_map_lookup_by_name(rmap);
5436 route_map_counter_increment(
5437 bgp_static->rmap.map);
5438 } else {
5439 XFREE(MTYPE_ROUTE_MAP_NAME,
5440 bgp_static->rmap.name);
5441 route_map_counter_decrement(
5442 bgp_static->rmap.map);
5443 bgp_static->rmap.name = NULL;
5444 bgp_static->rmap.map = NULL;
5445 bgp_static->valid = 0;
5446 }
5447 bgp_unlock_node(rn);
5448 } else {
5449 /* New configuration. */
5450 bgp_static = bgp_static_new();
5451 bgp_static->backdoor = backdoor;
5452 bgp_static->valid = 0;
5453 bgp_static->igpmetric = 0;
5454 bgp_static->igpnexthop.s_addr = 0;
5455 bgp_static->label_index = label_index;
5456
5457 if (rmap) {
5458 XFREE(MTYPE_ROUTE_MAP_NAME,
5459 bgp_static->rmap.name);
5460 route_map_counter_decrement(
5461 bgp_static->rmap.map);
5462 bgp_static->rmap.name =
5463 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5464 bgp_static->rmap.map =
5465 route_map_lookup_by_name(rmap);
5466 route_map_counter_increment(
5467 bgp_static->rmap.map);
5468 }
5469 bgp_node_set_bgp_static_info(rn, bgp_static);
5470 }
5471
5472 bgp_static->valid = 1;
5473 if (need_update)
5474 bgp_static_withdraw(bgp, &p, afi, safi);
5475
5476 if (!bgp_static->backdoor)
5477 bgp_static_update(bgp, &p, bgp_static, afi, safi);
5478 }
5479
5480 return CMD_SUCCESS;
5481 }
5482
5483 void bgp_static_add(struct bgp *bgp)
5484 {
5485 afi_t afi;
5486 safi_t safi;
5487 struct bgp_node *rn;
5488 struct bgp_node *rm;
5489 struct bgp_table *table;
5490 struct bgp_static *bgp_static;
5491
5492 FOREACH_AFI_SAFI (afi, safi)
5493 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5494 rn = bgp_route_next(rn)) {
5495 if (!bgp_node_has_bgp_path_info_data(rn))
5496 continue;
5497
5498 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5499 || (safi == SAFI_EVPN)) {
5500 table = bgp_node_get_bgp_table_info(rn);
5501
5502 for (rm = bgp_table_top(table); rm;
5503 rm = bgp_route_next(rm)) {
5504 bgp_static =
5505 bgp_node_get_bgp_static_info(
5506 rm);
5507 bgp_static_update_safi(bgp, &rm->p,
5508 bgp_static, afi,
5509 safi);
5510 }
5511 } else {
5512 bgp_static_update(
5513 bgp, &rn->p,
5514 bgp_node_get_bgp_static_info(rn), afi,
5515 safi);
5516 }
5517 }
5518 }
5519
5520 /* Called from bgp_delete(). Delete all static routes from the BGP
5521 instance. */
5522 void bgp_static_delete(struct bgp *bgp)
5523 {
5524 afi_t afi;
5525 safi_t safi;
5526 struct bgp_node *rn;
5527 struct bgp_node *rm;
5528 struct bgp_table *table;
5529 struct bgp_static *bgp_static;
5530
5531 FOREACH_AFI_SAFI (afi, safi)
5532 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5533 rn = bgp_route_next(rn)) {
5534 if (!bgp_node_has_bgp_path_info_data(rn))
5535 continue;
5536
5537 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5538 || (safi == SAFI_EVPN)) {
5539 table = bgp_node_get_bgp_table_info(rn);
5540
5541 for (rm = bgp_table_top(table); rm;
5542 rm = bgp_route_next(rm)) {
5543 bgp_static =
5544 bgp_node_get_bgp_static_info(
5545 rm);
5546 if (!bgp_static)
5547 continue;
5548
5549 bgp_static_withdraw_safi(
5550 bgp, &rm->p, AFI_IP, safi,
5551 (struct prefix_rd *)&rn->p);
5552 bgp_static_free(bgp_static);
5553 bgp_node_set_bgp_static_info(rn, NULL);
5554 bgp_unlock_node(rn);
5555 }
5556 } else {
5557 bgp_static = bgp_node_get_bgp_static_info(rn);
5558 bgp_static_withdraw(bgp, &rn->p, afi, safi);
5559 bgp_static_free(bgp_static);
5560 bgp_node_set_bgp_static_info(rn, NULL);
5561 bgp_unlock_node(rn);
5562 }
5563 }
5564 }
5565
5566 void bgp_static_redo_import_check(struct bgp *bgp)
5567 {
5568 afi_t afi;
5569 safi_t safi;
5570 struct bgp_node *rn;
5571 struct bgp_node *rm;
5572 struct bgp_table *table;
5573 struct bgp_static *bgp_static;
5574
5575 /* Use this flag to force reprocessing of the route */
5576 bgp_flag_set(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
5577 FOREACH_AFI_SAFI (afi, safi) {
5578 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5579 rn = bgp_route_next(rn)) {
5580 if (!bgp_node_has_bgp_path_info_data(rn))
5581 continue;
5582
5583 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5584 || (safi == SAFI_EVPN)) {
5585 table = bgp_node_get_bgp_table_info(rn);
5586
5587 for (rm = bgp_table_top(table); rm;
5588 rm = bgp_route_next(rm)) {
5589 bgp_static =
5590 bgp_node_get_bgp_static_info(
5591 rm);
5592 bgp_static_update_safi(bgp, &rm->p,
5593 bgp_static, afi,
5594 safi);
5595 }
5596 } else {
5597 bgp_static = bgp_node_get_bgp_static_info(rn);
5598 bgp_static_update(bgp, &rn->p, bgp_static, afi,
5599 safi);
5600 }
5601 }
5602 }
5603 bgp_flag_unset(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
5604 }
5605
5606 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
5607 safi_t safi)
5608 {
5609 struct bgp_table *table;
5610 struct bgp_node *rn;
5611 struct bgp_path_info *pi;
5612
5613 /* Do not install the aggregate route if BGP is in the
5614 * process of termination.
5615 */
5616 if (bgp_flag_check(bgp, BGP_FLAG_DELETE_IN_PROGRESS) ||
5617 (bgp->peer_self == NULL))
5618 return;
5619
5620 table = bgp->rib[afi][safi];
5621 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
5622 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
5623 if (pi->peer == bgp->peer_self
5624 && ((pi->type == ZEBRA_ROUTE_BGP
5625 && pi->sub_type == BGP_ROUTE_STATIC)
5626 || (pi->type != ZEBRA_ROUTE_BGP
5627 && pi->sub_type
5628 == BGP_ROUTE_REDISTRIBUTE))) {
5629 bgp_aggregate_decrement(bgp, &rn->p, pi, afi,
5630 safi);
5631 bgp_unlink_nexthop(pi);
5632 bgp_path_info_delete(rn, pi);
5633 bgp_process(bgp, rn, afi, safi);
5634 }
5635 }
5636 }
5637 }
5638
5639 /*
5640 * Purge all networks and redistributed routes from routing table.
5641 * Invoked upon the instance going down.
5642 */
5643 void bgp_purge_static_redist_routes(struct bgp *bgp)
5644 {
5645 afi_t afi;
5646 safi_t safi;
5647
5648 FOREACH_AFI_SAFI (afi, safi)
5649 bgp_purge_af_static_redist_routes(bgp, afi, safi);
5650 }
5651
5652 /*
5653 * gpz 110624
5654 * Currently this is used to set static routes for VPN and ENCAP.
5655 * I think it can probably be factored with bgp_static_set.
5656 */
5657 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
5658 const char *ip_str, const char *rd_str,
5659 const char *label_str, const char *rmap_str,
5660 int evpn_type, const char *esi, const char *gwip,
5661 const char *ethtag, const char *routermac)
5662 {
5663 VTY_DECLVAR_CONTEXT(bgp, bgp);
5664 int ret;
5665 struct prefix p;
5666 struct prefix_rd prd;
5667 struct bgp_node *prn;
5668 struct bgp_node *rn;
5669 struct bgp_table *table;
5670 struct bgp_static *bgp_static;
5671 mpls_label_t label = MPLS_INVALID_LABEL;
5672 struct prefix gw_ip;
5673
5674 /* validate ip prefix */
5675 ret = str2prefix(ip_str, &p);
5676 if (!ret) {
5677 vty_out(vty, "%% Malformed prefix\n");
5678 return CMD_WARNING_CONFIG_FAILED;
5679 }
5680 apply_mask(&p);
5681 if ((afi == AFI_L2VPN)
5682 && (bgp_build_evpn_prefix(evpn_type,
5683 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5684 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5685 return CMD_WARNING_CONFIG_FAILED;
5686 }
5687
5688 ret = str2prefix_rd(rd_str, &prd);
5689 if (!ret) {
5690 vty_out(vty, "%% Malformed rd\n");
5691 return CMD_WARNING_CONFIG_FAILED;
5692 }
5693
5694 if (label_str) {
5695 unsigned long label_val;
5696 label_val = strtoul(label_str, NULL, 10);
5697 encode_label(label_val, &label);
5698 }
5699
5700 if (safi == SAFI_EVPN) {
5701 if (esi && str2esi(esi, NULL) == 0) {
5702 vty_out(vty, "%% Malformed ESI\n");
5703 return CMD_WARNING_CONFIG_FAILED;
5704 }
5705 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
5706 vty_out(vty, "%% Malformed Router MAC\n");
5707 return CMD_WARNING_CONFIG_FAILED;
5708 }
5709 if (gwip) {
5710 memset(&gw_ip, 0, sizeof(struct prefix));
5711 ret = str2prefix(gwip, &gw_ip);
5712 if (!ret) {
5713 vty_out(vty, "%% Malformed GatewayIp\n");
5714 return CMD_WARNING_CONFIG_FAILED;
5715 }
5716 if ((gw_ip.family == AF_INET
5717 && is_evpn_prefix_ipaddr_v6(
5718 (struct prefix_evpn *)&p))
5719 || (gw_ip.family == AF_INET6
5720 && is_evpn_prefix_ipaddr_v4(
5721 (struct prefix_evpn *)&p))) {
5722 vty_out(vty,
5723 "%% GatewayIp family differs with IP prefix\n");
5724 return CMD_WARNING_CONFIG_FAILED;
5725 }
5726 }
5727 }
5728 prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5729 if (!bgp_node_has_bgp_path_info_data(prn))
5730 bgp_node_set_bgp_table_info(prn,
5731 bgp_table_init(bgp, afi, safi));
5732 table = bgp_node_get_bgp_table_info(prn);
5733
5734 rn = bgp_node_get(table, &p);
5735
5736 if (bgp_node_has_bgp_path_info_data(rn)) {
5737 vty_out(vty, "%% Same network configuration exists\n");
5738 bgp_unlock_node(rn);
5739 } else {
5740 /* New configuration. */
5741 bgp_static = bgp_static_new();
5742 bgp_static->backdoor = 0;
5743 bgp_static->valid = 0;
5744 bgp_static->igpmetric = 0;
5745 bgp_static->igpnexthop.s_addr = 0;
5746 bgp_static->label = label;
5747 bgp_static->prd = prd;
5748
5749 if (rmap_str) {
5750 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5751 route_map_counter_decrement(bgp_static->rmap.map);
5752 bgp_static->rmap.name =
5753 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
5754 bgp_static->rmap.map =
5755 route_map_lookup_by_name(rmap_str);
5756 route_map_counter_increment(bgp_static->rmap.map);
5757 }
5758
5759 if (safi == SAFI_EVPN) {
5760 if (esi) {
5761 bgp_static->eth_s_id =
5762 XCALLOC(MTYPE_ATTR,
5763 sizeof(struct eth_segment_id));
5764 str2esi(esi, bgp_static->eth_s_id);
5765 }
5766 if (routermac) {
5767 bgp_static->router_mac =
5768 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
5769 (void)prefix_str2mac(routermac,
5770 bgp_static->router_mac);
5771 }
5772 if (gwip)
5773 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
5774 }
5775 bgp_node_set_bgp_static_info(rn, bgp_static);
5776
5777 bgp_static->valid = 1;
5778 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
5779 }
5780
5781 return CMD_SUCCESS;
5782 }
5783
5784 /* Configure static BGP network. */
5785 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
5786 const char *ip_str, const char *rd_str,
5787 const char *label_str, int evpn_type, const char *esi,
5788 const char *gwip, const char *ethtag)
5789 {
5790 VTY_DECLVAR_CONTEXT(bgp, bgp);
5791 int ret;
5792 struct prefix p;
5793 struct prefix_rd prd;
5794 struct bgp_node *prn;
5795 struct bgp_node *rn;
5796 struct bgp_table *table;
5797 struct bgp_static *bgp_static;
5798 mpls_label_t label = MPLS_INVALID_LABEL;
5799
5800 /* Convert IP prefix string to struct prefix. */
5801 ret = str2prefix(ip_str, &p);
5802 if (!ret) {
5803 vty_out(vty, "%% Malformed prefix\n");
5804 return CMD_WARNING_CONFIG_FAILED;
5805 }
5806 apply_mask(&p);
5807 if ((afi == AFI_L2VPN)
5808 && (bgp_build_evpn_prefix(evpn_type,
5809 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5810 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5811 return CMD_WARNING_CONFIG_FAILED;
5812 }
5813 ret = str2prefix_rd(rd_str, &prd);
5814 if (!ret) {
5815 vty_out(vty, "%% Malformed rd\n");
5816 return CMD_WARNING_CONFIG_FAILED;
5817 }
5818
5819 if (label_str) {
5820 unsigned long label_val;
5821 label_val = strtoul(label_str, NULL, 10);
5822 encode_label(label_val, &label);
5823 }
5824
5825 prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5826 if (!bgp_node_has_bgp_path_info_data(prn))
5827 bgp_node_set_bgp_table_info(prn,
5828 bgp_table_init(bgp, afi, safi));
5829 else
5830 bgp_unlock_node(prn);
5831 table = bgp_node_get_bgp_table_info(prn);
5832
5833 rn = bgp_node_lookup(table, &p);
5834
5835 if (rn) {
5836 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
5837
5838 bgp_static = bgp_node_get_bgp_static_info(rn);
5839 bgp_static_free(bgp_static);
5840 bgp_node_set_bgp_static_info(rn, NULL);
5841 bgp_unlock_node(rn);
5842 bgp_unlock_node(rn);
5843 } else
5844 vty_out(vty, "%% Can't find the route\n");
5845
5846 return CMD_SUCCESS;
5847 }
5848
5849 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
5850 const char *rmap_name)
5851 {
5852 VTY_DECLVAR_CONTEXT(bgp, bgp);
5853 struct bgp_rmap *rmap;
5854
5855 rmap = &bgp->table_map[afi][safi];
5856 if (rmap_name) {
5857 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5858 route_map_counter_decrement(rmap->map);
5859 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
5860 rmap->map = route_map_lookup_by_name(rmap_name);
5861 route_map_counter_increment(rmap->map);
5862 } else {
5863 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5864 route_map_counter_decrement(rmap->map);
5865 rmap->name = NULL;
5866 rmap->map = NULL;
5867 }
5868
5869 if (bgp_fibupd_safi(safi))
5870 bgp_zebra_announce_table(bgp, afi, safi);
5871
5872 return CMD_SUCCESS;
5873 }
5874
5875 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
5876 const char *rmap_name)
5877 {
5878 VTY_DECLVAR_CONTEXT(bgp, bgp);
5879 struct bgp_rmap *rmap;
5880
5881 rmap = &bgp->table_map[afi][safi];
5882 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5883 route_map_counter_decrement(rmap->map);
5884 rmap->name = NULL;
5885 rmap->map = NULL;
5886
5887 if (bgp_fibupd_safi(safi))
5888 bgp_zebra_announce_table(bgp, afi, safi);
5889
5890 return CMD_SUCCESS;
5891 }
5892
5893 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
5894 safi_t safi)
5895 {
5896 if (bgp->table_map[afi][safi].name) {
5897 vty_out(vty, " table-map %s\n",
5898 bgp->table_map[afi][safi].name);
5899 }
5900 }
5901
5902 DEFUN (bgp_table_map,
5903 bgp_table_map_cmd,
5904 "table-map WORD",
5905 "BGP table to RIB route download filter\n"
5906 "Name of the route map\n")
5907 {
5908 int idx_word = 1;
5909 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
5910 argv[idx_word]->arg);
5911 }
5912 DEFUN (no_bgp_table_map,
5913 no_bgp_table_map_cmd,
5914 "no table-map WORD",
5915 NO_STR
5916 "BGP table to RIB route download filter\n"
5917 "Name of the route map\n")
5918 {
5919 int idx_word = 2;
5920 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
5921 argv[idx_word]->arg);
5922 }
5923
5924 DEFPY(bgp_network,
5925 bgp_network_cmd,
5926 "[no] network \
5927 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
5928 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
5929 backdoor$backdoor}]",
5930 NO_STR
5931 "Specify a network to announce via BGP\n"
5932 "IPv4 prefix\n"
5933 "Network number\n"
5934 "Network mask\n"
5935 "Network mask\n"
5936 "Route-map to modify the attributes\n"
5937 "Name of the route map\n"
5938 "Label index to associate with the prefix\n"
5939 "Label index value\n"
5940 "Specify a BGP backdoor route\n")
5941 {
5942 char addr_prefix_str[BUFSIZ];
5943
5944 if (address_str) {
5945 int ret;
5946
5947 ret = netmask_str2prefix_str(address_str, netmask_str,
5948 addr_prefix_str);
5949 if (!ret) {
5950 vty_out(vty, "%% Inconsistent address and mask\n");
5951 return CMD_WARNING_CONFIG_FAILED;
5952 }
5953 }
5954
5955 return bgp_static_set(
5956 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
5957 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
5958 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
5959 }
5960
5961 DEFPY(ipv6_bgp_network,
5962 ipv6_bgp_network_cmd,
5963 "[no] network X:X::X:X/M$prefix \
5964 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
5965 NO_STR
5966 "Specify a network to announce via BGP\n"
5967 "IPv6 prefix\n"
5968 "Route-map to modify the attributes\n"
5969 "Name of the route map\n"
5970 "Label index to associate with the prefix\n"
5971 "Label index value\n")
5972 {
5973 return bgp_static_set(
5974 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
5975 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
5976 }
5977
5978 static struct bgp_aggregate *bgp_aggregate_new(void)
5979 {
5980 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
5981 }
5982
5983 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
5984 {
5985 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
5986 route_map_counter_decrement(aggregate->rmap.map);
5987 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
5988 }
5989
5990 static int bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
5991 struct aspath *aspath,
5992 struct community *comm,
5993 struct ecommunity *ecomm,
5994 struct lcommunity *lcomm)
5995 {
5996 static struct aspath *ae = NULL;
5997
5998 if (!ae)
5999 ae = aspath_empty();
6000
6001 if (!pi)
6002 return 0;
6003
6004 if (origin != pi->attr->origin)
6005 return 0;
6006
6007 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
6008 return 0;
6009
6010 if (!community_cmp(pi->attr->community, comm))
6011 return 0;
6012
6013 if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
6014 return 0;
6015
6016 if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
6017 return 0;
6018
6019 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
6020 return 0;
6021
6022 return 1;
6023 }
6024
6025 static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
6026 struct prefix *p, uint8_t origin,
6027 struct aspath *aspath,
6028 struct community *community,
6029 struct ecommunity *ecommunity,
6030 struct lcommunity *lcommunity,
6031 uint8_t atomic_aggregate,
6032 struct bgp_aggregate *aggregate)
6033 {
6034 struct bgp_node *rn;
6035 struct bgp_table *table;
6036 struct bgp_path_info *pi, *orig, *new;
6037 struct attr *attr;
6038
6039 table = bgp->rib[afi][safi];
6040
6041 rn = bgp_node_get(table, p);
6042
6043 for (orig = pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
6044 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6045 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6046 break;
6047
6048 if (aggregate->count > 0) {
6049 /*
6050 * If the aggregate information has not changed
6051 * no need to re-install it again.
6052 */
6053 if (bgp_aggregate_info_same(orig, origin, aspath, community,
6054 ecommunity, lcommunity)) {
6055 bgp_unlock_node(rn);
6056
6057 if (aspath)
6058 aspath_free(aspath);
6059 if (community)
6060 community_free(&community);
6061 if (ecommunity)
6062 ecommunity_free(&ecommunity);
6063 if (lcommunity)
6064 lcommunity_free(&lcommunity);
6065
6066 return;
6067 }
6068
6069 /*
6070 * Mark the old as unusable
6071 */
6072 if (pi)
6073 bgp_path_info_delete(rn, pi);
6074
6075 attr = bgp_attr_aggregate_intern(
6076 bgp, origin, aspath, community, ecommunity, lcommunity,
6077 aggregate, atomic_aggregate, p);
6078
6079 if (!attr) {
6080 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
6081 return;
6082 }
6083
6084 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
6085 bgp->peer_self, attr, rn);
6086
6087 SET_FLAG(new->flags, BGP_PATH_VALID);
6088
6089 bgp_path_info_add(rn, new);
6090 bgp_process(bgp, rn, afi, safi);
6091 } else {
6092 for (pi = orig; pi; pi = pi->next)
6093 if (pi->peer == bgp->peer_self
6094 && pi->type == ZEBRA_ROUTE_BGP
6095 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6096 break;
6097
6098 /* Withdraw static BGP route from routing table. */
6099 if (pi) {
6100 bgp_path_info_delete(rn, pi);
6101 bgp_process(bgp, rn, afi, safi);
6102 }
6103 }
6104
6105 bgp_unlock_node(rn);
6106 }
6107
6108 /* Update an aggregate as routes are added/removed from the BGP table */
6109 void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
6110 afi_t afi, safi_t safi,
6111 struct bgp_aggregate *aggregate)
6112 {
6113 struct bgp_table *table;
6114 struct bgp_node *top;
6115 struct bgp_node *rn;
6116 uint8_t origin;
6117 struct aspath *aspath = NULL;
6118 struct community *community = NULL;
6119 struct ecommunity *ecommunity = NULL;
6120 struct lcommunity *lcommunity = NULL;
6121 struct bgp_path_info *pi;
6122 unsigned long match = 0;
6123 uint8_t atomic_aggregate = 0;
6124
6125 /* If the bgp instance is being deleted or self peer is deleted
6126 * then do not create aggregate route
6127 */
6128 if (bgp_flag_check(bgp, BGP_FLAG_DELETE_IN_PROGRESS) ||
6129 (bgp->peer_self == NULL))
6130 return;
6131
6132 /* ORIGIN attribute: If at least one route among routes that are
6133 aggregated has ORIGIN with the value INCOMPLETE, then the
6134 aggregated route must have the ORIGIN attribute with the value
6135 INCOMPLETE. Otherwise, if at least one route among routes that
6136 are aggregated has ORIGIN with the value EGP, then the aggregated
6137 route must have the origin attribute with the value EGP. In all
6138 other case the value of the ORIGIN attribute of the aggregated
6139 route is INTERNAL. */
6140 origin = BGP_ORIGIN_IGP;
6141
6142 table = bgp->rib[afi][safi];
6143
6144 top = bgp_node_get(table, p);
6145 for (rn = bgp_node_get(table, p); rn;
6146 rn = bgp_route_next_until(rn, top)) {
6147 if (rn->p.prefixlen <= p->prefixlen)
6148 continue;
6149
6150 match = 0;
6151
6152 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
6153 if (BGP_PATH_HOLDDOWN(pi))
6154 continue;
6155
6156 if (pi->attr->flag
6157 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
6158 atomic_aggregate = 1;
6159
6160 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6161 continue;
6162
6163 /*
6164 * summary-only aggregate route suppress
6165 * aggregated route announcements.
6166 */
6167 if (aggregate->summary_only) {
6168 (bgp_path_info_extra_get(pi))->suppress++;
6169 bgp_path_info_set_flag(rn, pi,
6170 BGP_PATH_ATTR_CHANGED);
6171 match++;
6172 }
6173
6174 aggregate->count++;
6175
6176 /*
6177 * If at least one route among routes that are
6178 * aggregated has ORIGIN with the value INCOMPLETE,
6179 * then the aggregated route MUST have the ORIGIN
6180 * attribute with the value INCOMPLETE. Otherwise, if
6181 * at least one route among routes that are aggregated
6182 * has ORIGIN with the value EGP, then the aggregated
6183 * route MUST have the ORIGIN attribute with the value
6184 * EGP.
6185 */
6186 switch (pi->attr->origin) {
6187 case BGP_ORIGIN_INCOMPLETE:
6188 aggregate->incomplete_origin_count++;
6189 break;
6190 case BGP_ORIGIN_EGP:
6191 aggregate->egp_origin_count++;
6192 break;
6193 default:
6194 /*Do nothing.
6195 */
6196 break;
6197 }
6198
6199 if (!aggregate->as_set)
6200 continue;
6201
6202 /*
6203 * as-set aggregate route generate origin, as path,
6204 * and community aggregation.
6205 */
6206 /* Compute aggregate route's as-path.
6207 */
6208 bgp_compute_aggregate_aspath_hash(aggregate,
6209 pi->attr->aspath);
6210
6211 /* Compute aggregate route's community.
6212 */
6213 if (pi->attr->community)
6214 bgp_compute_aggregate_community_hash(
6215 aggregate,
6216 pi->attr->community);
6217
6218 /* Compute aggregate route's extended community.
6219 */
6220 if (pi->attr->ecommunity)
6221 bgp_compute_aggregate_ecommunity_hash(
6222 aggregate,
6223 pi->attr->ecommunity);
6224
6225 /* Compute aggregate route's large community.
6226 */
6227 if (pi->attr->lcommunity)
6228 bgp_compute_aggregate_lcommunity_hash(
6229 aggregate,
6230 pi->attr->lcommunity);
6231 }
6232 if (match)
6233 bgp_process(bgp, rn, afi, safi);
6234 }
6235 if (aggregate->as_set) {
6236 bgp_compute_aggregate_aspath_val(aggregate);
6237 bgp_compute_aggregate_community_val(aggregate);
6238 bgp_compute_aggregate_ecommunity_val(aggregate);
6239 bgp_compute_aggregate_lcommunity_val(aggregate);
6240 }
6241
6242
6243 bgp_unlock_node(top);
6244
6245
6246 if (aggregate->incomplete_origin_count > 0)
6247 origin = BGP_ORIGIN_INCOMPLETE;
6248 else if (aggregate->egp_origin_count > 0)
6249 origin = BGP_ORIGIN_EGP;
6250
6251 if (aggregate->as_set) {
6252 if (aggregate->aspath)
6253 /* Retrieve aggregate route's as-path.
6254 */
6255 aspath = aspath_dup(aggregate->aspath);
6256
6257 if (aggregate->community)
6258 /* Retrieve aggregate route's community.
6259 */
6260 community = community_dup(aggregate->community);
6261
6262 if (aggregate->ecommunity)
6263 /* Retrieve aggregate route's ecommunity.
6264 */
6265 ecommunity = ecommunity_dup(aggregate->ecommunity);
6266
6267 if (aggregate->lcommunity)
6268 /* Retrieve aggregate route's lcommunity.
6269 */
6270 lcommunity = lcommunity_dup(aggregate->lcommunity);
6271 }
6272
6273 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
6274 ecommunity, lcommunity, atomic_aggregate,
6275 aggregate);
6276 }
6277
6278 void bgp_aggregate_delete(struct bgp *bgp, struct prefix *p, afi_t afi,
6279 safi_t safi, struct bgp_aggregate *aggregate)
6280 {
6281 struct bgp_table *table;
6282 struct bgp_node *top;
6283 struct bgp_node *rn;
6284 struct bgp_path_info *pi;
6285 unsigned long match;
6286
6287 table = bgp->rib[afi][safi];
6288
6289 /* If routes exists below this node, generate aggregate routes. */
6290 top = bgp_node_get(table, p);
6291 for (rn = bgp_node_get(table, p); rn;
6292 rn = bgp_route_next_until(rn, top)) {
6293 if (rn->p.prefixlen <= p->prefixlen)
6294 continue;
6295 match = 0;
6296
6297 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
6298 if (BGP_PATH_HOLDDOWN(pi))
6299 continue;
6300
6301 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6302 continue;
6303
6304 if (aggregate->summary_only && pi->extra) {
6305 pi->extra->suppress--;
6306
6307 if (pi->extra->suppress == 0) {
6308 bgp_path_info_set_flag(
6309 rn, pi, BGP_PATH_ATTR_CHANGED);
6310 match++;
6311 }
6312 }
6313 aggregate->count--;
6314
6315 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
6316 aggregate->incomplete_origin_count--;
6317 else if (pi->attr->origin == BGP_ORIGIN_EGP)
6318 aggregate->egp_origin_count--;
6319
6320 if (aggregate->as_set) {
6321 /* Remove as-path from aggregate.
6322 */
6323 bgp_remove_aspath_from_aggregate_hash(
6324 aggregate,
6325 pi->attr->aspath);
6326
6327 if (pi->attr->community)
6328 /* Remove community from aggregate.
6329 */
6330 bgp_remove_comm_from_aggregate_hash(
6331 aggregate,
6332 pi->attr->community);
6333
6334 if (pi->attr->ecommunity)
6335 /* Remove ecommunity from aggregate.
6336 */
6337 bgp_remove_ecomm_from_aggregate_hash(
6338 aggregate,
6339 pi->attr->ecommunity);
6340
6341 if (pi->attr->lcommunity)
6342 /* Remove lcommunity from aggregate.
6343 */
6344 bgp_remove_lcomm_from_aggregate_hash(
6345 aggregate,
6346 pi->attr->lcommunity);
6347 }
6348
6349 }
6350
6351 /* If this node was suppressed, process the change. */
6352 if (match)
6353 bgp_process(bgp, rn, afi, safi);
6354 }
6355 if (aggregate->as_set) {
6356 aspath_free(aggregate->aspath);
6357 aggregate->aspath = NULL;
6358 if (aggregate->community)
6359 community_free(&aggregate->community);
6360 if (aggregate->ecommunity)
6361 ecommunity_free(&aggregate->ecommunity);
6362 if (aggregate->lcommunity)
6363 lcommunity_free(&aggregate->lcommunity);
6364 }
6365
6366 bgp_unlock_node(top);
6367 }
6368
6369 static void bgp_add_route_to_aggregate(struct bgp *bgp, struct prefix *aggr_p,
6370 struct bgp_path_info *pinew, afi_t afi,
6371 safi_t safi,
6372 struct bgp_aggregate *aggregate)
6373 {
6374 uint8_t origin;
6375 struct aspath *aspath = NULL;
6376 uint8_t atomic_aggregate = 0;
6377 struct community *community = NULL;
6378 struct ecommunity *ecommunity = NULL;
6379 struct lcommunity *lcommunity = NULL;
6380
6381 /* ORIGIN attribute: If at least one route among routes that are
6382 * aggregated has ORIGIN with the value INCOMPLETE, then the
6383 * aggregated route must have the ORIGIN attribute with the value
6384 * INCOMPLETE. Otherwise, if at least one route among routes that
6385 * are aggregated has ORIGIN with the value EGP, then the aggregated
6386 * route must have the origin attribute with the value EGP. In all
6387 * other case the value of the ORIGIN attribute of the aggregated
6388 * route is INTERNAL.
6389 */
6390 origin = BGP_ORIGIN_IGP;
6391
6392 aggregate->count++;
6393
6394 if (aggregate->summary_only)
6395 (bgp_path_info_extra_get(pinew))->suppress++;
6396
6397 switch (pinew->attr->origin) {
6398 case BGP_ORIGIN_INCOMPLETE:
6399 aggregate->incomplete_origin_count++;
6400 break;
6401 case BGP_ORIGIN_EGP:
6402 aggregate->egp_origin_count++;
6403 break;
6404 default:
6405 /* Do nothing.
6406 */
6407 break;
6408 }
6409
6410 if (aggregate->incomplete_origin_count > 0)
6411 origin = BGP_ORIGIN_INCOMPLETE;
6412 else if (aggregate->egp_origin_count > 0)
6413 origin = BGP_ORIGIN_EGP;
6414
6415 if (aggregate->as_set) {
6416 /* Compute aggregate route's as-path.
6417 */
6418 bgp_compute_aggregate_aspath(aggregate,
6419 pinew->attr->aspath);
6420
6421 /* Compute aggregate route's community.
6422 */
6423 if (pinew->attr->community)
6424 bgp_compute_aggregate_community(
6425 aggregate,
6426 pinew->attr->community);
6427
6428 /* Compute aggregate route's extended community.
6429 */
6430 if (pinew->attr->ecommunity)
6431 bgp_compute_aggregate_ecommunity(
6432 aggregate,
6433 pinew->attr->ecommunity);
6434
6435 /* Compute aggregate route's large community.
6436 */
6437 if (pinew->attr->lcommunity)
6438 bgp_compute_aggregate_lcommunity(
6439 aggregate,
6440 pinew->attr->lcommunity);
6441
6442 /* Retrieve aggregate route's as-path.
6443 */
6444 if (aggregate->aspath)
6445 aspath = aspath_dup(aggregate->aspath);
6446
6447 /* Retrieve aggregate route's community.
6448 */
6449 if (aggregate->community)
6450 community = community_dup(aggregate->community);
6451
6452 /* Retrieve aggregate route's ecommunity.
6453 */
6454 if (aggregate->ecommunity)
6455 ecommunity = ecommunity_dup(aggregate->ecommunity);
6456
6457 /* Retrieve aggregate route's lcommunity.
6458 */
6459 if (aggregate->lcommunity)
6460 lcommunity = lcommunity_dup(aggregate->lcommunity);
6461 }
6462
6463 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
6464 aspath, community, ecommunity,
6465 lcommunity, atomic_aggregate, aggregate);
6466 }
6467
6468 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
6469 safi_t safi,
6470 struct bgp_path_info *pi,
6471 struct bgp_aggregate *aggregate,
6472 struct prefix *aggr_p)
6473 {
6474 uint8_t origin;
6475 struct aspath *aspath = NULL;
6476 uint8_t atomic_aggregate = 0;
6477 struct community *community = NULL;
6478 struct ecommunity *ecommunity = NULL;
6479 struct lcommunity *lcommunity = NULL;
6480 unsigned long match = 0;
6481
6482 if (BGP_PATH_HOLDDOWN(pi))
6483 return;
6484
6485 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6486 return;
6487
6488 if (aggregate->summary_only
6489 && pi->extra
6490 && pi->extra->suppress > 0) {
6491 pi->extra->suppress--;
6492
6493 if (pi->extra->suppress == 0) {
6494 bgp_path_info_set_flag(pi->net, pi,
6495 BGP_PATH_ATTR_CHANGED);
6496 match++;
6497 }
6498 }
6499
6500 if (aggregate->count > 0)
6501 aggregate->count--;
6502
6503 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
6504 aggregate->incomplete_origin_count--;
6505 else if (pi->attr->origin == BGP_ORIGIN_EGP)
6506 aggregate->egp_origin_count--;
6507
6508 if (aggregate->as_set) {
6509 /* Remove as-path from aggregate.
6510 */
6511 bgp_remove_aspath_from_aggregate(aggregate,
6512 pi->attr->aspath);
6513
6514 if (pi->attr->community)
6515 /* Remove community from aggregate.
6516 */
6517 bgp_remove_community_from_aggregate(
6518 aggregate,
6519 pi->attr->community);
6520
6521 if (pi->attr->ecommunity)
6522 /* Remove ecommunity from aggregate.
6523 */
6524 bgp_remove_ecommunity_from_aggregate(
6525 aggregate,
6526 pi->attr->ecommunity);
6527
6528 if (pi->attr->lcommunity)
6529 /* Remove lcommunity from aggregate.
6530 */
6531 bgp_remove_lcommunity_from_aggregate(
6532 aggregate,
6533 pi->attr->lcommunity);
6534 }
6535
6536 /* If this node was suppressed, process the change. */
6537 if (match)
6538 bgp_process(bgp, pi->net, afi, safi);
6539
6540 origin = BGP_ORIGIN_IGP;
6541 if (aggregate->incomplete_origin_count > 0)
6542 origin = BGP_ORIGIN_INCOMPLETE;
6543 else if (aggregate->egp_origin_count > 0)
6544 origin = BGP_ORIGIN_EGP;
6545
6546 if (aggregate->as_set) {
6547 /* Retrieve aggregate route's as-path.
6548 */
6549 if (aggregate->aspath)
6550 aspath = aspath_dup(aggregate->aspath);
6551
6552 /* Retrieve aggregate route's community.
6553 */
6554 if (aggregate->community)
6555 community = community_dup(aggregate->community);
6556
6557 /* Retrieve aggregate route's ecommunity.
6558 */
6559 if (aggregate->ecommunity)
6560 ecommunity = ecommunity_dup(aggregate->ecommunity);
6561
6562 /* Retrieve aggregate route's lcommunity.
6563 */
6564 if (aggregate->lcommunity)
6565 lcommunity = lcommunity_dup(aggregate->lcommunity);
6566 }
6567
6568 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
6569 aspath, community, ecommunity,
6570 lcommunity, atomic_aggregate, aggregate);
6571 }
6572
6573 void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p,
6574 struct bgp_path_info *pi, afi_t afi, safi_t safi)
6575 {
6576 struct bgp_node *child;
6577 struct bgp_node *rn;
6578 struct bgp_aggregate *aggregate;
6579 struct bgp_table *table;
6580
6581 table = bgp->aggregate[afi][safi];
6582
6583 /* No aggregates configured. */
6584 if (bgp_table_top_nolock(table) == NULL)
6585 return;
6586
6587 if (p->prefixlen == 0)
6588 return;
6589
6590 if (BGP_PATH_HOLDDOWN(pi))
6591 return;
6592
6593 child = bgp_node_get(table, p);
6594
6595 /* Aggregate address configuration check. */
6596 for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
6597 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6598 if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
6599 bgp_add_route_to_aggregate(bgp, &rn->p, pi, afi,
6600 safi, aggregate);
6601 }
6602 }
6603 bgp_unlock_node(child);
6604 }
6605
6606 void bgp_aggregate_decrement(struct bgp *bgp, struct prefix *p,
6607 struct bgp_path_info *del, afi_t afi, safi_t safi)
6608 {
6609 struct bgp_node *child;
6610 struct bgp_node *rn;
6611 struct bgp_aggregate *aggregate;
6612 struct bgp_table *table;
6613
6614 table = bgp->aggregate[afi][safi];
6615
6616 /* No aggregates configured. */
6617 if (bgp_table_top_nolock(table) == NULL)
6618 return;
6619
6620 if (p->prefixlen == 0)
6621 return;
6622
6623 child = bgp_node_get(table, p);
6624
6625 /* Aggregate address configuration check. */
6626 for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
6627 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6628 if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
6629 bgp_remove_route_from_aggregate(bgp, afi, safi,
6630 del, aggregate, &rn->p);
6631 }
6632 }
6633 bgp_unlock_node(child);
6634 }
6635
6636 /* Aggregate route attribute. */
6637 #define AGGREGATE_SUMMARY_ONLY 1
6638 #define AGGREGATE_AS_SET 1
6639 #define AGGREGATE_AS_UNSET 0
6640
6641 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
6642 afi_t afi, safi_t safi)
6643 {
6644 VTY_DECLVAR_CONTEXT(bgp, bgp);
6645 int ret;
6646 struct prefix p;
6647 struct bgp_node *rn;
6648 struct bgp_aggregate *aggregate;
6649
6650 /* Convert string to prefix structure. */
6651 ret = str2prefix(prefix_str, &p);
6652 if (!ret) {
6653 vty_out(vty, "Malformed prefix\n");
6654 return CMD_WARNING_CONFIG_FAILED;
6655 }
6656 apply_mask(&p);
6657
6658 /* Old configuration check. */
6659 rn = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
6660 if (!rn) {
6661 vty_out(vty,
6662 "%% There is no aggregate-address configuration.\n");
6663 return CMD_WARNING_CONFIG_FAILED;
6664 }
6665
6666 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6667 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
6668 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
6669 NULL, NULL, 0, aggregate);
6670
6671 /* Unlock aggregate address configuration. */
6672 bgp_node_set_bgp_aggregate_info(rn, NULL);
6673
6674 if (aggregate->community)
6675 community_free(&aggregate->community);
6676
6677 if (aggregate->community_hash) {
6678 /* Delete all communities in the hash.
6679 */
6680 hash_clean(aggregate->community_hash,
6681 bgp_aggr_community_remove);
6682 /* Free up the community_hash.
6683 */
6684 hash_free(aggregate->community_hash);
6685 }
6686
6687 if (aggregate->ecommunity)
6688 ecommunity_free(&aggregate->ecommunity);
6689
6690 if (aggregate->ecommunity_hash) {
6691 /* Delete all ecommunities in the hash.
6692 */
6693 hash_clean(aggregate->ecommunity_hash,
6694 bgp_aggr_ecommunity_remove);
6695 /* Free up the ecommunity_hash.
6696 */
6697 hash_free(aggregate->ecommunity_hash);
6698 }
6699
6700 if (aggregate->lcommunity)
6701 lcommunity_free(&aggregate->lcommunity);
6702
6703 if (aggregate->lcommunity_hash) {
6704 /* Delete all lcommunities in the hash.
6705 */
6706 hash_clean(aggregate->lcommunity_hash,
6707 bgp_aggr_lcommunity_remove);
6708 /* Free up the lcommunity_hash.
6709 */
6710 hash_free(aggregate->lcommunity_hash);
6711 }
6712
6713 if (aggregate->aspath)
6714 aspath_free(aggregate->aspath);
6715
6716 if (aggregate->aspath_hash) {
6717 /* Delete all as-paths in the hash.
6718 */
6719 hash_clean(aggregate->aspath_hash,
6720 bgp_aggr_aspath_remove);
6721 /* Free up the aspath_hash.
6722 */
6723 hash_free(aggregate->aspath_hash);
6724 }
6725
6726 bgp_aggregate_free(aggregate);
6727 bgp_unlock_node(rn);
6728 bgp_unlock_node(rn);
6729
6730 return CMD_SUCCESS;
6731 }
6732
6733 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
6734 safi_t safi, const char *rmap, uint8_t summary_only,
6735 uint8_t as_set)
6736 {
6737 VTY_DECLVAR_CONTEXT(bgp, bgp);
6738 int ret;
6739 struct prefix p;
6740 struct bgp_node *rn;
6741 struct bgp_aggregate *aggregate;
6742 uint8_t as_set_new = as_set;
6743
6744 /* Convert string to prefix structure. */
6745 ret = str2prefix(prefix_str, &p);
6746 if (!ret) {
6747 vty_out(vty, "Malformed prefix\n");
6748 return CMD_WARNING_CONFIG_FAILED;
6749 }
6750 apply_mask(&p);
6751
6752 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
6753 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
6754 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
6755 prefix_str);
6756 return CMD_WARNING_CONFIG_FAILED;
6757 }
6758
6759 /* Old configuration check. */
6760 rn = bgp_node_get(bgp->aggregate[afi][safi], &p);
6761 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6762
6763 if (aggregate) {
6764 vty_out(vty, "There is already same aggregate network.\n");
6765 /* try to remove the old entry */
6766 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
6767 if (ret) {
6768 vty_out(vty, "Error deleting aggregate.\n");
6769 bgp_unlock_node(rn);
6770 return CMD_WARNING_CONFIG_FAILED;
6771 }
6772 }
6773
6774 /* Make aggregate address structure. */
6775 aggregate = bgp_aggregate_new();
6776 aggregate->summary_only = summary_only;
6777
6778 /* Network operators MUST NOT locally generate any new
6779 * announcements containing AS_SET or AS_CONFED_SET. If they have
6780 * announced routes with AS_SET or AS_CONFED_SET in them, then they
6781 * SHOULD withdraw those routes and re-announce routes for the
6782 * aggregate or component prefixes (i.e., the more-specific routes
6783 * subsumed by the previously aggregated route) without AS_SET
6784 * or AS_CONFED_SET in the updates.
6785 */
6786 if (bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED) {
6787 if (as_set == AGGREGATE_AS_SET) {
6788 as_set_new = AGGREGATE_AS_UNSET;
6789 zlog_warn(
6790 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.\n",
6791 __func__);
6792 vty_out(vty,
6793 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
6794 }
6795 }
6796
6797 aggregate->as_set = as_set_new;
6798 aggregate->safi = safi;
6799
6800 if (rmap) {
6801 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
6802 route_map_counter_decrement(aggregate->rmap.map);
6803 aggregate->rmap.name =
6804 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6805 aggregate->rmap.map = route_map_lookup_by_name(rmap);
6806 route_map_counter_increment(aggregate->rmap.map);
6807 }
6808 bgp_node_set_bgp_aggregate_info(rn, aggregate);
6809
6810 /* Aggregate address insert into BGP routing table. */
6811 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
6812
6813 return CMD_SUCCESS;
6814 }
6815
6816 DEFUN (aggregate_address,
6817 aggregate_address_cmd,
6818 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6819 "Configure BGP aggregate entries\n"
6820 "Aggregate prefix\n"
6821 "Generate AS set path information\n"
6822 "Filter more specific routes from updates\n"
6823 "Filter more specific routes from updates\n"
6824 "Generate AS set path information\n"
6825 "Apply route map to aggregate network\n"
6826 "Name of route map\n")
6827 {
6828 int idx = 0;
6829 argv_find(argv, argc, "A.B.C.D/M", &idx);
6830 char *prefix = argv[idx]->arg;
6831 char *rmap = NULL;
6832 int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
6833 : AGGREGATE_AS_UNSET;
6834 idx = 0;
6835 int summary_only = argv_find(argv, argc, "summary-only", &idx)
6836 ? AGGREGATE_SUMMARY_ONLY
6837 : 0;
6838
6839 idx = 0;
6840 argv_find(argv, argc, "WORD", &idx);
6841 if (idx)
6842 rmap = argv[idx]->arg;
6843
6844 return bgp_aggregate_set(vty, prefix, AFI_IP, bgp_node_safi(vty),
6845 rmap, summary_only, as_set);
6846 }
6847
6848 DEFUN (aggregate_address_mask,
6849 aggregate_address_mask_cmd,
6850 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6851 "Configure BGP aggregate entries\n"
6852 "Aggregate address\n"
6853 "Aggregate mask\n"
6854 "Generate AS set path information\n"
6855 "Filter more specific routes from updates\n"
6856 "Filter more specific routes from updates\n"
6857 "Generate AS set path information\n"
6858 "Apply route map to aggregate network\n"
6859 "Name of route map\n")
6860 {
6861 int idx = 0;
6862 argv_find(argv, argc, "A.B.C.D", &idx);
6863 char *prefix = argv[idx]->arg;
6864 char *mask = argv[idx + 1]->arg;
6865 bool rmap_found;
6866 char *rmap = NULL;
6867 int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
6868 : AGGREGATE_AS_UNSET;
6869 idx = 0;
6870 int summary_only = argv_find(argv, argc, "summary-only", &idx)
6871 ? AGGREGATE_SUMMARY_ONLY
6872 : 0;
6873
6874 rmap_found = argv_find(argv, argc, "WORD", &idx);
6875 if (rmap_found)
6876 rmap = argv[idx]->arg;
6877
6878 char prefix_str[BUFSIZ];
6879 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
6880
6881 if (!ret) {
6882 vty_out(vty, "%% Inconsistent address and mask\n");
6883 return CMD_WARNING_CONFIG_FAILED;
6884 }
6885
6886 return bgp_aggregate_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty),
6887 rmap, summary_only, as_set);
6888 }
6889
6890 DEFUN (no_aggregate_address,
6891 no_aggregate_address_cmd,
6892 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6893 NO_STR
6894 "Configure BGP aggregate entries\n"
6895 "Aggregate prefix\n"
6896 "Generate AS set path information\n"
6897 "Filter more specific routes from updates\n"
6898 "Filter more specific routes from updates\n"
6899 "Generate AS set path information\n"
6900 "Apply route map to aggregate network\n"
6901 "Name of route map\n")
6902 {
6903 int idx = 0;
6904 argv_find(argv, argc, "A.B.C.D/M", &idx);
6905 char *prefix = argv[idx]->arg;
6906 return bgp_aggregate_unset(vty, prefix, AFI_IP, bgp_node_safi(vty));
6907 }
6908
6909 DEFUN (no_aggregate_address_mask,
6910 no_aggregate_address_mask_cmd,
6911 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6912 NO_STR
6913 "Configure BGP aggregate entries\n"
6914 "Aggregate address\n"
6915 "Aggregate mask\n"
6916 "Generate AS set path information\n"
6917 "Filter more specific routes from updates\n"
6918 "Filter more specific routes from updates\n"
6919 "Generate AS set path information\n"
6920 "Apply route map to aggregate network\n"
6921 "Name of route map\n")
6922 {
6923 int idx = 0;
6924 argv_find(argv, argc, "A.B.C.D", &idx);
6925 char *prefix = argv[idx]->arg;
6926 char *mask = argv[idx + 1]->arg;
6927
6928 char prefix_str[BUFSIZ];
6929 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
6930
6931 if (!ret) {
6932 vty_out(vty, "%% Inconsistent address and mask\n");
6933 return CMD_WARNING_CONFIG_FAILED;
6934 }
6935
6936 return bgp_aggregate_unset(vty, prefix_str, AFI_IP, bgp_node_safi(vty));
6937 }
6938
6939 DEFUN (ipv6_aggregate_address,
6940 ipv6_aggregate_address_cmd,
6941 "aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6942 "Configure BGP aggregate entries\n"
6943 "Aggregate prefix\n"
6944 "Generate AS set path information\n"
6945 "Filter more specific routes from updates\n"
6946 "Filter more specific routes from updates\n"
6947 "Generate AS set path information\n"
6948 "Apply route map to aggregate network\n"
6949 "Name of route map\n")
6950 {
6951 int idx = 0;
6952 argv_find(argv, argc, "X:X::X:X/M", &idx);
6953 char *prefix = argv[idx]->arg;
6954 char *rmap = NULL;
6955 bool rmap_found;
6956 int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
6957 : AGGREGATE_AS_UNSET;
6958
6959 idx = 0;
6960 int sum_only = argv_find(argv, argc, "summary-only", &idx)
6961 ? AGGREGATE_SUMMARY_ONLY
6962 : 0;
6963
6964 rmap_found = argv_find(argv, argc, "WORD", &idx);
6965 if (rmap_found)
6966 rmap = argv[idx]->arg;
6967
6968 return bgp_aggregate_set(vty, prefix, AFI_IP6, SAFI_UNICAST, rmap,
6969 sum_only, as_set);
6970 }
6971
6972 DEFUN (no_ipv6_aggregate_address,
6973 no_ipv6_aggregate_address_cmd,
6974 "no aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6975 NO_STR
6976 "Configure BGP aggregate entries\n"
6977 "Aggregate prefix\n"
6978 "Generate AS set path information\n"
6979 "Filter more specific routes from updates\n"
6980 "Filter more specific routes from updates\n"
6981 "Generate AS set path information\n"
6982 "Apply route map to aggregate network\n"
6983 "Name of route map\n")
6984 {
6985 int idx = 0;
6986 argv_find(argv, argc, "X:X::X:X/M", &idx);
6987 char *prefix = argv[idx]->arg;
6988 return bgp_aggregate_unset(vty, prefix, AFI_IP6, SAFI_UNICAST);
6989 }
6990
6991 /* Redistribute route treatment. */
6992 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
6993 const union g_addr *nexthop, ifindex_t ifindex,
6994 enum nexthop_types_t nhtype, uint32_t metric,
6995 uint8_t type, unsigned short instance,
6996 route_tag_t tag)
6997 {
6998 struct bgp_path_info *new;
6999 struct bgp_path_info *bpi;
7000 struct bgp_path_info rmap_path;
7001 struct bgp_node *bn;
7002 struct attr attr;
7003 struct attr *new_attr;
7004 afi_t afi;
7005 route_map_result_t ret;
7006 struct bgp_redist *red;
7007
7008 /* Make default attribute. */
7009 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
7010 /*
7011 * This must not be NULL to satisfy Coverity SA
7012 */
7013 assert(attr.aspath);
7014
7015 switch (nhtype) {
7016 case NEXTHOP_TYPE_IFINDEX:
7017 break;
7018 case NEXTHOP_TYPE_IPV4:
7019 case NEXTHOP_TYPE_IPV4_IFINDEX:
7020 attr.nexthop = nexthop->ipv4;
7021 break;
7022 case NEXTHOP_TYPE_IPV6:
7023 case NEXTHOP_TYPE_IPV6_IFINDEX:
7024 attr.mp_nexthop_global = nexthop->ipv6;
7025 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
7026 break;
7027 case NEXTHOP_TYPE_BLACKHOLE:
7028 switch (p->family) {
7029 case AF_INET:
7030 attr.nexthop.s_addr = INADDR_ANY;
7031 break;
7032 case AF_INET6:
7033 memset(&attr.mp_nexthop_global, 0,
7034 sizeof(attr.mp_nexthop_global));
7035 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
7036 break;
7037 }
7038 break;
7039 }
7040 attr.nh_ifindex = ifindex;
7041
7042 attr.med = metric;
7043 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
7044 attr.tag = tag;
7045
7046 afi = family2afi(p->family);
7047
7048 red = bgp_redist_lookup(bgp, afi, type, instance);
7049 if (red) {
7050 struct attr attr_new;
7051
7052 /* Copy attribute for modification. */
7053 attr_new = attr;
7054
7055 if (red->redist_metric_flag)
7056 attr_new.med = red->redist_metric;
7057
7058 /* Apply route-map. */
7059 if (red->rmap.name) {
7060 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
7061 rmap_path.peer = bgp->peer_self;
7062 rmap_path.attr = &attr_new;
7063
7064 SET_FLAG(bgp->peer_self->rmap_type,
7065 PEER_RMAP_TYPE_REDISTRIBUTE);
7066
7067 ret = route_map_apply(red->rmap.map, p, RMAP_BGP,
7068 &rmap_path);
7069
7070 bgp->peer_self->rmap_type = 0;
7071
7072 if (ret == RMAP_DENYMATCH) {
7073 /* Free uninterned attribute. */
7074 bgp_attr_flush(&attr_new);
7075
7076 /* Unintern original. */
7077 aspath_unintern(&attr.aspath);
7078 bgp_redistribute_delete(bgp, p, type, instance);
7079 return;
7080 }
7081 }
7082
7083 if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN))
7084 bgp_attr_add_gshut_community(&attr_new);
7085
7086 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
7087 SAFI_UNICAST, p, NULL);
7088
7089 new_attr = bgp_attr_intern(&attr_new);
7090
7091 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
7092 bpi = bpi->next)
7093 if (bpi->peer == bgp->peer_self
7094 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
7095 break;
7096
7097 if (bpi) {
7098 /* Ensure the (source route) type is updated. */
7099 bpi->type = type;
7100 if (attrhash_cmp(bpi->attr, new_attr)
7101 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
7102 bgp_attr_unintern(&new_attr);
7103 aspath_unintern(&attr.aspath);
7104 bgp_unlock_node(bn);
7105 return;
7106 } else {
7107 /* The attribute is changed. */
7108 bgp_path_info_set_flag(bn, bpi,
7109 BGP_PATH_ATTR_CHANGED);
7110
7111 /* Rewrite BGP route information. */
7112 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
7113 bgp_path_info_restore(bn, bpi);
7114 else
7115 bgp_aggregate_decrement(
7116 bgp, p, bpi, afi, SAFI_UNICAST);
7117 bgp_attr_unintern(&bpi->attr);
7118 bpi->attr = new_attr;
7119 bpi->uptime = bgp_clock();
7120
7121 /* Process change. */
7122 bgp_aggregate_increment(bgp, p, bpi, afi,
7123 SAFI_UNICAST);
7124 bgp_process(bgp, bn, afi, SAFI_UNICAST);
7125 bgp_unlock_node(bn);
7126 aspath_unintern(&attr.aspath);
7127
7128 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7129 || (bgp->inst_type
7130 == BGP_INSTANCE_TYPE_DEFAULT)) {
7131
7132 vpn_leak_from_vrf_update(
7133 bgp_get_default(), bgp, bpi);
7134 }
7135 return;
7136 }
7137 }
7138
7139 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
7140 bgp->peer_self, new_attr, bn);
7141 SET_FLAG(new->flags, BGP_PATH_VALID);
7142
7143 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
7144 bgp_path_info_add(bn, new);
7145 bgp_unlock_node(bn);
7146 bgp_process(bgp, bn, afi, SAFI_UNICAST);
7147
7148 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7149 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
7150
7151 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
7152 }
7153 }
7154
7155 /* Unintern original. */
7156 aspath_unintern(&attr.aspath);
7157 }
7158
7159 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
7160 unsigned short instance)
7161 {
7162 afi_t afi;
7163 struct bgp_node *rn;
7164 struct bgp_path_info *pi;
7165 struct bgp_redist *red;
7166
7167 afi = family2afi(p->family);
7168
7169 red = bgp_redist_lookup(bgp, afi, type, instance);
7170 if (red) {
7171 rn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
7172 SAFI_UNICAST, p, NULL);
7173
7174 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
7175 if (pi->peer == bgp->peer_self && pi->type == type)
7176 break;
7177
7178 if (pi) {
7179 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7180 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
7181
7182 vpn_leak_from_vrf_withdraw(bgp_get_default(),
7183 bgp, pi);
7184 }
7185 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
7186 bgp_path_info_delete(rn, pi);
7187 bgp_process(bgp, rn, afi, SAFI_UNICAST);
7188 }
7189 bgp_unlock_node(rn);
7190 }
7191 }
7192
7193 /* Withdraw specified route type's route. */
7194 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
7195 unsigned short instance)
7196 {
7197 struct bgp_node *rn;
7198 struct bgp_path_info *pi;
7199 struct bgp_table *table;
7200
7201 table = bgp->rib[afi][SAFI_UNICAST];
7202
7203 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
7204 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
7205 if (pi->peer == bgp->peer_self && pi->type == type
7206 && pi->instance == instance)
7207 break;
7208
7209 if (pi) {
7210 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7211 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
7212
7213 vpn_leak_from_vrf_withdraw(bgp_get_default(),
7214 bgp, pi);
7215 }
7216 bgp_aggregate_decrement(bgp, &rn->p, pi, afi,
7217 SAFI_UNICAST);
7218 bgp_path_info_delete(rn, pi);
7219 bgp_process(bgp, rn, afi, SAFI_UNICAST);
7220 }
7221 }
7222 }
7223
7224 /* Static function to display route. */
7225 static void route_vty_out_route(struct prefix *p, struct vty *vty,
7226 json_object *json)
7227 {
7228 int len = 0;
7229 char buf[BUFSIZ];
7230 char buf2[BUFSIZ];
7231
7232 if (p->family == AF_INET) {
7233 if (!json) {
7234 len = vty_out(
7235 vty, "%s/%d",
7236 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
7237 p->prefixlen);
7238 } else {
7239 json_object_string_add(json, "prefix",
7240 inet_ntop(p->family,
7241 &p->u.prefix, buf,
7242 BUFSIZ));
7243 json_object_int_add(json, "prefixLen", p->prefixlen);
7244 prefix2str(p, buf2, PREFIX_STRLEN);
7245 json_object_string_add(json, "network", buf2);
7246 }
7247 } else if (p->family == AF_ETHERNET) {
7248 prefix2str(p, buf, PREFIX_STRLEN);
7249 len = vty_out(vty, "%s", buf);
7250 } else if (p->family == AF_EVPN) {
7251 if (!json)
7252 len = vty_out(
7253 vty, "%s",
7254 bgp_evpn_route2str((struct prefix_evpn *)p, buf,
7255 BUFSIZ));
7256 else
7257 bgp_evpn_route2json((struct prefix_evpn *)p, json);
7258 } else if (p->family == AF_FLOWSPEC) {
7259 route_vty_out_flowspec(vty, p, NULL,
7260 json ?
7261 NLRI_STRING_FORMAT_JSON_SIMPLE :
7262 NLRI_STRING_FORMAT_MIN, json);
7263 } else {
7264 if (!json)
7265 len = vty_out(
7266 vty, "%s/%d",
7267 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
7268 p->prefixlen);
7269 else {
7270 json_object_string_add(json, "prefix",
7271 inet_ntop(p->family,
7272 &p->u.prefix, buf,
7273 BUFSIZ));
7274 json_object_int_add(json, "prefixLen", p->prefixlen);
7275 prefix2str(p, buf2, PREFIX_STRLEN);
7276 json_object_string_add(json, "network", buf2);
7277 }
7278 }
7279
7280 if (!json) {
7281 len = 17 - len;
7282 if (len < 1)
7283 vty_out(vty, "\n%*s", 20, " ");
7284 else
7285 vty_out(vty, "%*s", len, " ");
7286 }
7287 }
7288
7289 enum bgp_display_type {
7290 normal_list,
7291 };
7292
7293 /* Print the short form route status for a bgp_path_info */
7294 static void route_vty_short_status_out(struct vty *vty,
7295 struct bgp_path_info *path,
7296 json_object *json_path)
7297 {
7298 if (json_path) {
7299
7300 /* Route status display. */
7301 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
7302 json_object_boolean_true_add(json_path, "removed");
7303
7304 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
7305 json_object_boolean_true_add(json_path, "stale");
7306
7307 if (path->extra && path->extra->suppress)
7308 json_object_boolean_true_add(json_path, "suppressed");
7309
7310 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
7311 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7312 json_object_boolean_true_add(json_path, "valid");
7313
7314 /* Selected */
7315 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7316 json_object_boolean_true_add(json_path, "history");
7317
7318 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
7319 json_object_boolean_true_add(json_path, "damped");
7320
7321 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
7322 json_object_boolean_true_add(json_path, "bestpath");
7323
7324 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
7325 json_object_boolean_true_add(json_path, "multipath");
7326
7327 /* Internal route. */
7328 if ((path->peer->as)
7329 && (path->peer->as == path->peer->local_as))
7330 json_object_string_add(json_path, "pathFrom",
7331 "internal");
7332 else
7333 json_object_string_add(json_path, "pathFrom",
7334 "external");
7335
7336 return;
7337 }
7338
7339 /* Route status display. */
7340 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
7341 vty_out(vty, "R");
7342 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
7343 vty_out(vty, "S");
7344 else if (path->extra && path->extra->suppress)
7345 vty_out(vty, "s");
7346 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
7347 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7348 vty_out(vty, "*");
7349 else
7350 vty_out(vty, " ");
7351
7352 /* Selected */
7353 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7354 vty_out(vty, "h");
7355 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
7356 vty_out(vty, "d");
7357 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
7358 vty_out(vty, ">");
7359 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
7360 vty_out(vty, "=");
7361 else
7362 vty_out(vty, " ");
7363
7364 /* Internal route. */
7365 if (path->peer && (path->peer->as)
7366 && (path->peer->as == path->peer->local_as))
7367 vty_out(vty, "i");
7368 else
7369 vty_out(vty, " ");
7370 }
7371
7372 static char *bgp_nexthop_hostname(struct peer *peer, struct attr *attr)
7373 {
7374 if (peer->hostname && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)
7375 && !(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))
7376 return peer->hostname;
7377 return NULL;
7378 }
7379
7380 /* called from terminal list command */
7381 void route_vty_out(struct vty *vty, struct prefix *p,
7382 struct bgp_path_info *path, int display, safi_t safi,
7383 json_object *json_paths)
7384 {
7385 struct attr *attr = path->attr;
7386 json_object *json_path = NULL;
7387 json_object *json_nexthops = NULL;
7388 json_object *json_nexthop_global = NULL;
7389 json_object *json_nexthop_ll = NULL;
7390 json_object *json_ext_community = NULL;
7391 char vrf_id_str[VRF_NAMSIZ] = {0};
7392 bool nexthop_self =
7393 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
7394 bool nexthop_othervrf = false;
7395 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
7396 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
7397 char *nexthop_hostname = bgp_nexthop_hostname(path->peer, attr);
7398
7399 if (json_paths)
7400 json_path = json_object_new_object();
7401
7402 /* short status lead text */
7403 route_vty_short_status_out(vty, path, json_path);
7404
7405 if (!json_paths) {
7406 /* print prefix and mask */
7407 if (!display)
7408 route_vty_out_route(p, vty, json_path);
7409 else
7410 vty_out(vty, "%*s", 17, " ");
7411 } else {
7412 route_vty_out_route(p, vty, json_path);
7413 }
7414
7415 /*
7416 * If vrf id of nexthop is different from that of prefix,
7417 * set up printable string to append
7418 */
7419 if (path->extra && path->extra->bgp_orig) {
7420 const char *self = "";
7421
7422 if (nexthop_self)
7423 self = "<";
7424
7425 nexthop_othervrf = true;
7426 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
7427
7428 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
7429 snprintf(vrf_id_str, sizeof(vrf_id_str),
7430 "@%s%s", VRFID_NONE_STR, self);
7431 else
7432 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
7433 path->extra->bgp_orig->vrf_id, self);
7434
7435 if (path->extra->bgp_orig->inst_type
7436 != BGP_INSTANCE_TYPE_DEFAULT)
7437
7438 nexthop_vrfname = path->extra->bgp_orig->name;
7439 } else {
7440 const char *self = "";
7441
7442 if (nexthop_self)
7443 self = "<";
7444
7445 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
7446 }
7447
7448 /*
7449 * For ENCAP and EVPN routes, nexthop address family is not
7450 * neccessarily the same as the prefix address family.
7451 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
7452 * EVPN routes are also exchanged with a MP nexthop. Currently,
7453 * this
7454 * is only IPv4, the value will be present in either
7455 * attr->nexthop or
7456 * attr->mp_nexthop_global_in
7457 */
7458 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
7459 char buf[BUFSIZ];
7460 char nexthop[128];
7461 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
7462
7463 switch (af) {
7464 case AF_INET:
7465 sprintf(nexthop, "%s",
7466 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
7467 BUFSIZ));
7468 break;
7469 case AF_INET6:
7470 sprintf(nexthop, "%s",
7471 inet_ntop(af, &attr->mp_nexthop_global, buf,
7472 BUFSIZ));
7473 break;
7474 default:
7475 sprintf(nexthop, "?");
7476 break;
7477 }
7478
7479 if (json_paths) {
7480 json_nexthop_global = json_object_new_object();
7481
7482 json_object_string_add(json_nexthop_global, "ip",
7483 nexthop);
7484
7485 if (nexthop_hostname)
7486 json_object_string_add(json_nexthop_global,
7487 "hostname",
7488 nexthop_hostname);
7489
7490 json_object_string_add(json_nexthop_global, "afi",
7491 (af == AF_INET) ? "ipv4"
7492 : "ipv6");
7493 json_object_boolean_true_add(json_nexthop_global,
7494 "used");
7495 } else
7496 vty_out(vty, "%s%s",
7497 nexthop_hostname ? nexthop_hostname : nexthop,
7498 vrf_id_str);
7499 } else if (safi == SAFI_EVPN) {
7500 if (json_paths) {
7501 json_nexthop_global = json_object_new_object();
7502
7503 json_object_string_add(json_nexthop_global, "ip",
7504 inet_ntoa(attr->nexthop));
7505
7506 if (nexthop_hostname)
7507 json_object_string_add(json_nexthop_global,
7508 "hostname",
7509 nexthop_hostname);
7510
7511 json_object_string_add(json_nexthop_global, "afi",
7512 "ipv4");
7513 json_object_boolean_true_add(json_nexthop_global,
7514 "used");
7515 } else
7516 vty_out(vty, "%-16s%s",
7517 nexthop_hostname ? nexthop_hostname
7518 : inet_ntoa(attr->nexthop),
7519 vrf_id_str);
7520 } else if (safi == SAFI_FLOWSPEC) {
7521 if (attr->nexthop.s_addr != 0) {
7522 if (json_paths) {
7523 json_nexthop_global = json_object_new_object();
7524
7525 json_object_string_add(json_nexthop_global,
7526 "afi", "ipv4");
7527 json_object_string_add(
7528 json_nexthop_global, "ip",
7529 inet_ntoa(attr->nexthop));
7530
7531 if (nexthop_hostname)
7532 json_object_string_add(
7533 json_nexthop_global, "hostname",
7534 nexthop_hostname);
7535
7536 json_object_boolean_true_add(
7537 json_nexthop_global,
7538 "used");
7539 } else {
7540 vty_out(vty, "%-16s",
7541 nexthop_hostname
7542 ? nexthop_hostname
7543 : inet_ntoa(attr->nexthop));
7544 }
7545 }
7546 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7547 if (json_paths) {
7548 json_nexthop_global = json_object_new_object();
7549
7550 json_object_string_add(json_nexthop_global, "ip",
7551 inet_ntoa(attr->nexthop));
7552
7553 if (nexthop_hostname)
7554 json_object_string_add(json_nexthop_global,
7555 "hostname",
7556 nexthop_hostname);
7557
7558 json_object_string_add(json_nexthop_global, "afi",
7559 "ipv4");
7560 json_object_boolean_true_add(json_nexthop_global,
7561 "used");
7562 } else {
7563 char buf[BUFSIZ];
7564
7565 snprintf(buf, sizeof(buf), "%s%s",
7566 nexthop_hostname ? nexthop_hostname
7567 : inet_ntoa(attr->nexthop),
7568 vrf_id_str);
7569 vty_out(vty, "%-16s", buf);
7570 }
7571 }
7572
7573 /* IPv6 Next Hop */
7574 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7575 int len;
7576 char buf[BUFSIZ];
7577
7578 if (json_paths) {
7579 json_nexthop_global = json_object_new_object();
7580 json_object_string_add(
7581 json_nexthop_global, "ip",
7582 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
7583 buf, BUFSIZ));
7584
7585 if (nexthop_hostname)
7586 json_object_string_add(json_nexthop_global,
7587 "hostname",
7588 nexthop_hostname);
7589
7590 json_object_string_add(json_nexthop_global, "afi",
7591 "ipv6");
7592 json_object_string_add(json_nexthop_global, "scope",
7593 "global");
7594
7595 /* We display both LL & GL if both have been
7596 * received */
7597 if ((attr->mp_nexthop_len
7598 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
7599 || (path->peer->conf_if)) {
7600 json_nexthop_ll = json_object_new_object();
7601 json_object_string_add(
7602 json_nexthop_ll, "ip",
7603 inet_ntop(AF_INET6,
7604 &attr->mp_nexthop_local, buf,
7605 BUFSIZ));
7606
7607 if (nexthop_hostname)
7608 json_object_string_add(
7609 json_nexthop_ll, "hostname",
7610 nexthop_hostname);
7611
7612 json_object_string_add(json_nexthop_ll, "afi",
7613 "ipv6");
7614 json_object_string_add(json_nexthop_ll, "scope",
7615 "link-local");
7616
7617 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
7618 &attr->mp_nexthop_local)
7619 != 0)
7620 && !attr->mp_nexthop_prefer_global)
7621 json_object_boolean_true_add(
7622 json_nexthop_ll, "used");
7623 else
7624 json_object_boolean_true_add(
7625 json_nexthop_global, "used");
7626 } else
7627 json_object_boolean_true_add(
7628 json_nexthop_global, "used");
7629 } else {
7630 /* Display LL if LL/Global both in table unless
7631 * prefer-global is set */
7632 if (((attr->mp_nexthop_len
7633 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
7634 && !attr->mp_nexthop_prefer_global)
7635 || (path->peer->conf_if)) {
7636 if (path->peer->conf_if) {
7637 len = vty_out(vty, "%s",
7638 path->peer->conf_if);
7639 len = 16 - len; /* len of IPv6
7640 addr + max
7641 len of def
7642 ifname */
7643
7644 if (len < 1)
7645 vty_out(vty, "\n%*s", 36, " ");
7646 else
7647 vty_out(vty, "%*s", len, " ");
7648 } else {
7649 len = vty_out(
7650 vty, "%s%s",
7651 nexthop_hostname
7652 ? nexthop_hostname
7653 : inet_ntop(
7654 AF_INET6,
7655 &attr->mp_nexthop_local,
7656 buf, BUFSIZ),
7657 vrf_id_str);
7658 len = 16 - len;
7659
7660 if (len < 1)
7661 vty_out(vty, "\n%*s", 36, " ");
7662 else
7663 vty_out(vty, "%*s", len, " ");
7664 }
7665 } else {
7666 len = vty_out(
7667 vty, "%s%s",
7668 nexthop_hostname
7669 ? nexthop_hostname
7670 : inet_ntop(
7671 AF_INET6,
7672 &attr->mp_nexthop_global,
7673 buf, BUFSIZ),
7674 vrf_id_str);
7675 len = 16 - len;
7676
7677 if (len < 1)
7678 vty_out(vty, "\n%*s", 36, " ");
7679 else
7680 vty_out(vty, "%*s", len, " ");
7681 }
7682 }
7683 }
7684
7685 /* MED/Metric */
7686 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7687 if (json_paths) {
7688
7689 /*
7690 * Adding "metric" field to match with corresponding
7691 * CLI. "med" will be deprecated in future.
7692 */
7693 json_object_int_add(json_path, "med", attr->med);
7694 json_object_int_add(json_path, "metric", attr->med);
7695 } else
7696 vty_out(vty, "%10u", attr->med);
7697 else if (!json_paths)
7698 vty_out(vty, " ");
7699
7700 /* Local Pref */
7701 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
7702 if (json_paths) {
7703
7704 /*
7705 * Adding "locPrf" field to match with corresponding
7706 * CLI. "localPref" will be deprecated in future.
7707 */
7708 json_object_int_add(json_path, "localpref",
7709 attr->local_pref);
7710 json_object_int_add(json_path, "locPrf",
7711 attr->local_pref);
7712 } else
7713 vty_out(vty, "%7u", attr->local_pref);
7714 else if (!json_paths)
7715 vty_out(vty, " ");
7716
7717 if (json_paths)
7718 json_object_int_add(json_path, "weight", attr->weight);
7719 else
7720 vty_out(vty, "%7u ", attr->weight);
7721
7722 if (json_paths) {
7723 char buf[BUFSIZ];
7724 json_object_string_add(
7725 json_path, "peerId",
7726 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
7727 }
7728
7729 /* Print aspath */
7730 if (attr->aspath) {
7731 if (json_paths) {
7732
7733 /*
7734 * Adding "path" field to match with corresponding
7735 * CLI. "aspath" will be deprecated in future.
7736 */
7737 json_object_string_add(json_path, "aspath",
7738 attr->aspath->str);
7739 json_object_string_add(json_path, "path",
7740 attr->aspath->str);
7741 } else
7742 aspath_print_vty(vty, "%s", attr->aspath, " ");
7743 }
7744
7745 /* Print origin */
7746 if (json_paths)
7747 json_object_string_add(json_path, "origin",
7748 bgp_origin_long_str[attr->origin]);
7749 else
7750 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7751
7752 if (json_paths) {
7753 if (safi == SAFI_EVPN &&
7754 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
7755 json_ext_community = json_object_new_object();
7756 json_object_string_add(json_ext_community,
7757 "string",
7758 attr->ecommunity->str);
7759 json_object_object_add(json_path,
7760 "extendedCommunity",
7761 json_ext_community);
7762 }
7763
7764 if (nexthop_self)
7765 json_object_boolean_true_add(json_path,
7766 "announceNexthopSelf");
7767 if (nexthop_othervrf) {
7768 json_object_string_add(json_path, "nhVrfName",
7769 nexthop_vrfname);
7770
7771 json_object_int_add(json_path, "nhVrfId",
7772 ((nexthop_vrfid == VRF_UNKNOWN)
7773 ? -1
7774 : (int)nexthop_vrfid));
7775 }
7776 }
7777
7778 if (json_paths) {
7779 if (json_nexthop_global || json_nexthop_ll) {
7780 json_nexthops = json_object_new_array();
7781
7782 if (json_nexthop_global)
7783 json_object_array_add(json_nexthops,
7784 json_nexthop_global);
7785
7786 if (json_nexthop_ll)
7787 json_object_array_add(json_nexthops,
7788 json_nexthop_ll);
7789
7790 json_object_object_add(json_path, "nexthops",
7791 json_nexthops);
7792 }
7793
7794 json_object_array_add(json_paths, json_path);
7795 } else {
7796 vty_out(vty, "\n");
7797
7798 if (safi == SAFI_EVPN &&
7799 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
7800 vty_out(vty, "%*s", 20, " ");
7801 vty_out(vty, "%s\n", attr->ecommunity->str);
7802 }
7803
7804 #if ENABLE_BGP_VNC
7805 /* prints an additional line, indented, with VNC info, if
7806 * present */
7807 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
7808 rfapi_vty_out_vncinfo(vty, p, path, safi);
7809 #endif
7810 }
7811 }
7812
7813 /* called from terminal list command */
7814 void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
7815 safi_t safi, bool use_json, json_object *json_ar)
7816 {
7817 json_object *json_status = NULL;
7818 json_object *json_net = NULL;
7819 char buff[BUFSIZ];
7820
7821 /* Route status display. */
7822 if (use_json) {
7823 json_status = json_object_new_object();
7824 json_net = json_object_new_object();
7825 } else {
7826 vty_out(vty, "*");
7827 vty_out(vty, ">");
7828 vty_out(vty, " ");
7829 }
7830
7831 /* print prefix and mask */
7832 if (use_json) {
7833 if (safi == SAFI_EVPN)
7834 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
7835 else if (p->family == AF_INET || p->family == AF_INET6) {
7836 json_object_string_add(
7837 json_net, "addrPrefix",
7838 inet_ntop(p->family, &p->u.prefix, buff,
7839 BUFSIZ));
7840 json_object_int_add(json_net, "prefixLen",
7841 p->prefixlen);
7842 prefix2str(p, buff, PREFIX_STRLEN);
7843 json_object_string_add(json_net, "network", buff);
7844 }
7845 } else
7846 route_vty_out_route(p, vty, NULL);
7847
7848 /* Print attribute */
7849 if (attr) {
7850 if (use_json) {
7851 if (p->family == AF_INET
7852 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7853 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7854 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
7855 json_object_string_add(
7856 json_net, "nextHop",
7857 inet_ntoa(
7858 attr->mp_nexthop_global_in));
7859 else
7860 json_object_string_add(
7861 json_net, "nextHop",
7862 inet_ntoa(attr->nexthop));
7863 } else if (p->family == AF_INET6
7864 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7865 char buf[BUFSIZ];
7866
7867 json_object_string_add(
7868 json_net, "nextHopGlobal",
7869 inet_ntop(AF_INET6,
7870 &attr->mp_nexthop_global, buf,
7871 BUFSIZ));
7872 } else if (p->family == AF_EVPN &&
7873 !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7874 json_object_string_add(json_net,
7875 "nextHop", inet_ntoa(
7876 attr->mp_nexthop_global_in));
7877
7878 if (attr->flag
7879 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7880 json_object_int_add(json_net, "metric",
7881 attr->med);
7882
7883 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
7884
7885 /*
7886 * Adding "locPrf" field to match with
7887 * corresponding CLI. "localPref" will be
7888 * deprecated in future.
7889 */
7890 json_object_int_add(json_net, "localPref",
7891 attr->local_pref);
7892 json_object_int_add(json_net, "locPrf",
7893 attr->local_pref);
7894 }
7895
7896 json_object_int_add(json_net, "weight", attr->weight);
7897
7898 /* Print aspath */
7899 if (attr->aspath) {
7900
7901 /*
7902 * Adding "path" field to match with
7903 * corresponding CLI. "localPref" will be
7904 * deprecated in future.
7905 */
7906 json_object_string_add(json_net, "asPath",
7907 attr->aspath->str);
7908 json_object_string_add(json_net, "path",
7909 attr->aspath->str);
7910 }
7911
7912 /* Print origin */
7913 json_object_string_add(json_net, "bgpOriginCode",
7914 bgp_origin_str[attr->origin]);
7915 } else {
7916 if (p->family == AF_INET
7917 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7918 || safi == SAFI_EVPN
7919 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7920 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7921 || safi == SAFI_EVPN)
7922 vty_out(vty, "%-16s",
7923 inet_ntoa(
7924 attr->mp_nexthop_global_in));
7925 else
7926 vty_out(vty, "%-16s",
7927 inet_ntoa(attr->nexthop));
7928 } else if (p->family == AF_INET6
7929 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7930 int len;
7931 char buf[BUFSIZ];
7932
7933 len = vty_out(
7934 vty, "%s",
7935 inet_ntop(AF_INET6,
7936 &attr->mp_nexthop_global, buf,
7937 BUFSIZ));
7938 len = 16 - len;
7939 if (len < 1)
7940 vty_out(vty, "\n%*s", 36, " ");
7941 else
7942 vty_out(vty, "%*s", len, " ");
7943 }
7944 if (attr->flag
7945 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7946 vty_out(vty, "%10u", attr->med);
7947 else
7948 vty_out(vty, " ");
7949
7950 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
7951 vty_out(vty, "%7u", attr->local_pref);
7952 else
7953 vty_out(vty, " ");
7954
7955 vty_out(vty, "%7u ", attr->weight);
7956
7957 /* Print aspath */
7958 if (attr->aspath)
7959 aspath_print_vty(vty, "%s", attr->aspath, " ");
7960
7961 /* Print origin */
7962 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7963 }
7964 }
7965 if (use_json) {
7966 json_object_boolean_true_add(json_status, "*");
7967 json_object_boolean_true_add(json_status, ">");
7968 json_object_object_add(json_net, "appliedStatusSymbols",
7969 json_status);
7970
7971 prefix2str(p, buff, PREFIX_STRLEN);
7972 json_object_object_add(json_ar, buff, json_net);
7973 } else
7974 vty_out(vty, "\n");
7975 }
7976
7977 void route_vty_out_tag(struct vty *vty, struct prefix *p,
7978 struct bgp_path_info *path, int display, safi_t safi,
7979 json_object *json)
7980 {
7981 json_object *json_out = NULL;
7982 struct attr *attr;
7983 mpls_label_t label = MPLS_INVALID_LABEL;
7984
7985 if (!path->extra)
7986 return;
7987
7988 if (json)
7989 json_out = json_object_new_object();
7990
7991 /* short status lead text */
7992 route_vty_short_status_out(vty, path, json_out);
7993
7994 /* print prefix and mask */
7995 if (json == NULL) {
7996 if (!display)
7997 route_vty_out_route(p, vty, NULL);
7998 else
7999 vty_out(vty, "%*s", 17, " ");
8000 }
8001
8002 /* Print attribute */
8003 attr = path->attr;
8004 if (((p->family == AF_INET)
8005 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
8006 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
8007 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8008 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8009 || safi == SAFI_EVPN) {
8010 if (json)
8011 json_object_string_add(
8012 json_out, "mpNexthopGlobalIn",
8013 inet_ntoa(attr->mp_nexthop_global_in));
8014 else
8015 vty_out(vty, "%-16s",
8016 inet_ntoa(attr->mp_nexthop_global_in));
8017 } else {
8018 if (json)
8019 json_object_string_add(
8020 json_out, "nexthop",
8021 inet_ntoa(attr->nexthop));
8022 else
8023 vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
8024 }
8025 } else if (((p->family == AF_INET6)
8026 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
8027 || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
8028 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8029 char buf_a[512];
8030
8031 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
8032 if (json)
8033 json_object_string_add(
8034 json_out, "mpNexthopGlobalIn",
8035 inet_ntop(AF_INET6,
8036 &attr->mp_nexthop_global,
8037 buf_a, sizeof(buf_a)));
8038 else
8039 vty_out(vty, "%s",
8040 inet_ntop(AF_INET6,
8041 &attr->mp_nexthop_global,
8042 buf_a, sizeof(buf_a)));
8043 } else if (attr->mp_nexthop_len
8044 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
8045 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
8046 &attr->mp_nexthop_global,
8047 &attr->mp_nexthop_local);
8048 if (json)
8049 json_object_string_add(json_out,
8050 "mpNexthopGlobalLocal",
8051 buf_a);
8052 else
8053 vty_out(vty, "%s", buf_a);
8054 }
8055 }
8056
8057 label = decode_label(&path->extra->label[0]);
8058
8059 if (bgp_is_valid_label(&label)) {
8060 if (json) {
8061 json_object_int_add(json_out, "notag", label);
8062 json_object_array_add(json, json_out);
8063 } else {
8064 vty_out(vty, "notag/%d", label);
8065 vty_out(vty, "\n");
8066 }
8067 }
8068 }
8069
8070 void route_vty_out_overlay(struct vty *vty, struct prefix *p,
8071 struct bgp_path_info *path, int display,
8072 json_object *json_paths)
8073 {
8074 struct attr *attr;
8075 char buf[BUFSIZ] = {0};
8076 json_object *json_path = NULL;
8077 json_object *json_nexthop = NULL;
8078 json_object *json_overlay = NULL;
8079
8080 if (!path->extra)
8081 return;
8082
8083 if (json_paths) {
8084 json_path = json_object_new_object();
8085 json_overlay = json_object_new_object();
8086 json_nexthop = json_object_new_object();
8087 }
8088
8089 /* short status lead text */
8090 route_vty_short_status_out(vty, path, json_path);
8091
8092 /* print prefix and mask */
8093 if (!display)
8094 route_vty_out_route(p, vty, json_path);
8095 else
8096 vty_out(vty, "%*s", 17, " ");
8097
8098 /* Print attribute */
8099 attr = path->attr;
8100 char buf1[BUFSIZ];
8101 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
8102
8103 switch (af) {
8104 case AF_INET:
8105 inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ);
8106 if (!json_path) {
8107 vty_out(vty, "%-16s", buf);
8108 } else {
8109 json_object_string_add(json_nexthop, "ip", buf);
8110
8111 json_object_string_add(json_nexthop, "afi", "ipv4");
8112
8113 json_object_object_add(json_path, "nexthop",
8114 json_nexthop);
8115 }
8116 break;
8117 case AF_INET6:
8118 inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ);
8119 inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ);
8120 if (!json_path) {
8121 vty_out(vty, "%s(%s)", buf, buf1);
8122 } else {
8123 json_object_string_add(json_nexthop, "ipv6Global", buf);
8124
8125 json_object_string_add(json_nexthop, "ipv6LinkLocal",
8126 buf1);
8127
8128 json_object_string_add(json_nexthop, "afi", "ipv6");
8129
8130 json_object_object_add(json_path, "nexthop",
8131 json_nexthop);
8132 }
8133 break;
8134 default:
8135 if (!json_path) {
8136 vty_out(vty, "?");
8137 } else {
8138 json_object_string_add(json_nexthop, "Error",
8139 "Unsupported address-family");
8140 }
8141 }
8142
8143 char *str = esi2str(&(attr->evpn_overlay.eth_s_id));
8144
8145 if (!json_path)
8146 vty_out(vty, "%s", str);
8147 else
8148 json_object_string_add(json_overlay, "esi", str);
8149
8150 XFREE(MTYPE_TMP, str);
8151
8152 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) {
8153 inet_ntop(AF_INET, &(attr->evpn_overlay.gw_ip.ipv4), buf,
8154 BUFSIZ);
8155 } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) {
8156 inet_ntop(AF_INET6, &(attr->evpn_overlay.gw_ip.ipv6), buf,
8157 BUFSIZ);
8158 }
8159
8160 if (!json_path)
8161 vty_out(vty, "/%s", buf);
8162 else
8163 json_object_string_add(json_overlay, "gw", buf);
8164
8165 if (attr->ecommunity) {
8166 char *mac = NULL;
8167 struct ecommunity_val *routermac = ecommunity_lookup(
8168 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
8169 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
8170
8171 if (routermac)
8172 mac = ecom_mac2str((char *)routermac->val);
8173 if (mac) {
8174 if (!json_path) {
8175 vty_out(vty, "/%s", (char *)mac);
8176 } else {
8177 json_object_string_add(json_overlay, "rmac",
8178 mac);
8179 }
8180 XFREE(MTYPE_TMP, mac);
8181 }
8182 }
8183
8184 if (!json_path) {
8185 vty_out(vty, "\n");
8186 } else {
8187 json_object_object_add(json_path, "overlay", json_overlay);
8188
8189 json_object_array_add(json_paths, json_path);
8190 }
8191 }
8192
8193 /* dampening route */
8194 static void damp_route_vty_out(struct vty *vty, struct prefix *p,
8195 struct bgp_path_info *path, int display, afi_t afi,
8196 safi_t safi, bool use_json, json_object *json)
8197 {
8198 struct attr *attr;
8199 int len;
8200 char timebuf[BGP_UPTIME_LEN];
8201
8202 /* short status lead text */
8203 route_vty_short_status_out(vty, path, json);
8204
8205 /* print prefix and mask */
8206 if (!use_json) {
8207 if (!display)
8208 route_vty_out_route(p, vty, NULL);
8209 else
8210 vty_out(vty, "%*s", 17, " ");
8211 }
8212
8213 len = vty_out(vty, "%s", path->peer->host);
8214 len = 17 - len;
8215 if (len < 1) {
8216 if (!use_json)
8217 vty_out(vty, "\n%*s", 34, " ");
8218 } else {
8219 if (use_json)
8220 json_object_int_add(json, "peerHost", len);
8221 else
8222 vty_out(vty, "%*s", len, " ");
8223 }
8224
8225 if (use_json)
8226 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
8227 safi, use_json, json);
8228 else
8229 vty_out(vty, "%s ",
8230 bgp_damp_reuse_time_vty(vty, path, timebuf,
8231 BGP_UPTIME_LEN, afi, safi,
8232 use_json, json));
8233
8234 /* Print attribute */
8235 attr = path->attr;
8236
8237 /* Print aspath */
8238 if (attr->aspath) {
8239 if (use_json)
8240 json_object_string_add(json, "asPath",
8241 attr->aspath->str);
8242 else
8243 aspath_print_vty(vty, "%s", attr->aspath, " ");
8244 }
8245
8246 /* Print origin */
8247 if (use_json)
8248 json_object_string_add(json, "origin",
8249 bgp_origin_str[attr->origin]);
8250 else
8251 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8252
8253 if (!use_json)
8254 vty_out(vty, "\n");
8255 }
8256
8257 /* flap route */
8258 static void flap_route_vty_out(struct vty *vty, struct prefix *p,
8259 struct bgp_path_info *path, int display, afi_t afi,
8260 safi_t safi, bool use_json, json_object *json)
8261 {
8262 struct attr *attr;
8263 struct bgp_damp_info *bdi;
8264 char timebuf[BGP_UPTIME_LEN];
8265 int len;
8266
8267 if (!path->extra)
8268 return;
8269
8270 bdi = path->extra->damp_info;
8271
8272 /* short status lead text */
8273 route_vty_short_status_out(vty, path, json);
8274
8275 /* print prefix and mask */
8276 if (!use_json) {
8277 if (!display)
8278 route_vty_out_route(p, vty, NULL);
8279 else
8280 vty_out(vty, "%*s", 17, " ");
8281 }
8282
8283 len = vty_out(vty, "%s", path->peer->host);
8284 len = 16 - len;
8285 if (len < 1) {
8286 if (!use_json)
8287 vty_out(vty, "\n%*s", 33, " ");
8288 } else {
8289 if (use_json)
8290 json_object_int_add(json, "peerHost", len);
8291 else
8292 vty_out(vty, "%*s", len, " ");
8293 }
8294
8295 len = vty_out(vty, "%d", bdi->flap);
8296 len = 5 - len;
8297 if (len < 1) {
8298 if (!use_json)
8299 vty_out(vty, " ");
8300 } else {
8301 if (use_json)
8302 json_object_int_add(json, "bdiFlap", len);
8303 else
8304 vty_out(vty, "%*s", len, " ");
8305 }
8306
8307 if (use_json)
8308 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
8309 json);
8310 else
8311 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
8312 BGP_UPTIME_LEN, 0, NULL));
8313
8314 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
8315 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8316 if (use_json)
8317 bgp_damp_reuse_time_vty(vty, path, timebuf,
8318 BGP_UPTIME_LEN, afi, safi,
8319 use_json, json);
8320 else
8321 vty_out(vty, "%s ",
8322 bgp_damp_reuse_time_vty(vty, path, timebuf,
8323 BGP_UPTIME_LEN, afi,
8324 safi, use_json, json));
8325 } else {
8326 if (!use_json)
8327 vty_out(vty, "%*s ", 8, " ");
8328 }
8329
8330 /* Print attribute */
8331 attr = path->attr;
8332
8333 /* Print aspath */
8334 if (attr->aspath) {
8335 if (use_json)
8336 json_object_string_add(json, "asPath",
8337 attr->aspath->str);
8338 else
8339 aspath_print_vty(vty, "%s", attr->aspath, " ");
8340 }
8341
8342 /* Print origin */
8343 if (use_json)
8344 json_object_string_add(json, "origin",
8345 bgp_origin_str[attr->origin]);
8346 else
8347 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8348
8349 if (!use_json)
8350 vty_out(vty, "\n");
8351 }
8352
8353 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
8354 int *first, const char *header,
8355 json_object *json_adv_to)
8356 {
8357 char buf1[INET6_ADDRSTRLEN];
8358 json_object *json_peer = NULL;
8359
8360 if (json_adv_to) {
8361 /* 'advertised-to' is a dictionary of peers we have advertised
8362 * this
8363 * prefix too. The key is the peer's IP or swpX, the value is
8364 * the
8365 * hostname if we know it and "" if not.
8366 */
8367 json_peer = json_object_new_object();
8368
8369 if (peer->hostname)
8370 json_object_string_add(json_peer, "hostname",
8371 peer->hostname);
8372
8373 if (peer->conf_if)
8374 json_object_object_add(json_adv_to, peer->conf_if,
8375 json_peer);
8376 else
8377 json_object_object_add(
8378 json_adv_to,
8379 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
8380 json_peer);
8381 } else {
8382 if (*first) {
8383 vty_out(vty, "%s", header);
8384 *first = 0;
8385 }
8386
8387 if (peer->hostname
8388 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
8389 if (peer->conf_if)
8390 vty_out(vty, " %s(%s)", peer->hostname,
8391 peer->conf_if);
8392 else
8393 vty_out(vty, " %s(%s)", peer->hostname,
8394 sockunion2str(&peer->su, buf1,
8395 SU_ADDRSTRLEN));
8396 } else {
8397 if (peer->conf_if)
8398 vty_out(vty, " %s", peer->conf_if);
8399 else
8400 vty_out(vty, " %s",
8401 sockunion2str(&peer->su, buf1,
8402 SU_ADDRSTRLEN));
8403 }
8404 }
8405 }
8406
8407 static void route_vty_out_tx_ids(struct vty *vty,
8408 struct bgp_addpath_info_data *d)
8409 {
8410 int i;
8411
8412 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
8413 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
8414 d->addpath_tx_id[i],
8415 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
8416 }
8417 }
8418
8419 static const char *bgp_path_selection_reason2str(
8420 enum bgp_path_selection_reason reason)
8421 {
8422 switch (reason) {
8423 case bgp_path_selection_none:
8424 return "Nothing to Select";
8425 break;
8426 case bgp_path_selection_first:
8427 return "First path received";
8428 break;
8429 case bgp_path_selection_evpn_sticky_mac:
8430 return "EVPN Sticky Mac";
8431 break;
8432 case bgp_path_selection_evpn_seq:
8433 return "EVPN sequence number";
8434 break;
8435 case bgp_path_selection_evpn_lower_ip:
8436 return "EVPN lower IP";
8437 break;
8438 case bgp_path_selection_weight:
8439 return "Weight";
8440 break;
8441 case bgp_path_selection_local_pref:
8442 return "Local Pref";
8443 break;
8444 case bgp_path_selection_local_route:
8445 return "Local Route";
8446 break;
8447 case bgp_path_selection_confed_as_path:
8448 return "Confederation based AS Path";
8449 break;
8450 case bgp_path_selection_as_path:
8451 return "AS Path";
8452 break;
8453 case bgp_path_selection_origin:
8454 return "Origin";
8455 break;
8456 case bgp_path_selection_med:
8457 return "MED";
8458 break;
8459 case bgp_path_selection_peer:
8460 return "Peer Type";
8461 break;
8462 case bgp_path_selection_confed:
8463 return "Confed Peer Type";
8464 break;
8465 case bgp_path_selection_igp_metric:
8466 return "IGP Metric";
8467 break;
8468 case bgp_path_selection_older:
8469 return "Older Path";
8470 break;
8471 case bgp_path_selection_router_id:
8472 return "Router ID";
8473 break;
8474 case bgp_path_selection_cluster_length:
8475 return "Cluser length";
8476 break;
8477 case bgp_path_selection_stale:
8478 return "Path Staleness";
8479 break;
8480 case bgp_path_selection_local_configured:
8481 return "Locally configured route";
8482 break;
8483 case bgp_path_selection_neighbor_ip:
8484 return "Neighbor IP";
8485 break;
8486 case bgp_path_selection_default:
8487 return "Nothing left to compare";
8488 break;
8489 }
8490 return "Invalid (internal error)";
8491 }
8492
8493 void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
8494 struct bgp_node *bn, struct bgp_path_info *path,
8495 afi_t afi, safi_t safi, json_object *json_paths)
8496 {
8497 char buf[INET6_ADDRSTRLEN];
8498 char buf1[BUFSIZ];
8499 char buf2[EVPN_ROUTE_STRLEN];
8500 struct attr *attr = path->attr;
8501 int sockunion_vty_out(struct vty *, union sockunion *);
8502 time_t tbuf;
8503 json_object *json_bestpath = NULL;
8504 json_object *json_cluster_list = NULL;
8505 json_object *json_cluster_list_list = NULL;
8506 json_object *json_ext_community = NULL;
8507 json_object *json_last_update = NULL;
8508 json_object *json_pmsi = NULL;
8509 json_object *json_nexthop_global = NULL;
8510 json_object *json_nexthop_ll = NULL;
8511 json_object *json_nexthops = NULL;
8512 json_object *json_path = NULL;
8513 json_object *json_peer = NULL;
8514 json_object *json_string = NULL;
8515 json_object *json_adv_to = NULL;
8516 int first = 0;
8517 struct listnode *node, *nnode;
8518 struct peer *peer;
8519 int addpath_capable;
8520 int has_adj;
8521 unsigned int first_as;
8522 bool nexthop_self =
8523 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8524 int i;
8525 char *nexthop_hostname = bgp_nexthop_hostname(path->peer, attr);
8526
8527 if (json_paths) {
8528 json_path = json_object_new_object();
8529 json_peer = json_object_new_object();
8530 json_nexthop_global = json_object_new_object();
8531 }
8532
8533 if (path->extra) {
8534 char tag_buf[30];
8535
8536 buf2[0] = '\0';
8537 tag_buf[0] = '\0';
8538 if (path->extra && path->extra->num_labels) {
8539 bgp_evpn_label2str(path->extra->label,
8540 path->extra->num_labels, tag_buf,
8541 sizeof(tag_buf));
8542 }
8543 if (safi == SAFI_EVPN) {
8544 if (!json_paths) {
8545 bgp_evpn_route2str((struct prefix_evpn *)&bn->p,
8546 buf2, sizeof(buf2));
8547 vty_out(vty, " Route %s", buf2);
8548 if (tag_buf[0] != '\0')
8549 vty_out(vty, " VNI %s", tag_buf);
8550 vty_out(vty, "\n");
8551 } else {
8552 if (tag_buf[0])
8553 json_object_string_add(json_path, "VNI",
8554 tag_buf);
8555 }
8556 }
8557
8558 if (path->extra && path->extra->parent && !json_paths) {
8559 struct bgp_path_info *parent_ri;
8560 struct bgp_node *rn, *prn;
8561
8562 parent_ri = (struct bgp_path_info *)path->extra->parent;
8563 rn = parent_ri->net;
8564 if (rn && rn->prn) {
8565 prn = rn->prn;
8566 prefix_rd2str((struct prefix_rd *)&prn->p,
8567 buf1, sizeof(buf1));
8568 if (is_pi_family_evpn(parent_ri)) {
8569 bgp_evpn_route2str((struct prefix_evpn *)&rn->p,
8570 buf2, sizeof(buf2));
8571 vty_out(vty, " Imported from %s:%s, VNI %s\n", buf1, buf2, tag_buf);
8572 } else
8573 vty_out(vty, " Imported from %s:%s\n", buf1, buf2);
8574 }
8575 }
8576 }
8577
8578 /* Line1 display AS-path, Aggregator */
8579 if (attr->aspath) {
8580 if (json_paths) {
8581 if (!attr->aspath->json)
8582 aspath_str_update(attr->aspath, true);
8583 json_object_lock(attr->aspath->json);
8584 json_object_object_add(json_path, "aspath",
8585 attr->aspath->json);
8586 } else {
8587 if (attr->aspath->segments)
8588 aspath_print_vty(vty, " %s", attr->aspath, "");
8589 else
8590 vty_out(vty, " Local");
8591 }
8592 }
8593
8594 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
8595 if (json_paths)
8596 json_object_boolean_true_add(json_path, "removed");
8597 else
8598 vty_out(vty, ", (removed)");
8599 }
8600
8601 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
8602 if (json_paths)
8603 json_object_boolean_true_add(json_path, "stale");
8604 else
8605 vty_out(vty, ", (stale)");
8606 }
8607
8608 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
8609 if (json_paths) {
8610 json_object_int_add(json_path, "aggregatorAs",
8611 attr->aggregator_as);
8612 json_object_string_add(
8613 json_path, "aggregatorId",
8614 inet_ntoa(attr->aggregator_addr));
8615 } else {
8616 vty_out(vty, ", (aggregated by %u %s)",
8617 attr->aggregator_as,
8618 inet_ntoa(attr->aggregator_addr));
8619 }
8620 }
8621
8622 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
8623 PEER_FLAG_REFLECTOR_CLIENT)) {
8624 if (json_paths)
8625 json_object_boolean_true_add(json_path,
8626 "rxedFromRrClient");
8627 else
8628 vty_out(vty, ", (Received from a RR-client)");
8629 }
8630
8631 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
8632 PEER_FLAG_RSERVER_CLIENT)) {
8633 if (json_paths)
8634 json_object_boolean_true_add(json_path,
8635 "rxedFromRsClient");
8636 else
8637 vty_out(vty, ", (Received from a RS-client)");
8638 }
8639
8640 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8641 if (json_paths)
8642 json_object_boolean_true_add(json_path,
8643 "dampeningHistoryEntry");
8644 else
8645 vty_out(vty, ", (history entry)");
8646 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
8647 if (json_paths)
8648 json_object_boolean_true_add(json_path,
8649 "dampeningSuppressed");
8650 else
8651 vty_out(vty, ", (suppressed due to dampening)");
8652 }
8653
8654 if (!json_paths)
8655 vty_out(vty, "\n");
8656
8657 /* Line2 display Next-hop, Neighbor, Router-id */
8658 /* Display the nexthop */
8659 if ((bn->p.family == AF_INET || bn->p.family == AF_ETHERNET
8660 || bn->p.family == AF_EVPN)
8661 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
8662 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8663 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8664 || safi == SAFI_EVPN) {
8665 if (json_paths) {
8666 json_object_string_add(
8667 json_nexthop_global, "ip",
8668 inet_ntoa(attr->mp_nexthop_global_in));
8669
8670 if (nexthop_hostname)
8671 json_object_string_add(
8672 json_nexthop_global, "hostname",
8673 nexthop_hostname);
8674 } else
8675 vty_out(vty, " %s",
8676 nexthop_hostname
8677 ? nexthop_hostname
8678 : inet_ntoa(
8679 attr->mp_nexthop_global_in));
8680 } else {
8681 if (json_paths) {
8682 json_object_string_add(
8683 json_nexthop_global, "ip",
8684 inet_ntoa(attr->nexthop));
8685
8686 if (nexthop_hostname)
8687 json_object_string_add(
8688 json_nexthop_global, "hostname",
8689 nexthop_hostname);
8690 } else
8691 vty_out(vty, " %s",
8692 nexthop_hostname
8693 ? nexthop_hostname
8694 : inet_ntoa(attr->nexthop));
8695 }
8696
8697 if (json_paths)
8698 json_object_string_add(json_nexthop_global, "afi",
8699 "ipv4");
8700 } else {
8701 if (json_paths) {
8702 json_object_string_add(
8703 json_nexthop_global, "ip",
8704 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
8705 buf, INET6_ADDRSTRLEN));
8706
8707 if (nexthop_hostname)
8708 json_object_string_add(json_nexthop_global,
8709 "hostname",
8710 nexthop_hostname);
8711
8712 json_object_string_add(json_nexthop_global, "afi",
8713 "ipv6");
8714 json_object_string_add(json_nexthop_global, "scope",
8715 "global");
8716 } else {
8717 vty_out(vty, " %s",
8718 nexthop_hostname
8719 ? nexthop_hostname
8720 : inet_ntop(AF_INET6,
8721 &attr->mp_nexthop_global,
8722 buf, INET6_ADDRSTRLEN));
8723 }
8724 }
8725
8726 /* Display the IGP cost or 'inaccessible' */
8727 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
8728 if (json_paths)
8729 json_object_boolean_false_add(json_nexthop_global,
8730 "accessible");
8731 else
8732 vty_out(vty, " (inaccessible)");
8733 } else {
8734 if (path->extra && path->extra->igpmetric) {
8735 if (json_paths)
8736 json_object_int_add(json_nexthop_global,
8737 "metric",
8738 path->extra->igpmetric);
8739 else
8740 vty_out(vty, " (metric %u)",
8741 path->extra->igpmetric);
8742 }
8743
8744 /* IGP cost is 0, display this only for json */
8745 else {
8746 if (json_paths)
8747 json_object_int_add(json_nexthop_global,
8748 "metric", 0);
8749 }
8750
8751 if (json_paths)
8752 json_object_boolean_true_add(json_nexthop_global,
8753 "accessible");
8754 }
8755
8756 /* Display peer "from" output */
8757 /* This path was originated locally */
8758 if (path->peer == bgp->peer_self) {
8759
8760 if (safi == SAFI_EVPN
8761 || (bn->p.family == AF_INET
8762 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8763 if (json_paths)
8764 json_object_string_add(json_peer, "peerId",
8765 "0.0.0.0");
8766 else
8767 vty_out(vty, " from 0.0.0.0 ");
8768 } else {
8769 if (json_paths)
8770 json_object_string_add(json_peer, "peerId",
8771 "::");
8772 else
8773 vty_out(vty, " from :: ");
8774 }
8775
8776 if (json_paths)
8777 json_object_string_add(json_peer, "routerId",
8778 inet_ntoa(bgp->router_id));
8779 else
8780 vty_out(vty, "(%s)", inet_ntoa(bgp->router_id));
8781 }
8782
8783 /* We RXed this path from one of our peers */
8784 else {
8785
8786 if (json_paths) {
8787 json_object_string_add(json_peer, "peerId",
8788 sockunion2str(&path->peer->su,
8789 buf,
8790 SU_ADDRSTRLEN));
8791 json_object_string_add(json_peer, "routerId",
8792 inet_ntop(AF_INET,
8793 &path->peer->remote_id,
8794 buf1, sizeof(buf1)));
8795
8796 if (path->peer->hostname)
8797 json_object_string_add(json_peer, "hostname",
8798 path->peer->hostname);
8799
8800 if (path->peer->domainname)
8801 json_object_string_add(json_peer, "domainname",
8802 path->peer->domainname);
8803
8804 if (path->peer->conf_if)
8805 json_object_string_add(json_peer, "interface",
8806 path->peer->conf_if);
8807 } else {
8808 if (path->peer->conf_if) {
8809 if (path->peer->hostname
8810 && bgp_flag_check(path->peer->bgp,
8811 BGP_FLAG_SHOW_HOSTNAME))
8812 vty_out(vty, " from %s(%s)",
8813 path->peer->hostname,
8814 path->peer->conf_if);
8815 else
8816 vty_out(vty, " from %s",
8817 path->peer->conf_if);
8818 } else {
8819 if (path->peer->hostname
8820 && bgp_flag_check(path->peer->bgp,
8821 BGP_FLAG_SHOW_HOSTNAME))
8822 vty_out(vty, " from %s(%s)",
8823 path->peer->hostname,
8824 path->peer->host);
8825 else
8826 vty_out(vty, " from %s",
8827 sockunion2str(&path->peer->su,
8828 buf,
8829 SU_ADDRSTRLEN));
8830 }
8831
8832 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
8833 vty_out(vty, " (%s)",
8834 inet_ntoa(attr->originator_id));
8835 else
8836 vty_out(vty, " (%s)",
8837 inet_ntop(AF_INET,
8838 &path->peer->remote_id, buf1,
8839 sizeof(buf1)));
8840 }
8841 }
8842
8843 /*
8844 * Note when vrfid of nexthop is different from that of prefix
8845 */
8846 if (path->extra && path->extra->bgp_orig) {
8847 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
8848
8849 if (json_paths) {
8850 const char *vn;
8851
8852 if (path->extra->bgp_orig->inst_type
8853 == BGP_INSTANCE_TYPE_DEFAULT)
8854 vn = VRF_DEFAULT_NAME;
8855 else
8856 vn = path->extra->bgp_orig->name;
8857
8858 json_object_string_add(json_path, "nhVrfName", vn);
8859
8860 if (nexthop_vrfid == VRF_UNKNOWN) {
8861 json_object_int_add(json_path, "nhVrfId", -1);
8862 } else {
8863 json_object_int_add(json_path, "nhVrfId",
8864 (int)nexthop_vrfid);
8865 }
8866 } else {
8867 if (nexthop_vrfid == VRF_UNKNOWN)
8868 vty_out(vty, " vrf ?");
8869 else
8870 vty_out(vty, " vrf %u", nexthop_vrfid);
8871 }
8872 }
8873
8874 if (nexthop_self) {
8875 if (json_paths) {
8876 json_object_boolean_true_add(json_path,
8877 "announceNexthopSelf");
8878 } else {
8879 vty_out(vty, " announce-nh-self");
8880 }
8881 }
8882
8883 if (!json_paths)
8884 vty_out(vty, "\n");
8885
8886 /* display the link-local nexthop */
8887 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
8888 if (json_paths) {
8889 json_nexthop_ll = json_object_new_object();
8890 json_object_string_add(
8891 json_nexthop_ll, "ip",
8892 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
8893 buf, INET6_ADDRSTRLEN));
8894
8895 if (nexthop_hostname)
8896 json_object_string_add(json_nexthop_ll,
8897 "hostname",
8898 nexthop_hostname);
8899
8900 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
8901 json_object_string_add(json_nexthop_ll, "scope",
8902 "link-local");
8903
8904 json_object_boolean_true_add(json_nexthop_ll,
8905 "accessible");
8906
8907 if (!attr->mp_nexthop_prefer_global)
8908 json_object_boolean_true_add(json_nexthop_ll,
8909 "used");
8910 else
8911 json_object_boolean_true_add(
8912 json_nexthop_global, "used");
8913 } else {
8914 vty_out(vty, " (%s) %s\n",
8915 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
8916 buf, INET6_ADDRSTRLEN),
8917 attr->mp_nexthop_prefer_global
8918 ? "(prefer-global)"
8919 : "(used)");
8920 }
8921 }
8922 /* If we do not have a link-local nexthop then we must flag the
8923 global as "used" */
8924 else {
8925 if (json_paths)
8926 json_object_boolean_true_add(json_nexthop_global,
8927 "used");
8928 }
8929
8930 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
8931 * Int/Ext/Local, Atomic, best */
8932 if (json_paths)
8933 json_object_string_add(json_path, "origin",
8934 bgp_origin_long_str[attr->origin]);
8935 else
8936 vty_out(vty, " Origin %s",
8937 bgp_origin_long_str[attr->origin]);
8938
8939 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
8940 if (json_paths) {
8941 /*
8942 * Adding "metric" field to match with
8943 * corresponding CLI. "med" will be
8944 * deprecated in future.
8945 */
8946 json_object_int_add(json_path, "med", attr->med);
8947 json_object_int_add(json_path, "metric", attr->med);
8948 } else
8949 vty_out(vty, ", metric %u", attr->med);
8950 }
8951
8952 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
8953 if (json_paths)
8954 json_object_int_add(json_path, "localpref",
8955 attr->local_pref);
8956 else
8957 vty_out(vty, ", localpref %u", attr->local_pref);
8958 }
8959
8960 if (attr->weight != 0) {
8961 if (json_paths)
8962 json_object_int_add(json_path, "weight", attr->weight);
8963 else
8964 vty_out(vty, ", weight %u", attr->weight);
8965 }
8966
8967 if (attr->tag != 0) {
8968 if (json_paths)
8969 json_object_int_add(json_path, "tag", attr->tag);
8970 else
8971 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
8972 }
8973
8974 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
8975 if (json_paths)
8976 json_object_boolean_false_add(json_path, "valid");
8977 else
8978 vty_out(vty, ", invalid");
8979 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8980 if (json_paths)
8981 json_object_boolean_true_add(json_path, "valid");
8982 else
8983 vty_out(vty, ", valid");
8984 }
8985
8986 if (path->peer != bgp->peer_self) {
8987 if (path->peer->as == path->peer->local_as) {
8988 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
8989 if (json_paths)
8990 json_object_string_add(
8991 json_peer, "type",
8992 "confed-internal");
8993 else
8994 vty_out(vty, ", confed-internal");
8995 } else {
8996 if (json_paths)
8997 json_object_string_add(
8998 json_peer, "type", "internal");
8999 else
9000 vty_out(vty, ", internal");
9001 }
9002 } else {
9003 if (bgp_confederation_peers_check(bgp,
9004 path->peer->as)) {
9005 if (json_paths)
9006 json_object_string_add(
9007 json_peer, "type",
9008 "confed-external");
9009 else
9010 vty_out(vty, ", confed-external");
9011 } else {
9012 if (json_paths)
9013 json_object_string_add(
9014 json_peer, "type", "external");
9015 else
9016 vty_out(vty, ", external");
9017 }
9018 }
9019 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
9020 if (json_paths) {
9021 json_object_boolean_true_add(json_path, "aggregated");
9022 json_object_boolean_true_add(json_path, "local");
9023 } else {
9024 vty_out(vty, ", aggregated, local");
9025 }
9026 } else if (path->type != ZEBRA_ROUTE_BGP) {
9027 if (json_paths)
9028 json_object_boolean_true_add(json_path, "sourced");
9029 else
9030 vty_out(vty, ", sourced");
9031 } else {
9032 if (json_paths) {
9033 json_object_boolean_true_add(json_path, "sourced");
9034 json_object_boolean_true_add(json_path, "local");
9035 } else {
9036 vty_out(vty, ", sourced, local");
9037 }
9038 }
9039
9040 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
9041 if (json_paths)
9042 json_object_boolean_true_add(json_path,
9043 "atomicAggregate");
9044 else
9045 vty_out(vty, ", atomic-aggregate");
9046 }
9047
9048 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
9049 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
9050 && bgp_path_info_mpath_count(path))) {
9051 if (json_paths)
9052 json_object_boolean_true_add(json_path, "multipath");
9053 else
9054 vty_out(vty, ", multipath");
9055 }
9056
9057 // Mark the bestpath(s)
9058 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
9059 first_as = aspath_get_first_as(attr->aspath);
9060
9061 if (json_paths) {
9062 if (!json_bestpath)
9063 json_bestpath = json_object_new_object();
9064 json_object_int_add(json_bestpath, "bestpathFromAs",
9065 first_as);
9066 } else {
9067 if (first_as)
9068 vty_out(vty, ", bestpath-from-AS %u", first_as);
9069 else
9070 vty_out(vty, ", bestpath-from-AS Local");
9071 }
9072 }
9073
9074 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9075 if (json_paths) {
9076 if (!json_bestpath)
9077 json_bestpath = json_object_new_object();
9078 json_object_boolean_true_add(json_bestpath, "overall");
9079 json_object_string_add(
9080 json_bestpath, "selectionReason",
9081 bgp_path_selection_reason2str(bn->reason));
9082 } else {
9083 vty_out(vty, ", best");
9084 vty_out(vty, " (%s)",
9085 bgp_path_selection_reason2str(bn->reason));
9086 }
9087 }
9088
9089 if (json_bestpath)
9090 json_object_object_add(json_path, "bestpath", json_bestpath);
9091
9092 if (!json_paths)
9093 vty_out(vty, "\n");
9094
9095 /* Line 4 display Community */
9096 if (attr->community) {
9097 if (json_paths) {
9098 if (!attr->community->json)
9099 community_str(attr->community, true);
9100 json_object_lock(attr->community->json);
9101 json_object_object_add(json_path, "community",
9102 attr->community->json);
9103 } else {
9104 vty_out(vty, " Community: %s\n",
9105 attr->community->str);
9106 }
9107 }
9108
9109 /* Line 5 display Extended-community */
9110 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9111 if (json_paths) {
9112 json_ext_community = json_object_new_object();
9113 json_object_string_add(json_ext_community, "string",
9114 attr->ecommunity->str);
9115 json_object_object_add(json_path, "extendedCommunity",
9116 json_ext_community);
9117 } else {
9118 vty_out(vty, " Extended Community: %s\n",
9119 attr->ecommunity->str);
9120 }
9121 }
9122
9123 /* Line 6 display Large community */
9124 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
9125 if (json_paths) {
9126 if (!attr->lcommunity->json)
9127 lcommunity_str(attr->lcommunity, true);
9128 json_object_lock(attr->lcommunity->json);
9129 json_object_object_add(json_path, "largeCommunity",
9130 attr->lcommunity->json);
9131 } else {
9132 vty_out(vty, " Large Community: %s\n",
9133 attr->lcommunity->str);
9134 }
9135 }
9136
9137 /* Line 7 display Originator, Cluster-id */
9138 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
9139 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
9140 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
9141 if (json_paths)
9142 json_object_string_add(
9143 json_path, "originatorId",
9144 inet_ntoa(attr->originator_id));
9145 else
9146 vty_out(vty, " Originator: %s",
9147 inet_ntoa(attr->originator_id));
9148 }
9149
9150 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
9151 int i;
9152
9153 if (json_paths) {
9154 json_cluster_list = json_object_new_object();
9155 json_cluster_list_list =
9156 json_object_new_array();
9157
9158 for (i = 0; i < attr->cluster->length / 4;
9159 i++) {
9160 json_string = json_object_new_string(
9161 inet_ntoa(attr->cluster
9162 ->list[i]));
9163 json_object_array_add(
9164 json_cluster_list_list,
9165 json_string);
9166 }
9167
9168 /*
9169 * struct cluster_list does not have
9170 * "str" variable like aspath and community
9171 * do. Add this someday if someone asks
9172 * for it.
9173 * json_object_string_add(json_cluster_list,
9174 * "string", attr->cluster->str);
9175 */
9176 json_object_object_add(json_cluster_list,
9177 "list",
9178 json_cluster_list_list);
9179 json_object_object_add(json_path, "clusterList",
9180 json_cluster_list);
9181 } else {
9182 vty_out(vty, ", Cluster list: ");
9183
9184 for (i = 0; i < attr->cluster->length / 4;
9185 i++) {
9186 vty_out(vty, "%s ",
9187 inet_ntoa(attr->cluster
9188 ->list[i]));
9189 }
9190 }
9191 }
9192
9193 if (!json_paths)
9194 vty_out(vty, "\n");
9195 }
9196
9197 if (path->extra && path->extra->damp_info)
9198 bgp_damp_info_vty(vty, path, afi, safi, json_path);
9199
9200 /* Remote Label */
9201 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
9202 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
9203 mpls_label_t label = label_pton(&path->extra->label[0]);
9204
9205 if (json_paths)
9206 json_object_int_add(json_path, "remoteLabel", label);
9207 else
9208 vty_out(vty, " Remote label: %d\n", label);
9209 }
9210
9211 /* Label Index */
9212 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
9213 if (json_paths)
9214 json_object_int_add(json_path, "labelIndex",
9215 attr->label_index);
9216 else
9217 vty_out(vty, " Label Index: %d\n",
9218 attr->label_index);
9219 }
9220
9221 /* Line 8 display Addpath IDs */
9222 if (path->addpath_rx_id
9223 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
9224 if (json_paths) {
9225 json_object_int_add(json_path, "addpathRxId",
9226 path->addpath_rx_id);
9227
9228 /* Keep backwards compatibility with the old API
9229 * by putting TX All's ID in the old field
9230 */
9231 json_object_int_add(
9232 json_path, "addpathTxId",
9233 path->tx_addpath
9234 .addpath_tx_id[BGP_ADDPATH_ALL]);
9235
9236 /* ... but create a specific field for each
9237 * strategy
9238 */
9239 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9240 json_object_int_add(
9241 json_path,
9242 bgp_addpath_names(i)->id_json_name,
9243 path->tx_addpath.addpath_tx_id[i]);
9244 }
9245 } else {
9246 vty_out(vty, " AddPath ID: RX %u, ",
9247 path->addpath_rx_id);
9248
9249 route_vty_out_tx_ids(vty, &path->tx_addpath);
9250 }
9251 }
9252
9253 /* If we used addpath to TX a non-bestpath we need to display
9254 * "Advertised to" on a path-by-path basis
9255 */
9256 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
9257 first = 1;
9258
9259 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
9260 addpath_capable =
9261 bgp_addpath_encode_tx(peer, afi, safi);
9262 has_adj = bgp_adj_out_lookup(
9263 peer, path->net,
9264 bgp_addpath_id_for_peer(peer, afi, safi,
9265 &path->tx_addpath));
9266
9267 if ((addpath_capable && has_adj)
9268 || (!addpath_capable && has_adj
9269 && CHECK_FLAG(path->flags,
9270 BGP_PATH_SELECTED))) {
9271 if (json_path && !json_adv_to)
9272 json_adv_to = json_object_new_object();
9273
9274 route_vty_out_advertised_to(
9275 vty, peer, &first,
9276 " Advertised to:", json_adv_to);
9277 }
9278 }
9279
9280 if (json_path) {
9281 if (json_adv_to) {
9282 json_object_object_add(
9283 json_path, "advertisedTo", json_adv_to);
9284 }
9285 } else {
9286 if (!first) {
9287 vty_out(vty, "\n");
9288 }
9289 }
9290 }
9291
9292 /* Line 9 display Uptime */
9293 tbuf = time(NULL) - (bgp_clock() - path->uptime);
9294 if (json_paths) {
9295 json_last_update = json_object_new_object();
9296 json_object_int_add(json_last_update, "epoch", tbuf);
9297 json_object_string_add(json_last_update, "string",
9298 ctime(&tbuf));
9299 json_object_object_add(json_path, "lastUpdate",
9300 json_last_update);
9301 } else
9302 vty_out(vty, " Last update: %s", ctime(&tbuf));
9303
9304 /* Line 10 display PMSI tunnel attribute, if present */
9305 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
9306 const char *str =
9307 lookup_msg(bgp_pmsi_tnltype_str, attr->pmsi_tnl_type,
9308 PMSI_TNLTYPE_STR_DEFAULT);
9309
9310 if (json_paths) {
9311 json_pmsi = json_object_new_object();
9312 json_object_string_add(json_pmsi, "tunnelType", str);
9313 json_object_int_add(json_pmsi, "label",
9314 label2vni(&attr->label));
9315 json_object_object_add(json_path, "pmsi", json_pmsi);
9316 } else
9317 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
9318 str, label2vni(&attr->label));
9319 }
9320
9321 /* We've constructed the json object for this path, add it to the json
9322 * array of paths
9323 */
9324 if (json_paths) {
9325 if (json_nexthop_global || json_nexthop_ll) {
9326 json_nexthops = json_object_new_array();
9327
9328 if (json_nexthop_global)
9329 json_object_array_add(json_nexthops,
9330 json_nexthop_global);
9331
9332 if (json_nexthop_ll)
9333 json_object_array_add(json_nexthops,
9334 json_nexthop_ll);
9335
9336 json_object_object_add(json_path, "nexthops",
9337 json_nexthops);
9338 }
9339
9340 json_object_object_add(json_path, "peer", json_peer);
9341 json_object_array_add(json_paths, json_path);
9342 }
9343 }
9344
9345 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
9346 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
9347 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
9348
9349 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
9350 const char *prefix_list_str, afi_t afi,
9351 safi_t safi, enum bgp_show_type type);
9352 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
9353 const char *filter, afi_t afi, safi_t safi,
9354 enum bgp_show_type type);
9355 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
9356 const char *rmap_str, afi_t afi, safi_t safi,
9357 enum bgp_show_type type);
9358 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
9359 const char *com, int exact, afi_t afi,
9360 safi_t safi);
9361 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
9362 const char *prefix, afi_t afi, safi_t safi,
9363 enum bgp_show_type type);
9364 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
9365 afi_t afi, safi_t safi, enum bgp_show_type type,
9366 bool use_json);
9367 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
9368 const char *comstr, int exact, afi_t afi,
9369 safi_t safi, bool use_json);
9370
9371
9372 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
9373 struct bgp_table *table, enum bgp_show_type type,
9374 void *output_arg, bool use_json, char *rd,
9375 int is_last, unsigned long *output_cum,
9376 unsigned long *total_cum,
9377 unsigned long *json_header_depth)
9378 {
9379 struct bgp_path_info *pi;
9380 struct bgp_node *rn;
9381 int header = 1;
9382 int display;
9383 unsigned long output_count = 0;
9384 unsigned long total_count = 0;
9385 struct prefix *p;
9386 char buf2[BUFSIZ];
9387 json_object *json_paths = NULL;
9388 int first = 1;
9389
9390 if (output_cum && *output_cum != 0)
9391 header = 0;
9392
9393 if (use_json && !*json_header_depth) {
9394 vty_out(vty,
9395 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
9396 ",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n"
9397 " \"localAS\": %u,\n \"routes\": { ",
9398 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
9399 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
9400 ? VRF_DEFAULT_NAME
9401 : bgp->name,
9402 table->version, inet_ntoa(bgp->router_id),
9403 bgp->default_local_pref, bgp->as);
9404 *json_header_depth = 2;
9405 if (rd) {
9406 vty_out(vty, " \"routeDistinguishers\" : {");
9407 ++*json_header_depth;
9408 }
9409 }
9410
9411 if (use_json && rd) {
9412 vty_out(vty, " \"%s\" : { ", rd);
9413 }
9414
9415 /* Start processing of routes. */
9416 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
9417 pi = bgp_node_get_bgp_path_info(rn);
9418 if (pi == NULL)
9419 continue;
9420
9421 display = 0;
9422 if (use_json)
9423 json_paths = json_object_new_array();
9424 else
9425 json_paths = NULL;
9426
9427 for (; pi; pi = pi->next) {
9428 total_count++;
9429 if (type == bgp_show_type_flap_statistics
9430 || type == bgp_show_type_flap_neighbor
9431 || type == bgp_show_type_dampend_paths
9432 || type == bgp_show_type_damp_neighbor) {
9433 if (!(pi->extra && pi->extra->damp_info))
9434 continue;
9435 }
9436 if (type == bgp_show_type_regexp) {
9437 regex_t *regex = output_arg;
9438
9439 if (bgp_regexec(regex, pi->attr->aspath)
9440 == REG_NOMATCH)
9441 continue;
9442 }
9443 if (type == bgp_show_type_prefix_list) {
9444 struct prefix_list *plist = output_arg;
9445
9446 if (prefix_list_apply(plist, &rn->p)
9447 != PREFIX_PERMIT)
9448 continue;
9449 }
9450 if (type == bgp_show_type_filter_list) {
9451 struct as_list *as_list = output_arg;
9452
9453 if (as_list_apply(as_list, pi->attr->aspath)
9454 != AS_FILTER_PERMIT)
9455 continue;
9456 }
9457 if (type == bgp_show_type_route_map) {
9458 struct route_map *rmap = output_arg;
9459 struct bgp_path_info path;
9460 struct attr dummy_attr;
9461 route_map_result_t ret;
9462
9463 dummy_attr = *pi->attr;
9464
9465 path.peer = pi->peer;
9466 path.attr = &dummy_attr;
9467
9468 ret = route_map_apply(rmap, &rn->p, RMAP_BGP,
9469 &path);
9470 if (ret == RMAP_DENYMATCH)
9471 continue;
9472 }
9473 if (type == bgp_show_type_neighbor
9474 || type == bgp_show_type_flap_neighbor
9475 || type == bgp_show_type_damp_neighbor) {
9476 union sockunion *su = output_arg;
9477
9478 if (pi->peer == NULL
9479 || pi->peer->su_remote == NULL
9480 || !sockunion_same(pi->peer->su_remote, su))
9481 continue;
9482 }
9483 if (type == bgp_show_type_cidr_only) {
9484 uint32_t destination;
9485
9486 destination = ntohl(rn->p.u.prefix4.s_addr);
9487 if (IN_CLASSC(destination)
9488 && rn->p.prefixlen == 24)
9489 continue;
9490 if (IN_CLASSB(destination)
9491 && rn->p.prefixlen == 16)
9492 continue;
9493 if (IN_CLASSA(destination)
9494 && rn->p.prefixlen == 8)
9495 continue;
9496 }
9497 if (type == bgp_show_type_prefix_longer) {
9498 p = output_arg;
9499 if (!prefix_match(p, &rn->p))
9500 continue;
9501 }
9502 if (type == bgp_show_type_community_all) {
9503 if (!pi->attr->community)
9504 continue;
9505 }
9506 if (type == bgp_show_type_community) {
9507 struct community *com = output_arg;
9508
9509 if (!pi->attr->community
9510 || !community_match(pi->attr->community,
9511 com))
9512 continue;
9513 }
9514 if (type == bgp_show_type_community_exact) {
9515 struct community *com = output_arg;
9516
9517 if (!pi->attr->community
9518 || !community_cmp(pi->attr->community, com))
9519 continue;
9520 }
9521 if (type == bgp_show_type_community_list) {
9522 struct community_list *list = output_arg;
9523
9524 if (!community_list_match(pi->attr->community,
9525 list))
9526 continue;
9527 }
9528 if (type == bgp_show_type_community_list_exact) {
9529 struct community_list *list = output_arg;
9530
9531 if (!community_list_exact_match(
9532 pi->attr->community, list))
9533 continue;
9534 }
9535 if (type == bgp_show_type_lcommunity) {
9536 struct lcommunity *lcom = output_arg;
9537
9538 if (!pi->attr->lcommunity
9539 || !lcommunity_match(pi->attr->lcommunity,
9540 lcom))
9541 continue;
9542 }
9543
9544 if (type == bgp_show_type_lcommunity_exact) {
9545 struct lcommunity *lcom = output_arg;
9546
9547 if (!pi->attr->lcommunity
9548 || !lcommunity_cmp(pi->attr->lcommunity,
9549 lcom))
9550 continue;
9551 }
9552 if (type == bgp_show_type_lcommunity_list) {
9553 struct community_list *list = output_arg;
9554
9555 if (!lcommunity_list_match(pi->attr->lcommunity,
9556 list))
9557 continue;
9558 }
9559 if (type
9560 == bgp_show_type_lcommunity_list_exact) {
9561 struct community_list *list = output_arg;
9562
9563 if (!lcommunity_list_exact_match(
9564 pi->attr->lcommunity, list))
9565 continue;
9566 }
9567 if (type == bgp_show_type_lcommunity_all) {
9568 if (!pi->attr->lcommunity)
9569 continue;
9570 }
9571 if (type == bgp_show_type_dampend_paths
9572 || type == bgp_show_type_damp_neighbor) {
9573 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
9574 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
9575 continue;
9576 }
9577
9578 if (!use_json && header) {
9579 vty_out(vty, "BGP table version is %" PRIu64
9580 ", local router ID is %s, vrf id ",
9581 table->version,
9582 inet_ntoa(bgp->router_id));
9583 if (bgp->vrf_id == VRF_UNKNOWN)
9584 vty_out(vty, "%s", VRFID_NONE_STR);
9585 else
9586 vty_out(vty, "%u", bgp->vrf_id);
9587 vty_out(vty, "\n");
9588 vty_out(vty, "Default local pref %u, ",
9589 bgp->default_local_pref);
9590 vty_out(vty, "local AS %u\n", bgp->as);
9591 vty_out(vty, BGP_SHOW_SCODE_HEADER);
9592 vty_out(vty, BGP_SHOW_NCODE_HEADER);
9593 vty_out(vty, BGP_SHOW_OCODE_HEADER);
9594 if (type == bgp_show_type_dampend_paths
9595 || type == bgp_show_type_damp_neighbor)
9596 vty_out(vty, BGP_SHOW_DAMP_HEADER);
9597 else if (type == bgp_show_type_flap_statistics
9598 || type == bgp_show_type_flap_neighbor)
9599 vty_out(vty, BGP_SHOW_FLAP_HEADER);
9600 else
9601 vty_out(vty, BGP_SHOW_HEADER);
9602 header = 0;
9603 }
9604 if (rd != NULL && !display && !output_count) {
9605 if (!use_json)
9606 vty_out(vty,
9607 "Route Distinguisher: %s\n",
9608 rd);
9609 }
9610 if (type == bgp_show_type_dampend_paths
9611 || type == bgp_show_type_damp_neighbor)
9612 damp_route_vty_out(vty, &rn->p, pi, display, AFI_IP,
9613 safi, use_json, json_paths);
9614 else if (type == bgp_show_type_flap_statistics
9615 || type == bgp_show_type_flap_neighbor)
9616 flap_route_vty_out(vty, &rn->p, pi, display, AFI_IP,
9617 safi, use_json, json_paths);
9618 else
9619 route_vty_out(vty, &rn->p, pi, display, safi,
9620 json_paths);
9621 display++;
9622 }
9623
9624 if (display) {
9625 output_count++;
9626 if (!use_json)
9627 continue;
9628
9629 p = &rn->p;
9630 /* encode prefix */
9631 if (p->family == AF_FLOWSPEC) {
9632 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
9633
9634 bgp_fs_nlri_get_string((unsigned char *)
9635 p->u.prefix_flowspec.ptr,
9636 p->u.prefix_flowspec
9637 .prefixlen,
9638 retstr,
9639 NLRI_STRING_FORMAT_MIN,
9640 NULL);
9641 if (first)
9642 vty_out(vty, "\"%s/%d\": ",
9643 retstr,
9644 p->u.prefix_flowspec.prefixlen);
9645 else
9646 vty_out(vty, ",\"%s/%d\": ",
9647 retstr,
9648 p->u.prefix_flowspec.prefixlen);
9649 } else {
9650 prefix2str(p, buf2, sizeof(buf2));
9651 if (first)
9652 vty_out(vty, "\"%s\": ", buf2);
9653 else
9654 vty_out(vty, ",\"%s\": ", buf2);
9655 }
9656 vty_out(vty, "%s",
9657 json_object_to_json_string_ext(
9658 json_paths, JSON_C_TO_STRING_PRETTY));
9659 json_object_free(json_paths);
9660 json_paths = NULL;
9661 first = 0;
9662 } else
9663 json_object_free(json_paths);
9664 }
9665
9666 if (output_cum) {
9667 output_count += *output_cum;
9668 *output_cum = output_count;
9669 }
9670 if (total_cum) {
9671 total_count += *total_cum;
9672 *total_cum = total_count;
9673 }
9674 if (use_json) {
9675 if (rd) {
9676 vty_out(vty, " }%s ", (is_last ? "" : ","));
9677 }
9678 if (is_last) {
9679 unsigned long i;
9680 for (i = 0; i < *json_header_depth; ++i)
9681 vty_out(vty, " } ");
9682 vty_out(vty, "\n");
9683 }
9684 } else {
9685 if (is_last) {
9686 /* No route is displayed */
9687 if (output_count == 0) {
9688 if (type == bgp_show_type_normal)
9689 vty_out(vty,
9690 "No BGP prefixes displayed, %ld exist\n",
9691 total_count);
9692 } else
9693 vty_out(vty,
9694 "\nDisplayed %ld routes and %ld total paths\n",
9695 output_count, total_count);
9696 }
9697 }
9698
9699 return CMD_SUCCESS;
9700 }
9701
9702 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
9703 struct bgp_table *table, struct prefix_rd *prd_match,
9704 enum bgp_show_type type, void *output_arg, bool use_json)
9705 {
9706 struct bgp_node *rn, *next;
9707 unsigned long output_cum = 0;
9708 unsigned long total_cum = 0;
9709 unsigned long json_header_depth = 0;
9710 struct bgp_table *itable;
9711 bool show_msg;
9712
9713 show_msg = (!use_json && type == bgp_show_type_normal);
9714
9715 for (rn = bgp_table_top(table); rn; rn = next) {
9716 next = bgp_route_next(rn);
9717 if (prd_match && memcmp(rn->p.u.val, prd_match->val, 8) != 0)
9718 continue;
9719
9720 itable = bgp_node_get_bgp_table_info(rn);
9721 if (itable != NULL) {
9722 struct prefix_rd prd;
9723 char rd[RD_ADDRSTRLEN];
9724
9725 memcpy(&prd, &(rn->p), sizeof(struct prefix_rd));
9726 prefix_rd2str(&prd, rd, sizeof(rd));
9727 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
9728 use_json, rd, next == NULL, &output_cum,
9729 &total_cum, &json_header_depth);
9730 if (next == NULL)
9731 show_msg = false;
9732 }
9733 }
9734 if (show_msg) {
9735 if (output_cum == 0)
9736 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
9737 total_cum);
9738 else
9739 vty_out(vty,
9740 "\nDisplayed %ld routes and %ld total paths\n",
9741 output_cum, total_cum);
9742 }
9743 return CMD_SUCCESS;
9744 }
9745 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
9746 enum bgp_show_type type, void *output_arg, bool use_json)
9747 {
9748 struct bgp_table *table;
9749 unsigned long json_header_depth = 0;
9750
9751 if (bgp == NULL) {
9752 bgp = bgp_get_default();
9753 }
9754
9755 if (bgp == NULL) {
9756 if (!use_json)
9757 vty_out(vty, "No BGP process is configured\n");
9758 else
9759 vty_out(vty, "{}\n");
9760 return CMD_WARNING;
9761 }
9762
9763 table = bgp->rib[afi][safi];
9764 /* use MPLS and ENCAP specific shows until they are merged */
9765 if (safi == SAFI_MPLS_VPN) {
9766 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
9767 output_arg, use_json);
9768 }
9769
9770 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
9771 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
9772 output_arg, use_json,
9773 1, NULL, NULL);
9774 }
9775 /* labeled-unicast routes live in the unicast table */
9776 else if (safi == SAFI_LABELED_UNICAST)
9777 safi = SAFI_UNICAST;
9778
9779 return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json,
9780 NULL, 1, NULL, NULL, &json_header_depth);
9781 }
9782
9783 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
9784 safi_t safi, bool use_json)
9785 {
9786 struct listnode *node, *nnode;
9787 struct bgp *bgp;
9788 int is_first = 1;
9789 bool route_output = false;
9790
9791 if (use_json)
9792 vty_out(vty, "{\n");
9793
9794 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
9795 route_output = true;
9796 if (use_json) {
9797 if (!is_first)
9798 vty_out(vty, ",\n");
9799 else
9800 is_first = 0;
9801
9802 vty_out(vty, "\"%s\":",
9803 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9804 ? VRF_DEFAULT_NAME
9805 : bgp->name);
9806 } else {
9807 vty_out(vty, "\nInstance %s:\n",
9808 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9809 ? VRF_DEFAULT_NAME
9810 : bgp->name);
9811 }
9812 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
9813 use_json);
9814 }
9815
9816 if (use_json)
9817 vty_out(vty, "}\n");
9818 else if (!route_output)
9819 vty_out(vty, "%% BGP instance not found\n");
9820 }
9821
9822 /* Header of detailed BGP route information */
9823 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
9824 struct bgp_node *rn, struct prefix_rd *prd,
9825 afi_t afi, safi_t safi, json_object *json)
9826 {
9827 struct bgp_path_info *pi;
9828 struct prefix *p;
9829 struct peer *peer;
9830 struct listnode *node, *nnode;
9831 char buf1[RD_ADDRSTRLEN];
9832 char buf2[INET6_ADDRSTRLEN];
9833 char buf3[EVPN_ROUTE_STRLEN];
9834 char prefix_str[BUFSIZ];
9835 int count = 0;
9836 int best = 0;
9837 int suppress = 0;
9838 int accept_own = 0;
9839 int route_filter_translated_v4 = 0;
9840 int route_filter_v4 = 0;
9841 int route_filter_translated_v6 = 0;
9842 int route_filter_v6 = 0;
9843 int llgr_stale = 0;
9844 int no_llgr = 0;
9845 int accept_own_nexthop = 0;
9846 int blackhole = 0;
9847 int no_export = 0;
9848 int no_advertise = 0;
9849 int local_as = 0;
9850 int no_peer = 0;
9851 int first = 1;
9852 int has_valid_label = 0;
9853 mpls_label_t label = 0;
9854 json_object *json_adv_to = NULL;
9855
9856 p = &rn->p;
9857 has_valid_label = bgp_is_valid_label(&rn->local_label);
9858
9859 if (has_valid_label)
9860 label = label_pton(&rn->local_label);
9861
9862 if (safi == SAFI_EVPN) {
9863
9864 if (!json) {
9865 vty_out(vty, "BGP routing table entry for %s%s%s\n",
9866 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
9867 : "", prd ? ":" : "",
9868 bgp_evpn_route2str((struct prefix_evpn *)p,
9869 buf3, sizeof(buf3)));
9870 } else {
9871 json_object_string_add(json, "rd",
9872 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
9873 "");
9874 bgp_evpn_route2json((struct prefix_evpn *)p, json);
9875 }
9876 } else {
9877 if (!json) {
9878 vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
9879 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9880 ? prefix_rd2str(prd, buf1,
9881 sizeof(buf1))
9882 : ""),
9883 safi == SAFI_MPLS_VPN ? ":" : "",
9884 inet_ntop(p->family, &p->u.prefix, buf2,
9885 INET6_ADDRSTRLEN),
9886 p->prefixlen);
9887
9888 } else
9889 json_object_string_add(json, "prefix",
9890 prefix2str(p, prefix_str, sizeof(prefix_str)));
9891 }
9892
9893 if (has_valid_label) {
9894 if (json)
9895 json_object_int_add(json, "localLabel", label);
9896 else
9897 vty_out(vty, "Local label: %d\n", label);
9898 }
9899
9900 if (!json)
9901 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
9902 vty_out(vty, "not allocated\n");
9903
9904 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
9905 count++;
9906 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
9907 best = count;
9908 if (pi->extra && pi->extra->suppress)
9909 suppress = 1;
9910
9911 if (pi->attr->community == NULL)
9912 continue;
9913
9914 no_advertise += community_include(
9915 pi->attr->community, COMMUNITY_NO_ADVERTISE);
9916 no_export += community_include(pi->attr->community,
9917 COMMUNITY_NO_EXPORT);
9918 local_as += community_include(pi->attr->community,
9919 COMMUNITY_LOCAL_AS);
9920 accept_own += community_include(pi->attr->community,
9921 COMMUNITY_ACCEPT_OWN);
9922 route_filter_translated_v4 += community_include(
9923 pi->attr->community,
9924 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
9925 route_filter_translated_v6 += community_include(
9926 pi->attr->community,
9927 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
9928 route_filter_v4 += community_include(
9929 pi->attr->community, COMMUNITY_ROUTE_FILTER_v4);
9930 route_filter_v6 += community_include(
9931 pi->attr->community, COMMUNITY_ROUTE_FILTER_v6);
9932 llgr_stale += community_include(pi->attr->community,
9933 COMMUNITY_LLGR_STALE);
9934 no_llgr += community_include(pi->attr->community,
9935 COMMUNITY_NO_LLGR);
9936 accept_own_nexthop +=
9937 community_include(pi->attr->community,
9938 COMMUNITY_ACCEPT_OWN_NEXTHOP);
9939 blackhole += community_include(pi->attr->community,
9940 COMMUNITY_BLACKHOLE);
9941 no_peer += community_include(pi->attr->community,
9942 COMMUNITY_NO_PEER);
9943 }
9944 }
9945
9946 if (!json) {
9947 vty_out(vty, "Paths: (%d available", count);
9948 if (best) {
9949 vty_out(vty, ", best #%d", best);
9950 if (safi == SAFI_UNICAST) {
9951 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9952 vty_out(vty, ", table %s",
9953 VRF_DEFAULT_NAME);
9954 else
9955 vty_out(vty, ", vrf %s",
9956 bgp->name);
9957 }
9958 } else
9959 vty_out(vty, ", no best path");
9960
9961 if (accept_own)
9962 vty_out(vty,
9963 ", accept own local route exported and imported in different VRF");
9964 else if (route_filter_translated_v4)
9965 vty_out(vty,
9966 ", mark translated RTs for VPNv4 route filtering");
9967 else if (route_filter_v4)
9968 vty_out(vty,
9969 ", attach RT as-is for VPNv4 route filtering");
9970 else if (route_filter_translated_v6)
9971 vty_out(vty,
9972 ", mark translated RTs for VPNv6 route filtering");
9973 else if (route_filter_v6)
9974 vty_out(vty,
9975 ", attach RT as-is for VPNv6 route filtering");
9976 else if (llgr_stale)
9977 vty_out(vty,
9978 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
9979 else if (no_llgr)
9980 vty_out(vty,
9981 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
9982 else if (accept_own_nexthop)
9983 vty_out(vty,
9984 ", accept local nexthop");
9985 else if (blackhole)
9986 vty_out(vty, ", inform peer to blackhole prefix");
9987 else if (no_export)
9988 vty_out(vty, ", not advertised to EBGP peer");
9989 else if (no_advertise)
9990 vty_out(vty, ", not advertised to any peer");
9991 else if (local_as)
9992 vty_out(vty, ", not advertised outside local AS");
9993 else if (no_peer)
9994 vty_out(vty,
9995 ", inform EBGP peer not to advertise to their EBGP peers");
9996
9997 if (suppress)
9998 vty_out(vty,
9999 ", Advertisements suppressed by an aggregate.");
10000 vty_out(vty, ")\n");
10001 }
10002
10003 /* If we are not using addpath then we can display Advertised to and
10004 * that will
10005 * show what peers we advertised the bestpath to. If we are using
10006 * addpath
10007 * though then we must display Advertised to on a path-by-path basis. */
10008 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
10009 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
10010 if (bgp_adj_out_lookup(peer, rn, 0)) {
10011 if (json && !json_adv_to)
10012 json_adv_to = json_object_new_object();
10013
10014 route_vty_out_advertised_to(
10015 vty, peer, &first,
10016 " Advertised to non peer-group peers:\n ",
10017 json_adv_to);
10018 }
10019 }
10020
10021 if (json) {
10022 if (json_adv_to) {
10023 json_object_object_add(json, "advertisedTo",
10024 json_adv_to);
10025 }
10026 } else {
10027 if (first)
10028 vty_out(vty, " Not advertised to any peer");
10029 vty_out(vty, "\n");
10030 }
10031 }
10032 }
10033
10034 static void bgp_show_path_info(struct prefix_rd *pfx_rd,
10035 struct bgp_node *bgp_node, struct vty *vty,
10036 struct bgp *bgp, afi_t afi,
10037 safi_t safi, json_object *json,
10038 enum bgp_path_type pathtype, int *display)
10039 {
10040 struct bgp_path_info *pi;
10041 int header = 1;
10042 char rdbuf[RD_ADDRSTRLEN];
10043 json_object *json_header = NULL;
10044 json_object *json_paths = NULL;
10045
10046 for (pi = bgp_node_get_bgp_path_info(bgp_node); pi;
10047 pi = pi->next) {
10048
10049 if (json && !json_paths) {
10050 /* Instantiate json_paths only if path is valid */
10051 json_paths = json_object_new_array();
10052 if (pfx_rd) {
10053 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
10054 json_header = json_object_new_object();
10055 } else
10056 json_header = json;
10057 }
10058
10059 if (header) {
10060 route_vty_out_detail_header(
10061 vty, bgp, bgp_node, pfx_rd,
10062 AFI_IP, safi, json_header);
10063 header = 0;
10064 }
10065 (*display)++;
10066
10067 if (pathtype == BGP_PATH_SHOW_ALL
10068 || (pathtype == BGP_PATH_SHOW_BESTPATH
10069 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
10070 || (pathtype == BGP_PATH_SHOW_MULTIPATH
10071 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
10072 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
10073 route_vty_out_detail(vty, bgp, bgp_node,
10074 pi, AFI_IP, safi,
10075 json_paths);
10076 }
10077
10078 if (json && json_paths) {
10079 json_object_object_add(json_header, "paths", json_paths);
10080
10081 if (pfx_rd)
10082 json_object_object_add(json, rdbuf, json_header);
10083 }
10084 }
10085
10086 /* Display specified route of BGP table. */
10087 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
10088 struct bgp_table *rib, const char *ip_str,
10089 afi_t afi, safi_t safi,
10090 struct prefix_rd *prd, int prefix_check,
10091 enum bgp_path_type pathtype, bool use_json)
10092 {
10093 int ret;
10094 int display = 0;
10095 struct prefix match;
10096 struct bgp_node *rn;
10097 struct bgp_node *rm;
10098 struct bgp_table *table;
10099 json_object *json = NULL;
10100 json_object *json_paths = NULL;
10101
10102 /* Check IP address argument. */
10103 ret = str2prefix(ip_str, &match);
10104 if (!ret) {
10105 vty_out(vty, "address is malformed\n");
10106 return CMD_WARNING;
10107 }
10108
10109 match.family = afi2family(afi);
10110
10111 if (use_json)
10112 json = json_object_new_object();
10113
10114 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
10115 for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
10116 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
10117 continue;
10118 table = bgp_node_get_bgp_table_info(rn);
10119 if (!table)
10120 continue;
10121
10122 if ((rm = bgp_node_match(table, &match)) == NULL)
10123 continue;
10124
10125 if (prefix_check
10126 && rm->p.prefixlen != match.prefixlen) {
10127 bgp_unlock_node(rm);
10128 continue;
10129 }
10130
10131 bgp_show_path_info((struct prefix_rd *)&rn->p, rm,
10132 vty, bgp, afi, safi, json,
10133 pathtype, &display);
10134
10135 bgp_unlock_node(rm);
10136 }
10137 } else if (safi == SAFI_EVPN) {
10138 struct bgp_node *longest_pfx;
10139 bool is_exact_pfxlen_match = FALSE;
10140
10141 for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
10142 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
10143 continue;
10144 table = bgp_node_get_bgp_table_info(rn);
10145 if (!table)
10146 continue;
10147
10148 longest_pfx = NULL;
10149 is_exact_pfxlen_match = FALSE;
10150 /*
10151 * Search through all the prefixes for a match. The
10152 * pfx's are enumerated in ascending order of pfxlens.
10153 * So, the last pfx match is the longest match. Set
10154 * is_exact_pfxlen_match when we get exact pfxlen match
10155 */
10156 for (rm = bgp_table_top(table); rm;
10157 rm = bgp_route_next(rm)) {
10158 /*
10159 * Get prefixlen of the ip-prefix within type5
10160 * evpn route
10161 */
10162 if (evpn_type5_prefix_match(&rm->p,
10163 &match) && rm->info) {
10164 longest_pfx = rm;
10165 int type5_pfxlen =
10166 bgp_evpn_get_type5_prefixlen(&rm->p);
10167 if (type5_pfxlen == match.prefixlen) {
10168 is_exact_pfxlen_match = TRUE;
10169 bgp_unlock_node(rm);
10170 break;
10171 }
10172 }
10173 }
10174
10175 if (!longest_pfx)
10176 continue;
10177
10178 if (prefix_check && !is_exact_pfxlen_match)
10179 continue;
10180
10181 rm = longest_pfx;
10182 bgp_lock_node(rm);
10183
10184 bgp_show_path_info((struct prefix_rd *)&rn->p, rm,
10185 vty, bgp, afi, safi, json,
10186 pathtype, &display);
10187
10188 bgp_unlock_node(rm);
10189 }
10190 } else if (safi == SAFI_FLOWSPEC) {
10191 if (use_json)
10192 json_paths = json_object_new_array();
10193
10194 display = bgp_flowspec_display_match_per_ip(afi, rib,
10195 &match, prefix_check,
10196 vty,
10197 use_json,
10198 json_paths);
10199 if (use_json && display)
10200 json_object_object_add(json, "paths", json_paths);
10201 } else {
10202 if ((rn = bgp_node_match(rib, &match)) != NULL) {
10203 if (!prefix_check
10204 || rn->p.prefixlen == match.prefixlen) {
10205 bgp_show_path_info(NULL, rn, vty, bgp, afi,
10206 safi, json,
10207 pathtype, &display);
10208 }
10209
10210 bgp_unlock_node(rn);
10211 }
10212 }
10213
10214 if (use_json) {
10215 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10216 json, JSON_C_TO_STRING_PRETTY |
10217 JSON_C_TO_STRING_NOSLASHESCAPE));
10218 json_object_free(json);
10219 } else {
10220 if (!display) {
10221 vty_out(vty, "%% Network not in table\n");
10222 return CMD_WARNING;
10223 }
10224 }
10225
10226 return CMD_SUCCESS;
10227 }
10228
10229 /* Display specified route of Main RIB */
10230 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
10231 afi_t afi, safi_t safi, struct prefix_rd *prd,
10232 int prefix_check, enum bgp_path_type pathtype,
10233 bool use_json)
10234 {
10235 if (!bgp) {
10236 bgp = bgp_get_default();
10237 if (!bgp) {
10238 if (!use_json)
10239 vty_out(vty, "No BGP process is configured\n");
10240 else
10241 vty_out(vty, "{}\n");
10242 return CMD_WARNING;
10243 }
10244 }
10245
10246 /* labeled-unicast routes live in the unicast table */
10247 if (safi == SAFI_LABELED_UNICAST)
10248 safi = SAFI_UNICAST;
10249
10250 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
10251 afi, safi, prd, prefix_check, pathtype,
10252 use_json);
10253 }
10254
10255 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
10256 struct cmd_token **argv, bool exact, afi_t afi,
10257 safi_t safi, bool uj)
10258 {
10259 struct lcommunity *lcom;
10260 struct buffer *b;
10261 int i;
10262 char *str;
10263 int first = 0;
10264
10265 b = buffer_new(1024);
10266 for (i = 0; i < argc; i++) {
10267 if (first)
10268 buffer_putc(b, ' ');
10269 else {
10270 if (strmatch(argv[i]->text, "AA:BB:CC")) {
10271 first = 1;
10272 buffer_putstr(b, argv[i]->arg);
10273 }
10274 }
10275 }
10276 buffer_putc(b, '\0');
10277
10278 str = buffer_getstr(b);
10279 buffer_free(b);
10280
10281 lcom = lcommunity_str2com(str);
10282 XFREE(MTYPE_TMP, str);
10283 if (!lcom) {
10284 vty_out(vty, "%% Large-community malformed\n");
10285 return CMD_WARNING;
10286 }
10287
10288 return bgp_show(vty, bgp, afi, safi,
10289 (exact ? bgp_show_type_lcommunity_exact
10290 : bgp_show_type_lcommunity),
10291 lcom, uj);
10292 }
10293
10294 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
10295 const char *lcom, bool exact, afi_t afi,
10296 safi_t safi, bool uj)
10297 {
10298 struct community_list *list;
10299
10300 list = community_list_lookup(bgp_clist, lcom, 0,
10301 LARGE_COMMUNITY_LIST_MASTER);
10302 if (list == NULL) {
10303 vty_out(vty, "%% %s is not a valid large-community-list name\n",
10304 lcom);
10305 return CMD_WARNING;
10306 }
10307
10308 return bgp_show(vty, bgp, afi, safi,
10309 (exact ? bgp_show_type_lcommunity_list_exact
10310 : bgp_show_type_lcommunity_list),
10311 list, uj);
10312 }
10313
10314 DEFUN (show_ip_bgp_large_community_list,
10315 show_ip_bgp_large_community_list_cmd,
10316 "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]",
10317 SHOW_STR
10318 IP_STR
10319 BGP_STR
10320 BGP_INSTANCE_HELP_STR
10321 BGP_AFI_HELP_STR
10322 BGP_SAFI_WITH_LABEL_HELP_STR
10323 "Display routes matching the large-community-list\n"
10324 "large-community-list number\n"
10325 "large-community-list name\n"
10326 "Exact match of the large-communities\n"
10327 JSON_STR)
10328 {
10329 char *vrf = NULL;
10330 afi_t afi = AFI_IP6;
10331 safi_t safi = SAFI_UNICAST;
10332 int idx = 0;
10333 bool exact_match = 0;
10334
10335 if (argv_find(argv, argc, "ip", &idx))
10336 afi = AFI_IP;
10337 if (argv_find(argv, argc, "view", &idx)
10338 || argv_find(argv, argc, "vrf", &idx))
10339 vrf = argv[++idx]->arg;
10340 if (argv_find(argv, argc, "ipv4", &idx)
10341 || argv_find(argv, argc, "ipv6", &idx)) {
10342 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
10343 if (argv_find(argv, argc, "unicast", &idx)
10344 || argv_find(argv, argc, "multicast", &idx))
10345 safi = bgp_vty_safi_from_str(argv[idx]->text);
10346 }
10347
10348 bool uj = use_json(argc, argv);
10349
10350 struct bgp *bgp = bgp_lookup_by_name(vrf);
10351 if (bgp == NULL) {
10352 vty_out(vty, "Can't find BGP instance %s\n", vrf);
10353 return CMD_WARNING;
10354 }
10355
10356 argv_find(argv, argc, "large-community-list", &idx);
10357
10358 const char *clist_number_or_name = argv[++idx]->arg;
10359
10360 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
10361 exact_match = 1;
10362
10363 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
10364 exact_match, afi, safi, uj);
10365 }
10366 DEFUN (show_ip_bgp_large_community,
10367 show_ip_bgp_large_community_cmd,
10368 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
10369 SHOW_STR
10370 IP_STR
10371 BGP_STR
10372 BGP_INSTANCE_HELP_STR
10373 BGP_AFI_HELP_STR
10374 BGP_SAFI_WITH_LABEL_HELP_STR
10375 "Display routes matching the large-communities\n"
10376 "List of large-community numbers\n"
10377 "Exact match of the large-communities\n"
10378 JSON_STR)
10379 {
10380 char *vrf = NULL;
10381 afi_t afi = AFI_IP6;
10382 safi_t safi = SAFI_UNICAST;
10383 int idx = 0;
10384 bool exact_match = 0;
10385
10386 if (argv_find(argv, argc, "ip", &idx))
10387 afi = AFI_IP;
10388 if (argv_find(argv, argc, "view", &idx)
10389 || argv_find(argv, argc, "vrf", &idx))
10390 vrf = argv[++idx]->arg;
10391 if (argv_find(argv, argc, "ipv4", &idx)
10392 || argv_find(argv, argc, "ipv6", &idx)) {
10393 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
10394 if (argv_find(argv, argc, "unicast", &idx)
10395 || argv_find(argv, argc, "multicast", &idx))
10396 safi = bgp_vty_safi_from_str(argv[idx]->text);
10397 }
10398
10399 bool uj = use_json(argc, argv);
10400
10401 struct bgp *bgp = bgp_lookup_by_name(vrf);
10402 if (bgp == NULL) {
10403 vty_out(vty, "Can't find BGP instance %s\n", vrf);
10404 return CMD_WARNING;
10405 }
10406
10407 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
10408 if (argv_find(argv, argc, "exact-match", &idx))
10409 exact_match = 1;
10410 return bgp_show_lcommunity(vty, bgp, argc, argv,
10411 exact_match, afi, safi, uj);
10412 } else
10413 return bgp_show(vty, bgp, afi, safi,
10414 bgp_show_type_lcommunity_all, NULL, uj);
10415 }
10416
10417 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
10418 safi_t safi);
10419
10420
10421 /* BGP route print out function without JSON */
10422 DEFUN (show_ip_bgp,
10423 show_ip_bgp_cmd,
10424 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
10425 <dampening <parameters>\
10426 |route-map WORD\
10427 |prefix-list WORD\
10428 |filter-list WORD\
10429 |statistics\
10430 |community-list <(1-500)|WORD> [exact-match]\
10431 |A.B.C.D/M longer-prefixes\
10432 |X:X::X:X/M longer-prefixes\
10433 >",
10434 SHOW_STR
10435 IP_STR
10436 BGP_STR
10437 BGP_INSTANCE_HELP_STR
10438 BGP_AFI_HELP_STR
10439 BGP_SAFI_WITH_LABEL_HELP_STR
10440 "Display detailed information about dampening\n"
10441 "Display detail of configured dampening parameters\n"
10442 "Display routes matching the route-map\n"
10443 "A route-map to match on\n"
10444 "Display routes conforming to the prefix-list\n"
10445 "Prefix-list name\n"
10446 "Display routes conforming to the filter-list\n"
10447 "Regular expression access list name\n"
10448 "BGP RIB advertisement statistics\n"
10449 "Display routes matching the community-list\n"
10450 "community-list number\n"
10451 "community-list name\n"
10452 "Exact match of the communities\n"
10453 "IPv4 prefix\n"
10454 "Display route and more specific routes\n"
10455 "IPv6 prefix\n"
10456 "Display route and more specific routes\n")
10457 {
10458 afi_t afi = AFI_IP6;
10459 safi_t safi = SAFI_UNICAST;
10460 int exact_match = 0;
10461 struct bgp *bgp = NULL;
10462 int idx = 0;
10463
10464 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10465 &bgp, false);
10466 if (!idx)
10467 return CMD_WARNING;
10468
10469 if (argv_find(argv, argc, "dampening", &idx)) {
10470 if (argv_find(argv, argc, "parameters", &idx))
10471 return bgp_show_dampening_parameters(vty, afi, safi);
10472 }
10473
10474 if (argv_find(argv, argc, "prefix-list", &idx))
10475 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
10476 safi, bgp_show_type_prefix_list);
10477
10478 if (argv_find(argv, argc, "filter-list", &idx))
10479 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
10480 safi, bgp_show_type_filter_list);
10481
10482 if (argv_find(argv, argc, "statistics", &idx))
10483 return bgp_table_stats(vty, bgp, afi, safi);
10484
10485 if (argv_find(argv, argc, "route-map", &idx))
10486 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
10487 safi, bgp_show_type_route_map);
10488
10489 if (argv_find(argv, argc, "community-list", &idx)) {
10490 const char *clist_number_or_name = argv[++idx]->arg;
10491 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
10492 exact_match = 1;
10493 return bgp_show_community_list(vty, bgp, clist_number_or_name,
10494 exact_match, afi, safi);
10495 }
10496 /* prefix-longer */
10497 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
10498 || argv_find(argv, argc, "X:X::X:X/M", &idx))
10499 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
10500 safi,
10501 bgp_show_type_prefix_longer);
10502
10503 return CMD_WARNING;
10504 }
10505
10506 /* BGP route print out function with JSON */
10507 DEFUN (show_ip_bgp_json,
10508 show_ip_bgp_json_cmd,
10509 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
10510 [cidr-only\
10511 |dampening <flap-statistics|dampened-paths>\
10512 |community [AA:NN|local-AS|no-advertise|no-export\
10513 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
10514 |accept-own|accept-own-nexthop|route-filter-v6\
10515 |route-filter-v4|route-filter-translated-v6\
10516 |route-filter-translated-v4] [exact-match]\
10517 ] [json]",
10518 SHOW_STR
10519 IP_STR
10520 BGP_STR
10521 BGP_INSTANCE_HELP_STR
10522 BGP_AFI_HELP_STR
10523 BGP_SAFI_WITH_LABEL_HELP_STR
10524 "Display only routes with non-natural netmasks\n"
10525 "Display detailed information about dampening\n"
10526 "Display flap statistics of routes\n"
10527 "Display paths suppressed due to dampening\n"
10528 "Display routes matching the communities\n"
10529 COMMUNITY_AANN_STR
10530 "Do not send outside local AS (well-known community)\n"
10531 "Do not advertise to any peer (well-known community)\n"
10532 "Do not export to next AS (well-known community)\n"
10533 "Graceful shutdown (well-known community)\n"
10534 "Do not export to any peer (well-known community)\n"
10535 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
10536 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
10537 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
10538 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
10539 "Should accept VPN route with local nexthop (well-known community)\n"
10540 "RT VPNv6 route filtering (well-known community)\n"
10541 "RT VPNv4 route filtering (well-known community)\n"
10542 "RT translated VPNv6 route filtering (well-known community)\n"
10543 "RT translated VPNv4 route filtering (well-known community)\n"
10544 "Exact match of the communities\n"
10545 JSON_STR)
10546 {
10547 afi_t afi = AFI_IP6;
10548 safi_t safi = SAFI_UNICAST;
10549 enum bgp_show_type sh_type = bgp_show_type_normal;
10550 struct bgp *bgp = NULL;
10551 int idx = 0;
10552 int exact_match = 0;
10553 bool uj = use_json(argc, argv);
10554
10555 if (uj)
10556 argc--;
10557
10558 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10559 &bgp, uj);
10560 if (!idx)
10561 return CMD_WARNING;
10562
10563 if (argv_find(argv, argc, "cidr-only", &idx))
10564 return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only,
10565 NULL, uj);
10566
10567 if (argv_find(argv, argc, "dampening", &idx)) {
10568 if (argv_find(argv, argc, "dampened-paths", &idx))
10569 return bgp_show(vty, bgp, afi, safi,
10570 bgp_show_type_dampend_paths, NULL, uj);
10571 else if (argv_find(argv, argc, "flap-statistics", &idx))
10572 return bgp_show(vty, bgp, afi, safi,
10573 bgp_show_type_flap_statistics, NULL,
10574 uj);
10575 }
10576
10577 if (argv_find(argv, argc, "community", &idx)) {
10578 char *maybecomm = NULL;
10579 char *community = NULL;
10580
10581 if (idx + 1 < argc) {
10582 if (argv[idx + 1]->type == VARIABLE_TKN)
10583 maybecomm = argv[idx + 1]->arg;
10584 else
10585 maybecomm = argv[idx + 1]->text;
10586 }
10587
10588 if (maybecomm && !strmatch(maybecomm, "json")
10589 && !strmatch(maybecomm, "exact-match"))
10590 community = maybecomm;
10591
10592 if (argv_find(argv, argc, "exact-match", &idx))
10593 exact_match = 1;
10594
10595 if (community)
10596 return bgp_show_community(vty, bgp, community,
10597 exact_match, afi, safi, uj);
10598 else
10599 return (bgp_show(vty, bgp, afi, safi,
10600 bgp_show_type_community_all, NULL,
10601 uj));
10602 }
10603
10604 return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
10605 }
10606
10607 DEFUN (show_ip_bgp_route,
10608 show_ip_bgp_route_cmd,
10609 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]"
10610 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
10611 SHOW_STR
10612 IP_STR
10613 BGP_STR
10614 BGP_INSTANCE_HELP_STR
10615 BGP_AFI_HELP_STR
10616 BGP_SAFI_WITH_LABEL_HELP_STR
10617 "Network in the BGP routing table to display\n"
10618 "IPv4 prefix\n"
10619 "Network in the BGP routing table to display\n"
10620 "IPv6 prefix\n"
10621 "Display only the bestpath\n"
10622 "Display only multipaths\n"
10623 JSON_STR)
10624 {
10625 int prefix_check = 0;
10626
10627 afi_t afi = AFI_IP6;
10628 safi_t safi = SAFI_UNICAST;
10629 char *prefix = NULL;
10630 struct bgp *bgp = NULL;
10631 enum bgp_path_type path_type;
10632 bool uj = use_json(argc, argv);
10633
10634 int idx = 0;
10635
10636 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10637 &bgp, uj);
10638 if (!idx)
10639 return CMD_WARNING;
10640
10641 if (!bgp) {
10642 vty_out(vty,
10643 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
10644 return CMD_WARNING;
10645 }
10646
10647 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
10648 if (argv_find(argv, argc, "A.B.C.D", &idx)
10649 || argv_find(argv, argc, "X:X::X:X", &idx))
10650 prefix_check = 0;
10651 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
10652 || argv_find(argv, argc, "X:X::X:X/M", &idx))
10653 prefix_check = 1;
10654
10655 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
10656 && afi != AFI_IP6) {
10657 vty_out(vty,
10658 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
10659 return CMD_WARNING;
10660 }
10661 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
10662 && afi != AFI_IP) {
10663 vty_out(vty,
10664 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
10665 return CMD_WARNING;
10666 }
10667
10668 prefix = argv[idx]->arg;
10669
10670 /* [<bestpath|multipath>] */
10671 if (argv_find(argv, argc, "bestpath", &idx))
10672 path_type = BGP_PATH_SHOW_BESTPATH;
10673 else if (argv_find(argv, argc, "multipath", &idx))
10674 path_type = BGP_PATH_SHOW_MULTIPATH;
10675 else
10676 path_type = BGP_PATH_SHOW_ALL;
10677
10678 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
10679 path_type, uj);
10680 }
10681
10682 DEFUN (show_ip_bgp_regexp,
10683 show_ip_bgp_regexp_cmd,
10684 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
10685 SHOW_STR
10686 IP_STR
10687 BGP_STR
10688 BGP_INSTANCE_HELP_STR
10689 BGP_AFI_HELP_STR
10690 BGP_SAFI_WITH_LABEL_HELP_STR
10691 "Display routes matching the AS path regular expression\n"
10692 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
10693 JSON_STR)
10694 {
10695 afi_t afi = AFI_IP6;
10696 safi_t safi = SAFI_UNICAST;
10697 struct bgp *bgp = NULL;
10698 bool uj = use_json(argc, argv);
10699 char *regstr = NULL;
10700
10701 int idx = 0;
10702 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10703 &bgp, false);
10704 if (!idx)
10705 return CMD_WARNING;
10706
10707 // get index of regex
10708 if (argv_find(argv, argc, "REGEX", &idx))
10709 regstr = argv[idx]->arg;
10710
10711 assert(regstr);
10712 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
10713 bgp_show_type_regexp, uj);
10714 }
10715
10716 DEFUN (show_ip_bgp_instance_all,
10717 show_ip_bgp_instance_all_cmd,
10718 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json]",
10719 SHOW_STR
10720 IP_STR
10721 BGP_STR
10722 BGP_INSTANCE_ALL_HELP_STR
10723 BGP_AFI_HELP_STR
10724 BGP_SAFI_WITH_LABEL_HELP_STR
10725 JSON_STR)
10726 {
10727 afi_t afi = AFI_IP;
10728 safi_t safi = SAFI_UNICAST;
10729 struct bgp *bgp = NULL;
10730 int idx = 0;
10731 bool uj = use_json(argc, argv);
10732
10733 if (uj)
10734 argc--;
10735
10736 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10737 &bgp, uj);
10738 if (!idx)
10739 return CMD_WARNING;
10740
10741 bgp_show_all_instances_routes_vty(vty, afi, safi, uj);
10742 return CMD_SUCCESS;
10743 }
10744
10745 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
10746 afi_t afi, safi_t safi, enum bgp_show_type type,
10747 bool use_json)
10748 {
10749 regex_t *regex;
10750 int rc;
10751
10752 if (!config_bgp_aspath_validate(regstr)) {
10753 vty_out(vty, "Invalid character in REGEX %s\n",
10754 regstr);
10755 return CMD_WARNING_CONFIG_FAILED;
10756 }
10757
10758 regex = bgp_regcomp(regstr);
10759 if (!regex) {
10760 vty_out(vty, "Can't compile regexp %s\n", regstr);
10761 return CMD_WARNING;
10762 }
10763
10764 rc = bgp_show(vty, bgp, afi, safi, type, regex, use_json);
10765 bgp_regex_free(regex);
10766 return rc;
10767 }
10768
10769 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
10770 const char *prefix_list_str, afi_t afi,
10771 safi_t safi, enum bgp_show_type type)
10772 {
10773 struct prefix_list *plist;
10774
10775 plist = prefix_list_lookup(afi, prefix_list_str);
10776 if (plist == NULL) {
10777 vty_out(vty, "%% %s is not a valid prefix-list name\n",
10778 prefix_list_str);
10779 return CMD_WARNING;
10780 }
10781
10782 return bgp_show(vty, bgp, afi, safi, type, plist, 0);
10783 }
10784
10785 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
10786 const char *filter, afi_t afi, safi_t safi,
10787 enum bgp_show_type type)
10788 {
10789 struct as_list *as_list;
10790
10791 as_list = as_list_lookup(filter);
10792 if (as_list == NULL) {
10793 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
10794 filter);
10795 return CMD_WARNING;
10796 }
10797
10798 return bgp_show(vty, bgp, afi, safi, type, as_list, 0);
10799 }
10800
10801 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
10802 const char *rmap_str, afi_t afi, safi_t safi,
10803 enum bgp_show_type type)
10804 {
10805 struct route_map *rmap;
10806
10807 rmap = route_map_lookup_by_name(rmap_str);
10808 if (!rmap) {
10809 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
10810 return CMD_WARNING;
10811 }
10812
10813 return bgp_show(vty, bgp, afi, safi, type, rmap, 0);
10814 }
10815
10816 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
10817 const char *comstr, int exact, afi_t afi,
10818 safi_t safi, bool use_json)
10819 {
10820 struct community *com;
10821 int ret = 0;
10822
10823 com = community_str2com(comstr);
10824 if (!com) {
10825 vty_out(vty, "%% Community malformed: %s\n", comstr);
10826 return CMD_WARNING;
10827 }
10828
10829 ret = bgp_show(vty, bgp, afi, safi,
10830 (exact ? bgp_show_type_community_exact
10831 : bgp_show_type_community),
10832 com, use_json);
10833 community_free(&com);
10834
10835 return ret;
10836 }
10837
10838 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
10839 const char *com, int exact, afi_t afi,
10840 safi_t safi)
10841 {
10842 struct community_list *list;
10843
10844 list = community_list_lookup(bgp_clist, com, 0, COMMUNITY_LIST_MASTER);
10845 if (list == NULL) {
10846 vty_out(vty, "%% %s is not a valid community-list name\n", com);
10847 return CMD_WARNING;
10848 }
10849
10850 return bgp_show(vty, bgp, afi, safi,
10851 (exact ? bgp_show_type_community_list_exact
10852 : bgp_show_type_community_list),
10853 list, 0);
10854 }
10855
10856 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
10857 const char *prefix, afi_t afi, safi_t safi,
10858 enum bgp_show_type type)
10859 {
10860 int ret;
10861 struct prefix *p;
10862
10863 p = prefix_new();
10864
10865 ret = str2prefix(prefix, p);
10866 if (!ret) {
10867 vty_out(vty, "%% Malformed Prefix\n");
10868 return CMD_WARNING;
10869 }
10870
10871 ret = bgp_show(vty, bgp, afi, safi, type, p, 0);
10872 prefix_free(&p);
10873 return ret;
10874 }
10875
10876 enum bgp_stats {
10877 BGP_STATS_MAXBITLEN = 0,
10878 BGP_STATS_RIB,
10879 BGP_STATS_PREFIXES,
10880 BGP_STATS_TOTPLEN,
10881 BGP_STATS_UNAGGREGATEABLE,
10882 BGP_STATS_MAX_AGGREGATEABLE,
10883 BGP_STATS_AGGREGATES,
10884 BGP_STATS_SPACE,
10885 BGP_STATS_ASPATH_COUNT,
10886 BGP_STATS_ASPATH_MAXHOPS,
10887 BGP_STATS_ASPATH_TOTHOPS,
10888 BGP_STATS_ASPATH_MAXSIZE,
10889 BGP_STATS_ASPATH_TOTSIZE,
10890 BGP_STATS_ASN_HIGHEST,
10891 BGP_STATS_MAX,
10892 };
10893
10894 static const char *const table_stats_strs[] = {
10895 [BGP_STATS_PREFIXES] = "Total Prefixes",
10896 [BGP_STATS_TOTPLEN] = "Average prefix length",
10897 [BGP_STATS_RIB] = "Total Advertisements",
10898 [BGP_STATS_UNAGGREGATEABLE] = "Unaggregateable prefixes",
10899 [BGP_STATS_MAX_AGGREGATEABLE] =
10900 "Maximum aggregateable prefixes",
10901 [BGP_STATS_AGGREGATES] = "BGP Aggregate advertisements",
10902 [BGP_STATS_SPACE] = "Address space advertised",
10903 [BGP_STATS_ASPATH_COUNT] = "Advertisements with paths",
10904 [BGP_STATS_ASPATH_MAXHOPS] = "Longest AS-Path (hops)",
10905 [BGP_STATS_ASPATH_MAXSIZE] = "Largest AS-Path (bytes)",
10906 [BGP_STATS_ASPATH_TOTHOPS] = "Average AS-Path length (hops)",
10907 [BGP_STATS_ASPATH_TOTSIZE] = "Average AS-Path size (bytes)",
10908 [BGP_STATS_ASN_HIGHEST] = "Highest public ASN",
10909 [BGP_STATS_MAX] = NULL,
10910 };
10911
10912 struct bgp_table_stats {
10913 struct bgp_table *table;
10914 unsigned long long counts[BGP_STATS_MAX];
10915 double total_space;
10916 };
10917
10918 #if 0
10919 #define TALLY_SIGFIG 100000
10920 static unsigned long
10921 ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
10922 {
10923 unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
10924 unsigned long res = (newtot * TALLY_SIGFIG) / count;
10925 unsigned long ret = newtot / count;
10926
10927 if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
10928 return ret + 1;
10929 else
10930 return ret;
10931 }
10932 #endif
10933
10934 static void bgp_table_stats_rn(struct bgp_node *rn, struct bgp_node *top,
10935 struct bgp_table_stats *ts, unsigned int space)
10936 {
10937 struct bgp_node *prn = bgp_node_parent_nolock(rn);
10938 struct bgp_path_info *pi;
10939
10940 if (rn == top)
10941 return;
10942
10943 if (!bgp_node_has_bgp_path_info_data(rn))
10944 return;
10945
10946 ts->counts[BGP_STATS_PREFIXES]++;
10947 ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
10948
10949 #if 0
10950 ts->counts[BGP_STATS_AVGPLEN]
10951 = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
10952 ts->counts[BGP_STATS_AVGPLEN],
10953 rn->p.prefixlen);
10954 #endif
10955
10956 /* check if the prefix is included by any other announcements */
10957 while (prn && !bgp_node_has_bgp_path_info_data(prn))
10958 prn = bgp_node_parent_nolock(prn);
10959
10960 if (prn == NULL || prn == top) {
10961 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
10962 /* announced address space */
10963 if (space)
10964 ts->total_space += pow(2.0, space - rn->p.prefixlen);
10965 } else if (bgp_node_has_bgp_path_info_data(prn))
10966 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
10967
10968
10969 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
10970 ts->counts[BGP_STATS_RIB]++;
10971
10972 if (CHECK_FLAG(pi->attr->flag,
10973 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
10974 ts->counts[BGP_STATS_AGGREGATES]++;
10975
10976 /* as-path stats */
10977 if (pi->attr->aspath) {
10978 unsigned int hops = aspath_count_hops(pi->attr->aspath);
10979 unsigned int size = aspath_size(pi->attr->aspath);
10980 as_t highest = aspath_highest(pi->attr->aspath);
10981
10982 ts->counts[BGP_STATS_ASPATH_COUNT]++;
10983
10984 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
10985 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
10986
10987 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
10988 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
10989
10990 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
10991 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
10992 #if 0
10993 ts->counts[BGP_STATS_ASPATH_AVGHOPS]
10994 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
10995 ts->counts[BGP_STATS_ASPATH_AVGHOPS],
10996 hops);
10997 ts->counts[BGP_STATS_ASPATH_AVGSIZE]
10998 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
10999 ts->counts[BGP_STATS_ASPATH_AVGSIZE],
11000 size);
11001 #endif
11002 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
11003 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
11004 }
11005 }
11006 }
11007
11008 static int bgp_table_stats_walker(struct thread *t)
11009 {
11010 struct bgp_node *rn, *nrn;
11011 struct bgp_node *top;
11012 struct bgp_table_stats *ts = THREAD_ARG(t);
11013 unsigned int space = 0;
11014
11015 if (!(top = bgp_table_top(ts->table)))
11016 return 0;
11017
11018 switch (ts->table->afi) {
11019 case AFI_IP:
11020 space = IPV4_MAX_BITLEN;
11021 break;
11022 case AFI_IP6:
11023 space = IPV6_MAX_BITLEN;
11024 break;
11025 default:
11026 return 0;
11027 }
11028
11029 ts->counts[BGP_STATS_MAXBITLEN] = space;
11030
11031 for (rn = top; rn; rn = bgp_route_next(rn)) {
11032 if (ts->table->safi == SAFI_MPLS_VPN) {
11033 struct bgp_table *table;
11034
11035 table = bgp_node_get_bgp_table_info(rn);
11036 if (!table)
11037 continue;
11038
11039 top = bgp_table_top(table);
11040 for (nrn = bgp_table_top(table); nrn;
11041 nrn = bgp_route_next(nrn))
11042 bgp_table_stats_rn(nrn, top, ts, space);
11043 } else {
11044 bgp_table_stats_rn(rn, top, ts, space);
11045 }
11046 }
11047
11048 return 0;
11049 }
11050
11051 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
11052 safi_t safi)
11053 {
11054 struct bgp_table_stats ts;
11055 unsigned int i;
11056
11057 if (!bgp->rib[afi][safi]) {
11058 vty_out(vty, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
11059 afi, safi);
11060 return CMD_WARNING;
11061 }
11062
11063 vty_out(vty, "BGP %s RIB statistics\n", get_afi_safi_str(afi, safi, false));
11064
11065 /* labeled-unicast routes live in the unicast table */
11066 if (safi == SAFI_LABELED_UNICAST)
11067 safi = SAFI_UNICAST;
11068
11069 memset(&ts, 0, sizeof(ts));
11070 ts.table = bgp->rib[afi][safi];
11071 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
11072
11073 for (i = 0; i < BGP_STATS_MAX; i++) {
11074 if (!table_stats_strs[i])
11075 continue;
11076
11077 switch (i) {
11078 #if 0
11079 case BGP_STATS_ASPATH_AVGHOPS:
11080 case BGP_STATS_ASPATH_AVGSIZE:
11081 case BGP_STATS_AVGPLEN:
11082 vty_out (vty, "%-30s: ", table_stats_strs[i]);
11083 vty_out (vty, "%12.2f",
11084 (float)ts.counts[i] / (float)TALLY_SIGFIG);
11085 break;
11086 #endif
11087 case BGP_STATS_ASPATH_TOTHOPS:
11088 case BGP_STATS_ASPATH_TOTSIZE:
11089 vty_out(vty, "%-30s: ", table_stats_strs[i]);
11090 vty_out(vty, "%12.2f",
11091 ts.counts[i]
11092 ? (float)ts.counts[i]
11093 / (float)ts.counts
11094 [BGP_STATS_ASPATH_COUNT]
11095 : 0);
11096 break;
11097 case BGP_STATS_TOTPLEN:
11098 vty_out(vty, "%-30s: ", table_stats_strs[i]);
11099 vty_out(vty, "%12.2f",
11100 ts.counts[i]
11101 ? (float)ts.counts[i]
11102 / (float)ts.counts
11103 [BGP_STATS_PREFIXES]
11104 : 0);
11105 break;
11106 case BGP_STATS_SPACE:
11107 vty_out(vty, "%-30s: ", table_stats_strs[i]);
11108 vty_out(vty, "%12g\n", ts.total_space);
11109
11110 if (afi == AFI_IP6) {
11111 vty_out(vty, "%30s: ", "/32 equivalent ");
11112 vty_out(vty, "%12g\n",
11113 ts.total_space * pow(2.0, -128 + 32));
11114 vty_out(vty, "%30s: ", "/48 equivalent ");
11115 vty_out(vty, "%12g\n",
11116 ts.total_space * pow(2.0, -128 + 48));
11117 } else {
11118 vty_out(vty, "%30s: ", "% announced ");
11119 vty_out(vty, "%12.2f\n",
11120 ts.total_space * 100. * pow(2.0, -32));
11121 vty_out(vty, "%30s: ", "/8 equivalent ");
11122 vty_out(vty, "%12.2f\n",
11123 ts.total_space * pow(2.0, -32 + 8));
11124 vty_out(vty, "%30s: ", "/24 equivalent ");
11125 vty_out(vty, "%12.2f\n",
11126 ts.total_space * pow(2.0, -32 + 24));
11127 }
11128 break;
11129 default:
11130 vty_out(vty, "%-30s: ", table_stats_strs[i]);
11131 vty_out(vty, "%12llu", ts.counts[i]);
11132 }
11133
11134 vty_out(vty, "\n");
11135 }
11136 return CMD_SUCCESS;
11137 }
11138
11139 enum bgp_pcounts {
11140 PCOUNT_ADJ_IN = 0,
11141 PCOUNT_DAMPED,
11142 PCOUNT_REMOVED,
11143 PCOUNT_HISTORY,
11144 PCOUNT_STALE,
11145 PCOUNT_VALID,
11146 PCOUNT_ALL,
11147 PCOUNT_COUNTED,
11148 PCOUNT_PFCNT, /* the figure we display to users */
11149 PCOUNT_MAX,
11150 };
11151
11152 static const char *const pcount_strs[] = {
11153 [PCOUNT_ADJ_IN] = "Adj-in",
11154 [PCOUNT_DAMPED] = "Damped",
11155 [PCOUNT_REMOVED] = "Removed",
11156 [PCOUNT_HISTORY] = "History",
11157 [PCOUNT_STALE] = "Stale",
11158 [PCOUNT_VALID] = "Valid",
11159 [PCOUNT_ALL] = "All RIB",
11160 [PCOUNT_COUNTED] = "PfxCt counted",
11161 [PCOUNT_PFCNT] = "Useable",
11162 [PCOUNT_MAX] = NULL,
11163 };
11164
11165 struct peer_pcounts {
11166 unsigned int count[PCOUNT_MAX];
11167 const struct peer *peer;
11168 const struct bgp_table *table;
11169 safi_t safi;
11170 };
11171
11172 static void bgp_peer_count_proc(struct bgp_node *rn,
11173 struct peer_pcounts *pc)
11174 {
11175 const struct bgp_adj_in *ain;
11176 const struct bgp_path_info *pi;
11177 const struct peer *peer = pc->peer;
11178
11179 for (ain = rn->adj_in; ain; ain = ain->next)
11180 if (ain->peer == peer)
11181 pc->count[PCOUNT_ADJ_IN]++;
11182
11183 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
11184
11185 if (pi->peer != peer)
11186 continue;
11187
11188 pc->count[PCOUNT_ALL]++;
11189
11190 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
11191 pc->count[PCOUNT_DAMPED]++;
11192 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11193 pc->count[PCOUNT_HISTORY]++;
11194 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
11195 pc->count[PCOUNT_REMOVED]++;
11196 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
11197 pc->count[PCOUNT_STALE]++;
11198 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
11199 pc->count[PCOUNT_VALID]++;
11200 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
11201 pc->count[PCOUNT_PFCNT]++;
11202
11203 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
11204 pc->count[PCOUNT_COUNTED]++;
11205 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
11206 flog_err(
11207 EC_LIB_DEVELOPMENT,
11208 "Attempting to count but flags say it is unusable");
11209 } else {
11210 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
11211 flog_err(
11212 EC_LIB_DEVELOPMENT,
11213 "Not counted but flags say we should");
11214 }
11215 }
11216 }
11217
11218 static int bgp_peer_count_walker(struct thread *t)
11219 {
11220 struct bgp_node *rn, *rm;
11221 const struct bgp_table *table;
11222 struct peer_pcounts *pc = THREAD_ARG(t);
11223
11224 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
11225 || pc->safi == SAFI_EVPN) {
11226 /* Special handling for 2-level routing tables. */
11227 for (rn = bgp_table_top(pc->table); rn;
11228 rn = bgp_route_next(rn)) {
11229 table = bgp_node_get_bgp_table_info(rn);
11230 if (table != NULL)
11231 for (rm = bgp_table_top(table); rm;
11232 rm = bgp_route_next(rm))
11233 bgp_peer_count_proc(rm, pc);
11234 }
11235 } else
11236 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
11237 bgp_peer_count_proc(rn, pc);
11238
11239 return 0;
11240 }
11241
11242 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
11243 safi_t safi, bool use_json)
11244 {
11245 struct peer_pcounts pcounts = {.peer = peer};
11246 unsigned int i;
11247 json_object *json = NULL;
11248 json_object *json_loop = NULL;
11249
11250 if (use_json) {
11251 json = json_object_new_object();
11252 json_loop = json_object_new_object();
11253 }
11254
11255 if (!peer || !peer->bgp || !peer->afc[afi][safi]
11256 || !peer->bgp->rib[afi][safi]) {
11257 if (use_json) {
11258 json_object_string_add(
11259 json, "warning",
11260 "No such neighbor or address family");
11261 vty_out(vty, "%s\n", json_object_to_json_string(json));
11262 json_object_free(json);
11263 } else
11264 vty_out(vty, "%% No such neighbor or address family\n");
11265
11266 return CMD_WARNING;
11267 }
11268
11269 memset(&pcounts, 0, sizeof(pcounts));
11270 pcounts.peer = peer;
11271 pcounts.table = peer->bgp->rib[afi][safi];
11272 pcounts.safi = safi;
11273
11274 /* in-place call via thread subsystem so as to record execution time
11275 * stats for the thread-walk (i.e. ensure this can't be blamed on
11276 * on just vty_read()).
11277 */
11278 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
11279
11280 if (use_json) {
11281 json_object_string_add(json, "prefixCountsFor", peer->host);
11282 json_object_string_add(json, "multiProtocol",
11283 get_afi_safi_str(afi, safi, true));
11284 json_object_int_add(json, "pfxCounter",
11285 peer->pcount[afi][safi]);
11286
11287 for (i = 0; i < PCOUNT_MAX; i++)
11288 json_object_int_add(json_loop, pcount_strs[i],
11289 pcounts.count[i]);
11290
11291 json_object_object_add(json, "ribTableWalkCounters", json_loop);
11292
11293 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
11294 json_object_string_add(json, "pfxctDriftFor",
11295 peer->host);
11296 json_object_string_add(
11297 json, "recommended",
11298 "Please report this bug, with the above command output");
11299 }
11300 vty_out(vty, "%s\n", json_object_to_json_string_ext(
11301 json, JSON_C_TO_STRING_PRETTY));
11302 json_object_free(json);
11303 } else {
11304
11305 if (peer->hostname
11306 && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
11307 vty_out(vty, "Prefix counts for %s/%s, %s\n",
11308 peer->hostname, peer->host,
11309 get_afi_safi_str(afi, safi, false));
11310 } else {
11311 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
11312 get_afi_safi_str(afi, safi, false));
11313 }
11314
11315 vty_out(vty, "PfxCt: %" PRIu32 "\n", peer->pcount[afi][safi]);
11316 vty_out(vty, "\nCounts from RIB table walk:\n\n");
11317
11318 for (i = 0; i < PCOUNT_MAX; i++)
11319 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
11320 pcounts.count[i]);
11321
11322 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
11323 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
11324 vty_out(vty,
11325 "Please report this bug, with the above command output\n");
11326 }
11327 }
11328
11329 return CMD_SUCCESS;
11330 }
11331
11332 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
11333 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
11334 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] "
11335 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
11336 SHOW_STR
11337 IP_STR
11338 BGP_STR
11339 BGP_INSTANCE_HELP_STR
11340 BGP_AFI_HELP_STR
11341 BGP_SAFI_HELP_STR
11342 "Detailed information on TCP and BGP neighbor connections\n"
11343 "Neighbor to display information about\n"
11344 "Neighbor to display information about\n"
11345 "Neighbor on BGP configured interface\n"
11346 "Display detailed prefix count information\n"
11347 JSON_STR)
11348 {
11349 afi_t afi = AFI_IP6;
11350 safi_t safi = SAFI_UNICAST;
11351 struct peer *peer;
11352 int idx = 0;
11353 struct bgp *bgp = NULL;
11354 bool uj = use_json(argc, argv);
11355
11356 if (uj)
11357 argc--;
11358
11359 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11360 &bgp, uj);
11361 if (!idx)
11362 return CMD_WARNING;
11363
11364 argv_find(argv, argc, "neighbors", &idx);
11365 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
11366 if (!peer)
11367 return CMD_WARNING;
11368
11369 return bgp_peer_counts(vty, peer, afi, safi, uj);
11370 }
11371
11372 #ifdef KEEP_OLD_VPN_COMMANDS
11373 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
11374 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
11375 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
11376 SHOW_STR
11377 IP_STR
11378 BGP_STR
11379 BGP_VPNVX_HELP_STR
11380 "Display information about all VPNv4 NLRIs\n"
11381 "Detailed information on TCP and BGP neighbor connections\n"
11382 "Neighbor to display information about\n"
11383 "Neighbor to display information about\n"
11384 "Neighbor on BGP configured interface\n"
11385 "Display detailed prefix count information\n"
11386 JSON_STR)
11387 {
11388 int idx_peer = 6;
11389 struct peer *peer;
11390 bool uj = use_json(argc, argv);
11391
11392 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
11393 if (!peer)
11394 return CMD_WARNING;
11395
11396 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
11397 }
11398
11399 DEFUN (show_ip_bgp_vpn_all_route_prefix,
11400 show_ip_bgp_vpn_all_route_prefix_cmd,
11401 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
11402 SHOW_STR
11403 IP_STR
11404 BGP_STR
11405 BGP_VPNVX_HELP_STR
11406 "Display information about all VPNv4 NLRIs\n"
11407 "Network in the BGP routing table to display\n"
11408 "Network in the BGP routing table to display\n"
11409 JSON_STR)
11410 {
11411 int idx = 0;
11412 char *network = NULL;
11413 struct bgp *bgp = bgp_get_default();
11414 if (!bgp) {
11415 vty_out(vty, "Can't find default instance\n");
11416 return CMD_WARNING;
11417 }
11418
11419 if (argv_find(argv, argc, "A.B.C.D", &idx))
11420 network = argv[idx]->arg;
11421 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
11422 network = argv[idx]->arg;
11423 else {
11424 vty_out(vty, "Unable to figure out Network\n");
11425 return CMD_WARNING;
11426 }
11427
11428 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
11429 BGP_PATH_SHOW_ALL, use_json(argc, argv));
11430 }
11431 #endif /* KEEP_OLD_VPN_COMMANDS */
11432
11433 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
11434 show_bgp_l2vpn_evpn_route_prefix_cmd,
11435 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
11436 SHOW_STR
11437 BGP_STR
11438 L2VPN_HELP_STR
11439 EVPN_HELP_STR
11440 "Network in the BGP routing table to display\n"
11441 "Network in the BGP routing table to display\n"
11442 "Network in the BGP routing table to display\n"
11443 "Network in the BGP routing table to display\n"
11444 JSON_STR)
11445 {
11446 int idx = 0;
11447 char *network = NULL;
11448 int prefix_check = 0;
11449
11450 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
11451 argv_find(argv, argc, "X:X::X:X", &idx))
11452 network = argv[idx]->arg;
11453 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
11454 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
11455 network = argv[idx]->arg;
11456 prefix_check = 1;
11457 } else {
11458 vty_out(vty, "Unable to figure out Network\n");
11459 return CMD_WARNING;
11460 }
11461 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
11462 prefix_check, BGP_PATH_SHOW_ALL,
11463 use_json(argc, argv));
11464 }
11465
11466 static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
11467 safi_t safi, enum bgp_show_adj_route_type type,
11468 const char *rmap_name, bool use_json,
11469 json_object *json)
11470 {
11471 struct bgp_table *table;
11472 struct bgp_adj_in *ain;
11473 struct bgp_adj_out *adj;
11474 unsigned long output_count;
11475 unsigned long filtered_count;
11476 struct bgp_node *rn;
11477 int header1 = 1;
11478 struct bgp *bgp;
11479 int header2 = 1;
11480 struct attr attr;
11481 int ret;
11482 struct update_subgroup *subgrp;
11483 json_object *json_scode = NULL;
11484 json_object *json_ocode = NULL;
11485 json_object *json_ar = NULL;
11486 struct peer_af *paf;
11487 bool route_filtered;
11488
11489 if (use_json) {
11490 json_scode = json_object_new_object();
11491 json_ocode = json_object_new_object();
11492 json_ar = json_object_new_object();
11493
11494 json_object_string_add(json_scode, "suppressed", "s");
11495 json_object_string_add(json_scode, "damped", "d");
11496 json_object_string_add(json_scode, "history", "h");
11497 json_object_string_add(json_scode, "valid", "*");
11498 json_object_string_add(json_scode, "best", ">");
11499 json_object_string_add(json_scode, "multipath", "=");
11500 json_object_string_add(json_scode, "internal", "i");
11501 json_object_string_add(json_scode, "ribFailure", "r");
11502 json_object_string_add(json_scode, "stale", "S");
11503 json_object_string_add(json_scode, "removed", "R");
11504
11505 json_object_string_add(json_ocode, "igp", "i");
11506 json_object_string_add(json_ocode, "egp", "e");
11507 json_object_string_add(json_ocode, "incomplete", "?");
11508 }
11509
11510 bgp = peer->bgp;
11511
11512 if (!bgp) {
11513 if (use_json) {
11514 json_object_string_add(json, "alert", "no BGP");
11515 vty_out(vty, "%s\n", json_object_to_json_string(json));
11516 json_object_free(json);
11517 } else
11518 vty_out(vty, "%% No bgp\n");
11519 return;
11520 }
11521
11522 /* labeled-unicast routes live in the unicast table */
11523 if (safi == SAFI_LABELED_UNICAST)
11524 table = bgp->rib[afi][SAFI_UNICAST];
11525 else
11526 table = bgp->rib[afi][safi];
11527
11528 output_count = filtered_count = 0;
11529 subgrp = peer_subgroup(peer, afi, safi);
11530
11531 if (type == bgp_show_adj_route_advertised && subgrp
11532 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
11533 if (use_json) {
11534 json_object_int_add(json, "bgpTableVersion",
11535 table->version);
11536 json_object_string_add(json, "bgpLocalRouterId",
11537 inet_ntoa(bgp->router_id));
11538 json_object_int_add(json, "defaultLocPrf",
11539 bgp->default_local_pref);
11540 json_object_int_add(json, "localAS", bgp->as);
11541 json_object_object_add(json, "bgpStatusCodes",
11542 json_scode);
11543 json_object_object_add(json, "bgpOriginCodes",
11544 json_ocode);
11545 json_object_string_add(
11546 json, "bgpOriginatingDefaultNetwork",
11547 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
11548 } else {
11549 vty_out(vty, "BGP table version is %" PRIu64
11550 ", local router ID is %s, vrf id ",
11551 table->version, inet_ntoa(bgp->router_id));
11552 if (bgp->vrf_id == VRF_UNKNOWN)
11553 vty_out(vty, "%s", VRFID_NONE_STR);
11554 else
11555 vty_out(vty, "%u", bgp->vrf_id);
11556 vty_out(vty, "\n");
11557 vty_out(vty, "Default local pref %u, ",
11558 bgp->default_local_pref);
11559 vty_out(vty, "local AS %u\n", bgp->as);
11560 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11561 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11562 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11563
11564 vty_out(vty, "Originating default network %s\n\n",
11565 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
11566 }
11567 header1 = 0;
11568 }
11569
11570 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
11571 if (type == bgp_show_adj_route_received
11572 || type == bgp_show_adj_route_filtered) {
11573 for (ain = rn->adj_in; ain; ain = ain->next) {
11574 if (ain->peer != peer)
11575 continue;
11576
11577 if (header1) {
11578 if (use_json) {
11579 json_object_int_add(
11580 json, "bgpTableVersion",
11581 0);
11582 json_object_string_add(
11583 json,
11584 "bgpLocalRouterId",
11585 inet_ntoa(
11586 bgp->router_id));
11587 json_object_int_add(json,
11588 "defaultLocPrf",
11589 bgp->default_local_pref);
11590 json_object_int_add(json,
11591 "localAS", bgp->as);
11592 json_object_object_add(
11593 json, "bgpStatusCodes",
11594 json_scode);
11595 json_object_object_add(
11596 json, "bgpOriginCodes",
11597 json_ocode);
11598 } else {
11599 vty_out(vty,
11600 "BGP table version is 0, local router ID is %s, vrf id ",
11601 inet_ntoa(
11602 bgp->router_id));
11603 if (bgp->vrf_id == VRF_UNKNOWN)
11604 vty_out(vty, "%s",
11605 VRFID_NONE_STR);
11606 else
11607 vty_out(vty, "%u",
11608 bgp->vrf_id);
11609 vty_out(vty, "\n");
11610 vty_out(vty,
11611 "Default local pref %u, ",
11612 bgp->default_local_pref);
11613 vty_out(vty, "local AS %u\n",
11614 bgp->as);
11615 vty_out(vty,
11616 BGP_SHOW_SCODE_HEADER);
11617 vty_out(vty,
11618 BGP_SHOW_NCODE_HEADER);
11619 vty_out(vty,
11620 BGP_SHOW_OCODE_HEADER);
11621 }
11622 header1 = 0;
11623 }
11624 if (header2) {
11625 if (!use_json)
11626 vty_out(vty, BGP_SHOW_HEADER);
11627 header2 = 0;
11628 }
11629
11630 attr = *ain->attr;
11631 route_filtered = false;
11632
11633 /* Filter prefix using distribute list,
11634 * filter list or prefix list
11635 */
11636 if ((bgp_input_filter(peer, &rn->p, &attr, afi,
11637 safi)) == FILTER_DENY)
11638 route_filtered = true;
11639
11640 /* Filter prefix using route-map */
11641 ret = bgp_input_modifier(peer, &rn->p, &attr,
11642 afi, safi, rmap_name, NULL, 0,
11643 NULL);
11644
11645 if (type == bgp_show_adj_route_filtered &&
11646 !route_filtered && ret != RMAP_DENY) {
11647 bgp_attr_undup(&attr, ain->attr);
11648 continue;
11649 }
11650
11651 if (type == bgp_show_adj_route_received &&
11652 (route_filtered || ret == RMAP_DENY))
11653 filtered_count++;
11654
11655 route_vty_out_tmp(vty, &rn->p, &attr, safi,
11656 use_json, json_ar);
11657 bgp_attr_undup(&attr, ain->attr);
11658 output_count++;
11659 }
11660 } else if (type == bgp_show_adj_route_advertised) {
11661 RB_FOREACH (adj, bgp_adj_out_rb, &rn->adj_out)
11662 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
11663 if (paf->peer != peer || !adj->attr)
11664 continue;
11665
11666 if (header1) {
11667 if (use_json) {
11668 json_object_int_add(
11669 json,
11670 "bgpTableVersion",
11671 table->version);
11672 json_object_string_add(
11673 json,
11674 "bgpLocalRouterId",
11675 inet_ntoa(
11676 bgp->router_id));
11677 json_object_int_add(
11678 json, "defaultLocPrf",
11679 bgp->default_local_pref
11680 );
11681 json_object_int_add(
11682 json, "localAS",
11683 bgp->as);
11684 json_object_object_add(
11685 json,
11686 "bgpStatusCodes",
11687 json_scode);
11688 json_object_object_add(
11689 json,
11690 "bgpOriginCodes",
11691 json_ocode);
11692 } else {
11693 vty_out(vty,
11694 "BGP table version is %" PRIu64
11695 ", local router ID is %s, vrf id ",
11696 table->version,
11697 inet_ntoa(
11698 bgp->router_id));
11699 if (bgp->vrf_id ==
11700 VRF_UNKNOWN)
11701 vty_out(vty,
11702 "%s",
11703 VRFID_NONE_STR);
11704 else
11705 vty_out(vty,
11706 "%u",
11707 bgp->vrf_id);
11708 vty_out(vty, "\n");
11709 vty_out(vty,
11710 "Default local pref %u, ",
11711 bgp->default_local_pref
11712 );
11713 vty_out(vty,
11714 "local AS %u\n",
11715 bgp->as);
11716 vty_out(vty,
11717 BGP_SHOW_SCODE_HEADER);
11718 vty_out(vty,
11719 BGP_SHOW_NCODE_HEADER);
11720 vty_out(vty,
11721 BGP_SHOW_OCODE_HEADER);
11722 }
11723 header1 = 0;
11724 }
11725 if (header2) {
11726 if (!use_json)
11727 vty_out(vty,
11728 BGP_SHOW_HEADER);
11729 header2 = 0;
11730 }
11731
11732 attr = *adj->attr;
11733 ret = bgp_output_modifier(
11734 peer, &rn->p, &attr, afi, safi,
11735 rmap_name);
11736
11737 if (ret != RMAP_DENY) {
11738 route_vty_out_tmp(vty, &rn->p,
11739 &attr, safi,
11740 use_json,
11741 json_ar);
11742 output_count++;
11743 } else {
11744 filtered_count++;
11745 }
11746
11747 bgp_attr_undup(&attr, adj->attr);
11748 }
11749 }
11750 }
11751
11752 if (use_json) {
11753 json_object_object_add(json, "advertisedRoutes", json_ar);
11754 json_object_int_add(json, "totalPrefixCounter", output_count);
11755 json_object_int_add(json, "filteredPrefixCounter",
11756 filtered_count);
11757
11758 vty_out(vty, "%s\n", json_object_to_json_string_ext(
11759 json, JSON_C_TO_STRING_PRETTY));
11760 json_object_free(json);
11761 } else if (output_count > 0) {
11762 if (filtered_count > 0)
11763 vty_out(vty,
11764 "\nTotal number of prefixes %ld (%ld filtered)\n",
11765 output_count, filtered_count);
11766 else
11767 vty_out(vty, "\nTotal number of prefixes %ld\n",
11768 output_count);
11769 }
11770 }
11771
11772 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
11773 safi_t safi, enum bgp_show_adj_route_type type,
11774 const char *rmap_name, bool use_json)
11775 {
11776 json_object *json = NULL;
11777
11778 if (use_json)
11779 json = json_object_new_object();
11780
11781 if (!peer || !peer->afc[afi][safi]) {
11782 if (use_json) {
11783 json_object_string_add(
11784 json, "warning",
11785 "No such neighbor or address family");
11786 vty_out(vty, "%s\n", json_object_to_json_string(json));
11787 json_object_free(json);
11788 } else
11789 vty_out(vty, "%% No such neighbor or address family\n");
11790
11791 return CMD_WARNING;
11792 }
11793
11794 if ((type == bgp_show_adj_route_received
11795 || type == bgp_show_adj_route_filtered)
11796 && !CHECK_FLAG(peer->af_flags[afi][safi],
11797 PEER_FLAG_SOFT_RECONFIG)) {
11798 if (use_json) {
11799 json_object_string_add(
11800 json, "warning",
11801 "Inbound soft reconfiguration not enabled");
11802 vty_out(vty, "%s\n", json_object_to_json_string(json));
11803 json_object_free(json);
11804 } else
11805 vty_out(vty,
11806 "%% Inbound soft reconfiguration not enabled\n");
11807
11808 return CMD_WARNING;
11809 }
11810
11811 show_adj_route(vty, peer, afi, safi, type, rmap_name, use_json, json);
11812
11813 return CMD_SUCCESS;
11814 }
11815
11816 DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
11817 show_ip_bgp_instance_neighbor_advertised_route_cmd,
11818 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
11819 "neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map WORD] [json]",
11820 SHOW_STR
11821 IP_STR
11822 BGP_STR
11823 BGP_INSTANCE_HELP_STR
11824 BGP_AFI_HELP_STR
11825 BGP_SAFI_WITH_LABEL_HELP_STR
11826 "Detailed information on TCP and BGP neighbor connections\n"
11827 "Neighbor to display information about\n"
11828 "Neighbor to display information about\n"
11829 "Neighbor on BGP configured interface\n"
11830 "Display the routes advertised to a BGP neighbor\n"
11831 "Display the received routes from neighbor\n"
11832 "Display the filtered routes received from neighbor\n"
11833 "Route-map to modify the attributes\n"
11834 "Name of the route map\n"
11835 JSON_STR)
11836 {
11837 afi_t afi = AFI_IP6;
11838 safi_t safi = SAFI_UNICAST;
11839 char *rmap_name = NULL;
11840 char *peerstr = NULL;
11841 struct bgp *bgp = NULL;
11842 struct peer *peer;
11843 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
11844 int idx = 0;
11845 bool uj = use_json(argc, argv);
11846
11847 if (uj)
11848 argc--;
11849
11850 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11851 &bgp, uj);
11852 if (!idx)
11853 return CMD_WARNING;
11854
11855 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11856 argv_find(argv, argc, "neighbors", &idx);
11857 peerstr = argv[++idx]->arg;
11858
11859 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
11860 if (!peer)
11861 return CMD_WARNING;
11862
11863 if (argv_find(argv, argc, "advertised-routes", &idx))
11864 type = bgp_show_adj_route_advertised;
11865 else if (argv_find(argv, argc, "received-routes", &idx))
11866 type = bgp_show_adj_route_received;
11867 else if (argv_find(argv, argc, "filtered-routes", &idx))
11868 type = bgp_show_adj_route_filtered;
11869
11870 if (argv_find(argv, argc, "route-map", &idx))
11871 rmap_name = argv[++idx]->arg;
11872
11873 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, uj);
11874 }
11875
11876 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
11877 show_ip_bgp_neighbor_received_prefix_filter_cmd,
11878 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
11879 SHOW_STR
11880 IP_STR
11881 BGP_STR
11882 "Address Family\n"
11883 "Address Family\n"
11884 "Address Family modifier\n"
11885 "Detailed information on TCP and BGP neighbor connections\n"
11886 "Neighbor to display information about\n"
11887 "Neighbor to display information about\n"
11888 "Neighbor on BGP configured interface\n"
11889 "Display information received from a BGP neighbor\n"
11890 "Display the prefixlist filter\n"
11891 JSON_STR)
11892 {
11893 afi_t afi = AFI_IP6;
11894 safi_t safi = SAFI_UNICAST;
11895 char *peerstr = NULL;
11896
11897 char name[BUFSIZ];
11898 union sockunion su;
11899 struct peer *peer;
11900 int count, ret;
11901
11902 int idx = 0;
11903
11904 /* show [ip] bgp */
11905 if (argv_find(argv, argc, "ip", &idx))
11906 afi = AFI_IP;
11907 /* [<ipv4|ipv6> [unicast]] */
11908 if (argv_find(argv, argc, "ipv4", &idx))
11909 afi = AFI_IP;
11910 if (argv_find(argv, argc, "ipv6", &idx))
11911 afi = AFI_IP6;
11912 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11913 argv_find(argv, argc, "neighbors", &idx);
11914 peerstr = argv[++idx]->arg;
11915
11916 bool uj = use_json(argc, argv);
11917
11918 ret = str2sockunion(peerstr, &su);
11919 if (ret < 0) {
11920 peer = peer_lookup_by_conf_if(NULL, peerstr);
11921 if (!peer) {
11922 if (uj)
11923 vty_out(vty, "{}\n");
11924 else
11925 vty_out(vty,
11926 "%% Malformed address or name: %s\n",
11927 peerstr);
11928 return CMD_WARNING;
11929 }
11930 } else {
11931 peer = peer_lookup(NULL, &su);
11932 if (!peer) {
11933 if (uj)
11934 vty_out(vty, "{}\n");
11935 else
11936 vty_out(vty, "No peer\n");
11937 return CMD_WARNING;
11938 }
11939 }
11940
11941 sprintf(name, "%s.%d.%d", peer->host, afi, safi);
11942 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
11943 if (count) {
11944 if (!uj)
11945 vty_out(vty, "Address Family: %s\n",
11946 get_afi_safi_str(afi, safi, false));
11947 prefix_bgp_show_prefix_list(vty, afi, name, uj);
11948 } else {
11949 if (uj)
11950 vty_out(vty, "{}\n");
11951 else
11952 vty_out(vty, "No functional output\n");
11953 }
11954
11955 return CMD_SUCCESS;
11956 }
11957
11958 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
11959 afi_t afi, safi_t safi,
11960 enum bgp_show_type type, bool use_json)
11961 {
11962 /* labeled-unicast routes live in the unicast table */
11963 if (safi == SAFI_LABELED_UNICAST)
11964 safi = SAFI_UNICAST;
11965
11966 if (!peer || !peer->afc[afi][safi]) {
11967 if (use_json) {
11968 json_object *json_no = NULL;
11969 json_no = json_object_new_object();
11970 json_object_string_add(
11971 json_no, "warning",
11972 "No such neighbor or address family");
11973 vty_out(vty, "%s\n",
11974 json_object_to_json_string(json_no));
11975 json_object_free(json_no);
11976 } else
11977 vty_out(vty, "%% No such neighbor or address family\n");
11978 return CMD_WARNING;
11979 }
11980
11981 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, use_json);
11982 }
11983
11984 DEFUN (show_ip_bgp_flowspec_routes_detailed,
11985 show_ip_bgp_flowspec_routes_detailed_cmd,
11986 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
11987 SHOW_STR
11988 IP_STR
11989 BGP_STR
11990 BGP_INSTANCE_HELP_STR
11991 BGP_AFI_HELP_STR
11992 "SAFI Flowspec\n"
11993 "Detailed information on flowspec entries\n"
11994 JSON_STR)
11995 {
11996 afi_t afi = AFI_IP;
11997 safi_t safi = SAFI_UNICAST;
11998 struct bgp *bgp = NULL;
11999 int idx = 0;
12000 bool uj = use_json(argc, argv);
12001
12002 if (uj)
12003 argc--;
12004
12005 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12006 &bgp, uj);
12007 if (!idx)
12008 return CMD_WARNING;
12009
12010 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL, uj);
12011 }
12012
12013 DEFUN (show_ip_bgp_neighbor_routes,
12014 show_ip_bgp_neighbor_routes_cmd,
12015 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
12016 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
12017 SHOW_STR
12018 IP_STR
12019 BGP_STR
12020 BGP_INSTANCE_HELP_STR
12021 BGP_AFI_HELP_STR
12022 BGP_SAFI_WITH_LABEL_HELP_STR
12023 "Detailed information on TCP and BGP neighbor connections\n"
12024 "Neighbor to display information about\n"
12025 "Neighbor to display information about\n"
12026 "Neighbor on BGP configured interface\n"
12027 "Display flap statistics of the routes learned from neighbor\n"
12028 "Display the dampened routes received from neighbor\n"
12029 "Display routes learned from neighbor\n"
12030 JSON_STR)
12031 {
12032 char *peerstr = NULL;
12033 struct bgp *bgp = NULL;
12034 afi_t afi = AFI_IP6;
12035 safi_t safi = SAFI_UNICAST;
12036 struct peer *peer;
12037 enum bgp_show_type sh_type = bgp_show_type_neighbor;
12038 int idx = 0;
12039 bool uj = use_json(argc, argv);
12040
12041 if (uj)
12042 argc--;
12043
12044 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12045 &bgp, uj);
12046 if (!idx)
12047 return CMD_WARNING;
12048
12049 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
12050 argv_find(argv, argc, "neighbors", &idx);
12051 peerstr = argv[++idx]->arg;
12052
12053 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
12054 if (!peer)
12055 return CMD_WARNING;
12056
12057 if (argv_find(argv, argc, "flap-statistics", &idx))
12058 sh_type = bgp_show_type_flap_neighbor;
12059 else if (argv_find(argv, argc, "dampened-routes", &idx))
12060 sh_type = bgp_show_type_damp_neighbor;
12061 else if (argv_find(argv, argc, "routes", &idx))
12062 sh_type = bgp_show_type_neighbor;
12063
12064 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
12065 }
12066
12067 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
12068
12069 struct bgp_distance {
12070 /* Distance value for the IP source prefix. */
12071 uint8_t distance;
12072
12073 /* Name of the access-list to be matched. */
12074 char *access_list;
12075 };
12076
12077 DEFUN (show_bgp_afi_vpn_rd_route,
12078 show_bgp_afi_vpn_rd_route_cmd,
12079 "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]",
12080 SHOW_STR
12081 BGP_STR
12082 BGP_AFI_HELP_STR
12083 "Address Family modifier\n"
12084 "Display information for a route distinguisher\n"
12085 "Route Distinguisher\n"
12086 "Network in the BGP routing table to display\n"
12087 "Network in the BGP routing table to display\n"
12088 JSON_STR)
12089 {
12090 int ret;
12091 struct prefix_rd prd;
12092 afi_t afi = AFI_MAX;
12093 int idx = 0;
12094
12095 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
12096 vty_out(vty, "%% Malformed Address Family\n");
12097 return CMD_WARNING;
12098 }
12099
12100 ret = str2prefix_rd(argv[5]->arg, &prd);
12101 if (!ret) {
12102 vty_out(vty, "%% Malformed Route Distinguisher\n");
12103 return CMD_WARNING;
12104 }
12105
12106 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
12107 0, BGP_PATH_SHOW_ALL, use_json(argc, argv));
12108 }
12109
12110 static struct bgp_distance *bgp_distance_new(void)
12111 {
12112 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
12113 }
12114
12115 static void bgp_distance_free(struct bgp_distance *bdistance)
12116 {
12117 XFREE(MTYPE_BGP_DISTANCE, bdistance);
12118 }
12119
12120 static int bgp_distance_set(struct vty *vty, const char *distance_str,
12121 const char *ip_str, const char *access_list_str)
12122 {
12123 int ret;
12124 afi_t afi;
12125 safi_t safi;
12126 struct prefix p;
12127 uint8_t distance;
12128 struct bgp_node *rn;
12129 struct bgp_distance *bdistance;
12130
12131 afi = bgp_node_afi(vty);
12132 safi = bgp_node_safi(vty);
12133
12134 ret = str2prefix(ip_str, &p);
12135 if (ret == 0) {
12136 vty_out(vty, "Malformed prefix\n");
12137 return CMD_WARNING_CONFIG_FAILED;
12138 }
12139
12140 distance = atoi(distance_str);
12141
12142 /* Get BGP distance node. */
12143 rn = bgp_node_get(bgp_distance_table[afi][safi], (struct prefix *)&p);
12144 bdistance = bgp_node_get_bgp_distance_info(rn);
12145 if (bdistance)
12146 bgp_unlock_node(rn);
12147 else {
12148 bdistance = bgp_distance_new();
12149 bgp_node_set_bgp_distance_info(rn, bdistance);
12150 }
12151
12152 /* Set distance value. */
12153 bdistance->distance = distance;
12154
12155 /* Reset access-list configuration. */
12156 if (bdistance->access_list) {
12157 XFREE(MTYPE_AS_LIST, bdistance->access_list);
12158 bdistance->access_list = NULL;
12159 }
12160 if (access_list_str)
12161 bdistance->access_list =
12162 XSTRDUP(MTYPE_AS_LIST, access_list_str);
12163
12164 return CMD_SUCCESS;
12165 }
12166
12167 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
12168 const char *ip_str, const char *access_list_str)
12169 {
12170 int ret;
12171 afi_t afi;
12172 safi_t safi;
12173 struct prefix p;
12174 int distance;
12175 struct bgp_node *rn;
12176 struct bgp_distance *bdistance;
12177
12178 afi = bgp_node_afi(vty);
12179 safi = bgp_node_safi(vty);
12180
12181 ret = str2prefix(ip_str, &p);
12182 if (ret == 0) {
12183 vty_out(vty, "Malformed prefix\n");
12184 return CMD_WARNING_CONFIG_FAILED;
12185 }
12186
12187 rn = bgp_node_lookup(bgp_distance_table[afi][safi],
12188 (struct prefix *)&p);
12189 if (!rn) {
12190 vty_out(vty, "Can't find specified prefix\n");
12191 return CMD_WARNING_CONFIG_FAILED;
12192 }
12193
12194 bdistance = bgp_node_get_bgp_distance_info(rn);
12195 distance = atoi(distance_str);
12196
12197 if (bdistance->distance != distance) {
12198 vty_out(vty, "Distance does not match configured\n");
12199 return CMD_WARNING_CONFIG_FAILED;
12200 }
12201
12202 XFREE(MTYPE_AS_LIST, bdistance->access_list);
12203 bgp_distance_free(bdistance);
12204
12205 bgp_node_set_bgp_path_info(rn, NULL);
12206 bgp_unlock_node(rn);
12207 bgp_unlock_node(rn);
12208
12209 return CMD_SUCCESS;
12210 }
12211
12212 /* Apply BGP information to distance method. */
12213 uint8_t bgp_distance_apply(struct prefix *p, struct bgp_path_info *pinfo,
12214 afi_t afi, safi_t safi, struct bgp *bgp)
12215 {
12216 struct bgp_node *rn;
12217 struct prefix q;
12218 struct peer *peer;
12219 struct bgp_distance *bdistance;
12220 struct access_list *alist;
12221 struct bgp_static *bgp_static;
12222
12223 if (!bgp)
12224 return 0;
12225
12226 peer = pinfo->peer;
12227
12228 if (pinfo->attr->distance)
12229 return pinfo->attr->distance;
12230
12231 /* Check source address. */
12232 sockunion2hostprefix(&peer->su, &q);
12233 rn = bgp_node_match(bgp_distance_table[afi][safi], &q);
12234 if (rn) {
12235 bdistance = bgp_node_get_bgp_distance_info(rn);
12236 bgp_unlock_node(rn);
12237
12238 if (bdistance->access_list) {
12239 alist = access_list_lookup(afi, bdistance->access_list);
12240 if (alist
12241 && access_list_apply(alist, p) == FILTER_PERMIT)
12242 return bdistance->distance;
12243 } else
12244 return bdistance->distance;
12245 }
12246
12247 /* Backdoor check. */
12248 rn = bgp_node_lookup(bgp->route[afi][safi], p);
12249 if (rn) {
12250 bgp_static = bgp_node_get_bgp_static_info(rn);
12251 bgp_unlock_node(rn);
12252
12253 if (bgp_static->backdoor) {
12254 if (bgp->distance_local[afi][safi])
12255 return bgp->distance_local[afi][safi];
12256 else
12257 return ZEBRA_IBGP_DISTANCE_DEFAULT;
12258 }
12259 }
12260
12261 if (peer->sort == BGP_PEER_EBGP) {
12262 if (bgp->distance_ebgp[afi][safi])
12263 return bgp->distance_ebgp[afi][safi];
12264 return ZEBRA_EBGP_DISTANCE_DEFAULT;
12265 } else {
12266 if (bgp->distance_ibgp[afi][safi])
12267 return bgp->distance_ibgp[afi][safi];
12268 return ZEBRA_IBGP_DISTANCE_DEFAULT;
12269 }
12270 }
12271
12272 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
12273 * we should tell ZEBRA update the routes for a specific
12274 * AFI/SAFI to reflect changes in RIB.
12275 */
12276 static void bgp_announce_routes_distance_update(struct bgp *bgp,
12277 afi_t update_afi,
12278 safi_t update_safi)
12279 {
12280 afi_t afi;
12281 safi_t safi;
12282
12283 FOREACH_AFI_SAFI (afi, safi) {
12284 if (!bgp_fibupd_safi(safi))
12285 continue;
12286
12287 if (afi != update_afi && safi != update_safi)
12288 continue;
12289
12290 if (BGP_DEBUG(zebra, ZEBRA))
12291 zlog_debug(
12292 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
12293 __func__, afi, safi);
12294 bgp_zebra_announce_table(bgp, afi, safi);
12295 }
12296 }
12297
12298 DEFUN (bgp_distance,
12299 bgp_distance_cmd,
12300 "distance bgp (1-255) (1-255) (1-255)",
12301 "Define an administrative distance\n"
12302 "BGP distance\n"
12303 "Distance for routes external to the AS\n"
12304 "Distance for routes internal to the AS\n"
12305 "Distance for local routes\n")
12306 {
12307 VTY_DECLVAR_CONTEXT(bgp, bgp);
12308 int idx_number = 2;
12309 int idx_number_2 = 3;
12310 int idx_number_3 = 4;
12311 int distance_ebgp = atoi(argv[idx_number]->arg);
12312 int distance_ibgp = atoi(argv[idx_number_2]->arg);
12313 int distance_local = atoi(argv[idx_number_3]->arg);
12314 afi_t afi;
12315 safi_t safi;
12316
12317 afi = bgp_node_afi(vty);
12318 safi = bgp_node_safi(vty);
12319
12320 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
12321 || bgp->distance_ibgp[afi][safi] != distance_ibgp
12322 || bgp->distance_local[afi][safi] != distance_local) {
12323 bgp->distance_ebgp[afi][safi] = distance_ebgp;
12324 bgp->distance_ibgp[afi][safi] = distance_ibgp;
12325 bgp->distance_local[afi][safi] = distance_local;
12326 bgp_announce_routes_distance_update(bgp, afi, safi);
12327 }
12328 return CMD_SUCCESS;
12329 }
12330
12331 DEFUN (no_bgp_distance,
12332 no_bgp_distance_cmd,
12333 "no distance bgp [(1-255) (1-255) (1-255)]",
12334 NO_STR
12335 "Define an administrative distance\n"
12336 "BGP distance\n"
12337 "Distance for routes external to the AS\n"
12338 "Distance for routes internal to the AS\n"
12339 "Distance for local routes\n")
12340 {
12341 VTY_DECLVAR_CONTEXT(bgp, bgp);
12342 afi_t afi;
12343 safi_t safi;
12344
12345 afi = bgp_node_afi(vty);
12346 safi = bgp_node_safi(vty);
12347
12348 if (bgp->distance_ebgp[afi][safi] != 0
12349 || bgp->distance_ibgp[afi][safi] != 0
12350 || bgp->distance_local[afi][safi] != 0) {
12351 bgp->distance_ebgp[afi][safi] = 0;
12352 bgp->distance_ibgp[afi][safi] = 0;
12353 bgp->distance_local[afi][safi] = 0;
12354 bgp_announce_routes_distance_update(bgp, afi, safi);
12355 }
12356 return CMD_SUCCESS;
12357 }
12358
12359
12360 DEFUN (bgp_distance_source,
12361 bgp_distance_source_cmd,
12362 "distance (1-255) A.B.C.D/M",
12363 "Define an administrative distance\n"
12364 "Administrative distance\n"
12365 "IP source prefix\n")
12366 {
12367 int idx_number = 1;
12368 int idx_ipv4_prefixlen = 2;
12369 bgp_distance_set(vty, argv[idx_number]->arg,
12370 argv[idx_ipv4_prefixlen]->arg, NULL);
12371 return CMD_SUCCESS;
12372 }
12373
12374 DEFUN (no_bgp_distance_source,
12375 no_bgp_distance_source_cmd,
12376 "no distance (1-255) A.B.C.D/M",
12377 NO_STR
12378 "Define an administrative distance\n"
12379 "Administrative distance\n"
12380 "IP source prefix\n")
12381 {
12382 int idx_number = 2;
12383 int idx_ipv4_prefixlen = 3;
12384 bgp_distance_unset(vty, argv[idx_number]->arg,
12385 argv[idx_ipv4_prefixlen]->arg, NULL);
12386 return CMD_SUCCESS;
12387 }
12388
12389 DEFUN (bgp_distance_source_access_list,
12390 bgp_distance_source_access_list_cmd,
12391 "distance (1-255) A.B.C.D/M WORD",
12392 "Define an administrative distance\n"
12393 "Administrative distance\n"
12394 "IP source prefix\n"
12395 "Access list name\n")
12396 {
12397 int idx_number = 1;
12398 int idx_ipv4_prefixlen = 2;
12399 int idx_word = 3;
12400 bgp_distance_set(vty, argv[idx_number]->arg,
12401 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
12402 return CMD_SUCCESS;
12403 }
12404
12405 DEFUN (no_bgp_distance_source_access_list,
12406 no_bgp_distance_source_access_list_cmd,
12407 "no distance (1-255) A.B.C.D/M WORD",
12408 NO_STR
12409 "Define an administrative distance\n"
12410 "Administrative distance\n"
12411 "IP source prefix\n"
12412 "Access list name\n")
12413 {
12414 int idx_number = 2;
12415 int idx_ipv4_prefixlen = 3;
12416 int idx_word = 4;
12417 bgp_distance_unset(vty, argv[idx_number]->arg,
12418 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
12419 return CMD_SUCCESS;
12420 }
12421
12422 DEFUN (ipv6_bgp_distance_source,
12423 ipv6_bgp_distance_source_cmd,
12424 "distance (1-255) X:X::X:X/M",
12425 "Define an administrative distance\n"
12426 "Administrative distance\n"
12427 "IP source prefix\n")
12428 {
12429 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
12430 return CMD_SUCCESS;
12431 }
12432
12433 DEFUN (no_ipv6_bgp_distance_source,
12434 no_ipv6_bgp_distance_source_cmd,
12435 "no distance (1-255) X:X::X:X/M",
12436 NO_STR
12437 "Define an administrative distance\n"
12438 "Administrative distance\n"
12439 "IP source prefix\n")
12440 {
12441 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
12442 return CMD_SUCCESS;
12443 }
12444
12445 DEFUN (ipv6_bgp_distance_source_access_list,
12446 ipv6_bgp_distance_source_access_list_cmd,
12447 "distance (1-255) X:X::X:X/M WORD",
12448 "Define an administrative distance\n"
12449 "Administrative distance\n"
12450 "IP source prefix\n"
12451 "Access list name\n")
12452 {
12453 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
12454 return CMD_SUCCESS;
12455 }
12456
12457 DEFUN (no_ipv6_bgp_distance_source_access_list,
12458 no_ipv6_bgp_distance_source_access_list_cmd,
12459 "no distance (1-255) X:X::X:X/M WORD",
12460 NO_STR
12461 "Define an administrative distance\n"
12462 "Administrative distance\n"
12463 "IP source prefix\n"
12464 "Access list name\n")
12465 {
12466 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
12467 return CMD_SUCCESS;
12468 }
12469
12470 DEFUN (bgp_damp_set,
12471 bgp_damp_set_cmd,
12472 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
12473 "BGP Specific commands\n"
12474 "Enable route-flap dampening\n"
12475 "Half-life time for the penalty\n"
12476 "Value to start reusing a route\n"
12477 "Value to start suppressing a route\n"
12478 "Maximum duration to suppress a stable route\n")
12479 {
12480 VTY_DECLVAR_CONTEXT(bgp, bgp);
12481 int idx_half_life = 2;
12482 int idx_reuse = 3;
12483 int idx_suppress = 4;
12484 int idx_max_suppress = 5;
12485 int half = DEFAULT_HALF_LIFE * 60;
12486 int reuse = DEFAULT_REUSE;
12487 int suppress = DEFAULT_SUPPRESS;
12488 int max = 4 * half;
12489
12490 if (argc == 6) {
12491 half = atoi(argv[idx_half_life]->arg) * 60;
12492 reuse = atoi(argv[idx_reuse]->arg);
12493 suppress = atoi(argv[idx_suppress]->arg);
12494 max = atoi(argv[idx_max_suppress]->arg) * 60;
12495 } else if (argc == 3) {
12496 half = atoi(argv[idx_half_life]->arg) * 60;
12497 max = 4 * half;
12498 }
12499
12500 /*
12501 * These can't be 0 but our SA doesn't understand the
12502 * way our cli is constructed
12503 */
12504 assert(reuse);
12505 assert(half);
12506 if (suppress < reuse) {
12507 vty_out(vty,
12508 "Suppress value cannot be less than reuse value \n");
12509 return 0;
12510 }
12511
12512 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
12513 reuse, suppress, max);
12514 }
12515
12516 DEFUN (bgp_damp_unset,
12517 bgp_damp_unset_cmd,
12518 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
12519 NO_STR
12520 "BGP Specific commands\n"
12521 "Enable route-flap dampening\n"
12522 "Half-life time for the penalty\n"
12523 "Value to start reusing a route\n"
12524 "Value to start suppressing a route\n"
12525 "Maximum duration to suppress a stable route\n")
12526 {
12527 VTY_DECLVAR_CONTEXT(bgp, bgp);
12528 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
12529 }
12530
12531 /* Display specified route of BGP table. */
12532 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
12533 const char *ip_str, afi_t afi, safi_t safi,
12534 struct prefix_rd *prd, int prefix_check)
12535 {
12536 int ret;
12537 struct prefix match;
12538 struct bgp_node *rn;
12539 struct bgp_node *rm;
12540 struct bgp_path_info *pi;
12541 struct bgp_path_info *pi_temp;
12542 struct bgp *bgp;
12543 struct bgp_table *table;
12544
12545 /* BGP structure lookup. */
12546 if (view_name) {
12547 bgp = bgp_lookup_by_name(view_name);
12548 if (bgp == NULL) {
12549 vty_out(vty, "%% Can't find BGP instance %s\n",
12550 view_name);
12551 return CMD_WARNING;
12552 }
12553 } else {
12554 bgp = bgp_get_default();
12555 if (bgp == NULL) {
12556 vty_out(vty, "%% No BGP process is configured\n");
12557 return CMD_WARNING;
12558 }
12559 }
12560
12561 /* Check IP address argument. */
12562 ret = str2prefix(ip_str, &match);
12563 if (!ret) {
12564 vty_out(vty, "%% address is malformed\n");
12565 return CMD_WARNING;
12566 }
12567
12568 match.family = afi2family(afi);
12569
12570 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
12571 || (safi == SAFI_EVPN)) {
12572 for (rn = bgp_table_top(bgp->rib[AFI_IP][safi]); rn;
12573 rn = bgp_route_next(rn)) {
12574 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
12575 continue;
12576 table = bgp_node_get_bgp_table_info(rn);
12577 if (!table)
12578 continue;
12579 if ((rm = bgp_node_match(table, &match)) == NULL)
12580 continue;
12581
12582 if (!prefix_check
12583 || rm->p.prefixlen == match.prefixlen) {
12584 pi = bgp_node_get_bgp_path_info(rm);
12585 while (pi) {
12586 if (pi->extra && pi->extra->damp_info) {
12587 pi_temp = pi->next;
12588 bgp_damp_info_free(
12589 pi->extra->damp_info,
12590 1, afi, safi);
12591 pi = pi_temp;
12592 } else
12593 pi = pi->next;
12594 }
12595 }
12596
12597 bgp_unlock_node(rm);
12598 }
12599 } else {
12600 if ((rn = bgp_node_match(bgp->rib[afi][safi], &match))
12601 != NULL) {
12602 if (!prefix_check
12603 || rn->p.prefixlen == match.prefixlen) {
12604 pi = bgp_node_get_bgp_path_info(rn);
12605 while (pi) {
12606 if (pi->extra && pi->extra->damp_info) {
12607 pi_temp = pi->next;
12608 bgp_damp_info_free(
12609 pi->extra->damp_info,
12610 1, afi, safi);
12611 pi = pi_temp;
12612 } else
12613 pi = pi->next;
12614 }
12615 }
12616
12617 bgp_unlock_node(rn);
12618 }
12619 }
12620
12621 return CMD_SUCCESS;
12622 }
12623
12624 DEFUN (clear_ip_bgp_dampening,
12625 clear_ip_bgp_dampening_cmd,
12626 "clear ip bgp dampening",
12627 CLEAR_STR
12628 IP_STR
12629 BGP_STR
12630 "Clear route flap dampening information\n")
12631 {
12632 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
12633 return CMD_SUCCESS;
12634 }
12635
12636 DEFUN (clear_ip_bgp_dampening_prefix,
12637 clear_ip_bgp_dampening_prefix_cmd,
12638 "clear ip bgp dampening A.B.C.D/M",
12639 CLEAR_STR
12640 IP_STR
12641 BGP_STR
12642 "Clear route flap dampening information\n"
12643 "IPv4 prefix\n")
12644 {
12645 int idx_ipv4_prefixlen = 4;
12646 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
12647 AFI_IP, SAFI_UNICAST, NULL, 1);
12648 }
12649
12650 DEFUN (clear_ip_bgp_dampening_address,
12651 clear_ip_bgp_dampening_address_cmd,
12652 "clear ip bgp dampening A.B.C.D",
12653 CLEAR_STR
12654 IP_STR
12655 BGP_STR
12656 "Clear route flap dampening information\n"
12657 "Network to clear damping information\n")
12658 {
12659 int idx_ipv4 = 4;
12660 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
12661 SAFI_UNICAST, NULL, 0);
12662 }
12663
12664 DEFUN (clear_ip_bgp_dampening_address_mask,
12665 clear_ip_bgp_dampening_address_mask_cmd,
12666 "clear ip bgp dampening A.B.C.D A.B.C.D",
12667 CLEAR_STR
12668 IP_STR
12669 BGP_STR
12670 "Clear route flap dampening information\n"
12671 "Network to clear damping information\n"
12672 "Network mask\n")
12673 {
12674 int idx_ipv4 = 4;
12675 int idx_ipv4_2 = 5;
12676 int ret;
12677 char prefix_str[BUFSIZ];
12678
12679 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
12680 prefix_str);
12681 if (!ret) {
12682 vty_out(vty, "%% Inconsistent address and mask\n");
12683 return CMD_WARNING;
12684 }
12685
12686 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
12687 NULL, 0);
12688 }
12689
12690 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
12691 {
12692 struct vty *vty = arg;
12693 struct peer *peer = bucket->data;
12694 char buf[SU_ADDRSTRLEN];
12695
12696 vty_out(vty, "\tPeer: %s %s\n", peer->host,
12697 sockunion2str(&peer->su, buf, sizeof(buf)));
12698 }
12699
12700 DEFUN (show_bgp_peerhash,
12701 show_bgp_peerhash_cmd,
12702 "show bgp peerhash",
12703 SHOW_STR
12704 BGP_STR
12705 "Display information about the BGP peerhash\n")
12706 {
12707 struct list *instances = bm->bgp;
12708 struct listnode *node;
12709 struct bgp *bgp;
12710
12711 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
12712 vty_out(vty, "BGP: %s\n", bgp->name);
12713 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
12714 vty);
12715 }
12716
12717 return CMD_SUCCESS;
12718 }
12719
12720 /* also used for encap safi */
12721 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
12722 afi_t afi, safi_t safi)
12723 {
12724 struct bgp_node *prn;
12725 struct bgp_node *rn;
12726 struct bgp_table *table;
12727 struct prefix *p;
12728 struct prefix_rd *prd;
12729 struct bgp_static *bgp_static;
12730 mpls_label_t label;
12731 char buf[SU_ADDRSTRLEN];
12732 char rdbuf[RD_ADDRSTRLEN];
12733
12734 /* Network configuration. */
12735 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
12736 prn = bgp_route_next(prn)) {
12737 table = bgp_node_get_bgp_table_info(prn);
12738 if (!table)
12739 continue;
12740
12741 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
12742 bgp_static = bgp_node_get_bgp_static_info(rn);
12743 if (bgp_static == NULL)
12744 continue;
12745
12746 p = &rn->p;
12747 prd = (struct prefix_rd *)&prn->p;
12748
12749 /* "network" configuration display. */
12750 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
12751 label = decode_label(&bgp_static->label);
12752
12753 vty_out(vty, " network %s/%d rd %s",
12754 inet_ntop(p->family, &p->u.prefix, buf,
12755 SU_ADDRSTRLEN),
12756 p->prefixlen, rdbuf);
12757 if (safi == SAFI_MPLS_VPN)
12758 vty_out(vty, " label %u", label);
12759
12760 if (bgp_static->rmap.name)
12761 vty_out(vty, " route-map %s",
12762 bgp_static->rmap.name);
12763
12764 if (bgp_static->backdoor)
12765 vty_out(vty, " backdoor");
12766
12767 vty_out(vty, "\n");
12768 }
12769 }
12770 }
12771
12772 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
12773 afi_t afi, safi_t safi)
12774 {
12775 struct bgp_node *prn;
12776 struct bgp_node *rn;
12777 struct bgp_table *table;
12778 struct prefix *p;
12779 struct prefix_rd *prd;
12780 struct bgp_static *bgp_static;
12781 char buf[PREFIX_STRLEN * 2];
12782 char buf2[SU_ADDRSTRLEN];
12783 char rdbuf[RD_ADDRSTRLEN];
12784
12785 /* Network configuration. */
12786 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
12787 prn = bgp_route_next(prn)) {
12788 table = bgp_node_get_bgp_table_info(prn);
12789 if (!table)
12790 continue;
12791
12792 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
12793 bgp_static = bgp_node_get_bgp_static_info(rn);
12794 if (bgp_static == NULL)
12795 continue;
12796
12797 char *macrouter = NULL;
12798 char *esi = NULL;
12799
12800 if (bgp_static->router_mac)
12801 macrouter = prefix_mac2str(
12802 bgp_static->router_mac, NULL, 0);
12803 if (bgp_static->eth_s_id)
12804 esi = esi2str(bgp_static->eth_s_id);
12805 p = &rn->p;
12806 prd = (struct prefix_rd *)&prn->p;
12807
12808 /* "network" configuration display. */
12809 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
12810 if (p->u.prefix_evpn.route_type == 5) {
12811 char local_buf[PREFIX_STRLEN];
12812 uint8_t family = is_evpn_prefix_ipaddr_v4((
12813 struct prefix_evpn *)p)
12814 ? AF_INET
12815 : AF_INET6;
12816 inet_ntop(family,
12817 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
12818 local_buf, PREFIX_STRLEN);
12819 sprintf(buf, "%s/%u", local_buf,
12820 p->u.prefix_evpn.prefix_addr.ip_prefix_length);
12821 } else {
12822 prefix2str(p, buf, sizeof(buf));
12823 }
12824
12825 if (bgp_static->gatewayIp.family == AF_INET
12826 || bgp_static->gatewayIp.family == AF_INET6)
12827 inet_ntop(bgp_static->gatewayIp.family,
12828 &bgp_static->gatewayIp.u.prefix, buf2,
12829 sizeof(buf2));
12830 vty_out(vty,
12831 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
12832 buf, rdbuf,
12833 p->u.prefix_evpn.prefix_addr.eth_tag,
12834 decode_label(&bgp_static->label), esi, buf2,
12835 macrouter);
12836
12837 XFREE(MTYPE_TMP, macrouter);
12838 XFREE(MTYPE_TMP, esi);
12839 }
12840 }
12841 }
12842
12843 /* Configuration of static route announcement and aggregate
12844 information. */
12845 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
12846 safi_t safi)
12847 {
12848 struct bgp_node *rn;
12849 struct prefix *p;
12850 struct bgp_static *bgp_static;
12851 struct bgp_aggregate *bgp_aggregate;
12852 char buf[SU_ADDRSTRLEN];
12853
12854 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
12855 bgp_config_write_network_vpn(vty, bgp, afi, safi);
12856 return;
12857 }
12858
12859 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
12860 bgp_config_write_network_evpn(vty, bgp, afi, safi);
12861 return;
12862 }
12863
12864 /* Network configuration. */
12865 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
12866 rn = bgp_route_next(rn)) {
12867 bgp_static = bgp_node_get_bgp_static_info(rn);
12868 if (bgp_static == NULL)
12869 continue;
12870
12871 p = &rn->p;
12872
12873 vty_out(vty, " network %s/%d",
12874 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
12875 p->prefixlen);
12876
12877 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
12878 vty_out(vty, " label-index %u",
12879 bgp_static->label_index);
12880
12881 if (bgp_static->rmap.name)
12882 vty_out(vty, " route-map %s", bgp_static->rmap.name);
12883
12884 if (bgp_static->backdoor)
12885 vty_out(vty, " backdoor");
12886
12887 vty_out(vty, "\n");
12888 }
12889
12890 /* Aggregate-address configuration. */
12891 for (rn = bgp_table_top(bgp->aggregate[afi][safi]); rn;
12892 rn = bgp_route_next(rn)) {
12893 bgp_aggregate = bgp_node_get_bgp_aggregate_info(rn);
12894 if (bgp_aggregate == NULL)
12895 continue;
12896
12897 p = &rn->p;
12898
12899 vty_out(vty, " aggregate-address %s/%d",
12900 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
12901 p->prefixlen);
12902
12903 if (bgp_aggregate->as_set)
12904 vty_out(vty, " as-set");
12905
12906 if (bgp_aggregate->summary_only)
12907 vty_out(vty, " summary-only");
12908
12909 if (bgp_aggregate->rmap.name)
12910 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
12911
12912 vty_out(vty, "\n");
12913 }
12914 }
12915
12916 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
12917 safi_t safi)
12918 {
12919 struct bgp_node *rn;
12920 struct bgp_distance *bdistance;
12921
12922 /* Distance configuration. */
12923 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
12924 && bgp->distance_local[afi][safi]
12925 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
12926 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
12927 || bgp->distance_local[afi][safi]
12928 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
12929 vty_out(vty, " distance bgp %d %d %d\n",
12930 bgp->distance_ebgp[afi][safi],
12931 bgp->distance_ibgp[afi][safi],
12932 bgp->distance_local[afi][safi]);
12933 }
12934
12935 for (rn = bgp_table_top(bgp_distance_table[afi][safi]); rn;
12936 rn = bgp_route_next(rn)) {
12937 bdistance = bgp_node_get_bgp_distance_info(rn);
12938 if (bdistance != NULL) {
12939 char buf[PREFIX_STRLEN];
12940
12941 vty_out(vty, " distance %d %s %s\n",
12942 bdistance->distance,
12943 prefix2str(&rn->p, buf, sizeof(buf)),
12944 bdistance->access_list ? bdistance->access_list
12945 : "");
12946 }
12947 }
12948 }
12949
12950 /* Allocate routing table structure and install commands. */
12951 void bgp_route_init(void)
12952 {
12953 afi_t afi;
12954 safi_t safi;
12955
12956 /* Init BGP distance table. */
12957 FOREACH_AFI_SAFI (afi, safi)
12958 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
12959
12960 /* IPv4 BGP commands. */
12961 install_element(BGP_NODE, &bgp_table_map_cmd);
12962 install_element(BGP_NODE, &bgp_network_cmd);
12963 install_element(BGP_NODE, &no_bgp_table_map_cmd);
12964
12965 install_element(BGP_NODE, &aggregate_address_cmd);
12966 install_element(BGP_NODE, &aggregate_address_mask_cmd);
12967 install_element(BGP_NODE, &no_aggregate_address_cmd);
12968 install_element(BGP_NODE, &no_aggregate_address_mask_cmd);
12969
12970 /* IPv4 unicast configuration. */
12971 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
12972 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
12973 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
12974
12975 install_element(BGP_IPV4_NODE, &aggregate_address_cmd);
12976 install_element(BGP_IPV4_NODE, &aggregate_address_mask_cmd);
12977 install_element(BGP_IPV4_NODE, &no_aggregate_address_cmd);
12978 install_element(BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
12979
12980 /* IPv4 multicast configuration. */
12981 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
12982 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
12983 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
12984 install_element(BGP_IPV4M_NODE, &aggregate_address_cmd);
12985 install_element(BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
12986 install_element(BGP_IPV4M_NODE, &no_aggregate_address_cmd);
12987 install_element(BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
12988
12989 /* IPv4 labeled-unicast configuration. */
12990 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
12991 install_element(VIEW_NODE, &show_ip_bgp_cmd);
12992 install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
12993 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
12994 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
12995
12996 install_element(VIEW_NODE,
12997 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
12998 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
12999 install_element(VIEW_NODE,
13000 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
13001 #ifdef KEEP_OLD_VPN_COMMANDS
13002 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
13003 #endif /* KEEP_OLD_VPN_COMMANDS */
13004 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
13005 install_element(VIEW_NODE,
13006 &show_bgp_l2vpn_evpn_route_prefix_cmd);
13007
13008 /* BGP dampening clear commands */
13009 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
13010 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
13011
13012 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
13013 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
13014
13015 /* prefix count */
13016 install_element(ENABLE_NODE,
13017 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
13018 #ifdef KEEP_OLD_VPN_COMMANDS
13019 install_element(ENABLE_NODE,
13020 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
13021 #endif /* KEEP_OLD_VPN_COMMANDS */
13022
13023 /* New config IPv6 BGP commands. */
13024 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
13025 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
13026 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
13027
13028 install_element(BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
13029 install_element(BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
13030
13031 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
13032
13033 install_element(BGP_NODE, &bgp_distance_cmd);
13034 install_element(BGP_NODE, &no_bgp_distance_cmd);
13035 install_element(BGP_NODE, &bgp_distance_source_cmd);
13036 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
13037 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
13038 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
13039 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
13040 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
13041 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
13042 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
13043 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
13044 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
13045 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
13046 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
13047 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
13048 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
13049 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
13050 install_element(BGP_IPV4M_NODE,
13051 &no_bgp_distance_source_access_list_cmd);
13052 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
13053 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
13054 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
13055 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
13056 install_element(BGP_IPV6_NODE,
13057 &ipv6_bgp_distance_source_access_list_cmd);
13058 install_element(BGP_IPV6_NODE,
13059 &no_ipv6_bgp_distance_source_access_list_cmd);
13060 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
13061 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
13062 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
13063 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
13064 install_element(BGP_IPV6M_NODE,
13065 &ipv6_bgp_distance_source_access_list_cmd);
13066 install_element(BGP_IPV6M_NODE,
13067 &no_ipv6_bgp_distance_source_access_list_cmd);
13068
13069 install_element(BGP_NODE, &bgp_damp_set_cmd);
13070 install_element(BGP_NODE, &bgp_damp_unset_cmd);
13071 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
13072 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
13073
13074 /* IPv4 Multicast Mode */
13075 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
13076 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
13077
13078 /* Large Communities */
13079 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
13080 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
13081
13082 /* show bgp ipv4 flowspec detailed */
13083 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
13084
13085 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
13086 }
13087
13088 void bgp_route_finish(void)
13089 {
13090 afi_t afi;
13091 safi_t safi;
13092
13093 FOREACH_AFI_SAFI (afi, safi) {
13094 bgp_table_unlock(bgp_distance_table[afi][safi]);
13095 bgp_distance_table[afi][safi] = NULL;
13096 }
13097 }