]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
bgpd: encode properly vpnv6 nexthop
[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 "frrstr.h"
27 #include "prefix.h"
28 #include "linklist.h"
29 #include "memory.h"
30 #include "command.h"
31 #include "stream.h"
32 #include "filter.h"
33 #include "log.h"
34 #include "routemap.h"
35 #include "buffer.h"
36 #include "sockunion.h"
37 #include "plist.h"
38 #include "thread.h"
39 #include "workqueue.h"
40 #include "queue.h"
41 #include "memory.h"
42 #include "srv6.h"
43 #include "lib/json.h"
44 #include "lib_errors.h"
45 #include "zclient.h"
46 #include "bgpd/bgpd.h"
47 #include "bgpd/bgp_table.h"
48 #include "bgpd/bgp_route.h"
49 #include "bgpd/bgp_attr.h"
50 #include "bgpd/bgp_debug.h"
51 #include "bgpd/bgp_errors.h"
52 #include "bgpd/bgp_aspath.h"
53 #include "bgpd/bgp_regex.h"
54 #include "bgpd/bgp_community.h"
55 #include "bgpd/bgp_community_alias.h"
56 #include "bgpd/bgp_ecommunity.h"
57 #include "bgpd/bgp_lcommunity.h"
58 #include "bgpd/bgp_clist.h"
59 #include "bgpd/bgp_packet.h"
60 #include "bgpd/bgp_filter.h"
61 #include "bgpd/bgp_fsm.h"
62 #include "bgpd/bgp_mplsvpn.h"
63 #include "bgpd/bgp_nexthop.h"
64 #include "bgpd/bgp_damp.h"
65 #include "bgpd/bgp_advertise.h"
66 #include "bgpd/bgp_zebra.h"
67 #include "bgpd/bgp_vty.h"
68 #include "bgpd/bgp_mpath.h"
69 #include "bgpd/bgp_nht.h"
70 #include "bgpd/bgp_updgrp.h"
71 #include "bgpd/bgp_label.h"
72 #include "bgpd/bgp_addpath.h"
73 #include "bgpd/bgp_mac.h"
74 #include "bgpd/bgp_network.h"
75 #include "bgpd/bgp_trace.h"
76 #include "bgpd/bgp_rpki.h"
77
78 #ifdef ENABLE_BGP_VNC
79 #include "bgpd/rfapi/rfapi_backend.h"
80 #include "bgpd/rfapi/vnc_import_bgp.h"
81 #include "bgpd/rfapi/vnc_export_bgp.h"
82 #endif
83 #include "bgpd/bgp_encap_types.h"
84 #include "bgpd/bgp_encap_tlv.h"
85 #include "bgpd/bgp_evpn.h"
86 #include "bgpd/bgp_evpn_mh.h"
87 #include "bgpd/bgp_evpn_vty.h"
88 #include "bgpd/bgp_flowspec.h"
89 #include "bgpd/bgp_flowspec_util.h"
90 #include "bgpd/bgp_pbr.h"
91
92 #include "bgpd/bgp_route_clippy.c"
93
94 DEFINE_HOOK(bgp_snmp_update_stats,
95 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
96 (rn, pi, added));
97
98 DEFINE_HOOK(bgp_rpki_prefix_status,
99 (struct peer *peer, struct attr *attr,
100 const struct prefix *prefix),
101 (peer, attr, prefix));
102
103 /* Extern from bgp_dump.c */
104 extern const char *bgp_origin_str[];
105 extern const char *bgp_origin_long_str[];
106
107 /* PMSI strings. */
108 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
109 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
110 static const struct message bgp_pmsi_tnltype_str[] = {
111 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
112 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
113 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
114 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
115 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
116 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
117 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
118 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
119 {0}
120 };
121
122 #define VRFID_NONE_STR "-"
123 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
124
125 DEFINE_HOOK(bgp_process,
126 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
127 struct peer *peer, bool withdraw),
128 (bgp, afi, safi, bn, peer, withdraw));
129
130 /** Test if path is suppressed. */
131 static bool bgp_path_suppressed(struct bgp_path_info *pi)
132 {
133 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
134 return false;
135
136 return listcount(pi->extra->aggr_suppressors) > 0;
137 }
138
139 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
140 safi_t safi, const struct prefix *p,
141 struct prefix_rd *prd)
142 {
143 struct bgp_dest *dest;
144 struct bgp_dest *pdest = NULL;
145
146 assert(table);
147
148 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
149 || (safi == SAFI_EVPN)) {
150 pdest = bgp_node_get(table, (struct prefix *)prd);
151
152 if (!bgp_dest_has_bgp_path_info_data(pdest))
153 bgp_dest_set_bgp_table_info(
154 pdest, bgp_table_init(table->bgp, afi, safi));
155 else
156 bgp_dest_unlock_node(pdest);
157 table = bgp_dest_get_bgp_table_info(pdest);
158 }
159
160 dest = bgp_node_get(table, p);
161
162 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
163 || (safi == SAFI_EVPN))
164 dest->pdest = pdest;
165
166 return dest;
167 }
168
169 struct bgp_dest *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
170 safi_t safi, const struct prefix *p,
171 struct prefix_rd *prd)
172 {
173 struct bgp_dest *dest;
174 struct bgp_dest *pdest = NULL;
175
176 if (!table)
177 return NULL;
178
179 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
180 || (safi == SAFI_EVPN)) {
181 pdest = bgp_node_lookup(table, (struct prefix *)prd);
182 if (!pdest)
183 return NULL;
184
185 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
186 bgp_dest_unlock_node(pdest);
187 return NULL;
188 }
189
190 table = bgp_dest_get_bgp_table_info(pdest);
191 }
192
193 dest = bgp_node_lookup(table, p);
194
195 return dest;
196 }
197
198 /* Allocate bgp_path_info_extra */
199 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
200 {
201 struct bgp_path_info_extra *new;
202 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
203 sizeof(struct bgp_path_info_extra));
204 new->label[0] = MPLS_INVALID_LABEL;
205 new->num_labels = 0;
206 new->bgp_fs_pbr = NULL;
207 new->bgp_fs_iprule = NULL;
208 return new;
209 }
210
211 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
212 {
213 struct bgp_path_info_extra *e;
214
215 if (!extra || !*extra)
216 return;
217
218 e = *extra;
219 if (e->damp_info)
220 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
221 e->damp_info->safi);
222
223 e->damp_info = NULL;
224 if (e->parent) {
225 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
226
227 if (bpi->net) {
228 /* FIXME: since multiple e may have the same e->parent
229 * and e->parent->net is holding a refcount for each
230 * of them, we need to do some fudging here.
231 *
232 * WARNING: if bpi->net->lock drops to 0, bpi may be
233 * freed as well (because bpi->net was holding the
234 * last reference to bpi) => write after free!
235 */
236 unsigned refcount;
237
238 bpi = bgp_path_info_lock(bpi);
239 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
240 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
241 if (!refcount)
242 bpi->net = NULL;
243 bgp_path_info_unlock(bpi);
244 }
245 bgp_path_info_unlock(e->parent);
246 e->parent = NULL;
247 }
248
249 if (e->bgp_orig)
250 bgp_unlock(e->bgp_orig);
251
252 if (e->peer_orig)
253 peer_unlock(e->peer_orig);
254
255 if (e->aggr_suppressors)
256 list_delete(&e->aggr_suppressors);
257
258 if (e->mh_info)
259 bgp_evpn_path_mh_info_free(e->mh_info);
260
261 if ((*extra)->bgp_fs_iprule)
262 list_delete(&((*extra)->bgp_fs_iprule));
263 if ((*extra)->bgp_fs_pbr)
264 list_delete(&((*extra)->bgp_fs_pbr));
265 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
266 }
267
268 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
269 * allocated if required.
270 */
271 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
272 {
273 if (!pi->extra)
274 pi->extra = bgp_path_info_extra_new();
275 return pi->extra;
276 }
277
278 /* Free bgp route information. */
279 void bgp_path_info_free_with_caller(const char *name,
280 struct bgp_path_info *path)
281 {
282 frrtrace(2, frr_bgp, bgp_path_info_free, path, name);
283 bgp_attr_unintern(&path->attr);
284
285 bgp_unlink_nexthop(path);
286 bgp_path_info_extra_free(&path->extra);
287 bgp_path_info_mpath_free(&path->mpath);
288 if (path->net)
289 bgp_addpath_free_info_data(&path->tx_addpath,
290 &path->net->tx_addpath);
291
292 peer_unlock(path->peer); /* bgp_path_info peer reference */
293
294 XFREE(MTYPE_BGP_ROUTE, path);
295 }
296
297 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
298 {
299 path->lock++;
300 return path;
301 }
302
303 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
304 {
305 assert(path && path->lock > 0);
306 path->lock--;
307
308 if (path->lock == 0) {
309 bgp_path_info_free(path);
310 return NULL;
311 }
312
313 return path;
314 }
315
316 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
317 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
318 {
319 struct peer *peer;
320 struct bgp_path_info *old_pi, *nextpi;
321 bool set_flag = false;
322 struct bgp *bgp = NULL;
323 struct bgp_table *table = NULL;
324 afi_t afi = 0;
325 safi_t safi = 0;
326
327 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
328 * then the route selection is deferred
329 */
330 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
331 return 0;
332
333 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
334 if (BGP_DEBUG(update, UPDATE_OUT))
335 zlog_debug(
336 "Route %pBD is in workqueue and being processed, not deferred.",
337 dest);
338
339 return 0;
340 }
341
342 table = bgp_dest_table(dest);
343 if (table) {
344 bgp = table->bgp;
345 afi = table->afi;
346 safi = table->safi;
347 }
348
349 for (old_pi = bgp_dest_get_bgp_path_info(dest);
350 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
351 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
352 continue;
353
354 /* Route selection is deferred if there is a stale path which
355 * which indicates peer is in restart mode
356 */
357 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
358 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
359 set_flag = true;
360 } else {
361 /* If the peer is graceful restart capable and peer is
362 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
363 */
364 peer = old_pi->peer;
365 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
366 && BGP_PEER_RESTARTING_MODE(peer)
367 && (old_pi
368 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
369 set_flag = true;
370 }
371 }
372 if (set_flag)
373 break;
374 }
375
376 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
377 * is active
378 */
379 if (set_flag && table) {
380 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
381 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
382 bgp->gr_info[afi][safi].gr_deferred++;
383 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
384 if (BGP_DEBUG(update, UPDATE_OUT))
385 zlog_debug("DEFER route %pBD, dest %p", dest,
386 dest);
387 return 0;
388 }
389 }
390 return -1;
391 }
392
393 void bgp_path_info_add_with_caller(const char *name, struct bgp_dest *dest,
394 struct bgp_path_info *pi)
395 {
396 frrtrace(3, frr_bgp, bgp_path_info_add, dest, pi, name);
397 struct bgp_path_info *top;
398
399 top = bgp_dest_get_bgp_path_info(dest);
400
401 pi->next = top;
402 pi->prev = NULL;
403 if (top)
404 top->prev = pi;
405 bgp_dest_set_bgp_path_info(dest, pi);
406
407 bgp_path_info_lock(pi);
408 bgp_dest_lock_node(dest);
409 peer_lock(pi->peer); /* bgp_path_info peer reference */
410 bgp_dest_set_defer_flag(dest, false);
411 hook_call(bgp_snmp_update_stats, dest, pi, true);
412 }
413
414 /* Do the actual removal of info from RIB, for use by bgp_process
415 completion callback *only* */
416 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
417 {
418 if (pi->next)
419 pi->next->prev = pi->prev;
420 if (pi->prev)
421 pi->prev->next = pi->next;
422 else
423 bgp_dest_set_bgp_path_info(dest, pi->next);
424
425 bgp_path_info_mpath_dequeue(pi);
426 bgp_path_info_unlock(pi);
427 hook_call(bgp_snmp_update_stats, dest, pi, false);
428 bgp_dest_unlock_node(dest);
429 }
430
431 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
432 {
433 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
434 /* set of previous already took care of pcount */
435 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
436 }
437
438 /* undo the effects of a previous call to bgp_path_info_delete; typically
439 called when a route is deleted and then quickly re-added before the
440 deletion has been processed */
441 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
442 {
443 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
444 /* unset of previous already took care of pcount */
445 SET_FLAG(pi->flags, BGP_PATH_VALID);
446 }
447
448 /* Adjust pcount as required */
449 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
450 {
451 struct bgp_table *table;
452
453 assert(dest && bgp_dest_table(dest));
454 assert(pi && pi->peer && pi->peer->bgp);
455
456 table = bgp_dest_table(dest);
457
458 if (pi->peer == pi->peer->bgp->peer_self)
459 return;
460
461 if (!BGP_PATH_COUNTABLE(pi)
462 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
463
464 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
465
466 /* slight hack, but more robust against errors. */
467 if (pi->peer->pcount[table->afi][table->safi])
468 pi->peer->pcount[table->afi][table->safi]--;
469 else
470 flog_err(EC_LIB_DEVELOPMENT,
471 "Asked to decrement 0 prefix count for peer");
472 } else if (BGP_PATH_COUNTABLE(pi)
473 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
474 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
475 pi->peer->pcount[table->afi][table->safi]++;
476 }
477 }
478
479 static int bgp_label_index_differs(struct bgp_path_info *pi1,
480 struct bgp_path_info *pi2)
481 {
482 return (!(pi1->attr->label_index == pi2->attr->label_index));
483 }
484
485 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
486 * This is here primarily to keep prefix-count in check.
487 */
488 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
489 uint32_t flag)
490 {
491 SET_FLAG(pi->flags, flag);
492
493 /* early bath if we know it's not a flag that changes countability state
494 */
495 if (!CHECK_FLAG(flag,
496 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
497 return;
498
499 bgp_pcount_adjust(dest, pi);
500 }
501
502 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
503 uint32_t flag)
504 {
505 UNSET_FLAG(pi->flags, flag);
506
507 /* early bath if we know it's not a flag that changes countability state
508 */
509 if (!CHECK_FLAG(flag,
510 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
511 return;
512
513 bgp_pcount_adjust(dest, pi);
514 }
515
516 /* Get MED value. If MED value is missing and "bgp bestpath
517 missing-as-worst" is specified, treat it as the worst value. */
518 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
519 {
520 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
521 return attr->med;
522 else {
523 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
524 return BGP_MED_MAX;
525 else
526 return 0;
527 }
528 }
529
530 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
531 size_t buf_len)
532 {
533 if (pi->addpath_rx_id)
534 snprintf(buf, buf_len, "path %s (addpath rxid %d)",
535 pi->peer->host, pi->addpath_rx_id);
536 else
537 snprintf(buf, buf_len, "path %s", pi->peer->host);
538 }
539
540
541 /*
542 * Get the ultimate path info.
543 */
544 struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
545 {
546 struct bgp_path_info *bpi_ultimate;
547
548 if (info->sub_type != BGP_ROUTE_IMPORTED)
549 return info;
550
551 for (bpi_ultimate = info;
552 bpi_ultimate->extra && bpi_ultimate->extra->parent;
553 bpi_ultimate = bpi_ultimate->extra->parent)
554 ;
555
556 return bpi_ultimate;
557 }
558
559 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
560 */
561 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
562 struct bgp_path_info *exist, int *paths_eq,
563 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
564 char *pfx_buf, afi_t afi, safi_t safi,
565 enum bgp_path_selection_reason *reason)
566 {
567 const struct prefix *new_p;
568 struct attr *newattr, *existattr;
569 enum bgp_peer_sort new_sort;
570 enum bgp_peer_sort exist_sort;
571 uint32_t new_pref;
572 uint32_t exist_pref;
573 uint32_t new_med;
574 uint32_t exist_med;
575 uint32_t new_weight;
576 uint32_t exist_weight;
577 uint32_t newm, existm;
578 struct in_addr new_id;
579 struct in_addr exist_id;
580 int new_cluster;
581 int exist_cluster;
582 int internal_as_route;
583 int confed_as_route;
584 int ret = 0;
585 int igp_metric_ret = 0;
586 int peer_sort_ret = -1;
587 char new_buf[PATH_ADDPATH_STR_BUFFER];
588 char exist_buf[PATH_ADDPATH_STR_BUFFER];
589 uint32_t new_mm_seq;
590 uint32_t exist_mm_seq;
591 int nh_cmp;
592 esi_t *exist_esi;
593 esi_t *new_esi;
594 bool same_esi;
595 bool old_proxy;
596 bool new_proxy;
597 bool new_origin, exist_origin;
598 struct bgp_path_info *bpi_ultimate;
599
600 *paths_eq = 0;
601
602 /* 0. Null check. */
603 if (new == NULL) {
604 *reason = bgp_path_selection_none;
605 if (debug)
606 zlog_debug("%s: new is NULL", pfx_buf);
607 return 0;
608 }
609
610 if (debug) {
611 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
612 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, new_buf,
613 sizeof(new_buf));
614 }
615
616 if (exist == NULL) {
617 *reason = bgp_path_selection_first;
618 if (debug)
619 zlog_debug("%s(%s): %s is the initial bestpath",
620 pfx_buf, bgp->name_pretty, new_buf);
621 return 1;
622 }
623
624 if (debug) {
625 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
626 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, exist_buf,
627 sizeof(exist_buf));
628 zlog_debug("%s(%s): Comparing %s flags 0x%x with %s flags 0x%x",
629 pfx_buf, bgp->name_pretty, new_buf, new->flags,
630 exist_buf, exist->flags);
631 }
632
633 newattr = new->attr;
634 existattr = exist->attr;
635
636 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
637 * Capability" to a neighbor MUST perform the following upon receiving
638 * a route from that neighbor with the "LLGR_STALE" community, or upon
639 * attaching the "LLGR_STALE" community itself per Section 4.2:
640 *
641 * Treat the route as the least-preferred in route selection (see
642 * below). See the Risks of Depreferencing Routes section (Section 5.2)
643 * for a discussion of potential risks inherent in doing this.
644 */
645 if (bgp_attr_get_community(newattr) &&
646 community_include(bgp_attr_get_community(newattr),
647 COMMUNITY_LLGR_STALE)) {
648 if (debug)
649 zlog_debug(
650 "%s: %s wins over %s due to LLGR_STALE community",
651 pfx_buf, new_buf, exist_buf);
652 return 0;
653 }
654
655 if (bgp_attr_get_community(existattr) &&
656 community_include(bgp_attr_get_community(existattr),
657 COMMUNITY_LLGR_STALE)) {
658 if (debug)
659 zlog_debug(
660 "%s: %s loses to %s due to LLGR_STALE community",
661 pfx_buf, new_buf, exist_buf);
662 return 1;
663 }
664
665 new_p = bgp_dest_get_prefix(new->net);
666
667 /* For EVPN routes, we cannot just go by local vs remote, we have to
668 * look at the MAC mobility sequence number, if present.
669 */
670 if ((safi == SAFI_EVPN)
671 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
672 /* This is an error condition described in RFC 7432 Section
673 * 15.2. The RFC
674 * states that in this scenario "the PE MUST alert the operator"
675 * but it
676 * does not state what other action to take. In order to provide
677 * some
678 * consistency in this scenario we are going to prefer the path
679 * with the
680 * sticky flag.
681 */
682 if (newattr->sticky != existattr->sticky) {
683 if (!debug) {
684 prefix2str(new_p, pfx_buf,
685 sizeof(*pfx_buf)
686 * PREFIX2STR_BUFFER);
687 bgp_path_info_path_with_addpath_rx_str(
688 new, new_buf, sizeof(new_buf));
689 bgp_path_info_path_with_addpath_rx_str(
690 exist, exist_buf, sizeof(exist_buf));
691 }
692
693 if (newattr->sticky && !existattr->sticky) {
694 *reason = bgp_path_selection_evpn_sticky_mac;
695 if (debug)
696 zlog_debug(
697 "%s: %s wins over %s due to sticky MAC flag",
698 pfx_buf, new_buf, exist_buf);
699 return 1;
700 }
701
702 if (!newattr->sticky && existattr->sticky) {
703 *reason = bgp_path_selection_evpn_sticky_mac;
704 if (debug)
705 zlog_debug(
706 "%s: %s loses to %s due to sticky MAC flag",
707 pfx_buf, new_buf, exist_buf);
708 return 0;
709 }
710 }
711
712 new_esi = bgp_evpn_attr_get_esi(newattr);
713 exist_esi = bgp_evpn_attr_get_esi(existattr);
714 if (bgp_evpn_is_esi_valid(new_esi) &&
715 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
716 same_esi = true;
717 } else {
718 same_esi = false;
719 }
720
721 /* If both paths have the same non-zero ES and
722 * one path is local it wins.
723 * PS: Note the local path wins even if the remote
724 * has the higher MM seq. The local path's
725 * MM seq will be fixed up to match the highest
726 * rem seq, subsequently.
727 */
728 if (same_esi) {
729 char esi_buf[ESI_STR_LEN];
730
731 if (bgp_evpn_is_path_local(bgp, new)) {
732 *reason = bgp_path_selection_evpn_local_path;
733 if (debug)
734 zlog_debug(
735 "%s: %s wins over %s as ES %s is same and local",
736 pfx_buf, new_buf, exist_buf,
737 esi_to_str(new_esi, esi_buf,
738 sizeof(esi_buf)));
739 return 1;
740 }
741 if (bgp_evpn_is_path_local(bgp, exist)) {
742 *reason = bgp_path_selection_evpn_local_path;
743 if (debug)
744 zlog_debug(
745 "%s: %s loses to %s as ES %s is same and local",
746 pfx_buf, new_buf, exist_buf,
747 esi_to_str(new_esi, esi_buf,
748 sizeof(esi_buf)));
749 return 0;
750 }
751 }
752
753 new_mm_seq = mac_mobility_seqnum(newattr);
754 exist_mm_seq = mac_mobility_seqnum(existattr);
755
756 if (new_mm_seq > exist_mm_seq) {
757 *reason = bgp_path_selection_evpn_seq;
758 if (debug)
759 zlog_debug(
760 "%s: %s wins over %s due to MM seq %u > %u",
761 pfx_buf, new_buf, exist_buf, new_mm_seq,
762 exist_mm_seq);
763 return 1;
764 }
765
766 if (new_mm_seq < exist_mm_seq) {
767 *reason = bgp_path_selection_evpn_seq;
768 if (debug)
769 zlog_debug(
770 "%s: %s loses to %s due to MM seq %u < %u",
771 pfx_buf, new_buf, exist_buf, new_mm_seq,
772 exist_mm_seq);
773 return 0;
774 }
775
776 /* if the sequence numbers and ESI are the same and one path
777 * is non-proxy it wins (over proxy)
778 */
779 new_proxy = bgp_evpn_attr_is_proxy(newattr);
780 old_proxy = bgp_evpn_attr_is_proxy(existattr);
781 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
782 old_proxy != new_proxy) {
783 if (!new_proxy) {
784 *reason = bgp_path_selection_evpn_non_proxy;
785 if (debug)
786 zlog_debug(
787 "%s: %s wins over %s, same seq/es and non-proxy",
788 pfx_buf, new_buf, exist_buf);
789 return 1;
790 }
791
792 *reason = bgp_path_selection_evpn_non_proxy;
793 if (debug)
794 zlog_debug(
795 "%s: %s loses to %s, same seq/es and non-proxy",
796 pfx_buf, new_buf, exist_buf);
797 return 0;
798 }
799
800 /*
801 * if sequence numbers are the same path with the lowest IP
802 * wins
803 */
804 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
805 if (nh_cmp < 0) {
806 *reason = bgp_path_selection_evpn_lower_ip;
807 if (debug)
808 zlog_debug(
809 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
810 pfx_buf, new_buf, exist_buf, new_mm_seq,
811 &new->attr->nexthop);
812 return 1;
813 }
814 if (nh_cmp > 0) {
815 *reason = bgp_path_selection_evpn_lower_ip;
816 if (debug)
817 zlog_debug(
818 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
819 pfx_buf, new_buf, exist_buf, new_mm_seq,
820 &new->attr->nexthop);
821 return 0;
822 }
823 }
824
825 /* 1. Weight check. */
826 new_weight = newattr->weight;
827 exist_weight = existattr->weight;
828
829 if (new_weight > exist_weight) {
830 *reason = bgp_path_selection_weight;
831 if (debug)
832 zlog_debug("%s: %s wins over %s due to weight %d > %d",
833 pfx_buf, new_buf, exist_buf, new_weight,
834 exist_weight);
835 return 1;
836 }
837
838 if (new_weight < exist_weight) {
839 *reason = bgp_path_selection_weight;
840 if (debug)
841 zlog_debug("%s: %s loses to %s due to weight %d < %d",
842 pfx_buf, new_buf, exist_buf, new_weight,
843 exist_weight);
844 return 0;
845 }
846
847 /* 2. Local preference check. */
848 new_pref = exist_pref = bgp->default_local_pref;
849
850 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
851 new_pref = newattr->local_pref;
852 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
853 exist_pref = existattr->local_pref;
854
855 if (new_pref > exist_pref) {
856 *reason = bgp_path_selection_local_pref;
857 if (debug)
858 zlog_debug(
859 "%s: %s wins over %s due to localpref %d > %d",
860 pfx_buf, new_buf, exist_buf, new_pref,
861 exist_pref);
862 return 1;
863 }
864
865 if (new_pref < exist_pref) {
866 *reason = bgp_path_selection_local_pref;
867 if (debug)
868 zlog_debug(
869 "%s: %s loses to %s due to localpref %d < %d",
870 pfx_buf, new_buf, exist_buf, new_pref,
871 exist_pref);
872 return 0;
873 }
874
875 /* If a BGP speaker supports ACCEPT_OWN and is configured for the
876 * extensions defined in this document, the following step is inserted
877 * after the LOCAL_PREF comparison step in the BGP decision process:
878 * When comparing a pair of routes for a BGP destination, the
879 * route with the ACCEPT_OWN community attached is preferred over
880 * the route that does not have the community.
881 * This extra step MUST only be invoked during the best path selection
882 * process of VPN-IP routes.
883 */
884 if (safi == SAFI_MPLS_VPN &&
885 (CHECK_FLAG(new->peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN) ||
886 CHECK_FLAG(exist->peer->af_flags[afi][safi],
887 PEER_FLAG_ACCEPT_OWN))) {
888 bool new_accept_own = false;
889 bool exist_accept_own = false;
890 uint32_t accept_own = COMMUNITY_ACCEPT_OWN;
891
892 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
893 new_accept_own = community_include(
894 bgp_attr_get_community(newattr), accept_own);
895 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
896 exist_accept_own = community_include(
897 bgp_attr_get_community(existattr), accept_own);
898
899 if (new_accept_own && !exist_accept_own) {
900 *reason = bgp_path_selection_accept_own;
901 if (debug)
902 zlog_debug(
903 "%s: %s wins over %s due to accept-own",
904 pfx_buf, new_buf, exist_buf);
905 return 1;
906 }
907
908 if (!new_accept_own && exist_accept_own) {
909 *reason = bgp_path_selection_accept_own;
910 if (debug)
911 zlog_debug(
912 "%s: %s loses to %s due to accept-own",
913 pfx_buf, new_buf, exist_buf);
914 return 0;
915 }
916 }
917
918 /* Tie-breaker - AIGP (Metric TLV) attribute */
919 if (CHECK_FLAG(newattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
920 CHECK_FLAG(existattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
921 CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_AIGP)) {
922 uint64_t new_aigp = bgp_attr_get_aigp_metric(newattr);
923 uint64_t exist_aigp = bgp_attr_get_aigp_metric(existattr);
924
925 if (new_aigp < exist_aigp) {
926 *reason = bgp_path_selection_aigp;
927 if (debug)
928 zlog_debug(
929 "%s: %s wins over %s due to AIGP %" PRIu64
930 " < %" PRIu64,
931 pfx_buf, new_buf, exist_buf, new_aigp,
932 exist_aigp);
933 return 1;
934 }
935
936 if (new_aigp > exist_aigp) {
937 *reason = bgp_path_selection_aigp;
938 if (debug)
939 zlog_debug(
940 "%s: %s loses to %s due to AIGP %" PRIu64
941 " > %" PRIu64,
942 pfx_buf, new_buf, exist_buf, new_aigp,
943 exist_aigp);
944 return 0;
945 }
946 }
947
948 /* 3. Local route check. We prefer:
949 * - BGP_ROUTE_STATIC
950 * - BGP_ROUTE_AGGREGATE
951 * - BGP_ROUTE_REDISTRIBUTE
952 */
953 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
954 new->sub_type == BGP_ROUTE_IMPORTED);
955 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
956 exist->sub_type == BGP_ROUTE_IMPORTED);
957
958 if (new_origin && !exist_origin) {
959 *reason = bgp_path_selection_local_route;
960 if (debug)
961 zlog_debug(
962 "%s: %s wins over %s due to preferred BGP_ROUTE type",
963 pfx_buf, new_buf, exist_buf);
964 return 1;
965 }
966
967 if (!new_origin && exist_origin) {
968 *reason = bgp_path_selection_local_route;
969 if (debug)
970 zlog_debug(
971 "%s: %s loses to %s due to preferred BGP_ROUTE type",
972 pfx_buf, new_buf, exist_buf);
973 return 0;
974 }
975
976 /* Here if these are imported routes then get ultimate pi for
977 * path compare.
978 */
979 new = bgp_get_imported_bpi_ultimate(new);
980 exist = bgp_get_imported_bpi_ultimate(exist);
981 newattr = new->attr;
982 existattr = exist->attr;
983
984 /* 4. AS path length check. */
985 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
986 int exist_hops = aspath_count_hops(existattr->aspath);
987 int exist_confeds = aspath_count_confeds(existattr->aspath);
988
989 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
990 int aspath_hops;
991
992 aspath_hops = aspath_count_hops(newattr->aspath);
993 aspath_hops += aspath_count_confeds(newattr->aspath);
994
995 if (aspath_hops < (exist_hops + exist_confeds)) {
996 *reason = bgp_path_selection_confed_as_path;
997 if (debug)
998 zlog_debug(
999 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
1000 pfx_buf, new_buf, exist_buf,
1001 aspath_hops,
1002 (exist_hops + exist_confeds));
1003 return 1;
1004 }
1005
1006 if (aspath_hops > (exist_hops + exist_confeds)) {
1007 *reason = bgp_path_selection_confed_as_path;
1008 if (debug)
1009 zlog_debug(
1010 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
1011 pfx_buf, new_buf, exist_buf,
1012 aspath_hops,
1013 (exist_hops + exist_confeds));
1014 return 0;
1015 }
1016 } else {
1017 int newhops = aspath_count_hops(newattr->aspath);
1018
1019 if (newhops < exist_hops) {
1020 *reason = bgp_path_selection_as_path;
1021 if (debug)
1022 zlog_debug(
1023 "%s: %s wins over %s due to aspath hopcount %d < %d",
1024 pfx_buf, new_buf, exist_buf,
1025 newhops, exist_hops);
1026 return 1;
1027 }
1028
1029 if (newhops > exist_hops) {
1030 *reason = bgp_path_selection_as_path;
1031 if (debug)
1032 zlog_debug(
1033 "%s: %s loses to %s due to aspath hopcount %d > %d",
1034 pfx_buf, new_buf, exist_buf,
1035 newhops, exist_hops);
1036 return 0;
1037 }
1038 }
1039 }
1040
1041 /* 5. Origin check. */
1042 if (newattr->origin < existattr->origin) {
1043 *reason = bgp_path_selection_origin;
1044 if (debug)
1045 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
1046 pfx_buf, new_buf, exist_buf,
1047 bgp_origin_long_str[newattr->origin],
1048 bgp_origin_long_str[existattr->origin]);
1049 return 1;
1050 }
1051
1052 if (newattr->origin > existattr->origin) {
1053 *reason = bgp_path_selection_origin;
1054 if (debug)
1055 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
1056 pfx_buf, new_buf, exist_buf,
1057 bgp_origin_long_str[newattr->origin],
1058 bgp_origin_long_str[existattr->origin]);
1059 return 0;
1060 }
1061
1062 /* 6. MED check. */
1063 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
1064 && aspath_count_hops(existattr->aspath) == 0);
1065 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
1066 && aspath_count_confeds(existattr->aspath) > 0
1067 && aspath_count_hops(newattr->aspath) == 0
1068 && aspath_count_hops(existattr->aspath) == 0);
1069
1070 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
1071 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
1072 || aspath_cmp_left(newattr->aspath, existattr->aspath)
1073 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
1074 || internal_as_route) {
1075 new_med = bgp_med_value(new->attr, bgp);
1076 exist_med = bgp_med_value(exist->attr, bgp);
1077
1078 if (new_med < exist_med) {
1079 *reason = bgp_path_selection_med;
1080 if (debug)
1081 zlog_debug(
1082 "%s: %s wins over %s due to MED %d < %d",
1083 pfx_buf, new_buf, exist_buf, new_med,
1084 exist_med);
1085 return 1;
1086 }
1087
1088 if (new_med > exist_med) {
1089 *reason = bgp_path_selection_med;
1090 if (debug)
1091 zlog_debug(
1092 "%s: %s loses to %s due to MED %d > %d",
1093 pfx_buf, new_buf, exist_buf, new_med,
1094 exist_med);
1095 return 0;
1096 }
1097 }
1098
1099 /* 7. Peer type check. */
1100 new_sort = new->peer->sort;
1101 exist_sort = exist->peer->sort;
1102
1103 if (new_sort == BGP_PEER_EBGP
1104 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1105 *reason = bgp_path_selection_peer;
1106 if (debug)
1107 zlog_debug(
1108 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1109 pfx_buf, new_buf, exist_buf);
1110 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1111 return 1;
1112 peer_sort_ret = 1;
1113 }
1114
1115 if (exist_sort == BGP_PEER_EBGP
1116 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1117 *reason = bgp_path_selection_peer;
1118 if (debug)
1119 zlog_debug(
1120 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1121 pfx_buf, new_buf, exist_buf);
1122 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1123 return 0;
1124 peer_sort_ret = 0;
1125 }
1126
1127 /* 8. IGP metric check. */
1128 newm = existm = 0;
1129
1130 if (new->extra)
1131 newm = new->extra->igpmetric;
1132 if (exist->extra)
1133 existm = exist->extra->igpmetric;
1134
1135 if (newm < existm) {
1136 if (debug && peer_sort_ret < 0)
1137 zlog_debug(
1138 "%s: %s wins over %s due to IGP metric %u < %u",
1139 pfx_buf, new_buf, exist_buf, newm, existm);
1140 igp_metric_ret = 1;
1141 }
1142
1143 if (newm > existm) {
1144 if (debug && peer_sort_ret < 0)
1145 zlog_debug(
1146 "%s: %s loses to %s due to IGP metric %u > %u",
1147 pfx_buf, new_buf, exist_buf, newm, existm);
1148 igp_metric_ret = 0;
1149 }
1150
1151 /* 9. Same IGP metric. Compare the cluster list length as
1152 representative of IGP hops metric. Rewrite the metric value
1153 pair (newm, existm) with the cluster list length. Prefer the
1154 path with smaller cluster list length. */
1155 if (newm == existm) {
1156 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP &&
1157 peer_sort_lookup(exist->peer) == BGP_PEER_IBGP &&
1158 (mpath_cfg == NULL || mpath_cfg->same_clusterlen)) {
1159 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1160 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1161
1162 if (newm < existm) {
1163 if (debug && peer_sort_ret < 0)
1164 zlog_debug(
1165 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1166 pfx_buf, new_buf, exist_buf,
1167 newm, existm);
1168 igp_metric_ret = 1;
1169 }
1170
1171 if (newm > existm) {
1172 if (debug && peer_sort_ret < 0)
1173 zlog_debug(
1174 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1175 pfx_buf, new_buf, exist_buf,
1176 newm, existm);
1177 igp_metric_ret = 0;
1178 }
1179 }
1180 }
1181
1182 /* 10. confed-external vs. confed-internal */
1183 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1184 if (new_sort == BGP_PEER_CONFED
1185 && exist_sort == BGP_PEER_IBGP) {
1186 *reason = bgp_path_selection_confed;
1187 if (debug)
1188 zlog_debug(
1189 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1190 pfx_buf, new_buf, exist_buf);
1191 if (!CHECK_FLAG(bgp->flags,
1192 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1193 return 1;
1194 peer_sort_ret = 1;
1195 }
1196
1197 if (exist_sort == BGP_PEER_CONFED
1198 && new_sort == BGP_PEER_IBGP) {
1199 *reason = bgp_path_selection_confed;
1200 if (debug)
1201 zlog_debug(
1202 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1203 pfx_buf, new_buf, exist_buf);
1204 if (!CHECK_FLAG(bgp->flags,
1205 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1206 return 0;
1207 peer_sort_ret = 0;
1208 }
1209 }
1210
1211 /* 11. Maximum path check. */
1212 if (newm == existm) {
1213 /* If one path has a label but the other does not, do not treat
1214 * them as equals for multipath
1215 */
1216 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1217 != (exist->extra
1218 && bgp_is_valid_label(&exist->extra->label[0]))) {
1219 if (debug)
1220 zlog_debug(
1221 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1222 pfx_buf, new_buf, exist_buf);
1223 } else if (CHECK_FLAG(bgp->flags,
1224 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1225
1226 /*
1227 * For the two paths, all comparison steps till IGP
1228 * metric
1229 * have succeeded - including AS_PATH hop count. Since
1230 * 'bgp
1231 * bestpath as-path multipath-relax' knob is on, we
1232 * don't need
1233 * an exact match of AS_PATH. Thus, mark the paths are
1234 * equal.
1235 * That will trigger both these paths to get into the
1236 * multipath
1237 * array.
1238 */
1239 *paths_eq = 1;
1240
1241 if (debug)
1242 zlog_debug(
1243 "%s: %s and %s are equal via multipath-relax",
1244 pfx_buf, new_buf, exist_buf);
1245 } else if (new->peer->sort == BGP_PEER_IBGP) {
1246 if (aspath_cmp(new->attr->aspath,
1247 exist->attr->aspath)) {
1248 *paths_eq = 1;
1249
1250 if (debug)
1251 zlog_debug(
1252 "%s: %s and %s are equal via matching aspaths",
1253 pfx_buf, new_buf, exist_buf);
1254 }
1255 } else if (new->peer->as == exist->peer->as) {
1256 *paths_eq = 1;
1257
1258 if (debug)
1259 zlog_debug(
1260 "%s: %s and %s are equal via same remote-as",
1261 pfx_buf, new_buf, exist_buf);
1262 }
1263 } else {
1264 /*
1265 * TODO: If unequal cost ibgp multipath is enabled we can
1266 * mark the paths as equal here instead of returning
1267 */
1268
1269 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1270 * if either step 7 or 10 (peer type checks) yielded a winner,
1271 * that result was returned immediately. Returning from step 10
1272 * ignored the return value computed in steps 8 and 9 (IGP
1273 * metric checks). In order to preserve that behavior, if
1274 * peer_sort_ret is set, return that rather than igp_metric_ret.
1275 */
1276 ret = peer_sort_ret;
1277 if (peer_sort_ret < 0) {
1278 ret = igp_metric_ret;
1279 if (debug) {
1280 if (ret == 1)
1281 zlog_debug(
1282 "%s: %s wins over %s after IGP metric comparison",
1283 pfx_buf, new_buf, exist_buf);
1284 else
1285 zlog_debug(
1286 "%s: %s loses to %s after IGP metric comparison",
1287 pfx_buf, new_buf, exist_buf);
1288 }
1289 *reason = bgp_path_selection_igp_metric;
1290 }
1291 return ret;
1292 }
1293
1294 /*
1295 * At this point, the decision whether to set *paths_eq = 1 has been
1296 * completed. If we deferred returning because of bestpath peer-type
1297 * relax configuration, return now.
1298 */
1299 if (peer_sort_ret >= 0)
1300 return peer_sort_ret;
1301
1302 /* 12. If both paths are external, prefer the path that was received
1303 first (the oldest one). This step minimizes route-flap, since a
1304 newer path won't displace an older one, even if it was the
1305 preferred route based on the additional decision criteria below. */
1306 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1307 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1308 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1309 *reason = bgp_path_selection_older;
1310 if (debug)
1311 zlog_debug(
1312 "%s: %s wins over %s due to oldest external",
1313 pfx_buf, new_buf, exist_buf);
1314 return 1;
1315 }
1316
1317 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1318 *reason = bgp_path_selection_older;
1319 if (debug)
1320 zlog_debug(
1321 "%s: %s loses to %s due to oldest external",
1322 pfx_buf, new_buf, exist_buf);
1323 return 0;
1324 }
1325 }
1326
1327 /* 13. Router-ID comparison. */
1328 /* If one of the paths is "stale", the corresponding peer router-id will
1329 * be 0 and would always win over the other path. If originator id is
1330 * used for the comparison, it will decide which path is better.
1331 */
1332 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1333 new_id.s_addr = newattr->originator_id.s_addr;
1334 else
1335 new_id.s_addr = new->peer->remote_id.s_addr;
1336 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1337 exist_id.s_addr = existattr->originator_id.s_addr;
1338 else
1339 exist_id.s_addr = exist->peer->remote_id.s_addr;
1340
1341 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1342 *reason = bgp_path_selection_router_id;
1343 if (debug)
1344 zlog_debug(
1345 "%s: %s wins over %s due to Router-ID comparison",
1346 pfx_buf, new_buf, exist_buf);
1347 return 1;
1348 }
1349
1350 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1351 *reason = bgp_path_selection_router_id;
1352 if (debug)
1353 zlog_debug(
1354 "%s: %s loses to %s due to Router-ID comparison",
1355 pfx_buf, new_buf, exist_buf);
1356 return 0;
1357 }
1358
1359 /* 14. Cluster length comparison. */
1360 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1361 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1362
1363 if (new_cluster < exist_cluster) {
1364 *reason = bgp_path_selection_cluster_length;
1365 if (debug)
1366 zlog_debug(
1367 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1368 pfx_buf, new_buf, exist_buf, new_cluster,
1369 exist_cluster);
1370 return 1;
1371 }
1372
1373 if (new_cluster > exist_cluster) {
1374 *reason = bgp_path_selection_cluster_length;
1375 if (debug)
1376 zlog_debug(
1377 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1378 pfx_buf, new_buf, exist_buf, new_cluster,
1379 exist_cluster);
1380 return 0;
1381 }
1382
1383 /* 15. Neighbor address comparison. */
1384 /* Do this only if neither path is "stale" as stale paths do not have
1385 * valid peer information (as the connection may or may not be up).
1386 */
1387 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1388 *reason = bgp_path_selection_stale;
1389 if (debug)
1390 zlog_debug(
1391 "%s: %s wins over %s due to latter path being STALE",
1392 pfx_buf, new_buf, exist_buf);
1393 return 1;
1394 }
1395
1396 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1397 *reason = bgp_path_selection_stale;
1398 if (debug)
1399 zlog_debug(
1400 "%s: %s loses to %s due to former path being STALE",
1401 pfx_buf, new_buf, exist_buf);
1402 return 0;
1403 }
1404
1405 /* locally configured routes to advertise do not have su_remote */
1406 if (new->peer->su_remote == NULL) {
1407 *reason = bgp_path_selection_local_configured;
1408 return 0;
1409 }
1410 if (exist->peer->su_remote == NULL) {
1411 *reason = bgp_path_selection_local_configured;
1412 return 1;
1413 }
1414
1415 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1416
1417 if (ret == 1) {
1418 *reason = bgp_path_selection_neighbor_ip;
1419 if (debug)
1420 zlog_debug(
1421 "%s: %s loses to %s due to Neighor IP comparison",
1422 pfx_buf, new_buf, exist_buf);
1423 return 0;
1424 }
1425
1426 if (ret == -1) {
1427 *reason = bgp_path_selection_neighbor_ip;
1428 if (debug)
1429 zlog_debug(
1430 "%s: %s wins over %s due to Neighor IP comparison",
1431 pfx_buf, new_buf, exist_buf);
1432 return 1;
1433 }
1434
1435 *reason = bgp_path_selection_default;
1436 if (debug)
1437 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1438 pfx_buf, new_buf, exist_buf);
1439
1440 return 1;
1441 }
1442
1443
1444 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1445 struct bgp_path_info *exist, int *paths_eq)
1446 {
1447 enum bgp_path_selection_reason reason;
1448 char pfx_buf[PREFIX2STR_BUFFER];
1449
1450 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1451 AFI_L2VPN, SAFI_EVPN, &reason);
1452 }
1453
1454 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1455 * is preferred, or 0 if they are the same (usually will only occur if
1456 * multipath is enabled
1457 * This version is compatible with */
1458 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1459 struct bgp_path_info *exist, char *pfx_buf,
1460 afi_t afi, safi_t safi,
1461 enum bgp_path_selection_reason *reason)
1462 {
1463 int paths_eq;
1464 int ret;
1465 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1466 afi, safi, reason);
1467
1468 if (paths_eq)
1469 ret = 0;
1470 else {
1471 if (ret == 1)
1472 ret = -1;
1473 else
1474 ret = 1;
1475 }
1476 return ret;
1477 }
1478
1479 static enum filter_type bgp_input_filter(struct peer *peer,
1480 const struct prefix *p,
1481 struct attr *attr, afi_t afi,
1482 safi_t safi)
1483 {
1484 struct bgp_filter *filter;
1485 enum filter_type ret = FILTER_PERMIT;
1486
1487 filter = &peer->filter[afi][safi];
1488
1489 #define FILTER_EXIST_WARN(F, f, filter) \
1490 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1491 zlog_debug("%s: Could not find configured input %s-list %s!", \
1492 peer->host, #f, F##_IN_NAME(filter));
1493
1494 if (DISTRIBUTE_IN_NAME(filter)) {
1495 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1496
1497 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1498 == FILTER_DENY) {
1499 ret = FILTER_DENY;
1500 goto done;
1501 }
1502 }
1503
1504 if (PREFIX_LIST_IN_NAME(filter)) {
1505 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1506
1507 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1508 == PREFIX_DENY) {
1509 ret = FILTER_DENY;
1510 goto done;
1511 }
1512 }
1513
1514 if (FILTER_LIST_IN_NAME(filter)) {
1515 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1516
1517 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1518 == AS_FILTER_DENY) {
1519 ret = FILTER_DENY;
1520 goto done;
1521 }
1522 }
1523
1524 done:
1525 if (frrtrace_enabled(frr_bgp, input_filter)) {
1526 char pfxprint[PREFIX2STR_BUFFER];
1527
1528 prefix2str(p, pfxprint, sizeof(pfxprint));
1529 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1530 ret == FILTER_PERMIT ? "permit" : "deny");
1531 }
1532
1533 return ret;
1534 #undef FILTER_EXIST_WARN
1535 }
1536
1537 static enum filter_type bgp_output_filter(struct peer *peer,
1538 const struct prefix *p,
1539 struct attr *attr, afi_t afi,
1540 safi_t safi)
1541 {
1542 struct bgp_filter *filter;
1543 enum filter_type ret = FILTER_PERMIT;
1544
1545 filter = &peer->filter[afi][safi];
1546
1547 #define FILTER_EXIST_WARN(F, f, filter) \
1548 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1549 zlog_debug("%s: Could not find configured output %s-list %s!", \
1550 peer->host, #f, F##_OUT_NAME(filter));
1551
1552 if (DISTRIBUTE_OUT_NAME(filter)) {
1553 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1554
1555 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1556 == FILTER_DENY) {
1557 ret = FILTER_DENY;
1558 goto done;
1559 }
1560 }
1561
1562 if (PREFIX_LIST_OUT_NAME(filter)) {
1563 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1564
1565 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1566 == PREFIX_DENY) {
1567 ret = FILTER_DENY;
1568 goto done;
1569 }
1570 }
1571
1572 if (FILTER_LIST_OUT_NAME(filter)) {
1573 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1574
1575 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1576 == AS_FILTER_DENY) {
1577 ret = FILTER_DENY;
1578 goto done;
1579 }
1580 }
1581
1582 if (frrtrace_enabled(frr_bgp, output_filter)) {
1583 char pfxprint[PREFIX2STR_BUFFER];
1584
1585 prefix2str(p, pfxprint, sizeof(pfxprint));
1586 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1587 ret == FILTER_PERMIT ? "permit" : "deny");
1588 }
1589
1590 done:
1591 return ret;
1592 #undef FILTER_EXIST_WARN
1593 }
1594
1595 /* If community attribute includes no_export then return 1. */
1596 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1597 {
1598 if (bgp_attr_get_community(attr)) {
1599 /* NO_ADVERTISE check. */
1600 if (community_include(bgp_attr_get_community(attr),
1601 COMMUNITY_NO_ADVERTISE))
1602 return true;
1603
1604 /* NO_EXPORT check. */
1605 if (peer->sort == BGP_PEER_EBGP &&
1606 community_include(bgp_attr_get_community(attr),
1607 COMMUNITY_NO_EXPORT))
1608 return true;
1609
1610 /* NO_EXPORT_SUBCONFED check. */
1611 if (peer->sort == BGP_PEER_EBGP
1612 || peer->sort == BGP_PEER_CONFED)
1613 if (community_include(bgp_attr_get_community(attr),
1614 COMMUNITY_NO_EXPORT_SUBCONFED))
1615 return true;
1616 }
1617 return false;
1618 }
1619
1620 /* Route reflection loop check. */
1621 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1622 {
1623 struct in_addr cluster_id;
1624 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1625
1626 if (cluster) {
1627 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1628 cluster_id = peer->bgp->cluster_id;
1629 else
1630 cluster_id = peer->bgp->router_id;
1631
1632 if (cluster_loop_check(cluster, cluster_id))
1633 return true;
1634 }
1635 return false;
1636 }
1637
1638 static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
1639 {
1640 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1641 if (peer->local_role == ROLE_PROVIDER ||
1642 peer->local_role == ROLE_RS_SERVER)
1643 return true;
1644 if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
1645 return true;
1646 return false;
1647 }
1648 if (peer->local_role == ROLE_CUSTOMER ||
1649 peer->local_role == ROLE_PEER ||
1650 peer->local_role == ROLE_RS_CLIENT) {
1651 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1652 attr->otc = peer->as;
1653 }
1654 return false;
1655 }
1656
1657 static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
1658 {
1659 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1660 if (peer->local_role == ROLE_CUSTOMER ||
1661 peer->local_role == ROLE_RS_CLIENT ||
1662 peer->local_role == ROLE_PEER)
1663 return true;
1664 return false;
1665 }
1666 if (peer->local_role == ROLE_PROVIDER ||
1667 peer->local_role == ROLE_PEER ||
1668 peer->local_role == ROLE_RS_SERVER) {
1669 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1670 attr->otc = peer->bgp->as;
1671 }
1672 return false;
1673 }
1674
1675 static bool bgp_check_role_applicability(afi_t afi, safi_t safi)
1676 {
1677 return ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST);
1678 }
1679
1680 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1681 struct attr *attr, afi_t afi, safi_t safi,
1682 const char *rmap_name, mpls_label_t *label,
1683 uint32_t num_labels, struct bgp_dest *dest)
1684 {
1685 struct bgp_filter *filter;
1686 struct bgp_path_info rmap_path = { 0 };
1687 struct bgp_path_info_extra extra = { 0 };
1688 route_map_result_t ret;
1689 struct route_map *rmap = NULL;
1690
1691 filter = &peer->filter[afi][safi];
1692
1693 /* Apply default weight value. */
1694 if (peer->weight[afi][safi])
1695 attr->weight = peer->weight[afi][safi];
1696
1697 if (rmap_name) {
1698 rmap = route_map_lookup_by_name(rmap_name);
1699
1700 if (rmap == NULL)
1701 return RMAP_DENY;
1702 } else {
1703 if (ROUTE_MAP_IN_NAME(filter)) {
1704 rmap = ROUTE_MAP_IN(filter);
1705
1706 if (rmap == NULL)
1707 return RMAP_DENY;
1708 }
1709 }
1710
1711 /* Route map apply. */
1712 if (rmap) {
1713 memset(&rmap_path, 0, sizeof(rmap_path));
1714 /* Duplicate current value to new structure for modification. */
1715 rmap_path.peer = peer;
1716 rmap_path.attr = attr;
1717 rmap_path.extra = &extra;
1718 rmap_path.net = dest;
1719
1720 extra.num_labels = num_labels;
1721 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1722 memcpy(extra.label, label,
1723 num_labels * sizeof(mpls_label_t));
1724
1725 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1726
1727 /* Apply BGP route map to the attribute. */
1728 ret = route_map_apply(rmap, p, &rmap_path);
1729
1730 peer->rmap_type = 0;
1731
1732 if (ret == RMAP_DENYMATCH)
1733 return RMAP_DENY;
1734 }
1735 return RMAP_PERMIT;
1736 }
1737
1738 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1739 struct attr *attr, afi_t afi, safi_t safi,
1740 const char *rmap_name)
1741 {
1742 struct bgp_path_info rmap_path;
1743 route_map_result_t ret;
1744 struct route_map *rmap = NULL;
1745 uint8_t rmap_type;
1746
1747 /*
1748 * So if we get to this point and have no rmap_name
1749 * we want to just show the output as it currently
1750 * exists.
1751 */
1752 if (!rmap_name)
1753 return RMAP_PERMIT;
1754
1755 /* Apply default weight value. */
1756 if (peer->weight[afi][safi])
1757 attr->weight = peer->weight[afi][safi];
1758
1759 rmap = route_map_lookup_by_name(rmap_name);
1760
1761 /*
1762 * If we have a route map name and we do not find
1763 * the routemap that means we have an implicit
1764 * deny.
1765 */
1766 if (rmap == NULL)
1767 return RMAP_DENY;
1768
1769 memset(&rmap_path, 0, sizeof(rmap_path));
1770 /* Route map apply. */
1771 /* Duplicate current value to new structure for modification. */
1772 rmap_path.peer = peer;
1773 rmap_path.attr = attr;
1774
1775 rmap_type = peer->rmap_type;
1776 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1777
1778 /* Apply BGP route map to the attribute. */
1779 ret = route_map_apply(rmap, p, &rmap_path);
1780
1781 peer->rmap_type = rmap_type;
1782
1783 if (ret == RMAP_DENYMATCH)
1784 /*
1785 * caller has multiple error paths with bgp_attr_flush()
1786 */
1787 return RMAP_DENY;
1788
1789 return RMAP_PERMIT;
1790 }
1791
1792 /* If this is an EBGP peer with remove-private-AS */
1793 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1794 struct peer *peer, struct attr *attr)
1795 {
1796 if (peer->sort == BGP_PEER_EBGP
1797 && (peer_af_flag_check(peer, afi, safi,
1798 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1799 || peer_af_flag_check(peer, afi, safi,
1800 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1801 || peer_af_flag_check(peer, afi, safi,
1802 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1803 || peer_af_flag_check(peer, afi, safi,
1804 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1805 // Take action on the entire aspath
1806 if (peer_af_flag_check(peer, afi, safi,
1807 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1808 || peer_af_flag_check(peer, afi, safi,
1809 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1810 if (peer_af_flag_check(
1811 peer, afi, safi,
1812 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1813 attr->aspath = aspath_replace_private_asns(
1814 attr->aspath, bgp->as, peer->as);
1815
1816 /*
1817 * Even if the aspath consists of just private ASNs we
1818 * need to walk the AS-Path to maintain all instances
1819 * of the peer's ASN to break possible loops.
1820 */
1821 else
1822 attr->aspath = aspath_remove_private_asns(
1823 attr->aspath, peer->as);
1824 }
1825
1826 // 'all' was not specified so the entire aspath must be private
1827 // ASNs
1828 // for us to do anything
1829 else if (aspath_private_as_check(attr->aspath)) {
1830 if (peer_af_flag_check(
1831 peer, afi, safi,
1832 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1833 attr->aspath = aspath_replace_private_asns(
1834 attr->aspath, bgp->as, peer->as);
1835 else
1836 /*
1837 * Walk the aspath to retain any instances of
1838 * the peer_asn
1839 */
1840 attr->aspath = aspath_remove_private_asns(
1841 attr->aspath, peer->as);
1842 }
1843 }
1844 }
1845
1846 /* If this is an EBGP peer with as-override */
1847 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1848 struct peer *peer, struct attr *attr)
1849 {
1850 struct aspath *aspath;
1851
1852 if (peer->sort == BGP_PEER_EBGP &&
1853 peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1854 if (attr->aspath->refcnt)
1855 aspath = aspath_dup(attr->aspath);
1856 else
1857 aspath = attr->aspath;
1858
1859 attr->aspath = aspath_intern(
1860 aspath_replace_specific_asn(aspath, peer->as, bgp->as));
1861
1862 aspath_free(aspath);
1863 }
1864 }
1865
1866 void bgp_attr_add_llgr_community(struct attr *attr)
1867 {
1868 struct community *old;
1869 struct community *new;
1870 struct community *merge;
1871 struct community *llgr;
1872
1873 old = bgp_attr_get_community(attr);
1874 llgr = community_str2com("llgr-stale");
1875
1876 assert(llgr);
1877
1878 if (old) {
1879 merge = community_merge(community_dup(old), llgr);
1880
1881 if (old->refcnt == 0)
1882 community_free(&old);
1883
1884 new = community_uniq_sort(merge);
1885 community_free(&merge);
1886 } else {
1887 new = community_dup(llgr);
1888 }
1889
1890 community_free(&llgr);
1891
1892 bgp_attr_set_community(attr, new);
1893 }
1894
1895 void bgp_attr_add_gshut_community(struct attr *attr)
1896 {
1897 struct community *old;
1898 struct community *new;
1899 struct community *merge;
1900 struct community *gshut;
1901
1902 old = bgp_attr_get_community(attr);
1903 gshut = community_str2com("graceful-shutdown");
1904
1905 assert(gshut);
1906
1907 if (old) {
1908 merge = community_merge(community_dup(old), gshut);
1909
1910 if (old->refcnt == 0)
1911 community_free(&old);
1912
1913 new = community_uniq_sort(merge);
1914 community_free(&merge);
1915 } else {
1916 new = community_dup(gshut);
1917 }
1918
1919 community_free(&gshut);
1920 bgp_attr_set_community(attr, new);
1921
1922 /* When we add the graceful-shutdown community we must also
1923 * lower the local-preference */
1924 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1925 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1926 }
1927
1928
1929 /* Notify BGP Conditional advertisement scanner process. */
1930 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1931 {
1932 struct peer *peer = SUBGRP_PEER(subgrp);
1933 afi_t afi = SUBGRP_AFI(subgrp);
1934 safi_t safi = SUBGRP_SAFI(subgrp);
1935 struct bgp_filter *filter = &peer->filter[afi][safi];
1936
1937 if (!ADVERTISE_MAP_NAME(filter))
1938 return;
1939
1940 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1941 return;
1942
1943 peer->advmap_table_change = true;
1944 }
1945
1946
1947 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1948 {
1949 if (family == AF_INET) {
1950 attr->nexthop.s_addr = INADDR_ANY;
1951 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1952 }
1953 if (family == AF_INET6)
1954 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1955 if (family == AF_EVPN)
1956 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1957 }
1958
1959 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1960 struct update_subgroup *subgrp,
1961 const struct prefix *p, struct attr *attr,
1962 struct attr *post_attr)
1963 {
1964 struct bgp_filter *filter;
1965 struct peer *from;
1966 struct peer *peer;
1967 struct peer *onlypeer;
1968 struct bgp *bgp;
1969 struct attr *piattr;
1970 route_map_result_t ret;
1971 int transparent;
1972 int reflect;
1973 afi_t afi;
1974 safi_t safi;
1975 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1976 bool nh_reset = false;
1977 uint64_t cum_bw;
1978
1979 if (DISABLE_BGP_ANNOUNCE)
1980 return false;
1981
1982 afi = SUBGRP_AFI(subgrp);
1983 safi = SUBGRP_SAFI(subgrp);
1984 peer = SUBGRP_PEER(subgrp);
1985 onlypeer = NULL;
1986 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1987 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1988
1989 from = pi->peer;
1990 filter = &peer->filter[afi][safi];
1991 bgp = SUBGRP_INST(subgrp);
1992 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
1993 : pi->attr;
1994
1995 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
1996 peer->pmax_out[afi][safi] != 0 &&
1997 subgrp->pscount >= peer->pmax_out[afi][safi]) {
1998 if (BGP_DEBUG(update, UPDATE_OUT) ||
1999 BGP_DEBUG(update, UPDATE_PREFIX)) {
2000 zlog_debug("%s reached maximum prefix to be send (%u)",
2001 peer->host, peer->pmax_out[afi][safi]);
2002 }
2003 return false;
2004 }
2005
2006 #ifdef ENABLE_BGP_VNC
2007 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
2008 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
2009 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
2010
2011 /*
2012 * direct and direct_ext type routes originate internally even
2013 * though they can have peer pointers that reference other
2014 * systems
2015 */
2016 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
2017 __func__, p);
2018 samepeer_safe = 1;
2019 }
2020 #endif
2021
2022 if (((afi == AFI_IP) || (afi == AFI_IP6))
2023 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
2024 && (pi->type == ZEBRA_ROUTE_BGP)
2025 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
2026
2027 /* Applies to routes leaked vpn->vrf and vrf->vpn */
2028
2029 samepeer_safe = 1;
2030 }
2031
2032 /* With addpath we may be asked to TX all kinds of paths so make sure
2033 * pi is valid */
2034 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
2035 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
2036 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
2037 return false;
2038 }
2039
2040 /* If this is not the bestpath then check to see if there is an enabled
2041 * addpath
2042 * feature that requires us to advertise it */
2043 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2044 if (!bgp_addpath_capable(pi, peer, afi, safi))
2045 return false;
2046
2047 /* Aggregate-address suppress check. */
2048 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
2049 return false;
2050
2051 /*
2052 * If we are doing VRF 2 VRF leaking via the import
2053 * statement, we want to prevent the route going
2054 * off box as that the RT and RD created are localy
2055 * significant and globaly useless.
2056 */
2057 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
2058 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
2059 return false;
2060
2061 /* If it's labeled safi, make sure the route has a valid label. */
2062 if (safi == SAFI_LABELED_UNICAST) {
2063 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
2064 if (!bgp_is_valid_label(&label)) {
2065 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2066 zlog_debug("u%" PRIu64 ":s%" PRIu64
2067 " %pFX is filtered - no label (%p)",
2068 subgrp->update_group->id, subgrp->id,
2069 p, &label);
2070 return false;
2071 }
2072 }
2073
2074 /* Do not send back route to sender. */
2075 if (onlypeer && from == onlypeer) {
2076 return false;
2077 }
2078
2079 /* Do not send the default route in the BGP table if the neighbor is
2080 * configured for default-originate */
2081 if (CHECK_FLAG(peer->af_flags[afi][safi],
2082 PEER_FLAG_DEFAULT_ORIGINATE)) {
2083 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
2084 return false;
2085 else if (p->family == AF_INET6 && p->prefixlen == 0)
2086 return false;
2087 }
2088
2089 /* Transparency check. */
2090 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
2091 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
2092 transparent = 1;
2093 else
2094 transparent = 0;
2095
2096 /* If community is not disabled check the no-export and local. */
2097 if (!transparent && bgp_community_filter(peer, piattr)) {
2098 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2099 zlog_debug("%s: community filter check fail for %pFX",
2100 __func__, p);
2101 return false;
2102 }
2103
2104 /* If the attribute has originator-id and it is same as remote
2105 peer's id. */
2106 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
2107 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
2108 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2109 zlog_debug(
2110 "%pBP [Update:SEND] %pFX originator-id is same as remote router-id",
2111 onlypeer, p);
2112 return false;
2113 }
2114
2115 /* ORF prefix-list filter check */
2116 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
2117 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
2118 || CHECK_FLAG(peer->af_cap[afi][safi],
2119 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2120 if (peer->orf_plist[afi][safi]) {
2121 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2122 == PREFIX_DENY) {
2123 if (bgp_debug_update(NULL, p,
2124 subgrp->update_group, 0))
2125 zlog_debug(
2126 "%pBP [Update:SEND] %pFX is filtered via ORF",
2127 peer, p);
2128 return false;
2129 }
2130 }
2131
2132 /* Output filter check. */
2133 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2134 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2135 zlog_debug("%pBP [Update:SEND] %pFX is filtered", peer,
2136 p);
2137 return false;
2138 }
2139
2140 /* AS path loop check. */
2141 if (peer->as_path_loop_detection &&
2142 aspath_loop_check(piattr->aspath, peer->as)) {
2143 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2144 zlog_debug(
2145 "%pBP [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2146 peer, peer->as);
2147 return false;
2148 }
2149
2150 /* If we're a CONFED we need to loop check the CONFED ID too */
2151 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2152 if (aspath_loop_check_confed(piattr->aspath, bgp->confed_id)) {
2153 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2154 zlog_debug(
2155 "%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
2156 peer, bgp->confed_id);
2157 return false;
2158 }
2159 }
2160
2161 /* Route-Reflect check. */
2162 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2163 reflect = 1;
2164 else
2165 reflect = 0;
2166
2167 /* IBGP reflection check. */
2168 if (reflect && !samepeer_safe) {
2169 /* A route from a Client peer. */
2170 if (CHECK_FLAG(from->af_flags[afi][safi],
2171 PEER_FLAG_REFLECTOR_CLIENT)) {
2172 /* Reflect to all the Non-Client peers and also to the
2173 Client peers other than the originator. Originator
2174 check
2175 is already done. So there is noting to do. */
2176 /* no bgp client-to-client reflection check. */
2177 if (CHECK_FLAG(bgp->flags,
2178 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2179 if (CHECK_FLAG(peer->af_flags[afi][safi],
2180 PEER_FLAG_REFLECTOR_CLIENT))
2181 return false;
2182 } else {
2183 /* A route from a Non-client peer. Reflect to all other
2184 clients. */
2185 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2186 PEER_FLAG_REFLECTOR_CLIENT))
2187 return false;
2188 }
2189 }
2190
2191 /* For modify attribute, copy it to temporary structure.
2192 * post_attr comes from BGP conditional advertisements, where
2193 * attributes are already processed by advertise-map route-map,
2194 * and this needs to be saved instead of overwriting from the
2195 * path attributes.
2196 */
2197 if (post_attr)
2198 *attr = *post_attr;
2199 else
2200 *attr = *piattr;
2201
2202 /* If local-preference is not set. */
2203 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2204 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2205 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2206 attr->local_pref = bgp->default_local_pref;
2207 }
2208
2209 /* If originator-id is not set and the route is to be reflected,
2210 set the originator id */
2211 if (reflect
2212 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2213 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2214 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2215 }
2216
2217 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2218 */
2219 if (peer->sort == BGP_PEER_EBGP
2220 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2221 if (from != bgp->peer_self && !transparent
2222 && !CHECK_FLAG(peer->af_flags[afi][safi],
2223 PEER_FLAG_MED_UNCHANGED))
2224 attr->flag &=
2225 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2226 }
2227
2228 /* Since the nexthop attribute can vary per peer, it is not explicitly
2229 * set
2230 * in announce check, only certain flags and length (or number of
2231 * nexthops
2232 * -- for IPv6/MP_REACH) are set here in order to guide the update
2233 * formation
2234 * code in setting the nexthop(s) on a per peer basis in
2235 * reformat_peer().
2236 * Typically, the source nexthop in the attribute is preserved but in
2237 * the
2238 * scenarios where we know it will always be overwritten, we reset the
2239 * nexthop to "0" in an attempt to achieve better Update packing. An
2240 * example of this is when a prefix from each of 2 IBGP peers needs to
2241 * be
2242 * announced to an EBGP peer (and they have the same attributes barring
2243 * their nexthop).
2244 */
2245 if (reflect)
2246 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2247
2248 #define NEXTHOP_IS_V6 \
2249 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2250 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2251 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2252 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2253
2254 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2255 * if
2256 * the peer (group) is configured to receive link-local nexthop
2257 * unchanged
2258 * and it is available in the prefix OR we're not reflecting the route,
2259 * link-local nexthop address is valid and
2260 * the peer (group) to whom we're going to announce is on a shared
2261 * network
2262 * and this is either a self-originated route or the peer is EBGP.
2263 * By checking if nexthop LL address is valid we are sure that
2264 * we do not announce LL address as `::`.
2265 */
2266 if (NEXTHOP_IS_V6) {
2267 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2268 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2269 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2270 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2271 || (!reflect && !transparent
2272 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2273 && peer->shared_network
2274 && (from == bgp->peer_self
2275 || peer->sort == BGP_PEER_EBGP))) {
2276 if (safi == SAFI_MPLS_VPN)
2277 attr->mp_nexthop_len =
2278 BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL;
2279 else
2280 attr->mp_nexthop_len =
2281 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2282 }
2283
2284 /* Clear off link-local nexthop in source, whenever it is not
2285 * needed to
2286 * ensure more prefixes share the same attribute for
2287 * announcement.
2288 */
2289 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2290 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2291 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2292 }
2293
2294 if (bgp_check_role_applicability(afi, safi) &&
2295 bgp_otc_egress(peer, attr))
2296 return false;
2297
2298 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2299 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2300
2301 if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
2302 filter->advmap.aname &&
2303 route_map_lookup_by_name(filter->advmap.aname)) {
2304 struct bgp_path_info rmap_path = {0};
2305 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2306 struct attr dummy_attr = *attr;
2307
2308 /* Fill temp path_info */
2309 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2310 pi, peer, &dummy_attr);
2311
2312 struct route_map *amap =
2313 route_map_lookup_by_name(filter->advmap.aname);
2314
2315 ret = route_map_apply(amap, p, &rmap_path);
2316
2317 bgp_attr_flush(&dummy_attr);
2318
2319 /*
2320 * The conditional advertisement mode is Withdraw and this
2321 * prefix is a conditional prefix. Don't advertise it
2322 */
2323 if (ret == RMAP_PERMITMATCH)
2324 return false;
2325 }
2326
2327 /* Route map & unsuppress-map apply. */
2328 if (!post_attr &&
2329 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2330 struct bgp_path_info rmap_path = {0};
2331 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2332 struct attr dummy_attr = {0};
2333
2334 /* Fill temp path_info */
2335 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2336 pi, peer, attr);
2337
2338 /* don't confuse inbound and outbound setting */
2339 RESET_FLAG(attr->rmap_change_flags);
2340
2341 /*
2342 * The route reflector is not allowed to modify the attributes
2343 * of the reflected IBGP routes unless explicitly allowed.
2344 */
2345 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2346 && !CHECK_FLAG(bgp->flags,
2347 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2348 dummy_attr = *attr;
2349 rmap_path.attr = &dummy_attr;
2350 }
2351
2352 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2353
2354 if (bgp_path_suppressed(pi))
2355 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2356 &rmap_path);
2357 else
2358 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2359 &rmap_path);
2360
2361 bgp_attr_flush(&dummy_attr);
2362 peer->rmap_type = 0;
2363
2364 if (ret == RMAP_DENYMATCH) {
2365 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2366 zlog_debug(
2367 "%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
2368 peer, p, ROUTE_MAP_OUT_NAME(filter));
2369 bgp_attr_flush(rmap_path.attr);
2370 return false;
2371 }
2372 }
2373
2374 /* RFC 8212 to prevent route leaks.
2375 * This specification intends to improve this situation by requiring the
2376 * explicit configuration of both BGP Import and Export Policies for any
2377 * External BGP (EBGP) session such as customers, peers, or
2378 * confederation boundaries for all enabled address families. Through
2379 * codification of the aforementioned requirement, operators will
2380 * benefit from consistent behavior across different BGP
2381 * implementations.
2382 */
2383 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2384 if (!bgp_outbound_policy_exists(peer, filter)) {
2385 if (monotime_since(&bgp->ebgprequirespolicywarning,
2386 NULL) > FIFTEENMINUTE2USEC ||
2387 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2388 zlog_warn(
2389 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2390 monotime(&bgp->ebgprequirespolicywarning);
2391 }
2392 return false;
2393 }
2394
2395 /* draft-ietf-idr-deprecate-as-set-confed-set
2396 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2397 * Eventually, This document (if approved) updates RFC 4271
2398 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2399 * and obsoletes RFC 6472.
2400 */
2401 if (peer->bgp->reject_as_sets)
2402 if (aspath_check_as_sets(attr->aspath))
2403 return false;
2404
2405 /* If neighbor soo is configured, then check if the route has
2406 * SoO extended community and validate against the configured
2407 * one. If they match, do not announce, to prevent routing
2408 * loops.
2409 */
2410 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2411 peer->soo[afi][safi]) {
2412 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2413 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2414
2415 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2416 ECOMMUNITY_SITE_ORIGIN) ||
2417 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2418 ECOMMUNITY_SITE_ORIGIN) ||
2419 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
2420 ECOMMUNITY_SITE_ORIGIN)) &&
2421 ecommunity_include(ecomm, ecomm_soo)) {
2422 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2423 zlog_debug(
2424 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2425 peer, p, ecommunity_str(ecomm_soo));
2426 return false;
2427 }
2428 }
2429
2430 /* Codification of AS 0 Processing */
2431 if (aspath_check_as_zero(attr->aspath))
2432 return false;
2433
2434 if (bgp_in_graceful_shutdown(bgp)) {
2435 if (peer->sort == BGP_PEER_IBGP
2436 || peer->sort == BGP_PEER_CONFED) {
2437 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2438 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2439 } else {
2440 bgp_attr_add_gshut_community(attr);
2441 }
2442 }
2443
2444 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2445 * Capability" to a neighbor MUST perform the following upon receiving
2446 * a route from that neighbor with the "LLGR_STALE" community, or upon
2447 * attaching the "LLGR_STALE" community itself per Section 4.2:
2448 *
2449 * The route SHOULD NOT be advertised to any neighbor from which the
2450 * Long-lived Graceful Restart Capability has not been received.
2451 */
2452 if (bgp_attr_get_community(attr) &&
2453 community_include(bgp_attr_get_community(attr),
2454 COMMUNITY_LLGR_STALE) &&
2455 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2456 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2457 return false;
2458
2459 /* After route-map has been applied, we check to see if the nexthop to
2460 * be carried in the attribute (that is used for the announcement) can
2461 * be cleared off or not. We do this in all cases where we would be
2462 * setting the nexthop to "ourselves". For IPv6, we only need to
2463 * consider
2464 * the global nexthop here; the link-local nexthop would have been
2465 * cleared
2466 * already, and if not, it is required by the update formation code.
2467 * Also see earlier comments in this function.
2468 */
2469 /*
2470 * If route-map has performed some operation on the nexthop or the peer
2471 * configuration says to pass it unchanged, we cannot reset the nexthop
2472 * here, so only attempt to do it if these aren't true. Note that the
2473 * route-map handler itself might have cleared the nexthop, if for
2474 * example,
2475 * it is configured as 'peer-address'.
2476 */
2477 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2478 piattr->rmap_change_flags)
2479 && !transparent
2480 && !CHECK_FLAG(peer->af_flags[afi][safi],
2481 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2482 /* We can reset the nexthop, if setting (or forcing) it to
2483 * 'self' */
2484 if (CHECK_FLAG(peer->af_flags[afi][safi],
2485 PEER_FLAG_NEXTHOP_SELF)
2486 || CHECK_FLAG(peer->af_flags[afi][safi],
2487 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2488 if (!reflect
2489 || CHECK_FLAG(peer->af_flags[afi][safi],
2490 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2491 subgroup_announce_reset_nhop(
2492 (peer_cap_enhe(peer, afi, safi)
2493 ? AF_INET6
2494 : p->family),
2495 attr);
2496 nh_reset = true;
2497 }
2498 } else if (peer->sort == BGP_PEER_EBGP) {
2499 /* Can also reset the nexthop if announcing to EBGP, but
2500 * only if
2501 * no peer in the subgroup is on a shared subnet.
2502 * Note: 3rd party nexthop currently implemented for
2503 * IPv4 only.
2504 */
2505 if ((p->family == AF_INET) &&
2506 (!bgp_subgrp_multiaccess_check_v4(
2507 piattr->nexthop,
2508 subgrp, from))) {
2509 subgroup_announce_reset_nhop(
2510 (peer_cap_enhe(peer, afi, safi)
2511 ? AF_INET6
2512 : p->family),
2513 attr);
2514 nh_reset = true;
2515 }
2516
2517 if ((p->family == AF_INET6) &&
2518 (!bgp_subgrp_multiaccess_check_v6(
2519 piattr->mp_nexthop_global,
2520 subgrp, from))) {
2521 subgroup_announce_reset_nhop(
2522 (peer_cap_enhe(peer, afi, safi)
2523 ? AF_INET6
2524 : p->family),
2525 attr);
2526 nh_reset = true;
2527 }
2528
2529
2530
2531 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2532 /*
2533 * This flag is used for leaked vpn-vrf routes
2534 */
2535 int family = p->family;
2536
2537 if (peer_cap_enhe(peer, afi, safi))
2538 family = AF_INET6;
2539
2540 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2541 zlog_debug(
2542 "%s: %pFX BGP_PATH_ANNC_NH_SELF, family=%s",
2543 __func__, p, family2str(family));
2544 subgroup_announce_reset_nhop(family, attr);
2545 nh_reset = true;
2546 }
2547 }
2548
2549 /* If IPv6/MP and nexthop does not have any override and happens
2550 * to
2551 * be a link-local address, reset it so that we don't pass along
2552 * the
2553 * source's link-local IPv6 address to recipients who may not be
2554 * on
2555 * the same interface.
2556 */
2557 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2558 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2559 subgroup_announce_reset_nhop(AF_INET6, attr);
2560 nh_reset = true;
2561 }
2562 }
2563
2564 /* If this is an iBGP, send Origin Validation State (OVS)
2565 * extended community (rfc8097).
2566 */
2567 if (peer->sort == BGP_PEER_IBGP) {
2568 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2569
2570 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2571
2572 if (rpki_state != RPKI_NOT_BEING_USED)
2573 bgp_attr_set_ecommunity(
2574 attr, ecommunity_add_origin_validation_state(
2575 rpki_state,
2576 bgp_attr_get_ecommunity(attr)));
2577 }
2578
2579 /*
2580 * When the next hop is set to ourselves, if all multipaths have
2581 * link-bandwidth announce the cumulative bandwidth as that makes
2582 * the most sense. However, don't modify if the link-bandwidth has
2583 * been explicitly set by user policy.
2584 */
2585 if (nh_reset &&
2586 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2587 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2588 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2589 bgp_attr_set_ecommunity(
2590 attr,
2591 ecommunity_replace_linkbw(
2592 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2593 CHECK_FLAG(
2594 peer->flags,
2595 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2596
2597 return true;
2598 }
2599
2600 static void bgp_route_select_timer_expire(struct thread *thread)
2601 {
2602 struct afi_safi_info *info;
2603 afi_t afi;
2604 safi_t safi;
2605 struct bgp *bgp;
2606
2607 info = THREAD_ARG(thread);
2608 afi = info->afi;
2609 safi = info->safi;
2610 bgp = info->bgp;
2611
2612 bgp->gr_info[afi][safi].t_route_select = NULL;
2613 XFREE(MTYPE_TMP, info);
2614
2615 /* Best path selection */
2616 bgp_best_path_select_defer(bgp, afi, safi);
2617 }
2618
2619 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2620 struct bgp_maxpaths_cfg *mpath_cfg,
2621 struct bgp_path_info_pair *result, afi_t afi,
2622 safi_t safi)
2623 {
2624 struct bgp_path_info *new_select;
2625 struct bgp_path_info *old_select;
2626 struct bgp_path_info *pi;
2627 struct bgp_path_info *pi1;
2628 struct bgp_path_info *pi2;
2629 struct bgp_path_info *nextpi = NULL;
2630 int paths_eq, do_mpath, debug;
2631 struct list mp_list;
2632 char pfx_buf[PREFIX2STR_BUFFER];
2633 char path_buf[PATH_ADDPATH_STR_BUFFER];
2634
2635 bgp_mp_list_init(&mp_list);
2636 do_mpath =
2637 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2638
2639 debug = bgp_debug_bestpath(dest);
2640
2641 if (debug)
2642 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2643
2644 dest->reason = bgp_path_selection_none;
2645 /* bgp deterministic-med */
2646 new_select = NULL;
2647 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2648
2649 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2650 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2651 pi1 = pi1->next)
2652 bgp_path_info_unset_flag(dest, pi1,
2653 BGP_PATH_DMED_SELECTED);
2654
2655 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2656 pi1 = pi1->next) {
2657 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2658 continue;
2659 if (BGP_PATH_HOLDDOWN(pi1))
2660 continue;
2661 if (pi1->peer != bgp->peer_self)
2662 if (!peer_established(pi1->peer))
2663 continue;
2664
2665 new_select = pi1;
2666 if (pi1->next) {
2667 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2668 if (CHECK_FLAG(pi2->flags,
2669 BGP_PATH_DMED_CHECK))
2670 continue;
2671 if (BGP_PATH_HOLDDOWN(pi2))
2672 continue;
2673 if (pi2->peer != bgp->peer_self
2674 && !CHECK_FLAG(
2675 pi2->peer->sflags,
2676 PEER_STATUS_NSF_WAIT))
2677 if (pi2->peer->status
2678 != Established)
2679 continue;
2680
2681 if (!aspath_cmp_left(pi1->attr->aspath,
2682 pi2->attr->aspath)
2683 && !aspath_cmp_left_confed(
2684 pi1->attr->aspath,
2685 pi2->attr->aspath))
2686 continue;
2687
2688 if (bgp_path_info_cmp(
2689 bgp, pi2, new_select,
2690 &paths_eq, mpath_cfg, debug,
2691 pfx_buf, afi, safi,
2692 &dest->reason)) {
2693 bgp_path_info_unset_flag(
2694 dest, new_select,
2695 BGP_PATH_DMED_SELECTED);
2696 new_select = pi2;
2697 }
2698
2699 bgp_path_info_set_flag(
2700 dest, pi2, BGP_PATH_DMED_CHECK);
2701 }
2702 }
2703 bgp_path_info_set_flag(dest, new_select,
2704 BGP_PATH_DMED_CHECK);
2705 bgp_path_info_set_flag(dest, new_select,
2706 BGP_PATH_DMED_SELECTED);
2707
2708 if (debug) {
2709 bgp_path_info_path_with_addpath_rx_str(
2710 new_select, path_buf, sizeof(path_buf));
2711 zlog_debug(
2712 "%pBD(%s): %s is the bestpath from AS %u",
2713 dest, bgp->name_pretty, path_buf,
2714 aspath_get_first_as(
2715 new_select->attr->aspath));
2716 }
2717 }
2718 }
2719
2720 /* Check old selected route and new selected route. */
2721 old_select = NULL;
2722 new_select = NULL;
2723 for (pi = bgp_dest_get_bgp_path_info(dest);
2724 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2725 enum bgp_path_selection_reason reason;
2726
2727 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2728 old_select = pi;
2729
2730 if (BGP_PATH_HOLDDOWN(pi)) {
2731 /* reap REMOVED routes, if needs be
2732 * selected route must stay for a while longer though
2733 */
2734 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2735 && (pi != old_select))
2736 bgp_path_info_reap(dest, pi);
2737
2738 if (debug)
2739 zlog_debug("%s: pi %p in holddown", __func__,
2740 pi);
2741
2742 continue;
2743 }
2744
2745 if (pi->peer && pi->peer != bgp->peer_self
2746 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2747 if (!peer_established(pi->peer)) {
2748
2749 if (debug)
2750 zlog_debug(
2751 "%s: pi %p non self peer %s not estab state",
2752 __func__, pi, pi->peer->host);
2753
2754 continue;
2755 }
2756
2757 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2758 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2759 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2760 if (debug)
2761 zlog_debug("%s: pi %p dmed", __func__, pi);
2762 continue;
2763 }
2764
2765 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2766
2767 reason = dest->reason;
2768 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2769 debug, pfx_buf, afi, safi,
2770 &dest->reason)) {
2771 if (new_select == NULL &&
2772 reason != bgp_path_selection_none)
2773 dest->reason = reason;
2774 new_select = pi;
2775 }
2776 }
2777
2778 /* Now that we know which path is the bestpath see if any of the other
2779 * paths
2780 * qualify as multipaths
2781 */
2782 if (debug) {
2783 if (new_select)
2784 bgp_path_info_path_with_addpath_rx_str(
2785 new_select, path_buf, sizeof(path_buf));
2786 else
2787 snprintf(path_buf, sizeof(path_buf), "NONE");
2788 zlog_debug(
2789 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2790 dest, bgp->name_pretty, path_buf,
2791 old_select ? old_select->peer->host : "NONE");
2792 }
2793
2794 if (do_mpath && new_select) {
2795 for (pi = bgp_dest_get_bgp_path_info(dest);
2796 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2797
2798 if (debug)
2799 bgp_path_info_path_with_addpath_rx_str(
2800 pi, path_buf, sizeof(path_buf));
2801
2802 if (pi == new_select) {
2803 if (debug)
2804 zlog_debug(
2805 "%pBD(%s): %s is the bestpath, add to the multipath list",
2806 dest, bgp->name_pretty,
2807 path_buf);
2808 bgp_mp_list_add(&mp_list, pi);
2809 continue;
2810 }
2811
2812 if (BGP_PATH_HOLDDOWN(pi))
2813 continue;
2814
2815 if (pi->peer && pi->peer != bgp->peer_self
2816 && !CHECK_FLAG(pi->peer->sflags,
2817 PEER_STATUS_NSF_WAIT))
2818 if (!peer_established(pi->peer))
2819 continue;
2820
2821 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2822 if (debug)
2823 zlog_debug(
2824 "%pBD: %s has the same nexthop as the bestpath, skip it",
2825 dest, path_buf);
2826 continue;
2827 }
2828
2829 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2830 mpath_cfg, debug, pfx_buf, afi, safi,
2831 &dest->reason);
2832
2833 if (paths_eq) {
2834 if (debug)
2835 zlog_debug(
2836 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2837 dest, path_buf);
2838 bgp_mp_list_add(&mp_list, pi);
2839 }
2840 }
2841 }
2842
2843 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2844 mpath_cfg);
2845 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2846 bgp_mp_list_clear(&mp_list);
2847
2848 bgp_addpath_update_ids(bgp, dest, afi, safi);
2849
2850 result->old = old_select;
2851 result->new = new_select;
2852
2853 return;
2854 }
2855
2856 /*
2857 * A new route/change in bestpath of an existing route. Evaluate the path
2858 * for advertisement to the subgroup.
2859 */
2860 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2861 struct bgp_path_info *selected,
2862 struct bgp_dest *dest,
2863 uint32_t addpath_tx_id)
2864 {
2865 const struct prefix *p;
2866 struct peer *onlypeer;
2867 struct attr attr;
2868 afi_t afi;
2869 safi_t safi;
2870 struct bgp *bgp;
2871 bool advertise;
2872
2873 p = bgp_dest_get_prefix(dest);
2874 afi = SUBGRP_AFI(subgrp);
2875 safi = SUBGRP_SAFI(subgrp);
2876 bgp = SUBGRP_INST(subgrp);
2877 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2878 : NULL);
2879
2880 if (BGP_DEBUG(update, UPDATE_OUT))
2881 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2882
2883 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2884 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2885 PEER_STATUS_ORF_WAIT_REFRESH))
2886 return;
2887
2888 memset(&attr, 0, sizeof(attr));
2889 /* It's initialized in bgp_announce_check() */
2890
2891 /* Announcement to the subgroup. If the route is filtered withdraw it.
2892 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2893 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2894 * route
2895 */
2896 advertise = bgp_check_advertise(bgp, dest);
2897
2898 if (selected) {
2899 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2900 NULL)) {
2901 /* Route is selected, if the route is already installed
2902 * in FIB, then it is advertised
2903 */
2904 if (advertise) {
2905 if (!bgp_check_withdrawal(bgp, dest))
2906 bgp_adj_out_set_subgroup(
2907 dest, subgrp, &attr, selected);
2908 else
2909 bgp_adj_out_unset_subgroup(
2910 dest, subgrp, 1, addpath_tx_id);
2911 }
2912 } else
2913 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2914 addpath_tx_id);
2915 }
2916
2917 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2918 else {
2919 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2920 }
2921 }
2922
2923 /*
2924 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2925 * This is called at the end of route processing.
2926 */
2927 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2928 {
2929 struct bgp_path_info *pi;
2930
2931 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2932 if (BGP_PATH_HOLDDOWN(pi))
2933 continue;
2934 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2935 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2936 }
2937 }
2938
2939 /*
2940 * Has the route changed from the RIB's perspective? This is invoked only
2941 * if the route selection returns the same best route as earlier - to
2942 * determine if we need to update zebra or not.
2943 */
2944 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2945 {
2946 struct bgp_path_info *mpinfo;
2947
2948 /* If this is multipath, check all selected paths for any nexthop
2949 * change or attribute change. Some attribute changes (e.g., community)
2950 * aren't of relevance to the RIB, but we'll update zebra to ensure
2951 * we handle the case of BGP nexthop change. This is the behavior
2952 * when the best path has an attribute change anyway.
2953 */
2954 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2955 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2956 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2957 return true;
2958
2959 /*
2960 * If this is multipath, check all selected paths for any nexthop change
2961 */
2962 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2963 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2964 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2965 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2966 return true;
2967 }
2968
2969 /* Nothing has changed from the RIB's perspective. */
2970 return false;
2971 }
2972
2973 struct bgp_process_queue {
2974 struct bgp *bgp;
2975 STAILQ_HEAD(, bgp_dest) pqueue;
2976 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2977 unsigned int flags;
2978 unsigned int queued;
2979 };
2980
2981 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
2982 safi_t safi, struct bgp_dest *dest,
2983 struct bgp_path_info *new_select,
2984 struct bgp_path_info *old_select)
2985 {
2986 const struct prefix *p = bgp_dest_get_prefix(dest);
2987
2988 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
2989 return;
2990
2991 if (advertise_type5_routes(bgp, afi) && new_select
2992 && is_route_injectable_into_evpn(new_select)) {
2993
2994 /* apply the route-map */
2995 if (bgp->adv_cmd_rmap[afi][safi].map) {
2996 route_map_result_t ret;
2997 struct bgp_path_info rmap_path;
2998 struct bgp_path_info_extra rmap_path_extra;
2999 struct attr dummy_attr;
3000
3001 dummy_attr = *new_select->attr;
3002
3003 /* Fill temp path_info */
3004 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
3005 new_select, new_select->peer,
3006 &dummy_attr);
3007
3008 RESET_FLAG(dummy_attr.rmap_change_flags);
3009
3010 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
3011 p, &rmap_path);
3012
3013 if (ret == RMAP_DENYMATCH) {
3014 bgp_attr_flush(&dummy_attr);
3015 bgp_evpn_withdraw_type5_route(bgp, p, afi,
3016 safi);
3017 } else
3018 bgp_evpn_advertise_type5_route(
3019 bgp, p, &dummy_attr, afi, safi);
3020 } else {
3021 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
3022 afi, safi);
3023 }
3024 } else if (advertise_type5_routes(bgp, afi) && old_select
3025 && is_route_injectable_into_evpn(old_select))
3026 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
3027 }
3028
3029 /*
3030 * Utility to determine whether a particular path_info should use
3031 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
3032 * in a path where we basically _know_ this is a BGP-LU route.
3033 */
3034 static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
3035 {
3036 /* Certain types get imp null; so do paths where the nexthop is
3037 * not labeled.
3038 */
3039 if (new_select->sub_type == BGP_ROUTE_STATIC
3040 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3041 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
3042 return true;
3043 else if (new_select->extra == NULL ||
3044 !bgp_is_valid_label(&new_select->extra->label[0]))
3045 /* TODO -- should be configurable? */
3046 return true;
3047 else
3048 return false;
3049 }
3050
3051 /*
3052 * old_select = The old best path
3053 * new_select = the new best path
3054 *
3055 * if (!old_select && new_select)
3056 * We are sending new information on.
3057 *
3058 * if (old_select && new_select) {
3059 * if (new_select != old_select)
3060 * We have a new best path send a change
3061 * else
3062 * We've received a update with new attributes that needs
3063 * to be passed on.
3064 * }
3065 *
3066 * if (old_select && !new_select)
3067 * We have no eligible route that we can announce or the rn
3068 * is being removed.
3069 */
3070 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3071 afi_t afi, safi_t safi)
3072 {
3073 struct bgp_path_info *new_select;
3074 struct bgp_path_info *old_select;
3075 struct bgp_path_info_pair old_and_new;
3076 int debug = 0;
3077
3078 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3079 if (dest)
3080 debug = bgp_debug_bestpath(dest);
3081 if (debug)
3082 zlog_debug(
3083 "%s: bgp delete in progress, ignoring event, p=%pBD",
3084 __func__, dest);
3085 return;
3086 }
3087 /* Is it end of initial update? (after startup) */
3088 if (!dest) {
3089 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3090 sizeof(bgp->update_delay_zebra_resume_time));
3091
3092 bgp->main_zebra_update_hold = 0;
3093 FOREACH_AFI_SAFI (afi, safi) {
3094 if (bgp_fibupd_safi(safi))
3095 bgp_zebra_announce_table(bgp, afi, safi);
3096 }
3097 bgp->main_peers_update_hold = 0;
3098
3099 bgp_start_routeadv(bgp);
3100 return;
3101 }
3102
3103 const struct prefix *p = bgp_dest_get_prefix(dest);
3104
3105 debug = bgp_debug_bestpath(dest);
3106 if (debug)
3107 zlog_debug("%s: p=%pBDi(%s) afi=%s, safi=%s start", __func__,
3108 dest, bgp->name_pretty, afi2str(afi),
3109 safi2str(safi));
3110
3111 /* The best path calculation for the route is deferred if
3112 * BGP_NODE_SELECT_DEFER is set
3113 */
3114 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3115 if (BGP_DEBUG(update, UPDATE_OUT))
3116 zlog_debug("SELECT_DEFER flag set for route %p", dest);
3117 return;
3118 }
3119
3120 /* Best path selection. */
3121 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3122 afi, safi);
3123 old_select = old_and_new.old;
3124 new_select = old_and_new.new;
3125
3126 /* Do we need to allocate or free labels?
3127 * Right now, since we only deal with per-prefix labels, it is not
3128 * necessary to do this upon changes to best path. Exceptions:
3129 * - label index has changed -> recalculate resulting label
3130 * - path_info sub_type changed -> switch to/from implicit-null
3131 * - no valid label (due to removed static label binding) -> get new one
3132 */
3133 if (bgp->allocate_mpls_labels[afi][safi]) {
3134 if (new_select) {
3135 if (!old_select
3136 || bgp_label_index_differs(new_select, old_select)
3137 || new_select->sub_type != old_select->sub_type
3138 || !bgp_is_valid_label(&dest->local_label)) {
3139 /* Enforced penultimate hop popping:
3140 * implicit-null for local routes, aggregate
3141 * and redistributed routes
3142 */
3143 if (bgp_lu_need_imp_null(new_select)) {
3144 if (CHECK_FLAG(
3145 dest->flags,
3146 BGP_NODE_REGISTERED_FOR_LABEL)
3147 || CHECK_FLAG(
3148 dest->flags,
3149 BGP_NODE_LABEL_REQUESTED))
3150 bgp_unregister_for_label(dest);
3151 dest->local_label = mpls_lse_encode(
3152 MPLS_LABEL_IMPLICIT_NULL, 0, 0,
3153 1);
3154 bgp_set_valid_label(&dest->local_label);
3155 } else
3156 bgp_register_for_label(dest,
3157 new_select);
3158 }
3159 } else if (CHECK_FLAG(dest->flags,
3160 BGP_NODE_REGISTERED_FOR_LABEL)
3161 || CHECK_FLAG(dest->flags,
3162 BGP_NODE_LABEL_REQUESTED)) {
3163 bgp_unregister_for_label(dest);
3164 }
3165 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3166 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3167 bgp_unregister_for_label(dest);
3168 }
3169
3170 if (debug)
3171 zlog_debug(
3172 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3173 __func__, dest, bgp->name_pretty, afi2str(afi),
3174 safi2str(safi), old_select, new_select);
3175
3176 /* If best route remains the same and this is not due to user-initiated
3177 * clear, see exactly what needs to be done.
3178 */
3179 if (old_select && old_select == new_select
3180 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3181 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3182 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3183 if (bgp_zebra_has_route_changed(old_select)) {
3184 #ifdef ENABLE_BGP_VNC
3185 vnc_import_bgp_add_route(bgp, p, old_select);
3186 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3187 #endif
3188 if (bgp_fibupd_safi(safi)
3189 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3190
3191 if (BGP_SUPPRESS_FIB_ENABLED(bgp)
3192 && new_select->sub_type == BGP_ROUTE_NORMAL)
3193 SET_FLAG(dest->flags,
3194 BGP_NODE_FIB_INSTALL_PENDING);
3195
3196 if (new_select->type == ZEBRA_ROUTE_BGP
3197 && (new_select->sub_type == BGP_ROUTE_NORMAL
3198 || new_select->sub_type
3199 == BGP_ROUTE_IMPORTED))
3200
3201 bgp_zebra_announce(dest, p, old_select,
3202 bgp, afi, safi);
3203 }
3204 }
3205
3206 /* If there is a change of interest to peers, reannounce the
3207 * route. */
3208 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3209 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3210 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3211 group_announce_route(bgp, afi, safi, dest, new_select);
3212
3213 /* unicast routes must also be annouced to
3214 * labeled-unicast update-groups */
3215 if (safi == SAFI_UNICAST)
3216 group_announce_route(bgp, afi,
3217 SAFI_LABELED_UNICAST, dest,
3218 new_select);
3219
3220 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3221 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3222 }
3223
3224 /* advertise/withdraw type-5 routes */
3225 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3226 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3227 bgp_process_evpn_route_injection(
3228 bgp, afi, safi, dest, old_select, old_select);
3229
3230 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3231 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3232 bgp_zebra_clear_route_change_flags(dest);
3233 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3234 return;
3235 }
3236
3237 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3238 */
3239 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3240
3241 /* bestpath has changed; bump version */
3242 if (old_select || new_select) {
3243 bgp_bump_version(dest);
3244
3245 if (!bgp->t_rmap_def_originate_eval) {
3246 bgp_lock(bgp);
3247 thread_add_timer(
3248 bm->master,
3249 update_group_refresh_default_originate_route_map,
3250 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3251 &bgp->t_rmap_def_originate_eval);
3252 }
3253 }
3254
3255 if (old_select)
3256 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3257 if (new_select) {
3258 if (debug)
3259 zlog_debug("%s: setting SELECTED flag", __func__);
3260 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3261 bgp_path_info_unset_flag(dest, new_select,
3262 BGP_PATH_ATTR_CHANGED);
3263 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3264 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3265 }
3266
3267 #ifdef ENABLE_BGP_VNC
3268 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3269 if (old_select != new_select) {
3270 if (old_select) {
3271 vnc_import_bgp_exterior_del_route(bgp, p,
3272 old_select);
3273 vnc_import_bgp_del_route(bgp, p, old_select);
3274 }
3275 if (new_select) {
3276 vnc_import_bgp_exterior_add_route(bgp, p,
3277 new_select);
3278 vnc_import_bgp_add_route(bgp, p, new_select);
3279 }
3280 }
3281 }
3282 #endif
3283
3284 group_announce_route(bgp, afi, safi, dest, new_select);
3285
3286 /* unicast routes must also be annouced to labeled-unicast update-groups
3287 */
3288 if (safi == SAFI_UNICAST)
3289 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3290 new_select);
3291
3292 /* FIB update. */
3293 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3294 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3295
3296 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3297 && (new_select->sub_type == BGP_ROUTE_NORMAL
3298 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3299 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3300
3301 if (BGP_SUPPRESS_FIB_ENABLED(bgp))
3302 SET_FLAG(dest->flags,
3303 BGP_NODE_FIB_INSTALL_PENDING);
3304
3305 /* if this is an evpn imported type-5 prefix,
3306 * we need to withdraw the route first to clear
3307 * the nh neigh and the RMAC entry.
3308 */
3309 if (old_select &&
3310 is_route_parent_evpn(old_select))
3311 bgp_zebra_withdraw(p, old_select, bgp, safi);
3312
3313 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3314 } else {
3315 /* Withdraw the route from the kernel. */
3316 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3317 && (old_select->sub_type == BGP_ROUTE_NORMAL
3318 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3319 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3320
3321 bgp_zebra_withdraw(p, old_select, bgp, safi);
3322 }
3323 }
3324
3325 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3326 old_select);
3327
3328 /* Clear any route change flags. */
3329 bgp_zebra_clear_route_change_flags(dest);
3330
3331 /* Reap old select bgp_path_info, if it has been removed */
3332 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3333 bgp_path_info_reap(dest, old_select);
3334
3335 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3336 return;
3337 }
3338
3339 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3340 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3341 {
3342 struct bgp_dest *dest;
3343 int cnt = 0;
3344 struct afi_safi_info *thread_info;
3345
3346 if (bgp->gr_info[afi][safi].t_route_select) {
3347 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
3348
3349 thread_info = THREAD_ARG(t);
3350 XFREE(MTYPE_TMP, thread_info);
3351 THREAD_OFF(bgp->gr_info[afi][safi].t_route_select);
3352 }
3353
3354 if (BGP_DEBUG(update, UPDATE_OUT)) {
3355 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3356 get_afi_safi_str(afi, safi, false),
3357 bgp->gr_info[afi][safi].gr_deferred);
3358 }
3359
3360 /* Process the route list */
3361 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3362 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3363 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3364 dest = bgp_route_next(dest)) {
3365 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3366 continue;
3367
3368 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3369 bgp->gr_info[afi][safi].gr_deferred--;
3370 bgp_process_main_one(bgp, dest, afi, safi);
3371 cnt++;
3372 }
3373 /* If iteration stopped before the entire table was traversed then the
3374 * node needs to be unlocked.
3375 */
3376 if (dest) {
3377 bgp_dest_unlock_node(dest);
3378 dest = NULL;
3379 }
3380
3381 /* Send EOR message when all routes are processed */
3382 if (!bgp->gr_info[afi][safi].gr_deferred) {
3383 bgp_send_delayed_eor(bgp);
3384 /* Send route processing complete message to RIB */
3385 bgp_zebra_update(afi, safi, bgp->vrf_id,
3386 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3387 return;
3388 }
3389
3390 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3391
3392 thread_info->afi = afi;
3393 thread_info->safi = safi;
3394 thread_info->bgp = bgp;
3395
3396 /* If there are more routes to be processed, start the
3397 * selection timer
3398 */
3399 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3400 BGP_ROUTE_SELECT_DELAY,
3401 &bgp->gr_info[afi][safi].t_route_select);
3402 }
3403
3404 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3405 {
3406 struct bgp_process_queue *pqnode = data;
3407 struct bgp *bgp = pqnode->bgp;
3408 struct bgp_table *table;
3409 struct bgp_dest *dest;
3410
3411 /* eoiu marker */
3412 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3413 bgp_process_main_one(bgp, NULL, 0, 0);
3414 /* should always have dedicated wq call */
3415 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3416 return WQ_SUCCESS;
3417 }
3418
3419 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3420 dest = STAILQ_FIRST(&pqnode->pqueue);
3421 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3422 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3423 table = bgp_dest_table(dest);
3424 /* note, new DESTs may be added as part of processing */
3425 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3426
3427 bgp_dest_unlock_node(dest);
3428 bgp_table_unlock(table);
3429 }
3430
3431 return WQ_SUCCESS;
3432 }
3433
3434 static void bgp_processq_del(struct work_queue *wq, void *data)
3435 {
3436 struct bgp_process_queue *pqnode = data;
3437
3438 bgp_unlock(pqnode->bgp);
3439
3440 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3441 }
3442
3443 void bgp_process_queue_init(struct bgp *bgp)
3444 {
3445 if (!bgp->process_queue) {
3446 char name[BUFSIZ];
3447
3448 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3449 bgp->process_queue = work_queue_new(bm->master, name);
3450 }
3451
3452 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3453 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3454 bgp->process_queue->spec.max_retries = 0;
3455 bgp->process_queue->spec.hold = 50;
3456 /* Use a higher yield value of 50ms for main queue processing */
3457 bgp->process_queue->spec.yield = 50 * 1000L;
3458 }
3459
3460 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3461 {
3462 struct bgp_process_queue *pqnode;
3463
3464 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3465 sizeof(struct bgp_process_queue));
3466
3467 /* unlocked in bgp_processq_del */
3468 pqnode->bgp = bgp_lock(bgp);
3469 STAILQ_INIT(&pqnode->pqueue);
3470
3471 return pqnode;
3472 }
3473
3474 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3475 {
3476 #define ARBITRARY_PROCESS_QLEN 10000
3477 struct work_queue *wq = bgp->process_queue;
3478 struct bgp_process_queue *pqnode;
3479 int pqnode_reuse = 0;
3480
3481 /* already scheduled for processing? */
3482 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3483 return;
3484
3485 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3486 * the workqueue
3487 */
3488 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3489 if (BGP_DEBUG(update, UPDATE_OUT))
3490 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3491 dest);
3492 return;
3493 }
3494
3495 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3496 if (BGP_DEBUG(update, UPDATE_OUT))
3497 zlog_debug(
3498 "Soft reconfigure table in progress for route %p",
3499 dest);
3500 return;
3501 }
3502
3503 if (wq == NULL)
3504 return;
3505
3506 /* Add route nodes to an existing work queue item until reaching the
3507 limit only if is from the same BGP view and it's not an EOIU marker
3508 */
3509 if (work_queue_item_count(wq)) {
3510 struct work_queue_item *item = work_queue_last_item(wq);
3511 pqnode = item->data;
3512
3513 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3514 || pqnode->bgp != bgp
3515 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3516 pqnode = bgp_processq_alloc(bgp);
3517 else
3518 pqnode_reuse = 1;
3519 } else
3520 pqnode = bgp_processq_alloc(bgp);
3521 /* all unlocked in bgp_process_wq */
3522 bgp_table_lock(bgp_dest_table(dest));
3523
3524 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3525 bgp_dest_lock_node(dest);
3526
3527 /* can't be enqueued twice */
3528 assert(STAILQ_NEXT(dest, pq) == NULL);
3529 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3530 pqnode->queued++;
3531
3532 if (!pqnode_reuse)
3533 work_queue_add(wq, pqnode);
3534
3535 return;
3536 }
3537
3538 void bgp_add_eoiu_mark(struct bgp *bgp)
3539 {
3540 struct bgp_process_queue *pqnode;
3541
3542 if (bgp->process_queue == NULL)
3543 return;
3544
3545 pqnode = bgp_processq_alloc(bgp);
3546
3547 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3548 work_queue_add(bgp->process_queue, pqnode);
3549 }
3550
3551 static void bgp_maximum_prefix_restart_timer(struct thread *thread)
3552 {
3553 struct peer *peer;
3554
3555 peer = THREAD_ARG(thread);
3556 peer->t_pmax_restart = NULL;
3557
3558 if (bgp_debug_neighbor_events(peer))
3559 zlog_debug(
3560 "%s Maximum-prefix restart timer expired, restore peering",
3561 peer->host);
3562
3563 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3564 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3565 }
3566
3567 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3568 safi_t safi)
3569 {
3570 uint32_t count = 0;
3571 bool filtered = false;
3572 struct bgp_dest *dest;
3573 struct bgp_adj_in *ain;
3574 struct attr attr = {};
3575 struct bgp_table *table = peer->bgp->rib[afi][safi];
3576
3577 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3578 for (ain = dest->adj_in; ain; ain = ain->next) {
3579 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3580
3581 attr = *ain->attr;
3582
3583 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3584 == FILTER_DENY)
3585 filtered = true;
3586
3587 if (bgp_input_modifier(
3588 peer, rn_p, &attr, afi, safi,
3589 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3590 NULL, 0, NULL)
3591 == RMAP_DENY)
3592 filtered = true;
3593
3594 if (filtered)
3595 count++;
3596
3597 bgp_attr_flush(&attr);
3598 }
3599 }
3600
3601 return count;
3602 }
3603
3604 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3605 int always)
3606 {
3607 iana_afi_t pkt_afi;
3608 iana_safi_t pkt_safi;
3609 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3610 PEER_FLAG_MAX_PREFIX_FORCE))
3611 ? bgp_filtered_routes_count(peer, afi, safi)
3612 + peer->pcount[afi][safi]
3613 : peer->pcount[afi][safi];
3614
3615 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3616 return false;
3617
3618 if (pcount > peer->pmax[afi][safi]) {
3619 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3620 PEER_STATUS_PREFIX_LIMIT)
3621 && !always)
3622 return false;
3623
3624 zlog_info(
3625 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3626 get_afi_safi_str(afi, safi, false), peer, pcount,
3627 peer->pmax[afi][safi]);
3628 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3629
3630 if (CHECK_FLAG(peer->af_flags[afi][safi],
3631 PEER_FLAG_MAX_PREFIX_WARNING))
3632 return false;
3633
3634 /* Convert AFI, SAFI to values for packet. */
3635 pkt_afi = afi_int2iana(afi);
3636 pkt_safi = safi_int2iana(safi);
3637 {
3638 uint8_t ndata[7];
3639
3640 ndata[0] = (pkt_afi >> 8);
3641 ndata[1] = pkt_afi;
3642 ndata[2] = pkt_safi;
3643 ndata[3] = (peer->pmax[afi][safi] >> 24);
3644 ndata[4] = (peer->pmax[afi][safi] >> 16);
3645 ndata[5] = (peer->pmax[afi][safi] >> 8);
3646 ndata[6] = (peer->pmax[afi][safi]);
3647
3648 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3649 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3650 BGP_NOTIFY_CEASE_MAX_PREFIX,
3651 ndata, 7);
3652 }
3653
3654 /* Dynamic peers will just close their connection. */
3655 if (peer_dynamic_neighbor(peer))
3656 return true;
3657
3658 /* restart timer start */
3659 if (peer->pmax_restart[afi][safi]) {
3660 peer->v_pmax_restart =
3661 peer->pmax_restart[afi][safi] * 60;
3662
3663 if (bgp_debug_neighbor_events(peer))
3664 zlog_debug(
3665 "%pBP Maximum-prefix restart timer started for %d secs",
3666 peer, peer->v_pmax_restart);
3667
3668 BGP_TIMER_ON(peer->t_pmax_restart,
3669 bgp_maximum_prefix_restart_timer,
3670 peer->v_pmax_restart);
3671 }
3672
3673 return true;
3674 } else
3675 UNSET_FLAG(peer->af_sflags[afi][safi],
3676 PEER_STATUS_PREFIX_LIMIT);
3677
3678 if (pcount
3679 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3680 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3681 PEER_STATUS_PREFIX_THRESHOLD)
3682 && !always)
3683 return false;
3684
3685 zlog_info(
3686 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3687 get_afi_safi_str(afi, safi, false), peer, pcount,
3688 peer->pmax[afi][safi]);
3689 SET_FLAG(peer->af_sflags[afi][safi],
3690 PEER_STATUS_PREFIX_THRESHOLD);
3691 } else
3692 UNSET_FLAG(peer->af_sflags[afi][safi],
3693 PEER_STATUS_PREFIX_THRESHOLD);
3694 return false;
3695 }
3696
3697 /* Unconditionally remove the route from the RIB, without taking
3698 * damping into consideration (eg, because the session went down)
3699 */
3700 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3701 struct peer *peer, afi_t afi, safi_t safi)
3702 {
3703
3704 struct bgp *bgp = NULL;
3705 bool delete_route = false;
3706
3707 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3708 safi);
3709
3710 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3711 bgp_path_info_delete(dest, pi); /* keep historical info */
3712
3713 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3714 * flag
3715 */
3716 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3717 delete_route = true;
3718 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3719 delete_route = true;
3720 if (delete_route) {
3721 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3722 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3723 bgp = pi->peer->bgp;
3724 bgp->gr_info[afi][safi].gr_deferred--;
3725 }
3726 }
3727 }
3728
3729 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3730 bgp_process(peer->bgp, dest, afi, safi);
3731 }
3732
3733 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3734 struct peer *peer, afi_t afi, safi_t safi,
3735 struct prefix_rd *prd)
3736 {
3737 const struct prefix *p = bgp_dest_get_prefix(dest);
3738
3739 /* apply dampening, if result is suppressed, we'll be retaining
3740 * the bgp_path_info in the RIB for historical reference.
3741 */
3742 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3743 && peer->sort == BGP_PEER_EBGP)
3744 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3745 == BGP_DAMP_SUPPRESSED) {
3746 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3747 safi);
3748 return;
3749 }
3750
3751 #ifdef ENABLE_BGP_VNC
3752 if (safi == SAFI_MPLS_VPN) {
3753 struct bgp_dest *pdest = NULL;
3754 struct bgp_table *table = NULL;
3755
3756 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3757 (struct prefix *)prd);
3758 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3759 table = bgp_dest_get_bgp_table_info(pdest);
3760
3761 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3762 peer->bgp, prd, table, p, pi);
3763 }
3764 bgp_dest_unlock_node(pdest);
3765 }
3766 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3767 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3768
3769 vnc_import_bgp_del_route(peer->bgp, p, pi);
3770 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3771 }
3772 }
3773 #endif
3774
3775 /* If this is an EVPN route, process for un-import. */
3776 if (safi == SAFI_EVPN)
3777 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3778
3779 bgp_rib_remove(dest, pi, peer, afi, safi);
3780 }
3781
3782 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3783 struct peer *peer, struct attr *attr,
3784 struct bgp_dest *dest)
3785 {
3786 struct bgp_path_info *new;
3787
3788 /* Make new BGP info. */
3789 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3790 new->type = type;
3791 new->instance = instance;
3792 new->sub_type = sub_type;
3793 new->peer = peer;
3794 new->attr = attr;
3795 new->uptime = monotime(NULL);
3796 new->net = dest;
3797 return new;
3798 }
3799
3800 /* Check if received nexthop is valid or not. */
3801 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3802 uint8_t type, uint8_t stype, struct attr *attr,
3803 struct bgp_dest *dest)
3804 {
3805 bool ret = false;
3806 bool is_bgp_static_route =
3807 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3808 : false;
3809
3810 /*
3811 * Only validated for unicast and multicast currently.
3812 * Also valid for EVPN where the nexthop is an IP address.
3813 * If we are a bgp static route being checked then there is
3814 * no need to check to see if the nexthop is martian as
3815 * that it should be ok.
3816 */
3817 if (is_bgp_static_route ||
3818 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3819 return false;
3820
3821 /* If NEXT_HOP is present, validate it. */
3822 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3823 if (attr->nexthop.s_addr == INADDR_ANY ||
3824 !ipv4_unicast_valid(&attr->nexthop) ||
3825 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3826 return true;
3827 }
3828
3829 /* If MP_NEXTHOP is present, validate it. */
3830 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3831 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3832 * it is not an IPv6 link-local address.
3833 *
3834 * If we receive an UPDATE with nexthop length set to 32 bytes
3835 * we shouldn't discard an UPDATE if it's set to (::).
3836 * The link-local (2st) is validated along the code path later.
3837 */
3838 if (attr->mp_nexthop_len) {
3839 switch (attr->mp_nexthop_len) {
3840 case BGP_ATTR_NHLEN_IPV4:
3841 case BGP_ATTR_NHLEN_VPNV4:
3842 ret = (attr->mp_nexthop_global_in.s_addr ==
3843 INADDR_ANY ||
3844 !ipv4_unicast_valid(
3845 &attr->mp_nexthop_global_in) ||
3846 bgp_nexthop_self(bgp, afi, type, stype, attr,
3847 dest));
3848 break;
3849
3850 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3851 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3852 ret = (IN6_IS_ADDR_UNSPECIFIED(
3853 &attr->mp_nexthop_global)
3854 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3855 || IN6_IS_ADDR_MULTICAST(
3856 &attr->mp_nexthop_global)
3857 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3858 dest));
3859 break;
3860 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3861 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3862 || IN6_IS_ADDR_MULTICAST(
3863 &attr->mp_nexthop_global)
3864 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3865 dest));
3866 break;
3867
3868 default:
3869 ret = true;
3870 break;
3871 }
3872 }
3873
3874 return ret;
3875 }
3876
3877 static void bgp_attr_add_no_export_community(struct attr *attr)
3878 {
3879 struct community *old;
3880 struct community *new;
3881 struct community *merge;
3882 struct community *no_export;
3883
3884 old = bgp_attr_get_community(attr);
3885 no_export = community_str2com("no-export");
3886
3887 assert(no_export);
3888
3889 if (old) {
3890 merge = community_merge(community_dup(old), no_export);
3891
3892 if (!old->refcnt)
3893 community_free(&old);
3894
3895 new = community_uniq_sort(merge);
3896 community_free(&merge);
3897 } else {
3898 new = community_dup(no_export);
3899 }
3900
3901 community_free(&no_export);
3902
3903 bgp_attr_set_community(attr, new);
3904 }
3905
3906 static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi,
3907 struct attr *attr, const struct prefix *prefix,
3908 int *sub_type)
3909 {
3910 struct listnode *node, *nnode;
3911 struct bgp *bgp;
3912 bool accept_own_found = false;
3913
3914 if (safi != SAFI_MPLS_VPN)
3915 return false;
3916
3917 /* Processing of the ACCEPT_OWN community is enabled by configuration */
3918 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN))
3919 return false;
3920
3921 /* The route in question carries the ACCEPT_OWN community */
3922 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3923 struct community *comm = bgp_attr_get_community(attr);
3924
3925 if (community_include(comm, COMMUNITY_ACCEPT_OWN))
3926 accept_own_found = true;
3927 }
3928
3929 /* The route in question is targeted to one or more destination VRFs
3930 * on the router (as determined by inspecting the Route Target(s)).
3931 */
3932 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3933 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3934 continue;
3935
3936 if (accept_own_found &&
3937 ecommunity_include(
3938 bgp->vpn_policy[afi]
3939 .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
3940 bgp_attr_get_ecommunity(attr))) {
3941 if (bgp_debug_update(peer, prefix, NULL, 1))
3942 zlog_debug(
3943 "%pBP prefix %pFX has ORIGINATOR_ID, but it's accepted due to ACCEPT_OWN",
3944 peer, prefix);
3945
3946 /* Treat this route as imported, because it's leaked
3947 * already from another VRF, and we got an updated
3948 * version from route-reflector with ACCEPT_OWN
3949 * community.
3950 */
3951 *sub_type = BGP_ROUTE_IMPORTED;
3952
3953 return true;
3954 }
3955 }
3956
3957 return false;
3958 }
3959
3960 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3961 struct attr *attr, afi_t afi, safi_t safi, int type,
3962 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3963 uint32_t num_labels, int soft_reconfig,
3964 struct bgp_route_evpn *evpn)
3965 {
3966 int ret;
3967 int aspath_loop_count = 0;
3968 struct bgp_dest *dest;
3969 struct bgp *bgp;
3970 struct attr new_attr;
3971 struct attr *attr_new;
3972 struct bgp_path_info *pi;
3973 struct bgp_path_info *new = NULL;
3974 struct bgp_path_info_extra *extra;
3975 const char *reason;
3976 char pfx_buf[BGP_PRD_PATH_STRLEN];
3977 int connected = 0;
3978 int do_loop_check = 1;
3979 int has_valid_label = 0;
3980 afi_t nh_afi;
3981 bool force_evpn_import = false;
3982 safi_t orig_safi = safi;
3983 bool leak_success = true;
3984 int allowas_in = 0;
3985
3986 if (frrtrace_enabled(frr_bgp, process_update)) {
3987 char pfxprint[PREFIX2STR_BUFFER];
3988
3989 prefix2str(p, pfxprint, sizeof(pfxprint));
3990 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
3991 afi, safi, attr);
3992 }
3993
3994 #ifdef ENABLE_BGP_VNC
3995 int vnc_implicit_withdraw = 0;
3996 #endif
3997 int same_attr = 0;
3998 const struct prefix *bgp_nht_param_prefix;
3999
4000 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
4001 if (orig_safi == SAFI_LABELED_UNICAST)
4002 safi = SAFI_UNICAST;
4003
4004 memset(&new_attr, 0, sizeof(new_attr));
4005 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4006 new_attr.label = MPLS_INVALID_LABEL;
4007
4008 bgp = peer->bgp;
4009 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4010 /* TODO: Check to see if we can get rid of "is_valid_label" */
4011 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4012 has_valid_label = (num_labels > 0) ? 1 : 0;
4013 else
4014 has_valid_label = bgp_is_valid_label(label);
4015
4016 if (has_valid_label)
4017 assert(label != NULL);
4018
4019 /* Update overlay index of the attribute */
4020 if (afi == AFI_L2VPN && evpn)
4021 memcpy(&attr->evpn_overlay, evpn,
4022 sizeof(struct bgp_route_evpn));
4023
4024 /* When peer's soft reconfiguration enabled. Record input packet in
4025 Adj-RIBs-In. */
4026 if (!soft_reconfig
4027 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4028 && peer != bgp->peer_self)
4029 bgp_adj_in_set(dest, peer, attr, addpath_id);
4030
4031 /* Update permitted loop count */
4032 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
4033 allowas_in = peer->allowas_in[afi][safi];
4034
4035 /* Check previously received route. */
4036 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4037 if (pi->peer == peer && pi->type == type
4038 && pi->sub_type == sub_type
4039 && pi->addpath_rx_id == addpath_id)
4040 break;
4041
4042 /* AS path local-as loop check. */
4043 if (peer->change_local_as) {
4044 if (allowas_in)
4045 aspath_loop_count = allowas_in;
4046 else if (!CHECK_FLAG(peer->flags,
4047 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4048 aspath_loop_count = 1;
4049
4050 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4051 > aspath_loop_count) {
4052 peer->stat_pfx_aspath_loop++;
4053 reason = "as-path contains our own AS;";
4054 goto filtered;
4055 }
4056 }
4057
4058 /* If the peer is configured for "allowas-in origin" and the last ASN in
4059 * the
4060 * as-path is our ASN then we do not need to call aspath_loop_check
4061 */
4062 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4063 if (aspath_get_last_as(attr->aspath) == bgp->as)
4064 do_loop_check = 0;
4065
4066 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
4067 bgp_nht_param_prefix = NULL;
4068 else
4069 bgp_nht_param_prefix = p;
4070
4071 /* AS path loop check. */
4072 if (do_loop_check) {
4073 if (aspath_loop_check(attr->aspath, bgp->as) >
4074 peer->allowas_in[afi][safi]) {
4075 peer->stat_pfx_aspath_loop++;
4076 reason = "as-path contains our own AS;";
4077 goto filtered;
4078 }
4079 }
4080
4081 /* If we're a CONFED we need to loop check the CONFED ID too */
4082 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check)
4083 if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) >
4084 peer->allowas_in[afi][safi]) {
4085 peer->stat_pfx_aspath_loop++;
4086 reason = "as-path contains our own confed AS;";
4087 goto filtered;
4088 }
4089
4090 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4091 * enabled, then take care of that too.
4092 */
4093 bool accept_own = false;
4094
4095 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4096 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4097 accept_own =
4098 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4099 if (!accept_own) {
4100 peer->stat_pfx_originator_loop++;
4101 reason = "originator is us;";
4102 goto filtered;
4103 }
4104 }
4105
4106 /* Route reflector cluster ID check. */
4107 if (bgp_cluster_filter(peer, attr)) {
4108 peer->stat_pfx_cluster_loop++;
4109 reason = "reflected from the same cluster;";
4110 goto filtered;
4111 }
4112
4113 /* Apply incoming filter. */
4114 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4115 peer->stat_pfx_filter++;
4116 reason = "filter;";
4117 goto filtered;
4118 }
4119
4120 /* RFC 8212 to prevent route leaks.
4121 * This specification intends to improve this situation by requiring the
4122 * explicit configuration of both BGP Import and Export Policies for any
4123 * External BGP (EBGP) session such as customers, peers, or
4124 * confederation boundaries for all enabled address families. Through
4125 * codification of the aforementioned requirement, operators will
4126 * benefit from consistent behavior across different BGP
4127 * implementations.
4128 */
4129 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4130 if (!bgp_inbound_policy_exists(peer,
4131 &peer->filter[afi][safi])) {
4132 reason = "inbound policy missing";
4133 if (monotime_since(&bgp->ebgprequirespolicywarning,
4134 NULL) > FIFTEENMINUTE2USEC ||
4135 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4136 zlog_warn(
4137 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4138 monotime(&bgp->ebgprequirespolicywarning);
4139 }
4140 goto filtered;
4141 }
4142
4143 /* draft-ietf-idr-deprecate-as-set-confed-set
4144 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4145 * Eventually, This document (if approved) updates RFC 4271
4146 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4147 * and obsoletes RFC 6472.
4148 */
4149 if (peer->bgp->reject_as_sets)
4150 if (aspath_check_as_sets(attr->aspath)) {
4151 reason =
4152 "as-path contains AS_SET or AS_CONFED_SET type;";
4153 goto filtered;
4154 }
4155
4156 new_attr = *attr;
4157
4158 /* Apply incoming route-map.
4159 * NB: new_attr may now contain newly allocated values from route-map
4160 * "set"
4161 * commands, so we need bgp_attr_flush in the error paths, until we
4162 * intern
4163 * the attr (which takes over the memory references) */
4164 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4165 num_labels, dest)
4166 == RMAP_DENY) {
4167 peer->stat_pfx_filter++;
4168 reason = "route-map;";
4169 bgp_attr_flush(&new_attr);
4170 goto filtered;
4171 }
4172
4173 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4174 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4175 /* remove from RIB previous entry */
4176 bgp_zebra_withdraw(p, pi, bgp, safi);
4177 }
4178
4179 if (peer->sort == BGP_PEER_EBGP) {
4180
4181 /* rfc7999:
4182 * A BGP speaker receiving an announcement tagged with the
4183 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4184 * NO_EXPORT community as defined in RFC1997, or a
4185 * similar community, to prevent propagation of the
4186 * prefix outside the local AS. The community to prevent
4187 * propagation SHOULD be chosen according to the operator's
4188 * routing policy.
4189 */
4190 if (bgp_attr_get_community(&new_attr) &&
4191 community_include(bgp_attr_get_community(&new_attr),
4192 COMMUNITY_BLACKHOLE))
4193 bgp_attr_add_no_export_community(&new_attr);
4194
4195 /* If we receive the graceful-shutdown community from an eBGP
4196 * peer we must lower local-preference */
4197 if (bgp_attr_get_community(&new_attr) &&
4198 community_include(bgp_attr_get_community(&new_attr),
4199 COMMUNITY_GSHUT)) {
4200 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4201 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4202
4203 /* If graceful-shutdown is configured globally or
4204 * per neighbor, then add the GSHUT community to
4205 * all paths received from eBGP peers. */
4206 } else if (bgp_in_graceful_shutdown(peer->bgp) ||
4207 CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_SHUTDOWN))
4208 bgp_attr_add_gshut_community(&new_attr);
4209 }
4210
4211 /* next hop check. */
4212 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4213 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4214 &new_attr, dest)) {
4215 peer->stat_pfx_nh_invalid++;
4216 reason = "martian or self next-hop;";
4217 bgp_attr_flush(&new_attr);
4218 goto filtered;
4219 }
4220
4221 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4222 peer->stat_pfx_nh_invalid++;
4223 reason = "self mac;";
4224 bgp_attr_flush(&new_attr);
4225 goto filtered;
4226 }
4227
4228 if (bgp_check_role_applicability(afi, safi) &&
4229 bgp_otc_filter(peer, &new_attr)) {
4230 reason = "failing otc validation";
4231 bgp_attr_flush(&new_attr);
4232 goto filtered;
4233 }
4234 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
4235 * condition :
4236 * Suppress fib is enabled
4237 * BGP_OPT_NO_FIB is not enabled
4238 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
4239 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
4240 */
4241 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
4242 && (sub_type == BGP_ROUTE_NORMAL)
4243 && (!bgp_option_check(BGP_OPT_NO_FIB))
4244 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
4245 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
4246
4247 /* If neighbor soo is configured, tag all incoming routes with
4248 * this SoO tag and then filter out advertisements in
4249 * subgroup_announce_check() if it matches the configured SoO
4250 * on the other peer.
4251 */
4252 if (peer->soo[afi][safi]) {
4253 struct ecommunity *old_ecomm =
4254 bgp_attr_get_ecommunity(&new_attr);
4255 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4256 struct ecommunity *new_ecomm;
4257
4258 if (old_ecomm) {
4259 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4260 ecomm_soo);
4261
4262 if (!old_ecomm->refcnt)
4263 ecommunity_free(&old_ecomm);
4264 } else {
4265 new_ecomm = ecommunity_dup(ecomm_soo);
4266 }
4267
4268 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4269 }
4270
4271 attr_new = bgp_attr_intern(&new_attr);
4272
4273 /* If the update is implicit withdraw. */
4274 if (pi) {
4275 pi->uptime = monotime(NULL);
4276 same_attr = attrhash_cmp(pi->attr, attr_new);
4277
4278 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4279
4280 /* Same attribute comes in. */
4281 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4282 && same_attr
4283 && (!has_valid_label
4284 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4285 num_labels * sizeof(mpls_label_t))
4286 == 0)) {
4287 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4288 BGP_CONFIG_DAMPENING)
4289 && peer->sort == BGP_PEER_EBGP
4290 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4291 if (bgp_debug_update(peer, p, NULL, 1)) {
4292 bgp_debug_rdpfxpath2str(
4293 afi, safi, prd, p, label,
4294 num_labels, addpath_id ? 1 : 0,
4295 addpath_id, evpn, pfx_buf,
4296 sizeof(pfx_buf));
4297 zlog_debug("%pBP rcvd %s", peer,
4298 pfx_buf);
4299 }
4300
4301 if (bgp_damp_update(pi, dest, afi, safi)
4302 != BGP_DAMP_SUPPRESSED) {
4303 bgp_aggregate_increment(bgp, p, pi, afi,
4304 safi);
4305 bgp_process(bgp, dest, afi, safi);
4306 }
4307 } else /* Duplicate - odd */
4308 {
4309 if (bgp_debug_update(peer, p, NULL, 1)) {
4310 if (!peer->rcvd_attr_printed) {
4311 zlog_debug(
4312 "%pBP rcvd UPDATE w/ attr: %s",
4313 peer,
4314 peer->rcvd_attr_str);
4315 peer->rcvd_attr_printed = 1;
4316 }
4317
4318 bgp_debug_rdpfxpath2str(
4319 afi, safi, prd, p, label,
4320 num_labels, addpath_id ? 1 : 0,
4321 addpath_id, evpn, pfx_buf,
4322 sizeof(pfx_buf));
4323 zlog_debug(
4324 "%pBP rcvd %s...duplicate ignored",
4325 peer, pfx_buf);
4326 }
4327
4328 /* graceful restart STALE flag unset. */
4329 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4330 bgp_path_info_unset_flag(
4331 dest, pi, BGP_PATH_STALE);
4332 bgp_dest_set_defer_flag(dest, false);
4333 bgp_process(bgp, dest, afi, safi);
4334 }
4335 }
4336
4337 bgp_dest_unlock_node(dest);
4338 bgp_attr_unintern(&attr_new);
4339
4340 return 0;
4341 }
4342
4343 /* Withdraw/Announce before we fully processed the withdraw */
4344 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4345 if (bgp_debug_update(peer, p, NULL, 1)) {
4346 bgp_debug_rdpfxpath2str(
4347 afi, safi, prd, p, label, num_labels,
4348 addpath_id ? 1 : 0, addpath_id, evpn,
4349 pfx_buf, sizeof(pfx_buf));
4350 zlog_debug(
4351 "%pBP rcvd %s, flapped quicker than processing",
4352 peer, pfx_buf);
4353 }
4354
4355 bgp_path_info_restore(dest, pi);
4356
4357 /*
4358 * If the BGP_PATH_REMOVED flag is set, then EVPN
4359 * routes would have been unimported already when a
4360 * prior BGP withdraw processing happened. Such routes
4361 * need to be imported again, so flag accordingly.
4362 */
4363 force_evpn_import = true;
4364 } else {
4365 /* implicit withdraw, decrement aggregate and pcount
4366 * here. only if update is accepted, they'll increment
4367 * below.
4368 */
4369 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4370 }
4371
4372 /* Received Logging. */
4373 if (bgp_debug_update(peer, p, NULL, 1)) {
4374 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4375 num_labels, addpath_id ? 1 : 0,
4376 addpath_id, evpn, pfx_buf,
4377 sizeof(pfx_buf));
4378 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4379 }
4380
4381 /* graceful restart STALE flag unset. */
4382 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4383 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4384 bgp_dest_set_defer_flag(dest, false);
4385 }
4386
4387 /* The attribute is changed. */
4388 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4389
4390 /* Update bgp route dampening information. */
4391 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4392 && peer->sort == BGP_PEER_EBGP) {
4393 /* This is implicit withdraw so we should update
4394 dampening
4395 information. */
4396 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4397 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4398 }
4399 #ifdef ENABLE_BGP_VNC
4400 if (safi == SAFI_MPLS_VPN) {
4401 struct bgp_dest *pdest = NULL;
4402 struct bgp_table *table = NULL;
4403
4404 pdest = bgp_node_get(bgp->rib[afi][safi],
4405 (struct prefix *)prd);
4406 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4407 table = bgp_dest_get_bgp_table_info(pdest);
4408
4409 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4410 bgp, prd, table, p, pi);
4411 }
4412 bgp_dest_unlock_node(pdest);
4413 }
4414 if ((afi == AFI_IP || afi == AFI_IP6)
4415 && (safi == SAFI_UNICAST)) {
4416 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4417 /*
4418 * Implicit withdraw case.
4419 */
4420 ++vnc_implicit_withdraw;
4421 vnc_import_bgp_del_route(bgp, p, pi);
4422 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4423 }
4424 }
4425 #endif
4426
4427 /* Special handling for EVPN update of an existing route. If the
4428 * extended community attribute has changed, we need to
4429 * un-import
4430 * the route using its existing extended community. It will be
4431 * subsequently processed for import with the new extended
4432 * community.
4433 */
4434 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4435 && !same_attr) {
4436 if ((pi->attr->flag
4437 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4438 && (attr_new->flag
4439 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4440 int cmp;
4441
4442 cmp = ecommunity_cmp(
4443 bgp_attr_get_ecommunity(pi->attr),
4444 bgp_attr_get_ecommunity(attr_new));
4445 if (!cmp) {
4446 if (bgp_debug_update(peer, p, NULL, 1))
4447 zlog_debug(
4448 "Change in EXT-COMM, existing %s new %s",
4449 ecommunity_str(
4450 bgp_attr_get_ecommunity(
4451 pi->attr)),
4452 ecommunity_str(
4453 bgp_attr_get_ecommunity(
4454 attr_new)));
4455 if (safi == SAFI_EVPN)
4456 bgp_evpn_unimport_route(
4457 bgp, afi, safi, p, pi);
4458 else /* SAFI_MPLS_VPN */
4459 vpn_leak_to_vrf_withdraw(bgp,
4460 pi);
4461 }
4462 }
4463 }
4464
4465 /* Update to new attribute. */
4466 bgp_attr_unintern(&pi->attr);
4467 pi->attr = attr_new;
4468
4469 /* Update MPLS label */
4470 if (has_valid_label) {
4471 extra = bgp_path_info_extra_get(pi);
4472 if (extra->label != label) {
4473 memcpy(&extra->label, label,
4474 num_labels * sizeof(mpls_label_t));
4475 extra->num_labels = num_labels;
4476 }
4477 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4478 bgp_set_valid_label(&extra->label[0]);
4479 }
4480
4481 /* Update SRv6 SID */
4482 if (attr->srv6_l3vpn) {
4483 extra = bgp_path_info_extra_get(pi);
4484 if (sid_diff(&extra->sid[0].sid,
4485 &attr->srv6_l3vpn->sid)) {
4486 sid_copy(&extra->sid[0].sid,
4487 &attr->srv6_l3vpn->sid);
4488 extra->num_sids = 1;
4489
4490 extra->sid[0].loc_block_len = 0;
4491 extra->sid[0].loc_node_len = 0;
4492 extra->sid[0].func_len = 0;
4493 extra->sid[0].arg_len = 0;
4494 extra->sid[0].transposition_len = 0;
4495 extra->sid[0].transposition_offset = 0;
4496
4497 if (attr->srv6_l3vpn->loc_block_len != 0) {
4498 extra->sid[0].loc_block_len =
4499 attr->srv6_l3vpn->loc_block_len;
4500 extra->sid[0].loc_node_len =
4501 attr->srv6_l3vpn->loc_node_len;
4502 extra->sid[0].func_len =
4503 attr->srv6_l3vpn->func_len;
4504 extra->sid[0].arg_len =
4505 attr->srv6_l3vpn->arg_len;
4506 extra->sid[0].transposition_len =
4507 attr->srv6_l3vpn
4508 ->transposition_len;
4509 extra->sid[0].transposition_offset =
4510 attr->srv6_l3vpn
4511 ->transposition_offset;
4512 }
4513 }
4514 } else if (attr->srv6_vpn) {
4515 extra = bgp_path_info_extra_get(pi);
4516 if (sid_diff(&extra->sid[0].sid,
4517 &attr->srv6_vpn->sid)) {
4518 sid_copy(&extra->sid[0].sid,
4519 &attr->srv6_vpn->sid);
4520 extra->num_sids = 1;
4521 }
4522 }
4523
4524 #ifdef ENABLE_BGP_VNC
4525 if ((afi == AFI_IP || afi == AFI_IP6)
4526 && (safi == SAFI_UNICAST)) {
4527 if (vnc_implicit_withdraw) {
4528 /*
4529 * Add back the route with its new attributes
4530 * (e.g., nexthop).
4531 * The route is still selected, until the route
4532 * selection
4533 * queued by bgp_process actually runs. We have
4534 * to make this
4535 * update to the VNC side immediately to avoid
4536 * racing against
4537 * configuration changes (e.g., route-map
4538 * changes) which
4539 * trigger re-importation of the entire RIB.
4540 */
4541 vnc_import_bgp_add_route(bgp, p, pi);
4542 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4543 }
4544 }
4545 #endif
4546
4547 /* Update bgp route dampening information. */
4548 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4549 && peer->sort == BGP_PEER_EBGP) {
4550 /* Now we do normal update dampening. */
4551 ret = bgp_damp_update(pi, dest, afi, safi);
4552 if (ret == BGP_DAMP_SUPPRESSED) {
4553 bgp_dest_unlock_node(dest);
4554 return 0;
4555 }
4556 }
4557
4558 /* Nexthop reachability check - for unicast and
4559 * labeled-unicast.. */
4560 if (((afi == AFI_IP || afi == AFI_IP6)
4561 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4562 || (safi == SAFI_EVPN &&
4563 bgp_evpn_is_prefix_nht_supported(p))) {
4564 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4565 && peer->ttl == BGP_DEFAULT_TTL
4566 && !CHECK_FLAG(peer->flags,
4567 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4568 && !CHECK_FLAG(bgp->flags,
4569 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4570 connected = 1;
4571 else
4572 connected = 0;
4573
4574 struct bgp *bgp_nexthop = bgp;
4575
4576 if (pi->extra && pi->extra->bgp_orig)
4577 bgp_nexthop = pi->extra->bgp_orig;
4578
4579 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4580
4581 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4582 safi, pi, NULL, connected,
4583 bgp_nht_param_prefix) ||
4584 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4585 bgp_path_info_set_flag(dest, pi,
4586 BGP_PATH_VALID);
4587 else {
4588 if (BGP_DEBUG(nht, NHT)) {
4589 zlog_debug("%s(%pI4): NH unresolved",
4590 __func__,
4591 (in_addr_t *)&attr_new->nexthop);
4592 }
4593 bgp_path_info_unset_flag(dest, pi,
4594 BGP_PATH_VALID);
4595 }
4596 } else {
4597 if (accept_own)
4598 bgp_path_info_set_flag(dest, pi,
4599 BGP_PATH_ACCEPT_OWN);
4600
4601 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4602 }
4603
4604 #ifdef ENABLE_BGP_VNC
4605 if (safi == SAFI_MPLS_VPN) {
4606 struct bgp_dest *pdest = NULL;
4607 struct bgp_table *table = NULL;
4608
4609 pdest = bgp_node_get(bgp->rib[afi][safi],
4610 (struct prefix *)prd);
4611 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4612 table = bgp_dest_get_bgp_table_info(pdest);
4613
4614 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4615 bgp, prd, table, p, pi);
4616 }
4617 bgp_dest_unlock_node(pdest);
4618 }
4619 #endif
4620
4621 /* If this is an EVPN route and some attribute has changed,
4622 * or we are explicitly told to perform a route import, process
4623 * route for import. If the extended community has changed, we
4624 * would
4625 * have done the un-import earlier and the import would result
4626 * in the
4627 * route getting injected into appropriate L2 VNIs. If it is
4628 * just
4629 * some other attribute change, the import will result in
4630 * updating
4631 * the attributes for the route in the VNI(s).
4632 */
4633 if (safi == SAFI_EVPN &&
4634 (!same_attr || force_evpn_import) &&
4635 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4636 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4637
4638 /* Process change. */
4639 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4640
4641 bgp_process(bgp, dest, afi, safi);
4642 bgp_dest_unlock_node(dest);
4643
4644 if (SAFI_UNICAST == safi
4645 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4646 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4647
4648 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4649 }
4650 if ((SAFI_MPLS_VPN == safi)
4651 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4652 leak_success = vpn_leak_to_vrf_update(bgp, pi, prd);
4653 }
4654
4655 #ifdef ENABLE_BGP_VNC
4656 if (SAFI_MPLS_VPN == safi) {
4657 mpls_label_t label_decoded = decode_label(label);
4658
4659 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4660 type, sub_type, &label_decoded);
4661 }
4662 if (SAFI_ENCAP == safi) {
4663 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4664 type, sub_type, NULL);
4665 }
4666 #endif
4667 if ((safi == SAFI_MPLS_VPN) &&
4668 !CHECK_FLAG(bgp->af_flags[afi][safi],
4669 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4670 !leak_success) {
4671 bgp_unlink_nexthop(pi);
4672 bgp_path_info_delete(dest, pi);
4673 }
4674 return 0;
4675 } // End of implicit withdraw
4676
4677 /* Received Logging. */
4678 if (bgp_debug_update(peer, p, NULL, 1)) {
4679 if (!peer->rcvd_attr_printed) {
4680 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4681 peer->rcvd_attr_str);
4682 peer->rcvd_attr_printed = 1;
4683 }
4684
4685 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4686 addpath_id ? 1 : 0, addpath_id, evpn,
4687 pfx_buf, sizeof(pfx_buf));
4688 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4689 }
4690
4691 /* Make new BGP info. */
4692 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4693
4694 /* Update MPLS label */
4695 if (has_valid_label) {
4696 extra = bgp_path_info_extra_get(new);
4697 if (extra->label != label) {
4698 memcpy(&extra->label, label,
4699 num_labels * sizeof(mpls_label_t));
4700 extra->num_labels = num_labels;
4701 }
4702 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4703 bgp_set_valid_label(&extra->label[0]);
4704 }
4705
4706 /* Update SRv6 SID */
4707 if (safi == SAFI_MPLS_VPN) {
4708 extra = bgp_path_info_extra_get(new);
4709 if (attr->srv6_l3vpn) {
4710 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4711 extra->num_sids = 1;
4712
4713 extra->sid[0].loc_block_len =
4714 attr->srv6_l3vpn->loc_block_len;
4715 extra->sid[0].loc_node_len =
4716 attr->srv6_l3vpn->loc_node_len;
4717 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4718 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4719 extra->sid[0].transposition_len =
4720 attr->srv6_l3vpn->transposition_len;
4721 extra->sid[0].transposition_offset =
4722 attr->srv6_l3vpn->transposition_offset;
4723 } else if (attr->srv6_vpn) {
4724 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4725 extra->num_sids = 1;
4726 }
4727 }
4728
4729 /* Nexthop reachability check. */
4730 if (((afi == AFI_IP || afi == AFI_IP6)
4731 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4732 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4733 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4734 && peer->ttl == BGP_DEFAULT_TTL
4735 && !CHECK_FLAG(peer->flags,
4736 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4737 && !CHECK_FLAG(bgp->flags,
4738 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4739 connected = 1;
4740 else
4741 connected = 0;
4742
4743 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4744
4745 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4746 connected, bgp_nht_param_prefix) ||
4747 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4748 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4749 else {
4750 if (BGP_DEBUG(nht, NHT))
4751 zlog_debug("%s(%pI4): NH unresolved", __func__,
4752 &attr_new->nexthop);
4753 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4754 }
4755 } else {
4756 if (accept_own)
4757 bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
4758
4759 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4760 }
4761
4762 /* If maximum prefix count is configured and current prefix
4763 * count exeed it.
4764 */
4765 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4766 reason = "maximum-prefix overflow";
4767 bgp_attr_flush(&new_attr);
4768 goto filtered;
4769 }
4770
4771 /* Addpath ID */
4772 new->addpath_rx_id = addpath_id;
4773
4774 /* Increment prefix */
4775 bgp_aggregate_increment(bgp, p, new, afi, safi);
4776
4777 /* Register new BGP information. */
4778 bgp_path_info_add(dest, new);
4779
4780 /* route_node_get lock */
4781 bgp_dest_unlock_node(dest);
4782
4783 #ifdef ENABLE_BGP_VNC
4784 if (safi == SAFI_MPLS_VPN) {
4785 struct bgp_dest *pdest = NULL;
4786 struct bgp_table *table = NULL;
4787
4788 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4789 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4790 table = bgp_dest_get_bgp_table_info(pdest);
4791
4792 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4793 bgp, prd, table, p, new);
4794 }
4795 bgp_dest_unlock_node(pdest);
4796 }
4797 #endif
4798
4799 /* If this is an EVPN route, process for import. */
4800 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4801 bgp_evpn_import_route(bgp, afi, safi, p, new);
4802
4803 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4804
4805 /* Process change. */
4806 bgp_process(bgp, dest, afi, safi);
4807
4808 if (SAFI_UNICAST == safi
4809 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4810 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4811 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4812 }
4813 if ((SAFI_MPLS_VPN == safi)
4814 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4815 leak_success = vpn_leak_to_vrf_update(bgp, new, prd);
4816 }
4817 #ifdef ENABLE_BGP_VNC
4818 if (SAFI_MPLS_VPN == safi) {
4819 mpls_label_t label_decoded = decode_label(label);
4820
4821 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4822 sub_type, &label_decoded);
4823 }
4824 if (SAFI_ENCAP == safi) {
4825 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4826 sub_type, NULL);
4827 }
4828 #endif
4829 if ((safi == SAFI_MPLS_VPN) &&
4830 !CHECK_FLAG(bgp->af_flags[afi][safi],
4831 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4832 !leak_success) {
4833 bgp_unlink_nexthop(new);
4834 bgp_path_info_delete(dest, new);
4835 }
4836
4837 return 0;
4838
4839 /* This BGP update is filtered. Log the reason then update BGP
4840 entry. */
4841 filtered:
4842 if (new) {
4843 bgp_unlink_nexthop(new);
4844 bgp_path_info_delete(dest, new);
4845 bgp_path_info_extra_free(&new->extra);
4846 XFREE(MTYPE_BGP_ROUTE, new);
4847 }
4848
4849 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4850
4851 if (bgp_debug_update(peer, p, NULL, 1)) {
4852 if (!peer->rcvd_attr_printed) {
4853 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4854 peer->rcvd_attr_str);
4855 peer->rcvd_attr_printed = 1;
4856 }
4857
4858 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4859 addpath_id ? 1 : 0, addpath_id, evpn,
4860 pfx_buf, sizeof(pfx_buf));
4861 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4862 peer, pfx_buf, reason);
4863 }
4864
4865 if (pi) {
4866 /* If this is an EVPN route, un-import it as it is now filtered.
4867 */
4868 if (safi == SAFI_EVPN)
4869 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4870
4871 if (SAFI_UNICAST == safi
4872 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4873 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4874
4875 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4876 }
4877 if ((SAFI_MPLS_VPN == safi)
4878 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4879
4880 vpn_leak_to_vrf_withdraw(bgp, pi);
4881 }
4882
4883 bgp_rib_remove(dest, pi, peer, afi, safi);
4884 }
4885
4886 bgp_dest_unlock_node(dest);
4887
4888 #ifdef ENABLE_BGP_VNC
4889 /*
4890 * Filtered update is treated as an implicit withdrawal (see
4891 * bgp_rib_remove()
4892 * a few lines above)
4893 */
4894 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4895 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4896 0);
4897 }
4898 #endif
4899
4900 return 0;
4901 }
4902
4903 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4904 struct attr *attr, afi_t afi, safi_t safi, int type,
4905 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4906 uint32_t num_labels, struct bgp_route_evpn *evpn)
4907 {
4908 struct bgp *bgp;
4909 char pfx_buf[BGP_PRD_PATH_STRLEN];
4910 struct bgp_dest *dest;
4911 struct bgp_path_info *pi;
4912
4913 #ifdef ENABLE_BGP_VNC
4914 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4915 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4916 0);
4917 }
4918 #endif
4919
4920 bgp = peer->bgp;
4921
4922 /* Lookup node. */
4923 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4924
4925 /* If peer is soft reconfiguration enabled. Record input packet for
4926 * further calculation.
4927 *
4928 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4929 * routes that are filtered. This tanks out Quagga RS pretty badly due
4930 * to
4931 * the iteration over all RS clients.
4932 * Since we need to remove the entry from adj_in anyway, do that first
4933 * and
4934 * if there was no entry, we don't need to do anything more.
4935 */
4936 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4937 && peer != bgp->peer_self)
4938 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4939 peer->stat_pfx_dup_withdraw++;
4940
4941 if (bgp_debug_update(peer, p, NULL, 1)) {
4942 bgp_debug_rdpfxpath2str(
4943 afi, safi, prd, p, label, num_labels,
4944 addpath_id ? 1 : 0, addpath_id, NULL,
4945 pfx_buf, sizeof(pfx_buf));
4946 zlog_debug(
4947 "%s withdrawing route %s not in adj-in",
4948 peer->host, pfx_buf);
4949 }
4950 bgp_dest_unlock_node(dest);
4951 return 0;
4952 }
4953
4954 /* Lookup withdrawn route. */
4955 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4956 if (pi->peer == peer && pi->type == type
4957 && pi->sub_type == sub_type
4958 && pi->addpath_rx_id == addpath_id)
4959 break;
4960
4961 /* Logging. */
4962 if (bgp_debug_update(peer, p, NULL, 1)) {
4963 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4964 addpath_id ? 1 : 0, addpath_id, NULL,
4965 pfx_buf, sizeof(pfx_buf));
4966 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
4967 pfx_buf);
4968 }
4969
4970 /* Withdraw specified route from routing table. */
4971 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4972 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4973 if (SAFI_UNICAST == safi
4974 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4975 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4976 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4977 }
4978 if ((SAFI_MPLS_VPN == safi)
4979 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4980
4981 vpn_leak_to_vrf_withdraw(bgp, pi);
4982 }
4983 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4984 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4985 addpath_id ? 1 : 0, addpath_id, NULL,
4986 pfx_buf, sizeof(pfx_buf));
4987 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4988 }
4989
4990 /* Unlock bgp_node_get() lock. */
4991 bgp_dest_unlock_node(dest);
4992
4993 return 0;
4994 }
4995
4996 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4997 int withdraw)
4998 {
4999 struct update_subgroup *subgrp;
5000 subgrp = peer_subgroup(peer, afi, safi);
5001 subgroup_default_originate(subgrp, withdraw);
5002 }
5003
5004
5005 /*
5006 * bgp_stop_announce_route_timer
5007 */
5008 void bgp_stop_announce_route_timer(struct peer_af *paf)
5009 {
5010 if (!paf->t_announce_route)
5011 return;
5012
5013 THREAD_OFF(paf->t_announce_route);
5014 }
5015
5016 /*
5017 * bgp_announce_route_timer_expired
5018 *
5019 * Callback that is invoked when the route announcement timer for a
5020 * peer_af expires.
5021 */
5022 static void bgp_announce_route_timer_expired(struct thread *t)
5023 {
5024 struct peer_af *paf;
5025 struct peer *peer;
5026
5027 paf = THREAD_ARG(t);
5028 peer = paf->peer;
5029
5030 if (!peer_established(peer))
5031 return;
5032
5033 if (!peer->afc_nego[paf->afi][paf->safi])
5034 return;
5035
5036 peer_af_announce_route(paf, 1);
5037
5038 /* Notify BGP conditional advertisement scanner percess */
5039 peer->advmap_config_change[paf->afi][paf->safi] = true;
5040 }
5041
5042 /*
5043 * bgp_announce_route
5044 *
5045 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
5046 *
5047 * if force is true we will force an update even if the update
5048 * limiting code is attempted to kick in.
5049 */
5050 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
5051 {
5052 struct peer_af *paf;
5053 struct update_subgroup *subgrp;
5054
5055 paf = peer_af_find(peer, afi, safi);
5056 if (!paf)
5057 return;
5058 subgrp = PAF_SUBGRP(paf);
5059
5060 /*
5061 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
5062 * or a refresh has already been triggered.
5063 */
5064 if (!subgrp || paf->t_announce_route)
5065 return;
5066
5067 if (force)
5068 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
5069
5070 /*
5071 * Start a timer to stagger/delay the announce. This serves
5072 * two purposes - announcement can potentially be combined for
5073 * multiple peers and the announcement doesn't happen in the
5074 * vty context.
5075 */
5076 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
5077 (subgrp->peer_count == 1)
5078 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
5079 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
5080 &paf->t_announce_route);
5081 }
5082
5083 /*
5084 * Announce routes from all AF tables to a peer.
5085 *
5086 * This should ONLY be called when there is a need to refresh the
5087 * routes to the peer based on a policy change for this peer alone
5088 * or a route refresh request received from the peer.
5089 * The operation will result in splitting the peer from its existing
5090 * subgroups and putting it in new subgroups.
5091 */
5092 void bgp_announce_route_all(struct peer *peer)
5093 {
5094 afi_t afi;
5095 safi_t safi;
5096
5097 FOREACH_AFI_SAFI (afi, safi)
5098 bgp_announce_route(peer, afi, safi, false);
5099 }
5100
5101 /* Flag or unflag bgp_dest to determine whether it should be treated by
5102 * bgp_soft_reconfig_table_task.
5103 * Flag if flag is true. Unflag if flag is false.
5104 */
5105 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
5106 {
5107 struct bgp_dest *dest;
5108 struct bgp_adj_in *ain;
5109
5110 if (!table)
5111 return;
5112
5113 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5114 for (ain = dest->adj_in; ain; ain = ain->next) {
5115 if (ain->peer != NULL)
5116 break;
5117 }
5118 if (flag && ain != NULL && ain->peer != NULL)
5119 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5120 else
5121 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5122 }
5123 }
5124
5125 static int bgp_soft_reconfig_table_update(struct peer *peer,
5126 struct bgp_dest *dest,
5127 struct bgp_adj_in *ain, afi_t afi,
5128 safi_t safi, struct prefix_rd *prd)
5129 {
5130 struct bgp_path_info *pi;
5131 uint32_t num_labels = 0;
5132 mpls_label_t *label_pnt = NULL;
5133 struct bgp_route_evpn evpn;
5134
5135 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5136 if (pi->peer == peer)
5137 break;
5138
5139 if (pi && pi->extra)
5140 num_labels = pi->extra->num_labels;
5141 if (num_labels)
5142 label_pnt = &pi->extra->label[0];
5143 if (pi)
5144 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
5145 sizeof(evpn));
5146 else
5147 memset(&evpn, 0, sizeof(evpn));
5148
5149 return bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
5150 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
5151 BGP_ROUTE_NORMAL, prd, label_pnt, num_labels, 1,
5152 &evpn);
5153 }
5154
5155 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5156 struct bgp_table *table,
5157 struct prefix_rd *prd)
5158 {
5159 int ret;
5160 struct bgp_dest *dest;
5161 struct bgp_adj_in *ain;
5162
5163 if (!table)
5164 table = peer->bgp->rib[afi][safi];
5165
5166 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5167 for (ain = dest->adj_in; ain; ain = ain->next) {
5168 if (ain->peer != peer)
5169 continue;
5170
5171 ret = bgp_soft_reconfig_table_update(peer, dest, ain,
5172 afi, safi, prd);
5173
5174 if (ret < 0) {
5175 bgp_dest_unlock_node(dest);
5176 return;
5177 }
5178 }
5179 }
5180
5181 /* Do soft reconfig table per bgp table.
5182 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5183 * when BGP_NODE_SOFT_RECONFIG is set,
5184 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5185 * Schedule a new thread to continue the job.
5186 * Without splitting the full job into several part,
5187 * vtysh waits for the job to finish before responding to a BGP command
5188 */
5189 static void bgp_soft_reconfig_table_task(struct thread *thread)
5190 {
5191 uint32_t iter, max_iter;
5192 int ret;
5193 struct bgp_dest *dest;
5194 struct bgp_adj_in *ain;
5195 struct peer *peer;
5196 struct bgp_table *table;
5197 struct prefix_rd *prd;
5198 struct listnode *node, *nnode;
5199
5200 table = THREAD_ARG(thread);
5201 prd = NULL;
5202
5203 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5204 if (table->soft_reconfig_init) {
5205 /* first call of the function with a new srta structure.
5206 * Don't do any treatment this time on nodes
5207 * in order vtysh to respond quickly
5208 */
5209 max_iter = 0;
5210 }
5211
5212 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5213 dest = bgp_route_next(dest)) {
5214 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5215 continue;
5216
5217 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5218
5219 for (ain = dest->adj_in; ain; ain = ain->next) {
5220 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5221 nnode, peer)) {
5222 if (ain->peer != peer)
5223 continue;
5224
5225 ret = bgp_soft_reconfig_table_update(
5226 peer, dest, ain, table->afi,
5227 table->safi, prd);
5228 iter++;
5229
5230 if (ret < 0) {
5231 bgp_dest_unlock_node(dest);
5232 listnode_delete(
5233 table->soft_reconfig_peers,
5234 peer);
5235 bgp_announce_route(peer, table->afi,
5236 table->safi, false);
5237 if (list_isempty(
5238 table->soft_reconfig_peers)) {
5239 list_delete(
5240 &table->soft_reconfig_peers);
5241 bgp_soft_reconfig_table_flag(
5242 table, false);
5243 return;
5244 }
5245 }
5246 }
5247 }
5248 }
5249
5250 /* we're either starting the initial iteration,
5251 * or we're going to continue an ongoing iteration
5252 */
5253 if (dest || table->soft_reconfig_init) {
5254 table->soft_reconfig_init = false;
5255 thread_add_event(bm->master, bgp_soft_reconfig_table_task,
5256 table, 0, &table->soft_reconfig_thread);
5257 return;
5258 }
5259 /* we're done, clean up the background iteration context info and
5260 schedule route annoucement
5261 */
5262 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5263 listnode_delete(table->soft_reconfig_peers, peer);
5264 bgp_announce_route(peer, table->afi, table->safi, false);
5265 }
5266
5267 list_delete(&table->soft_reconfig_peers);
5268 }
5269
5270
5271 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5272 * and peer.
5273 * - bgp cannot be NULL
5274 * - if table and peer are NULL, cancel all threads within the bgp instance
5275 * - if table is NULL and peer is not,
5276 * remove peer in all threads within the bgp instance
5277 * - if peer is NULL, cancel all threads matching table within the bgp instance
5278 */
5279 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5280 const struct bgp_table *table,
5281 const struct peer *peer)
5282 {
5283 struct peer *npeer;
5284 struct listnode *node, *nnode;
5285 int afi, safi;
5286 struct bgp_table *ntable;
5287
5288 if (!bgp)
5289 return;
5290
5291 FOREACH_AFI_SAFI (afi, safi) {
5292 ntable = bgp->rib[afi][safi];
5293 if (!ntable)
5294 continue;
5295 if (table && table != ntable)
5296 continue;
5297
5298 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5299 npeer)) {
5300 if (peer && peer != npeer)
5301 continue;
5302 listnode_delete(ntable->soft_reconfig_peers, npeer);
5303 }
5304
5305 if (!ntable->soft_reconfig_peers
5306 || !list_isempty(ntable->soft_reconfig_peers))
5307 continue;
5308
5309 list_delete(&ntable->soft_reconfig_peers);
5310 bgp_soft_reconfig_table_flag(ntable, false);
5311 THREAD_OFF(ntable->soft_reconfig_thread);
5312 }
5313 }
5314
5315 /*
5316 * Returns false if the peer is not configured for soft reconfig in
5317 */
5318 bool bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5319 {
5320 struct bgp_dest *dest;
5321 struct bgp_table *table;
5322 struct listnode *node, *nnode;
5323 struct peer *npeer;
5324 struct peer_af *paf;
5325
5326 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5327 return false;
5328
5329 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5330 && (safi != SAFI_EVPN)) {
5331 table = peer->bgp->rib[afi][safi];
5332 if (!table)
5333 return true;
5334
5335 table->soft_reconfig_init = true;
5336
5337 if (!table->soft_reconfig_peers)
5338 table->soft_reconfig_peers = list_new();
5339 npeer = NULL;
5340 /* add peer to the table soft_reconfig_peers if not already
5341 * there
5342 */
5343 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5344 npeer)) {
5345 if (peer == npeer)
5346 break;
5347 }
5348 if (peer != npeer)
5349 listnode_add(table->soft_reconfig_peers, peer);
5350
5351 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5352 * on table would start back at the beginning.
5353 */
5354 bgp_soft_reconfig_table_flag(table, true);
5355
5356 if (!table->soft_reconfig_thread)
5357 thread_add_event(bm->master,
5358 bgp_soft_reconfig_table_task, table, 0,
5359 &table->soft_reconfig_thread);
5360 /* Cancel bgp_announce_route_timer_expired threads.
5361 * bgp_announce_route_timer_expired threads have been scheduled
5362 * to announce routes as soon as the soft_reconfigure process
5363 * finishes.
5364 * In this case, soft_reconfigure is also scheduled by using
5365 * a thread but is planned after the
5366 * bgp_announce_route_timer_expired threads. It means that,
5367 * without cancelling the threads, the route announcement task
5368 * would run before the soft reconfiguration one. That would
5369 * useless and would block vtysh during several seconds. Route
5370 * announcements are rescheduled as soon as the soft_reconfigure
5371 * process finishes.
5372 */
5373 paf = peer_af_find(peer, afi, safi);
5374 if (paf)
5375 bgp_stop_announce_route_timer(paf);
5376 } else
5377 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5378 dest = bgp_route_next(dest)) {
5379 table = bgp_dest_get_bgp_table_info(dest);
5380
5381 if (table == NULL)
5382 continue;
5383
5384 const struct prefix *p = bgp_dest_get_prefix(dest);
5385 struct prefix_rd prd;
5386
5387 prd.family = AF_UNSPEC;
5388 prd.prefixlen = 64;
5389 memcpy(&prd.val, p->u.val, 8);
5390
5391 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5392 }
5393
5394 return true;
5395 }
5396
5397
5398 struct bgp_clear_node_queue {
5399 struct bgp_dest *dest;
5400 };
5401
5402 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5403 {
5404 struct bgp_clear_node_queue *cnq = data;
5405 struct bgp_dest *dest = cnq->dest;
5406 struct peer *peer = wq->spec.data;
5407 struct bgp_path_info *pi;
5408 struct bgp *bgp;
5409 afi_t afi = bgp_dest_table(dest)->afi;
5410 safi_t safi = bgp_dest_table(dest)->safi;
5411
5412 assert(dest && peer);
5413 bgp = peer->bgp;
5414
5415 /* It is possible that we have multiple paths for a prefix from a peer
5416 * if that peer is using AddPath.
5417 */
5418 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5419 if (pi->peer != peer)
5420 continue;
5421
5422 /* graceful restart STALE flag set. */
5423 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5424 && peer->nsf[afi][safi])
5425 || CHECK_FLAG(peer->af_sflags[afi][safi],
5426 PEER_STATUS_ENHANCED_REFRESH))
5427 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5428 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5429 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5430 else {
5431 /* If this is an EVPN route, process for
5432 * un-import. */
5433 if (safi == SAFI_EVPN)
5434 bgp_evpn_unimport_route(
5435 bgp, afi, safi,
5436 bgp_dest_get_prefix(dest), pi);
5437 /* Handle withdraw for VRF route-leaking and L3VPN */
5438 if (SAFI_UNICAST == safi
5439 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5440 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5441 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5442 bgp, pi);
5443 }
5444 if (SAFI_MPLS_VPN == safi &&
5445 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5446 vpn_leak_to_vrf_withdraw(bgp, pi);
5447 }
5448
5449 bgp_rib_remove(dest, pi, peer, afi, safi);
5450 }
5451 }
5452 return WQ_SUCCESS;
5453 }
5454
5455 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5456 {
5457 struct bgp_clear_node_queue *cnq = data;
5458 struct bgp_dest *dest = cnq->dest;
5459 struct bgp_table *table = bgp_dest_table(dest);
5460
5461 bgp_dest_unlock_node(dest);
5462 bgp_table_unlock(table);
5463 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5464 }
5465
5466 static void bgp_clear_node_complete(struct work_queue *wq)
5467 {
5468 struct peer *peer = wq->spec.data;
5469
5470 /* Tickle FSM to start moving again */
5471 BGP_EVENT_ADD(peer, Clearing_Completed);
5472
5473 peer_unlock(peer); /* bgp_clear_route */
5474 }
5475
5476 static void bgp_clear_node_queue_init(struct peer *peer)
5477 {
5478 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5479
5480 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5481 #undef CLEAR_QUEUE_NAME_LEN
5482
5483 peer->clear_node_queue = work_queue_new(bm->master, wname);
5484 peer->clear_node_queue->spec.hold = 10;
5485 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5486 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5487 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5488 peer->clear_node_queue->spec.max_retries = 0;
5489
5490 /* we only 'lock' this peer reference when the queue is actually active
5491 */
5492 peer->clear_node_queue->spec.data = peer;
5493 }
5494
5495 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5496 struct bgp_table *table)
5497 {
5498 struct bgp_dest *dest;
5499 int force = peer->bgp->process_queue ? 0 : 1;
5500
5501 if (!table)
5502 table = peer->bgp->rib[afi][safi];
5503
5504 /* If still no table => afi/safi isn't configured at all or smth. */
5505 if (!table)
5506 return;
5507
5508 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5509 struct bgp_path_info *pi, *next;
5510 struct bgp_adj_in *ain;
5511 struct bgp_adj_in *ain_next;
5512
5513 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5514 * queued for every clearing peer, regardless of whether it is
5515 * relevant to the peer at hand.
5516 *
5517 * Overview: There are 3 different indices which need to be
5518 * scrubbed, potentially, when a peer is removed:
5519 *
5520 * 1 peer's routes visible via the RIB (ie accepted routes)
5521 * 2 peer's routes visible by the (optional) peer's adj-in index
5522 * 3 other routes visible by the peer's adj-out index
5523 *
5524 * 3 there is no hurry in scrubbing, once the struct peer is
5525 * removed from bgp->peer, we could just GC such deleted peer's
5526 * adj-outs at our leisure.
5527 *
5528 * 1 and 2 must be 'scrubbed' in some way, at least made
5529 * invisible via RIB index before peer session is allowed to be
5530 * brought back up. So one needs to know when such a 'search' is
5531 * complete.
5532 *
5533 * Ideally:
5534 *
5535 * - there'd be a single global queue or a single RIB walker
5536 * - rather than tracking which route_nodes still need to be
5537 * examined on a peer basis, we'd track which peers still
5538 * aren't cleared
5539 *
5540 * Given that our per-peer prefix-counts now should be reliable,
5541 * this may actually be achievable. It doesn't seem to be a huge
5542 * problem at this time,
5543 *
5544 * It is possible that we have multiple paths for a prefix from
5545 * a peer
5546 * if that peer is using AddPath.
5547 */
5548 ain = dest->adj_in;
5549 while (ain) {
5550 ain_next = ain->next;
5551
5552 if (ain->peer == peer)
5553 bgp_adj_in_remove(dest, ain);
5554
5555 ain = ain_next;
5556 }
5557
5558 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5559 next = pi->next;
5560 if (pi->peer != peer)
5561 continue;
5562
5563 if (force)
5564 bgp_path_info_reap(dest, pi);
5565 else {
5566 struct bgp_clear_node_queue *cnq;
5567
5568 /* both unlocked in bgp_clear_node_queue_del */
5569 bgp_table_lock(bgp_dest_table(dest));
5570 bgp_dest_lock_node(dest);
5571 cnq = XCALLOC(
5572 MTYPE_BGP_CLEAR_NODE_QUEUE,
5573 sizeof(struct bgp_clear_node_queue));
5574 cnq->dest = dest;
5575 work_queue_add(peer->clear_node_queue, cnq);
5576 break;
5577 }
5578 }
5579 }
5580 return;
5581 }
5582
5583 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5584 {
5585 struct bgp_dest *dest;
5586 struct bgp_table *table;
5587
5588 if (peer->clear_node_queue == NULL)
5589 bgp_clear_node_queue_init(peer);
5590
5591 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5592 * Idle until it receives a Clearing_Completed event. This protects
5593 * against peers which flap faster than we can we clear, which could
5594 * lead to:
5595 *
5596 * a) race with routes from the new session being installed before
5597 * clear_route_node visits the node (to delete the route of that
5598 * peer)
5599 * b) resource exhaustion, clear_route_node likely leads to an entry
5600 * on the process_main queue. Fast-flapping could cause that queue
5601 * to grow and grow.
5602 */
5603
5604 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5605 * the unlock will happen upon work-queue completion; other wise, the
5606 * unlock happens at the end of this function.
5607 */
5608 if (!peer->clear_node_queue->thread)
5609 peer_lock(peer);
5610
5611 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5612 bgp_clear_route_table(peer, afi, safi, NULL);
5613 else
5614 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5615 dest = bgp_route_next(dest)) {
5616 table = bgp_dest_get_bgp_table_info(dest);
5617 if (!table)
5618 continue;
5619
5620 bgp_clear_route_table(peer, afi, safi, table);
5621 }
5622
5623 /* unlock if no nodes got added to the clear-node-queue. */
5624 if (!peer->clear_node_queue->thread)
5625 peer_unlock(peer);
5626 }
5627
5628 void bgp_clear_route_all(struct peer *peer)
5629 {
5630 afi_t afi;
5631 safi_t safi;
5632
5633 FOREACH_AFI_SAFI (afi, safi)
5634 bgp_clear_route(peer, afi, safi);
5635
5636 #ifdef ENABLE_BGP_VNC
5637 rfapiProcessPeerDown(peer);
5638 #endif
5639 }
5640
5641 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5642 {
5643 struct bgp_table *table;
5644 struct bgp_dest *dest;
5645 struct bgp_adj_in *ain;
5646 struct bgp_adj_in *ain_next;
5647
5648 table = peer->bgp->rib[afi][safi];
5649
5650 /* It is possible that we have multiple paths for a prefix from a peer
5651 * if that peer is using AddPath.
5652 */
5653 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5654 ain = dest->adj_in;
5655
5656 while (ain) {
5657 ain_next = ain->next;
5658
5659 if (ain->peer == peer)
5660 bgp_adj_in_remove(dest, ain);
5661
5662 ain = ain_next;
5663 }
5664 }
5665 }
5666
5667 /* If any of the routes from the peer have been marked with the NO_LLGR
5668 * community, either as sent by the peer, or as the result of a configured
5669 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5670 * operation of [RFC4271].
5671 */
5672 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5673 {
5674 struct bgp_dest *dest;
5675 struct bgp_path_info *pi;
5676 struct bgp_table *table;
5677
5678 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5679 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5680 dest = bgp_route_next(dest)) {
5681 struct bgp_dest *rm;
5682
5683 /* look for neighbor in tables */
5684 table = bgp_dest_get_bgp_table_info(dest);
5685 if (!table)
5686 continue;
5687
5688 for (rm = bgp_table_top(table); rm;
5689 rm = bgp_route_next(rm))
5690 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5691 pi = pi->next) {
5692 if (pi->peer != peer)
5693 continue;
5694 if (CHECK_FLAG(
5695 peer->af_sflags[afi][safi],
5696 PEER_STATUS_LLGR_WAIT) &&
5697 bgp_attr_get_community(pi->attr) &&
5698 !community_include(
5699 bgp_attr_get_community(
5700 pi->attr),
5701 COMMUNITY_NO_LLGR))
5702 continue;
5703 if (!CHECK_FLAG(pi->flags,
5704 BGP_PATH_STALE))
5705 continue;
5706
5707 /*
5708 * If this is VRF leaked route
5709 * process for withdraw.
5710 */
5711 if (pi->sub_type ==
5712 BGP_ROUTE_IMPORTED &&
5713 peer->bgp->inst_type ==
5714 BGP_INSTANCE_TYPE_DEFAULT)
5715 vpn_leak_to_vrf_withdraw(
5716 peer->bgp, pi);
5717
5718 bgp_rib_remove(rm, pi, peer, afi, safi);
5719 break;
5720 }
5721 }
5722 } else {
5723 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5724 dest = bgp_route_next(dest))
5725 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5726 pi = pi->next) {
5727 if (pi->peer != peer)
5728 continue;
5729 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5730 PEER_STATUS_LLGR_WAIT) &&
5731 bgp_attr_get_community(pi->attr) &&
5732 !community_include(
5733 bgp_attr_get_community(pi->attr),
5734 COMMUNITY_NO_LLGR))
5735 continue;
5736 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5737 continue;
5738 if (safi == SAFI_UNICAST &&
5739 (peer->bgp->inst_type ==
5740 BGP_INSTANCE_TYPE_VRF ||
5741 peer->bgp->inst_type ==
5742 BGP_INSTANCE_TYPE_DEFAULT))
5743 vpn_leak_from_vrf_withdraw(
5744 bgp_get_default(), peer->bgp,
5745 pi);
5746
5747 bgp_rib_remove(dest, pi, peer, afi, safi);
5748 break;
5749 }
5750 }
5751 }
5752
5753 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5754 {
5755 struct bgp_dest *dest, *ndest;
5756 struct bgp_path_info *pi;
5757 struct bgp_table *table;
5758
5759 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5760 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5761 dest = bgp_route_next(dest)) {
5762 table = bgp_dest_get_bgp_table_info(dest);
5763 if (!table)
5764 continue;
5765
5766 for (ndest = bgp_table_top(table); ndest;
5767 ndest = bgp_route_next(ndest)) {
5768 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5769 pi = pi->next) {
5770 if (pi->peer != peer)
5771 continue;
5772
5773 if ((CHECK_FLAG(
5774 peer->af_sflags[afi][safi],
5775 PEER_STATUS_ENHANCED_REFRESH))
5776 && !CHECK_FLAG(pi->flags,
5777 BGP_PATH_STALE)
5778 && !CHECK_FLAG(
5779 pi->flags,
5780 BGP_PATH_UNUSEABLE)) {
5781 if (bgp_debug_neighbor_events(
5782 peer))
5783 zlog_debug(
5784 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5785 peer,
5786 afi2str(afi),
5787 safi2str(safi),
5788 bgp_dest_get_prefix(
5789 ndest));
5790
5791 bgp_path_info_set_flag(
5792 ndest, pi,
5793 BGP_PATH_STALE);
5794 }
5795 }
5796 }
5797 }
5798 } else {
5799 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5800 dest = bgp_route_next(dest)) {
5801 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5802 pi = pi->next) {
5803 if (pi->peer != peer)
5804 continue;
5805
5806 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5807 PEER_STATUS_ENHANCED_REFRESH))
5808 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5809 && !CHECK_FLAG(pi->flags,
5810 BGP_PATH_UNUSEABLE)) {
5811 if (bgp_debug_neighbor_events(peer))
5812 zlog_debug(
5813 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5814 peer, afi2str(afi),
5815 safi2str(safi),
5816 bgp_dest_get_prefix(
5817 dest));
5818
5819 bgp_path_info_set_flag(dest, pi,
5820 BGP_PATH_STALE);
5821 }
5822 }
5823 }
5824 }
5825 }
5826
5827 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5828 {
5829 if (peer->sort == BGP_PEER_IBGP)
5830 return true;
5831
5832 if (peer->sort == BGP_PEER_EBGP
5833 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5834 || FILTER_LIST_OUT_NAME(filter)
5835 || DISTRIBUTE_OUT_NAME(filter)))
5836 return true;
5837 return false;
5838 }
5839
5840 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5841 {
5842 if (peer->sort == BGP_PEER_IBGP)
5843 return true;
5844
5845 if (peer->sort == BGP_PEER_EBGP
5846 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5847 || FILTER_LIST_IN_NAME(filter)
5848 || DISTRIBUTE_IN_NAME(filter)))
5849 return true;
5850 return false;
5851 }
5852
5853 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5854 safi_t safi)
5855 {
5856 struct bgp_dest *dest;
5857 struct bgp_path_info *pi;
5858 struct bgp_path_info *next;
5859
5860 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5861 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5862 const struct prefix *p = bgp_dest_get_prefix(dest);
5863
5864 next = pi->next;
5865
5866 /* Unimport EVPN routes from VRFs */
5867 if (safi == SAFI_EVPN)
5868 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5869 SAFI_EVPN, p, pi);
5870
5871 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5872 && pi->type == ZEBRA_ROUTE_BGP
5873 && (pi->sub_type == BGP_ROUTE_NORMAL
5874 || pi->sub_type == BGP_ROUTE_AGGREGATE
5875 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5876
5877 if (bgp_fibupd_safi(safi))
5878 bgp_zebra_withdraw(p, pi, bgp, safi);
5879 }
5880
5881 bgp_path_info_reap(dest, pi);
5882 }
5883 }
5884
5885 /* Delete all kernel routes. */
5886 void bgp_cleanup_routes(struct bgp *bgp)
5887 {
5888 afi_t afi;
5889 struct bgp_dest *dest;
5890 struct bgp_table *table;
5891
5892 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5893 if (afi == AFI_L2VPN)
5894 continue;
5895 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5896 SAFI_UNICAST);
5897 /*
5898 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5899 */
5900 if (afi != AFI_L2VPN) {
5901 safi_t safi;
5902 safi = SAFI_MPLS_VPN;
5903 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5904 dest = bgp_route_next(dest)) {
5905 table = bgp_dest_get_bgp_table_info(dest);
5906 if (table != NULL) {
5907 bgp_cleanup_table(bgp, table, safi);
5908 bgp_table_finish(&table);
5909 bgp_dest_set_bgp_table_info(dest, NULL);
5910 bgp_dest_unlock_node(dest);
5911 }
5912 }
5913 safi = SAFI_ENCAP;
5914 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5915 dest = bgp_route_next(dest)) {
5916 table = bgp_dest_get_bgp_table_info(dest);
5917 if (table != NULL) {
5918 bgp_cleanup_table(bgp, table, safi);
5919 bgp_table_finish(&table);
5920 bgp_dest_set_bgp_table_info(dest, NULL);
5921 bgp_dest_unlock_node(dest);
5922 }
5923 }
5924 }
5925 }
5926 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5927 dest = bgp_route_next(dest)) {
5928 table = bgp_dest_get_bgp_table_info(dest);
5929 if (table != NULL) {
5930 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5931 bgp_table_finish(&table);
5932 bgp_dest_set_bgp_table_info(dest, NULL);
5933 bgp_dest_unlock_node(dest);
5934 }
5935 }
5936 }
5937
5938 void bgp_reset(void)
5939 {
5940 vty_reset();
5941 bgp_zclient_reset();
5942 access_list_reset();
5943 prefix_list_reset();
5944 }
5945
5946 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5947 {
5948 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5949 && CHECK_FLAG(peer->af_cap[afi][safi],
5950 PEER_CAP_ADDPATH_AF_TX_RCV));
5951 }
5952
5953 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5954 value. */
5955 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5956 struct bgp_nlri *packet)
5957 {
5958 uint8_t *pnt;
5959 uint8_t *lim;
5960 struct prefix p;
5961 int psize;
5962 int ret;
5963 afi_t afi;
5964 safi_t safi;
5965 bool addpath_capable;
5966 uint32_t addpath_id;
5967
5968 pnt = packet->nlri;
5969 lim = pnt + packet->length;
5970 afi = packet->afi;
5971 safi = packet->safi;
5972 addpath_id = 0;
5973 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
5974
5975 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5976 syntactic validity. If the field is syntactically incorrect,
5977 then the Error Subcode is set to Invalid Network Field. */
5978 for (; pnt < lim; pnt += psize) {
5979 /* Clear prefix structure. */
5980 memset(&p, 0, sizeof(p));
5981
5982 if (addpath_capable) {
5983
5984 /* When packet overflow occurs return immediately. */
5985 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5986 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5987
5988 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5989 addpath_id = ntohl(addpath_id);
5990 pnt += BGP_ADDPATH_ID_LEN;
5991 }
5992
5993 /* Fetch prefix length. */
5994 p.prefixlen = *pnt++;
5995 /* afi/safi validity already verified by caller,
5996 * bgp_update_receive */
5997 p.family = afi2family(afi);
5998
5999 /* Prefix length check. */
6000 if (p.prefixlen > prefix_blen(&p) * 8) {
6001 flog_err(
6002 EC_BGP_UPDATE_RCV,
6003 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
6004 peer->host, p.prefixlen, packet->afi);
6005 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
6006 }
6007
6008 /* Packet size overflow check. */
6009 psize = PSIZE(p.prefixlen);
6010
6011 /* When packet overflow occur return immediately. */
6012 if (pnt + psize > lim) {
6013 flog_err(
6014 EC_BGP_UPDATE_RCV,
6015 "%s [Error] Update packet error (prefix length %d overflows packet)",
6016 peer->host, p.prefixlen);
6017 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6018 }
6019
6020 /* Defensive coding, double-check the psize fits in a struct
6021 * prefix for the v4 and v6 afi's and unicast/multicast */
6022 if (psize > (ssize_t)sizeof(p.u.val)) {
6023 flog_err(
6024 EC_BGP_UPDATE_RCV,
6025 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
6026 peer->host, p.prefixlen, sizeof(p.u.val));
6027 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6028 }
6029
6030 /* Fetch prefix from NLRI packet. */
6031 memcpy(p.u.val, pnt, psize);
6032
6033 /* Check address. */
6034 if (afi == AFI_IP && safi == SAFI_UNICAST) {
6035 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
6036 /* From RFC4271 Section 6.3:
6037 *
6038 * If a prefix in the NLRI field is semantically
6039 * incorrect
6040 * (e.g., an unexpected multicast IP address),
6041 * an error SHOULD
6042 * be logged locally, and the prefix SHOULD be
6043 * ignored.
6044 */
6045 flog_err(
6046 EC_BGP_UPDATE_RCV,
6047 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
6048 peer->host, &p.u.prefix4);
6049 continue;
6050 }
6051 }
6052
6053 /* Check address. */
6054 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
6055 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6056 flog_err(
6057 EC_BGP_UPDATE_RCV,
6058 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
6059 peer->host, &p.u.prefix6);
6060
6061 continue;
6062 }
6063 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
6064 flog_err(
6065 EC_BGP_UPDATE_RCV,
6066 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
6067 peer->host, &p.u.prefix6);
6068
6069 continue;
6070 }
6071 }
6072
6073 /* Normal process. */
6074 if (attr)
6075 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
6076 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
6077 NULL, NULL, 0, 0, NULL);
6078 else
6079 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
6080 safi, ZEBRA_ROUTE_BGP,
6081 BGP_ROUTE_NORMAL, NULL, NULL, 0,
6082 NULL);
6083
6084 /* Do not send BGP notification twice when maximum-prefix count
6085 * overflow. */
6086 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
6087 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
6088
6089 /* Address family configuration mismatch. */
6090 if (ret < 0)
6091 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
6092 }
6093
6094 /* Packet length consistency check. */
6095 if (pnt != lim) {
6096 flog_err(
6097 EC_BGP_UPDATE_RCV,
6098 "%s [Error] Update packet error (prefix length mismatch with total length)",
6099 peer->host);
6100 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6101 }
6102
6103 return BGP_NLRI_PARSE_OK;
6104 }
6105
6106 static struct bgp_static *bgp_static_new(void)
6107 {
6108 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
6109 }
6110
6111 static void bgp_static_free(struct bgp_static *bgp_static)
6112 {
6113 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6114 route_map_counter_decrement(bgp_static->rmap.map);
6115
6116 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
6117 XFREE(MTYPE_BGP_STATIC, bgp_static);
6118 }
6119
6120 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
6121 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
6122 {
6123 struct bgp_dest *dest;
6124 struct bgp_path_info *pi;
6125 struct bgp_path_info *new;
6126 struct bgp_path_info rmap_path;
6127 struct attr attr;
6128 struct attr *attr_new;
6129 route_map_result_t ret;
6130 #ifdef ENABLE_BGP_VNC
6131 int vnc_implicit_withdraw = 0;
6132 #endif
6133
6134 assert(bgp_static);
6135
6136 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6137
6138 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6139
6140 attr.nexthop = bgp_static->igpnexthop;
6141 attr.med = bgp_static->igpmetric;
6142 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6143
6144 if (afi == AFI_IP)
6145 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
6146
6147 if (bgp_static->igpmetric)
6148 bgp_attr_set_aigp_metric(&attr, bgp_static->igpmetric);
6149
6150 if (bgp_static->atomic)
6151 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
6152
6153 /* Store label index, if required. */
6154 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
6155 attr.label_index = bgp_static->label_index;
6156 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
6157 }
6158
6159 /* Apply route-map. */
6160 if (bgp_static->rmap.name) {
6161 struct attr attr_tmp = attr;
6162
6163 memset(&rmap_path, 0, sizeof(rmap_path));
6164 rmap_path.peer = bgp->peer_self;
6165 rmap_path.attr = &attr_tmp;
6166
6167 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6168
6169 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6170
6171 bgp->peer_self->rmap_type = 0;
6172
6173 if (ret == RMAP_DENYMATCH) {
6174 /* Free uninterned attribute. */
6175 bgp_attr_flush(&attr_tmp);
6176
6177 /* Unintern original. */
6178 aspath_unintern(&attr.aspath);
6179 bgp_static_withdraw(bgp, p, afi, safi);
6180 bgp_dest_unlock_node(dest);
6181 return;
6182 }
6183
6184 if (bgp_in_graceful_shutdown(bgp))
6185 bgp_attr_add_gshut_community(&attr_tmp);
6186
6187 attr_new = bgp_attr_intern(&attr_tmp);
6188 } else {
6189
6190 if (bgp_in_graceful_shutdown(bgp))
6191 bgp_attr_add_gshut_community(&attr);
6192
6193 attr_new = bgp_attr_intern(&attr);
6194 }
6195
6196 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6197 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6198 && pi->sub_type == BGP_ROUTE_STATIC)
6199 break;
6200
6201 if (pi) {
6202 if (attrhash_cmp(pi->attr, attr_new)
6203 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6204 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6205 bgp_dest_unlock_node(dest);
6206 bgp_attr_unintern(&attr_new);
6207 aspath_unintern(&attr.aspath);
6208 return;
6209 } else {
6210 /* The attribute is changed. */
6211 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6212
6213 /* Rewrite BGP route information. */
6214 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6215 bgp_path_info_restore(dest, pi);
6216 else
6217 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6218 #ifdef ENABLE_BGP_VNC
6219 if ((afi == AFI_IP || afi == AFI_IP6)
6220 && (safi == SAFI_UNICAST)) {
6221 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6222 /*
6223 * Implicit withdraw case.
6224 * We have to do this before pi is
6225 * changed
6226 */
6227 ++vnc_implicit_withdraw;
6228 vnc_import_bgp_del_route(bgp, p, pi);
6229 vnc_import_bgp_exterior_del_route(
6230 bgp, p, pi);
6231 }
6232 }
6233 #endif
6234 bgp_attr_unintern(&pi->attr);
6235 pi->attr = attr_new;
6236 pi->uptime = monotime(NULL);
6237 #ifdef ENABLE_BGP_VNC
6238 if ((afi == AFI_IP || afi == AFI_IP6)
6239 && (safi == SAFI_UNICAST)) {
6240 if (vnc_implicit_withdraw) {
6241 vnc_import_bgp_add_route(bgp, p, pi);
6242 vnc_import_bgp_exterior_add_route(
6243 bgp, p, pi);
6244 }
6245 }
6246 #endif
6247
6248 /* Nexthop reachability check. */
6249 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6250 && (safi == SAFI_UNICAST
6251 || safi == SAFI_LABELED_UNICAST)) {
6252
6253 struct bgp *bgp_nexthop = bgp;
6254
6255 if (pi->extra && pi->extra->bgp_orig)
6256 bgp_nexthop = pi->extra->bgp_orig;
6257
6258 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6259 afi, safi, pi, NULL,
6260 0, p))
6261 bgp_path_info_set_flag(dest, pi,
6262 BGP_PATH_VALID);
6263 else {
6264 if (BGP_DEBUG(nht, NHT)) {
6265 char buf1[INET6_ADDRSTRLEN];
6266 inet_ntop(p->family,
6267 &p->u.prefix, buf1,
6268 sizeof(buf1));
6269 zlog_debug(
6270 "%s(%s): Route not in table, not advertising",
6271 __func__, buf1);
6272 }
6273 bgp_path_info_unset_flag(
6274 dest, pi, BGP_PATH_VALID);
6275 }
6276 } else {
6277 /* Delete the NHT structure if any, if we're
6278 * toggling between
6279 * enabling/disabling import check. We
6280 * deregister the route
6281 * from NHT to avoid overloading NHT and the
6282 * process interaction
6283 */
6284 bgp_unlink_nexthop(pi);
6285 bgp_path_info_set_flag(dest, pi,
6286 BGP_PATH_VALID);
6287 }
6288 /* Process change. */
6289 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6290 bgp_process(bgp, dest, afi, safi);
6291
6292 if (SAFI_UNICAST == safi
6293 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6294 || bgp->inst_type
6295 == BGP_INSTANCE_TYPE_DEFAULT)) {
6296 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6297 pi);
6298 }
6299
6300 bgp_dest_unlock_node(dest);
6301 aspath_unintern(&attr.aspath);
6302 return;
6303 }
6304 }
6305
6306 /* Make new BGP info. */
6307 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6308 attr_new, dest);
6309 /* Nexthop reachability check. */
6310 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6311 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6312 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6313 p))
6314 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6315 else {
6316 if (BGP_DEBUG(nht, NHT)) {
6317 char buf1[INET6_ADDRSTRLEN];
6318
6319 inet_ntop(p->family, &p->u.prefix, buf1,
6320 sizeof(buf1));
6321 zlog_debug(
6322 "%s(%s): Route not in table, not advertising",
6323 __func__, buf1);
6324 }
6325 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6326 }
6327 } else {
6328 /* Delete the NHT structure if any, if we're toggling between
6329 * enabling/disabling import check. We deregister the route
6330 * from NHT to avoid overloading NHT and the process interaction
6331 */
6332 bgp_unlink_nexthop(new);
6333
6334 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6335 }
6336
6337 /* Aggregate address increment. */
6338 bgp_aggregate_increment(bgp, p, new, afi, safi);
6339
6340 /* Register new BGP information. */
6341 bgp_path_info_add(dest, new);
6342
6343 /* route_node_get lock */
6344 bgp_dest_unlock_node(dest);
6345
6346 /* Process change. */
6347 bgp_process(bgp, dest, afi, safi);
6348
6349 if (SAFI_UNICAST == safi
6350 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6351 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6352 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6353 }
6354
6355 /* Unintern original. */
6356 aspath_unintern(&attr.aspath);
6357 }
6358
6359 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6360 safi_t safi)
6361 {
6362 struct bgp_dest *dest;
6363 struct bgp_path_info *pi;
6364
6365 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6366
6367 /* Check selected route and self inserted route. */
6368 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6369 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6370 && pi->sub_type == BGP_ROUTE_STATIC)
6371 break;
6372
6373 /* Withdraw static BGP route from routing table. */
6374 if (pi) {
6375 if (SAFI_UNICAST == safi
6376 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6377 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6378 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6379 }
6380 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6381 bgp_unlink_nexthop(pi);
6382 bgp_path_info_delete(dest, pi);
6383 bgp_process(bgp, dest, afi, safi);
6384 }
6385
6386 /* Unlock bgp_node_lookup. */
6387 bgp_dest_unlock_node(dest);
6388 }
6389
6390 /*
6391 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6392 */
6393 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6394 afi_t afi, safi_t safi,
6395 struct prefix_rd *prd)
6396 {
6397 struct bgp_dest *dest;
6398 struct bgp_path_info *pi;
6399
6400 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6401
6402 /* Check selected route and self inserted route. */
6403 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6404 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6405 && pi->sub_type == BGP_ROUTE_STATIC)
6406 break;
6407
6408 /* Withdraw static BGP route from routing table. */
6409 if (pi) {
6410 #ifdef ENABLE_BGP_VNC
6411 rfapiProcessWithdraw(
6412 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6413 1); /* Kill, since it is an administrative change */
6414 #endif
6415 if (SAFI_MPLS_VPN == safi
6416 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6417 vpn_leak_to_vrf_withdraw(bgp, pi);
6418 }
6419 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6420 bgp_path_info_delete(dest, pi);
6421 bgp_process(bgp, dest, afi, safi);
6422 }
6423
6424 /* Unlock bgp_node_lookup. */
6425 bgp_dest_unlock_node(dest);
6426 }
6427
6428 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6429 struct bgp_static *bgp_static, afi_t afi,
6430 safi_t safi)
6431 {
6432 struct bgp_dest *dest;
6433 struct bgp_path_info *new;
6434 struct attr *attr_new;
6435 struct attr attr = {0};
6436 struct bgp_path_info *pi;
6437 #ifdef ENABLE_BGP_VNC
6438 mpls_label_t label = 0;
6439 #endif
6440 uint32_t num_labels = 0;
6441
6442 assert(bgp_static);
6443
6444 if (bgp_static->label != MPLS_INVALID_LABEL)
6445 num_labels = 1;
6446 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6447 &bgp_static->prd);
6448
6449 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6450
6451 attr.nexthop = bgp_static->igpnexthop;
6452 attr.med = bgp_static->igpmetric;
6453 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6454
6455 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6456 || (safi == SAFI_ENCAP)) {
6457 if (afi == AFI_IP) {
6458 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6459 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6460 }
6461 }
6462 if (afi == AFI_L2VPN) {
6463 if (bgp_static->gatewayIp.family == AF_INET) {
6464 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6465 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6466 &bgp_static->gatewayIp.u.prefix4,
6467 IPV4_MAX_BYTELEN);
6468 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6469 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6470 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6471 &bgp_static->gatewayIp.u.prefix6,
6472 IPV6_MAX_BYTELEN);
6473 }
6474 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6475 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6476 struct bgp_encap_type_vxlan bet;
6477 memset(&bet, 0, sizeof(bet));
6478 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6479 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6480 }
6481 if (bgp_static->router_mac) {
6482 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6483 }
6484 }
6485 /* Apply route-map. */
6486 if (bgp_static->rmap.name) {
6487 struct attr attr_tmp = attr;
6488 struct bgp_path_info rmap_path;
6489 route_map_result_t ret;
6490
6491 rmap_path.peer = bgp->peer_self;
6492 rmap_path.attr = &attr_tmp;
6493
6494 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6495
6496 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6497
6498 bgp->peer_self->rmap_type = 0;
6499
6500 if (ret == RMAP_DENYMATCH) {
6501 /* Free uninterned attribute. */
6502 bgp_attr_flush(&attr_tmp);
6503
6504 /* Unintern original. */
6505 aspath_unintern(&attr.aspath);
6506 bgp_static_withdraw_safi(bgp, p, afi, safi,
6507 &bgp_static->prd);
6508 bgp_dest_unlock_node(dest);
6509 return;
6510 }
6511
6512 attr_new = bgp_attr_intern(&attr_tmp);
6513 } else {
6514 attr_new = bgp_attr_intern(&attr);
6515 }
6516
6517 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6518 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6519 && pi->sub_type == BGP_ROUTE_STATIC)
6520 break;
6521
6522 if (pi) {
6523 if (attrhash_cmp(pi->attr, attr_new)
6524 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6525 bgp_dest_unlock_node(dest);
6526 bgp_attr_unintern(&attr_new);
6527 aspath_unintern(&attr.aspath);
6528 return;
6529 } else {
6530 /* The attribute is changed. */
6531 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6532
6533 /* Rewrite BGP route information. */
6534 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6535 bgp_path_info_restore(dest, pi);
6536 else
6537 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6538 bgp_attr_unintern(&pi->attr);
6539 pi->attr = attr_new;
6540 pi->uptime = monotime(NULL);
6541 #ifdef ENABLE_BGP_VNC
6542 if (pi->extra)
6543 label = decode_label(&pi->extra->label[0]);
6544 #endif
6545
6546 /* Process change. */
6547 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6548 bgp_process(bgp, dest, afi, safi);
6549
6550 if (SAFI_MPLS_VPN == safi
6551 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6552 vpn_leak_to_vrf_update(bgp, pi,
6553 &bgp_static->prd);
6554 }
6555 #ifdef ENABLE_BGP_VNC
6556 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6557 pi->attr, afi, safi, pi->type,
6558 pi->sub_type, &label);
6559 #endif
6560 bgp_dest_unlock_node(dest);
6561 aspath_unintern(&attr.aspath);
6562 return;
6563 }
6564 }
6565
6566
6567 /* Make new BGP info. */
6568 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6569 attr_new, dest);
6570 SET_FLAG(new->flags, BGP_PATH_VALID);
6571 bgp_path_info_extra_get(new);
6572 if (num_labels) {
6573 new->extra->label[0] = bgp_static->label;
6574 new->extra->num_labels = num_labels;
6575 }
6576 #ifdef ENABLE_BGP_VNC
6577 label = decode_label(&bgp_static->label);
6578 #endif
6579
6580 /* Aggregate address increment. */
6581 bgp_aggregate_increment(bgp, p, new, afi, safi);
6582
6583 /* Register new BGP information. */
6584 bgp_path_info_add(dest, new);
6585 /* route_node_get lock */
6586 bgp_dest_unlock_node(dest);
6587
6588 /* Process change. */
6589 bgp_process(bgp, dest, afi, safi);
6590
6591 if (SAFI_MPLS_VPN == safi
6592 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6593 vpn_leak_to_vrf_update(bgp, new, &bgp_static->prd);
6594 }
6595 #ifdef ENABLE_BGP_VNC
6596 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6597 safi, new->type, new->sub_type, &label);
6598 #endif
6599
6600 /* Unintern original. */
6601 aspath_unintern(&attr.aspath);
6602 }
6603
6604 /* Configure static BGP network. When user don't run zebra, static
6605 route should be installed as valid. */
6606 static int bgp_static_set(struct vty *vty, const char *negate,
6607 const char *ip_str, afi_t afi, safi_t safi,
6608 const char *rmap, int backdoor, uint32_t label_index)
6609 {
6610 VTY_DECLVAR_CONTEXT(bgp, bgp);
6611 int ret;
6612 struct prefix p;
6613 struct bgp_static *bgp_static;
6614 struct bgp_dest *dest;
6615 uint8_t need_update = 0;
6616
6617 /* Convert IP prefix string to struct prefix. */
6618 ret = str2prefix(ip_str, &p);
6619 if (!ret) {
6620 vty_out(vty, "%% Malformed prefix\n");
6621 return CMD_WARNING_CONFIG_FAILED;
6622 }
6623 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6624 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6625 return CMD_WARNING_CONFIG_FAILED;
6626 }
6627
6628 apply_mask(&p);
6629
6630 if (negate) {
6631
6632 /* Set BGP static route configuration. */
6633 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6634
6635 if (!dest) {
6636 vty_out(vty, "%% Can't find static route specified\n");
6637 return CMD_WARNING_CONFIG_FAILED;
6638 }
6639
6640 bgp_static = bgp_dest_get_bgp_static_info(dest);
6641
6642 if ((label_index != BGP_INVALID_LABEL_INDEX)
6643 && (label_index != bgp_static->label_index)) {
6644 vty_out(vty,
6645 "%% label-index doesn't match static route\n");
6646 bgp_dest_unlock_node(dest);
6647 return CMD_WARNING_CONFIG_FAILED;
6648 }
6649
6650 if ((rmap && bgp_static->rmap.name)
6651 && strcmp(rmap, bgp_static->rmap.name)) {
6652 vty_out(vty,
6653 "%% route-map name doesn't match static route\n");
6654 bgp_dest_unlock_node(dest);
6655 return CMD_WARNING_CONFIG_FAILED;
6656 }
6657
6658 /* Update BGP RIB. */
6659 if (!bgp_static->backdoor)
6660 bgp_static_withdraw(bgp, &p, afi, safi);
6661
6662 /* Clear configuration. */
6663 bgp_static_free(bgp_static);
6664 bgp_dest_set_bgp_static_info(dest, NULL);
6665 bgp_dest_unlock_node(dest);
6666 bgp_dest_unlock_node(dest);
6667 } else {
6668
6669 /* Set BGP static route configuration. */
6670 dest = bgp_node_get(bgp->route[afi][safi], &p);
6671 bgp_static = bgp_dest_get_bgp_static_info(dest);
6672 if (bgp_static) {
6673 /* Configuration change. */
6674 /* Label index cannot be changed. */
6675 if (bgp_static->label_index != label_index) {
6676 vty_out(vty, "%% cannot change label-index\n");
6677 bgp_dest_unlock_node(dest);
6678 return CMD_WARNING_CONFIG_FAILED;
6679 }
6680
6681 /* Check previous routes are installed into BGP. */
6682 if (bgp_static->valid
6683 && bgp_static->backdoor != backdoor)
6684 need_update = 1;
6685
6686 bgp_static->backdoor = backdoor;
6687
6688 if (rmap) {
6689 XFREE(MTYPE_ROUTE_MAP_NAME,
6690 bgp_static->rmap.name);
6691 route_map_counter_decrement(
6692 bgp_static->rmap.map);
6693 bgp_static->rmap.name =
6694 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6695 bgp_static->rmap.map =
6696 route_map_lookup_by_name(rmap);
6697 route_map_counter_increment(
6698 bgp_static->rmap.map);
6699 } else {
6700 XFREE(MTYPE_ROUTE_MAP_NAME,
6701 bgp_static->rmap.name);
6702 route_map_counter_decrement(
6703 bgp_static->rmap.map);
6704 bgp_static->rmap.map = NULL;
6705 bgp_static->valid = 0;
6706 }
6707 bgp_dest_unlock_node(dest);
6708 } else {
6709 /* New configuration. */
6710 bgp_static = bgp_static_new();
6711 bgp_static->backdoor = backdoor;
6712 bgp_static->valid = 0;
6713 bgp_static->igpmetric = 0;
6714 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6715 bgp_static->label_index = label_index;
6716
6717 if (rmap) {
6718 XFREE(MTYPE_ROUTE_MAP_NAME,
6719 bgp_static->rmap.name);
6720 route_map_counter_decrement(
6721 bgp_static->rmap.map);
6722 bgp_static->rmap.name =
6723 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6724 bgp_static->rmap.map =
6725 route_map_lookup_by_name(rmap);
6726 route_map_counter_increment(
6727 bgp_static->rmap.map);
6728 }
6729 bgp_dest_set_bgp_static_info(dest, bgp_static);
6730 }
6731
6732 bgp_static->valid = 1;
6733 if (need_update)
6734 bgp_static_withdraw(bgp, &p, afi, safi);
6735
6736 if (!bgp_static->backdoor)
6737 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6738 }
6739
6740 return CMD_SUCCESS;
6741 }
6742
6743 void bgp_static_add(struct bgp *bgp)
6744 {
6745 afi_t afi;
6746 safi_t safi;
6747 struct bgp_dest *dest;
6748 struct bgp_dest *rm;
6749 struct bgp_table *table;
6750 struct bgp_static *bgp_static;
6751
6752 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6753 FOREACH_AFI_SAFI (afi, safi)
6754 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6755 dest = bgp_route_next(dest)) {
6756 if (!bgp_dest_has_bgp_path_info_data(dest))
6757 continue;
6758
6759 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6760 || (safi == SAFI_EVPN)) {
6761 table = bgp_dest_get_bgp_table_info(dest);
6762
6763 for (rm = bgp_table_top(table); rm;
6764 rm = bgp_route_next(rm)) {
6765 bgp_static =
6766 bgp_dest_get_bgp_static_info(
6767 rm);
6768 bgp_static_update_safi(
6769 bgp, bgp_dest_get_prefix(rm),
6770 bgp_static, afi, safi);
6771 }
6772 } else {
6773 bgp_static_update(
6774 bgp, bgp_dest_get_prefix(dest),
6775 bgp_dest_get_bgp_static_info(dest), afi,
6776 safi);
6777 }
6778 }
6779 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6780 }
6781
6782 /* Called from bgp_delete(). Delete all static routes from the BGP
6783 instance. */
6784 void bgp_static_delete(struct bgp *bgp)
6785 {
6786 afi_t afi;
6787 safi_t safi;
6788 struct bgp_dest *dest;
6789 struct bgp_dest *rm;
6790 struct bgp_table *table;
6791 struct bgp_static *bgp_static;
6792
6793 FOREACH_AFI_SAFI (afi, safi)
6794 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6795 dest = bgp_route_next(dest)) {
6796 if (!bgp_dest_has_bgp_path_info_data(dest))
6797 continue;
6798
6799 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6800 || (safi == SAFI_EVPN)) {
6801 table = bgp_dest_get_bgp_table_info(dest);
6802
6803 for (rm = bgp_table_top(table); rm;
6804 rm = bgp_route_next(rm)) {
6805 bgp_static =
6806 bgp_dest_get_bgp_static_info(
6807 rm);
6808 if (!bgp_static)
6809 continue;
6810
6811 bgp_static_withdraw_safi(
6812 bgp, bgp_dest_get_prefix(rm),
6813 AFI_IP, safi,
6814 (struct prefix_rd *)
6815 bgp_dest_get_prefix(
6816 dest));
6817 bgp_static_free(bgp_static);
6818 bgp_dest_set_bgp_static_info(rm,
6819 NULL);
6820 bgp_dest_unlock_node(rm);
6821 }
6822 } else {
6823 bgp_static = bgp_dest_get_bgp_static_info(dest);
6824 bgp_static_withdraw(bgp,
6825 bgp_dest_get_prefix(dest),
6826 afi, safi);
6827 bgp_static_free(bgp_static);
6828 bgp_dest_set_bgp_static_info(dest, NULL);
6829 bgp_dest_unlock_node(dest);
6830 }
6831 }
6832 }
6833
6834 void bgp_static_redo_import_check(struct bgp *bgp)
6835 {
6836 afi_t afi;
6837 safi_t safi;
6838 struct bgp_dest *dest;
6839 struct bgp_dest *rm;
6840 struct bgp_table *table;
6841 struct bgp_static *bgp_static;
6842
6843 /* Use this flag to force reprocessing of the route */
6844 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6845 FOREACH_AFI_SAFI (afi, safi) {
6846 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6847 dest = bgp_route_next(dest)) {
6848 if (!bgp_dest_has_bgp_path_info_data(dest))
6849 continue;
6850
6851 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6852 || (safi == SAFI_EVPN)) {
6853 table = bgp_dest_get_bgp_table_info(dest);
6854
6855 for (rm = bgp_table_top(table); rm;
6856 rm = bgp_route_next(rm)) {
6857 bgp_static =
6858 bgp_dest_get_bgp_static_info(
6859 rm);
6860 bgp_static_update_safi(
6861 bgp, bgp_dest_get_prefix(rm),
6862 bgp_static, afi, safi);
6863 }
6864 } else {
6865 bgp_static = bgp_dest_get_bgp_static_info(dest);
6866 bgp_static_update(bgp,
6867 bgp_dest_get_prefix(dest),
6868 bgp_static, afi, safi);
6869 }
6870 }
6871 }
6872 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6873 }
6874
6875 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6876 safi_t safi)
6877 {
6878 struct bgp_table *table;
6879 struct bgp_dest *dest;
6880 struct bgp_path_info *pi;
6881
6882 /* Do not install the aggregate route if BGP is in the
6883 * process of termination.
6884 */
6885 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6886 || (bgp->peer_self == NULL))
6887 return;
6888
6889 table = bgp->rib[afi][safi];
6890 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6891 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6892 if (pi->peer == bgp->peer_self
6893 && ((pi->type == ZEBRA_ROUTE_BGP
6894 && pi->sub_type == BGP_ROUTE_STATIC)
6895 || (pi->type != ZEBRA_ROUTE_BGP
6896 && pi->sub_type
6897 == BGP_ROUTE_REDISTRIBUTE))) {
6898 bgp_aggregate_decrement(
6899 bgp, bgp_dest_get_prefix(dest), pi, afi,
6900 safi);
6901 bgp_unlink_nexthop(pi);
6902 bgp_path_info_delete(dest, pi);
6903 bgp_process(bgp, dest, afi, safi);
6904 }
6905 }
6906 }
6907 }
6908
6909 /*
6910 * Purge all networks and redistributed routes from routing table.
6911 * Invoked upon the instance going down.
6912 */
6913 void bgp_purge_static_redist_routes(struct bgp *bgp)
6914 {
6915 afi_t afi;
6916 safi_t safi;
6917
6918 FOREACH_AFI_SAFI (afi, safi)
6919 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6920 }
6921
6922 /*
6923 * gpz 110624
6924 * Currently this is used to set static routes for VPN and ENCAP.
6925 * I think it can probably be factored with bgp_static_set.
6926 */
6927 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6928 const char *ip_str, const char *rd_str,
6929 const char *label_str, const char *rmap_str,
6930 int evpn_type, const char *esi, const char *gwip,
6931 const char *ethtag, const char *routermac)
6932 {
6933 VTY_DECLVAR_CONTEXT(bgp, bgp);
6934 int ret;
6935 struct prefix p;
6936 struct prefix_rd prd;
6937 struct bgp_dest *pdest;
6938 struct bgp_dest *dest;
6939 struct bgp_table *table;
6940 struct bgp_static *bgp_static;
6941 mpls_label_t label = MPLS_INVALID_LABEL;
6942 struct prefix gw_ip;
6943
6944 /* validate ip prefix */
6945 ret = str2prefix(ip_str, &p);
6946 if (!ret) {
6947 vty_out(vty, "%% Malformed prefix\n");
6948 return CMD_WARNING_CONFIG_FAILED;
6949 }
6950 apply_mask(&p);
6951 if ((afi == AFI_L2VPN)
6952 && (bgp_build_evpn_prefix(evpn_type,
6953 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6954 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6955 return CMD_WARNING_CONFIG_FAILED;
6956 }
6957
6958 ret = str2prefix_rd(rd_str, &prd);
6959 if (!ret) {
6960 vty_out(vty, "%% Malformed rd\n");
6961 return CMD_WARNING_CONFIG_FAILED;
6962 }
6963
6964 if (label_str) {
6965 unsigned long label_val;
6966 label_val = strtoul(label_str, NULL, 10);
6967 encode_label(label_val, &label);
6968 }
6969
6970 if (safi == SAFI_EVPN) {
6971 if (esi && str2esi(esi, NULL) == 0) {
6972 vty_out(vty, "%% Malformed ESI\n");
6973 return CMD_WARNING_CONFIG_FAILED;
6974 }
6975 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6976 vty_out(vty, "%% Malformed Router MAC\n");
6977 return CMD_WARNING_CONFIG_FAILED;
6978 }
6979 if (gwip) {
6980 memset(&gw_ip, 0, sizeof(gw_ip));
6981 ret = str2prefix(gwip, &gw_ip);
6982 if (!ret) {
6983 vty_out(vty, "%% Malformed GatewayIp\n");
6984 return CMD_WARNING_CONFIG_FAILED;
6985 }
6986 if ((gw_ip.family == AF_INET
6987 && is_evpn_prefix_ipaddr_v6(
6988 (struct prefix_evpn *)&p))
6989 || (gw_ip.family == AF_INET6
6990 && is_evpn_prefix_ipaddr_v4(
6991 (struct prefix_evpn *)&p))) {
6992 vty_out(vty,
6993 "%% GatewayIp family differs with IP prefix\n");
6994 return CMD_WARNING_CONFIG_FAILED;
6995 }
6996 }
6997 }
6998 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6999 if (!bgp_dest_has_bgp_path_info_data(pdest))
7000 bgp_dest_set_bgp_table_info(pdest,
7001 bgp_table_init(bgp, afi, safi));
7002 table = bgp_dest_get_bgp_table_info(pdest);
7003
7004 dest = bgp_node_get(table, &p);
7005
7006 if (bgp_dest_has_bgp_path_info_data(dest)) {
7007 vty_out(vty, "%% Same network configuration exists\n");
7008 bgp_dest_unlock_node(dest);
7009 } else {
7010 /* New configuration. */
7011 bgp_static = bgp_static_new();
7012 bgp_static->backdoor = 0;
7013 bgp_static->valid = 0;
7014 bgp_static->igpmetric = 0;
7015 bgp_static->igpnexthop.s_addr = INADDR_ANY;
7016 bgp_static->label = label;
7017 bgp_static->prd = prd;
7018
7019 if (rmap_str) {
7020 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
7021 route_map_counter_decrement(bgp_static->rmap.map);
7022 bgp_static->rmap.name =
7023 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
7024 bgp_static->rmap.map =
7025 route_map_lookup_by_name(rmap_str);
7026 route_map_counter_increment(bgp_static->rmap.map);
7027 }
7028
7029 if (safi == SAFI_EVPN) {
7030 if (esi) {
7031 bgp_static->eth_s_id =
7032 XCALLOC(MTYPE_ATTR,
7033 sizeof(esi_t));
7034 str2esi(esi, bgp_static->eth_s_id);
7035 }
7036 if (routermac) {
7037 bgp_static->router_mac =
7038 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
7039 (void)prefix_str2mac(routermac,
7040 bgp_static->router_mac);
7041 }
7042 if (gwip)
7043 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
7044 }
7045 bgp_dest_set_bgp_static_info(dest, bgp_static);
7046
7047 bgp_static->valid = 1;
7048 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
7049 }
7050
7051 return CMD_SUCCESS;
7052 }
7053
7054 /* Configure static BGP network. */
7055 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
7056 const char *ip_str, const char *rd_str,
7057 const char *label_str, int evpn_type, const char *esi,
7058 const char *gwip, const char *ethtag)
7059 {
7060 VTY_DECLVAR_CONTEXT(bgp, bgp);
7061 int ret;
7062 struct prefix p;
7063 struct prefix_rd prd;
7064 struct bgp_dest *pdest;
7065 struct bgp_dest *dest;
7066 struct bgp_table *table;
7067 struct bgp_static *bgp_static;
7068 mpls_label_t label = MPLS_INVALID_LABEL;
7069
7070 /* Convert IP prefix string to struct prefix. */
7071 ret = str2prefix(ip_str, &p);
7072 if (!ret) {
7073 vty_out(vty, "%% Malformed prefix\n");
7074 return CMD_WARNING_CONFIG_FAILED;
7075 }
7076 apply_mask(&p);
7077 if ((afi == AFI_L2VPN)
7078 && (bgp_build_evpn_prefix(evpn_type,
7079 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7080 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7081 return CMD_WARNING_CONFIG_FAILED;
7082 }
7083 ret = str2prefix_rd(rd_str, &prd);
7084 if (!ret) {
7085 vty_out(vty, "%% Malformed rd\n");
7086 return CMD_WARNING_CONFIG_FAILED;
7087 }
7088
7089 if (label_str) {
7090 unsigned long label_val;
7091 label_val = strtoul(label_str, NULL, 10);
7092 encode_label(label_val, &label);
7093 }
7094
7095 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7096 if (!bgp_dest_has_bgp_path_info_data(pdest))
7097 bgp_dest_set_bgp_table_info(pdest,
7098 bgp_table_init(bgp, afi, safi));
7099 else
7100 bgp_dest_unlock_node(pdest);
7101 table = bgp_dest_get_bgp_table_info(pdest);
7102
7103 dest = bgp_node_lookup(table, &p);
7104
7105 if (dest) {
7106 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
7107
7108 bgp_static = bgp_dest_get_bgp_static_info(dest);
7109 bgp_static_free(bgp_static);
7110 bgp_dest_set_bgp_static_info(dest, NULL);
7111 bgp_dest_unlock_node(dest);
7112 bgp_dest_unlock_node(dest);
7113 } else
7114 vty_out(vty, "%% Can't find the route\n");
7115
7116 return CMD_SUCCESS;
7117 }
7118
7119 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
7120 const char *rmap_name)
7121 {
7122 VTY_DECLVAR_CONTEXT(bgp, bgp);
7123 struct bgp_rmap *rmap;
7124
7125 rmap = &bgp->table_map[afi][safi];
7126 if (rmap_name) {
7127 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7128 route_map_counter_decrement(rmap->map);
7129 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
7130 rmap->map = route_map_lookup_by_name(rmap_name);
7131 route_map_counter_increment(rmap->map);
7132 } else {
7133 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7134 route_map_counter_decrement(rmap->map);
7135 rmap->map = NULL;
7136 }
7137
7138 if (bgp_fibupd_safi(safi))
7139 bgp_zebra_announce_table(bgp, afi, safi);
7140
7141 return CMD_SUCCESS;
7142 }
7143
7144 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
7145 const char *rmap_name)
7146 {
7147 VTY_DECLVAR_CONTEXT(bgp, bgp);
7148 struct bgp_rmap *rmap;
7149
7150 rmap = &bgp->table_map[afi][safi];
7151 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7152 route_map_counter_decrement(rmap->map);
7153 rmap->map = NULL;
7154
7155 if (bgp_fibupd_safi(safi))
7156 bgp_zebra_announce_table(bgp, afi, safi);
7157
7158 return CMD_SUCCESS;
7159 }
7160
7161 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
7162 safi_t safi)
7163 {
7164 if (bgp->table_map[afi][safi].name) {
7165 vty_out(vty, " table-map %s\n",
7166 bgp->table_map[afi][safi].name);
7167 }
7168 }
7169
7170 DEFUN (bgp_table_map,
7171 bgp_table_map_cmd,
7172 "table-map WORD",
7173 "BGP table to RIB route download filter\n"
7174 "Name of the route map\n")
7175 {
7176 int idx_word = 1;
7177 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7178 argv[idx_word]->arg);
7179 }
7180 DEFUN (no_bgp_table_map,
7181 no_bgp_table_map_cmd,
7182 "no table-map WORD",
7183 NO_STR
7184 "BGP table to RIB route download filter\n"
7185 "Name of the route map\n")
7186 {
7187 int idx_word = 2;
7188 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7189 argv[idx_word]->arg);
7190 }
7191
7192 DEFPY(bgp_network,
7193 bgp_network_cmd,
7194 "[no] network \
7195 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7196 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7197 backdoor$backdoor}]",
7198 NO_STR
7199 "Specify a network to announce via BGP\n"
7200 "IPv4 prefix\n"
7201 "Network number\n"
7202 "Network mask\n"
7203 "Network mask\n"
7204 "Route-map to modify the attributes\n"
7205 "Name of the route map\n"
7206 "Label index to associate with the prefix\n"
7207 "Label index value\n"
7208 "Specify a BGP backdoor route\n")
7209 {
7210 char addr_prefix_str[BUFSIZ];
7211
7212 if (address_str) {
7213 int ret;
7214
7215 ret = netmask_str2prefix_str(address_str, netmask_str,
7216 addr_prefix_str,
7217 sizeof(addr_prefix_str));
7218 if (!ret) {
7219 vty_out(vty, "%% Inconsistent address and mask\n");
7220 return CMD_WARNING_CONFIG_FAILED;
7221 }
7222 }
7223
7224 return bgp_static_set(
7225 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7226 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7227 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7228 }
7229
7230 DEFPY(ipv6_bgp_network,
7231 ipv6_bgp_network_cmd,
7232 "[no] network X:X::X:X/M$prefix \
7233 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7234 NO_STR
7235 "Specify a network to announce via BGP\n"
7236 "IPv6 prefix\n"
7237 "Route-map to modify the attributes\n"
7238 "Name of the route map\n"
7239 "Label index to associate with the prefix\n"
7240 "Label index value\n")
7241 {
7242 return bgp_static_set(
7243 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7244 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7245 }
7246
7247 static struct bgp_aggregate *bgp_aggregate_new(void)
7248 {
7249 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7250 }
7251
7252 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7253 {
7254 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7255 route_map_counter_decrement(aggregate->suppress_map);
7256 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7257 route_map_counter_decrement(aggregate->rmap.map);
7258 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7259 }
7260
7261 /**
7262 * Helper function to avoid repeated code: prepare variables for a
7263 * `route_map_apply` call.
7264 *
7265 * \returns `true` on route map match, otherwise `false`.
7266 */
7267 static bool aggr_suppress_map_test(struct bgp *bgp,
7268 struct bgp_aggregate *aggregate,
7269 struct bgp_path_info *pi)
7270 {
7271 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7272 route_map_result_t rmr = RMAP_DENYMATCH;
7273 struct bgp_path_info rmap_path = {};
7274 struct attr attr = {};
7275
7276 /* No route map entries created, just don't match. */
7277 if (aggregate->suppress_map == NULL)
7278 return false;
7279
7280 /* Call route map matching and return result. */
7281 attr.aspath = aspath_empty();
7282 rmap_path.peer = bgp->peer_self;
7283 rmap_path.attr = &attr;
7284
7285 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7286 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7287 bgp->peer_self->rmap_type = 0;
7288
7289 bgp_attr_flush(&attr);
7290 aspath_unintern(&attr.aspath);
7291
7292 return rmr == RMAP_PERMITMATCH;
7293 }
7294
7295 /** Test whether the aggregation has suppressed this path or not. */
7296 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7297 struct bgp_path_info *pi)
7298 {
7299 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7300 return false;
7301
7302 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7303 }
7304
7305 /**
7306 * Suppress this path and keep the reference.
7307 *
7308 * \returns `true` if needs processing otherwise `false`.
7309 */
7310 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7311 struct bgp_path_info *pi)
7312 {
7313 struct bgp_path_info_extra *pie;
7314
7315 /* Path is already suppressed by this aggregation. */
7316 if (aggr_suppress_exists(aggregate, pi))
7317 return false;
7318
7319 pie = bgp_path_info_extra_get(pi);
7320
7321 /* This is the first suppression, allocate memory and list it. */
7322 if (pie->aggr_suppressors == NULL)
7323 pie->aggr_suppressors = list_new();
7324
7325 listnode_add(pie->aggr_suppressors, aggregate);
7326
7327 /* Only mark for processing if suppressed. */
7328 if (listcount(pie->aggr_suppressors) == 1) {
7329 if (BGP_DEBUG(update, UPDATE_OUT))
7330 zlog_debug("aggregate-address suppressing: %pFX",
7331 bgp_dest_get_prefix(pi->net));
7332
7333 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7334 return true;
7335 }
7336
7337 return false;
7338 }
7339
7340 /**
7341 * Unsuppress this path and remove the reference.
7342 *
7343 * \returns `true` if needs processing otherwise `false`.
7344 */
7345 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7346 struct bgp_path_info *pi)
7347 {
7348 /* Path wasn't suppressed. */
7349 if (!aggr_suppress_exists(aggregate, pi))
7350 return false;
7351
7352 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7353
7354 /* Unsuppress and free extra memory if last item. */
7355 if (listcount(pi->extra->aggr_suppressors) == 0) {
7356 if (BGP_DEBUG(update, UPDATE_OUT))
7357 zlog_debug("aggregate-address unsuppressing: %pFX",
7358 bgp_dest_get_prefix(pi->net));
7359
7360 list_delete(&pi->extra->aggr_suppressors);
7361 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7362 return true;
7363 }
7364
7365 return false;
7366 }
7367
7368 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7369 struct aspath *aspath,
7370 struct community *comm,
7371 struct ecommunity *ecomm,
7372 struct lcommunity *lcomm)
7373 {
7374 static struct aspath *ae = NULL;
7375
7376 if (!ae)
7377 ae = aspath_empty();
7378
7379 if (!pi)
7380 return false;
7381
7382 if (origin != pi->attr->origin)
7383 return false;
7384
7385 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7386 return false;
7387
7388 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7389 return false;
7390
7391 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7392 return false;
7393
7394 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7395 return false;
7396
7397 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7398 return false;
7399
7400 return true;
7401 }
7402
7403 static void bgp_aggregate_install(
7404 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7405 uint8_t origin, struct aspath *aspath, struct community *community,
7406 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7407 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7408 {
7409 struct bgp_dest *dest;
7410 struct bgp_table *table;
7411 struct bgp_path_info *pi, *orig, *new;
7412 struct attr *attr;
7413
7414 table = bgp->rib[afi][safi];
7415
7416 dest = bgp_node_get(table, p);
7417
7418 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7419 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7420 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7421 break;
7422
7423 /*
7424 * If we have paths with different MEDs, then don't install
7425 * (or uninstall) the aggregate route.
7426 */
7427 if (aggregate->match_med && aggregate->med_mismatched)
7428 goto uninstall_aggregate_route;
7429
7430 if (aggregate->count > 0) {
7431 /*
7432 * If the aggregate information has not changed
7433 * no need to re-install it again.
7434 */
7435 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7436 ecommunity, lcommunity)) {
7437 bgp_dest_unlock_node(dest);
7438
7439 if (aspath)
7440 aspath_free(aspath);
7441 if (community)
7442 community_free(&community);
7443 if (ecommunity)
7444 ecommunity_free(&ecommunity);
7445 if (lcommunity)
7446 lcommunity_free(&lcommunity);
7447
7448 return;
7449 }
7450
7451 /*
7452 * Mark the old as unusable
7453 */
7454 if (pi)
7455 bgp_path_info_delete(dest, pi);
7456
7457 attr = bgp_attr_aggregate_intern(
7458 bgp, origin, aspath, community, ecommunity, lcommunity,
7459 aggregate, atomic_aggregate, p);
7460
7461 if (!attr) {
7462 bgp_dest_unlock_node(dest);
7463 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7464 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7465 zlog_debug("%s: %pFX null attribute", __func__,
7466 p);
7467 return;
7468 }
7469
7470 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7471 bgp->peer_self, attr, dest);
7472
7473 SET_FLAG(new->flags, BGP_PATH_VALID);
7474
7475 bgp_path_info_add(dest, new);
7476 bgp_process(bgp, dest, afi, safi);
7477 } else {
7478 uninstall_aggregate_route:
7479 for (pi = orig; pi; pi = pi->next)
7480 if (pi->peer == bgp->peer_self
7481 && pi->type == ZEBRA_ROUTE_BGP
7482 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7483 break;
7484
7485 /* Withdraw static BGP route from routing table. */
7486 if (pi) {
7487 bgp_path_info_delete(dest, pi);
7488 bgp_process(bgp, dest, afi, safi);
7489 }
7490 }
7491
7492 bgp_dest_unlock_node(dest);
7493 }
7494
7495 /**
7496 * Check if the current path has different MED than other known paths.
7497 *
7498 * \returns `true` if the MED matched the others else `false`.
7499 */
7500 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7501 struct bgp *bgp, struct bgp_path_info *pi)
7502 {
7503 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7504
7505 /* This is the first route being analyzed. */
7506 if (!aggregate->med_initialized) {
7507 aggregate->med_initialized = true;
7508 aggregate->med_mismatched = false;
7509 aggregate->med_matched_value = cur_med;
7510 } else {
7511 /* Check if routes with different MED showed up. */
7512 if (cur_med != aggregate->med_matched_value)
7513 aggregate->med_mismatched = true;
7514 }
7515
7516 return !aggregate->med_mismatched;
7517 }
7518
7519 /**
7520 * Initializes and tests all routes in the aggregate address path for MED
7521 * values.
7522 *
7523 * \returns `true` if all MEDs are the same otherwise `false`.
7524 */
7525 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7526 struct bgp *bgp, const struct prefix *p,
7527 afi_t afi, safi_t safi)
7528 {
7529 struct bgp_table *table = bgp->rib[afi][safi];
7530 const struct prefix *dest_p;
7531 struct bgp_dest *dest, *top;
7532 struct bgp_path_info *pi;
7533 bool med_matched = true;
7534
7535 aggregate->med_initialized = false;
7536
7537 top = bgp_node_get(table, p);
7538 for (dest = bgp_node_get(table, p); dest;
7539 dest = bgp_route_next_until(dest, top)) {
7540 dest_p = bgp_dest_get_prefix(dest);
7541 if (dest_p->prefixlen <= p->prefixlen)
7542 continue;
7543
7544 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7545 if (BGP_PATH_HOLDDOWN(pi))
7546 continue;
7547 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7548 continue;
7549 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7550 med_matched = false;
7551 break;
7552 }
7553 }
7554 if (!med_matched)
7555 break;
7556 }
7557 bgp_dest_unlock_node(top);
7558
7559 return med_matched;
7560 }
7561
7562 /**
7563 * Toggles the route suppression status for this aggregate address
7564 * configuration.
7565 */
7566 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7567 struct bgp *bgp, const struct prefix *p,
7568 afi_t afi, safi_t safi, bool suppress)
7569 {
7570 struct bgp_table *table = bgp->rib[afi][safi];
7571 const struct prefix *dest_p;
7572 struct bgp_dest *dest, *top;
7573 struct bgp_path_info *pi;
7574 bool toggle_suppression;
7575
7576 /* We've found a different MED we must revert any suppressed routes. */
7577 top = bgp_node_get(table, p);
7578 for (dest = bgp_node_get(table, p); dest;
7579 dest = bgp_route_next_until(dest, top)) {
7580 dest_p = bgp_dest_get_prefix(dest);
7581 if (dest_p->prefixlen <= p->prefixlen)
7582 continue;
7583
7584 toggle_suppression = false;
7585 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7586 if (BGP_PATH_HOLDDOWN(pi))
7587 continue;
7588 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7589 continue;
7590
7591 /* We are toggling suppression back. */
7592 if (suppress) {
7593 /* Suppress route if not suppressed already. */
7594 if (aggr_suppress_path(aggregate, pi))
7595 toggle_suppression = true;
7596 continue;
7597 }
7598
7599 /* Install route if there is no more suppression. */
7600 if (aggr_unsuppress_path(aggregate, pi))
7601 toggle_suppression = true;
7602 }
7603
7604 if (toggle_suppression)
7605 bgp_process(bgp, dest, afi, safi);
7606 }
7607 bgp_dest_unlock_node(top);
7608 }
7609
7610 /**
7611 * Aggregate address MED matching incremental test: this function is called
7612 * when the initial aggregation occurred and we are only testing a single
7613 * new path.
7614 *
7615 * In addition to testing and setting the MED validity it also installs back
7616 * suppressed routes (if summary is configured).
7617 *
7618 * Must not be called in `bgp_aggregate_route`.
7619 */
7620 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7621 struct bgp *bgp, const struct prefix *p,
7622 afi_t afi, safi_t safi,
7623 struct bgp_path_info *pi)
7624 {
7625 /* MED matching disabled. */
7626 if (!aggregate->match_med)
7627 return;
7628
7629 /* Aggregation with different MED, recheck if we have got equal MEDs
7630 * now.
7631 */
7632 if (aggregate->med_mismatched &&
7633 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7634 aggregate->summary_only)
7635 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7636 true);
7637 else
7638 bgp_aggregate_med_match(aggregate, bgp, pi);
7639
7640 /* No mismatches, just quit. */
7641 if (!aggregate->med_mismatched)
7642 return;
7643
7644 /* Route summarization is disabled. */
7645 if (!aggregate->summary_only)
7646 return;
7647
7648 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7649 }
7650
7651 /* Update an aggregate as routes are added/removed from the BGP table */
7652 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7653 safi_t safi, struct bgp_aggregate *aggregate)
7654 {
7655 struct bgp_table *table;
7656 struct bgp_dest *top;
7657 struct bgp_dest *dest;
7658 uint8_t origin;
7659 struct aspath *aspath = NULL;
7660 struct community *community = NULL;
7661 struct ecommunity *ecommunity = NULL;
7662 struct lcommunity *lcommunity = NULL;
7663 struct bgp_path_info *pi;
7664 unsigned long match = 0;
7665 uint8_t atomic_aggregate = 0;
7666
7667 /* If the bgp instance is being deleted or self peer is deleted
7668 * then do not create aggregate route
7669 */
7670 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7671 || (bgp->peer_self == NULL))
7672 return;
7673
7674 /* Initialize and test routes for MED difference. */
7675 if (aggregate->match_med)
7676 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7677
7678 /*
7679 * Reset aggregate count: we might've been called from route map
7680 * update so in that case we must retest all more specific routes.
7681 *
7682 * \see `bgp_route_map_process_update`.
7683 */
7684 aggregate->count = 0;
7685 aggregate->incomplete_origin_count = 0;
7686 aggregate->incomplete_origin_count = 0;
7687 aggregate->egp_origin_count = 0;
7688
7689 /* ORIGIN attribute: If at least one route among routes that are
7690 aggregated has ORIGIN with the value INCOMPLETE, then the
7691 aggregated route must have the ORIGIN attribute with the value
7692 INCOMPLETE. Otherwise, if at least one route among routes that
7693 are aggregated has ORIGIN with the value EGP, then the aggregated
7694 route must have the origin attribute with the value EGP. In all
7695 other case the value of the ORIGIN attribute of the aggregated
7696 route is INTERNAL. */
7697 origin = BGP_ORIGIN_IGP;
7698
7699 table = bgp->rib[afi][safi];
7700
7701 top = bgp_node_get(table, p);
7702 for (dest = bgp_node_get(table, p); dest;
7703 dest = bgp_route_next_until(dest, top)) {
7704 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7705
7706 if (dest_p->prefixlen <= p->prefixlen)
7707 continue;
7708
7709 /* If suppress fib is enabled and route not installed
7710 * in FIB, skip the route
7711 */
7712 if (!bgp_check_advertise(bgp, dest))
7713 continue;
7714
7715 match = 0;
7716
7717 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7718 if (BGP_PATH_HOLDDOWN(pi))
7719 continue;
7720
7721 if (pi->attr->flag
7722 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7723 atomic_aggregate = 1;
7724
7725 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7726 continue;
7727
7728 /*
7729 * summary-only aggregate route suppress
7730 * aggregated route announcements.
7731 *
7732 * MED matching:
7733 * Don't create summaries if MED didn't match
7734 * otherwise neither the specific routes and the
7735 * aggregation will be announced.
7736 */
7737 if (aggregate->summary_only
7738 && AGGREGATE_MED_VALID(aggregate)) {
7739 if (aggr_suppress_path(aggregate, pi))
7740 match++;
7741 }
7742
7743 /*
7744 * Suppress more specific routes that match the route
7745 * map results.
7746 *
7747 * MED matching:
7748 * Don't suppress routes if MED matching is enabled and
7749 * it mismatched otherwise we might end up with no
7750 * routes for this path.
7751 */
7752 if (aggregate->suppress_map_name
7753 && AGGREGATE_MED_VALID(aggregate)
7754 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7755 if (aggr_suppress_path(aggregate, pi))
7756 match++;
7757 }
7758
7759 aggregate->count++;
7760
7761 /*
7762 * If at least one route among routes that are
7763 * aggregated has ORIGIN with the value INCOMPLETE,
7764 * then the aggregated route MUST have the ORIGIN
7765 * attribute with the value INCOMPLETE. Otherwise, if
7766 * at least one route among routes that are aggregated
7767 * has ORIGIN with the value EGP, then the aggregated
7768 * route MUST have the ORIGIN attribute with the value
7769 * EGP.
7770 */
7771 switch (pi->attr->origin) {
7772 case BGP_ORIGIN_INCOMPLETE:
7773 aggregate->incomplete_origin_count++;
7774 break;
7775 case BGP_ORIGIN_EGP:
7776 aggregate->egp_origin_count++;
7777 break;
7778 default:
7779 /*Do nothing.
7780 */
7781 break;
7782 }
7783
7784 if (!aggregate->as_set)
7785 continue;
7786
7787 /*
7788 * as-set aggregate route generate origin, as path,
7789 * and community aggregation.
7790 */
7791 /* Compute aggregate route's as-path.
7792 */
7793 bgp_compute_aggregate_aspath_hash(aggregate,
7794 pi->attr->aspath);
7795
7796 /* Compute aggregate route's community.
7797 */
7798 if (bgp_attr_get_community(pi->attr))
7799 bgp_compute_aggregate_community_hash(
7800 aggregate,
7801 bgp_attr_get_community(pi->attr));
7802
7803 /* Compute aggregate route's extended community.
7804 */
7805 if (bgp_attr_get_ecommunity(pi->attr))
7806 bgp_compute_aggregate_ecommunity_hash(
7807 aggregate,
7808 bgp_attr_get_ecommunity(pi->attr));
7809
7810 /* Compute aggregate route's large community.
7811 */
7812 if (bgp_attr_get_lcommunity(pi->attr))
7813 bgp_compute_aggregate_lcommunity_hash(
7814 aggregate,
7815 bgp_attr_get_lcommunity(pi->attr));
7816 }
7817 if (match)
7818 bgp_process(bgp, dest, afi, safi);
7819 }
7820 if (aggregate->as_set) {
7821 bgp_compute_aggregate_aspath_val(aggregate);
7822 bgp_compute_aggregate_community_val(aggregate);
7823 bgp_compute_aggregate_ecommunity_val(aggregate);
7824 bgp_compute_aggregate_lcommunity_val(aggregate);
7825 }
7826
7827
7828 bgp_dest_unlock_node(top);
7829
7830
7831 if (aggregate->incomplete_origin_count > 0)
7832 origin = BGP_ORIGIN_INCOMPLETE;
7833 else if (aggregate->egp_origin_count > 0)
7834 origin = BGP_ORIGIN_EGP;
7835
7836 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7837 origin = aggregate->origin;
7838
7839 if (aggregate->as_set) {
7840 if (aggregate->aspath)
7841 /* Retrieve aggregate route's as-path.
7842 */
7843 aspath = aspath_dup(aggregate->aspath);
7844
7845 if (aggregate->community)
7846 /* Retrieve aggregate route's community.
7847 */
7848 community = community_dup(aggregate->community);
7849
7850 if (aggregate->ecommunity)
7851 /* Retrieve aggregate route's ecommunity.
7852 */
7853 ecommunity = ecommunity_dup(aggregate->ecommunity);
7854
7855 if (aggregate->lcommunity)
7856 /* Retrieve aggregate route's lcommunity.
7857 */
7858 lcommunity = lcommunity_dup(aggregate->lcommunity);
7859 }
7860
7861 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7862 ecommunity, lcommunity, atomic_aggregate,
7863 aggregate);
7864 }
7865
7866 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7867 safi_t safi, struct bgp_aggregate *aggregate)
7868 {
7869 struct bgp_table *table;
7870 struct bgp_dest *top;
7871 struct bgp_dest *dest;
7872 struct bgp_path_info *pi;
7873 unsigned long match;
7874
7875 table = bgp->rib[afi][safi];
7876
7877 /* If routes exists below this node, generate aggregate routes. */
7878 top = bgp_node_get(table, p);
7879 for (dest = bgp_node_get(table, p); dest;
7880 dest = bgp_route_next_until(dest, top)) {
7881 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7882
7883 if (dest_p->prefixlen <= p->prefixlen)
7884 continue;
7885 match = 0;
7886
7887 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7888 if (BGP_PATH_HOLDDOWN(pi))
7889 continue;
7890
7891 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7892 continue;
7893
7894 /*
7895 * This route is suppressed: attempt to unsuppress it.
7896 *
7897 * `aggr_unsuppress_path` will fail if this particular
7898 * aggregate route was not the suppressor.
7899 */
7900 if (pi->extra && pi->extra->aggr_suppressors &&
7901 listcount(pi->extra->aggr_suppressors)) {
7902 if (aggr_unsuppress_path(aggregate, pi))
7903 match++;
7904 }
7905
7906 aggregate->count--;
7907
7908 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7909 aggregate->incomplete_origin_count--;
7910 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7911 aggregate->egp_origin_count--;
7912
7913 if (aggregate->as_set) {
7914 /* Remove as-path from aggregate.
7915 */
7916 bgp_remove_aspath_from_aggregate_hash(
7917 aggregate,
7918 pi->attr->aspath);
7919
7920 if (bgp_attr_get_community(pi->attr))
7921 /* Remove community from aggregate.
7922 */
7923 bgp_remove_comm_from_aggregate_hash(
7924 aggregate,
7925 bgp_attr_get_community(
7926 pi->attr));
7927
7928 if (bgp_attr_get_ecommunity(pi->attr))
7929 /* Remove ecommunity from aggregate.
7930 */
7931 bgp_remove_ecomm_from_aggregate_hash(
7932 aggregate,
7933 bgp_attr_get_ecommunity(
7934 pi->attr));
7935
7936 if (bgp_attr_get_lcommunity(pi->attr))
7937 /* Remove lcommunity from aggregate.
7938 */
7939 bgp_remove_lcomm_from_aggregate_hash(
7940 aggregate,
7941 bgp_attr_get_lcommunity(
7942 pi->attr));
7943 }
7944 }
7945
7946 /* If this node was suppressed, process the change. */
7947 if (match)
7948 bgp_process(bgp, dest, afi, safi);
7949 }
7950 if (aggregate->as_set) {
7951 aspath_free(aggregate->aspath);
7952 aggregate->aspath = NULL;
7953 if (aggregate->community)
7954 community_free(&aggregate->community);
7955 if (aggregate->ecommunity)
7956 ecommunity_free(&aggregate->ecommunity);
7957 if (aggregate->lcommunity)
7958 lcommunity_free(&aggregate->lcommunity);
7959 }
7960
7961 bgp_dest_unlock_node(top);
7962 }
7963
7964 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7965 const struct prefix *aggr_p,
7966 struct bgp_path_info *pinew, afi_t afi,
7967 safi_t safi,
7968 struct bgp_aggregate *aggregate)
7969 {
7970 uint8_t origin;
7971 struct aspath *aspath = NULL;
7972 uint8_t atomic_aggregate = 0;
7973 struct community *community = NULL;
7974 struct ecommunity *ecommunity = NULL;
7975 struct lcommunity *lcommunity = NULL;
7976
7977 /* If the bgp instance is being deleted or self peer is deleted
7978 * then do not create aggregate route
7979 */
7980 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7981 || (bgp->peer_self == NULL))
7982 return;
7983
7984 /* ORIGIN attribute: If at least one route among routes that are
7985 * aggregated has ORIGIN with the value INCOMPLETE, then the
7986 * aggregated route must have the ORIGIN attribute with the value
7987 * INCOMPLETE. Otherwise, if at least one route among routes that
7988 * are aggregated has ORIGIN with the value EGP, then the aggregated
7989 * route must have the origin attribute with the value EGP. In all
7990 * other case the value of the ORIGIN attribute of the aggregated
7991 * route is INTERNAL.
7992 */
7993 origin = BGP_ORIGIN_IGP;
7994
7995 aggregate->count++;
7996
7997 /*
7998 * This must be called before `summary` check to avoid
7999 * "suppressing" twice.
8000 */
8001 if (aggregate->match_med)
8002 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
8003 pinew);
8004
8005 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8006 aggr_suppress_path(aggregate, pinew);
8007
8008 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8009 && aggr_suppress_map_test(bgp, aggregate, pinew))
8010 aggr_suppress_path(aggregate, pinew);
8011
8012 switch (pinew->attr->origin) {
8013 case BGP_ORIGIN_INCOMPLETE:
8014 aggregate->incomplete_origin_count++;
8015 break;
8016 case BGP_ORIGIN_EGP:
8017 aggregate->egp_origin_count++;
8018 break;
8019 default:
8020 /* Do nothing.
8021 */
8022 break;
8023 }
8024
8025 if (aggregate->incomplete_origin_count > 0)
8026 origin = BGP_ORIGIN_INCOMPLETE;
8027 else if (aggregate->egp_origin_count > 0)
8028 origin = BGP_ORIGIN_EGP;
8029
8030 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8031 origin = aggregate->origin;
8032
8033 if (aggregate->as_set) {
8034 /* Compute aggregate route's as-path.
8035 */
8036 bgp_compute_aggregate_aspath(aggregate,
8037 pinew->attr->aspath);
8038
8039 /* Compute aggregate route's community.
8040 */
8041 if (bgp_attr_get_community(pinew->attr))
8042 bgp_compute_aggregate_community(
8043 aggregate, bgp_attr_get_community(pinew->attr));
8044
8045 /* Compute aggregate route's extended community.
8046 */
8047 if (bgp_attr_get_ecommunity(pinew->attr))
8048 bgp_compute_aggregate_ecommunity(
8049 aggregate,
8050 bgp_attr_get_ecommunity(pinew->attr));
8051
8052 /* Compute aggregate route's large community.
8053 */
8054 if (bgp_attr_get_lcommunity(pinew->attr))
8055 bgp_compute_aggregate_lcommunity(
8056 aggregate,
8057 bgp_attr_get_lcommunity(pinew->attr));
8058
8059 /* Retrieve aggregate route's as-path.
8060 */
8061 if (aggregate->aspath)
8062 aspath = aspath_dup(aggregate->aspath);
8063
8064 /* Retrieve aggregate route's community.
8065 */
8066 if (aggregate->community)
8067 community = community_dup(aggregate->community);
8068
8069 /* Retrieve aggregate route's ecommunity.
8070 */
8071 if (aggregate->ecommunity)
8072 ecommunity = ecommunity_dup(aggregate->ecommunity);
8073
8074 /* Retrieve aggregate route's lcommunity.
8075 */
8076 if (aggregate->lcommunity)
8077 lcommunity = lcommunity_dup(aggregate->lcommunity);
8078 }
8079
8080 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8081 aspath, community, ecommunity,
8082 lcommunity, atomic_aggregate, aggregate);
8083 }
8084
8085 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
8086 safi_t safi,
8087 struct bgp_path_info *pi,
8088 struct bgp_aggregate *aggregate,
8089 const struct prefix *aggr_p)
8090 {
8091 uint8_t origin;
8092 struct aspath *aspath = NULL;
8093 uint8_t atomic_aggregate = 0;
8094 struct community *community = NULL;
8095 struct ecommunity *ecommunity = NULL;
8096 struct lcommunity *lcommunity = NULL;
8097 unsigned long match = 0;
8098
8099 /* If the bgp instance is being deleted or self peer is deleted
8100 * then do not create aggregate route
8101 */
8102 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8103 || (bgp->peer_self == NULL))
8104 return;
8105
8106 if (BGP_PATH_HOLDDOWN(pi))
8107 return;
8108
8109 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
8110 return;
8111
8112 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8113 if (aggr_unsuppress_path(aggregate, pi))
8114 match++;
8115
8116 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8117 && aggr_suppress_map_test(bgp, aggregate, pi))
8118 if (aggr_unsuppress_path(aggregate, pi))
8119 match++;
8120
8121 /*
8122 * This must be called after `summary`, `suppress-map` check to avoid
8123 * "unsuppressing" twice.
8124 */
8125 if (aggregate->match_med)
8126 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
8127
8128 if (aggregate->count > 0)
8129 aggregate->count--;
8130
8131 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
8132 aggregate->incomplete_origin_count--;
8133 else if (pi->attr->origin == BGP_ORIGIN_EGP)
8134 aggregate->egp_origin_count--;
8135
8136 if (aggregate->as_set) {
8137 /* Remove as-path from aggregate.
8138 */
8139 bgp_remove_aspath_from_aggregate(aggregate,
8140 pi->attr->aspath);
8141
8142 if (bgp_attr_get_community(pi->attr))
8143 /* Remove community from aggregate.
8144 */
8145 bgp_remove_community_from_aggregate(
8146 aggregate, bgp_attr_get_community(pi->attr));
8147
8148 if (bgp_attr_get_ecommunity(pi->attr))
8149 /* Remove ecommunity from aggregate.
8150 */
8151 bgp_remove_ecommunity_from_aggregate(
8152 aggregate, bgp_attr_get_ecommunity(pi->attr));
8153
8154 if (bgp_attr_get_lcommunity(pi->attr))
8155 /* Remove lcommunity from aggregate.
8156 */
8157 bgp_remove_lcommunity_from_aggregate(
8158 aggregate, bgp_attr_get_lcommunity(pi->attr));
8159 }
8160
8161 /* If this node was suppressed, process the change. */
8162 if (match)
8163 bgp_process(bgp, pi->net, afi, safi);
8164
8165 origin = BGP_ORIGIN_IGP;
8166 if (aggregate->incomplete_origin_count > 0)
8167 origin = BGP_ORIGIN_INCOMPLETE;
8168 else if (aggregate->egp_origin_count > 0)
8169 origin = BGP_ORIGIN_EGP;
8170
8171 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8172 origin = aggregate->origin;
8173
8174 if (aggregate->as_set) {
8175 /* Retrieve aggregate route's as-path.
8176 */
8177 if (aggregate->aspath)
8178 aspath = aspath_dup(aggregate->aspath);
8179
8180 /* Retrieve aggregate route's community.
8181 */
8182 if (aggregate->community)
8183 community = community_dup(aggregate->community);
8184
8185 /* Retrieve aggregate route's ecommunity.
8186 */
8187 if (aggregate->ecommunity)
8188 ecommunity = ecommunity_dup(aggregate->ecommunity);
8189
8190 /* Retrieve aggregate route's lcommunity.
8191 */
8192 if (aggregate->lcommunity)
8193 lcommunity = lcommunity_dup(aggregate->lcommunity);
8194 }
8195
8196 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8197 aspath, community, ecommunity,
8198 lcommunity, atomic_aggregate, aggregate);
8199 }
8200
8201 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8202 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8203 {
8204 struct bgp_dest *child;
8205 struct bgp_dest *dest;
8206 struct bgp_aggregate *aggregate;
8207 struct bgp_table *table;
8208
8209 table = bgp->aggregate[afi][safi];
8210
8211 /* No aggregates configured. */
8212 if (bgp_table_top_nolock(table) == NULL)
8213 return;
8214
8215 if (p->prefixlen == 0)
8216 return;
8217
8218 if (BGP_PATH_HOLDDOWN(pi))
8219 return;
8220
8221 /* If suppress fib is enabled and route not installed
8222 * in FIB, do not update the aggregate route
8223 */
8224 if (!bgp_check_advertise(bgp, pi->net))
8225 return;
8226
8227 child = bgp_node_get(table, p);
8228
8229 /* Aggregate address configuration check. */
8230 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8231 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8232
8233 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8234 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8235 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8236 aggregate);
8237 }
8238 }
8239 bgp_dest_unlock_node(child);
8240 }
8241
8242 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8243 struct bgp_path_info *del, afi_t afi, safi_t safi)
8244 {
8245 struct bgp_dest *child;
8246 struct bgp_dest *dest;
8247 struct bgp_aggregate *aggregate;
8248 struct bgp_table *table;
8249
8250 table = bgp->aggregate[afi][safi];
8251
8252 /* No aggregates configured. */
8253 if (bgp_table_top_nolock(table) == NULL)
8254 return;
8255
8256 if (p->prefixlen == 0)
8257 return;
8258
8259 child = bgp_node_get(table, p);
8260
8261 /* Aggregate address configuration check. */
8262 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8263 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8264
8265 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8266 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8267 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8268 aggregate, dest_p);
8269 }
8270 }
8271 bgp_dest_unlock_node(child);
8272 }
8273
8274 /* Aggregate route attribute. */
8275 #define AGGREGATE_SUMMARY_ONLY 1
8276 #define AGGREGATE_AS_SET 1
8277 #define AGGREGATE_AS_UNSET 0
8278
8279 static const char *bgp_origin2str(uint8_t origin)
8280 {
8281 switch (origin) {
8282 case BGP_ORIGIN_IGP:
8283 return "igp";
8284 case BGP_ORIGIN_EGP:
8285 return "egp";
8286 case BGP_ORIGIN_INCOMPLETE:
8287 return "incomplete";
8288 }
8289 return "n/a";
8290 }
8291
8292 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8293 {
8294 switch (v_state) {
8295 case RPKI_NOT_BEING_USED:
8296 return "not used";
8297 case RPKI_VALID:
8298 return "valid";
8299 case RPKI_NOTFOUND:
8300 return "not found";
8301 case RPKI_INVALID:
8302 return "invalid";
8303 }
8304
8305 assert(!"We should never get here this is a dev escape");
8306 return "ERROR";
8307 }
8308
8309 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8310 afi_t afi, safi_t safi)
8311 {
8312 VTY_DECLVAR_CONTEXT(bgp, bgp);
8313 int ret;
8314 struct prefix p;
8315 struct bgp_dest *dest;
8316 struct bgp_aggregate *aggregate;
8317
8318 /* Convert string to prefix structure. */
8319 ret = str2prefix(prefix_str, &p);
8320 if (!ret) {
8321 vty_out(vty, "Malformed prefix\n");
8322 return CMD_WARNING_CONFIG_FAILED;
8323 }
8324 apply_mask(&p);
8325
8326 /* Old configuration check. */
8327 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8328 if (!dest) {
8329 vty_out(vty,
8330 "%% There is no aggregate-address configuration.\n");
8331 return CMD_WARNING_CONFIG_FAILED;
8332 }
8333
8334 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8335 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8336 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8337 NULL, NULL, 0, aggregate);
8338
8339 /* Unlock aggregate address configuration. */
8340 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8341
8342 if (aggregate->community)
8343 community_free(&aggregate->community);
8344
8345 if (aggregate->community_hash) {
8346 /* Delete all communities in the hash.
8347 */
8348 hash_clean(aggregate->community_hash,
8349 bgp_aggr_community_remove);
8350 /* Free up the community_hash.
8351 */
8352 hash_free(aggregate->community_hash);
8353 }
8354
8355 if (aggregate->ecommunity)
8356 ecommunity_free(&aggregate->ecommunity);
8357
8358 if (aggregate->ecommunity_hash) {
8359 /* Delete all ecommunities in the hash.
8360 */
8361 hash_clean(aggregate->ecommunity_hash,
8362 bgp_aggr_ecommunity_remove);
8363 /* Free up the ecommunity_hash.
8364 */
8365 hash_free(aggregate->ecommunity_hash);
8366 }
8367
8368 if (aggregate->lcommunity)
8369 lcommunity_free(&aggregate->lcommunity);
8370
8371 if (aggregate->lcommunity_hash) {
8372 /* Delete all lcommunities in the hash.
8373 */
8374 hash_clean(aggregate->lcommunity_hash,
8375 bgp_aggr_lcommunity_remove);
8376 /* Free up the lcommunity_hash.
8377 */
8378 hash_free(aggregate->lcommunity_hash);
8379 }
8380
8381 if (aggregate->aspath)
8382 aspath_free(aggregate->aspath);
8383
8384 if (aggregate->aspath_hash) {
8385 /* Delete all as-paths in the hash.
8386 */
8387 hash_clean(aggregate->aspath_hash,
8388 bgp_aggr_aspath_remove);
8389 /* Free up the aspath_hash.
8390 */
8391 hash_free(aggregate->aspath_hash);
8392 }
8393
8394 bgp_aggregate_free(aggregate);
8395 bgp_dest_unlock_node(dest);
8396 bgp_dest_unlock_node(dest);
8397
8398 return CMD_SUCCESS;
8399 }
8400
8401 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8402 safi_t safi, const char *rmap,
8403 uint8_t summary_only, uint8_t as_set,
8404 uint8_t origin, bool match_med,
8405 const char *suppress_map)
8406 {
8407 VTY_DECLVAR_CONTEXT(bgp, bgp);
8408 int ret;
8409 struct prefix p;
8410 struct bgp_dest *dest;
8411 struct bgp_aggregate *aggregate;
8412 uint8_t as_set_new = as_set;
8413
8414 if (suppress_map && summary_only) {
8415 vty_out(vty,
8416 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8417 return CMD_WARNING_CONFIG_FAILED;
8418 }
8419
8420 /* Convert string to prefix structure. */
8421 ret = str2prefix(prefix_str, &p);
8422 if (!ret) {
8423 vty_out(vty, "Malformed prefix\n");
8424 return CMD_WARNING_CONFIG_FAILED;
8425 }
8426 apply_mask(&p);
8427
8428 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8429 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8430 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8431 prefix_str);
8432 return CMD_WARNING_CONFIG_FAILED;
8433 }
8434
8435 /* Old configuration check. */
8436 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8437 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8438
8439 if (aggregate) {
8440 vty_out(vty, "There is already same aggregate network.\n");
8441 /* try to remove the old entry */
8442 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8443 if (ret) {
8444 vty_out(vty, "Error deleting aggregate.\n");
8445 bgp_dest_unlock_node(dest);
8446 return CMD_WARNING_CONFIG_FAILED;
8447 }
8448 }
8449
8450 /* Make aggregate address structure. */
8451 aggregate = bgp_aggregate_new();
8452 aggregate->summary_only = summary_only;
8453 aggregate->match_med = match_med;
8454
8455 /* Network operators MUST NOT locally generate any new
8456 * announcements containing AS_SET or AS_CONFED_SET. If they have
8457 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8458 * SHOULD withdraw those routes and re-announce routes for the
8459 * aggregate or component prefixes (i.e., the more-specific routes
8460 * subsumed by the previously aggregated route) without AS_SET
8461 * or AS_CONFED_SET in the updates.
8462 */
8463 if (bgp->reject_as_sets) {
8464 if (as_set == AGGREGATE_AS_SET) {
8465 as_set_new = AGGREGATE_AS_UNSET;
8466 zlog_warn(
8467 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8468 __func__);
8469 vty_out(vty,
8470 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8471 }
8472 }
8473
8474 aggregate->as_set = as_set_new;
8475 aggregate->safi = safi;
8476 /* Override ORIGIN attribute if defined.
8477 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8478 * to IGP which is not what rfc4271 says.
8479 * This enables the same behavior, optionally.
8480 */
8481 aggregate->origin = origin;
8482
8483 if (rmap) {
8484 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8485 route_map_counter_decrement(aggregate->rmap.map);
8486 aggregate->rmap.name =
8487 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8488 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8489 route_map_counter_increment(aggregate->rmap.map);
8490 }
8491
8492 if (suppress_map) {
8493 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8494 route_map_counter_decrement(aggregate->suppress_map);
8495
8496 aggregate->suppress_map_name =
8497 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8498 aggregate->suppress_map =
8499 route_map_lookup_by_name(aggregate->suppress_map_name);
8500 route_map_counter_increment(aggregate->suppress_map);
8501 }
8502
8503 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8504
8505 /* Aggregate address insert into BGP routing table. */
8506 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
8507
8508 return CMD_SUCCESS;
8509 }
8510
8511 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8512 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8513 "as-set$as_set_s"
8514 "|summary-only$summary_only"
8515 "|route-map RMAP_NAME$rmap_name"
8516 "|origin <egp|igp|incomplete>$origin_s"
8517 "|matching-MED-only$match_med"
8518 "|suppress-map RMAP_NAME$suppress_map"
8519 "}]",
8520 NO_STR
8521 "Configure BGP aggregate entries\n"
8522 "Aggregate prefix\n"
8523 "Aggregate address\n"
8524 "Aggregate mask\n"
8525 "Generate AS set path information\n"
8526 "Filter more specific routes from updates\n"
8527 "Apply route map to aggregate network\n"
8528 "Route map name\n"
8529 "BGP origin code\n"
8530 "Remote EGP\n"
8531 "Local IGP\n"
8532 "Unknown heritage\n"
8533 "Only aggregate routes with matching MED\n"
8534 "Suppress the selected more specific routes\n"
8535 "Route map with the route selectors\n")
8536 {
8537 const char *prefix_s = NULL;
8538 safi_t safi = bgp_node_safi(vty);
8539 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8540 int as_set = AGGREGATE_AS_UNSET;
8541 char prefix_buf[PREFIX2STR_BUFFER];
8542
8543 if (addr_str) {
8544 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8545 sizeof(prefix_buf))
8546 == 0) {
8547 vty_out(vty, "%% Inconsistent address and mask\n");
8548 return CMD_WARNING_CONFIG_FAILED;
8549 }
8550 prefix_s = prefix_buf;
8551 } else
8552 prefix_s = prefix_str;
8553
8554 if (origin_s) {
8555 if (strcmp(origin_s, "egp") == 0)
8556 origin = BGP_ORIGIN_EGP;
8557 else if (strcmp(origin_s, "igp") == 0)
8558 origin = BGP_ORIGIN_IGP;
8559 else if (strcmp(origin_s, "incomplete") == 0)
8560 origin = BGP_ORIGIN_INCOMPLETE;
8561 }
8562
8563 if (as_set_s)
8564 as_set = AGGREGATE_AS_SET;
8565
8566 /* Handle configuration removal, otherwise installation. */
8567 if (no)
8568 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8569
8570 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8571 summary_only != NULL, as_set, origin,
8572 match_med != NULL, suppress_map);
8573 }
8574
8575 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8576 "[no] aggregate-address X:X::X:X/M$prefix [{"
8577 "as-set$as_set_s"
8578 "|summary-only$summary_only"
8579 "|route-map RMAP_NAME$rmap_name"
8580 "|origin <egp|igp|incomplete>$origin_s"
8581 "|matching-MED-only$match_med"
8582 "|suppress-map RMAP_NAME$suppress_map"
8583 "}]",
8584 NO_STR
8585 "Configure BGP aggregate entries\n"
8586 "Aggregate prefix\n"
8587 "Generate AS set path information\n"
8588 "Filter more specific routes from updates\n"
8589 "Apply route map to aggregate network\n"
8590 "Route map name\n"
8591 "BGP origin code\n"
8592 "Remote EGP\n"
8593 "Local IGP\n"
8594 "Unknown heritage\n"
8595 "Only aggregate routes with matching MED\n"
8596 "Suppress the selected more specific routes\n"
8597 "Route map with the route selectors\n")
8598 {
8599 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8600 int as_set = AGGREGATE_AS_UNSET;
8601
8602 if (origin_s) {
8603 if (strcmp(origin_s, "egp") == 0)
8604 origin = BGP_ORIGIN_EGP;
8605 else if (strcmp(origin_s, "igp") == 0)
8606 origin = BGP_ORIGIN_IGP;
8607 else if (strcmp(origin_s, "incomplete") == 0)
8608 origin = BGP_ORIGIN_INCOMPLETE;
8609 }
8610
8611 if (as_set_s)
8612 as_set = AGGREGATE_AS_SET;
8613
8614 /* Handle configuration removal, otherwise installation. */
8615 if (no)
8616 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8617 SAFI_UNICAST);
8618
8619 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8620 rmap_name, summary_only != NULL, as_set,
8621 origin, match_med != NULL, suppress_map);
8622 }
8623
8624 /* Redistribute route treatment. */
8625 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8626 const union g_addr *nexthop, ifindex_t ifindex,
8627 enum nexthop_types_t nhtype, uint8_t distance,
8628 enum blackhole_type bhtype, uint32_t metric,
8629 uint8_t type, unsigned short instance,
8630 route_tag_t tag)
8631 {
8632 struct bgp_path_info *new;
8633 struct bgp_path_info *bpi;
8634 struct bgp_path_info rmap_path;
8635 struct bgp_dest *bn;
8636 struct attr attr;
8637 struct attr *new_attr;
8638 afi_t afi;
8639 route_map_result_t ret;
8640 struct bgp_redist *red;
8641
8642 /* Make default attribute. */
8643 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8644 /*
8645 * This must not be NULL to satisfy Coverity SA
8646 */
8647 assert(attr.aspath);
8648
8649 switch (nhtype) {
8650 case NEXTHOP_TYPE_IFINDEX:
8651 switch (p->family) {
8652 case AF_INET:
8653 attr.nexthop.s_addr = INADDR_ANY;
8654 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8655 break;
8656 case AF_INET6:
8657 memset(&attr.mp_nexthop_global, 0,
8658 sizeof(attr.mp_nexthop_global));
8659 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8660 break;
8661 }
8662 break;
8663 case NEXTHOP_TYPE_IPV4:
8664 case NEXTHOP_TYPE_IPV4_IFINDEX:
8665 attr.nexthop = nexthop->ipv4;
8666 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8667 break;
8668 case NEXTHOP_TYPE_IPV6:
8669 case NEXTHOP_TYPE_IPV6_IFINDEX:
8670 attr.mp_nexthop_global = nexthop->ipv6;
8671 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8672 break;
8673 case NEXTHOP_TYPE_BLACKHOLE:
8674 switch (p->family) {
8675 case AF_INET:
8676 attr.nexthop.s_addr = INADDR_ANY;
8677 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8678 break;
8679 case AF_INET6:
8680 memset(&attr.mp_nexthop_global, 0,
8681 sizeof(attr.mp_nexthop_global));
8682 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8683 break;
8684 }
8685 attr.bh_type = bhtype;
8686 break;
8687 }
8688 attr.nh_type = nhtype;
8689 attr.nh_ifindex = ifindex;
8690
8691 attr.med = metric;
8692 attr.distance = distance;
8693 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8694 attr.tag = tag;
8695
8696 if (metric)
8697 bgp_attr_set_aigp_metric(&attr, metric);
8698
8699 afi = family2afi(p->family);
8700
8701 red = bgp_redist_lookup(bgp, afi, type, instance);
8702 if (red) {
8703 struct attr attr_new;
8704
8705 /* Copy attribute for modification. */
8706 attr_new = attr;
8707
8708 if (red->redist_metric_flag) {
8709 attr_new.med = red->redist_metric;
8710 bgp_attr_set_aigp_metric(&attr_new, red->redist_metric);
8711 }
8712
8713 /* Apply route-map. */
8714 if (red->rmap.name) {
8715 memset(&rmap_path, 0, sizeof(rmap_path));
8716 rmap_path.peer = bgp->peer_self;
8717 rmap_path.attr = &attr_new;
8718
8719 SET_FLAG(bgp->peer_self->rmap_type,
8720 PEER_RMAP_TYPE_REDISTRIBUTE);
8721
8722 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8723
8724 bgp->peer_self->rmap_type = 0;
8725
8726 if (ret == RMAP_DENYMATCH) {
8727 /* Free uninterned attribute. */
8728 bgp_attr_flush(&attr_new);
8729
8730 /* Unintern original. */
8731 aspath_unintern(&attr.aspath);
8732 bgp_redistribute_delete(bgp, p, type, instance);
8733 return;
8734 }
8735 }
8736
8737 if (bgp_in_graceful_shutdown(bgp))
8738 bgp_attr_add_gshut_community(&attr_new);
8739
8740 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8741 SAFI_UNICAST, p, NULL);
8742
8743 new_attr = bgp_attr_intern(&attr_new);
8744
8745 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8746 if (bpi->peer == bgp->peer_self
8747 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8748 break;
8749
8750 if (bpi) {
8751 /* Ensure the (source route) type is updated. */
8752 bpi->type = type;
8753 if (attrhash_cmp(bpi->attr, new_attr)
8754 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8755 bgp_attr_unintern(&new_attr);
8756 aspath_unintern(&attr.aspath);
8757 bgp_dest_unlock_node(bn);
8758 return;
8759 } else {
8760 /* The attribute is changed. */
8761 bgp_path_info_set_flag(bn, bpi,
8762 BGP_PATH_ATTR_CHANGED);
8763
8764 /* Rewrite BGP route information. */
8765 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8766 bgp_path_info_restore(bn, bpi);
8767 else
8768 bgp_aggregate_decrement(
8769 bgp, p, bpi, afi, SAFI_UNICAST);
8770 bgp_attr_unintern(&bpi->attr);
8771 bpi->attr = new_attr;
8772 bpi->uptime = monotime(NULL);
8773
8774 /* Process change. */
8775 bgp_aggregate_increment(bgp, p, bpi, afi,
8776 SAFI_UNICAST);
8777 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8778 bgp_dest_unlock_node(bn);
8779 aspath_unintern(&attr.aspath);
8780
8781 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8782 || (bgp->inst_type
8783 == BGP_INSTANCE_TYPE_DEFAULT)) {
8784
8785 vpn_leak_from_vrf_update(
8786 bgp_get_default(), bgp, bpi);
8787 }
8788 return;
8789 }
8790 }
8791
8792 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8793 bgp->peer_self, new_attr, bn);
8794 SET_FLAG(new->flags, BGP_PATH_VALID);
8795
8796 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8797 bgp_path_info_add(bn, new);
8798 bgp_dest_unlock_node(bn);
8799 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8800 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8801
8802 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8803 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8804
8805 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8806 }
8807 }
8808
8809 /* Unintern original. */
8810 aspath_unintern(&attr.aspath);
8811 }
8812
8813 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8814 unsigned short instance)
8815 {
8816 afi_t afi;
8817 struct bgp_dest *dest;
8818 struct bgp_path_info *pi;
8819 struct bgp_redist *red;
8820
8821 afi = family2afi(p->family);
8822
8823 red = bgp_redist_lookup(bgp, afi, type, instance);
8824 if (red) {
8825 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8826 SAFI_UNICAST, p, NULL);
8827
8828 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8829 if (pi->peer == bgp->peer_self && pi->type == type)
8830 break;
8831
8832 if (pi) {
8833 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8834 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8835
8836 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8837 bgp, pi);
8838 }
8839 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8840 bgp_path_info_delete(dest, pi);
8841 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8842 }
8843 bgp_dest_unlock_node(dest);
8844 }
8845 }
8846
8847 /* Withdraw specified route type's route. */
8848 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8849 unsigned short instance)
8850 {
8851 struct bgp_dest *dest;
8852 struct bgp_path_info *pi;
8853 struct bgp_table *table;
8854
8855 table = bgp->rib[afi][SAFI_UNICAST];
8856
8857 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8858 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8859 if (pi->peer == bgp->peer_self && pi->type == type
8860 && pi->instance == instance)
8861 break;
8862
8863 if (pi) {
8864 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8865 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8866
8867 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8868 bgp, pi);
8869 }
8870 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8871 pi, afi, SAFI_UNICAST);
8872 bgp_path_info_delete(dest, pi);
8873 if (!CHECK_FLAG(bgp->flags,
8874 BGP_FLAG_DELETE_IN_PROGRESS))
8875 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8876 else
8877 bgp_path_info_reap(dest, pi);
8878 }
8879 }
8880 }
8881
8882 /* Static function to display route. */
8883 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8884 struct vty *vty, json_object *json, bool wide)
8885 {
8886 int len = 0;
8887 char buf[INET6_ADDRSTRLEN];
8888
8889 if (p->family == AF_INET) {
8890 if (!json) {
8891 len = vty_out(vty, "%pFX", p);
8892 } else {
8893 json_object_string_add(json, "prefix",
8894 inet_ntop(p->family,
8895 &p->u.prefix, buf,
8896 sizeof(buf)));
8897 json_object_int_add(json, "prefixLen", p->prefixlen);
8898 json_object_string_addf(json, "network", "%pFX", p);
8899 json_object_int_add(json, "version", dest->version);
8900 }
8901 } else if (p->family == AF_ETHERNET) {
8902 len = vty_out(vty, "%pFX", p);
8903 } else if (p->family == AF_EVPN) {
8904 if (!json)
8905 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8906 else
8907 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8908 } else if (p->family == AF_FLOWSPEC) {
8909 route_vty_out_flowspec(vty, p, NULL,
8910 json ?
8911 NLRI_STRING_FORMAT_JSON_SIMPLE :
8912 NLRI_STRING_FORMAT_MIN, json);
8913 } else {
8914 if (!json)
8915 len = vty_out(vty, "%pFX", p);
8916 else {
8917 json_object_string_add(json, "prefix",
8918 inet_ntop(p->family,
8919 &p->u.prefix, buf,
8920 sizeof(buf)));
8921 json_object_int_add(json, "prefixLen", p->prefixlen);
8922 json_object_string_addf(json, "network", "%pFX", p);
8923 json_object_int_add(json, "version", dest->version);
8924 }
8925 }
8926
8927 if (!json) {
8928 len = wide ? (45 - len) : (17 - len);
8929 if (len < 1)
8930 vty_out(vty, "\n%*s", 20, " ");
8931 else
8932 vty_out(vty, "%*s", len, " ");
8933 }
8934 }
8935
8936 enum bgp_display_type {
8937 normal_list,
8938 };
8939
8940 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8941 {
8942 switch (reason) {
8943 case bgp_path_selection_none:
8944 return "Nothing to Select";
8945 case bgp_path_selection_first:
8946 return "First path received";
8947 case bgp_path_selection_evpn_sticky_mac:
8948 return "EVPN Sticky Mac";
8949 case bgp_path_selection_evpn_seq:
8950 return "EVPN sequence number";
8951 case bgp_path_selection_evpn_lower_ip:
8952 return "EVPN lower IP";
8953 case bgp_path_selection_evpn_local_path:
8954 return "EVPN local ES path";
8955 case bgp_path_selection_evpn_non_proxy:
8956 return "EVPN non proxy";
8957 case bgp_path_selection_weight:
8958 return "Weight";
8959 case bgp_path_selection_local_pref:
8960 return "Local Pref";
8961 case bgp_path_selection_accept_own:
8962 return "Accept Own";
8963 case bgp_path_selection_local_route:
8964 return "Local Route";
8965 case bgp_path_selection_aigp:
8966 return "AIGP";
8967 case bgp_path_selection_confed_as_path:
8968 return "Confederation based AS Path";
8969 case bgp_path_selection_as_path:
8970 return "AS Path";
8971 case bgp_path_selection_origin:
8972 return "Origin";
8973 case bgp_path_selection_med:
8974 return "MED";
8975 case bgp_path_selection_peer:
8976 return "Peer Type";
8977 case bgp_path_selection_confed:
8978 return "Confed Peer Type";
8979 case bgp_path_selection_igp_metric:
8980 return "IGP Metric";
8981 case bgp_path_selection_older:
8982 return "Older Path";
8983 case bgp_path_selection_router_id:
8984 return "Router ID";
8985 case bgp_path_selection_cluster_length:
8986 return "Cluster length";
8987 case bgp_path_selection_stale:
8988 return "Path Staleness";
8989 case bgp_path_selection_local_configured:
8990 return "Locally configured route";
8991 case bgp_path_selection_neighbor_ip:
8992 return "Neighbor IP";
8993 case bgp_path_selection_default:
8994 return "Nothing left to compare";
8995 }
8996 return "Invalid (internal error)";
8997 }
8998
8999 /* Print the short form route status for a bgp_path_info */
9000 static void route_vty_short_status_out(struct vty *vty,
9001 struct bgp_path_info *path,
9002 const struct prefix *p,
9003 json_object *json_path)
9004 {
9005 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
9006
9007 if (json_path) {
9008
9009 /* Route status display. */
9010 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9011 json_object_boolean_true_add(json_path, "removed");
9012
9013 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9014 json_object_boolean_true_add(json_path, "stale");
9015
9016 if (path->extra && bgp_path_suppressed(path))
9017 json_object_boolean_true_add(json_path, "suppressed");
9018
9019 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9020 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9021 json_object_boolean_true_add(json_path, "valid");
9022
9023 /* Selected */
9024 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9025 json_object_boolean_true_add(json_path, "history");
9026
9027 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9028 json_object_boolean_true_add(json_path, "damped");
9029
9030 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9031 json_object_boolean_true_add(json_path, "bestpath");
9032 json_object_string_add(json_path, "selectionReason",
9033 bgp_path_selection_reason2str(
9034 path->net->reason));
9035 }
9036
9037 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9038 json_object_boolean_true_add(json_path, "multipath");
9039
9040 /* Internal route. */
9041 if ((path->peer->as)
9042 && (path->peer->as == path->peer->local_as))
9043 json_object_string_add(json_path, "pathFrom",
9044 "internal");
9045 else
9046 json_object_string_add(json_path, "pathFrom",
9047 "external");
9048
9049 return;
9050 }
9051
9052 /* RPKI validation state */
9053 rpki_state =
9054 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9055
9056 if (rpki_state == RPKI_VALID)
9057 vty_out(vty, "V");
9058 else if (rpki_state == RPKI_INVALID)
9059 vty_out(vty, "I");
9060 else if (rpki_state == RPKI_NOTFOUND)
9061 vty_out(vty, "N");
9062 else
9063 vty_out(vty, " ");
9064
9065 /* Route status display. */
9066 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9067 vty_out(vty, "R");
9068 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9069 vty_out(vty, "S");
9070 else if (bgp_path_suppressed(path))
9071 vty_out(vty, "s");
9072 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9073 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9074 vty_out(vty, "*");
9075 else
9076 vty_out(vty, " ");
9077
9078 /* Selected */
9079 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9080 vty_out(vty, "h");
9081 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9082 vty_out(vty, "d");
9083 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9084 vty_out(vty, ">");
9085 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9086 vty_out(vty, "=");
9087 else
9088 vty_out(vty, " ");
9089
9090 /* Internal route. */
9091 if (path->peer && (path->peer->as)
9092 && (path->peer->as == path->peer->local_as))
9093 vty_out(vty, "i");
9094 else
9095 vty_out(vty, " ");
9096 }
9097
9098 static char *bgp_nexthop_hostname(struct peer *peer,
9099 struct bgp_nexthop_cache *bnc)
9100 {
9101 if (peer->hostname
9102 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9103 return peer->hostname;
9104 return NULL;
9105 }
9106
9107 /* called from terminal list command */
9108 void route_vty_out(struct vty *vty, const struct prefix *p,
9109 struct bgp_path_info *path, int display, safi_t safi,
9110 json_object *json_paths, bool wide)
9111 {
9112 int len;
9113 struct attr *attr = path->attr;
9114 json_object *json_path = NULL;
9115 json_object *json_nexthops = NULL;
9116 json_object *json_nexthop_global = NULL;
9117 json_object *json_nexthop_ll = NULL;
9118 json_object *json_ext_community = NULL;
9119 char vrf_id_str[VRF_NAMSIZ] = {0};
9120 bool nexthop_self =
9121 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9122 bool nexthop_othervrf = false;
9123 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9124 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9125 char *nexthop_hostname =
9126 bgp_nexthop_hostname(path->peer, path->nexthop);
9127 char esi_buf[ESI_STR_LEN];
9128
9129 if (json_paths)
9130 json_path = json_object_new_object();
9131
9132 /* short status lead text */
9133 route_vty_short_status_out(vty, path, p, json_path);
9134
9135 if (!json_paths) {
9136 /* print prefix and mask */
9137 if (!display)
9138 route_vty_out_route(path->net, p, vty, json_path, wide);
9139 else
9140 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9141 } else {
9142 route_vty_out_route(path->net, p, vty, json_path, wide);
9143 }
9144
9145 /*
9146 * If vrf id of nexthop is different from that of prefix,
9147 * set up printable string to append
9148 */
9149 if (path->extra && path->extra->bgp_orig) {
9150 const char *self = "";
9151
9152 if (nexthop_self)
9153 self = "<";
9154
9155 nexthop_othervrf = true;
9156 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9157
9158 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9159 snprintf(vrf_id_str, sizeof(vrf_id_str),
9160 "@%s%s", VRFID_NONE_STR, self);
9161 else
9162 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9163 path->extra->bgp_orig->vrf_id, self);
9164
9165 if (path->extra->bgp_orig->inst_type
9166 != BGP_INSTANCE_TYPE_DEFAULT)
9167
9168 nexthop_vrfname = path->extra->bgp_orig->name;
9169 } else {
9170 const char *self = "";
9171
9172 if (nexthop_self)
9173 self = "<";
9174
9175 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9176 }
9177
9178 /*
9179 * For ENCAP and EVPN routes, nexthop address family is not
9180 * neccessarily the same as the prefix address family.
9181 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9182 * EVPN routes are also exchanged with a MP nexthop. Currently,
9183 * this
9184 * is only IPv4, the value will be present in either
9185 * attr->nexthop or
9186 * attr->mp_nexthop_global_in
9187 */
9188 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9189 char nexthop[128];
9190 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9191
9192 switch (af) {
9193 case AF_INET:
9194 snprintfrr(nexthop, sizeof(nexthop), "%pI4",
9195 &attr->mp_nexthop_global_in);
9196 break;
9197 case AF_INET6:
9198 snprintfrr(nexthop, sizeof(nexthop), "%pI6",
9199 &attr->mp_nexthop_global);
9200 break;
9201 default:
9202 snprintf(nexthop, sizeof(nexthop), "?");
9203 break;
9204 }
9205
9206 if (json_paths) {
9207 json_nexthop_global = json_object_new_object();
9208
9209 json_object_string_add(json_nexthop_global, "ip",
9210 nexthop);
9211
9212 if (path->peer->hostname)
9213 json_object_string_add(json_nexthop_global,
9214 "hostname",
9215 path->peer->hostname);
9216
9217 json_object_string_add(json_nexthop_global, "afi",
9218 (af == AF_INET) ? "ipv4"
9219 : "ipv6");
9220 json_object_boolean_true_add(json_nexthop_global,
9221 "used");
9222 } else {
9223 if (nexthop_hostname)
9224 len = vty_out(vty, "%s(%s)%s", nexthop,
9225 nexthop_hostname, vrf_id_str);
9226 else
9227 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9228
9229 len = wide ? (41 - len) : (16 - len);
9230 if (len < 1)
9231 vty_out(vty, "\n%*s", 36, " ");
9232 else
9233 vty_out(vty, "%*s", len, " ");
9234 }
9235 } else if (safi == SAFI_EVPN) {
9236 if (json_paths) {
9237 json_nexthop_global = json_object_new_object();
9238
9239 json_object_string_addf(json_nexthop_global, "ip",
9240 "%pI4",
9241 &attr->mp_nexthop_global_in);
9242
9243 if (path->peer->hostname)
9244 json_object_string_add(json_nexthop_global,
9245 "hostname",
9246 path->peer->hostname);
9247
9248 json_object_string_add(json_nexthop_global, "afi",
9249 "ipv4");
9250 json_object_boolean_true_add(json_nexthop_global,
9251 "used");
9252 } else {
9253 if (nexthop_hostname)
9254 len = vty_out(vty, "%pI4(%s)%s",
9255 &attr->mp_nexthop_global_in,
9256 nexthop_hostname, vrf_id_str);
9257 else
9258 len = vty_out(vty, "%pI4%s",
9259 &attr->mp_nexthop_global_in,
9260 vrf_id_str);
9261
9262 len = wide ? (41 - len) : (16 - len);
9263 if (len < 1)
9264 vty_out(vty, "\n%*s", 36, " ");
9265 else
9266 vty_out(vty, "%*s", len, " ");
9267 }
9268 } else if (safi == SAFI_FLOWSPEC) {
9269 if (attr->nexthop.s_addr != INADDR_ANY) {
9270 if (json_paths) {
9271 json_nexthop_global = json_object_new_object();
9272
9273 json_object_string_add(json_nexthop_global,
9274 "afi", "ipv4");
9275 json_object_string_addf(json_nexthop_global,
9276 "ip", "%pI4",
9277 &attr->nexthop);
9278
9279 if (path->peer->hostname)
9280 json_object_string_add(
9281 json_nexthop_global, "hostname",
9282 path->peer->hostname);
9283
9284 json_object_boolean_true_add(
9285 json_nexthop_global,
9286 "used");
9287 } else {
9288 if (nexthop_hostname)
9289 len = vty_out(vty, "%pI4(%s)%s",
9290 &attr->nexthop,
9291 nexthop_hostname,
9292 vrf_id_str);
9293 else
9294 len = vty_out(vty, "%pI4%s",
9295 &attr->nexthop,
9296 vrf_id_str);
9297
9298 len = wide ? (41 - len) : (16 - len);
9299 if (len < 1)
9300 vty_out(vty, "\n%*s", 36, " ");
9301 else
9302 vty_out(vty, "%*s", len, " ");
9303 }
9304 }
9305 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9306 if (json_paths) {
9307 json_nexthop_global = json_object_new_object();
9308
9309 json_object_string_addf(json_nexthop_global, "ip",
9310 "%pI4", &attr->nexthop);
9311
9312 if (path->peer->hostname)
9313 json_object_string_add(json_nexthop_global,
9314 "hostname",
9315 path->peer->hostname);
9316
9317 json_object_string_add(json_nexthop_global, "afi",
9318 "ipv4");
9319 json_object_boolean_true_add(json_nexthop_global,
9320 "used");
9321 } else {
9322 if (nexthop_hostname)
9323 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9324 nexthop_hostname, vrf_id_str);
9325 else
9326 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9327 vrf_id_str);
9328
9329 len = wide ? (41 - len) : (16 - len);
9330 if (len < 1)
9331 vty_out(vty, "\n%*s", 36, " ");
9332 else
9333 vty_out(vty, "%*s", len, " ");
9334 }
9335 }
9336
9337 /* IPv6 Next Hop */
9338 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9339 if (json_paths) {
9340 json_nexthop_global = json_object_new_object();
9341 json_object_string_addf(json_nexthop_global, "ip",
9342 "%pI6",
9343 &attr->mp_nexthop_global);
9344
9345 if (path->peer->hostname)
9346 json_object_string_add(json_nexthop_global,
9347 "hostname",
9348 path->peer->hostname);
9349
9350 json_object_string_add(json_nexthop_global, "afi",
9351 "ipv6");
9352 json_object_string_add(json_nexthop_global, "scope",
9353 "global");
9354
9355 /* We display both LL & GL if both have been
9356 * received */
9357 if ((attr->mp_nexthop_len
9358 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9359 || (path->peer->conf_if)) {
9360 json_nexthop_ll = json_object_new_object();
9361 json_object_string_addf(
9362 json_nexthop_ll, "ip", "%pI6",
9363 &attr->mp_nexthop_local);
9364
9365 if (path->peer->hostname)
9366 json_object_string_add(
9367 json_nexthop_ll, "hostname",
9368 path->peer->hostname);
9369
9370 json_object_string_add(json_nexthop_ll, "afi",
9371 "ipv6");
9372 json_object_string_add(json_nexthop_ll, "scope",
9373 "link-local");
9374
9375 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9376 &attr->mp_nexthop_local)
9377 != 0)
9378 && !attr->mp_nexthop_prefer_global)
9379 json_object_boolean_true_add(
9380 json_nexthop_ll, "used");
9381 else
9382 json_object_boolean_true_add(
9383 json_nexthop_global, "used");
9384 } else
9385 json_object_boolean_true_add(
9386 json_nexthop_global, "used");
9387 } else {
9388 /* Display LL if LL/Global both in table unless
9389 * prefer-global is set */
9390 if (((attr->mp_nexthop_len
9391 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9392 && !attr->mp_nexthop_prefer_global)
9393 || (path->peer->conf_if)) {
9394 if (path->peer->conf_if) {
9395 len = vty_out(vty, "%s",
9396 path->peer->conf_if);
9397 /* len of IPv6 addr + max len of def
9398 * ifname */
9399 len = wide ? (41 - len) : (16 - len);
9400
9401 if (len < 1)
9402 vty_out(vty, "\n%*s", 36, " ");
9403 else
9404 vty_out(vty, "%*s", len, " ");
9405 } else {
9406 if (nexthop_hostname)
9407 len = vty_out(
9408 vty, "%pI6(%s)%s",
9409 &attr->mp_nexthop_local,
9410 nexthop_hostname,
9411 vrf_id_str);
9412 else
9413 len = vty_out(
9414 vty, "%pI6%s",
9415 &attr->mp_nexthop_local,
9416 vrf_id_str);
9417
9418 len = wide ? (41 - len) : (16 - len);
9419
9420 if (len < 1)
9421 vty_out(vty, "\n%*s", 36, " ");
9422 else
9423 vty_out(vty, "%*s", len, " ");
9424 }
9425 } else {
9426 if (nexthop_hostname)
9427 len = vty_out(vty, "%pI6(%s)%s",
9428 &attr->mp_nexthop_global,
9429 nexthop_hostname,
9430 vrf_id_str);
9431 else
9432 len = vty_out(vty, "%pI6%s",
9433 &attr->mp_nexthop_global,
9434 vrf_id_str);
9435
9436 len = wide ? (41 - len) : (16 - len);
9437
9438 if (len < 1)
9439 vty_out(vty, "\n%*s", 36, " ");
9440 else
9441 vty_out(vty, "%*s", len, " ");
9442 }
9443 }
9444 }
9445
9446 /* MED/Metric */
9447 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9448 if (json_paths)
9449 json_object_int_add(json_path, "metric", attr->med);
9450 else if (wide)
9451 vty_out(vty, "%7u", attr->med);
9452 else
9453 vty_out(vty, "%10u", attr->med);
9454 else if (!json_paths) {
9455 if (wide)
9456 vty_out(vty, "%*s", 7, " ");
9457 else
9458 vty_out(vty, "%*s", 10, " ");
9459 }
9460
9461 /* Local Pref */
9462 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9463 if (json_paths)
9464 json_object_int_add(json_path, "locPrf",
9465 attr->local_pref);
9466 else
9467 vty_out(vty, "%7u", attr->local_pref);
9468 else if (!json_paths)
9469 vty_out(vty, " ");
9470
9471 if (json_paths)
9472 json_object_int_add(json_path, "weight", attr->weight);
9473 else
9474 vty_out(vty, "%7u ", attr->weight);
9475
9476 if (json_paths)
9477 json_object_string_addf(json_path, "peerId", "%pSU",
9478 &path->peer->su);
9479
9480 /* Print aspath */
9481 if (attr->aspath) {
9482 if (json_paths)
9483 json_object_string_add(json_path, "path",
9484 attr->aspath->str);
9485 else
9486 aspath_print_vty(vty, "%s", attr->aspath, " ");
9487 }
9488
9489 /* Print origin */
9490 if (json_paths)
9491 json_object_string_add(json_path, "origin",
9492 bgp_origin_long_str[attr->origin]);
9493 else
9494 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9495
9496 if (json_paths) {
9497 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9498 json_object_string_add(json_path, "esi",
9499 esi_to_str(&attr->esi,
9500 esi_buf, sizeof(esi_buf)));
9501 }
9502 if (safi == SAFI_EVPN &&
9503 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9504 json_ext_community = json_object_new_object();
9505 json_object_string_add(
9506 json_ext_community, "string",
9507 bgp_attr_get_ecommunity(attr)->str);
9508 json_object_object_add(json_path,
9509 "extendedCommunity",
9510 json_ext_community);
9511 }
9512
9513 if (nexthop_self)
9514 json_object_boolean_true_add(json_path,
9515 "announceNexthopSelf");
9516 if (nexthop_othervrf) {
9517 json_object_string_add(json_path, "nhVrfName",
9518 nexthop_vrfname);
9519
9520 json_object_int_add(json_path, "nhVrfId",
9521 ((nexthop_vrfid == VRF_UNKNOWN)
9522 ? -1
9523 : (int)nexthop_vrfid));
9524 }
9525 }
9526
9527 if (json_paths) {
9528 if (json_nexthop_global || json_nexthop_ll) {
9529 json_nexthops = json_object_new_array();
9530
9531 if (json_nexthop_global)
9532 json_object_array_add(json_nexthops,
9533 json_nexthop_global);
9534
9535 if (json_nexthop_ll)
9536 json_object_array_add(json_nexthops,
9537 json_nexthop_ll);
9538
9539 json_object_object_add(json_path, "nexthops",
9540 json_nexthops);
9541 }
9542
9543 json_object_array_add(json_paths, json_path);
9544 } else {
9545 vty_out(vty, "\n");
9546
9547 if (safi == SAFI_EVPN) {
9548 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9549 /* XXX - add these params to the json out */
9550 vty_out(vty, "%*s", 20, " ");
9551 vty_out(vty, "ESI:%s",
9552 esi_to_str(&attr->esi, esi_buf,
9553 sizeof(esi_buf)));
9554
9555 vty_out(vty, "\n");
9556 }
9557 if (attr->flag &
9558 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9559 vty_out(vty, "%*s", 20, " ");
9560 vty_out(vty, "%s\n",
9561 bgp_attr_get_ecommunity(attr)->str);
9562 }
9563 }
9564
9565 #ifdef ENABLE_BGP_VNC
9566 /* prints an additional line, indented, with VNC info, if
9567 * present */
9568 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9569 rfapi_vty_out_vncinfo(vty, p, path, safi);
9570 #endif
9571 }
9572 }
9573
9574 /* called from terminal list command */
9575 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9576 const struct prefix *p, struct attr *attr, safi_t safi,
9577 bool use_json, json_object *json_ar, bool wide)
9578 {
9579 json_object *json_status = NULL;
9580 json_object *json_net = NULL;
9581 int len;
9582 char buff[BUFSIZ];
9583
9584 /* Route status display. */
9585 if (use_json) {
9586 json_status = json_object_new_object();
9587 json_net = json_object_new_object();
9588 } else {
9589 vty_out(vty, " *");
9590 vty_out(vty, ">");
9591 vty_out(vty, " ");
9592 }
9593
9594 /* print prefix and mask */
9595 if (use_json) {
9596 if (safi == SAFI_EVPN)
9597 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9598 else if (p->family == AF_INET || p->family == AF_INET6) {
9599 json_object_string_add(
9600 json_net, "addrPrefix",
9601 inet_ntop(p->family, &p->u.prefix, buff,
9602 BUFSIZ));
9603 json_object_int_add(json_net, "prefixLen",
9604 p->prefixlen);
9605 json_object_string_addf(json_net, "network", "%pFX", p);
9606 }
9607 } else
9608 route_vty_out_route(dest, p, vty, NULL, wide);
9609
9610 /* Print attribute */
9611 if (attr) {
9612 if (use_json) {
9613 if (p->family == AF_INET &&
9614 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9615 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9616 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9617 json_object_string_addf(
9618 json_net, "nextHop", "%pI4",
9619 &attr->mp_nexthop_global_in);
9620 else
9621 json_object_string_addf(
9622 json_net, "nextHop", "%pI4",
9623 &attr->nexthop);
9624 } else if (p->family == AF_INET6 ||
9625 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9626 json_object_string_addf(
9627 json_net, "nextHopGlobal", "%pI6",
9628 &attr->mp_nexthop_global);
9629 } else if (p->family == AF_EVPN &&
9630 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9631 json_object_string_addf(
9632 json_net, "nextHop", "%pI4",
9633 &attr->mp_nexthop_global_in);
9634 }
9635
9636 if (attr->flag
9637 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9638 json_object_int_add(json_net, "metric",
9639 attr->med);
9640
9641 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9642 json_object_int_add(json_net, "locPrf",
9643 attr->local_pref);
9644
9645 json_object_int_add(json_net, "weight", attr->weight);
9646
9647 /* Print aspath */
9648 if (attr->aspath)
9649 json_object_string_add(json_net, "path",
9650 attr->aspath->str);
9651
9652 /* Print origin */
9653 #if CONFDATE > 20231208
9654 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
9655 #endif
9656 json_object_string_add(json_net, "bgpOriginCode",
9657 bgp_origin_str[attr->origin]);
9658 json_object_string_add(
9659 json_net, "origin",
9660 bgp_origin_long_str[attr->origin]);
9661 } else {
9662 if (p->family == AF_INET &&
9663 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9664 safi == SAFI_EVPN ||
9665 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9666 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9667 || safi == SAFI_EVPN)
9668 vty_out(vty, "%-16pI4",
9669 &attr->mp_nexthop_global_in);
9670 else if (wide)
9671 vty_out(vty, "%-41pI4", &attr->nexthop);
9672 else
9673 vty_out(vty, "%-16pI4", &attr->nexthop);
9674 } else if (p->family == AF_INET6 ||
9675 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9676 len = vty_out(vty, "%pI6",
9677 &attr->mp_nexthop_global);
9678 len = wide ? (41 - len) : (16 - len);
9679 if (len < 1)
9680 vty_out(vty, "\n%*s", 36, " ");
9681 else
9682 vty_out(vty, "%*s", len, " ");
9683 }
9684 if (attr->flag
9685 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9686 if (wide)
9687 vty_out(vty, "%7u", attr->med);
9688 else
9689 vty_out(vty, "%10u", attr->med);
9690 else if (wide)
9691 vty_out(vty, " ");
9692 else
9693 vty_out(vty, " ");
9694
9695 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9696 vty_out(vty, "%7u", attr->local_pref);
9697 else
9698 vty_out(vty, " ");
9699
9700 vty_out(vty, "%7u ", attr->weight);
9701
9702 /* Print aspath */
9703 if (attr->aspath)
9704 aspath_print_vty(vty, "%s", attr->aspath, " ");
9705
9706 /* Print origin */
9707 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9708 }
9709 }
9710 if (use_json) {
9711 struct bgp_path_info *bpi = bgp_dest_get_bgp_path_info(dest);
9712
9713 #if CONFDATE > 20231208
9714 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
9715 #endif
9716 json_object_boolean_true_add(json_status, "*");
9717 json_object_boolean_true_add(json_status, ">");
9718 json_object_boolean_true_add(json_net, "valid");
9719 json_object_boolean_true_add(json_net, "best");
9720
9721 if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_MULTIPATH)) {
9722 json_object_boolean_true_add(json_status, "=");
9723 json_object_boolean_true_add(json_net, "multipath");
9724 }
9725 json_object_object_add(json_net, "appliedStatusSymbols",
9726 json_status);
9727 json_object_object_addf(json_ar, json_net, "%pFX", p);
9728 } else
9729 vty_out(vty, "\n");
9730 }
9731
9732 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9733 struct bgp_path_info *path, int display, safi_t safi,
9734 json_object *json)
9735 {
9736 json_object *json_out = NULL;
9737 struct attr *attr;
9738 mpls_label_t label = MPLS_INVALID_LABEL;
9739
9740 if (!path->extra)
9741 return;
9742
9743 if (json)
9744 json_out = json_object_new_object();
9745
9746 /* short status lead text */
9747 route_vty_short_status_out(vty, path, p, json_out);
9748
9749 /* print prefix and mask */
9750 if (json == NULL) {
9751 if (!display)
9752 route_vty_out_route(path->net, p, vty, NULL, false);
9753 else
9754 vty_out(vty, "%*s", 17, " ");
9755 }
9756
9757 /* Print attribute */
9758 attr = path->attr;
9759 if (((p->family == AF_INET) &&
9760 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9761 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9762 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9763 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9764 || safi == SAFI_EVPN) {
9765 if (json)
9766 json_object_string_addf(
9767 json_out, "mpNexthopGlobalIn", "%pI4",
9768 &attr->mp_nexthop_global_in);
9769 else
9770 vty_out(vty, "%-16pI4",
9771 &attr->mp_nexthop_global_in);
9772 } else {
9773 if (json)
9774 json_object_string_addf(json_out, "nexthop",
9775 "%pI4", &attr->nexthop);
9776 else
9777 vty_out(vty, "%-16pI4", &attr->nexthop);
9778 }
9779 } else if (((p->family == AF_INET6) &&
9780 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9781 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9782 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9783 char buf_a[512];
9784
9785 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9786 if (json)
9787 json_object_string_addf(
9788 json_out, "mpNexthopGlobalIn", "%pI6",
9789 &attr->mp_nexthop_global);
9790 else
9791 vty_out(vty, "%s",
9792 inet_ntop(AF_INET6,
9793 &attr->mp_nexthop_global,
9794 buf_a, sizeof(buf_a)));
9795 } else if (attr->mp_nexthop_len
9796 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9797 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9798 &attr->mp_nexthop_global,
9799 &attr->mp_nexthop_local);
9800 if (json)
9801 json_object_string_add(json_out,
9802 "mpNexthopGlobalLocal",
9803 buf_a);
9804 else
9805 vty_out(vty, "%s", buf_a);
9806 }
9807 }
9808
9809 label = decode_label(&path->extra->label[0]);
9810
9811 if (bgp_is_valid_label(&label)) {
9812 if (json) {
9813 json_object_int_add(json_out, "notag", label);
9814 json_object_array_add(json, json_out);
9815 } else {
9816 vty_out(vty, "notag/%d", label);
9817 vty_out(vty, "\n");
9818 }
9819 } else if (!json)
9820 vty_out(vty, "\n");
9821 }
9822
9823 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9824 struct bgp_path_info *path, int display,
9825 json_object *json_paths)
9826 {
9827 struct attr *attr;
9828 json_object *json_path = NULL;
9829 json_object *json_nexthop = NULL;
9830 json_object *json_overlay = NULL;
9831
9832 if (!path->extra)
9833 return;
9834
9835 if (json_paths) {
9836 json_path = json_object_new_object();
9837 json_overlay = json_object_new_object();
9838 json_nexthop = json_object_new_object();
9839 }
9840
9841 /* short status lead text */
9842 route_vty_short_status_out(vty, path, p, json_path);
9843
9844 /* print prefix and mask */
9845 if (!display)
9846 route_vty_out_route(path->net, p, vty, json_path, false);
9847 else
9848 vty_out(vty, "%*s", 17, " ");
9849
9850 /* Print attribute */
9851 attr = path->attr;
9852 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9853
9854 switch (af) {
9855 case AF_INET:
9856 if (!json_path) {
9857 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9858 } else {
9859 json_object_string_addf(json_nexthop, "ip", "%pI4",
9860 &attr->mp_nexthop_global_in);
9861
9862 json_object_string_add(json_nexthop, "afi", "ipv4");
9863
9864 json_object_object_add(json_path, "nexthop",
9865 json_nexthop);
9866 }
9867 break;
9868 case AF_INET6:
9869 if (!json_path) {
9870 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9871 &attr->mp_nexthop_local);
9872 } else {
9873 json_object_string_addf(json_nexthop, "ipv6Global",
9874 "%pI6",
9875 &attr->mp_nexthop_global);
9876
9877 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9878 "%pI6",
9879 &attr->mp_nexthop_local);
9880
9881 json_object_string_add(json_nexthop, "afi", "ipv6");
9882
9883 json_object_object_add(json_path, "nexthop",
9884 json_nexthop);
9885 }
9886 break;
9887 default:
9888 if (!json_path) {
9889 vty_out(vty, "?");
9890 } else {
9891 json_object_string_add(json_nexthop, "Error",
9892 "Unsupported address-family");
9893 json_object_string_add(json_nexthop, "error",
9894 "Unsupported address-family");
9895 }
9896 }
9897
9898 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9899
9900 if (!json_path)
9901 vty_out(vty, "/%pIA", &eo->gw_ip);
9902 else
9903 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9904
9905 if (bgp_attr_get_ecommunity(attr)) {
9906 char *mac = NULL;
9907 struct ecommunity_val *routermac = ecommunity_lookup(
9908 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9909 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9910
9911 if (routermac)
9912 mac = ecom_mac2str((char *)routermac->val);
9913 if (mac) {
9914 if (!json_path) {
9915 vty_out(vty, "/%s", mac);
9916 } else {
9917 json_object_string_add(json_overlay, "rmac",
9918 mac);
9919 }
9920 XFREE(MTYPE_TMP, mac);
9921 }
9922 }
9923
9924 if (!json_path) {
9925 vty_out(vty, "\n");
9926 } else {
9927 json_object_object_add(json_path, "overlay", json_overlay);
9928
9929 json_object_array_add(json_paths, json_path);
9930 }
9931 }
9932
9933 /* dampening route */
9934 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9935 struct bgp_path_info *path, int display,
9936 afi_t afi, safi_t safi, bool use_json,
9937 json_object *json_paths)
9938 {
9939 struct attr *attr = path->attr;
9940 int len;
9941 char timebuf[BGP_UPTIME_LEN];
9942 json_object *json_path = NULL;
9943
9944 if (use_json)
9945 json_path = json_object_new_object();
9946
9947 /* short status lead text */
9948 route_vty_short_status_out(vty, path, p, json_path);
9949
9950 /* print prefix and mask */
9951 if (!use_json) {
9952 if (!display)
9953 route_vty_out_route(path->net, p, vty, NULL, false);
9954 else
9955 vty_out(vty, "%*s", 17, " ");
9956
9957 len = vty_out(vty, "%s", path->peer->host);
9958 len = 17 - len;
9959
9960 if (len < 1)
9961 vty_out(vty, "\n%*s", 34, " ");
9962 else
9963 vty_out(vty, "%*s", len, " ");
9964
9965 vty_out(vty, "%s ",
9966 bgp_damp_reuse_time_vty(vty, path, timebuf,
9967 BGP_UPTIME_LEN, afi, safi,
9968 use_json, NULL));
9969
9970 if (attr->aspath)
9971 aspath_print_vty(vty, "%s", attr->aspath, " ");
9972
9973 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9974
9975 vty_out(vty, "\n");
9976 } else {
9977 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9978 safi, use_json, json_path);
9979
9980 if (attr->aspath)
9981 json_object_string_add(json_path, "asPath",
9982 attr->aspath->str);
9983
9984 json_object_string_add(json_path, "origin",
9985 bgp_origin_str[attr->origin]);
9986 json_object_string_add(json_path, "peerHost", path->peer->host);
9987
9988 json_object_array_add(json_paths, json_path);
9989 }
9990 }
9991
9992 /* flap route */
9993 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9994 struct bgp_path_info *path, int display,
9995 afi_t afi, safi_t safi, bool use_json,
9996 json_object *json_paths)
9997 {
9998 struct attr *attr = path->attr;
9999 struct bgp_damp_info *bdi;
10000 char timebuf[BGP_UPTIME_LEN];
10001 int len;
10002 json_object *json_path = NULL;
10003
10004 if (!path->extra)
10005 return;
10006
10007 if (use_json)
10008 json_path = json_object_new_object();
10009
10010 bdi = path->extra->damp_info;
10011
10012 /* short status lead text */
10013 route_vty_short_status_out(vty, path, p, json_path);
10014
10015 if (!use_json) {
10016 if (!display)
10017 route_vty_out_route(path->net, p, vty, NULL, false);
10018 else
10019 vty_out(vty, "%*s", 17, " ");
10020
10021 len = vty_out(vty, "%s", path->peer->host);
10022 len = 16 - len;
10023 if (len < 1)
10024 vty_out(vty, "\n%*s", 33, " ");
10025 else
10026 vty_out(vty, "%*s", len, " ");
10027
10028 len = vty_out(vty, "%d", bdi->flap);
10029 len = 5 - len;
10030 if (len < 1)
10031 vty_out(vty, " ");
10032 else
10033 vty_out(vty, "%*s", len, " ");
10034
10035 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10036 BGP_UPTIME_LEN, 0, NULL));
10037
10038 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10039 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10040 vty_out(vty, "%s ",
10041 bgp_damp_reuse_time_vty(vty, path, timebuf,
10042 BGP_UPTIME_LEN, afi,
10043 safi, use_json, NULL));
10044 else
10045 vty_out(vty, "%*s ", 8, " ");
10046
10047 if (attr->aspath)
10048 aspath_print_vty(vty, "%s", attr->aspath, " ");
10049
10050 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10051
10052 vty_out(vty, "\n");
10053 } else {
10054 json_object_string_add(json_path, "peerHost", path->peer->host);
10055 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10056
10057 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10058 json_path);
10059
10060 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10061 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10062 bgp_damp_reuse_time_vty(vty, path, timebuf,
10063 BGP_UPTIME_LEN, afi, safi,
10064 use_json, json_path);
10065
10066 if (attr->aspath)
10067 json_object_string_add(json_path, "asPath",
10068 attr->aspath->str);
10069
10070 json_object_string_add(json_path, "origin",
10071 bgp_origin_str[attr->origin]);
10072
10073 json_object_array_add(json_paths, json_path);
10074 }
10075 }
10076
10077 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10078 int *first, const char *header,
10079 json_object *json_adv_to)
10080 {
10081 json_object *json_peer = NULL;
10082
10083 if (json_adv_to) {
10084 /* 'advertised-to' is a dictionary of peers we have advertised
10085 * this
10086 * prefix too. The key is the peer's IP or swpX, the value is
10087 * the
10088 * hostname if we know it and "" if not.
10089 */
10090 json_peer = json_object_new_object();
10091
10092 if (peer->hostname)
10093 json_object_string_add(json_peer, "hostname",
10094 peer->hostname);
10095
10096 if (peer->conf_if)
10097 json_object_object_add(json_adv_to, peer->conf_if,
10098 json_peer);
10099 else
10100 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10101 &peer->su);
10102 } else {
10103 if (*first) {
10104 vty_out(vty, "%s", header);
10105 *first = 0;
10106 }
10107
10108 if (peer->hostname
10109 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10110 if (peer->conf_if)
10111 vty_out(vty, " %s(%s)", peer->hostname,
10112 peer->conf_if);
10113 else
10114 vty_out(vty, " %s(%pSU)", peer->hostname,
10115 &peer->su);
10116 } else {
10117 if (peer->conf_if)
10118 vty_out(vty, " %s", peer->conf_if);
10119 else
10120 vty_out(vty, " %pSU", &peer->su);
10121 }
10122 }
10123 }
10124
10125 static void route_vty_out_tx_ids(struct vty *vty,
10126 struct bgp_addpath_info_data *d)
10127 {
10128 int i;
10129
10130 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10131 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10132 d->addpath_tx_id[i],
10133 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10134 }
10135 }
10136
10137 static void route_vty_out_detail_es_info(struct vty *vty,
10138 struct bgp_path_info *pi,
10139 struct attr *attr,
10140 json_object *json_path)
10141 {
10142 char esi_buf[ESI_STR_LEN];
10143 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10144 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10145 ATTR_ES_PEER_ROUTER);
10146 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10147 ATTR_ES_PEER_ACTIVE);
10148 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10149 ATTR_ES_PEER_PROXY);
10150 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10151 if (json_path) {
10152 json_object *json_es_info = NULL;
10153
10154 json_object_string_add(
10155 json_path, "esi",
10156 esi_buf);
10157 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10158 json_es_info = json_object_new_object();
10159 if (es_local)
10160 json_object_boolean_true_add(
10161 json_es_info, "localEs");
10162 if (peer_active)
10163 json_object_boolean_true_add(
10164 json_es_info, "peerActive");
10165 if (peer_proxy)
10166 json_object_boolean_true_add(
10167 json_es_info, "peerProxy");
10168 if (peer_router)
10169 json_object_boolean_true_add(
10170 json_es_info, "peerRouter");
10171 if (attr->mm_sync_seqnum)
10172 json_object_int_add(
10173 json_es_info, "peerSeq",
10174 attr->mm_sync_seqnum);
10175 json_object_object_add(
10176 json_path, "es_info",
10177 json_es_info);
10178 }
10179 } else {
10180 if (bgp_evpn_attr_is_sync(attr))
10181 vty_out(vty,
10182 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10183 esi_buf,
10184 es_local ? "local-es":"",
10185 peer_proxy ? "proxy " : "",
10186 peer_active ? "active ":"",
10187 peer_router ? "router ":"",
10188 attr->mm_sync_seqnum);
10189 else
10190 vty_out(vty, " ESI %s %s\n",
10191 esi_buf,
10192 es_local ? "local-es":"");
10193 }
10194 }
10195
10196 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10197 const struct prefix *p, struct bgp_path_info *path,
10198 afi_t afi, safi_t safi,
10199 enum rpki_states rpki_curr_state,
10200 json_object *json_paths)
10201 {
10202 char buf[INET6_ADDRSTRLEN];
10203 char tag_buf[30];
10204 struct attr *attr = path->attr;
10205 time_t tbuf;
10206 json_object *json_bestpath = NULL;
10207 json_object *json_cluster_list = NULL;
10208 json_object *json_cluster_list_list = NULL;
10209 json_object *json_ext_community = NULL;
10210 json_object *json_last_update = NULL;
10211 json_object *json_pmsi = NULL;
10212 json_object *json_nexthop_global = NULL;
10213 json_object *json_nexthop_ll = NULL;
10214 json_object *json_nexthops = NULL;
10215 json_object *json_path = NULL;
10216 json_object *json_peer = NULL;
10217 json_object *json_string = NULL;
10218 json_object *json_adv_to = NULL;
10219 int first = 0;
10220 struct listnode *node, *nnode;
10221 struct peer *peer;
10222 bool addpath_capable;
10223 int has_adj;
10224 unsigned int first_as;
10225 bool nexthop_self =
10226 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10227 int i;
10228 char *nexthop_hostname =
10229 bgp_nexthop_hostname(path->peer, path->nexthop);
10230 uint32_t ttl = 0;
10231 uint32_t bos = 0;
10232 uint32_t exp = 0;
10233 mpls_label_t label = MPLS_INVALID_LABEL;
10234 tag_buf[0] = '\0';
10235 struct bgp_path_info *bpi_ultimate =
10236 bgp_get_imported_bpi_ultimate(path);
10237
10238 if (json_paths) {
10239 json_path = json_object_new_object();
10240 json_peer = json_object_new_object();
10241 json_nexthop_global = json_object_new_object();
10242 }
10243
10244 if (safi == SAFI_EVPN) {
10245 if (!json_paths)
10246 vty_out(vty, " Route %pFX", p);
10247 }
10248
10249 if (path->extra) {
10250 if (path->extra && path->extra->num_labels) {
10251 bgp_evpn_label2str(path->extra->label,
10252 path->extra->num_labels, tag_buf,
10253 sizeof(tag_buf));
10254 }
10255 if (safi == SAFI_EVPN) {
10256 if (!json_paths) {
10257 if (tag_buf[0] != '\0')
10258 vty_out(vty, " VNI %s", tag_buf);
10259 } else {
10260 if (tag_buf[0]) {
10261 json_object_string_add(json_path, "VNI",
10262 tag_buf);
10263 json_object_string_add(json_path, "vni",
10264 tag_buf);
10265 }
10266 }
10267 }
10268 }
10269
10270 if (safi == SAFI_EVPN
10271 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10272 char gwip_buf[INET6_ADDRSTRLEN];
10273
10274 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10275 sizeof(gwip_buf));
10276
10277 if (json_paths)
10278 json_object_string_add(json_path, "gatewayIP",
10279 gwip_buf);
10280 else
10281 vty_out(vty, " Gateway IP %s", gwip_buf);
10282 }
10283
10284 if (safi == SAFI_EVPN && !json_path)
10285 vty_out(vty, "\n");
10286
10287
10288 if (path->extra && path->extra->parent && !json_paths) {
10289 struct bgp_path_info *parent_ri;
10290 struct bgp_dest *dest, *pdest;
10291
10292 parent_ri = (struct bgp_path_info *)path->extra->parent;
10293 dest = parent_ri->net;
10294 if (dest && dest->pdest) {
10295 pdest = dest->pdest;
10296 if (is_pi_family_evpn(parent_ri)) {
10297 vty_out(vty,
10298 " Imported from %pRD:%pFX, VNI %s",
10299 (struct prefix_rd *)bgp_dest_get_prefix(
10300 pdest),
10301 (struct prefix_evpn *)
10302 bgp_dest_get_prefix(dest),
10303 tag_buf);
10304 if (CHECK_FLAG(attr->es_flags, ATTR_ES_L3_NHG))
10305 vty_out(vty, ", L3NHG %s",
10306 CHECK_FLAG(
10307 attr->es_flags,
10308 ATTR_ES_L3_NHG_ACTIVE)
10309 ? "active"
10310 : "inactive");
10311 vty_out(vty, "\n");
10312
10313 } else
10314 vty_out(vty, " Imported from %pRD:%pFX\n",
10315 (struct prefix_rd *)bgp_dest_get_prefix(
10316 pdest),
10317 (struct prefix_evpn *)
10318 bgp_dest_get_prefix(dest));
10319 }
10320 }
10321
10322 /* Line1 display AS-path, Aggregator */
10323 if (attr->aspath) {
10324 if (json_paths) {
10325 if (!attr->aspath->json)
10326 aspath_str_update(attr->aspath, true);
10327 json_object_lock(attr->aspath->json);
10328 json_object_object_add(json_path, "aspath",
10329 attr->aspath->json);
10330 } else {
10331 if (attr->aspath->segments)
10332 aspath_print_vty(vty, " %s", attr->aspath, "");
10333 else
10334 vty_out(vty, " Local");
10335 }
10336 }
10337
10338 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10339 if (json_paths)
10340 json_object_boolean_true_add(json_path, "removed");
10341 else
10342 vty_out(vty, ", (removed)");
10343 }
10344
10345 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10346 if (json_paths)
10347 json_object_boolean_true_add(json_path, "stale");
10348 else
10349 vty_out(vty, ", (stale)");
10350 }
10351
10352 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10353 if (json_paths) {
10354 json_object_int_add(json_path, "aggregatorAs",
10355 attr->aggregator_as);
10356 json_object_string_addf(json_path, "aggregatorId",
10357 "%pI4", &attr->aggregator_addr);
10358 } else {
10359 vty_out(vty, ", (aggregated by %u %pI4)",
10360 attr->aggregator_as, &attr->aggregator_addr);
10361 }
10362 }
10363
10364 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10365 PEER_FLAG_REFLECTOR_CLIENT)) {
10366 if (json_paths)
10367 json_object_boolean_true_add(json_path,
10368 "rxedFromRrClient");
10369 else
10370 vty_out(vty, ", (Received from a RR-client)");
10371 }
10372
10373 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10374 PEER_FLAG_RSERVER_CLIENT)) {
10375 if (json_paths)
10376 json_object_boolean_true_add(json_path,
10377 "rxedFromRsClient");
10378 else
10379 vty_out(vty, ", (Received from a RS-client)");
10380 }
10381
10382 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10383 if (json_paths)
10384 json_object_boolean_true_add(json_path,
10385 "dampeningHistoryEntry");
10386 else
10387 vty_out(vty, ", (history entry)");
10388 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10389 if (json_paths)
10390 json_object_boolean_true_add(json_path,
10391 "dampeningSuppressed");
10392 else
10393 vty_out(vty, ", (suppressed due to dampening)");
10394 }
10395
10396 if (!json_paths)
10397 vty_out(vty, "\n");
10398
10399 /* Line2 display Next-hop, Neighbor, Router-id */
10400 /* Display the nexthop */
10401
10402 if ((p->family == AF_INET || p->family == AF_ETHERNET ||
10403 p->family == AF_EVPN) &&
10404 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10405 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10406 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10407 || safi == SAFI_EVPN) {
10408 if (json_paths) {
10409 json_object_string_addf(
10410 json_nexthop_global, "ip", "%pI4",
10411 &attr->mp_nexthop_global_in);
10412
10413 if (path->peer->hostname)
10414 json_object_string_add(
10415 json_nexthop_global, "hostname",
10416 path->peer->hostname);
10417 } else {
10418 if (nexthop_hostname)
10419 vty_out(vty, " %pI4(%s)",
10420 &attr->mp_nexthop_global_in,
10421 nexthop_hostname);
10422 else
10423 vty_out(vty, " %pI4",
10424 &attr->mp_nexthop_global_in);
10425 }
10426 } else {
10427 if (json_paths) {
10428 json_object_string_addf(json_nexthop_global,
10429 "ip", "%pI4",
10430 &attr->nexthop);
10431
10432 if (path->peer->hostname)
10433 json_object_string_add(
10434 json_nexthop_global, "hostname",
10435 path->peer->hostname);
10436 } else {
10437 if (nexthop_hostname)
10438 vty_out(vty, " %pI4(%s)",
10439 &attr->nexthop,
10440 nexthop_hostname);
10441 else
10442 vty_out(vty, " %pI4",
10443 &attr->nexthop);
10444 }
10445 }
10446
10447 if (json_paths)
10448 json_object_string_add(json_nexthop_global, "afi",
10449 "ipv4");
10450 } else {
10451 if (json_paths) {
10452 json_object_string_addf(json_nexthop_global, "ip",
10453 "%pI6",
10454 &attr->mp_nexthop_global);
10455
10456 if (path->peer->hostname)
10457 json_object_string_add(json_nexthop_global,
10458 "hostname",
10459 path->peer->hostname);
10460
10461 json_object_string_add(json_nexthop_global, "afi",
10462 "ipv6");
10463 json_object_string_add(json_nexthop_global, "scope",
10464 "global");
10465 } else {
10466 if (nexthop_hostname)
10467 vty_out(vty, " %pI6(%s)",
10468 &attr->mp_nexthop_global,
10469 nexthop_hostname);
10470 else
10471 vty_out(vty, " %pI6",
10472 &attr->mp_nexthop_global);
10473 }
10474 }
10475
10476 /* Display the IGP cost or 'inaccessible' */
10477 if (!CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_VALID)) {
10478 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10479
10480 if (json_paths) {
10481 json_object_boolean_false_add(json_nexthop_global,
10482 "accessible");
10483 json_object_boolean_add(json_nexthop_global,
10484 "importCheckEnabled", import);
10485 } else {
10486 vty_out(vty, " (inaccessible%s)",
10487 import ? ", import-check enabled" : "");
10488 }
10489 } else {
10490 if (bpi_ultimate->extra && bpi_ultimate->extra->igpmetric) {
10491 if (json_paths)
10492 json_object_int_add(
10493 json_nexthop_global, "metric",
10494 bpi_ultimate->extra->igpmetric);
10495 else
10496 vty_out(vty, " (metric %u)",
10497 bpi_ultimate->extra->igpmetric);
10498 }
10499
10500 /* IGP cost is 0, display this only for json */
10501 else {
10502 if (json_paths)
10503 json_object_int_add(json_nexthop_global,
10504 "metric", 0);
10505 }
10506
10507 if (json_paths)
10508 json_object_boolean_true_add(json_nexthop_global,
10509 "accessible");
10510 }
10511
10512 /* Display peer "from" output */
10513 /* This path was originated locally */
10514 if (path->peer == bgp->peer_self) {
10515
10516 if (safi == SAFI_EVPN || (p->family == AF_INET &&
10517 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10518 if (json_paths)
10519 json_object_string_add(json_peer, "peerId",
10520 "0.0.0.0");
10521 else
10522 vty_out(vty, " from 0.0.0.0 ");
10523 } else {
10524 if (json_paths)
10525 json_object_string_add(json_peer, "peerId",
10526 "::");
10527 else
10528 vty_out(vty, " from :: ");
10529 }
10530
10531 if (json_paths)
10532 json_object_string_addf(json_peer, "routerId", "%pI4",
10533 &bgp->router_id);
10534 else
10535 vty_out(vty, "(%pI4)", &bgp->router_id);
10536 }
10537
10538 /* We RXed this path from one of our peers */
10539 else {
10540
10541 if (json_paths) {
10542 json_object_string_addf(json_peer, "peerId", "%pSU",
10543 &path->peer->su);
10544 json_object_string_addf(json_peer, "routerId", "%pI4",
10545 &path->peer->remote_id);
10546
10547 if (path->peer->hostname)
10548 json_object_string_add(json_peer, "hostname",
10549 path->peer->hostname);
10550
10551 if (path->peer->domainname)
10552 json_object_string_add(json_peer, "domainname",
10553 path->peer->domainname);
10554
10555 if (path->peer->conf_if)
10556 json_object_string_add(json_peer, "interface",
10557 path->peer->conf_if);
10558 } else {
10559 if (path->peer->conf_if) {
10560 if (path->peer->hostname
10561 && CHECK_FLAG(path->peer->bgp->flags,
10562 BGP_FLAG_SHOW_HOSTNAME))
10563 vty_out(vty, " from %s(%s)",
10564 path->peer->hostname,
10565 path->peer->conf_if);
10566 else
10567 vty_out(vty, " from %s",
10568 path->peer->conf_if);
10569 } else {
10570 if (path->peer->hostname
10571 && CHECK_FLAG(path->peer->bgp->flags,
10572 BGP_FLAG_SHOW_HOSTNAME))
10573 vty_out(vty, " from %s(%s)",
10574 path->peer->hostname,
10575 path->peer->host);
10576 else
10577 vty_out(vty, " from %pSU",
10578 &path->peer->su);
10579 }
10580
10581 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10582 vty_out(vty, " (%pI4)", &attr->originator_id);
10583 else
10584 vty_out(vty, " (%pI4)", &path->peer->remote_id);
10585 }
10586 }
10587
10588 /*
10589 * Note when vrfid of nexthop is different from that of prefix
10590 */
10591 if (path->extra && path->extra->bgp_orig) {
10592 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10593
10594 if (json_paths) {
10595 const char *vn;
10596
10597 if (path->extra->bgp_orig->inst_type
10598 == BGP_INSTANCE_TYPE_DEFAULT)
10599 vn = VRF_DEFAULT_NAME;
10600 else
10601 vn = path->extra->bgp_orig->name;
10602
10603 json_object_string_add(json_path, "nhVrfName", vn);
10604
10605 if (nexthop_vrfid == VRF_UNKNOWN) {
10606 json_object_int_add(json_path, "nhVrfId", -1);
10607 } else {
10608 json_object_int_add(json_path, "nhVrfId",
10609 (int)nexthop_vrfid);
10610 }
10611 } else {
10612 if (nexthop_vrfid == VRF_UNKNOWN)
10613 vty_out(vty, " vrf ?");
10614 else {
10615 struct vrf *vrf;
10616
10617 vrf = vrf_lookup_by_id(nexthop_vrfid);
10618 vty_out(vty, " vrf %s(%u)",
10619 VRF_LOGNAME(vrf), nexthop_vrfid);
10620 }
10621 }
10622 }
10623
10624 if (nexthop_self) {
10625 if (json_paths) {
10626 json_object_boolean_true_add(json_path,
10627 "announceNexthopSelf");
10628 } else {
10629 vty_out(vty, " announce-nh-self");
10630 }
10631 }
10632
10633 if (!json_paths)
10634 vty_out(vty, "\n");
10635
10636 /* display the link-local nexthop */
10637 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10638 if (json_paths) {
10639 json_nexthop_ll = json_object_new_object();
10640 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10641 &attr->mp_nexthop_local);
10642
10643 if (path->peer->hostname)
10644 json_object_string_add(json_nexthop_ll,
10645 "hostname",
10646 path->peer->hostname);
10647
10648 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10649 json_object_string_add(json_nexthop_ll, "scope",
10650 "link-local");
10651
10652 json_object_boolean_true_add(json_nexthop_ll,
10653 "accessible");
10654
10655 if (!attr->mp_nexthop_prefer_global)
10656 json_object_boolean_true_add(json_nexthop_ll,
10657 "used");
10658 else
10659 json_object_boolean_true_add(
10660 json_nexthop_global, "used");
10661 } else {
10662 vty_out(vty, " (%s) %s\n",
10663 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10664 buf, INET6_ADDRSTRLEN),
10665 attr->mp_nexthop_prefer_global
10666 ? "(prefer-global)"
10667 : "(used)");
10668 }
10669 }
10670 /* If we do not have a link-local nexthop then we must flag the
10671 global as "used" */
10672 else {
10673 if (json_paths)
10674 json_object_boolean_true_add(json_nexthop_global,
10675 "used");
10676 }
10677
10678 if (safi == SAFI_EVPN &&
10679 bgp_evpn_is_esi_valid(&attr->esi)) {
10680 route_vty_out_detail_es_info(vty, path, attr, json_path);
10681 }
10682
10683 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10684 * Int/Ext/Local, Atomic, best */
10685 if (json_paths)
10686 json_object_string_add(json_path, "origin",
10687 bgp_origin_long_str[attr->origin]);
10688 else
10689 vty_out(vty, " Origin %s",
10690 bgp_origin_long_str[attr->origin]);
10691
10692 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10693 if (json_paths)
10694 json_object_int_add(json_path, "metric", attr->med);
10695 else
10696 vty_out(vty, ", metric %u", attr->med);
10697 }
10698
10699 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10700 if (json_paths)
10701 json_object_int_add(json_path, "locPrf",
10702 attr->local_pref);
10703 else
10704 vty_out(vty, ", localpref %u", attr->local_pref);
10705 }
10706
10707 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
10708 if (json_paths)
10709 json_object_int_add(json_path, "aigpMetric",
10710 bgp_attr_get_aigp_metric(attr));
10711 else
10712 vty_out(vty, ", aigp-metric %" PRIu64,
10713 bgp_attr_get_aigp_metric(attr));
10714 }
10715
10716 if (attr->weight != 0) {
10717 if (json_paths)
10718 json_object_int_add(json_path, "weight", attr->weight);
10719 else
10720 vty_out(vty, ", weight %u", attr->weight);
10721 }
10722
10723 if (attr->tag != 0) {
10724 if (json_paths)
10725 json_object_int_add(json_path, "tag", attr->tag);
10726 else
10727 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10728 }
10729
10730 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10731 if (json_paths)
10732 json_object_boolean_false_add(json_path, "valid");
10733 else
10734 vty_out(vty, ", invalid");
10735 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10736 if (json_paths)
10737 json_object_boolean_true_add(json_path, "valid");
10738 else
10739 vty_out(vty, ", valid");
10740 }
10741
10742 if (json_paths)
10743 json_object_int_add(json_path, "version", bn->version);
10744
10745 if (path->peer != bgp->peer_self) {
10746 if (path->peer->as == path->peer->local_as) {
10747 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10748 if (json_paths)
10749 json_object_string_add(
10750 json_peer, "type",
10751 "confed-internal");
10752 else
10753 vty_out(vty, ", confed-internal");
10754 } else {
10755 if (json_paths)
10756 json_object_string_add(
10757 json_peer, "type", "internal");
10758 else
10759 vty_out(vty, ", internal");
10760 }
10761 } else {
10762 if (bgp_confederation_peers_check(bgp,
10763 path->peer->as)) {
10764 if (json_paths)
10765 json_object_string_add(
10766 json_peer, "type",
10767 "confed-external");
10768 else
10769 vty_out(vty, ", confed-external");
10770 } else {
10771 if (json_paths)
10772 json_object_string_add(
10773 json_peer, "type", "external");
10774 else
10775 vty_out(vty, ", external");
10776 }
10777 }
10778 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10779 if (json_paths) {
10780 json_object_boolean_true_add(json_path, "aggregated");
10781 json_object_boolean_true_add(json_path, "local");
10782 } else {
10783 vty_out(vty, ", aggregated, local");
10784 }
10785 } else if (path->type != ZEBRA_ROUTE_BGP) {
10786 if (json_paths)
10787 json_object_boolean_true_add(json_path, "sourced");
10788 else
10789 vty_out(vty, ", sourced");
10790 } else {
10791 if (json_paths) {
10792 json_object_boolean_true_add(json_path, "sourced");
10793 json_object_boolean_true_add(json_path, "local");
10794 } else {
10795 vty_out(vty, ", sourced, local");
10796 }
10797 }
10798
10799 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10800 if (json_paths)
10801 json_object_boolean_true_add(json_path,
10802 "atomicAggregate");
10803 else
10804 vty_out(vty, ", atomic-aggregate");
10805 }
10806
10807 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10808 if (json_paths)
10809 json_object_int_add(json_path, "otc", attr->otc);
10810 else
10811 vty_out(vty, ", otc %u", attr->otc);
10812 }
10813
10814 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10815 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10816 && bgp_path_info_mpath_count(path))) {
10817 if (json_paths)
10818 json_object_boolean_true_add(json_path, "multipath");
10819 else
10820 vty_out(vty, ", multipath");
10821 }
10822
10823 // Mark the bestpath(s)
10824 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10825 first_as = aspath_get_first_as(attr->aspath);
10826
10827 if (json_paths) {
10828 if (!json_bestpath)
10829 json_bestpath = json_object_new_object();
10830 json_object_int_add(json_bestpath, "bestpathFromAs",
10831 first_as);
10832 } else {
10833 if (first_as)
10834 vty_out(vty, ", bestpath-from-AS %u", first_as);
10835 else
10836 vty_out(vty, ", bestpath-from-AS Local");
10837 }
10838 }
10839
10840 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10841 if (json_paths) {
10842 if (!json_bestpath)
10843 json_bestpath = json_object_new_object();
10844 json_object_boolean_true_add(json_bestpath, "overall");
10845 json_object_string_add(
10846 json_bestpath, "selectionReason",
10847 bgp_path_selection_reason2str(bn->reason));
10848 } else {
10849 vty_out(vty, ", best");
10850 vty_out(vty, " (%s)",
10851 bgp_path_selection_reason2str(bn->reason));
10852 }
10853 }
10854
10855 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10856 if (json_paths)
10857 json_object_string_add(
10858 json_path, "rpkiValidationState",
10859 bgp_rpki_validation2str(rpki_curr_state));
10860 else
10861 vty_out(vty, ", rpki validation-state: %s",
10862 bgp_rpki_validation2str(rpki_curr_state));
10863 }
10864
10865 if (json_bestpath)
10866 json_object_object_add(json_path, "bestpath", json_bestpath);
10867
10868 if (!json_paths)
10869 vty_out(vty, "\n");
10870
10871 /* Line 4 display Community */
10872 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10873 if (json_paths) {
10874 if (!bgp_attr_get_community(attr)->json)
10875 community_str(bgp_attr_get_community(attr),
10876 true, true);
10877 json_object_lock(bgp_attr_get_community(attr)->json);
10878 json_object_object_add(
10879 json_path, "community",
10880 bgp_attr_get_community(attr)->json);
10881 } else {
10882 vty_out(vty, " Community: %s\n",
10883 bgp_attr_get_community(attr)->str);
10884 }
10885 }
10886
10887 /* Line 5 display Extended-community */
10888 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10889 if (json_paths) {
10890 json_ext_community = json_object_new_object();
10891 json_object_string_add(
10892 json_ext_community, "string",
10893 bgp_attr_get_ecommunity(attr)->str);
10894 json_object_object_add(json_path, "extendedCommunity",
10895 json_ext_community);
10896 } else {
10897 vty_out(vty, " Extended Community: %s\n",
10898 bgp_attr_get_ecommunity(attr)->str);
10899 }
10900 }
10901
10902 /* Line 6 display Large community */
10903 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10904 if (json_paths) {
10905 if (!bgp_attr_get_lcommunity(attr)->json)
10906 lcommunity_str(bgp_attr_get_lcommunity(attr),
10907 true, true);
10908 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10909 json_object_object_add(
10910 json_path, "largeCommunity",
10911 bgp_attr_get_lcommunity(attr)->json);
10912 } else {
10913 vty_out(vty, " Large Community: %s\n",
10914 bgp_attr_get_lcommunity(attr)->str);
10915 }
10916 }
10917
10918 /* Line 7 display Originator, Cluster-id */
10919 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10920 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10921 char buf[BUFSIZ] = {0};
10922
10923 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10924 if (json_paths)
10925 json_object_string_addf(json_path,
10926 "originatorId", "%pI4",
10927 &attr->originator_id);
10928 else
10929 vty_out(vty, " Originator: %pI4",
10930 &attr->originator_id);
10931 }
10932
10933 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10934 struct cluster_list *cluster =
10935 bgp_attr_get_cluster(attr);
10936 int i;
10937
10938 if (json_paths) {
10939 json_cluster_list = json_object_new_object();
10940 json_cluster_list_list =
10941 json_object_new_array();
10942
10943 for (i = 0; i < cluster->length / 4; i++) {
10944 json_string = json_object_new_string(
10945 inet_ntop(AF_INET,
10946 &cluster->list[i],
10947 buf, sizeof(buf)));
10948 json_object_array_add(
10949 json_cluster_list_list,
10950 json_string);
10951 }
10952
10953 /*
10954 * struct cluster_list does not have
10955 * "str" variable like aspath and community
10956 * do. Add this someday if someone asks
10957 * for it.
10958 * json_object_string_add(json_cluster_list,
10959 * "string", cluster->str);
10960 */
10961 json_object_object_add(json_cluster_list,
10962 "list",
10963 json_cluster_list_list);
10964 json_object_object_add(json_path, "clusterList",
10965 json_cluster_list);
10966 } else {
10967 vty_out(vty, ", Cluster list: ");
10968
10969 for (i = 0; i < cluster->length / 4; i++) {
10970 vty_out(vty, "%pI4 ",
10971 &cluster->list[i]);
10972 }
10973 }
10974 }
10975
10976 if (!json_paths)
10977 vty_out(vty, "\n");
10978 }
10979
10980 if (path->extra && path->extra->damp_info)
10981 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10982
10983 /* Remote Label */
10984 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10985 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10986 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
10987 &bos);
10988
10989 if (json_paths)
10990 json_object_int_add(json_path, "remoteLabel", label);
10991 else
10992 vty_out(vty, " Remote label: %d\n", label);
10993 }
10994
10995 /* Remote SID */
10996 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10997 if (json_paths)
10998 json_object_string_addf(json_path, "remoteSid", "%pI6",
10999 &path->extra->sid[0].sid);
11000 else
11001 vty_out(vty, " Remote SID: %pI6\n",
11002 &path->extra->sid[0].sid);
11003 }
11004
11005 /* Label Index */
11006 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
11007 if (json_paths)
11008 json_object_int_add(json_path, "labelIndex",
11009 attr->label_index);
11010 else
11011 vty_out(vty, " Label Index: %d\n",
11012 attr->label_index);
11013 }
11014
11015 /* Line 8 display Addpath IDs */
11016 if (path->addpath_rx_id
11017 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
11018 if (json_paths) {
11019 json_object_int_add(json_path, "addpathRxId",
11020 path->addpath_rx_id);
11021
11022 /* Keep backwards compatibility with the old API
11023 * by putting TX All's ID in the old field
11024 */
11025 json_object_int_add(
11026 json_path, "addpathTxId",
11027 path->tx_addpath
11028 .addpath_tx_id[BGP_ADDPATH_ALL]);
11029
11030 /* ... but create a specific field for each
11031 * strategy
11032 */
11033 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
11034 json_object_int_add(
11035 json_path,
11036 bgp_addpath_names(i)->id_json_name,
11037 path->tx_addpath.addpath_tx_id[i]);
11038 }
11039 } else {
11040 vty_out(vty, " AddPath ID: RX %u, ",
11041 path->addpath_rx_id);
11042
11043 route_vty_out_tx_ids(vty, &path->tx_addpath);
11044 }
11045 }
11046
11047 /* If we used addpath to TX a non-bestpath we need to display
11048 * "Advertised to" on a path-by-path basis
11049 */
11050 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11051 first = 1;
11052
11053 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11054 addpath_capable =
11055 bgp_addpath_encode_tx(peer, afi, safi);
11056 has_adj = bgp_adj_out_lookup(
11057 peer, path->net,
11058 bgp_addpath_id_for_peer(peer, afi, safi,
11059 &path->tx_addpath));
11060
11061 if ((addpath_capable && has_adj)
11062 || (!addpath_capable && has_adj
11063 && CHECK_FLAG(path->flags,
11064 BGP_PATH_SELECTED))) {
11065 if (json_path && !json_adv_to)
11066 json_adv_to = json_object_new_object();
11067
11068 route_vty_out_advertised_to(
11069 vty, peer, &first,
11070 " Advertised to:", json_adv_to);
11071 }
11072 }
11073
11074 if (json_path) {
11075 if (json_adv_to) {
11076 json_object_object_add(
11077 json_path, "advertisedTo", json_adv_to);
11078 }
11079 } else {
11080 if (!first) {
11081 vty_out(vty, "\n");
11082 }
11083 }
11084 }
11085
11086 /* Line 9 display Uptime */
11087 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11088 if (json_paths) {
11089 json_last_update = json_object_new_object();
11090 json_object_int_add(json_last_update, "epoch", tbuf);
11091 json_object_string_add(json_last_update, "string",
11092 ctime(&tbuf));
11093 json_object_object_add(json_path, "lastUpdate",
11094 json_last_update);
11095 } else
11096 vty_out(vty, " Last update: %s", ctime(&tbuf));
11097
11098 /* Line 10 display PMSI tunnel attribute, if present */
11099 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11100 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11101 bgp_attr_get_pmsi_tnl_type(attr),
11102 PMSI_TNLTYPE_STR_DEFAULT);
11103
11104 if (json_paths) {
11105 json_pmsi = json_object_new_object();
11106 json_object_string_add(json_pmsi, "tunnelType", str);
11107 json_object_int_add(json_pmsi, "label",
11108 label2vni(&attr->label));
11109 json_object_object_add(json_path, "pmsi", json_pmsi);
11110 } else
11111 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11112 str, label2vni(&attr->label));
11113 }
11114
11115 if (path->peer->t_gr_restart &&
11116 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11117 unsigned long gr_remaining =
11118 thread_timer_remain_second(path->peer->t_gr_restart);
11119
11120 if (json_paths) {
11121 json_object_int_add(json_path,
11122 "gracefulRestartSecondsRemaining",
11123 gr_remaining);
11124 } else
11125 vty_out(vty,
11126 " Time until Graceful Restart stale route deleted: %lu\n",
11127 gr_remaining);
11128 }
11129
11130 if (path->peer->t_llgr_stale[afi][safi] &&
11131 bgp_attr_get_community(attr) &&
11132 community_include(bgp_attr_get_community(attr),
11133 COMMUNITY_LLGR_STALE)) {
11134 unsigned long llgr_remaining = thread_timer_remain_second(
11135 path->peer->t_llgr_stale[afi][safi]);
11136
11137 if (json_paths) {
11138 json_object_int_add(json_path, "llgrSecondsRemaining",
11139 llgr_remaining);
11140 } else
11141 vty_out(vty,
11142 " Time until Long-lived stale route deleted: %lu\n",
11143 llgr_remaining);
11144 }
11145
11146 /* Output some debug about internal state of the dest flags */
11147 if (json_paths) {
11148 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11149 json_object_boolean_true_add(json_path, "processScheduled");
11150 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11151 json_object_boolean_true_add(json_path, "userCleared");
11152 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11153 json_object_boolean_true_add(json_path, "labelChanged");
11154 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11155 json_object_boolean_true_add(json_path, "registeredForLabel");
11156 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11157 json_object_boolean_true_add(json_path, "selectDefered");
11158 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11159 json_object_boolean_true_add(json_path, "fibInstalled");
11160 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11161 json_object_boolean_true_add(json_path, "fibPending");
11162
11163 if (json_nexthop_global || json_nexthop_ll) {
11164 json_nexthops = json_object_new_array();
11165
11166 if (json_nexthop_global)
11167 json_object_array_add(json_nexthops,
11168 json_nexthop_global);
11169
11170 if (json_nexthop_ll)
11171 json_object_array_add(json_nexthops,
11172 json_nexthop_ll);
11173
11174 json_object_object_add(json_path, "nexthops",
11175 json_nexthops);
11176 }
11177
11178 json_object_object_add(json_path, "peer", json_peer);
11179 json_object_array_add(json_paths, json_path);
11180 }
11181 }
11182
11183 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11184 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11185 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11186
11187 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11188 afi_t afi, safi_t safi, enum bgp_show_type type,
11189 bool use_json);
11190 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11191 const char *comstr, int exact, afi_t afi,
11192 safi_t safi, uint16_t show_flags);
11193
11194 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11195 struct bgp_table *table, enum bgp_show_type type,
11196 void *output_arg, const char *rd, int is_last,
11197 unsigned long *output_cum, unsigned long *total_cum,
11198 unsigned long *json_header_depth, uint16_t show_flags,
11199 enum rpki_states rpki_target_state)
11200 {
11201 struct bgp_path_info *pi;
11202 struct bgp_dest *dest;
11203 bool header = true;
11204 bool json_detail_header = false;
11205 int display;
11206 unsigned long output_count = 0;
11207 unsigned long total_count = 0;
11208 struct prefix *p;
11209 json_object *json_paths = NULL;
11210 int first = 1;
11211 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11212 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11213 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11214 bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
11215 bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
11216
11217 if (output_cum && *output_cum != 0)
11218 header = false;
11219
11220 if (use_json && !*json_header_depth) {
11221 if (all)
11222 *json_header_depth = 1;
11223 else {
11224 vty_out(vty, "{\n");
11225 *json_header_depth = 2;
11226 }
11227
11228 vty_out(vty,
11229 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11230 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11231 " \"localAS\": %u,\n \"routes\": { ",
11232 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11233 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11234 ? VRF_DEFAULT_NAME
11235 : bgp->name,
11236 table->version, &bgp->router_id,
11237 bgp->default_local_pref, bgp->as);
11238 if (rd) {
11239 vty_out(vty, " \"routeDistinguishers\" : {");
11240 ++*json_header_depth;
11241 }
11242 }
11243
11244 if (use_json && rd) {
11245 vty_out(vty, " \"%s\" : { ", rd);
11246 }
11247
11248 /* Check for 'json detail', where we need header output once per dest */
11249 if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
11250 type != bgp_show_type_damp_neighbor &&
11251 type != bgp_show_type_flap_statistics &&
11252 type != bgp_show_type_flap_neighbor)
11253 json_detail_header = true;
11254
11255 /* Start processing of routes. */
11256 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11257 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11258 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11259 bool json_detail = json_detail_header;
11260
11261 pi = bgp_dest_get_bgp_path_info(dest);
11262 if (pi == NULL)
11263 continue;
11264
11265 display = 0;
11266 if (use_json)
11267 json_paths = json_object_new_array();
11268 else
11269 json_paths = NULL;
11270
11271 for (; pi; pi = pi->next) {
11272 struct community *picomm = NULL;
11273
11274 picomm = bgp_attr_get_community(pi->attr);
11275
11276 total_count++;
11277
11278 if (type == bgp_show_type_prefix_version) {
11279 uint32_t version =
11280 strtoul(output_arg, NULL, 10);
11281 if (dest->version < version)
11282 continue;
11283 }
11284
11285 if (type == bgp_show_type_community_alias) {
11286 char *alias = output_arg;
11287 char **communities;
11288 int num;
11289 bool found = false;
11290
11291 if (picomm) {
11292 frrstr_split(picomm->str, " ",
11293 &communities, &num);
11294 for (int i = 0; i < num; i++) {
11295 const char *com2alias =
11296 bgp_community2alias(
11297 communities[i]);
11298 if (!found
11299 && strcmp(alias, com2alias)
11300 == 0)
11301 found = true;
11302 XFREE(MTYPE_TMP,
11303 communities[i]);
11304 }
11305 XFREE(MTYPE_TMP, communities);
11306 }
11307
11308 if (!found &&
11309 bgp_attr_get_lcommunity(pi->attr)) {
11310 frrstr_split(bgp_attr_get_lcommunity(
11311 pi->attr)
11312 ->str,
11313 " ", &communities, &num);
11314 for (int i = 0; i < num; i++) {
11315 const char *com2alias =
11316 bgp_community2alias(
11317 communities[i]);
11318 if (!found
11319 && strcmp(alias, com2alias)
11320 == 0)
11321 found = true;
11322 XFREE(MTYPE_TMP,
11323 communities[i]);
11324 }
11325 XFREE(MTYPE_TMP, communities);
11326 }
11327
11328 if (!found)
11329 continue;
11330 }
11331
11332 if (type == bgp_show_type_rpki) {
11333 if (dest_p->family == AF_INET
11334 || dest_p->family == AF_INET6)
11335 rpki_curr_state = hook_call(
11336 bgp_rpki_prefix_status,
11337 pi->peer, pi->attr, dest_p);
11338 if (rpki_target_state != RPKI_NOT_BEING_USED
11339 && rpki_curr_state != rpki_target_state)
11340 continue;
11341 }
11342
11343 if (type == bgp_show_type_flap_statistics
11344 || type == bgp_show_type_flap_neighbor
11345 || type == bgp_show_type_dampend_paths
11346 || type == bgp_show_type_damp_neighbor) {
11347 if (!(pi->extra && pi->extra->damp_info))
11348 continue;
11349 }
11350 if (type == bgp_show_type_regexp) {
11351 regex_t *regex = output_arg;
11352
11353 if (bgp_regexec(regex, pi->attr->aspath)
11354 == REG_NOMATCH)
11355 continue;
11356 }
11357 if (type == bgp_show_type_prefix_list) {
11358 struct prefix_list *plist = output_arg;
11359
11360 if (prefix_list_apply(plist, dest_p)
11361 != PREFIX_PERMIT)
11362 continue;
11363 }
11364 if (type == bgp_show_type_access_list) {
11365 struct access_list *alist = output_arg;
11366
11367 if (access_list_apply(alist, dest_p) !=
11368 FILTER_PERMIT)
11369 continue;
11370 }
11371 if (type == bgp_show_type_filter_list) {
11372 struct as_list *as_list = output_arg;
11373
11374 if (as_list_apply(as_list, pi->attr->aspath)
11375 != AS_FILTER_PERMIT)
11376 continue;
11377 }
11378 if (type == bgp_show_type_route_map) {
11379 struct route_map *rmap = output_arg;
11380 struct bgp_path_info path;
11381 struct bgp_path_info_extra extra;
11382 struct attr dummy_attr = {};
11383 route_map_result_t ret;
11384
11385 dummy_attr = *pi->attr;
11386
11387 prep_for_rmap_apply(&path, &extra, dest, pi,
11388 pi->peer, &dummy_attr);
11389
11390 ret = route_map_apply(rmap, dest_p, &path);
11391 bgp_attr_flush(&dummy_attr);
11392 if (ret == RMAP_DENYMATCH)
11393 continue;
11394 }
11395 if (type == bgp_show_type_neighbor
11396 || type == bgp_show_type_flap_neighbor
11397 || type == bgp_show_type_damp_neighbor) {
11398 union sockunion *su = output_arg;
11399
11400 if (pi->peer == NULL
11401 || pi->peer->su_remote == NULL
11402 || !sockunion_same(pi->peer->su_remote, su))
11403 continue;
11404 }
11405 if (type == bgp_show_type_cidr_only) {
11406 uint32_t destination;
11407
11408 destination = ntohl(dest_p->u.prefix4.s_addr);
11409 if (IN_CLASSC(destination)
11410 && dest_p->prefixlen == 24)
11411 continue;
11412 if (IN_CLASSB(destination)
11413 && dest_p->prefixlen == 16)
11414 continue;
11415 if (IN_CLASSA(destination)
11416 && dest_p->prefixlen == 8)
11417 continue;
11418 }
11419 if (type == bgp_show_type_prefix_longer) {
11420 p = output_arg;
11421 if (!prefix_match(p, dest_p))
11422 continue;
11423 }
11424 if (type == bgp_show_type_community_all) {
11425 if (!picomm)
11426 continue;
11427 }
11428 if (type == bgp_show_type_community) {
11429 struct community *com = output_arg;
11430
11431 if (!picomm || !community_match(picomm, com))
11432 continue;
11433 }
11434 if (type == bgp_show_type_community_exact) {
11435 struct community *com = output_arg;
11436
11437 if (!picomm || !community_cmp(picomm, com))
11438 continue;
11439 }
11440 if (type == bgp_show_type_community_list) {
11441 struct community_list *list = output_arg;
11442
11443 if (!community_list_match(picomm, list))
11444 continue;
11445 }
11446 if (type == bgp_show_type_community_list_exact) {
11447 struct community_list *list = output_arg;
11448
11449 if (!community_list_exact_match(picomm, list))
11450 continue;
11451 }
11452 if (type == bgp_show_type_lcommunity) {
11453 struct lcommunity *lcom = output_arg;
11454
11455 if (!bgp_attr_get_lcommunity(pi->attr) ||
11456 !lcommunity_match(
11457 bgp_attr_get_lcommunity(pi->attr),
11458 lcom))
11459 continue;
11460 }
11461
11462 if (type == bgp_show_type_lcommunity_exact) {
11463 struct lcommunity *lcom = output_arg;
11464
11465 if (!bgp_attr_get_lcommunity(pi->attr) ||
11466 !lcommunity_cmp(
11467 bgp_attr_get_lcommunity(pi->attr),
11468 lcom))
11469 continue;
11470 }
11471 if (type == bgp_show_type_lcommunity_list) {
11472 struct community_list *list = output_arg;
11473
11474 if (!lcommunity_list_match(
11475 bgp_attr_get_lcommunity(pi->attr),
11476 list))
11477 continue;
11478 }
11479 if (type
11480 == bgp_show_type_lcommunity_list_exact) {
11481 struct community_list *list = output_arg;
11482
11483 if (!lcommunity_list_exact_match(
11484 bgp_attr_get_lcommunity(pi->attr),
11485 list))
11486 continue;
11487 }
11488 if (type == bgp_show_type_lcommunity_all) {
11489 if (!bgp_attr_get_lcommunity(pi->attr))
11490 continue;
11491 }
11492 if (type == bgp_show_type_dampend_paths
11493 || type == bgp_show_type_damp_neighbor) {
11494 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11495 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11496 continue;
11497 }
11498
11499 if (!use_json && header) {
11500 vty_out(vty,
11501 "BGP table version is %" PRIu64
11502 ", local router ID is %pI4, vrf id ",
11503 table->version, &bgp->router_id);
11504 if (bgp->vrf_id == VRF_UNKNOWN)
11505 vty_out(vty, "%s", VRFID_NONE_STR);
11506 else
11507 vty_out(vty, "%u", bgp->vrf_id);
11508 vty_out(vty, "\n");
11509 vty_out(vty, "Default local pref %u, ",
11510 bgp->default_local_pref);
11511 vty_out(vty, "local AS %u\n", bgp->as);
11512 if (!detail_routes) {
11513 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11514 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11515 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11516 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11517 }
11518 if (type == bgp_show_type_dampend_paths
11519 || type == bgp_show_type_damp_neighbor)
11520 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11521 else if (type == bgp_show_type_flap_statistics
11522 || type == bgp_show_type_flap_neighbor)
11523 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11524 else if (!detail_routes)
11525 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11526 : BGP_SHOW_HEADER));
11527 header = false;
11528
11529 } else if (json_detail && json_paths != NULL) {
11530 const struct prefix_rd *prd;
11531 json_object *jtemp;
11532
11533 /* Use common detail header, for most types;
11534 * need a json 'object'.
11535 */
11536
11537 jtemp = json_object_new_object();
11538 prd = bgp_rd_from_dest(dest, safi);
11539
11540 route_vty_out_detail_header(
11541 vty, bgp, dest,
11542 bgp_dest_get_prefix(dest), prd,
11543 table->afi, safi, jtemp);
11544
11545 json_object_array_add(json_paths, jtemp);
11546
11547 json_detail = false;
11548 }
11549
11550 if (rd != NULL && !display && !output_count) {
11551 if (!use_json)
11552 vty_out(vty,
11553 "Route Distinguisher: %s\n",
11554 rd);
11555 }
11556 if (type == bgp_show_type_dampend_paths
11557 || type == bgp_show_type_damp_neighbor)
11558 damp_route_vty_out(vty, dest_p, pi, display,
11559 AFI_IP, safi, use_json,
11560 json_paths);
11561 else if (type == bgp_show_type_flap_statistics
11562 || type == bgp_show_type_flap_neighbor)
11563 flap_route_vty_out(vty, dest_p, pi, display,
11564 AFI_IP, safi, use_json,
11565 json_paths);
11566 else {
11567 if (detail_routes || detail_json) {
11568 const struct prefix_rd *prd = NULL;
11569
11570 if (dest->pdest)
11571 prd = bgp_rd_from_dest(
11572 dest->pdest, safi);
11573
11574 if (!use_json)
11575 route_vty_out_detail_header(
11576 vty, bgp, dest,
11577 bgp_dest_get_prefix(
11578 dest),
11579 prd, table->afi, safi,
11580 NULL);
11581
11582 route_vty_out_detail(
11583 vty, bgp, dest, dest_p, pi,
11584 family2afi(dest_p->family),
11585 safi, RPKI_NOT_BEING_USED,
11586 json_paths);
11587 } else {
11588 route_vty_out(vty, dest_p, pi, display,
11589 safi, json_paths, wide);
11590 }
11591 }
11592 display++;
11593 }
11594
11595 if (display) {
11596 output_count++;
11597 if (!use_json)
11598 continue;
11599
11600 /* encode prefix */
11601 if (dest_p->family == AF_FLOWSPEC) {
11602 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11603
11604
11605 bgp_fs_nlri_get_string(
11606 (unsigned char *)
11607 dest_p->u.prefix_flowspec.ptr,
11608 dest_p->u.prefix_flowspec.prefixlen,
11609 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11610 family2afi(dest_p->u
11611 .prefix_flowspec.family));
11612 if (first)
11613 vty_out(vty, "\"%s/%d\": ", retstr,
11614 dest_p->u.prefix_flowspec
11615 .prefixlen);
11616 else
11617 vty_out(vty, ",\"%s/%d\": ", retstr,
11618 dest_p->u.prefix_flowspec
11619 .prefixlen);
11620 } else {
11621 if (first)
11622 vty_out(vty, "\"%pFX\": ", dest_p);
11623 else
11624 vty_out(vty, ",\"%pFX\": ", dest_p);
11625 }
11626 vty_json(vty, json_paths);
11627 json_paths = NULL;
11628 first = 0;
11629 } else
11630 json_object_free(json_paths);
11631 }
11632
11633 if (output_cum) {
11634 output_count += *output_cum;
11635 *output_cum = output_count;
11636 }
11637 if (total_cum) {
11638 total_count += *total_cum;
11639 *total_cum = total_count;
11640 }
11641 if (use_json) {
11642 if (rd) {
11643 vty_out(vty, " }%s ", (is_last ? "" : ","));
11644 }
11645 if (is_last) {
11646 unsigned long i;
11647 for (i = 0; i < *json_header_depth; ++i)
11648 vty_out(vty, " } ");
11649 if (!all)
11650 vty_out(vty, "\n");
11651 }
11652 } else {
11653 if (is_last) {
11654 /* No route is displayed */
11655 if (output_count == 0) {
11656 if (type == bgp_show_type_normal)
11657 vty_out(vty,
11658 "No BGP prefixes displayed, %ld exist\n",
11659 total_count);
11660 } else
11661 vty_out(vty,
11662 "\nDisplayed %ld routes and %ld total paths\n",
11663 output_count, total_count);
11664 }
11665 }
11666
11667 return CMD_SUCCESS;
11668 }
11669
11670 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11671 struct bgp_table *table, struct prefix_rd *prd_match,
11672 enum bgp_show_type type, void *output_arg,
11673 uint16_t show_flags)
11674 {
11675 struct bgp_dest *dest, *next;
11676 unsigned long output_cum = 0;
11677 unsigned long total_cum = 0;
11678 unsigned long json_header_depth = 0;
11679 struct bgp_table *itable;
11680 bool show_msg;
11681 bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11682
11683 show_msg = (!use_json && type == bgp_show_type_normal);
11684
11685 for (dest = bgp_table_top(table); dest; dest = next) {
11686 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11687
11688 next = bgp_route_next(dest);
11689 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11690 continue;
11691
11692 itable = bgp_dest_get_bgp_table_info(dest);
11693 if (itable != NULL) {
11694 struct prefix_rd prd;
11695 char rd[RD_ADDRSTRLEN];
11696
11697 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11698 prefix_rd2str(&prd, rd, sizeof(rd));
11699 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11700 rd, next == NULL, &output_cum,
11701 &total_cum, &json_header_depth,
11702 show_flags, RPKI_NOT_BEING_USED);
11703 if (next == NULL)
11704 show_msg = false;
11705 }
11706 }
11707 if (show_msg) {
11708 if (output_cum == 0)
11709 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11710 total_cum);
11711 else
11712 vty_out(vty,
11713 "\nDisplayed %ld routes and %ld total paths\n",
11714 output_cum, total_cum);
11715 } else {
11716 if (use_json && output_cum == 0)
11717 vty_out(vty, "{}\n");
11718 }
11719 return CMD_SUCCESS;
11720 }
11721
11722 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11723 enum bgp_show_type type, void *output_arg,
11724 uint16_t show_flags, enum rpki_states rpki_target_state)
11725 {
11726 struct bgp_table *table;
11727 unsigned long json_header_depth = 0;
11728 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11729
11730 if (bgp == NULL) {
11731 bgp = bgp_get_default();
11732 }
11733
11734 if (bgp == NULL) {
11735 if (!use_json)
11736 vty_out(vty, "No BGP process is configured\n");
11737 else
11738 vty_out(vty, "{}\n");
11739 return CMD_WARNING;
11740 }
11741
11742 /* Labeled-unicast routes live in the unicast table. */
11743 if (safi == SAFI_LABELED_UNICAST)
11744 safi = SAFI_UNICAST;
11745
11746 table = bgp->rib[afi][safi];
11747 /* use MPLS and ENCAP specific shows until they are merged */
11748 if (safi == SAFI_MPLS_VPN) {
11749 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11750 output_arg, show_flags);
11751 }
11752
11753 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11754 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11755 output_arg, use_json,
11756 1, NULL, NULL);
11757 }
11758
11759 if (safi == SAFI_EVPN)
11760 return bgp_evpn_show_all_routes(vty, bgp, type, use_json, 0);
11761
11762 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11763 NULL, NULL, &json_header_depth, show_flags,
11764 rpki_target_state);
11765 }
11766
11767 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11768 safi_t safi, uint16_t show_flags)
11769 {
11770 struct listnode *node, *nnode;
11771 struct bgp *bgp;
11772 int is_first = 1;
11773 bool route_output = false;
11774 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11775
11776 if (use_json)
11777 vty_out(vty, "{\n");
11778
11779 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11780 route_output = true;
11781 if (use_json) {
11782 if (!is_first)
11783 vty_out(vty, ",\n");
11784 else
11785 is_first = 0;
11786
11787 vty_out(vty, "\"%s\":",
11788 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11789 ? VRF_DEFAULT_NAME
11790 : bgp->name);
11791 } else {
11792 vty_out(vty, "\nInstance %s:\n",
11793 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11794 ? VRF_DEFAULT_NAME
11795 : bgp->name);
11796 }
11797 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11798 show_flags, RPKI_NOT_BEING_USED);
11799 }
11800
11801 if (use_json)
11802 vty_out(vty, "}\n");
11803 else if (!route_output)
11804 vty_out(vty, "%% BGP instance not found\n");
11805 }
11806
11807 /* Header of detailed BGP route information */
11808 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11809 struct bgp_dest *dest, const struct prefix *p,
11810 const struct prefix_rd *prd, afi_t afi,
11811 safi_t safi, json_object *json)
11812 {
11813 struct bgp_path_info *pi;
11814 struct peer *peer;
11815 struct listnode *node, *nnode;
11816 char buf1[RD_ADDRSTRLEN];
11817 int count = 0;
11818 int best = 0;
11819 int suppress = 0;
11820 int accept_own = 0;
11821 int route_filter_translated_v4 = 0;
11822 int route_filter_v4 = 0;
11823 int route_filter_translated_v6 = 0;
11824 int route_filter_v6 = 0;
11825 int llgr_stale = 0;
11826 int no_llgr = 0;
11827 int accept_own_nexthop = 0;
11828 int blackhole = 0;
11829 int no_export = 0;
11830 int no_advertise = 0;
11831 int local_as = 0;
11832 int no_peer = 0;
11833 int first = 1;
11834 int has_valid_label = 0;
11835 mpls_label_t label = 0;
11836 json_object *json_adv_to = NULL;
11837 uint32_t ttl = 0;
11838 uint32_t bos = 0;
11839 uint32_t exp = 0;
11840
11841 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11842
11843 has_valid_label = bgp_is_valid_label(&label);
11844
11845 if (safi == SAFI_EVPN) {
11846 if (!json) {
11847 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11848 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
11849 : "",
11850 prd ? ":" : "", (struct prefix_evpn *)p);
11851 } else {
11852 json_object_string_add(json, "rd",
11853 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11854 "");
11855 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11856 }
11857 } else {
11858 if (!json) {
11859 vty_out(vty,
11860 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11861 "\n",
11862 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11863 ? prefix_rd2str(prd, buf1,
11864 sizeof(buf1))
11865 : ""),
11866 safi == SAFI_MPLS_VPN ? ":" : "", p,
11867 dest->version);
11868
11869 } else {
11870 json_object_string_addf(json, "prefix", "%pFX", p);
11871 json_object_int_add(json, "version", dest->version);
11872
11873 }
11874 }
11875
11876 if (has_valid_label) {
11877 if (json)
11878 json_object_int_add(json, "localLabel", label);
11879 else
11880 vty_out(vty, "Local label: %d\n", label);
11881 }
11882
11883 if (!json)
11884 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11885 vty_out(vty, "not allocated\n");
11886
11887 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11888 struct community *picomm = NULL;
11889
11890 picomm = bgp_attr_get_community(pi->attr);
11891
11892 count++;
11893 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11894 best = count;
11895 if (bgp_path_suppressed(pi))
11896 suppress = 1;
11897
11898 if (!picomm)
11899 continue;
11900
11901 no_advertise += community_include(
11902 picomm, COMMUNITY_NO_ADVERTISE);
11903 no_export +=
11904 community_include(picomm, COMMUNITY_NO_EXPORT);
11905 local_as +=
11906 community_include(picomm, COMMUNITY_LOCAL_AS);
11907 accept_own +=
11908 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11909 route_filter_translated_v4 += community_include(
11910 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11911 route_filter_translated_v6 += community_include(
11912 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11913 route_filter_v4 += community_include(
11914 picomm, COMMUNITY_ROUTE_FILTER_v4);
11915 route_filter_v6 += community_include(
11916 picomm, COMMUNITY_ROUTE_FILTER_v6);
11917 llgr_stale +=
11918 community_include(picomm, COMMUNITY_LLGR_STALE);
11919 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11920 accept_own_nexthop += community_include(
11921 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11922 blackhole +=
11923 community_include(picomm, COMMUNITY_BLACKHOLE);
11924 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11925 }
11926 }
11927
11928 if (!json) {
11929 vty_out(vty, "Paths: (%d available", count);
11930 if (best) {
11931 vty_out(vty, ", best #%d", best);
11932 if (safi == SAFI_UNICAST) {
11933 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11934 vty_out(vty, ", table %s",
11935 VRF_DEFAULT_NAME);
11936 else
11937 vty_out(vty, ", vrf %s",
11938 bgp->name);
11939 }
11940 } else
11941 vty_out(vty, ", no best path");
11942
11943 if (accept_own)
11944 vty_out(vty,
11945 ", accept own local route exported and imported in different VRF");
11946 else if (route_filter_translated_v4)
11947 vty_out(vty,
11948 ", mark translated RTs for VPNv4 route filtering");
11949 else if (route_filter_v4)
11950 vty_out(vty,
11951 ", attach RT as-is for VPNv4 route filtering");
11952 else if (route_filter_translated_v6)
11953 vty_out(vty,
11954 ", mark translated RTs for VPNv6 route filtering");
11955 else if (route_filter_v6)
11956 vty_out(vty,
11957 ", attach RT as-is for VPNv6 route filtering");
11958 else if (llgr_stale)
11959 vty_out(vty,
11960 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
11961 else if (no_llgr)
11962 vty_out(vty,
11963 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11964 else if (accept_own_nexthop)
11965 vty_out(vty,
11966 ", accept local nexthop");
11967 else if (blackhole)
11968 vty_out(vty, ", inform peer to blackhole prefix");
11969 else if (no_export)
11970 vty_out(vty, ", not advertised to EBGP peer");
11971 else if (no_advertise)
11972 vty_out(vty, ", not advertised to any peer");
11973 else if (local_as)
11974 vty_out(vty, ", not advertised outside local AS");
11975 else if (no_peer)
11976 vty_out(vty,
11977 ", inform EBGP peer not to advertise to their EBGP peers");
11978
11979 if (suppress)
11980 vty_out(vty,
11981 ", Advertisements suppressed by an aggregate.");
11982 vty_out(vty, ")\n");
11983 }
11984
11985 /* If we are not using addpath then we can display Advertised to and
11986 * that will
11987 * show what peers we advertised the bestpath to. If we are using
11988 * addpath
11989 * though then we must display Advertised to on a path-by-path basis. */
11990 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11991 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11992 if (bgp_adj_out_lookup(peer, dest, 0)) {
11993 if (json && !json_adv_to)
11994 json_adv_to = json_object_new_object();
11995
11996 route_vty_out_advertised_to(
11997 vty, peer, &first,
11998 " Advertised to non peer-group peers:\n ",
11999 json_adv_to);
12000 }
12001 }
12002
12003 if (json) {
12004 if (json_adv_to) {
12005 json_object_object_add(json, "advertisedTo",
12006 json_adv_to);
12007 }
12008 } else {
12009 if (first)
12010 vty_out(vty, " Not advertised to any peer");
12011 vty_out(vty, "\n");
12012 }
12013 }
12014 }
12015
12016 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
12017 struct bgp_dest *bgp_node, struct vty *vty,
12018 struct bgp *bgp, afi_t afi, safi_t safi,
12019 json_object *json, enum bgp_path_type pathtype,
12020 int *display, enum rpki_states rpki_target_state)
12021 {
12022 struct bgp_path_info *pi;
12023 int header = 1;
12024 json_object *json_header = NULL;
12025 json_object *json_paths = NULL;
12026 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
12027
12028 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
12029 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
12030
12031 if (p->family == AF_INET || p->family == AF_INET6)
12032 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
12033 pi->peer, pi->attr, p);
12034
12035 if (rpki_target_state != RPKI_NOT_BEING_USED
12036 && rpki_curr_state != rpki_target_state)
12037 continue;
12038
12039 if (json && !json_paths) {
12040 /* Instantiate json_paths only if path is valid */
12041 json_paths = json_object_new_array();
12042 if (pfx_rd)
12043 json_header = json_object_new_object();
12044 else
12045 json_header = json;
12046 }
12047
12048 if (header) {
12049 route_vty_out_detail_header(
12050 vty, bgp, bgp_node,
12051 bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP,
12052 safi, json_header);
12053 header = 0;
12054 }
12055 (*display)++;
12056
12057 if (pathtype == BGP_PATH_SHOW_ALL
12058 || (pathtype == BGP_PATH_SHOW_BESTPATH
12059 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12060 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12061 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12062 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12063 route_vty_out_detail(vty, bgp, bgp_node,
12064 bgp_dest_get_prefix(bgp_node), pi,
12065 AFI_IP, safi, rpki_curr_state,
12066 json_paths);
12067 }
12068
12069 if (json && json_paths) {
12070 json_object_object_add(json_header, "paths", json_paths);
12071
12072 if (pfx_rd)
12073 json_object_object_addf(json, json_header, "%pRD",
12074 pfx_rd);
12075 }
12076 }
12077
12078 /*
12079 * Return rd based on safi
12080 */
12081 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12082 safi_t safi)
12083 {
12084 switch (safi) {
12085 case SAFI_MPLS_VPN:
12086 case SAFI_ENCAP:
12087 case SAFI_EVPN:
12088 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12089 default:
12090 return NULL;
12091 }
12092 }
12093
12094 /* Display specified route of BGP table. */
12095 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12096 struct bgp_table *rib, const char *ip_str,
12097 afi_t afi, safi_t safi,
12098 enum rpki_states rpki_target_state,
12099 struct prefix_rd *prd, int prefix_check,
12100 enum bgp_path_type pathtype, bool use_json)
12101 {
12102 int ret;
12103 int display = 0;
12104 struct prefix match;
12105 struct bgp_dest *dest;
12106 struct bgp_dest *rm;
12107 struct bgp_table *table;
12108 json_object *json = NULL;
12109 json_object *json_paths = NULL;
12110
12111 /* Check IP address argument. */
12112 ret = str2prefix(ip_str, &match);
12113 if (!ret) {
12114 vty_out(vty, "address is malformed\n");
12115 return CMD_WARNING;
12116 }
12117
12118 match.family = afi2family(afi);
12119
12120 if (use_json)
12121 json = json_object_new_object();
12122
12123 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12124 for (dest = bgp_table_top(rib); dest;
12125 dest = bgp_route_next(dest)) {
12126 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12127
12128 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12129 continue;
12130 table = bgp_dest_get_bgp_table_info(dest);
12131 if (!table)
12132 continue;
12133
12134 rm = bgp_node_match(table, &match);
12135 if (rm == NULL)
12136 continue;
12137
12138 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12139 if (prefix_check
12140 && rm_p->prefixlen != match.prefixlen) {
12141 bgp_dest_unlock_node(rm);
12142 continue;
12143 }
12144
12145 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12146 bgp, afi, safi, json, pathtype,
12147 &display, rpki_target_state);
12148
12149 bgp_dest_unlock_node(rm);
12150 }
12151 } else if (safi == SAFI_EVPN) {
12152 struct bgp_dest *longest_pfx;
12153 bool is_exact_pfxlen_match = false;
12154
12155 for (dest = bgp_table_top(rib); dest;
12156 dest = bgp_route_next(dest)) {
12157 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12158
12159 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12160 continue;
12161 table = bgp_dest_get_bgp_table_info(dest);
12162 if (!table)
12163 continue;
12164
12165 longest_pfx = NULL;
12166 is_exact_pfxlen_match = false;
12167 /*
12168 * Search through all the prefixes for a match. The
12169 * pfx's are enumerated in ascending order of pfxlens.
12170 * So, the last pfx match is the longest match. Set
12171 * is_exact_pfxlen_match when we get exact pfxlen match
12172 */
12173 for (rm = bgp_table_top(table); rm;
12174 rm = bgp_route_next(rm)) {
12175 const struct prefix *rm_p =
12176 bgp_dest_get_prefix(rm);
12177 /*
12178 * Get prefixlen of the ip-prefix within type5
12179 * evpn route
12180 */
12181 if (evpn_type5_prefix_match(rm_p, &match)
12182 && rm->info) {
12183 longest_pfx = rm;
12184 int type5_pfxlen =
12185 bgp_evpn_get_type5_prefixlen(
12186 rm_p);
12187 if (type5_pfxlen == match.prefixlen) {
12188 is_exact_pfxlen_match = true;
12189 bgp_dest_unlock_node(rm);
12190 break;
12191 }
12192 }
12193 }
12194
12195 if (!longest_pfx)
12196 continue;
12197
12198 if (prefix_check && !is_exact_pfxlen_match)
12199 continue;
12200
12201 rm = longest_pfx;
12202 bgp_dest_lock_node(rm);
12203
12204 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12205 bgp, afi, safi, json, pathtype,
12206 &display, rpki_target_state);
12207
12208 bgp_dest_unlock_node(rm);
12209 }
12210 } else if (safi == SAFI_FLOWSPEC) {
12211 if (use_json)
12212 json_paths = json_object_new_array();
12213
12214 display = bgp_flowspec_display_match_per_ip(afi, rib,
12215 &match, prefix_check,
12216 vty,
12217 use_json,
12218 json_paths);
12219 if (use_json) {
12220 if (display)
12221 json_object_object_add(json, "paths",
12222 json_paths);
12223 else
12224 json_object_free(json_paths);
12225 }
12226 } else {
12227 dest = bgp_node_match(rib, &match);
12228 if (dest != NULL) {
12229 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12230 if (!prefix_check
12231 || dest_p->prefixlen == match.prefixlen) {
12232 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12233 safi, json, pathtype,
12234 &display, rpki_target_state);
12235 }
12236
12237 bgp_dest_unlock_node(dest);
12238 }
12239 }
12240
12241 if (use_json) {
12242 vty_json(vty, json);
12243 } else {
12244 if (!display) {
12245 vty_out(vty, "%% Network not in table\n");
12246 return CMD_WARNING;
12247 }
12248 }
12249
12250 return CMD_SUCCESS;
12251 }
12252
12253 /* Display specified route of Main RIB */
12254 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12255 afi_t afi, safi_t safi, struct prefix_rd *prd,
12256 int prefix_check, enum bgp_path_type pathtype,
12257 enum rpki_states rpki_target_state, bool use_json)
12258 {
12259 if (!bgp) {
12260 bgp = bgp_get_default();
12261 if (!bgp) {
12262 if (!use_json)
12263 vty_out(vty, "No BGP process is configured\n");
12264 else
12265 vty_out(vty, "{}\n");
12266 return CMD_WARNING;
12267 }
12268 }
12269
12270 /* labeled-unicast routes live in the unicast table */
12271 if (safi == SAFI_LABELED_UNICAST)
12272 safi = SAFI_UNICAST;
12273
12274 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12275 afi, safi, rpki_target_state, prd,
12276 prefix_check, pathtype, use_json);
12277 }
12278
12279 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12280 struct cmd_token **argv, bool exact, afi_t afi,
12281 safi_t safi, bool uj)
12282 {
12283 struct lcommunity *lcom;
12284 struct buffer *b;
12285 int i;
12286 char *str;
12287 int first = 0;
12288 uint16_t show_flags = 0;
12289 int ret;
12290
12291 if (uj)
12292 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12293
12294 b = buffer_new(1024);
12295 for (i = 0; i < argc; i++) {
12296 if (first)
12297 buffer_putc(b, ' ');
12298 else {
12299 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12300 first = 1;
12301 buffer_putstr(b, argv[i]->arg);
12302 }
12303 }
12304 }
12305 buffer_putc(b, '\0');
12306
12307 str = buffer_getstr(b);
12308 buffer_free(b);
12309
12310 lcom = lcommunity_str2com(str);
12311 XFREE(MTYPE_TMP, str);
12312 if (!lcom) {
12313 vty_out(vty, "%% Large-community malformed\n");
12314 return CMD_WARNING;
12315 }
12316
12317 ret = bgp_show(vty, bgp, afi, safi,
12318 (exact ? bgp_show_type_lcommunity_exact
12319 : bgp_show_type_lcommunity),
12320 lcom, show_flags, RPKI_NOT_BEING_USED);
12321
12322 lcommunity_free(&lcom);
12323 return ret;
12324 }
12325
12326 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12327 const char *lcom, bool exact, afi_t afi,
12328 safi_t safi, bool uj)
12329 {
12330 struct community_list *list;
12331 uint16_t show_flags = 0;
12332
12333 if (uj)
12334 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12335
12336
12337 list = community_list_lookup(bgp_clist, lcom, 0,
12338 LARGE_COMMUNITY_LIST_MASTER);
12339 if (list == NULL) {
12340 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12341 lcom);
12342 return CMD_WARNING;
12343 }
12344
12345 return bgp_show(vty, bgp, afi, safi,
12346 (exact ? bgp_show_type_lcommunity_list_exact
12347 : bgp_show_type_lcommunity_list),
12348 list, show_flags, RPKI_NOT_BEING_USED);
12349 }
12350
12351 DEFUN (show_ip_bgp_large_community_list,
12352 show_ip_bgp_large_community_list_cmd,
12353 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community-list <(1-500)|LCOMMUNITY_LIST_NAME> [exact-match] [json]",
12354 SHOW_STR
12355 IP_STR
12356 BGP_STR
12357 BGP_INSTANCE_HELP_STR
12358 BGP_AFI_HELP_STR
12359 BGP_SAFI_WITH_LABEL_HELP_STR
12360 "Display routes matching the large-community-list\n"
12361 "large-community-list number\n"
12362 "large-community-list name\n"
12363 "Exact match of the large-communities\n"
12364 JSON_STR)
12365 {
12366 afi_t afi = AFI_IP6;
12367 safi_t safi = SAFI_UNICAST;
12368 int idx = 0;
12369 bool exact_match = 0;
12370 struct bgp *bgp = NULL;
12371 bool uj = use_json(argc, argv);
12372
12373 if (uj)
12374 argc--;
12375
12376 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12377 &bgp, uj);
12378 if (!idx)
12379 return CMD_WARNING;
12380
12381 argv_find(argv, argc, "large-community-list", &idx);
12382
12383 const char *clist_number_or_name = argv[++idx]->arg;
12384
12385 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12386 exact_match = 1;
12387
12388 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12389 exact_match, afi, safi, uj);
12390 }
12391 DEFUN (show_ip_bgp_large_community,
12392 show_ip_bgp_large_community_cmd,
12393 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12394 SHOW_STR
12395 IP_STR
12396 BGP_STR
12397 BGP_INSTANCE_HELP_STR
12398 BGP_AFI_HELP_STR
12399 BGP_SAFI_WITH_LABEL_HELP_STR
12400 "Display routes matching the large-communities\n"
12401 "List of large-community numbers\n"
12402 "Exact match of the large-communities\n"
12403 JSON_STR)
12404 {
12405 afi_t afi = AFI_IP6;
12406 safi_t safi = SAFI_UNICAST;
12407 int idx = 0;
12408 bool exact_match = 0;
12409 struct bgp *bgp = NULL;
12410 bool uj = use_json(argc, argv);
12411 uint16_t show_flags = 0;
12412
12413 if (uj) {
12414 argc--;
12415 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12416 }
12417
12418 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12419 &bgp, uj);
12420 if (!idx)
12421 return CMD_WARNING;
12422
12423 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12424 if (argv_find(argv, argc, "exact-match", &idx)) {
12425 argc--;
12426 exact_match = 1;
12427 }
12428 return bgp_show_lcommunity(vty, bgp, argc, argv,
12429 exact_match, afi, safi, uj);
12430 } else
12431 return bgp_show(vty, bgp, afi, safi,
12432 bgp_show_type_lcommunity_all, NULL, show_flags,
12433 RPKI_NOT_BEING_USED);
12434 }
12435
12436 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12437 safi_t safi, struct json_object *json_array);
12438 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12439 safi_t safi, struct json_object *json);
12440
12441
12442 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12443 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12444 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12445 "Display number of prefixes for all afi/safi\n" JSON_STR)
12446 {
12447 bool uj = use_json(argc, argv);
12448 struct bgp *bgp = NULL;
12449 safi_t safi = SAFI_UNICAST;
12450 afi_t afi = AFI_IP6;
12451 int idx = 0;
12452 struct json_object *json_all = NULL;
12453 struct json_object *json_afi_safi = NULL;
12454
12455 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12456 &bgp, false);
12457 if (!idx)
12458 return CMD_WARNING;
12459
12460 if (uj)
12461 json_all = json_object_new_object();
12462
12463 FOREACH_AFI_SAFI (afi, safi) {
12464 /*
12465 * So limit output to those afi/safi pairs that
12466 * actually have something interesting in them
12467 */
12468 if (strmatch(get_afi_safi_str(afi, safi, true),
12469 "Unknown")) {
12470 continue;
12471 }
12472 if (uj) {
12473 json_afi_safi = json_object_new_array();
12474 json_object_object_add(
12475 json_all,
12476 get_afi_safi_str(afi, safi, true),
12477 json_afi_safi);
12478 } else {
12479 json_afi_safi = NULL;
12480 }
12481
12482 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12483 }
12484
12485 if (uj)
12486 vty_json(vty, json_all);
12487
12488 return CMD_SUCCESS;
12489 }
12490
12491 /* BGP route print out function without JSON */
12492 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12493 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12494 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12495 SHOW_STR
12496 IP_STR
12497 BGP_STR
12498 BGP_INSTANCE_HELP_STR
12499 L2VPN_HELP_STR
12500 EVPN_HELP_STR
12501 "BGP RIB advertisement statistics\n"
12502 JSON_STR)
12503 {
12504 afi_t afi = AFI_IP6;
12505 safi_t safi = SAFI_UNICAST;
12506 struct bgp *bgp = NULL;
12507 int idx = 0, ret;
12508 bool uj = use_json(argc, argv);
12509 struct json_object *json_afi_safi = NULL, *json = NULL;
12510
12511 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12512 &bgp, false);
12513 if (!idx)
12514 return CMD_WARNING;
12515
12516 if (uj)
12517 json_afi_safi = json_object_new_array();
12518 else
12519 json_afi_safi = NULL;
12520
12521 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12522
12523 if (uj) {
12524 json = json_object_new_object();
12525 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12526 json_afi_safi);
12527 vty_json(vty, json);
12528 }
12529 return ret;
12530 }
12531
12532 /* BGP route print out function without JSON */
12533 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12534 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12535 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12536 "]]\
12537 statistics [json]",
12538 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12539 BGP_SAFI_WITH_LABEL_HELP_STR
12540 "BGP RIB advertisement statistics\n" JSON_STR)
12541 {
12542 afi_t afi = AFI_IP6;
12543 safi_t safi = SAFI_UNICAST;
12544 struct bgp *bgp = NULL;
12545 int idx = 0, ret;
12546 bool uj = use_json(argc, argv);
12547 struct json_object *json_afi_safi = NULL, *json = NULL;
12548
12549 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12550 &bgp, false);
12551 if (!idx)
12552 return CMD_WARNING;
12553
12554 if (uj)
12555 json_afi_safi = json_object_new_array();
12556 else
12557 json_afi_safi = NULL;
12558
12559 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12560
12561 if (uj) {
12562 json = json_object_new_object();
12563 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12564 json_afi_safi);
12565 vty_json(vty, json);
12566 }
12567 return ret;
12568 }
12569
12570 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12571 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12572 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12573 "]] [all$all] dampening parameters [json]",
12574 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12575 BGP_SAFI_WITH_LABEL_HELP_STR
12576 "Display the entries for all address families\n"
12577 "Display detailed information about dampening\n"
12578 "Display detail of configured dampening parameters\n"
12579 JSON_STR)
12580 {
12581 afi_t afi = AFI_IP6;
12582 safi_t safi = SAFI_UNICAST;
12583 struct bgp *bgp = NULL;
12584 int idx = 0;
12585 uint16_t show_flags = 0;
12586 bool uj = use_json(argc, argv);
12587
12588 if (uj) {
12589 argc--;
12590 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12591 }
12592
12593 /* [<ipv4|ipv6> [all]] */
12594 if (all) {
12595 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12596 if (argv_find(argv, argc, "ipv4", &idx))
12597 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12598
12599 if (argv_find(argv, argc, "ipv6", &idx))
12600 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12601 }
12602
12603 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12604 &bgp, false);
12605 if (!idx)
12606 return CMD_WARNING;
12607
12608 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12609 }
12610
12611 /* BGP route print out function */
12612 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12613 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12614 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12615 "]]\
12616 [all$all]\
12617 [cidr-only\
12618 |dampening <flap-statistics|dampened-paths>\
12619 |community [AA:NN|local-AS|no-advertise|no-export\
12620 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12621 |accept-own|accept-own-nexthop|route-filter-v6\
12622 |route-filter-v4|route-filter-translated-v6\
12623 |route-filter-translated-v4] [exact-match]\
12624 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12625 |filter-list AS_PATH_FILTER_NAME\
12626 |prefix-list WORD\
12627 |access-list ACCESSLIST_NAME\
12628 |route-map RMAP_NAME\
12629 |rpki <invalid|valid|notfound>\
12630 |version (1-4294967295)\
12631 |alias ALIAS_NAME\
12632 |A.B.C.D/M longer-prefixes\
12633 |X:X::X:X/M longer-prefixes\
12634 |detail-routes$detail_routes\
12635 ] [json$uj [detail$detail_json] | wide$wide]",
12636 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12637 BGP_SAFI_WITH_LABEL_HELP_STR
12638 "Display the entries for all address families\n"
12639 "Display only routes with non-natural netmasks\n"
12640 "Display detailed information about dampening\n"
12641 "Display flap statistics of routes\n"
12642 "Display paths suppressed due to dampening\n"
12643 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12644 "Do not send outside local AS (well-known community)\n"
12645 "Do not advertise to any peer (well-known community)\n"
12646 "Do not export to next AS (well-known community)\n"
12647 "Graceful shutdown (well-known community)\n"
12648 "Do not export to any peer (well-known community)\n"
12649 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12650 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12651 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12652 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12653 "Should accept VPN route with local nexthop (well-known community)\n"
12654 "RT VPNv6 route filtering (well-known community)\n"
12655 "RT VPNv4 route filtering (well-known community)\n"
12656 "RT translated VPNv6 route filtering (well-known community)\n"
12657 "RT translated VPNv4 route filtering (well-known community)\n"
12658 "Exact match of the communities\n"
12659 "Community-list number\n"
12660 "Community-list name\n"
12661 "Display routes matching the community-list\n"
12662 "Exact match of the communities\n"
12663 "Display routes conforming to the filter-list\n"
12664 "Regular expression access list name\n"
12665 "Display routes conforming to the prefix-list\n"
12666 "Prefix-list name\n"
12667 "Display routes conforming to the access-list\n"
12668 "Access-list name\n"
12669 "Display routes matching the route-map\n"
12670 "A route-map to match on\n"
12671 "RPKI route types\n"
12672 "A valid path as determined by rpki\n"
12673 "A invalid path as determined by rpki\n"
12674 "A path that has no rpki data\n"
12675 "Display prefixes with matching version numbers\n"
12676 "Version number and above\n"
12677 "Display prefixes with matching BGP community alias\n"
12678 "BGP community alias\n"
12679 "IPv4 prefix\n"
12680 "Display route and more specific routes\n"
12681 "IPv6 prefix\n"
12682 "Display route and more specific routes\n"
12683 "Display detailed version of all routes\n"
12684 JSON_STR
12685 "Display detailed version of JSON output\n"
12686 "Increase table width for longer prefixes\n")
12687 {
12688 afi_t afi = AFI_IP6;
12689 safi_t safi = SAFI_UNICAST;
12690 enum bgp_show_type sh_type = bgp_show_type_normal;
12691 void *output_arg = NULL;
12692 struct bgp *bgp = NULL;
12693 int idx = 0;
12694 int exact_match = 0;
12695 char *community = NULL;
12696 bool first = true;
12697 uint16_t show_flags = 0;
12698 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12699 struct prefix p;
12700
12701 if (uj) {
12702 argc--;
12703 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12704 }
12705
12706 if (detail_json)
12707 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
12708
12709 if (detail_routes)
12710 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
12711
12712 /* [<ipv4|ipv6> [all]] */
12713 if (all) {
12714 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12715
12716 if (argv_find(argv, argc, "ipv4", &idx))
12717 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12718
12719 if (argv_find(argv, argc, "ipv6", &idx))
12720 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12721 }
12722
12723 if (wide)
12724 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12725
12726 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12727 &bgp, uj);
12728 if (!idx)
12729 return CMD_WARNING;
12730
12731 if (argv_find(argv, argc, "cidr-only", &idx))
12732 sh_type = bgp_show_type_cidr_only;
12733
12734 if (argv_find(argv, argc, "dampening", &idx)) {
12735 if (argv_find(argv, argc, "dampened-paths", &idx))
12736 sh_type = bgp_show_type_dampend_paths;
12737 else if (argv_find(argv, argc, "flap-statistics", &idx))
12738 sh_type = bgp_show_type_flap_statistics;
12739 }
12740
12741 if (argv_find(argv, argc, "community", &idx)) {
12742 char *maybecomm = NULL;
12743
12744 if (idx + 1 < argc) {
12745 if (argv[idx + 1]->type == VARIABLE_TKN)
12746 maybecomm = argv[idx + 1]->arg;
12747 else
12748 maybecomm = argv[idx + 1]->text;
12749 }
12750
12751 if (maybecomm && !strmatch(maybecomm, "json")
12752 && !strmatch(maybecomm, "exact-match"))
12753 community = maybecomm;
12754
12755 if (argv_find(argv, argc, "exact-match", &idx))
12756 exact_match = 1;
12757
12758 if (!community)
12759 sh_type = bgp_show_type_community_all;
12760 }
12761
12762 if (argv_find(argv, argc, "community-list", &idx)) {
12763 const char *clist_number_or_name = argv[++idx]->arg;
12764 struct community_list *list;
12765
12766 if (argv_find(argv, argc, "exact-match", &idx))
12767 exact_match = 1;
12768
12769 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12770 COMMUNITY_LIST_MASTER);
12771 if (list == NULL) {
12772 vty_out(vty, "%% %s community-list not found\n",
12773 clist_number_or_name);
12774 return CMD_WARNING;
12775 }
12776
12777 if (exact_match)
12778 sh_type = bgp_show_type_community_list_exact;
12779 else
12780 sh_type = bgp_show_type_community_list;
12781 output_arg = list;
12782 }
12783
12784 if (argv_find(argv, argc, "filter-list", &idx)) {
12785 const char *filter = argv[++idx]->arg;
12786 struct as_list *as_list;
12787
12788 as_list = as_list_lookup(filter);
12789 if (as_list == NULL) {
12790 vty_out(vty, "%% %s AS-path access-list not found\n",
12791 filter);
12792 return CMD_WARNING;
12793 }
12794
12795 sh_type = bgp_show_type_filter_list;
12796 output_arg = as_list;
12797 }
12798
12799 if (argv_find(argv, argc, "prefix-list", &idx)) {
12800 const char *prefix_list_str = argv[++idx]->arg;
12801 struct prefix_list *plist;
12802
12803 plist = prefix_list_lookup(afi, prefix_list_str);
12804 if (plist == NULL) {
12805 vty_out(vty, "%% %s prefix-list not found\n",
12806 prefix_list_str);
12807 return CMD_WARNING;
12808 }
12809
12810 sh_type = bgp_show_type_prefix_list;
12811 output_arg = plist;
12812 }
12813
12814 if (argv_find(argv, argc, "access-list", &idx)) {
12815 const char *access_list_str = argv[++idx]->arg;
12816 struct access_list *alist;
12817
12818 alist = access_list_lookup(afi, access_list_str);
12819 if (!alist) {
12820 vty_out(vty, "%% %s access-list not found\n",
12821 access_list_str);
12822 return CMD_WARNING;
12823 }
12824
12825 sh_type = bgp_show_type_access_list;
12826 output_arg = alist;
12827 }
12828
12829 if (argv_find(argv, argc, "route-map", &idx)) {
12830 const char *rmap_str = argv[++idx]->arg;
12831 struct route_map *rmap;
12832
12833 rmap = route_map_lookup_by_name(rmap_str);
12834 if (!rmap) {
12835 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12836 return CMD_WARNING;
12837 }
12838
12839 sh_type = bgp_show_type_route_map;
12840 output_arg = rmap;
12841 }
12842
12843 if (argv_find(argv, argc, "rpki", &idx)) {
12844 sh_type = bgp_show_type_rpki;
12845 if (argv_find(argv, argc, "valid", &idx))
12846 rpki_target_state = RPKI_VALID;
12847 else if (argv_find(argv, argc, "invalid", &idx))
12848 rpki_target_state = RPKI_INVALID;
12849 }
12850
12851 /* Display prefixes with matching version numbers */
12852 if (argv_find(argv, argc, "version", &idx)) {
12853 sh_type = bgp_show_type_prefix_version;
12854 output_arg = argv[idx + 1]->arg;
12855 }
12856
12857 /* Display prefixes with matching BGP community alias */
12858 if (argv_find(argv, argc, "alias", &idx)) {
12859 sh_type = bgp_show_type_community_alias;
12860 output_arg = argv[idx + 1]->arg;
12861 }
12862
12863 /* prefix-longer */
12864 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12865 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12866 const char *prefix_str = argv[idx]->arg;
12867
12868 if (!str2prefix(prefix_str, &p)) {
12869 vty_out(vty, "%% Malformed Prefix\n");
12870 return CMD_WARNING;
12871 }
12872
12873 sh_type = bgp_show_type_prefix_longer;
12874 output_arg = &p;
12875 }
12876
12877 if (!all) {
12878 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12879 if (community)
12880 return bgp_show_community(vty, bgp, community,
12881 exact_match, afi, safi,
12882 show_flags);
12883 else
12884 return bgp_show(vty, bgp, afi, safi, sh_type,
12885 output_arg, show_flags,
12886 rpki_target_state);
12887 } else {
12888 struct listnode *node;
12889 struct bgp *abgp;
12890 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12891 * AFI_IP6 */
12892
12893 if (uj)
12894 vty_out(vty, "{\n");
12895
12896 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12897 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12898 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12899 ? AFI_IP
12900 : AFI_IP6;
12901 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12902 FOREACH_SAFI (safi) {
12903 if (!bgp_afi_safi_peer_exists(abgp, afi,
12904 safi))
12905 continue;
12906
12907 if (uj) {
12908 if (first)
12909 first = false;
12910 else
12911 vty_out(vty, ",\n");
12912 vty_out(vty, "\"%s\":{\n",
12913 get_afi_safi_str(afi,
12914 safi,
12915 true));
12916 } else
12917 vty_out(vty,
12918 "\nFor address family: %s\n",
12919 get_afi_safi_str(
12920 afi, safi,
12921 false));
12922
12923 if (community)
12924 bgp_show_community(
12925 vty, abgp, community,
12926 exact_match, afi, safi,
12927 show_flags);
12928 else
12929 bgp_show(vty, abgp, afi, safi,
12930 sh_type, output_arg,
12931 show_flags,
12932 rpki_target_state);
12933 if (uj)
12934 vty_out(vty, "}\n");
12935 }
12936 }
12937 } else {
12938 /* show <ip> bgp all: for each AFI and SAFI*/
12939 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12940 FOREACH_AFI_SAFI (afi, safi) {
12941 if (!bgp_afi_safi_peer_exists(abgp, afi,
12942 safi))
12943 continue;
12944
12945 if (uj) {
12946 if (first)
12947 first = false;
12948 else
12949 vty_out(vty, ",\n");
12950
12951 vty_out(vty, "\"%s\":{\n",
12952 get_afi_safi_str(afi,
12953 safi,
12954 true));
12955 } else
12956 vty_out(vty,
12957 "\nFor address family: %s\n",
12958 get_afi_safi_str(
12959 afi, safi,
12960 false));
12961
12962 if (community)
12963 bgp_show_community(
12964 vty, abgp, community,
12965 exact_match, afi, safi,
12966 show_flags);
12967 else
12968 bgp_show(vty, abgp, afi, safi,
12969 sh_type, output_arg,
12970 show_flags,
12971 rpki_target_state);
12972 if (uj)
12973 vty_out(vty, "}\n");
12974 }
12975 }
12976 }
12977 if (uj)
12978 vty_out(vty, "}\n");
12979 }
12980 return CMD_SUCCESS;
12981 }
12982
12983 DEFUN (show_ip_bgp_route,
12984 show_ip_bgp_route_cmd,
12985 "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>] [rpki <valid|invalid|notfound>] [json]",
12986 SHOW_STR
12987 IP_STR
12988 BGP_STR
12989 BGP_INSTANCE_HELP_STR
12990 BGP_AFI_HELP_STR
12991 BGP_SAFI_WITH_LABEL_HELP_STR
12992 "Network in the BGP routing table to display\n"
12993 "IPv4 prefix\n"
12994 "Network in the BGP routing table to display\n"
12995 "IPv6 prefix\n"
12996 "Display only the bestpath\n"
12997 "Display only multipaths\n"
12998 "Display only paths that match the specified rpki state\n"
12999 "A valid path as determined by rpki\n"
13000 "A invalid path as determined by rpki\n"
13001 "A path that has no rpki data\n"
13002 JSON_STR)
13003 {
13004 int prefix_check = 0;
13005
13006 afi_t afi = AFI_IP6;
13007 safi_t safi = SAFI_UNICAST;
13008 char *prefix = NULL;
13009 struct bgp *bgp = NULL;
13010 enum bgp_path_type path_type;
13011 bool uj = use_json(argc, argv);
13012
13013 int idx = 0;
13014
13015 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13016 &bgp, uj);
13017 if (!idx)
13018 return CMD_WARNING;
13019
13020 if (!bgp) {
13021 vty_out(vty,
13022 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
13023 return CMD_WARNING;
13024 }
13025
13026 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
13027 if (argv_find(argv, argc, "A.B.C.D", &idx)
13028 || argv_find(argv, argc, "X:X::X:X", &idx))
13029 prefix_check = 0;
13030 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
13031 || argv_find(argv, argc, "X:X::X:X/M", &idx))
13032 prefix_check = 1;
13033
13034 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
13035 && afi != AFI_IP6) {
13036 vty_out(vty,
13037 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
13038 return CMD_WARNING;
13039 }
13040 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
13041 && afi != AFI_IP) {
13042 vty_out(vty,
13043 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13044 return CMD_WARNING;
13045 }
13046
13047 prefix = argv[idx]->arg;
13048
13049 /* [<bestpath|multipath>] */
13050 if (argv_find(argv, argc, "bestpath", &idx))
13051 path_type = BGP_PATH_SHOW_BESTPATH;
13052 else if (argv_find(argv, argc, "multipath", &idx))
13053 path_type = BGP_PATH_SHOW_MULTIPATH;
13054 else
13055 path_type = BGP_PATH_SHOW_ALL;
13056
13057 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13058 path_type, RPKI_NOT_BEING_USED, uj);
13059 }
13060
13061 DEFUN (show_ip_bgp_regexp,
13062 show_ip_bgp_regexp_cmd,
13063 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13064 SHOW_STR
13065 IP_STR
13066 BGP_STR
13067 BGP_INSTANCE_HELP_STR
13068 BGP_AFI_HELP_STR
13069 BGP_SAFI_WITH_LABEL_HELP_STR
13070 "Display routes matching the AS path regular expression\n"
13071 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13072 JSON_STR)
13073 {
13074 afi_t afi = AFI_IP6;
13075 safi_t safi = SAFI_UNICAST;
13076 struct bgp *bgp = NULL;
13077 bool uj = use_json(argc, argv);
13078 char *regstr = NULL;
13079
13080 int idx = 0;
13081 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13082 &bgp, false);
13083 if (!idx)
13084 return CMD_WARNING;
13085
13086 // get index of regex
13087 if (argv_find(argv, argc, "REGEX", &idx))
13088 regstr = argv[idx]->arg;
13089
13090 assert(regstr);
13091 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13092 bgp_show_type_regexp, uj);
13093 }
13094
13095 DEFPY (show_ip_bgp_instance_all,
13096 show_ip_bgp_instance_all_cmd,
13097 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13098 SHOW_STR
13099 IP_STR
13100 BGP_STR
13101 BGP_INSTANCE_ALL_HELP_STR
13102 BGP_AFI_HELP_STR
13103 BGP_SAFI_WITH_LABEL_HELP_STR
13104 JSON_STR
13105 "Increase table width for longer prefixes\n")
13106 {
13107 afi_t afi = AFI_IP6;
13108 safi_t safi = SAFI_UNICAST;
13109 struct bgp *bgp = NULL;
13110 int idx = 0;
13111 uint16_t show_flags = 0;
13112
13113 if (uj) {
13114 argc--;
13115 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13116 }
13117
13118 if (wide)
13119 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13120
13121 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13122 &bgp, uj);
13123 if (!idx)
13124 return CMD_WARNING;
13125
13126 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13127 return CMD_SUCCESS;
13128 }
13129
13130 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13131 afi_t afi, safi_t safi, enum bgp_show_type type,
13132 bool use_json)
13133 {
13134 regex_t *regex;
13135 int rc;
13136 uint16_t show_flags = 0;
13137
13138 if (use_json)
13139 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13140
13141 if (!config_bgp_aspath_validate(regstr)) {
13142 vty_out(vty, "Invalid character in REGEX %s\n",
13143 regstr);
13144 return CMD_WARNING_CONFIG_FAILED;
13145 }
13146
13147 regex = bgp_regcomp(regstr);
13148 if (!regex) {
13149 vty_out(vty, "Can't compile regexp %s\n", regstr);
13150 return CMD_WARNING;
13151 }
13152
13153 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13154 RPKI_NOT_BEING_USED);
13155 bgp_regex_free(regex);
13156 return rc;
13157 }
13158
13159 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13160 const char *comstr, int exact, afi_t afi,
13161 safi_t safi, uint16_t show_flags)
13162 {
13163 struct community *com;
13164 int ret = 0;
13165
13166 com = community_str2com(comstr);
13167 if (!com) {
13168 vty_out(vty, "%% Community malformed: %s\n", comstr);
13169 return CMD_WARNING;
13170 }
13171
13172 ret = bgp_show(vty, bgp, afi, safi,
13173 (exact ? bgp_show_type_community_exact
13174 : bgp_show_type_community),
13175 com, show_flags, RPKI_NOT_BEING_USED);
13176 community_free(&com);
13177
13178 return ret;
13179 }
13180
13181 enum bgp_stats {
13182 BGP_STATS_MAXBITLEN = 0,
13183 BGP_STATS_RIB,
13184 BGP_STATS_PREFIXES,
13185 BGP_STATS_TOTPLEN,
13186 BGP_STATS_UNAGGREGATEABLE,
13187 BGP_STATS_MAX_AGGREGATEABLE,
13188 BGP_STATS_AGGREGATES,
13189 BGP_STATS_SPACE,
13190 BGP_STATS_ASPATH_COUNT,
13191 BGP_STATS_ASPATH_MAXHOPS,
13192 BGP_STATS_ASPATH_TOTHOPS,
13193 BGP_STATS_ASPATH_MAXSIZE,
13194 BGP_STATS_ASPATH_TOTSIZE,
13195 BGP_STATS_ASN_HIGHEST,
13196 BGP_STATS_MAX,
13197 };
13198
13199 #define TABLE_STATS_IDX_VTY 0
13200 #define TABLE_STATS_IDX_JSON 1
13201
13202 static const char *table_stats_strs[][2] = {
13203 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13204 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13205 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13206 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13207 "unaggregateablePrefixes"},
13208 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13209 "maximumAggregateablePrefixes"},
13210 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13211 "bgpAggregateAdvertisements"},
13212 [BGP_STATS_SPACE] = {"Address space advertised",
13213 "addressSpaceAdvertised"},
13214 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13215 "advertisementsWithPaths"},
13216 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13217 "longestAsPath"},
13218 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13219 "largestAsPath"},
13220 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13221 "averageAsPathLengthHops"},
13222 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13223 "averageAsPathSizeBytes"},
13224 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13225 [BGP_STATS_MAX] = {NULL, NULL}
13226 };
13227
13228 struct bgp_table_stats {
13229 struct bgp_table *table;
13230 unsigned long long counts[BGP_STATS_MAX];
13231
13232 unsigned long long
13233 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13234 1];
13235
13236 double total_space;
13237 };
13238
13239 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13240 struct bgp_table_stats *ts, unsigned int space)
13241 {
13242 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13243 struct bgp_path_info *pi;
13244 const struct prefix *rn_p;
13245
13246 if (!bgp_dest_has_bgp_path_info_data(dest))
13247 return;
13248
13249 rn_p = bgp_dest_get_prefix(dest);
13250 ts->counts[BGP_STATS_PREFIXES]++;
13251 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13252
13253 ts->prefix_len_count[rn_p->prefixlen]++;
13254 /* check if the prefix is included by any other announcements */
13255 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13256 pdest = bgp_dest_parent_nolock(pdest);
13257
13258 if (pdest == NULL || pdest == top) {
13259 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13260 /* announced address space */
13261 if (space)
13262 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13263 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13264 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13265
13266
13267 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13268 ts->counts[BGP_STATS_RIB]++;
13269
13270 if (CHECK_FLAG(pi->attr->flag,
13271 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13272 ts->counts[BGP_STATS_AGGREGATES]++;
13273
13274 /* as-path stats */
13275 if (pi->attr->aspath) {
13276 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13277 unsigned int size = aspath_size(pi->attr->aspath);
13278 as_t highest = aspath_highest(pi->attr->aspath);
13279
13280 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13281
13282 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13283 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13284
13285 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13286 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13287
13288 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13289 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13290 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13291 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13292 }
13293 }
13294 }
13295
13296 static void bgp_table_stats_walker(struct thread *t)
13297 {
13298 struct bgp_dest *dest, *ndest;
13299 struct bgp_dest *top;
13300 struct bgp_table_stats *ts = THREAD_ARG(t);
13301 unsigned int space = 0;
13302
13303 if (!(top = bgp_table_top(ts->table)))
13304 return;
13305
13306 switch (ts->table->afi) {
13307 case AFI_IP:
13308 space = IPV4_MAX_BITLEN;
13309 break;
13310 case AFI_IP6:
13311 space = IPV6_MAX_BITLEN;
13312 break;
13313 case AFI_L2VPN:
13314 space = EVPN_ROUTE_PREFIXLEN;
13315 break;
13316 default:
13317 return;
13318 }
13319
13320 ts->counts[BGP_STATS_MAXBITLEN] = space;
13321
13322 for (dest = top; dest; dest = bgp_route_next(dest)) {
13323 if (ts->table->safi == SAFI_MPLS_VPN
13324 || ts->table->safi == SAFI_ENCAP
13325 || ts->table->safi == SAFI_EVPN) {
13326 struct bgp_table *table;
13327
13328 table = bgp_dest_get_bgp_table_info(dest);
13329 if (!table)
13330 continue;
13331
13332 top = bgp_table_top(table);
13333 for (ndest = bgp_table_top(table); ndest;
13334 ndest = bgp_route_next(ndest))
13335 bgp_table_stats_rn(ndest, top, ts, space);
13336 } else {
13337 bgp_table_stats_rn(dest, top, ts, space);
13338 }
13339 }
13340 }
13341
13342 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13343 struct json_object *json_array)
13344 {
13345 struct listnode *node, *nnode;
13346 struct bgp *bgp;
13347
13348 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13349 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13350 }
13351
13352 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13353 safi_t safi, struct json_object *json_array)
13354 {
13355 struct bgp_table_stats ts;
13356 unsigned int i;
13357 int ret = CMD_SUCCESS;
13358 char temp_buf[20];
13359 struct json_object *json = NULL;
13360 uint32_t bitlen = 0;
13361 struct json_object *json_bitlen;
13362
13363 if (json_array)
13364 json = json_object_new_object();
13365
13366 if (!bgp->rib[afi][safi]) {
13367 char warning_msg[50];
13368
13369 snprintf(warning_msg, sizeof(warning_msg),
13370 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13371 safi);
13372
13373 if (!json)
13374 vty_out(vty, "%s\n", warning_msg);
13375 else
13376 json_object_string_add(json, "warning", warning_msg);
13377
13378 ret = CMD_WARNING;
13379 goto end_table_stats;
13380 }
13381
13382 if (!json)
13383 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13384 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13385 else
13386 json_object_string_add(json, "instance", bgp->name_pretty);
13387
13388 /* labeled-unicast routes live in the unicast table */
13389 if (safi == SAFI_LABELED_UNICAST)
13390 safi = SAFI_UNICAST;
13391
13392 memset(&ts, 0, sizeof(ts));
13393 ts.table = bgp->rib[afi][safi];
13394 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13395
13396 for (i = 0; i < BGP_STATS_MAX; i++) {
13397 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13398 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13399 continue;
13400
13401 switch (i) {
13402 case BGP_STATS_ASPATH_TOTHOPS:
13403 case BGP_STATS_ASPATH_TOTSIZE:
13404 if (!json) {
13405 snprintf(
13406 temp_buf, sizeof(temp_buf), "%12.2f",
13407 ts.counts[i]
13408 ? (float)ts.counts[i]
13409 / (float)ts.counts
13410 [BGP_STATS_ASPATH_COUNT]
13411 : 0);
13412 vty_out(vty, "%-30s: %s",
13413 table_stats_strs[i]
13414 [TABLE_STATS_IDX_VTY],
13415 temp_buf);
13416 } else {
13417 json_object_double_add(
13418 json,
13419 table_stats_strs[i]
13420 [TABLE_STATS_IDX_JSON],
13421 ts.counts[i]
13422 ? (double)ts.counts[i]
13423 / (double)ts.counts
13424 [BGP_STATS_ASPATH_COUNT]
13425 : 0);
13426 }
13427 break;
13428 case BGP_STATS_TOTPLEN:
13429 if (!json) {
13430 snprintf(
13431 temp_buf, sizeof(temp_buf), "%12.2f",
13432 ts.counts[i]
13433 ? (float)ts.counts[i]
13434 / (float)ts.counts
13435 [BGP_STATS_PREFIXES]
13436 : 0);
13437 vty_out(vty, "%-30s: %s",
13438 table_stats_strs[i]
13439 [TABLE_STATS_IDX_VTY],
13440 temp_buf);
13441 } else {
13442 json_object_double_add(
13443 json,
13444 table_stats_strs[i]
13445 [TABLE_STATS_IDX_JSON],
13446 ts.counts[i]
13447 ? (double)ts.counts[i]
13448 / (double)ts.counts
13449 [BGP_STATS_PREFIXES]
13450 : 0);
13451 }
13452 break;
13453 case BGP_STATS_SPACE:
13454 if (!json) {
13455 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13456 ts.total_space);
13457 vty_out(vty, "%-30s: %s\n",
13458 table_stats_strs[i]
13459 [TABLE_STATS_IDX_VTY],
13460 temp_buf);
13461 } else {
13462 json_object_double_add(
13463 json,
13464 table_stats_strs[i]
13465 [TABLE_STATS_IDX_JSON],
13466 (double)ts.total_space);
13467 }
13468 if (afi == AFI_IP6) {
13469 if (!json) {
13470 snprintf(temp_buf, sizeof(temp_buf),
13471 "%12g",
13472 ts.total_space
13473 * pow(2.0, -128 + 32));
13474 vty_out(vty, "%30s: %s\n",
13475 "/32 equivalent %s\n",
13476 temp_buf);
13477 } else {
13478 json_object_double_add(
13479 json, "/32equivalent",
13480 (double)(ts.total_space
13481 * pow(2.0,
13482 -128 + 32)));
13483 }
13484 if (!json) {
13485 snprintf(temp_buf, sizeof(temp_buf),
13486 "%12g",
13487 ts.total_space
13488 * pow(2.0, -128 + 48));
13489 vty_out(vty, "%30s: %s\n",
13490 "/48 equivalent %s\n",
13491 temp_buf);
13492 } else {
13493 json_object_double_add(
13494 json, "/48equivalent",
13495 (double)(ts.total_space
13496 * pow(2.0,
13497 -128 + 48)));
13498 }
13499 } else {
13500 if (!json) {
13501 snprintf(temp_buf, sizeof(temp_buf),
13502 "%12.2f",
13503 ts.total_space * 100.
13504 * pow(2.0, -32));
13505 vty_out(vty, "%30s: %s\n",
13506 "% announced ", temp_buf);
13507 } else {
13508 json_object_double_add(
13509 json, "%announced",
13510 (double)(ts.total_space * 100.
13511 * pow(2.0, -32)));
13512 }
13513 if (!json) {
13514 snprintf(temp_buf, sizeof(temp_buf),
13515 "%12.2f",
13516 ts.total_space
13517 * pow(2.0, -32 + 8));
13518 vty_out(vty, "%30s: %s\n",
13519 "/8 equivalent ", temp_buf);
13520 } else {
13521 json_object_double_add(
13522 json, "/8equivalent",
13523 (double)(ts.total_space
13524 * pow(2.0, -32 + 8)));
13525 }
13526 if (!json) {
13527 snprintf(temp_buf, sizeof(temp_buf),
13528 "%12.2f",
13529 ts.total_space
13530 * pow(2.0, -32 + 24));
13531 vty_out(vty, "%30s: %s\n",
13532 "/24 equivalent ", temp_buf);
13533 } else {
13534 json_object_double_add(
13535 json, "/24equivalent",
13536 (double)(ts.total_space
13537 * pow(2.0, -32 + 24)));
13538 }
13539 }
13540 break;
13541 default:
13542 if (!json) {
13543 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13544 ts.counts[i]);
13545 vty_out(vty, "%-30s: %s",
13546 table_stats_strs[i]
13547 [TABLE_STATS_IDX_VTY],
13548 temp_buf);
13549 } else {
13550 json_object_int_add(
13551 json,
13552 table_stats_strs[i]
13553 [TABLE_STATS_IDX_JSON],
13554 ts.counts[i]);
13555 }
13556 }
13557 if (!json)
13558 vty_out(vty, "\n");
13559 }
13560
13561 switch (afi) {
13562 case AFI_IP:
13563 bitlen = IPV4_MAX_BITLEN;
13564 break;
13565 case AFI_IP6:
13566 bitlen = IPV6_MAX_BITLEN;
13567 break;
13568 case AFI_L2VPN:
13569 bitlen = EVPN_ROUTE_PREFIXLEN;
13570 break;
13571 default:
13572 break;
13573 }
13574
13575 if (json) {
13576 json_bitlen = json_object_new_array();
13577
13578 for (i = 0; i <= bitlen; i++) {
13579 struct json_object *ind_bit = json_object_new_object();
13580
13581 if (!ts.prefix_len_count[i])
13582 continue;
13583
13584 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13585 json_object_int_add(ind_bit, temp_buf,
13586 ts.prefix_len_count[i]);
13587 json_object_array_add(json_bitlen, ind_bit);
13588 }
13589 json_object_object_add(json, "prefixLength", json_bitlen);
13590 }
13591
13592 end_table_stats:
13593 if (json)
13594 json_object_array_add(json_array, json);
13595 return ret;
13596 }
13597
13598 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13599 safi_t safi, struct json_object *json_array)
13600 {
13601 if (!bgp) {
13602 bgp_table_stats_all(vty, afi, safi, json_array);
13603 return CMD_SUCCESS;
13604 }
13605
13606 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13607 }
13608
13609 enum bgp_pcounts {
13610 PCOUNT_ADJ_IN = 0,
13611 PCOUNT_DAMPED,
13612 PCOUNT_REMOVED,
13613 PCOUNT_HISTORY,
13614 PCOUNT_STALE,
13615 PCOUNT_VALID,
13616 PCOUNT_ALL,
13617 PCOUNT_COUNTED,
13618 PCOUNT_BPATH_SELECTED,
13619 PCOUNT_PFCNT, /* the figure we display to users */
13620 PCOUNT_MAX,
13621 };
13622
13623 static const char *const pcount_strs[] = {
13624 [PCOUNT_ADJ_IN] = "Adj-in",
13625 [PCOUNT_DAMPED] = "Damped",
13626 [PCOUNT_REMOVED] = "Removed",
13627 [PCOUNT_HISTORY] = "History",
13628 [PCOUNT_STALE] = "Stale",
13629 [PCOUNT_VALID] = "Valid",
13630 [PCOUNT_ALL] = "All RIB",
13631 [PCOUNT_COUNTED] = "PfxCt counted",
13632 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13633 [PCOUNT_PFCNT] = "Useable",
13634 [PCOUNT_MAX] = NULL,
13635 };
13636
13637 struct peer_pcounts {
13638 unsigned int count[PCOUNT_MAX];
13639 const struct peer *peer;
13640 const struct bgp_table *table;
13641 safi_t safi;
13642 };
13643
13644 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13645 {
13646 const struct bgp_adj_in *ain;
13647 const struct bgp_path_info *pi;
13648 const struct peer *peer = pc->peer;
13649
13650 for (ain = rn->adj_in; ain; ain = ain->next)
13651 if (ain->peer == peer)
13652 pc->count[PCOUNT_ADJ_IN]++;
13653
13654 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13655
13656 if (pi->peer != peer)
13657 continue;
13658
13659 pc->count[PCOUNT_ALL]++;
13660
13661 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13662 pc->count[PCOUNT_DAMPED]++;
13663 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13664 pc->count[PCOUNT_HISTORY]++;
13665 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13666 pc->count[PCOUNT_REMOVED]++;
13667 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13668 pc->count[PCOUNT_STALE]++;
13669 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13670 pc->count[PCOUNT_VALID]++;
13671 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13672 pc->count[PCOUNT_PFCNT]++;
13673 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13674 pc->count[PCOUNT_BPATH_SELECTED]++;
13675
13676 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13677 pc->count[PCOUNT_COUNTED]++;
13678 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13679 flog_err(
13680 EC_LIB_DEVELOPMENT,
13681 "Attempting to count but flags say it is unusable");
13682 } else {
13683 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13684 flog_err(
13685 EC_LIB_DEVELOPMENT,
13686 "Not counted but flags say we should");
13687 }
13688 }
13689 }
13690
13691 static void bgp_peer_count_walker(struct thread *t)
13692 {
13693 struct bgp_dest *rn, *rm;
13694 const struct bgp_table *table;
13695 struct peer_pcounts *pc = THREAD_ARG(t);
13696
13697 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13698 || pc->safi == SAFI_EVPN) {
13699 /* Special handling for 2-level routing tables. */
13700 for (rn = bgp_table_top(pc->table); rn;
13701 rn = bgp_route_next(rn)) {
13702 table = bgp_dest_get_bgp_table_info(rn);
13703 if (table != NULL)
13704 for (rm = bgp_table_top(table); rm;
13705 rm = bgp_route_next(rm))
13706 bgp_peer_count_proc(rm, pc);
13707 }
13708 } else
13709 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13710 bgp_peer_count_proc(rn, pc);
13711 }
13712
13713 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13714 safi_t safi, bool use_json)
13715 {
13716 struct peer_pcounts pcounts = {.peer = peer};
13717 unsigned int i;
13718 json_object *json = NULL;
13719 json_object *json_loop = NULL;
13720
13721 if (use_json) {
13722 json = json_object_new_object();
13723 json_loop = json_object_new_object();
13724 }
13725
13726 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13727 || !peer->bgp->rib[afi][safi]) {
13728 if (use_json) {
13729 json_object_string_add(
13730 json, "warning",
13731 "No such neighbor or address family");
13732 vty_out(vty, "%s\n", json_object_to_json_string(json));
13733 json_object_free(json);
13734 json_object_free(json_loop);
13735 } else
13736 vty_out(vty, "%% No such neighbor or address family\n");
13737
13738 return CMD_WARNING;
13739 }
13740
13741 memset(&pcounts, 0, sizeof(pcounts));
13742 pcounts.peer = peer;
13743 pcounts.table = peer->bgp->rib[afi][safi];
13744 pcounts.safi = safi;
13745
13746 /* in-place call via thread subsystem so as to record execution time
13747 * stats for the thread-walk (i.e. ensure this can't be blamed on
13748 * on just vty_read()).
13749 */
13750 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13751
13752 if (use_json) {
13753 json_object_string_add(json, "prefixCountsFor", peer->host);
13754 json_object_string_add(json, "multiProtocol",
13755 get_afi_safi_str(afi, safi, true));
13756 json_object_int_add(json, "pfxCounter",
13757 peer->pcount[afi][safi]);
13758
13759 for (i = 0; i < PCOUNT_MAX; i++)
13760 json_object_int_add(json_loop, pcount_strs[i],
13761 pcounts.count[i]);
13762
13763 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13764
13765 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13766 json_object_string_add(json, "pfxctDriftFor",
13767 peer->host);
13768 json_object_string_add(
13769 json, "recommended",
13770 "Please report this bug, with the above command output");
13771 }
13772 vty_json(vty, json);
13773 } else {
13774
13775 if (peer->hostname
13776 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13777 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13778 peer->hostname, peer->host,
13779 get_afi_safi_str(afi, safi, false));
13780 } else {
13781 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13782 get_afi_safi_str(afi, safi, false));
13783 }
13784
13785 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13786 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13787
13788 for (i = 0; i < PCOUNT_MAX; i++)
13789 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13790 pcounts.count[i]);
13791
13792 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13793 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13794 vty_out(vty,
13795 "Please report this bug, with the above command output\n");
13796 }
13797 }
13798
13799 return CMD_SUCCESS;
13800 }
13801
13802 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13803 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13804 "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]",
13805 SHOW_STR
13806 IP_STR
13807 BGP_STR
13808 BGP_INSTANCE_HELP_STR
13809 BGP_AFI_HELP_STR
13810 BGP_SAFI_HELP_STR
13811 "Detailed information on TCP and BGP neighbor connections\n"
13812 "Neighbor to display information about\n"
13813 "Neighbor to display information about\n"
13814 "Neighbor on BGP configured interface\n"
13815 "Display detailed prefix count information\n"
13816 JSON_STR)
13817 {
13818 afi_t afi = AFI_IP6;
13819 safi_t safi = SAFI_UNICAST;
13820 struct peer *peer;
13821 int idx = 0;
13822 struct bgp *bgp = NULL;
13823 bool uj = use_json(argc, argv);
13824
13825 if (uj)
13826 argc--;
13827
13828 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13829 &bgp, uj);
13830 if (!idx)
13831 return CMD_WARNING;
13832
13833 argv_find(argv, argc, "neighbors", &idx);
13834 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13835 if (!peer)
13836 return CMD_WARNING;
13837
13838 return bgp_peer_counts(vty, peer, afi, safi, uj);
13839 }
13840
13841 #ifdef KEEP_OLD_VPN_COMMANDS
13842 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13843 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13844 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13845 SHOW_STR
13846 IP_STR
13847 BGP_STR
13848 BGP_VPNVX_HELP_STR
13849 "Display information about all VPNv4 NLRIs\n"
13850 "Detailed information on TCP and BGP neighbor connections\n"
13851 "Neighbor to display information about\n"
13852 "Neighbor to display information about\n"
13853 "Neighbor on BGP configured interface\n"
13854 "Display detailed prefix count information\n"
13855 JSON_STR)
13856 {
13857 int idx_peer = 6;
13858 struct peer *peer;
13859 bool uj = use_json(argc, argv);
13860
13861 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13862 if (!peer)
13863 return CMD_WARNING;
13864
13865 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13866 }
13867
13868 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13869 show_ip_bgp_vpn_all_route_prefix_cmd,
13870 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13871 SHOW_STR
13872 IP_STR
13873 BGP_STR
13874 BGP_VPNVX_HELP_STR
13875 "Display information about all VPNv4 NLRIs\n"
13876 "Network in the BGP routing table to display\n"
13877 "Network in the BGP routing table to display\n"
13878 JSON_STR)
13879 {
13880 int idx = 0;
13881 char *network = NULL;
13882 struct bgp *bgp = bgp_get_default();
13883 if (!bgp) {
13884 vty_out(vty, "Can't find default instance\n");
13885 return CMD_WARNING;
13886 }
13887
13888 if (argv_find(argv, argc, "A.B.C.D", &idx))
13889 network = argv[idx]->arg;
13890 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13891 network = argv[idx]->arg;
13892 else {
13893 vty_out(vty, "Unable to figure out Network\n");
13894 return CMD_WARNING;
13895 }
13896
13897 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13898 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13899 use_json(argc, argv));
13900 }
13901 #endif /* KEEP_OLD_VPN_COMMANDS */
13902
13903 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13904 show_bgp_l2vpn_evpn_route_prefix_cmd,
13905 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13906 SHOW_STR
13907 BGP_STR
13908 L2VPN_HELP_STR
13909 EVPN_HELP_STR
13910 "Network in the BGP routing table to display\n"
13911 "Network in the BGP routing table to display\n"
13912 "Network in the BGP routing table to display\n"
13913 "Network in the BGP routing table to display\n"
13914 JSON_STR)
13915 {
13916 int idx = 0;
13917 char *network = NULL;
13918 int prefix_check = 0;
13919
13920 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13921 argv_find(argv, argc, "X:X::X:X", &idx))
13922 network = argv[idx]->arg;
13923 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13924 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13925 network = argv[idx]->arg;
13926 prefix_check = 1;
13927 } else {
13928 vty_out(vty, "Unable to figure out Network\n");
13929 return CMD_WARNING;
13930 }
13931 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13932 prefix_check, BGP_PATH_SHOW_ALL,
13933 RPKI_NOT_BEING_USED, use_json(argc, argv));
13934 }
13935
13936 static void show_adj_route_header(struct vty *vty, struct peer *peer,
13937 struct bgp_table *table, int *header1,
13938 int *header2, json_object *json,
13939 json_object *json_scode,
13940 json_object *json_ocode, bool wide,
13941 bool detail)
13942 {
13943 uint64_t version = table ? table->version : 0;
13944
13945 if (*header1) {
13946 if (json) {
13947 json_object_int_add(json, "bgpTableVersion", version);
13948 json_object_string_addf(json, "bgpLocalRouterId",
13949 "%pI4", &peer->bgp->router_id);
13950 json_object_int_add(json, "defaultLocPrf",
13951 peer->bgp->default_local_pref);
13952 json_object_int_add(json, "localAS",
13953 peer->change_local_as
13954 ? peer->change_local_as
13955 : peer->local_as);
13956 json_object_object_add(json, "bgpStatusCodes",
13957 json_scode);
13958 json_object_object_add(json, "bgpOriginCodes",
13959 json_ocode);
13960 } else {
13961 vty_out(vty,
13962 "BGP table version is %" PRIu64
13963 ", local router ID is %pI4, vrf id ",
13964 version, &peer->bgp->router_id);
13965 if (peer->bgp->vrf_id == VRF_UNKNOWN)
13966 vty_out(vty, "%s", VRFID_NONE_STR);
13967 else
13968 vty_out(vty, "%u", peer->bgp->vrf_id);
13969 vty_out(vty, "\n");
13970 vty_out(vty, "Default local pref %u, ",
13971 peer->bgp->default_local_pref);
13972 vty_out(vty, "local AS %u\n",
13973 peer->change_local_as ? peer->change_local_as
13974 : peer->local_as);
13975 if (!detail) {
13976 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13977 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13978 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13979 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13980 }
13981 }
13982 *header1 = 0;
13983 }
13984 if (*header2) {
13985 if (!json && !detail)
13986 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
13987 : BGP_SHOW_HEADER));
13988 *header2 = 0;
13989 }
13990 }
13991
13992 static void
13993 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
13994 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
13995 const char *rmap_name, json_object *json, json_object *json_ar,
13996 json_object *json_scode, json_object *json_ocode,
13997 uint16_t show_flags, int *header1, int *header2, char *rd_str,
13998 unsigned long *output_count, unsigned long *filtered_count)
13999 {
14000 struct bgp_adj_in *ain;
14001 struct bgp_adj_out *adj;
14002 struct bgp_dest *dest;
14003 struct bgp *bgp;
14004 struct attr attr;
14005 int ret;
14006 struct update_subgroup *subgrp;
14007 struct peer_af *paf;
14008 bool route_filtered;
14009 bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14010 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14011 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14012 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14013 || (safi == SAFI_EVPN))
14014 ? true
14015 : false;
14016 int display = 0;
14017 json_object *json_net = NULL;
14018
14019 bgp = peer->bgp;
14020
14021 subgrp = peer_subgroup(peer, afi, safi);
14022
14023 if (type == bgp_show_adj_route_advertised && subgrp
14024 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
14025 if (use_json) {
14026 json_object_int_add(json, "bgpTableVersion",
14027 table->version);
14028 json_object_string_addf(json, "bgpLocalRouterId",
14029 "%pI4", &bgp->router_id);
14030 json_object_int_add(json, "defaultLocPrf",
14031 bgp->default_local_pref);
14032 json_object_int_add(json, "localAS",
14033 peer->change_local_as
14034 ? peer->change_local_as
14035 : peer->local_as);
14036 json_object_object_add(json, "bgpStatusCodes",
14037 json_scode);
14038 json_object_object_add(json, "bgpOriginCodes",
14039 json_ocode);
14040 json_object_string_add(
14041 json, "bgpOriginatingDefaultNetwork",
14042 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14043 } else {
14044 vty_out(vty,
14045 "BGP table version is %" PRIu64
14046 ", local router ID is %pI4, vrf id ",
14047 table->version, &bgp->router_id);
14048 if (bgp->vrf_id == VRF_UNKNOWN)
14049 vty_out(vty, "%s", VRFID_NONE_STR);
14050 else
14051 vty_out(vty, "%u", bgp->vrf_id);
14052 vty_out(vty, "\n");
14053 vty_out(vty, "Default local pref %u, ",
14054 bgp->default_local_pref);
14055 vty_out(vty, "local AS %u\n",
14056 peer->change_local_as ? peer->change_local_as
14057 : peer->local_as);
14058 if (!detail) {
14059 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14060 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14061 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14062 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14063 }
14064
14065 vty_out(vty, "Originating default network %s\n\n",
14066 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14067 }
14068 (*output_count)++;
14069 *header1 = 0;
14070 }
14071
14072 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14073 if (type == bgp_show_adj_route_received
14074 || type == bgp_show_adj_route_filtered) {
14075 for (ain = dest->adj_in; ain; ain = ain->next) {
14076 if (ain->peer != peer)
14077 continue;
14078
14079 show_adj_route_header(vty, peer, table, header1,
14080 header2, json, json_scode,
14081 json_ocode, wide, detail);
14082
14083 if ((safi == SAFI_MPLS_VPN)
14084 || (safi == SAFI_ENCAP)
14085 || (safi == SAFI_EVPN)) {
14086 if (use_json)
14087 json_object_string_add(
14088 json_ar, "rd", rd_str);
14089 else if (show_rd && rd_str) {
14090 vty_out(vty,
14091 "Route Distinguisher: %s\n",
14092 rd_str);
14093 show_rd = false;
14094 }
14095 }
14096
14097 attr = *ain->attr;
14098 route_filtered = false;
14099
14100 /* Filter prefix using distribute list,
14101 * filter list or prefix list
14102 */
14103 const struct prefix *rn_p =
14104 bgp_dest_get_prefix(dest);
14105 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14106 safi))
14107 == FILTER_DENY)
14108 route_filtered = true;
14109
14110 /* Filter prefix using route-map */
14111 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14112 safi, rmap_name, NULL,
14113 0, NULL);
14114
14115 if (type == bgp_show_adj_route_filtered &&
14116 !route_filtered && ret != RMAP_DENY) {
14117 bgp_attr_flush(&attr);
14118 continue;
14119 }
14120
14121 if (type == bgp_show_adj_route_received
14122 && (route_filtered || ret == RMAP_DENY))
14123 (*filtered_count)++;
14124
14125 if (detail) {
14126 if (use_json)
14127 json_net =
14128 json_object_new_object();
14129 bgp_show_path_info(
14130 NULL /* prefix_rd */, dest, vty,
14131 bgp, afi, safi, json_net,
14132 BGP_PATH_SHOW_ALL, &display,
14133 RPKI_NOT_BEING_USED);
14134 if (use_json)
14135 json_object_object_addf(
14136 json_ar, json_net,
14137 "%pFX", rn_p);
14138 } else
14139 route_vty_out_tmp(vty, dest, rn_p,
14140 &attr, safi, use_json,
14141 json_ar, wide);
14142 bgp_attr_flush(&attr);
14143 (*output_count)++;
14144 }
14145 } else if (type == bgp_show_adj_route_advertised) {
14146 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14147 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14148 if (paf->peer != peer || !adj->attr)
14149 continue;
14150
14151 show_adj_route_header(
14152 vty, peer, table, header1,
14153 header2, json, json_scode,
14154 json_ocode, wide, detail);
14155
14156 const struct prefix *rn_p =
14157 bgp_dest_get_prefix(dest);
14158
14159 attr = *adj->attr;
14160 ret = bgp_output_modifier(
14161 peer, rn_p, &attr, afi, safi,
14162 rmap_name);
14163
14164 if (ret != RMAP_DENY) {
14165 if ((safi == SAFI_MPLS_VPN)
14166 || (safi == SAFI_ENCAP)
14167 || (safi == SAFI_EVPN)) {
14168 if (use_json)
14169 json_object_string_add(
14170 json_ar,
14171 "rd",
14172 rd_str);
14173 else if (show_rd
14174 && rd_str) {
14175 vty_out(vty,
14176 "Route Distinguisher: %s\n",
14177 rd_str);
14178 show_rd = false;
14179 }
14180 }
14181 if (detail) {
14182 if (use_json)
14183 json_net =
14184 json_object_new_object();
14185 bgp_show_path_info(
14186 NULL /* prefix_rd
14187 */
14188 ,
14189 dest, vty, bgp,
14190 afi, safi,
14191 json_net,
14192 BGP_PATH_SHOW_ALL,
14193 &display,
14194 RPKI_NOT_BEING_USED);
14195 if (use_json)
14196 json_object_object_addf(
14197 json_ar,
14198 json_net,
14199 "%pFX",
14200 rn_p);
14201 } else
14202 route_vty_out_tmp(
14203 vty, dest, rn_p,
14204 &attr, safi,
14205 use_json,
14206 json_ar, wide);
14207 (*output_count)++;
14208 } else {
14209 (*filtered_count)++;
14210 }
14211
14212 bgp_attr_flush(&attr);
14213 }
14214 } else if (type == bgp_show_adj_route_bestpath) {
14215 struct bgp_path_info *pi;
14216
14217 show_adj_route_header(vty, peer, table, header1,
14218 header2, json, json_scode,
14219 json_ocode, wide, detail);
14220
14221 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14222 pi = pi->next) {
14223 if (pi->peer != peer)
14224 continue;
14225
14226 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14227 continue;
14228
14229 route_vty_out_tmp(vty, dest,
14230 bgp_dest_get_prefix(dest),
14231 pi->attr, safi, use_json,
14232 json_ar, wide);
14233 (*output_count)++;
14234 }
14235 }
14236 }
14237 }
14238
14239 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14240 safi_t safi, enum bgp_show_adj_route_type type,
14241 const char *rmap_name, uint16_t show_flags)
14242 {
14243 struct bgp *bgp;
14244 struct bgp_table *table;
14245 json_object *json = NULL;
14246 json_object *json_scode = NULL;
14247 json_object *json_ocode = NULL;
14248 json_object *json_ar = NULL;
14249 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14250
14251 /* Init BGP headers here so they're only displayed once
14252 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14253 */
14254 int header1 = 1;
14255 int header2 = 1;
14256
14257 /*
14258 * Initialize variables for each RD
14259 * All prefixes under an RD is aggregated within "json_routes"
14260 */
14261 char rd_str[BUFSIZ] = {0};
14262 json_object *json_routes = NULL;
14263
14264
14265 /* For 2-tier tables, prefix counts need to be
14266 * maintained across multiple runs of show_adj_route()
14267 */
14268 unsigned long output_count_per_rd;
14269 unsigned long filtered_count_per_rd;
14270 unsigned long output_count = 0;
14271 unsigned long filtered_count = 0;
14272
14273 if (use_json) {
14274 json = json_object_new_object();
14275 json_ar = json_object_new_object();
14276 json_scode = json_object_new_object();
14277 json_ocode = json_object_new_object();
14278 #if CONFDATE > 20231208
14279 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
14280 #endif
14281 json_object_string_add(json_scode, "suppressed", "s");
14282 json_object_string_add(json_scode, "damped", "d");
14283 json_object_string_add(json_scode, "history", "h");
14284 json_object_string_add(json_scode, "valid", "*");
14285 json_object_string_add(json_scode, "best", ">");
14286 json_object_string_add(json_scode, "multipath", "=");
14287 json_object_string_add(json_scode, "internal", "i");
14288 json_object_string_add(json_scode, "ribFailure", "r");
14289 json_object_string_add(json_scode, "stale", "S");
14290 json_object_string_add(json_scode, "removed", "R");
14291
14292 #if CONFDATE > 20231208
14293 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
14294 #endif
14295 json_object_string_add(json_ocode, "igp", "i");
14296 json_object_string_add(json_ocode, "egp", "e");
14297 json_object_string_add(json_ocode, "incomplete", "?");
14298 }
14299
14300 if (!peer || !peer->afc[afi][safi]) {
14301 if (use_json) {
14302 json_object_string_add(
14303 json, "warning",
14304 "No such neighbor or address family");
14305 vty_out(vty, "%s\n", json_object_to_json_string(json));
14306 json_object_free(json);
14307 json_object_free(json_ar);
14308 json_object_free(json_scode);
14309 json_object_free(json_ocode);
14310 } else
14311 vty_out(vty, "%% No such neighbor or address family\n");
14312
14313 return CMD_WARNING;
14314 }
14315
14316 if ((type == bgp_show_adj_route_received
14317 || type == bgp_show_adj_route_filtered)
14318 && !CHECK_FLAG(peer->af_flags[afi][safi],
14319 PEER_FLAG_SOFT_RECONFIG)) {
14320 if (use_json) {
14321 json_object_string_add(
14322 json, "warning",
14323 "Inbound soft reconfiguration not enabled");
14324 vty_out(vty, "%s\n", json_object_to_json_string(json));
14325 json_object_free(json);
14326 json_object_free(json_ar);
14327 json_object_free(json_scode);
14328 json_object_free(json_ocode);
14329 } else
14330 vty_out(vty,
14331 "%% Inbound soft reconfiguration not enabled\n");
14332
14333 return CMD_WARNING;
14334 }
14335
14336 bgp = peer->bgp;
14337
14338 /* labeled-unicast routes live in the unicast table */
14339 if (safi == SAFI_LABELED_UNICAST)
14340 table = bgp->rib[afi][SAFI_UNICAST];
14341 else
14342 table = bgp->rib[afi][safi];
14343
14344 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14345 || (safi == SAFI_EVPN)) {
14346
14347 struct bgp_dest *dest;
14348
14349 for (dest = bgp_table_top(table); dest;
14350 dest = bgp_route_next(dest)) {
14351 table = bgp_dest_get_bgp_table_info(dest);
14352 if (!table)
14353 continue;
14354
14355 output_count_per_rd = 0;
14356 filtered_count_per_rd = 0;
14357
14358 if (use_json)
14359 json_routes = json_object_new_object();
14360
14361 const struct prefix_rd *prd;
14362 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14363 dest);
14364
14365 prefix_rd2str(prd, rd_str, sizeof(rd_str));
14366
14367 show_adj_route(vty, peer, table, afi, safi, type,
14368 rmap_name, json, json_routes, json_scode,
14369 json_ocode, show_flags, &header1,
14370 &header2, rd_str, &output_count_per_rd,
14371 &filtered_count_per_rd);
14372
14373 /* Don't include an empty RD in the output! */
14374 if (json_routes && (output_count_per_rd > 0))
14375 json_object_object_add(json_ar, rd_str,
14376 json_routes);
14377
14378 output_count += output_count_per_rd;
14379 filtered_count += filtered_count_per_rd;
14380 }
14381 } else
14382 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14383 json, json_ar, json_scode, json_ocode,
14384 show_flags, &header1, &header2, rd_str,
14385 &output_count, &filtered_count);
14386
14387 if (use_json) {
14388 if (type == bgp_show_adj_route_advertised)
14389 json_object_object_add(json, "advertisedRoutes",
14390 json_ar);
14391 else
14392 json_object_object_add(json, "receivedRoutes", json_ar);
14393 json_object_int_add(json, "totalPrefixCounter", output_count);
14394 json_object_int_add(json, "filteredPrefixCounter",
14395 filtered_count);
14396
14397 /*
14398 * These fields only give up ownership to `json` when `header1`
14399 * is used (set to zero). See code in `show_adj_route` and
14400 * `show_adj_route_header`.
14401 */
14402 if (header1 == 1) {
14403 json_object_free(json_scode);
14404 json_object_free(json_ocode);
14405 }
14406
14407 vty_json(vty, json);
14408 } else if (output_count > 0) {
14409 if (filtered_count > 0)
14410 vty_out(vty,
14411 "\nTotal number of prefixes %ld (%ld filtered)\n",
14412 output_count, filtered_count);
14413 else
14414 vty_out(vty, "\nTotal number of prefixes %ld\n",
14415 output_count);
14416 }
14417
14418 return CMD_SUCCESS;
14419 }
14420
14421 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14422 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14423 "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]",
14424 SHOW_STR
14425 IP_STR
14426 BGP_STR
14427 BGP_INSTANCE_HELP_STR
14428 BGP_AFI_HELP_STR
14429 BGP_SAFI_WITH_LABEL_HELP_STR
14430 "Detailed information on TCP and BGP neighbor connections\n"
14431 "Neighbor to display information about\n"
14432 "Neighbor to display information about\n"
14433 "Neighbor on BGP configured interface\n"
14434 "Display the routes selected by best path\n"
14435 JSON_STR
14436 "Increase table width for longer prefixes\n")
14437 {
14438 afi_t afi = AFI_IP6;
14439 safi_t safi = SAFI_UNICAST;
14440 char *rmap_name = NULL;
14441 char *peerstr = NULL;
14442 struct bgp *bgp = NULL;
14443 struct peer *peer;
14444 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14445 int idx = 0;
14446 uint16_t show_flags = 0;
14447
14448 if (uj)
14449 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14450
14451 if (wide)
14452 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14453
14454 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14455 &bgp, uj);
14456
14457 if (!idx)
14458 return CMD_WARNING;
14459
14460 argv_find(argv, argc, "neighbors", &idx);
14461 peerstr = argv[++idx]->arg;
14462
14463 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14464 if (!peer)
14465 return CMD_WARNING;
14466
14467 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14468 show_flags);
14469 }
14470
14471 DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
14472 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14473 "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 RMAP_NAME$route_map] [detail$detail] [json$uj | wide$wide]",
14474 SHOW_STR
14475 IP_STR
14476 BGP_STR
14477 BGP_INSTANCE_HELP_STR
14478 BGP_AFI_HELP_STR
14479 BGP_SAFI_WITH_LABEL_HELP_STR
14480 "Display the entries for all address families\n"
14481 "Detailed information on TCP and BGP neighbor connections\n"
14482 "Neighbor to display information about\n"
14483 "Neighbor to display information about\n"
14484 "Neighbor on BGP configured interface\n"
14485 "Display the routes advertised to a BGP neighbor\n"
14486 "Display the received routes from neighbor\n"
14487 "Display the filtered routes received from neighbor\n"
14488 "Route-map to modify the attributes\n"
14489 "Name of the route map\n"
14490 "Display detailed version of routes\n"
14491 JSON_STR
14492 "Increase table width for longer prefixes\n")
14493 {
14494 afi_t afi = AFI_IP6;
14495 safi_t safi = SAFI_UNICAST;
14496 char *peerstr = NULL;
14497 struct bgp *bgp = NULL;
14498 struct peer *peer;
14499 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14500 int idx = 0;
14501 bool first = true;
14502 uint16_t show_flags = 0;
14503 struct listnode *node;
14504 struct bgp *abgp;
14505
14506 if (detail)
14507 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14508
14509 if (uj) {
14510 argc--;
14511 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14512 }
14513
14514 if (all) {
14515 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14516 if (argv_find(argv, argc, "ipv4", &idx))
14517 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14518
14519 if (argv_find(argv, argc, "ipv6", &idx))
14520 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14521 }
14522
14523 if (wide)
14524 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14525
14526 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14527 &bgp, uj);
14528 if (!idx)
14529 return CMD_WARNING;
14530
14531 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14532 argv_find(argv, argc, "neighbors", &idx);
14533 peerstr = argv[++idx]->arg;
14534
14535 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14536 if (!peer)
14537 return CMD_WARNING;
14538
14539 if (argv_find(argv, argc, "advertised-routes", &idx))
14540 type = bgp_show_adj_route_advertised;
14541 else if (argv_find(argv, argc, "received-routes", &idx))
14542 type = bgp_show_adj_route_received;
14543 else if (argv_find(argv, argc, "filtered-routes", &idx))
14544 type = bgp_show_adj_route_filtered;
14545
14546 if (!all)
14547 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14548 show_flags);
14549 if (uj)
14550 vty_out(vty, "{\n");
14551
14552 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14553 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14554 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14555 : AFI_IP6;
14556 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14557 FOREACH_SAFI (safi) {
14558 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14559 continue;
14560
14561 if (uj) {
14562 if (first)
14563 first = false;
14564 else
14565 vty_out(vty, ",\n");
14566 vty_out(vty, "\"%s\":",
14567 get_afi_safi_str(afi, safi,
14568 true));
14569 } else
14570 vty_out(vty,
14571 "\nFor address family: %s\n",
14572 get_afi_safi_str(afi, safi,
14573 false));
14574
14575 peer_adj_routes(vty, peer, afi, safi, type,
14576 route_map, show_flags);
14577 }
14578 }
14579 } else {
14580 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14581 FOREACH_AFI_SAFI (afi, safi) {
14582 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14583 continue;
14584
14585 if (uj) {
14586 if (first)
14587 first = false;
14588 else
14589 vty_out(vty, ",\n");
14590 vty_out(vty, "\"%s\":",
14591 get_afi_safi_str(afi, safi,
14592 true));
14593 } else
14594 vty_out(vty,
14595 "\nFor address family: %s\n",
14596 get_afi_safi_str(afi, safi,
14597 false));
14598
14599 peer_adj_routes(vty, peer, afi, safi, type,
14600 route_map, show_flags);
14601 }
14602 }
14603 }
14604 if (uj)
14605 vty_out(vty, "}\n");
14606
14607 return CMD_SUCCESS;
14608 }
14609
14610 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14611 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14612 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14613 SHOW_STR
14614 IP_STR
14615 BGP_STR
14616 BGP_INSTANCE_HELP_STR
14617 BGP_AF_STR
14618 BGP_AF_STR
14619 BGP_AF_MODIFIER_STR
14620 "Detailed information on TCP and BGP neighbor connections\n"
14621 "Neighbor to display information about\n"
14622 "Neighbor to display information about\n"
14623 "Neighbor on BGP configured interface\n"
14624 "Display information received from a BGP neighbor\n"
14625 "Display the prefixlist filter\n"
14626 JSON_STR)
14627 {
14628 afi_t afi = AFI_IP6;
14629 safi_t safi = SAFI_UNICAST;
14630 char *peerstr = NULL;
14631 char name[BUFSIZ];
14632 struct peer *peer;
14633 int count;
14634 int idx = 0;
14635 struct bgp *bgp = NULL;
14636 bool uj = use_json(argc, argv);
14637
14638 if (uj)
14639 argc--;
14640
14641 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14642 &bgp, uj);
14643 if (!idx)
14644 return CMD_WARNING;
14645
14646 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14647 argv_find(argv, argc, "neighbors", &idx);
14648 peerstr = argv[++idx]->arg;
14649
14650 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14651 if (!peer)
14652 return CMD_WARNING;
14653
14654 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14655 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14656 if (count) {
14657 if (!uj)
14658 vty_out(vty, "Address Family: %s\n",
14659 get_afi_safi_str(afi, safi, false));
14660 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14661 } else {
14662 if (uj)
14663 vty_out(vty, "{}\n");
14664 else
14665 vty_out(vty, "No functional output\n");
14666 }
14667
14668 return CMD_SUCCESS;
14669 }
14670
14671 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14672 afi_t afi, safi_t safi,
14673 enum bgp_show_type type, bool use_json)
14674 {
14675 uint16_t show_flags = 0;
14676
14677 if (use_json)
14678 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14679
14680 if (!peer || !peer->afc[afi][safi]) {
14681 if (use_json) {
14682 json_object *json_no = NULL;
14683 json_no = json_object_new_object();
14684 json_object_string_add(
14685 json_no, "warning",
14686 "No such neighbor or address family");
14687 vty_out(vty, "%s\n",
14688 json_object_to_json_string(json_no));
14689 json_object_free(json_no);
14690 } else
14691 vty_out(vty, "%% No such neighbor or address family\n");
14692 return CMD_WARNING;
14693 }
14694
14695 /* labeled-unicast routes live in the unicast table */
14696 if (safi == SAFI_LABELED_UNICAST)
14697 safi = SAFI_UNICAST;
14698
14699 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14700 RPKI_NOT_BEING_USED);
14701 }
14702
14703 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14704 show_ip_bgp_flowspec_routes_detailed_cmd,
14705 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14706 SHOW_STR
14707 IP_STR
14708 BGP_STR
14709 BGP_INSTANCE_HELP_STR
14710 BGP_AFI_HELP_STR
14711 "SAFI Flowspec\n"
14712 "Detailed information on flowspec entries\n"
14713 JSON_STR)
14714 {
14715 afi_t afi = AFI_IP6;
14716 safi_t safi = SAFI_UNICAST;
14717 struct bgp *bgp = NULL;
14718 int idx = 0;
14719 bool uj = use_json(argc, argv);
14720 uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
14721
14722 if (uj) {
14723 argc--;
14724 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14725 }
14726
14727 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14728 &bgp, uj);
14729 if (!idx)
14730 return CMD_WARNING;
14731
14732 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14733 show_flags, RPKI_NOT_BEING_USED);
14734 }
14735
14736 DEFUN (show_ip_bgp_neighbor_routes,
14737 show_ip_bgp_neighbor_routes_cmd,
14738 "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]",
14739 SHOW_STR
14740 IP_STR
14741 BGP_STR
14742 BGP_INSTANCE_HELP_STR
14743 BGP_AFI_HELP_STR
14744 BGP_SAFI_WITH_LABEL_HELP_STR
14745 "Detailed information on TCP and BGP neighbor connections\n"
14746 "Neighbor to display information about\n"
14747 "Neighbor to display information about\n"
14748 "Neighbor on BGP configured interface\n"
14749 "Display flap statistics of the routes learned from neighbor\n"
14750 "Display the dampened routes received from neighbor\n"
14751 "Display routes learned from neighbor\n"
14752 JSON_STR)
14753 {
14754 char *peerstr = NULL;
14755 struct bgp *bgp = NULL;
14756 afi_t afi = AFI_IP6;
14757 safi_t safi = SAFI_UNICAST;
14758 struct peer *peer;
14759 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14760 int idx = 0;
14761 bool uj = use_json(argc, argv);
14762
14763 if (uj)
14764 argc--;
14765
14766 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14767 &bgp, uj);
14768 if (!idx)
14769 return CMD_WARNING;
14770
14771 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14772 argv_find(argv, argc, "neighbors", &idx);
14773 peerstr = argv[++idx]->arg;
14774
14775 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14776 if (!peer)
14777 return CMD_WARNING;
14778
14779 if (argv_find(argv, argc, "flap-statistics", &idx))
14780 sh_type = bgp_show_type_flap_neighbor;
14781 else if (argv_find(argv, argc, "dampened-routes", &idx))
14782 sh_type = bgp_show_type_damp_neighbor;
14783 else if (argv_find(argv, argc, "routes", &idx))
14784 sh_type = bgp_show_type_neighbor;
14785
14786 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14787 }
14788
14789 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14790
14791 struct bgp_distance {
14792 /* Distance value for the IP source prefix. */
14793 uint8_t distance;
14794
14795 /* Name of the access-list to be matched. */
14796 char *access_list;
14797 };
14798
14799 DEFUN (show_bgp_afi_vpn_rd_route,
14800 show_bgp_afi_vpn_rd_route_cmd,
14801 "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]",
14802 SHOW_STR
14803 BGP_STR
14804 BGP_AFI_HELP_STR
14805 BGP_AF_MODIFIER_STR
14806 "Display information for a route distinguisher\n"
14807 "Route Distinguisher\n"
14808 "All Route Distinguishers\n"
14809 "Network in the BGP routing table to display\n"
14810 "Network in the BGP routing table to display\n"
14811 JSON_STR)
14812 {
14813 int ret;
14814 struct prefix_rd prd;
14815 afi_t afi = AFI_MAX;
14816 int idx = 0;
14817
14818 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14819 vty_out(vty, "%% Malformed Address Family\n");
14820 return CMD_WARNING;
14821 }
14822
14823 if (!strcmp(argv[5]->arg, "all"))
14824 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14825 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14826 RPKI_NOT_BEING_USED,
14827 use_json(argc, argv));
14828
14829 ret = str2prefix_rd(argv[5]->arg, &prd);
14830 if (!ret) {
14831 vty_out(vty, "%% Malformed Route Distinguisher\n");
14832 return CMD_WARNING;
14833 }
14834
14835 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14836 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14837 use_json(argc, argv));
14838 }
14839
14840 static struct bgp_distance *bgp_distance_new(void)
14841 {
14842 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14843 }
14844
14845 static void bgp_distance_free(struct bgp_distance *bdistance)
14846 {
14847 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14848 }
14849
14850 static int bgp_distance_set(struct vty *vty, const char *distance_str,
14851 const char *ip_str, const char *access_list_str)
14852 {
14853 int ret;
14854 afi_t afi;
14855 safi_t safi;
14856 struct prefix p;
14857 uint8_t distance;
14858 struct bgp_dest *dest;
14859 struct bgp_distance *bdistance;
14860
14861 afi = bgp_node_afi(vty);
14862 safi = bgp_node_safi(vty);
14863
14864 ret = str2prefix(ip_str, &p);
14865 if (ret == 0) {
14866 vty_out(vty, "Malformed prefix\n");
14867 return CMD_WARNING_CONFIG_FAILED;
14868 }
14869
14870 distance = atoi(distance_str);
14871
14872 /* Get BGP distance node. */
14873 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
14874 bdistance = bgp_dest_get_bgp_distance_info(dest);
14875 if (bdistance)
14876 bgp_dest_unlock_node(dest);
14877 else {
14878 bdistance = bgp_distance_new();
14879 bgp_dest_set_bgp_distance_info(dest, bdistance);
14880 }
14881
14882 /* Set distance value. */
14883 bdistance->distance = distance;
14884
14885 /* Reset access-list configuration. */
14886 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14887 if (access_list_str)
14888 bdistance->access_list =
14889 XSTRDUP(MTYPE_AS_LIST, access_list_str);
14890
14891 return CMD_SUCCESS;
14892 }
14893
14894 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
14895 const char *ip_str, const char *access_list_str)
14896 {
14897 int ret;
14898 afi_t afi;
14899 safi_t safi;
14900 struct prefix p;
14901 int distance;
14902 struct bgp_dest *dest;
14903 struct bgp_distance *bdistance;
14904
14905 afi = bgp_node_afi(vty);
14906 safi = bgp_node_safi(vty);
14907
14908 ret = str2prefix(ip_str, &p);
14909 if (ret == 0) {
14910 vty_out(vty, "Malformed prefix\n");
14911 return CMD_WARNING_CONFIG_FAILED;
14912 }
14913
14914 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
14915 if (!dest) {
14916 vty_out(vty, "Can't find specified prefix\n");
14917 return CMD_WARNING_CONFIG_FAILED;
14918 }
14919
14920 bdistance = bgp_dest_get_bgp_distance_info(dest);
14921 distance = atoi(distance_str);
14922
14923 if (bdistance->distance != distance) {
14924 vty_out(vty, "Distance does not match configured\n");
14925 bgp_dest_unlock_node(dest);
14926 return CMD_WARNING_CONFIG_FAILED;
14927 }
14928
14929 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14930 bgp_distance_free(bdistance);
14931
14932 bgp_dest_set_bgp_path_info(dest, NULL);
14933 bgp_dest_unlock_node(dest);
14934 bgp_dest_unlock_node(dest);
14935
14936 return CMD_SUCCESS;
14937 }
14938
14939 /* Apply BGP information to distance method. */
14940 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
14941 afi_t afi, safi_t safi, struct bgp *bgp)
14942 {
14943 struct bgp_dest *dest;
14944 struct prefix q = {0};
14945 struct peer *peer;
14946 struct bgp_distance *bdistance;
14947 struct access_list *alist;
14948 struct bgp_static *bgp_static;
14949 struct bgp_path_info *bpi_ultimate;
14950
14951 if (!bgp)
14952 return 0;
14953
14954 peer = pinfo->peer;
14955
14956 if (pinfo->attr->distance)
14957 return pinfo->attr->distance;
14958
14959 /* get peer origin to calculate appropriate distance */
14960 if (pinfo->sub_type == BGP_ROUTE_IMPORTED) {
14961 bpi_ultimate = bgp_get_imported_bpi_ultimate(pinfo);
14962 peer = bpi_ultimate->peer;
14963 }
14964
14965 /* Check source address.
14966 * Note: for aggregate route, peer can have unspec af type.
14967 */
14968 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
14969 && !sockunion2hostprefix(&peer->su, &q))
14970 return 0;
14971
14972 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
14973 if (dest) {
14974 bdistance = bgp_dest_get_bgp_distance_info(dest);
14975 bgp_dest_unlock_node(dest);
14976
14977 if (bdistance->access_list) {
14978 alist = access_list_lookup(afi, bdistance->access_list);
14979 if (alist
14980 && access_list_apply(alist, p) == FILTER_PERMIT)
14981 return bdistance->distance;
14982 } else
14983 return bdistance->distance;
14984 }
14985
14986 /* Backdoor check. */
14987 dest = bgp_node_lookup(bgp->route[afi][safi], p);
14988 if (dest) {
14989 bgp_static = bgp_dest_get_bgp_static_info(dest);
14990 bgp_dest_unlock_node(dest);
14991
14992 if (bgp_static->backdoor) {
14993 if (bgp->distance_local[afi][safi])
14994 return bgp->distance_local[afi][safi];
14995 else
14996 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14997 }
14998 }
14999
15000 if (peer->sort == BGP_PEER_EBGP) {
15001 if (bgp->distance_ebgp[afi][safi])
15002 return bgp->distance_ebgp[afi][safi];
15003 return ZEBRA_EBGP_DISTANCE_DEFAULT;
15004 } else if (peer->sort == BGP_PEER_IBGP) {
15005 if (bgp->distance_ibgp[afi][safi])
15006 return bgp->distance_ibgp[afi][safi];
15007 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15008 } else {
15009 if (bgp->distance_local[afi][safi])
15010 return bgp->distance_local[afi][safi];
15011 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15012 }
15013 }
15014
15015 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
15016 * we should tell ZEBRA update the routes for a specific
15017 * AFI/SAFI to reflect changes in RIB.
15018 */
15019 static void bgp_announce_routes_distance_update(struct bgp *bgp,
15020 afi_t update_afi,
15021 safi_t update_safi)
15022 {
15023 afi_t afi;
15024 safi_t safi;
15025
15026 FOREACH_AFI_SAFI (afi, safi) {
15027 if (!bgp_fibupd_safi(safi))
15028 continue;
15029
15030 if (afi != update_afi && safi != update_safi)
15031 continue;
15032
15033 if (BGP_DEBUG(zebra, ZEBRA))
15034 zlog_debug(
15035 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
15036 __func__, afi, safi);
15037 bgp_zebra_announce_table(bgp, afi, safi);
15038 }
15039 }
15040
15041 DEFUN (bgp_distance,
15042 bgp_distance_cmd,
15043 "distance bgp (1-255) (1-255) (1-255)",
15044 "Define an administrative distance\n"
15045 "BGP distance\n"
15046 "Distance for routes external to the AS\n"
15047 "Distance for routes internal to the AS\n"
15048 "Distance for local routes\n")
15049 {
15050 VTY_DECLVAR_CONTEXT(bgp, bgp);
15051 int idx_number = 2;
15052 int idx_number_2 = 3;
15053 int idx_number_3 = 4;
15054 int distance_ebgp = atoi(argv[idx_number]->arg);
15055 int distance_ibgp = atoi(argv[idx_number_2]->arg);
15056 int distance_local = atoi(argv[idx_number_3]->arg);
15057 afi_t afi;
15058 safi_t safi;
15059
15060 afi = bgp_node_afi(vty);
15061 safi = bgp_node_safi(vty);
15062
15063 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
15064 || bgp->distance_ibgp[afi][safi] != distance_ibgp
15065 || bgp->distance_local[afi][safi] != distance_local) {
15066 bgp->distance_ebgp[afi][safi] = distance_ebgp;
15067 bgp->distance_ibgp[afi][safi] = distance_ibgp;
15068 bgp->distance_local[afi][safi] = distance_local;
15069 bgp_announce_routes_distance_update(bgp, afi, safi);
15070 }
15071 return CMD_SUCCESS;
15072 }
15073
15074 DEFUN (no_bgp_distance,
15075 no_bgp_distance_cmd,
15076 "no distance bgp [(1-255) (1-255) (1-255)]",
15077 NO_STR
15078 "Define an administrative distance\n"
15079 "BGP distance\n"
15080 "Distance for routes external to the AS\n"
15081 "Distance for routes internal to the AS\n"
15082 "Distance for local routes\n")
15083 {
15084 VTY_DECLVAR_CONTEXT(bgp, bgp);
15085 afi_t afi;
15086 safi_t safi;
15087
15088 afi = bgp_node_afi(vty);
15089 safi = bgp_node_safi(vty);
15090
15091 if (bgp->distance_ebgp[afi][safi] != 0
15092 || bgp->distance_ibgp[afi][safi] != 0
15093 || bgp->distance_local[afi][safi] != 0) {
15094 bgp->distance_ebgp[afi][safi] = 0;
15095 bgp->distance_ibgp[afi][safi] = 0;
15096 bgp->distance_local[afi][safi] = 0;
15097 bgp_announce_routes_distance_update(bgp, afi, safi);
15098 }
15099 return CMD_SUCCESS;
15100 }
15101
15102
15103 DEFUN (bgp_distance_source,
15104 bgp_distance_source_cmd,
15105 "distance (1-255) A.B.C.D/M",
15106 "Define an administrative distance\n"
15107 "Administrative distance\n"
15108 "IP source prefix\n")
15109 {
15110 int idx_number = 1;
15111 int idx_ipv4_prefixlen = 2;
15112 bgp_distance_set(vty, argv[idx_number]->arg,
15113 argv[idx_ipv4_prefixlen]->arg, NULL);
15114 return CMD_SUCCESS;
15115 }
15116
15117 DEFUN (no_bgp_distance_source,
15118 no_bgp_distance_source_cmd,
15119 "no distance (1-255) A.B.C.D/M",
15120 NO_STR
15121 "Define an administrative distance\n"
15122 "Administrative distance\n"
15123 "IP source prefix\n")
15124 {
15125 int idx_number = 2;
15126 int idx_ipv4_prefixlen = 3;
15127 bgp_distance_unset(vty, argv[idx_number]->arg,
15128 argv[idx_ipv4_prefixlen]->arg, NULL);
15129 return CMD_SUCCESS;
15130 }
15131
15132 DEFUN (bgp_distance_source_access_list,
15133 bgp_distance_source_access_list_cmd,
15134 "distance (1-255) A.B.C.D/M WORD",
15135 "Define an administrative distance\n"
15136 "Administrative distance\n"
15137 "IP source prefix\n"
15138 "Access list name\n")
15139 {
15140 int idx_number = 1;
15141 int idx_ipv4_prefixlen = 2;
15142 int idx_word = 3;
15143 bgp_distance_set(vty, argv[idx_number]->arg,
15144 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15145 return CMD_SUCCESS;
15146 }
15147
15148 DEFUN (no_bgp_distance_source_access_list,
15149 no_bgp_distance_source_access_list_cmd,
15150 "no distance (1-255) A.B.C.D/M WORD",
15151 NO_STR
15152 "Define an administrative distance\n"
15153 "Administrative distance\n"
15154 "IP source prefix\n"
15155 "Access list name\n")
15156 {
15157 int idx_number = 2;
15158 int idx_ipv4_prefixlen = 3;
15159 int idx_word = 4;
15160 bgp_distance_unset(vty, argv[idx_number]->arg,
15161 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15162 return CMD_SUCCESS;
15163 }
15164
15165 DEFUN (ipv6_bgp_distance_source,
15166 ipv6_bgp_distance_source_cmd,
15167 "distance (1-255) X:X::X:X/M",
15168 "Define an administrative distance\n"
15169 "Administrative distance\n"
15170 "IP source prefix\n")
15171 {
15172 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15173 return CMD_SUCCESS;
15174 }
15175
15176 DEFUN (no_ipv6_bgp_distance_source,
15177 no_ipv6_bgp_distance_source_cmd,
15178 "no distance (1-255) X:X::X:X/M",
15179 NO_STR
15180 "Define an administrative distance\n"
15181 "Administrative distance\n"
15182 "IP source prefix\n")
15183 {
15184 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15185 return CMD_SUCCESS;
15186 }
15187
15188 DEFUN (ipv6_bgp_distance_source_access_list,
15189 ipv6_bgp_distance_source_access_list_cmd,
15190 "distance (1-255) X:X::X:X/M WORD",
15191 "Define an administrative distance\n"
15192 "Administrative distance\n"
15193 "IP source prefix\n"
15194 "Access list name\n")
15195 {
15196 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15197 return CMD_SUCCESS;
15198 }
15199
15200 DEFUN (no_ipv6_bgp_distance_source_access_list,
15201 no_ipv6_bgp_distance_source_access_list_cmd,
15202 "no distance (1-255) X:X::X:X/M WORD",
15203 NO_STR
15204 "Define an administrative distance\n"
15205 "Administrative distance\n"
15206 "IP source prefix\n"
15207 "Access list name\n")
15208 {
15209 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15210 return CMD_SUCCESS;
15211 }
15212
15213 DEFUN (bgp_damp_set,
15214 bgp_damp_set_cmd,
15215 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15216 "BGP Specific commands\n"
15217 "Enable route-flap dampening\n"
15218 "Half-life time for the penalty\n"
15219 "Value to start reusing a route\n"
15220 "Value to start suppressing a route\n"
15221 "Maximum duration to suppress a stable route\n")
15222 {
15223 VTY_DECLVAR_CONTEXT(bgp, bgp);
15224 int idx_half_life = 2;
15225 int idx_reuse = 3;
15226 int idx_suppress = 4;
15227 int idx_max_suppress = 5;
15228 int half = DEFAULT_HALF_LIFE * 60;
15229 int reuse = DEFAULT_REUSE;
15230 int suppress = DEFAULT_SUPPRESS;
15231 int max = 4 * half;
15232
15233 if (argc == 6) {
15234 half = atoi(argv[idx_half_life]->arg) * 60;
15235 reuse = atoi(argv[idx_reuse]->arg);
15236 suppress = atoi(argv[idx_suppress]->arg);
15237 max = atoi(argv[idx_max_suppress]->arg) * 60;
15238 } else if (argc == 3) {
15239 half = atoi(argv[idx_half_life]->arg) * 60;
15240 max = 4 * half;
15241 }
15242
15243 /*
15244 * These can't be 0 but our SA doesn't understand the
15245 * way our cli is constructed
15246 */
15247 assert(reuse);
15248 assert(half);
15249 if (suppress < reuse) {
15250 vty_out(vty,
15251 "Suppress value cannot be less than reuse value \n");
15252 return 0;
15253 }
15254
15255 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15256 reuse, suppress, max);
15257 }
15258
15259 DEFUN (bgp_damp_unset,
15260 bgp_damp_unset_cmd,
15261 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15262 NO_STR
15263 "BGP Specific commands\n"
15264 "Enable route-flap dampening\n"
15265 "Half-life time for the penalty\n"
15266 "Value to start reusing a route\n"
15267 "Value to start suppressing a route\n"
15268 "Maximum duration to suppress a stable route\n")
15269 {
15270 VTY_DECLVAR_CONTEXT(bgp, bgp);
15271 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15272 }
15273
15274 /* Display specified route of BGP table. */
15275 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15276 const char *ip_str, afi_t afi, safi_t safi,
15277 struct prefix_rd *prd, int prefix_check)
15278 {
15279 int ret;
15280 struct prefix match;
15281 struct bgp_dest *dest;
15282 struct bgp_dest *rm;
15283 struct bgp_path_info *pi;
15284 struct bgp_path_info *pi_temp;
15285 struct bgp *bgp;
15286 struct bgp_table *table;
15287
15288 /* BGP structure lookup. */
15289 if (view_name) {
15290 bgp = bgp_lookup_by_name(view_name);
15291 if (bgp == NULL) {
15292 vty_out(vty, "%% Can't find BGP instance %s\n",
15293 view_name);
15294 return CMD_WARNING;
15295 }
15296 } else {
15297 bgp = bgp_get_default();
15298 if (bgp == NULL) {
15299 vty_out(vty, "%% No BGP process is configured\n");
15300 return CMD_WARNING;
15301 }
15302 }
15303
15304 /* Check IP address argument. */
15305 ret = str2prefix(ip_str, &match);
15306 if (!ret) {
15307 vty_out(vty, "%% address is malformed\n");
15308 return CMD_WARNING;
15309 }
15310
15311 match.family = afi2family(afi);
15312
15313 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15314 || (safi == SAFI_EVPN)) {
15315 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15316 dest = bgp_route_next(dest)) {
15317 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15318
15319 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15320 continue;
15321 table = bgp_dest_get_bgp_table_info(dest);
15322 if (!table)
15323 continue;
15324 rm = bgp_node_match(table, &match);
15325 if (rm == NULL)
15326 continue;
15327
15328 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15329
15330 if (!prefix_check
15331 || rm_p->prefixlen == match.prefixlen) {
15332 pi = bgp_dest_get_bgp_path_info(rm);
15333 while (pi) {
15334 if (pi->extra && pi->extra->damp_info) {
15335 pi_temp = pi->next;
15336 bgp_damp_info_free(
15337 pi->extra->damp_info,
15338 1, afi, safi);
15339 pi = pi_temp;
15340 } else
15341 pi = pi->next;
15342 }
15343 }
15344
15345 bgp_dest_unlock_node(rm);
15346 }
15347 } else {
15348 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15349 if (dest != NULL) {
15350 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15351
15352 if (!prefix_check
15353 || dest_p->prefixlen == match.prefixlen) {
15354 pi = bgp_dest_get_bgp_path_info(dest);
15355 while (pi) {
15356 if (pi->extra && pi->extra->damp_info) {
15357 pi_temp = pi->next;
15358 bgp_damp_info_free(
15359 pi->extra->damp_info,
15360 1, afi, safi);
15361 pi = pi_temp;
15362 } else
15363 pi = pi->next;
15364 }
15365 }
15366
15367 bgp_dest_unlock_node(dest);
15368 }
15369 }
15370
15371 return CMD_SUCCESS;
15372 }
15373
15374 DEFUN (clear_ip_bgp_dampening,
15375 clear_ip_bgp_dampening_cmd,
15376 "clear ip bgp dampening",
15377 CLEAR_STR
15378 IP_STR
15379 BGP_STR
15380 "Clear route flap dampening information\n")
15381 {
15382 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15383 return CMD_SUCCESS;
15384 }
15385
15386 DEFUN (clear_ip_bgp_dampening_prefix,
15387 clear_ip_bgp_dampening_prefix_cmd,
15388 "clear ip bgp dampening A.B.C.D/M",
15389 CLEAR_STR
15390 IP_STR
15391 BGP_STR
15392 "Clear route flap dampening information\n"
15393 "IPv4 prefix\n")
15394 {
15395 int idx_ipv4_prefixlen = 4;
15396 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15397 AFI_IP, SAFI_UNICAST, NULL, 1);
15398 }
15399
15400 DEFUN (clear_ip_bgp_dampening_address,
15401 clear_ip_bgp_dampening_address_cmd,
15402 "clear ip bgp dampening A.B.C.D",
15403 CLEAR_STR
15404 IP_STR
15405 BGP_STR
15406 "Clear route flap dampening information\n"
15407 "Network to clear damping information\n")
15408 {
15409 int idx_ipv4 = 4;
15410 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15411 SAFI_UNICAST, NULL, 0);
15412 }
15413
15414 DEFUN (clear_ip_bgp_dampening_address_mask,
15415 clear_ip_bgp_dampening_address_mask_cmd,
15416 "clear ip bgp dampening A.B.C.D A.B.C.D",
15417 CLEAR_STR
15418 IP_STR
15419 BGP_STR
15420 "Clear route flap dampening information\n"
15421 "Network to clear damping information\n"
15422 "Network mask\n")
15423 {
15424 int idx_ipv4 = 4;
15425 int idx_ipv4_2 = 5;
15426 int ret;
15427 char prefix_str[BUFSIZ];
15428
15429 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15430 prefix_str, sizeof(prefix_str));
15431 if (!ret) {
15432 vty_out(vty, "%% Inconsistent address and mask\n");
15433 return CMD_WARNING;
15434 }
15435
15436 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15437 NULL, 0);
15438 }
15439
15440 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15441 {
15442 struct vty *vty = arg;
15443 struct peer *peer = bucket->data;
15444
15445 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15446 }
15447
15448 DEFUN (show_bgp_listeners,
15449 show_bgp_listeners_cmd,
15450 "show bgp listeners",
15451 SHOW_STR
15452 BGP_STR
15453 "Display Listen Sockets and who created them\n")
15454 {
15455 bgp_dump_listener_info(vty);
15456
15457 return CMD_SUCCESS;
15458 }
15459
15460 DEFUN (show_bgp_peerhash,
15461 show_bgp_peerhash_cmd,
15462 "show bgp peerhash",
15463 SHOW_STR
15464 BGP_STR
15465 "Display information about the BGP peerhash\n")
15466 {
15467 struct list *instances = bm->bgp;
15468 struct listnode *node;
15469 struct bgp *bgp;
15470
15471 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15472 vty_out(vty, "BGP: %s\n", bgp->name);
15473 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15474 vty);
15475 }
15476
15477 return CMD_SUCCESS;
15478 }
15479
15480 /* also used for encap safi */
15481 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15482 afi_t afi, safi_t safi)
15483 {
15484 struct bgp_dest *pdest;
15485 struct bgp_dest *dest;
15486 struct bgp_table *table;
15487 const struct prefix *p;
15488 const struct prefix_rd *prd;
15489 struct bgp_static *bgp_static;
15490 mpls_label_t label;
15491
15492 /* Network configuration. */
15493 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15494 pdest = bgp_route_next(pdest)) {
15495 table = bgp_dest_get_bgp_table_info(pdest);
15496 if (!table)
15497 continue;
15498
15499 for (dest = bgp_table_top(table); dest;
15500 dest = bgp_route_next(dest)) {
15501 bgp_static = bgp_dest_get_bgp_static_info(dest);
15502 if (bgp_static == NULL)
15503 continue;
15504
15505 p = bgp_dest_get_prefix(dest);
15506 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
15507 pdest);
15508
15509 /* "network" configuration display. */
15510 label = decode_label(&bgp_static->label);
15511
15512 vty_out(vty, " network %pFX rd %pRD", p, prd);
15513 if (safi == SAFI_MPLS_VPN)
15514 vty_out(vty, " label %u", label);
15515
15516 if (bgp_static->rmap.name)
15517 vty_out(vty, " route-map %s",
15518 bgp_static->rmap.name);
15519
15520 if (bgp_static->backdoor)
15521 vty_out(vty, " backdoor");
15522
15523 vty_out(vty, "\n");
15524 }
15525 }
15526 }
15527
15528 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15529 afi_t afi, safi_t safi)
15530 {
15531 struct bgp_dest *pdest;
15532 struct bgp_dest *dest;
15533 struct bgp_table *table;
15534 const struct prefix *p;
15535 const struct prefix_rd *prd;
15536 struct bgp_static *bgp_static;
15537 char buf[PREFIX_STRLEN * 2];
15538 char buf2[SU_ADDRSTRLEN];
15539 char esi_buf[ESI_STR_LEN];
15540
15541 /* Network configuration. */
15542 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15543 pdest = bgp_route_next(pdest)) {
15544 table = bgp_dest_get_bgp_table_info(pdest);
15545 if (!table)
15546 continue;
15547
15548 for (dest = bgp_table_top(table); dest;
15549 dest = bgp_route_next(dest)) {
15550 bgp_static = bgp_dest_get_bgp_static_info(dest);
15551 if (bgp_static == NULL)
15552 continue;
15553
15554 char *macrouter = NULL;
15555
15556 if (bgp_static->router_mac)
15557 macrouter = prefix_mac2str(
15558 bgp_static->router_mac, NULL, 0);
15559 if (bgp_static->eth_s_id)
15560 esi_to_str(bgp_static->eth_s_id,
15561 esi_buf, sizeof(esi_buf));
15562 p = bgp_dest_get_prefix(dest);
15563 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
15564
15565 /* "network" configuration display. */
15566 if (p->u.prefix_evpn.route_type == 5) {
15567 char local_buf[PREFIX_STRLEN];
15568
15569 uint8_t family = is_evpn_prefix_ipaddr_v4((
15570 struct prefix_evpn *)p)
15571 ? AF_INET
15572 : AF_INET6;
15573 inet_ntop(family,
15574 &p->u.prefix_evpn.prefix_addr.ip.ip
15575 .addr,
15576 local_buf, sizeof(local_buf));
15577 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15578 p->u.prefix_evpn.prefix_addr
15579 .ip_prefix_length);
15580 } else {
15581 prefix2str(p, buf, sizeof(buf));
15582 }
15583
15584 if (bgp_static->gatewayIp.family == AF_INET
15585 || bgp_static->gatewayIp.family == AF_INET6)
15586 inet_ntop(bgp_static->gatewayIp.family,
15587 &bgp_static->gatewayIp.u.prefix, buf2,
15588 sizeof(buf2));
15589 vty_out(vty,
15590 " network %s rd %pRD ethtag %u label %u esi %s gwip %s routermac %s\n",
15591 buf, prd, p->u.prefix_evpn.prefix_addr.eth_tag,
15592 decode_label(&bgp_static->label), esi_buf, buf2,
15593 macrouter);
15594
15595 XFREE(MTYPE_TMP, macrouter);
15596 }
15597 }
15598 }
15599
15600 /* Configuration of static route announcement and aggregate
15601 information. */
15602 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15603 safi_t safi)
15604 {
15605 struct bgp_dest *dest;
15606 const struct prefix *p;
15607 struct bgp_static *bgp_static;
15608 struct bgp_aggregate *bgp_aggregate;
15609
15610 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15611 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15612 return;
15613 }
15614
15615 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15616 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15617 return;
15618 }
15619
15620 /* Network configuration. */
15621 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15622 dest = bgp_route_next(dest)) {
15623 bgp_static = bgp_dest_get_bgp_static_info(dest);
15624 if (bgp_static == NULL)
15625 continue;
15626
15627 p = bgp_dest_get_prefix(dest);
15628
15629 vty_out(vty, " network %pFX", p);
15630
15631 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15632 vty_out(vty, " label-index %u",
15633 bgp_static->label_index);
15634
15635 if (bgp_static->rmap.name)
15636 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15637
15638 if (bgp_static->backdoor)
15639 vty_out(vty, " backdoor");
15640
15641 vty_out(vty, "\n");
15642 }
15643
15644 /* Aggregate-address configuration. */
15645 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15646 dest = bgp_route_next(dest)) {
15647 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15648 if (bgp_aggregate == NULL)
15649 continue;
15650
15651 p = bgp_dest_get_prefix(dest);
15652
15653 vty_out(vty, " aggregate-address %pFX", p);
15654
15655 if (bgp_aggregate->as_set)
15656 vty_out(vty, " as-set");
15657
15658 if (bgp_aggregate->summary_only)
15659 vty_out(vty, " summary-only");
15660
15661 if (bgp_aggregate->rmap.name)
15662 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15663
15664 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15665 vty_out(vty, " origin %s",
15666 bgp_origin2str(bgp_aggregate->origin));
15667
15668 if (bgp_aggregate->match_med)
15669 vty_out(vty, " matching-MED-only");
15670
15671 if (bgp_aggregate->suppress_map_name)
15672 vty_out(vty, " suppress-map %s",
15673 bgp_aggregate->suppress_map_name);
15674
15675 vty_out(vty, "\n");
15676 }
15677 }
15678
15679 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15680 safi_t safi)
15681 {
15682 struct bgp_dest *dest;
15683 struct bgp_distance *bdistance;
15684
15685 /* Distance configuration. */
15686 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15687 && bgp->distance_local[afi][safi]
15688 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15689 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15690 || bgp->distance_local[afi][safi]
15691 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15692 vty_out(vty, " distance bgp %d %d %d\n",
15693 bgp->distance_ebgp[afi][safi],
15694 bgp->distance_ibgp[afi][safi],
15695 bgp->distance_local[afi][safi]);
15696 }
15697
15698 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15699 dest = bgp_route_next(dest)) {
15700 bdistance = bgp_dest_get_bgp_distance_info(dest);
15701 if (bdistance != NULL)
15702 vty_out(vty, " distance %d %pBD %s\n",
15703 bdistance->distance, dest,
15704 bdistance->access_list ? bdistance->access_list
15705 : "");
15706 }
15707 }
15708
15709 /* Allocate routing table structure and install commands. */
15710 void bgp_route_init(void)
15711 {
15712 afi_t afi;
15713 safi_t safi;
15714
15715 /* Init BGP distance table. */
15716 FOREACH_AFI_SAFI (afi, safi)
15717 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15718
15719 /* IPv4 BGP commands. */
15720 install_element(BGP_NODE, &bgp_table_map_cmd);
15721 install_element(BGP_NODE, &bgp_network_cmd);
15722 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15723
15724 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15725
15726 /* IPv4 unicast configuration. */
15727 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15728 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15729 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15730
15731 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15732
15733 /* IPv4 multicast configuration. */
15734 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15735 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15736 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15737 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15738
15739 /* IPv4 labeled-unicast configuration. */
15740 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15741 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15742
15743 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15744 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15745 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15746 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15747 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15748 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15749 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15750 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15751
15752 install_element(VIEW_NODE,
15753 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15754 install_element(VIEW_NODE,
15755 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15756 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15757 install_element(VIEW_NODE,
15758 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15759 #ifdef KEEP_OLD_VPN_COMMANDS
15760 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15761 #endif /* KEEP_OLD_VPN_COMMANDS */
15762 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15763 install_element(VIEW_NODE,
15764 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15765
15766 /* BGP dampening clear commands */
15767 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15768 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15769
15770 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15771 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15772
15773 /* prefix count */
15774 install_element(ENABLE_NODE,
15775 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15776 #ifdef KEEP_OLD_VPN_COMMANDS
15777 install_element(ENABLE_NODE,
15778 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15779 #endif /* KEEP_OLD_VPN_COMMANDS */
15780
15781 /* New config IPv6 BGP commands. */
15782 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15783 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15784 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15785
15786 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15787
15788 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15789
15790 /* IPv6 labeled unicast address family. */
15791 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15792 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15793
15794 install_element(BGP_NODE, &bgp_distance_cmd);
15795 install_element(BGP_NODE, &no_bgp_distance_cmd);
15796 install_element(BGP_NODE, &bgp_distance_source_cmd);
15797 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15798 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15799 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15800 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15801 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15802 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15803 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15804 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15805 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15806 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15807 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15808 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15809 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15810 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15811 install_element(BGP_IPV4M_NODE,
15812 &no_bgp_distance_source_access_list_cmd);
15813 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15814 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15815 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15816 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15817 install_element(BGP_IPV6_NODE,
15818 &ipv6_bgp_distance_source_access_list_cmd);
15819 install_element(BGP_IPV6_NODE,
15820 &no_ipv6_bgp_distance_source_access_list_cmd);
15821 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15822 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15823 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15824 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15825 install_element(BGP_IPV6M_NODE,
15826 &ipv6_bgp_distance_source_access_list_cmd);
15827 install_element(BGP_IPV6M_NODE,
15828 &no_ipv6_bgp_distance_source_access_list_cmd);
15829
15830 /* BGP dampening */
15831 install_element(BGP_NODE, &bgp_damp_set_cmd);
15832 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15833 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15834 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15835 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15836 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15837 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15838 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15839 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15840 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15841 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15842 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15843 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15844 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15845
15846 /* Large Communities */
15847 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15848 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15849
15850 /* show bgp ipv4 flowspec detailed */
15851 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15852
15853 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15854 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15855 }
15856
15857 void bgp_route_finish(void)
15858 {
15859 afi_t afi;
15860 safi_t safi;
15861
15862 FOREACH_AFI_SAFI (afi, safi) {
15863 bgp_table_unlock(bgp_distance_table[afi][safi]);
15864 bgp_distance_table[afi][safi] = NULL;
15865 }
15866 }