]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
bgpd: Add 'rd all' keyword to EVPN/L3VPN show cmds
[mirror_frr.git] / bgpd / bgp_route.c
1 /* BGP routing information
2 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 * Copyright (C) 2016 Job Snijders <job@instituut.net>
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <zebra.h>
23 #include <math.h>
24
25 #include "printfrr.h"
26 #include "prefix.h"
27 #include "linklist.h"
28 #include "memory.h"
29 #include "command.h"
30 #include "stream.h"
31 #include "filter.h"
32 #include "log.h"
33 #include "routemap.h"
34 #include "buffer.h"
35 #include "sockunion.h"
36 #include "plist.h"
37 #include "thread.h"
38 #include "workqueue.h"
39 #include "queue.h"
40 #include "memory.h"
41 #include "srv6.h"
42 #include "lib/json.h"
43 #include "lib_errors.h"
44 #include "zclient.h"
45 #include "bgpd/bgpd.h"
46 #include "bgpd/bgp_table.h"
47 #include "bgpd/bgp_route.h"
48 #include "bgpd/bgp_attr.h"
49 #include "bgpd/bgp_debug.h"
50 #include "bgpd/bgp_errors.h"
51 #include "bgpd/bgp_aspath.h"
52 #include "bgpd/bgp_regex.h"
53 #include "bgpd/bgp_community.h"
54 #include "bgpd/bgp_ecommunity.h"
55 #include "bgpd/bgp_lcommunity.h"
56 #include "bgpd/bgp_clist.h"
57 #include "bgpd/bgp_packet.h"
58 #include "bgpd/bgp_filter.h"
59 #include "bgpd/bgp_fsm.h"
60 #include "bgpd/bgp_mplsvpn.h"
61 #include "bgpd/bgp_nexthop.h"
62 #include "bgpd/bgp_damp.h"
63 #include "bgpd/bgp_advertise.h"
64 #include "bgpd/bgp_zebra.h"
65 #include "bgpd/bgp_vty.h"
66 #include "bgpd/bgp_mpath.h"
67 #include "bgpd/bgp_nht.h"
68 #include "bgpd/bgp_updgrp.h"
69 #include "bgpd/bgp_label.h"
70 #include "bgpd/bgp_addpath.h"
71 #include "bgpd/bgp_mac.h"
72 #include "bgpd/bgp_network.h"
73 #include "bgpd/bgp_trace.h"
74
75 #ifdef ENABLE_BGP_VNC
76 #include "bgpd/rfapi/rfapi_backend.h"
77 #include "bgpd/rfapi/vnc_import_bgp.h"
78 #include "bgpd/rfapi/vnc_export_bgp.h"
79 #endif
80 #include "bgpd/bgp_encap_types.h"
81 #include "bgpd/bgp_encap_tlv.h"
82 #include "bgpd/bgp_evpn.h"
83 #include "bgpd/bgp_evpn_mh.h"
84 #include "bgpd/bgp_evpn_vty.h"
85 #include "bgpd/bgp_flowspec.h"
86 #include "bgpd/bgp_flowspec_util.h"
87 #include "bgpd/bgp_pbr.h"
88 #include "northbound.h"
89 #include "northbound_cli.h"
90 #include "bgpd/bgp_nb.h"
91
92 #ifndef VTYSH_EXTRACT_PL
93 #include "bgpd/bgp_route_clippy.c"
94 #endif
95
96 DEFINE_HOOK(bgp_snmp_update_stats,
97 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
98 (rn, pi, added))
99
100 DEFINE_HOOK(bgp_rpki_prefix_status,
101 (struct peer *peer, struct attr *attr,
102 const struct prefix *prefix),
103 (peer, attr, prefix))
104
105 /* Extern from bgp_dump.c */
106 extern const char *bgp_origin_str[];
107 extern const char *bgp_origin_long_str[];
108
109 /* PMSI strings. */
110 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
111 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
112 static const struct message bgp_pmsi_tnltype_str[] = {
113 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
114 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
115 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
116 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
117 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
118 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
119 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
120 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
121 {0}
122 };
123
124 #define VRFID_NONE_STR "-"
125
126 DEFINE_HOOK(bgp_process,
127 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
128 struct peer *peer, bool withdraw),
129 (bgp, afi, safi, bn, peer, withdraw))
130
131 /** Test if path is suppressed. */
132 static bool bgp_path_suppressed(struct bgp_path_info *pi)
133 {
134 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
135 return false;
136
137 return listcount(pi->extra->aggr_suppressors) > 0;
138 }
139
140 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
141 safi_t safi, const struct prefix *p,
142 struct prefix_rd *prd)
143 {
144 struct bgp_dest *dest;
145 struct bgp_dest *pdest = NULL;
146
147 assert(table);
148
149 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
150 || (safi == SAFI_EVPN)) {
151 pdest = bgp_node_get(table, (struct prefix *)prd);
152
153 if (!bgp_dest_has_bgp_path_info_data(pdest))
154 bgp_dest_set_bgp_table_info(
155 pdest, bgp_table_init(table->bgp, afi, safi));
156 else
157 bgp_dest_unlock_node(pdest);
158 table = bgp_dest_get_bgp_table_info(pdest);
159 }
160
161 dest = bgp_node_get(table, p);
162
163 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
164 || (safi == SAFI_EVPN))
165 dest->pdest = pdest;
166
167 return dest;
168 }
169
170 struct bgp_dest *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
171 safi_t safi, const struct prefix *p,
172 struct prefix_rd *prd)
173 {
174 struct bgp_dest *dest;
175 struct bgp_dest *pdest = NULL;
176
177 if (!table)
178 return NULL;
179
180 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
181 || (safi == SAFI_EVPN)) {
182 pdest = bgp_node_lookup(table, (struct prefix *)prd);
183 if (!pdest)
184 return NULL;
185
186 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
187 bgp_dest_unlock_node(pdest);
188 return NULL;
189 }
190
191 table = bgp_dest_get_bgp_table_info(pdest);
192 }
193
194 dest = bgp_node_lookup(table, p);
195
196 return dest;
197 }
198
199 /* Allocate bgp_path_info_extra */
200 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
201 {
202 struct bgp_path_info_extra *new;
203 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
204 sizeof(struct bgp_path_info_extra));
205 new->label[0] = MPLS_INVALID_LABEL;
206 new->num_labels = 0;
207 new->bgp_fs_pbr = NULL;
208 new->bgp_fs_iprule = NULL;
209 return new;
210 }
211
212 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
213 {
214 struct bgp_path_info_extra *e;
215
216 if (!extra || !*extra)
217 return;
218
219 e = *extra;
220
221 e->damp_info = NULL;
222 if (e->parent) {
223 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
224
225 if (bpi->net) {
226 /* FIXME: since multiple e may have the same e->parent
227 * and e->parent->net is holding a refcount for each
228 * of them, we need to do some fudging here.
229 *
230 * WARNING: if bpi->net->lock drops to 0, bpi may be
231 * freed as well (because bpi->net was holding the
232 * last reference to bpi) => write after free!
233 */
234 unsigned refcount;
235
236 bpi = bgp_path_info_lock(bpi);
237 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
238 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
239 if (!refcount)
240 bpi->net = NULL;
241 bgp_path_info_unlock(bpi);
242 }
243 bgp_path_info_unlock(e->parent);
244 e->parent = NULL;
245 }
246
247 if (e->bgp_orig)
248 bgp_unlock(e->bgp_orig);
249
250 if (e->aggr_suppressors)
251 list_delete(&e->aggr_suppressors);
252
253 if (e->es_info)
254 bgp_evpn_path_es_info_free(e->es_info);
255
256 if ((*extra)->bgp_fs_iprule)
257 list_delete(&((*extra)->bgp_fs_iprule));
258 if ((*extra)->bgp_fs_pbr)
259 list_delete(&((*extra)->bgp_fs_pbr));
260 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
261 }
262
263 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
264 * allocated if required.
265 */
266 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
267 {
268 if (!pi->extra)
269 pi->extra = bgp_path_info_extra_new();
270 return pi->extra;
271 }
272
273 /* Free bgp route information. */
274 static void bgp_path_info_free(struct bgp_path_info *path)
275 {
276 bgp_attr_unintern(&path->attr);
277
278 bgp_unlink_nexthop(path);
279 bgp_path_info_extra_free(&path->extra);
280 bgp_path_info_mpath_free(&path->mpath);
281 if (path->net)
282 bgp_addpath_free_info_data(&path->tx_addpath,
283 &path->net->tx_addpath);
284
285 peer_unlock(path->peer); /* bgp_path_info peer reference */
286
287 XFREE(MTYPE_BGP_ROUTE, path);
288 }
289
290 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
291 {
292 path->lock++;
293 return path;
294 }
295
296 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
297 {
298 assert(path && path->lock > 0);
299 path->lock--;
300
301 if (path->lock == 0) {
302 #if 0
303 zlog_debug ("%s: unlocked and freeing", __func__);
304 zlog_backtrace (LOG_DEBUG);
305 #endif
306 bgp_path_info_free(path);
307 return NULL;
308 }
309
310 #if 0
311 if (path->lock == 1)
312 {
313 zlog_debug ("%s: unlocked to 1", __func__);
314 zlog_backtrace (LOG_DEBUG);
315 }
316 #endif
317
318 return path;
319 }
320
321 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
322 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
323 {
324 struct peer *peer;
325 struct bgp_path_info *old_pi, *nextpi;
326 bool set_flag = false;
327 struct bgp *bgp = NULL;
328 struct bgp_table *table = NULL;
329 afi_t afi = 0;
330 safi_t safi = 0;
331
332 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
333 * then the route selection is deferred
334 */
335 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
336 return 0;
337
338 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
339 if (BGP_DEBUG(update, UPDATE_OUT))
340 zlog_debug(
341 "Route %pBD is in workqueue and being processed, not deferred.",
342 dest);
343
344 return 0;
345 }
346
347 table = bgp_dest_table(dest);
348 if (table) {
349 bgp = table->bgp;
350 afi = table->afi;
351 safi = table->safi;
352 }
353
354 for (old_pi = bgp_dest_get_bgp_path_info(dest);
355 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
356 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
357 continue;
358
359 /* Route selection is deferred if there is a stale path which
360 * which indicates peer is in restart mode
361 */
362 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
363 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
364 set_flag = true;
365 } else {
366 /* If the peer is graceful restart capable and peer is
367 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
368 */
369 peer = old_pi->peer;
370 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
371 && BGP_PEER_RESTARTING_MODE(peer)
372 && (old_pi
373 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
374 set_flag = true;
375 }
376 }
377 if (set_flag)
378 break;
379 }
380
381 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
382 * is active
383 */
384 if (set_flag && table) {
385 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
386 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
387 bgp->gr_info[afi][safi].gr_deferred++;
388 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
389 if (BGP_DEBUG(update, UPDATE_OUT))
390 zlog_debug("DEFER route %pBD, dest %p", dest,
391 dest);
392 return 0;
393 }
394 }
395 return -1;
396 }
397
398 void bgp_path_info_add(struct bgp_dest *dest, struct bgp_path_info *pi)
399 {
400 struct bgp_path_info *top;
401
402 top = bgp_dest_get_bgp_path_info(dest);
403
404 pi->next = top;
405 pi->prev = NULL;
406 if (top)
407 top->prev = pi;
408 bgp_dest_set_bgp_path_info(dest, pi);
409
410 bgp_path_info_lock(pi);
411 bgp_dest_lock_node(dest);
412 peer_lock(pi->peer); /* bgp_path_info peer reference */
413 bgp_dest_set_defer_flag(dest, false);
414 hook_call(bgp_snmp_update_stats, dest, pi, true);
415 }
416
417 /* Do the actual removal of info from RIB, for use by bgp_process
418 completion callback *only* */
419 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
420 {
421 if (pi->next)
422 pi->next->prev = pi->prev;
423 if (pi->prev)
424 pi->prev->next = pi->next;
425 else
426 bgp_dest_set_bgp_path_info(dest, pi->next);
427
428 bgp_path_info_mpath_dequeue(pi);
429 bgp_path_info_unlock(pi);
430 hook_call(bgp_snmp_update_stats, dest, pi, false);
431 bgp_dest_unlock_node(dest);
432 }
433
434 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
435 {
436 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
437 /* set of previous already took care of pcount */
438 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
439 }
440
441 /* undo the effects of a previous call to bgp_path_info_delete; typically
442 called when a route is deleted and then quickly re-added before the
443 deletion has been processed */
444 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
445 {
446 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
447 /* unset of previous already took care of pcount */
448 SET_FLAG(pi->flags, BGP_PATH_VALID);
449 }
450
451 /* Adjust pcount as required */
452 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
453 {
454 struct bgp_table *table;
455
456 assert(dest && bgp_dest_table(dest));
457 assert(pi && pi->peer && pi->peer->bgp);
458
459 table = bgp_dest_table(dest);
460
461 if (pi->peer == pi->peer->bgp->peer_self)
462 return;
463
464 if (!BGP_PATH_COUNTABLE(pi)
465 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
466
467 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
468
469 /* slight hack, but more robust against errors. */
470 if (pi->peer->pcount[table->afi][table->safi])
471 pi->peer->pcount[table->afi][table->safi]--;
472 else
473 flog_err(EC_LIB_DEVELOPMENT,
474 "Asked to decrement 0 prefix count for peer");
475 } else if (BGP_PATH_COUNTABLE(pi)
476 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
477 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
478 pi->peer->pcount[table->afi][table->safi]++;
479 }
480 }
481
482 static int bgp_label_index_differs(struct bgp_path_info *pi1,
483 struct bgp_path_info *pi2)
484 {
485 return (!(pi1->attr->label_index == pi2->attr->label_index));
486 }
487
488 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
489 * This is here primarily to keep prefix-count in check.
490 */
491 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
492 uint32_t flag)
493 {
494 SET_FLAG(pi->flags, flag);
495
496 /* early bath if we know it's not a flag that changes countability state
497 */
498 if (!CHECK_FLAG(flag,
499 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
500 return;
501
502 bgp_pcount_adjust(dest, pi);
503 }
504
505 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
506 uint32_t flag)
507 {
508 UNSET_FLAG(pi->flags, flag);
509
510 /* early bath if we know it's not a flag that changes countability state
511 */
512 if (!CHECK_FLAG(flag,
513 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
514 return;
515
516 bgp_pcount_adjust(dest, pi);
517 }
518
519 /* Get MED value. If MED value is missing and "bgp bestpath
520 missing-as-worst" is specified, treat it as the worst value. */
521 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
522 {
523 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
524 return attr->med;
525 else {
526 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
527 return BGP_MED_MAX;
528 else
529 return 0;
530 }
531 }
532
533 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
534 size_t buf_len)
535 {
536 if (pi->addpath_rx_id)
537 snprintf(buf, buf_len, "path %s (addpath rxid %d)",
538 pi->peer->host, pi->addpath_rx_id);
539 else
540 snprintf(buf, buf_len, "path %s", pi->peer->host);
541 }
542
543 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
544 */
545 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
546 struct bgp_path_info *exist, int *paths_eq,
547 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
548 char *pfx_buf, afi_t afi, safi_t safi,
549 enum bgp_path_selection_reason *reason)
550 {
551 struct attr *newattr, *existattr;
552 bgp_peer_sort_t new_sort;
553 bgp_peer_sort_t exist_sort;
554 uint32_t new_pref;
555 uint32_t exist_pref;
556 uint32_t new_med;
557 uint32_t exist_med;
558 uint32_t new_weight;
559 uint32_t exist_weight;
560 uint32_t newm, existm;
561 struct in_addr new_id;
562 struct in_addr exist_id;
563 int new_cluster;
564 int exist_cluster;
565 int internal_as_route;
566 int confed_as_route;
567 int ret = 0;
568 char new_buf[PATH_ADDPATH_STR_BUFFER];
569 char exist_buf[PATH_ADDPATH_STR_BUFFER];
570 uint32_t new_mm_seq;
571 uint32_t exist_mm_seq;
572 int nh_cmp;
573 esi_t *exist_esi;
574 esi_t *new_esi;
575 bool same_esi;
576 bool old_proxy;
577 bool new_proxy;
578 bool new_origin, exist_origin;
579
580 *paths_eq = 0;
581
582 /* 0. Null check. */
583 if (new == NULL) {
584 *reason = bgp_path_selection_none;
585 if (debug)
586 zlog_debug("%s: new is NULL", pfx_buf);
587 return 0;
588 }
589
590 if (debug)
591 bgp_path_info_path_with_addpath_rx_str(new, new_buf,
592 sizeof(new_buf));
593
594 if (exist == NULL) {
595 *reason = bgp_path_selection_first;
596 if (debug)
597 zlog_debug("%s: %s is the initial bestpath", pfx_buf,
598 new_buf);
599 return 1;
600 }
601
602 if (debug) {
603 bgp_path_info_path_with_addpath_rx_str(exist, exist_buf,
604 sizeof(exist_buf));
605 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
606 pfx_buf, new_buf, new->flags, exist_buf,
607 exist->flags);
608 }
609
610 newattr = new->attr;
611 existattr = exist->attr;
612
613 /* For EVPN routes, we cannot just go by local vs remote, we have to
614 * look at the MAC mobility sequence number, if present.
615 */
616 if (safi == SAFI_EVPN) {
617 /* This is an error condition described in RFC 7432 Section
618 * 15.2. The RFC
619 * states that in this scenario "the PE MUST alert the operator"
620 * but it
621 * does not state what other action to take. In order to provide
622 * some
623 * consistency in this scenario we are going to prefer the path
624 * with the
625 * sticky flag.
626 */
627 if (newattr->sticky != existattr->sticky) {
628 if (!debug) {
629 prefix2str(
630 bgp_dest_get_prefix(new->net), pfx_buf,
631 sizeof(*pfx_buf) * PREFIX2STR_BUFFER);
632 bgp_path_info_path_with_addpath_rx_str(
633 new, new_buf, sizeof(new_buf));
634 bgp_path_info_path_with_addpath_rx_str(
635 exist, exist_buf, sizeof(exist_buf));
636 }
637
638 if (newattr->sticky && !existattr->sticky) {
639 *reason = bgp_path_selection_evpn_sticky_mac;
640 if (debug)
641 zlog_debug(
642 "%s: %s wins over %s due to sticky MAC flag",
643 pfx_buf, new_buf, exist_buf);
644 return 1;
645 }
646
647 if (!newattr->sticky && existattr->sticky) {
648 *reason = bgp_path_selection_evpn_sticky_mac;
649 if (debug)
650 zlog_debug(
651 "%s: %s loses to %s due to sticky MAC flag",
652 pfx_buf, new_buf, exist_buf);
653 return 0;
654 }
655 }
656
657 new_esi = bgp_evpn_attr_get_esi(newattr);
658 exist_esi = bgp_evpn_attr_get_esi(existattr);
659 if (bgp_evpn_is_esi_valid(new_esi) &&
660 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
661 same_esi = true;
662 } else {
663 same_esi = false;
664 }
665
666 /* If both paths have the same non-zero ES and
667 * one path is local it wins.
668 * PS: Note the local path wins even if the remote
669 * has the higher MM seq. The local path's
670 * MM seq will be fixed up to match the highest
671 * rem seq, subsequently.
672 */
673 if (same_esi) {
674 char esi_buf[ESI_STR_LEN];
675
676 if (bgp_evpn_is_path_local(bgp, new)) {
677 *reason = bgp_path_selection_evpn_local_path;
678 if (debug)
679 zlog_debug(
680 "%s: %s wins over %s as ES %s is same and local",
681 pfx_buf, new_buf, exist_buf,
682 esi_to_str(new_esi, esi_buf,
683 sizeof(esi_buf)));
684 return 1;
685 }
686 if (bgp_evpn_is_path_local(bgp, exist)) {
687 *reason = bgp_path_selection_evpn_local_path;
688 if (debug)
689 zlog_debug(
690 "%s: %s loses to %s as ES %s is same and local",
691 pfx_buf, new_buf, exist_buf,
692 esi_to_str(new_esi, esi_buf,
693 sizeof(esi_buf)));
694 return 0;
695 }
696 }
697
698 new_mm_seq = mac_mobility_seqnum(newattr);
699 exist_mm_seq = mac_mobility_seqnum(existattr);
700
701 if (new_mm_seq > exist_mm_seq) {
702 *reason = bgp_path_selection_evpn_seq;
703 if (debug)
704 zlog_debug(
705 "%s: %s wins over %s due to MM seq %u > %u",
706 pfx_buf, new_buf, exist_buf, new_mm_seq,
707 exist_mm_seq);
708 return 1;
709 }
710
711 if (new_mm_seq < exist_mm_seq) {
712 *reason = bgp_path_selection_evpn_seq;
713 if (debug)
714 zlog_debug(
715 "%s: %s loses to %s due to MM seq %u < %u",
716 pfx_buf, new_buf, exist_buf, new_mm_seq,
717 exist_mm_seq);
718 return 0;
719 }
720
721 /* if the sequence numbers and ESI are the same and one path
722 * is non-proxy it wins (over proxy)
723 */
724 new_proxy = bgp_evpn_attr_is_proxy(newattr);
725 old_proxy = bgp_evpn_attr_is_proxy(existattr);
726 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
727 old_proxy != new_proxy) {
728 if (!new_proxy) {
729 *reason = bgp_path_selection_evpn_non_proxy;
730 if (debug)
731 zlog_debug(
732 "%s: %s wins over %s, same seq/es and non-proxy",
733 pfx_buf, new_buf, exist_buf);
734 return 1;
735 }
736
737 *reason = bgp_path_selection_evpn_non_proxy;
738 if (debug)
739 zlog_debug(
740 "%s: %s loses to %s, same seq/es and non-proxy",
741 pfx_buf, new_buf, exist_buf);
742 return 0;
743 }
744
745 /*
746 * if sequence numbers are the same path with the lowest IP
747 * wins
748 */
749 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
750 if (nh_cmp < 0) {
751 *reason = bgp_path_selection_evpn_lower_ip;
752 if (debug)
753 zlog_debug(
754 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
755 pfx_buf, new_buf, exist_buf, new_mm_seq,
756 &new->attr->nexthop);
757 return 1;
758 }
759 if (nh_cmp > 0) {
760 *reason = bgp_path_selection_evpn_lower_ip;
761 if (debug)
762 zlog_debug(
763 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
764 pfx_buf, new_buf, exist_buf, new_mm_seq,
765 &new->attr->nexthop);
766 return 0;
767 }
768 }
769
770 /* 1. Weight check. */
771 new_weight = newattr->weight;
772 exist_weight = existattr->weight;
773
774 if (new_weight > exist_weight) {
775 *reason = bgp_path_selection_weight;
776 if (debug)
777 zlog_debug("%s: %s wins over %s due to weight %d > %d",
778 pfx_buf, new_buf, exist_buf, new_weight,
779 exist_weight);
780 return 1;
781 }
782
783 if (new_weight < exist_weight) {
784 *reason = bgp_path_selection_weight;
785 if (debug)
786 zlog_debug("%s: %s loses to %s due to weight %d < %d",
787 pfx_buf, new_buf, exist_buf, new_weight,
788 exist_weight);
789 return 0;
790 }
791
792 /* 2. Local preference check. */
793 new_pref = exist_pref = bgp->default_local_pref;
794
795 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
796 new_pref = newattr->local_pref;
797 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
798 exist_pref = existattr->local_pref;
799
800 if (new_pref > exist_pref) {
801 *reason = bgp_path_selection_local_pref;
802 if (debug)
803 zlog_debug(
804 "%s: %s wins over %s due to localpref %d > %d",
805 pfx_buf, new_buf, exist_buf, new_pref,
806 exist_pref);
807 return 1;
808 }
809
810 if (new_pref < exist_pref) {
811 *reason = bgp_path_selection_local_pref;
812 if (debug)
813 zlog_debug(
814 "%s: %s loses to %s due to localpref %d < %d",
815 pfx_buf, new_buf, exist_buf, new_pref,
816 exist_pref);
817 return 0;
818 }
819
820 /* 3. Local route check. We prefer:
821 * - BGP_ROUTE_STATIC
822 * - BGP_ROUTE_AGGREGATE
823 * - BGP_ROUTE_REDISTRIBUTE
824 */
825 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
826 new->sub_type == BGP_ROUTE_IMPORTED);
827 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
828 exist->sub_type == BGP_ROUTE_IMPORTED);
829
830 if (new_origin && !exist_origin) {
831 *reason = bgp_path_selection_local_route;
832 if (debug)
833 zlog_debug(
834 "%s: %s wins over %s due to preferred BGP_ROUTE type",
835 pfx_buf, new_buf, exist_buf);
836 return 1;
837 }
838
839 if (!new_origin && exist_origin) {
840 *reason = bgp_path_selection_local_route;
841 if (debug)
842 zlog_debug(
843 "%s: %s loses to %s due to preferred BGP_ROUTE type",
844 pfx_buf, new_buf, exist_buf);
845 return 0;
846 }
847
848 /* 4. AS path length check. */
849 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
850 int exist_hops = aspath_count_hops(existattr->aspath);
851 int exist_confeds = aspath_count_confeds(existattr->aspath);
852
853 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
854 int aspath_hops;
855
856 aspath_hops = aspath_count_hops(newattr->aspath);
857 aspath_hops += aspath_count_confeds(newattr->aspath);
858
859 if (aspath_hops < (exist_hops + exist_confeds)) {
860 *reason = bgp_path_selection_confed_as_path;
861 if (debug)
862 zlog_debug(
863 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
864 pfx_buf, new_buf, exist_buf,
865 aspath_hops,
866 (exist_hops + exist_confeds));
867 return 1;
868 }
869
870 if (aspath_hops > (exist_hops + exist_confeds)) {
871 *reason = bgp_path_selection_confed_as_path;
872 if (debug)
873 zlog_debug(
874 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
875 pfx_buf, new_buf, exist_buf,
876 aspath_hops,
877 (exist_hops + exist_confeds));
878 return 0;
879 }
880 } else {
881 int newhops = aspath_count_hops(newattr->aspath);
882
883 if (newhops < exist_hops) {
884 *reason = bgp_path_selection_as_path;
885 if (debug)
886 zlog_debug(
887 "%s: %s wins over %s due to aspath hopcount %d < %d",
888 pfx_buf, new_buf, exist_buf,
889 newhops, exist_hops);
890 return 1;
891 }
892
893 if (newhops > exist_hops) {
894 *reason = bgp_path_selection_as_path;
895 if (debug)
896 zlog_debug(
897 "%s: %s loses to %s due to aspath hopcount %d > %d",
898 pfx_buf, new_buf, exist_buf,
899 newhops, exist_hops);
900 return 0;
901 }
902 }
903 }
904
905 /* 5. Origin check. */
906 if (newattr->origin < existattr->origin) {
907 *reason = bgp_path_selection_origin;
908 if (debug)
909 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
910 pfx_buf, new_buf, exist_buf,
911 bgp_origin_long_str[newattr->origin],
912 bgp_origin_long_str[existattr->origin]);
913 return 1;
914 }
915
916 if (newattr->origin > existattr->origin) {
917 *reason = bgp_path_selection_origin;
918 if (debug)
919 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
920 pfx_buf, new_buf, exist_buf,
921 bgp_origin_long_str[newattr->origin],
922 bgp_origin_long_str[existattr->origin]);
923 return 0;
924 }
925
926 /* 6. MED check. */
927 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
928 && aspath_count_hops(existattr->aspath) == 0);
929 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
930 && aspath_count_confeds(existattr->aspath) > 0
931 && aspath_count_hops(newattr->aspath) == 0
932 && aspath_count_hops(existattr->aspath) == 0);
933
934 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
935 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
936 || aspath_cmp_left(newattr->aspath, existattr->aspath)
937 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
938 || internal_as_route) {
939 new_med = bgp_med_value(new->attr, bgp);
940 exist_med = bgp_med_value(exist->attr, bgp);
941
942 if (new_med < exist_med) {
943 *reason = bgp_path_selection_med;
944 if (debug)
945 zlog_debug(
946 "%s: %s wins over %s due to MED %d < %d",
947 pfx_buf, new_buf, exist_buf, new_med,
948 exist_med);
949 return 1;
950 }
951
952 if (new_med > exist_med) {
953 *reason = bgp_path_selection_med;
954 if (debug)
955 zlog_debug(
956 "%s: %s loses to %s due to MED %d > %d",
957 pfx_buf, new_buf, exist_buf, new_med,
958 exist_med);
959 return 0;
960 }
961 }
962
963 /* 7. Peer type check. */
964 new_sort = new->peer->sort;
965 exist_sort = exist->peer->sort;
966
967 if (new_sort == BGP_PEER_EBGP
968 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
969 *reason = bgp_path_selection_peer;
970 if (debug)
971 zlog_debug(
972 "%s: %s wins over %s due to eBGP peer > iBGP peer",
973 pfx_buf, new_buf, exist_buf);
974 return 1;
975 }
976
977 if (exist_sort == BGP_PEER_EBGP
978 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
979 *reason = bgp_path_selection_peer;
980 if (debug)
981 zlog_debug(
982 "%s: %s loses to %s due to iBGP peer < eBGP peer",
983 pfx_buf, new_buf, exist_buf);
984 return 0;
985 }
986
987 /* 8. IGP metric check. */
988 newm = existm = 0;
989
990 if (new->extra)
991 newm = new->extra->igpmetric;
992 if (exist->extra)
993 existm = exist->extra->igpmetric;
994
995 if (newm < existm) {
996 if (debug)
997 zlog_debug(
998 "%s: %s wins over %s due to IGP metric %u < %u",
999 pfx_buf, new_buf, exist_buf, newm, existm);
1000 ret = 1;
1001 }
1002
1003 if (newm > existm) {
1004 if (debug)
1005 zlog_debug(
1006 "%s: %s loses to %s due to IGP metric %u > %u",
1007 pfx_buf, new_buf, exist_buf, newm, existm);
1008 ret = 0;
1009 }
1010
1011 /* 9. Same IGP metric. Compare the cluster list length as
1012 representative of IGP hops metric. Rewrite the metric value
1013 pair (newm, existm) with the cluster list length. Prefer the
1014 path with smaller cluster list length. */
1015 if (newm == existm) {
1016 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP
1017 && peer_sort_lookup(exist->peer) == BGP_PEER_IBGP
1018 && (mpath_cfg == NULL
1019 || CHECK_FLAG(
1020 mpath_cfg->ibgp_flags,
1021 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN))) {
1022 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1023 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1024
1025 if (newm < existm) {
1026 if (debug)
1027 zlog_debug(
1028 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1029 pfx_buf, new_buf, exist_buf,
1030 newm, existm);
1031 ret = 1;
1032 }
1033
1034 if (newm > existm) {
1035 if (debug)
1036 zlog_debug(
1037 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1038 pfx_buf, new_buf, exist_buf,
1039 newm, existm);
1040 ret = 0;
1041 }
1042 }
1043 }
1044
1045 /* 10. confed-external vs. confed-internal */
1046 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1047 if (new_sort == BGP_PEER_CONFED
1048 && exist_sort == BGP_PEER_IBGP) {
1049 *reason = bgp_path_selection_confed;
1050 if (debug)
1051 zlog_debug(
1052 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1053 pfx_buf, new_buf, exist_buf);
1054 return 1;
1055 }
1056
1057 if (exist_sort == BGP_PEER_CONFED
1058 && new_sort == BGP_PEER_IBGP) {
1059 *reason = bgp_path_selection_confed;
1060 if (debug)
1061 zlog_debug(
1062 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1063 pfx_buf, new_buf, exist_buf);
1064 return 0;
1065 }
1066 }
1067
1068 /* 11. Maximum path check. */
1069 if (newm == existm) {
1070 /* If one path has a label but the other does not, do not treat
1071 * them as equals for multipath
1072 */
1073 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1074 != (exist->extra
1075 && bgp_is_valid_label(&exist->extra->label[0]))) {
1076 if (debug)
1077 zlog_debug(
1078 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1079 pfx_buf, new_buf, exist_buf);
1080 } else if (CHECK_FLAG(bgp->flags,
1081 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1082
1083 /*
1084 * For the two paths, all comparison steps till IGP
1085 * metric
1086 * have succeeded - including AS_PATH hop count. Since
1087 * 'bgp
1088 * bestpath as-path multipath-relax' knob is on, we
1089 * don't need
1090 * an exact match of AS_PATH. Thus, mark the paths are
1091 * equal.
1092 * That will trigger both these paths to get into the
1093 * multipath
1094 * array.
1095 */
1096 *paths_eq = 1;
1097
1098 if (debug)
1099 zlog_debug(
1100 "%s: %s and %s are equal via multipath-relax",
1101 pfx_buf, new_buf, exist_buf);
1102 } else if (new->peer->sort == BGP_PEER_IBGP) {
1103 if (aspath_cmp(new->attr->aspath,
1104 exist->attr->aspath)) {
1105 *paths_eq = 1;
1106
1107 if (debug)
1108 zlog_debug(
1109 "%s: %s and %s are equal via matching aspaths",
1110 pfx_buf, new_buf, exist_buf);
1111 }
1112 } else if (new->peer->as == exist->peer->as) {
1113 *paths_eq = 1;
1114
1115 if (debug)
1116 zlog_debug(
1117 "%s: %s and %s are equal via same remote-as",
1118 pfx_buf, new_buf, exist_buf);
1119 }
1120 } else {
1121 /*
1122 * TODO: If unequal cost ibgp multipath is enabled we can
1123 * mark the paths as equal here instead of returning
1124 */
1125 if (debug) {
1126 if (ret == 1)
1127 zlog_debug(
1128 "%s: %s wins over %s after IGP metric comparison",
1129 pfx_buf, new_buf, exist_buf);
1130 else
1131 zlog_debug(
1132 "%s: %s loses to %s after IGP metric comparison",
1133 pfx_buf, new_buf, exist_buf);
1134 }
1135 *reason = bgp_path_selection_igp_metric;
1136 return ret;
1137 }
1138
1139 /* 12. If both paths are external, prefer the path that was received
1140 first (the oldest one). This step minimizes route-flap, since a
1141 newer path won't displace an older one, even if it was the
1142 preferred route based on the additional decision criteria below. */
1143 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1144 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1145 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1146 *reason = bgp_path_selection_older;
1147 if (debug)
1148 zlog_debug(
1149 "%s: %s wins over %s due to oldest external",
1150 pfx_buf, new_buf, exist_buf);
1151 return 1;
1152 }
1153
1154 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1155 *reason = bgp_path_selection_older;
1156 if (debug)
1157 zlog_debug(
1158 "%s: %s loses to %s due to oldest external",
1159 pfx_buf, new_buf, exist_buf);
1160 return 0;
1161 }
1162 }
1163
1164 /* 13. Router-ID comparision. */
1165 /* If one of the paths is "stale", the corresponding peer router-id will
1166 * be 0 and would always win over the other path. If originator id is
1167 * used for the comparision, it will decide which path is better.
1168 */
1169 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1170 new_id.s_addr = newattr->originator_id.s_addr;
1171 else
1172 new_id.s_addr = new->peer->remote_id.s_addr;
1173 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1174 exist_id.s_addr = existattr->originator_id.s_addr;
1175 else
1176 exist_id.s_addr = exist->peer->remote_id.s_addr;
1177
1178 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1179 *reason = bgp_path_selection_router_id;
1180 if (debug)
1181 zlog_debug(
1182 "%s: %s wins over %s due to Router-ID comparison",
1183 pfx_buf, new_buf, exist_buf);
1184 return 1;
1185 }
1186
1187 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1188 *reason = bgp_path_selection_router_id;
1189 if (debug)
1190 zlog_debug(
1191 "%s: %s loses to %s due to Router-ID comparison",
1192 pfx_buf, new_buf, exist_buf);
1193 return 0;
1194 }
1195
1196 /* 14. Cluster length comparision. */
1197 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1198 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1199
1200 if (new_cluster < exist_cluster) {
1201 *reason = bgp_path_selection_cluster_length;
1202 if (debug)
1203 zlog_debug(
1204 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1205 pfx_buf, new_buf, exist_buf, new_cluster,
1206 exist_cluster);
1207 return 1;
1208 }
1209
1210 if (new_cluster > exist_cluster) {
1211 *reason = bgp_path_selection_cluster_length;
1212 if (debug)
1213 zlog_debug(
1214 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1215 pfx_buf, new_buf, exist_buf, new_cluster,
1216 exist_cluster);
1217 return 0;
1218 }
1219
1220 /* 15. Neighbor address comparision. */
1221 /* Do this only if neither path is "stale" as stale paths do not have
1222 * valid peer information (as the connection may or may not be up).
1223 */
1224 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1225 *reason = bgp_path_selection_stale;
1226 if (debug)
1227 zlog_debug(
1228 "%s: %s wins over %s due to latter path being STALE",
1229 pfx_buf, new_buf, exist_buf);
1230 return 1;
1231 }
1232
1233 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1234 *reason = bgp_path_selection_stale;
1235 if (debug)
1236 zlog_debug(
1237 "%s: %s loses to %s due to former path being STALE",
1238 pfx_buf, new_buf, exist_buf);
1239 return 0;
1240 }
1241
1242 /* locally configured routes to advertise do not have su_remote */
1243 if (new->peer->su_remote == NULL) {
1244 *reason = bgp_path_selection_local_configured;
1245 return 0;
1246 }
1247 if (exist->peer->su_remote == NULL) {
1248 *reason = bgp_path_selection_local_configured;
1249 return 1;
1250 }
1251
1252 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1253
1254 if (ret == 1) {
1255 *reason = bgp_path_selection_neighbor_ip;
1256 if (debug)
1257 zlog_debug(
1258 "%s: %s loses to %s due to Neighor IP comparison",
1259 pfx_buf, new_buf, exist_buf);
1260 return 0;
1261 }
1262
1263 if (ret == -1) {
1264 *reason = bgp_path_selection_neighbor_ip;
1265 if (debug)
1266 zlog_debug(
1267 "%s: %s wins over %s due to Neighor IP comparison",
1268 pfx_buf, new_buf, exist_buf);
1269 return 1;
1270 }
1271
1272 *reason = bgp_path_selection_default;
1273 if (debug)
1274 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1275 pfx_buf, new_buf, exist_buf);
1276
1277 return 1;
1278 }
1279
1280
1281 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1282 struct bgp_path_info *exist, int *paths_eq)
1283 {
1284 enum bgp_path_selection_reason reason;
1285 char pfx_buf[PREFIX2STR_BUFFER];
1286
1287 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1288 AFI_L2VPN, SAFI_EVPN, &reason);
1289 }
1290
1291 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1292 * is preferred, or 0 if they are the same (usually will only occur if
1293 * multipath is enabled
1294 * This version is compatible with */
1295 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1296 struct bgp_path_info *exist, char *pfx_buf,
1297 afi_t afi, safi_t safi,
1298 enum bgp_path_selection_reason *reason)
1299 {
1300 int paths_eq;
1301 int ret;
1302 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1303 afi, safi, reason);
1304
1305 if (paths_eq)
1306 ret = 0;
1307 else {
1308 if (ret == 1)
1309 ret = -1;
1310 else
1311 ret = 1;
1312 }
1313 return ret;
1314 }
1315
1316 static enum filter_type bgp_input_filter(struct peer *peer,
1317 const struct prefix *p,
1318 struct attr *attr, afi_t afi,
1319 safi_t safi)
1320 {
1321 struct bgp_filter *filter;
1322 enum filter_type ret = FILTER_PERMIT;
1323
1324 filter = &peer->filter[afi][safi];
1325
1326 #define FILTER_EXIST_WARN(F, f, filter) \
1327 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1328 zlog_debug("%s: Could not find configured input %s-list %s!", \
1329 peer->host, #f, F##_IN_NAME(filter));
1330
1331 if (DISTRIBUTE_IN_NAME(filter)) {
1332 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1333
1334 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1335 == FILTER_DENY) {
1336 ret = FILTER_DENY;
1337 goto done;
1338 }
1339 }
1340
1341 if (PREFIX_LIST_IN_NAME(filter)) {
1342 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1343
1344 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1345 == PREFIX_DENY) {
1346 ret = FILTER_DENY;
1347 goto done;
1348 }
1349 }
1350
1351 if (FILTER_LIST_IN_NAME(filter)) {
1352 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1353
1354 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1355 == AS_FILTER_DENY) {
1356 ret = FILTER_DENY;
1357 goto done;
1358 }
1359 }
1360
1361 done:
1362 if (frrtrace_enabled(frr_bgp, input_filter)) {
1363 char pfxprint[PREFIX2STR_BUFFER];
1364
1365 prefix2str(p, pfxprint, sizeof(pfxprint));
1366 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1367 ret == FILTER_PERMIT ? "permit" : "deny");
1368 }
1369
1370 return ret;
1371 #undef FILTER_EXIST_WARN
1372 }
1373
1374 static enum filter_type bgp_output_filter(struct peer *peer,
1375 const struct prefix *p,
1376 struct attr *attr, afi_t afi,
1377 safi_t safi)
1378 {
1379 struct bgp_filter *filter;
1380 enum filter_type ret = FILTER_PERMIT;
1381
1382 filter = &peer->filter[afi][safi];
1383
1384 #define FILTER_EXIST_WARN(F, f, filter) \
1385 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1386 zlog_debug("%s: Could not find configured output %s-list %s!", \
1387 peer->host, #f, F##_OUT_NAME(filter));
1388
1389 if (DISTRIBUTE_OUT_NAME(filter)) {
1390 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1391
1392 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1393 == FILTER_DENY) {
1394 ret = FILTER_DENY;
1395 goto done;
1396 }
1397 }
1398
1399 if (PREFIX_LIST_OUT_NAME(filter)) {
1400 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1401
1402 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1403 == PREFIX_DENY) {
1404 ret = FILTER_DENY;
1405 goto done;
1406 }
1407 }
1408
1409 if (FILTER_LIST_OUT_NAME(filter)) {
1410 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1411
1412 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1413 == AS_FILTER_DENY) {
1414 ret = FILTER_DENY;
1415 goto done;
1416 }
1417 }
1418
1419 if (frrtrace_enabled(frr_bgp, output_filter)) {
1420 char pfxprint[PREFIX2STR_BUFFER];
1421
1422 prefix2str(p, pfxprint, sizeof(pfxprint));
1423 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1424 ret == FILTER_PERMIT ? "permit" : "deny");
1425 }
1426
1427 done:
1428 return ret;
1429 #undef FILTER_EXIST_WARN
1430 }
1431
1432 /* If community attribute includes no_export then return 1. */
1433 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1434 {
1435 if (attr->community) {
1436 /* NO_ADVERTISE check. */
1437 if (community_include(attr->community, COMMUNITY_NO_ADVERTISE))
1438 return true;
1439
1440 /* NO_EXPORT check. */
1441 if (peer->sort == BGP_PEER_EBGP
1442 && community_include(attr->community, COMMUNITY_NO_EXPORT))
1443 return true;
1444
1445 /* NO_EXPORT_SUBCONFED check. */
1446 if (peer->sort == BGP_PEER_EBGP
1447 || peer->sort == BGP_PEER_CONFED)
1448 if (community_include(attr->community,
1449 COMMUNITY_NO_EXPORT_SUBCONFED))
1450 return true;
1451 }
1452 return false;
1453 }
1454
1455 /* Route reflection loop check. */
1456 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1457 {
1458 struct in_addr cluster_id;
1459 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1460
1461 if (cluster) {
1462 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1463 cluster_id = peer->bgp->cluster_id;
1464 else
1465 cluster_id = peer->bgp->router_id;
1466
1467 if (cluster_loop_check(cluster, cluster_id))
1468 return true;
1469 }
1470 return false;
1471 }
1472
1473 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1474 struct attr *attr, afi_t afi, safi_t safi,
1475 const char *rmap_name, mpls_label_t *label,
1476 uint32_t num_labels, struct bgp_dest *dest)
1477 {
1478 struct bgp_filter *filter;
1479 struct bgp_path_info rmap_path = { 0 };
1480 struct bgp_path_info_extra extra = { 0 };
1481 route_map_result_t ret;
1482 struct route_map *rmap = NULL;
1483
1484 filter = &peer->filter[afi][safi];
1485
1486 /* Apply default weight value. */
1487 if (peer->weight[afi][safi])
1488 attr->weight = peer->weight[afi][safi];
1489
1490 if (rmap_name) {
1491 rmap = route_map_lookup_by_name(rmap_name);
1492
1493 if (rmap == NULL)
1494 return RMAP_DENY;
1495 } else {
1496 if (ROUTE_MAP_IN_NAME(filter)) {
1497 rmap = ROUTE_MAP_IN(filter);
1498
1499 if (rmap == NULL)
1500 return RMAP_DENY;
1501 }
1502 }
1503
1504 /* Route map apply. */
1505 if (rmap) {
1506 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1507 /* Duplicate current value to new strucutre for modification. */
1508 rmap_path.peer = peer;
1509 rmap_path.attr = attr;
1510 rmap_path.extra = &extra;
1511 rmap_path.net = dest;
1512
1513 extra.num_labels = num_labels;
1514 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1515 memcpy(extra.label, label,
1516 num_labels * sizeof(mpls_label_t));
1517
1518 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1519
1520 /* Apply BGP route map to the attribute. */
1521 ret = route_map_apply(rmap, p, &rmap_path);
1522
1523 peer->rmap_type = 0;
1524
1525 if (ret == RMAP_DENYMATCH)
1526 return RMAP_DENY;
1527 }
1528 return RMAP_PERMIT;
1529 }
1530
1531 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1532 struct attr *attr, afi_t afi, safi_t safi,
1533 const char *rmap_name)
1534 {
1535 struct bgp_path_info rmap_path;
1536 route_map_result_t ret;
1537 struct route_map *rmap = NULL;
1538 uint8_t rmap_type;
1539
1540 /*
1541 * So if we get to this point and have no rmap_name
1542 * we want to just show the output as it currently
1543 * exists.
1544 */
1545 if (!rmap_name)
1546 return RMAP_PERMIT;
1547
1548 /* Apply default weight value. */
1549 if (peer->weight[afi][safi])
1550 attr->weight = peer->weight[afi][safi];
1551
1552 rmap = route_map_lookup_by_name(rmap_name);
1553
1554 /*
1555 * If we have a route map name and we do not find
1556 * the routemap that means we have an implicit
1557 * deny.
1558 */
1559 if (rmap == NULL)
1560 return RMAP_DENY;
1561
1562 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1563 /* Route map apply. */
1564 /* Duplicate current value to new strucutre for modification. */
1565 rmap_path.peer = peer;
1566 rmap_path.attr = attr;
1567
1568 rmap_type = peer->rmap_type;
1569 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1570
1571 /* Apply BGP route map to the attribute. */
1572 ret = route_map_apply(rmap, p, &rmap_path);
1573
1574 peer->rmap_type = rmap_type;
1575
1576 if (ret == RMAP_DENYMATCH)
1577 /*
1578 * caller has multiple error paths with bgp_attr_flush()
1579 */
1580 return RMAP_DENY;
1581
1582 return RMAP_PERMIT;
1583 }
1584
1585 /* If this is an EBGP peer with remove-private-AS */
1586 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1587 struct peer *peer, struct attr *attr)
1588 {
1589 if (peer->sort == BGP_PEER_EBGP
1590 && (peer_af_flag_check(peer, afi, safi,
1591 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1592 || peer_af_flag_check(peer, afi, safi,
1593 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1594 || peer_af_flag_check(peer, afi, safi,
1595 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1596 || peer_af_flag_check(peer, afi, safi,
1597 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1598 // Take action on the entire aspath
1599 if (peer_af_flag_check(peer, afi, safi,
1600 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1601 || peer_af_flag_check(peer, afi, safi,
1602 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1603 if (peer_af_flag_check(
1604 peer, afi, safi,
1605 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1606 attr->aspath = aspath_replace_private_asns(
1607 attr->aspath, bgp->as, peer->as);
1608
1609 // The entire aspath consists of private ASNs so create
1610 // an empty aspath
1611 else if (aspath_private_as_check(attr->aspath))
1612 attr->aspath = aspath_empty_get();
1613
1614 // There are some public and some private ASNs, remove
1615 // the private ASNs
1616 else
1617 attr->aspath = aspath_remove_private_asns(
1618 attr->aspath, peer->as);
1619 }
1620
1621 // 'all' was not specified so the entire aspath must be private
1622 // ASNs
1623 // for us to do anything
1624 else if (aspath_private_as_check(attr->aspath)) {
1625 if (peer_af_flag_check(
1626 peer, afi, safi,
1627 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1628 attr->aspath = aspath_replace_private_asns(
1629 attr->aspath, bgp->as, peer->as);
1630 else
1631 attr->aspath = aspath_empty_get();
1632 }
1633 }
1634 }
1635
1636 /* If this is an EBGP peer with as-override */
1637 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1638 struct peer *peer, struct attr *attr)
1639 {
1640 if (peer->sort == BGP_PEER_EBGP
1641 && peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1642 if (aspath_single_asn_check(attr->aspath, peer->as))
1643 attr->aspath = aspath_replace_specific_asn(
1644 attr->aspath, peer->as, bgp->as);
1645 }
1646 }
1647
1648 void bgp_attr_add_gshut_community(struct attr *attr)
1649 {
1650 struct community *old;
1651 struct community *new;
1652 struct community *merge;
1653 struct community *gshut;
1654
1655 old = attr->community;
1656 gshut = community_str2com("graceful-shutdown");
1657
1658 assert(gshut);
1659
1660 if (old) {
1661 merge = community_merge(community_dup(old), gshut);
1662
1663 if (old->refcnt == 0)
1664 community_free(&old);
1665
1666 new = community_uniq_sort(merge);
1667 community_free(&merge);
1668 } else {
1669 new = community_dup(gshut);
1670 }
1671
1672 community_free(&gshut);
1673 attr->community = new;
1674 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
1675
1676 /* When we add the graceful-shutdown community we must also
1677 * lower the local-preference */
1678 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1679 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1680 }
1681
1682
1683 /* Notify BGP Conditional advertisement scanner process. */
1684 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1685 {
1686 struct peer *temp_peer;
1687 struct peer *peer = SUBGRP_PEER(subgrp);
1688 struct listnode *temp_node, *temp_nnode = NULL;
1689 afi_t afi = SUBGRP_AFI(subgrp);
1690 safi_t safi = SUBGRP_SAFI(subgrp);
1691 struct bgp *bgp = SUBGRP_INST(subgrp);
1692 struct bgp_filter *filter = &peer->filter[afi][safi];
1693
1694 if (!ADVERTISE_MAP_NAME(filter))
1695 return;
1696
1697 for (ALL_LIST_ELEMENTS(bgp->peer, temp_node, temp_nnode, temp_peer)) {
1698 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1699 continue;
1700
1701 if (peer != temp_peer)
1702 continue;
1703
1704 temp_peer->advmap_table_change = true;
1705 break;
1706 }
1707 }
1708
1709
1710 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1711 {
1712 if (family == AF_INET) {
1713 attr->nexthop.s_addr = INADDR_ANY;
1714 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1715 }
1716 if (family == AF_INET6)
1717 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1718 if (family == AF_EVPN)
1719 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1720 }
1721
1722 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1723 struct update_subgroup *subgrp,
1724 const struct prefix *p, struct attr *attr,
1725 bool skip_rmap_check)
1726 {
1727 struct bgp_filter *filter;
1728 struct peer *from;
1729 struct peer *peer;
1730 struct peer *onlypeer;
1731 struct bgp *bgp;
1732 struct attr *piattr;
1733 route_map_result_t ret;
1734 int transparent;
1735 int reflect;
1736 afi_t afi;
1737 safi_t safi;
1738 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1739 bool nh_reset = false;
1740 uint64_t cum_bw;
1741
1742 if (DISABLE_BGP_ANNOUNCE)
1743 return false;
1744
1745 afi = SUBGRP_AFI(subgrp);
1746 safi = SUBGRP_SAFI(subgrp);
1747 peer = SUBGRP_PEER(subgrp);
1748 onlypeer = NULL;
1749 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1750 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1751
1752 from = pi->peer;
1753 filter = &peer->filter[afi][safi];
1754 bgp = SUBGRP_INST(subgrp);
1755 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
1756 : pi->attr;
1757
1758 #ifdef ENABLE_BGP_VNC
1759 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
1760 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
1761 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
1762
1763 /*
1764 * direct and direct_ext type routes originate internally even
1765 * though they can have peer pointers that reference other
1766 * systems
1767 */
1768 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
1769 __func__, p);
1770 samepeer_safe = 1;
1771 }
1772 #endif
1773
1774 if (((afi == AFI_IP) || (afi == AFI_IP6))
1775 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
1776 && (pi->type == ZEBRA_ROUTE_BGP)
1777 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
1778
1779 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1780
1781 samepeer_safe = 1;
1782 }
1783
1784 /* With addpath we may be asked to TX all kinds of paths so make sure
1785 * pi is valid */
1786 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
1787 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
1788 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
1789 return false;
1790 }
1791
1792 /* If this is not the bestpath then check to see if there is an enabled
1793 * addpath
1794 * feature that requires us to advertise it */
1795 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
1796 if (!bgp_addpath_tx_path(peer->addpath_type[afi][safi], pi)) {
1797 return false;
1798 }
1799 }
1800
1801 /* Aggregate-address suppress check. */
1802 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
1803 return false;
1804
1805 /*
1806 * If we are doing VRF 2 VRF leaking via the import
1807 * statement, we want to prevent the route going
1808 * off box as that the RT and RD created are localy
1809 * significant and globaly useless.
1810 */
1811 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
1812 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
1813 return false;
1814
1815 /* If it's labeled safi, make sure the route has a valid label. */
1816 if (safi == SAFI_LABELED_UNICAST) {
1817 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
1818 if (!bgp_is_valid_label(&label)) {
1819 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1820 zlog_debug("u%" PRIu64 ":s%" PRIu64
1821 " %pFX is filtered - no label (%p)",
1822 subgrp->update_group->id, subgrp->id,
1823 p, &label);
1824 return false;
1825 }
1826 }
1827
1828 /* Do not send back route to sender. */
1829 if (onlypeer && from == onlypeer) {
1830 return false;
1831 }
1832
1833 /* Do not send the default route in the BGP table if the neighbor is
1834 * configured for default-originate */
1835 if (CHECK_FLAG(peer->af_flags[afi][safi],
1836 PEER_FLAG_DEFAULT_ORIGINATE)) {
1837 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
1838 return false;
1839 else if (p->family == AF_INET6 && p->prefixlen == 0)
1840 return false;
1841 }
1842
1843 /* Transparency check. */
1844 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
1845 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1846 transparent = 1;
1847 else
1848 transparent = 0;
1849
1850 /* If community is not disabled check the no-export and local. */
1851 if (!transparent && bgp_community_filter(peer, piattr)) {
1852 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1853 zlog_debug("%s: community filter check fail for %pFX",
1854 __func__, p);
1855 return false;
1856 }
1857
1858 /* If the attribute has originator-id and it is same as remote
1859 peer's id. */
1860 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
1861 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
1862 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1863 zlog_debug(
1864 "%s [Update:SEND] %pFX originator-id is same as remote router-id",
1865 onlypeer->host, p);
1866 return false;
1867 }
1868
1869 /* ORF prefix-list filter check */
1870 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
1871 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
1872 || CHECK_FLAG(peer->af_cap[afi][safi],
1873 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
1874 if (peer->orf_plist[afi][safi]) {
1875 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
1876 == PREFIX_DENY) {
1877 if (bgp_debug_update(NULL, p,
1878 subgrp->update_group, 0))
1879 zlog_debug(
1880 "%s [Update:SEND] %pFX is filtered via ORF",
1881 peer->host, p);
1882 return false;
1883 }
1884 }
1885
1886 /* Output filter check. */
1887 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
1888 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1889 zlog_debug("%s [Update:SEND] %pFX is filtered",
1890 peer->host, p);
1891 return false;
1892 }
1893
1894 /* AS path loop check. */
1895 if (onlypeer && onlypeer->as_path_loop_detection
1896 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
1897 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1898 zlog_debug(
1899 "%s [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
1900 onlypeer->host, onlypeer->as);
1901 return false;
1902 }
1903
1904 /* If we're a CONFED we need to loop check the CONFED ID too */
1905 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1906 if (aspath_loop_check(piattr->aspath, bgp->confed_id)) {
1907 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1908 zlog_debug(
1909 "%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
1910 peer->host, bgp->confed_id);
1911 return false;
1912 }
1913 }
1914
1915 /* Route-Reflect check. */
1916 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
1917 reflect = 1;
1918 else
1919 reflect = 0;
1920
1921 /* IBGP reflection check. */
1922 if (reflect && !samepeer_safe) {
1923 /* A route from a Client peer. */
1924 if (CHECK_FLAG(from->af_flags[afi][safi],
1925 PEER_FLAG_REFLECTOR_CLIENT)) {
1926 /* Reflect to all the Non-Client peers and also to the
1927 Client peers other than the originator. Originator
1928 check
1929 is already done. So there is noting to do. */
1930 /* no bgp client-to-client reflection check. */
1931 if (CHECK_FLAG(bgp->flags,
1932 BGP_FLAG_NO_CLIENT_TO_CLIENT))
1933 if (CHECK_FLAG(peer->af_flags[afi][safi],
1934 PEER_FLAG_REFLECTOR_CLIENT))
1935 return false;
1936 } else {
1937 /* A route from a Non-client peer. Reflect to all other
1938 clients. */
1939 if (!CHECK_FLAG(peer->af_flags[afi][safi],
1940 PEER_FLAG_REFLECTOR_CLIENT))
1941 return false;
1942 }
1943 }
1944
1945 /* For modify attribute, copy it to temporary structure. */
1946 *attr = *piattr;
1947
1948 /* If local-preference is not set. */
1949 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
1950 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
1951 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1952 attr->local_pref = bgp->default_local_pref;
1953 }
1954
1955 /* If originator-id is not set and the route is to be reflected,
1956 set the originator id */
1957 if (reflect
1958 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
1959 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
1960 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
1961 }
1962
1963 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
1964 */
1965 if (peer->sort == BGP_PEER_EBGP
1966 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
1967 if (from != bgp->peer_self && !transparent
1968 && !CHECK_FLAG(peer->af_flags[afi][safi],
1969 PEER_FLAG_MED_UNCHANGED))
1970 attr->flag &=
1971 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
1972 }
1973
1974 /* Since the nexthop attribute can vary per peer, it is not explicitly
1975 * set
1976 * in announce check, only certain flags and length (or number of
1977 * nexthops
1978 * -- for IPv6/MP_REACH) are set here in order to guide the update
1979 * formation
1980 * code in setting the nexthop(s) on a per peer basis in
1981 * reformat_peer().
1982 * Typically, the source nexthop in the attribute is preserved but in
1983 * the
1984 * scenarios where we know it will always be overwritten, we reset the
1985 * nexthop to "0" in an attempt to achieve better Update packing. An
1986 * example of this is when a prefix from each of 2 IBGP peers needs to
1987 * be
1988 * announced to an EBGP peer (and they have the same attributes barring
1989 * their nexthop).
1990 */
1991 if (reflect)
1992 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
1993
1994 #define NEXTHOP_IS_V6 \
1995 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
1996 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
1997 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
1998 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1999
2000 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2001 * if
2002 * the peer (group) is configured to receive link-local nexthop
2003 * unchanged
2004 * and it is available in the prefix OR we're not reflecting the route,
2005 * link-local nexthop address is valid and
2006 * the peer (group) to whom we're going to announce is on a shared
2007 * network
2008 * and this is either a self-originated route or the peer is EBGP.
2009 * By checking if nexthop LL address is valid we are sure that
2010 * we do not announce LL address as `::`.
2011 */
2012 if (NEXTHOP_IS_V6) {
2013 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2014 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2015 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2016 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2017 || (!reflect
2018 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2019 && peer->shared_network
2020 && (from == bgp->peer_self
2021 || peer->sort == BGP_PEER_EBGP))) {
2022 attr->mp_nexthop_len =
2023 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2024 }
2025
2026 /* Clear off link-local nexthop in source, whenever it is not
2027 * needed to
2028 * ensure more prefixes share the same attribute for
2029 * announcement.
2030 */
2031 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2032 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2033 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2034 }
2035
2036 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2037 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2038
2039 /* Route map & unsuppress-map apply. */
2040 if (!skip_rmap_check
2041 && (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2042 struct bgp_path_info rmap_path = {0};
2043 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2044 struct attr dummy_attr = {0};
2045
2046 /* Fill temp path_info */
2047 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2048 pi, peer, attr);
2049
2050 /* don't confuse inbound and outbound setting */
2051 RESET_FLAG(attr->rmap_change_flags);
2052
2053 /*
2054 * The route reflector is not allowed to modify the attributes
2055 * of the reflected IBGP routes unless explicitly allowed.
2056 */
2057 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2058 && !CHECK_FLAG(bgp->flags,
2059 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2060 dummy_attr = *attr;
2061 rmap_path.attr = &dummy_attr;
2062 }
2063
2064 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2065
2066 if (bgp_path_suppressed(pi))
2067 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2068 &rmap_path);
2069 else
2070 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2071 &rmap_path);
2072
2073 peer->rmap_type = 0;
2074
2075 if (ret == RMAP_DENYMATCH) {
2076 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2077 zlog_debug(
2078 "%s [Update:SEND] %pFX is filtered by route-map",
2079 peer->host, p);
2080
2081 bgp_attr_flush(attr);
2082 return false;
2083 }
2084 }
2085
2086 /* RFC 8212 to prevent route leaks.
2087 * This specification intends to improve this situation by requiring the
2088 * explicit configuration of both BGP Import and Export Policies for any
2089 * External BGP (EBGP) session such as customers, peers, or
2090 * confederation boundaries for all enabled address families. Through
2091 * codification of the aforementioned requirement, operators will
2092 * benefit from consistent behavior across different BGP
2093 * implementations.
2094 */
2095 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2096 if (!bgp_outbound_policy_exists(peer, filter))
2097 return false;
2098
2099 /* draft-ietf-idr-deprecate-as-set-confed-set
2100 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2101 * Eventually, This document (if approved) updates RFC 4271
2102 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2103 * and obsoletes RFC 6472.
2104 */
2105 if (peer->bgp->reject_as_sets)
2106 if (aspath_check_as_sets(attr->aspath))
2107 return false;
2108
2109 /* Codification of AS 0 Processing */
2110 if (aspath_check_as_zero(attr->aspath))
2111 return false;
2112
2113 if (bgp_in_graceful_shutdown(bgp)) {
2114 if (peer->sort == BGP_PEER_IBGP
2115 || peer->sort == BGP_PEER_CONFED) {
2116 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2117 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2118 } else {
2119 bgp_attr_add_gshut_community(attr);
2120 }
2121 }
2122
2123 /* After route-map has been applied, we check to see if the nexthop to
2124 * be carried in the attribute (that is used for the announcement) can
2125 * be cleared off or not. We do this in all cases where we would be
2126 * setting the nexthop to "ourselves". For IPv6, we only need to
2127 * consider
2128 * the global nexthop here; the link-local nexthop would have been
2129 * cleared
2130 * already, and if not, it is required by the update formation code.
2131 * Also see earlier comments in this function.
2132 */
2133 /*
2134 * If route-map has performed some operation on the nexthop or the peer
2135 * configuration says to pass it unchanged, we cannot reset the nexthop
2136 * here, so only attempt to do it if these aren't true. Note that the
2137 * route-map handler itself might have cleared the nexthop, if for
2138 * example,
2139 * it is configured as 'peer-address'.
2140 */
2141 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2142 piattr->rmap_change_flags)
2143 && !transparent
2144 && !CHECK_FLAG(peer->af_flags[afi][safi],
2145 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2146 /* We can reset the nexthop, if setting (or forcing) it to
2147 * 'self' */
2148 if (CHECK_FLAG(peer->af_flags[afi][safi],
2149 PEER_FLAG_NEXTHOP_SELF)
2150 || CHECK_FLAG(peer->af_flags[afi][safi],
2151 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2152 if (!reflect
2153 || CHECK_FLAG(peer->af_flags[afi][safi],
2154 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2155 subgroup_announce_reset_nhop(
2156 (peer_cap_enhe(peer, afi, safi)
2157 ? AF_INET6
2158 : p->family),
2159 attr);
2160 nh_reset = true;
2161 }
2162 } else if (peer->sort == BGP_PEER_EBGP) {
2163 /* Can also reset the nexthop if announcing to EBGP, but
2164 * only if
2165 * no peer in the subgroup is on a shared subnet.
2166 * Note: 3rd party nexthop currently implemented for
2167 * IPv4 only.
2168 */
2169 if ((p->family == AF_INET) &&
2170 (!bgp_subgrp_multiaccess_check_v4(
2171 piattr->nexthop,
2172 subgrp, from))) {
2173 subgroup_announce_reset_nhop(
2174 (peer_cap_enhe(peer, afi, safi)
2175 ? AF_INET6
2176 : p->family),
2177 attr);
2178 nh_reset = true;
2179 }
2180
2181 if ((p->family == AF_INET6) &&
2182 (!bgp_subgrp_multiaccess_check_v6(
2183 piattr->mp_nexthop_global,
2184 subgrp, from))) {
2185 subgroup_announce_reset_nhop(
2186 (peer_cap_enhe(peer, afi, safi)
2187 ? AF_INET6
2188 : p->family),
2189 attr);
2190 nh_reset = true;
2191 }
2192
2193
2194
2195 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2196 /*
2197 * This flag is used for leaked vpn-vrf routes
2198 */
2199 int family = p->family;
2200
2201 if (peer_cap_enhe(peer, afi, safi))
2202 family = AF_INET6;
2203
2204 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2205 zlog_debug(
2206 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
2207 __func__, family2str(family));
2208 subgroup_announce_reset_nhop(family, attr);
2209 nh_reset = true;
2210 }
2211 }
2212
2213 /* If IPv6/MP and nexthop does not have any override and happens
2214 * to
2215 * be a link-local address, reset it so that we don't pass along
2216 * the
2217 * source's link-local IPv6 address to recipients who may not be
2218 * on
2219 * the same interface.
2220 */
2221 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2222 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2223 subgroup_announce_reset_nhop(AF_INET6, attr);
2224 nh_reset = true;
2225 }
2226 }
2227
2228 /*
2229 * When the next hop is set to ourselves, if all multipaths have
2230 * link-bandwidth announce the cumulative bandwidth as that makes
2231 * the most sense. However, don't modify if the link-bandwidth has
2232 * been explicitly set by user policy.
2233 */
2234 if (nh_reset &&
2235 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2236 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2237 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2238 attr->ecommunity = ecommunity_replace_linkbw(
2239 bgp->as, attr->ecommunity, cum_bw);
2240
2241 return true;
2242 }
2243
2244 static int bgp_route_select_timer_expire(struct thread *thread)
2245 {
2246 struct afi_safi_info *info;
2247 afi_t afi;
2248 safi_t safi;
2249 struct bgp *bgp;
2250
2251 info = THREAD_ARG(thread);
2252 afi = info->afi;
2253 safi = info->safi;
2254 bgp = info->bgp;
2255
2256 if (BGP_DEBUG(update, UPDATE_OUT))
2257 zlog_debug("afi %d, safi %d : route select timer expired", afi,
2258 safi);
2259
2260 bgp->gr_info[afi][safi].t_route_select = NULL;
2261
2262 XFREE(MTYPE_TMP, info);
2263
2264 /* Best path selection */
2265 return bgp_best_path_select_defer(bgp, afi, safi);
2266 }
2267
2268 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2269 struct bgp_maxpaths_cfg *mpath_cfg,
2270 struct bgp_path_info_pair *result, afi_t afi,
2271 safi_t safi)
2272 {
2273 struct bgp_path_info *new_select;
2274 struct bgp_path_info *old_select;
2275 struct bgp_path_info *pi;
2276 struct bgp_path_info *pi1;
2277 struct bgp_path_info *pi2;
2278 struct bgp_path_info *nextpi = NULL;
2279 int paths_eq, do_mpath, debug;
2280 struct list mp_list;
2281 char pfx_buf[PREFIX2STR_BUFFER];
2282 char path_buf[PATH_ADDPATH_STR_BUFFER];
2283
2284 bgp_mp_list_init(&mp_list);
2285 do_mpath =
2286 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2287
2288 debug = bgp_debug_bestpath(dest);
2289
2290 if (debug)
2291 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2292
2293 dest->reason = bgp_path_selection_none;
2294 /* bgp deterministic-med */
2295 new_select = NULL;
2296 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2297
2298 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2299 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2300 pi1 = pi1->next)
2301 bgp_path_info_unset_flag(dest, pi1,
2302 BGP_PATH_DMED_SELECTED);
2303
2304 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2305 pi1 = pi1->next) {
2306 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2307 continue;
2308 if (BGP_PATH_HOLDDOWN(pi1))
2309 continue;
2310 if (pi1->peer != bgp->peer_self)
2311 if (pi1->peer->status != Established)
2312 continue;
2313
2314 new_select = pi1;
2315 if (pi1->next) {
2316 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2317 if (CHECK_FLAG(pi2->flags,
2318 BGP_PATH_DMED_CHECK))
2319 continue;
2320 if (BGP_PATH_HOLDDOWN(pi2))
2321 continue;
2322 if (pi2->peer != bgp->peer_self
2323 && !CHECK_FLAG(
2324 pi2->peer->sflags,
2325 PEER_STATUS_NSF_WAIT))
2326 if (pi2->peer->status
2327 != Established)
2328 continue;
2329
2330 if (!aspath_cmp_left(pi1->attr->aspath,
2331 pi2->attr->aspath)
2332 && !aspath_cmp_left_confed(
2333 pi1->attr->aspath,
2334 pi2->attr->aspath))
2335 continue;
2336
2337 if (bgp_path_info_cmp(
2338 bgp, pi2, new_select,
2339 &paths_eq, mpath_cfg, debug,
2340 pfx_buf, afi, safi,
2341 &dest->reason)) {
2342 bgp_path_info_unset_flag(
2343 dest, new_select,
2344 BGP_PATH_DMED_SELECTED);
2345 new_select = pi2;
2346 }
2347
2348 bgp_path_info_set_flag(
2349 dest, pi2, BGP_PATH_DMED_CHECK);
2350 }
2351 }
2352 bgp_path_info_set_flag(dest, new_select,
2353 BGP_PATH_DMED_CHECK);
2354 bgp_path_info_set_flag(dest, new_select,
2355 BGP_PATH_DMED_SELECTED);
2356
2357 if (debug) {
2358 bgp_path_info_path_with_addpath_rx_str(
2359 new_select, path_buf, sizeof(path_buf));
2360 zlog_debug(
2361 "%pBD: %s is the bestpath from AS %u",
2362 dest, path_buf,
2363 aspath_get_first_as(
2364 new_select->attr->aspath));
2365 }
2366 }
2367 }
2368
2369 /* Check old selected route and new selected route. */
2370 old_select = NULL;
2371 new_select = NULL;
2372 for (pi = bgp_dest_get_bgp_path_info(dest);
2373 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2374 enum bgp_path_selection_reason reason;
2375
2376 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2377 old_select = pi;
2378
2379 if (BGP_PATH_HOLDDOWN(pi)) {
2380 /* reap REMOVED routes, if needs be
2381 * selected route must stay for a while longer though
2382 */
2383 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2384 && (pi != old_select))
2385 bgp_path_info_reap(dest, pi);
2386
2387 if (debug)
2388 zlog_debug("%s: pi %p in holddown", __func__,
2389 pi);
2390
2391 continue;
2392 }
2393
2394 if (pi->peer && pi->peer != bgp->peer_self
2395 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2396 if (pi->peer->status != Established) {
2397
2398 if (debug)
2399 zlog_debug(
2400 "%s: pi %p non self peer %s not estab state",
2401 __func__, pi, pi->peer->host);
2402
2403 continue;
2404 }
2405
2406 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2407 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2408 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2409 if (debug)
2410 zlog_debug("%s: pi %p dmed", __func__, pi);
2411 continue;
2412 }
2413
2414 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2415
2416 reason = dest->reason;
2417 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2418 debug, pfx_buf, afi, safi,
2419 &dest->reason)) {
2420 if (new_select == NULL &&
2421 reason != bgp_path_selection_none)
2422 dest->reason = reason;
2423 new_select = pi;
2424 }
2425 }
2426
2427 /* Now that we know which path is the bestpath see if any of the other
2428 * paths
2429 * qualify as multipaths
2430 */
2431 if (debug) {
2432 if (new_select)
2433 bgp_path_info_path_with_addpath_rx_str(
2434 new_select, path_buf, sizeof(path_buf));
2435 else
2436 snprintf(path_buf, sizeof(path_buf), "NONE");
2437 zlog_debug(
2438 "%pBD: After path selection, newbest is %s oldbest was %s",
2439 dest, path_buf,
2440 old_select ? old_select->peer->host : "NONE");
2441 }
2442
2443 if (do_mpath && new_select) {
2444 for (pi = bgp_dest_get_bgp_path_info(dest);
2445 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2446
2447 if (debug)
2448 bgp_path_info_path_with_addpath_rx_str(
2449 pi, path_buf, sizeof(path_buf));
2450
2451 if (pi == new_select) {
2452 if (debug)
2453 zlog_debug(
2454 "%pBD: %s is the bestpath, add to the multipath list",
2455 dest, path_buf);
2456 bgp_mp_list_add(&mp_list, pi);
2457 continue;
2458 }
2459
2460 if (BGP_PATH_HOLDDOWN(pi))
2461 continue;
2462
2463 if (pi->peer && pi->peer != bgp->peer_self
2464 && !CHECK_FLAG(pi->peer->sflags,
2465 PEER_STATUS_NSF_WAIT))
2466 if (pi->peer->status != Established)
2467 continue;
2468
2469 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2470 if (debug)
2471 zlog_debug(
2472 "%pBD: %s has the same nexthop as the bestpath, skip it",
2473 dest, path_buf);
2474 continue;
2475 }
2476
2477 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2478 mpath_cfg, debug, pfx_buf, afi, safi,
2479 &dest->reason);
2480
2481 if (paths_eq) {
2482 if (debug)
2483 zlog_debug(
2484 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2485 dest, path_buf);
2486 bgp_mp_list_add(&mp_list, pi);
2487 }
2488 }
2489 }
2490
2491 bgp_path_info_mpath_update(dest, new_select, old_select, &mp_list,
2492 mpath_cfg);
2493 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2494 bgp_mp_list_clear(&mp_list);
2495
2496 bgp_addpath_update_ids(bgp, dest, afi, safi);
2497
2498 result->old = old_select;
2499 result->new = new_select;
2500
2501 return;
2502 }
2503
2504 /*
2505 * A new route/change in bestpath of an existing route. Evaluate the path
2506 * for advertisement to the subgroup.
2507 */
2508 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2509 struct bgp_path_info *selected,
2510 struct bgp_dest *dest,
2511 uint32_t addpath_tx_id)
2512 {
2513 const struct prefix *p;
2514 struct peer *onlypeer;
2515 struct attr attr;
2516 afi_t afi;
2517 safi_t safi;
2518 struct bgp *bgp;
2519 bool advertise;
2520
2521 p = bgp_dest_get_prefix(dest);
2522 afi = SUBGRP_AFI(subgrp);
2523 safi = SUBGRP_SAFI(subgrp);
2524 bgp = SUBGRP_INST(subgrp);
2525 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2526 : NULL);
2527
2528 if (BGP_DEBUG(update, UPDATE_OUT))
2529 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2530
2531 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2532 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2533 PEER_STATUS_ORF_WAIT_REFRESH))
2534 return;
2535
2536 memset(&attr, 0, sizeof(struct attr));
2537 /* It's initialized in bgp_announce_check() */
2538
2539 /* Announcement to the subgroup. If the route is filtered withdraw it.
2540 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2541 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2542 * route
2543 */
2544 advertise = bgp_check_advertise(bgp, dest);
2545
2546 if (selected) {
2547 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2548 false)) {
2549 /* Route is selected, if the route is already installed
2550 * in FIB, then it is advertised
2551 */
2552 if (advertise)
2553 bgp_adj_out_set_subgroup(dest, subgrp, &attr,
2554 selected);
2555 } else
2556 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2557 addpath_tx_id);
2558 }
2559
2560 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2561 else {
2562 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2563 }
2564 }
2565
2566 /*
2567 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2568 * This is called at the end of route processing.
2569 */
2570 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2571 {
2572 struct bgp_path_info *pi;
2573
2574 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2575 if (BGP_PATH_HOLDDOWN(pi))
2576 continue;
2577 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2578 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2579 }
2580 }
2581
2582 /*
2583 * Has the route changed from the RIB's perspective? This is invoked only
2584 * if the route selection returns the same best route as earlier - to
2585 * determine if we need to update zebra or not.
2586 */
2587 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2588 {
2589 struct bgp_path_info *mpinfo;
2590
2591 /* If this is multipath, check all selected paths for any nexthop
2592 * change or attribute change. Some attribute changes (e.g., community)
2593 * aren't of relevance to the RIB, but we'll update zebra to ensure
2594 * we handle the case of BGP nexthop change. This is the behavior
2595 * when the best path has an attribute change anyway.
2596 */
2597 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2598 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2599 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2600 return true;
2601
2602 /*
2603 * If this is multipath, check all selected paths for any nexthop change
2604 */
2605 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2606 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2607 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2608 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2609 return true;
2610 }
2611
2612 /* Nothing has changed from the RIB's perspective. */
2613 return false;
2614 }
2615
2616 struct bgp_process_queue {
2617 struct bgp *bgp;
2618 STAILQ_HEAD(, bgp_dest) pqueue;
2619 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2620 unsigned int flags;
2621 unsigned int queued;
2622 };
2623
2624 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
2625 safi_t safi, struct bgp_dest *dest,
2626 struct bgp_path_info *new_select,
2627 struct bgp_path_info *old_select)
2628 {
2629 const struct prefix *p = bgp_dest_get_prefix(dest);
2630
2631 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
2632 return;
2633
2634 if (advertise_type5_routes(bgp, afi) && new_select
2635 && is_route_injectable_into_evpn(new_select)) {
2636
2637 /* apply the route-map */
2638 if (bgp->adv_cmd_rmap[afi][safi].map) {
2639 route_map_result_t ret;
2640 struct bgp_path_info rmap_path;
2641 struct bgp_path_info_extra rmap_path_extra;
2642 struct attr dummy_attr;
2643
2644 dummy_attr = *new_select->attr;
2645
2646 /* Fill temp path_info */
2647 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
2648 new_select, new_select->peer,
2649 &dummy_attr);
2650
2651 RESET_FLAG(dummy_attr.rmap_change_flags);
2652
2653 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
2654 p, &rmap_path);
2655
2656 if (ret == RMAP_DENYMATCH) {
2657 bgp_attr_flush(&dummy_attr);
2658 bgp_evpn_withdraw_type5_route(bgp, p, afi,
2659 safi);
2660 } else
2661 bgp_evpn_advertise_type5_route(
2662 bgp, p, &dummy_attr, afi, safi);
2663 } else {
2664 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
2665 afi, safi);
2666 }
2667 } else if (advertise_type5_routes(bgp, afi) && old_select
2668 && is_route_injectable_into_evpn(old_select))
2669 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
2670 }
2671
2672 /*
2673 * old_select = The old best path
2674 * new_select = the new best path
2675 *
2676 * if (!old_select && new_select)
2677 * We are sending new information on.
2678 *
2679 * if (old_select && new_select) {
2680 * if (new_select != old_select)
2681 * We have a new best path send a change
2682 * else
2683 * We've received a update with new attributes that needs
2684 * to be passed on.
2685 * }
2686 *
2687 * if (old_select && !new_select)
2688 * We have no eligible route that we can announce or the rn
2689 * is being removed.
2690 */
2691 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
2692 afi_t afi, safi_t safi)
2693 {
2694 struct bgp_path_info *new_select;
2695 struct bgp_path_info *old_select;
2696 struct bgp_path_info_pair old_and_new;
2697 int debug = 0;
2698
2699 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
2700 if (dest)
2701 debug = bgp_debug_bestpath(dest);
2702 if (debug)
2703 zlog_debug(
2704 "%s: bgp delete in progress, ignoring event, p=%pBD",
2705 __func__, dest);
2706 return;
2707 }
2708 /* Is it end of initial update? (after startup) */
2709 if (!dest) {
2710 quagga_timestamp(3, bgp->update_delay_zebra_resume_time,
2711 sizeof(bgp->update_delay_zebra_resume_time));
2712
2713 bgp->main_zebra_update_hold = 0;
2714 FOREACH_AFI_SAFI (afi, safi) {
2715 if (bgp_fibupd_safi(safi))
2716 bgp_zebra_announce_table(bgp, afi, safi);
2717 }
2718 bgp->main_peers_update_hold = 0;
2719
2720 bgp_start_routeadv(bgp);
2721 return;
2722 }
2723
2724 const struct prefix *p = bgp_dest_get_prefix(dest);
2725
2726 debug = bgp_debug_bestpath(dest);
2727 if (debug)
2728 zlog_debug("%s: p=%pBD afi=%s, safi=%s start", __func__, dest,
2729 afi2str(afi), safi2str(safi));
2730
2731 /* The best path calculation for the route is deferred if
2732 * BGP_NODE_SELECT_DEFER is set
2733 */
2734 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
2735 if (BGP_DEBUG(update, UPDATE_OUT))
2736 zlog_debug("SELECT_DEFER flag set for route %p", dest);
2737 return;
2738 }
2739
2740 /* Best path selection. */
2741 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
2742 afi, safi);
2743 old_select = old_and_new.old;
2744 new_select = old_and_new.new;
2745
2746 /* Do we need to allocate or free labels?
2747 * Right now, since we only deal with per-prefix labels, it is not
2748 * necessary to do this upon changes to best path. Exceptions:
2749 * - label index has changed -> recalculate resulting label
2750 * - path_info sub_type changed -> switch to/from implicit-null
2751 * - no valid label (due to removed static label binding) -> get new one
2752 */
2753 if (bgp->allocate_mpls_labels[afi][safi]) {
2754 if (new_select) {
2755 if (!old_select
2756 || bgp_label_index_differs(new_select, old_select)
2757 || new_select->sub_type != old_select->sub_type
2758 || !bgp_is_valid_label(&dest->local_label)) {
2759 /* Enforced penultimate hop popping:
2760 * implicit-null for local routes, aggregate
2761 * and redistributed routes
2762 */
2763 if (new_select->sub_type == BGP_ROUTE_STATIC
2764 || new_select->sub_type
2765 == BGP_ROUTE_AGGREGATE
2766 || new_select->sub_type
2767 == BGP_ROUTE_REDISTRIBUTE) {
2768 if (CHECK_FLAG(
2769 dest->flags,
2770 BGP_NODE_REGISTERED_FOR_LABEL)
2771 || CHECK_FLAG(
2772 dest->flags,
2773 BGP_NODE_LABEL_REQUESTED))
2774 bgp_unregister_for_label(dest);
2775 label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1,
2776 &dest->local_label);
2777 bgp_set_valid_label(&dest->local_label);
2778 } else
2779 bgp_register_for_label(dest,
2780 new_select);
2781 }
2782 } else if (CHECK_FLAG(dest->flags,
2783 BGP_NODE_REGISTERED_FOR_LABEL)
2784 || CHECK_FLAG(dest->flags,
2785 BGP_NODE_LABEL_REQUESTED)) {
2786 bgp_unregister_for_label(dest);
2787 }
2788 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
2789 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
2790 bgp_unregister_for_label(dest);
2791 }
2792
2793 if (debug)
2794 zlog_debug(
2795 "%s: p=%pBD afi=%s, safi=%s, old_select=%p, new_select=%p",
2796 __func__, dest, afi2str(afi), safi2str(safi),
2797 old_select, new_select);
2798
2799 /* If best route remains the same and this is not due to user-initiated
2800 * clear, see exactly what needs to be done.
2801 */
2802 if (old_select && old_select == new_select
2803 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
2804 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2805 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
2806 if (bgp_zebra_has_route_changed(old_select)) {
2807 #ifdef ENABLE_BGP_VNC
2808 vnc_import_bgp_add_route(bgp, p, old_select);
2809 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
2810 #endif
2811 if (bgp_fibupd_safi(safi)
2812 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2813
2814 if (new_select->type == ZEBRA_ROUTE_BGP
2815 && (new_select->sub_type == BGP_ROUTE_NORMAL
2816 || new_select->sub_type
2817 == BGP_ROUTE_IMPORTED))
2818
2819 bgp_zebra_announce(dest, p, old_select,
2820 bgp, afi, safi);
2821 }
2822 }
2823
2824 /* If there is a change of interest to peers, reannounce the
2825 * route. */
2826 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2827 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
2828 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
2829 group_announce_route(bgp, afi, safi, dest, new_select);
2830
2831 /* unicast routes must also be annouced to
2832 * labeled-unicast update-groups */
2833 if (safi == SAFI_UNICAST)
2834 group_announce_route(bgp, afi,
2835 SAFI_LABELED_UNICAST, dest,
2836 new_select);
2837
2838 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
2839 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
2840 }
2841
2842 /* advertise/withdraw type-5 routes */
2843 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
2844 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
2845 bgp_process_evpn_route_injection(
2846 bgp, afi, safi, dest, old_select, old_select);
2847
2848 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
2849 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
2850 bgp_zebra_clear_route_change_flags(dest);
2851 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
2852 return;
2853 }
2854
2855 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2856 */
2857 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
2858
2859 /* bestpath has changed; bump version */
2860 if (old_select || new_select) {
2861 bgp_bump_version(dest);
2862
2863 if (!bgp->t_rmap_def_originate_eval) {
2864 bgp_lock(bgp);
2865 thread_add_timer(
2866 bm->master,
2867 update_group_refresh_default_originate_route_map,
2868 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
2869 &bgp->t_rmap_def_originate_eval);
2870 }
2871 }
2872
2873 if (old_select)
2874 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
2875 if (new_select) {
2876 if (debug)
2877 zlog_debug("%s: setting SELECTED flag", __func__);
2878 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
2879 bgp_path_info_unset_flag(dest, new_select,
2880 BGP_PATH_ATTR_CHANGED);
2881 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
2882 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
2883 }
2884
2885 #ifdef ENABLE_BGP_VNC
2886 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
2887 if (old_select != new_select) {
2888 if (old_select) {
2889 vnc_import_bgp_exterior_del_route(bgp, p,
2890 old_select);
2891 vnc_import_bgp_del_route(bgp, p, old_select);
2892 }
2893 if (new_select) {
2894 vnc_import_bgp_exterior_add_route(bgp, p,
2895 new_select);
2896 vnc_import_bgp_add_route(bgp, p, new_select);
2897 }
2898 }
2899 }
2900 #endif
2901
2902 group_announce_route(bgp, afi, safi, dest, new_select);
2903
2904 /* unicast routes must also be annouced to labeled-unicast update-groups
2905 */
2906 if (safi == SAFI_UNICAST)
2907 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
2908 new_select);
2909
2910 /* FIB update. */
2911 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
2912 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2913 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
2914 && (new_select->sub_type == BGP_ROUTE_NORMAL
2915 || new_select->sub_type == BGP_ROUTE_AGGREGATE
2916 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
2917
2918 /* if this is an evpn imported type-5 prefix,
2919 * we need to withdraw the route first to clear
2920 * the nh neigh and the RMAC entry.
2921 */
2922 if (old_select &&
2923 is_route_parent_evpn(old_select))
2924 bgp_zebra_withdraw(p, old_select, bgp, safi);
2925
2926 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
2927 } else {
2928 /* Withdraw the route from the kernel. */
2929 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
2930 && (old_select->sub_type == BGP_ROUTE_NORMAL
2931 || old_select->sub_type == BGP_ROUTE_AGGREGATE
2932 || old_select->sub_type == BGP_ROUTE_IMPORTED))
2933
2934 bgp_zebra_withdraw(p, old_select, bgp, safi);
2935 }
2936 }
2937
2938 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
2939 old_select);
2940
2941 /* Clear any route change flags. */
2942 bgp_zebra_clear_route_change_flags(dest);
2943
2944 /* Reap old select bgp_path_info, if it has been removed */
2945 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
2946 bgp_path_info_reap(dest, old_select);
2947
2948 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
2949 return;
2950 }
2951
2952 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
2953 int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
2954 {
2955 struct bgp_dest *dest;
2956 int cnt = 0;
2957 struct afi_safi_info *thread_info;
2958
2959 if (bgp->gr_info[afi][safi].t_route_select) {
2960 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
2961
2962 thread_info = THREAD_ARG(t);
2963 XFREE(MTYPE_TMP, thread_info);
2964 BGP_TIMER_OFF(bgp->gr_info[afi][safi].t_route_select);
2965 }
2966
2967 if (BGP_DEBUG(update, UPDATE_OUT)) {
2968 zlog_debug("%s: processing route for %s : cnt %d", __func__,
2969 get_afi_safi_str(afi, safi, false),
2970 bgp->gr_info[afi][safi].gr_deferred);
2971 }
2972
2973 /* Process the route list */
2974 for (dest = bgp_table_top(bgp->rib[afi][safi]);
2975 dest && bgp->gr_info[afi][safi].gr_deferred != 0;
2976 dest = bgp_route_next(dest)) {
2977 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
2978 continue;
2979
2980 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
2981 bgp->gr_info[afi][safi].gr_deferred--;
2982 bgp_process_main_one(bgp, dest, afi, safi);
2983 cnt++;
2984 if (cnt >= BGP_MAX_BEST_ROUTE_SELECT) {
2985 bgp_dest_unlock_node(dest);
2986 break;
2987 }
2988 }
2989
2990 /* Send EOR message when all routes are processed */
2991 if (!bgp->gr_info[afi][safi].gr_deferred) {
2992 bgp_send_delayed_eor(bgp);
2993 /* Send route processing complete message to RIB */
2994 bgp_zebra_update(afi, safi, bgp->vrf_id,
2995 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
2996 return 0;
2997 }
2998
2999 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3000
3001 thread_info->afi = afi;
3002 thread_info->safi = safi;
3003 thread_info->bgp = bgp;
3004
3005 /* If there are more routes to be processed, start the
3006 * selection timer
3007 */
3008 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3009 BGP_ROUTE_SELECT_DELAY,
3010 &bgp->gr_info[afi][safi].t_route_select);
3011 return 0;
3012 }
3013
3014 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3015 {
3016 struct bgp_process_queue *pqnode = data;
3017 struct bgp *bgp = pqnode->bgp;
3018 struct bgp_table *table;
3019 struct bgp_dest *dest;
3020
3021 /* eoiu marker */
3022 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3023 bgp_process_main_one(bgp, NULL, 0, 0);
3024 /* should always have dedicated wq call */
3025 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3026 return WQ_SUCCESS;
3027 }
3028
3029 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3030 dest = STAILQ_FIRST(&pqnode->pqueue);
3031 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3032 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3033 table = bgp_dest_table(dest);
3034 /* note, new DESTs may be added as part of processing */
3035 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3036
3037 bgp_dest_unlock_node(dest);
3038 bgp_table_unlock(table);
3039 }
3040
3041 return WQ_SUCCESS;
3042 }
3043
3044 static void bgp_processq_del(struct work_queue *wq, void *data)
3045 {
3046 struct bgp_process_queue *pqnode = data;
3047
3048 bgp_unlock(pqnode->bgp);
3049
3050 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3051 }
3052
3053 void bgp_process_queue_init(struct bgp *bgp)
3054 {
3055 if (!bgp->process_queue) {
3056 char name[BUFSIZ];
3057
3058 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3059 bgp->process_queue = work_queue_new(bm->master, name);
3060 }
3061
3062 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3063 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3064 bgp->process_queue->spec.max_retries = 0;
3065 bgp->process_queue->spec.hold = 50;
3066 /* Use a higher yield value of 50ms for main queue processing */
3067 bgp->process_queue->spec.yield = 50 * 1000L;
3068 }
3069
3070 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3071 {
3072 struct bgp_process_queue *pqnode;
3073
3074 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3075 sizeof(struct bgp_process_queue));
3076
3077 /* unlocked in bgp_processq_del */
3078 pqnode->bgp = bgp_lock(bgp);
3079 STAILQ_INIT(&pqnode->pqueue);
3080
3081 return pqnode;
3082 }
3083
3084 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3085 {
3086 #define ARBITRARY_PROCESS_QLEN 10000
3087 struct work_queue *wq = bgp->process_queue;
3088 struct bgp_process_queue *pqnode;
3089 int pqnode_reuse = 0;
3090
3091 /* already scheduled for processing? */
3092 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3093 return;
3094
3095 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3096 * the workqueue
3097 */
3098 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3099 if (BGP_DEBUG(update, UPDATE_OUT))
3100 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3101 dest);
3102 return;
3103 }
3104
3105 if (wq == NULL)
3106 return;
3107
3108 /* Add route nodes to an existing work queue item until reaching the
3109 limit only if is from the same BGP view and it's not an EOIU marker
3110 */
3111 if (work_queue_item_count(wq)) {
3112 struct work_queue_item *item = work_queue_last_item(wq);
3113 pqnode = item->data;
3114
3115 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3116 || pqnode->bgp != bgp
3117 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3118 pqnode = bgp_processq_alloc(bgp);
3119 else
3120 pqnode_reuse = 1;
3121 } else
3122 pqnode = bgp_processq_alloc(bgp);
3123 /* all unlocked in bgp_process_wq */
3124 bgp_table_lock(bgp_dest_table(dest));
3125
3126 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3127 bgp_dest_lock_node(dest);
3128
3129 /* can't be enqueued twice */
3130 assert(STAILQ_NEXT(dest, pq) == NULL);
3131 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3132 pqnode->queued++;
3133
3134 if (!pqnode_reuse)
3135 work_queue_add(wq, pqnode);
3136
3137 return;
3138 }
3139
3140 void bgp_add_eoiu_mark(struct bgp *bgp)
3141 {
3142 struct bgp_process_queue *pqnode;
3143
3144 if (bgp->process_queue == NULL)
3145 return;
3146
3147 pqnode = bgp_processq_alloc(bgp);
3148
3149 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3150 work_queue_add(bgp->process_queue, pqnode);
3151 }
3152
3153 static int bgp_maximum_prefix_restart_timer(struct thread *thread)
3154 {
3155 struct peer *peer;
3156
3157 peer = THREAD_ARG(thread);
3158 peer->t_pmax_restart = NULL;
3159
3160 if (bgp_debug_neighbor_events(peer))
3161 zlog_debug(
3162 "%s Maximum-prefix restart timer expired, restore peering",
3163 peer->host);
3164
3165 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3166 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3167
3168 return 0;
3169 }
3170
3171 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3172 safi_t safi)
3173 {
3174 uint32_t count = 0;
3175 bool filtered = false;
3176 struct bgp_dest *dest;
3177 struct bgp_adj_in *ain;
3178 struct attr attr = {};
3179 struct bgp_table *table = peer->bgp->rib[afi][safi];
3180
3181 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3182 for (ain = dest->adj_in; ain; ain = ain->next) {
3183 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3184
3185 attr = *ain->attr;
3186
3187 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3188 == FILTER_DENY)
3189 filtered = true;
3190
3191 if (bgp_input_modifier(
3192 peer, rn_p, &attr, afi, safi,
3193 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3194 NULL, 0, NULL)
3195 == RMAP_DENY)
3196 filtered = true;
3197
3198 if (filtered)
3199 count++;
3200
3201 bgp_attr_undup(&attr, ain->attr);
3202 }
3203 }
3204
3205 return count;
3206 }
3207
3208 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3209 int always)
3210 {
3211 iana_afi_t pkt_afi;
3212 iana_safi_t pkt_safi;
3213 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3214 PEER_FLAG_MAX_PREFIX_FORCE))
3215 ? bgp_filtered_routes_count(peer, afi, safi)
3216 + peer->pcount[afi][safi]
3217 : peer->pcount[afi][safi];
3218
3219 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3220 return false;
3221
3222 if (pcount > peer->pmax[afi][safi]) {
3223 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3224 PEER_STATUS_PREFIX_LIMIT)
3225 && !always)
3226 return false;
3227
3228 zlog_info(
3229 "%%MAXPFXEXCEED: No. of %s prefix received from %s %u exceed, limit %u",
3230 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3231 peer->pmax[afi][safi]);
3232 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3233
3234 if (CHECK_FLAG(peer->af_flags[afi][safi],
3235 PEER_FLAG_MAX_PREFIX_WARNING))
3236 return false;
3237
3238 /* Convert AFI, SAFI to values for packet. */
3239 pkt_afi = afi_int2iana(afi);
3240 pkt_safi = safi_int2iana(safi);
3241 {
3242 uint8_t ndata[7];
3243
3244 ndata[0] = (pkt_afi >> 8);
3245 ndata[1] = pkt_afi;
3246 ndata[2] = pkt_safi;
3247 ndata[3] = (peer->pmax[afi][safi] >> 24);
3248 ndata[4] = (peer->pmax[afi][safi] >> 16);
3249 ndata[5] = (peer->pmax[afi][safi] >> 8);
3250 ndata[6] = (peer->pmax[afi][safi]);
3251
3252 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3253 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3254 BGP_NOTIFY_CEASE_MAX_PREFIX,
3255 ndata, 7);
3256 }
3257
3258 /* Dynamic peers will just close their connection. */
3259 if (peer_dynamic_neighbor(peer))
3260 return true;
3261
3262 /* restart timer start */
3263 if (peer->pmax_restart[afi][safi]) {
3264 peer->v_pmax_restart =
3265 peer->pmax_restart[afi][safi] * 60;
3266
3267 if (bgp_debug_neighbor_events(peer))
3268 zlog_debug(
3269 "%s Maximum-prefix restart timer started for %d secs",
3270 peer->host, peer->v_pmax_restart);
3271
3272 BGP_TIMER_ON(peer->t_pmax_restart,
3273 bgp_maximum_prefix_restart_timer,
3274 peer->v_pmax_restart);
3275 }
3276
3277 return true;
3278 } else
3279 UNSET_FLAG(peer->af_sflags[afi][safi],
3280 PEER_STATUS_PREFIX_LIMIT);
3281
3282 if (pcount
3283 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3284 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3285 PEER_STATUS_PREFIX_THRESHOLD)
3286 && !always)
3287 return false;
3288
3289 zlog_info(
3290 "%%MAXPFX: No. of %s prefix received from %s reaches %u, max %u",
3291 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3292 peer->pmax[afi][safi]);
3293 SET_FLAG(peer->af_sflags[afi][safi],
3294 PEER_STATUS_PREFIX_THRESHOLD);
3295 } else
3296 UNSET_FLAG(peer->af_sflags[afi][safi],
3297 PEER_STATUS_PREFIX_THRESHOLD);
3298 return false;
3299 }
3300
3301 /* Unconditionally remove the route from the RIB, without taking
3302 * damping into consideration (eg, because the session went down)
3303 */
3304 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3305 struct peer *peer, afi_t afi, safi_t safi)
3306 {
3307
3308 struct bgp *bgp = NULL;
3309 bool delete_route = false;
3310
3311 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3312 safi);
3313
3314 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3315 bgp_path_info_delete(dest, pi); /* keep historical info */
3316
3317 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3318 * flag
3319 */
3320 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3321 delete_route = true;
3322 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3323 delete_route = true;
3324 if (delete_route) {
3325 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3326 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3327 bgp = pi->peer->bgp;
3328 bgp->gr_info[afi][safi].gr_deferred--;
3329 }
3330 }
3331 }
3332
3333 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3334 bgp_process(peer->bgp, dest, afi, safi);
3335 }
3336
3337 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3338 struct peer *peer, afi_t afi, safi_t safi,
3339 struct prefix_rd *prd)
3340 {
3341 const struct prefix *p = bgp_dest_get_prefix(dest);
3342
3343 /* apply dampening, if result is suppressed, we'll be retaining
3344 * the bgp_path_info in the RIB for historical reference.
3345 */
3346 if (peer->sort == BGP_PEER_EBGP) {
3347 if (get_active_bdc_from_pi(pi, afi, safi)) {
3348 if (bgp_damp_withdraw(pi, dest, afi, safi, 0)
3349 == BGP_DAMP_SUPPRESSED) {
3350 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3351 safi);
3352 return;
3353 }
3354 }
3355 }
3356
3357 #ifdef ENABLE_BGP_VNC
3358 if (safi == SAFI_MPLS_VPN) {
3359 struct bgp_dest *pdest = NULL;
3360 struct bgp_table *table = NULL;
3361
3362 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3363 (struct prefix *)prd);
3364 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3365 table = bgp_dest_get_bgp_table_info(pdest);
3366
3367 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3368 peer->bgp, prd, table, p, pi);
3369 }
3370 bgp_dest_unlock_node(pdest);
3371 }
3372 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3373 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3374
3375 vnc_import_bgp_del_route(peer->bgp, p, pi);
3376 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3377 }
3378 }
3379 #endif
3380
3381 /* If this is an EVPN route, process for un-import. */
3382 if (safi == SAFI_EVPN)
3383 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3384
3385 bgp_rib_remove(dest, pi, peer, afi, safi);
3386 }
3387
3388 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3389 struct peer *peer, struct attr *attr,
3390 struct bgp_dest *dest)
3391 {
3392 struct bgp_path_info *new;
3393
3394 /* Make new BGP info. */
3395 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3396 new->type = type;
3397 new->instance = instance;
3398 new->sub_type = sub_type;
3399 new->peer = peer;
3400 new->attr = attr;
3401 new->uptime = bgp_clock();
3402 new->net = dest;
3403 return new;
3404 }
3405
3406 static void overlay_index_update(struct attr *attr,
3407 union gw_addr *gw_ip)
3408 {
3409 if (!attr)
3410 return;
3411 if (gw_ip == NULL) {
3412 struct bgp_route_evpn eo;
3413
3414 memset(&eo, 0, sizeof(eo));
3415 bgp_attr_set_evpn_overlay(attr, &eo);
3416 } else {
3417 struct bgp_route_evpn eo = {.gw_ip = *gw_ip};
3418
3419 bgp_attr_set_evpn_overlay(attr, &eo);
3420 }
3421 }
3422
3423 static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path,
3424 union gw_addr *gw_ip)
3425 {
3426 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(path->attr);
3427 union gw_addr path_gw_ip, *path_gw_ip_remote;
3428 union {
3429 esi_t esi;
3430 union gw_addr ip;
3431 } temp;
3432
3433 if (afi != AFI_L2VPN)
3434 return true;
3435
3436 path_gw_ip = eo->gw_ip;
3437
3438 if (gw_ip == NULL) {
3439 memset(&temp, 0, sizeof(temp));
3440 path_gw_ip_remote = &temp.ip;
3441 } else
3442 path_gw_ip_remote = gw_ip;
3443
3444 return !!memcmp(&path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr));
3445 }
3446
3447 /* Check if received nexthop is valid or not. */
3448 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3449 uint8_t type, uint8_t stype, struct attr *attr,
3450 struct bgp_dest *dest)
3451 {
3452 bool ret = false;
3453 bool is_bgp_static_route =
3454 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3455 : false;
3456
3457 /*
3458 * Only validated for unicast and multicast currently.
3459 * Also valid for EVPN where the nexthop is an IP address.
3460 * If we are a bgp static route being checked then there is
3461 * no need to check to see if the nexthop is martian as
3462 * that it should be ok.
3463 */
3464 if (is_bgp_static_route ||
3465 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3466 return false;
3467
3468 /* If NEXT_HOP is present, validate it. */
3469 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3470 if (attr->nexthop.s_addr == INADDR_ANY
3471 || IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr))
3472 || bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3473 return true;
3474 }
3475
3476 /* If MP_NEXTHOP is present, validate it. */
3477 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3478 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3479 * it is not an IPv6 link-local address.
3480 *
3481 * If we receive an UPDATE with nexthop length set to 32 bytes
3482 * we shouldn't discard an UPDATE if it's set to (::).
3483 * The link-local (2st) is validated along the code path later.
3484 */
3485 if (attr->mp_nexthop_len) {
3486 switch (attr->mp_nexthop_len) {
3487 case BGP_ATTR_NHLEN_IPV4:
3488 case BGP_ATTR_NHLEN_VPNV4:
3489 ret = (attr->mp_nexthop_global_in.s_addr == INADDR_ANY
3490 || IPV4_CLASS_DE(
3491 ntohl(attr->mp_nexthop_global_in.s_addr))
3492 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3493 dest));
3494 break;
3495
3496 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3497 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3498 ret = (IN6_IS_ADDR_UNSPECIFIED(
3499 &attr->mp_nexthop_global)
3500 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3501 || IN6_IS_ADDR_MULTICAST(
3502 &attr->mp_nexthop_global)
3503 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3504 dest));
3505 break;
3506 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3507 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3508 || IN6_IS_ADDR_MULTICAST(
3509 &attr->mp_nexthop_global)
3510 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3511 dest));
3512 break;
3513
3514 default:
3515 ret = true;
3516 break;
3517 }
3518 }
3519
3520 return ret;
3521 }
3522
3523 static void bgp_attr_add_no_export_community(struct attr *attr)
3524 {
3525 struct community *old;
3526 struct community *new;
3527 struct community *merge;
3528 struct community *no_export;
3529
3530 old = attr->community;
3531 no_export = community_str2com("no-export");
3532
3533 assert(no_export);
3534
3535 if (old) {
3536 merge = community_merge(community_dup(old), no_export);
3537
3538 if (!old->refcnt)
3539 community_free(&old);
3540
3541 new = community_uniq_sort(merge);
3542 community_free(&merge);
3543 } else {
3544 new = community_dup(no_export);
3545 }
3546
3547 community_free(&no_export);
3548
3549 attr->community = new;
3550 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
3551 }
3552
3553 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3554 struct attr *attr, afi_t afi, safi_t safi, int type,
3555 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3556 uint32_t num_labels, int soft_reconfig,
3557 struct bgp_route_evpn *evpn)
3558 {
3559 int ret;
3560 int aspath_loop_count = 0;
3561 struct bgp_dest *dest;
3562 struct bgp *bgp;
3563 struct attr new_attr;
3564 struct attr *attr_new;
3565 struct bgp_path_info *pi;
3566 struct bgp_path_info *new;
3567 struct bgp_path_info_extra *extra;
3568 const char *reason;
3569 char pfx_buf[BGP_PRD_PATH_STRLEN];
3570 int connected = 0;
3571 int do_loop_check = 1;
3572 int has_valid_label = 0;
3573 afi_t nh_afi;
3574 uint8_t pi_type = 0;
3575 uint8_t pi_sub_type = 0;
3576
3577 if (frrtrace_enabled(frr_bgp, process_update)) {
3578 char pfxprint[PREFIX2STR_BUFFER];
3579
3580 prefix2str(p, pfxprint, sizeof(pfxprint));
3581 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
3582 afi, safi, attr);
3583 }
3584
3585 #ifdef ENABLE_BGP_VNC
3586 int vnc_implicit_withdraw = 0;
3587 #endif
3588 int same_attr = 0;
3589
3590 memset(&new_attr, 0, sizeof(struct attr));
3591 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
3592 new_attr.label = MPLS_INVALID_LABEL;
3593
3594 bgp = peer->bgp;
3595 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3596 /* TODO: Check to see if we can get rid of "is_valid_label" */
3597 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3598 has_valid_label = (num_labels > 0) ? 1 : 0;
3599 else
3600 has_valid_label = bgp_is_valid_label(label);
3601
3602 if (has_valid_label)
3603 assert(label != NULL);
3604
3605 /* When peer's soft reconfiguration enabled. Record input packet in
3606 Adj-RIBs-In. */
3607 if (!soft_reconfig
3608 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3609 && peer != bgp->peer_self)
3610 bgp_adj_in_set(dest, peer, attr, addpath_id);
3611
3612 /* Check previously received route. */
3613 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
3614 if (pi->peer == peer && pi->type == type
3615 && pi->sub_type == sub_type
3616 && pi->addpath_rx_id == addpath_id)
3617 break;
3618
3619 /* AS path local-as loop check. */
3620 if (peer->change_local_as) {
3621 if (peer->allowas_in[afi][safi])
3622 aspath_loop_count = peer->allowas_in[afi][safi];
3623 else if (!CHECK_FLAG(peer->flags,
3624 PEER_FLAG_LOCAL_AS_NO_PREPEND))
3625 aspath_loop_count = 1;
3626
3627 if (aspath_loop_check(attr->aspath, peer->change_local_as)
3628 > aspath_loop_count) {
3629 peer->stat_pfx_aspath_loop++;
3630 reason = "as-path contains our own AS A;";
3631 goto filtered;
3632 }
3633 }
3634
3635 /* If the peer is configured for "allowas-in origin" and the last ASN in
3636 * the
3637 * as-path is our ASN then we do not need to call aspath_loop_check
3638 */
3639 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
3640 if (aspath_get_last_as(attr->aspath) == bgp->as)
3641 do_loop_check = 0;
3642
3643 /* AS path loop check. */
3644 if (do_loop_check) {
3645 if (aspath_loop_check(attr->aspath, bgp->as)
3646 > peer->allowas_in[afi][safi]
3647 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
3648 && aspath_loop_check(attr->aspath, bgp->confed_id)
3649 > peer->allowas_in[afi][safi])) {
3650 peer->stat_pfx_aspath_loop++;
3651 reason = "as-path contains our own AS;";
3652 goto filtered;
3653 }
3654 }
3655
3656 /* Route reflector originator ID check. */
3657 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
3658 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
3659 peer->stat_pfx_originator_loop++;
3660 reason = "originator is us;";
3661 goto filtered;
3662 }
3663
3664 /* Route reflector cluster ID check. */
3665 if (bgp_cluster_filter(peer, attr)) {
3666 peer->stat_pfx_cluster_loop++;
3667 reason = "reflected from the same cluster;";
3668 goto filtered;
3669 }
3670
3671 /* Apply incoming filter. */
3672 if (bgp_input_filter(peer, p, attr, afi, safi) == FILTER_DENY) {
3673 peer->stat_pfx_filter++;
3674 reason = "filter;";
3675 goto filtered;
3676 }
3677
3678 /* RFC 8212 to prevent route leaks.
3679 * This specification intends to improve this situation by requiring the
3680 * explicit configuration of both BGP Import and Export Policies for any
3681 * External BGP (EBGP) session such as customers, peers, or
3682 * confederation boundaries for all enabled address families. Through
3683 * codification of the aforementioned requirement, operators will
3684 * benefit from consistent behavior across different BGP
3685 * implementations.
3686 */
3687 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
3688 if (!bgp_inbound_policy_exists(peer,
3689 &peer->filter[afi][safi])) {
3690 reason = "inbound policy missing";
3691 goto filtered;
3692 }
3693
3694 /* draft-ietf-idr-deprecate-as-set-confed-set
3695 * Filter routes having AS_SET or AS_CONFED_SET in the path.
3696 * Eventually, This document (if approved) updates RFC 4271
3697 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
3698 * and obsoletes RFC 6472.
3699 */
3700 if (peer->bgp->reject_as_sets)
3701 if (aspath_check_as_sets(attr->aspath)) {
3702 reason =
3703 "as-path contains AS_SET or AS_CONFED_SET type;";
3704 goto filtered;
3705 }
3706
3707 new_attr = *attr;
3708
3709 /* Apply incoming route-map.
3710 * NB: new_attr may now contain newly allocated values from route-map
3711 * "set"
3712 * commands, so we need bgp_attr_flush in the error paths, until we
3713 * intern
3714 * the attr (which takes over the memory references) */
3715 if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL, label,
3716 num_labels, dest)
3717 == RMAP_DENY) {
3718 peer->stat_pfx_filter++;
3719 reason = "route-map;";
3720 bgp_attr_flush(&new_attr);
3721 goto filtered;
3722 }
3723
3724 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
3725 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3726 /* remove from RIB previous entry */
3727 bgp_zebra_withdraw(p, pi, bgp, safi);
3728 }
3729
3730 if (peer->sort == BGP_PEER_EBGP) {
3731
3732 /* rfc7999:
3733 * A BGP speaker receiving an announcement tagged with the
3734 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
3735 * NO_EXPORT community as defined in RFC1997, or a
3736 * similar community, to prevent propagation of the
3737 * prefix outside the local AS. The community to prevent
3738 * propagation SHOULD be chosen according to the operator's
3739 * routing policy.
3740 */
3741 if (new_attr.community
3742 && community_include(new_attr.community,
3743 COMMUNITY_BLACKHOLE))
3744 bgp_attr_add_no_export_community(&new_attr);
3745
3746 /* If we receive the graceful-shutdown community from an eBGP
3747 * peer we must lower local-preference */
3748 if (new_attr.community
3749 && community_include(new_attr.community, COMMUNITY_GSHUT)) {
3750 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
3751 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
3752
3753 /* If graceful-shutdown is configured then add the GSHUT
3754 * community to all paths received from eBGP peers */
3755 } else if (bgp_in_graceful_shutdown(peer->bgp))
3756 bgp_attr_add_gshut_community(&new_attr);
3757 }
3758
3759 if (pi) {
3760 pi_type = pi->type;
3761 pi_sub_type = pi->sub_type;
3762 }
3763
3764 /* next hop check. */
3765 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
3766 && bgp_update_martian_nexthop(bgp, afi, safi, pi_type, pi_sub_type,
3767 &new_attr, dest)) {
3768 peer->stat_pfx_nh_invalid++;
3769 reason = "martian or self next-hop;";
3770 bgp_attr_flush(&new_attr);
3771 goto filtered;
3772 }
3773
3774 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
3775 peer->stat_pfx_nh_invalid++;
3776 reason = "self mac;";
3777 goto filtered;
3778 }
3779
3780 /* Update Overlay Index */
3781 if (afi == AFI_L2VPN) {
3782 overlay_index_update(&new_attr,
3783 evpn == NULL ? NULL : &evpn->gw_ip);
3784 }
3785
3786 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
3787 * condition :
3788 * Suppress fib is enabled
3789 * BGP_OPT_NO_FIB is not enabled
3790 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
3791 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
3792 */
3793 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
3794 && (sub_type == BGP_ROUTE_NORMAL)
3795 && (!bgp_option_check(BGP_OPT_NO_FIB))
3796 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
3797 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
3798
3799 attr_new = bgp_attr_intern(&new_attr);
3800
3801 /* If maximum prefix count is configured and current prefix
3802 * count exeed it.
3803 */
3804 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0))
3805 return -1;
3806
3807 /* If the update is implicit withdraw. */
3808 if (pi) {
3809 pi->uptime = bgp_clock();
3810 same_attr = attrhash_cmp(pi->attr, attr_new);
3811
3812 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
3813
3814 /* Same attribute comes in. */
3815 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
3816 && same_attr
3817 && (!has_valid_label
3818 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
3819 num_labels * sizeof(mpls_label_t))
3820 == 0)
3821 && (overlay_index_equal(
3822 afi, pi,
3823 evpn == NULL ? NULL : &evpn->gw_ip))) {
3824 if (get_active_bdc_from_pi(pi, afi, safi)
3825 && peer->sort == BGP_PEER_EBGP
3826 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3827 if (bgp_debug_update(peer, p, NULL, 1)) {
3828 bgp_debug_rdpfxpath2str(
3829 afi, safi, prd, p, label,
3830 num_labels, addpath_id ? 1 : 0,
3831 addpath_id, pfx_buf,
3832 sizeof(pfx_buf));
3833 zlog_debug("%s rcvd %s", peer->host,
3834 pfx_buf);
3835 }
3836
3837 if (bgp_damp_update(pi, dest, afi, safi)
3838 != BGP_DAMP_SUPPRESSED) {
3839 bgp_aggregate_increment(bgp, p, pi, afi,
3840 safi);
3841 bgp_process(bgp, dest, afi, safi);
3842 }
3843 } else /* Duplicate - odd */
3844 {
3845 if (bgp_debug_update(peer, p, NULL, 1)) {
3846 if (!peer->rcvd_attr_printed) {
3847 zlog_debug(
3848 "%s rcvd UPDATE w/ attr: %s",
3849 peer->host,
3850 peer->rcvd_attr_str);
3851 peer->rcvd_attr_printed = 1;
3852 }
3853
3854 bgp_debug_rdpfxpath2str(
3855 afi, safi, prd, p, label,
3856 num_labels, addpath_id ? 1 : 0,
3857 addpath_id, pfx_buf,
3858 sizeof(pfx_buf));
3859 zlog_debug(
3860 "%s rcvd %s...duplicate ignored",
3861 peer->host, pfx_buf);
3862 }
3863
3864 /* graceful restart STALE flag unset. */
3865 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3866 bgp_path_info_unset_flag(
3867 dest, pi, BGP_PATH_STALE);
3868 bgp_dest_set_defer_flag(dest, false);
3869 bgp_process(bgp, dest, afi, safi);
3870 }
3871 }
3872
3873 bgp_dest_unlock_node(dest);
3874 bgp_attr_unintern(&attr_new);
3875
3876 return 0;
3877 }
3878
3879 /* Withdraw/Announce before we fully processed the withdraw */
3880 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
3881 if (bgp_debug_update(peer, p, NULL, 1)) {
3882 bgp_debug_rdpfxpath2str(
3883 afi, safi, prd, p, label, num_labels,
3884 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3885 sizeof(pfx_buf));
3886 zlog_debug(
3887 "%s rcvd %s, flapped quicker than processing",
3888 peer->host, pfx_buf);
3889 }
3890
3891 bgp_path_info_restore(dest, pi);
3892 }
3893
3894 /* Received Logging. */
3895 if (bgp_debug_update(peer, p, NULL, 1)) {
3896 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
3897 num_labels, addpath_id ? 1 : 0,
3898 addpath_id, pfx_buf,
3899 sizeof(pfx_buf));
3900 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3901 }
3902
3903 /* graceful restart STALE flag unset. */
3904 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3905 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
3906 bgp_dest_set_defer_flag(dest, false);
3907 }
3908
3909 /* The attribute is changed. */
3910 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
3911
3912 /* implicit withdraw, decrement aggregate and pcount here.
3913 * only if update is accepted, they'll increment below.
3914 */
3915 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
3916
3917 /* Update bgp route dampening information. */
3918 if (get_active_bdc_from_pi(pi, afi, safi)
3919 && peer->sort == BGP_PEER_EBGP) {
3920 /* This is implicit withdraw so we should update
3921 * dampening information.
3922 */
3923 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
3924 bgp_damp_withdraw(pi, dest, afi, safi, 1);
3925 }
3926 #ifdef ENABLE_BGP_VNC
3927 if (safi == SAFI_MPLS_VPN) {
3928 struct bgp_dest *pdest = NULL;
3929 struct bgp_table *table = NULL;
3930
3931 pdest = bgp_node_get(bgp->rib[afi][safi],
3932 (struct prefix *)prd);
3933 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3934 table = bgp_dest_get_bgp_table_info(pdest);
3935
3936 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3937 bgp, prd, table, p, pi);
3938 }
3939 bgp_dest_unlock_node(pdest);
3940 }
3941 if ((afi == AFI_IP || afi == AFI_IP6)
3942 && (safi == SAFI_UNICAST)) {
3943 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3944 /*
3945 * Implicit withdraw case.
3946 */
3947 ++vnc_implicit_withdraw;
3948 vnc_import_bgp_del_route(bgp, p, pi);
3949 vnc_import_bgp_exterior_del_route(bgp, p, pi);
3950 }
3951 }
3952 #endif
3953
3954 /* Special handling for EVPN update of an existing route. If the
3955 * extended community attribute has changed, we need to
3956 * un-import
3957 * the route using its existing extended community. It will be
3958 * subsequently processed for import with the new extended
3959 * community.
3960 */
3961 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
3962 && !same_attr) {
3963 if ((pi->attr->flag
3964 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
3965 && (attr_new->flag
3966 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
3967 int cmp;
3968
3969 cmp = ecommunity_cmp(pi->attr->ecommunity,
3970 attr_new->ecommunity);
3971 if (!cmp) {
3972 if (bgp_debug_update(peer, p, NULL, 1))
3973 zlog_debug(
3974 "Change in EXT-COMM, existing %s new %s",
3975 ecommunity_str(
3976 pi->attr->ecommunity),
3977 ecommunity_str(
3978 attr_new->ecommunity));
3979 if (safi == SAFI_EVPN)
3980 bgp_evpn_unimport_route(
3981 bgp, afi, safi, p, pi);
3982 else /* SAFI_MPLS_VPN */
3983 vpn_leak_to_vrf_withdraw(bgp,
3984 pi);
3985 }
3986 }
3987 }
3988
3989 /* Update to new attribute. */
3990 bgp_attr_unintern(&pi->attr);
3991 pi->attr = attr_new;
3992
3993 /* Update MPLS label */
3994 if (has_valid_label) {
3995 extra = bgp_path_info_extra_get(pi);
3996 if (extra->label != label) {
3997 memcpy(&extra->label, label,
3998 num_labels * sizeof(mpls_label_t));
3999 extra->num_labels = num_labels;
4000 }
4001 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4002 bgp_set_valid_label(&extra->label[0]);
4003 }
4004
4005 /* Update SRv6 SID */
4006 if (attr->srv6_l3vpn) {
4007 extra = bgp_path_info_extra_get(pi);
4008 if (sid_diff(&extra->sid[0], &attr->srv6_l3vpn->sid)) {
4009 sid_copy(&extra->sid[0],
4010 &attr->srv6_l3vpn->sid);
4011 extra->num_sids = 1;
4012 }
4013 } else if (attr->srv6_vpn) {
4014 extra = bgp_path_info_extra_get(pi);
4015 if (sid_diff(&extra->sid[0], &attr->srv6_vpn->sid)) {
4016 sid_copy(&extra->sid[0], &attr->srv6_vpn->sid);
4017 extra->num_sids = 1;
4018 }
4019 }
4020
4021 #ifdef ENABLE_BGP_VNC
4022 if ((afi == AFI_IP || afi == AFI_IP6)
4023 && (safi == SAFI_UNICAST)) {
4024 if (vnc_implicit_withdraw) {
4025 /*
4026 * Add back the route with its new attributes
4027 * (e.g., nexthop).
4028 * The route is still selected, until the route
4029 * selection
4030 * queued by bgp_process actually runs. We have
4031 * to make this
4032 * update to the VNC side immediately to avoid
4033 * racing against
4034 * configuration changes (e.g., route-map
4035 * changes) which
4036 * trigger re-importation of the entire RIB.
4037 */
4038 vnc_import_bgp_add_route(bgp, p, pi);
4039 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4040 }
4041 }
4042 #endif
4043
4044 /* Update bgp route dampening information. */
4045 if (get_active_bdc_from_pi(pi, afi, safi)
4046 && peer->sort == BGP_PEER_EBGP) {
4047 /* Now we do normal update dampening. */
4048 ret = bgp_damp_update(pi, dest, afi, safi);
4049 if (ret == BGP_DAMP_SUPPRESSED) {
4050 bgp_dest_unlock_node(dest);
4051 return 0;
4052 }
4053 }
4054
4055 /* Nexthop reachability check - for unicast and
4056 * labeled-unicast.. */
4057 if (((afi == AFI_IP || afi == AFI_IP6)
4058 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4059 || (safi == SAFI_EVPN &&
4060 bgp_evpn_is_prefix_nht_supported(p))) {
4061 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4062 && peer->ttl == BGP_DEFAULT_TTL
4063 && !CHECK_FLAG(peer->flags,
4064 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4065 && !CHECK_FLAG(bgp->flags,
4066 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4067 connected = 1;
4068 else
4069 connected = 0;
4070
4071 struct bgp *bgp_nexthop = bgp;
4072
4073 if (pi->extra && pi->extra->bgp_orig)
4074 bgp_nexthop = pi->extra->bgp_orig;
4075
4076 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4077
4078 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4079 safi, pi, NULL, connected)
4080 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4081 bgp_path_info_set_flag(dest, pi,
4082 BGP_PATH_VALID);
4083 else {
4084 if (BGP_DEBUG(nht, NHT)) {
4085 zlog_debug("%s(%pI4): NH unresolved",
4086 __func__,
4087 (in_addr_t *)&attr_new->nexthop);
4088 }
4089 bgp_path_info_unset_flag(dest, pi,
4090 BGP_PATH_VALID);
4091 }
4092 } else
4093 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4094
4095 #ifdef ENABLE_BGP_VNC
4096 if (safi == SAFI_MPLS_VPN) {
4097 struct bgp_dest *pdest = NULL;
4098 struct bgp_table *table = NULL;
4099
4100 pdest = bgp_node_get(bgp->rib[afi][safi],
4101 (struct prefix *)prd);
4102 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4103 table = bgp_dest_get_bgp_table_info(pdest);
4104
4105 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4106 bgp, prd, table, p, pi);
4107 }
4108 bgp_dest_unlock_node(pdest);
4109 }
4110 #endif
4111
4112 /* If this is an EVPN route and some attribute has changed,
4113 * process
4114 * route for import. If the extended community has changed, we
4115 * would
4116 * have done the un-import earlier and the import would result
4117 * in the
4118 * route getting injected into appropriate L2 VNIs. If it is
4119 * just
4120 * some other attribute change, the import will result in
4121 * updating
4122 * the attributes for the route in the VNI(s).
4123 */
4124 if (safi == SAFI_EVPN && !same_attr &&
4125 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4126 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4127
4128 /* Process change. */
4129 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4130
4131 bgp_process(bgp, dest, afi, safi);
4132 bgp_dest_unlock_node(dest);
4133
4134 if (SAFI_UNICAST == safi
4135 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4136 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4137
4138 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4139 }
4140 if ((SAFI_MPLS_VPN == safi)
4141 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4142
4143 vpn_leak_to_vrf_update(bgp, pi);
4144 }
4145
4146 #ifdef ENABLE_BGP_VNC
4147 if (SAFI_MPLS_VPN == safi) {
4148 mpls_label_t label_decoded = decode_label(label);
4149
4150 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4151 type, sub_type, &label_decoded);
4152 }
4153 if (SAFI_ENCAP == safi) {
4154 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4155 type, sub_type, NULL);
4156 }
4157 #endif
4158
4159 return 0;
4160 } // End of implicit withdraw
4161
4162 /* Received Logging. */
4163 if (bgp_debug_update(peer, p, NULL, 1)) {
4164 if (!peer->rcvd_attr_printed) {
4165 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
4166 peer->rcvd_attr_str);
4167 peer->rcvd_attr_printed = 1;
4168 }
4169
4170 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4171 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4172 sizeof(pfx_buf));
4173 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
4174 }
4175
4176 /* Make new BGP info. */
4177 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4178
4179 /* Update MPLS label */
4180 if (has_valid_label) {
4181 extra = bgp_path_info_extra_get(new);
4182 if (extra->label != label) {
4183 memcpy(&extra->label, label,
4184 num_labels * sizeof(mpls_label_t));
4185 extra->num_labels = num_labels;
4186 }
4187 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4188 bgp_set_valid_label(&extra->label[0]);
4189 }
4190
4191 /* Update SRv6 SID */
4192 if (safi == SAFI_MPLS_VPN) {
4193 extra = bgp_path_info_extra_get(new);
4194 if (attr->srv6_l3vpn) {
4195 sid_copy(&extra->sid[0], &attr->srv6_l3vpn->sid);
4196 extra->num_sids = 1;
4197 } else if (attr->srv6_vpn) {
4198 sid_copy(&extra->sid[0], &attr->srv6_vpn->sid);
4199 extra->num_sids = 1;
4200 }
4201 }
4202
4203 /* Update Overlay Index */
4204 if (afi == AFI_L2VPN) {
4205 overlay_index_update(new->attr,
4206 evpn == NULL ? NULL : &evpn->gw_ip);
4207 }
4208 /* Nexthop reachability check. */
4209 if (((afi == AFI_IP || afi == AFI_IP6)
4210 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4211 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4212 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4213 && peer->ttl == BGP_DEFAULT_TTL
4214 && !CHECK_FLAG(peer->flags,
4215 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4216 && !CHECK_FLAG(bgp->flags,
4217 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4218 connected = 1;
4219 else
4220 connected = 0;
4221
4222 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4223
4224 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4225 connected)
4226 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4227 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4228 else {
4229 if (BGP_DEBUG(nht, NHT)) {
4230 char buf1[INET6_ADDRSTRLEN];
4231 inet_ntop(AF_INET,
4232 (const void *)&attr_new->nexthop,
4233 buf1, INET6_ADDRSTRLEN);
4234 zlog_debug("%s(%s): NH unresolved", __func__,
4235 buf1);
4236 }
4237 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4238 }
4239 } else
4240 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4241
4242 /* Addpath ID */
4243 new->addpath_rx_id = addpath_id;
4244
4245 /* Increment prefix */
4246 bgp_aggregate_increment(bgp, p, new, afi, safi);
4247
4248 /* Register new BGP information. */
4249 bgp_path_info_add(dest, new);
4250
4251 /* route_node_get lock */
4252 bgp_dest_unlock_node(dest);
4253
4254 #ifdef ENABLE_BGP_VNC
4255 if (safi == SAFI_MPLS_VPN) {
4256 struct bgp_dest *pdest = NULL;
4257 struct bgp_table *table = NULL;
4258
4259 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4260 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4261 table = bgp_dest_get_bgp_table_info(pdest);
4262
4263 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4264 bgp, prd, table, p, new);
4265 }
4266 bgp_dest_unlock_node(pdest);
4267 }
4268 #endif
4269
4270 /* If this is an EVPN route, process for import. */
4271 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4272 bgp_evpn_import_route(bgp, afi, safi, p, new);
4273
4274 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4275
4276 /* Process change. */
4277 bgp_process(bgp, dest, afi, safi);
4278
4279 if (SAFI_UNICAST == safi
4280 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4281 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4282 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4283 }
4284 if ((SAFI_MPLS_VPN == safi)
4285 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4286
4287 vpn_leak_to_vrf_update(bgp, new);
4288 }
4289 #ifdef ENABLE_BGP_VNC
4290 if (SAFI_MPLS_VPN == safi) {
4291 mpls_label_t label_decoded = decode_label(label);
4292
4293 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4294 sub_type, &label_decoded);
4295 }
4296 if (SAFI_ENCAP == safi) {
4297 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4298 sub_type, NULL);
4299 }
4300 #endif
4301
4302 return 0;
4303
4304 /* This BGP update is filtered. Log the reason then update BGP
4305 entry. */
4306 filtered:
4307 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4308
4309 if (bgp_debug_update(peer, p, NULL, 1)) {
4310 if (!peer->rcvd_attr_printed) {
4311 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
4312 peer->rcvd_attr_str);
4313 peer->rcvd_attr_printed = 1;
4314 }
4315
4316 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4317 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4318 sizeof(pfx_buf));
4319 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
4320 peer->host, pfx_buf, reason);
4321 }
4322
4323 if (pi) {
4324 /* If this is an EVPN route, un-import it as it is now filtered.
4325 */
4326 if (safi == SAFI_EVPN)
4327 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4328
4329 if (SAFI_UNICAST == safi
4330 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4331 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4332
4333 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4334 }
4335 if ((SAFI_MPLS_VPN == safi)
4336 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4337
4338 vpn_leak_to_vrf_withdraw(bgp, pi);
4339 }
4340
4341 bgp_rib_remove(dest, pi, peer, afi, safi);
4342 }
4343
4344 bgp_dest_unlock_node(dest);
4345
4346 #ifdef ENABLE_BGP_VNC
4347 /*
4348 * Filtered update is treated as an implicit withdrawal (see
4349 * bgp_rib_remove()
4350 * a few lines above)
4351 */
4352 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4353 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4354 0);
4355 }
4356 #endif
4357
4358 return 0;
4359 }
4360
4361 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4362 struct attr *attr, afi_t afi, safi_t safi, int type,
4363 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4364 uint32_t num_labels, struct bgp_route_evpn *evpn)
4365 {
4366 struct bgp *bgp;
4367 char pfx_buf[BGP_PRD_PATH_STRLEN];
4368 struct bgp_dest *dest;
4369 struct bgp_path_info *pi;
4370
4371 #ifdef ENABLE_BGP_VNC
4372 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4373 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4374 0);
4375 }
4376 #endif
4377
4378 bgp = peer->bgp;
4379
4380 /* Lookup node. */
4381 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4382
4383 /* If peer is soft reconfiguration enabled. Record input packet for
4384 * further calculation.
4385 *
4386 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4387 * routes that are filtered. This tanks out Quagga RS pretty badly due
4388 * to
4389 * the iteration over all RS clients.
4390 * Since we need to remove the entry from adj_in anyway, do that first
4391 * and
4392 * if there was no entry, we don't need to do anything more.
4393 */
4394 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4395 && peer != bgp->peer_self)
4396 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4397 peer->stat_pfx_dup_withdraw++;
4398
4399 if (bgp_debug_update(peer, p, NULL, 1)) {
4400 bgp_debug_rdpfxpath2str(
4401 afi, safi, prd, p, label, num_labels,
4402 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4403 sizeof(pfx_buf));
4404 zlog_debug(
4405 "%s withdrawing route %s not in adj-in",
4406 peer->host, pfx_buf);
4407 }
4408 bgp_dest_unlock_node(dest);
4409 return 0;
4410 }
4411
4412 /* Lookup withdrawn route. */
4413 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4414 if (pi->peer == peer && pi->type == type
4415 && pi->sub_type == sub_type
4416 && pi->addpath_rx_id == addpath_id)
4417 break;
4418
4419 /* Logging. */
4420 if (bgp_debug_update(peer, p, NULL, 1)) {
4421 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4422 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4423 sizeof(pfx_buf));
4424 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
4425 pfx_buf);
4426 }
4427
4428 /* Withdraw specified route from routing table. */
4429 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4430 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4431 if (SAFI_UNICAST == safi
4432 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4433 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4434 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4435 }
4436 if ((SAFI_MPLS_VPN == safi)
4437 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4438
4439 vpn_leak_to_vrf_withdraw(bgp, pi);
4440 }
4441 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4442 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4443 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4444 sizeof(pfx_buf));
4445 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4446 }
4447
4448 /* Unlock bgp_node_get() lock. */
4449 bgp_dest_unlock_node(dest);
4450
4451 return 0;
4452 }
4453
4454 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4455 int withdraw)
4456 {
4457 struct update_subgroup *subgrp;
4458 subgrp = peer_subgroup(peer, afi, safi);
4459 subgroup_default_originate(subgrp, withdraw);
4460 }
4461
4462
4463 /*
4464 * bgp_stop_announce_route_timer
4465 */
4466 void bgp_stop_announce_route_timer(struct peer_af *paf)
4467 {
4468 if (!paf->t_announce_route)
4469 return;
4470
4471 thread_cancel(&paf->t_announce_route);
4472 }
4473
4474 /*
4475 * bgp_announce_route_timer_expired
4476 *
4477 * Callback that is invoked when the route announcement timer for a
4478 * peer_af expires.
4479 */
4480 static int bgp_announce_route_timer_expired(struct thread *t)
4481 {
4482 struct peer_af *paf;
4483 struct peer *peer;
4484
4485 paf = THREAD_ARG(t);
4486 peer = paf->peer;
4487
4488 if (peer->status != Established)
4489 return 0;
4490
4491 if (!peer->afc_nego[paf->afi][paf->safi])
4492 return 0;
4493
4494 peer_af_announce_route(paf, 1);
4495
4496 /* Notify BGP conditional advertisement scanner percess */
4497 peer->advmap_config_change[paf->afi][paf->safi] = true;
4498
4499 return 0;
4500 }
4501
4502 /*
4503 * bgp_announce_route
4504 *
4505 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
4506 */
4507 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi)
4508 {
4509 struct peer_af *paf;
4510 struct update_subgroup *subgrp;
4511
4512 paf = peer_af_find(peer, afi, safi);
4513 if (!paf)
4514 return;
4515 subgrp = PAF_SUBGRP(paf);
4516
4517 /*
4518 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
4519 * or a refresh has already been triggered.
4520 */
4521 if (!subgrp || paf->t_announce_route)
4522 return;
4523
4524 /*
4525 * Start a timer to stagger/delay the announce. This serves
4526 * two purposes - announcement can potentially be combined for
4527 * multiple peers and the announcement doesn't happen in the
4528 * vty context.
4529 */
4530 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
4531 (subgrp->peer_count == 1)
4532 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
4533 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
4534 &paf->t_announce_route);
4535 }
4536
4537 /*
4538 * Announce routes from all AF tables to a peer.
4539 *
4540 * This should ONLY be called when there is a need to refresh the
4541 * routes to the peer based on a policy change for this peer alone
4542 * or a route refresh request received from the peer.
4543 * The operation will result in splitting the peer from its existing
4544 * subgroups and putting it in new subgroups.
4545 */
4546 void bgp_announce_route_all(struct peer *peer)
4547 {
4548 afi_t afi;
4549 safi_t safi;
4550
4551 FOREACH_AFI_SAFI (afi, safi)
4552 bgp_announce_route(peer, afi, safi);
4553 }
4554
4555 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
4556 struct bgp_table *table,
4557 struct prefix_rd *prd)
4558 {
4559 int ret;
4560 struct bgp_dest *dest;
4561 struct bgp_adj_in *ain;
4562
4563 if (!table)
4564 table = peer->bgp->rib[afi][safi];
4565
4566 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
4567 for (ain = dest->adj_in; ain; ain = ain->next) {
4568 if (ain->peer != peer)
4569 continue;
4570
4571 struct bgp_path_info *pi;
4572 uint32_t num_labels = 0;
4573 mpls_label_t *label_pnt = NULL;
4574 struct bgp_route_evpn evpn;
4575
4576 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
4577 pi = pi->next)
4578 if (pi->peer == peer)
4579 break;
4580
4581 if (pi && pi->extra)
4582 num_labels = pi->extra->num_labels;
4583 if (num_labels)
4584 label_pnt = &pi->extra->label[0];
4585 if (pi)
4586 memcpy(&evpn,
4587 bgp_attr_get_evpn_overlay(pi->attr),
4588 sizeof(evpn));
4589 else
4590 memset(&evpn, 0, sizeof(evpn));
4591
4592 ret = bgp_update(peer, bgp_dest_get_prefix(dest),
4593 ain->addpath_rx_id, ain->attr, afi,
4594 safi, ZEBRA_ROUTE_BGP,
4595 BGP_ROUTE_NORMAL, prd, label_pnt,
4596 num_labels, 1, &evpn);
4597
4598 if (ret < 0) {
4599 bgp_dest_unlock_node(dest);
4600 return;
4601 }
4602 }
4603 }
4604
4605 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
4606 {
4607 struct bgp_dest *dest;
4608 struct bgp_table *table;
4609
4610 if (peer->status != Established)
4611 return;
4612
4613 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
4614 && (safi != SAFI_EVPN))
4615 bgp_soft_reconfig_table(peer, afi, safi, NULL, NULL);
4616 else
4617 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4618 dest = bgp_route_next(dest)) {
4619 table = bgp_dest_get_bgp_table_info(dest);
4620
4621 if (table == NULL)
4622 continue;
4623
4624 const struct prefix *p = bgp_dest_get_prefix(dest);
4625 struct prefix_rd prd;
4626
4627 prd.family = AF_UNSPEC;
4628 prd.prefixlen = 64;
4629 memcpy(&prd.val, p->u.val, 8);
4630
4631 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
4632 }
4633 }
4634
4635
4636 struct bgp_clear_node_queue {
4637 struct bgp_dest *dest;
4638 };
4639
4640 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
4641 {
4642 struct bgp_clear_node_queue *cnq = data;
4643 struct bgp_dest *dest = cnq->dest;
4644 struct peer *peer = wq->spec.data;
4645 struct bgp_path_info *pi;
4646 struct bgp *bgp;
4647 afi_t afi = bgp_dest_table(dest)->afi;
4648 safi_t safi = bgp_dest_table(dest)->safi;
4649
4650 assert(dest && peer);
4651 bgp = peer->bgp;
4652
4653 /* It is possible that we have multiple paths for a prefix from a peer
4654 * if that peer is using AddPath.
4655 */
4656 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
4657 if (pi->peer != peer)
4658 continue;
4659
4660 /* graceful restart STALE flag set. */
4661 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
4662 && peer->nsf[afi][safi])
4663 || CHECK_FLAG(peer->af_sflags[afi][safi],
4664 PEER_STATUS_ENHANCED_REFRESH))
4665 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
4666 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
4667 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
4668 else {
4669 /* If this is an EVPN route, process for
4670 * un-import. */
4671 if (safi == SAFI_EVPN)
4672 bgp_evpn_unimport_route(
4673 bgp, afi, safi,
4674 bgp_dest_get_prefix(dest), pi);
4675 /* Handle withdraw for VRF route-leaking and L3VPN */
4676 if (SAFI_UNICAST == safi
4677 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
4678 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4679 vpn_leak_from_vrf_withdraw(bgp_get_default(),
4680 bgp, pi);
4681 }
4682 if (SAFI_MPLS_VPN == safi &&
4683 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4684 vpn_leak_to_vrf_withdraw(bgp, pi);
4685 }
4686
4687 bgp_rib_remove(dest, pi, peer, afi, safi);
4688 }
4689 }
4690 return WQ_SUCCESS;
4691 }
4692
4693 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
4694 {
4695 struct bgp_clear_node_queue *cnq = data;
4696 struct bgp_dest *dest = cnq->dest;
4697 struct bgp_table *table = bgp_dest_table(dest);
4698
4699 bgp_dest_unlock_node(dest);
4700 bgp_table_unlock(table);
4701 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
4702 }
4703
4704 static void bgp_clear_node_complete(struct work_queue *wq)
4705 {
4706 struct peer *peer = wq->spec.data;
4707
4708 /* Tickle FSM to start moving again */
4709 BGP_EVENT_ADD(peer, Clearing_Completed);
4710
4711 peer_unlock(peer); /* bgp_clear_route */
4712 }
4713
4714 static void bgp_clear_node_queue_init(struct peer *peer)
4715 {
4716 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
4717
4718 snprintf(wname, sizeof(wname), "clear %s", peer->host);
4719 #undef CLEAR_QUEUE_NAME_LEN
4720
4721 peer->clear_node_queue = work_queue_new(bm->master, wname);
4722 peer->clear_node_queue->spec.hold = 10;
4723 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
4724 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
4725 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
4726 peer->clear_node_queue->spec.max_retries = 0;
4727
4728 /* we only 'lock' this peer reference when the queue is actually active
4729 */
4730 peer->clear_node_queue->spec.data = peer;
4731 }
4732
4733 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
4734 struct bgp_table *table)
4735 {
4736 struct bgp_dest *dest;
4737 int force = peer->bgp->process_queue ? 0 : 1;
4738
4739 if (!table)
4740 table = peer->bgp->rib[afi][safi];
4741
4742 /* If still no table => afi/safi isn't configured at all or smth. */
4743 if (!table)
4744 return;
4745
4746 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4747 struct bgp_path_info *pi, *next;
4748 struct bgp_adj_in *ain;
4749 struct bgp_adj_in *ain_next;
4750
4751 /* XXX:TODO: This is suboptimal, every non-empty route_node is
4752 * queued for every clearing peer, regardless of whether it is
4753 * relevant to the peer at hand.
4754 *
4755 * Overview: There are 3 different indices which need to be
4756 * scrubbed, potentially, when a peer is removed:
4757 *
4758 * 1 peer's routes visible via the RIB (ie accepted routes)
4759 * 2 peer's routes visible by the (optional) peer's adj-in index
4760 * 3 other routes visible by the peer's adj-out index
4761 *
4762 * 3 there is no hurry in scrubbing, once the struct peer is
4763 * removed from bgp->peer, we could just GC such deleted peer's
4764 * adj-outs at our leisure.
4765 *
4766 * 1 and 2 must be 'scrubbed' in some way, at least made
4767 * invisible via RIB index before peer session is allowed to be
4768 * brought back up. So one needs to know when such a 'search' is
4769 * complete.
4770 *
4771 * Ideally:
4772 *
4773 * - there'd be a single global queue or a single RIB walker
4774 * - rather than tracking which route_nodes still need to be
4775 * examined on a peer basis, we'd track which peers still
4776 * aren't cleared
4777 *
4778 * Given that our per-peer prefix-counts now should be reliable,
4779 * this may actually be achievable. It doesn't seem to be a huge
4780 * problem at this time,
4781 *
4782 * It is possible that we have multiple paths for a prefix from
4783 * a peer
4784 * if that peer is using AddPath.
4785 */
4786 ain = dest->adj_in;
4787 while (ain) {
4788 ain_next = ain->next;
4789
4790 if (ain->peer == peer) {
4791 bgp_adj_in_remove(dest, ain);
4792 bgp_dest_unlock_node(dest);
4793 }
4794
4795 ain = ain_next;
4796 }
4797
4798 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
4799 next = pi->next;
4800 if (pi->peer != peer)
4801 continue;
4802
4803 if (force)
4804 bgp_path_info_reap(dest, pi);
4805 else {
4806 struct bgp_clear_node_queue *cnq;
4807
4808 /* both unlocked in bgp_clear_node_queue_del */
4809 bgp_table_lock(bgp_dest_table(dest));
4810 bgp_dest_lock_node(dest);
4811 cnq = XCALLOC(
4812 MTYPE_BGP_CLEAR_NODE_QUEUE,
4813 sizeof(struct bgp_clear_node_queue));
4814 cnq->dest = dest;
4815 work_queue_add(peer->clear_node_queue, cnq);
4816 break;
4817 }
4818 }
4819 }
4820 return;
4821 }
4822
4823 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
4824 {
4825 struct bgp_dest *dest;
4826 struct bgp_table *table;
4827
4828 if (peer->clear_node_queue == NULL)
4829 bgp_clear_node_queue_init(peer);
4830
4831 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
4832 * Idle until it receives a Clearing_Completed event. This protects
4833 * against peers which flap faster than we can we clear, which could
4834 * lead to:
4835 *
4836 * a) race with routes from the new session being installed before
4837 * clear_route_node visits the node (to delete the route of that
4838 * peer)
4839 * b) resource exhaustion, clear_route_node likely leads to an entry
4840 * on the process_main queue. Fast-flapping could cause that queue
4841 * to grow and grow.
4842 */
4843
4844 /* lock peer in assumption that clear-node-queue will get nodes; if so,
4845 * the unlock will happen upon work-queue completion; other wise, the
4846 * unlock happens at the end of this function.
4847 */
4848 if (!peer->clear_node_queue->thread)
4849 peer_lock(peer);
4850
4851 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
4852 bgp_clear_route_table(peer, afi, safi, NULL);
4853 else
4854 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4855 dest = bgp_route_next(dest)) {
4856 table = bgp_dest_get_bgp_table_info(dest);
4857 if (!table)
4858 continue;
4859
4860 bgp_clear_route_table(peer, afi, safi, table);
4861 }
4862
4863 /* unlock if no nodes got added to the clear-node-queue. */
4864 if (!peer->clear_node_queue->thread)
4865 peer_unlock(peer);
4866 }
4867
4868 void bgp_clear_route_all(struct peer *peer)
4869 {
4870 afi_t afi;
4871 safi_t safi;
4872
4873 FOREACH_AFI_SAFI (afi, safi)
4874 bgp_clear_route(peer, afi, safi);
4875
4876 #ifdef ENABLE_BGP_VNC
4877 rfapiProcessPeerDown(peer);
4878 #endif
4879 }
4880
4881 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
4882 {
4883 struct bgp_table *table;
4884 struct bgp_dest *dest;
4885 struct bgp_adj_in *ain;
4886 struct bgp_adj_in *ain_next;
4887
4888 table = peer->bgp->rib[afi][safi];
4889
4890 /* It is possible that we have multiple paths for a prefix from a peer
4891 * if that peer is using AddPath.
4892 */
4893 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4894 ain = dest->adj_in;
4895
4896 while (ain) {
4897 ain_next = ain->next;
4898
4899 if (ain->peer == peer) {
4900 bgp_adj_in_remove(dest, ain);
4901 bgp_dest_unlock_node(dest);
4902 }
4903
4904 ain = ain_next;
4905 }
4906 }
4907 }
4908
4909 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
4910 {
4911 struct bgp_dest *dest;
4912 struct bgp_path_info *pi;
4913 struct bgp_table *table;
4914
4915 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
4916 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4917 dest = bgp_route_next(dest)) {
4918 struct bgp_dest *rm;
4919
4920 /* look for neighbor in tables */
4921 table = bgp_dest_get_bgp_table_info(dest);
4922 if (!table)
4923 continue;
4924
4925 for (rm = bgp_table_top(table); rm;
4926 rm = bgp_route_next(rm))
4927 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
4928 pi = pi->next) {
4929 if (pi->peer != peer)
4930 continue;
4931 if (!CHECK_FLAG(pi->flags,
4932 BGP_PATH_STALE))
4933 break;
4934
4935 bgp_rib_remove(rm, pi, peer, afi, safi);
4936 break;
4937 }
4938 }
4939 } else {
4940 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4941 dest = bgp_route_next(dest))
4942 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
4943 pi = pi->next) {
4944 if (pi->peer != peer)
4945 continue;
4946 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
4947 break;
4948 bgp_rib_remove(dest, pi, peer, afi, safi);
4949 break;
4950 }
4951 }
4952 }
4953
4954 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
4955 {
4956 struct bgp_dest *dest, *ndest;
4957 struct bgp_path_info *pi;
4958 struct bgp_table *table;
4959
4960 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
4961 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4962 dest = bgp_route_next(dest)) {
4963 table = bgp_dest_get_bgp_table_info(dest);
4964 if (!table)
4965 continue;
4966
4967 for (ndest = bgp_table_top(table); ndest;
4968 ndest = bgp_route_next(ndest)) {
4969 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
4970 pi = pi->next) {
4971 if (pi->peer != peer)
4972 continue;
4973
4974 if ((CHECK_FLAG(
4975 peer->af_sflags[afi][safi],
4976 PEER_STATUS_ENHANCED_REFRESH))
4977 && !CHECK_FLAG(pi->flags,
4978 BGP_PATH_STALE)
4979 && !CHECK_FLAG(
4980 pi->flags,
4981 BGP_PATH_UNUSEABLE)) {
4982 if (bgp_debug_neighbor_events(
4983 peer))
4984 zlog_debug(
4985 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
4986 peer->host,
4987 afi2str(afi),
4988 safi2str(safi),
4989 bgp_dest_get_prefix(
4990 ndest));
4991
4992 bgp_path_info_set_flag(
4993 ndest, pi,
4994 BGP_PATH_STALE);
4995 }
4996 }
4997 }
4998 }
4999 } else {
5000 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5001 dest = bgp_route_next(dest)) {
5002 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5003 pi = pi->next) {
5004 if (pi->peer != peer)
5005 continue;
5006
5007 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5008 PEER_STATUS_ENHANCED_REFRESH))
5009 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5010 && !CHECK_FLAG(pi->flags,
5011 BGP_PATH_UNUSEABLE)) {
5012 if (bgp_debug_neighbor_events(peer))
5013 zlog_debug(
5014 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
5015 peer->host,
5016 afi2str(afi),
5017 safi2str(safi),
5018 bgp_dest_get_prefix(
5019 dest));
5020
5021 bgp_path_info_set_flag(dest, pi,
5022 BGP_PATH_STALE);
5023 }
5024 }
5025 }
5026 }
5027 }
5028
5029 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5030 {
5031 if (peer->sort == BGP_PEER_IBGP)
5032 return true;
5033
5034 if (peer->sort == BGP_PEER_EBGP
5035 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5036 || FILTER_LIST_OUT_NAME(filter)
5037 || DISTRIBUTE_OUT_NAME(filter)))
5038 return true;
5039 return false;
5040 }
5041
5042 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5043 {
5044 if (peer->sort == BGP_PEER_IBGP)
5045 return true;
5046
5047 if (peer->sort == BGP_PEER_EBGP
5048 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5049 || FILTER_LIST_IN_NAME(filter)
5050 || DISTRIBUTE_IN_NAME(filter)))
5051 return true;
5052 return false;
5053 }
5054
5055 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5056 safi_t safi)
5057 {
5058 struct bgp_dest *dest;
5059 struct bgp_path_info *pi;
5060 struct bgp_path_info *next;
5061
5062 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5063 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5064 const struct prefix *p = bgp_dest_get_prefix(dest);
5065
5066 next = pi->next;
5067
5068 /* Unimport EVPN routes from VRFs */
5069 if (safi == SAFI_EVPN)
5070 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5071 SAFI_EVPN, p, pi);
5072
5073 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5074 && pi->type == ZEBRA_ROUTE_BGP
5075 && (pi->sub_type == BGP_ROUTE_NORMAL
5076 || pi->sub_type == BGP_ROUTE_AGGREGATE
5077 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5078
5079 if (bgp_fibupd_safi(safi))
5080 bgp_zebra_withdraw(p, pi, bgp, safi);
5081 }
5082
5083 bgp_path_info_reap(dest, pi);
5084 }
5085 }
5086
5087 /* Delete all kernel routes. */
5088 void bgp_cleanup_routes(struct bgp *bgp)
5089 {
5090 afi_t afi;
5091 struct bgp_dest *dest;
5092 struct bgp_table *table;
5093
5094 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5095 if (afi == AFI_L2VPN)
5096 continue;
5097 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5098 SAFI_UNICAST);
5099 /*
5100 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5101 */
5102 if (afi != AFI_L2VPN) {
5103 safi_t safi;
5104 safi = SAFI_MPLS_VPN;
5105 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5106 dest = bgp_route_next(dest)) {
5107 table = bgp_dest_get_bgp_table_info(dest);
5108 if (table != NULL) {
5109 bgp_cleanup_table(bgp, table, safi);
5110 bgp_table_finish(&table);
5111 bgp_dest_set_bgp_table_info(dest, NULL);
5112 bgp_dest_unlock_node(dest);
5113 }
5114 }
5115 safi = SAFI_ENCAP;
5116 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5117 dest = bgp_route_next(dest)) {
5118 table = bgp_dest_get_bgp_table_info(dest);
5119 if (table != NULL) {
5120 bgp_cleanup_table(bgp, table, safi);
5121 bgp_table_finish(&table);
5122 bgp_dest_set_bgp_table_info(dest, NULL);
5123 bgp_dest_unlock_node(dest);
5124 }
5125 }
5126 }
5127 }
5128 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5129 dest = bgp_route_next(dest)) {
5130 table = bgp_dest_get_bgp_table_info(dest);
5131 if (table != NULL) {
5132 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5133 bgp_table_finish(&table);
5134 bgp_dest_set_bgp_table_info(dest, NULL);
5135 bgp_dest_unlock_node(dest);
5136 }
5137 }
5138 }
5139
5140 void bgp_reset(void)
5141 {
5142 vty_reset();
5143 bgp_zclient_reset();
5144 access_list_reset();
5145 prefix_list_reset();
5146 }
5147
5148 static int bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5149 {
5150 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5151 && CHECK_FLAG(peer->af_cap[afi][safi],
5152 PEER_CAP_ADDPATH_AF_TX_RCV));
5153 }
5154
5155 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5156 value. */
5157 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5158 struct bgp_nlri *packet)
5159 {
5160 uint8_t *pnt;
5161 uint8_t *lim;
5162 struct prefix p;
5163 int psize;
5164 int ret;
5165 afi_t afi;
5166 safi_t safi;
5167 int addpath_encoded;
5168 uint32_t addpath_id;
5169
5170 pnt = packet->nlri;
5171 lim = pnt + packet->length;
5172 afi = packet->afi;
5173 safi = packet->safi;
5174 addpath_id = 0;
5175 addpath_encoded = bgp_addpath_encode_rx(peer, afi, safi);
5176
5177 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5178 syntactic validity. If the field is syntactically incorrect,
5179 then the Error Subcode is set to Invalid Network Field. */
5180 for (; pnt < lim; pnt += psize) {
5181 /* Clear prefix structure. */
5182 memset(&p, 0, sizeof(struct prefix));
5183
5184 if (addpath_encoded) {
5185
5186 /* When packet overflow occurs return immediately. */
5187 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5188 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5189
5190 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5191 addpath_id = ntohl(addpath_id);
5192 pnt += BGP_ADDPATH_ID_LEN;
5193 }
5194
5195 /* Fetch prefix length. */
5196 p.prefixlen = *pnt++;
5197 /* afi/safi validity already verified by caller,
5198 * bgp_update_receive */
5199 p.family = afi2family(afi);
5200
5201 /* Prefix length check. */
5202 if (p.prefixlen > prefix_blen(&p) * 8) {
5203 flog_err(
5204 EC_BGP_UPDATE_RCV,
5205 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
5206 peer->host, p.prefixlen, packet->afi);
5207 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
5208 }
5209
5210 /* Packet size overflow check. */
5211 psize = PSIZE(p.prefixlen);
5212
5213 /* When packet overflow occur return immediately. */
5214 if (pnt + psize > lim) {
5215 flog_err(
5216 EC_BGP_UPDATE_RCV,
5217 "%s [Error] Update packet error (prefix length %d overflows packet)",
5218 peer->host, p.prefixlen);
5219 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5220 }
5221
5222 /* Defensive coding, double-check the psize fits in a struct
5223 * prefix */
5224 if (psize > (ssize_t)sizeof(p.u)) {
5225 flog_err(
5226 EC_BGP_UPDATE_RCV,
5227 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
5228 peer->host, p.prefixlen, sizeof(p.u));
5229 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5230 }
5231
5232 /* Fetch prefix from NLRI packet. */
5233 memcpy(p.u.val, pnt, psize);
5234
5235 /* Check address. */
5236 if (afi == AFI_IP && safi == SAFI_UNICAST) {
5237 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
5238 /* From RFC4271 Section 6.3:
5239 *
5240 * If a prefix in the NLRI field is semantically
5241 * incorrect
5242 * (e.g., an unexpected multicast IP address),
5243 * an error SHOULD
5244 * be logged locally, and the prefix SHOULD be
5245 * ignored.
5246 */
5247 flog_err(
5248 EC_BGP_UPDATE_RCV,
5249 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
5250 peer->host, &p.u.prefix4);
5251 continue;
5252 }
5253 }
5254
5255 /* Check address. */
5256 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
5257 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
5258 flog_err(
5259 EC_BGP_UPDATE_RCV,
5260 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
5261 peer->host, &p.u.prefix6);
5262
5263 continue;
5264 }
5265 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
5266 flog_err(
5267 EC_BGP_UPDATE_RCV,
5268 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
5269 peer->host, &p.u.prefix6);
5270
5271 continue;
5272 }
5273 }
5274
5275 /* Normal process. */
5276 if (attr)
5277 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
5278 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
5279 NULL, NULL, 0, 0, NULL);
5280 else
5281 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
5282 safi, ZEBRA_ROUTE_BGP,
5283 BGP_ROUTE_NORMAL, NULL, NULL, 0,
5284 NULL);
5285
5286 /* Do not send BGP notification twice when maximum-prefix count
5287 * overflow. */
5288 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
5289 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
5290
5291 /* Address family configuration mismatch. */
5292 if (ret < 0)
5293 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
5294 }
5295
5296 /* Packet length consistency check. */
5297 if (pnt != lim) {
5298 flog_err(
5299 EC_BGP_UPDATE_RCV,
5300 "%s [Error] Update packet error (prefix length mismatch with total length)",
5301 peer->host);
5302 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5303 }
5304
5305 return BGP_NLRI_PARSE_OK;
5306 }
5307
5308 static struct bgp_static *bgp_static_new(void)
5309 {
5310 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
5311 }
5312
5313 static void bgp_static_free(struct bgp_static *bgp_static)
5314 {
5315 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5316 route_map_counter_decrement(bgp_static->rmap.map);
5317
5318 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
5319 XFREE(MTYPE_BGP_STATIC, bgp_static);
5320 }
5321
5322 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
5323 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
5324 {
5325 struct bgp_dest *dest;
5326 struct bgp_path_info *pi;
5327 struct bgp_path_info *new;
5328 struct bgp_path_info rmap_path;
5329 struct attr attr;
5330 struct attr *attr_new;
5331 route_map_result_t ret;
5332 #ifdef ENABLE_BGP_VNC
5333 int vnc_implicit_withdraw = 0;
5334 #endif
5335
5336 assert(bgp_static);
5337
5338 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5339
5340 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5341
5342 attr.nexthop = bgp_static->igpnexthop;
5343 attr.med = bgp_static->igpmetric;
5344 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5345
5346 if (bgp_static->atomic)
5347 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
5348
5349 /* Store label index, if required. */
5350 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
5351 attr.label_index = bgp_static->label_index;
5352 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
5353 }
5354
5355 /* Apply route-map. */
5356 if (bgp_static->rmap.name) {
5357 struct attr attr_tmp = attr;
5358
5359 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
5360 rmap_path.peer = bgp->peer_self;
5361 rmap_path.attr = &attr_tmp;
5362
5363 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5364
5365 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
5366
5367 bgp->peer_self->rmap_type = 0;
5368
5369 if (ret == RMAP_DENYMATCH) {
5370 /* Free uninterned attribute. */
5371 bgp_attr_flush(&attr_tmp);
5372
5373 /* Unintern original. */
5374 aspath_unintern(&attr.aspath);
5375 bgp_static_withdraw(bgp, p, afi, safi);
5376 return;
5377 }
5378
5379 if (bgp_in_graceful_shutdown(bgp))
5380 bgp_attr_add_gshut_community(&attr_tmp);
5381
5382 attr_new = bgp_attr_intern(&attr_tmp);
5383 } else {
5384
5385 if (bgp_in_graceful_shutdown(bgp))
5386 bgp_attr_add_gshut_community(&attr);
5387
5388 attr_new = bgp_attr_intern(&attr);
5389 }
5390
5391 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5392 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5393 && pi->sub_type == BGP_ROUTE_STATIC)
5394 break;
5395
5396 if (pi) {
5397 if (attrhash_cmp(pi->attr, attr_new)
5398 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
5399 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
5400 bgp_dest_unlock_node(dest);
5401 bgp_attr_unintern(&attr_new);
5402 aspath_unintern(&attr.aspath);
5403 return;
5404 } else {
5405 /* The attribute is changed. */
5406 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5407
5408 /* Rewrite BGP route information. */
5409 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5410 bgp_path_info_restore(dest, pi);
5411 else
5412 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5413 #ifdef ENABLE_BGP_VNC
5414 if ((afi == AFI_IP || afi == AFI_IP6)
5415 && (safi == SAFI_UNICAST)) {
5416 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
5417 /*
5418 * Implicit withdraw case.
5419 * We have to do this before pi is
5420 * changed
5421 */
5422 ++vnc_implicit_withdraw;
5423 vnc_import_bgp_del_route(bgp, p, pi);
5424 vnc_import_bgp_exterior_del_route(
5425 bgp, p, pi);
5426 }
5427 }
5428 #endif
5429 bgp_attr_unintern(&pi->attr);
5430 pi->attr = attr_new;
5431 pi->uptime = bgp_clock();
5432 #ifdef ENABLE_BGP_VNC
5433 if ((afi == AFI_IP || afi == AFI_IP6)
5434 && (safi == SAFI_UNICAST)) {
5435 if (vnc_implicit_withdraw) {
5436 vnc_import_bgp_add_route(bgp, p, pi);
5437 vnc_import_bgp_exterior_add_route(
5438 bgp, p, pi);
5439 }
5440 }
5441 #endif
5442
5443 /* Nexthop reachability check. */
5444 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5445 && (safi == SAFI_UNICAST
5446 || safi == SAFI_LABELED_UNICAST)) {
5447
5448 struct bgp *bgp_nexthop = bgp;
5449
5450 if (pi->extra && pi->extra->bgp_orig)
5451 bgp_nexthop = pi->extra->bgp_orig;
5452
5453 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
5454 afi, safi, pi, NULL,
5455 0))
5456 bgp_path_info_set_flag(dest, pi,
5457 BGP_PATH_VALID);
5458 else {
5459 if (BGP_DEBUG(nht, NHT)) {
5460 char buf1[INET6_ADDRSTRLEN];
5461 inet_ntop(p->family,
5462 &p->u.prefix, buf1,
5463 INET6_ADDRSTRLEN);
5464 zlog_debug(
5465 "%s(%s): Route not in table, not advertising",
5466 __func__, buf1);
5467 }
5468 bgp_path_info_unset_flag(
5469 dest, pi, BGP_PATH_VALID);
5470 }
5471 } else {
5472 /* Delete the NHT structure if any, if we're
5473 * toggling between
5474 * enabling/disabling import check. We
5475 * deregister the route
5476 * from NHT to avoid overloading NHT and the
5477 * process interaction
5478 */
5479 bgp_unlink_nexthop(pi);
5480 bgp_path_info_set_flag(dest, pi,
5481 BGP_PATH_VALID);
5482 }
5483 /* Process change. */
5484 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5485 bgp_process(bgp, dest, afi, safi);
5486
5487 if (SAFI_UNICAST == safi
5488 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5489 || bgp->inst_type
5490 == BGP_INSTANCE_TYPE_DEFAULT)) {
5491 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
5492 pi);
5493 }
5494
5495 bgp_dest_unlock_node(dest);
5496 aspath_unintern(&attr.aspath);
5497 return;
5498 }
5499 }
5500
5501 /* Make new BGP info. */
5502 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5503 attr_new, dest);
5504 /* Nexthop reachability check. */
5505 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5506 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
5507 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0))
5508 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5509 else {
5510 if (BGP_DEBUG(nht, NHT)) {
5511 char buf1[INET6_ADDRSTRLEN];
5512 inet_ntop(p->family, &p->u.prefix, buf1,
5513 INET6_ADDRSTRLEN);
5514 zlog_debug(
5515 "%s(%s): Route not in table, not advertising",
5516 __func__, buf1);
5517 }
5518 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
5519 }
5520 } else {
5521 /* Delete the NHT structure if any, if we're toggling between
5522 * enabling/disabling import check. We deregister the route
5523 * from NHT to avoid overloading NHT and the process interaction
5524 */
5525 bgp_unlink_nexthop(new);
5526
5527 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5528 }
5529
5530 /* Aggregate address increment. */
5531 bgp_aggregate_increment(bgp, p, new, afi, safi);
5532
5533 /* Register new BGP information. */
5534 bgp_path_info_add(dest, new);
5535
5536 /* route_node_get lock */
5537 bgp_dest_unlock_node(dest);
5538
5539 /* Process change. */
5540 bgp_process(bgp, dest, afi, safi);
5541
5542 if (SAFI_UNICAST == safi
5543 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5544 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5545 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
5546 }
5547
5548 /* Unintern original. */
5549 aspath_unintern(&attr.aspath);
5550 }
5551
5552 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
5553 safi_t safi)
5554 {
5555 struct bgp_dest *dest;
5556 struct bgp_path_info *pi;
5557
5558 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5559
5560 /* Check selected route and self inserted route. */
5561 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5562 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5563 && pi->sub_type == BGP_ROUTE_STATIC)
5564 break;
5565
5566 /* Withdraw static BGP route from routing table. */
5567 if (pi) {
5568 if (SAFI_UNICAST == safi
5569 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5570 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5571 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5572 }
5573 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5574 bgp_unlink_nexthop(pi);
5575 bgp_path_info_delete(dest, pi);
5576 bgp_process(bgp, dest, afi, safi);
5577 }
5578
5579 /* Unlock bgp_node_lookup. */
5580 bgp_dest_unlock_node(dest);
5581 }
5582
5583 /*
5584 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
5585 */
5586 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
5587 afi_t afi, safi_t safi,
5588 struct prefix_rd *prd)
5589 {
5590 struct bgp_dest *dest;
5591 struct bgp_path_info *pi;
5592
5593 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
5594
5595 /* Check selected route and self inserted route. */
5596 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5597 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5598 && pi->sub_type == BGP_ROUTE_STATIC)
5599 break;
5600
5601 /* Withdraw static BGP route from routing table. */
5602 if (pi) {
5603 #ifdef ENABLE_BGP_VNC
5604 rfapiProcessWithdraw(
5605 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
5606 1); /* Kill, since it is an administrative change */
5607 #endif
5608 if (SAFI_MPLS_VPN == safi
5609 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5610 vpn_leak_to_vrf_withdraw(bgp, pi);
5611 }
5612 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5613 bgp_path_info_delete(dest, pi);
5614 bgp_process(bgp, dest, afi, safi);
5615 }
5616
5617 /* Unlock bgp_node_lookup. */
5618 bgp_dest_unlock_node(dest);
5619 }
5620
5621 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
5622 struct bgp_static *bgp_static, afi_t afi,
5623 safi_t safi)
5624 {
5625 struct bgp_dest *dest;
5626 struct bgp_path_info *new;
5627 struct attr *attr_new;
5628 struct attr attr = {0};
5629 struct bgp_path_info *pi;
5630 #ifdef ENABLE_BGP_VNC
5631 mpls_label_t label = 0;
5632 #endif
5633 uint32_t num_labels = 0;
5634 union gw_addr add;
5635
5636 assert(bgp_static);
5637
5638 if (bgp_static->label != MPLS_INVALID_LABEL)
5639 num_labels = 1;
5640 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
5641 &bgp_static->prd);
5642
5643 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5644
5645 attr.nexthop = bgp_static->igpnexthop;
5646 attr.med = bgp_static->igpmetric;
5647 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5648
5649 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
5650 || (safi == SAFI_ENCAP)) {
5651 if (afi == AFI_IP) {
5652 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
5653 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
5654 }
5655 }
5656 if (afi == AFI_L2VPN) {
5657 if (bgp_static->gatewayIp.family == AF_INET)
5658 add.ipv4.s_addr =
5659 bgp_static->gatewayIp.u.prefix4.s_addr;
5660 else if (bgp_static->gatewayIp.family == AF_INET6)
5661 memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
5662 sizeof(struct in6_addr));
5663 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
5664 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
5665 struct bgp_encap_type_vxlan bet;
5666 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
5667 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
5668 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
5669 }
5670 if (bgp_static->router_mac) {
5671 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
5672 }
5673 }
5674 /* Apply route-map. */
5675 if (bgp_static->rmap.name) {
5676 struct attr attr_tmp = attr;
5677 struct bgp_path_info rmap_path;
5678 route_map_result_t ret;
5679
5680 rmap_path.peer = bgp->peer_self;
5681 rmap_path.attr = &attr_tmp;
5682
5683 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5684
5685 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
5686
5687 bgp->peer_self->rmap_type = 0;
5688
5689 if (ret == RMAP_DENYMATCH) {
5690 /* Free uninterned attribute. */
5691 bgp_attr_flush(&attr_tmp);
5692
5693 /* Unintern original. */
5694 aspath_unintern(&attr.aspath);
5695 bgp_static_withdraw_safi(bgp, p, afi, safi,
5696 &bgp_static->prd);
5697 return;
5698 }
5699
5700 attr_new = bgp_attr_intern(&attr_tmp);
5701 } else {
5702 attr_new = bgp_attr_intern(&attr);
5703 }
5704
5705 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5706 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5707 && pi->sub_type == BGP_ROUTE_STATIC)
5708 break;
5709
5710 if (pi) {
5711 memset(&add, 0, sizeof(union gw_addr));
5712 if (attrhash_cmp(pi->attr, attr_new)
5713 && overlay_index_equal(afi, pi, &add)
5714 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
5715 bgp_dest_unlock_node(dest);
5716 bgp_attr_unintern(&attr_new);
5717 aspath_unintern(&attr.aspath);
5718 return;
5719 } else {
5720 /* The attribute is changed. */
5721 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5722
5723 /* Rewrite BGP route information. */
5724 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5725 bgp_path_info_restore(dest, pi);
5726 else
5727 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5728 bgp_attr_unintern(&pi->attr);
5729 pi->attr = attr_new;
5730 pi->uptime = bgp_clock();
5731 #ifdef ENABLE_BGP_VNC
5732 if (pi->extra)
5733 label = decode_label(&pi->extra->label[0]);
5734 #endif
5735
5736 /* Process change. */
5737 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5738 bgp_process(bgp, dest, afi, safi);
5739
5740 if (SAFI_MPLS_VPN == safi
5741 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5742 vpn_leak_to_vrf_update(bgp, pi);
5743 }
5744 #ifdef ENABLE_BGP_VNC
5745 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
5746 pi->attr, afi, safi, pi->type,
5747 pi->sub_type, &label);
5748 #endif
5749 bgp_dest_unlock_node(dest);
5750 aspath_unintern(&attr.aspath);
5751 return;
5752 }
5753 }
5754
5755
5756 /* Make new BGP info. */
5757 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5758 attr_new, dest);
5759 SET_FLAG(new->flags, BGP_PATH_VALID);
5760 new->extra = bgp_path_info_extra_new();
5761 if (num_labels) {
5762 new->extra->label[0] = bgp_static->label;
5763 new->extra->num_labels = num_labels;
5764 }
5765 #ifdef ENABLE_BGP_VNC
5766 label = decode_label(&bgp_static->label);
5767 #endif
5768
5769 /* Aggregate address increment. */
5770 bgp_aggregate_increment(bgp, p, new, afi, safi);
5771
5772 /* Register new BGP information. */
5773 bgp_path_info_add(dest, new);
5774 /* route_node_get lock */
5775 bgp_dest_unlock_node(dest);
5776
5777 /* Process change. */
5778 bgp_process(bgp, dest, afi, safi);
5779
5780 if (SAFI_MPLS_VPN == safi
5781 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5782 vpn_leak_to_vrf_update(bgp, new);
5783 }
5784 #ifdef ENABLE_BGP_VNC
5785 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
5786 safi, new->type, new->sub_type, &label);
5787 #endif
5788
5789 /* Unintern original. */
5790 aspath_unintern(&attr.aspath);
5791 }
5792
5793 /* Configure static BGP network. When user don't run zebra, static
5794 route should be installed as valid. */
5795 int bgp_static_set(struct bgp *bgp, const char *negate, struct prefix *pfx,
5796 afi_t afi, safi_t safi, const char *rmap, int backdoor,
5797 uint32_t label_index, char *errmsg, size_t errmsg_len)
5798 {
5799 struct prefix p;
5800 struct bgp_static *bgp_static;
5801 struct bgp_dest *dest;
5802 uint8_t need_update = 0;
5803
5804 prefix_copy(&p, pfx);
5805 apply_mask(&p);
5806
5807 if (negate) {
5808
5809 /* Set BGP static route configuration. */
5810 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
5811
5812 if (!dest) {
5813 snprintf(errmsg, errmsg_len,
5814 "Can't find static route specified\n");
5815 return -1;
5816 }
5817
5818 bgp_static = bgp_dest_get_bgp_static_info(dest);
5819
5820 if ((label_index != BGP_INVALID_LABEL_INDEX)
5821 && (label_index != bgp_static->label_index)) {
5822 snprintf(errmsg, errmsg_len,
5823 "label-index doesn't match static route\n");
5824 return -1;
5825 }
5826
5827 if ((rmap && bgp_static->rmap.name)
5828 && strcmp(rmap, bgp_static->rmap.name)) {
5829 snprintf(errmsg, errmsg_len,
5830 "route-map name doesn't match static route\n");
5831 return -1;
5832 }
5833
5834 /* Update BGP RIB. */
5835 if (!bgp_static->backdoor)
5836 bgp_static_withdraw(bgp, &p, afi, safi);
5837
5838 /* Clear configuration. */
5839 bgp_static_free(bgp_static);
5840 bgp_dest_set_bgp_static_info(dest, NULL);
5841 bgp_dest_unlock_node(dest);
5842 bgp_dest_unlock_node(dest);
5843 } else {
5844
5845 /* Set BGP static route configuration. */
5846 dest = bgp_node_get(bgp->route[afi][safi], &p);
5847 bgp_static = bgp_dest_get_bgp_static_info(dest);
5848 if (bgp_static) {
5849 /* Configuration change. */
5850 /* Label index cannot be changed. */
5851 if (bgp_static->label_index != label_index) {
5852 snprintf(errmsg, errmsg_len,
5853 "cannot change label-index\n");
5854 return -1;
5855 }
5856
5857 /* Check previous routes are installed into BGP. */
5858 if (bgp_static->valid
5859 && bgp_static->backdoor != backdoor)
5860 need_update = 1;
5861
5862 bgp_static->backdoor = backdoor;
5863
5864 if (rmap) {
5865 XFREE(MTYPE_ROUTE_MAP_NAME,
5866 bgp_static->rmap.name);
5867 route_map_counter_decrement(
5868 bgp_static->rmap.map);
5869 bgp_static->rmap.name =
5870 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5871 bgp_static->rmap.map =
5872 route_map_lookup_by_name(rmap);
5873 route_map_counter_increment(
5874 bgp_static->rmap.map);
5875 } else {
5876 XFREE(MTYPE_ROUTE_MAP_NAME,
5877 bgp_static->rmap.name);
5878 route_map_counter_decrement(
5879 bgp_static->rmap.map);
5880 bgp_static->rmap.map = NULL;
5881 bgp_static->valid = 0;
5882 }
5883 bgp_dest_unlock_node(dest);
5884 } else {
5885 /* New configuration. */
5886 bgp_static = bgp_static_new();
5887 bgp_static->backdoor = backdoor;
5888 bgp_static->valid = 0;
5889 bgp_static->igpmetric = 0;
5890 bgp_static->igpnexthop.s_addr = INADDR_ANY;
5891 bgp_static->label_index = label_index;
5892
5893 if (rmap) {
5894 XFREE(MTYPE_ROUTE_MAP_NAME,
5895 bgp_static->rmap.name);
5896 route_map_counter_decrement(
5897 bgp_static->rmap.map);
5898 bgp_static->rmap.name =
5899 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5900 bgp_static->rmap.map =
5901 route_map_lookup_by_name(rmap);
5902 route_map_counter_increment(
5903 bgp_static->rmap.map);
5904 }
5905 bgp_dest_set_bgp_static_info(dest, bgp_static);
5906 }
5907
5908 bgp_static->valid = 1;
5909 if (need_update)
5910 bgp_static_withdraw(bgp, &p, afi, safi);
5911
5912 if (!bgp_static->backdoor)
5913 bgp_static_update(bgp, &p, bgp_static, afi, safi);
5914 }
5915
5916 return 0;
5917 }
5918
5919 void bgp_static_add(struct bgp *bgp)
5920 {
5921 afi_t afi;
5922 safi_t safi;
5923 struct bgp_dest *dest;
5924 struct bgp_dest *rm;
5925 struct bgp_table *table;
5926 struct bgp_static *bgp_static;
5927
5928 FOREACH_AFI_SAFI (afi, safi)
5929 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
5930 dest = bgp_route_next(dest)) {
5931 if (!bgp_dest_has_bgp_path_info_data(dest))
5932 continue;
5933
5934 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5935 || (safi == SAFI_EVPN)) {
5936 table = bgp_dest_get_bgp_table_info(dest);
5937
5938 for (rm = bgp_table_top(table); rm;
5939 rm = bgp_route_next(rm)) {
5940 bgp_static =
5941 bgp_dest_get_bgp_static_info(
5942 rm);
5943 bgp_static_update_safi(
5944 bgp, bgp_dest_get_prefix(rm),
5945 bgp_static, afi, safi);
5946 }
5947 } else {
5948 bgp_static_update(
5949 bgp, bgp_dest_get_prefix(dest),
5950 bgp_dest_get_bgp_static_info(dest), afi,
5951 safi);
5952 }
5953 }
5954 }
5955
5956 /* Called from bgp_delete(). Delete all static routes from the BGP
5957 instance. */
5958 void bgp_static_delete(struct bgp *bgp)
5959 {
5960 afi_t afi;
5961 safi_t safi;
5962 struct bgp_dest *dest;
5963 struct bgp_dest *rm;
5964 struct bgp_table *table;
5965 struct bgp_static *bgp_static;
5966
5967 FOREACH_AFI_SAFI (afi, safi)
5968 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
5969 dest = bgp_route_next(dest)) {
5970 if (!bgp_dest_has_bgp_path_info_data(dest))
5971 continue;
5972
5973 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5974 || (safi == SAFI_EVPN)) {
5975 table = bgp_dest_get_bgp_table_info(dest);
5976
5977 for (rm = bgp_table_top(table); rm;
5978 rm = bgp_route_next(rm)) {
5979 bgp_static =
5980 bgp_dest_get_bgp_static_info(
5981 rm);
5982 if (!bgp_static)
5983 continue;
5984
5985 bgp_static_withdraw_safi(
5986 bgp, bgp_dest_get_prefix(rm),
5987 AFI_IP, safi,
5988 (struct prefix_rd *)
5989 bgp_dest_get_prefix(
5990 dest));
5991 bgp_static_free(bgp_static);
5992 bgp_dest_set_bgp_static_info(rm,
5993 NULL);
5994 bgp_dest_unlock_node(rm);
5995 }
5996 } else {
5997 bgp_static = bgp_dest_get_bgp_static_info(dest);
5998 bgp_static_withdraw(bgp,
5999 bgp_dest_get_prefix(dest),
6000 afi, safi);
6001 bgp_static_free(bgp_static);
6002 bgp_dest_set_bgp_static_info(dest, NULL);
6003 bgp_dest_unlock_node(dest);
6004 }
6005 }
6006 }
6007
6008 void bgp_static_redo_import_check(struct bgp *bgp)
6009 {
6010 afi_t afi;
6011 safi_t safi;
6012 struct bgp_dest *dest;
6013 struct bgp_dest *rm;
6014 struct bgp_table *table;
6015 struct bgp_static *bgp_static;
6016
6017 /* Use this flag to force reprocessing of the route */
6018 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6019 FOREACH_AFI_SAFI (afi, safi) {
6020 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6021 dest = bgp_route_next(dest)) {
6022 if (!bgp_dest_has_bgp_path_info_data(dest))
6023 continue;
6024
6025 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6026 || (safi == SAFI_EVPN)) {
6027 table = bgp_dest_get_bgp_table_info(dest);
6028
6029 for (rm = bgp_table_top(table); rm;
6030 rm = bgp_route_next(rm)) {
6031 bgp_static =
6032 bgp_dest_get_bgp_static_info(
6033 rm);
6034 bgp_static_update_safi(
6035 bgp, bgp_dest_get_prefix(rm),
6036 bgp_static, afi, safi);
6037 }
6038 } else {
6039 bgp_static = bgp_dest_get_bgp_static_info(dest);
6040 bgp_static_update(bgp,
6041 bgp_dest_get_prefix(dest),
6042 bgp_static, afi, safi);
6043 }
6044 }
6045 }
6046 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6047 }
6048
6049 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6050 safi_t safi)
6051 {
6052 struct bgp_table *table;
6053 struct bgp_dest *dest;
6054 struct bgp_path_info *pi;
6055
6056 /* Do not install the aggregate route if BGP is in the
6057 * process of termination.
6058 */
6059 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6060 || (bgp->peer_self == NULL))
6061 return;
6062
6063 table = bgp->rib[afi][safi];
6064 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6065 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6066 if (pi->peer == bgp->peer_self
6067 && ((pi->type == ZEBRA_ROUTE_BGP
6068 && pi->sub_type == BGP_ROUTE_STATIC)
6069 || (pi->type != ZEBRA_ROUTE_BGP
6070 && pi->sub_type
6071 == BGP_ROUTE_REDISTRIBUTE))) {
6072 bgp_aggregate_decrement(
6073 bgp, bgp_dest_get_prefix(dest), pi, afi,
6074 safi);
6075 bgp_unlink_nexthop(pi);
6076 bgp_path_info_delete(dest, pi);
6077 bgp_process(bgp, dest, afi, safi);
6078 }
6079 }
6080 }
6081 }
6082
6083 /*
6084 * Purge all networks and redistributed routes from routing table.
6085 * Invoked upon the instance going down.
6086 */
6087 void bgp_purge_static_redist_routes(struct bgp *bgp)
6088 {
6089 afi_t afi;
6090 safi_t safi;
6091
6092 FOREACH_AFI_SAFI (afi, safi)
6093 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6094 }
6095
6096 /*
6097 * gpz 110624
6098 * Currently this is used to set static routes for VPN and ENCAP.
6099 * I think it can probably be factored with bgp_static_set.
6100 */
6101 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6102 const char *ip_str, const char *rd_str,
6103 const char *label_str, const char *rmap_str,
6104 int evpn_type, const char *esi, const char *gwip,
6105 const char *ethtag, const char *routermac)
6106 {
6107 VTY_DECLVAR_CONTEXT(bgp, bgp);
6108 int ret;
6109 struct prefix p;
6110 struct prefix_rd prd;
6111 struct bgp_dest *pdest;
6112 struct bgp_dest *dest;
6113 struct bgp_table *table;
6114 struct bgp_static *bgp_static;
6115 mpls_label_t label = MPLS_INVALID_LABEL;
6116 struct prefix gw_ip;
6117
6118 /* validate ip prefix */
6119 ret = str2prefix(ip_str, &p);
6120 if (!ret) {
6121 vty_out(vty, "%% Malformed prefix\n");
6122 return CMD_WARNING_CONFIG_FAILED;
6123 }
6124 apply_mask(&p);
6125 if ((afi == AFI_L2VPN)
6126 && (bgp_build_evpn_prefix(evpn_type,
6127 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6128 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6129 return CMD_WARNING_CONFIG_FAILED;
6130 }
6131
6132 ret = str2prefix_rd(rd_str, &prd);
6133 if (!ret) {
6134 vty_out(vty, "%% Malformed rd\n");
6135 return CMD_WARNING_CONFIG_FAILED;
6136 }
6137
6138 if (label_str) {
6139 unsigned long label_val;
6140 label_val = strtoul(label_str, NULL, 10);
6141 encode_label(label_val, &label);
6142 }
6143
6144 if (safi == SAFI_EVPN) {
6145 if (esi && str2esi(esi, NULL) == 0) {
6146 vty_out(vty, "%% Malformed ESI\n");
6147 return CMD_WARNING_CONFIG_FAILED;
6148 }
6149 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6150 vty_out(vty, "%% Malformed Router MAC\n");
6151 return CMD_WARNING_CONFIG_FAILED;
6152 }
6153 if (gwip) {
6154 memset(&gw_ip, 0, sizeof(struct prefix));
6155 ret = str2prefix(gwip, &gw_ip);
6156 if (!ret) {
6157 vty_out(vty, "%% Malformed GatewayIp\n");
6158 return CMD_WARNING_CONFIG_FAILED;
6159 }
6160 if ((gw_ip.family == AF_INET
6161 && is_evpn_prefix_ipaddr_v6(
6162 (struct prefix_evpn *)&p))
6163 || (gw_ip.family == AF_INET6
6164 && is_evpn_prefix_ipaddr_v4(
6165 (struct prefix_evpn *)&p))) {
6166 vty_out(vty,
6167 "%% GatewayIp family differs with IP prefix\n");
6168 return CMD_WARNING_CONFIG_FAILED;
6169 }
6170 }
6171 }
6172 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6173 if (!bgp_dest_has_bgp_path_info_data(pdest))
6174 bgp_dest_set_bgp_table_info(pdest,
6175 bgp_table_init(bgp, afi, safi));
6176 table = bgp_dest_get_bgp_table_info(pdest);
6177
6178 dest = bgp_node_get(table, &p);
6179
6180 if (bgp_dest_has_bgp_path_info_data(dest)) {
6181 vty_out(vty, "%% Same network configuration exists\n");
6182 bgp_dest_unlock_node(dest);
6183 } else {
6184 /* New configuration. */
6185 bgp_static = bgp_static_new();
6186 bgp_static->backdoor = 0;
6187 bgp_static->valid = 0;
6188 bgp_static->igpmetric = 0;
6189 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6190 bgp_static->label = label;
6191 bgp_static->prd = prd;
6192
6193 if (rmap_str) {
6194 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6195 route_map_counter_decrement(bgp_static->rmap.map);
6196 bgp_static->rmap.name =
6197 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
6198 bgp_static->rmap.map =
6199 route_map_lookup_by_name(rmap_str);
6200 route_map_counter_increment(bgp_static->rmap.map);
6201 }
6202
6203 if (safi == SAFI_EVPN) {
6204 if (esi) {
6205 bgp_static->eth_s_id =
6206 XCALLOC(MTYPE_ATTR,
6207 sizeof(esi_t));
6208 str2esi(esi, bgp_static->eth_s_id);
6209 }
6210 if (routermac) {
6211 bgp_static->router_mac =
6212 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
6213 (void)prefix_str2mac(routermac,
6214 bgp_static->router_mac);
6215 }
6216 if (gwip)
6217 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
6218 }
6219 bgp_dest_set_bgp_static_info(dest, bgp_static);
6220
6221 bgp_static->valid = 1;
6222 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
6223 }
6224
6225 return CMD_SUCCESS;
6226 }
6227
6228 /* Configure static BGP network. */
6229 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
6230 const char *ip_str, const char *rd_str,
6231 const char *label_str, int evpn_type, const char *esi,
6232 const char *gwip, const char *ethtag)
6233 {
6234 VTY_DECLVAR_CONTEXT(bgp, bgp);
6235 int ret;
6236 struct prefix p;
6237 struct prefix_rd prd;
6238 struct bgp_dest *pdest;
6239 struct bgp_dest *dest;
6240 struct bgp_table *table;
6241 struct bgp_static *bgp_static;
6242 mpls_label_t label = MPLS_INVALID_LABEL;
6243
6244 /* Convert IP prefix string to struct prefix. */
6245 ret = str2prefix(ip_str, &p);
6246 if (!ret) {
6247 vty_out(vty, "%% Malformed prefix\n");
6248 return CMD_WARNING_CONFIG_FAILED;
6249 }
6250 apply_mask(&p);
6251 if ((afi == AFI_L2VPN)
6252 && (bgp_build_evpn_prefix(evpn_type,
6253 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6254 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6255 return CMD_WARNING_CONFIG_FAILED;
6256 }
6257 ret = str2prefix_rd(rd_str, &prd);
6258 if (!ret) {
6259 vty_out(vty, "%% Malformed rd\n");
6260 return CMD_WARNING_CONFIG_FAILED;
6261 }
6262
6263 if (label_str) {
6264 unsigned long label_val;
6265 label_val = strtoul(label_str, NULL, 10);
6266 encode_label(label_val, &label);
6267 }
6268
6269 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6270 if (!bgp_dest_has_bgp_path_info_data(pdest))
6271 bgp_dest_set_bgp_table_info(pdest,
6272 bgp_table_init(bgp, afi, safi));
6273 else
6274 bgp_dest_unlock_node(pdest);
6275 table = bgp_dest_get_bgp_table_info(pdest);
6276
6277 dest = bgp_node_lookup(table, &p);
6278
6279 if (dest) {
6280 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
6281
6282 bgp_static = bgp_dest_get_bgp_static_info(dest);
6283 bgp_static_free(bgp_static);
6284 bgp_dest_set_bgp_static_info(dest, NULL);
6285 bgp_dest_unlock_node(dest);
6286 bgp_dest_unlock_node(dest);
6287 } else
6288 vty_out(vty, "%% Can't find the route\n");
6289
6290 return CMD_SUCCESS;
6291 }
6292
6293 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
6294 const char *rmap_name)
6295 {
6296 VTY_DECLVAR_CONTEXT(bgp, bgp);
6297 struct bgp_rmap *rmap;
6298
6299 rmap = &bgp->table_map[afi][safi];
6300 if (rmap_name) {
6301 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6302 route_map_counter_decrement(rmap->map);
6303 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
6304 rmap->map = route_map_lookup_by_name(rmap_name);
6305 route_map_counter_increment(rmap->map);
6306 } else {
6307 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6308 route_map_counter_decrement(rmap->map);
6309 rmap->map = NULL;
6310 }
6311
6312 if (bgp_fibupd_safi(safi))
6313 bgp_zebra_announce_table(bgp, afi, safi);
6314
6315 return CMD_SUCCESS;
6316 }
6317
6318 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
6319 const char *rmap_name)
6320 {
6321 VTY_DECLVAR_CONTEXT(bgp, bgp);
6322 struct bgp_rmap *rmap;
6323
6324 rmap = &bgp->table_map[afi][safi];
6325 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6326 route_map_counter_decrement(rmap->map);
6327 rmap->map = NULL;
6328
6329 if (bgp_fibupd_safi(safi))
6330 bgp_zebra_announce_table(bgp, afi, safi);
6331
6332 return CMD_SUCCESS;
6333 }
6334
6335 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
6336 safi_t safi)
6337 {
6338 if (bgp->table_map[afi][safi].name) {
6339 vty_out(vty, " table-map %s\n",
6340 bgp->table_map[afi][safi].name);
6341 }
6342 }
6343
6344 DEFUN (bgp_table_map,
6345 bgp_table_map_cmd,
6346 "table-map WORD",
6347 "BGP table to RIB route download filter\n"
6348 "Name of the route map\n")
6349 {
6350 int idx_word = 1;
6351 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6352 argv[idx_word]->arg);
6353 }
6354 DEFUN (no_bgp_table_map,
6355 no_bgp_table_map_cmd,
6356 "no table-map WORD",
6357 NO_STR
6358 "BGP table to RIB route download filter\n"
6359 "Name of the route map\n")
6360 {
6361 int idx_word = 2;
6362 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6363 argv[idx_word]->arg);
6364 }
6365
6366 DEFPY_YANG (bgp_network, bgp_network_cmd,
6367 "[no] network \
6368 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
6369 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
6370 backdoor$backdoor}]",
6371 NO_STR
6372 "Specify a network to announce via BGP\n"
6373 "IPv4 prefix\n"
6374 "Network number\n"
6375 "Network mask\n"
6376 "Network mask\n"
6377 "Route-map to modify the attributes\n"
6378 "Name of the route map\n"
6379 "Label index to associate with the prefix\n"
6380 "Label index value\n"
6381 "Specify a BGP backdoor route\n")
6382 {
6383 char addr_prefix_str[PREFIX_STRLEN];
6384 char base_xpath[XPATH_MAXLEN];
6385 afi_t afi;
6386 safi_t safi;
6387
6388 if (address_str) {
6389 int ret;
6390
6391 ret = netmask_str2prefix_str(address_str, netmask_str,
6392 addr_prefix_str,
6393 sizeof(addr_prefix_str));
6394 if (!ret) {
6395 vty_out(vty, "%% Inconsistent address and mask\n");
6396 return CMD_WARNING_CONFIG_FAILED;
6397 }
6398 }
6399
6400 afi = bgp_node_afi(vty);
6401 safi = bgp_node_safi(vty);
6402
6403 if (no) {
6404 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
6405 } else {
6406 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
6407
6408 if (map_name)
6409 nb_cli_enqueue_change(vty, "./rmap-policy-export",
6410 NB_OP_CREATE, map_name);
6411 else
6412 nb_cli_enqueue_change(vty, "./rmap-policy-export",
6413 NB_OP_DESTROY, NULL);
6414
6415 if (label_index_str)
6416 nb_cli_enqueue_change(vty, "./label-index",
6417 NB_OP_MODIFY, label_index_str);
6418
6419 nb_cli_enqueue_change(vty, "./backdoor", NB_OP_MODIFY,
6420 backdoor ? "true" : "false");
6421 }
6422
6423 snprintf(
6424 base_xpath, sizeof(base_xpath),
6425 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/network-config[prefix='%s']",
6426 yang_afi_safi_value2identity(afi, safi),
6427 bgp_afi_safi_get_container_str(afi, safi),
6428 address_str ? addr_prefix_str : prefix_str);
6429
6430 return nb_cli_apply_changes(vty, base_xpath);
6431 }
6432
6433 DEFPY_YANG (ipv6_bgp_network,
6434 ipv6_bgp_network_cmd,
6435 "[no] network X:X::X:X/M$prefix \
6436 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
6437 NO_STR
6438 "Specify a network to announce via BGP\n"
6439 "IPv6 prefix\n"
6440 "Route-map to modify the attributes\n"
6441 "Name of the route map\n"
6442 "Label index to associate with the prefix\n"
6443 "Label index value\n")
6444 {
6445 char base_xpath[XPATH_MAXLEN];
6446 afi_t afi;
6447 safi_t safi;
6448
6449 afi = bgp_node_afi(vty);
6450 safi = bgp_node_safi(vty);
6451
6452 if (no) {
6453 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
6454 } else {
6455 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
6456
6457 if (map_name)
6458 nb_cli_enqueue_change(vty, "./rmap-policy-export",
6459 NB_OP_MODIFY, map_name);
6460 else
6461 nb_cli_enqueue_change(vty, "./rmap-policy-export",
6462 NB_OP_DESTROY, NULL);
6463
6464 if (label_index_str)
6465 nb_cli_enqueue_change(vty, "./label-index",
6466 NB_OP_MODIFY, label_index_str);
6467 }
6468
6469 snprintf(
6470 base_xpath, sizeof(base_xpath),
6471 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/network-config[prefix='%s']",
6472 yang_afi_safi_value2identity(afi, safi),
6473 bgp_afi_safi_get_container_str(afi, safi), prefix_str);
6474
6475 return nb_cli_apply_changes(vty, base_xpath);
6476 }
6477
6478 void cli_show_bgp_global_afi_safi_network_config(struct vty *vty,
6479 struct lyd_node *dnode,
6480 bool show_defaults)
6481 {
6482 vty_out(vty, " network %s", yang_dnode_get_string(dnode, "./prefix"));
6483
6484 if (yang_dnode_exists(dnode, "./label-index"))
6485 vty_out(vty, " label-index %s",
6486 yang_dnode_get_string(dnode, "./label-index"));
6487
6488 if (yang_dnode_exists(dnode, "./rmap-policy-export"))
6489 vty_out(vty, " route-map %s",
6490 yang_dnode_get_string(dnode, "./rmap-policy-export"));
6491
6492 if (yang_dnode_get_bool(dnode, "./backdoor"))
6493 vty_out(vty, " backdoor");
6494
6495 vty_out(vty, "\n");
6496 }
6497
6498 static struct bgp_aggregate *bgp_aggregate_new(void)
6499 {
6500 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
6501 }
6502
6503 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
6504 {
6505 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
6506 route_map_counter_decrement(aggregate->suppress_map);
6507 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
6508 route_map_counter_decrement(aggregate->rmap.map);
6509 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
6510 }
6511
6512 /**
6513 * Helper function to avoid repeated code: prepare variables for a
6514 * `route_map_apply` call.
6515 *
6516 * \returns `true` on route map match, otherwise `false`.
6517 */
6518 static bool aggr_suppress_map_test(struct bgp *bgp,
6519 struct bgp_aggregate *aggregate,
6520 struct bgp_path_info *pi)
6521 {
6522 const struct prefix *p = bgp_dest_get_prefix(pi->net);
6523 route_map_result_t rmr = RMAP_DENYMATCH;
6524 struct bgp_path_info rmap_path = {};
6525 struct attr attr = {};
6526
6527 /* No route map entries created, just don't match. */
6528 if (aggregate->suppress_map == NULL)
6529 return false;
6530
6531 /* Call route map matching and return result. */
6532 attr.aspath = aspath_empty();
6533 rmap_path.peer = bgp->peer_self;
6534 rmap_path.attr = &attr;
6535
6536 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
6537 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
6538 bgp->peer_self->rmap_type = 0;
6539
6540 bgp_attr_flush(&attr);
6541
6542 return rmr == RMAP_PERMITMATCH;
6543 }
6544
6545 /** Test whether the aggregation has suppressed this path or not. */
6546 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
6547 struct bgp_path_info *pi)
6548 {
6549 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
6550 return false;
6551
6552 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
6553 }
6554
6555 /**
6556 * Suppress this path and keep the reference.
6557 *
6558 * \returns `true` if needs processing otherwise `false`.
6559 */
6560 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
6561 struct bgp_path_info *pi)
6562 {
6563 struct bgp_path_info_extra *pie;
6564
6565 /* Path is already suppressed by this aggregation. */
6566 if (aggr_suppress_exists(aggregate, pi))
6567 return false;
6568
6569 pie = bgp_path_info_extra_get(pi);
6570
6571 /* This is the first suppression, allocate memory and list it. */
6572 if (pie->aggr_suppressors == NULL)
6573 pie->aggr_suppressors = list_new();
6574
6575 listnode_add(pie->aggr_suppressors, aggregate);
6576
6577 /* Only mark for processing if suppressed. */
6578 if (listcount(pie->aggr_suppressors) == 1) {
6579 if (BGP_DEBUG(update, UPDATE_OUT))
6580 zlog_debug("aggregate-address suppressing: %pFX",
6581 bgp_dest_get_prefix(pi->net));
6582
6583 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
6584 return true;
6585 }
6586
6587 return false;
6588 }
6589
6590 /**
6591 * Unsuppress this path and remove the reference.
6592 *
6593 * \returns `true` if needs processing otherwise `false`.
6594 */
6595 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
6596 struct bgp_path_info *pi)
6597 {
6598 /* Path wasn't suppressed. */
6599 if (!aggr_suppress_exists(aggregate, pi))
6600 return false;
6601
6602 listnode_delete(pi->extra->aggr_suppressors, aggregate);
6603
6604 /* Unsuppress and free extra memory if last item. */
6605 if (listcount(pi->extra->aggr_suppressors) == 0) {
6606 if (BGP_DEBUG(update, UPDATE_OUT))
6607 zlog_debug("aggregate-address unsuppressing: %pFX",
6608 bgp_dest_get_prefix(pi->net));
6609
6610 list_delete(&pi->extra->aggr_suppressors);
6611 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
6612 return true;
6613 }
6614
6615 return false;
6616 }
6617
6618 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
6619 struct aspath *aspath,
6620 struct community *comm,
6621 struct ecommunity *ecomm,
6622 struct lcommunity *lcomm)
6623 {
6624 static struct aspath *ae = NULL;
6625
6626 if (!ae)
6627 ae = aspath_empty();
6628
6629 if (!pi)
6630 return false;
6631
6632 if (origin != pi->attr->origin)
6633 return false;
6634
6635 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
6636 return false;
6637
6638 if (!community_cmp(pi->attr->community, comm))
6639 return false;
6640
6641 if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
6642 return false;
6643
6644 if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
6645 return false;
6646
6647 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
6648 return false;
6649
6650 return true;
6651 }
6652
6653 static void bgp_aggregate_install(
6654 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
6655 uint8_t origin, struct aspath *aspath, struct community *community,
6656 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
6657 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
6658 {
6659 struct bgp_dest *dest;
6660 struct bgp_table *table;
6661 struct bgp_path_info *pi, *orig, *new;
6662 struct attr *attr;
6663
6664 table = bgp->rib[afi][safi];
6665
6666 dest = bgp_node_get(table, p);
6667
6668 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6669 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6670 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6671 break;
6672
6673 /*
6674 * If we have paths with different MEDs, then don't install
6675 * (or uninstall) the aggregate route.
6676 */
6677 if (aggregate->match_med && aggregate->med_mismatched)
6678 goto uninstall_aggregate_route;
6679
6680 if (aggregate->count > 0) {
6681 /*
6682 * If the aggregate information has not changed
6683 * no need to re-install it again.
6684 */
6685 if (bgp_aggregate_info_same(orig, origin, aspath, community,
6686 ecommunity, lcommunity)) {
6687 bgp_dest_unlock_node(dest);
6688
6689 if (aspath)
6690 aspath_free(aspath);
6691 if (community)
6692 community_free(&community);
6693 if (ecommunity)
6694 ecommunity_free(&ecommunity);
6695 if (lcommunity)
6696 lcommunity_free(&lcommunity);
6697
6698 return;
6699 }
6700
6701 /*
6702 * Mark the old as unusable
6703 */
6704 if (pi)
6705 bgp_path_info_delete(dest, pi);
6706
6707 attr = bgp_attr_aggregate_intern(
6708 bgp, origin, aspath, community, ecommunity, lcommunity,
6709 aggregate, atomic_aggregate, p);
6710
6711 if (!attr) {
6712 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
6713 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
6714 zlog_debug("%s: %pFX null attribute", __func__,
6715 p);
6716 return;
6717 }
6718
6719 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
6720 bgp->peer_self, attr, dest);
6721
6722 SET_FLAG(new->flags, BGP_PATH_VALID);
6723
6724 bgp_path_info_add(dest, new);
6725 bgp_process(bgp, dest, afi, safi);
6726 } else {
6727 uninstall_aggregate_route:
6728 for (pi = orig; pi; pi = pi->next)
6729 if (pi->peer == bgp->peer_self
6730 && pi->type == ZEBRA_ROUTE_BGP
6731 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6732 break;
6733
6734 /* Withdraw static BGP route from routing table. */
6735 if (pi) {
6736 bgp_path_info_delete(dest, pi);
6737 bgp_process(bgp, dest, afi, safi);
6738 }
6739 }
6740
6741 bgp_dest_unlock_node(dest);
6742 }
6743
6744 /**
6745 * Check if the current path has different MED than other known paths.
6746 *
6747 * \returns `true` if the MED matched the others else `false`.
6748 */
6749 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
6750 struct bgp *bgp, struct bgp_path_info *pi)
6751 {
6752 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
6753
6754 /* This is the first route being analyzed. */
6755 if (!aggregate->med_initialized) {
6756 aggregate->med_initialized = true;
6757 aggregate->med_mismatched = false;
6758 aggregate->med_matched_value = cur_med;
6759 } else {
6760 /* Check if routes with different MED showed up. */
6761 if (cur_med != aggregate->med_matched_value)
6762 aggregate->med_mismatched = true;
6763 }
6764
6765 return !aggregate->med_mismatched;
6766 }
6767
6768 /**
6769 * Initializes and tests all routes in the aggregate address path for MED
6770 * values.
6771 *
6772 * \returns `true` if all MEDs are the same otherwise `false`.
6773 */
6774 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
6775 struct bgp *bgp, const struct prefix *p,
6776 afi_t afi, safi_t safi)
6777 {
6778 struct bgp_table *table = bgp->rib[afi][safi];
6779 const struct prefix *dest_p;
6780 struct bgp_dest *dest, *top;
6781 struct bgp_path_info *pi;
6782 bool med_matched = true;
6783
6784 aggregate->med_initialized = false;
6785
6786 top = bgp_node_get(table, p);
6787 for (dest = bgp_node_get(table, p); dest;
6788 dest = bgp_route_next_until(dest, top)) {
6789 dest_p = bgp_dest_get_prefix(dest);
6790 if (dest_p->prefixlen <= p->prefixlen)
6791 continue;
6792
6793 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6794 if (BGP_PATH_HOLDDOWN(pi))
6795 continue;
6796 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6797 continue;
6798 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
6799 med_matched = false;
6800 break;
6801 }
6802 }
6803 if (!med_matched)
6804 break;
6805 }
6806 bgp_dest_unlock_node(top);
6807
6808 return med_matched;
6809 }
6810
6811 /**
6812 * Toggles the route suppression status for this aggregate address
6813 * configuration.
6814 */
6815 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
6816 struct bgp *bgp, const struct prefix *p,
6817 afi_t afi, safi_t safi, bool suppress)
6818 {
6819 struct bgp_table *table = bgp->rib[afi][safi];
6820 const struct prefix *dest_p;
6821 struct bgp_dest *dest, *top;
6822 struct bgp_path_info *pi;
6823 bool toggle_suppression;
6824
6825 /* We've found a different MED we must revert any suppressed routes. */
6826 top = bgp_node_get(table, p);
6827 for (dest = bgp_node_get(table, p); dest;
6828 dest = bgp_route_next_until(dest, top)) {
6829 dest_p = bgp_dest_get_prefix(dest);
6830 if (dest_p->prefixlen <= p->prefixlen)
6831 continue;
6832
6833 toggle_suppression = false;
6834 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6835 if (BGP_PATH_HOLDDOWN(pi))
6836 continue;
6837 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6838 continue;
6839
6840 /* We are toggling suppression back. */
6841 if (suppress) {
6842 /* Suppress route if not suppressed already. */
6843 if (aggr_suppress_path(aggregate, pi))
6844 toggle_suppression = true;
6845 continue;
6846 }
6847
6848 /* Install route if there is no more suppression. */
6849 if (aggr_unsuppress_path(aggregate, pi))
6850 toggle_suppression = true;
6851 }
6852
6853 if (toggle_suppression)
6854 bgp_process(bgp, dest, afi, safi);
6855 }
6856 bgp_dest_unlock_node(top);
6857 }
6858
6859 /**
6860 * Aggregate address MED matching incremental test: this function is called
6861 * when the initial aggregation occurred and we are only testing a single
6862 * new path.
6863 *
6864 * In addition to testing and setting the MED validity it also installs back
6865 * suppressed routes (if summary is configured).
6866 *
6867 * Must not be called in `bgp_aggregate_route`.
6868 */
6869 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
6870 struct bgp *bgp, const struct prefix *p,
6871 afi_t afi, safi_t safi,
6872 struct bgp_path_info *pi, bool is_adding)
6873 {
6874 /* MED matching disabled. */
6875 if (!aggregate->match_med)
6876 return;
6877
6878 /* Aggregation with different MED, nothing to do. */
6879 if (aggregate->med_mismatched)
6880 return;
6881
6882 /*
6883 * Test the current entry:
6884 *
6885 * is_adding == true: if the new entry doesn't match then we must
6886 * install all suppressed routes.
6887 *
6888 * is_adding == false: if the entry being removed was the last
6889 * unmatching entry then we can suppress all routes.
6890 */
6891 if (!is_adding) {
6892 if (bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi)
6893 && aggregate->summary_only)
6894 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi,
6895 safi, true);
6896 } else
6897 bgp_aggregate_med_match(aggregate, bgp, pi);
6898
6899 /* No mismatches, just quit. */
6900 if (!aggregate->med_mismatched)
6901 return;
6902
6903 /* Route summarization is disabled. */
6904 if (!aggregate->summary_only)
6905 return;
6906
6907 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
6908 }
6909
6910 /* Update an aggregate as routes are added/removed from the BGP table */
6911 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
6912 safi_t safi, struct bgp_aggregate *aggregate)
6913 {
6914 struct bgp_table *table;
6915 struct bgp_dest *top;
6916 struct bgp_dest *dest;
6917 uint8_t origin;
6918 struct aspath *aspath = NULL;
6919 struct community *community = NULL;
6920 struct ecommunity *ecommunity = NULL;
6921 struct lcommunity *lcommunity = NULL;
6922 struct bgp_path_info *pi;
6923 unsigned long match = 0;
6924 uint8_t atomic_aggregate = 0;
6925
6926 /* If the bgp instance is being deleted or self peer is deleted
6927 * then do not create aggregate route
6928 */
6929 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6930 || (bgp->peer_self == NULL))
6931 return;
6932
6933 /* Initialize and test routes for MED difference. */
6934 if (aggregate->match_med)
6935 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
6936
6937 /*
6938 * Reset aggregate count: we might've been called from route map
6939 * update so in that case we must retest all more specific routes.
6940 *
6941 * \see `bgp_route_map_process_update`.
6942 */
6943 aggregate->count = 0;
6944 aggregate->incomplete_origin_count = 0;
6945 aggregate->incomplete_origin_count = 0;
6946 aggregate->egp_origin_count = 0;
6947
6948 /* ORIGIN attribute: If at least one route among routes that are
6949 aggregated has ORIGIN with the value INCOMPLETE, then the
6950 aggregated route must have the ORIGIN attribute with the value
6951 INCOMPLETE. Otherwise, if at least one route among routes that
6952 are aggregated has ORIGIN with the value EGP, then the aggregated
6953 route must have the origin attribute with the value EGP. In all
6954 other case the value of the ORIGIN attribute of the aggregated
6955 route is INTERNAL. */
6956 origin = BGP_ORIGIN_IGP;
6957
6958 table = bgp->rib[afi][safi];
6959
6960 top = bgp_node_get(table, p);
6961 for (dest = bgp_node_get(table, p); dest;
6962 dest = bgp_route_next_until(dest, top)) {
6963 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
6964
6965 if (dest_p->prefixlen <= p->prefixlen)
6966 continue;
6967
6968 /* If suppress fib is enabled and route not installed
6969 * in FIB, skip the route
6970 */
6971 if (!bgp_check_advertise(bgp, dest))
6972 continue;
6973
6974 match = 0;
6975
6976 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6977 if (BGP_PATH_HOLDDOWN(pi))
6978 continue;
6979
6980 if (pi->attr->flag
6981 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
6982 atomic_aggregate = 1;
6983
6984 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6985 continue;
6986
6987 /*
6988 * summary-only aggregate route suppress
6989 * aggregated route announcements.
6990 *
6991 * MED matching:
6992 * Don't create summaries if MED didn't match
6993 * otherwise neither the specific routes and the
6994 * aggregation will be announced.
6995 */
6996 if (aggregate->summary_only
6997 && AGGREGATE_MED_VALID(aggregate)) {
6998 if (aggr_suppress_path(aggregate, pi))
6999 match++;
7000 }
7001
7002 /*
7003 * Suppress more specific routes that match the route
7004 * map results.
7005 *
7006 * MED matching:
7007 * Don't suppress routes if MED matching is enabled and
7008 * it mismatched otherwise we might end up with no
7009 * routes for this path.
7010 */
7011 if (aggregate->suppress_map_name
7012 && AGGREGATE_MED_VALID(aggregate)
7013 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7014 if (aggr_suppress_path(aggregate, pi))
7015 match++;
7016 }
7017
7018 aggregate->count++;
7019
7020 /*
7021 * If at least one route among routes that are
7022 * aggregated has ORIGIN with the value INCOMPLETE,
7023 * then the aggregated route MUST have the ORIGIN
7024 * attribute with the value INCOMPLETE. Otherwise, if
7025 * at least one route among routes that are aggregated
7026 * has ORIGIN with the value EGP, then the aggregated
7027 * route MUST have the ORIGIN attribute with the value
7028 * EGP.
7029 */
7030 switch (pi->attr->origin) {
7031 case BGP_ORIGIN_INCOMPLETE:
7032 aggregate->incomplete_origin_count++;
7033 break;
7034 case BGP_ORIGIN_EGP:
7035 aggregate->egp_origin_count++;
7036 break;
7037 default:
7038 /*Do nothing.
7039 */
7040 break;
7041 }
7042
7043 if (!aggregate->as_set)
7044 continue;
7045
7046 /*
7047 * as-set aggregate route generate origin, as path,
7048 * and community aggregation.
7049 */
7050 /* Compute aggregate route's as-path.
7051 */
7052 bgp_compute_aggregate_aspath_hash(aggregate,
7053 pi->attr->aspath);
7054
7055 /* Compute aggregate route's community.
7056 */
7057 if (pi->attr->community)
7058 bgp_compute_aggregate_community_hash(
7059 aggregate,
7060 pi->attr->community);
7061
7062 /* Compute aggregate route's extended community.
7063 */
7064 if (pi->attr->ecommunity)
7065 bgp_compute_aggregate_ecommunity_hash(
7066 aggregate,
7067 pi->attr->ecommunity);
7068
7069 /* Compute aggregate route's large community.
7070 */
7071 if (pi->attr->lcommunity)
7072 bgp_compute_aggregate_lcommunity_hash(
7073 aggregate,
7074 pi->attr->lcommunity);
7075 }
7076 if (match)
7077 bgp_process(bgp, dest, afi, safi);
7078 }
7079 if (aggregate->as_set) {
7080 bgp_compute_aggregate_aspath_val(aggregate);
7081 bgp_compute_aggregate_community_val(aggregate);
7082 bgp_compute_aggregate_ecommunity_val(aggregate);
7083 bgp_compute_aggregate_lcommunity_val(aggregate);
7084 }
7085
7086
7087 bgp_dest_unlock_node(top);
7088
7089
7090 if (aggregate->incomplete_origin_count > 0)
7091 origin = BGP_ORIGIN_INCOMPLETE;
7092 else if (aggregate->egp_origin_count > 0)
7093 origin = BGP_ORIGIN_EGP;
7094
7095 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7096 origin = aggregate->origin;
7097
7098 if (aggregate->as_set) {
7099 if (aggregate->aspath)
7100 /* Retrieve aggregate route's as-path.
7101 */
7102 aspath = aspath_dup(aggregate->aspath);
7103
7104 if (aggregate->community)
7105 /* Retrieve aggregate route's community.
7106 */
7107 community = community_dup(aggregate->community);
7108
7109 if (aggregate->ecommunity)
7110 /* Retrieve aggregate route's ecommunity.
7111 */
7112 ecommunity = ecommunity_dup(aggregate->ecommunity);
7113
7114 if (aggregate->lcommunity)
7115 /* Retrieve aggregate route's lcommunity.
7116 */
7117 lcommunity = lcommunity_dup(aggregate->lcommunity);
7118 }
7119
7120 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7121 ecommunity, lcommunity, atomic_aggregate,
7122 aggregate);
7123 }
7124
7125 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7126 safi_t safi, struct bgp_aggregate *aggregate)
7127 {
7128 struct bgp_table *table;
7129 struct bgp_dest *top;
7130 struct bgp_dest *dest;
7131 struct bgp_path_info *pi;
7132 unsigned long match;
7133
7134 table = bgp->rib[afi][safi];
7135
7136 /* If routes exists below this node, generate aggregate routes. */
7137 top = bgp_node_get(table, p);
7138 for (dest = bgp_node_get(table, p); dest;
7139 dest = bgp_route_next_until(dest, top)) {
7140 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7141
7142 if (dest_p->prefixlen <= p->prefixlen)
7143 continue;
7144 match = 0;
7145
7146 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7147 if (BGP_PATH_HOLDDOWN(pi))
7148 continue;
7149
7150 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7151 continue;
7152
7153 if (aggregate->summary_only && pi->extra
7154 && AGGREGATE_MED_VALID(aggregate)) {
7155 if (aggr_unsuppress_path(aggregate, pi))
7156 match++;
7157 }
7158
7159 if (aggregate->suppress_map_name
7160 && AGGREGATE_MED_VALID(aggregate)
7161 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7162 if (aggr_unsuppress_path(aggregate, pi))
7163 match++;
7164 }
7165
7166 aggregate->count--;
7167
7168 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7169 aggregate->incomplete_origin_count--;
7170 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7171 aggregate->egp_origin_count--;
7172
7173 if (aggregate->as_set) {
7174 /* Remove as-path from aggregate.
7175 */
7176 bgp_remove_aspath_from_aggregate_hash(
7177 aggregate,
7178 pi->attr->aspath);
7179
7180 if (pi->attr->community)
7181 /* Remove community from aggregate.
7182 */
7183 bgp_remove_comm_from_aggregate_hash(
7184 aggregate,
7185 pi->attr->community);
7186
7187 if (pi->attr->ecommunity)
7188 /* Remove ecommunity from aggregate.
7189 */
7190 bgp_remove_ecomm_from_aggregate_hash(
7191 aggregate,
7192 pi->attr->ecommunity);
7193
7194 if (pi->attr->lcommunity)
7195 /* Remove lcommunity from aggregate.
7196 */
7197 bgp_remove_lcomm_from_aggregate_hash(
7198 aggregate,
7199 pi->attr->lcommunity);
7200 }
7201 }
7202
7203 /* If this node was suppressed, process the change. */
7204 if (match)
7205 bgp_process(bgp, dest, afi, safi);
7206 }
7207 if (aggregate->as_set) {
7208 aspath_free(aggregate->aspath);
7209 aggregate->aspath = NULL;
7210 if (aggregate->community)
7211 community_free(&aggregate->community);
7212 if (aggregate->ecommunity)
7213 ecommunity_free(&aggregate->ecommunity);
7214 if (aggregate->lcommunity)
7215 lcommunity_free(&aggregate->lcommunity);
7216 }
7217
7218 bgp_dest_unlock_node(top);
7219 }
7220
7221 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7222 const struct prefix *aggr_p,
7223 struct bgp_path_info *pinew, afi_t afi,
7224 safi_t safi,
7225 struct bgp_aggregate *aggregate)
7226 {
7227 uint8_t origin;
7228 struct aspath *aspath = NULL;
7229 uint8_t atomic_aggregate = 0;
7230 struct community *community = NULL;
7231 struct ecommunity *ecommunity = NULL;
7232 struct lcommunity *lcommunity = NULL;
7233
7234 /* If the bgp instance is being deleted or self peer is deleted
7235 * then do not create aggregate route
7236 */
7237 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7238 || (bgp->peer_self == NULL))
7239 return;
7240
7241 /* ORIGIN attribute: If at least one route among routes that are
7242 * aggregated has ORIGIN with the value INCOMPLETE, then the
7243 * aggregated route must have the ORIGIN attribute with the value
7244 * INCOMPLETE. Otherwise, if at least one route among routes that
7245 * are aggregated has ORIGIN with the value EGP, then the aggregated
7246 * route must have the origin attribute with the value EGP. In all
7247 * other case the value of the ORIGIN attribute of the aggregated
7248 * route is INTERNAL.
7249 */
7250 origin = BGP_ORIGIN_IGP;
7251
7252 aggregate->count++;
7253
7254 /*
7255 * This must be called before `summary` check to avoid
7256 * "suppressing" twice.
7257 */
7258 if (aggregate->match_med)
7259 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
7260 pinew, true);
7261
7262 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7263 aggr_suppress_path(aggregate, pinew);
7264
7265 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7266 && aggr_suppress_map_test(bgp, aggregate, pinew))
7267 aggr_suppress_path(aggregate, pinew);
7268
7269 switch (pinew->attr->origin) {
7270 case BGP_ORIGIN_INCOMPLETE:
7271 aggregate->incomplete_origin_count++;
7272 break;
7273 case BGP_ORIGIN_EGP:
7274 aggregate->egp_origin_count++;
7275 break;
7276 default:
7277 /* Do nothing.
7278 */
7279 break;
7280 }
7281
7282 if (aggregate->incomplete_origin_count > 0)
7283 origin = BGP_ORIGIN_INCOMPLETE;
7284 else if (aggregate->egp_origin_count > 0)
7285 origin = BGP_ORIGIN_EGP;
7286
7287 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7288 origin = aggregate->origin;
7289
7290 if (aggregate->as_set) {
7291 /* Compute aggregate route's as-path.
7292 */
7293 bgp_compute_aggregate_aspath(aggregate,
7294 pinew->attr->aspath);
7295
7296 /* Compute aggregate route's community.
7297 */
7298 if (pinew->attr->community)
7299 bgp_compute_aggregate_community(
7300 aggregate,
7301 pinew->attr->community);
7302
7303 /* Compute aggregate route's extended community.
7304 */
7305 if (pinew->attr->ecommunity)
7306 bgp_compute_aggregate_ecommunity(
7307 aggregate,
7308 pinew->attr->ecommunity);
7309
7310 /* Compute aggregate route's large community.
7311 */
7312 if (pinew->attr->lcommunity)
7313 bgp_compute_aggregate_lcommunity(
7314 aggregate,
7315 pinew->attr->lcommunity);
7316
7317 /* Retrieve aggregate route's as-path.
7318 */
7319 if (aggregate->aspath)
7320 aspath = aspath_dup(aggregate->aspath);
7321
7322 /* Retrieve aggregate route's community.
7323 */
7324 if (aggregate->community)
7325 community = community_dup(aggregate->community);
7326
7327 /* Retrieve aggregate route's ecommunity.
7328 */
7329 if (aggregate->ecommunity)
7330 ecommunity = ecommunity_dup(aggregate->ecommunity);
7331
7332 /* Retrieve aggregate route's lcommunity.
7333 */
7334 if (aggregate->lcommunity)
7335 lcommunity = lcommunity_dup(aggregate->lcommunity);
7336 }
7337
7338 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
7339 aspath, community, ecommunity,
7340 lcommunity, atomic_aggregate, aggregate);
7341 }
7342
7343 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
7344 safi_t safi,
7345 struct bgp_path_info *pi,
7346 struct bgp_aggregate *aggregate,
7347 const struct prefix *aggr_p)
7348 {
7349 uint8_t origin;
7350 struct aspath *aspath = NULL;
7351 uint8_t atomic_aggregate = 0;
7352 struct community *community = NULL;
7353 struct ecommunity *ecommunity = NULL;
7354 struct lcommunity *lcommunity = NULL;
7355 unsigned long match = 0;
7356
7357 /* If the bgp instance is being deleted or self peer is deleted
7358 * then do not create aggregate route
7359 */
7360 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7361 || (bgp->peer_self == NULL))
7362 return;
7363
7364 if (BGP_PATH_HOLDDOWN(pi))
7365 return;
7366
7367 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7368 return;
7369
7370 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7371 if (aggr_unsuppress_path(aggregate, pi))
7372 match++;
7373
7374 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7375 && aggr_suppress_map_test(bgp, aggregate, pi))
7376 if (aggr_unsuppress_path(aggregate, pi))
7377 match++;
7378
7379 /*
7380 * This must be called after `summary`, `suppress-map` check to avoid
7381 * "unsuppressing" twice.
7382 */
7383 if (aggregate->match_med)
7384 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi,
7385 true);
7386
7387 if (aggregate->count > 0)
7388 aggregate->count--;
7389
7390 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7391 aggregate->incomplete_origin_count--;
7392 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7393 aggregate->egp_origin_count--;
7394
7395 if (aggregate->as_set) {
7396 /* Remove as-path from aggregate.
7397 */
7398 bgp_remove_aspath_from_aggregate(aggregate,
7399 pi->attr->aspath);
7400
7401 if (pi->attr->community)
7402 /* Remove community from aggregate.
7403 */
7404 bgp_remove_community_from_aggregate(
7405 aggregate,
7406 pi->attr->community);
7407
7408 if (pi->attr->ecommunity)
7409 /* Remove ecommunity from aggregate.
7410 */
7411 bgp_remove_ecommunity_from_aggregate(
7412 aggregate,
7413 pi->attr->ecommunity);
7414
7415 if (pi->attr->lcommunity)
7416 /* Remove lcommunity from aggregate.
7417 */
7418 bgp_remove_lcommunity_from_aggregate(
7419 aggregate,
7420 pi->attr->lcommunity);
7421 }
7422
7423 /* If this node was suppressed, process the change. */
7424 if (match)
7425 bgp_process(bgp, pi->net, afi, safi);
7426
7427 origin = BGP_ORIGIN_IGP;
7428 if (aggregate->incomplete_origin_count > 0)
7429 origin = BGP_ORIGIN_INCOMPLETE;
7430 else if (aggregate->egp_origin_count > 0)
7431 origin = BGP_ORIGIN_EGP;
7432
7433 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7434 origin = aggregate->origin;
7435
7436 if (aggregate->as_set) {
7437 /* Retrieve aggregate route's as-path.
7438 */
7439 if (aggregate->aspath)
7440 aspath = aspath_dup(aggregate->aspath);
7441
7442 /* Retrieve aggregate route's community.
7443 */
7444 if (aggregate->community)
7445 community = community_dup(aggregate->community);
7446
7447 /* Retrieve aggregate route's ecommunity.
7448 */
7449 if (aggregate->ecommunity)
7450 ecommunity = ecommunity_dup(aggregate->ecommunity);
7451
7452 /* Retrieve aggregate route's lcommunity.
7453 */
7454 if (aggregate->lcommunity)
7455 lcommunity = lcommunity_dup(aggregate->lcommunity);
7456 }
7457
7458 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
7459 aspath, community, ecommunity,
7460 lcommunity, atomic_aggregate, aggregate);
7461 }
7462
7463 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
7464 struct bgp_path_info *pi, afi_t afi, safi_t safi)
7465 {
7466 struct bgp_dest *child;
7467 struct bgp_dest *dest;
7468 struct bgp_aggregate *aggregate;
7469 struct bgp_table *table;
7470
7471 table = bgp->aggregate[afi][safi];
7472
7473 /* No aggregates configured. */
7474 if (bgp_table_top_nolock(table) == NULL)
7475 return;
7476
7477 if (p->prefixlen == 0)
7478 return;
7479
7480 if (BGP_PATH_HOLDDOWN(pi))
7481 return;
7482
7483 /* If suppress fib is enabled and route not installed
7484 * in FIB, do not update the aggregate route
7485 */
7486 if (!bgp_check_advertise(bgp, pi->net))
7487 return;
7488
7489 child = bgp_node_get(table, p);
7490
7491 /* Aggregate address configuration check. */
7492 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
7493 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7494
7495 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7496 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
7497 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
7498 aggregate);
7499 }
7500 }
7501 bgp_dest_unlock_node(child);
7502 }
7503
7504 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
7505 struct bgp_path_info *del, afi_t afi, safi_t safi)
7506 {
7507 struct bgp_dest *child;
7508 struct bgp_dest *dest;
7509 struct bgp_aggregate *aggregate;
7510 struct bgp_table *table;
7511
7512 table = bgp->aggregate[afi][safi];
7513
7514 /* No aggregates configured. */
7515 if (bgp_table_top_nolock(table) == NULL)
7516 return;
7517
7518 if (p->prefixlen == 0)
7519 return;
7520
7521 child = bgp_node_get(table, p);
7522
7523 /* Aggregate address configuration check. */
7524 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
7525 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7526
7527 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7528 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
7529 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
7530 aggregate, dest_p);
7531 }
7532 }
7533 bgp_dest_unlock_node(child);
7534 }
7535
7536 /* Aggregate route attribute. */
7537 #define AGGREGATE_SUMMARY_ONLY 1
7538 #define AGGREGATE_AS_SET 1
7539 #define AGGREGATE_AS_UNSET 0
7540
7541 static const char *bgp_origin2str(uint8_t origin)
7542 {
7543 switch (origin) {
7544 case BGP_ORIGIN_IGP:
7545 return "igp";
7546 case BGP_ORIGIN_EGP:
7547 return "egp";
7548 case BGP_ORIGIN_INCOMPLETE:
7549 return "incomplete";
7550 }
7551 return "n/a";
7552 }
7553
7554 static const char *bgp_rpki_validation2str(int v_state)
7555 {
7556 switch (v_state) {
7557 case 1:
7558 return "valid";
7559 case 2:
7560 return "not found";
7561 case 3:
7562 return "invalid";
7563 default:
7564 break;
7565 }
7566 return "ERROR";
7567 }
7568
7569 int bgp_aggregate_unset(struct bgp *bgp, struct prefix *prefix, afi_t afi,
7570 safi_t safi, char *errmsg, size_t errmsg_len)
7571 {
7572 struct bgp_dest *dest;
7573 struct bgp_aggregate *aggregate;
7574
7575 /* If the bgp instance is being deleted or self peer is deleted
7576 * then do not create aggregate route
7577 */
7578 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7579 || (bgp->peer_self == NULL))
7580 return 0;
7581
7582 apply_mask(prefix);
7583 /* Old configuration check. */
7584 dest = bgp_node_lookup(bgp->aggregate[afi][safi], prefix);
7585 if (!dest) {
7586 snprintf(errmsg, errmsg_len,
7587 "There is no aggregate-address configuration.\n");
7588 return -1;
7589 }
7590
7591 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7592 bgp_aggregate_delete(bgp, prefix, afi, safi, aggregate);
7593 bgp_aggregate_install(bgp, afi, safi, prefix, 0, NULL, NULL, NULL, NULL,
7594 0, aggregate);
7595
7596 /* Unlock aggregate address configuration. */
7597 bgp_dest_set_bgp_aggregate_info(dest, NULL);
7598
7599 if (aggregate->community)
7600 community_free(&aggregate->community);
7601
7602 if (aggregate->community_hash) {
7603 /* Delete all communities in the hash.
7604 */
7605 hash_clean(aggregate->community_hash,
7606 bgp_aggr_community_remove);
7607 /* Free up the community_hash.
7608 */
7609 hash_free(aggregate->community_hash);
7610 }
7611
7612 if (aggregate->ecommunity)
7613 ecommunity_free(&aggregate->ecommunity);
7614
7615 if (aggregate->ecommunity_hash) {
7616 /* Delete all ecommunities in the hash.
7617 */
7618 hash_clean(aggregate->ecommunity_hash,
7619 bgp_aggr_ecommunity_remove);
7620 /* Free up the ecommunity_hash.
7621 */
7622 hash_free(aggregate->ecommunity_hash);
7623 }
7624
7625 if (aggregate->lcommunity)
7626 lcommunity_free(&aggregate->lcommunity);
7627
7628 if (aggregate->lcommunity_hash) {
7629 /* Delete all lcommunities in the hash.
7630 */
7631 hash_clean(aggregate->lcommunity_hash,
7632 bgp_aggr_lcommunity_remove);
7633 /* Free up the lcommunity_hash.
7634 */
7635 hash_free(aggregate->lcommunity_hash);
7636 }
7637
7638 if (aggregate->aspath)
7639 aspath_free(aggregate->aspath);
7640
7641 if (aggregate->aspath_hash) {
7642 /* Delete all as-paths in the hash.
7643 */
7644 hash_clean(aggregate->aspath_hash,
7645 bgp_aggr_aspath_remove);
7646 /* Free up the aspath_hash.
7647 */
7648 hash_free(aggregate->aspath_hash);
7649 }
7650
7651 bgp_aggregate_free(aggregate);
7652 bgp_dest_unlock_node(dest);
7653 bgp_dest_unlock_node(dest);
7654
7655 return 0;
7656 }
7657
7658 int bgp_aggregate_set(struct bgp *bgp, struct prefix *prefix, afi_t afi,
7659 safi_t safi, const char *rmap, uint8_t summary_only,
7660 uint8_t as_set, uint8_t origin, bool match_med,
7661 const char *suppress_map,
7662 char *errmsg, size_t errmsg_len)
7663 {
7664 int ret;
7665 struct bgp_dest *dest;
7666 struct bgp_aggregate *aggregate;
7667 uint8_t as_set_new = as_set;
7668 char buf[PREFIX2STR_BUFFER];
7669
7670 if (suppress_map && summary_only) {
7671 snprintf(errmsg, errmsg_len,
7672 "'summary-only' and 'suppress-map' can't be used at the same time\n");
7673 return -1;
7674 }
7675
7676 apply_mask(prefix);
7677
7678 if ((afi == AFI_IP && prefix->prefixlen == IPV4_MAX_BITLEN)
7679 || (afi == AFI_IP6 && prefix->prefixlen == IPV6_MAX_BITLEN)) {
7680 snprintf(
7681 errmsg, errmsg_len,
7682 "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
7683 prefix2str(prefix, buf, PREFIX_STRLEN));
7684 return -1;
7685 }
7686
7687 /* Old configuration check. */
7688 dest = bgp_node_get(bgp->aggregate[afi][safi], prefix);
7689 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7690
7691 if (aggregate) {
7692 snprintf(errmsg, errmsg_len,
7693 "There is already same aggregate network.\n");
7694 /* try to remove the old entry */
7695 ret = bgp_aggregate_unset(bgp, prefix, afi, safi, errmsg,
7696 errmsg_len);
7697 if (ret) {
7698 snprintf(errmsg, errmsg_len,
7699 "Error deleting aggregate.\n");
7700 bgp_dest_unlock_node(dest);
7701 return -1;
7702 }
7703 }
7704
7705 /* Make aggregate address structure. */
7706 aggregate = bgp_aggregate_new();
7707 aggregate->summary_only = summary_only;
7708 aggregate->match_med = match_med;
7709
7710 /* Network operators MUST NOT locally generate any new
7711 * announcements containing AS_SET or AS_CONFED_SET. If they have
7712 * announced routes with AS_SET or AS_CONFED_SET in them, then they
7713 * SHOULD withdraw those routes and re-announce routes for the
7714 * aggregate or component prefixes (i.e., the more-specific routes
7715 * subsumed by the previously aggregated route) without AS_SET
7716 * or AS_CONFED_SET in the updates.
7717 */
7718 if (bgp->reject_as_sets) {
7719 if (as_set == AGGREGATE_AS_SET) {
7720 as_set_new = AGGREGATE_AS_UNSET;
7721 zlog_warn(
7722 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
7723 __func__);
7724 snprintf(
7725 errmsg, errmsg_len,
7726 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
7727 }
7728 }
7729
7730 aggregate->as_set = as_set_new;
7731 aggregate->safi = safi;
7732 /* Override ORIGIN attribute if defined.
7733 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
7734 * to IGP which is not what rfc4271 says.
7735 * This enables the same behavior, optionally.
7736 */
7737 aggregate->origin = origin;
7738
7739 if (rmap) {
7740 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7741 route_map_counter_decrement(aggregate->rmap.map);
7742 aggregate->rmap.name =
7743 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
7744 aggregate->rmap.map = route_map_lookup_by_name(rmap);
7745 route_map_counter_increment(aggregate->rmap.map);
7746 }
7747
7748 if (suppress_map) {
7749 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7750 route_map_counter_decrement(aggregate->suppress_map);
7751
7752 aggregate->suppress_map_name =
7753 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
7754 aggregate->suppress_map =
7755 route_map_lookup_by_name(aggregate->suppress_map_name);
7756 route_map_counter_increment(aggregate->suppress_map);
7757 }
7758
7759 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
7760
7761 /* Aggregate address insert into BGP routing table. */
7762 bgp_aggregate_route(bgp, prefix, afi, safi, aggregate);
7763
7764 return 0;
7765 }
7766
7767 DEFPY_YANG(
7768 aggregate_addressv4, aggregate_addressv4_cmd,
7769 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> {"
7770 "as-set$as_set_s"
7771 "|summary-only$summary_only"
7772 "|route-map WORD$rmap_name"
7773 "|origin <egp|igp|incomplete>$origin_s"
7774 "|matching-MED-only$match_med"
7775 "|suppress-map WORD$suppress_map"
7776 "}",
7777 NO_STR
7778 "Configure BGP aggregate entries\n"
7779 "Aggregate prefix\n"
7780 "Aggregate address\n"
7781 "Aggregate mask\n"
7782 "Generate AS set path information\n"
7783 "Filter more specific routes from updates\n"
7784 "Apply route map to aggregate network\n"
7785 "Route map name\n"
7786 "BGP origin code\n"
7787 "Remote EGP\n"
7788 "Local IGP\n"
7789 "Unknown heritage\n"
7790 "Only aggregate routes with matching MED\n"
7791 "Suppress the selected more specific routes\n"
7792 "Route map with the route selectors\n")
7793 {
7794 char base_xpath[XPATH_MAXLEN];
7795 safi_t safi = bgp_node_safi(vty);
7796 char prefix_buf[PREFIX2STR_BUFFER];
7797
7798 if (addr_str) {
7799 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
7800 sizeof(prefix_buf))
7801 == 0) {
7802 vty_out(vty, "%% Inconsistent address and mask\n");
7803 return CMD_WARNING_CONFIG_FAILED;
7804 }
7805 } else {
7806 strlcpy(prefix_buf, prefix_str, sizeof(prefix_buf));
7807 }
7808
7809 if (!no && origin_s)
7810 nb_cli_enqueue_change(vty, "./origin", NB_OP_MODIFY, origin_s);
7811
7812 if (!no && as_set_s)
7813 nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "true");
7814 else
7815 nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "false");
7816
7817 if (!no && summary_only)
7818 nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
7819 "true");
7820 else
7821 nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
7822 "false");
7823
7824 if (!no && match_med)
7825 nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, "true");
7826 else
7827 nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY,
7828 "false");
7829
7830 if (rmap_name)
7831 nb_cli_enqueue_change(vty, "./rmap-policy-export", NB_OP_MODIFY,
7832 rmap_name);
7833 else
7834 nb_cli_enqueue_change(vty, "./rmap-policy-export",
7835 NB_OP_DESTROY, NULL);
7836
7837 if (suppress_map)
7838 nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_MODIFY,
7839 suppress_map);
7840 else
7841 nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_DESTROY,
7842 NULL);
7843
7844 snprintf(
7845 base_xpath, sizeof(base_xpath),
7846 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/aggregate-route[prefix='%s']",
7847 yang_afi_safi_value2identity(AFI_IP, safi),
7848 bgp_afi_safi_get_container_str(AFI_IP, safi), prefix_buf);
7849
7850 if (no)
7851 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
7852 else
7853 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
7854
7855 return nb_cli_apply_changes(vty, base_xpath);
7856 }
7857
7858 DEFPY_YANG(aggregate_addressv6, aggregate_addressv6_cmd,
7859 "[no] aggregate-address X:X::X:X/M$prefix {"
7860 "as-set$as_set_s"
7861 "|summary-only$summary_only"
7862 "|route-map WORD$rmap_name"
7863 "|origin <egp|igp|incomplete>$origin_s"
7864 "|matching-MED-only$match_med"
7865 "|suppress-map WORD$suppress_map"
7866 "}",
7867 NO_STR
7868 "Configure BGP aggregate entries\n"
7869 "Aggregate prefix\n"
7870 "Generate AS set path information\n"
7871 "Filter more specific routes from updates\n"
7872 "Apply route map to aggregate network\n"
7873 "Route map name\n"
7874 "BGP origin code\n"
7875 "Remote EGP\n"
7876 "Local IGP\n"
7877 "Unknown heritage\n"
7878 "Only aggregate routes with matching MED\n"
7879 "Suppress the selected more specific routes\n"
7880 "Route map with the route selectors\n")
7881 {
7882 char base_xpath[XPATH_MAXLEN];
7883 safi_t safi = bgp_node_safi(vty);
7884
7885 if (!no && origin_s)
7886 nb_cli_enqueue_change(vty, "./origin", NB_OP_MODIFY, origin_s);
7887
7888 if (!no && as_set_s)
7889 nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "true");
7890 else
7891 nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "false");
7892
7893 if (!no && summary_only)
7894 nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
7895 "true");
7896 else
7897 nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
7898 "false");
7899
7900 if (!no && match_med)
7901 nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, "true");
7902 else
7903 nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY,
7904 "false");
7905
7906 if (rmap_name)
7907 nb_cli_enqueue_change(vty, "./rmap-policy-export", NB_OP_MODIFY,
7908 rmap_name);
7909
7910 if (suppress_map)
7911 nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_MODIFY,
7912 suppress_map);
7913 else
7914 nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_DESTROY,
7915 NULL);
7916
7917 snprintf(
7918 base_xpath, sizeof(base_xpath),
7919 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/aggregate-route[prefix='%s']",
7920 yang_afi_safi_value2identity(AFI_IP6, safi),
7921 bgp_afi_safi_get_container_str(AFI_IP6, safi), prefix_str);
7922
7923 if (no)
7924 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
7925 else
7926 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
7927
7928 return nb_cli_apply_changes(vty, base_xpath);
7929 }
7930
7931 void cli_show_bgp_global_afi_safi_unicast_aggregate_route(
7932 struct vty *vty, struct lyd_node *dnode, bool show_defaults)
7933 {
7934 uint8_t origin;
7935
7936 vty_out(vty, " aggregate-address %s",
7937 yang_dnode_get_string(dnode, "./prefix"));
7938
7939 if (yang_dnode_get_bool(dnode, "./as-set"))
7940 vty_out(vty, " as-set");
7941
7942 if (yang_dnode_get_bool(dnode, "./summary-only"))
7943 vty_out(vty, " summary-only");
7944
7945 if (yang_dnode_exists(dnode, "./rmap-policy-export"))
7946 vty_out(vty, " route-map %s",
7947 yang_dnode_get_string(dnode, "./rmap-policy-export"));
7948
7949 origin = yang_dnode_get_enum(dnode, "./origin");
7950 if (origin != BGP_ORIGIN_UNSPECIFIED)
7951 vty_out(vty, " origin %s", bgp_origin2str(origin));
7952
7953 if (yang_dnode_get_bool(dnode, "./match-med"))
7954 vty_out(vty, " matching-MED-only");
7955
7956 vty_out(vty, "\n");
7957 }
7958
7959 /* Redistribute route treatment. */
7960 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
7961 const union g_addr *nexthop, ifindex_t ifindex,
7962 enum nexthop_types_t nhtype, uint32_t metric,
7963 uint8_t type, unsigned short instance,
7964 route_tag_t tag)
7965 {
7966 struct bgp_path_info *new;
7967 struct bgp_path_info *bpi;
7968 struct bgp_path_info rmap_path;
7969 struct bgp_dest *bn;
7970 struct attr attr;
7971 struct attr *new_attr;
7972 afi_t afi;
7973 route_map_result_t ret;
7974 struct bgp_redist *red;
7975
7976 /* Make default attribute. */
7977 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
7978 /*
7979 * This must not be NULL to satisfy Coverity SA
7980 */
7981 assert(attr.aspath);
7982
7983 switch (nhtype) {
7984 case NEXTHOP_TYPE_IFINDEX:
7985 break;
7986 case NEXTHOP_TYPE_IPV4:
7987 case NEXTHOP_TYPE_IPV4_IFINDEX:
7988 attr.nexthop = nexthop->ipv4;
7989 break;
7990 case NEXTHOP_TYPE_IPV6:
7991 case NEXTHOP_TYPE_IPV6_IFINDEX:
7992 attr.mp_nexthop_global = nexthop->ipv6;
7993 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
7994 break;
7995 case NEXTHOP_TYPE_BLACKHOLE:
7996 switch (p->family) {
7997 case AF_INET:
7998 attr.nexthop.s_addr = INADDR_ANY;
7999 break;
8000 case AF_INET6:
8001 memset(&attr.mp_nexthop_global, 0,
8002 sizeof(attr.mp_nexthop_global));
8003 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8004 break;
8005 }
8006 break;
8007 }
8008 attr.nh_ifindex = ifindex;
8009
8010 attr.med = metric;
8011 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8012 attr.tag = tag;
8013
8014 afi = family2afi(p->family);
8015
8016 red = bgp_redist_lookup(bgp, afi, type, instance);
8017 if (red) {
8018 struct attr attr_new;
8019
8020 /* Copy attribute for modification. */
8021 attr_new = attr;
8022
8023 if (red->redist_metric_flag)
8024 attr_new.med = red->redist_metric;
8025
8026 /* Apply route-map. */
8027 if (red->rmap.name) {
8028 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
8029 rmap_path.peer = bgp->peer_self;
8030 rmap_path.attr = &attr_new;
8031
8032 SET_FLAG(bgp->peer_self->rmap_type,
8033 PEER_RMAP_TYPE_REDISTRIBUTE);
8034
8035 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8036
8037 bgp->peer_self->rmap_type = 0;
8038
8039 if (ret == RMAP_DENYMATCH) {
8040 /* Free uninterned attribute. */
8041 bgp_attr_flush(&attr_new);
8042
8043 /* Unintern original. */
8044 aspath_unintern(&attr.aspath);
8045 bgp_redistribute_delete(bgp, p, type, instance);
8046 return;
8047 }
8048 }
8049
8050 if (bgp_in_graceful_shutdown(bgp))
8051 bgp_attr_add_gshut_community(&attr_new);
8052
8053 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8054 SAFI_UNICAST, p, NULL);
8055
8056 new_attr = bgp_attr_intern(&attr_new);
8057
8058 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8059 if (bpi->peer == bgp->peer_self
8060 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8061 break;
8062
8063 if (bpi) {
8064 /* Ensure the (source route) type is updated. */
8065 bpi->type = type;
8066 if (attrhash_cmp(bpi->attr, new_attr)
8067 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8068 bgp_attr_unintern(&new_attr);
8069 aspath_unintern(&attr.aspath);
8070 bgp_dest_unlock_node(bn);
8071 return;
8072 } else {
8073 /* The attribute is changed. */
8074 bgp_path_info_set_flag(bn, bpi,
8075 BGP_PATH_ATTR_CHANGED);
8076
8077 /* Rewrite BGP route information. */
8078 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8079 bgp_path_info_restore(bn, bpi);
8080 else
8081 bgp_aggregate_decrement(
8082 bgp, p, bpi, afi, SAFI_UNICAST);
8083 bgp_attr_unintern(&bpi->attr);
8084 bpi->attr = new_attr;
8085 bpi->uptime = bgp_clock();
8086
8087 /* Process change. */
8088 bgp_aggregate_increment(bgp, p, bpi, afi,
8089 SAFI_UNICAST);
8090 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8091 bgp_dest_unlock_node(bn);
8092 aspath_unintern(&attr.aspath);
8093
8094 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8095 || (bgp->inst_type
8096 == BGP_INSTANCE_TYPE_DEFAULT)) {
8097
8098 vpn_leak_from_vrf_update(
8099 bgp_get_default(), bgp, bpi);
8100 }
8101 return;
8102 }
8103 }
8104
8105 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8106 bgp->peer_self, new_attr, bn);
8107 SET_FLAG(new->flags, BGP_PATH_VALID);
8108
8109 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8110 bgp_path_info_add(bn, new);
8111 bgp_dest_unlock_node(bn);
8112 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8113
8114 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8115 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8116
8117 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8118 }
8119 }
8120
8121 /* Unintern original. */
8122 aspath_unintern(&attr.aspath);
8123 }
8124
8125 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8126 unsigned short instance)
8127 {
8128 afi_t afi;
8129 struct bgp_dest *dest;
8130 struct bgp_path_info *pi;
8131 struct bgp_redist *red;
8132
8133 afi = family2afi(p->family);
8134
8135 red = bgp_redist_lookup(bgp, afi, type, instance);
8136 if (red) {
8137 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8138 SAFI_UNICAST, p, NULL);
8139
8140 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8141 if (pi->peer == bgp->peer_self && pi->type == type)
8142 break;
8143
8144 if (pi) {
8145 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8146 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8147
8148 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8149 bgp, pi);
8150 }
8151 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8152 bgp_path_info_delete(dest, pi);
8153 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8154 }
8155 bgp_dest_unlock_node(dest);
8156 }
8157 }
8158
8159 /* Withdraw specified route type's route. */
8160 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8161 unsigned short instance)
8162 {
8163 struct bgp_dest *dest;
8164 struct bgp_path_info *pi;
8165 struct bgp_table *table;
8166
8167 table = bgp->rib[afi][SAFI_UNICAST];
8168
8169 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8170 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8171 if (pi->peer == bgp->peer_self && pi->type == type
8172 && pi->instance == instance)
8173 break;
8174
8175 if (pi) {
8176 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8177 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8178
8179 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8180 bgp, pi);
8181 }
8182 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8183 pi, afi, SAFI_UNICAST);
8184 bgp_path_info_delete(dest, pi);
8185 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8186 }
8187 }
8188 }
8189
8190 /* Static function to display route. */
8191 static void route_vty_out_route(const struct prefix *p, struct vty *vty,
8192 json_object *json, bool wide)
8193 {
8194 int len = 0;
8195 char buf[BUFSIZ];
8196 char buf2[BUFSIZ];
8197
8198 if (p->family == AF_INET) {
8199 if (!json) {
8200 len = vty_out(vty, "%pFX", p);
8201 } else {
8202 json_object_string_add(json, "prefix",
8203 inet_ntop(p->family,
8204 &p->u.prefix, buf,
8205 BUFSIZ));
8206 json_object_int_add(json, "prefixLen", p->prefixlen);
8207 prefix2str(p, buf2, PREFIX_STRLEN);
8208 json_object_string_add(json, "network", buf2);
8209 }
8210 } else if (p->family == AF_ETHERNET) {
8211 len = vty_out(vty, "%pFX", p);
8212 } else if (p->family == AF_EVPN) {
8213 if (!json)
8214 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8215 else
8216 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8217 } else if (p->family == AF_FLOWSPEC) {
8218 route_vty_out_flowspec(vty, p, NULL,
8219 json ?
8220 NLRI_STRING_FORMAT_JSON_SIMPLE :
8221 NLRI_STRING_FORMAT_MIN, json);
8222 } else {
8223 if (!json)
8224 len = vty_out(vty, "%pFX", p);
8225 else {
8226 json_object_string_add(json, "prefix",
8227 inet_ntop(p->family,
8228 &p->u.prefix, buf,
8229 BUFSIZ));
8230 json_object_int_add(json, "prefixLen", p->prefixlen);
8231 prefix2str(p, buf2, PREFIX_STRLEN);
8232 json_object_string_add(json, "network", buf2);
8233 }
8234 }
8235
8236 if (!json) {
8237 len = wide ? (45 - len) : (17 - len);
8238 if (len < 1)
8239 vty_out(vty, "\n%*s", 20, " ");
8240 else
8241 vty_out(vty, "%*s", len, " ");
8242 }
8243 }
8244
8245 enum bgp_display_type {
8246 normal_list,
8247 };
8248
8249 static const char *
8250 bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8251 {
8252 switch (reason) {
8253 case bgp_path_selection_none:
8254 return "Nothing to Select";
8255 case bgp_path_selection_first:
8256 return "First path received";
8257 case bgp_path_selection_evpn_sticky_mac:
8258 return "EVPN Sticky Mac";
8259 case bgp_path_selection_evpn_seq:
8260 return "EVPN sequence number";
8261 case bgp_path_selection_evpn_lower_ip:
8262 return "EVPN lower IP";
8263 case bgp_path_selection_evpn_local_path:
8264 return "EVPN local ES path";
8265 case bgp_path_selection_evpn_non_proxy:
8266 return "EVPN non proxy";
8267 case bgp_path_selection_weight:
8268 return "Weight";
8269 case bgp_path_selection_local_pref:
8270 return "Local Pref";
8271 case bgp_path_selection_local_route:
8272 return "Local Route";
8273 case bgp_path_selection_confed_as_path:
8274 return "Confederation based AS Path";
8275 case bgp_path_selection_as_path:
8276 return "AS Path";
8277 case bgp_path_selection_origin:
8278 return "Origin";
8279 case bgp_path_selection_med:
8280 return "MED";
8281 case bgp_path_selection_peer:
8282 return "Peer Type";
8283 case bgp_path_selection_confed:
8284 return "Confed Peer Type";
8285 case bgp_path_selection_igp_metric:
8286 return "IGP Metric";
8287 case bgp_path_selection_older:
8288 return "Older Path";
8289 case bgp_path_selection_router_id:
8290 return "Router ID";
8291 case bgp_path_selection_cluster_length:
8292 return "Cluster length";
8293 case bgp_path_selection_stale:
8294 return "Path Staleness";
8295 case bgp_path_selection_local_configured:
8296 return "Locally configured route";
8297 case bgp_path_selection_neighbor_ip:
8298 return "Neighbor IP";
8299 case bgp_path_selection_default:
8300 return "Nothing left to compare";
8301 }
8302 return "Invalid (internal error)";
8303 }
8304
8305 /* Print the short form route status for a bgp_path_info */
8306 static void route_vty_short_status_out(struct vty *vty,
8307 struct bgp_path_info *path,
8308 json_object *json_path)
8309 {
8310 if (json_path) {
8311
8312 /* Route status display. */
8313 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8314 json_object_boolean_true_add(json_path, "removed");
8315
8316 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8317 json_object_boolean_true_add(json_path, "stale");
8318
8319 if (path->extra && bgp_path_suppressed(path))
8320 json_object_boolean_true_add(json_path, "suppressed");
8321
8322 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8323 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8324 json_object_boolean_true_add(json_path, "valid");
8325
8326 /* Selected */
8327 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8328 json_object_boolean_true_add(json_path, "history");
8329
8330 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8331 json_object_boolean_true_add(json_path, "damped");
8332
8333 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
8334 json_object_boolean_true_add(json_path, "bestpath");
8335 json_object_string_add(json_path, "selectionReason",
8336 bgp_path_selection_reason2str(
8337 path->net->reason));
8338 }
8339
8340 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8341 json_object_boolean_true_add(json_path, "multipath");
8342
8343 /* Internal route. */
8344 if ((path->peer->as)
8345 && (path->peer->as == path->peer->local_as))
8346 json_object_string_add(json_path, "pathFrom",
8347 "internal");
8348 else
8349 json_object_string_add(json_path, "pathFrom",
8350 "external");
8351
8352 return;
8353 }
8354
8355 /* Route status display. */
8356 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8357 vty_out(vty, "R");
8358 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8359 vty_out(vty, "S");
8360 else if (bgp_path_suppressed(path))
8361 vty_out(vty, "s");
8362 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8363 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8364 vty_out(vty, "*");
8365 else
8366 vty_out(vty, " ");
8367
8368 /* Selected */
8369 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8370 vty_out(vty, "h");
8371 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8372 vty_out(vty, "d");
8373 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
8374 vty_out(vty, ">");
8375 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8376 vty_out(vty, "=");
8377 else
8378 vty_out(vty, " ");
8379
8380 /* Internal route. */
8381 if (path->peer && (path->peer->as)
8382 && (path->peer->as == path->peer->local_as))
8383 vty_out(vty, "i");
8384 else
8385 vty_out(vty, " ");
8386 }
8387
8388 static char *bgp_nexthop_hostname(struct peer *peer,
8389 struct bgp_nexthop_cache *bnc)
8390 {
8391 if (peer->hostname
8392 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
8393 return peer->hostname;
8394 return NULL;
8395 }
8396
8397 /* called from terminal list command */
8398 void route_vty_out(struct vty *vty, const struct prefix *p,
8399 struct bgp_path_info *path, int display, safi_t safi,
8400 json_object *json_paths, bool wide)
8401 {
8402 int len;
8403 struct attr *attr = path->attr;
8404 json_object *json_path = NULL;
8405 json_object *json_nexthops = NULL;
8406 json_object *json_nexthop_global = NULL;
8407 json_object *json_nexthop_ll = NULL;
8408 json_object *json_ext_community = NULL;
8409 char vrf_id_str[VRF_NAMSIZ] = {0};
8410 bool nexthop_self =
8411 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8412 bool nexthop_othervrf = false;
8413 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
8414 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
8415 char *nexthop_hostname =
8416 bgp_nexthop_hostname(path->peer, path->nexthop);
8417 char esi_buf[ESI_STR_LEN];
8418
8419 if (json_paths)
8420 json_path = json_object_new_object();
8421
8422 /* short status lead text */
8423 route_vty_short_status_out(vty, path, json_path);
8424
8425 if (!json_paths) {
8426 /* print prefix and mask */
8427 if (!display)
8428 route_vty_out_route(p, vty, json_path, wide);
8429 else
8430 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
8431 } else {
8432 route_vty_out_route(p, vty, json_path, wide);
8433 }
8434
8435 /*
8436 * If vrf id of nexthop is different from that of prefix,
8437 * set up printable string to append
8438 */
8439 if (path->extra && path->extra->bgp_orig) {
8440 const char *self = "";
8441
8442 if (nexthop_self)
8443 self = "<";
8444
8445 nexthop_othervrf = true;
8446 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
8447
8448 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
8449 snprintf(vrf_id_str, sizeof(vrf_id_str),
8450 "@%s%s", VRFID_NONE_STR, self);
8451 else
8452 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
8453 path->extra->bgp_orig->vrf_id, self);
8454
8455 if (path->extra->bgp_orig->inst_type
8456 != BGP_INSTANCE_TYPE_DEFAULT)
8457
8458 nexthop_vrfname = path->extra->bgp_orig->name;
8459 } else {
8460 const char *self = "";
8461
8462 if (nexthop_self)
8463 self = "<";
8464
8465 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
8466 }
8467
8468 /*
8469 * For ENCAP and EVPN routes, nexthop address family is not
8470 * neccessarily the same as the prefix address family.
8471 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
8472 * EVPN routes are also exchanged with a MP nexthop. Currently,
8473 * this
8474 * is only IPv4, the value will be present in either
8475 * attr->nexthop or
8476 * attr->mp_nexthop_global_in
8477 */
8478 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
8479 char buf[BUFSIZ];
8480 char nexthop[128];
8481 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
8482
8483 switch (af) {
8484 case AF_INET:
8485 snprintf(nexthop, sizeof(nexthop), "%s",
8486 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
8487 BUFSIZ));
8488 break;
8489 case AF_INET6:
8490 snprintf(nexthop, sizeof(nexthop), "%s",
8491 inet_ntop(af, &attr->mp_nexthop_global, buf,
8492 BUFSIZ));
8493 break;
8494 default:
8495 snprintf(nexthop, sizeof(nexthop), "?");
8496 break;
8497 }
8498
8499 if (json_paths) {
8500 json_nexthop_global = json_object_new_object();
8501
8502 json_object_string_add(json_nexthop_global, "ip",
8503 nexthop);
8504
8505 if (path->peer->hostname)
8506 json_object_string_add(json_nexthop_global,
8507 "hostname",
8508 path->peer->hostname);
8509
8510 json_object_string_add(json_nexthop_global, "afi",
8511 (af == AF_INET) ? "ipv4"
8512 : "ipv6");
8513 json_object_boolean_true_add(json_nexthop_global,
8514 "used");
8515 } else {
8516 if (nexthop_hostname)
8517 len = vty_out(vty, "%s(%s)%s", nexthop,
8518 nexthop_hostname, vrf_id_str);
8519 else
8520 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
8521
8522 len = wide ? (41 - len) : (16 - len);
8523 if (len < 1)
8524 vty_out(vty, "\n%*s", 36, " ");
8525 else
8526 vty_out(vty, "%*s", len, " ");
8527 }
8528 } else if (safi == SAFI_EVPN) {
8529 if (json_paths) {
8530 char buf[BUFSIZ] = {0};
8531
8532 json_nexthop_global = json_object_new_object();
8533
8534 json_object_string_add(json_nexthop_global, "ip",
8535 inet_ntop(AF_INET,
8536 &attr->nexthop, buf,
8537 sizeof(buf)));
8538
8539 if (path->peer->hostname)
8540 json_object_string_add(json_nexthop_global,
8541 "hostname",
8542 path->peer->hostname);
8543
8544 json_object_string_add(json_nexthop_global, "afi",
8545 "ipv4");
8546 json_object_boolean_true_add(json_nexthop_global,
8547 "used");
8548 } else {
8549 if (nexthop_hostname)
8550 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
8551 nexthop_hostname, vrf_id_str);
8552 else
8553 len = vty_out(vty, "%pI4%s", &attr->nexthop,
8554 vrf_id_str);
8555
8556 len = wide ? (41 - len) : (16 - len);
8557 if (len < 1)
8558 vty_out(vty, "\n%*s", 36, " ");
8559 else
8560 vty_out(vty, "%*s", len, " ");
8561 }
8562 } else if (safi == SAFI_FLOWSPEC) {
8563 if (attr->nexthop.s_addr != INADDR_ANY) {
8564 if (json_paths) {
8565 char buf[BUFSIZ] = {0};
8566
8567 json_nexthop_global = json_object_new_object();
8568
8569 json_object_string_add(json_nexthop_global,
8570 "afi", "ipv4");
8571 json_object_string_add(
8572 json_nexthop_global, "ip",
8573 inet_ntop(AF_INET, &attr->nexthop, buf,
8574 sizeof(buf)));
8575
8576 if (path->peer->hostname)
8577 json_object_string_add(
8578 json_nexthop_global, "hostname",
8579 path->peer->hostname);
8580
8581 json_object_boolean_true_add(
8582 json_nexthop_global,
8583 "used");
8584 } else {
8585 if (nexthop_hostname)
8586 len = vty_out(vty, "%pI4(%s)%s",
8587 &attr->nexthop,
8588 nexthop_hostname,
8589 vrf_id_str);
8590 else
8591 len = vty_out(vty, "%pI4%s",
8592 &attr->nexthop,
8593 vrf_id_str);
8594
8595 len = wide ? (41 - len) : (16 - len);
8596 if (len < 1)
8597 vty_out(vty, "\n%*s", 36, " ");
8598 else
8599 vty_out(vty, "%*s", len, " ");
8600 }
8601 }
8602 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8603 if (json_paths) {
8604 char buf[BUFSIZ] = {0};
8605
8606 json_nexthop_global = json_object_new_object();
8607
8608 json_object_string_add(json_nexthop_global, "ip",
8609 inet_ntop(AF_INET,
8610 &attr->nexthop, buf,
8611 sizeof(buf)));
8612
8613 if (path->peer->hostname)
8614 json_object_string_add(json_nexthop_global,
8615 "hostname",
8616 path->peer->hostname);
8617
8618 json_object_string_add(json_nexthop_global, "afi",
8619 "ipv4");
8620 json_object_boolean_true_add(json_nexthop_global,
8621 "used");
8622 } else {
8623 if (nexthop_hostname)
8624 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
8625 nexthop_hostname, vrf_id_str);
8626 else
8627 len = vty_out(vty, "%pI4%s", &attr->nexthop,
8628 vrf_id_str);
8629
8630 len = wide ? (41 - len) : (16 - len);
8631 if (len < 1)
8632 vty_out(vty, "\n%*s", 36, " ");
8633 else
8634 vty_out(vty, "%*s", len, " ");
8635 }
8636 }
8637
8638 /* IPv6 Next Hop */
8639 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8640 char buf[BUFSIZ];
8641
8642 if (json_paths) {
8643 json_nexthop_global = json_object_new_object();
8644 json_object_string_add(
8645 json_nexthop_global, "ip",
8646 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
8647 buf, BUFSIZ));
8648
8649 if (path->peer->hostname)
8650 json_object_string_add(json_nexthop_global,
8651 "hostname",
8652 path->peer->hostname);
8653
8654 json_object_string_add(json_nexthop_global, "afi",
8655 "ipv6");
8656 json_object_string_add(json_nexthop_global, "scope",
8657 "global");
8658
8659 /* We display both LL & GL if both have been
8660 * received */
8661 if ((attr->mp_nexthop_len
8662 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
8663 || (path->peer->conf_if)) {
8664 json_nexthop_ll = json_object_new_object();
8665 json_object_string_add(
8666 json_nexthop_ll, "ip",
8667 inet_ntop(AF_INET6,
8668 &attr->mp_nexthop_local, buf,
8669 BUFSIZ));
8670
8671 if (path->peer->hostname)
8672 json_object_string_add(
8673 json_nexthop_ll, "hostname",
8674 path->peer->hostname);
8675
8676 json_object_string_add(json_nexthop_ll, "afi",
8677 "ipv6");
8678 json_object_string_add(json_nexthop_ll, "scope",
8679 "link-local");
8680
8681 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
8682 &attr->mp_nexthop_local)
8683 != 0)
8684 && !attr->mp_nexthop_prefer_global)
8685 json_object_boolean_true_add(
8686 json_nexthop_ll, "used");
8687 else
8688 json_object_boolean_true_add(
8689 json_nexthop_global, "used");
8690 } else
8691 json_object_boolean_true_add(
8692 json_nexthop_global, "used");
8693 } else {
8694 /* Display LL if LL/Global both in table unless
8695 * prefer-global is set */
8696 if (((attr->mp_nexthop_len
8697 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
8698 && !attr->mp_nexthop_prefer_global)
8699 || (path->peer->conf_if)) {
8700 if (path->peer->conf_if) {
8701 len = vty_out(vty, "%s",
8702 path->peer->conf_if);
8703 /* len of IPv6 addr + max len of def
8704 * ifname */
8705 len = wide ? (41 - len) : (16 - len);
8706
8707 if (len < 1)
8708 vty_out(vty, "\n%*s", 36, " ");
8709 else
8710 vty_out(vty, "%*s", len, " ");
8711 } else {
8712 if (nexthop_hostname)
8713 len = vty_out(
8714 vty, "%pI6(%s)%s",
8715 &attr->mp_nexthop_local,
8716 nexthop_hostname,
8717 vrf_id_str);
8718 else
8719 len = vty_out(
8720 vty, "%pI6%s",
8721 &attr->mp_nexthop_local,
8722 vrf_id_str);
8723
8724 len = wide ? (41 - len) : (16 - len);
8725
8726 if (len < 1)
8727 vty_out(vty, "\n%*s", 36, " ");
8728 else
8729 vty_out(vty, "%*s", len, " ");
8730 }
8731 } else {
8732 if (nexthop_hostname)
8733 len = vty_out(vty, "%pI6(%s)%s",
8734 &attr->mp_nexthop_global,
8735 nexthop_hostname,
8736 vrf_id_str);
8737 else
8738 len = vty_out(vty, "%pI6%s",
8739 &attr->mp_nexthop_global,
8740 vrf_id_str);
8741
8742 len = wide ? (41 - len) : (16 - len);
8743
8744 if (len < 1)
8745 vty_out(vty, "\n%*s", 36, " ");
8746 else
8747 vty_out(vty, "%*s", len, " ");
8748 }
8749 }
8750 }
8751
8752 /* MED/Metric */
8753 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
8754 if (json_paths)
8755 json_object_int_add(json_path, "metric", attr->med);
8756 else if (wide)
8757 vty_out(vty, "%7u", attr->med);
8758 else
8759 vty_out(vty, "%10u", attr->med);
8760 else if (!json_paths) {
8761 if (wide)
8762 vty_out(vty, "%*s", 7, " ");
8763 else
8764 vty_out(vty, "%*s", 10, " ");
8765 }
8766
8767 /* Local Pref */
8768 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
8769 if (json_paths)
8770 json_object_int_add(json_path, "locPrf",
8771 attr->local_pref);
8772 else
8773 vty_out(vty, "%7u", attr->local_pref);
8774 else if (!json_paths)
8775 vty_out(vty, " ");
8776
8777 if (json_paths)
8778 json_object_int_add(json_path, "weight", attr->weight);
8779 else
8780 vty_out(vty, "%7u ", attr->weight);
8781
8782 if (json_paths) {
8783 char buf[BUFSIZ];
8784 json_object_string_add(
8785 json_path, "peerId",
8786 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
8787 }
8788
8789 /* Print aspath */
8790 if (attr->aspath) {
8791 if (json_paths)
8792 json_object_string_add(json_path, "path",
8793 attr->aspath->str);
8794 else
8795 aspath_print_vty(vty, "%s", attr->aspath, " ");
8796 }
8797
8798 /* Print origin */
8799 if (json_paths)
8800 json_object_string_add(json_path, "origin",
8801 bgp_origin_long_str[attr->origin]);
8802 else
8803 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8804
8805 if (json_paths) {
8806 if (bgp_evpn_is_esi_valid(&attr->esi)) {
8807 json_object_string_add(json_path, "esi",
8808 esi_to_str(&attr->esi,
8809 esi_buf, sizeof(esi_buf)));
8810 }
8811 if (safi == SAFI_EVPN &&
8812 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8813 json_ext_community = json_object_new_object();
8814 json_object_string_add(json_ext_community,
8815 "string",
8816 attr->ecommunity->str);
8817 json_object_object_add(json_path,
8818 "extendedCommunity",
8819 json_ext_community);
8820 }
8821
8822 if (nexthop_self)
8823 json_object_boolean_true_add(json_path,
8824 "announceNexthopSelf");
8825 if (nexthop_othervrf) {
8826 json_object_string_add(json_path, "nhVrfName",
8827 nexthop_vrfname);
8828
8829 json_object_int_add(json_path, "nhVrfId",
8830 ((nexthop_vrfid == VRF_UNKNOWN)
8831 ? -1
8832 : (int)nexthop_vrfid));
8833 }
8834 }
8835
8836 if (json_paths) {
8837 if (json_nexthop_global || json_nexthop_ll) {
8838 json_nexthops = json_object_new_array();
8839
8840 if (json_nexthop_global)
8841 json_object_array_add(json_nexthops,
8842 json_nexthop_global);
8843
8844 if (json_nexthop_ll)
8845 json_object_array_add(json_nexthops,
8846 json_nexthop_ll);
8847
8848 json_object_object_add(json_path, "nexthops",
8849 json_nexthops);
8850 }
8851
8852 json_object_array_add(json_paths, json_path);
8853 } else {
8854 vty_out(vty, "\n");
8855
8856 if (safi == SAFI_EVPN) {
8857 struct bgp_path_es_info *path_es_info = NULL;
8858
8859 if (path->extra)
8860 path_es_info = path->extra->es_info;
8861
8862 if (bgp_evpn_is_esi_valid(&attr->esi)) {
8863 /* XXX - add these params to the json out */
8864 vty_out(vty, "%*s", 20, " ");
8865 vty_out(vty, "ESI:%s",
8866 esi_to_str(&attr->esi, esi_buf,
8867 sizeof(esi_buf)));
8868 if (path_es_info && path_es_info->es)
8869 vty_out(vty, " VNI: %u",
8870 path_es_info->vni);
8871 vty_out(vty, "\n");
8872 }
8873 if (attr->flag &
8874 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8875 vty_out(vty, "%*s", 20, " ");
8876 vty_out(vty, "%s\n", attr->ecommunity->str);
8877 }
8878 }
8879
8880 #ifdef ENABLE_BGP_VNC
8881 /* prints an additional line, indented, with VNC info, if
8882 * present */
8883 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
8884 rfapi_vty_out_vncinfo(vty, p, path, safi);
8885 #endif
8886 }
8887 }
8888
8889 /* called from terminal list command */
8890 void route_vty_out_tmp(struct vty *vty, const struct prefix *p,
8891 struct attr *attr, safi_t safi, bool use_json,
8892 json_object *json_ar, bool wide)
8893 {
8894 json_object *json_status = NULL;
8895 json_object *json_net = NULL;
8896 int len;
8897 char buff[BUFSIZ];
8898
8899 /* Route status display. */
8900 if (use_json) {
8901 json_status = json_object_new_object();
8902 json_net = json_object_new_object();
8903 } else {
8904 vty_out(vty, "*");
8905 vty_out(vty, ">");
8906 vty_out(vty, " ");
8907 }
8908
8909 /* print prefix and mask */
8910 if (use_json) {
8911 if (safi == SAFI_EVPN)
8912 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
8913 else if (p->family == AF_INET || p->family == AF_INET6) {
8914 json_object_string_add(
8915 json_net, "addrPrefix",
8916 inet_ntop(p->family, &p->u.prefix, buff,
8917 BUFSIZ));
8918 json_object_int_add(json_net, "prefixLen",
8919 p->prefixlen);
8920 prefix2str(p, buff, PREFIX_STRLEN);
8921 json_object_string_add(json_net, "network", buff);
8922 }
8923 } else
8924 route_vty_out_route(p, vty, NULL, wide);
8925
8926 /* Print attribute */
8927 if (attr) {
8928 if (use_json) {
8929 char buf[BUFSIZ] = {0};
8930
8931 if (p->family == AF_INET
8932 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8933 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8934 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
8935 json_object_string_add(
8936 json_net, "nextHop",
8937 inet_ntop(
8938 AF_INET,
8939 &attr->mp_nexthop_global_in,
8940 buf, sizeof(buf)));
8941 else
8942 json_object_string_add(
8943 json_net, "nextHop",
8944 inet_ntop(AF_INET,
8945 &attr->nexthop, buf,
8946 sizeof(buf)));
8947 } else if (p->family == AF_INET6
8948 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8949 char buf[BUFSIZ];
8950
8951 json_object_string_add(
8952 json_net, "nextHopGlobal",
8953 inet_ntop(AF_INET6,
8954 &attr->mp_nexthop_global, buf,
8955 BUFSIZ));
8956 } else if (p->family == AF_EVPN
8957 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8958 char buf[BUFSIZ] = {0};
8959
8960 json_object_string_add(
8961 json_net, "nextHop",
8962 inet_ntop(AF_INET,
8963 &attr->mp_nexthop_global_in,
8964 buf, sizeof(buf)));
8965 }
8966
8967 if (attr->flag
8968 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
8969 json_object_int_add(json_net, "metric",
8970 attr->med);
8971
8972 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
8973 json_object_int_add(json_net, "locPrf",
8974 attr->local_pref);
8975
8976 json_object_int_add(json_net, "weight", attr->weight);
8977
8978 /* Print aspath */
8979 if (attr->aspath)
8980 json_object_string_add(json_net, "path",
8981 attr->aspath->str);
8982
8983 /* Print origin */
8984 json_object_string_add(json_net, "bgpOriginCode",
8985 bgp_origin_str[attr->origin]);
8986 } else {
8987 if (p->family == AF_INET
8988 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8989 || safi == SAFI_EVPN
8990 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8991 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8992 || safi == SAFI_EVPN)
8993 vty_out(vty, "%-16pI4",
8994 &attr->mp_nexthop_global_in);
8995 else if (wide)
8996 vty_out(vty, "%-41pI4", &attr->nexthop);
8997 else
8998 vty_out(vty, "%-16pI4", &attr->nexthop);
8999 } else if (p->family == AF_INET6
9000 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9001 char buf[BUFSIZ];
9002
9003 len = vty_out(
9004 vty, "%s",
9005 inet_ntop(AF_INET6,
9006 &attr->mp_nexthop_global, buf,
9007 BUFSIZ));
9008 len = wide ? (41 - len) : (16 - len);
9009 if (len < 1)
9010 vty_out(vty, "\n%*s", 36, " ");
9011 else
9012 vty_out(vty, "%*s", len, " ");
9013 }
9014 if (attr->flag
9015 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9016 if (wide)
9017 vty_out(vty, "%7u", attr->med);
9018 else
9019 vty_out(vty, "%10u", attr->med);
9020 else if (wide)
9021 vty_out(vty, " ");
9022 else
9023 vty_out(vty, " ");
9024
9025 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9026 vty_out(vty, "%7u", attr->local_pref);
9027 else
9028 vty_out(vty, " ");
9029
9030 vty_out(vty, "%7u ", attr->weight);
9031
9032 /* Print aspath */
9033 if (attr->aspath)
9034 aspath_print_vty(vty, "%s", attr->aspath, " ");
9035
9036 /* Print origin */
9037 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9038 }
9039 }
9040 if (use_json) {
9041 json_object_boolean_true_add(json_status, "*");
9042 json_object_boolean_true_add(json_status, ">");
9043 json_object_object_add(json_net, "appliedStatusSymbols",
9044 json_status);
9045
9046 prefix2str(p, buff, PREFIX_STRLEN);
9047 json_object_object_add(json_ar, buff, json_net);
9048 } else
9049 vty_out(vty, "\n");
9050 }
9051
9052 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9053 struct bgp_path_info *path, int display, safi_t safi,
9054 json_object *json)
9055 {
9056 json_object *json_out = NULL;
9057 struct attr *attr;
9058 mpls_label_t label = MPLS_INVALID_LABEL;
9059
9060 if (!path->extra)
9061 return;
9062
9063 if (json)
9064 json_out = json_object_new_object();
9065
9066 /* short status lead text */
9067 route_vty_short_status_out(vty, path, json_out);
9068
9069 /* print prefix and mask */
9070 if (json == NULL) {
9071 if (!display)
9072 route_vty_out_route(p, vty, NULL, false);
9073 else
9074 vty_out(vty, "%*s", 17, " ");
9075 }
9076
9077 /* Print attribute */
9078 attr = path->attr;
9079 if (((p->family == AF_INET)
9080 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
9081 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
9082 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9083 char buf[BUFSIZ] = {0};
9084
9085 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9086 || safi == SAFI_EVPN) {
9087 if (json)
9088 json_object_string_add(
9089 json_out, "mpNexthopGlobalIn",
9090 inet_ntop(AF_INET,
9091 &attr->mp_nexthop_global_in,
9092 buf, sizeof(buf)));
9093 else
9094 vty_out(vty, "%-16pI4",
9095 &attr->mp_nexthop_global_in);
9096 } else {
9097 if (json)
9098 json_object_string_add(
9099 json_out, "nexthop",
9100 inet_ntop(AF_INET, &attr->nexthop, buf,
9101 sizeof(buf)));
9102 else
9103 vty_out(vty, "%-16pI4", &attr->nexthop);
9104 }
9105 } else if (((p->family == AF_INET6)
9106 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
9107 || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
9108 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9109 char buf_a[512];
9110
9111 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9112 if (json)
9113 json_object_string_add(
9114 json_out, "mpNexthopGlobalIn",
9115 inet_ntop(AF_INET6,
9116 &attr->mp_nexthop_global,
9117 buf_a, sizeof(buf_a)));
9118 else
9119 vty_out(vty, "%s",
9120 inet_ntop(AF_INET6,
9121 &attr->mp_nexthop_global,
9122 buf_a, sizeof(buf_a)));
9123 } else if (attr->mp_nexthop_len
9124 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9125 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9126 &attr->mp_nexthop_global,
9127 &attr->mp_nexthop_local);
9128 if (json)
9129 json_object_string_add(json_out,
9130 "mpNexthopGlobalLocal",
9131 buf_a);
9132 else
9133 vty_out(vty, "%s", buf_a);
9134 }
9135 }
9136
9137 label = decode_label(&path->extra->label[0]);
9138
9139 if (bgp_is_valid_label(&label)) {
9140 if (json) {
9141 json_object_int_add(json_out, "notag", label);
9142 json_object_array_add(json, json_out);
9143 } else {
9144 vty_out(vty, "notag/%d", label);
9145 vty_out(vty, "\n");
9146 }
9147 }
9148 }
9149
9150 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9151 struct bgp_path_info *path, int display,
9152 json_object *json_paths)
9153 {
9154 struct attr *attr;
9155 char buf[BUFSIZ] = {0};
9156 json_object *json_path = NULL;
9157 json_object *json_nexthop = NULL;
9158 json_object *json_overlay = NULL;
9159
9160 if (!path->extra)
9161 return;
9162
9163 if (json_paths) {
9164 json_path = json_object_new_object();
9165 json_overlay = json_object_new_object();
9166 json_nexthop = json_object_new_object();
9167 }
9168
9169 /* short status lead text */
9170 route_vty_short_status_out(vty, path, json_path);
9171
9172 /* print prefix and mask */
9173 if (!display)
9174 route_vty_out_route(p, vty, json_path, false);
9175 else
9176 vty_out(vty, "%*s", 17, " ");
9177
9178 /* Print attribute */
9179 attr = path->attr;
9180 char buf1[BUFSIZ];
9181 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9182
9183 switch (af) {
9184 case AF_INET:
9185 inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ);
9186 if (!json_path) {
9187 vty_out(vty, "%-16s", buf);
9188 } else {
9189 json_object_string_add(json_nexthop, "ip", buf);
9190
9191 json_object_string_add(json_nexthop, "afi", "ipv4");
9192
9193 json_object_object_add(json_path, "nexthop",
9194 json_nexthop);
9195 }
9196 break;
9197 case AF_INET6:
9198 inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ);
9199 inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ);
9200 if (!json_path) {
9201 vty_out(vty, "%s(%s)", buf, buf1);
9202 } else {
9203 json_object_string_add(json_nexthop, "ipv6Global", buf);
9204
9205 json_object_string_add(json_nexthop, "ipv6LinkLocal",
9206 buf1);
9207
9208 json_object_string_add(json_nexthop, "afi", "ipv6");
9209
9210 json_object_object_add(json_path, "nexthop",
9211 json_nexthop);
9212 }
9213 break;
9214 default:
9215 if (!json_path) {
9216 vty_out(vty, "?");
9217 } else {
9218 json_object_string_add(json_nexthop, "Error",
9219 "Unsupported address-family");
9220 }
9221 }
9222
9223 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9224
9225 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p))
9226 inet_ntop(AF_INET, &eo->gw_ip.ipv4, buf, BUFSIZ);
9227 else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p))
9228 inet_ntop(AF_INET6, &eo->gw_ip.ipv6, buf, BUFSIZ);
9229
9230 if (!json_path)
9231 vty_out(vty, "/%s", buf);
9232 else
9233 json_object_string_add(json_overlay, "gw", buf);
9234
9235 if (attr->ecommunity) {
9236 char *mac = NULL;
9237 struct ecommunity_val *routermac = ecommunity_lookup(
9238 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
9239 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9240
9241 if (routermac)
9242 mac = ecom_mac2str((char *)routermac->val);
9243 if (mac) {
9244 if (!json_path) {
9245 vty_out(vty, "/%s", mac);
9246 } else {
9247 json_object_string_add(json_overlay, "rmac",
9248 mac);
9249 }
9250 XFREE(MTYPE_TMP, mac);
9251 }
9252 }
9253
9254 if (!json_path) {
9255 vty_out(vty, "\n");
9256 } else {
9257 json_object_object_add(json_path, "overlay", json_overlay);
9258
9259 json_object_array_add(json_paths, json_path);
9260 }
9261 }
9262
9263 /* dampening route */
9264 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9265 struct bgp_path_info *path, int display,
9266 afi_t afi, safi_t safi, bool use_json,
9267 json_object *json)
9268 {
9269 struct attr *attr;
9270 int len;
9271 char timebuf[BGP_UPTIME_LEN];
9272
9273 /* short status lead text */
9274 route_vty_short_status_out(vty, path, json);
9275
9276 /* print prefix and mask */
9277 if (!use_json) {
9278 if (!display)
9279 route_vty_out_route(p, vty, NULL, false);
9280 else
9281 vty_out(vty, "%*s", 17, " ");
9282 }
9283
9284 len = vty_out(vty, "%s", path->peer->host);
9285 len = 17 - len;
9286 if (len < 1) {
9287 if (!use_json)
9288 vty_out(vty, "\n%*s", 34, " ");
9289 } else {
9290 if (use_json)
9291 json_object_int_add(json, "peerHost", len);
9292 else
9293 vty_out(vty, "%*s", len, " ");
9294 }
9295
9296 if (use_json)
9297 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9298 safi, use_json, json);
9299 else
9300 vty_out(vty, "%s ",
9301 bgp_damp_reuse_time_vty(vty, path, timebuf,
9302 BGP_UPTIME_LEN, afi, safi,
9303 use_json, json));
9304
9305 /* Print attribute */
9306 attr = path->attr;
9307
9308 /* Print aspath */
9309 if (attr->aspath) {
9310 if (use_json)
9311 json_object_string_add(json, "asPath",
9312 attr->aspath->str);
9313 else
9314 aspath_print_vty(vty, "%s", attr->aspath, " ");
9315 }
9316
9317 /* Print origin */
9318 if (use_json)
9319 json_object_string_add(json, "origin",
9320 bgp_origin_str[attr->origin]);
9321 else
9322 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9323
9324 if (!use_json)
9325 vty_out(vty, "\n");
9326 }
9327
9328 /* flap route */
9329 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9330 struct bgp_path_info *path, int display,
9331 afi_t afi, safi_t safi, bool use_json,
9332 json_object *json)
9333 {
9334 struct attr *attr;
9335 struct bgp_damp_info *bdi;
9336 char timebuf[BGP_UPTIME_LEN];
9337 int len;
9338
9339 if (!path->extra)
9340 return;
9341
9342 bdi = path->extra->damp_info;
9343
9344 /* short status lead text */
9345 route_vty_short_status_out(vty, path, json);
9346
9347 /* print prefix and mask */
9348 if (!use_json) {
9349 if (!display)
9350 route_vty_out_route(p, vty, NULL, false);
9351 else
9352 vty_out(vty, "%*s", 17, " ");
9353 }
9354
9355 len = vty_out(vty, "%s", path->peer->host);
9356 len = 16 - len;
9357 if (len < 1) {
9358 if (!use_json)
9359 vty_out(vty, "\n%*s", 33, " ");
9360 } else {
9361 if (use_json)
9362 json_object_int_add(json, "peerHost", len);
9363 else
9364 vty_out(vty, "%*s", len, " ");
9365 }
9366
9367 len = vty_out(vty, "%d", bdi->flap);
9368 len = 5 - len;
9369 if (len < 1) {
9370 if (!use_json)
9371 vty_out(vty, " ");
9372 } else {
9373 if (use_json)
9374 json_object_int_add(json, "bdiFlap", len);
9375 else
9376 vty_out(vty, "%*s", len, " ");
9377 }
9378
9379 if (use_json)
9380 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
9381 json);
9382 else
9383 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
9384 BGP_UPTIME_LEN, 0, NULL));
9385
9386 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9387 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
9388 if (use_json)
9389 bgp_damp_reuse_time_vty(vty, path, timebuf,
9390 BGP_UPTIME_LEN, afi, safi,
9391 use_json, json);
9392 else
9393 vty_out(vty, "%s ",
9394 bgp_damp_reuse_time_vty(vty, path, timebuf,
9395 BGP_UPTIME_LEN, afi,
9396 safi, use_json, json));
9397 } else {
9398 if (!use_json)
9399 vty_out(vty, "%*s ", 8, " ");
9400 }
9401
9402 /* Print attribute */
9403 attr = path->attr;
9404
9405 /* Print aspath */
9406 if (attr->aspath) {
9407 if (use_json)
9408 json_object_string_add(json, "asPath",
9409 attr->aspath->str);
9410 else
9411 aspath_print_vty(vty, "%s", attr->aspath, " ");
9412 }
9413
9414 /* Print origin */
9415 if (use_json)
9416 json_object_string_add(json, "origin",
9417 bgp_origin_str[attr->origin]);
9418 else
9419 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9420
9421 if (!use_json)
9422 vty_out(vty, "\n");
9423 }
9424
9425 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
9426 int *first, const char *header,
9427 json_object *json_adv_to)
9428 {
9429 char buf1[INET6_ADDRSTRLEN];
9430 json_object *json_peer = NULL;
9431
9432 if (json_adv_to) {
9433 /* 'advertised-to' is a dictionary of peers we have advertised
9434 * this
9435 * prefix too. The key is the peer's IP or swpX, the value is
9436 * the
9437 * hostname if we know it and "" if not.
9438 */
9439 json_peer = json_object_new_object();
9440
9441 if (peer->hostname)
9442 json_object_string_add(json_peer, "hostname",
9443 peer->hostname);
9444
9445 if (peer->conf_if)
9446 json_object_object_add(json_adv_to, peer->conf_if,
9447 json_peer);
9448 else
9449 json_object_object_add(
9450 json_adv_to,
9451 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
9452 json_peer);
9453 } else {
9454 if (*first) {
9455 vty_out(vty, "%s", header);
9456 *first = 0;
9457 }
9458
9459 if (peer->hostname
9460 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
9461 if (peer->conf_if)
9462 vty_out(vty, " %s(%s)", peer->hostname,
9463 peer->conf_if);
9464 else
9465 vty_out(vty, " %s(%s)", peer->hostname,
9466 sockunion2str(&peer->su, buf1,
9467 SU_ADDRSTRLEN));
9468 } else {
9469 if (peer->conf_if)
9470 vty_out(vty, " %s", peer->conf_if);
9471 else
9472 vty_out(vty, " %s",
9473 sockunion2str(&peer->su, buf1,
9474 SU_ADDRSTRLEN));
9475 }
9476 }
9477 }
9478
9479 static void route_vty_out_tx_ids(struct vty *vty,
9480 struct bgp_addpath_info_data *d)
9481 {
9482 int i;
9483
9484 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9485 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
9486 d->addpath_tx_id[i],
9487 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
9488 }
9489 }
9490
9491 static void route_vty_out_detail_es_info(struct vty *vty,
9492 struct bgp_path_info *pi,
9493 struct attr *attr,
9494 json_object *json_path)
9495 {
9496 char esi_buf[ESI_STR_LEN];
9497 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
9498 bool peer_router = !!CHECK_FLAG(attr->es_flags,
9499 ATTR_ES_PEER_ROUTER);
9500 bool peer_active = !!CHECK_FLAG(attr->es_flags,
9501 ATTR_ES_PEER_ACTIVE);
9502 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
9503 ATTR_ES_PEER_PROXY);
9504 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
9505 if (json_path) {
9506 json_object *json_es_info = NULL;
9507
9508 json_object_string_add(
9509 json_path, "esi",
9510 esi_buf);
9511 if (es_local || bgp_evpn_attr_is_sync(attr)) {
9512 json_es_info = json_object_new_object();
9513 if (es_local)
9514 json_object_boolean_true_add(
9515 json_es_info, "localEs");
9516 if (peer_active)
9517 json_object_boolean_true_add(
9518 json_es_info, "peerActive");
9519 if (peer_proxy)
9520 json_object_boolean_true_add(
9521 json_es_info, "peerProxy");
9522 if (peer_router)
9523 json_object_boolean_true_add(
9524 json_es_info, "peerRouter");
9525 if (attr->mm_sync_seqnum)
9526 json_object_int_add(
9527 json_es_info, "peerSeq",
9528 attr->mm_sync_seqnum);
9529 json_object_object_add(
9530 json_path, "es_info",
9531 json_es_info);
9532 }
9533 } else {
9534 if (bgp_evpn_attr_is_sync(attr))
9535 vty_out(vty,
9536 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
9537 esi_buf,
9538 es_local ? "local-es":"",
9539 peer_proxy ? "proxy " : "",
9540 peer_active ? "active ":"",
9541 peer_router ? "router ":"",
9542 attr->mm_sync_seqnum);
9543 else
9544 vty_out(vty, " ESI %s %s\n",
9545 esi_buf,
9546 es_local ? "local-es":"");
9547 }
9548 }
9549
9550 void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
9551 struct bgp_dest *bn, struct bgp_path_info *path,
9552 afi_t afi, safi_t safi, json_object *json_paths)
9553 {
9554 char buf[INET6_ADDRSTRLEN];
9555 char buf1[BUFSIZ];
9556 struct attr *attr = path->attr;
9557 int sockunion_vty_out(struct vty *, union sockunion *);
9558 time_t tbuf;
9559 json_object *json_bestpath = NULL;
9560 json_object *json_cluster_list = NULL;
9561 json_object *json_cluster_list_list = NULL;
9562 json_object *json_ext_community = NULL;
9563 json_object *json_last_update = NULL;
9564 json_object *json_pmsi = NULL;
9565 json_object *json_nexthop_global = NULL;
9566 json_object *json_nexthop_ll = NULL;
9567 json_object *json_nexthops = NULL;
9568 json_object *json_path = NULL;
9569 json_object *json_peer = NULL;
9570 json_object *json_string = NULL;
9571 json_object *json_adv_to = NULL;
9572 int first = 0;
9573 struct listnode *node, *nnode;
9574 struct peer *peer;
9575 int addpath_capable;
9576 int has_adj;
9577 unsigned int first_as;
9578 bool nexthop_self =
9579 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9580 int i;
9581 char *nexthop_hostname =
9582 bgp_nexthop_hostname(path->peer, path->nexthop);
9583 int rpki_validation_state = 0;
9584
9585 if (json_paths) {
9586 json_path = json_object_new_object();
9587 json_peer = json_object_new_object();
9588 json_nexthop_global = json_object_new_object();
9589 }
9590
9591 if (path->extra) {
9592 char tag_buf[30];
9593
9594 tag_buf[0] = '\0';
9595 if (path->extra && path->extra->num_labels) {
9596 bgp_evpn_label2str(path->extra->label,
9597 path->extra->num_labels, tag_buf,
9598 sizeof(tag_buf));
9599 }
9600 if (safi == SAFI_EVPN) {
9601 if (!json_paths) {
9602 vty_out(vty, " Route %pFX",
9603 (struct prefix_evpn *)
9604 bgp_dest_get_prefix(bn));
9605 if (tag_buf[0] != '\0')
9606 vty_out(vty, " VNI %s", tag_buf);
9607 vty_out(vty, "\n");
9608 } else {
9609 if (tag_buf[0])
9610 json_object_string_add(json_path, "VNI",
9611 tag_buf);
9612 }
9613 }
9614
9615 if (path->extra && path->extra->parent && !json_paths) {
9616 struct bgp_path_info *parent_ri;
9617 struct bgp_dest *dest, *pdest;
9618
9619 parent_ri = (struct bgp_path_info *)path->extra->parent;
9620 dest = parent_ri->net;
9621 if (dest && dest->pdest) {
9622 pdest = dest->pdest;
9623 prefix_rd2str(
9624 (struct prefix_rd *)bgp_dest_get_prefix(
9625 pdest),
9626 buf1, sizeof(buf1));
9627 if (is_pi_family_evpn(parent_ri)) {
9628 vty_out(vty,
9629 " Imported from %s:%pFX, VNI %s\n",
9630 buf1,
9631 (struct prefix_evpn *)
9632 bgp_dest_get_prefix(
9633 dest),
9634 tag_buf);
9635 } else
9636 vty_out(vty,
9637 " Imported from %s:%pFX\n",
9638 buf1,
9639 (struct prefix_evpn *)
9640 bgp_dest_get_prefix(
9641 dest));
9642 }
9643 }
9644 }
9645
9646 /* Line1 display AS-path, Aggregator */
9647 if (attr->aspath) {
9648 if (json_paths) {
9649 if (!attr->aspath->json)
9650 aspath_str_update(attr->aspath, true);
9651 json_object_lock(attr->aspath->json);
9652 json_object_object_add(json_path, "aspath",
9653 attr->aspath->json);
9654 } else {
9655 if (attr->aspath->segments)
9656 aspath_print_vty(vty, " %s", attr->aspath, "");
9657 else
9658 vty_out(vty, " Local");
9659 }
9660 }
9661
9662 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
9663 if (json_paths)
9664 json_object_boolean_true_add(json_path, "removed");
9665 else
9666 vty_out(vty, ", (removed)");
9667 }
9668
9669 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
9670 if (json_paths)
9671 json_object_boolean_true_add(json_path, "stale");
9672 else
9673 vty_out(vty, ", (stale)");
9674 }
9675
9676 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
9677 if (json_paths) {
9678 char buf[BUFSIZ] = {0};
9679
9680 json_object_int_add(json_path, "aggregatorAs",
9681 attr->aggregator_as);
9682 json_object_string_add(json_path, "aggregatorId",
9683 inet_ntop(AF_INET,
9684 &attr->aggregator_addr,
9685 buf, sizeof(buf)));
9686 } else {
9687 vty_out(vty, ", (aggregated by %u %pI4)",
9688 attr->aggregator_as, &attr->aggregator_addr);
9689 }
9690 }
9691
9692 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
9693 PEER_FLAG_REFLECTOR_CLIENT)) {
9694 if (json_paths)
9695 json_object_boolean_true_add(json_path,
9696 "rxedFromRrClient");
9697 else
9698 vty_out(vty, ", (Received from a RR-client)");
9699 }
9700
9701 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
9702 PEER_FLAG_RSERVER_CLIENT)) {
9703 if (json_paths)
9704 json_object_boolean_true_add(json_path,
9705 "rxedFromRsClient");
9706 else
9707 vty_out(vty, ", (Received from a RS-client)");
9708 }
9709
9710 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
9711 if (json_paths)
9712 json_object_boolean_true_add(json_path,
9713 "dampeningHistoryEntry");
9714 else
9715 vty_out(vty, ", (history entry)");
9716 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
9717 if (json_paths)
9718 json_object_boolean_true_add(json_path,
9719 "dampeningSuppressed");
9720 else
9721 vty_out(vty, ", (suppressed due to dampening)");
9722 }
9723
9724 if (!json_paths)
9725 vty_out(vty, "\n");
9726
9727 /* Line2 display Next-hop, Neighbor, Router-id */
9728 /* Display the nexthop */
9729 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
9730
9731 if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET
9732 || bn_p->family == AF_EVPN)
9733 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
9734 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9735 char buf[BUFSIZ] = {0};
9736
9737 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9738 || safi == SAFI_EVPN) {
9739 if (json_paths) {
9740 json_object_string_add(
9741 json_nexthop_global, "ip",
9742 inet_ntop(AF_INET,
9743 &attr->mp_nexthop_global_in,
9744 buf, sizeof(buf)));
9745
9746 if (path->peer->hostname)
9747 json_object_string_add(
9748 json_nexthop_global, "hostname",
9749 path->peer->hostname);
9750 } else {
9751 if (nexthop_hostname)
9752 vty_out(vty, " %pI4(%s)",
9753 &attr->mp_nexthop_global_in,
9754 nexthop_hostname);
9755 else
9756 vty_out(vty, " %pI4",
9757 &attr->mp_nexthop_global_in);
9758 }
9759 } else {
9760 if (json_paths) {
9761 json_object_string_add(
9762 json_nexthop_global, "ip",
9763 inet_ntop(AF_INET, &attr->nexthop, buf,
9764 sizeof(buf)));
9765
9766 if (path->peer->hostname)
9767 json_object_string_add(
9768 json_nexthop_global, "hostname",
9769 path->peer->hostname);
9770 } else {
9771 if (nexthop_hostname)
9772 vty_out(vty, " %pI4(%s)",
9773 &attr->nexthop,
9774 nexthop_hostname);
9775 else
9776 vty_out(vty, " %pI4",
9777 &attr->nexthop);
9778 }
9779 }
9780
9781 if (json_paths)
9782 json_object_string_add(json_nexthop_global, "afi",
9783 "ipv4");
9784 } else {
9785 if (json_paths) {
9786 json_object_string_add(
9787 json_nexthop_global, "ip",
9788 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
9789 buf, INET6_ADDRSTRLEN));
9790
9791 if (path->peer->hostname)
9792 json_object_string_add(json_nexthop_global,
9793 "hostname",
9794 path->peer->hostname);
9795
9796 json_object_string_add(json_nexthop_global, "afi",
9797 "ipv6");
9798 json_object_string_add(json_nexthop_global, "scope",
9799 "global");
9800 } else {
9801 if (nexthop_hostname)
9802 vty_out(vty, " %pI6(%s)",
9803 &attr->mp_nexthop_global,
9804 nexthop_hostname);
9805 else
9806 vty_out(vty, " %pI6",
9807 &attr->mp_nexthop_global);
9808 }
9809 }
9810
9811 /* Display the IGP cost or 'inaccessible' */
9812 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
9813 if (json_paths)
9814 json_object_boolean_false_add(json_nexthop_global,
9815 "accessible");
9816 else
9817 vty_out(vty, " (inaccessible)");
9818 } else {
9819 if (path->extra && path->extra->igpmetric) {
9820 if (json_paths)
9821 json_object_int_add(json_nexthop_global,
9822 "metric",
9823 path->extra->igpmetric);
9824 else
9825 vty_out(vty, " (metric %u)",
9826 path->extra->igpmetric);
9827 }
9828
9829 /* IGP cost is 0, display this only for json */
9830 else {
9831 if (json_paths)
9832 json_object_int_add(json_nexthop_global,
9833 "metric", 0);
9834 }
9835
9836 if (json_paths)
9837 json_object_boolean_true_add(json_nexthop_global,
9838 "accessible");
9839 }
9840
9841 /* Display peer "from" output */
9842 /* This path was originated locally */
9843 if (path->peer == bgp->peer_self) {
9844
9845 if (safi == SAFI_EVPN
9846 || (bn_p->family == AF_INET
9847 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9848 if (json_paths)
9849 json_object_string_add(json_peer, "peerId",
9850 "0.0.0.0");
9851 else
9852 vty_out(vty, " from 0.0.0.0 ");
9853 } else {
9854 if (json_paths)
9855 json_object_string_add(json_peer, "peerId",
9856 "::");
9857 else
9858 vty_out(vty, " from :: ");
9859 }
9860
9861 if (json_paths) {
9862 char buf[BUFSIZ] = {0};
9863
9864 json_object_string_add(json_peer, "routerId",
9865 inet_ntop(AF_INET,
9866 &bgp->router_id, buf,
9867 sizeof(buf)));
9868 } else {
9869 vty_out(vty, "(%pI4)", &bgp->router_id);
9870 }
9871 }
9872
9873 /* We RXed this path from one of our peers */
9874 else {
9875
9876 if (json_paths) {
9877 json_object_string_add(json_peer, "peerId",
9878 sockunion2str(&path->peer->su,
9879 buf,
9880 SU_ADDRSTRLEN));
9881 json_object_string_add(json_peer, "routerId",
9882 inet_ntop(AF_INET,
9883 &path->peer->remote_id,
9884 buf1, sizeof(buf1)));
9885
9886 if (path->peer->hostname)
9887 json_object_string_add(json_peer, "hostname",
9888 path->peer->hostname);
9889
9890 if (path->peer->domainname)
9891 json_object_string_add(json_peer, "domainname",
9892 path->peer->domainname);
9893
9894 if (path->peer->conf_if)
9895 json_object_string_add(json_peer, "interface",
9896 path->peer->conf_if);
9897 } else {
9898 if (path->peer->conf_if) {
9899 if (path->peer->hostname
9900 && CHECK_FLAG(path->peer->bgp->flags,
9901 BGP_FLAG_SHOW_HOSTNAME))
9902 vty_out(vty, " from %s(%s)",
9903 path->peer->hostname,
9904 path->peer->conf_if);
9905 else
9906 vty_out(vty, " from %s",
9907 path->peer->conf_if);
9908 } else {
9909 if (path->peer->hostname
9910 && CHECK_FLAG(path->peer->bgp->flags,
9911 BGP_FLAG_SHOW_HOSTNAME))
9912 vty_out(vty, " from %s(%s)",
9913 path->peer->hostname,
9914 path->peer->host);
9915 else
9916 vty_out(vty, " from %s",
9917 sockunion2str(&path->peer->su,
9918 buf,
9919 SU_ADDRSTRLEN));
9920 }
9921
9922 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
9923 vty_out(vty, " (%pI4)", &attr->originator_id);
9924 else
9925 vty_out(vty, " (%s)",
9926 inet_ntop(AF_INET,
9927 &path->peer->remote_id, buf1,
9928 sizeof(buf1)));
9929 }
9930 }
9931
9932 /*
9933 * Note when vrfid of nexthop is different from that of prefix
9934 */
9935 if (path->extra && path->extra->bgp_orig) {
9936 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9937
9938 if (json_paths) {
9939 const char *vn;
9940
9941 if (path->extra->bgp_orig->inst_type
9942 == BGP_INSTANCE_TYPE_DEFAULT)
9943 vn = VRF_DEFAULT_NAME;
9944 else
9945 vn = path->extra->bgp_orig->name;
9946
9947 json_object_string_add(json_path, "nhVrfName", vn);
9948
9949 if (nexthop_vrfid == VRF_UNKNOWN) {
9950 json_object_int_add(json_path, "nhVrfId", -1);
9951 } else {
9952 json_object_int_add(json_path, "nhVrfId",
9953 (int)nexthop_vrfid);
9954 }
9955 } else {
9956 if (nexthop_vrfid == VRF_UNKNOWN)
9957 vty_out(vty, " vrf ?");
9958 else {
9959 struct vrf *vrf;
9960
9961 vrf = vrf_lookup_by_id(nexthop_vrfid);
9962 vty_out(vty, " vrf %s(%u)",
9963 VRF_LOGNAME(vrf), nexthop_vrfid);
9964 }
9965 }
9966 }
9967
9968 if (nexthop_self) {
9969 if (json_paths) {
9970 json_object_boolean_true_add(json_path,
9971 "announceNexthopSelf");
9972 } else {
9973 vty_out(vty, " announce-nh-self");
9974 }
9975 }
9976
9977 if (!json_paths)
9978 vty_out(vty, "\n");
9979
9980 /* display the link-local nexthop */
9981 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9982 if (json_paths) {
9983 json_nexthop_ll = json_object_new_object();
9984 json_object_string_add(
9985 json_nexthop_ll, "ip",
9986 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
9987 buf, INET6_ADDRSTRLEN));
9988
9989 if (path->peer->hostname)
9990 json_object_string_add(json_nexthop_ll,
9991 "hostname",
9992 path->peer->hostname);
9993
9994 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
9995 json_object_string_add(json_nexthop_ll, "scope",
9996 "link-local");
9997
9998 json_object_boolean_true_add(json_nexthop_ll,
9999 "accessible");
10000
10001 if (!attr->mp_nexthop_prefer_global)
10002 json_object_boolean_true_add(json_nexthop_ll,
10003 "used");
10004 else
10005 json_object_boolean_true_add(
10006 json_nexthop_global, "used");
10007 } else {
10008 vty_out(vty, " (%s) %s\n",
10009 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10010 buf, INET6_ADDRSTRLEN),
10011 attr->mp_nexthop_prefer_global
10012 ? "(prefer-global)"
10013 : "(used)");
10014 }
10015 }
10016 /* If we do not have a link-local nexthop then we must flag the
10017 global as "used" */
10018 else {
10019 if (json_paths)
10020 json_object_boolean_true_add(json_nexthop_global,
10021 "used");
10022 }
10023
10024 if (safi == SAFI_EVPN &&
10025 bgp_evpn_is_esi_valid(&attr->esi)) {
10026 route_vty_out_detail_es_info(vty, path, attr, json_path);
10027 }
10028
10029 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10030 * Int/Ext/Local, Atomic, best */
10031 if (json_paths)
10032 json_object_string_add(json_path, "origin",
10033 bgp_origin_long_str[attr->origin]);
10034 else
10035 vty_out(vty, " Origin %s",
10036 bgp_origin_long_str[attr->origin]);
10037
10038 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10039 if (json_paths)
10040 json_object_int_add(json_path, "metric", attr->med);
10041 else
10042 vty_out(vty, ", metric %u", attr->med);
10043 }
10044
10045 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10046 if (json_paths)
10047 json_object_int_add(json_path, "locPrf",
10048 attr->local_pref);
10049 else
10050 vty_out(vty, ", localpref %u", attr->local_pref);
10051 }
10052
10053 if (attr->weight != 0) {
10054 if (json_paths)
10055 json_object_int_add(json_path, "weight", attr->weight);
10056 else
10057 vty_out(vty, ", weight %u", attr->weight);
10058 }
10059
10060 if (attr->tag != 0) {
10061 if (json_paths)
10062 json_object_int_add(json_path, "tag", attr->tag);
10063 else
10064 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10065 }
10066
10067 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10068 if (json_paths)
10069 json_object_boolean_false_add(json_path, "valid");
10070 else
10071 vty_out(vty, ", invalid");
10072 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10073 if (json_paths)
10074 json_object_boolean_true_add(json_path, "valid");
10075 else
10076 vty_out(vty, ", valid");
10077 }
10078
10079 if (path->peer != bgp->peer_self) {
10080 if (path->peer->as == path->peer->local_as) {
10081 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10082 if (json_paths)
10083 json_object_string_add(
10084 json_peer, "type",
10085 "confed-internal");
10086 else
10087 vty_out(vty, ", confed-internal");
10088 } else {
10089 if (json_paths)
10090 json_object_string_add(
10091 json_peer, "type", "internal");
10092 else
10093 vty_out(vty, ", internal");
10094 }
10095 } else {
10096 if (bgp_confederation_peers_check(bgp,
10097 path->peer->as)) {
10098 if (json_paths)
10099 json_object_string_add(
10100 json_peer, "type",
10101 "confed-external");
10102 else
10103 vty_out(vty, ", confed-external");
10104 } else {
10105 if (json_paths)
10106 json_object_string_add(
10107 json_peer, "type", "external");
10108 else
10109 vty_out(vty, ", external");
10110 }
10111 }
10112 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10113 if (json_paths) {
10114 json_object_boolean_true_add(json_path, "aggregated");
10115 json_object_boolean_true_add(json_path, "local");
10116 } else {
10117 vty_out(vty, ", aggregated, local");
10118 }
10119 } else if (path->type != ZEBRA_ROUTE_BGP) {
10120 if (json_paths)
10121 json_object_boolean_true_add(json_path, "sourced");
10122 else
10123 vty_out(vty, ", sourced");
10124 } else {
10125 if (json_paths) {
10126 json_object_boolean_true_add(json_path, "sourced");
10127 json_object_boolean_true_add(json_path, "local");
10128 } else {
10129 vty_out(vty, ", sourced, local");
10130 }
10131 }
10132
10133 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10134 if (json_paths)
10135 json_object_boolean_true_add(json_path,
10136 "atomicAggregate");
10137 else
10138 vty_out(vty, ", atomic-aggregate");
10139 }
10140
10141 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10142 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10143 && bgp_path_info_mpath_count(path))) {
10144 if (json_paths)
10145 json_object_boolean_true_add(json_path, "multipath");
10146 else
10147 vty_out(vty, ", multipath");
10148 }
10149
10150 // Mark the bestpath(s)
10151 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10152 first_as = aspath_get_first_as(attr->aspath);
10153
10154 if (json_paths) {
10155 if (!json_bestpath)
10156 json_bestpath = json_object_new_object();
10157 json_object_int_add(json_bestpath, "bestpathFromAs",
10158 first_as);
10159 } else {
10160 if (first_as)
10161 vty_out(vty, ", bestpath-from-AS %u", first_as);
10162 else
10163 vty_out(vty, ", bestpath-from-AS Local");
10164 }
10165 }
10166
10167 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10168 if (json_paths) {
10169 if (!json_bestpath)
10170 json_bestpath = json_object_new_object();
10171 json_object_boolean_true_add(json_bestpath, "overall");
10172 json_object_string_add(
10173 json_bestpath, "selectionReason",
10174 bgp_path_selection_reason2str(bn->reason));
10175 } else {
10176 vty_out(vty, ", best");
10177 vty_out(vty, " (%s)",
10178 bgp_path_selection_reason2str(bn->reason));
10179 }
10180 }
10181
10182 const struct prefix *p = bgp_dest_get_prefix(bn);
10183 if (p->family == AF_INET || p->family == AF_INET6)
10184 rpki_validation_state = hook_call(bgp_rpki_prefix_status,
10185 path->peer, path->attr, p);
10186 if (rpki_validation_state) {
10187 if (json_paths)
10188 json_object_string_add(
10189 json_path, "rpkiValidationState",
10190 bgp_rpki_validation2str(rpki_validation_state));
10191 else
10192 vty_out(vty, ", validation-state: %s",
10193 bgp_rpki_validation2str(rpki_validation_state));
10194 }
10195
10196 if (json_bestpath)
10197 json_object_object_add(json_path, "bestpath", json_bestpath);
10198
10199 if (!json_paths)
10200 vty_out(vty, "\n");
10201
10202 /* Line 4 display Community */
10203 if (attr->community) {
10204 if (json_paths) {
10205 if (!attr->community->json)
10206 community_str(attr->community, true);
10207 json_object_lock(attr->community->json);
10208 json_object_object_add(json_path, "community",
10209 attr->community->json);
10210 } else {
10211 vty_out(vty, " Community: %s\n",
10212 attr->community->str);
10213 }
10214 }
10215
10216 /* Line 5 display Extended-community */
10217 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10218 if (json_paths) {
10219 json_ext_community = json_object_new_object();
10220 json_object_string_add(json_ext_community, "string",
10221 attr->ecommunity->str);
10222 json_object_object_add(json_path, "extendedCommunity",
10223 json_ext_community);
10224 } else {
10225 vty_out(vty, " Extended Community: %s\n",
10226 attr->ecommunity->str);
10227 }
10228 }
10229
10230 /* Line 6 display Large community */
10231 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10232 if (json_paths) {
10233 if (!attr->lcommunity->json)
10234 lcommunity_str(attr->lcommunity, true);
10235 json_object_lock(attr->lcommunity->json);
10236 json_object_object_add(json_path, "largeCommunity",
10237 attr->lcommunity->json);
10238 } else {
10239 vty_out(vty, " Large Community: %s\n",
10240 attr->lcommunity->str);
10241 }
10242 }
10243
10244 /* Line 7 display Originator, Cluster-id */
10245 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10246 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10247 char buf[BUFSIZ] = {0};
10248
10249 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10250 if (json_paths)
10251 json_object_string_add(
10252 json_path, "originatorId",
10253 inet_ntop(AF_INET, &attr->originator_id,
10254 buf, sizeof(buf)));
10255 else
10256 vty_out(vty, " Originator: %pI4",
10257 &attr->originator_id);
10258 }
10259
10260 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10261 struct cluster_list *cluster =
10262 bgp_attr_get_cluster(attr);
10263 int i;
10264
10265 if (json_paths) {
10266 json_cluster_list = json_object_new_object();
10267 json_cluster_list_list =
10268 json_object_new_array();
10269
10270 for (i = 0; i < cluster->length / 4; i++) {
10271 json_string = json_object_new_string(
10272 inet_ntop(AF_INET,
10273 &cluster->list[i],
10274 buf, sizeof(buf)));
10275 json_object_array_add(
10276 json_cluster_list_list,
10277 json_string);
10278 }
10279
10280 /*
10281 * struct cluster_list does not have
10282 * "str" variable like aspath and community
10283 * do. Add this someday if someone asks
10284 * for it.
10285 * json_object_string_add(json_cluster_list,
10286 * "string", cluster->str);
10287 */
10288 json_object_object_add(json_cluster_list,
10289 "list",
10290 json_cluster_list_list);
10291 json_object_object_add(json_path, "clusterList",
10292 json_cluster_list);
10293 } else {
10294 vty_out(vty, ", Cluster list: ");
10295
10296 for (i = 0; i < cluster->length / 4; i++) {
10297 vty_out(vty, "%pI4 ",
10298 &cluster->list[i]);
10299 }
10300 }
10301 }
10302
10303 if (!json_paths)
10304 vty_out(vty, "\n");
10305 }
10306
10307 if (path->extra && path->extra->damp_info)
10308 bgp_damp_info_vty(vty, bgp, path, afi, safi, json_path);
10309
10310 /* Remote Label */
10311 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10312 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10313 mpls_label_t label = label_pton(&path->extra->label[0]);
10314
10315 if (json_paths)
10316 json_object_int_add(json_path, "remoteLabel", label);
10317 else
10318 vty_out(vty, " Remote label: %d\n", label);
10319 }
10320
10321 /* Remote SID */
10322 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10323 inet_ntop(AF_INET6, &path->extra->sid, buf, sizeof(buf));
10324 if (json_paths)
10325 json_object_string_add(json_path, "remoteSid", buf);
10326 else
10327 vty_out(vty, " Remote SID: %s\n", buf);
10328 }
10329
10330 /* Label Index */
10331 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10332 if (json_paths)
10333 json_object_int_add(json_path, "labelIndex",
10334 attr->label_index);
10335 else
10336 vty_out(vty, " Label Index: %d\n",
10337 attr->label_index);
10338 }
10339
10340 /* Line 8 display Addpath IDs */
10341 if (path->addpath_rx_id
10342 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
10343 if (json_paths) {
10344 json_object_int_add(json_path, "addpathRxId",
10345 path->addpath_rx_id);
10346
10347 /* Keep backwards compatibility with the old API
10348 * by putting TX All's ID in the old field
10349 */
10350 json_object_int_add(
10351 json_path, "addpathTxId",
10352 path->tx_addpath
10353 .addpath_tx_id[BGP_ADDPATH_ALL]);
10354
10355 /* ... but create a specific field for each
10356 * strategy
10357 */
10358 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10359 json_object_int_add(
10360 json_path,
10361 bgp_addpath_names(i)->id_json_name,
10362 path->tx_addpath.addpath_tx_id[i]);
10363 }
10364 } else {
10365 vty_out(vty, " AddPath ID: RX %u, ",
10366 path->addpath_rx_id);
10367
10368 route_vty_out_tx_ids(vty, &path->tx_addpath);
10369 }
10370 }
10371
10372 /* If we used addpath to TX a non-bestpath we need to display
10373 * "Advertised to" on a path-by-path basis
10374 */
10375 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
10376 first = 1;
10377
10378 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
10379 addpath_capable =
10380 bgp_addpath_encode_tx(peer, afi, safi);
10381 has_adj = bgp_adj_out_lookup(
10382 peer, path->net,
10383 bgp_addpath_id_for_peer(peer, afi, safi,
10384 &path->tx_addpath));
10385
10386 if ((addpath_capable && has_adj)
10387 || (!addpath_capable && has_adj
10388 && CHECK_FLAG(path->flags,
10389 BGP_PATH_SELECTED))) {
10390 if (json_path && !json_adv_to)
10391 json_adv_to = json_object_new_object();
10392
10393 route_vty_out_advertised_to(
10394 vty, peer, &first,
10395 " Advertised to:", json_adv_to);
10396 }
10397 }
10398
10399 if (json_path) {
10400 if (json_adv_to) {
10401 json_object_object_add(
10402 json_path, "advertisedTo", json_adv_to);
10403 }
10404 } else {
10405 if (!first) {
10406 vty_out(vty, "\n");
10407 }
10408 }
10409 }
10410
10411 /* Line 9 display Uptime */
10412 tbuf = time(NULL) - (bgp_clock() - path->uptime);
10413 if (json_paths) {
10414 json_last_update = json_object_new_object();
10415 json_object_int_add(json_last_update, "epoch", tbuf);
10416 json_object_string_add(json_last_update, "string",
10417 ctime(&tbuf));
10418 json_object_object_add(json_path, "lastUpdate",
10419 json_last_update);
10420 } else
10421 vty_out(vty, " Last update: %s", ctime(&tbuf));
10422
10423 /* Line 10 display PMSI tunnel attribute, if present */
10424 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
10425 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
10426 bgp_attr_get_pmsi_tnl_type(attr),
10427 PMSI_TNLTYPE_STR_DEFAULT);
10428
10429 if (json_paths) {
10430 json_pmsi = json_object_new_object();
10431 json_object_string_add(json_pmsi, "tunnelType", str);
10432 json_object_int_add(json_pmsi, "label",
10433 label2vni(&attr->label));
10434 json_object_object_add(json_path, "pmsi", json_pmsi);
10435 } else
10436 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
10437 str, label2vni(&attr->label));
10438 }
10439
10440 /* Output some debug about internal state of the dest flags */
10441 if (json_paths) {
10442 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
10443 json_object_boolean_true_add(json_path, "processScheduled");
10444 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
10445 json_object_boolean_true_add(json_path, "userCleared");
10446 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
10447 json_object_boolean_true_add(json_path, "labelChanged");
10448 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
10449 json_object_boolean_true_add(json_path, "registeredForLabel");
10450 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
10451 json_object_boolean_true_add(json_path, "selectDefered");
10452 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
10453 json_object_boolean_true_add(json_path, "fibInstalled");
10454 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
10455 json_object_boolean_true_add(json_path, "fibPending");
10456 }
10457
10458 /* We've constructed the json object for this path, add it to the json
10459 * array of paths
10460 */
10461 if (json_paths) {
10462 if (json_nexthop_global || json_nexthop_ll) {
10463 json_nexthops = json_object_new_array();
10464
10465 if (json_nexthop_global)
10466 json_object_array_add(json_nexthops,
10467 json_nexthop_global);
10468
10469 if (json_nexthop_ll)
10470 json_object_array_add(json_nexthops,
10471 json_nexthop_ll);
10472
10473 json_object_object_add(json_path, "nexthops",
10474 json_nexthops);
10475 }
10476
10477 json_object_object_add(json_path, "peer", json_peer);
10478 json_object_array_add(json_paths, json_path);
10479 }
10480 }
10481
10482 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
10483 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
10484 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
10485
10486 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
10487 const char *prefix_list_str, afi_t afi,
10488 safi_t safi, enum bgp_show_type type);
10489 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
10490 const char *filter, afi_t afi, safi_t safi,
10491 enum bgp_show_type type);
10492 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
10493 const char *rmap_str, afi_t afi, safi_t safi,
10494 enum bgp_show_type type);
10495 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
10496 const char *com, int exact, afi_t afi,
10497 safi_t safi);
10498 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
10499 const char *prefix, afi_t afi, safi_t safi,
10500 enum bgp_show_type type);
10501 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
10502 afi_t afi, safi_t safi, enum bgp_show_type type,
10503 bool use_json);
10504 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
10505 const char *comstr, int exact, afi_t afi,
10506 safi_t safi, uint8_t show_flags);
10507
10508
10509 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
10510 struct bgp_table *table, enum bgp_show_type type,
10511 void *output_arg, char *rd, int is_last,
10512 unsigned long *output_cum, unsigned long *total_cum,
10513 unsigned long *json_header_depth, uint8_t show_flags)
10514 {
10515 struct bgp_path_info *pi;
10516 struct bgp_dest *dest;
10517 int header = 1;
10518 int display;
10519 unsigned long output_count = 0;
10520 unsigned long total_count = 0;
10521 struct prefix *p;
10522 json_object *json_paths = NULL;
10523 int first = 1;
10524 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10525 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
10526 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
10527
10528 if (output_cum && *output_cum != 0)
10529 header = 0;
10530
10531 if (use_json && !*json_header_depth) {
10532 if (all)
10533 *json_header_depth = 1;
10534 else {
10535 vty_out(vty, "{\n");
10536 *json_header_depth = 2;
10537 }
10538
10539 vty_out(vty,
10540 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
10541 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
10542 " \"localAS\": %u,\n \"routes\": { ",
10543 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
10544 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
10545 ? VRF_DEFAULT_NAME
10546 : bgp->name,
10547 table->version, &bgp->router_id,
10548 bgp->default_local_pref, bgp->as);
10549 if (rd) {
10550 vty_out(vty, " \"routeDistinguishers\" : {");
10551 ++*json_header_depth;
10552 }
10553 }
10554
10555 if (use_json && rd) {
10556 vty_out(vty, " \"%s\" : { ", rd);
10557 }
10558
10559 /* Start processing of routes. */
10560 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
10561 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10562
10563 pi = bgp_dest_get_bgp_path_info(dest);
10564 if (pi == NULL)
10565 continue;
10566
10567 display = 0;
10568 if (use_json)
10569 json_paths = json_object_new_array();
10570 else
10571 json_paths = NULL;
10572
10573 for (; pi; pi = pi->next) {
10574 total_count++;
10575 if (type == bgp_show_type_flap_statistics
10576 || type == bgp_show_type_flap_neighbor
10577 || type == bgp_show_type_dampend_paths
10578 || type == bgp_show_type_damp_neighbor) {
10579 if (!(pi->extra && pi->extra->damp_info))
10580 continue;
10581 }
10582 if (type == bgp_show_type_regexp) {
10583 regex_t *regex = output_arg;
10584
10585 if (bgp_regexec(regex, pi->attr->aspath)
10586 == REG_NOMATCH)
10587 continue;
10588 }
10589 if (type == bgp_show_type_prefix_list) {
10590 struct prefix_list *plist = output_arg;
10591
10592 if (prefix_list_apply(plist, dest_p)
10593 != PREFIX_PERMIT)
10594 continue;
10595 }
10596 if (type == bgp_show_type_filter_list) {
10597 struct as_list *as_list = output_arg;
10598
10599 if (as_list_apply(as_list, pi->attr->aspath)
10600 != AS_FILTER_PERMIT)
10601 continue;
10602 }
10603 if (type == bgp_show_type_route_map) {
10604 struct route_map *rmap = output_arg;
10605 struct bgp_path_info path;
10606 struct attr dummy_attr;
10607 route_map_result_t ret;
10608
10609 dummy_attr = *pi->attr;
10610
10611 path.peer = pi->peer;
10612 path.attr = &dummy_attr;
10613
10614 ret = route_map_apply(rmap, dest_p, &path);
10615 if (ret == RMAP_DENYMATCH)
10616 continue;
10617 }
10618 if (type == bgp_show_type_neighbor
10619 || type == bgp_show_type_flap_neighbor
10620 || type == bgp_show_type_damp_neighbor) {
10621 union sockunion *su = output_arg;
10622
10623 if (pi->peer == NULL
10624 || pi->peer->su_remote == NULL
10625 || !sockunion_same(pi->peer->su_remote, su))
10626 continue;
10627 }
10628 if (type == bgp_show_type_cidr_only) {
10629 uint32_t destination;
10630
10631 destination = ntohl(dest_p->u.prefix4.s_addr);
10632 if (IN_CLASSC(destination)
10633 && dest_p->prefixlen == 24)
10634 continue;
10635 if (IN_CLASSB(destination)
10636 && dest_p->prefixlen == 16)
10637 continue;
10638 if (IN_CLASSA(destination)
10639 && dest_p->prefixlen == 8)
10640 continue;
10641 }
10642 if (type == bgp_show_type_prefix_longer) {
10643 p = output_arg;
10644 if (!prefix_match(p, dest_p))
10645 continue;
10646 }
10647 if (type == bgp_show_type_community_all) {
10648 if (!pi->attr->community)
10649 continue;
10650 }
10651 if (type == bgp_show_type_community) {
10652 struct community *com = output_arg;
10653
10654 if (!pi->attr->community
10655 || !community_match(pi->attr->community,
10656 com))
10657 continue;
10658 }
10659 if (type == bgp_show_type_community_exact) {
10660 struct community *com = output_arg;
10661
10662 if (!pi->attr->community
10663 || !community_cmp(pi->attr->community, com))
10664 continue;
10665 }
10666 if (type == bgp_show_type_community_list) {
10667 struct community_list *list = output_arg;
10668
10669 if (!community_list_match(pi->attr->community,
10670 list))
10671 continue;
10672 }
10673 if (type == bgp_show_type_community_list_exact) {
10674 struct community_list *list = output_arg;
10675
10676 if (!community_list_exact_match(
10677 pi->attr->community, list))
10678 continue;
10679 }
10680 if (type == bgp_show_type_lcommunity) {
10681 struct lcommunity *lcom = output_arg;
10682
10683 if (!pi->attr->lcommunity
10684 || !lcommunity_match(pi->attr->lcommunity,
10685 lcom))
10686 continue;
10687 }
10688
10689 if (type == bgp_show_type_lcommunity_exact) {
10690 struct lcommunity *lcom = output_arg;
10691
10692 if (!pi->attr->lcommunity
10693 || !lcommunity_cmp(pi->attr->lcommunity,
10694 lcom))
10695 continue;
10696 }
10697 if (type == bgp_show_type_lcommunity_list) {
10698 struct community_list *list = output_arg;
10699
10700 if (!lcommunity_list_match(pi->attr->lcommunity,
10701 list))
10702 continue;
10703 }
10704 if (type
10705 == bgp_show_type_lcommunity_list_exact) {
10706 struct community_list *list = output_arg;
10707
10708 if (!lcommunity_list_exact_match(
10709 pi->attr->lcommunity, list))
10710 continue;
10711 }
10712 if (type == bgp_show_type_lcommunity_all) {
10713 if (!pi->attr->lcommunity)
10714 continue;
10715 }
10716 if (type == bgp_show_type_dampend_paths
10717 || type == bgp_show_type_damp_neighbor) {
10718 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
10719 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
10720 continue;
10721 }
10722
10723 if (!use_json && header) {
10724 vty_out(vty,
10725 "BGP table version is %" PRIu64
10726 ", local router ID is %pI4, vrf id ",
10727 table->version, &bgp->router_id);
10728 if (bgp->vrf_id == VRF_UNKNOWN)
10729 vty_out(vty, "%s", VRFID_NONE_STR);
10730 else
10731 vty_out(vty, "%u", bgp->vrf_id);
10732 vty_out(vty, "\n");
10733 vty_out(vty, "Default local pref %u, ",
10734 bgp->default_local_pref);
10735 vty_out(vty, "local AS %u\n", bgp->as);
10736 vty_out(vty, BGP_SHOW_SCODE_HEADER);
10737 vty_out(vty, BGP_SHOW_NCODE_HEADER);
10738 vty_out(vty, BGP_SHOW_OCODE_HEADER);
10739 if (type == bgp_show_type_dampend_paths
10740 || type == bgp_show_type_damp_neighbor)
10741 vty_out(vty, BGP_SHOW_DAMP_HEADER);
10742 else if (type == bgp_show_type_flap_statistics
10743 || type == bgp_show_type_flap_neighbor)
10744 vty_out(vty, BGP_SHOW_FLAP_HEADER);
10745 else
10746 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
10747 : BGP_SHOW_HEADER));
10748 header = 0;
10749 }
10750 if (rd != NULL && !display && !output_count) {
10751 if (!use_json)
10752 vty_out(vty,
10753 "Route Distinguisher: %s\n",
10754 rd);
10755 }
10756 if (type == bgp_show_type_dampend_paths
10757 || type == bgp_show_type_damp_neighbor)
10758 damp_route_vty_out(vty, dest_p, pi, display,
10759 AFI_IP, safi, use_json,
10760 json_paths);
10761 else if (type == bgp_show_type_flap_statistics
10762 || type == bgp_show_type_flap_neighbor)
10763 flap_route_vty_out(vty, dest_p, pi, display,
10764 AFI_IP, safi, use_json,
10765 json_paths);
10766 else
10767 route_vty_out(vty, dest_p, pi, display, safi,
10768 json_paths, wide);
10769 display++;
10770 }
10771
10772 if (display) {
10773 output_count++;
10774 if (!use_json)
10775 continue;
10776
10777 /* encode prefix */
10778 if (dest_p->family == AF_FLOWSPEC) {
10779 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
10780
10781
10782 bgp_fs_nlri_get_string(
10783 (unsigned char *)
10784 dest_p->u.prefix_flowspec.ptr,
10785 dest_p->u.prefix_flowspec.prefixlen,
10786 retstr, NLRI_STRING_FORMAT_MIN, NULL,
10787 family2afi(dest_p->u
10788 .prefix_flowspec.family));
10789 if (first)
10790 vty_out(vty, "\"%s/%d\": ", retstr,
10791 dest_p->u.prefix_flowspec
10792 .prefixlen);
10793 else
10794 vty_out(vty, ",\"%s/%d\": ", retstr,
10795 dest_p->u.prefix_flowspec
10796 .prefixlen);
10797 } else {
10798 if (first)
10799 vty_out(vty, "\"%pFX\": ", dest_p);
10800 else
10801 vty_out(vty, ",\"%pFX\": ", dest_p);
10802 }
10803 vty_out(vty, "%s",
10804 json_object_to_json_string_ext(
10805 json_paths, JSON_C_TO_STRING_PRETTY));
10806 json_object_free(json_paths);
10807 json_paths = NULL;
10808 first = 0;
10809 } else
10810 json_object_free(json_paths);
10811 }
10812
10813 if (output_cum) {
10814 output_count += *output_cum;
10815 *output_cum = output_count;
10816 }
10817 if (total_cum) {
10818 total_count += *total_cum;
10819 *total_cum = total_count;
10820 }
10821 if (use_json) {
10822 if (rd) {
10823 vty_out(vty, " }%s ", (is_last ? "" : ","));
10824 }
10825 if (is_last) {
10826 unsigned long i;
10827 for (i = 0; i < *json_header_depth; ++i)
10828 vty_out(vty, " } ");
10829 if (!all)
10830 vty_out(vty, "\n");
10831 }
10832 } else {
10833 if (is_last) {
10834 /* No route is displayed */
10835 if (output_count == 0) {
10836 if (type == bgp_show_type_normal)
10837 vty_out(vty,
10838 "No BGP prefixes displayed, %ld exist\n",
10839 total_count);
10840 } else
10841 vty_out(vty,
10842 "\nDisplayed %ld routes and %ld total paths\n",
10843 output_count, total_count);
10844 }
10845 }
10846
10847 return CMD_SUCCESS;
10848 }
10849
10850 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
10851 struct bgp_table *table, struct prefix_rd *prd_match,
10852 enum bgp_show_type type, void *output_arg, bool use_json)
10853 {
10854 struct bgp_dest *dest, *next;
10855 unsigned long output_cum = 0;
10856 unsigned long total_cum = 0;
10857 unsigned long json_header_depth = 0;
10858 struct bgp_table *itable;
10859 bool show_msg;
10860 uint8_t show_flags = 0;
10861
10862 show_msg = (!use_json && type == bgp_show_type_normal);
10863
10864 if (use_json)
10865 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10866
10867 for (dest = bgp_table_top(table); dest; dest = next) {
10868 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10869
10870 next = bgp_route_next(dest);
10871 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
10872 continue;
10873
10874 itable = bgp_dest_get_bgp_table_info(dest);
10875 if (itable != NULL) {
10876 struct prefix_rd prd;
10877 char rd[RD_ADDRSTRLEN];
10878
10879 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
10880 prefix_rd2str(&prd, rd, sizeof(rd));
10881 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
10882 rd, next == NULL, &output_cum,
10883 &total_cum, &json_header_depth,
10884 show_flags);
10885 if (next == NULL)
10886 show_msg = false;
10887 }
10888 }
10889 if (show_msg) {
10890 if (output_cum == 0)
10891 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
10892 total_cum);
10893 else
10894 vty_out(vty,
10895 "\nDisplayed %ld routes and %ld total paths\n",
10896 output_cum, total_cum);
10897 }
10898 return CMD_SUCCESS;
10899 }
10900 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
10901 enum bgp_show_type type, void *output_arg,
10902 uint8_t show_flags)
10903 {
10904 struct bgp_table *table;
10905 unsigned long json_header_depth = 0;
10906 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10907
10908 if (bgp == NULL) {
10909 bgp = bgp_get_default();
10910 }
10911
10912 if (bgp == NULL) {
10913 if (!use_json)
10914 vty_out(vty, "No BGP process is configured\n");
10915 else
10916 vty_out(vty, "{}\n");
10917 return CMD_WARNING;
10918 }
10919
10920 table = bgp->rib[afi][safi];
10921 /* use MPLS and ENCAP specific shows until they are merged */
10922 if (safi == SAFI_MPLS_VPN) {
10923 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
10924 output_arg, use_json);
10925 }
10926
10927 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
10928 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
10929 output_arg, use_json,
10930 1, NULL, NULL);
10931 }
10932 /* labeled-unicast routes live in the unicast table */
10933 else if (safi == SAFI_LABELED_UNICAST)
10934 safi = SAFI_UNICAST;
10935
10936 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
10937 NULL, NULL, &json_header_depth, show_flags);
10938 }
10939
10940 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
10941 safi_t safi, uint8_t show_flags)
10942 {
10943 struct listnode *node, *nnode;
10944 struct bgp *bgp;
10945 int is_first = 1;
10946 bool route_output = false;
10947 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10948
10949 if (use_json)
10950 vty_out(vty, "{\n");
10951
10952 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
10953 route_output = true;
10954 if (use_json) {
10955 if (!is_first)
10956 vty_out(vty, ",\n");
10957 else
10958 is_first = 0;
10959
10960 vty_out(vty, "\"%s\":",
10961 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
10962 ? VRF_DEFAULT_NAME
10963 : bgp->name);
10964 } else {
10965 vty_out(vty, "\nInstance %s:\n",
10966 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
10967 ? VRF_DEFAULT_NAME
10968 : bgp->name);
10969 }
10970 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
10971 show_flags);
10972 }
10973
10974 if (use_json)
10975 vty_out(vty, "}\n");
10976 else if (!route_output)
10977 vty_out(vty, "%% BGP instance not found\n");
10978 }
10979
10980 /* Header of detailed BGP route information */
10981 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
10982 struct bgp_dest *dest, struct prefix_rd *prd,
10983 afi_t afi, safi_t safi, json_object *json)
10984 {
10985 struct bgp_path_info *pi;
10986 const struct prefix *p;
10987 struct peer *peer;
10988 struct listnode *node, *nnode;
10989 char buf1[RD_ADDRSTRLEN];
10990 char prefix_str[BUFSIZ];
10991 int count = 0;
10992 int best = 0;
10993 int suppress = 0;
10994 int accept_own = 0;
10995 int route_filter_translated_v4 = 0;
10996 int route_filter_v4 = 0;
10997 int route_filter_translated_v6 = 0;
10998 int route_filter_v6 = 0;
10999 int llgr_stale = 0;
11000 int no_llgr = 0;
11001 int accept_own_nexthop = 0;
11002 int blackhole = 0;
11003 int no_export = 0;
11004 int no_advertise = 0;
11005 int local_as = 0;
11006 int no_peer = 0;
11007 int first = 1;
11008 int has_valid_label = 0;
11009 mpls_label_t label = 0;
11010 json_object *json_adv_to = NULL;
11011
11012 p = bgp_dest_get_prefix(dest);
11013 has_valid_label = bgp_is_valid_label(&dest->local_label);
11014
11015 if (has_valid_label)
11016 label = label_pton(&dest->local_label);
11017
11018 if (safi == SAFI_EVPN) {
11019
11020 if (!json) {
11021 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11022 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
11023 : "",
11024 prd ? ":" : "", (struct prefix_evpn *)p);
11025 } else {
11026 json_object_string_add(json, "rd",
11027 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11028 "");
11029 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11030 }
11031 } else {
11032 if (!json) {
11033 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11034 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11035 ? prefix_rd2str(prd, buf1,
11036 sizeof(buf1))
11037 : ""),
11038 safi == SAFI_MPLS_VPN ? ":" : "", p);
11039
11040 } else
11041 json_object_string_add(json, "prefix",
11042 prefix2str(p, prefix_str, sizeof(prefix_str)));
11043 }
11044
11045 if (has_valid_label) {
11046 if (json)
11047 json_object_int_add(json, "localLabel", label);
11048 else
11049 vty_out(vty, "Local label: %d\n", label);
11050 }
11051
11052 if (!json)
11053 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11054 vty_out(vty, "not allocated\n");
11055
11056 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11057 count++;
11058 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11059 best = count;
11060 if (bgp_path_suppressed(pi))
11061 suppress = 1;
11062
11063 if (pi->attr->community == NULL)
11064 continue;
11065
11066 no_advertise += community_include(
11067 pi->attr->community, COMMUNITY_NO_ADVERTISE);
11068 no_export += community_include(pi->attr->community,
11069 COMMUNITY_NO_EXPORT);
11070 local_as += community_include(pi->attr->community,
11071 COMMUNITY_LOCAL_AS);
11072 accept_own += community_include(pi->attr->community,
11073 COMMUNITY_ACCEPT_OWN);
11074 route_filter_translated_v4 += community_include(
11075 pi->attr->community,
11076 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11077 route_filter_translated_v6 += community_include(
11078 pi->attr->community,
11079 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11080 route_filter_v4 += community_include(
11081 pi->attr->community, COMMUNITY_ROUTE_FILTER_v4);
11082 route_filter_v6 += community_include(
11083 pi->attr->community, COMMUNITY_ROUTE_FILTER_v6);
11084 llgr_stale += community_include(pi->attr->community,
11085 COMMUNITY_LLGR_STALE);
11086 no_llgr += community_include(pi->attr->community,
11087 COMMUNITY_NO_LLGR);
11088 accept_own_nexthop +=
11089 community_include(pi->attr->community,
11090 COMMUNITY_ACCEPT_OWN_NEXTHOP);
11091 blackhole += community_include(pi->attr->community,
11092 COMMUNITY_BLACKHOLE);
11093 no_peer += community_include(pi->attr->community,
11094 COMMUNITY_NO_PEER);
11095 }
11096 }
11097
11098 if (!json) {
11099 vty_out(vty, "Paths: (%d available", count);
11100 if (best) {
11101 vty_out(vty, ", best #%d", best);
11102 if (safi == SAFI_UNICAST) {
11103 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11104 vty_out(vty, ", table %s",
11105 VRF_DEFAULT_NAME);
11106 else
11107 vty_out(vty, ", vrf %s",
11108 bgp->name);
11109 }
11110 } else
11111 vty_out(vty, ", no best path");
11112
11113 if (accept_own)
11114 vty_out(vty,
11115 ", accept own local route exported and imported in different VRF");
11116 else if (route_filter_translated_v4)
11117 vty_out(vty,
11118 ", mark translated RTs for VPNv4 route filtering");
11119 else if (route_filter_v4)
11120 vty_out(vty,
11121 ", attach RT as-is for VPNv4 route filtering");
11122 else if (route_filter_translated_v6)
11123 vty_out(vty,
11124 ", mark translated RTs for VPNv6 route filtering");
11125 else if (route_filter_v6)
11126 vty_out(vty,
11127 ", attach RT as-is for VPNv6 route filtering");
11128 else if (llgr_stale)
11129 vty_out(vty,
11130 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
11131 else if (no_llgr)
11132 vty_out(vty,
11133 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11134 else if (accept_own_nexthop)
11135 vty_out(vty,
11136 ", accept local nexthop");
11137 else if (blackhole)
11138 vty_out(vty, ", inform peer to blackhole prefix");
11139 else if (no_export)
11140 vty_out(vty, ", not advertised to EBGP peer");
11141 else if (no_advertise)
11142 vty_out(vty, ", not advertised to any peer");
11143 else if (local_as)
11144 vty_out(vty, ", not advertised outside local AS");
11145 else if (no_peer)
11146 vty_out(vty,
11147 ", inform EBGP peer not to advertise to their EBGP peers");
11148
11149 if (suppress)
11150 vty_out(vty,
11151 ", Advertisements suppressed by an aggregate.");
11152 vty_out(vty, ")\n");
11153 }
11154
11155 /* If we are not using addpath then we can display Advertised to and
11156 * that will
11157 * show what peers we advertised the bestpath to. If we are using
11158 * addpath
11159 * though then we must display Advertised to on a path-by-path basis. */
11160 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11161 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11162 if (bgp_adj_out_lookup(peer, dest, 0)) {
11163 if (json && !json_adv_to)
11164 json_adv_to = json_object_new_object();
11165
11166 route_vty_out_advertised_to(
11167 vty, peer, &first,
11168 " Advertised to non peer-group peers:\n ",
11169 json_adv_to);
11170 }
11171 }
11172
11173 if (json) {
11174 if (json_adv_to) {
11175 json_object_object_add(json, "advertisedTo",
11176 json_adv_to);
11177 }
11178 } else {
11179 if (first)
11180 vty_out(vty, " Not advertised to any peer");
11181 vty_out(vty, "\n");
11182 }
11183 }
11184 }
11185
11186 static void bgp_show_path_info(struct prefix_rd *pfx_rd,
11187 struct bgp_dest *bgp_node, struct vty *vty,
11188 struct bgp *bgp, afi_t afi, safi_t safi,
11189 json_object *json, enum bgp_path_type pathtype,
11190 int *display)
11191 {
11192 struct bgp_path_info *pi;
11193 int header = 1;
11194 char rdbuf[RD_ADDRSTRLEN];
11195 json_object *json_header = NULL;
11196 json_object *json_paths = NULL;
11197
11198 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
11199
11200 if (json && !json_paths) {
11201 /* Instantiate json_paths only if path is valid */
11202 json_paths = json_object_new_array();
11203 if (pfx_rd) {
11204 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
11205 json_header = json_object_new_object();
11206 } else
11207 json_header = json;
11208 }
11209
11210 if (header) {
11211 route_vty_out_detail_header(
11212 vty, bgp, bgp_node, pfx_rd,
11213 AFI_IP, safi, json_header);
11214 header = 0;
11215 }
11216 (*display)++;
11217
11218 if (pathtype == BGP_PATH_SHOW_ALL
11219 || (pathtype == BGP_PATH_SHOW_BESTPATH
11220 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
11221 || (pathtype == BGP_PATH_SHOW_MULTIPATH
11222 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
11223 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
11224 route_vty_out_detail(vty, bgp, bgp_node,
11225 pi, AFI_IP, safi,
11226 json_paths);
11227 }
11228
11229 if (json && json_paths) {
11230 json_object_object_add(json_header, "paths", json_paths);
11231
11232 if (pfx_rd)
11233 json_object_object_add(json, rdbuf, json_header);
11234 }
11235 }
11236
11237 /* Display specified route of BGP table. */
11238 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
11239 struct bgp_table *rib, const char *ip_str,
11240 afi_t afi, safi_t safi,
11241 struct prefix_rd *prd, int prefix_check,
11242 enum bgp_path_type pathtype, bool use_json)
11243 {
11244 int ret;
11245 int display = 0;
11246 struct prefix match;
11247 struct bgp_dest *dest;
11248 struct bgp_dest *rm;
11249 struct bgp_table *table;
11250 json_object *json = NULL;
11251 json_object *json_paths = NULL;
11252
11253 /* Check IP address argument. */
11254 ret = str2prefix(ip_str, &match);
11255 if (!ret) {
11256 vty_out(vty, "address is malformed\n");
11257 return CMD_WARNING;
11258 }
11259
11260 match.family = afi2family(afi);
11261
11262 if (use_json)
11263 json = json_object_new_object();
11264
11265 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
11266 for (dest = bgp_table_top(rib); dest;
11267 dest = bgp_route_next(dest)) {
11268 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11269
11270 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
11271 continue;
11272 table = bgp_dest_get_bgp_table_info(dest);
11273 if (!table)
11274 continue;
11275
11276 if ((rm = bgp_node_match(table, &match)) == NULL)
11277 continue;
11278
11279 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
11280 if (prefix_check
11281 && rm_p->prefixlen != match.prefixlen) {
11282 bgp_dest_unlock_node(rm);
11283 continue;
11284 }
11285
11286 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11287 bgp, afi, safi, json, pathtype,
11288 &display);
11289
11290 bgp_dest_unlock_node(rm);
11291 }
11292 } else if (safi == SAFI_EVPN) {
11293 struct bgp_dest *longest_pfx;
11294 bool is_exact_pfxlen_match = false;
11295
11296 for (dest = bgp_table_top(rib); dest;
11297 dest = bgp_route_next(dest)) {
11298 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11299
11300 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
11301 continue;
11302 table = bgp_dest_get_bgp_table_info(dest);
11303 if (!table)
11304 continue;
11305
11306 longest_pfx = NULL;
11307 is_exact_pfxlen_match = false;
11308 /*
11309 * Search through all the prefixes for a match. The
11310 * pfx's are enumerated in ascending order of pfxlens.
11311 * So, the last pfx match is the longest match. Set
11312 * is_exact_pfxlen_match when we get exact pfxlen match
11313 */
11314 for (rm = bgp_table_top(table); rm;
11315 rm = bgp_route_next(rm)) {
11316 const struct prefix *rm_p =
11317 bgp_dest_get_prefix(rm);
11318 /*
11319 * Get prefixlen of the ip-prefix within type5
11320 * evpn route
11321 */
11322 if (evpn_type5_prefix_match(rm_p, &match)
11323 && rm->info) {
11324 longest_pfx = rm;
11325 int type5_pfxlen =
11326 bgp_evpn_get_type5_prefixlen(
11327 rm_p);
11328 if (type5_pfxlen == match.prefixlen) {
11329 is_exact_pfxlen_match = true;
11330 bgp_dest_unlock_node(rm);
11331 break;
11332 }
11333 }
11334 }
11335
11336 if (!longest_pfx)
11337 continue;
11338
11339 if (prefix_check && !is_exact_pfxlen_match)
11340 continue;
11341
11342 rm = longest_pfx;
11343 bgp_dest_lock_node(rm);
11344
11345 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11346 bgp, afi, safi, json, pathtype,
11347 &display);
11348
11349 bgp_dest_unlock_node(rm);
11350 }
11351 } else if (safi == SAFI_FLOWSPEC) {
11352 if (use_json)
11353 json_paths = json_object_new_array();
11354
11355 display = bgp_flowspec_display_match_per_ip(afi, rib,
11356 &match, prefix_check,
11357 vty,
11358 use_json,
11359 json_paths);
11360 if (use_json) {
11361 if (display)
11362 json_object_object_add(json, "paths",
11363 json_paths);
11364 else
11365 json_object_free(json_paths);
11366 }
11367 } else {
11368 if ((dest = bgp_node_match(rib, &match)) != NULL) {
11369 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11370 if (!prefix_check
11371 || dest_p->prefixlen == match.prefixlen) {
11372 bgp_show_path_info(NULL, dest, vty, bgp, afi,
11373 safi, json, pathtype,
11374 &display);
11375 }
11376
11377 bgp_dest_unlock_node(dest);
11378 }
11379 }
11380
11381 if (use_json) {
11382 vty_out(vty, "%s\n", json_object_to_json_string_ext(
11383 json, JSON_C_TO_STRING_PRETTY |
11384 JSON_C_TO_STRING_NOSLASHESCAPE));
11385 json_object_free(json);
11386 } else {
11387 if (!display) {
11388 vty_out(vty, "%% Network not in table\n");
11389 return CMD_WARNING;
11390 }
11391 }
11392
11393 return CMD_SUCCESS;
11394 }
11395
11396 /* Display specified route of Main RIB */
11397 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
11398 afi_t afi, safi_t safi, struct prefix_rd *prd,
11399 int prefix_check, enum bgp_path_type pathtype,
11400 bool use_json)
11401 {
11402 if (!bgp) {
11403 bgp = bgp_get_default();
11404 if (!bgp) {
11405 if (!use_json)
11406 vty_out(vty, "No BGP process is configured\n");
11407 else
11408 vty_out(vty, "{}\n");
11409 return CMD_WARNING;
11410 }
11411 }
11412
11413 /* labeled-unicast routes live in the unicast table */
11414 if (safi == SAFI_LABELED_UNICAST)
11415 safi = SAFI_UNICAST;
11416
11417 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
11418 afi, safi, prd, prefix_check, pathtype,
11419 use_json);
11420 }
11421
11422 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
11423 struct cmd_token **argv, bool exact, afi_t afi,
11424 safi_t safi, bool uj)
11425 {
11426 struct lcommunity *lcom;
11427 struct buffer *b;
11428 int i;
11429 char *str;
11430 int first = 0;
11431 uint8_t show_flags = 0;
11432 int ret;
11433
11434 if (uj)
11435 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11436
11437 b = buffer_new(1024);
11438 for (i = 0; i < argc; i++) {
11439 if (first)
11440 buffer_putc(b, ' ');
11441 else {
11442 if (strmatch(argv[i]->text, "AA:BB:CC")) {
11443 first = 1;
11444 buffer_putstr(b, argv[i]->arg);
11445 }
11446 }
11447 }
11448 buffer_putc(b, '\0');
11449
11450 str = buffer_getstr(b);
11451 buffer_free(b);
11452
11453 lcom = lcommunity_str2com(str);
11454 XFREE(MTYPE_TMP, str);
11455 if (!lcom) {
11456 vty_out(vty, "%% Large-community malformed\n");
11457 return CMD_WARNING;
11458 }
11459
11460 ret = bgp_show(vty, bgp, afi, safi,
11461 (exact ? bgp_show_type_lcommunity_exact
11462 : bgp_show_type_lcommunity),
11463 lcom, show_flags);
11464
11465 lcommunity_free(&lcom);
11466 return ret;
11467 }
11468
11469 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
11470 const char *lcom, bool exact, afi_t afi,
11471 safi_t safi, bool uj)
11472 {
11473 struct community_list *list;
11474 uint8_t show_flags = 0;
11475
11476 if (uj)
11477 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11478
11479
11480 list = community_list_lookup(bgp_clist, lcom, 0,
11481 LARGE_COMMUNITY_LIST_MASTER);
11482 if (list == NULL) {
11483 vty_out(vty, "%% %s is not a valid large-community-list name\n",
11484 lcom);
11485 return CMD_WARNING;
11486 }
11487
11488 return bgp_show(vty, bgp, afi, safi,
11489 (exact ? bgp_show_type_lcommunity_list_exact
11490 : bgp_show_type_lcommunity_list),
11491 list, show_flags);
11492 }
11493
11494 DEFUN (show_ip_bgp_large_community_list,
11495 show_ip_bgp_large_community_list_cmd,
11496 "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]",
11497 SHOW_STR
11498 IP_STR
11499 BGP_STR
11500 BGP_INSTANCE_HELP_STR
11501 BGP_AFI_HELP_STR
11502 BGP_SAFI_WITH_LABEL_HELP_STR
11503 "Display routes matching the large-community-list\n"
11504 "large-community-list number\n"
11505 "large-community-list name\n"
11506 "Exact match of the large-communities\n"
11507 JSON_STR)
11508 {
11509 afi_t afi = AFI_IP6;
11510 safi_t safi = SAFI_UNICAST;
11511 int idx = 0;
11512 bool exact_match = 0;
11513 struct bgp *bgp = NULL;
11514 bool uj = use_json(argc, argv);
11515
11516 if (uj)
11517 argc--;
11518
11519 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11520 &bgp, uj);
11521 if (!idx)
11522 return CMD_WARNING;
11523
11524 argv_find(argv, argc, "large-community-list", &idx);
11525
11526 const char *clist_number_or_name = argv[++idx]->arg;
11527
11528 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
11529 exact_match = 1;
11530
11531 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
11532 exact_match, afi, safi, uj);
11533 }
11534 DEFUN (show_ip_bgp_large_community,
11535 show_ip_bgp_large_community_cmd,
11536 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
11537 SHOW_STR
11538 IP_STR
11539 BGP_STR
11540 BGP_INSTANCE_HELP_STR
11541 BGP_AFI_HELP_STR
11542 BGP_SAFI_WITH_LABEL_HELP_STR
11543 "Display routes matching the large-communities\n"
11544 "List of large-community numbers\n"
11545 "Exact match of the large-communities\n"
11546 JSON_STR)
11547 {
11548 afi_t afi = AFI_IP6;
11549 safi_t safi = SAFI_UNICAST;
11550 int idx = 0;
11551 bool exact_match = 0;
11552 struct bgp *bgp = NULL;
11553 bool uj = use_json(argc, argv);
11554 uint8_t show_flags = 0;
11555
11556 if (uj) {
11557 argc--;
11558 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11559 }
11560
11561 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11562 &bgp, uj);
11563 if (!idx)
11564 return CMD_WARNING;
11565
11566 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
11567 if (argv_find(argv, argc, "exact-match", &idx))
11568 exact_match = 1;
11569 return bgp_show_lcommunity(vty, bgp, argc, argv,
11570 exact_match, afi, safi, uj);
11571 } else
11572 return bgp_show(vty, bgp, afi, safi,
11573 bgp_show_type_lcommunity_all, NULL, show_flags);
11574 }
11575
11576 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
11577 safi_t safi, struct json_object *json_array);
11578 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
11579 safi_t safi, struct json_object *json);
11580
11581
11582 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
11583 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
11584 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
11585 "Display number of prefixes for all afi/safi\n" JSON_STR)
11586 {
11587 bool uj = use_json(argc, argv);
11588 struct bgp *bgp = NULL;
11589 safi_t safi = SAFI_UNICAST;
11590 afi_t afi = AFI_IP6;
11591 int idx = 0;
11592 struct json_object *json_all = NULL;
11593 struct json_object *json_afi_safi = NULL;
11594
11595 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11596 &bgp, false);
11597 if (!idx)
11598 return CMD_WARNING;
11599
11600 if (uj)
11601 json_all = json_object_new_object();
11602
11603 FOREACH_AFI_SAFI (afi, safi) {
11604 /*
11605 * So limit output to those afi/safi pairs that
11606 * actually have something interesting in them
11607 */
11608 if (strmatch(get_afi_safi_str(afi, safi, true),
11609 "Unknown")) {
11610 continue;
11611 }
11612 if (uj) {
11613 json_afi_safi = json_object_new_array();
11614 json_object_object_add(
11615 json_all,
11616 get_afi_safi_str(afi, safi, true),
11617 json_afi_safi);
11618 } else {
11619 json_afi_safi = NULL;
11620 }
11621
11622 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
11623 }
11624
11625 if (uj) {
11626 vty_out(vty, "%s",
11627 json_object_to_json_string_ext(
11628 json_all, JSON_C_TO_STRING_PRETTY));
11629 json_object_free(json_all);
11630 }
11631
11632 return CMD_SUCCESS;
11633 }
11634
11635 /* BGP route print out function without JSON */
11636 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
11637 show_ip_bgp_l2vpn_evpn_statistics_cmd,
11638 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
11639 SHOW_STR
11640 IP_STR
11641 BGP_STR
11642 BGP_INSTANCE_HELP_STR
11643 L2VPN_HELP_STR
11644 EVPN_HELP_STR
11645 "BGP RIB advertisement statistics\n"
11646 JSON_STR)
11647 {
11648 afi_t afi = AFI_IP6;
11649 safi_t safi = SAFI_UNICAST;
11650 struct bgp *bgp = NULL;
11651 int idx = 0, ret;
11652 bool uj = use_json(argc, argv);
11653 struct json_object *json_afi_safi = NULL, *json = NULL;
11654
11655 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11656 &bgp, false);
11657 if (!idx)
11658 return CMD_WARNING;
11659
11660 if (uj)
11661 json_afi_safi = json_object_new_array();
11662 else
11663 json_afi_safi = NULL;
11664
11665 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
11666
11667 if (uj) {
11668 json = json_object_new_object();
11669 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
11670 json_afi_safi);
11671 vty_out(vty, "%s", json_object_to_json_string_ext(
11672 json, JSON_C_TO_STRING_PRETTY));
11673 json_object_free(json);
11674 }
11675 return ret;
11676 }
11677
11678 /* BGP route print out function without JSON */
11679 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
11680 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
11681 " [" BGP_SAFI_WITH_LABEL_CMD_STR
11682 "]]\
11683 statistics [json]",
11684 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
11685 BGP_SAFI_WITH_LABEL_HELP_STR
11686 "BGP RIB advertisement statistics\n" JSON_STR)
11687 {
11688 afi_t afi = AFI_IP6;
11689 safi_t safi = SAFI_UNICAST;
11690 struct bgp *bgp = NULL;
11691 int idx = 0, ret;
11692 bool uj = use_json(argc, argv);
11693 struct json_object *json_afi_safi = NULL, *json = NULL;
11694
11695 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11696 &bgp, false);
11697 if (!idx)
11698 return CMD_WARNING;
11699
11700 if (uj)
11701 json_afi_safi = json_object_new_array();
11702 else
11703 json_afi_safi = NULL;
11704
11705 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
11706
11707 if (uj) {
11708 json = json_object_new_object();
11709 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
11710 json_afi_safi);
11711 vty_out(vty, "%s",
11712 json_object_to_json_string_ext(
11713 json, JSON_C_TO_STRING_PRETTY));
11714 json_object_free(json);
11715 }
11716 return ret;
11717 }
11718
11719 /* BGP route print out function without JSON */
11720 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
11721 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
11722 " [" BGP_SAFI_WITH_LABEL_CMD_STR
11723 "]]\
11724 <[all$all] dampening <parameters>\
11725 |route-map WORD\
11726 |prefix-list WORD\
11727 |filter-list WORD\
11728 |community-list <(1-500)|WORD> [exact-match]\
11729 |A.B.C.D/M longer-prefixes\
11730 |X:X::X:X/M longer-prefixes\
11731 >",
11732 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
11733 BGP_SAFI_WITH_LABEL_HELP_STR
11734 "Display the entries for all address families\n"
11735 "Display detailed information about dampening\n"
11736 "Display detail of configured dampening parameters\n"
11737 "Display routes matching the route-map\n"
11738 "A route-map to match on\n"
11739 "Display routes conforming to the prefix-list\n"
11740 "Prefix-list name\n"
11741 "Display routes conforming to the filter-list\n"
11742 "Regular expression access list name\n"
11743 "Display routes matching the community-list\n"
11744 "community-list number\n"
11745 "community-list name\n"
11746 "Exact match of the communities\n"
11747 "IPv4 prefix\n"
11748 "Display route and more specific routes\n"
11749 "IPv6 prefix\n"
11750 "Display route and more specific routes\n")
11751 {
11752 afi_t afi = AFI_IP6;
11753 safi_t safi = SAFI_UNICAST;
11754 int exact_match = 0;
11755 struct bgp *bgp = NULL;
11756 int idx = 0;
11757 uint8_t show_flags = 0;
11758
11759 /* [<ipv4|ipv6> [all]] */
11760 if (all) {
11761 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11762 if (argv_find(argv, argc, "ipv4", &idx))
11763 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
11764
11765 if (argv_find(argv, argc, "ipv6", &idx))
11766 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
11767 }
11768
11769 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11770 &bgp, false);
11771 if (!idx)
11772 return CMD_WARNING;
11773
11774 if (argv_find(argv, argc, "dampening", &idx)) {
11775 if (argv_find(argv, argc, "parameters", &idx))
11776 return bgp_show_dampening_parameters(vty, afi, safi,
11777 show_flags);
11778 }
11779
11780 if (argv_find(argv, argc, "prefix-list", &idx))
11781 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
11782 safi, bgp_show_type_prefix_list);
11783
11784 if (argv_find(argv, argc, "filter-list", &idx))
11785 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
11786 safi, bgp_show_type_filter_list);
11787
11788 if (argv_find(argv, argc, "route-map", &idx))
11789 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
11790 safi, bgp_show_type_route_map);
11791
11792 if (argv_find(argv, argc, "community-list", &idx)) {
11793 const char *clist_number_or_name = argv[++idx]->arg;
11794 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
11795 exact_match = 1;
11796 return bgp_show_community_list(vty, bgp, clist_number_or_name,
11797 exact_match, afi, safi);
11798 }
11799 /* prefix-longer */
11800 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
11801 || argv_find(argv, argc, "X:X::X:X/M", &idx))
11802 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
11803 safi,
11804 bgp_show_type_prefix_longer);
11805
11806 return CMD_WARNING;
11807 }
11808
11809 /* BGP route print out function with JSON */
11810 DEFPY (show_ip_bgp_json,
11811 show_ip_bgp_json_cmd,
11812 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
11813 [all$all]\
11814 [cidr-only\
11815 |dampening <flap-statistics|dampened-paths>\
11816 |community [AA:NN|local-AS|no-advertise|no-export\
11817 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
11818 |accept-own|accept-own-nexthop|route-filter-v6\
11819 |route-filter-v4|route-filter-translated-v6\
11820 |route-filter-translated-v4] [exact-match]\
11821 ] [json$uj | wide$wide]",
11822 SHOW_STR
11823 IP_STR
11824 BGP_STR
11825 BGP_INSTANCE_HELP_STR
11826 BGP_AFI_HELP_STR
11827 BGP_SAFI_WITH_LABEL_HELP_STR
11828 "Display the entries for all address families\n"
11829 "Display only routes with non-natural netmasks\n"
11830 "Display detailed information about dampening\n"
11831 "Display flap statistics of routes\n"
11832 "Display paths suppressed due to dampening\n"
11833 "Display routes matching the communities\n"
11834 COMMUNITY_AANN_STR
11835 "Do not send outside local AS (well-known community)\n"
11836 "Do not advertise to any peer (well-known community)\n"
11837 "Do not export to next AS (well-known community)\n"
11838 "Graceful shutdown (well-known community)\n"
11839 "Do not export to any peer (well-known community)\n"
11840 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
11841 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
11842 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
11843 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
11844 "Should accept VPN route with local nexthop (well-known community)\n"
11845 "RT VPNv6 route filtering (well-known community)\n"
11846 "RT VPNv4 route filtering (well-known community)\n"
11847 "RT translated VPNv6 route filtering (well-known community)\n"
11848 "RT translated VPNv4 route filtering (well-known community)\n"
11849 "Exact match of the communities\n"
11850 JSON_STR
11851 "Increase table width for longer prefixes\n")
11852 {
11853 afi_t afi = AFI_IP6;
11854 safi_t safi = SAFI_UNICAST;
11855 enum bgp_show_type sh_type = bgp_show_type_normal;
11856 struct bgp *bgp = NULL;
11857 int idx = 0;
11858 int exact_match = 0;
11859 char *community = NULL;
11860 bool first = true;
11861 uint8_t show_flags = 0;
11862
11863
11864 if (uj) {
11865 argc--;
11866 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11867 }
11868
11869 /* [<ipv4|ipv6> [all]] */
11870 if (all) {
11871 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11872
11873 if (argv_find(argv, argc, "ipv4", &idx))
11874 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
11875
11876 if (argv_find(argv, argc, "ipv6", &idx))
11877 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
11878 }
11879
11880 if (wide)
11881 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11882
11883 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11884 &bgp, uj);
11885 if (!idx)
11886 return CMD_WARNING;
11887
11888 if (argv_find(argv, argc, "cidr-only", &idx))
11889 sh_type = bgp_show_type_cidr_only;
11890
11891 if (argv_find(argv, argc, "dampening", &idx)) {
11892 if (argv_find(argv, argc, "dampened-paths", &idx))
11893 sh_type = bgp_show_type_dampend_paths;
11894 else if (argv_find(argv, argc, "flap-statistics", &idx))
11895 sh_type = bgp_show_type_flap_statistics;
11896 }
11897
11898 if (argv_find(argv, argc, "community", &idx)) {
11899 char *maybecomm = NULL;
11900
11901 if (idx + 1 < argc) {
11902 if (argv[idx + 1]->type == VARIABLE_TKN)
11903 maybecomm = argv[idx + 1]->arg;
11904 else
11905 maybecomm = argv[idx + 1]->text;
11906 }
11907
11908 if (maybecomm && !strmatch(maybecomm, "json")
11909 && !strmatch(maybecomm, "exact-match"))
11910 community = maybecomm;
11911
11912 if (argv_find(argv, argc, "exact-match", &idx))
11913 exact_match = 1;
11914
11915 if (!community)
11916 sh_type = bgp_show_type_community_all;
11917 }
11918
11919 if (!all) {
11920 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
11921 if (community)
11922 return bgp_show_community(vty, bgp, community,
11923 exact_match, afi, safi,
11924 show_flags);
11925 else
11926 return bgp_show(vty, bgp, afi, safi, sh_type, NULL,
11927 show_flags);
11928 } else {
11929 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
11930 * AFI_IP6 */
11931
11932 if (uj)
11933 vty_out(vty, "{\n");
11934
11935 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
11936 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
11937 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
11938 ? AFI_IP
11939 : AFI_IP6;
11940 FOREACH_SAFI (safi) {
11941 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
11942 continue;
11943
11944 if (uj) {
11945 if (first)
11946 first = false;
11947 else
11948 vty_out(vty, ",\n");
11949 vty_out(vty, "\"%s\":{\n",
11950 get_afi_safi_str(afi, safi,
11951 true));
11952 } else
11953 vty_out(vty,
11954 "\nFor address family: %s\n",
11955 get_afi_safi_str(afi, safi,
11956 false));
11957
11958 if (community)
11959 bgp_show_community(vty, bgp, community,
11960 exact_match, afi,
11961 safi, show_flags);
11962 else
11963 bgp_show(vty, bgp, afi, safi, sh_type,
11964 NULL, show_flags);
11965 if (uj)
11966 vty_out(vty, "}\n");
11967 }
11968 } else {
11969 /* show <ip> bgp all: for each AFI and SAFI*/
11970 FOREACH_AFI_SAFI (afi, safi) {
11971 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
11972 continue;
11973
11974 if (uj) {
11975 if (first)
11976 first = false;
11977 else
11978 vty_out(vty, ",\n");
11979
11980 vty_out(vty, "\"%s\":{\n",
11981 get_afi_safi_str(afi, safi,
11982 true));
11983 } else
11984 vty_out(vty,
11985 "\nFor address family: %s\n",
11986 get_afi_safi_str(afi, safi,
11987 false));
11988
11989 if (community)
11990 bgp_show_community(vty, bgp, community,
11991 exact_match, afi,
11992 safi, show_flags);
11993 else
11994 bgp_show(vty, bgp, afi, safi, sh_type,
11995 NULL, show_flags);
11996 if (uj)
11997 vty_out(vty, "}\n");
11998 }
11999 }
12000 if (uj)
12001 vty_out(vty, "}\n");
12002 }
12003 return CMD_SUCCESS;
12004 }
12005
12006 DEFUN (show_ip_bgp_route,
12007 show_ip_bgp_route_cmd,
12008 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
12009 SHOW_STR
12010 IP_STR
12011 BGP_STR
12012 BGP_INSTANCE_HELP_STR
12013 BGP_AFI_HELP_STR
12014 BGP_SAFI_WITH_LABEL_HELP_STR
12015 "Network in the BGP routing table to display\n"
12016 "IPv4 prefix\n"
12017 "Network in the BGP routing table to display\n"
12018 "IPv6 prefix\n"
12019 "Display only the bestpath\n"
12020 "Display only multipaths\n"
12021 JSON_STR)
12022 {
12023 int prefix_check = 0;
12024
12025 afi_t afi = AFI_IP6;
12026 safi_t safi = SAFI_UNICAST;
12027 char *prefix = NULL;
12028 struct bgp *bgp = NULL;
12029 enum bgp_path_type path_type;
12030 bool uj = use_json(argc, argv);
12031
12032 int idx = 0;
12033
12034 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12035 &bgp, uj);
12036 if (!idx)
12037 return CMD_WARNING;
12038
12039 if (!bgp) {
12040 vty_out(vty,
12041 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
12042 return CMD_WARNING;
12043 }
12044
12045 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
12046 if (argv_find(argv, argc, "A.B.C.D", &idx)
12047 || argv_find(argv, argc, "X:X::X:X", &idx))
12048 prefix_check = 0;
12049 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12050 || argv_find(argv, argc, "X:X::X:X/M", &idx))
12051 prefix_check = 1;
12052
12053 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
12054 && afi != AFI_IP6) {
12055 vty_out(vty,
12056 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
12057 return CMD_WARNING;
12058 }
12059 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
12060 && afi != AFI_IP) {
12061 vty_out(vty,
12062 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
12063 return CMD_WARNING;
12064 }
12065
12066 prefix = argv[idx]->arg;
12067
12068 /* [<bestpath|multipath>] */
12069 if (argv_find(argv, argc, "bestpath", &idx))
12070 path_type = BGP_PATH_SHOW_BESTPATH;
12071 else if (argv_find(argv, argc, "multipath", &idx))
12072 path_type = BGP_PATH_SHOW_MULTIPATH;
12073 else
12074 path_type = BGP_PATH_SHOW_ALL;
12075
12076 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
12077 path_type, uj);
12078 }
12079
12080 DEFUN (show_ip_bgp_regexp,
12081 show_ip_bgp_regexp_cmd,
12082 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
12083 SHOW_STR
12084 IP_STR
12085 BGP_STR
12086 BGP_INSTANCE_HELP_STR
12087 BGP_AFI_HELP_STR
12088 BGP_SAFI_WITH_LABEL_HELP_STR
12089 "Display routes matching the AS path regular expression\n"
12090 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
12091 JSON_STR)
12092 {
12093 afi_t afi = AFI_IP6;
12094 safi_t safi = SAFI_UNICAST;
12095 struct bgp *bgp = NULL;
12096 bool uj = use_json(argc, argv);
12097 char *regstr = NULL;
12098
12099 int idx = 0;
12100 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12101 &bgp, false);
12102 if (!idx)
12103 return CMD_WARNING;
12104
12105 // get index of regex
12106 if (argv_find(argv, argc, "REGEX", &idx))
12107 regstr = argv[idx]->arg;
12108
12109 assert(regstr);
12110 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
12111 bgp_show_type_regexp, uj);
12112 }
12113
12114 DEFPY (show_ip_bgp_instance_all,
12115 show_ip_bgp_instance_all_cmd,
12116 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
12117 SHOW_STR
12118 IP_STR
12119 BGP_STR
12120 BGP_INSTANCE_ALL_HELP_STR
12121 BGP_AFI_HELP_STR
12122 BGP_SAFI_WITH_LABEL_HELP_STR
12123 JSON_STR
12124 "Increase table width for longer prefixes\n")
12125 {
12126 afi_t afi = AFI_IP;
12127 safi_t safi = SAFI_UNICAST;
12128 struct bgp *bgp = NULL;
12129 int idx = 0;
12130 uint8_t show_flags = 0;
12131
12132 if (uj) {
12133 argc--;
12134 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12135 }
12136
12137 if (wide)
12138 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12139
12140 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12141 &bgp, uj);
12142 if (!idx)
12143 return CMD_WARNING;
12144
12145 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
12146 return CMD_SUCCESS;
12147 }
12148
12149 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
12150 afi_t afi, safi_t safi, enum bgp_show_type type,
12151 bool use_json)
12152 {
12153 regex_t *regex;
12154 int rc;
12155 uint8_t show_flags = 0;
12156
12157 if (use_json)
12158 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12159
12160 if (!config_bgp_aspath_validate(regstr)) {
12161 vty_out(vty, "Invalid character in REGEX %s\n",
12162 regstr);
12163 return CMD_WARNING_CONFIG_FAILED;
12164 }
12165
12166 regex = bgp_regcomp(regstr);
12167 if (!regex) {
12168 vty_out(vty, "Can't compile regexp %s\n", regstr);
12169 return CMD_WARNING;
12170 }
12171
12172 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags);
12173 bgp_regex_free(regex);
12174 return rc;
12175 }
12176
12177 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
12178 const char *prefix_list_str, afi_t afi,
12179 safi_t safi, enum bgp_show_type type)
12180 {
12181 struct prefix_list *plist;
12182 uint8_t show_flags = 0;
12183
12184 plist = prefix_list_lookup(afi, prefix_list_str);
12185 if (plist == NULL) {
12186 vty_out(vty, "%% %s is not a valid prefix-list name\n",
12187 prefix_list_str);
12188 return CMD_WARNING;
12189 }
12190
12191 return bgp_show(vty, bgp, afi, safi, type, plist, show_flags);
12192 }
12193
12194 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
12195 const char *filter, afi_t afi, safi_t safi,
12196 enum bgp_show_type type)
12197 {
12198 struct as_list *as_list;
12199 uint8_t show_flags = 0;
12200
12201 as_list = as_list_lookup(filter);
12202 if (as_list == NULL) {
12203 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
12204 filter);
12205 return CMD_WARNING;
12206 }
12207
12208 return bgp_show(vty, bgp, afi, safi, type, as_list, show_flags);
12209 }
12210
12211 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
12212 const char *rmap_str, afi_t afi, safi_t safi,
12213 enum bgp_show_type type)
12214 {
12215 struct route_map *rmap;
12216 uint8_t show_flags = 0;
12217
12218 rmap = route_map_lookup_by_name(rmap_str);
12219 if (!rmap) {
12220 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
12221 return CMD_WARNING;
12222 }
12223
12224 return bgp_show(vty, bgp, afi, safi, type, rmap, show_flags);
12225 }
12226
12227 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
12228 const char *comstr, int exact, afi_t afi,
12229 safi_t safi, uint8_t show_flags)
12230 {
12231 struct community *com;
12232 int ret = 0;
12233
12234 com = community_str2com(comstr);
12235 if (!com) {
12236 vty_out(vty, "%% Community malformed: %s\n", comstr);
12237 return CMD_WARNING;
12238 }
12239
12240 ret = bgp_show(vty, bgp, afi, safi,
12241 (exact ? bgp_show_type_community_exact
12242 : bgp_show_type_community),
12243 com, show_flags);
12244 community_free(&com);
12245
12246 return ret;
12247 }
12248
12249 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
12250 const char *com, int exact, afi_t afi,
12251 safi_t safi)
12252 {
12253 struct community_list *list;
12254 uint8_t show_flags = 0;
12255
12256 list = community_list_lookup(bgp_clist, com, 0, COMMUNITY_LIST_MASTER);
12257 if (list == NULL) {
12258 vty_out(vty, "%% %s is not a valid community-list name\n", com);
12259 return CMD_WARNING;
12260 }
12261
12262 return bgp_show(vty, bgp, afi, safi,
12263 (exact ? bgp_show_type_community_list_exact
12264 : bgp_show_type_community_list),
12265 list, show_flags);
12266 }
12267
12268 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
12269 const char *prefix, afi_t afi, safi_t safi,
12270 enum bgp_show_type type)
12271 {
12272 int ret;
12273 struct prefix *p;
12274 uint8_t show_flags = 0;
12275
12276 p = prefix_new();
12277
12278 ret = str2prefix(prefix, p);
12279 if (!ret) {
12280 vty_out(vty, "%% Malformed Prefix\n");
12281 return CMD_WARNING;
12282 }
12283
12284 ret = bgp_show(vty, bgp, afi, safi, type, p, show_flags);
12285 prefix_free(&p);
12286 return ret;
12287 }
12288
12289 enum bgp_stats {
12290 BGP_STATS_MAXBITLEN = 0,
12291 BGP_STATS_RIB,
12292 BGP_STATS_PREFIXES,
12293 BGP_STATS_TOTPLEN,
12294 BGP_STATS_UNAGGREGATEABLE,
12295 BGP_STATS_MAX_AGGREGATEABLE,
12296 BGP_STATS_AGGREGATES,
12297 BGP_STATS_SPACE,
12298 BGP_STATS_ASPATH_COUNT,
12299 BGP_STATS_ASPATH_MAXHOPS,
12300 BGP_STATS_ASPATH_TOTHOPS,
12301 BGP_STATS_ASPATH_MAXSIZE,
12302 BGP_STATS_ASPATH_TOTSIZE,
12303 BGP_STATS_ASN_HIGHEST,
12304 BGP_STATS_MAX,
12305 };
12306
12307 #define TABLE_STATS_IDX_VTY 0
12308 #define TABLE_STATS_IDX_JSON 1
12309
12310 static const char *table_stats_strs[][2] = {
12311 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
12312 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
12313 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
12314 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
12315 "unaggregateablePrefixes"},
12316 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
12317 "maximumAggregateablePrefixes"},
12318 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
12319 "bgpAggregateAdvertisements"},
12320 [BGP_STATS_SPACE] = {"Address space advertised",
12321 "addressSpaceAdvertised"},
12322 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
12323 "advertisementsWithPaths"},
12324 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
12325 "longestAsPath"},
12326 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
12327 "largestAsPath"},
12328 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
12329 "averageAsPathLengthHops"},
12330 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
12331 "averageAsPathSizeBytes"},
12332 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
12333 [BGP_STATS_MAX] = {NULL, NULL}
12334 };
12335
12336 struct bgp_table_stats {
12337 struct bgp_table *table;
12338 unsigned long long counts[BGP_STATS_MAX];
12339 double total_space;
12340 };
12341
12342 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
12343 struct bgp_table_stats *ts, unsigned int space)
12344 {
12345 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
12346 struct bgp_path_info *pi;
12347 const struct prefix *rn_p;
12348
12349 if (!bgp_dest_has_bgp_path_info_data(dest))
12350 return;
12351
12352 rn_p = bgp_dest_get_prefix(dest);
12353 ts->counts[BGP_STATS_PREFIXES]++;
12354 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
12355
12356 /* check if the prefix is included by any other announcements */
12357 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
12358 pdest = bgp_dest_parent_nolock(pdest);
12359
12360 if (pdest == NULL || pdest == top) {
12361 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
12362 /* announced address space */
12363 if (space)
12364 ts->total_space += pow(2.0, space - rn_p->prefixlen);
12365 } else if (bgp_dest_has_bgp_path_info_data(pdest))
12366 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
12367
12368
12369 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
12370 ts->counts[BGP_STATS_RIB]++;
12371
12372 if (CHECK_FLAG(pi->attr->flag,
12373 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
12374 ts->counts[BGP_STATS_AGGREGATES]++;
12375
12376 /* as-path stats */
12377 if (pi->attr->aspath) {
12378 unsigned int hops = aspath_count_hops(pi->attr->aspath);
12379 unsigned int size = aspath_size(pi->attr->aspath);
12380 as_t highest = aspath_highest(pi->attr->aspath);
12381
12382 ts->counts[BGP_STATS_ASPATH_COUNT]++;
12383
12384 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
12385 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
12386
12387 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
12388 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
12389
12390 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
12391 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
12392 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
12393 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
12394 }
12395 }
12396 }
12397
12398 static int bgp_table_stats_walker(struct thread *t)
12399 {
12400 struct bgp_dest *dest, *ndest;
12401 struct bgp_dest *top;
12402 struct bgp_table_stats *ts = THREAD_ARG(t);
12403 unsigned int space = 0;
12404
12405 if (!(top = bgp_table_top(ts->table)))
12406 return 0;
12407
12408 switch (ts->table->afi) {
12409 case AFI_IP:
12410 space = IPV4_MAX_BITLEN;
12411 break;
12412 case AFI_IP6:
12413 space = IPV6_MAX_BITLEN;
12414 break;
12415 case AFI_L2VPN:
12416 space = EVPN_ROUTE_PREFIXLEN;
12417 break;
12418 default:
12419 return 0;
12420 }
12421
12422 ts->counts[BGP_STATS_MAXBITLEN] = space;
12423
12424 for (dest = top; dest; dest = bgp_route_next(dest)) {
12425 if (ts->table->safi == SAFI_MPLS_VPN
12426 || ts->table->safi == SAFI_ENCAP
12427 || ts->table->safi == SAFI_EVPN) {
12428 struct bgp_table *table;
12429
12430 table = bgp_dest_get_bgp_table_info(dest);
12431 if (!table)
12432 continue;
12433
12434 top = bgp_table_top(table);
12435 for (ndest = bgp_table_top(table); ndest;
12436 ndest = bgp_route_next(ndest))
12437 bgp_table_stats_rn(ndest, top, ts, space);
12438 } else {
12439 bgp_table_stats_rn(dest, top, ts, space);
12440 }
12441 }
12442
12443 return 0;
12444 }
12445
12446 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
12447 struct json_object *json_array)
12448 {
12449 struct listnode *node, *nnode;
12450 struct bgp *bgp;
12451
12452 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
12453 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
12454 }
12455
12456 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12457 safi_t safi, struct json_object *json_array)
12458 {
12459 struct bgp_table_stats ts;
12460 unsigned int i;
12461 int ret = CMD_SUCCESS;
12462 char temp_buf[20];
12463 struct json_object *json = NULL;
12464
12465 if (json_array)
12466 json = json_object_new_object();
12467
12468 if (!bgp->rib[afi][safi]) {
12469 char warning_msg[50];
12470
12471 snprintf(warning_msg, sizeof(warning_msg),
12472 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
12473 safi);
12474
12475 if (!json)
12476 vty_out(vty, "%s\n", warning_msg);
12477 else
12478 json_object_string_add(json, "warning", warning_msg);
12479
12480 ret = CMD_WARNING;
12481 goto end_table_stats;
12482 }
12483
12484 if (!json)
12485 vty_out(vty, "BGP %s RIB statistics (%s)\n",
12486 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
12487 else
12488 json_object_string_add(json, "instance", bgp->name_pretty);
12489
12490 /* labeled-unicast routes live in the unicast table */
12491 if (safi == SAFI_LABELED_UNICAST)
12492 safi = SAFI_UNICAST;
12493
12494 memset(&ts, 0, sizeof(ts));
12495 ts.table = bgp->rib[afi][safi];
12496 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
12497
12498 for (i = 0; i < BGP_STATS_MAX; i++) {
12499 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
12500 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
12501 continue;
12502
12503 switch (i) {
12504 case BGP_STATS_ASPATH_TOTHOPS:
12505 case BGP_STATS_ASPATH_TOTSIZE:
12506 if (!json) {
12507 snprintf(
12508 temp_buf, sizeof(temp_buf), "%12.2f",
12509 ts.counts[i]
12510 ? (float)ts.counts[i]
12511 / (float)ts.counts
12512 [BGP_STATS_ASPATH_COUNT]
12513 : 0);
12514 vty_out(vty, "%-30s: %s",
12515 table_stats_strs[i]
12516 [TABLE_STATS_IDX_VTY],
12517 temp_buf);
12518 } else {
12519 json_object_double_add(
12520 json,
12521 table_stats_strs[i]
12522 [TABLE_STATS_IDX_JSON],
12523 ts.counts[i]
12524 ? (double)ts.counts[i]
12525 / (double)ts.counts
12526 [BGP_STATS_ASPATH_COUNT]
12527 : 0);
12528 }
12529 break;
12530 case BGP_STATS_TOTPLEN:
12531 if (!json) {
12532 snprintf(
12533 temp_buf, sizeof(temp_buf), "%12.2f",
12534 ts.counts[i]
12535 ? (float)ts.counts[i]
12536 / (float)ts.counts
12537 [BGP_STATS_PREFIXES]
12538 : 0);
12539 vty_out(vty, "%-30s: %s",
12540 table_stats_strs[i]
12541 [TABLE_STATS_IDX_VTY],
12542 temp_buf);
12543 } else {
12544 json_object_double_add(
12545 json,
12546 table_stats_strs[i]
12547 [TABLE_STATS_IDX_JSON],
12548 ts.counts[i]
12549 ? (double)ts.counts[i]
12550 / (double)ts.counts
12551 [BGP_STATS_PREFIXES]
12552 : 0);
12553 }
12554 break;
12555 case BGP_STATS_SPACE:
12556 if (!json) {
12557 snprintf(temp_buf, sizeof(temp_buf), "%12g",
12558 ts.total_space);
12559 vty_out(vty, "%-30s: %s\n",
12560 table_stats_strs[i]
12561 [TABLE_STATS_IDX_VTY],
12562 temp_buf);
12563 } else {
12564 json_object_double_add(
12565 json,
12566 table_stats_strs[i]
12567 [TABLE_STATS_IDX_JSON],
12568 (double)ts.total_space);
12569 }
12570 if (afi == AFI_IP6) {
12571 if (!json) {
12572 snprintf(temp_buf, sizeof(temp_buf),
12573 "%12g",
12574 ts.total_space
12575 * pow(2.0, -128 + 32));
12576 vty_out(vty, "%30s: %s\n",
12577 "/32 equivalent %s\n",
12578 temp_buf);
12579 } else {
12580 json_object_double_add(
12581 json, "/32equivalent",
12582 (double)(ts.total_space
12583 * pow(2.0,
12584 -128 + 32)));
12585 }
12586 if (!json) {
12587 snprintf(temp_buf, sizeof(temp_buf),
12588 "%12g",
12589 ts.total_space
12590 * pow(2.0, -128 + 48));
12591 vty_out(vty, "%30s: %s\n",
12592 "/48 equivalent %s\n",
12593 temp_buf);
12594 } else {
12595 json_object_double_add(
12596 json, "/48equivalent",
12597 (double)(ts.total_space
12598 * pow(2.0,
12599 -128 + 48)));
12600 }
12601 } else {
12602 if (!json) {
12603 snprintf(temp_buf, sizeof(temp_buf),
12604 "%12.2f",
12605 ts.total_space * 100.
12606 * pow(2.0, -32));
12607 vty_out(vty, "%30s: %s\n",
12608 "% announced ", temp_buf);
12609 } else {
12610 json_object_double_add(
12611 json, "%announced",
12612 (double)(ts.total_space * 100.
12613 * pow(2.0, -32)));
12614 }
12615 if (!json) {
12616 snprintf(temp_buf, sizeof(temp_buf),
12617 "%12.2f",
12618 ts.total_space
12619 * pow(2.0, -32 + 8));
12620 vty_out(vty, "%30s: %s\n",
12621 "/8 equivalent ", temp_buf);
12622 } else {
12623 json_object_double_add(
12624 json, "/8equivalent",
12625 (double)(ts.total_space
12626 * pow(2.0, -32 + 8)));
12627 }
12628 if (!json) {
12629 snprintf(temp_buf, sizeof(temp_buf),
12630 "%12.2f",
12631 ts.total_space
12632 * pow(2.0, -32 + 24));
12633 vty_out(vty, "%30s: %s\n",
12634 "/24 equivalent ", temp_buf);
12635 } else {
12636 json_object_double_add(
12637 json, "/24equivalent",
12638 (double)(ts.total_space
12639 * pow(2.0, -32 + 24)));
12640 }
12641 }
12642 break;
12643 default:
12644 if (!json) {
12645 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
12646 ts.counts[i]);
12647 vty_out(vty, "%-30s: %s",
12648 table_stats_strs[i]
12649 [TABLE_STATS_IDX_VTY],
12650 temp_buf);
12651 } else {
12652 json_object_int_add(
12653 json,
12654 table_stats_strs[i]
12655 [TABLE_STATS_IDX_JSON],
12656 ts.counts[i]);
12657 }
12658 }
12659 if (!json)
12660 vty_out(vty, "\n");
12661 }
12662 end_table_stats:
12663 if (json)
12664 json_object_array_add(json_array, json);
12665 return ret;
12666 }
12667
12668 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12669 safi_t safi, struct json_object *json_array)
12670 {
12671 if (!bgp) {
12672 bgp_table_stats_all(vty, afi, safi, json_array);
12673 return CMD_SUCCESS;
12674 }
12675
12676 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
12677 }
12678
12679 enum bgp_pcounts {
12680 PCOUNT_ADJ_IN = 0,
12681 PCOUNT_DAMPED,
12682 PCOUNT_REMOVED,
12683 PCOUNT_HISTORY,
12684 PCOUNT_STALE,
12685 PCOUNT_VALID,
12686 PCOUNT_ALL,
12687 PCOUNT_COUNTED,
12688 PCOUNT_BPATH_SELECTED,
12689 PCOUNT_PFCNT, /* the figure we display to users */
12690 PCOUNT_MAX,
12691 };
12692
12693 static const char *const pcount_strs[] = {
12694 [PCOUNT_ADJ_IN] = "Adj-in",
12695 [PCOUNT_DAMPED] = "Damped",
12696 [PCOUNT_REMOVED] = "Removed",
12697 [PCOUNT_HISTORY] = "History",
12698 [PCOUNT_STALE] = "Stale",
12699 [PCOUNT_VALID] = "Valid",
12700 [PCOUNT_ALL] = "All RIB",
12701 [PCOUNT_COUNTED] = "PfxCt counted",
12702 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
12703 [PCOUNT_PFCNT] = "Useable",
12704 [PCOUNT_MAX] = NULL,
12705 };
12706
12707 struct peer_pcounts {
12708 unsigned int count[PCOUNT_MAX];
12709 const struct peer *peer;
12710 const struct bgp_table *table;
12711 safi_t safi;
12712 };
12713
12714 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
12715 {
12716 const struct bgp_adj_in *ain;
12717 const struct bgp_path_info *pi;
12718 const struct peer *peer = pc->peer;
12719
12720 for (ain = rn->adj_in; ain; ain = ain->next)
12721 if (ain->peer == peer)
12722 pc->count[PCOUNT_ADJ_IN]++;
12723
12724 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
12725
12726 if (pi->peer != peer)
12727 continue;
12728
12729 pc->count[PCOUNT_ALL]++;
12730
12731 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
12732 pc->count[PCOUNT_DAMPED]++;
12733 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
12734 pc->count[PCOUNT_HISTORY]++;
12735 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
12736 pc->count[PCOUNT_REMOVED]++;
12737 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
12738 pc->count[PCOUNT_STALE]++;
12739 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
12740 pc->count[PCOUNT_VALID]++;
12741 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
12742 pc->count[PCOUNT_PFCNT]++;
12743 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12744 pc->count[PCOUNT_BPATH_SELECTED]++;
12745
12746 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
12747 pc->count[PCOUNT_COUNTED]++;
12748 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
12749 flog_err(
12750 EC_LIB_DEVELOPMENT,
12751 "Attempting to count but flags say it is unusable");
12752 } else {
12753 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
12754 flog_err(
12755 EC_LIB_DEVELOPMENT,
12756 "Not counted but flags say we should");
12757 }
12758 }
12759 }
12760
12761 static int bgp_peer_count_walker(struct thread *t)
12762 {
12763 struct bgp_dest *rn, *rm;
12764 const struct bgp_table *table;
12765 struct peer_pcounts *pc = THREAD_ARG(t);
12766
12767 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
12768 || pc->safi == SAFI_EVPN) {
12769 /* Special handling for 2-level routing tables. */
12770 for (rn = bgp_table_top(pc->table); rn;
12771 rn = bgp_route_next(rn)) {
12772 table = bgp_dest_get_bgp_table_info(rn);
12773 if (table != NULL)
12774 for (rm = bgp_table_top(table); rm;
12775 rm = bgp_route_next(rm))
12776 bgp_peer_count_proc(rm, pc);
12777 }
12778 } else
12779 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
12780 bgp_peer_count_proc(rn, pc);
12781
12782 return 0;
12783 }
12784
12785 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
12786 safi_t safi, bool use_json)
12787 {
12788 struct peer_pcounts pcounts = {.peer = peer};
12789 unsigned int i;
12790 json_object *json = NULL;
12791 json_object *json_loop = NULL;
12792
12793 if (use_json) {
12794 json = json_object_new_object();
12795 json_loop = json_object_new_object();
12796 }
12797
12798 if (!peer || !peer->bgp || !peer->afc[afi][safi]
12799 || !peer->bgp->rib[afi][safi]) {
12800 if (use_json) {
12801 json_object_string_add(
12802 json, "warning",
12803 "No such neighbor or address family");
12804 vty_out(vty, "%s\n", json_object_to_json_string(json));
12805 json_object_free(json);
12806 json_object_free(json_loop);
12807 } else
12808 vty_out(vty, "%% No such neighbor or address family\n");
12809
12810 return CMD_WARNING;
12811 }
12812
12813 memset(&pcounts, 0, sizeof(pcounts));
12814 pcounts.peer = peer;
12815 pcounts.table = peer->bgp->rib[afi][safi];
12816 pcounts.safi = safi;
12817
12818 /* in-place call via thread subsystem so as to record execution time
12819 * stats for the thread-walk (i.e. ensure this can't be blamed on
12820 * on just vty_read()).
12821 */
12822 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
12823
12824 if (use_json) {
12825 json_object_string_add(json, "prefixCountsFor", peer->host);
12826 json_object_string_add(json, "multiProtocol",
12827 get_afi_safi_str(afi, safi, true));
12828 json_object_int_add(json, "pfxCounter",
12829 peer->pcount[afi][safi]);
12830
12831 for (i = 0; i < PCOUNT_MAX; i++)
12832 json_object_int_add(json_loop, pcount_strs[i],
12833 pcounts.count[i]);
12834
12835 json_object_object_add(json, "ribTableWalkCounters", json_loop);
12836
12837 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
12838 json_object_string_add(json, "pfxctDriftFor",
12839 peer->host);
12840 json_object_string_add(
12841 json, "recommended",
12842 "Please report this bug, with the above command output");
12843 }
12844 vty_out(vty, "%s\n", json_object_to_json_string_ext(
12845 json, JSON_C_TO_STRING_PRETTY));
12846 json_object_free(json);
12847 } else {
12848
12849 if (peer->hostname
12850 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
12851 vty_out(vty, "Prefix counts for %s/%s, %s\n",
12852 peer->hostname, peer->host,
12853 get_afi_safi_str(afi, safi, false));
12854 } else {
12855 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
12856 get_afi_safi_str(afi, safi, false));
12857 }
12858
12859 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
12860 vty_out(vty, "\nCounts from RIB table walk:\n\n");
12861
12862 for (i = 0; i < PCOUNT_MAX; i++)
12863 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
12864 pcounts.count[i]);
12865
12866 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
12867 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
12868 vty_out(vty,
12869 "Please report this bug, with the above command output\n");
12870 }
12871 }
12872
12873 return CMD_SUCCESS;
12874 }
12875
12876 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
12877 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
12878 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
12879 SHOW_STR
12880 IP_STR
12881 BGP_STR
12882 BGP_INSTANCE_HELP_STR
12883 BGP_AFI_HELP_STR
12884 BGP_SAFI_HELP_STR
12885 "Detailed information on TCP and BGP neighbor connections\n"
12886 "Neighbor to display information about\n"
12887 "Neighbor to display information about\n"
12888 "Neighbor on BGP configured interface\n"
12889 "Display detailed prefix count information\n"
12890 JSON_STR)
12891 {
12892 afi_t afi = AFI_IP6;
12893 safi_t safi = SAFI_UNICAST;
12894 struct peer *peer;
12895 int idx = 0;
12896 struct bgp *bgp = NULL;
12897 bool uj = use_json(argc, argv);
12898
12899 if (uj)
12900 argc--;
12901
12902 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12903 &bgp, uj);
12904 if (!idx)
12905 return CMD_WARNING;
12906
12907 argv_find(argv, argc, "neighbors", &idx);
12908 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
12909 if (!peer)
12910 return CMD_WARNING;
12911
12912 return bgp_peer_counts(vty, peer, afi, safi, uj);
12913 }
12914
12915 #ifdef KEEP_OLD_VPN_COMMANDS
12916 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
12917 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
12918 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
12919 SHOW_STR
12920 IP_STR
12921 BGP_STR
12922 BGP_VPNVX_HELP_STR
12923 "Display information about all VPNv4 NLRIs\n"
12924 "Detailed information on TCP and BGP neighbor connections\n"
12925 "Neighbor to display information about\n"
12926 "Neighbor to display information about\n"
12927 "Neighbor on BGP configured interface\n"
12928 "Display detailed prefix count information\n"
12929 JSON_STR)
12930 {
12931 int idx_peer = 6;
12932 struct peer *peer;
12933 bool uj = use_json(argc, argv);
12934
12935 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
12936 if (!peer)
12937 return CMD_WARNING;
12938
12939 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
12940 }
12941
12942 DEFUN (show_ip_bgp_vpn_all_route_prefix,
12943 show_ip_bgp_vpn_all_route_prefix_cmd,
12944 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
12945 SHOW_STR
12946 IP_STR
12947 BGP_STR
12948 BGP_VPNVX_HELP_STR
12949 "Display information about all VPNv4 NLRIs\n"
12950 "Network in the BGP routing table to display\n"
12951 "Network in the BGP routing table to display\n"
12952 JSON_STR)
12953 {
12954 int idx = 0;
12955 char *network = NULL;
12956 struct bgp *bgp = bgp_get_default();
12957 if (!bgp) {
12958 vty_out(vty, "Can't find default instance\n");
12959 return CMD_WARNING;
12960 }
12961
12962 if (argv_find(argv, argc, "A.B.C.D", &idx))
12963 network = argv[idx]->arg;
12964 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
12965 network = argv[idx]->arg;
12966 else {
12967 vty_out(vty, "Unable to figure out Network\n");
12968 return CMD_WARNING;
12969 }
12970
12971 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
12972 BGP_PATH_SHOW_ALL, use_json(argc, argv));
12973 }
12974 #endif /* KEEP_OLD_VPN_COMMANDS */
12975
12976 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
12977 show_bgp_l2vpn_evpn_route_prefix_cmd,
12978 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
12979 SHOW_STR
12980 BGP_STR
12981 L2VPN_HELP_STR
12982 EVPN_HELP_STR
12983 "Network in the BGP routing table to display\n"
12984 "Network in the BGP routing table to display\n"
12985 "Network in the BGP routing table to display\n"
12986 "Network in the BGP routing table to display\n"
12987 JSON_STR)
12988 {
12989 int idx = 0;
12990 char *network = NULL;
12991 int prefix_check = 0;
12992
12993 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
12994 argv_find(argv, argc, "X:X::X:X", &idx))
12995 network = argv[idx]->arg;
12996 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
12997 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12998 network = argv[idx]->arg;
12999 prefix_check = 1;
13000 } else {
13001 vty_out(vty, "Unable to figure out Network\n");
13002 return CMD_WARNING;
13003 }
13004 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13005 prefix_check, BGP_PATH_SHOW_ALL,
13006 use_json(argc, argv));
13007 }
13008
13009 static void show_adj_route_header(struct vty *vty, struct bgp *bgp,
13010 struct bgp_table *table, int *header1,
13011 int *header2, json_object *json,
13012 json_object *json_scode,
13013 json_object *json_ocode, bool wide)
13014 {
13015 uint64_t version = table ? table->version : 0;
13016 char buf[BUFSIZ] = {0};
13017
13018 if (*header1) {
13019 if (json) {
13020 json_object_int_add(json, "bgpTableVersion", version);
13021 json_object_string_add(json, "bgpLocalRouterId",
13022 inet_ntop(AF_INET,
13023 &bgp->router_id, buf,
13024 sizeof(buf)));
13025 json_object_int_add(json, "defaultLocPrf",
13026 bgp->default_local_pref);
13027 json_object_int_add(json, "localAS", bgp->as);
13028 json_object_object_add(json, "bgpStatusCodes",
13029 json_scode);
13030 json_object_object_add(json, "bgpOriginCodes",
13031 json_ocode);
13032 } else {
13033 vty_out(vty,
13034 "BGP table version is %" PRIu64
13035 ", local router ID is %pI4, vrf id ",
13036 version, &bgp->router_id);
13037 if (bgp->vrf_id == VRF_UNKNOWN)
13038 vty_out(vty, "%s", VRFID_NONE_STR);
13039 else
13040 vty_out(vty, "%u", bgp->vrf_id);
13041 vty_out(vty, "\n");
13042 vty_out(vty, "Default local pref %u, ",
13043 bgp->default_local_pref);
13044 vty_out(vty, "local AS %u\n", bgp->as);
13045 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13046 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13047 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13048 }
13049 *header1 = 0;
13050 }
13051 if (*header2) {
13052 if (!json)
13053 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
13054 : BGP_SHOW_HEADER));
13055 *header2 = 0;
13056 }
13057 }
13058
13059 static void
13060 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
13061 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
13062 const char *rmap_name, json_object *json, json_object *json_ar,
13063 json_object *json_scode, json_object *json_ocode,
13064 uint8_t show_flags, int *header1, int *header2, char *rd_str,
13065 unsigned long *output_count, unsigned long *filtered_count)
13066 {
13067 struct bgp_adj_in *ain;
13068 struct bgp_adj_out *adj;
13069 struct bgp_dest *dest;
13070 struct bgp *bgp;
13071 struct attr attr;
13072 int ret;
13073 struct update_subgroup *subgrp;
13074 struct peer_af *paf;
13075 bool route_filtered;
13076 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13077 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13078 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13079 || (safi == SAFI_EVPN))
13080 ? true
13081 : false;
13082
13083 bgp = peer->bgp;
13084
13085 if (!bgp) {
13086 if (use_json) {
13087 json_object_string_add(json, "alert", "no BGP");
13088 vty_out(vty, "%s\n", json_object_to_json_string(json));
13089 json_object_free(json);
13090 } else
13091 vty_out(vty, "%% No bgp\n");
13092 return;
13093 }
13094
13095 subgrp = peer_subgroup(peer, afi, safi);
13096
13097 if (type == bgp_show_adj_route_advertised && subgrp
13098 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
13099 char buf[BUFSIZ] = {0};
13100
13101 if (use_json) {
13102 json_object_int_add(json, "bgpTableVersion",
13103 table->version);
13104 json_object_string_add(json, "bgpLocalRouterId",
13105 inet_ntop(AF_INET,
13106 &bgp->router_id, buf,
13107 sizeof(buf)));
13108 json_object_int_add(json, "defaultLocPrf",
13109 bgp->default_local_pref);
13110 json_object_int_add(json, "localAS", bgp->as);
13111 json_object_object_add(json, "bgpStatusCodes",
13112 json_scode);
13113 json_object_object_add(json, "bgpOriginCodes",
13114 json_ocode);
13115 json_object_string_add(
13116 json, "bgpOriginatingDefaultNetwork",
13117 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13118 } else {
13119 vty_out(vty,
13120 "BGP table version is %" PRIu64
13121 ", local router ID is %pI4, vrf id ",
13122 table->version, &bgp->router_id);
13123 if (bgp->vrf_id == VRF_UNKNOWN)
13124 vty_out(vty, "%s", VRFID_NONE_STR);
13125 else
13126 vty_out(vty, "%u", bgp->vrf_id);
13127 vty_out(vty, "\n");
13128 vty_out(vty, "Default local pref %u, ",
13129 bgp->default_local_pref);
13130 vty_out(vty, "local AS %u\n", bgp->as);
13131 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13132 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13133 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13134
13135 vty_out(vty, "Originating default network %s\n\n",
13136 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13137 }
13138 *header1 = 0;
13139 }
13140
13141 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
13142 if (type == bgp_show_adj_route_received
13143 || type == bgp_show_adj_route_filtered) {
13144 for (ain = dest->adj_in; ain; ain = ain->next) {
13145 if (ain->peer != peer)
13146 continue;
13147
13148 show_adj_route_header(vty, bgp, table, header1,
13149 header2, json, json_scode,
13150 json_ocode, wide);
13151
13152 if ((safi == SAFI_MPLS_VPN)
13153 || (safi == SAFI_ENCAP)
13154 || (safi == SAFI_EVPN)) {
13155 if (use_json)
13156 json_object_string_add(
13157 json_ar, "rd", rd_str);
13158 else if (show_rd && rd_str) {
13159 vty_out(vty,
13160 "Route Distinguisher: %s\n",
13161 rd_str);
13162 show_rd = false;
13163 }
13164 }
13165
13166 attr = *ain->attr;
13167 route_filtered = false;
13168
13169 /* Filter prefix using distribute list,
13170 * filter list or prefix list
13171 */
13172 const struct prefix *rn_p =
13173 bgp_dest_get_prefix(dest);
13174 if ((bgp_input_filter(peer, rn_p, &attr, afi,
13175 safi))
13176 == FILTER_DENY)
13177 route_filtered = true;
13178
13179 /* Filter prefix using route-map */
13180 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
13181 safi, rmap_name, NULL,
13182 0, NULL);
13183
13184 if (type == bgp_show_adj_route_filtered &&
13185 !route_filtered && ret != RMAP_DENY) {
13186 bgp_attr_undup(&attr, ain->attr);
13187 continue;
13188 }
13189
13190 if (type == bgp_show_adj_route_received
13191 && (route_filtered || ret == RMAP_DENY))
13192 (*filtered_count)++;
13193
13194 route_vty_out_tmp(vty, rn_p, &attr, safi,
13195 use_json, json_ar, wide);
13196 bgp_attr_undup(&attr, ain->attr);
13197 (*output_count)++;
13198 }
13199 } else if (type == bgp_show_adj_route_advertised) {
13200 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
13201 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
13202 if (paf->peer != peer || !adj->attr)
13203 continue;
13204
13205 show_adj_route_header(vty, bgp, table,
13206 header1, header2,
13207 json, json_scode,
13208 json_ocode, wide);
13209
13210 const struct prefix *rn_p =
13211 bgp_dest_get_prefix(dest);
13212
13213 attr = *adj->attr;
13214 ret = bgp_output_modifier(
13215 peer, rn_p, &attr, afi, safi,
13216 rmap_name);
13217
13218 if (ret != RMAP_DENY) {
13219 if ((safi == SAFI_MPLS_VPN)
13220 || (safi == SAFI_ENCAP)
13221 || (safi == SAFI_EVPN)) {
13222 if (use_json)
13223 json_object_string_add(
13224 json_ar,
13225 "rd",
13226 rd_str);
13227 else if (show_rd
13228 && rd_str) {
13229 vty_out(vty,
13230 "Route Distinguisher: %s\n",
13231 rd_str);
13232 show_rd = false;
13233 }
13234 }
13235 route_vty_out_tmp(
13236 vty, rn_p, &attr, safi,
13237 use_json, json_ar,
13238 wide);
13239 (*output_count)++;
13240 } else {
13241 (*filtered_count)++;
13242 }
13243
13244 bgp_attr_undup(&attr, adj->attr);
13245 }
13246 } else if (type == bgp_show_adj_route_bestpath) {
13247 struct bgp_path_info *pi;
13248
13249 show_adj_route_header(vty, bgp, table, header1, header2,
13250 json, json_scode, json_ocode,
13251 wide);
13252
13253 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
13254 pi = pi->next) {
13255 if (pi->peer != peer)
13256 continue;
13257
13258 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13259 continue;
13260
13261 route_vty_out_tmp(vty,
13262 bgp_dest_get_prefix(dest),
13263 pi->attr, safi, use_json,
13264 json_ar, wide);
13265 (*output_count)++;
13266 }
13267 }
13268 }
13269 }
13270
13271 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
13272 safi_t safi, enum bgp_show_adj_route_type type,
13273 const char *rmap_name, uint8_t show_flags)
13274 {
13275 struct bgp *bgp;
13276 struct bgp_table *table;
13277 json_object *json = NULL;
13278 json_object *json_scode = NULL;
13279 json_object *json_ocode = NULL;
13280 json_object *json_ar = NULL;
13281 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13282
13283 /* Init BGP headers here so they're only displayed once
13284 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
13285 */
13286 int header1 = 1;
13287 int header2 = 1;
13288
13289 /*
13290 * Initialize variables for each RD
13291 * All prefixes under an RD is aggregated within "json_routes"
13292 */
13293 char rd_str[BUFSIZ] = {0};
13294 json_object *json_routes = NULL;
13295
13296
13297 /* For 2-tier tables, prefix counts need to be
13298 * maintained across multiple runs of show_adj_route()
13299 */
13300 unsigned long output_count_per_rd;
13301 unsigned long filtered_count_per_rd;
13302 unsigned long output_count = 0;
13303 unsigned long filtered_count = 0;
13304
13305 if (use_json) {
13306 json = json_object_new_object();
13307 json_ar = json_object_new_object();
13308 json_scode = json_object_new_object();
13309 json_ocode = json_object_new_object();
13310
13311 json_object_string_add(json_scode, "suppressed", "s");
13312 json_object_string_add(json_scode, "damped", "d");
13313 json_object_string_add(json_scode, "history", "h");
13314 json_object_string_add(json_scode, "valid", "*");
13315 json_object_string_add(json_scode, "best", ">");
13316 json_object_string_add(json_scode, "multipath", "=");
13317 json_object_string_add(json_scode, "internal", "i");
13318 json_object_string_add(json_scode, "ribFailure", "r");
13319 json_object_string_add(json_scode, "stale", "S");
13320 json_object_string_add(json_scode, "removed", "R");
13321
13322 json_object_string_add(json_ocode, "igp", "i");
13323 json_object_string_add(json_ocode, "egp", "e");
13324 json_object_string_add(json_ocode, "incomplete", "?");
13325 }
13326
13327 if (!peer || !peer->afc[afi][safi]) {
13328 if (use_json) {
13329 json_object_string_add(
13330 json, "warning",
13331 "No such neighbor or address family");
13332 vty_out(vty, "%s\n", json_object_to_json_string(json));
13333 json_object_free(json);
13334 } else
13335 vty_out(vty, "%% No such neighbor or address family\n");
13336
13337 return CMD_WARNING;
13338 }
13339
13340 if ((type == bgp_show_adj_route_received
13341 || type == bgp_show_adj_route_filtered)
13342 && !CHECK_FLAG(peer->af_flags[afi][safi],
13343 PEER_FLAG_SOFT_RECONFIG)) {
13344 if (use_json) {
13345 json_object_string_add(
13346 json, "warning",
13347 "Inbound soft reconfiguration not enabled");
13348 vty_out(vty, "%s\n", json_object_to_json_string(json));
13349 json_object_free(json);
13350 } else
13351 vty_out(vty,
13352 "%% Inbound soft reconfiguration not enabled\n");
13353
13354 return CMD_WARNING;
13355 }
13356
13357 bgp = peer->bgp;
13358
13359 /* labeled-unicast routes live in the unicast table */
13360 if (safi == SAFI_LABELED_UNICAST)
13361 table = bgp->rib[afi][SAFI_UNICAST];
13362 else
13363 table = bgp->rib[afi][safi];
13364
13365 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13366 || (safi == SAFI_EVPN)) {
13367
13368 struct bgp_dest *dest;
13369
13370 for (dest = bgp_table_top(table); dest;
13371 dest = bgp_route_next(dest)) {
13372 table = bgp_dest_get_bgp_table_info(dest);
13373 if (!table)
13374 continue;
13375
13376 output_count_per_rd = 0;
13377 filtered_count_per_rd = 0;
13378
13379 if (use_json)
13380 json_routes = json_object_new_object();
13381
13382 const struct prefix_rd *prd;
13383 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
13384 dest);
13385
13386 prefix_rd2str(prd, rd_str, sizeof(rd_str));
13387
13388 show_adj_route(vty, peer, table, afi, safi, type,
13389 rmap_name, json, json_routes, json_scode,
13390 json_ocode, show_flags, &header1,
13391 &header2, rd_str, &output_count_per_rd,
13392 &filtered_count_per_rd);
13393
13394 /* Don't include an empty RD in the output! */
13395 if (json_routes && (output_count_per_rd > 0))
13396 json_object_object_add(json_ar, rd_str,
13397 json_routes);
13398
13399 output_count += output_count_per_rd;
13400 filtered_count += filtered_count_per_rd;
13401 }
13402 } else
13403 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
13404 json, json_ar, json_scode, json_ocode,
13405 show_flags, &header1, &header2, rd_str,
13406 &output_count, &filtered_count);
13407
13408 if (use_json) {
13409 json_object_object_add(json, "advertisedRoutes", json_ar);
13410 json_object_int_add(json, "totalPrefixCounter", output_count);
13411 json_object_int_add(json, "filteredPrefixCounter",
13412 filtered_count);
13413
13414 vty_out(vty, "%s\n",
13415 json_object_to_json_string_ext(
13416 json, JSON_C_TO_STRING_PRETTY));
13417
13418 if (!output_count && !filtered_count) {
13419 json_object_free(json_scode);
13420 json_object_free(json_ocode);
13421 }
13422
13423 if (json)
13424 json_object_free(json);
13425
13426 } else if (output_count > 0) {
13427 if (filtered_count > 0)
13428 vty_out(vty,
13429 "\nTotal number of prefixes %ld (%ld filtered)\n",
13430 output_count, filtered_count);
13431 else
13432 vty_out(vty, "\nTotal number of prefixes %ld\n",
13433 output_count);
13434 }
13435
13436 return CMD_SUCCESS;
13437 }
13438
13439 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
13440 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
13441 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] neighbors <A.B.C.D|X:X::X:X|WORD> bestpath-routes [json$uj | wide$wide]",
13442 SHOW_STR
13443 IP_STR
13444 BGP_STR
13445 BGP_INSTANCE_HELP_STR
13446 BGP_AFI_HELP_STR
13447 BGP_SAFI_WITH_LABEL_HELP_STR
13448 "Detailed information on TCP and BGP neighbor connections\n"
13449 "Neighbor to display information about\n"
13450 "Neighbor to display information about\n"
13451 "Neighbor on BGP configured interface\n"
13452 "Display the routes selected by best path\n"
13453 JSON_STR
13454 "Increase table width for longer prefixes\n")
13455 {
13456 afi_t afi = AFI_IP6;
13457 safi_t safi = SAFI_UNICAST;
13458 char *rmap_name = NULL;
13459 char *peerstr = NULL;
13460 struct bgp *bgp = NULL;
13461 struct peer *peer;
13462 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
13463 int idx = 0;
13464 uint8_t show_flags = 0;
13465
13466 if (uj)
13467 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13468
13469 if (wide)
13470 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13471
13472 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13473 &bgp, uj);
13474
13475 if (!idx)
13476 return CMD_WARNING;
13477
13478 argv_find(argv, argc, "neighbors", &idx);
13479 peerstr = argv[++idx]->arg;
13480
13481 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13482 if (!peer)
13483 return CMD_WARNING;
13484
13485 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13486 show_flags);
13487 }
13488
13489 DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
13490 show_ip_bgp_instance_neighbor_advertised_route_cmd,
13491 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [all$all] neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map WORD] [json$uj | wide$wide]",
13492 SHOW_STR
13493 IP_STR
13494 BGP_STR
13495 BGP_INSTANCE_HELP_STR
13496 BGP_AFI_HELP_STR
13497 BGP_SAFI_WITH_LABEL_HELP_STR
13498 "Display the entries for all address families\n"
13499 "Detailed information on TCP and BGP neighbor connections\n"
13500 "Neighbor to display information about\n"
13501 "Neighbor to display information about\n"
13502 "Neighbor on BGP configured interface\n"
13503 "Display the routes advertised to a BGP neighbor\n"
13504 "Display the received routes from neighbor\n"
13505 "Display the filtered routes received from neighbor\n"
13506 "Route-map to modify the attributes\n"
13507 "Name of the route map\n"
13508 JSON_STR
13509 "Increase table width for longer prefixes\n")
13510 {
13511 afi_t afi = AFI_IP6;
13512 safi_t safi = SAFI_UNICAST;
13513 char *rmap_name = NULL;
13514 char *peerstr = NULL;
13515 struct bgp *bgp = NULL;
13516 struct peer *peer;
13517 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
13518 int idx = 0;
13519 bool first = true;
13520 uint8_t show_flags = 0;
13521
13522 if (uj) {
13523 argc--;
13524 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13525 }
13526
13527 if (all) {
13528 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
13529 if (argv_find(argv, argc, "ipv4", &idx))
13530 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
13531
13532 if (argv_find(argv, argc, "ipv6", &idx))
13533 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
13534 }
13535
13536 if (wide)
13537 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13538
13539 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13540 &bgp, uj);
13541 if (!idx)
13542 return CMD_WARNING;
13543
13544 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
13545 argv_find(argv, argc, "neighbors", &idx);
13546 peerstr = argv[++idx]->arg;
13547
13548 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13549 if (!peer)
13550 return CMD_WARNING;
13551
13552 if (argv_find(argv, argc, "advertised-routes", &idx))
13553 type = bgp_show_adj_route_advertised;
13554 else if (argv_find(argv, argc, "received-routes", &idx))
13555 type = bgp_show_adj_route_received;
13556 else if (argv_find(argv, argc, "filtered-routes", &idx))
13557 type = bgp_show_adj_route_filtered;
13558
13559 if (argv_find(argv, argc, "route-map", &idx))
13560 rmap_name = argv[++idx]->arg;
13561
13562 if (!all)
13563 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13564 show_flags);
13565 if (uj)
13566 vty_out(vty, "{\n");
13567
13568 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
13569 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
13570 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
13571 : AFI_IP6;
13572 FOREACH_SAFI (safi) {
13573 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
13574 continue;
13575
13576 if (uj) {
13577 if (first)
13578 first = false;
13579 else
13580 vty_out(vty, ",\n");
13581 vty_out(vty, "\"%s\":",
13582 get_afi_safi_str(afi, safi, true));
13583 } else
13584 vty_out(vty, "\nFor address family: %s\n",
13585 get_afi_safi_str(afi, safi, false));
13586
13587 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13588 show_flags);
13589 }
13590 } else {
13591 FOREACH_AFI_SAFI (afi, safi) {
13592 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
13593 continue;
13594
13595 if (uj) {
13596 if (first)
13597 first = false;
13598 else
13599 vty_out(vty, ",\n");
13600 vty_out(vty, "\"%s\":",
13601 get_afi_safi_str(afi, safi, true));
13602 } else
13603 vty_out(vty, "\nFor address family: %s\n",
13604 get_afi_safi_str(afi, safi, false));
13605
13606 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13607 show_flags);
13608 }
13609 }
13610 if (uj)
13611 vty_out(vty, "}\n");
13612
13613 return CMD_SUCCESS;
13614 }
13615
13616 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
13617 show_ip_bgp_neighbor_received_prefix_filter_cmd,
13618 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
13619 SHOW_STR
13620 IP_STR
13621 BGP_STR
13622 "Address Family\n"
13623 "Address Family\n"
13624 "Address Family modifier\n"
13625 "Detailed information on TCP and BGP neighbor connections\n"
13626 "Neighbor to display information about\n"
13627 "Neighbor to display information about\n"
13628 "Neighbor on BGP configured interface\n"
13629 "Display information received from a BGP neighbor\n"
13630 "Display the prefixlist filter\n"
13631 JSON_STR)
13632 {
13633 afi_t afi = AFI_IP6;
13634 safi_t safi = SAFI_UNICAST;
13635 char *peerstr = NULL;
13636
13637 char name[BUFSIZ];
13638 union sockunion su;
13639 struct peer *peer;
13640 int count, ret;
13641
13642 int idx = 0;
13643
13644 /* show [ip] bgp */
13645 if (argv_find(argv, argc, "ip", &idx))
13646 afi = AFI_IP;
13647 /* [<ipv4|ipv6> [unicast]] */
13648 if (argv_find(argv, argc, "ipv4", &idx))
13649 afi = AFI_IP;
13650 if (argv_find(argv, argc, "ipv6", &idx))
13651 afi = AFI_IP6;
13652 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
13653 argv_find(argv, argc, "neighbors", &idx);
13654 peerstr = argv[++idx]->arg;
13655
13656 bool uj = use_json(argc, argv);
13657
13658 ret = str2sockunion(peerstr, &su);
13659 if (ret < 0) {
13660 peer = peer_lookup_by_conf_if(NULL, peerstr);
13661 if (!peer) {
13662 if (uj)
13663 vty_out(vty, "{}\n");
13664 else
13665 vty_out(vty,
13666 "%% Malformed address or name: %s\n",
13667 peerstr);
13668 return CMD_WARNING;
13669 }
13670 } else {
13671 peer = peer_lookup(NULL, &su);
13672 if (!peer) {
13673 if (uj)
13674 vty_out(vty, "{}\n");
13675 else
13676 vty_out(vty, "No peer\n");
13677 return CMD_WARNING;
13678 }
13679 }
13680
13681 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
13682 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
13683 if (count) {
13684 if (!uj)
13685 vty_out(vty, "Address Family: %s\n",
13686 get_afi_safi_str(afi, safi, false));
13687 prefix_bgp_show_prefix_list(vty, afi, name, uj);
13688 } else {
13689 if (uj)
13690 vty_out(vty, "{}\n");
13691 else
13692 vty_out(vty, "No functional output\n");
13693 }
13694
13695 return CMD_SUCCESS;
13696 }
13697
13698 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
13699 afi_t afi, safi_t safi,
13700 enum bgp_show_type type, bool use_json)
13701 {
13702 uint8_t show_flags = 0;
13703
13704 if (use_json)
13705 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13706
13707 if (!peer || !peer->afc[afi][safi]) {
13708 if (use_json) {
13709 json_object *json_no = NULL;
13710 json_no = json_object_new_object();
13711 json_object_string_add(
13712 json_no, "warning",
13713 "No such neighbor or address family");
13714 vty_out(vty, "%s\n",
13715 json_object_to_json_string(json_no));
13716 json_object_free(json_no);
13717 } else
13718 vty_out(vty, "%% No such neighbor or address family\n");
13719 return CMD_WARNING;
13720 }
13721
13722 /* labeled-unicast routes live in the unicast table */
13723 if (safi == SAFI_LABELED_UNICAST)
13724 safi = SAFI_UNICAST;
13725
13726 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags);
13727 }
13728
13729 DEFUN (show_ip_bgp_flowspec_routes_detailed,
13730 show_ip_bgp_flowspec_routes_detailed_cmd,
13731 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
13732 SHOW_STR
13733 IP_STR
13734 BGP_STR
13735 BGP_INSTANCE_HELP_STR
13736 BGP_AFI_HELP_STR
13737 "SAFI Flowspec\n"
13738 "Detailed information on flowspec entries\n"
13739 JSON_STR)
13740 {
13741 afi_t afi = AFI_IP;
13742 safi_t safi = SAFI_UNICAST;
13743 struct bgp *bgp = NULL;
13744 int idx = 0;
13745 bool uj = use_json(argc, argv);
13746 uint8_t show_flags = 0;
13747
13748 if (uj) {
13749 argc--;
13750 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13751 }
13752
13753 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13754 &bgp, uj);
13755 if (!idx)
13756 return CMD_WARNING;
13757
13758 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
13759 show_flags);
13760 }
13761
13762 DEFUN (show_ip_bgp_neighbor_routes,
13763 show_ip_bgp_neighbor_routes_cmd,
13764 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
13765 SHOW_STR
13766 IP_STR
13767 BGP_STR
13768 BGP_INSTANCE_HELP_STR
13769 BGP_AFI_HELP_STR
13770 BGP_SAFI_WITH_LABEL_HELP_STR
13771 "Detailed information on TCP and BGP neighbor connections\n"
13772 "Neighbor to display information about\n"
13773 "Neighbor to display information about\n"
13774 "Neighbor on BGP configured interface\n"
13775 "Display flap statistics of the routes learned from neighbor\n"
13776 "Display the dampened routes received from neighbor\n"
13777 "Display routes learned from neighbor\n"
13778 JSON_STR)
13779 {
13780 char *peerstr = NULL;
13781 struct bgp *bgp = NULL;
13782 afi_t afi = AFI_IP6;
13783 safi_t safi = SAFI_UNICAST;
13784 struct peer *peer;
13785 enum bgp_show_type sh_type = bgp_show_type_neighbor;
13786 int idx = 0;
13787 bool uj = use_json(argc, argv);
13788
13789 if (uj)
13790 argc--;
13791
13792 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13793 &bgp, uj);
13794 if (!idx)
13795 return CMD_WARNING;
13796
13797 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
13798 argv_find(argv, argc, "neighbors", &idx);
13799 peerstr = argv[++idx]->arg;
13800
13801 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13802 if (!peer)
13803 return CMD_WARNING;
13804
13805 if (argv_find(argv, argc, "flap-statistics", &idx))
13806 sh_type = bgp_show_type_flap_neighbor;
13807 else if (argv_find(argv, argc, "dampened-routes", &idx))
13808 sh_type = bgp_show_type_damp_neighbor;
13809 else if (argv_find(argv, argc, "routes", &idx))
13810 sh_type = bgp_show_type_neighbor;
13811
13812 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
13813 }
13814
13815 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
13816
13817 struct bgp_distance {
13818 /* Distance value for the IP source prefix. */
13819 uint8_t distance;
13820
13821 /* Name of the access-list to be matched. */
13822 char *access_list;
13823 };
13824
13825 DEFUN (show_bgp_afi_vpn_rd_route,
13826 show_bgp_afi_vpn_rd_route_cmd,
13827 "show bgp "BGP_AFI_CMD_STR" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> <A.B.C.D/M|X:X::X:X/M> [json]",
13828 SHOW_STR
13829 BGP_STR
13830 BGP_AFI_HELP_STR
13831 "Address Family modifier\n"
13832 "Display information for a route distinguisher\n"
13833 "Route Distinguisher\n"
13834 "All Route Distinguishers\n"
13835 "Network in the BGP routing table to display\n"
13836 "Network in the BGP routing table to display\n"
13837 JSON_STR)
13838 {
13839 int ret;
13840 struct prefix_rd prd;
13841 afi_t afi = AFI_MAX;
13842 int idx = 0;
13843
13844 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
13845 vty_out(vty, "%% Malformed Address Family\n");
13846 return CMD_WARNING;
13847 }
13848
13849 if (!strcmp(argv[5]->arg, "all"))
13850 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
13851 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
13852 use_json(argc, argv));
13853
13854 ret = str2prefix_rd(argv[5]->arg, &prd);
13855 if (!ret) {
13856 vty_out(vty, "%% Malformed Route Distinguisher\n");
13857 return CMD_WARNING;
13858 }
13859
13860 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
13861 0, BGP_PATH_SHOW_ALL, use_json(argc, argv));
13862 }
13863
13864 static struct bgp_distance *bgp_distance_new(void)
13865 {
13866 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
13867 }
13868
13869 static void bgp_distance_free(struct bgp_distance *bdistance)
13870 {
13871 XFREE(MTYPE_BGP_DISTANCE, bdistance);
13872 }
13873
13874 int bgp_distance_set(uint8_t distance, const char *ip_str,
13875 const char *access_list_str, afi_t afi, safi_t safi,
13876 char *errmsg, size_t errmsg_len)
13877 {
13878 int ret;
13879 struct prefix p;
13880 struct bgp_dest *dest;
13881 struct bgp_distance *bdistance;
13882
13883 ret = str2prefix(ip_str, &p);
13884 if (ret == 0) {
13885 snprintf(errmsg, errmsg_len, "Malformed prefix\n");
13886 return CMD_WARNING_CONFIG_FAILED;
13887 }
13888
13889 /* Get BGP distance node. */
13890 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
13891 bdistance = bgp_dest_get_bgp_distance_info(dest);
13892 if (bdistance)
13893 bgp_dest_unlock_node(dest);
13894 else {
13895 bdistance = bgp_distance_new();
13896 bgp_dest_set_bgp_distance_info(dest, bdistance);
13897 }
13898
13899 /* Set distance value. */
13900 bdistance->distance = distance;
13901
13902 /* Reset access-list configuration. */
13903 XFREE(MTYPE_AS_LIST, bdistance->access_list);
13904 if (access_list_str)
13905 bdistance->access_list =
13906 XSTRDUP(MTYPE_AS_LIST, access_list_str);
13907
13908 return CMD_SUCCESS;
13909 }
13910
13911 int bgp_distance_unset(uint8_t distance, const char *ip_str,
13912 const char *access_list_str, afi_t afi, safi_t safi,
13913 char *errmsg, size_t errmsg_len)
13914 {
13915 int ret;
13916 struct prefix p;
13917 struct bgp_dest *dest;
13918 struct bgp_distance *bdistance;
13919
13920 ret = str2prefix(ip_str, &p);
13921 if (ret == 0) {
13922 snprintf(errmsg, errmsg_len, "Malformed prefix\n");
13923 return CMD_WARNING_CONFIG_FAILED;
13924 }
13925
13926 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
13927 if (!dest) {
13928 snprintf(errmsg, errmsg_len, "Can't find specified prefix\n");
13929 return CMD_WARNING_CONFIG_FAILED;
13930 }
13931
13932 bdistance = bgp_dest_get_bgp_distance_info(dest);
13933
13934 if (bdistance->distance != distance) {
13935 snprintf(errmsg, errmsg_len,
13936 "Distance does not match configured\n");
13937 return CMD_WARNING_CONFIG_FAILED;
13938 }
13939
13940 XFREE(MTYPE_AS_LIST, bdistance->access_list);
13941 bgp_distance_free(bdistance);
13942
13943 bgp_dest_set_bgp_path_info(dest, NULL);
13944 bgp_dest_unlock_node(dest);
13945 bgp_dest_unlock_node(dest);
13946
13947 return CMD_SUCCESS;
13948 }
13949
13950 /* Apply BGP information to distance method. */
13951 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
13952 afi_t afi, safi_t safi, struct bgp *bgp)
13953 {
13954 struct bgp_dest *dest;
13955 struct prefix q = {0};
13956 struct peer *peer;
13957 struct bgp_distance *bdistance;
13958 struct access_list *alist;
13959 struct bgp_static *bgp_static;
13960
13961 if (!bgp)
13962 return 0;
13963
13964 peer = pinfo->peer;
13965
13966 if (pinfo->attr->distance)
13967 return pinfo->attr->distance;
13968
13969 /* Check source address.
13970 * Note: for aggregate route, peer can have unspec af type.
13971 */
13972 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
13973 && !sockunion2hostprefix(&peer->su, &q))
13974 return 0;
13975
13976 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
13977 if (dest) {
13978 bdistance = bgp_dest_get_bgp_distance_info(dest);
13979 bgp_dest_unlock_node(dest);
13980
13981 if (bdistance->access_list) {
13982 alist = access_list_lookup(afi, bdistance->access_list);
13983 if (alist
13984 && access_list_apply(alist, p) == FILTER_PERMIT)
13985 return bdistance->distance;
13986 } else
13987 return bdistance->distance;
13988 }
13989
13990 /* Backdoor check. */
13991 dest = bgp_node_lookup(bgp->route[afi][safi], p);
13992 if (dest) {
13993 bgp_static = bgp_dest_get_bgp_static_info(dest);
13994 bgp_dest_unlock_node(dest);
13995
13996 if (bgp_static->backdoor) {
13997 if (bgp->distance_local[afi][safi])
13998 return bgp->distance_local[afi][safi];
13999 else
14000 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14001 }
14002 }
14003
14004 if (peer->sort == BGP_PEER_EBGP) {
14005 if (bgp->distance_ebgp[afi][safi])
14006 return bgp->distance_ebgp[afi][safi];
14007 return ZEBRA_EBGP_DISTANCE_DEFAULT;
14008 } else if (peer->sort == BGP_PEER_IBGP) {
14009 if (bgp->distance_ibgp[afi][safi])
14010 return bgp->distance_ibgp[afi][safi];
14011 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14012 } else {
14013 if (bgp->distance_local[afi][safi])
14014 return bgp->distance_local[afi][safi];
14015 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14016 }
14017 }
14018
14019 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
14020 * we should tell ZEBRA update the routes for a specific
14021 * AFI/SAFI to reflect changes in RIB.
14022 */
14023 void bgp_announce_routes_distance_update(struct bgp *bgp, afi_t update_afi,
14024 safi_t update_safi)
14025 {
14026 afi_t afi;
14027 safi_t safi;
14028
14029 FOREACH_AFI_SAFI (afi, safi) {
14030 if (!bgp_fibupd_safi(safi))
14031 continue;
14032
14033 if (afi != update_afi && safi != update_safi)
14034 continue;
14035
14036 if (BGP_DEBUG(zebra, ZEBRA))
14037 zlog_debug(
14038 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
14039 __func__, afi, safi);
14040 bgp_zebra_announce_table(bgp, afi, safi);
14041 }
14042 }
14043
14044 DEFUN_YANG(bgp_distance, bgp_distance_cmd,
14045 "distance bgp (1-255) (1-255) (1-255)",
14046 "Define an administrative distance\n"
14047 "BGP distance\n"
14048 "Distance for routes external to the AS\n"
14049 "Distance for routes internal to the AS\n"
14050 "Distance for local routes\n")
14051 {
14052 int idx_number = 2;
14053 int idx_number_2 = 3;
14054 int idx_number_3 = 4;
14055 afi_t afi;
14056 safi_t safi;
14057 char xpath[XPATH_MAXLEN];
14058
14059 afi = bgp_node_afi(vty);
14060 safi = bgp_node_safi(vty);
14061
14062 snprintf(
14063 xpath, sizeof(xpath),
14064 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/external",
14065 yang_afi_safi_value2identity(afi, safi),
14066 bgp_afi_safi_get_container_str(afi, safi));
14067 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, argv[idx_number]->arg);
14068 snprintf(
14069 xpath, sizeof(xpath),
14070 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/internal",
14071 yang_afi_safi_value2identity(afi, safi),
14072 bgp_afi_safi_get_container_str(afi, safi));
14073 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
14074 argv[idx_number_2]->arg);
14075 snprintf(
14076 xpath, sizeof(xpath),
14077 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/local",
14078 yang_afi_safi_value2identity(afi, safi),
14079 bgp_afi_safi_get_container_str(afi, safi));
14080
14081 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
14082 argv[idx_number_3]->arg);
14083
14084 return nb_cli_apply_changes(vty, NULL);
14085 }
14086
14087 DEFUN_YANG(no_bgp_distance, no_bgp_distance_cmd,
14088 "no distance bgp [(1-255) (1-255) (1-255)]",
14089 NO_STR
14090 "Define an administrative distance\n"
14091 "BGP distance\n"
14092 "Distance for routes external to the AS\n"
14093 "Distance for routes internal to the AS\n"
14094 "Distance for local routes\n")
14095 {
14096 afi_t afi;
14097 safi_t safi;
14098 char xpath[XPATH_MAXLEN];
14099
14100 afi = bgp_node_afi(vty);
14101 safi = bgp_node_safi(vty);
14102
14103 snprintf(
14104 xpath, sizeof(xpath),
14105 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/external",
14106 yang_afi_safi_value2identity(afi, safi),
14107 bgp_afi_safi_get_container_str(afi, safi));
14108 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL);
14109 snprintf(
14110 xpath, sizeof(xpath),
14111 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/internal",
14112 yang_afi_safi_value2identity(afi, safi),
14113 bgp_afi_safi_get_container_str(afi, safi));
14114 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL);
14115 snprintf(
14116 xpath, sizeof(xpath),
14117 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/local",
14118 yang_afi_safi_value2identity(afi, safi),
14119 bgp_afi_safi_get_container_str(afi, safi));
14120
14121 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL);
14122
14123 return nb_cli_apply_changes(vty, NULL);
14124 }
14125
14126 void cli_show_bgp_global_afi_safi_admin_distance_config(struct vty *vty,
14127 struct lyd_node *dnode,
14128 bool show_defaults)
14129 {
14130 uint8_t distance_ebgp, distance_ibgp, distance_local;
14131
14132 distance_ebgp = yang_dnode_get_uint8(dnode, "./external");
14133 distance_ibgp = yang_dnode_get_uint8(dnode, "./internal");
14134 distance_local = yang_dnode_get_uint8(dnode, "./local");
14135
14136 vty_out(vty, " distance bgp %d %d %d\n", distance_ebgp, distance_ibgp,
14137 distance_local);
14138 }
14139
14140 DEFPY_YANG(bgp_distance_source,
14141 bgp_distance_source_cmd,
14142 "[no] distance (1-255) <A.B.C.D/M | X:X::X:X/M>$prefix [WORD$acl]",
14143 NO_STR
14144 "Define an administrative distance\n"
14145 "Distance value\n"
14146 "IPv4 source prefix\n"
14147 "IPv6 source prefix\n"
14148 "Access list name\n")
14149 {
14150 afi_t afi;
14151 safi_t safi;
14152 char xpath[XPATH_MAXLEN];
14153
14154 afi = bgp_node_afi(vty);
14155 safi = bgp_node_safi(vty);
14156
14157 if (!no) {
14158 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
14159 nb_cli_enqueue_change(vty, "./distance", NB_OP_MODIFY,
14160 distance_str);
14161 if (acl)
14162 nb_cli_enqueue_change(vty,
14163 "./access-list-policy-export",
14164 NB_OP_CREATE, acl);
14165 else
14166 nb_cli_enqueue_change(vty,
14167 "./access-list-policy-export",
14168 NB_OP_DESTROY, NULL);
14169 } else {
14170 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
14171 }
14172
14173 snprintf(
14174 xpath, sizeof(xpath),
14175 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance-route[prefix='%s']",
14176 yang_afi_safi_value2identity(afi, safi),
14177 bgp_afi_safi_get_container_str(afi, safi), prefix_str);
14178
14179 return nb_cli_apply_changes(vty, xpath);
14180 }
14181
14182 void cli_show_bgp_global_afi_safi_unicast_admin_distance_route(
14183 struct vty *vty, struct lyd_node *dnode, bool show_defaults)
14184 {
14185 vty_out(vty, " distance %d %s %s\n",
14186 yang_dnode_get_uint8(dnode, "./distance"),
14187 yang_dnode_get_string(dnode, "./prefix"),
14188 (yang_dnode_exists(dnode, "./access-list-policy-export"))
14189 ? yang_dnode_get_string(dnode,
14190 "./access-list-policy-export")
14191 : "");
14192 }
14193
14194 DEFPY_YANG(
14195 bgp_dampening, bgp_dampening_cmd,
14196 "[no] bgp dampening [(1-45)$halflife [(1-20000)$reuse (1-20000)$suppress (1-255)$max_suppress]]",
14197 NO_STR
14198 "BGP Specific commands\n"
14199 "Enable route-flap dampening\n"
14200 "Half-life time for the penalty\n"
14201 "Value to start reusing a route\n"
14202 "Value to start suppressing a route\n"
14203 "Maximum duration to suppress a stable route\n")
14204 {
14205 afi_t afi;
14206 safi_t safi;
14207 char xpath[XPATH_MAXLEN];
14208
14209 afi = bgp_node_afi(vty);
14210 safi = bgp_node_safi(vty);
14211
14212 if (!no) {
14213 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "true");
14214 if (argc == 6) {
14215 nb_cli_enqueue_change(vty, "./reach-decay",
14216 NB_OP_MODIFY, halflife_str);
14217 nb_cli_enqueue_change(vty, "./reuse-above",
14218 NB_OP_MODIFY, reuse_str);
14219 nb_cli_enqueue_change(vty, "./suppress-above",
14220 NB_OP_MODIFY, suppress_str);
14221 nb_cli_enqueue_change(vty, "./unreach-decay",
14222 NB_OP_MODIFY, max_suppress_str);
14223 } if (argc == 3) {
14224 nb_cli_enqueue_change(vty, "./reach-decay",
14225 NB_OP_MODIFY, halflife_str);
14226 }
14227 } else {
14228 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "false");
14229 }
14230
14231 snprintf(
14232 xpath, sizeof(xpath),
14233 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/route-flap-dampening",
14234 yang_afi_safi_value2identity(afi, safi),
14235 bgp_afi_safi_get_container_str(afi, safi));
14236
14237 return nb_cli_apply_changes(vty, xpath);
14238 }
14239
14240 void cli_show_bgp_global_afi_safi_route_flap_dampening(struct vty *vty,
14241 struct lyd_node *dnode,
14242 bool show_defaults)
14243 {
14244 if (!yang_dnode_get_bool(dnode, "./enable"))
14245 return;
14246
14247 int half = DEFAULT_HALF_LIFE * 60;
14248 int reuse = DEFAULT_REUSE;
14249 int suppress = DEFAULT_SUPPRESS;
14250 int max;
14251
14252 half = yang_dnode_get_uint8(dnode, "../reach-decay");
14253 reuse = yang_dnode_get_uint16(dnode, "../reuse-above");
14254 suppress = yang_dnode_get_uint16(dnode, "../suppress-above");
14255 max = yang_dnode_get_uint8(dnode, "../unreach-decay");
14256
14257 if (half == DEFAULT_HALF_LIFE * 60 && reuse == DEFAULT_REUSE
14258 && suppress == DEFAULT_SUPPRESS && max == half * 4)
14259 vty_out(vty, " bgp dampening\n");
14260 else if (half != DEFAULT_HALF_LIFE * 60 && reuse == DEFAULT_REUSE
14261 && suppress == DEFAULT_SUPPRESS && max == half * 4)
14262 vty_out(vty, " bgp dampening %u\n", half);
14263 else
14264 vty_out(vty, " bgp dampening %u %d %d %d\n", half, reuse,
14265 suppress, max);
14266 }
14267
14268 /* Display specified route of BGP table. */
14269 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
14270 const char *ip_str, afi_t afi, safi_t safi,
14271 struct prefix_rd *prd, int prefix_check)
14272 {
14273 int ret;
14274 struct prefix match;
14275 struct bgp_dest *dest;
14276 struct bgp_dest *rm;
14277 struct bgp_path_info *pi;
14278 struct bgp_path_info *pi_temp;
14279 struct bgp *bgp;
14280 struct bgp_table *table;
14281
14282 /* BGP structure lookup. */
14283 if (view_name) {
14284 bgp = bgp_lookup_by_name(view_name);
14285 if (bgp == NULL) {
14286 vty_out(vty, "%% Can't find BGP instance %s\n",
14287 view_name);
14288 return CMD_WARNING;
14289 }
14290 } else {
14291 bgp = bgp_get_default();
14292 if (bgp == NULL) {
14293 vty_out(vty, "%% No BGP process is configured\n");
14294 return CMD_WARNING;
14295 }
14296 }
14297
14298 /* Check IP address argument. */
14299 ret = str2prefix(ip_str, &match);
14300 if (!ret) {
14301 vty_out(vty, "%% address is malformed\n");
14302 return CMD_WARNING;
14303 }
14304
14305 match.family = afi2family(afi);
14306
14307 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14308 || (safi == SAFI_EVPN)) {
14309 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
14310 dest = bgp_route_next(dest)) {
14311 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14312
14313 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
14314 continue;
14315 table = bgp_dest_get_bgp_table_info(dest);
14316 if (!table)
14317 continue;
14318 if ((rm = bgp_node_match(table, &match)) == NULL)
14319 continue;
14320
14321 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
14322
14323 if (!prefix_check
14324 || rm_p->prefixlen == match.prefixlen) {
14325 pi = bgp_dest_get_bgp_path_info(rm);
14326 while (pi) {
14327 if (pi->extra && pi->extra->damp_info) {
14328 pi_temp = pi->next;
14329 bgp_damp_info_free(
14330 &pi->extra->damp_info,
14331 &bgp->damp[afi][safi],
14332 1, afi, safi);
14333 pi = pi_temp;
14334 } else
14335 pi = pi->next;
14336 }
14337 }
14338
14339 bgp_dest_unlock_node(rm);
14340 }
14341 } else {
14342 if ((dest = bgp_node_match(bgp->rib[afi][safi], &match))
14343 != NULL) {
14344 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14345
14346 if (!prefix_check
14347 || dest_p->prefixlen == match.prefixlen) {
14348 pi = bgp_dest_get_bgp_path_info(dest);
14349 while (pi) {
14350 if (pi->extra && pi->extra->damp_info) {
14351 pi_temp = pi->next;
14352 struct bgp_damp_info *bdi =
14353 pi->extra->damp_info;
14354 if (bdi->lastrecord
14355 == BGP_RECORD_UPDATE) {
14356 bgp_aggregate_increment(
14357 bgp,
14358 &bdi->dest->p,
14359 bdi->path,
14360 bdi->afi,
14361 bdi->safi);
14362 bgp_process(bgp,
14363 bdi->dest,
14364 bdi->afi,
14365 bdi->safi);
14366 }
14367 bgp_damp_info_free(
14368 &pi->extra->damp_info,
14369 &bgp->damp[afi][safi],
14370 1, afi, safi);
14371 pi = pi_temp;
14372 } else
14373 pi = pi->next;
14374 }
14375 }
14376
14377 bgp_dest_unlock_node(dest);
14378 }
14379 }
14380
14381 return CMD_SUCCESS;
14382 }
14383
14384 DEFUN (clear_ip_bgp_dampening,
14385 clear_ip_bgp_dampening_cmd,
14386 "clear ip bgp dampening",
14387 CLEAR_STR
14388 IP_STR
14389 BGP_STR
14390 "Clear route flap dampening information\n")
14391 {
14392 VTY_DECLVAR_CONTEXT(bgp, bgp);
14393 bgp_damp_info_clean(bgp, &bgp->damp[AFI_IP][SAFI_UNICAST], AFI_IP,
14394 SAFI_UNICAST);
14395 return CMD_SUCCESS;
14396 }
14397
14398 DEFUN (clear_ip_bgp_dampening_prefix,
14399 clear_ip_bgp_dampening_prefix_cmd,
14400 "clear ip bgp dampening A.B.C.D/M",
14401 CLEAR_STR
14402 IP_STR
14403 BGP_STR
14404 "Clear route flap dampening information\n"
14405 "IPv4 prefix\n")
14406 {
14407 int idx_ipv4_prefixlen = 4;
14408 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
14409 AFI_IP, SAFI_UNICAST, NULL, 1);
14410 }
14411
14412 DEFUN (clear_ip_bgp_dampening_address,
14413 clear_ip_bgp_dampening_address_cmd,
14414 "clear ip bgp dampening A.B.C.D",
14415 CLEAR_STR
14416 IP_STR
14417 BGP_STR
14418 "Clear route flap dampening information\n"
14419 "Network to clear damping information\n")
14420 {
14421 int idx_ipv4 = 4;
14422 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
14423 SAFI_UNICAST, NULL, 0);
14424 }
14425
14426 DEFUN (clear_ip_bgp_dampening_address_mask,
14427 clear_ip_bgp_dampening_address_mask_cmd,
14428 "clear ip bgp dampening A.B.C.D A.B.C.D",
14429 CLEAR_STR
14430 IP_STR
14431 BGP_STR
14432 "Clear route flap dampening information\n"
14433 "Network to clear damping information\n"
14434 "Network mask\n")
14435 {
14436 int idx_ipv4 = 4;
14437 int idx_ipv4_2 = 5;
14438 int ret;
14439 char prefix_str[BUFSIZ];
14440
14441 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
14442 prefix_str, sizeof(prefix_str));
14443 if (!ret) {
14444 vty_out(vty, "%% Inconsistent address and mask\n");
14445 return CMD_WARNING;
14446 }
14447
14448 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
14449 NULL, 0);
14450 }
14451
14452 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
14453 {
14454 struct vty *vty = arg;
14455 struct peer *peer = bucket->data;
14456 char buf[SU_ADDRSTRLEN];
14457
14458 vty_out(vty, "\tPeer: %s %s\n", peer->host,
14459 sockunion2str(&peer->su, buf, sizeof(buf)));
14460 }
14461
14462 DEFUN (show_bgp_listeners,
14463 show_bgp_listeners_cmd,
14464 "show bgp listeners",
14465 SHOW_STR
14466 BGP_STR
14467 "Display Listen Sockets and who created them\n")
14468 {
14469 bgp_dump_listener_info(vty);
14470
14471 return CMD_SUCCESS;
14472 }
14473
14474 DEFUN (show_bgp_peerhash,
14475 show_bgp_peerhash_cmd,
14476 "show bgp peerhash",
14477 SHOW_STR
14478 BGP_STR
14479 "Display information about the BGP peerhash\n")
14480 {
14481 struct list *instances = bm->bgp;
14482 struct listnode *node;
14483 struct bgp *bgp;
14484
14485 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
14486 vty_out(vty, "BGP: %s\n", bgp->name);
14487 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
14488 vty);
14489 }
14490
14491 return CMD_SUCCESS;
14492 }
14493
14494 /* also used for encap safi */
14495 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
14496 afi_t afi, safi_t safi)
14497 {
14498 struct bgp_dest *pdest;
14499 struct bgp_dest *dest;
14500 struct bgp_table *table;
14501 const struct prefix *p;
14502 const struct prefix_rd *prd;
14503 struct bgp_static *bgp_static;
14504 mpls_label_t label;
14505 char rdbuf[RD_ADDRSTRLEN];
14506
14507 /* Network configuration. */
14508 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
14509 pdest = bgp_route_next(pdest)) {
14510 table = bgp_dest_get_bgp_table_info(pdest);
14511 if (!table)
14512 continue;
14513
14514 for (dest = bgp_table_top(table); dest;
14515 dest = bgp_route_next(dest)) {
14516 bgp_static = bgp_dest_get_bgp_static_info(dest);
14517 if (bgp_static == NULL)
14518 continue;
14519
14520 p = bgp_dest_get_prefix(dest);
14521 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14522 pdest);
14523
14524 /* "network" configuration display. */
14525 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
14526 label = decode_label(&bgp_static->label);
14527
14528 vty_out(vty, " network %pFX rd %s", p, rdbuf);
14529 if (safi == SAFI_MPLS_VPN)
14530 vty_out(vty, " label %u", label);
14531
14532 if (bgp_static->rmap.name)
14533 vty_out(vty, " route-map %s",
14534 bgp_static->rmap.name);
14535
14536 if (bgp_static->backdoor)
14537 vty_out(vty, " backdoor");
14538
14539 vty_out(vty, "\n");
14540 }
14541 }
14542 }
14543
14544 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
14545 afi_t afi, safi_t safi)
14546 {
14547 struct bgp_dest *pdest;
14548 struct bgp_dest *dest;
14549 struct bgp_table *table;
14550 const struct prefix *p;
14551 const struct prefix_rd *prd;
14552 struct bgp_static *bgp_static;
14553 char buf[PREFIX_STRLEN * 2];
14554 char buf2[SU_ADDRSTRLEN];
14555 char rdbuf[RD_ADDRSTRLEN];
14556 char esi_buf[ESI_BYTES];
14557
14558 /* Network configuration. */
14559 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
14560 pdest = bgp_route_next(pdest)) {
14561 table = bgp_dest_get_bgp_table_info(pdest);
14562 if (!table)
14563 continue;
14564
14565 for (dest = bgp_table_top(table); dest;
14566 dest = bgp_route_next(dest)) {
14567 bgp_static = bgp_dest_get_bgp_static_info(dest);
14568 if (bgp_static == NULL)
14569 continue;
14570
14571 char *macrouter = NULL;
14572
14573 if (bgp_static->router_mac)
14574 macrouter = prefix_mac2str(
14575 bgp_static->router_mac, NULL, 0);
14576 if (bgp_static->eth_s_id)
14577 esi_to_str(bgp_static->eth_s_id,
14578 esi_buf, sizeof(esi_buf));
14579 p = bgp_dest_get_prefix(dest);
14580 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
14581
14582 /* "network" configuration display. */
14583 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
14584 if (p->u.prefix_evpn.route_type == 5) {
14585 char local_buf[PREFIX_STRLEN];
14586 uint8_t family = is_evpn_prefix_ipaddr_v4((
14587 struct prefix_evpn *)p)
14588 ? AF_INET
14589 : AF_INET6;
14590 inet_ntop(family,
14591 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
14592 local_buf, PREFIX_STRLEN);
14593 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
14594 p->u.prefix_evpn.prefix_addr
14595 .ip_prefix_length);
14596 } else {
14597 prefix2str(p, buf, sizeof(buf));
14598 }
14599
14600 if (bgp_static->gatewayIp.family == AF_INET
14601 || bgp_static->gatewayIp.family == AF_INET6)
14602 inet_ntop(bgp_static->gatewayIp.family,
14603 &bgp_static->gatewayIp.u.prefix, buf2,
14604 sizeof(buf2));
14605 vty_out(vty,
14606 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
14607 buf, rdbuf,
14608 p->u.prefix_evpn.prefix_addr.eth_tag,
14609 decode_label(&bgp_static->label), esi_buf, buf2,
14610 macrouter);
14611
14612 XFREE(MTYPE_TMP, macrouter);
14613 }
14614 }
14615 }
14616
14617 /* Configuration of static route announcement and aggregate
14618 information. */
14619 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
14620 safi_t safi)
14621 {
14622 struct bgp_dest *dest;
14623 const struct prefix *p;
14624 struct bgp_static *bgp_static;
14625 struct bgp_aggregate *bgp_aggregate;
14626
14627 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
14628 bgp_config_write_network_vpn(vty, bgp, afi, safi);
14629 return;
14630 }
14631
14632 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
14633 bgp_config_write_network_evpn(vty, bgp, afi, safi);
14634 return;
14635 }
14636
14637 /* Network configuration. */
14638 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
14639 dest = bgp_route_next(dest)) {
14640 bgp_static = bgp_dest_get_bgp_static_info(dest);
14641 if (bgp_static == NULL)
14642 continue;
14643
14644 p = bgp_dest_get_prefix(dest);
14645
14646 vty_out(vty, " network %pFX", p);
14647
14648 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
14649 vty_out(vty, " label-index %u",
14650 bgp_static->label_index);
14651
14652 if (bgp_static->rmap.name)
14653 vty_out(vty, " route-map %s", bgp_static->rmap.name);
14654
14655 if (bgp_static->backdoor)
14656 vty_out(vty, " backdoor");
14657
14658 vty_out(vty, "\n");
14659 }
14660
14661 /* Aggregate-address configuration. */
14662 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
14663 dest = bgp_route_next(dest)) {
14664 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
14665 if (bgp_aggregate == NULL)
14666 continue;
14667
14668 p = bgp_dest_get_prefix(dest);
14669
14670 vty_out(vty, " aggregate-address %pFX", p);
14671
14672 if (bgp_aggregate->as_set)
14673 vty_out(vty, " as-set");
14674
14675 if (bgp_aggregate->summary_only)
14676 vty_out(vty, " summary-only");
14677
14678 if (bgp_aggregate->rmap.name)
14679 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
14680
14681 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
14682 vty_out(vty, " origin %s",
14683 bgp_origin2str(bgp_aggregate->origin));
14684
14685 if (bgp_aggregate->match_med)
14686 vty_out(vty, " matching-MED-only");
14687
14688 if (bgp_aggregate->suppress_map_name)
14689 vty_out(vty, " suppress-map %s",
14690 bgp_aggregate->suppress_map_name);
14691
14692 vty_out(vty, "\n");
14693 }
14694 }
14695
14696 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
14697 safi_t safi)
14698 {
14699 struct bgp_dest *dest;
14700 struct bgp_distance *bdistance;
14701
14702 /* Distance configuration. */
14703 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
14704 && bgp->distance_local[afi][safi]
14705 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
14706 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
14707 || bgp->distance_local[afi][safi]
14708 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
14709 vty_out(vty, " distance bgp %d %d %d\n",
14710 bgp->distance_ebgp[afi][safi],
14711 bgp->distance_ibgp[afi][safi],
14712 bgp->distance_local[afi][safi]);
14713 }
14714
14715 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
14716 dest = bgp_route_next(dest)) {
14717 bdistance = bgp_dest_get_bgp_distance_info(dest);
14718 if (bdistance != NULL)
14719 vty_out(vty, " distance %d %pBD %s\n",
14720 bdistance->distance, dest,
14721 bdistance->access_list ? bdistance->access_list
14722 : "");
14723 }
14724 }
14725
14726 /* Allocate routing table structure and install commands. */
14727 void bgp_route_init(void)
14728 {
14729 afi_t afi;
14730 safi_t safi;
14731
14732 /* Init BGP distance table. */
14733 FOREACH_AFI_SAFI (afi, safi)
14734 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
14735
14736 /* IPv4 BGP commands. */
14737 install_element(BGP_NODE, &bgp_table_map_cmd);
14738 install_element(BGP_NODE, &bgp_network_cmd);
14739 install_element(BGP_NODE, &no_bgp_table_map_cmd);
14740
14741 install_element(BGP_NODE, &aggregate_addressv4_cmd);
14742
14743 /* IPv4 unicast configuration. */
14744 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
14745 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
14746 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
14747
14748 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
14749
14750 /* IPv4 multicast configuration. */
14751 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
14752 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
14753 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
14754 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
14755
14756 /* IPv4 labeled-unicast configuration. */
14757 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
14758 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
14759
14760 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
14761 install_element(VIEW_NODE, &show_ip_bgp_cmd);
14762 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
14763 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
14764 install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
14765 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
14766 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
14767 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
14768
14769 install_element(VIEW_NODE,
14770 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
14771 install_element(VIEW_NODE,
14772 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
14773 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
14774 install_element(VIEW_NODE,
14775 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
14776 #ifdef KEEP_OLD_VPN_COMMANDS
14777 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
14778 #endif /* KEEP_OLD_VPN_COMMANDS */
14779 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
14780 install_element(VIEW_NODE,
14781 &show_bgp_l2vpn_evpn_route_prefix_cmd);
14782
14783 /* BGP dampening clear commands */
14784 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
14785 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
14786
14787 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
14788 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
14789
14790 /* prefix count */
14791 install_element(ENABLE_NODE,
14792 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
14793 #ifdef KEEP_OLD_VPN_COMMANDS
14794 install_element(ENABLE_NODE,
14795 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
14796 #endif /* KEEP_OLD_VPN_COMMANDS */
14797
14798 /* New config IPv6 BGP commands. */
14799 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
14800 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
14801 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
14802
14803 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
14804
14805 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
14806
14807 /* IPv6 labeled unicast address family. */
14808 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
14809 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
14810
14811 install_element(BGP_NODE, &bgp_distance_cmd);
14812 install_element(BGP_NODE, &no_bgp_distance_cmd);
14813 install_element(BGP_NODE, &bgp_distance_source_cmd);
14814 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
14815 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
14816 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
14817 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
14818 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
14819 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
14820 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
14821 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
14822 install_element(BGP_IPV6_NODE, &bgp_distance_source_cmd);
14823 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
14824 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
14825 install_element(BGP_IPV6M_NODE, &bgp_distance_source_cmd);
14826
14827 /* BGP dampening */
14828 install_element(BGP_NODE, &bgp_dampening_cmd);
14829 install_element(BGP_IPV4_NODE, &bgp_dampening_cmd);
14830 install_element(BGP_IPV4M_NODE, &bgp_dampening_cmd);
14831 install_element(BGP_IPV4L_NODE, &bgp_dampening_cmd);
14832 install_element(BGP_IPV6_NODE, &bgp_dampening_cmd);
14833 install_element(BGP_IPV6M_NODE, &bgp_dampening_cmd);
14834 install_element(BGP_IPV6L_NODE, &bgp_dampening_cmd);
14835
14836 /* Large Communities */
14837 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
14838 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
14839
14840 /* show bgp ipv4 flowspec detailed */
14841 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
14842
14843 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
14844 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
14845 }
14846
14847 void bgp_route_finish(void)
14848 {
14849 afi_t afi;
14850 safi_t safi;
14851
14852 FOREACH_AFI_SAFI (afi, safi) {
14853 bgp_table_unlock(bgp_distance_table[afi][safi]);
14854 bgp_distance_table[afi][safi] = NULL;
14855 }
14856 }