]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #12651 from opensourcerouting/fix/revert_bgp_orr
[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 attr->mp_nexthop_len =
2277 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2278 }
2279
2280 /* Clear off link-local nexthop in source, whenever it is not
2281 * needed to
2282 * ensure more prefixes share the same attribute for
2283 * announcement.
2284 */
2285 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2286 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2287 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2288 }
2289
2290 if (bgp_check_role_applicability(afi, safi) &&
2291 bgp_otc_egress(peer, attr))
2292 return false;
2293
2294 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2295 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2296
2297 if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
2298 filter->advmap.aname &&
2299 route_map_lookup_by_name(filter->advmap.aname)) {
2300 struct bgp_path_info rmap_path = {0};
2301 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2302 struct attr dummy_attr = *attr;
2303
2304 /* Fill temp path_info */
2305 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2306 pi, peer, &dummy_attr);
2307
2308 struct route_map *amap =
2309 route_map_lookup_by_name(filter->advmap.aname);
2310
2311 ret = route_map_apply(amap, p, &rmap_path);
2312
2313 bgp_attr_flush(&dummy_attr);
2314
2315 /*
2316 * The conditional advertisement mode is Withdraw and this
2317 * prefix is a conditional prefix. Don't advertise it
2318 */
2319 if (ret == RMAP_PERMITMATCH)
2320 return false;
2321 }
2322
2323 /* Route map & unsuppress-map apply. */
2324 if (!post_attr &&
2325 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2326 struct bgp_path_info rmap_path = {0};
2327 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2328 struct attr dummy_attr = {0};
2329
2330 /* Fill temp path_info */
2331 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2332 pi, peer, attr);
2333
2334 /* don't confuse inbound and outbound setting */
2335 RESET_FLAG(attr->rmap_change_flags);
2336
2337 /*
2338 * The route reflector is not allowed to modify the attributes
2339 * of the reflected IBGP routes unless explicitly allowed.
2340 */
2341 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2342 && !CHECK_FLAG(bgp->flags,
2343 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2344 dummy_attr = *attr;
2345 rmap_path.attr = &dummy_attr;
2346 }
2347
2348 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2349
2350 if (bgp_path_suppressed(pi))
2351 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2352 &rmap_path);
2353 else
2354 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2355 &rmap_path);
2356
2357 bgp_attr_flush(&dummy_attr);
2358 peer->rmap_type = 0;
2359
2360 if (ret == RMAP_DENYMATCH) {
2361 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2362 zlog_debug(
2363 "%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
2364 peer, p, ROUTE_MAP_OUT_NAME(filter));
2365 bgp_attr_flush(rmap_path.attr);
2366 return false;
2367 }
2368 }
2369
2370 /* RFC 8212 to prevent route leaks.
2371 * This specification intends to improve this situation by requiring the
2372 * explicit configuration of both BGP Import and Export Policies for any
2373 * External BGP (EBGP) session such as customers, peers, or
2374 * confederation boundaries for all enabled address families. Through
2375 * codification of the aforementioned requirement, operators will
2376 * benefit from consistent behavior across different BGP
2377 * implementations.
2378 */
2379 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2380 if (!bgp_outbound_policy_exists(peer, filter)) {
2381 if (monotime_since(&bgp->ebgprequirespolicywarning,
2382 NULL) > FIFTEENMINUTE2USEC ||
2383 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2384 zlog_warn(
2385 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2386 monotime(&bgp->ebgprequirespolicywarning);
2387 }
2388 return false;
2389 }
2390
2391 /* draft-ietf-idr-deprecate-as-set-confed-set
2392 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2393 * Eventually, This document (if approved) updates RFC 4271
2394 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2395 * and obsoletes RFC 6472.
2396 */
2397 if (peer->bgp->reject_as_sets)
2398 if (aspath_check_as_sets(attr->aspath))
2399 return false;
2400
2401 /* If neighbor soo is configured, then check if the route has
2402 * SoO extended community and validate against the configured
2403 * one. If they match, do not announce, to prevent routing
2404 * loops.
2405 */
2406 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2407 peer->soo[afi][safi]) {
2408 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2409 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2410
2411 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2412 ECOMMUNITY_SITE_ORIGIN) ||
2413 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2414 ECOMMUNITY_SITE_ORIGIN) ||
2415 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
2416 ECOMMUNITY_SITE_ORIGIN)) &&
2417 ecommunity_include(ecomm, ecomm_soo)) {
2418 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2419 zlog_debug(
2420 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2421 peer, p, ecommunity_str(ecomm_soo));
2422 return false;
2423 }
2424 }
2425
2426 /* Codification of AS 0 Processing */
2427 if (aspath_check_as_zero(attr->aspath))
2428 return false;
2429
2430 if (bgp_in_graceful_shutdown(bgp)) {
2431 if (peer->sort == BGP_PEER_IBGP
2432 || peer->sort == BGP_PEER_CONFED) {
2433 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2434 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2435 } else {
2436 bgp_attr_add_gshut_community(attr);
2437 }
2438 }
2439
2440 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2441 * Capability" to a neighbor MUST perform the following upon receiving
2442 * a route from that neighbor with the "LLGR_STALE" community, or upon
2443 * attaching the "LLGR_STALE" community itself per Section 4.2:
2444 *
2445 * The route SHOULD NOT be advertised to any neighbor from which the
2446 * Long-lived Graceful Restart Capability has not been received.
2447 */
2448 if (bgp_attr_get_community(attr) &&
2449 community_include(bgp_attr_get_community(attr),
2450 COMMUNITY_LLGR_STALE) &&
2451 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2452 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2453 return false;
2454
2455 /* After route-map has been applied, we check to see if the nexthop to
2456 * be carried in the attribute (that is used for the announcement) can
2457 * be cleared off or not. We do this in all cases where we would be
2458 * setting the nexthop to "ourselves". For IPv6, we only need to
2459 * consider
2460 * the global nexthop here; the link-local nexthop would have been
2461 * cleared
2462 * already, and if not, it is required by the update formation code.
2463 * Also see earlier comments in this function.
2464 */
2465 /*
2466 * If route-map has performed some operation on the nexthop or the peer
2467 * configuration says to pass it unchanged, we cannot reset the nexthop
2468 * here, so only attempt to do it if these aren't true. Note that the
2469 * route-map handler itself might have cleared the nexthop, if for
2470 * example,
2471 * it is configured as 'peer-address'.
2472 */
2473 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2474 piattr->rmap_change_flags)
2475 && !transparent
2476 && !CHECK_FLAG(peer->af_flags[afi][safi],
2477 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2478 /* We can reset the nexthop, if setting (or forcing) it to
2479 * 'self' */
2480 if (CHECK_FLAG(peer->af_flags[afi][safi],
2481 PEER_FLAG_NEXTHOP_SELF)
2482 || CHECK_FLAG(peer->af_flags[afi][safi],
2483 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2484 if (!reflect
2485 || CHECK_FLAG(peer->af_flags[afi][safi],
2486 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2487 subgroup_announce_reset_nhop(
2488 (peer_cap_enhe(peer, afi, safi)
2489 ? AF_INET6
2490 : p->family),
2491 attr);
2492 nh_reset = true;
2493 }
2494 } else if (peer->sort == BGP_PEER_EBGP) {
2495 /* Can also reset the nexthop if announcing to EBGP, but
2496 * only if
2497 * no peer in the subgroup is on a shared subnet.
2498 * Note: 3rd party nexthop currently implemented for
2499 * IPv4 only.
2500 */
2501 if ((p->family == AF_INET) &&
2502 (!bgp_subgrp_multiaccess_check_v4(
2503 piattr->nexthop,
2504 subgrp, from))) {
2505 subgroup_announce_reset_nhop(
2506 (peer_cap_enhe(peer, afi, safi)
2507 ? AF_INET6
2508 : p->family),
2509 attr);
2510 nh_reset = true;
2511 }
2512
2513 if ((p->family == AF_INET6) &&
2514 (!bgp_subgrp_multiaccess_check_v6(
2515 piattr->mp_nexthop_global,
2516 subgrp, from))) {
2517 subgroup_announce_reset_nhop(
2518 (peer_cap_enhe(peer, afi, safi)
2519 ? AF_INET6
2520 : p->family),
2521 attr);
2522 nh_reset = true;
2523 }
2524
2525
2526
2527 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2528 /*
2529 * This flag is used for leaked vpn-vrf routes
2530 */
2531 int family = p->family;
2532
2533 if (peer_cap_enhe(peer, afi, safi))
2534 family = AF_INET6;
2535
2536 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2537 zlog_debug(
2538 "%s: %pFX BGP_PATH_ANNC_NH_SELF, family=%s",
2539 __func__, p, family2str(family));
2540 subgroup_announce_reset_nhop(family, attr);
2541 nh_reset = true;
2542 }
2543 }
2544
2545 /* If IPv6/MP and nexthop does not have any override and happens
2546 * to
2547 * be a link-local address, reset it so that we don't pass along
2548 * the
2549 * source's link-local IPv6 address to recipients who may not be
2550 * on
2551 * the same interface.
2552 */
2553 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2554 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2555 subgroup_announce_reset_nhop(AF_INET6, attr);
2556 nh_reset = true;
2557 }
2558 }
2559
2560 /* If this is an iBGP, send Origin Validation State (OVS)
2561 * extended community (rfc8097).
2562 */
2563 if (peer->sort == BGP_PEER_IBGP) {
2564 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2565
2566 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2567
2568 if (rpki_state != RPKI_NOT_BEING_USED)
2569 bgp_attr_set_ecommunity(
2570 attr, ecommunity_add_origin_validation_state(
2571 rpki_state,
2572 bgp_attr_get_ecommunity(attr)));
2573 }
2574
2575 /*
2576 * When the next hop is set to ourselves, if all multipaths have
2577 * link-bandwidth announce the cumulative bandwidth as that makes
2578 * the most sense. However, don't modify if the link-bandwidth has
2579 * been explicitly set by user policy.
2580 */
2581 if (nh_reset &&
2582 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2583 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2584 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2585 bgp_attr_set_ecommunity(
2586 attr,
2587 ecommunity_replace_linkbw(
2588 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2589 CHECK_FLAG(
2590 peer->flags,
2591 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2592
2593 return true;
2594 }
2595
2596 static void bgp_route_select_timer_expire(struct thread *thread)
2597 {
2598 struct afi_safi_info *info;
2599 afi_t afi;
2600 safi_t safi;
2601 struct bgp *bgp;
2602
2603 info = THREAD_ARG(thread);
2604 afi = info->afi;
2605 safi = info->safi;
2606 bgp = info->bgp;
2607
2608 bgp->gr_info[afi][safi].t_route_select = NULL;
2609 XFREE(MTYPE_TMP, info);
2610
2611 /* Best path selection */
2612 bgp_best_path_select_defer(bgp, afi, safi);
2613 }
2614
2615 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2616 struct bgp_maxpaths_cfg *mpath_cfg,
2617 struct bgp_path_info_pair *result, afi_t afi,
2618 safi_t safi)
2619 {
2620 struct bgp_path_info *new_select;
2621 struct bgp_path_info *old_select;
2622 struct bgp_path_info *pi;
2623 struct bgp_path_info *pi1;
2624 struct bgp_path_info *pi2;
2625 struct bgp_path_info *nextpi = NULL;
2626 int paths_eq, do_mpath, debug;
2627 struct list mp_list;
2628 char pfx_buf[PREFIX2STR_BUFFER];
2629 char path_buf[PATH_ADDPATH_STR_BUFFER];
2630
2631 bgp_mp_list_init(&mp_list);
2632 do_mpath =
2633 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2634
2635 debug = bgp_debug_bestpath(dest);
2636
2637 if (debug)
2638 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2639
2640 dest->reason = bgp_path_selection_none;
2641 /* bgp deterministic-med */
2642 new_select = NULL;
2643 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2644
2645 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2646 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2647 pi1 = pi1->next)
2648 bgp_path_info_unset_flag(dest, pi1,
2649 BGP_PATH_DMED_SELECTED);
2650
2651 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2652 pi1 = pi1->next) {
2653 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2654 continue;
2655 if (BGP_PATH_HOLDDOWN(pi1))
2656 continue;
2657 if (pi1->peer != bgp->peer_self)
2658 if (!peer_established(pi1->peer))
2659 continue;
2660
2661 new_select = pi1;
2662 if (pi1->next) {
2663 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2664 if (CHECK_FLAG(pi2->flags,
2665 BGP_PATH_DMED_CHECK))
2666 continue;
2667 if (BGP_PATH_HOLDDOWN(pi2))
2668 continue;
2669 if (pi2->peer != bgp->peer_self
2670 && !CHECK_FLAG(
2671 pi2->peer->sflags,
2672 PEER_STATUS_NSF_WAIT))
2673 if (pi2->peer->status
2674 != Established)
2675 continue;
2676
2677 if (!aspath_cmp_left(pi1->attr->aspath,
2678 pi2->attr->aspath)
2679 && !aspath_cmp_left_confed(
2680 pi1->attr->aspath,
2681 pi2->attr->aspath))
2682 continue;
2683
2684 if (bgp_path_info_cmp(
2685 bgp, pi2, new_select,
2686 &paths_eq, mpath_cfg, debug,
2687 pfx_buf, afi, safi,
2688 &dest->reason)) {
2689 bgp_path_info_unset_flag(
2690 dest, new_select,
2691 BGP_PATH_DMED_SELECTED);
2692 new_select = pi2;
2693 }
2694
2695 bgp_path_info_set_flag(
2696 dest, pi2, BGP_PATH_DMED_CHECK);
2697 }
2698 }
2699 bgp_path_info_set_flag(dest, new_select,
2700 BGP_PATH_DMED_CHECK);
2701 bgp_path_info_set_flag(dest, new_select,
2702 BGP_PATH_DMED_SELECTED);
2703
2704 if (debug) {
2705 bgp_path_info_path_with_addpath_rx_str(
2706 new_select, path_buf, sizeof(path_buf));
2707 zlog_debug(
2708 "%pBD(%s): %s is the bestpath from AS %u",
2709 dest, bgp->name_pretty, path_buf,
2710 aspath_get_first_as(
2711 new_select->attr->aspath));
2712 }
2713 }
2714 }
2715
2716 /* Check old selected route and new selected route. */
2717 old_select = NULL;
2718 new_select = NULL;
2719 for (pi = bgp_dest_get_bgp_path_info(dest);
2720 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2721 enum bgp_path_selection_reason reason;
2722
2723 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2724 old_select = pi;
2725
2726 if (BGP_PATH_HOLDDOWN(pi)) {
2727 /* reap REMOVED routes, if needs be
2728 * selected route must stay for a while longer though
2729 */
2730 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2731 && (pi != old_select))
2732 bgp_path_info_reap(dest, pi);
2733
2734 if (debug)
2735 zlog_debug("%s: pi %p in holddown", __func__,
2736 pi);
2737
2738 continue;
2739 }
2740
2741 if (pi->peer && pi->peer != bgp->peer_self
2742 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2743 if (!peer_established(pi->peer)) {
2744
2745 if (debug)
2746 zlog_debug(
2747 "%s: pi %p non self peer %s not estab state",
2748 __func__, pi, pi->peer->host);
2749
2750 continue;
2751 }
2752
2753 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2754 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2755 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2756 if (debug)
2757 zlog_debug("%s: pi %p dmed", __func__, pi);
2758 continue;
2759 }
2760
2761 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2762
2763 reason = dest->reason;
2764 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2765 debug, pfx_buf, afi, safi,
2766 &dest->reason)) {
2767 if (new_select == NULL &&
2768 reason != bgp_path_selection_none)
2769 dest->reason = reason;
2770 new_select = pi;
2771 }
2772 }
2773
2774 /* Now that we know which path is the bestpath see if any of the other
2775 * paths
2776 * qualify as multipaths
2777 */
2778 if (debug) {
2779 if (new_select)
2780 bgp_path_info_path_with_addpath_rx_str(
2781 new_select, path_buf, sizeof(path_buf));
2782 else
2783 snprintf(path_buf, sizeof(path_buf), "NONE");
2784 zlog_debug(
2785 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2786 dest, bgp->name_pretty, path_buf,
2787 old_select ? old_select->peer->host : "NONE");
2788 }
2789
2790 if (do_mpath && new_select) {
2791 for (pi = bgp_dest_get_bgp_path_info(dest);
2792 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2793
2794 if (debug)
2795 bgp_path_info_path_with_addpath_rx_str(
2796 pi, path_buf, sizeof(path_buf));
2797
2798 if (pi == new_select) {
2799 if (debug)
2800 zlog_debug(
2801 "%pBD(%s): %s is the bestpath, add to the multipath list",
2802 dest, bgp->name_pretty,
2803 path_buf);
2804 bgp_mp_list_add(&mp_list, pi);
2805 continue;
2806 }
2807
2808 if (BGP_PATH_HOLDDOWN(pi))
2809 continue;
2810
2811 if (pi->peer && pi->peer != bgp->peer_self
2812 && !CHECK_FLAG(pi->peer->sflags,
2813 PEER_STATUS_NSF_WAIT))
2814 if (!peer_established(pi->peer))
2815 continue;
2816
2817 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2818 if (debug)
2819 zlog_debug(
2820 "%pBD: %s has the same nexthop as the bestpath, skip it",
2821 dest, path_buf);
2822 continue;
2823 }
2824
2825 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2826 mpath_cfg, debug, pfx_buf, afi, safi,
2827 &dest->reason);
2828
2829 if (paths_eq) {
2830 if (debug)
2831 zlog_debug(
2832 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2833 dest, path_buf);
2834 bgp_mp_list_add(&mp_list, pi);
2835 }
2836 }
2837 }
2838
2839 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2840 mpath_cfg);
2841 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2842 bgp_mp_list_clear(&mp_list);
2843
2844 bgp_addpath_update_ids(bgp, dest, afi, safi);
2845
2846 result->old = old_select;
2847 result->new = new_select;
2848
2849 return;
2850 }
2851
2852 /*
2853 * A new route/change in bestpath of an existing route. Evaluate the path
2854 * for advertisement to the subgroup.
2855 */
2856 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2857 struct bgp_path_info *selected,
2858 struct bgp_dest *dest,
2859 uint32_t addpath_tx_id)
2860 {
2861 const struct prefix *p;
2862 struct peer *onlypeer;
2863 struct attr attr;
2864 afi_t afi;
2865 safi_t safi;
2866 struct bgp *bgp;
2867 bool advertise;
2868
2869 p = bgp_dest_get_prefix(dest);
2870 afi = SUBGRP_AFI(subgrp);
2871 safi = SUBGRP_SAFI(subgrp);
2872 bgp = SUBGRP_INST(subgrp);
2873 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2874 : NULL);
2875
2876 if (BGP_DEBUG(update, UPDATE_OUT))
2877 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2878
2879 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2880 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2881 PEER_STATUS_ORF_WAIT_REFRESH))
2882 return;
2883
2884 memset(&attr, 0, sizeof(attr));
2885 /* It's initialized in bgp_announce_check() */
2886
2887 /* Announcement to the subgroup. If the route is filtered withdraw it.
2888 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2889 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2890 * route
2891 */
2892 advertise = bgp_check_advertise(bgp, dest);
2893
2894 if (selected) {
2895 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2896 NULL)) {
2897 /* Route is selected, if the route is already installed
2898 * in FIB, then it is advertised
2899 */
2900 if (advertise) {
2901 if (!bgp_check_withdrawal(bgp, dest))
2902 bgp_adj_out_set_subgroup(
2903 dest, subgrp, &attr, selected);
2904 else
2905 bgp_adj_out_unset_subgroup(
2906 dest, subgrp, 1, addpath_tx_id);
2907 }
2908 } else
2909 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2910 addpath_tx_id);
2911 }
2912
2913 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2914 else {
2915 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2916 }
2917 }
2918
2919 /*
2920 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2921 * This is called at the end of route processing.
2922 */
2923 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2924 {
2925 struct bgp_path_info *pi;
2926
2927 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2928 if (BGP_PATH_HOLDDOWN(pi))
2929 continue;
2930 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2931 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2932 }
2933 }
2934
2935 /*
2936 * Has the route changed from the RIB's perspective? This is invoked only
2937 * if the route selection returns the same best route as earlier - to
2938 * determine if we need to update zebra or not.
2939 */
2940 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2941 {
2942 struct bgp_path_info *mpinfo;
2943
2944 /* If this is multipath, check all selected paths for any nexthop
2945 * change or attribute change. Some attribute changes (e.g., community)
2946 * aren't of relevance to the RIB, but we'll update zebra to ensure
2947 * we handle the case of BGP nexthop change. This is the behavior
2948 * when the best path has an attribute change anyway.
2949 */
2950 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2951 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2952 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2953 return true;
2954
2955 /*
2956 * If this is multipath, check all selected paths for any nexthop change
2957 */
2958 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2959 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2960 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2961 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2962 return true;
2963 }
2964
2965 /* Nothing has changed from the RIB's perspective. */
2966 return false;
2967 }
2968
2969 struct bgp_process_queue {
2970 struct bgp *bgp;
2971 STAILQ_HEAD(, bgp_dest) pqueue;
2972 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2973 unsigned int flags;
2974 unsigned int queued;
2975 };
2976
2977 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
2978 safi_t safi, struct bgp_dest *dest,
2979 struct bgp_path_info *new_select,
2980 struct bgp_path_info *old_select)
2981 {
2982 const struct prefix *p = bgp_dest_get_prefix(dest);
2983
2984 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
2985 return;
2986
2987 if (advertise_type5_routes(bgp, afi) && new_select
2988 && is_route_injectable_into_evpn(new_select)) {
2989
2990 /* apply the route-map */
2991 if (bgp->adv_cmd_rmap[afi][safi].map) {
2992 route_map_result_t ret;
2993 struct bgp_path_info rmap_path;
2994 struct bgp_path_info_extra rmap_path_extra;
2995 struct attr dummy_attr;
2996
2997 dummy_attr = *new_select->attr;
2998
2999 /* Fill temp path_info */
3000 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
3001 new_select, new_select->peer,
3002 &dummy_attr);
3003
3004 RESET_FLAG(dummy_attr.rmap_change_flags);
3005
3006 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
3007 p, &rmap_path);
3008
3009 if (ret == RMAP_DENYMATCH) {
3010 bgp_attr_flush(&dummy_attr);
3011 bgp_evpn_withdraw_type5_route(bgp, p, afi,
3012 safi);
3013 } else
3014 bgp_evpn_advertise_type5_route(
3015 bgp, p, &dummy_attr, afi, safi);
3016 } else {
3017 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
3018 afi, safi);
3019 }
3020 } else if (advertise_type5_routes(bgp, afi) && old_select
3021 && is_route_injectable_into_evpn(old_select))
3022 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
3023 }
3024
3025 /*
3026 * Utility to determine whether a particular path_info should use
3027 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
3028 * in a path where we basically _know_ this is a BGP-LU route.
3029 */
3030 static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
3031 {
3032 /* Certain types get imp null; so do paths where the nexthop is
3033 * not labeled.
3034 */
3035 if (new_select->sub_type == BGP_ROUTE_STATIC
3036 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3037 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
3038 return true;
3039 else if (new_select->extra == NULL ||
3040 !bgp_is_valid_label(&new_select->extra->label[0]))
3041 /* TODO -- should be configurable? */
3042 return true;
3043 else
3044 return false;
3045 }
3046
3047 /*
3048 * old_select = The old best path
3049 * new_select = the new best path
3050 *
3051 * if (!old_select && new_select)
3052 * We are sending new information on.
3053 *
3054 * if (old_select && new_select) {
3055 * if (new_select != old_select)
3056 * We have a new best path send a change
3057 * else
3058 * We've received a update with new attributes that needs
3059 * to be passed on.
3060 * }
3061 *
3062 * if (old_select && !new_select)
3063 * We have no eligible route that we can announce or the rn
3064 * is being removed.
3065 */
3066 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3067 afi_t afi, safi_t safi)
3068 {
3069 struct bgp_path_info *new_select;
3070 struct bgp_path_info *old_select;
3071 struct bgp_path_info_pair old_and_new;
3072 int debug = 0;
3073
3074 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3075 if (dest)
3076 debug = bgp_debug_bestpath(dest);
3077 if (debug)
3078 zlog_debug(
3079 "%s: bgp delete in progress, ignoring event, p=%pBD",
3080 __func__, dest);
3081 return;
3082 }
3083 /* Is it end of initial update? (after startup) */
3084 if (!dest) {
3085 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3086 sizeof(bgp->update_delay_zebra_resume_time));
3087
3088 bgp->main_zebra_update_hold = 0;
3089 FOREACH_AFI_SAFI (afi, safi) {
3090 if (bgp_fibupd_safi(safi))
3091 bgp_zebra_announce_table(bgp, afi, safi);
3092 }
3093 bgp->main_peers_update_hold = 0;
3094
3095 bgp_start_routeadv(bgp);
3096 return;
3097 }
3098
3099 const struct prefix *p = bgp_dest_get_prefix(dest);
3100
3101 debug = bgp_debug_bestpath(dest);
3102 if (debug)
3103 zlog_debug("%s: p=%pBDi(%s) afi=%s, safi=%s start", __func__,
3104 dest, bgp->name_pretty, afi2str(afi),
3105 safi2str(safi));
3106
3107 /* The best path calculation for the route is deferred if
3108 * BGP_NODE_SELECT_DEFER is set
3109 */
3110 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3111 if (BGP_DEBUG(update, UPDATE_OUT))
3112 zlog_debug("SELECT_DEFER flag set for route %p", dest);
3113 return;
3114 }
3115
3116 /* Best path selection. */
3117 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3118 afi, safi);
3119 old_select = old_and_new.old;
3120 new_select = old_and_new.new;
3121
3122 /* Do we need to allocate or free labels?
3123 * Right now, since we only deal with per-prefix labels, it is not
3124 * necessary to do this upon changes to best path. Exceptions:
3125 * - label index has changed -> recalculate resulting label
3126 * - path_info sub_type changed -> switch to/from implicit-null
3127 * - no valid label (due to removed static label binding) -> get new one
3128 */
3129 if (bgp->allocate_mpls_labels[afi][safi]) {
3130 if (new_select) {
3131 if (!old_select
3132 || bgp_label_index_differs(new_select, old_select)
3133 || new_select->sub_type != old_select->sub_type
3134 || !bgp_is_valid_label(&dest->local_label)) {
3135 /* Enforced penultimate hop popping:
3136 * implicit-null for local routes, aggregate
3137 * and redistributed routes
3138 */
3139 if (bgp_lu_need_imp_null(new_select)) {
3140 if (CHECK_FLAG(
3141 dest->flags,
3142 BGP_NODE_REGISTERED_FOR_LABEL)
3143 || CHECK_FLAG(
3144 dest->flags,
3145 BGP_NODE_LABEL_REQUESTED))
3146 bgp_unregister_for_label(dest);
3147 dest->local_label = mpls_lse_encode(
3148 MPLS_LABEL_IMPLICIT_NULL, 0, 0,
3149 1);
3150 bgp_set_valid_label(&dest->local_label);
3151 } else
3152 bgp_register_for_label(dest,
3153 new_select);
3154 }
3155 } else if (CHECK_FLAG(dest->flags,
3156 BGP_NODE_REGISTERED_FOR_LABEL)
3157 || CHECK_FLAG(dest->flags,
3158 BGP_NODE_LABEL_REQUESTED)) {
3159 bgp_unregister_for_label(dest);
3160 }
3161 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3162 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3163 bgp_unregister_for_label(dest);
3164 }
3165
3166 if (debug)
3167 zlog_debug(
3168 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3169 __func__, dest, bgp->name_pretty, afi2str(afi),
3170 safi2str(safi), old_select, new_select);
3171
3172 /* If best route remains the same and this is not due to user-initiated
3173 * clear, see exactly what needs to be done.
3174 */
3175 if (old_select && old_select == new_select
3176 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3177 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3178 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3179 if (bgp_zebra_has_route_changed(old_select)) {
3180 #ifdef ENABLE_BGP_VNC
3181 vnc_import_bgp_add_route(bgp, p, old_select);
3182 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3183 #endif
3184 if (bgp_fibupd_safi(safi)
3185 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3186
3187 if (BGP_SUPPRESS_FIB_ENABLED(bgp)
3188 && new_select->sub_type == BGP_ROUTE_NORMAL)
3189 SET_FLAG(dest->flags,
3190 BGP_NODE_FIB_INSTALL_PENDING);
3191
3192 if (new_select->type == ZEBRA_ROUTE_BGP
3193 && (new_select->sub_type == BGP_ROUTE_NORMAL
3194 || new_select->sub_type
3195 == BGP_ROUTE_IMPORTED))
3196
3197 bgp_zebra_announce(dest, p, old_select,
3198 bgp, afi, safi);
3199 }
3200 }
3201
3202 /* If there is a change of interest to peers, reannounce the
3203 * route. */
3204 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3205 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3206 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3207 group_announce_route(bgp, afi, safi, dest, new_select);
3208
3209 /* unicast routes must also be annouced to
3210 * labeled-unicast update-groups */
3211 if (safi == SAFI_UNICAST)
3212 group_announce_route(bgp, afi,
3213 SAFI_LABELED_UNICAST, dest,
3214 new_select);
3215
3216 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3217 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3218 }
3219
3220 /* advertise/withdraw type-5 routes */
3221 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3222 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3223 bgp_process_evpn_route_injection(
3224 bgp, afi, safi, dest, old_select, old_select);
3225
3226 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3227 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3228 bgp_zebra_clear_route_change_flags(dest);
3229 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3230 return;
3231 }
3232
3233 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3234 */
3235 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3236
3237 /* bestpath has changed; bump version */
3238 if (old_select || new_select) {
3239 bgp_bump_version(dest);
3240
3241 if (!bgp->t_rmap_def_originate_eval) {
3242 bgp_lock(bgp);
3243 thread_add_timer(
3244 bm->master,
3245 update_group_refresh_default_originate_route_map,
3246 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3247 &bgp->t_rmap_def_originate_eval);
3248 }
3249 }
3250
3251 if (old_select)
3252 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3253 if (new_select) {
3254 if (debug)
3255 zlog_debug("%s: setting SELECTED flag", __func__);
3256 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3257 bgp_path_info_unset_flag(dest, new_select,
3258 BGP_PATH_ATTR_CHANGED);
3259 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3260 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3261 }
3262
3263 #ifdef ENABLE_BGP_VNC
3264 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3265 if (old_select != new_select) {
3266 if (old_select) {
3267 vnc_import_bgp_exterior_del_route(bgp, p,
3268 old_select);
3269 vnc_import_bgp_del_route(bgp, p, old_select);
3270 }
3271 if (new_select) {
3272 vnc_import_bgp_exterior_add_route(bgp, p,
3273 new_select);
3274 vnc_import_bgp_add_route(bgp, p, new_select);
3275 }
3276 }
3277 }
3278 #endif
3279
3280 group_announce_route(bgp, afi, safi, dest, new_select);
3281
3282 /* unicast routes must also be annouced to labeled-unicast update-groups
3283 */
3284 if (safi == SAFI_UNICAST)
3285 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3286 new_select);
3287
3288 /* FIB update. */
3289 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3290 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3291
3292 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3293 && (new_select->sub_type == BGP_ROUTE_NORMAL
3294 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3295 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3296
3297 if (BGP_SUPPRESS_FIB_ENABLED(bgp))
3298 SET_FLAG(dest->flags,
3299 BGP_NODE_FIB_INSTALL_PENDING);
3300
3301 /* if this is an evpn imported type-5 prefix,
3302 * we need to withdraw the route first to clear
3303 * the nh neigh and the RMAC entry.
3304 */
3305 if (old_select &&
3306 is_route_parent_evpn(old_select))
3307 bgp_zebra_withdraw(p, old_select, bgp, safi);
3308
3309 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3310 } else {
3311 /* Withdraw the route from the kernel. */
3312 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3313 && (old_select->sub_type == BGP_ROUTE_NORMAL
3314 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3315 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3316
3317 bgp_zebra_withdraw(p, old_select, bgp, safi);
3318 }
3319 }
3320
3321 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3322 old_select);
3323
3324 /* Clear any route change flags. */
3325 bgp_zebra_clear_route_change_flags(dest);
3326
3327 /* Reap old select bgp_path_info, if it has been removed */
3328 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3329 bgp_path_info_reap(dest, old_select);
3330
3331 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3332 return;
3333 }
3334
3335 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3336 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3337 {
3338 struct bgp_dest *dest;
3339 int cnt = 0;
3340 struct afi_safi_info *thread_info;
3341
3342 if (bgp->gr_info[afi][safi].t_route_select) {
3343 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
3344
3345 thread_info = THREAD_ARG(t);
3346 XFREE(MTYPE_TMP, thread_info);
3347 THREAD_OFF(bgp->gr_info[afi][safi].t_route_select);
3348 }
3349
3350 if (BGP_DEBUG(update, UPDATE_OUT)) {
3351 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3352 get_afi_safi_str(afi, safi, false),
3353 bgp->gr_info[afi][safi].gr_deferred);
3354 }
3355
3356 /* Process the route list */
3357 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3358 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3359 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3360 dest = bgp_route_next(dest)) {
3361 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3362 continue;
3363
3364 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3365 bgp->gr_info[afi][safi].gr_deferred--;
3366 bgp_process_main_one(bgp, dest, afi, safi);
3367 cnt++;
3368 }
3369 /* If iteration stopped before the entire table was traversed then the
3370 * node needs to be unlocked.
3371 */
3372 if (dest) {
3373 bgp_dest_unlock_node(dest);
3374 dest = NULL;
3375 }
3376
3377 /* Send EOR message when all routes are processed */
3378 if (!bgp->gr_info[afi][safi].gr_deferred) {
3379 bgp_send_delayed_eor(bgp);
3380 /* Send route processing complete message to RIB */
3381 bgp_zebra_update(afi, safi, bgp->vrf_id,
3382 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3383 return;
3384 }
3385
3386 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3387
3388 thread_info->afi = afi;
3389 thread_info->safi = safi;
3390 thread_info->bgp = bgp;
3391
3392 /* If there are more routes to be processed, start the
3393 * selection timer
3394 */
3395 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3396 BGP_ROUTE_SELECT_DELAY,
3397 &bgp->gr_info[afi][safi].t_route_select);
3398 }
3399
3400 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3401 {
3402 struct bgp_process_queue *pqnode = data;
3403 struct bgp *bgp = pqnode->bgp;
3404 struct bgp_table *table;
3405 struct bgp_dest *dest;
3406
3407 /* eoiu marker */
3408 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3409 bgp_process_main_one(bgp, NULL, 0, 0);
3410 /* should always have dedicated wq call */
3411 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3412 return WQ_SUCCESS;
3413 }
3414
3415 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3416 dest = STAILQ_FIRST(&pqnode->pqueue);
3417 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3418 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3419 table = bgp_dest_table(dest);
3420 /* note, new DESTs may be added as part of processing */
3421 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3422
3423 bgp_dest_unlock_node(dest);
3424 bgp_table_unlock(table);
3425 }
3426
3427 return WQ_SUCCESS;
3428 }
3429
3430 static void bgp_processq_del(struct work_queue *wq, void *data)
3431 {
3432 struct bgp_process_queue *pqnode = data;
3433
3434 bgp_unlock(pqnode->bgp);
3435
3436 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3437 }
3438
3439 void bgp_process_queue_init(struct bgp *bgp)
3440 {
3441 if (!bgp->process_queue) {
3442 char name[BUFSIZ];
3443
3444 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3445 bgp->process_queue = work_queue_new(bm->master, name);
3446 }
3447
3448 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3449 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3450 bgp->process_queue->spec.max_retries = 0;
3451 bgp->process_queue->spec.hold = 50;
3452 /* Use a higher yield value of 50ms for main queue processing */
3453 bgp->process_queue->spec.yield = 50 * 1000L;
3454 }
3455
3456 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3457 {
3458 struct bgp_process_queue *pqnode;
3459
3460 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3461 sizeof(struct bgp_process_queue));
3462
3463 /* unlocked in bgp_processq_del */
3464 pqnode->bgp = bgp_lock(bgp);
3465 STAILQ_INIT(&pqnode->pqueue);
3466
3467 return pqnode;
3468 }
3469
3470 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3471 {
3472 #define ARBITRARY_PROCESS_QLEN 10000
3473 struct work_queue *wq = bgp->process_queue;
3474 struct bgp_process_queue *pqnode;
3475 int pqnode_reuse = 0;
3476
3477 /* already scheduled for processing? */
3478 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3479 return;
3480
3481 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3482 * the workqueue
3483 */
3484 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3485 if (BGP_DEBUG(update, UPDATE_OUT))
3486 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3487 dest);
3488 return;
3489 }
3490
3491 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3492 if (BGP_DEBUG(update, UPDATE_OUT))
3493 zlog_debug(
3494 "Soft reconfigure table in progress for route %p",
3495 dest);
3496 return;
3497 }
3498
3499 if (wq == NULL)
3500 return;
3501
3502 /* Add route nodes to an existing work queue item until reaching the
3503 limit only if is from the same BGP view and it's not an EOIU marker
3504 */
3505 if (work_queue_item_count(wq)) {
3506 struct work_queue_item *item = work_queue_last_item(wq);
3507 pqnode = item->data;
3508
3509 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3510 || pqnode->bgp != bgp
3511 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3512 pqnode = bgp_processq_alloc(bgp);
3513 else
3514 pqnode_reuse = 1;
3515 } else
3516 pqnode = bgp_processq_alloc(bgp);
3517 /* all unlocked in bgp_process_wq */
3518 bgp_table_lock(bgp_dest_table(dest));
3519
3520 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3521 bgp_dest_lock_node(dest);
3522
3523 /* can't be enqueued twice */
3524 assert(STAILQ_NEXT(dest, pq) == NULL);
3525 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3526 pqnode->queued++;
3527
3528 if (!pqnode_reuse)
3529 work_queue_add(wq, pqnode);
3530
3531 return;
3532 }
3533
3534 void bgp_add_eoiu_mark(struct bgp *bgp)
3535 {
3536 struct bgp_process_queue *pqnode;
3537
3538 if (bgp->process_queue == NULL)
3539 return;
3540
3541 pqnode = bgp_processq_alloc(bgp);
3542
3543 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3544 work_queue_add(bgp->process_queue, pqnode);
3545 }
3546
3547 static void bgp_maximum_prefix_restart_timer(struct thread *thread)
3548 {
3549 struct peer *peer;
3550
3551 peer = THREAD_ARG(thread);
3552 peer->t_pmax_restart = NULL;
3553
3554 if (bgp_debug_neighbor_events(peer))
3555 zlog_debug(
3556 "%s Maximum-prefix restart timer expired, restore peering",
3557 peer->host);
3558
3559 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3560 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3561 }
3562
3563 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3564 safi_t safi)
3565 {
3566 uint32_t count = 0;
3567 bool filtered = false;
3568 struct bgp_dest *dest;
3569 struct bgp_adj_in *ain;
3570 struct attr attr = {};
3571 struct bgp_table *table = peer->bgp->rib[afi][safi];
3572
3573 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3574 for (ain = dest->adj_in; ain; ain = ain->next) {
3575 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3576
3577 attr = *ain->attr;
3578
3579 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3580 == FILTER_DENY)
3581 filtered = true;
3582
3583 if (bgp_input_modifier(
3584 peer, rn_p, &attr, afi, safi,
3585 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3586 NULL, 0, NULL)
3587 == RMAP_DENY)
3588 filtered = true;
3589
3590 if (filtered)
3591 count++;
3592
3593 bgp_attr_flush(&attr);
3594 }
3595 }
3596
3597 return count;
3598 }
3599
3600 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3601 int always)
3602 {
3603 iana_afi_t pkt_afi;
3604 iana_safi_t pkt_safi;
3605 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3606 PEER_FLAG_MAX_PREFIX_FORCE))
3607 ? bgp_filtered_routes_count(peer, afi, safi)
3608 + peer->pcount[afi][safi]
3609 : peer->pcount[afi][safi];
3610
3611 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3612 return false;
3613
3614 if (pcount > peer->pmax[afi][safi]) {
3615 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3616 PEER_STATUS_PREFIX_LIMIT)
3617 && !always)
3618 return false;
3619
3620 zlog_info(
3621 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3622 get_afi_safi_str(afi, safi, false), peer, pcount,
3623 peer->pmax[afi][safi]);
3624 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3625
3626 if (CHECK_FLAG(peer->af_flags[afi][safi],
3627 PEER_FLAG_MAX_PREFIX_WARNING))
3628 return false;
3629
3630 /* Convert AFI, SAFI to values for packet. */
3631 pkt_afi = afi_int2iana(afi);
3632 pkt_safi = safi_int2iana(safi);
3633 {
3634 uint8_t ndata[7];
3635
3636 ndata[0] = (pkt_afi >> 8);
3637 ndata[1] = pkt_afi;
3638 ndata[2] = pkt_safi;
3639 ndata[3] = (peer->pmax[afi][safi] >> 24);
3640 ndata[4] = (peer->pmax[afi][safi] >> 16);
3641 ndata[5] = (peer->pmax[afi][safi] >> 8);
3642 ndata[6] = (peer->pmax[afi][safi]);
3643
3644 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3645 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3646 BGP_NOTIFY_CEASE_MAX_PREFIX,
3647 ndata, 7);
3648 }
3649
3650 /* Dynamic peers will just close their connection. */
3651 if (peer_dynamic_neighbor(peer))
3652 return true;
3653
3654 /* restart timer start */
3655 if (peer->pmax_restart[afi][safi]) {
3656 peer->v_pmax_restart =
3657 peer->pmax_restart[afi][safi] * 60;
3658
3659 if (bgp_debug_neighbor_events(peer))
3660 zlog_debug(
3661 "%pBP Maximum-prefix restart timer started for %d secs",
3662 peer, peer->v_pmax_restart);
3663
3664 BGP_TIMER_ON(peer->t_pmax_restart,
3665 bgp_maximum_prefix_restart_timer,
3666 peer->v_pmax_restart);
3667 }
3668
3669 return true;
3670 } else
3671 UNSET_FLAG(peer->af_sflags[afi][safi],
3672 PEER_STATUS_PREFIX_LIMIT);
3673
3674 if (pcount
3675 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3676 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3677 PEER_STATUS_PREFIX_THRESHOLD)
3678 && !always)
3679 return false;
3680
3681 zlog_info(
3682 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3683 get_afi_safi_str(afi, safi, false), peer, pcount,
3684 peer->pmax[afi][safi]);
3685 SET_FLAG(peer->af_sflags[afi][safi],
3686 PEER_STATUS_PREFIX_THRESHOLD);
3687 } else
3688 UNSET_FLAG(peer->af_sflags[afi][safi],
3689 PEER_STATUS_PREFIX_THRESHOLD);
3690 return false;
3691 }
3692
3693 /* Unconditionally remove the route from the RIB, without taking
3694 * damping into consideration (eg, because the session went down)
3695 */
3696 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3697 struct peer *peer, afi_t afi, safi_t safi)
3698 {
3699
3700 struct bgp *bgp = NULL;
3701 bool delete_route = false;
3702
3703 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3704 safi);
3705
3706 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3707 bgp_path_info_delete(dest, pi); /* keep historical info */
3708
3709 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3710 * flag
3711 */
3712 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3713 delete_route = true;
3714 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3715 delete_route = true;
3716 if (delete_route) {
3717 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3718 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3719 bgp = pi->peer->bgp;
3720 bgp->gr_info[afi][safi].gr_deferred--;
3721 }
3722 }
3723 }
3724
3725 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3726 bgp_process(peer->bgp, dest, afi, safi);
3727 }
3728
3729 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3730 struct peer *peer, afi_t afi, safi_t safi,
3731 struct prefix_rd *prd)
3732 {
3733 const struct prefix *p = bgp_dest_get_prefix(dest);
3734
3735 /* apply dampening, if result is suppressed, we'll be retaining
3736 * the bgp_path_info in the RIB for historical reference.
3737 */
3738 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3739 && peer->sort == BGP_PEER_EBGP)
3740 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3741 == BGP_DAMP_SUPPRESSED) {
3742 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3743 safi);
3744 return;
3745 }
3746
3747 #ifdef ENABLE_BGP_VNC
3748 if (safi == SAFI_MPLS_VPN) {
3749 struct bgp_dest *pdest = NULL;
3750 struct bgp_table *table = NULL;
3751
3752 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3753 (struct prefix *)prd);
3754 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3755 table = bgp_dest_get_bgp_table_info(pdest);
3756
3757 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3758 peer->bgp, prd, table, p, pi);
3759 }
3760 bgp_dest_unlock_node(pdest);
3761 }
3762 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3763 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3764
3765 vnc_import_bgp_del_route(peer->bgp, p, pi);
3766 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3767 }
3768 }
3769 #endif
3770
3771 /* If this is an EVPN route, process for un-import. */
3772 if (safi == SAFI_EVPN)
3773 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3774
3775 bgp_rib_remove(dest, pi, peer, afi, safi);
3776 }
3777
3778 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3779 struct peer *peer, struct attr *attr,
3780 struct bgp_dest *dest)
3781 {
3782 struct bgp_path_info *new;
3783
3784 /* Make new BGP info. */
3785 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3786 new->type = type;
3787 new->instance = instance;
3788 new->sub_type = sub_type;
3789 new->peer = peer;
3790 new->attr = attr;
3791 new->uptime = monotime(NULL);
3792 new->net = dest;
3793 return new;
3794 }
3795
3796 /* Check if received nexthop is valid or not. */
3797 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3798 uint8_t type, uint8_t stype, struct attr *attr,
3799 struct bgp_dest *dest)
3800 {
3801 bool ret = false;
3802 bool is_bgp_static_route =
3803 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3804 : false;
3805
3806 /*
3807 * Only validated for unicast and multicast currently.
3808 * Also valid for EVPN where the nexthop is an IP address.
3809 * If we are a bgp static route being checked then there is
3810 * no need to check to see if the nexthop is martian as
3811 * that it should be ok.
3812 */
3813 if (is_bgp_static_route ||
3814 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3815 return false;
3816
3817 /* If NEXT_HOP is present, validate it. */
3818 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3819 if (attr->nexthop.s_addr == INADDR_ANY ||
3820 !ipv4_unicast_valid(&attr->nexthop) ||
3821 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3822 return true;
3823 }
3824
3825 /* If MP_NEXTHOP is present, validate it. */
3826 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3827 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3828 * it is not an IPv6 link-local address.
3829 *
3830 * If we receive an UPDATE with nexthop length set to 32 bytes
3831 * we shouldn't discard an UPDATE if it's set to (::).
3832 * The link-local (2st) is validated along the code path later.
3833 */
3834 if (attr->mp_nexthop_len) {
3835 switch (attr->mp_nexthop_len) {
3836 case BGP_ATTR_NHLEN_IPV4:
3837 case BGP_ATTR_NHLEN_VPNV4:
3838 ret = (attr->mp_nexthop_global_in.s_addr ==
3839 INADDR_ANY ||
3840 !ipv4_unicast_valid(
3841 &attr->mp_nexthop_global_in) ||
3842 bgp_nexthop_self(bgp, afi, type, stype, attr,
3843 dest));
3844 break;
3845
3846 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3847 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3848 ret = (IN6_IS_ADDR_UNSPECIFIED(
3849 &attr->mp_nexthop_global)
3850 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3851 || IN6_IS_ADDR_MULTICAST(
3852 &attr->mp_nexthop_global)
3853 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3854 dest));
3855 break;
3856 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3857 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3858 || IN6_IS_ADDR_MULTICAST(
3859 &attr->mp_nexthop_global)
3860 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3861 dest));
3862 break;
3863
3864 default:
3865 ret = true;
3866 break;
3867 }
3868 }
3869
3870 return ret;
3871 }
3872
3873 static void bgp_attr_add_no_export_community(struct attr *attr)
3874 {
3875 struct community *old;
3876 struct community *new;
3877 struct community *merge;
3878 struct community *no_export;
3879
3880 old = bgp_attr_get_community(attr);
3881 no_export = community_str2com("no-export");
3882
3883 assert(no_export);
3884
3885 if (old) {
3886 merge = community_merge(community_dup(old), no_export);
3887
3888 if (!old->refcnt)
3889 community_free(&old);
3890
3891 new = community_uniq_sort(merge);
3892 community_free(&merge);
3893 } else {
3894 new = community_dup(no_export);
3895 }
3896
3897 community_free(&no_export);
3898
3899 bgp_attr_set_community(attr, new);
3900 }
3901
3902 static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi,
3903 struct attr *attr, const struct prefix *prefix,
3904 int *sub_type)
3905 {
3906 struct listnode *node, *nnode;
3907 struct bgp *bgp;
3908 bool accept_own_found = false;
3909
3910 if (safi != SAFI_MPLS_VPN)
3911 return false;
3912
3913 /* Processing of the ACCEPT_OWN community is enabled by configuration */
3914 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN))
3915 return false;
3916
3917 /* The route in question carries the ACCEPT_OWN community */
3918 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3919 struct community *comm = bgp_attr_get_community(attr);
3920
3921 if (community_include(comm, COMMUNITY_ACCEPT_OWN))
3922 accept_own_found = true;
3923 }
3924
3925 /* The route in question is targeted to one or more destination VRFs
3926 * on the router (as determined by inspecting the Route Target(s)).
3927 */
3928 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3929 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3930 continue;
3931
3932 if (accept_own_found &&
3933 ecommunity_include(
3934 bgp->vpn_policy[afi]
3935 .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
3936 bgp_attr_get_ecommunity(attr))) {
3937 if (bgp_debug_update(peer, prefix, NULL, 1))
3938 zlog_debug(
3939 "%pBP prefix %pFX has ORIGINATOR_ID, but it's accepted due to ACCEPT_OWN",
3940 peer, prefix);
3941
3942 /* Treat this route as imported, because it's leaked
3943 * already from another VRF, and we got an updated
3944 * version from route-reflector with ACCEPT_OWN
3945 * community.
3946 */
3947 *sub_type = BGP_ROUTE_IMPORTED;
3948
3949 return true;
3950 }
3951 }
3952
3953 return false;
3954 }
3955
3956 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3957 struct attr *attr, afi_t afi, safi_t safi, int type,
3958 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3959 uint32_t num_labels, int soft_reconfig,
3960 struct bgp_route_evpn *evpn)
3961 {
3962 int ret;
3963 int aspath_loop_count = 0;
3964 struct bgp_dest *dest;
3965 struct bgp *bgp;
3966 struct attr new_attr;
3967 struct attr *attr_new;
3968 struct bgp_path_info *pi;
3969 struct bgp_path_info *new = NULL;
3970 struct bgp_path_info_extra *extra;
3971 const char *reason;
3972 char pfx_buf[BGP_PRD_PATH_STRLEN];
3973 int connected = 0;
3974 int do_loop_check = 1;
3975 int has_valid_label = 0;
3976 afi_t nh_afi;
3977 bool force_evpn_import = false;
3978 safi_t orig_safi = safi;
3979 bool leak_success = true;
3980 int allowas_in = 0;
3981
3982 if (frrtrace_enabled(frr_bgp, process_update)) {
3983 char pfxprint[PREFIX2STR_BUFFER];
3984
3985 prefix2str(p, pfxprint, sizeof(pfxprint));
3986 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
3987 afi, safi, attr);
3988 }
3989
3990 #ifdef ENABLE_BGP_VNC
3991 int vnc_implicit_withdraw = 0;
3992 #endif
3993 int same_attr = 0;
3994 const struct prefix *bgp_nht_param_prefix;
3995
3996 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
3997 if (orig_safi == SAFI_LABELED_UNICAST)
3998 safi = SAFI_UNICAST;
3999
4000 memset(&new_attr, 0, sizeof(new_attr));
4001 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4002 new_attr.label = MPLS_INVALID_LABEL;
4003
4004 bgp = peer->bgp;
4005 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4006 /* TODO: Check to see if we can get rid of "is_valid_label" */
4007 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4008 has_valid_label = (num_labels > 0) ? 1 : 0;
4009 else
4010 has_valid_label = bgp_is_valid_label(label);
4011
4012 if (has_valid_label)
4013 assert(label != NULL);
4014
4015 /* Update overlay index of the attribute */
4016 if (afi == AFI_L2VPN && evpn)
4017 memcpy(&attr->evpn_overlay, evpn,
4018 sizeof(struct bgp_route_evpn));
4019
4020 /* When peer's soft reconfiguration enabled. Record input packet in
4021 Adj-RIBs-In. */
4022 if (!soft_reconfig
4023 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4024 && peer != bgp->peer_self)
4025 bgp_adj_in_set(dest, peer, attr, addpath_id);
4026
4027 /* Update permitted loop count */
4028 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
4029 allowas_in = peer->allowas_in[afi][safi];
4030
4031 /* Check previously received route. */
4032 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4033 if (pi->peer == peer && pi->type == type
4034 && pi->sub_type == sub_type
4035 && pi->addpath_rx_id == addpath_id)
4036 break;
4037
4038 /* AS path local-as loop check. */
4039 if (peer->change_local_as) {
4040 if (allowas_in)
4041 aspath_loop_count = allowas_in;
4042 else if (!CHECK_FLAG(peer->flags,
4043 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4044 aspath_loop_count = 1;
4045
4046 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4047 > aspath_loop_count) {
4048 peer->stat_pfx_aspath_loop++;
4049 reason = "as-path contains our own AS;";
4050 goto filtered;
4051 }
4052 }
4053
4054 /* If the peer is configured for "allowas-in origin" and the last ASN in
4055 * the
4056 * as-path is our ASN then we do not need to call aspath_loop_check
4057 */
4058 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4059 if (aspath_get_last_as(attr->aspath) == bgp->as)
4060 do_loop_check = 0;
4061
4062 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
4063 bgp_nht_param_prefix = NULL;
4064 else
4065 bgp_nht_param_prefix = p;
4066
4067 /* AS path loop check. */
4068 if (do_loop_check) {
4069 if (aspath_loop_check(attr->aspath, bgp->as) >
4070 peer->allowas_in[afi][safi]) {
4071 peer->stat_pfx_aspath_loop++;
4072 reason = "as-path contains our own AS;";
4073 goto filtered;
4074 }
4075 }
4076
4077 /* If we're a CONFED we need to loop check the CONFED ID too */
4078 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check)
4079 if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) >
4080 peer->allowas_in[afi][safi]) {
4081 peer->stat_pfx_aspath_loop++;
4082 reason = "as-path contains our own confed AS;";
4083 goto filtered;
4084 }
4085
4086 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4087 * enabled, then take care of that too.
4088 */
4089 bool accept_own = false;
4090
4091 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4092 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4093 accept_own =
4094 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4095 if (!accept_own) {
4096 peer->stat_pfx_originator_loop++;
4097 reason = "originator is us;";
4098 goto filtered;
4099 }
4100 }
4101
4102 /* Route reflector cluster ID check. */
4103 if (bgp_cluster_filter(peer, attr)) {
4104 peer->stat_pfx_cluster_loop++;
4105 reason = "reflected from the same cluster;";
4106 goto filtered;
4107 }
4108
4109 /* Apply incoming filter. */
4110 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4111 peer->stat_pfx_filter++;
4112 reason = "filter;";
4113 goto filtered;
4114 }
4115
4116 /* RFC 8212 to prevent route leaks.
4117 * This specification intends to improve this situation by requiring the
4118 * explicit configuration of both BGP Import and Export Policies for any
4119 * External BGP (EBGP) session such as customers, peers, or
4120 * confederation boundaries for all enabled address families. Through
4121 * codification of the aforementioned requirement, operators will
4122 * benefit from consistent behavior across different BGP
4123 * implementations.
4124 */
4125 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4126 if (!bgp_inbound_policy_exists(peer,
4127 &peer->filter[afi][safi])) {
4128 reason = "inbound policy missing";
4129 if (monotime_since(&bgp->ebgprequirespolicywarning,
4130 NULL) > FIFTEENMINUTE2USEC ||
4131 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4132 zlog_warn(
4133 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4134 monotime(&bgp->ebgprequirespolicywarning);
4135 }
4136 goto filtered;
4137 }
4138
4139 /* draft-ietf-idr-deprecate-as-set-confed-set
4140 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4141 * Eventually, This document (if approved) updates RFC 4271
4142 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4143 * and obsoletes RFC 6472.
4144 */
4145 if (peer->bgp->reject_as_sets)
4146 if (aspath_check_as_sets(attr->aspath)) {
4147 reason =
4148 "as-path contains AS_SET or AS_CONFED_SET type;";
4149 goto filtered;
4150 }
4151
4152 new_attr = *attr;
4153
4154 /* Apply incoming route-map.
4155 * NB: new_attr may now contain newly allocated values from route-map
4156 * "set"
4157 * commands, so we need bgp_attr_flush in the error paths, until we
4158 * intern
4159 * the attr (which takes over the memory references) */
4160 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4161 num_labels, dest)
4162 == RMAP_DENY) {
4163 peer->stat_pfx_filter++;
4164 reason = "route-map;";
4165 bgp_attr_flush(&new_attr);
4166 goto filtered;
4167 }
4168
4169 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4170 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4171 /* remove from RIB previous entry */
4172 bgp_zebra_withdraw(p, pi, bgp, safi);
4173 }
4174
4175 if (peer->sort == BGP_PEER_EBGP) {
4176
4177 /* rfc7999:
4178 * A BGP speaker receiving an announcement tagged with the
4179 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4180 * NO_EXPORT community as defined in RFC1997, or a
4181 * similar community, to prevent propagation of the
4182 * prefix outside the local AS. The community to prevent
4183 * propagation SHOULD be chosen according to the operator's
4184 * routing policy.
4185 */
4186 if (bgp_attr_get_community(&new_attr) &&
4187 community_include(bgp_attr_get_community(&new_attr),
4188 COMMUNITY_BLACKHOLE))
4189 bgp_attr_add_no_export_community(&new_attr);
4190
4191 /* If we receive the graceful-shutdown community from an eBGP
4192 * peer we must lower local-preference */
4193 if (bgp_attr_get_community(&new_attr) &&
4194 community_include(bgp_attr_get_community(&new_attr),
4195 COMMUNITY_GSHUT)) {
4196 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4197 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4198
4199 /* If graceful-shutdown is configured globally or
4200 * per neighbor, then add the GSHUT community to
4201 * all paths received from eBGP peers. */
4202 } else if (bgp_in_graceful_shutdown(peer->bgp) ||
4203 CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_SHUTDOWN))
4204 bgp_attr_add_gshut_community(&new_attr);
4205 }
4206
4207 /* next hop check. */
4208 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4209 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4210 &new_attr, dest)) {
4211 peer->stat_pfx_nh_invalid++;
4212 reason = "martian or self next-hop;";
4213 bgp_attr_flush(&new_attr);
4214 goto filtered;
4215 }
4216
4217 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4218 peer->stat_pfx_nh_invalid++;
4219 reason = "self mac;";
4220 bgp_attr_flush(&new_attr);
4221 goto filtered;
4222 }
4223
4224 if (bgp_check_role_applicability(afi, safi) &&
4225 bgp_otc_filter(peer, &new_attr)) {
4226 reason = "failing otc validation";
4227 bgp_attr_flush(&new_attr);
4228 goto filtered;
4229 }
4230 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
4231 * condition :
4232 * Suppress fib is enabled
4233 * BGP_OPT_NO_FIB is not enabled
4234 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
4235 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
4236 */
4237 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
4238 && (sub_type == BGP_ROUTE_NORMAL)
4239 && (!bgp_option_check(BGP_OPT_NO_FIB))
4240 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
4241 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
4242
4243 /* If neighbor soo is configured, tag all incoming routes with
4244 * this SoO tag and then filter out advertisements in
4245 * subgroup_announce_check() if it matches the configured SoO
4246 * on the other peer.
4247 */
4248 if (peer->soo[afi][safi]) {
4249 struct ecommunity *old_ecomm =
4250 bgp_attr_get_ecommunity(&new_attr);
4251 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4252 struct ecommunity *new_ecomm;
4253
4254 if (old_ecomm) {
4255 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4256 ecomm_soo);
4257
4258 if (!old_ecomm->refcnt)
4259 ecommunity_free(&old_ecomm);
4260 } else {
4261 new_ecomm = ecommunity_dup(ecomm_soo);
4262 }
4263
4264 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4265 }
4266
4267 attr_new = bgp_attr_intern(&new_attr);
4268
4269 /* If the update is implicit withdraw. */
4270 if (pi) {
4271 pi->uptime = monotime(NULL);
4272 same_attr = attrhash_cmp(pi->attr, attr_new);
4273
4274 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4275
4276 /* Same attribute comes in. */
4277 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4278 && same_attr
4279 && (!has_valid_label
4280 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4281 num_labels * sizeof(mpls_label_t))
4282 == 0)) {
4283 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4284 BGP_CONFIG_DAMPENING)
4285 && peer->sort == BGP_PEER_EBGP
4286 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4287 if (bgp_debug_update(peer, p, NULL, 1)) {
4288 bgp_debug_rdpfxpath2str(
4289 afi, safi, prd, p, label,
4290 num_labels, addpath_id ? 1 : 0,
4291 addpath_id, evpn, pfx_buf,
4292 sizeof(pfx_buf));
4293 zlog_debug("%pBP rcvd %s", peer,
4294 pfx_buf);
4295 }
4296
4297 if (bgp_damp_update(pi, dest, afi, safi)
4298 != BGP_DAMP_SUPPRESSED) {
4299 bgp_aggregate_increment(bgp, p, pi, afi,
4300 safi);
4301 bgp_process(bgp, dest, afi, safi);
4302 }
4303 } else /* Duplicate - odd */
4304 {
4305 if (bgp_debug_update(peer, p, NULL, 1)) {
4306 if (!peer->rcvd_attr_printed) {
4307 zlog_debug(
4308 "%pBP rcvd UPDATE w/ attr: %s",
4309 peer,
4310 peer->rcvd_attr_str);
4311 peer->rcvd_attr_printed = 1;
4312 }
4313
4314 bgp_debug_rdpfxpath2str(
4315 afi, safi, prd, p, label,
4316 num_labels, addpath_id ? 1 : 0,
4317 addpath_id, evpn, pfx_buf,
4318 sizeof(pfx_buf));
4319 zlog_debug(
4320 "%pBP rcvd %s...duplicate ignored",
4321 peer, pfx_buf);
4322 }
4323
4324 /* graceful restart STALE flag unset. */
4325 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4326 bgp_path_info_unset_flag(
4327 dest, pi, BGP_PATH_STALE);
4328 bgp_dest_set_defer_flag(dest, false);
4329 bgp_process(bgp, dest, afi, safi);
4330 }
4331 }
4332
4333 bgp_dest_unlock_node(dest);
4334 bgp_attr_unintern(&attr_new);
4335
4336 return 0;
4337 }
4338
4339 /* Withdraw/Announce before we fully processed the withdraw */
4340 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4341 if (bgp_debug_update(peer, p, NULL, 1)) {
4342 bgp_debug_rdpfxpath2str(
4343 afi, safi, prd, p, label, num_labels,
4344 addpath_id ? 1 : 0, addpath_id, evpn,
4345 pfx_buf, sizeof(pfx_buf));
4346 zlog_debug(
4347 "%pBP rcvd %s, flapped quicker than processing",
4348 peer, pfx_buf);
4349 }
4350
4351 bgp_path_info_restore(dest, pi);
4352
4353 /*
4354 * If the BGP_PATH_REMOVED flag is set, then EVPN
4355 * routes would have been unimported already when a
4356 * prior BGP withdraw processing happened. Such routes
4357 * need to be imported again, so flag accordingly.
4358 */
4359 force_evpn_import = true;
4360 } else {
4361 /* implicit withdraw, decrement aggregate and pcount
4362 * here. only if update is accepted, they'll increment
4363 * below.
4364 */
4365 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4366 }
4367
4368 /* Received Logging. */
4369 if (bgp_debug_update(peer, p, NULL, 1)) {
4370 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4371 num_labels, addpath_id ? 1 : 0,
4372 addpath_id, evpn, pfx_buf,
4373 sizeof(pfx_buf));
4374 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4375 }
4376
4377 /* graceful restart STALE flag unset. */
4378 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4379 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4380 bgp_dest_set_defer_flag(dest, false);
4381 }
4382
4383 /* The attribute is changed. */
4384 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4385
4386 /* Update bgp route dampening information. */
4387 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4388 && peer->sort == BGP_PEER_EBGP) {
4389 /* This is implicit withdraw so we should update
4390 dampening
4391 information. */
4392 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4393 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4394 }
4395 #ifdef ENABLE_BGP_VNC
4396 if (safi == SAFI_MPLS_VPN) {
4397 struct bgp_dest *pdest = NULL;
4398 struct bgp_table *table = NULL;
4399
4400 pdest = bgp_node_get(bgp->rib[afi][safi],
4401 (struct prefix *)prd);
4402 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4403 table = bgp_dest_get_bgp_table_info(pdest);
4404
4405 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4406 bgp, prd, table, p, pi);
4407 }
4408 bgp_dest_unlock_node(pdest);
4409 }
4410 if ((afi == AFI_IP || afi == AFI_IP6)
4411 && (safi == SAFI_UNICAST)) {
4412 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4413 /*
4414 * Implicit withdraw case.
4415 */
4416 ++vnc_implicit_withdraw;
4417 vnc_import_bgp_del_route(bgp, p, pi);
4418 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4419 }
4420 }
4421 #endif
4422
4423 /* Special handling for EVPN update of an existing route. If the
4424 * extended community attribute has changed, we need to
4425 * un-import
4426 * the route using its existing extended community. It will be
4427 * subsequently processed for import with the new extended
4428 * community.
4429 */
4430 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4431 && !same_attr) {
4432 if ((pi->attr->flag
4433 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4434 && (attr_new->flag
4435 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4436 int cmp;
4437
4438 cmp = ecommunity_cmp(
4439 bgp_attr_get_ecommunity(pi->attr),
4440 bgp_attr_get_ecommunity(attr_new));
4441 if (!cmp) {
4442 if (bgp_debug_update(peer, p, NULL, 1))
4443 zlog_debug(
4444 "Change in EXT-COMM, existing %s new %s",
4445 ecommunity_str(
4446 bgp_attr_get_ecommunity(
4447 pi->attr)),
4448 ecommunity_str(
4449 bgp_attr_get_ecommunity(
4450 attr_new)));
4451 if (safi == SAFI_EVPN)
4452 bgp_evpn_unimport_route(
4453 bgp, afi, safi, p, pi);
4454 else /* SAFI_MPLS_VPN */
4455 vpn_leak_to_vrf_withdraw(bgp,
4456 pi);
4457 }
4458 }
4459 }
4460
4461 /* Update to new attribute. */
4462 bgp_attr_unintern(&pi->attr);
4463 pi->attr = attr_new;
4464
4465 /* Update MPLS label */
4466 if (has_valid_label) {
4467 extra = bgp_path_info_extra_get(pi);
4468 if (extra->label != label) {
4469 memcpy(&extra->label, label,
4470 num_labels * sizeof(mpls_label_t));
4471 extra->num_labels = num_labels;
4472 }
4473 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4474 bgp_set_valid_label(&extra->label[0]);
4475 }
4476
4477 /* Update SRv6 SID */
4478 if (attr->srv6_l3vpn) {
4479 extra = bgp_path_info_extra_get(pi);
4480 if (sid_diff(&extra->sid[0].sid,
4481 &attr->srv6_l3vpn->sid)) {
4482 sid_copy(&extra->sid[0].sid,
4483 &attr->srv6_l3vpn->sid);
4484 extra->num_sids = 1;
4485
4486 extra->sid[0].loc_block_len = 0;
4487 extra->sid[0].loc_node_len = 0;
4488 extra->sid[0].func_len = 0;
4489 extra->sid[0].arg_len = 0;
4490 extra->sid[0].transposition_len = 0;
4491 extra->sid[0].transposition_offset = 0;
4492
4493 if (attr->srv6_l3vpn->loc_block_len != 0) {
4494 extra->sid[0].loc_block_len =
4495 attr->srv6_l3vpn->loc_block_len;
4496 extra->sid[0].loc_node_len =
4497 attr->srv6_l3vpn->loc_node_len;
4498 extra->sid[0].func_len =
4499 attr->srv6_l3vpn->func_len;
4500 extra->sid[0].arg_len =
4501 attr->srv6_l3vpn->arg_len;
4502 extra->sid[0].transposition_len =
4503 attr->srv6_l3vpn
4504 ->transposition_len;
4505 extra->sid[0].transposition_offset =
4506 attr->srv6_l3vpn
4507 ->transposition_offset;
4508 }
4509 }
4510 } else if (attr->srv6_vpn) {
4511 extra = bgp_path_info_extra_get(pi);
4512 if (sid_diff(&extra->sid[0].sid,
4513 &attr->srv6_vpn->sid)) {
4514 sid_copy(&extra->sid[0].sid,
4515 &attr->srv6_vpn->sid);
4516 extra->num_sids = 1;
4517 }
4518 }
4519
4520 #ifdef ENABLE_BGP_VNC
4521 if ((afi == AFI_IP || afi == AFI_IP6)
4522 && (safi == SAFI_UNICAST)) {
4523 if (vnc_implicit_withdraw) {
4524 /*
4525 * Add back the route with its new attributes
4526 * (e.g., nexthop).
4527 * The route is still selected, until the route
4528 * selection
4529 * queued by bgp_process actually runs. We have
4530 * to make this
4531 * update to the VNC side immediately to avoid
4532 * racing against
4533 * configuration changes (e.g., route-map
4534 * changes) which
4535 * trigger re-importation of the entire RIB.
4536 */
4537 vnc_import_bgp_add_route(bgp, p, pi);
4538 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4539 }
4540 }
4541 #endif
4542
4543 /* Update bgp route dampening information. */
4544 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4545 && peer->sort == BGP_PEER_EBGP) {
4546 /* Now we do normal update dampening. */
4547 ret = bgp_damp_update(pi, dest, afi, safi);
4548 if (ret == BGP_DAMP_SUPPRESSED) {
4549 bgp_dest_unlock_node(dest);
4550 return 0;
4551 }
4552 }
4553
4554 /* Nexthop reachability check - for unicast and
4555 * labeled-unicast.. */
4556 if (((afi == AFI_IP || afi == AFI_IP6)
4557 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4558 || (safi == SAFI_EVPN &&
4559 bgp_evpn_is_prefix_nht_supported(p))) {
4560 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4561 && peer->ttl == BGP_DEFAULT_TTL
4562 && !CHECK_FLAG(peer->flags,
4563 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4564 && !CHECK_FLAG(bgp->flags,
4565 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4566 connected = 1;
4567 else
4568 connected = 0;
4569
4570 struct bgp *bgp_nexthop = bgp;
4571
4572 if (pi->extra && pi->extra->bgp_orig)
4573 bgp_nexthop = pi->extra->bgp_orig;
4574
4575 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4576
4577 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4578 safi, pi, NULL, connected,
4579 bgp_nht_param_prefix) ||
4580 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4581 bgp_path_info_set_flag(dest, pi,
4582 BGP_PATH_VALID);
4583 else {
4584 if (BGP_DEBUG(nht, NHT)) {
4585 zlog_debug("%s(%pI4): NH unresolved",
4586 __func__,
4587 (in_addr_t *)&attr_new->nexthop);
4588 }
4589 bgp_path_info_unset_flag(dest, pi,
4590 BGP_PATH_VALID);
4591 }
4592 } else {
4593 if (accept_own)
4594 bgp_path_info_set_flag(dest, pi,
4595 BGP_PATH_ACCEPT_OWN);
4596
4597 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4598 }
4599
4600 #ifdef ENABLE_BGP_VNC
4601 if (safi == SAFI_MPLS_VPN) {
4602 struct bgp_dest *pdest = NULL;
4603 struct bgp_table *table = NULL;
4604
4605 pdest = bgp_node_get(bgp->rib[afi][safi],
4606 (struct prefix *)prd);
4607 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4608 table = bgp_dest_get_bgp_table_info(pdest);
4609
4610 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4611 bgp, prd, table, p, pi);
4612 }
4613 bgp_dest_unlock_node(pdest);
4614 }
4615 #endif
4616
4617 /* If this is an EVPN route and some attribute has changed,
4618 * or we are explicitly told to perform a route import, process
4619 * route for import. If the extended community has changed, we
4620 * would
4621 * have done the un-import earlier and the import would result
4622 * in the
4623 * route getting injected into appropriate L2 VNIs. If it is
4624 * just
4625 * some other attribute change, the import will result in
4626 * updating
4627 * the attributes for the route in the VNI(s).
4628 */
4629 if (safi == SAFI_EVPN &&
4630 (!same_attr || force_evpn_import) &&
4631 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4632 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4633
4634 /* Process change. */
4635 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4636
4637 bgp_process(bgp, dest, afi, safi);
4638 bgp_dest_unlock_node(dest);
4639
4640 if (SAFI_UNICAST == safi
4641 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4642 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4643
4644 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4645 }
4646 if ((SAFI_MPLS_VPN == safi)
4647 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4648 leak_success = vpn_leak_to_vrf_update(bgp, pi, prd);
4649 }
4650
4651 #ifdef ENABLE_BGP_VNC
4652 if (SAFI_MPLS_VPN == safi) {
4653 mpls_label_t label_decoded = decode_label(label);
4654
4655 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4656 type, sub_type, &label_decoded);
4657 }
4658 if (SAFI_ENCAP == safi) {
4659 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4660 type, sub_type, NULL);
4661 }
4662 #endif
4663 if ((safi == SAFI_MPLS_VPN) &&
4664 !CHECK_FLAG(bgp->af_flags[afi][safi],
4665 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4666 !leak_success) {
4667 bgp_unlink_nexthop(pi);
4668 bgp_path_info_delete(dest, pi);
4669 }
4670 return 0;
4671 } // End of implicit withdraw
4672
4673 /* Received Logging. */
4674 if (bgp_debug_update(peer, p, NULL, 1)) {
4675 if (!peer->rcvd_attr_printed) {
4676 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4677 peer->rcvd_attr_str);
4678 peer->rcvd_attr_printed = 1;
4679 }
4680
4681 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4682 addpath_id ? 1 : 0, addpath_id, evpn,
4683 pfx_buf, sizeof(pfx_buf));
4684 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4685 }
4686
4687 /* Make new BGP info. */
4688 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4689
4690 /* Update MPLS label */
4691 if (has_valid_label) {
4692 extra = bgp_path_info_extra_get(new);
4693 if (extra->label != label) {
4694 memcpy(&extra->label, label,
4695 num_labels * sizeof(mpls_label_t));
4696 extra->num_labels = num_labels;
4697 }
4698 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4699 bgp_set_valid_label(&extra->label[0]);
4700 }
4701
4702 /* Update SRv6 SID */
4703 if (safi == SAFI_MPLS_VPN) {
4704 extra = bgp_path_info_extra_get(new);
4705 if (attr->srv6_l3vpn) {
4706 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4707 extra->num_sids = 1;
4708
4709 extra->sid[0].loc_block_len =
4710 attr->srv6_l3vpn->loc_block_len;
4711 extra->sid[0].loc_node_len =
4712 attr->srv6_l3vpn->loc_node_len;
4713 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4714 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4715 extra->sid[0].transposition_len =
4716 attr->srv6_l3vpn->transposition_len;
4717 extra->sid[0].transposition_offset =
4718 attr->srv6_l3vpn->transposition_offset;
4719 } else if (attr->srv6_vpn) {
4720 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4721 extra->num_sids = 1;
4722 }
4723 }
4724
4725 /* Nexthop reachability check. */
4726 if (((afi == AFI_IP || afi == AFI_IP6)
4727 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4728 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4729 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4730 && peer->ttl == BGP_DEFAULT_TTL
4731 && !CHECK_FLAG(peer->flags,
4732 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4733 && !CHECK_FLAG(bgp->flags,
4734 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4735 connected = 1;
4736 else
4737 connected = 0;
4738
4739 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4740
4741 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4742 connected, bgp_nht_param_prefix) ||
4743 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4744 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4745 else {
4746 if (BGP_DEBUG(nht, NHT))
4747 zlog_debug("%s(%pI4): NH unresolved", __func__,
4748 &attr_new->nexthop);
4749 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4750 }
4751 } else {
4752 if (accept_own)
4753 bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
4754
4755 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4756 }
4757
4758 /* If maximum prefix count is configured and current prefix
4759 * count exeed it.
4760 */
4761 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4762 reason = "maximum-prefix overflow";
4763 bgp_attr_flush(&new_attr);
4764 goto filtered;
4765 }
4766
4767 /* Addpath ID */
4768 new->addpath_rx_id = addpath_id;
4769
4770 /* Increment prefix */
4771 bgp_aggregate_increment(bgp, p, new, afi, safi);
4772
4773 /* Register new BGP information. */
4774 bgp_path_info_add(dest, new);
4775
4776 /* route_node_get lock */
4777 bgp_dest_unlock_node(dest);
4778
4779 #ifdef ENABLE_BGP_VNC
4780 if (safi == SAFI_MPLS_VPN) {
4781 struct bgp_dest *pdest = NULL;
4782 struct bgp_table *table = NULL;
4783
4784 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4785 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4786 table = bgp_dest_get_bgp_table_info(pdest);
4787
4788 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4789 bgp, prd, table, p, new);
4790 }
4791 bgp_dest_unlock_node(pdest);
4792 }
4793 #endif
4794
4795 /* If this is an EVPN route, process for import. */
4796 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4797 bgp_evpn_import_route(bgp, afi, safi, p, new);
4798
4799 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4800
4801 /* Process change. */
4802 bgp_process(bgp, dest, afi, safi);
4803
4804 if (SAFI_UNICAST == safi
4805 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4806 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4807 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4808 }
4809 if ((SAFI_MPLS_VPN == safi)
4810 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4811 leak_success = vpn_leak_to_vrf_update(bgp, new, prd);
4812 }
4813 #ifdef ENABLE_BGP_VNC
4814 if (SAFI_MPLS_VPN == safi) {
4815 mpls_label_t label_decoded = decode_label(label);
4816
4817 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4818 sub_type, &label_decoded);
4819 }
4820 if (SAFI_ENCAP == safi) {
4821 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4822 sub_type, NULL);
4823 }
4824 #endif
4825 if ((safi == SAFI_MPLS_VPN) &&
4826 !CHECK_FLAG(bgp->af_flags[afi][safi],
4827 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4828 !leak_success) {
4829 bgp_unlink_nexthop(new);
4830 bgp_path_info_delete(dest, new);
4831 }
4832
4833 return 0;
4834
4835 /* This BGP update is filtered. Log the reason then update BGP
4836 entry. */
4837 filtered:
4838 if (new) {
4839 bgp_unlink_nexthop(new);
4840 bgp_path_info_delete(dest, new);
4841 bgp_path_info_extra_free(&new->extra);
4842 XFREE(MTYPE_BGP_ROUTE, new);
4843 }
4844
4845 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4846
4847 if (bgp_debug_update(peer, p, NULL, 1)) {
4848 if (!peer->rcvd_attr_printed) {
4849 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4850 peer->rcvd_attr_str);
4851 peer->rcvd_attr_printed = 1;
4852 }
4853
4854 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4855 addpath_id ? 1 : 0, addpath_id, evpn,
4856 pfx_buf, sizeof(pfx_buf));
4857 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4858 peer, pfx_buf, reason);
4859 }
4860
4861 if (pi) {
4862 /* If this is an EVPN route, un-import it as it is now filtered.
4863 */
4864 if (safi == SAFI_EVPN)
4865 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4866
4867 if (SAFI_UNICAST == safi
4868 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4869 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4870
4871 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4872 }
4873 if ((SAFI_MPLS_VPN == safi)
4874 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4875
4876 vpn_leak_to_vrf_withdraw(bgp, pi);
4877 }
4878
4879 bgp_rib_remove(dest, pi, peer, afi, safi);
4880 }
4881
4882 bgp_dest_unlock_node(dest);
4883
4884 #ifdef ENABLE_BGP_VNC
4885 /*
4886 * Filtered update is treated as an implicit withdrawal (see
4887 * bgp_rib_remove()
4888 * a few lines above)
4889 */
4890 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4891 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4892 0);
4893 }
4894 #endif
4895
4896 return 0;
4897 }
4898
4899 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4900 struct attr *attr, afi_t afi, safi_t safi, int type,
4901 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4902 uint32_t num_labels, struct bgp_route_evpn *evpn)
4903 {
4904 struct bgp *bgp;
4905 char pfx_buf[BGP_PRD_PATH_STRLEN];
4906 struct bgp_dest *dest;
4907 struct bgp_path_info *pi;
4908
4909 #ifdef ENABLE_BGP_VNC
4910 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4911 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4912 0);
4913 }
4914 #endif
4915
4916 bgp = peer->bgp;
4917
4918 /* Lookup node. */
4919 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4920
4921 /* If peer is soft reconfiguration enabled. Record input packet for
4922 * further calculation.
4923 *
4924 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4925 * routes that are filtered. This tanks out Quagga RS pretty badly due
4926 * to
4927 * the iteration over all RS clients.
4928 * Since we need to remove the entry from adj_in anyway, do that first
4929 * and
4930 * if there was no entry, we don't need to do anything more.
4931 */
4932 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4933 && peer != bgp->peer_self)
4934 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4935 peer->stat_pfx_dup_withdraw++;
4936
4937 if (bgp_debug_update(peer, p, NULL, 1)) {
4938 bgp_debug_rdpfxpath2str(
4939 afi, safi, prd, p, label, num_labels,
4940 addpath_id ? 1 : 0, addpath_id, NULL,
4941 pfx_buf, sizeof(pfx_buf));
4942 zlog_debug(
4943 "%s withdrawing route %s not in adj-in",
4944 peer->host, pfx_buf);
4945 }
4946 bgp_dest_unlock_node(dest);
4947 return 0;
4948 }
4949
4950 /* Lookup withdrawn route. */
4951 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4952 if (pi->peer == peer && pi->type == type
4953 && pi->sub_type == sub_type
4954 && pi->addpath_rx_id == addpath_id)
4955 break;
4956
4957 /* Logging. */
4958 if (bgp_debug_update(peer, p, NULL, 1)) {
4959 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4960 addpath_id ? 1 : 0, addpath_id, NULL,
4961 pfx_buf, sizeof(pfx_buf));
4962 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
4963 pfx_buf);
4964 }
4965
4966 /* Withdraw specified route from routing table. */
4967 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4968 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4969 if (SAFI_UNICAST == safi
4970 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4971 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4972 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4973 }
4974 if ((SAFI_MPLS_VPN == safi)
4975 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4976
4977 vpn_leak_to_vrf_withdraw(bgp, pi);
4978 }
4979 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4980 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4981 addpath_id ? 1 : 0, addpath_id, NULL,
4982 pfx_buf, sizeof(pfx_buf));
4983 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4984 }
4985
4986 /* Unlock bgp_node_get() lock. */
4987 bgp_dest_unlock_node(dest);
4988
4989 return 0;
4990 }
4991
4992 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4993 int withdraw)
4994 {
4995 struct update_subgroup *subgrp;
4996 subgrp = peer_subgroup(peer, afi, safi);
4997 subgroup_default_originate(subgrp, withdraw);
4998 }
4999
5000
5001 /*
5002 * bgp_stop_announce_route_timer
5003 */
5004 void bgp_stop_announce_route_timer(struct peer_af *paf)
5005 {
5006 if (!paf->t_announce_route)
5007 return;
5008
5009 THREAD_OFF(paf->t_announce_route);
5010 }
5011
5012 /*
5013 * bgp_announce_route_timer_expired
5014 *
5015 * Callback that is invoked when the route announcement timer for a
5016 * peer_af expires.
5017 */
5018 static void bgp_announce_route_timer_expired(struct thread *t)
5019 {
5020 struct peer_af *paf;
5021 struct peer *peer;
5022
5023 paf = THREAD_ARG(t);
5024 peer = paf->peer;
5025
5026 if (!peer_established(peer))
5027 return;
5028
5029 if (!peer->afc_nego[paf->afi][paf->safi])
5030 return;
5031
5032 peer_af_announce_route(paf, 1);
5033
5034 /* Notify BGP conditional advertisement scanner percess */
5035 peer->advmap_config_change[paf->afi][paf->safi] = true;
5036 }
5037
5038 /*
5039 * bgp_announce_route
5040 *
5041 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
5042 *
5043 * if force is true we will force an update even if the update
5044 * limiting code is attempted to kick in.
5045 */
5046 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
5047 {
5048 struct peer_af *paf;
5049 struct update_subgroup *subgrp;
5050
5051 paf = peer_af_find(peer, afi, safi);
5052 if (!paf)
5053 return;
5054 subgrp = PAF_SUBGRP(paf);
5055
5056 /*
5057 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
5058 * or a refresh has already been triggered.
5059 */
5060 if (!subgrp || paf->t_announce_route)
5061 return;
5062
5063 if (force)
5064 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
5065
5066 /*
5067 * Start a timer to stagger/delay the announce. This serves
5068 * two purposes - announcement can potentially be combined for
5069 * multiple peers and the announcement doesn't happen in the
5070 * vty context.
5071 */
5072 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
5073 (subgrp->peer_count == 1)
5074 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
5075 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
5076 &paf->t_announce_route);
5077 }
5078
5079 /*
5080 * Announce routes from all AF tables to a peer.
5081 *
5082 * This should ONLY be called when there is a need to refresh the
5083 * routes to the peer based on a policy change for this peer alone
5084 * or a route refresh request received from the peer.
5085 * The operation will result in splitting the peer from its existing
5086 * subgroups and putting it in new subgroups.
5087 */
5088 void bgp_announce_route_all(struct peer *peer)
5089 {
5090 afi_t afi;
5091 safi_t safi;
5092
5093 FOREACH_AFI_SAFI (afi, safi)
5094 bgp_announce_route(peer, afi, safi, false);
5095 }
5096
5097 /* Flag or unflag bgp_dest to determine whether it should be treated by
5098 * bgp_soft_reconfig_table_task.
5099 * Flag if flag is true. Unflag if flag is false.
5100 */
5101 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
5102 {
5103 struct bgp_dest *dest;
5104 struct bgp_adj_in *ain;
5105
5106 if (!table)
5107 return;
5108
5109 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5110 for (ain = dest->adj_in; ain; ain = ain->next) {
5111 if (ain->peer != NULL)
5112 break;
5113 }
5114 if (flag && ain != NULL && ain->peer != NULL)
5115 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5116 else
5117 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5118 }
5119 }
5120
5121 static int bgp_soft_reconfig_table_update(struct peer *peer,
5122 struct bgp_dest *dest,
5123 struct bgp_adj_in *ain, afi_t afi,
5124 safi_t safi, struct prefix_rd *prd)
5125 {
5126 struct bgp_path_info *pi;
5127 uint32_t num_labels = 0;
5128 mpls_label_t *label_pnt = NULL;
5129 struct bgp_route_evpn evpn;
5130
5131 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5132 if (pi->peer == peer)
5133 break;
5134
5135 if (pi && pi->extra)
5136 num_labels = pi->extra->num_labels;
5137 if (num_labels)
5138 label_pnt = &pi->extra->label[0];
5139 if (pi)
5140 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
5141 sizeof(evpn));
5142 else
5143 memset(&evpn, 0, sizeof(evpn));
5144
5145 return bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
5146 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
5147 BGP_ROUTE_NORMAL, prd, label_pnt, num_labels, 1,
5148 &evpn);
5149 }
5150
5151 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5152 struct bgp_table *table,
5153 struct prefix_rd *prd)
5154 {
5155 int ret;
5156 struct bgp_dest *dest;
5157 struct bgp_adj_in *ain;
5158
5159 if (!table)
5160 table = peer->bgp->rib[afi][safi];
5161
5162 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5163 for (ain = dest->adj_in; ain; ain = ain->next) {
5164 if (ain->peer != peer)
5165 continue;
5166
5167 ret = bgp_soft_reconfig_table_update(peer, dest, ain,
5168 afi, safi, prd);
5169
5170 if (ret < 0) {
5171 bgp_dest_unlock_node(dest);
5172 return;
5173 }
5174 }
5175 }
5176
5177 /* Do soft reconfig table per bgp table.
5178 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5179 * when BGP_NODE_SOFT_RECONFIG is set,
5180 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5181 * Schedule a new thread to continue the job.
5182 * Without splitting the full job into several part,
5183 * vtysh waits for the job to finish before responding to a BGP command
5184 */
5185 static void bgp_soft_reconfig_table_task(struct thread *thread)
5186 {
5187 uint32_t iter, max_iter;
5188 int ret;
5189 struct bgp_dest *dest;
5190 struct bgp_adj_in *ain;
5191 struct peer *peer;
5192 struct bgp_table *table;
5193 struct prefix_rd *prd;
5194 struct listnode *node, *nnode;
5195
5196 table = THREAD_ARG(thread);
5197 prd = NULL;
5198
5199 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5200 if (table->soft_reconfig_init) {
5201 /* first call of the function with a new srta structure.
5202 * Don't do any treatment this time on nodes
5203 * in order vtysh to respond quickly
5204 */
5205 max_iter = 0;
5206 }
5207
5208 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5209 dest = bgp_route_next(dest)) {
5210 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5211 continue;
5212
5213 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5214
5215 for (ain = dest->adj_in; ain; ain = ain->next) {
5216 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5217 nnode, peer)) {
5218 if (ain->peer != peer)
5219 continue;
5220
5221 ret = bgp_soft_reconfig_table_update(
5222 peer, dest, ain, table->afi,
5223 table->safi, prd);
5224 iter++;
5225
5226 if (ret < 0) {
5227 bgp_dest_unlock_node(dest);
5228 listnode_delete(
5229 table->soft_reconfig_peers,
5230 peer);
5231 bgp_announce_route(peer, table->afi,
5232 table->safi, false);
5233 if (list_isempty(
5234 table->soft_reconfig_peers)) {
5235 list_delete(
5236 &table->soft_reconfig_peers);
5237 bgp_soft_reconfig_table_flag(
5238 table, false);
5239 return;
5240 }
5241 }
5242 }
5243 }
5244 }
5245
5246 /* we're either starting the initial iteration,
5247 * or we're going to continue an ongoing iteration
5248 */
5249 if (dest || table->soft_reconfig_init) {
5250 table->soft_reconfig_init = false;
5251 thread_add_event(bm->master, bgp_soft_reconfig_table_task,
5252 table, 0, &table->soft_reconfig_thread);
5253 return;
5254 }
5255 /* we're done, clean up the background iteration context info and
5256 schedule route annoucement
5257 */
5258 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5259 listnode_delete(table->soft_reconfig_peers, peer);
5260 bgp_announce_route(peer, table->afi, table->safi, false);
5261 }
5262
5263 list_delete(&table->soft_reconfig_peers);
5264 }
5265
5266
5267 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5268 * and peer.
5269 * - bgp cannot be NULL
5270 * - if table and peer are NULL, cancel all threads within the bgp instance
5271 * - if table is NULL and peer is not,
5272 * remove peer in all threads within the bgp instance
5273 * - if peer is NULL, cancel all threads matching table within the bgp instance
5274 */
5275 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5276 const struct bgp_table *table,
5277 const struct peer *peer)
5278 {
5279 struct peer *npeer;
5280 struct listnode *node, *nnode;
5281 int afi, safi;
5282 struct bgp_table *ntable;
5283
5284 if (!bgp)
5285 return;
5286
5287 FOREACH_AFI_SAFI (afi, safi) {
5288 ntable = bgp->rib[afi][safi];
5289 if (!ntable)
5290 continue;
5291 if (table && table != ntable)
5292 continue;
5293
5294 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5295 npeer)) {
5296 if (peer && peer != npeer)
5297 continue;
5298 listnode_delete(ntable->soft_reconfig_peers, npeer);
5299 }
5300
5301 if (!ntable->soft_reconfig_peers
5302 || !list_isempty(ntable->soft_reconfig_peers))
5303 continue;
5304
5305 list_delete(&ntable->soft_reconfig_peers);
5306 bgp_soft_reconfig_table_flag(ntable, false);
5307 THREAD_OFF(ntable->soft_reconfig_thread);
5308 }
5309 }
5310
5311 /*
5312 * Returns false if the peer is not configured for soft reconfig in
5313 */
5314 bool bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5315 {
5316 struct bgp_dest *dest;
5317 struct bgp_table *table;
5318 struct listnode *node, *nnode;
5319 struct peer *npeer;
5320 struct peer_af *paf;
5321
5322 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5323 return false;
5324
5325 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5326 && (safi != SAFI_EVPN)) {
5327 table = peer->bgp->rib[afi][safi];
5328 if (!table)
5329 return true;
5330
5331 table->soft_reconfig_init = true;
5332
5333 if (!table->soft_reconfig_peers)
5334 table->soft_reconfig_peers = list_new();
5335 npeer = NULL;
5336 /* add peer to the table soft_reconfig_peers if not already
5337 * there
5338 */
5339 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5340 npeer)) {
5341 if (peer == npeer)
5342 break;
5343 }
5344 if (peer != npeer)
5345 listnode_add(table->soft_reconfig_peers, peer);
5346
5347 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5348 * on table would start back at the beginning.
5349 */
5350 bgp_soft_reconfig_table_flag(table, true);
5351
5352 if (!table->soft_reconfig_thread)
5353 thread_add_event(bm->master,
5354 bgp_soft_reconfig_table_task, table, 0,
5355 &table->soft_reconfig_thread);
5356 /* Cancel bgp_announce_route_timer_expired threads.
5357 * bgp_announce_route_timer_expired threads have been scheduled
5358 * to announce routes as soon as the soft_reconfigure process
5359 * finishes.
5360 * In this case, soft_reconfigure is also scheduled by using
5361 * a thread but is planned after the
5362 * bgp_announce_route_timer_expired threads. It means that,
5363 * without cancelling the threads, the route announcement task
5364 * would run before the soft reconfiguration one. That would
5365 * useless and would block vtysh during several seconds. Route
5366 * announcements are rescheduled as soon as the soft_reconfigure
5367 * process finishes.
5368 */
5369 paf = peer_af_find(peer, afi, safi);
5370 if (paf)
5371 bgp_stop_announce_route_timer(paf);
5372 } else
5373 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5374 dest = bgp_route_next(dest)) {
5375 table = bgp_dest_get_bgp_table_info(dest);
5376
5377 if (table == NULL)
5378 continue;
5379
5380 const struct prefix *p = bgp_dest_get_prefix(dest);
5381 struct prefix_rd prd;
5382
5383 prd.family = AF_UNSPEC;
5384 prd.prefixlen = 64;
5385 memcpy(&prd.val, p->u.val, 8);
5386
5387 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5388 }
5389
5390 return true;
5391 }
5392
5393
5394 struct bgp_clear_node_queue {
5395 struct bgp_dest *dest;
5396 };
5397
5398 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5399 {
5400 struct bgp_clear_node_queue *cnq = data;
5401 struct bgp_dest *dest = cnq->dest;
5402 struct peer *peer = wq->spec.data;
5403 struct bgp_path_info *pi;
5404 struct bgp *bgp;
5405 afi_t afi = bgp_dest_table(dest)->afi;
5406 safi_t safi = bgp_dest_table(dest)->safi;
5407
5408 assert(dest && peer);
5409 bgp = peer->bgp;
5410
5411 /* It is possible that we have multiple paths for a prefix from a peer
5412 * if that peer is using AddPath.
5413 */
5414 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5415 if (pi->peer != peer)
5416 continue;
5417
5418 /* graceful restart STALE flag set. */
5419 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5420 && peer->nsf[afi][safi])
5421 || CHECK_FLAG(peer->af_sflags[afi][safi],
5422 PEER_STATUS_ENHANCED_REFRESH))
5423 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5424 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5425 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5426 else {
5427 /* If this is an EVPN route, process for
5428 * un-import. */
5429 if (safi == SAFI_EVPN)
5430 bgp_evpn_unimport_route(
5431 bgp, afi, safi,
5432 bgp_dest_get_prefix(dest), pi);
5433 /* Handle withdraw for VRF route-leaking and L3VPN */
5434 if (SAFI_UNICAST == safi
5435 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5436 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5437 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5438 bgp, pi);
5439 }
5440 if (SAFI_MPLS_VPN == safi &&
5441 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5442 vpn_leak_to_vrf_withdraw(bgp, pi);
5443 }
5444
5445 bgp_rib_remove(dest, pi, peer, afi, safi);
5446 }
5447 }
5448 return WQ_SUCCESS;
5449 }
5450
5451 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5452 {
5453 struct bgp_clear_node_queue *cnq = data;
5454 struct bgp_dest *dest = cnq->dest;
5455 struct bgp_table *table = bgp_dest_table(dest);
5456
5457 bgp_dest_unlock_node(dest);
5458 bgp_table_unlock(table);
5459 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5460 }
5461
5462 static void bgp_clear_node_complete(struct work_queue *wq)
5463 {
5464 struct peer *peer = wq->spec.data;
5465
5466 /* Tickle FSM to start moving again */
5467 BGP_EVENT_ADD(peer, Clearing_Completed);
5468
5469 peer_unlock(peer); /* bgp_clear_route */
5470 }
5471
5472 static void bgp_clear_node_queue_init(struct peer *peer)
5473 {
5474 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5475
5476 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5477 #undef CLEAR_QUEUE_NAME_LEN
5478
5479 peer->clear_node_queue = work_queue_new(bm->master, wname);
5480 peer->clear_node_queue->spec.hold = 10;
5481 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5482 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5483 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5484 peer->clear_node_queue->spec.max_retries = 0;
5485
5486 /* we only 'lock' this peer reference when the queue is actually active
5487 */
5488 peer->clear_node_queue->spec.data = peer;
5489 }
5490
5491 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5492 struct bgp_table *table)
5493 {
5494 struct bgp_dest *dest;
5495 int force = peer->bgp->process_queue ? 0 : 1;
5496
5497 if (!table)
5498 table = peer->bgp->rib[afi][safi];
5499
5500 /* If still no table => afi/safi isn't configured at all or smth. */
5501 if (!table)
5502 return;
5503
5504 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5505 struct bgp_path_info *pi, *next;
5506 struct bgp_adj_in *ain;
5507 struct bgp_adj_in *ain_next;
5508
5509 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5510 * queued for every clearing peer, regardless of whether it is
5511 * relevant to the peer at hand.
5512 *
5513 * Overview: There are 3 different indices which need to be
5514 * scrubbed, potentially, when a peer is removed:
5515 *
5516 * 1 peer's routes visible via the RIB (ie accepted routes)
5517 * 2 peer's routes visible by the (optional) peer's adj-in index
5518 * 3 other routes visible by the peer's adj-out index
5519 *
5520 * 3 there is no hurry in scrubbing, once the struct peer is
5521 * removed from bgp->peer, we could just GC such deleted peer's
5522 * adj-outs at our leisure.
5523 *
5524 * 1 and 2 must be 'scrubbed' in some way, at least made
5525 * invisible via RIB index before peer session is allowed to be
5526 * brought back up. So one needs to know when such a 'search' is
5527 * complete.
5528 *
5529 * Ideally:
5530 *
5531 * - there'd be a single global queue or a single RIB walker
5532 * - rather than tracking which route_nodes still need to be
5533 * examined on a peer basis, we'd track which peers still
5534 * aren't cleared
5535 *
5536 * Given that our per-peer prefix-counts now should be reliable,
5537 * this may actually be achievable. It doesn't seem to be a huge
5538 * problem at this time,
5539 *
5540 * It is possible that we have multiple paths for a prefix from
5541 * a peer
5542 * if that peer is using AddPath.
5543 */
5544 ain = dest->adj_in;
5545 while (ain) {
5546 ain_next = ain->next;
5547
5548 if (ain->peer == peer)
5549 bgp_adj_in_remove(dest, ain);
5550
5551 ain = ain_next;
5552 }
5553
5554 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5555 next = pi->next;
5556 if (pi->peer != peer)
5557 continue;
5558
5559 if (force)
5560 bgp_path_info_reap(dest, pi);
5561 else {
5562 struct bgp_clear_node_queue *cnq;
5563
5564 /* both unlocked in bgp_clear_node_queue_del */
5565 bgp_table_lock(bgp_dest_table(dest));
5566 bgp_dest_lock_node(dest);
5567 cnq = XCALLOC(
5568 MTYPE_BGP_CLEAR_NODE_QUEUE,
5569 sizeof(struct bgp_clear_node_queue));
5570 cnq->dest = dest;
5571 work_queue_add(peer->clear_node_queue, cnq);
5572 break;
5573 }
5574 }
5575 }
5576 return;
5577 }
5578
5579 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5580 {
5581 struct bgp_dest *dest;
5582 struct bgp_table *table;
5583
5584 if (peer->clear_node_queue == NULL)
5585 bgp_clear_node_queue_init(peer);
5586
5587 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5588 * Idle until it receives a Clearing_Completed event. This protects
5589 * against peers which flap faster than we can we clear, which could
5590 * lead to:
5591 *
5592 * a) race with routes from the new session being installed before
5593 * clear_route_node visits the node (to delete the route of that
5594 * peer)
5595 * b) resource exhaustion, clear_route_node likely leads to an entry
5596 * on the process_main queue. Fast-flapping could cause that queue
5597 * to grow and grow.
5598 */
5599
5600 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5601 * the unlock will happen upon work-queue completion; other wise, the
5602 * unlock happens at the end of this function.
5603 */
5604 if (!peer->clear_node_queue->thread)
5605 peer_lock(peer);
5606
5607 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5608 bgp_clear_route_table(peer, afi, safi, NULL);
5609 else
5610 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5611 dest = bgp_route_next(dest)) {
5612 table = bgp_dest_get_bgp_table_info(dest);
5613 if (!table)
5614 continue;
5615
5616 bgp_clear_route_table(peer, afi, safi, table);
5617 }
5618
5619 /* unlock if no nodes got added to the clear-node-queue. */
5620 if (!peer->clear_node_queue->thread)
5621 peer_unlock(peer);
5622 }
5623
5624 void bgp_clear_route_all(struct peer *peer)
5625 {
5626 afi_t afi;
5627 safi_t safi;
5628
5629 FOREACH_AFI_SAFI (afi, safi)
5630 bgp_clear_route(peer, afi, safi);
5631
5632 #ifdef ENABLE_BGP_VNC
5633 rfapiProcessPeerDown(peer);
5634 #endif
5635 }
5636
5637 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5638 {
5639 struct bgp_table *table;
5640 struct bgp_dest *dest;
5641 struct bgp_adj_in *ain;
5642 struct bgp_adj_in *ain_next;
5643
5644 table = peer->bgp->rib[afi][safi];
5645
5646 /* It is possible that we have multiple paths for a prefix from a peer
5647 * if that peer is using AddPath.
5648 */
5649 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5650 ain = dest->adj_in;
5651
5652 while (ain) {
5653 ain_next = ain->next;
5654
5655 if (ain->peer == peer)
5656 bgp_adj_in_remove(dest, ain);
5657
5658 ain = ain_next;
5659 }
5660 }
5661 }
5662
5663 /* If any of the routes from the peer have been marked with the NO_LLGR
5664 * community, either as sent by the peer, or as the result of a configured
5665 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5666 * operation of [RFC4271].
5667 */
5668 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5669 {
5670 struct bgp_dest *dest;
5671 struct bgp_path_info *pi;
5672 struct bgp_table *table;
5673
5674 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5675 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5676 dest = bgp_route_next(dest)) {
5677 struct bgp_dest *rm;
5678
5679 /* look for neighbor in tables */
5680 table = bgp_dest_get_bgp_table_info(dest);
5681 if (!table)
5682 continue;
5683
5684 for (rm = bgp_table_top(table); rm;
5685 rm = bgp_route_next(rm))
5686 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5687 pi = pi->next) {
5688 if (pi->peer != peer)
5689 continue;
5690 if (CHECK_FLAG(
5691 peer->af_sflags[afi][safi],
5692 PEER_STATUS_LLGR_WAIT) &&
5693 bgp_attr_get_community(pi->attr) &&
5694 !community_include(
5695 bgp_attr_get_community(
5696 pi->attr),
5697 COMMUNITY_NO_LLGR))
5698 continue;
5699 if (!CHECK_FLAG(pi->flags,
5700 BGP_PATH_STALE))
5701 continue;
5702
5703 /*
5704 * If this is VRF leaked route
5705 * process for withdraw.
5706 */
5707 if (pi->sub_type ==
5708 BGP_ROUTE_IMPORTED &&
5709 peer->bgp->inst_type ==
5710 BGP_INSTANCE_TYPE_DEFAULT)
5711 vpn_leak_to_vrf_withdraw(
5712 peer->bgp, pi);
5713
5714 bgp_rib_remove(rm, pi, peer, afi, safi);
5715 break;
5716 }
5717 }
5718 } else {
5719 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5720 dest = bgp_route_next(dest))
5721 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5722 pi = pi->next) {
5723 if (pi->peer != peer)
5724 continue;
5725 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5726 PEER_STATUS_LLGR_WAIT) &&
5727 bgp_attr_get_community(pi->attr) &&
5728 !community_include(
5729 bgp_attr_get_community(pi->attr),
5730 COMMUNITY_NO_LLGR))
5731 continue;
5732 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5733 continue;
5734 if (safi == SAFI_UNICAST &&
5735 (peer->bgp->inst_type ==
5736 BGP_INSTANCE_TYPE_VRF ||
5737 peer->bgp->inst_type ==
5738 BGP_INSTANCE_TYPE_DEFAULT))
5739 vpn_leak_from_vrf_withdraw(
5740 bgp_get_default(), peer->bgp,
5741 pi);
5742
5743 bgp_rib_remove(dest, pi, peer, afi, safi);
5744 break;
5745 }
5746 }
5747 }
5748
5749 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5750 {
5751 struct bgp_dest *dest, *ndest;
5752 struct bgp_path_info *pi;
5753 struct bgp_table *table;
5754
5755 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5756 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5757 dest = bgp_route_next(dest)) {
5758 table = bgp_dest_get_bgp_table_info(dest);
5759 if (!table)
5760 continue;
5761
5762 for (ndest = bgp_table_top(table); ndest;
5763 ndest = bgp_route_next(ndest)) {
5764 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5765 pi = pi->next) {
5766 if (pi->peer != peer)
5767 continue;
5768
5769 if ((CHECK_FLAG(
5770 peer->af_sflags[afi][safi],
5771 PEER_STATUS_ENHANCED_REFRESH))
5772 && !CHECK_FLAG(pi->flags,
5773 BGP_PATH_STALE)
5774 && !CHECK_FLAG(
5775 pi->flags,
5776 BGP_PATH_UNUSEABLE)) {
5777 if (bgp_debug_neighbor_events(
5778 peer))
5779 zlog_debug(
5780 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5781 peer,
5782 afi2str(afi),
5783 safi2str(safi),
5784 bgp_dest_get_prefix(
5785 ndest));
5786
5787 bgp_path_info_set_flag(
5788 ndest, pi,
5789 BGP_PATH_STALE);
5790 }
5791 }
5792 }
5793 }
5794 } else {
5795 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5796 dest = bgp_route_next(dest)) {
5797 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5798 pi = pi->next) {
5799 if (pi->peer != peer)
5800 continue;
5801
5802 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5803 PEER_STATUS_ENHANCED_REFRESH))
5804 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5805 && !CHECK_FLAG(pi->flags,
5806 BGP_PATH_UNUSEABLE)) {
5807 if (bgp_debug_neighbor_events(peer))
5808 zlog_debug(
5809 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5810 peer, afi2str(afi),
5811 safi2str(safi),
5812 bgp_dest_get_prefix(
5813 dest));
5814
5815 bgp_path_info_set_flag(dest, pi,
5816 BGP_PATH_STALE);
5817 }
5818 }
5819 }
5820 }
5821 }
5822
5823 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5824 {
5825 if (peer->sort == BGP_PEER_IBGP)
5826 return true;
5827
5828 if (peer->sort == BGP_PEER_EBGP
5829 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5830 || FILTER_LIST_OUT_NAME(filter)
5831 || DISTRIBUTE_OUT_NAME(filter)))
5832 return true;
5833 return false;
5834 }
5835
5836 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5837 {
5838 if (peer->sort == BGP_PEER_IBGP)
5839 return true;
5840
5841 if (peer->sort == BGP_PEER_EBGP
5842 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5843 || FILTER_LIST_IN_NAME(filter)
5844 || DISTRIBUTE_IN_NAME(filter)))
5845 return true;
5846 return false;
5847 }
5848
5849 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5850 safi_t safi)
5851 {
5852 struct bgp_dest *dest;
5853 struct bgp_path_info *pi;
5854 struct bgp_path_info *next;
5855
5856 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5857 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5858 const struct prefix *p = bgp_dest_get_prefix(dest);
5859
5860 next = pi->next;
5861
5862 /* Unimport EVPN routes from VRFs */
5863 if (safi == SAFI_EVPN)
5864 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5865 SAFI_EVPN, p, pi);
5866
5867 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5868 && pi->type == ZEBRA_ROUTE_BGP
5869 && (pi->sub_type == BGP_ROUTE_NORMAL
5870 || pi->sub_type == BGP_ROUTE_AGGREGATE
5871 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5872
5873 if (bgp_fibupd_safi(safi))
5874 bgp_zebra_withdraw(p, pi, bgp, safi);
5875 }
5876
5877 bgp_path_info_reap(dest, pi);
5878 }
5879 }
5880
5881 /* Delete all kernel routes. */
5882 void bgp_cleanup_routes(struct bgp *bgp)
5883 {
5884 afi_t afi;
5885 struct bgp_dest *dest;
5886 struct bgp_table *table;
5887
5888 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5889 if (afi == AFI_L2VPN)
5890 continue;
5891 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5892 SAFI_UNICAST);
5893 /*
5894 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5895 */
5896 if (afi != AFI_L2VPN) {
5897 safi_t safi;
5898 safi = SAFI_MPLS_VPN;
5899 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5900 dest = bgp_route_next(dest)) {
5901 table = bgp_dest_get_bgp_table_info(dest);
5902 if (table != NULL) {
5903 bgp_cleanup_table(bgp, table, safi);
5904 bgp_table_finish(&table);
5905 bgp_dest_set_bgp_table_info(dest, NULL);
5906 bgp_dest_unlock_node(dest);
5907 }
5908 }
5909 safi = SAFI_ENCAP;
5910 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5911 dest = bgp_route_next(dest)) {
5912 table = bgp_dest_get_bgp_table_info(dest);
5913 if (table != NULL) {
5914 bgp_cleanup_table(bgp, table, safi);
5915 bgp_table_finish(&table);
5916 bgp_dest_set_bgp_table_info(dest, NULL);
5917 bgp_dest_unlock_node(dest);
5918 }
5919 }
5920 }
5921 }
5922 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5923 dest = bgp_route_next(dest)) {
5924 table = bgp_dest_get_bgp_table_info(dest);
5925 if (table != NULL) {
5926 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5927 bgp_table_finish(&table);
5928 bgp_dest_set_bgp_table_info(dest, NULL);
5929 bgp_dest_unlock_node(dest);
5930 }
5931 }
5932 }
5933
5934 void bgp_reset(void)
5935 {
5936 vty_reset();
5937 bgp_zclient_reset();
5938 access_list_reset();
5939 prefix_list_reset();
5940 }
5941
5942 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5943 {
5944 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5945 && CHECK_FLAG(peer->af_cap[afi][safi],
5946 PEER_CAP_ADDPATH_AF_TX_RCV));
5947 }
5948
5949 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5950 value. */
5951 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5952 struct bgp_nlri *packet)
5953 {
5954 uint8_t *pnt;
5955 uint8_t *lim;
5956 struct prefix p;
5957 int psize;
5958 int ret;
5959 afi_t afi;
5960 safi_t safi;
5961 bool addpath_capable;
5962 uint32_t addpath_id;
5963
5964 pnt = packet->nlri;
5965 lim = pnt + packet->length;
5966 afi = packet->afi;
5967 safi = packet->safi;
5968 addpath_id = 0;
5969 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
5970
5971 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5972 syntactic validity. If the field is syntactically incorrect,
5973 then the Error Subcode is set to Invalid Network Field. */
5974 for (; pnt < lim; pnt += psize) {
5975 /* Clear prefix structure. */
5976 memset(&p, 0, sizeof(p));
5977
5978 if (addpath_capable) {
5979
5980 /* When packet overflow occurs return immediately. */
5981 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5982 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5983
5984 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5985 addpath_id = ntohl(addpath_id);
5986 pnt += BGP_ADDPATH_ID_LEN;
5987 }
5988
5989 /* Fetch prefix length. */
5990 p.prefixlen = *pnt++;
5991 /* afi/safi validity already verified by caller,
5992 * bgp_update_receive */
5993 p.family = afi2family(afi);
5994
5995 /* Prefix length check. */
5996 if (p.prefixlen > prefix_blen(&p) * 8) {
5997 flog_err(
5998 EC_BGP_UPDATE_RCV,
5999 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
6000 peer->host, p.prefixlen, packet->afi);
6001 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
6002 }
6003
6004 /* Packet size overflow check. */
6005 psize = PSIZE(p.prefixlen);
6006
6007 /* When packet overflow occur return immediately. */
6008 if (pnt + psize > lim) {
6009 flog_err(
6010 EC_BGP_UPDATE_RCV,
6011 "%s [Error] Update packet error (prefix length %d overflows packet)",
6012 peer->host, p.prefixlen);
6013 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6014 }
6015
6016 /* Defensive coding, double-check the psize fits in a struct
6017 * prefix for the v4 and v6 afi's and unicast/multicast */
6018 if (psize > (ssize_t)sizeof(p.u.val)) {
6019 flog_err(
6020 EC_BGP_UPDATE_RCV,
6021 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
6022 peer->host, p.prefixlen, sizeof(p.u.val));
6023 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6024 }
6025
6026 /* Fetch prefix from NLRI packet. */
6027 memcpy(p.u.val, pnt, psize);
6028
6029 /* Check address. */
6030 if (afi == AFI_IP && safi == SAFI_UNICAST) {
6031 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
6032 /* From RFC4271 Section 6.3:
6033 *
6034 * If a prefix in the NLRI field is semantically
6035 * incorrect
6036 * (e.g., an unexpected multicast IP address),
6037 * an error SHOULD
6038 * be logged locally, and the prefix SHOULD be
6039 * ignored.
6040 */
6041 flog_err(
6042 EC_BGP_UPDATE_RCV,
6043 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
6044 peer->host, &p.u.prefix4);
6045 continue;
6046 }
6047 }
6048
6049 /* Check address. */
6050 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
6051 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6052 flog_err(
6053 EC_BGP_UPDATE_RCV,
6054 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
6055 peer->host, &p.u.prefix6);
6056
6057 continue;
6058 }
6059 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
6060 flog_err(
6061 EC_BGP_UPDATE_RCV,
6062 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
6063 peer->host, &p.u.prefix6);
6064
6065 continue;
6066 }
6067 }
6068
6069 /* Normal process. */
6070 if (attr)
6071 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
6072 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
6073 NULL, NULL, 0, 0, NULL);
6074 else
6075 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
6076 safi, ZEBRA_ROUTE_BGP,
6077 BGP_ROUTE_NORMAL, NULL, NULL, 0,
6078 NULL);
6079
6080 /* Do not send BGP notification twice when maximum-prefix count
6081 * overflow. */
6082 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
6083 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
6084
6085 /* Address family configuration mismatch. */
6086 if (ret < 0)
6087 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
6088 }
6089
6090 /* Packet length consistency check. */
6091 if (pnt != lim) {
6092 flog_err(
6093 EC_BGP_UPDATE_RCV,
6094 "%s [Error] Update packet error (prefix length mismatch with total length)",
6095 peer->host);
6096 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6097 }
6098
6099 return BGP_NLRI_PARSE_OK;
6100 }
6101
6102 static struct bgp_static *bgp_static_new(void)
6103 {
6104 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
6105 }
6106
6107 static void bgp_static_free(struct bgp_static *bgp_static)
6108 {
6109 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6110 route_map_counter_decrement(bgp_static->rmap.map);
6111
6112 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
6113 XFREE(MTYPE_BGP_STATIC, bgp_static);
6114 }
6115
6116 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
6117 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
6118 {
6119 struct bgp_dest *dest;
6120 struct bgp_path_info *pi;
6121 struct bgp_path_info *new;
6122 struct bgp_path_info rmap_path;
6123 struct attr attr;
6124 struct attr *attr_new;
6125 route_map_result_t ret;
6126 #ifdef ENABLE_BGP_VNC
6127 int vnc_implicit_withdraw = 0;
6128 #endif
6129
6130 assert(bgp_static);
6131
6132 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6133
6134 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6135
6136 attr.nexthop = bgp_static->igpnexthop;
6137 attr.med = bgp_static->igpmetric;
6138 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6139
6140 if (afi == AFI_IP)
6141 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
6142
6143 if (bgp_static->igpmetric)
6144 bgp_attr_set_aigp_metric(&attr, bgp_static->igpmetric);
6145
6146 if (bgp_static->atomic)
6147 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
6148
6149 /* Store label index, if required. */
6150 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
6151 attr.label_index = bgp_static->label_index;
6152 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
6153 }
6154
6155 /* Apply route-map. */
6156 if (bgp_static->rmap.name) {
6157 struct attr attr_tmp = attr;
6158
6159 memset(&rmap_path, 0, sizeof(rmap_path));
6160 rmap_path.peer = bgp->peer_self;
6161 rmap_path.attr = &attr_tmp;
6162
6163 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6164
6165 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6166
6167 bgp->peer_self->rmap_type = 0;
6168
6169 if (ret == RMAP_DENYMATCH) {
6170 /* Free uninterned attribute. */
6171 bgp_attr_flush(&attr_tmp);
6172
6173 /* Unintern original. */
6174 aspath_unintern(&attr.aspath);
6175 bgp_static_withdraw(bgp, p, afi, safi);
6176 bgp_dest_unlock_node(dest);
6177 return;
6178 }
6179
6180 if (bgp_in_graceful_shutdown(bgp))
6181 bgp_attr_add_gshut_community(&attr_tmp);
6182
6183 attr_new = bgp_attr_intern(&attr_tmp);
6184 } else {
6185
6186 if (bgp_in_graceful_shutdown(bgp))
6187 bgp_attr_add_gshut_community(&attr);
6188
6189 attr_new = bgp_attr_intern(&attr);
6190 }
6191
6192 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6193 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6194 && pi->sub_type == BGP_ROUTE_STATIC)
6195 break;
6196
6197 if (pi) {
6198 if (attrhash_cmp(pi->attr, attr_new)
6199 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6200 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6201 bgp_dest_unlock_node(dest);
6202 bgp_attr_unintern(&attr_new);
6203 aspath_unintern(&attr.aspath);
6204 return;
6205 } else {
6206 /* The attribute is changed. */
6207 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6208
6209 /* Rewrite BGP route information. */
6210 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6211 bgp_path_info_restore(dest, pi);
6212 else
6213 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6214 #ifdef ENABLE_BGP_VNC
6215 if ((afi == AFI_IP || afi == AFI_IP6)
6216 && (safi == SAFI_UNICAST)) {
6217 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6218 /*
6219 * Implicit withdraw case.
6220 * We have to do this before pi is
6221 * changed
6222 */
6223 ++vnc_implicit_withdraw;
6224 vnc_import_bgp_del_route(bgp, p, pi);
6225 vnc_import_bgp_exterior_del_route(
6226 bgp, p, pi);
6227 }
6228 }
6229 #endif
6230 bgp_attr_unintern(&pi->attr);
6231 pi->attr = attr_new;
6232 pi->uptime = monotime(NULL);
6233 #ifdef ENABLE_BGP_VNC
6234 if ((afi == AFI_IP || afi == AFI_IP6)
6235 && (safi == SAFI_UNICAST)) {
6236 if (vnc_implicit_withdraw) {
6237 vnc_import_bgp_add_route(bgp, p, pi);
6238 vnc_import_bgp_exterior_add_route(
6239 bgp, p, pi);
6240 }
6241 }
6242 #endif
6243
6244 /* Nexthop reachability check. */
6245 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6246 && (safi == SAFI_UNICAST
6247 || safi == SAFI_LABELED_UNICAST)) {
6248
6249 struct bgp *bgp_nexthop = bgp;
6250
6251 if (pi->extra && pi->extra->bgp_orig)
6252 bgp_nexthop = pi->extra->bgp_orig;
6253
6254 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6255 afi, safi, pi, NULL,
6256 0, p))
6257 bgp_path_info_set_flag(dest, pi,
6258 BGP_PATH_VALID);
6259 else {
6260 if (BGP_DEBUG(nht, NHT)) {
6261 char buf1[INET6_ADDRSTRLEN];
6262 inet_ntop(p->family,
6263 &p->u.prefix, buf1,
6264 sizeof(buf1));
6265 zlog_debug(
6266 "%s(%s): Route not in table, not advertising",
6267 __func__, buf1);
6268 }
6269 bgp_path_info_unset_flag(
6270 dest, pi, BGP_PATH_VALID);
6271 }
6272 } else {
6273 /* Delete the NHT structure if any, if we're
6274 * toggling between
6275 * enabling/disabling import check. We
6276 * deregister the route
6277 * from NHT to avoid overloading NHT and the
6278 * process interaction
6279 */
6280 bgp_unlink_nexthop(pi);
6281 bgp_path_info_set_flag(dest, pi,
6282 BGP_PATH_VALID);
6283 }
6284 /* Process change. */
6285 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6286 bgp_process(bgp, dest, afi, safi);
6287
6288 if (SAFI_UNICAST == safi
6289 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6290 || bgp->inst_type
6291 == BGP_INSTANCE_TYPE_DEFAULT)) {
6292 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6293 pi);
6294 }
6295
6296 bgp_dest_unlock_node(dest);
6297 aspath_unintern(&attr.aspath);
6298 return;
6299 }
6300 }
6301
6302 /* Make new BGP info. */
6303 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6304 attr_new, dest);
6305 /* Nexthop reachability check. */
6306 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6307 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6308 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6309 p))
6310 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6311 else {
6312 if (BGP_DEBUG(nht, NHT)) {
6313 char buf1[INET6_ADDRSTRLEN];
6314
6315 inet_ntop(p->family, &p->u.prefix, buf1,
6316 sizeof(buf1));
6317 zlog_debug(
6318 "%s(%s): Route not in table, not advertising",
6319 __func__, buf1);
6320 }
6321 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6322 }
6323 } else {
6324 /* Delete the NHT structure if any, if we're toggling between
6325 * enabling/disabling import check. We deregister the route
6326 * from NHT to avoid overloading NHT and the process interaction
6327 */
6328 bgp_unlink_nexthop(new);
6329
6330 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6331 }
6332
6333 /* Aggregate address increment. */
6334 bgp_aggregate_increment(bgp, p, new, afi, safi);
6335
6336 /* Register new BGP information. */
6337 bgp_path_info_add(dest, new);
6338
6339 /* route_node_get lock */
6340 bgp_dest_unlock_node(dest);
6341
6342 /* Process change. */
6343 bgp_process(bgp, dest, afi, safi);
6344
6345 if (SAFI_UNICAST == safi
6346 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6347 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6348 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6349 }
6350
6351 /* Unintern original. */
6352 aspath_unintern(&attr.aspath);
6353 }
6354
6355 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6356 safi_t safi)
6357 {
6358 struct bgp_dest *dest;
6359 struct bgp_path_info *pi;
6360
6361 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6362
6363 /* Check selected route and self inserted route. */
6364 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6365 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6366 && pi->sub_type == BGP_ROUTE_STATIC)
6367 break;
6368
6369 /* Withdraw static BGP route from routing table. */
6370 if (pi) {
6371 if (SAFI_UNICAST == safi
6372 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6373 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6374 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6375 }
6376 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6377 bgp_unlink_nexthop(pi);
6378 bgp_path_info_delete(dest, pi);
6379 bgp_process(bgp, dest, afi, safi);
6380 }
6381
6382 /* Unlock bgp_node_lookup. */
6383 bgp_dest_unlock_node(dest);
6384 }
6385
6386 /*
6387 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6388 */
6389 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6390 afi_t afi, safi_t safi,
6391 struct prefix_rd *prd)
6392 {
6393 struct bgp_dest *dest;
6394 struct bgp_path_info *pi;
6395
6396 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6397
6398 /* Check selected route and self inserted route. */
6399 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6400 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6401 && pi->sub_type == BGP_ROUTE_STATIC)
6402 break;
6403
6404 /* Withdraw static BGP route from routing table. */
6405 if (pi) {
6406 #ifdef ENABLE_BGP_VNC
6407 rfapiProcessWithdraw(
6408 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6409 1); /* Kill, since it is an administrative change */
6410 #endif
6411 if (SAFI_MPLS_VPN == safi
6412 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6413 vpn_leak_to_vrf_withdraw(bgp, pi);
6414 }
6415 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6416 bgp_path_info_delete(dest, pi);
6417 bgp_process(bgp, dest, afi, safi);
6418 }
6419
6420 /* Unlock bgp_node_lookup. */
6421 bgp_dest_unlock_node(dest);
6422 }
6423
6424 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6425 struct bgp_static *bgp_static, afi_t afi,
6426 safi_t safi)
6427 {
6428 struct bgp_dest *dest;
6429 struct bgp_path_info *new;
6430 struct attr *attr_new;
6431 struct attr attr = {0};
6432 struct bgp_path_info *pi;
6433 #ifdef ENABLE_BGP_VNC
6434 mpls_label_t label = 0;
6435 #endif
6436 uint32_t num_labels = 0;
6437
6438 assert(bgp_static);
6439
6440 if (bgp_static->label != MPLS_INVALID_LABEL)
6441 num_labels = 1;
6442 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6443 &bgp_static->prd);
6444
6445 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6446
6447 attr.nexthop = bgp_static->igpnexthop;
6448 attr.med = bgp_static->igpmetric;
6449 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6450
6451 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6452 || (safi == SAFI_ENCAP)) {
6453 if (afi == AFI_IP) {
6454 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6455 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6456 }
6457 }
6458 if (afi == AFI_L2VPN) {
6459 if (bgp_static->gatewayIp.family == AF_INET) {
6460 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6461 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6462 &bgp_static->gatewayIp.u.prefix4,
6463 IPV4_MAX_BYTELEN);
6464 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6465 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6466 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6467 &bgp_static->gatewayIp.u.prefix6,
6468 IPV6_MAX_BYTELEN);
6469 }
6470 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6471 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6472 struct bgp_encap_type_vxlan bet;
6473 memset(&bet, 0, sizeof(bet));
6474 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6475 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6476 }
6477 if (bgp_static->router_mac) {
6478 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6479 }
6480 }
6481 /* Apply route-map. */
6482 if (bgp_static->rmap.name) {
6483 struct attr attr_tmp = attr;
6484 struct bgp_path_info rmap_path;
6485 route_map_result_t ret;
6486
6487 rmap_path.peer = bgp->peer_self;
6488 rmap_path.attr = &attr_tmp;
6489
6490 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6491
6492 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6493
6494 bgp->peer_self->rmap_type = 0;
6495
6496 if (ret == RMAP_DENYMATCH) {
6497 /* Free uninterned attribute. */
6498 bgp_attr_flush(&attr_tmp);
6499
6500 /* Unintern original. */
6501 aspath_unintern(&attr.aspath);
6502 bgp_static_withdraw_safi(bgp, p, afi, safi,
6503 &bgp_static->prd);
6504 bgp_dest_unlock_node(dest);
6505 return;
6506 }
6507
6508 attr_new = bgp_attr_intern(&attr_tmp);
6509 } else {
6510 attr_new = bgp_attr_intern(&attr);
6511 }
6512
6513 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6514 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6515 && pi->sub_type == BGP_ROUTE_STATIC)
6516 break;
6517
6518 if (pi) {
6519 if (attrhash_cmp(pi->attr, attr_new)
6520 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6521 bgp_dest_unlock_node(dest);
6522 bgp_attr_unintern(&attr_new);
6523 aspath_unintern(&attr.aspath);
6524 return;
6525 } else {
6526 /* The attribute is changed. */
6527 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6528
6529 /* Rewrite BGP route information. */
6530 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6531 bgp_path_info_restore(dest, pi);
6532 else
6533 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6534 bgp_attr_unintern(&pi->attr);
6535 pi->attr = attr_new;
6536 pi->uptime = monotime(NULL);
6537 #ifdef ENABLE_BGP_VNC
6538 if (pi->extra)
6539 label = decode_label(&pi->extra->label[0]);
6540 #endif
6541
6542 /* Process change. */
6543 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6544 bgp_process(bgp, dest, afi, safi);
6545
6546 if (SAFI_MPLS_VPN == safi
6547 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6548 vpn_leak_to_vrf_update(bgp, pi,
6549 &bgp_static->prd);
6550 }
6551 #ifdef ENABLE_BGP_VNC
6552 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6553 pi->attr, afi, safi, pi->type,
6554 pi->sub_type, &label);
6555 #endif
6556 bgp_dest_unlock_node(dest);
6557 aspath_unintern(&attr.aspath);
6558 return;
6559 }
6560 }
6561
6562
6563 /* Make new BGP info. */
6564 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6565 attr_new, dest);
6566 SET_FLAG(new->flags, BGP_PATH_VALID);
6567 bgp_path_info_extra_get(new);
6568 if (num_labels) {
6569 new->extra->label[0] = bgp_static->label;
6570 new->extra->num_labels = num_labels;
6571 }
6572 #ifdef ENABLE_BGP_VNC
6573 label = decode_label(&bgp_static->label);
6574 #endif
6575
6576 /* Aggregate address increment. */
6577 bgp_aggregate_increment(bgp, p, new, afi, safi);
6578
6579 /* Register new BGP information. */
6580 bgp_path_info_add(dest, new);
6581 /* route_node_get lock */
6582 bgp_dest_unlock_node(dest);
6583
6584 /* Process change. */
6585 bgp_process(bgp, dest, afi, safi);
6586
6587 if (SAFI_MPLS_VPN == safi
6588 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6589 vpn_leak_to_vrf_update(bgp, new, &bgp_static->prd);
6590 }
6591 #ifdef ENABLE_BGP_VNC
6592 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6593 safi, new->type, new->sub_type, &label);
6594 #endif
6595
6596 /* Unintern original. */
6597 aspath_unintern(&attr.aspath);
6598 }
6599
6600 /* Configure static BGP network. When user don't run zebra, static
6601 route should be installed as valid. */
6602 static int bgp_static_set(struct vty *vty, const char *negate,
6603 const char *ip_str, afi_t afi, safi_t safi,
6604 const char *rmap, int backdoor, uint32_t label_index)
6605 {
6606 VTY_DECLVAR_CONTEXT(bgp, bgp);
6607 int ret;
6608 struct prefix p;
6609 struct bgp_static *bgp_static;
6610 struct bgp_dest *dest;
6611 uint8_t need_update = 0;
6612
6613 /* Convert IP prefix string to struct prefix. */
6614 ret = str2prefix(ip_str, &p);
6615 if (!ret) {
6616 vty_out(vty, "%% Malformed prefix\n");
6617 return CMD_WARNING_CONFIG_FAILED;
6618 }
6619 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6620 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6621 return CMD_WARNING_CONFIG_FAILED;
6622 }
6623
6624 apply_mask(&p);
6625
6626 if (negate) {
6627
6628 /* Set BGP static route configuration. */
6629 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6630
6631 if (!dest) {
6632 vty_out(vty, "%% Can't find static route specified\n");
6633 return CMD_WARNING_CONFIG_FAILED;
6634 }
6635
6636 bgp_static = bgp_dest_get_bgp_static_info(dest);
6637
6638 if ((label_index != BGP_INVALID_LABEL_INDEX)
6639 && (label_index != bgp_static->label_index)) {
6640 vty_out(vty,
6641 "%% label-index doesn't match static route\n");
6642 bgp_dest_unlock_node(dest);
6643 return CMD_WARNING_CONFIG_FAILED;
6644 }
6645
6646 if ((rmap && bgp_static->rmap.name)
6647 && strcmp(rmap, bgp_static->rmap.name)) {
6648 vty_out(vty,
6649 "%% route-map name doesn't match static route\n");
6650 bgp_dest_unlock_node(dest);
6651 return CMD_WARNING_CONFIG_FAILED;
6652 }
6653
6654 /* Update BGP RIB. */
6655 if (!bgp_static->backdoor)
6656 bgp_static_withdraw(bgp, &p, afi, safi);
6657
6658 /* Clear configuration. */
6659 bgp_static_free(bgp_static);
6660 bgp_dest_set_bgp_static_info(dest, NULL);
6661 bgp_dest_unlock_node(dest);
6662 bgp_dest_unlock_node(dest);
6663 } else {
6664
6665 /* Set BGP static route configuration. */
6666 dest = bgp_node_get(bgp->route[afi][safi], &p);
6667 bgp_static = bgp_dest_get_bgp_static_info(dest);
6668 if (bgp_static) {
6669 /* Configuration change. */
6670 /* Label index cannot be changed. */
6671 if (bgp_static->label_index != label_index) {
6672 vty_out(vty, "%% cannot change label-index\n");
6673 bgp_dest_unlock_node(dest);
6674 return CMD_WARNING_CONFIG_FAILED;
6675 }
6676
6677 /* Check previous routes are installed into BGP. */
6678 if (bgp_static->valid
6679 && bgp_static->backdoor != backdoor)
6680 need_update = 1;
6681
6682 bgp_static->backdoor = backdoor;
6683
6684 if (rmap) {
6685 XFREE(MTYPE_ROUTE_MAP_NAME,
6686 bgp_static->rmap.name);
6687 route_map_counter_decrement(
6688 bgp_static->rmap.map);
6689 bgp_static->rmap.name =
6690 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6691 bgp_static->rmap.map =
6692 route_map_lookup_by_name(rmap);
6693 route_map_counter_increment(
6694 bgp_static->rmap.map);
6695 } else {
6696 XFREE(MTYPE_ROUTE_MAP_NAME,
6697 bgp_static->rmap.name);
6698 route_map_counter_decrement(
6699 bgp_static->rmap.map);
6700 bgp_static->rmap.map = NULL;
6701 bgp_static->valid = 0;
6702 }
6703 bgp_dest_unlock_node(dest);
6704 } else {
6705 /* New configuration. */
6706 bgp_static = bgp_static_new();
6707 bgp_static->backdoor = backdoor;
6708 bgp_static->valid = 0;
6709 bgp_static->igpmetric = 0;
6710 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6711 bgp_static->label_index = label_index;
6712
6713 if (rmap) {
6714 XFREE(MTYPE_ROUTE_MAP_NAME,
6715 bgp_static->rmap.name);
6716 route_map_counter_decrement(
6717 bgp_static->rmap.map);
6718 bgp_static->rmap.name =
6719 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6720 bgp_static->rmap.map =
6721 route_map_lookup_by_name(rmap);
6722 route_map_counter_increment(
6723 bgp_static->rmap.map);
6724 }
6725 bgp_dest_set_bgp_static_info(dest, bgp_static);
6726 }
6727
6728 bgp_static->valid = 1;
6729 if (need_update)
6730 bgp_static_withdraw(bgp, &p, afi, safi);
6731
6732 if (!bgp_static->backdoor)
6733 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6734 }
6735
6736 return CMD_SUCCESS;
6737 }
6738
6739 void bgp_static_add(struct bgp *bgp)
6740 {
6741 afi_t afi;
6742 safi_t safi;
6743 struct bgp_dest *dest;
6744 struct bgp_dest *rm;
6745 struct bgp_table *table;
6746 struct bgp_static *bgp_static;
6747
6748 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6749 FOREACH_AFI_SAFI (afi, safi)
6750 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6751 dest = bgp_route_next(dest)) {
6752 if (!bgp_dest_has_bgp_path_info_data(dest))
6753 continue;
6754
6755 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6756 || (safi == SAFI_EVPN)) {
6757 table = bgp_dest_get_bgp_table_info(dest);
6758
6759 for (rm = bgp_table_top(table); rm;
6760 rm = bgp_route_next(rm)) {
6761 bgp_static =
6762 bgp_dest_get_bgp_static_info(
6763 rm);
6764 bgp_static_update_safi(
6765 bgp, bgp_dest_get_prefix(rm),
6766 bgp_static, afi, safi);
6767 }
6768 } else {
6769 bgp_static_update(
6770 bgp, bgp_dest_get_prefix(dest),
6771 bgp_dest_get_bgp_static_info(dest), afi,
6772 safi);
6773 }
6774 }
6775 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6776 }
6777
6778 /* Called from bgp_delete(). Delete all static routes from the BGP
6779 instance. */
6780 void bgp_static_delete(struct bgp *bgp)
6781 {
6782 afi_t afi;
6783 safi_t safi;
6784 struct bgp_dest *dest;
6785 struct bgp_dest *rm;
6786 struct bgp_table *table;
6787 struct bgp_static *bgp_static;
6788
6789 FOREACH_AFI_SAFI (afi, safi)
6790 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6791 dest = bgp_route_next(dest)) {
6792 if (!bgp_dest_has_bgp_path_info_data(dest))
6793 continue;
6794
6795 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6796 || (safi == SAFI_EVPN)) {
6797 table = bgp_dest_get_bgp_table_info(dest);
6798
6799 for (rm = bgp_table_top(table); rm;
6800 rm = bgp_route_next(rm)) {
6801 bgp_static =
6802 bgp_dest_get_bgp_static_info(
6803 rm);
6804 if (!bgp_static)
6805 continue;
6806
6807 bgp_static_withdraw_safi(
6808 bgp, bgp_dest_get_prefix(rm),
6809 AFI_IP, safi,
6810 (struct prefix_rd *)
6811 bgp_dest_get_prefix(
6812 dest));
6813 bgp_static_free(bgp_static);
6814 bgp_dest_set_bgp_static_info(rm,
6815 NULL);
6816 bgp_dest_unlock_node(rm);
6817 }
6818 } else {
6819 bgp_static = bgp_dest_get_bgp_static_info(dest);
6820 bgp_static_withdraw(bgp,
6821 bgp_dest_get_prefix(dest),
6822 afi, safi);
6823 bgp_static_free(bgp_static);
6824 bgp_dest_set_bgp_static_info(dest, NULL);
6825 bgp_dest_unlock_node(dest);
6826 }
6827 }
6828 }
6829
6830 void bgp_static_redo_import_check(struct bgp *bgp)
6831 {
6832 afi_t afi;
6833 safi_t safi;
6834 struct bgp_dest *dest;
6835 struct bgp_dest *rm;
6836 struct bgp_table *table;
6837 struct bgp_static *bgp_static;
6838
6839 /* Use this flag to force reprocessing of the route */
6840 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6841 FOREACH_AFI_SAFI (afi, safi) {
6842 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6843 dest = bgp_route_next(dest)) {
6844 if (!bgp_dest_has_bgp_path_info_data(dest))
6845 continue;
6846
6847 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6848 || (safi == SAFI_EVPN)) {
6849 table = bgp_dest_get_bgp_table_info(dest);
6850
6851 for (rm = bgp_table_top(table); rm;
6852 rm = bgp_route_next(rm)) {
6853 bgp_static =
6854 bgp_dest_get_bgp_static_info(
6855 rm);
6856 bgp_static_update_safi(
6857 bgp, bgp_dest_get_prefix(rm),
6858 bgp_static, afi, safi);
6859 }
6860 } else {
6861 bgp_static = bgp_dest_get_bgp_static_info(dest);
6862 bgp_static_update(bgp,
6863 bgp_dest_get_prefix(dest),
6864 bgp_static, afi, safi);
6865 }
6866 }
6867 }
6868 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6869 }
6870
6871 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6872 safi_t safi)
6873 {
6874 struct bgp_table *table;
6875 struct bgp_dest *dest;
6876 struct bgp_path_info *pi;
6877
6878 /* Do not install the aggregate route if BGP is in the
6879 * process of termination.
6880 */
6881 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6882 || (bgp->peer_self == NULL))
6883 return;
6884
6885 table = bgp->rib[afi][safi];
6886 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6887 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6888 if (pi->peer == bgp->peer_self
6889 && ((pi->type == ZEBRA_ROUTE_BGP
6890 && pi->sub_type == BGP_ROUTE_STATIC)
6891 || (pi->type != ZEBRA_ROUTE_BGP
6892 && pi->sub_type
6893 == BGP_ROUTE_REDISTRIBUTE))) {
6894 bgp_aggregate_decrement(
6895 bgp, bgp_dest_get_prefix(dest), pi, afi,
6896 safi);
6897 bgp_unlink_nexthop(pi);
6898 bgp_path_info_delete(dest, pi);
6899 bgp_process(bgp, dest, afi, safi);
6900 }
6901 }
6902 }
6903 }
6904
6905 /*
6906 * Purge all networks and redistributed routes from routing table.
6907 * Invoked upon the instance going down.
6908 */
6909 void bgp_purge_static_redist_routes(struct bgp *bgp)
6910 {
6911 afi_t afi;
6912 safi_t safi;
6913
6914 FOREACH_AFI_SAFI (afi, safi)
6915 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6916 }
6917
6918 /*
6919 * gpz 110624
6920 * Currently this is used to set static routes for VPN and ENCAP.
6921 * I think it can probably be factored with bgp_static_set.
6922 */
6923 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6924 const char *ip_str, const char *rd_str,
6925 const char *label_str, const char *rmap_str,
6926 int evpn_type, const char *esi, const char *gwip,
6927 const char *ethtag, const char *routermac)
6928 {
6929 VTY_DECLVAR_CONTEXT(bgp, bgp);
6930 int ret;
6931 struct prefix p;
6932 struct prefix_rd prd;
6933 struct bgp_dest *pdest;
6934 struct bgp_dest *dest;
6935 struct bgp_table *table;
6936 struct bgp_static *bgp_static;
6937 mpls_label_t label = MPLS_INVALID_LABEL;
6938 struct prefix gw_ip;
6939
6940 /* validate ip prefix */
6941 ret = str2prefix(ip_str, &p);
6942 if (!ret) {
6943 vty_out(vty, "%% Malformed prefix\n");
6944 return CMD_WARNING_CONFIG_FAILED;
6945 }
6946 apply_mask(&p);
6947 if ((afi == AFI_L2VPN)
6948 && (bgp_build_evpn_prefix(evpn_type,
6949 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6950 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6951 return CMD_WARNING_CONFIG_FAILED;
6952 }
6953
6954 ret = str2prefix_rd(rd_str, &prd);
6955 if (!ret) {
6956 vty_out(vty, "%% Malformed rd\n");
6957 return CMD_WARNING_CONFIG_FAILED;
6958 }
6959
6960 if (label_str) {
6961 unsigned long label_val;
6962 label_val = strtoul(label_str, NULL, 10);
6963 encode_label(label_val, &label);
6964 }
6965
6966 if (safi == SAFI_EVPN) {
6967 if (esi && str2esi(esi, NULL) == 0) {
6968 vty_out(vty, "%% Malformed ESI\n");
6969 return CMD_WARNING_CONFIG_FAILED;
6970 }
6971 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6972 vty_out(vty, "%% Malformed Router MAC\n");
6973 return CMD_WARNING_CONFIG_FAILED;
6974 }
6975 if (gwip) {
6976 memset(&gw_ip, 0, sizeof(gw_ip));
6977 ret = str2prefix(gwip, &gw_ip);
6978 if (!ret) {
6979 vty_out(vty, "%% Malformed GatewayIp\n");
6980 return CMD_WARNING_CONFIG_FAILED;
6981 }
6982 if ((gw_ip.family == AF_INET
6983 && is_evpn_prefix_ipaddr_v6(
6984 (struct prefix_evpn *)&p))
6985 || (gw_ip.family == AF_INET6
6986 && is_evpn_prefix_ipaddr_v4(
6987 (struct prefix_evpn *)&p))) {
6988 vty_out(vty,
6989 "%% GatewayIp family differs with IP prefix\n");
6990 return CMD_WARNING_CONFIG_FAILED;
6991 }
6992 }
6993 }
6994 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6995 if (!bgp_dest_has_bgp_path_info_data(pdest))
6996 bgp_dest_set_bgp_table_info(pdest,
6997 bgp_table_init(bgp, afi, safi));
6998 table = bgp_dest_get_bgp_table_info(pdest);
6999
7000 dest = bgp_node_get(table, &p);
7001
7002 if (bgp_dest_has_bgp_path_info_data(dest)) {
7003 vty_out(vty, "%% Same network configuration exists\n");
7004 bgp_dest_unlock_node(dest);
7005 } else {
7006 /* New configuration. */
7007 bgp_static = bgp_static_new();
7008 bgp_static->backdoor = 0;
7009 bgp_static->valid = 0;
7010 bgp_static->igpmetric = 0;
7011 bgp_static->igpnexthop.s_addr = INADDR_ANY;
7012 bgp_static->label = label;
7013 bgp_static->prd = prd;
7014
7015 if (rmap_str) {
7016 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
7017 route_map_counter_decrement(bgp_static->rmap.map);
7018 bgp_static->rmap.name =
7019 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
7020 bgp_static->rmap.map =
7021 route_map_lookup_by_name(rmap_str);
7022 route_map_counter_increment(bgp_static->rmap.map);
7023 }
7024
7025 if (safi == SAFI_EVPN) {
7026 if (esi) {
7027 bgp_static->eth_s_id =
7028 XCALLOC(MTYPE_ATTR,
7029 sizeof(esi_t));
7030 str2esi(esi, bgp_static->eth_s_id);
7031 }
7032 if (routermac) {
7033 bgp_static->router_mac =
7034 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
7035 (void)prefix_str2mac(routermac,
7036 bgp_static->router_mac);
7037 }
7038 if (gwip)
7039 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
7040 }
7041 bgp_dest_set_bgp_static_info(dest, bgp_static);
7042
7043 bgp_static->valid = 1;
7044 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
7045 }
7046
7047 return CMD_SUCCESS;
7048 }
7049
7050 /* Configure static BGP network. */
7051 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
7052 const char *ip_str, const char *rd_str,
7053 const char *label_str, int evpn_type, const char *esi,
7054 const char *gwip, const char *ethtag)
7055 {
7056 VTY_DECLVAR_CONTEXT(bgp, bgp);
7057 int ret;
7058 struct prefix p;
7059 struct prefix_rd prd;
7060 struct bgp_dest *pdest;
7061 struct bgp_dest *dest;
7062 struct bgp_table *table;
7063 struct bgp_static *bgp_static;
7064 mpls_label_t label = MPLS_INVALID_LABEL;
7065
7066 /* Convert IP prefix string to struct prefix. */
7067 ret = str2prefix(ip_str, &p);
7068 if (!ret) {
7069 vty_out(vty, "%% Malformed prefix\n");
7070 return CMD_WARNING_CONFIG_FAILED;
7071 }
7072 apply_mask(&p);
7073 if ((afi == AFI_L2VPN)
7074 && (bgp_build_evpn_prefix(evpn_type,
7075 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7076 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7077 return CMD_WARNING_CONFIG_FAILED;
7078 }
7079 ret = str2prefix_rd(rd_str, &prd);
7080 if (!ret) {
7081 vty_out(vty, "%% Malformed rd\n");
7082 return CMD_WARNING_CONFIG_FAILED;
7083 }
7084
7085 if (label_str) {
7086 unsigned long label_val;
7087 label_val = strtoul(label_str, NULL, 10);
7088 encode_label(label_val, &label);
7089 }
7090
7091 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7092 if (!bgp_dest_has_bgp_path_info_data(pdest))
7093 bgp_dest_set_bgp_table_info(pdest,
7094 bgp_table_init(bgp, afi, safi));
7095 else
7096 bgp_dest_unlock_node(pdest);
7097 table = bgp_dest_get_bgp_table_info(pdest);
7098
7099 dest = bgp_node_lookup(table, &p);
7100
7101 if (dest) {
7102 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
7103
7104 bgp_static = bgp_dest_get_bgp_static_info(dest);
7105 bgp_static_free(bgp_static);
7106 bgp_dest_set_bgp_static_info(dest, NULL);
7107 bgp_dest_unlock_node(dest);
7108 bgp_dest_unlock_node(dest);
7109 } else
7110 vty_out(vty, "%% Can't find the route\n");
7111
7112 return CMD_SUCCESS;
7113 }
7114
7115 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
7116 const char *rmap_name)
7117 {
7118 VTY_DECLVAR_CONTEXT(bgp, bgp);
7119 struct bgp_rmap *rmap;
7120
7121 rmap = &bgp->table_map[afi][safi];
7122 if (rmap_name) {
7123 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7124 route_map_counter_decrement(rmap->map);
7125 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
7126 rmap->map = route_map_lookup_by_name(rmap_name);
7127 route_map_counter_increment(rmap->map);
7128 } else {
7129 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7130 route_map_counter_decrement(rmap->map);
7131 rmap->map = NULL;
7132 }
7133
7134 if (bgp_fibupd_safi(safi))
7135 bgp_zebra_announce_table(bgp, afi, safi);
7136
7137 return CMD_SUCCESS;
7138 }
7139
7140 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
7141 const char *rmap_name)
7142 {
7143 VTY_DECLVAR_CONTEXT(bgp, bgp);
7144 struct bgp_rmap *rmap;
7145
7146 rmap = &bgp->table_map[afi][safi];
7147 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7148 route_map_counter_decrement(rmap->map);
7149 rmap->map = NULL;
7150
7151 if (bgp_fibupd_safi(safi))
7152 bgp_zebra_announce_table(bgp, afi, safi);
7153
7154 return CMD_SUCCESS;
7155 }
7156
7157 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
7158 safi_t safi)
7159 {
7160 if (bgp->table_map[afi][safi].name) {
7161 vty_out(vty, " table-map %s\n",
7162 bgp->table_map[afi][safi].name);
7163 }
7164 }
7165
7166 DEFUN (bgp_table_map,
7167 bgp_table_map_cmd,
7168 "table-map WORD",
7169 "BGP table to RIB route download filter\n"
7170 "Name of the route map\n")
7171 {
7172 int idx_word = 1;
7173 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7174 argv[idx_word]->arg);
7175 }
7176 DEFUN (no_bgp_table_map,
7177 no_bgp_table_map_cmd,
7178 "no table-map WORD",
7179 NO_STR
7180 "BGP table to RIB route download filter\n"
7181 "Name of the route map\n")
7182 {
7183 int idx_word = 2;
7184 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7185 argv[idx_word]->arg);
7186 }
7187
7188 DEFPY(bgp_network,
7189 bgp_network_cmd,
7190 "[no] network \
7191 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7192 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7193 backdoor$backdoor}]",
7194 NO_STR
7195 "Specify a network to announce via BGP\n"
7196 "IPv4 prefix\n"
7197 "Network number\n"
7198 "Network mask\n"
7199 "Network mask\n"
7200 "Route-map to modify the attributes\n"
7201 "Name of the route map\n"
7202 "Label index to associate with the prefix\n"
7203 "Label index value\n"
7204 "Specify a BGP backdoor route\n")
7205 {
7206 char addr_prefix_str[BUFSIZ];
7207
7208 if (address_str) {
7209 int ret;
7210
7211 ret = netmask_str2prefix_str(address_str, netmask_str,
7212 addr_prefix_str,
7213 sizeof(addr_prefix_str));
7214 if (!ret) {
7215 vty_out(vty, "%% Inconsistent address and mask\n");
7216 return CMD_WARNING_CONFIG_FAILED;
7217 }
7218 }
7219
7220 return bgp_static_set(
7221 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7222 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7223 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7224 }
7225
7226 DEFPY(ipv6_bgp_network,
7227 ipv6_bgp_network_cmd,
7228 "[no] network X:X::X:X/M$prefix \
7229 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7230 NO_STR
7231 "Specify a network to announce via BGP\n"
7232 "IPv6 prefix\n"
7233 "Route-map to modify the attributes\n"
7234 "Name of the route map\n"
7235 "Label index to associate with the prefix\n"
7236 "Label index value\n")
7237 {
7238 return bgp_static_set(
7239 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7240 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7241 }
7242
7243 static struct bgp_aggregate *bgp_aggregate_new(void)
7244 {
7245 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7246 }
7247
7248 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7249 {
7250 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7251 route_map_counter_decrement(aggregate->suppress_map);
7252 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7253 route_map_counter_decrement(aggregate->rmap.map);
7254 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7255 }
7256
7257 /**
7258 * Helper function to avoid repeated code: prepare variables for a
7259 * `route_map_apply` call.
7260 *
7261 * \returns `true` on route map match, otherwise `false`.
7262 */
7263 static bool aggr_suppress_map_test(struct bgp *bgp,
7264 struct bgp_aggregate *aggregate,
7265 struct bgp_path_info *pi)
7266 {
7267 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7268 route_map_result_t rmr = RMAP_DENYMATCH;
7269 struct bgp_path_info rmap_path = {};
7270 struct attr attr = {};
7271
7272 /* No route map entries created, just don't match. */
7273 if (aggregate->suppress_map == NULL)
7274 return false;
7275
7276 /* Call route map matching and return result. */
7277 attr.aspath = aspath_empty();
7278 rmap_path.peer = bgp->peer_self;
7279 rmap_path.attr = &attr;
7280
7281 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7282 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7283 bgp->peer_self->rmap_type = 0;
7284
7285 bgp_attr_flush(&attr);
7286 aspath_unintern(&attr.aspath);
7287
7288 return rmr == RMAP_PERMITMATCH;
7289 }
7290
7291 /** Test whether the aggregation has suppressed this path or not. */
7292 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7293 struct bgp_path_info *pi)
7294 {
7295 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7296 return false;
7297
7298 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7299 }
7300
7301 /**
7302 * Suppress this path and keep the reference.
7303 *
7304 * \returns `true` if needs processing otherwise `false`.
7305 */
7306 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7307 struct bgp_path_info *pi)
7308 {
7309 struct bgp_path_info_extra *pie;
7310
7311 /* Path is already suppressed by this aggregation. */
7312 if (aggr_suppress_exists(aggregate, pi))
7313 return false;
7314
7315 pie = bgp_path_info_extra_get(pi);
7316
7317 /* This is the first suppression, allocate memory and list it. */
7318 if (pie->aggr_suppressors == NULL)
7319 pie->aggr_suppressors = list_new();
7320
7321 listnode_add(pie->aggr_suppressors, aggregate);
7322
7323 /* Only mark for processing if suppressed. */
7324 if (listcount(pie->aggr_suppressors) == 1) {
7325 if (BGP_DEBUG(update, UPDATE_OUT))
7326 zlog_debug("aggregate-address suppressing: %pFX",
7327 bgp_dest_get_prefix(pi->net));
7328
7329 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7330 return true;
7331 }
7332
7333 return false;
7334 }
7335
7336 /**
7337 * Unsuppress this path and remove the reference.
7338 *
7339 * \returns `true` if needs processing otherwise `false`.
7340 */
7341 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7342 struct bgp_path_info *pi)
7343 {
7344 /* Path wasn't suppressed. */
7345 if (!aggr_suppress_exists(aggregate, pi))
7346 return false;
7347
7348 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7349
7350 /* Unsuppress and free extra memory if last item. */
7351 if (listcount(pi->extra->aggr_suppressors) == 0) {
7352 if (BGP_DEBUG(update, UPDATE_OUT))
7353 zlog_debug("aggregate-address unsuppressing: %pFX",
7354 bgp_dest_get_prefix(pi->net));
7355
7356 list_delete(&pi->extra->aggr_suppressors);
7357 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7358 return true;
7359 }
7360
7361 return false;
7362 }
7363
7364 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7365 struct aspath *aspath,
7366 struct community *comm,
7367 struct ecommunity *ecomm,
7368 struct lcommunity *lcomm)
7369 {
7370 static struct aspath *ae = NULL;
7371
7372 if (!ae)
7373 ae = aspath_empty();
7374
7375 if (!pi)
7376 return false;
7377
7378 if (origin != pi->attr->origin)
7379 return false;
7380
7381 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7382 return false;
7383
7384 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7385 return false;
7386
7387 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7388 return false;
7389
7390 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7391 return false;
7392
7393 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7394 return false;
7395
7396 return true;
7397 }
7398
7399 static void bgp_aggregate_install(
7400 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7401 uint8_t origin, struct aspath *aspath, struct community *community,
7402 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7403 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7404 {
7405 struct bgp_dest *dest;
7406 struct bgp_table *table;
7407 struct bgp_path_info *pi, *orig, *new;
7408 struct attr *attr;
7409
7410 table = bgp->rib[afi][safi];
7411
7412 dest = bgp_node_get(table, p);
7413
7414 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7415 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7416 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7417 break;
7418
7419 /*
7420 * If we have paths with different MEDs, then don't install
7421 * (or uninstall) the aggregate route.
7422 */
7423 if (aggregate->match_med && aggregate->med_mismatched)
7424 goto uninstall_aggregate_route;
7425
7426 if (aggregate->count > 0) {
7427 /*
7428 * If the aggregate information has not changed
7429 * no need to re-install it again.
7430 */
7431 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7432 ecommunity, lcommunity)) {
7433 bgp_dest_unlock_node(dest);
7434
7435 if (aspath)
7436 aspath_free(aspath);
7437 if (community)
7438 community_free(&community);
7439 if (ecommunity)
7440 ecommunity_free(&ecommunity);
7441 if (lcommunity)
7442 lcommunity_free(&lcommunity);
7443
7444 return;
7445 }
7446
7447 /*
7448 * Mark the old as unusable
7449 */
7450 if (pi)
7451 bgp_path_info_delete(dest, pi);
7452
7453 attr = bgp_attr_aggregate_intern(
7454 bgp, origin, aspath, community, ecommunity, lcommunity,
7455 aggregate, atomic_aggregate, p);
7456
7457 if (!attr) {
7458 bgp_dest_unlock_node(dest);
7459 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7460 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7461 zlog_debug("%s: %pFX null attribute", __func__,
7462 p);
7463 return;
7464 }
7465
7466 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7467 bgp->peer_self, attr, dest);
7468
7469 SET_FLAG(new->flags, BGP_PATH_VALID);
7470
7471 bgp_path_info_add(dest, new);
7472 bgp_process(bgp, dest, afi, safi);
7473 } else {
7474 uninstall_aggregate_route:
7475 for (pi = orig; pi; pi = pi->next)
7476 if (pi->peer == bgp->peer_self
7477 && pi->type == ZEBRA_ROUTE_BGP
7478 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7479 break;
7480
7481 /* Withdraw static BGP route from routing table. */
7482 if (pi) {
7483 bgp_path_info_delete(dest, pi);
7484 bgp_process(bgp, dest, afi, safi);
7485 }
7486 }
7487
7488 bgp_dest_unlock_node(dest);
7489 }
7490
7491 /**
7492 * Check if the current path has different MED than other known paths.
7493 *
7494 * \returns `true` if the MED matched the others else `false`.
7495 */
7496 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7497 struct bgp *bgp, struct bgp_path_info *pi)
7498 {
7499 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7500
7501 /* This is the first route being analyzed. */
7502 if (!aggregate->med_initialized) {
7503 aggregate->med_initialized = true;
7504 aggregate->med_mismatched = false;
7505 aggregate->med_matched_value = cur_med;
7506 } else {
7507 /* Check if routes with different MED showed up. */
7508 if (cur_med != aggregate->med_matched_value)
7509 aggregate->med_mismatched = true;
7510 }
7511
7512 return !aggregate->med_mismatched;
7513 }
7514
7515 /**
7516 * Initializes and tests all routes in the aggregate address path for MED
7517 * values.
7518 *
7519 * \returns `true` if all MEDs are the same otherwise `false`.
7520 */
7521 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7522 struct bgp *bgp, const struct prefix *p,
7523 afi_t afi, safi_t safi)
7524 {
7525 struct bgp_table *table = bgp->rib[afi][safi];
7526 const struct prefix *dest_p;
7527 struct bgp_dest *dest, *top;
7528 struct bgp_path_info *pi;
7529 bool med_matched = true;
7530
7531 aggregate->med_initialized = false;
7532
7533 top = bgp_node_get(table, p);
7534 for (dest = bgp_node_get(table, p); dest;
7535 dest = bgp_route_next_until(dest, top)) {
7536 dest_p = bgp_dest_get_prefix(dest);
7537 if (dest_p->prefixlen <= p->prefixlen)
7538 continue;
7539
7540 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7541 if (BGP_PATH_HOLDDOWN(pi))
7542 continue;
7543 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7544 continue;
7545 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7546 med_matched = false;
7547 break;
7548 }
7549 }
7550 if (!med_matched)
7551 break;
7552 }
7553 bgp_dest_unlock_node(top);
7554
7555 return med_matched;
7556 }
7557
7558 /**
7559 * Toggles the route suppression status for this aggregate address
7560 * configuration.
7561 */
7562 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7563 struct bgp *bgp, const struct prefix *p,
7564 afi_t afi, safi_t safi, bool suppress)
7565 {
7566 struct bgp_table *table = bgp->rib[afi][safi];
7567 const struct prefix *dest_p;
7568 struct bgp_dest *dest, *top;
7569 struct bgp_path_info *pi;
7570 bool toggle_suppression;
7571
7572 /* We've found a different MED we must revert any suppressed routes. */
7573 top = bgp_node_get(table, p);
7574 for (dest = bgp_node_get(table, p); dest;
7575 dest = bgp_route_next_until(dest, top)) {
7576 dest_p = bgp_dest_get_prefix(dest);
7577 if (dest_p->prefixlen <= p->prefixlen)
7578 continue;
7579
7580 toggle_suppression = false;
7581 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7582 if (BGP_PATH_HOLDDOWN(pi))
7583 continue;
7584 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7585 continue;
7586
7587 /* We are toggling suppression back. */
7588 if (suppress) {
7589 /* Suppress route if not suppressed already. */
7590 if (aggr_suppress_path(aggregate, pi))
7591 toggle_suppression = true;
7592 continue;
7593 }
7594
7595 /* Install route if there is no more suppression. */
7596 if (aggr_unsuppress_path(aggregate, pi))
7597 toggle_suppression = true;
7598 }
7599
7600 if (toggle_suppression)
7601 bgp_process(bgp, dest, afi, safi);
7602 }
7603 bgp_dest_unlock_node(top);
7604 }
7605
7606 /**
7607 * Aggregate address MED matching incremental test: this function is called
7608 * when the initial aggregation occurred and we are only testing a single
7609 * new path.
7610 *
7611 * In addition to testing and setting the MED validity it also installs back
7612 * suppressed routes (if summary is configured).
7613 *
7614 * Must not be called in `bgp_aggregate_route`.
7615 */
7616 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7617 struct bgp *bgp, const struct prefix *p,
7618 afi_t afi, safi_t safi,
7619 struct bgp_path_info *pi)
7620 {
7621 /* MED matching disabled. */
7622 if (!aggregate->match_med)
7623 return;
7624
7625 /* Aggregation with different MED, recheck if we have got equal MEDs
7626 * now.
7627 */
7628 if (aggregate->med_mismatched &&
7629 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7630 aggregate->summary_only)
7631 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7632 true);
7633 else
7634 bgp_aggregate_med_match(aggregate, bgp, pi);
7635
7636 /* No mismatches, just quit. */
7637 if (!aggregate->med_mismatched)
7638 return;
7639
7640 /* Route summarization is disabled. */
7641 if (!aggregate->summary_only)
7642 return;
7643
7644 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7645 }
7646
7647 /* Update an aggregate as routes are added/removed from the BGP table */
7648 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7649 safi_t safi, struct bgp_aggregate *aggregate)
7650 {
7651 struct bgp_table *table;
7652 struct bgp_dest *top;
7653 struct bgp_dest *dest;
7654 uint8_t origin;
7655 struct aspath *aspath = NULL;
7656 struct community *community = NULL;
7657 struct ecommunity *ecommunity = NULL;
7658 struct lcommunity *lcommunity = NULL;
7659 struct bgp_path_info *pi;
7660 unsigned long match = 0;
7661 uint8_t atomic_aggregate = 0;
7662
7663 /* If the bgp instance is being deleted or self peer is deleted
7664 * then do not create aggregate route
7665 */
7666 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7667 || (bgp->peer_self == NULL))
7668 return;
7669
7670 /* Initialize and test routes for MED difference. */
7671 if (aggregate->match_med)
7672 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7673
7674 /*
7675 * Reset aggregate count: we might've been called from route map
7676 * update so in that case we must retest all more specific routes.
7677 *
7678 * \see `bgp_route_map_process_update`.
7679 */
7680 aggregate->count = 0;
7681 aggregate->incomplete_origin_count = 0;
7682 aggregate->incomplete_origin_count = 0;
7683 aggregate->egp_origin_count = 0;
7684
7685 /* ORIGIN attribute: If at least one route among routes that are
7686 aggregated has ORIGIN with the value INCOMPLETE, then the
7687 aggregated route must have the ORIGIN attribute with the value
7688 INCOMPLETE. Otherwise, if at least one route among routes that
7689 are aggregated has ORIGIN with the value EGP, then the aggregated
7690 route must have the origin attribute with the value EGP. In all
7691 other case the value of the ORIGIN attribute of the aggregated
7692 route is INTERNAL. */
7693 origin = BGP_ORIGIN_IGP;
7694
7695 table = bgp->rib[afi][safi];
7696
7697 top = bgp_node_get(table, p);
7698 for (dest = bgp_node_get(table, p); dest;
7699 dest = bgp_route_next_until(dest, top)) {
7700 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7701
7702 if (dest_p->prefixlen <= p->prefixlen)
7703 continue;
7704
7705 /* If suppress fib is enabled and route not installed
7706 * in FIB, skip the route
7707 */
7708 if (!bgp_check_advertise(bgp, dest))
7709 continue;
7710
7711 match = 0;
7712
7713 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7714 if (BGP_PATH_HOLDDOWN(pi))
7715 continue;
7716
7717 if (pi->attr->flag
7718 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7719 atomic_aggregate = 1;
7720
7721 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7722 continue;
7723
7724 /*
7725 * summary-only aggregate route suppress
7726 * aggregated route announcements.
7727 *
7728 * MED matching:
7729 * Don't create summaries if MED didn't match
7730 * otherwise neither the specific routes and the
7731 * aggregation will be announced.
7732 */
7733 if (aggregate->summary_only
7734 && AGGREGATE_MED_VALID(aggregate)) {
7735 if (aggr_suppress_path(aggregate, pi))
7736 match++;
7737 }
7738
7739 /*
7740 * Suppress more specific routes that match the route
7741 * map results.
7742 *
7743 * MED matching:
7744 * Don't suppress routes if MED matching is enabled and
7745 * it mismatched otherwise we might end up with no
7746 * routes for this path.
7747 */
7748 if (aggregate->suppress_map_name
7749 && AGGREGATE_MED_VALID(aggregate)
7750 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7751 if (aggr_suppress_path(aggregate, pi))
7752 match++;
7753 }
7754
7755 aggregate->count++;
7756
7757 /*
7758 * If at least one route among routes that are
7759 * aggregated has ORIGIN with the value INCOMPLETE,
7760 * then the aggregated route MUST have the ORIGIN
7761 * attribute with the value INCOMPLETE. Otherwise, if
7762 * at least one route among routes that are aggregated
7763 * has ORIGIN with the value EGP, then the aggregated
7764 * route MUST have the ORIGIN attribute with the value
7765 * EGP.
7766 */
7767 switch (pi->attr->origin) {
7768 case BGP_ORIGIN_INCOMPLETE:
7769 aggregate->incomplete_origin_count++;
7770 break;
7771 case BGP_ORIGIN_EGP:
7772 aggregate->egp_origin_count++;
7773 break;
7774 default:
7775 /*Do nothing.
7776 */
7777 break;
7778 }
7779
7780 if (!aggregate->as_set)
7781 continue;
7782
7783 /*
7784 * as-set aggregate route generate origin, as path,
7785 * and community aggregation.
7786 */
7787 /* Compute aggregate route's as-path.
7788 */
7789 bgp_compute_aggregate_aspath_hash(aggregate,
7790 pi->attr->aspath);
7791
7792 /* Compute aggregate route's community.
7793 */
7794 if (bgp_attr_get_community(pi->attr))
7795 bgp_compute_aggregate_community_hash(
7796 aggregate,
7797 bgp_attr_get_community(pi->attr));
7798
7799 /* Compute aggregate route's extended community.
7800 */
7801 if (bgp_attr_get_ecommunity(pi->attr))
7802 bgp_compute_aggregate_ecommunity_hash(
7803 aggregate,
7804 bgp_attr_get_ecommunity(pi->attr));
7805
7806 /* Compute aggregate route's large community.
7807 */
7808 if (bgp_attr_get_lcommunity(pi->attr))
7809 bgp_compute_aggregate_lcommunity_hash(
7810 aggregate,
7811 bgp_attr_get_lcommunity(pi->attr));
7812 }
7813 if (match)
7814 bgp_process(bgp, dest, afi, safi);
7815 }
7816 if (aggregate->as_set) {
7817 bgp_compute_aggregate_aspath_val(aggregate);
7818 bgp_compute_aggregate_community_val(aggregate);
7819 bgp_compute_aggregate_ecommunity_val(aggregate);
7820 bgp_compute_aggregate_lcommunity_val(aggregate);
7821 }
7822
7823
7824 bgp_dest_unlock_node(top);
7825
7826
7827 if (aggregate->incomplete_origin_count > 0)
7828 origin = BGP_ORIGIN_INCOMPLETE;
7829 else if (aggregate->egp_origin_count > 0)
7830 origin = BGP_ORIGIN_EGP;
7831
7832 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7833 origin = aggregate->origin;
7834
7835 if (aggregate->as_set) {
7836 if (aggregate->aspath)
7837 /* Retrieve aggregate route's as-path.
7838 */
7839 aspath = aspath_dup(aggregate->aspath);
7840
7841 if (aggregate->community)
7842 /* Retrieve aggregate route's community.
7843 */
7844 community = community_dup(aggregate->community);
7845
7846 if (aggregate->ecommunity)
7847 /* Retrieve aggregate route's ecommunity.
7848 */
7849 ecommunity = ecommunity_dup(aggregate->ecommunity);
7850
7851 if (aggregate->lcommunity)
7852 /* Retrieve aggregate route's lcommunity.
7853 */
7854 lcommunity = lcommunity_dup(aggregate->lcommunity);
7855 }
7856
7857 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7858 ecommunity, lcommunity, atomic_aggregate,
7859 aggregate);
7860 }
7861
7862 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7863 safi_t safi, struct bgp_aggregate *aggregate)
7864 {
7865 struct bgp_table *table;
7866 struct bgp_dest *top;
7867 struct bgp_dest *dest;
7868 struct bgp_path_info *pi;
7869 unsigned long match;
7870
7871 table = bgp->rib[afi][safi];
7872
7873 /* If routes exists below this node, generate aggregate routes. */
7874 top = bgp_node_get(table, p);
7875 for (dest = bgp_node_get(table, p); dest;
7876 dest = bgp_route_next_until(dest, top)) {
7877 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7878
7879 if (dest_p->prefixlen <= p->prefixlen)
7880 continue;
7881 match = 0;
7882
7883 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7884 if (BGP_PATH_HOLDDOWN(pi))
7885 continue;
7886
7887 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7888 continue;
7889
7890 /*
7891 * This route is suppressed: attempt to unsuppress it.
7892 *
7893 * `aggr_unsuppress_path` will fail if this particular
7894 * aggregate route was not the suppressor.
7895 */
7896 if (pi->extra && pi->extra->aggr_suppressors &&
7897 listcount(pi->extra->aggr_suppressors)) {
7898 if (aggr_unsuppress_path(aggregate, pi))
7899 match++;
7900 }
7901
7902 aggregate->count--;
7903
7904 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7905 aggregate->incomplete_origin_count--;
7906 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7907 aggregate->egp_origin_count--;
7908
7909 if (aggregate->as_set) {
7910 /* Remove as-path from aggregate.
7911 */
7912 bgp_remove_aspath_from_aggregate_hash(
7913 aggregate,
7914 pi->attr->aspath);
7915
7916 if (bgp_attr_get_community(pi->attr))
7917 /* Remove community from aggregate.
7918 */
7919 bgp_remove_comm_from_aggregate_hash(
7920 aggregate,
7921 bgp_attr_get_community(
7922 pi->attr));
7923
7924 if (bgp_attr_get_ecommunity(pi->attr))
7925 /* Remove ecommunity from aggregate.
7926 */
7927 bgp_remove_ecomm_from_aggregate_hash(
7928 aggregate,
7929 bgp_attr_get_ecommunity(
7930 pi->attr));
7931
7932 if (bgp_attr_get_lcommunity(pi->attr))
7933 /* Remove lcommunity from aggregate.
7934 */
7935 bgp_remove_lcomm_from_aggregate_hash(
7936 aggregate,
7937 bgp_attr_get_lcommunity(
7938 pi->attr));
7939 }
7940 }
7941
7942 /* If this node was suppressed, process the change. */
7943 if (match)
7944 bgp_process(bgp, dest, afi, safi);
7945 }
7946 if (aggregate->as_set) {
7947 aspath_free(aggregate->aspath);
7948 aggregate->aspath = NULL;
7949 if (aggregate->community)
7950 community_free(&aggregate->community);
7951 if (aggregate->ecommunity)
7952 ecommunity_free(&aggregate->ecommunity);
7953 if (aggregate->lcommunity)
7954 lcommunity_free(&aggregate->lcommunity);
7955 }
7956
7957 bgp_dest_unlock_node(top);
7958 }
7959
7960 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7961 const struct prefix *aggr_p,
7962 struct bgp_path_info *pinew, afi_t afi,
7963 safi_t safi,
7964 struct bgp_aggregate *aggregate)
7965 {
7966 uint8_t origin;
7967 struct aspath *aspath = NULL;
7968 uint8_t atomic_aggregate = 0;
7969 struct community *community = NULL;
7970 struct ecommunity *ecommunity = NULL;
7971 struct lcommunity *lcommunity = NULL;
7972
7973 /* If the bgp instance is being deleted or self peer is deleted
7974 * then do not create aggregate route
7975 */
7976 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7977 || (bgp->peer_self == NULL))
7978 return;
7979
7980 /* ORIGIN attribute: If at least one route among routes that are
7981 * aggregated has ORIGIN with the value INCOMPLETE, then the
7982 * aggregated route must have the ORIGIN attribute with the value
7983 * INCOMPLETE. Otherwise, if at least one route among routes that
7984 * are aggregated has ORIGIN with the value EGP, then the aggregated
7985 * route must have the origin attribute with the value EGP. In all
7986 * other case the value of the ORIGIN attribute of the aggregated
7987 * route is INTERNAL.
7988 */
7989 origin = BGP_ORIGIN_IGP;
7990
7991 aggregate->count++;
7992
7993 /*
7994 * This must be called before `summary` check to avoid
7995 * "suppressing" twice.
7996 */
7997 if (aggregate->match_med)
7998 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
7999 pinew);
8000
8001 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8002 aggr_suppress_path(aggregate, pinew);
8003
8004 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8005 && aggr_suppress_map_test(bgp, aggregate, pinew))
8006 aggr_suppress_path(aggregate, pinew);
8007
8008 switch (pinew->attr->origin) {
8009 case BGP_ORIGIN_INCOMPLETE:
8010 aggregate->incomplete_origin_count++;
8011 break;
8012 case BGP_ORIGIN_EGP:
8013 aggregate->egp_origin_count++;
8014 break;
8015 default:
8016 /* Do nothing.
8017 */
8018 break;
8019 }
8020
8021 if (aggregate->incomplete_origin_count > 0)
8022 origin = BGP_ORIGIN_INCOMPLETE;
8023 else if (aggregate->egp_origin_count > 0)
8024 origin = BGP_ORIGIN_EGP;
8025
8026 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8027 origin = aggregate->origin;
8028
8029 if (aggregate->as_set) {
8030 /* Compute aggregate route's as-path.
8031 */
8032 bgp_compute_aggregate_aspath(aggregate,
8033 pinew->attr->aspath);
8034
8035 /* Compute aggregate route's community.
8036 */
8037 if (bgp_attr_get_community(pinew->attr))
8038 bgp_compute_aggregate_community(
8039 aggregate, bgp_attr_get_community(pinew->attr));
8040
8041 /* Compute aggregate route's extended community.
8042 */
8043 if (bgp_attr_get_ecommunity(pinew->attr))
8044 bgp_compute_aggregate_ecommunity(
8045 aggregate,
8046 bgp_attr_get_ecommunity(pinew->attr));
8047
8048 /* Compute aggregate route's large community.
8049 */
8050 if (bgp_attr_get_lcommunity(pinew->attr))
8051 bgp_compute_aggregate_lcommunity(
8052 aggregate,
8053 bgp_attr_get_lcommunity(pinew->attr));
8054
8055 /* Retrieve aggregate route's as-path.
8056 */
8057 if (aggregate->aspath)
8058 aspath = aspath_dup(aggregate->aspath);
8059
8060 /* Retrieve aggregate route's community.
8061 */
8062 if (aggregate->community)
8063 community = community_dup(aggregate->community);
8064
8065 /* Retrieve aggregate route's ecommunity.
8066 */
8067 if (aggregate->ecommunity)
8068 ecommunity = ecommunity_dup(aggregate->ecommunity);
8069
8070 /* Retrieve aggregate route's lcommunity.
8071 */
8072 if (aggregate->lcommunity)
8073 lcommunity = lcommunity_dup(aggregate->lcommunity);
8074 }
8075
8076 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8077 aspath, community, ecommunity,
8078 lcommunity, atomic_aggregate, aggregate);
8079 }
8080
8081 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
8082 safi_t safi,
8083 struct bgp_path_info *pi,
8084 struct bgp_aggregate *aggregate,
8085 const struct prefix *aggr_p)
8086 {
8087 uint8_t origin;
8088 struct aspath *aspath = NULL;
8089 uint8_t atomic_aggregate = 0;
8090 struct community *community = NULL;
8091 struct ecommunity *ecommunity = NULL;
8092 struct lcommunity *lcommunity = NULL;
8093 unsigned long match = 0;
8094
8095 /* If the bgp instance is being deleted or self peer is deleted
8096 * then do not create aggregate route
8097 */
8098 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8099 || (bgp->peer_self == NULL))
8100 return;
8101
8102 if (BGP_PATH_HOLDDOWN(pi))
8103 return;
8104
8105 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
8106 return;
8107
8108 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8109 if (aggr_unsuppress_path(aggregate, pi))
8110 match++;
8111
8112 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8113 && aggr_suppress_map_test(bgp, aggregate, pi))
8114 if (aggr_unsuppress_path(aggregate, pi))
8115 match++;
8116
8117 /*
8118 * This must be called after `summary`, `suppress-map` check to avoid
8119 * "unsuppressing" twice.
8120 */
8121 if (aggregate->match_med)
8122 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
8123
8124 if (aggregate->count > 0)
8125 aggregate->count--;
8126
8127 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
8128 aggregate->incomplete_origin_count--;
8129 else if (pi->attr->origin == BGP_ORIGIN_EGP)
8130 aggregate->egp_origin_count--;
8131
8132 if (aggregate->as_set) {
8133 /* Remove as-path from aggregate.
8134 */
8135 bgp_remove_aspath_from_aggregate(aggregate,
8136 pi->attr->aspath);
8137
8138 if (bgp_attr_get_community(pi->attr))
8139 /* Remove community from aggregate.
8140 */
8141 bgp_remove_community_from_aggregate(
8142 aggregate, bgp_attr_get_community(pi->attr));
8143
8144 if (bgp_attr_get_ecommunity(pi->attr))
8145 /* Remove ecommunity from aggregate.
8146 */
8147 bgp_remove_ecommunity_from_aggregate(
8148 aggregate, bgp_attr_get_ecommunity(pi->attr));
8149
8150 if (bgp_attr_get_lcommunity(pi->attr))
8151 /* Remove lcommunity from aggregate.
8152 */
8153 bgp_remove_lcommunity_from_aggregate(
8154 aggregate, bgp_attr_get_lcommunity(pi->attr));
8155 }
8156
8157 /* If this node was suppressed, process the change. */
8158 if (match)
8159 bgp_process(bgp, pi->net, afi, safi);
8160
8161 origin = BGP_ORIGIN_IGP;
8162 if (aggregate->incomplete_origin_count > 0)
8163 origin = BGP_ORIGIN_INCOMPLETE;
8164 else if (aggregate->egp_origin_count > 0)
8165 origin = BGP_ORIGIN_EGP;
8166
8167 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8168 origin = aggregate->origin;
8169
8170 if (aggregate->as_set) {
8171 /* Retrieve aggregate route's as-path.
8172 */
8173 if (aggregate->aspath)
8174 aspath = aspath_dup(aggregate->aspath);
8175
8176 /* Retrieve aggregate route's community.
8177 */
8178 if (aggregate->community)
8179 community = community_dup(aggregate->community);
8180
8181 /* Retrieve aggregate route's ecommunity.
8182 */
8183 if (aggregate->ecommunity)
8184 ecommunity = ecommunity_dup(aggregate->ecommunity);
8185
8186 /* Retrieve aggregate route's lcommunity.
8187 */
8188 if (aggregate->lcommunity)
8189 lcommunity = lcommunity_dup(aggregate->lcommunity);
8190 }
8191
8192 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8193 aspath, community, ecommunity,
8194 lcommunity, atomic_aggregate, aggregate);
8195 }
8196
8197 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8198 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8199 {
8200 struct bgp_dest *child;
8201 struct bgp_dest *dest;
8202 struct bgp_aggregate *aggregate;
8203 struct bgp_table *table;
8204
8205 table = bgp->aggregate[afi][safi];
8206
8207 /* No aggregates configured. */
8208 if (bgp_table_top_nolock(table) == NULL)
8209 return;
8210
8211 if (p->prefixlen == 0)
8212 return;
8213
8214 if (BGP_PATH_HOLDDOWN(pi))
8215 return;
8216
8217 /* If suppress fib is enabled and route not installed
8218 * in FIB, do not update the aggregate route
8219 */
8220 if (!bgp_check_advertise(bgp, pi->net))
8221 return;
8222
8223 child = bgp_node_get(table, p);
8224
8225 /* Aggregate address configuration check. */
8226 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8227 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8228
8229 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8230 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8231 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8232 aggregate);
8233 }
8234 }
8235 bgp_dest_unlock_node(child);
8236 }
8237
8238 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8239 struct bgp_path_info *del, afi_t afi, safi_t safi)
8240 {
8241 struct bgp_dest *child;
8242 struct bgp_dest *dest;
8243 struct bgp_aggregate *aggregate;
8244 struct bgp_table *table;
8245
8246 table = bgp->aggregate[afi][safi];
8247
8248 /* No aggregates configured. */
8249 if (bgp_table_top_nolock(table) == NULL)
8250 return;
8251
8252 if (p->prefixlen == 0)
8253 return;
8254
8255 child = bgp_node_get(table, p);
8256
8257 /* Aggregate address configuration check. */
8258 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8259 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8260
8261 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8262 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8263 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8264 aggregate, dest_p);
8265 }
8266 }
8267 bgp_dest_unlock_node(child);
8268 }
8269
8270 /* Aggregate route attribute. */
8271 #define AGGREGATE_SUMMARY_ONLY 1
8272 #define AGGREGATE_AS_SET 1
8273 #define AGGREGATE_AS_UNSET 0
8274
8275 static const char *bgp_origin2str(uint8_t origin)
8276 {
8277 switch (origin) {
8278 case BGP_ORIGIN_IGP:
8279 return "igp";
8280 case BGP_ORIGIN_EGP:
8281 return "egp";
8282 case BGP_ORIGIN_INCOMPLETE:
8283 return "incomplete";
8284 }
8285 return "n/a";
8286 }
8287
8288 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8289 {
8290 switch (v_state) {
8291 case RPKI_NOT_BEING_USED:
8292 return "not used";
8293 case RPKI_VALID:
8294 return "valid";
8295 case RPKI_NOTFOUND:
8296 return "not found";
8297 case RPKI_INVALID:
8298 return "invalid";
8299 }
8300
8301 assert(!"We should never get here this is a dev escape");
8302 return "ERROR";
8303 }
8304
8305 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8306 afi_t afi, safi_t safi)
8307 {
8308 VTY_DECLVAR_CONTEXT(bgp, bgp);
8309 int ret;
8310 struct prefix p;
8311 struct bgp_dest *dest;
8312 struct bgp_aggregate *aggregate;
8313
8314 /* Convert string to prefix structure. */
8315 ret = str2prefix(prefix_str, &p);
8316 if (!ret) {
8317 vty_out(vty, "Malformed prefix\n");
8318 return CMD_WARNING_CONFIG_FAILED;
8319 }
8320 apply_mask(&p);
8321
8322 /* Old configuration check. */
8323 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8324 if (!dest) {
8325 vty_out(vty,
8326 "%% There is no aggregate-address configuration.\n");
8327 return CMD_WARNING_CONFIG_FAILED;
8328 }
8329
8330 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8331 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8332 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8333 NULL, NULL, 0, aggregate);
8334
8335 /* Unlock aggregate address configuration. */
8336 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8337
8338 if (aggregate->community)
8339 community_free(&aggregate->community);
8340
8341 if (aggregate->community_hash) {
8342 /* Delete all communities in the hash.
8343 */
8344 hash_clean(aggregate->community_hash,
8345 bgp_aggr_community_remove);
8346 /* Free up the community_hash.
8347 */
8348 hash_free(aggregate->community_hash);
8349 }
8350
8351 if (aggregate->ecommunity)
8352 ecommunity_free(&aggregate->ecommunity);
8353
8354 if (aggregate->ecommunity_hash) {
8355 /* Delete all ecommunities in the hash.
8356 */
8357 hash_clean(aggregate->ecommunity_hash,
8358 bgp_aggr_ecommunity_remove);
8359 /* Free up the ecommunity_hash.
8360 */
8361 hash_free(aggregate->ecommunity_hash);
8362 }
8363
8364 if (aggregate->lcommunity)
8365 lcommunity_free(&aggregate->lcommunity);
8366
8367 if (aggregate->lcommunity_hash) {
8368 /* Delete all lcommunities in the hash.
8369 */
8370 hash_clean(aggregate->lcommunity_hash,
8371 bgp_aggr_lcommunity_remove);
8372 /* Free up the lcommunity_hash.
8373 */
8374 hash_free(aggregate->lcommunity_hash);
8375 }
8376
8377 if (aggregate->aspath)
8378 aspath_free(aggregate->aspath);
8379
8380 if (aggregate->aspath_hash) {
8381 /* Delete all as-paths in the hash.
8382 */
8383 hash_clean(aggregate->aspath_hash,
8384 bgp_aggr_aspath_remove);
8385 /* Free up the aspath_hash.
8386 */
8387 hash_free(aggregate->aspath_hash);
8388 }
8389
8390 bgp_aggregate_free(aggregate);
8391 bgp_dest_unlock_node(dest);
8392 bgp_dest_unlock_node(dest);
8393
8394 return CMD_SUCCESS;
8395 }
8396
8397 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8398 safi_t safi, const char *rmap,
8399 uint8_t summary_only, uint8_t as_set,
8400 uint8_t origin, bool match_med,
8401 const char *suppress_map)
8402 {
8403 VTY_DECLVAR_CONTEXT(bgp, bgp);
8404 int ret;
8405 struct prefix p;
8406 struct bgp_dest *dest;
8407 struct bgp_aggregate *aggregate;
8408 uint8_t as_set_new = as_set;
8409
8410 if (suppress_map && summary_only) {
8411 vty_out(vty,
8412 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8413 return CMD_WARNING_CONFIG_FAILED;
8414 }
8415
8416 /* Convert string to prefix structure. */
8417 ret = str2prefix(prefix_str, &p);
8418 if (!ret) {
8419 vty_out(vty, "Malformed prefix\n");
8420 return CMD_WARNING_CONFIG_FAILED;
8421 }
8422 apply_mask(&p);
8423
8424 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8425 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8426 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8427 prefix_str);
8428 return CMD_WARNING_CONFIG_FAILED;
8429 }
8430
8431 /* Old configuration check. */
8432 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8433 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8434
8435 if (aggregate) {
8436 vty_out(vty, "There is already same aggregate network.\n");
8437 /* try to remove the old entry */
8438 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8439 if (ret) {
8440 vty_out(vty, "Error deleting aggregate.\n");
8441 bgp_dest_unlock_node(dest);
8442 return CMD_WARNING_CONFIG_FAILED;
8443 }
8444 }
8445
8446 /* Make aggregate address structure. */
8447 aggregate = bgp_aggregate_new();
8448 aggregate->summary_only = summary_only;
8449 aggregate->match_med = match_med;
8450
8451 /* Network operators MUST NOT locally generate any new
8452 * announcements containing AS_SET or AS_CONFED_SET. If they have
8453 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8454 * SHOULD withdraw those routes and re-announce routes for the
8455 * aggregate or component prefixes (i.e., the more-specific routes
8456 * subsumed by the previously aggregated route) without AS_SET
8457 * or AS_CONFED_SET in the updates.
8458 */
8459 if (bgp->reject_as_sets) {
8460 if (as_set == AGGREGATE_AS_SET) {
8461 as_set_new = AGGREGATE_AS_UNSET;
8462 zlog_warn(
8463 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8464 __func__);
8465 vty_out(vty,
8466 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8467 }
8468 }
8469
8470 aggregate->as_set = as_set_new;
8471 aggregate->safi = safi;
8472 /* Override ORIGIN attribute if defined.
8473 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8474 * to IGP which is not what rfc4271 says.
8475 * This enables the same behavior, optionally.
8476 */
8477 aggregate->origin = origin;
8478
8479 if (rmap) {
8480 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8481 route_map_counter_decrement(aggregate->rmap.map);
8482 aggregate->rmap.name =
8483 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8484 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8485 route_map_counter_increment(aggregate->rmap.map);
8486 }
8487
8488 if (suppress_map) {
8489 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8490 route_map_counter_decrement(aggregate->suppress_map);
8491
8492 aggregate->suppress_map_name =
8493 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8494 aggregate->suppress_map =
8495 route_map_lookup_by_name(aggregate->suppress_map_name);
8496 route_map_counter_increment(aggregate->suppress_map);
8497 }
8498
8499 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8500
8501 /* Aggregate address insert into BGP routing table. */
8502 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
8503
8504 return CMD_SUCCESS;
8505 }
8506
8507 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8508 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8509 "as-set$as_set_s"
8510 "|summary-only$summary_only"
8511 "|route-map RMAP_NAME$rmap_name"
8512 "|origin <egp|igp|incomplete>$origin_s"
8513 "|matching-MED-only$match_med"
8514 "|suppress-map RMAP_NAME$suppress_map"
8515 "}]",
8516 NO_STR
8517 "Configure BGP aggregate entries\n"
8518 "Aggregate prefix\n"
8519 "Aggregate address\n"
8520 "Aggregate mask\n"
8521 "Generate AS set path information\n"
8522 "Filter more specific routes from updates\n"
8523 "Apply route map to aggregate network\n"
8524 "Route map name\n"
8525 "BGP origin code\n"
8526 "Remote EGP\n"
8527 "Local IGP\n"
8528 "Unknown heritage\n"
8529 "Only aggregate routes with matching MED\n"
8530 "Suppress the selected more specific routes\n"
8531 "Route map with the route selectors\n")
8532 {
8533 const char *prefix_s = NULL;
8534 safi_t safi = bgp_node_safi(vty);
8535 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8536 int as_set = AGGREGATE_AS_UNSET;
8537 char prefix_buf[PREFIX2STR_BUFFER];
8538
8539 if (addr_str) {
8540 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8541 sizeof(prefix_buf))
8542 == 0) {
8543 vty_out(vty, "%% Inconsistent address and mask\n");
8544 return CMD_WARNING_CONFIG_FAILED;
8545 }
8546 prefix_s = prefix_buf;
8547 } else
8548 prefix_s = prefix_str;
8549
8550 if (origin_s) {
8551 if (strcmp(origin_s, "egp") == 0)
8552 origin = BGP_ORIGIN_EGP;
8553 else if (strcmp(origin_s, "igp") == 0)
8554 origin = BGP_ORIGIN_IGP;
8555 else if (strcmp(origin_s, "incomplete") == 0)
8556 origin = BGP_ORIGIN_INCOMPLETE;
8557 }
8558
8559 if (as_set_s)
8560 as_set = AGGREGATE_AS_SET;
8561
8562 /* Handle configuration removal, otherwise installation. */
8563 if (no)
8564 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8565
8566 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8567 summary_only != NULL, as_set, origin,
8568 match_med != NULL, suppress_map);
8569 }
8570
8571 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8572 "[no] aggregate-address X:X::X:X/M$prefix [{"
8573 "as-set$as_set_s"
8574 "|summary-only$summary_only"
8575 "|route-map RMAP_NAME$rmap_name"
8576 "|origin <egp|igp|incomplete>$origin_s"
8577 "|matching-MED-only$match_med"
8578 "|suppress-map RMAP_NAME$suppress_map"
8579 "}]",
8580 NO_STR
8581 "Configure BGP aggregate entries\n"
8582 "Aggregate prefix\n"
8583 "Generate AS set path information\n"
8584 "Filter more specific routes from updates\n"
8585 "Apply route map to aggregate network\n"
8586 "Route map name\n"
8587 "BGP origin code\n"
8588 "Remote EGP\n"
8589 "Local IGP\n"
8590 "Unknown heritage\n"
8591 "Only aggregate routes with matching MED\n"
8592 "Suppress the selected more specific routes\n"
8593 "Route map with the route selectors\n")
8594 {
8595 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8596 int as_set = AGGREGATE_AS_UNSET;
8597
8598 if (origin_s) {
8599 if (strcmp(origin_s, "egp") == 0)
8600 origin = BGP_ORIGIN_EGP;
8601 else if (strcmp(origin_s, "igp") == 0)
8602 origin = BGP_ORIGIN_IGP;
8603 else if (strcmp(origin_s, "incomplete") == 0)
8604 origin = BGP_ORIGIN_INCOMPLETE;
8605 }
8606
8607 if (as_set_s)
8608 as_set = AGGREGATE_AS_SET;
8609
8610 /* Handle configuration removal, otherwise installation. */
8611 if (no)
8612 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8613 SAFI_UNICAST);
8614
8615 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8616 rmap_name, summary_only != NULL, as_set,
8617 origin, match_med != NULL, suppress_map);
8618 }
8619
8620 /* Redistribute route treatment. */
8621 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8622 const union g_addr *nexthop, ifindex_t ifindex,
8623 enum nexthop_types_t nhtype, uint8_t distance,
8624 enum blackhole_type bhtype, uint32_t metric,
8625 uint8_t type, unsigned short instance,
8626 route_tag_t tag)
8627 {
8628 struct bgp_path_info *new;
8629 struct bgp_path_info *bpi;
8630 struct bgp_path_info rmap_path;
8631 struct bgp_dest *bn;
8632 struct attr attr;
8633 struct attr *new_attr;
8634 afi_t afi;
8635 route_map_result_t ret;
8636 struct bgp_redist *red;
8637
8638 /* Make default attribute. */
8639 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8640 /*
8641 * This must not be NULL to satisfy Coverity SA
8642 */
8643 assert(attr.aspath);
8644
8645 switch (nhtype) {
8646 case NEXTHOP_TYPE_IFINDEX:
8647 switch (p->family) {
8648 case AF_INET:
8649 attr.nexthop.s_addr = INADDR_ANY;
8650 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8651 break;
8652 case AF_INET6:
8653 memset(&attr.mp_nexthop_global, 0,
8654 sizeof(attr.mp_nexthop_global));
8655 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8656 break;
8657 }
8658 break;
8659 case NEXTHOP_TYPE_IPV4:
8660 case NEXTHOP_TYPE_IPV4_IFINDEX:
8661 attr.nexthop = nexthop->ipv4;
8662 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8663 break;
8664 case NEXTHOP_TYPE_IPV6:
8665 case NEXTHOP_TYPE_IPV6_IFINDEX:
8666 attr.mp_nexthop_global = nexthop->ipv6;
8667 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8668 break;
8669 case NEXTHOP_TYPE_BLACKHOLE:
8670 switch (p->family) {
8671 case AF_INET:
8672 attr.nexthop.s_addr = INADDR_ANY;
8673 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8674 break;
8675 case AF_INET6:
8676 memset(&attr.mp_nexthop_global, 0,
8677 sizeof(attr.mp_nexthop_global));
8678 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8679 break;
8680 }
8681 attr.bh_type = bhtype;
8682 break;
8683 }
8684 attr.nh_type = nhtype;
8685 attr.nh_ifindex = ifindex;
8686
8687 attr.med = metric;
8688 attr.distance = distance;
8689 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8690 attr.tag = tag;
8691
8692 if (metric)
8693 bgp_attr_set_aigp_metric(&attr, metric);
8694
8695 afi = family2afi(p->family);
8696
8697 red = bgp_redist_lookup(bgp, afi, type, instance);
8698 if (red) {
8699 struct attr attr_new;
8700
8701 /* Copy attribute for modification. */
8702 attr_new = attr;
8703
8704 if (red->redist_metric_flag) {
8705 attr_new.med = red->redist_metric;
8706 bgp_attr_set_aigp_metric(&attr_new, red->redist_metric);
8707 }
8708
8709 /* Apply route-map. */
8710 if (red->rmap.name) {
8711 memset(&rmap_path, 0, sizeof(rmap_path));
8712 rmap_path.peer = bgp->peer_self;
8713 rmap_path.attr = &attr_new;
8714
8715 SET_FLAG(bgp->peer_self->rmap_type,
8716 PEER_RMAP_TYPE_REDISTRIBUTE);
8717
8718 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8719
8720 bgp->peer_self->rmap_type = 0;
8721
8722 if (ret == RMAP_DENYMATCH) {
8723 /* Free uninterned attribute. */
8724 bgp_attr_flush(&attr_new);
8725
8726 /* Unintern original. */
8727 aspath_unintern(&attr.aspath);
8728 bgp_redistribute_delete(bgp, p, type, instance);
8729 return;
8730 }
8731 }
8732
8733 if (bgp_in_graceful_shutdown(bgp))
8734 bgp_attr_add_gshut_community(&attr_new);
8735
8736 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8737 SAFI_UNICAST, p, NULL);
8738
8739 new_attr = bgp_attr_intern(&attr_new);
8740
8741 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8742 if (bpi->peer == bgp->peer_self
8743 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8744 break;
8745
8746 if (bpi) {
8747 /* Ensure the (source route) type is updated. */
8748 bpi->type = type;
8749 if (attrhash_cmp(bpi->attr, new_attr)
8750 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8751 bgp_attr_unintern(&new_attr);
8752 aspath_unintern(&attr.aspath);
8753 bgp_dest_unlock_node(bn);
8754 return;
8755 } else {
8756 /* The attribute is changed. */
8757 bgp_path_info_set_flag(bn, bpi,
8758 BGP_PATH_ATTR_CHANGED);
8759
8760 /* Rewrite BGP route information. */
8761 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8762 bgp_path_info_restore(bn, bpi);
8763 else
8764 bgp_aggregate_decrement(
8765 bgp, p, bpi, afi, SAFI_UNICAST);
8766 bgp_attr_unintern(&bpi->attr);
8767 bpi->attr = new_attr;
8768 bpi->uptime = monotime(NULL);
8769
8770 /* Process change. */
8771 bgp_aggregate_increment(bgp, p, bpi, afi,
8772 SAFI_UNICAST);
8773 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8774 bgp_dest_unlock_node(bn);
8775 aspath_unintern(&attr.aspath);
8776
8777 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8778 || (bgp->inst_type
8779 == BGP_INSTANCE_TYPE_DEFAULT)) {
8780
8781 vpn_leak_from_vrf_update(
8782 bgp_get_default(), bgp, bpi);
8783 }
8784 return;
8785 }
8786 }
8787
8788 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8789 bgp->peer_self, new_attr, bn);
8790 SET_FLAG(new->flags, BGP_PATH_VALID);
8791
8792 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8793 bgp_path_info_add(bn, new);
8794 bgp_dest_unlock_node(bn);
8795 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8796 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8797
8798 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8799 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8800
8801 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8802 }
8803 }
8804
8805 /* Unintern original. */
8806 aspath_unintern(&attr.aspath);
8807 }
8808
8809 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8810 unsigned short instance)
8811 {
8812 afi_t afi;
8813 struct bgp_dest *dest;
8814 struct bgp_path_info *pi;
8815 struct bgp_redist *red;
8816
8817 afi = family2afi(p->family);
8818
8819 red = bgp_redist_lookup(bgp, afi, type, instance);
8820 if (red) {
8821 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8822 SAFI_UNICAST, p, NULL);
8823
8824 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8825 if (pi->peer == bgp->peer_self && pi->type == type)
8826 break;
8827
8828 if (pi) {
8829 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8830 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8831
8832 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8833 bgp, pi);
8834 }
8835 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8836 bgp_path_info_delete(dest, pi);
8837 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8838 }
8839 bgp_dest_unlock_node(dest);
8840 }
8841 }
8842
8843 /* Withdraw specified route type's route. */
8844 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8845 unsigned short instance)
8846 {
8847 struct bgp_dest *dest;
8848 struct bgp_path_info *pi;
8849 struct bgp_table *table;
8850
8851 table = bgp->rib[afi][SAFI_UNICAST];
8852
8853 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8854 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8855 if (pi->peer == bgp->peer_self && pi->type == type
8856 && pi->instance == instance)
8857 break;
8858
8859 if (pi) {
8860 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8861 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8862
8863 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8864 bgp, pi);
8865 }
8866 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8867 pi, afi, SAFI_UNICAST);
8868 bgp_path_info_delete(dest, pi);
8869 if (!CHECK_FLAG(bgp->flags,
8870 BGP_FLAG_DELETE_IN_PROGRESS))
8871 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8872 else
8873 bgp_path_info_reap(dest, pi);
8874 }
8875 }
8876 }
8877
8878 /* Static function to display route. */
8879 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8880 struct vty *vty, json_object *json, bool wide)
8881 {
8882 int len = 0;
8883 char buf[INET6_ADDRSTRLEN];
8884
8885 if (p->family == AF_INET) {
8886 if (!json) {
8887 len = vty_out(vty, "%pFX", p);
8888 } else {
8889 json_object_string_add(json, "prefix",
8890 inet_ntop(p->family,
8891 &p->u.prefix, buf,
8892 sizeof(buf)));
8893 json_object_int_add(json, "prefixLen", p->prefixlen);
8894 json_object_string_addf(json, "network", "%pFX", p);
8895 json_object_int_add(json, "version", dest->version);
8896 }
8897 } else if (p->family == AF_ETHERNET) {
8898 len = vty_out(vty, "%pFX", p);
8899 } else if (p->family == AF_EVPN) {
8900 if (!json)
8901 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8902 else
8903 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8904 } else if (p->family == AF_FLOWSPEC) {
8905 route_vty_out_flowspec(vty, p, NULL,
8906 json ?
8907 NLRI_STRING_FORMAT_JSON_SIMPLE :
8908 NLRI_STRING_FORMAT_MIN, json);
8909 } else {
8910 if (!json)
8911 len = vty_out(vty, "%pFX", p);
8912 else {
8913 json_object_string_add(json, "prefix",
8914 inet_ntop(p->family,
8915 &p->u.prefix, buf,
8916 sizeof(buf)));
8917 json_object_int_add(json, "prefixLen", p->prefixlen);
8918 json_object_string_addf(json, "network", "%pFX", p);
8919 json_object_int_add(json, "version", dest->version);
8920 }
8921 }
8922
8923 if (!json) {
8924 len = wide ? (45 - len) : (17 - len);
8925 if (len < 1)
8926 vty_out(vty, "\n%*s", 20, " ");
8927 else
8928 vty_out(vty, "%*s", len, " ");
8929 }
8930 }
8931
8932 enum bgp_display_type {
8933 normal_list,
8934 };
8935
8936 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8937 {
8938 switch (reason) {
8939 case bgp_path_selection_none:
8940 return "Nothing to Select";
8941 case bgp_path_selection_first:
8942 return "First path received";
8943 case bgp_path_selection_evpn_sticky_mac:
8944 return "EVPN Sticky Mac";
8945 case bgp_path_selection_evpn_seq:
8946 return "EVPN sequence number";
8947 case bgp_path_selection_evpn_lower_ip:
8948 return "EVPN lower IP";
8949 case bgp_path_selection_evpn_local_path:
8950 return "EVPN local ES path";
8951 case bgp_path_selection_evpn_non_proxy:
8952 return "EVPN non proxy";
8953 case bgp_path_selection_weight:
8954 return "Weight";
8955 case bgp_path_selection_local_pref:
8956 return "Local Pref";
8957 case bgp_path_selection_accept_own:
8958 return "Accept Own";
8959 case bgp_path_selection_local_route:
8960 return "Local Route";
8961 case bgp_path_selection_aigp:
8962 return "AIGP";
8963 case bgp_path_selection_confed_as_path:
8964 return "Confederation based AS Path";
8965 case bgp_path_selection_as_path:
8966 return "AS Path";
8967 case bgp_path_selection_origin:
8968 return "Origin";
8969 case bgp_path_selection_med:
8970 return "MED";
8971 case bgp_path_selection_peer:
8972 return "Peer Type";
8973 case bgp_path_selection_confed:
8974 return "Confed Peer Type";
8975 case bgp_path_selection_igp_metric:
8976 return "IGP Metric";
8977 case bgp_path_selection_older:
8978 return "Older Path";
8979 case bgp_path_selection_router_id:
8980 return "Router ID";
8981 case bgp_path_selection_cluster_length:
8982 return "Cluster length";
8983 case bgp_path_selection_stale:
8984 return "Path Staleness";
8985 case bgp_path_selection_local_configured:
8986 return "Locally configured route";
8987 case bgp_path_selection_neighbor_ip:
8988 return "Neighbor IP";
8989 case bgp_path_selection_default:
8990 return "Nothing left to compare";
8991 }
8992 return "Invalid (internal error)";
8993 }
8994
8995 /* Print the short form route status for a bgp_path_info */
8996 static void route_vty_short_status_out(struct vty *vty,
8997 struct bgp_path_info *path,
8998 const struct prefix *p,
8999 json_object *json_path)
9000 {
9001 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
9002
9003 if (json_path) {
9004
9005 /* Route status display. */
9006 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9007 json_object_boolean_true_add(json_path, "removed");
9008
9009 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9010 json_object_boolean_true_add(json_path, "stale");
9011
9012 if (path->extra && bgp_path_suppressed(path))
9013 json_object_boolean_true_add(json_path, "suppressed");
9014
9015 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9016 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9017 json_object_boolean_true_add(json_path, "valid");
9018
9019 /* Selected */
9020 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9021 json_object_boolean_true_add(json_path, "history");
9022
9023 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9024 json_object_boolean_true_add(json_path, "damped");
9025
9026 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9027 json_object_boolean_true_add(json_path, "bestpath");
9028 json_object_string_add(json_path, "selectionReason",
9029 bgp_path_selection_reason2str(
9030 path->net->reason));
9031 }
9032
9033 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9034 json_object_boolean_true_add(json_path, "multipath");
9035
9036 /* Internal route. */
9037 if ((path->peer->as)
9038 && (path->peer->as == path->peer->local_as))
9039 json_object_string_add(json_path, "pathFrom",
9040 "internal");
9041 else
9042 json_object_string_add(json_path, "pathFrom",
9043 "external");
9044
9045 return;
9046 }
9047
9048 /* RPKI validation state */
9049 rpki_state =
9050 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9051
9052 if (rpki_state == RPKI_VALID)
9053 vty_out(vty, "V");
9054 else if (rpki_state == RPKI_INVALID)
9055 vty_out(vty, "I");
9056 else if (rpki_state == RPKI_NOTFOUND)
9057 vty_out(vty, "N");
9058 else
9059 vty_out(vty, " ");
9060
9061 /* Route status display. */
9062 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9063 vty_out(vty, "R");
9064 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9065 vty_out(vty, "S");
9066 else if (bgp_path_suppressed(path))
9067 vty_out(vty, "s");
9068 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9069 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9070 vty_out(vty, "*");
9071 else
9072 vty_out(vty, " ");
9073
9074 /* Selected */
9075 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9076 vty_out(vty, "h");
9077 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9078 vty_out(vty, "d");
9079 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9080 vty_out(vty, ">");
9081 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9082 vty_out(vty, "=");
9083 else
9084 vty_out(vty, " ");
9085
9086 /* Internal route. */
9087 if (path->peer && (path->peer->as)
9088 && (path->peer->as == path->peer->local_as))
9089 vty_out(vty, "i");
9090 else
9091 vty_out(vty, " ");
9092 }
9093
9094 static char *bgp_nexthop_hostname(struct peer *peer,
9095 struct bgp_nexthop_cache *bnc)
9096 {
9097 if (peer->hostname
9098 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9099 return peer->hostname;
9100 return NULL;
9101 }
9102
9103 /* called from terminal list command */
9104 void route_vty_out(struct vty *vty, const struct prefix *p,
9105 struct bgp_path_info *path, int display, safi_t safi,
9106 json_object *json_paths, bool wide)
9107 {
9108 int len;
9109 struct attr *attr = path->attr;
9110 json_object *json_path = NULL;
9111 json_object *json_nexthops = NULL;
9112 json_object *json_nexthop_global = NULL;
9113 json_object *json_nexthop_ll = NULL;
9114 json_object *json_ext_community = NULL;
9115 char vrf_id_str[VRF_NAMSIZ] = {0};
9116 bool nexthop_self =
9117 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9118 bool nexthop_othervrf = false;
9119 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9120 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9121 char *nexthop_hostname =
9122 bgp_nexthop_hostname(path->peer, path->nexthop);
9123 char esi_buf[ESI_STR_LEN];
9124
9125 if (json_paths)
9126 json_path = json_object_new_object();
9127
9128 /* short status lead text */
9129 route_vty_short_status_out(vty, path, p, json_path);
9130
9131 if (!json_paths) {
9132 /* print prefix and mask */
9133 if (!display)
9134 route_vty_out_route(path->net, p, vty, json_path, wide);
9135 else
9136 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9137 } else {
9138 route_vty_out_route(path->net, p, vty, json_path, wide);
9139 }
9140
9141 /*
9142 * If vrf id of nexthop is different from that of prefix,
9143 * set up printable string to append
9144 */
9145 if (path->extra && path->extra->bgp_orig) {
9146 const char *self = "";
9147
9148 if (nexthop_self)
9149 self = "<";
9150
9151 nexthop_othervrf = true;
9152 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9153
9154 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9155 snprintf(vrf_id_str, sizeof(vrf_id_str),
9156 "@%s%s", VRFID_NONE_STR, self);
9157 else
9158 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9159 path->extra->bgp_orig->vrf_id, self);
9160
9161 if (path->extra->bgp_orig->inst_type
9162 != BGP_INSTANCE_TYPE_DEFAULT)
9163
9164 nexthop_vrfname = path->extra->bgp_orig->name;
9165 } else {
9166 const char *self = "";
9167
9168 if (nexthop_self)
9169 self = "<";
9170
9171 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9172 }
9173
9174 /*
9175 * For ENCAP and EVPN routes, nexthop address family is not
9176 * neccessarily the same as the prefix address family.
9177 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9178 * EVPN routes are also exchanged with a MP nexthop. Currently,
9179 * this
9180 * is only IPv4, the value will be present in either
9181 * attr->nexthop or
9182 * attr->mp_nexthop_global_in
9183 */
9184 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9185 char nexthop[128];
9186 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9187
9188 switch (af) {
9189 case AF_INET:
9190 snprintfrr(nexthop, sizeof(nexthop), "%pI4",
9191 &attr->mp_nexthop_global_in);
9192 break;
9193 case AF_INET6:
9194 snprintfrr(nexthop, sizeof(nexthop), "%pI6",
9195 &attr->mp_nexthop_global);
9196 break;
9197 default:
9198 snprintf(nexthop, sizeof(nexthop), "?");
9199 break;
9200 }
9201
9202 if (json_paths) {
9203 json_nexthop_global = json_object_new_object();
9204
9205 json_object_string_add(json_nexthop_global, "ip",
9206 nexthop);
9207
9208 if (path->peer->hostname)
9209 json_object_string_add(json_nexthop_global,
9210 "hostname",
9211 path->peer->hostname);
9212
9213 json_object_string_add(json_nexthop_global, "afi",
9214 (af == AF_INET) ? "ipv4"
9215 : "ipv6");
9216 json_object_boolean_true_add(json_nexthop_global,
9217 "used");
9218 } else {
9219 if (nexthop_hostname)
9220 len = vty_out(vty, "%s(%s)%s", nexthop,
9221 nexthop_hostname, vrf_id_str);
9222 else
9223 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9224
9225 len = wide ? (41 - len) : (16 - len);
9226 if (len < 1)
9227 vty_out(vty, "\n%*s", 36, " ");
9228 else
9229 vty_out(vty, "%*s", len, " ");
9230 }
9231 } else if (safi == SAFI_EVPN) {
9232 if (json_paths) {
9233 json_nexthop_global = json_object_new_object();
9234
9235 json_object_string_addf(json_nexthop_global, "ip",
9236 "%pI4",
9237 &attr->mp_nexthop_global_in);
9238
9239 if (path->peer->hostname)
9240 json_object_string_add(json_nexthop_global,
9241 "hostname",
9242 path->peer->hostname);
9243
9244 json_object_string_add(json_nexthop_global, "afi",
9245 "ipv4");
9246 json_object_boolean_true_add(json_nexthop_global,
9247 "used");
9248 } else {
9249 if (nexthop_hostname)
9250 len = vty_out(vty, "%pI4(%s)%s",
9251 &attr->mp_nexthop_global_in,
9252 nexthop_hostname, vrf_id_str);
9253 else
9254 len = vty_out(vty, "%pI4%s",
9255 &attr->mp_nexthop_global_in,
9256 vrf_id_str);
9257
9258 len = wide ? (41 - len) : (16 - len);
9259 if (len < 1)
9260 vty_out(vty, "\n%*s", 36, " ");
9261 else
9262 vty_out(vty, "%*s", len, " ");
9263 }
9264 } else if (safi == SAFI_FLOWSPEC) {
9265 if (attr->nexthop.s_addr != INADDR_ANY) {
9266 if (json_paths) {
9267 json_nexthop_global = json_object_new_object();
9268
9269 json_object_string_add(json_nexthop_global,
9270 "afi", "ipv4");
9271 json_object_string_addf(json_nexthop_global,
9272 "ip", "%pI4",
9273 &attr->nexthop);
9274
9275 if (path->peer->hostname)
9276 json_object_string_add(
9277 json_nexthop_global, "hostname",
9278 path->peer->hostname);
9279
9280 json_object_boolean_true_add(
9281 json_nexthop_global,
9282 "used");
9283 } else {
9284 if (nexthop_hostname)
9285 len = vty_out(vty, "%pI4(%s)%s",
9286 &attr->nexthop,
9287 nexthop_hostname,
9288 vrf_id_str);
9289 else
9290 len = vty_out(vty, "%pI4%s",
9291 &attr->nexthop,
9292 vrf_id_str);
9293
9294 len = wide ? (41 - len) : (16 - len);
9295 if (len < 1)
9296 vty_out(vty, "\n%*s", 36, " ");
9297 else
9298 vty_out(vty, "%*s", len, " ");
9299 }
9300 }
9301 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9302 if (json_paths) {
9303 json_nexthop_global = json_object_new_object();
9304
9305 json_object_string_addf(json_nexthop_global, "ip",
9306 "%pI4", &attr->nexthop);
9307
9308 if (path->peer->hostname)
9309 json_object_string_add(json_nexthop_global,
9310 "hostname",
9311 path->peer->hostname);
9312
9313 json_object_string_add(json_nexthop_global, "afi",
9314 "ipv4");
9315 json_object_boolean_true_add(json_nexthop_global,
9316 "used");
9317 } else {
9318 if (nexthop_hostname)
9319 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9320 nexthop_hostname, vrf_id_str);
9321 else
9322 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9323 vrf_id_str);
9324
9325 len = wide ? (41 - len) : (16 - len);
9326 if (len < 1)
9327 vty_out(vty, "\n%*s", 36, " ");
9328 else
9329 vty_out(vty, "%*s", len, " ");
9330 }
9331 }
9332
9333 /* IPv6 Next Hop */
9334 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9335 if (json_paths) {
9336 json_nexthop_global = json_object_new_object();
9337 json_object_string_addf(json_nexthop_global, "ip",
9338 "%pI6",
9339 &attr->mp_nexthop_global);
9340
9341 if (path->peer->hostname)
9342 json_object_string_add(json_nexthop_global,
9343 "hostname",
9344 path->peer->hostname);
9345
9346 json_object_string_add(json_nexthop_global, "afi",
9347 "ipv6");
9348 json_object_string_add(json_nexthop_global, "scope",
9349 "global");
9350
9351 /* We display both LL & GL if both have been
9352 * received */
9353 if ((attr->mp_nexthop_len
9354 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9355 || (path->peer->conf_if)) {
9356 json_nexthop_ll = json_object_new_object();
9357 json_object_string_addf(
9358 json_nexthop_ll, "ip", "%pI6",
9359 &attr->mp_nexthop_local);
9360
9361 if (path->peer->hostname)
9362 json_object_string_add(
9363 json_nexthop_ll, "hostname",
9364 path->peer->hostname);
9365
9366 json_object_string_add(json_nexthop_ll, "afi",
9367 "ipv6");
9368 json_object_string_add(json_nexthop_ll, "scope",
9369 "link-local");
9370
9371 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9372 &attr->mp_nexthop_local)
9373 != 0)
9374 && !attr->mp_nexthop_prefer_global)
9375 json_object_boolean_true_add(
9376 json_nexthop_ll, "used");
9377 else
9378 json_object_boolean_true_add(
9379 json_nexthop_global, "used");
9380 } else
9381 json_object_boolean_true_add(
9382 json_nexthop_global, "used");
9383 } else {
9384 /* Display LL if LL/Global both in table unless
9385 * prefer-global is set */
9386 if (((attr->mp_nexthop_len
9387 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9388 && !attr->mp_nexthop_prefer_global)
9389 || (path->peer->conf_if)) {
9390 if (path->peer->conf_if) {
9391 len = vty_out(vty, "%s",
9392 path->peer->conf_if);
9393 /* len of IPv6 addr + max len of def
9394 * ifname */
9395 len = wide ? (41 - len) : (16 - len);
9396
9397 if (len < 1)
9398 vty_out(vty, "\n%*s", 36, " ");
9399 else
9400 vty_out(vty, "%*s", len, " ");
9401 } else {
9402 if (nexthop_hostname)
9403 len = vty_out(
9404 vty, "%pI6(%s)%s",
9405 &attr->mp_nexthop_local,
9406 nexthop_hostname,
9407 vrf_id_str);
9408 else
9409 len = vty_out(
9410 vty, "%pI6%s",
9411 &attr->mp_nexthop_local,
9412 vrf_id_str);
9413
9414 len = wide ? (41 - len) : (16 - len);
9415
9416 if (len < 1)
9417 vty_out(vty, "\n%*s", 36, " ");
9418 else
9419 vty_out(vty, "%*s", len, " ");
9420 }
9421 } else {
9422 if (nexthop_hostname)
9423 len = vty_out(vty, "%pI6(%s)%s",
9424 &attr->mp_nexthop_global,
9425 nexthop_hostname,
9426 vrf_id_str);
9427 else
9428 len = vty_out(vty, "%pI6%s",
9429 &attr->mp_nexthop_global,
9430 vrf_id_str);
9431
9432 len = wide ? (41 - len) : (16 - len);
9433
9434 if (len < 1)
9435 vty_out(vty, "\n%*s", 36, " ");
9436 else
9437 vty_out(vty, "%*s", len, " ");
9438 }
9439 }
9440 }
9441
9442 /* MED/Metric */
9443 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9444 if (json_paths)
9445 json_object_int_add(json_path, "metric", attr->med);
9446 else if (wide)
9447 vty_out(vty, "%7u", attr->med);
9448 else
9449 vty_out(vty, "%10u", attr->med);
9450 else if (!json_paths) {
9451 if (wide)
9452 vty_out(vty, "%*s", 7, " ");
9453 else
9454 vty_out(vty, "%*s", 10, " ");
9455 }
9456
9457 /* Local Pref */
9458 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9459 if (json_paths)
9460 json_object_int_add(json_path, "locPrf",
9461 attr->local_pref);
9462 else
9463 vty_out(vty, "%7u", attr->local_pref);
9464 else if (!json_paths)
9465 vty_out(vty, " ");
9466
9467 if (json_paths)
9468 json_object_int_add(json_path, "weight", attr->weight);
9469 else
9470 vty_out(vty, "%7u ", attr->weight);
9471
9472 if (json_paths)
9473 json_object_string_addf(json_path, "peerId", "%pSU",
9474 &path->peer->su);
9475
9476 /* Print aspath */
9477 if (attr->aspath) {
9478 if (json_paths)
9479 json_object_string_add(json_path, "path",
9480 attr->aspath->str);
9481 else
9482 aspath_print_vty(vty, "%s", attr->aspath, " ");
9483 }
9484
9485 /* Print origin */
9486 if (json_paths)
9487 json_object_string_add(json_path, "origin",
9488 bgp_origin_long_str[attr->origin]);
9489 else
9490 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9491
9492 if (json_paths) {
9493 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9494 json_object_string_add(json_path, "esi",
9495 esi_to_str(&attr->esi,
9496 esi_buf, sizeof(esi_buf)));
9497 }
9498 if (safi == SAFI_EVPN &&
9499 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9500 json_ext_community = json_object_new_object();
9501 json_object_string_add(
9502 json_ext_community, "string",
9503 bgp_attr_get_ecommunity(attr)->str);
9504 json_object_object_add(json_path,
9505 "extendedCommunity",
9506 json_ext_community);
9507 }
9508
9509 if (nexthop_self)
9510 json_object_boolean_true_add(json_path,
9511 "announceNexthopSelf");
9512 if (nexthop_othervrf) {
9513 json_object_string_add(json_path, "nhVrfName",
9514 nexthop_vrfname);
9515
9516 json_object_int_add(json_path, "nhVrfId",
9517 ((nexthop_vrfid == VRF_UNKNOWN)
9518 ? -1
9519 : (int)nexthop_vrfid));
9520 }
9521 }
9522
9523 if (json_paths) {
9524 if (json_nexthop_global || json_nexthop_ll) {
9525 json_nexthops = json_object_new_array();
9526
9527 if (json_nexthop_global)
9528 json_object_array_add(json_nexthops,
9529 json_nexthop_global);
9530
9531 if (json_nexthop_ll)
9532 json_object_array_add(json_nexthops,
9533 json_nexthop_ll);
9534
9535 json_object_object_add(json_path, "nexthops",
9536 json_nexthops);
9537 }
9538
9539 json_object_array_add(json_paths, json_path);
9540 } else {
9541 vty_out(vty, "\n");
9542
9543 if (safi == SAFI_EVPN) {
9544 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9545 /* XXX - add these params to the json out */
9546 vty_out(vty, "%*s", 20, " ");
9547 vty_out(vty, "ESI:%s",
9548 esi_to_str(&attr->esi, esi_buf,
9549 sizeof(esi_buf)));
9550
9551 vty_out(vty, "\n");
9552 }
9553 if (attr->flag &
9554 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9555 vty_out(vty, "%*s", 20, " ");
9556 vty_out(vty, "%s\n",
9557 bgp_attr_get_ecommunity(attr)->str);
9558 }
9559 }
9560
9561 #ifdef ENABLE_BGP_VNC
9562 /* prints an additional line, indented, with VNC info, if
9563 * present */
9564 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9565 rfapi_vty_out_vncinfo(vty, p, path, safi);
9566 #endif
9567 }
9568 }
9569
9570 /* called from terminal list command */
9571 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9572 const struct prefix *p, struct attr *attr, safi_t safi,
9573 bool use_json, json_object *json_ar, bool wide)
9574 {
9575 json_object *json_status = NULL;
9576 json_object *json_net = NULL;
9577 int len;
9578 char buff[BUFSIZ];
9579
9580 /* Route status display. */
9581 if (use_json) {
9582 json_status = json_object_new_object();
9583 json_net = json_object_new_object();
9584 } else {
9585 vty_out(vty, " *");
9586 vty_out(vty, ">");
9587 vty_out(vty, " ");
9588 }
9589
9590 /* print prefix and mask */
9591 if (use_json) {
9592 if (safi == SAFI_EVPN)
9593 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9594 else if (p->family == AF_INET || p->family == AF_INET6) {
9595 json_object_string_add(
9596 json_net, "addrPrefix",
9597 inet_ntop(p->family, &p->u.prefix, buff,
9598 BUFSIZ));
9599 json_object_int_add(json_net, "prefixLen",
9600 p->prefixlen);
9601 json_object_string_addf(json_net, "network", "%pFX", p);
9602 }
9603 } else
9604 route_vty_out_route(dest, p, vty, NULL, wide);
9605
9606 /* Print attribute */
9607 if (attr) {
9608 if (use_json) {
9609 if (p->family == AF_INET &&
9610 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9611 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9612 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9613 json_object_string_addf(
9614 json_net, "nextHop", "%pI4",
9615 &attr->mp_nexthop_global_in);
9616 else
9617 json_object_string_addf(
9618 json_net, "nextHop", "%pI4",
9619 &attr->nexthop);
9620 } else if (p->family == AF_INET6 ||
9621 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9622 json_object_string_addf(
9623 json_net, "nextHopGlobal", "%pI6",
9624 &attr->mp_nexthop_global);
9625 } else if (p->family == AF_EVPN &&
9626 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9627 json_object_string_addf(
9628 json_net, "nextHop", "%pI4",
9629 &attr->mp_nexthop_global_in);
9630 }
9631
9632 if (attr->flag
9633 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9634 json_object_int_add(json_net, "metric",
9635 attr->med);
9636
9637 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9638 json_object_int_add(json_net, "locPrf",
9639 attr->local_pref);
9640
9641 json_object_int_add(json_net, "weight", attr->weight);
9642
9643 /* Print aspath */
9644 if (attr->aspath)
9645 json_object_string_add(json_net, "path",
9646 attr->aspath->str);
9647
9648 /* Print origin */
9649 #if CONFDATE > 20231208
9650 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
9651 #endif
9652 json_object_string_add(json_net, "bgpOriginCode",
9653 bgp_origin_str[attr->origin]);
9654 json_object_string_add(
9655 json_net, "origin",
9656 bgp_origin_long_str[attr->origin]);
9657 } else {
9658 if (p->family == AF_INET &&
9659 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9660 safi == SAFI_EVPN ||
9661 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9662 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9663 || safi == SAFI_EVPN)
9664 vty_out(vty, "%-16pI4",
9665 &attr->mp_nexthop_global_in);
9666 else if (wide)
9667 vty_out(vty, "%-41pI4", &attr->nexthop);
9668 else
9669 vty_out(vty, "%-16pI4", &attr->nexthop);
9670 } else if (p->family == AF_INET6 ||
9671 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9672 len = vty_out(vty, "%pI6",
9673 &attr->mp_nexthop_global);
9674 len = wide ? (41 - len) : (16 - len);
9675 if (len < 1)
9676 vty_out(vty, "\n%*s", 36, " ");
9677 else
9678 vty_out(vty, "%*s", len, " ");
9679 }
9680 if (attr->flag
9681 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9682 if (wide)
9683 vty_out(vty, "%7u", attr->med);
9684 else
9685 vty_out(vty, "%10u", attr->med);
9686 else if (wide)
9687 vty_out(vty, " ");
9688 else
9689 vty_out(vty, " ");
9690
9691 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9692 vty_out(vty, "%7u", attr->local_pref);
9693 else
9694 vty_out(vty, " ");
9695
9696 vty_out(vty, "%7u ", attr->weight);
9697
9698 /* Print aspath */
9699 if (attr->aspath)
9700 aspath_print_vty(vty, "%s", attr->aspath, " ");
9701
9702 /* Print origin */
9703 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9704 }
9705 }
9706 if (use_json) {
9707 struct bgp_path_info *bpi = bgp_dest_get_bgp_path_info(dest);
9708
9709 #if CONFDATE > 20231208
9710 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
9711 #endif
9712 json_object_boolean_true_add(json_status, "*");
9713 json_object_boolean_true_add(json_status, ">");
9714 json_object_boolean_true_add(json_net, "valid");
9715 json_object_boolean_true_add(json_net, "best");
9716
9717 if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_MULTIPATH)) {
9718 json_object_boolean_true_add(json_status, "=");
9719 json_object_boolean_true_add(json_net, "multipath");
9720 }
9721 json_object_object_add(json_net, "appliedStatusSymbols",
9722 json_status);
9723 json_object_object_addf(json_ar, json_net, "%pFX", p);
9724 } else
9725 vty_out(vty, "\n");
9726 }
9727
9728 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9729 struct bgp_path_info *path, int display, safi_t safi,
9730 json_object *json)
9731 {
9732 json_object *json_out = NULL;
9733 struct attr *attr;
9734 mpls_label_t label = MPLS_INVALID_LABEL;
9735
9736 if (!path->extra)
9737 return;
9738
9739 if (json)
9740 json_out = json_object_new_object();
9741
9742 /* short status lead text */
9743 route_vty_short_status_out(vty, path, p, json_out);
9744
9745 /* print prefix and mask */
9746 if (json == NULL) {
9747 if (!display)
9748 route_vty_out_route(path->net, p, vty, NULL, false);
9749 else
9750 vty_out(vty, "%*s", 17, " ");
9751 }
9752
9753 /* Print attribute */
9754 attr = path->attr;
9755 if (((p->family == AF_INET) &&
9756 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9757 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9758 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9759 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9760 || safi == SAFI_EVPN) {
9761 if (json)
9762 json_object_string_addf(
9763 json_out, "mpNexthopGlobalIn", "%pI4",
9764 &attr->mp_nexthop_global_in);
9765 else
9766 vty_out(vty, "%-16pI4",
9767 &attr->mp_nexthop_global_in);
9768 } else {
9769 if (json)
9770 json_object_string_addf(json_out, "nexthop",
9771 "%pI4", &attr->nexthop);
9772 else
9773 vty_out(vty, "%-16pI4", &attr->nexthop);
9774 }
9775 } else if (((p->family == AF_INET6) &&
9776 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9777 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9778 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9779 char buf_a[512];
9780
9781 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9782 if (json)
9783 json_object_string_addf(
9784 json_out, "mpNexthopGlobalIn", "%pI6",
9785 &attr->mp_nexthop_global);
9786 else
9787 vty_out(vty, "%s",
9788 inet_ntop(AF_INET6,
9789 &attr->mp_nexthop_global,
9790 buf_a, sizeof(buf_a)));
9791 } else if (attr->mp_nexthop_len
9792 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9793 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9794 &attr->mp_nexthop_global,
9795 &attr->mp_nexthop_local);
9796 if (json)
9797 json_object_string_add(json_out,
9798 "mpNexthopGlobalLocal",
9799 buf_a);
9800 else
9801 vty_out(vty, "%s", buf_a);
9802 }
9803 }
9804
9805 label = decode_label(&path->extra->label[0]);
9806
9807 if (bgp_is_valid_label(&label)) {
9808 if (json) {
9809 json_object_int_add(json_out, "notag", label);
9810 json_object_array_add(json, json_out);
9811 } else {
9812 vty_out(vty, "notag/%d", label);
9813 vty_out(vty, "\n");
9814 }
9815 } else if (!json)
9816 vty_out(vty, "\n");
9817 }
9818
9819 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9820 struct bgp_path_info *path, int display,
9821 json_object *json_paths)
9822 {
9823 struct attr *attr;
9824 json_object *json_path = NULL;
9825 json_object *json_nexthop = NULL;
9826 json_object *json_overlay = NULL;
9827
9828 if (!path->extra)
9829 return;
9830
9831 if (json_paths) {
9832 json_path = json_object_new_object();
9833 json_overlay = json_object_new_object();
9834 json_nexthop = json_object_new_object();
9835 }
9836
9837 /* short status lead text */
9838 route_vty_short_status_out(vty, path, p, json_path);
9839
9840 /* print prefix and mask */
9841 if (!display)
9842 route_vty_out_route(path->net, p, vty, json_path, false);
9843 else
9844 vty_out(vty, "%*s", 17, " ");
9845
9846 /* Print attribute */
9847 attr = path->attr;
9848 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9849
9850 switch (af) {
9851 case AF_INET:
9852 if (!json_path) {
9853 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9854 } else {
9855 json_object_string_addf(json_nexthop, "ip", "%pI4",
9856 &attr->mp_nexthop_global_in);
9857
9858 json_object_string_add(json_nexthop, "afi", "ipv4");
9859
9860 json_object_object_add(json_path, "nexthop",
9861 json_nexthop);
9862 }
9863 break;
9864 case AF_INET6:
9865 if (!json_path) {
9866 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9867 &attr->mp_nexthop_local);
9868 } else {
9869 json_object_string_addf(json_nexthop, "ipv6Global",
9870 "%pI6",
9871 &attr->mp_nexthop_global);
9872
9873 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9874 "%pI6",
9875 &attr->mp_nexthop_local);
9876
9877 json_object_string_add(json_nexthop, "afi", "ipv6");
9878
9879 json_object_object_add(json_path, "nexthop",
9880 json_nexthop);
9881 }
9882 break;
9883 default:
9884 if (!json_path) {
9885 vty_out(vty, "?");
9886 } else {
9887 json_object_string_add(json_nexthop, "Error",
9888 "Unsupported address-family");
9889 json_object_string_add(json_nexthop, "error",
9890 "Unsupported address-family");
9891 }
9892 }
9893
9894 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9895
9896 if (!json_path)
9897 vty_out(vty, "/%pIA", &eo->gw_ip);
9898 else
9899 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9900
9901 if (bgp_attr_get_ecommunity(attr)) {
9902 char *mac = NULL;
9903 struct ecommunity_val *routermac = ecommunity_lookup(
9904 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9905 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9906
9907 if (routermac)
9908 mac = ecom_mac2str((char *)routermac->val);
9909 if (mac) {
9910 if (!json_path) {
9911 vty_out(vty, "/%s", mac);
9912 } else {
9913 json_object_string_add(json_overlay, "rmac",
9914 mac);
9915 }
9916 XFREE(MTYPE_TMP, mac);
9917 }
9918 }
9919
9920 if (!json_path) {
9921 vty_out(vty, "\n");
9922 } else {
9923 json_object_object_add(json_path, "overlay", json_overlay);
9924
9925 json_object_array_add(json_paths, json_path);
9926 }
9927 }
9928
9929 /* dampening route */
9930 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9931 struct bgp_path_info *path, int display,
9932 afi_t afi, safi_t safi, bool use_json,
9933 json_object *json_paths)
9934 {
9935 struct attr *attr = path->attr;
9936 int len;
9937 char timebuf[BGP_UPTIME_LEN];
9938 json_object *json_path = NULL;
9939
9940 if (use_json)
9941 json_path = json_object_new_object();
9942
9943 /* short status lead text */
9944 route_vty_short_status_out(vty, path, p, json_path);
9945
9946 /* print prefix and mask */
9947 if (!use_json) {
9948 if (!display)
9949 route_vty_out_route(path->net, p, vty, NULL, false);
9950 else
9951 vty_out(vty, "%*s", 17, " ");
9952
9953 len = vty_out(vty, "%s", path->peer->host);
9954 len = 17 - len;
9955
9956 if (len < 1)
9957 vty_out(vty, "\n%*s", 34, " ");
9958 else
9959 vty_out(vty, "%*s", len, " ");
9960
9961 vty_out(vty, "%s ",
9962 bgp_damp_reuse_time_vty(vty, path, timebuf,
9963 BGP_UPTIME_LEN, afi, safi,
9964 use_json, NULL));
9965
9966 if (attr->aspath)
9967 aspath_print_vty(vty, "%s", attr->aspath, " ");
9968
9969 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9970
9971 vty_out(vty, "\n");
9972 } else {
9973 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9974 safi, use_json, json_path);
9975
9976 if (attr->aspath)
9977 json_object_string_add(json_path, "asPath",
9978 attr->aspath->str);
9979
9980 json_object_string_add(json_path, "origin",
9981 bgp_origin_str[attr->origin]);
9982 json_object_string_add(json_path, "peerHost", path->peer->host);
9983
9984 json_object_array_add(json_paths, json_path);
9985 }
9986 }
9987
9988 /* flap route */
9989 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9990 struct bgp_path_info *path, int display,
9991 afi_t afi, safi_t safi, bool use_json,
9992 json_object *json_paths)
9993 {
9994 struct attr *attr = path->attr;
9995 struct bgp_damp_info *bdi;
9996 char timebuf[BGP_UPTIME_LEN];
9997 int len;
9998 json_object *json_path = NULL;
9999
10000 if (!path->extra)
10001 return;
10002
10003 if (use_json)
10004 json_path = json_object_new_object();
10005
10006 bdi = path->extra->damp_info;
10007
10008 /* short status lead text */
10009 route_vty_short_status_out(vty, path, p, json_path);
10010
10011 if (!use_json) {
10012 if (!display)
10013 route_vty_out_route(path->net, p, vty, NULL, false);
10014 else
10015 vty_out(vty, "%*s", 17, " ");
10016
10017 len = vty_out(vty, "%s", path->peer->host);
10018 len = 16 - len;
10019 if (len < 1)
10020 vty_out(vty, "\n%*s", 33, " ");
10021 else
10022 vty_out(vty, "%*s", len, " ");
10023
10024 len = vty_out(vty, "%d", bdi->flap);
10025 len = 5 - len;
10026 if (len < 1)
10027 vty_out(vty, " ");
10028 else
10029 vty_out(vty, "%*s", len, " ");
10030
10031 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10032 BGP_UPTIME_LEN, 0, NULL));
10033
10034 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10035 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10036 vty_out(vty, "%s ",
10037 bgp_damp_reuse_time_vty(vty, path, timebuf,
10038 BGP_UPTIME_LEN, afi,
10039 safi, use_json, NULL));
10040 else
10041 vty_out(vty, "%*s ", 8, " ");
10042
10043 if (attr->aspath)
10044 aspath_print_vty(vty, "%s", attr->aspath, " ");
10045
10046 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10047
10048 vty_out(vty, "\n");
10049 } else {
10050 json_object_string_add(json_path, "peerHost", path->peer->host);
10051 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10052
10053 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10054 json_path);
10055
10056 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10057 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10058 bgp_damp_reuse_time_vty(vty, path, timebuf,
10059 BGP_UPTIME_LEN, afi, safi,
10060 use_json, json_path);
10061
10062 if (attr->aspath)
10063 json_object_string_add(json_path, "asPath",
10064 attr->aspath->str);
10065
10066 json_object_string_add(json_path, "origin",
10067 bgp_origin_str[attr->origin]);
10068
10069 json_object_array_add(json_paths, json_path);
10070 }
10071 }
10072
10073 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10074 int *first, const char *header,
10075 json_object *json_adv_to)
10076 {
10077 json_object *json_peer = NULL;
10078
10079 if (json_adv_to) {
10080 /* 'advertised-to' is a dictionary of peers we have advertised
10081 * this
10082 * prefix too. The key is the peer's IP or swpX, the value is
10083 * the
10084 * hostname if we know it and "" if not.
10085 */
10086 json_peer = json_object_new_object();
10087
10088 if (peer->hostname)
10089 json_object_string_add(json_peer, "hostname",
10090 peer->hostname);
10091
10092 if (peer->conf_if)
10093 json_object_object_add(json_adv_to, peer->conf_if,
10094 json_peer);
10095 else
10096 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10097 &peer->su);
10098 } else {
10099 if (*first) {
10100 vty_out(vty, "%s", header);
10101 *first = 0;
10102 }
10103
10104 if (peer->hostname
10105 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10106 if (peer->conf_if)
10107 vty_out(vty, " %s(%s)", peer->hostname,
10108 peer->conf_if);
10109 else
10110 vty_out(vty, " %s(%pSU)", peer->hostname,
10111 &peer->su);
10112 } else {
10113 if (peer->conf_if)
10114 vty_out(vty, " %s", peer->conf_if);
10115 else
10116 vty_out(vty, " %pSU", &peer->su);
10117 }
10118 }
10119 }
10120
10121 static void route_vty_out_tx_ids(struct vty *vty,
10122 struct bgp_addpath_info_data *d)
10123 {
10124 int i;
10125
10126 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10127 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10128 d->addpath_tx_id[i],
10129 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10130 }
10131 }
10132
10133 static void route_vty_out_detail_es_info(struct vty *vty,
10134 struct bgp_path_info *pi,
10135 struct attr *attr,
10136 json_object *json_path)
10137 {
10138 char esi_buf[ESI_STR_LEN];
10139 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10140 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10141 ATTR_ES_PEER_ROUTER);
10142 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10143 ATTR_ES_PEER_ACTIVE);
10144 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10145 ATTR_ES_PEER_PROXY);
10146 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10147 if (json_path) {
10148 json_object *json_es_info = NULL;
10149
10150 json_object_string_add(
10151 json_path, "esi",
10152 esi_buf);
10153 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10154 json_es_info = json_object_new_object();
10155 if (es_local)
10156 json_object_boolean_true_add(
10157 json_es_info, "localEs");
10158 if (peer_active)
10159 json_object_boolean_true_add(
10160 json_es_info, "peerActive");
10161 if (peer_proxy)
10162 json_object_boolean_true_add(
10163 json_es_info, "peerProxy");
10164 if (peer_router)
10165 json_object_boolean_true_add(
10166 json_es_info, "peerRouter");
10167 if (attr->mm_sync_seqnum)
10168 json_object_int_add(
10169 json_es_info, "peerSeq",
10170 attr->mm_sync_seqnum);
10171 json_object_object_add(
10172 json_path, "es_info",
10173 json_es_info);
10174 }
10175 } else {
10176 if (bgp_evpn_attr_is_sync(attr))
10177 vty_out(vty,
10178 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10179 esi_buf,
10180 es_local ? "local-es":"",
10181 peer_proxy ? "proxy " : "",
10182 peer_active ? "active ":"",
10183 peer_router ? "router ":"",
10184 attr->mm_sync_seqnum);
10185 else
10186 vty_out(vty, " ESI %s %s\n",
10187 esi_buf,
10188 es_local ? "local-es":"");
10189 }
10190 }
10191
10192 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10193 const struct prefix *p, struct bgp_path_info *path,
10194 afi_t afi, safi_t safi,
10195 enum rpki_states rpki_curr_state,
10196 json_object *json_paths)
10197 {
10198 char buf[INET6_ADDRSTRLEN];
10199 char tag_buf[30];
10200 struct attr *attr = path->attr;
10201 time_t tbuf;
10202 json_object *json_bestpath = NULL;
10203 json_object *json_cluster_list = NULL;
10204 json_object *json_cluster_list_list = NULL;
10205 json_object *json_ext_community = NULL;
10206 json_object *json_last_update = NULL;
10207 json_object *json_pmsi = NULL;
10208 json_object *json_nexthop_global = NULL;
10209 json_object *json_nexthop_ll = NULL;
10210 json_object *json_nexthops = NULL;
10211 json_object *json_path = NULL;
10212 json_object *json_peer = NULL;
10213 json_object *json_string = NULL;
10214 json_object *json_adv_to = NULL;
10215 int first = 0;
10216 struct listnode *node, *nnode;
10217 struct peer *peer;
10218 bool addpath_capable;
10219 int has_adj;
10220 unsigned int first_as;
10221 bool nexthop_self =
10222 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10223 int i;
10224 char *nexthop_hostname =
10225 bgp_nexthop_hostname(path->peer, path->nexthop);
10226 uint32_t ttl = 0;
10227 uint32_t bos = 0;
10228 uint32_t exp = 0;
10229 mpls_label_t label = MPLS_INVALID_LABEL;
10230 tag_buf[0] = '\0';
10231 struct bgp_path_info *bpi_ultimate =
10232 bgp_get_imported_bpi_ultimate(path);
10233
10234 if (json_paths) {
10235 json_path = json_object_new_object();
10236 json_peer = json_object_new_object();
10237 json_nexthop_global = json_object_new_object();
10238 }
10239
10240 if (safi == SAFI_EVPN) {
10241 if (!json_paths)
10242 vty_out(vty, " Route %pFX", p);
10243 }
10244
10245 if (path->extra) {
10246 if (path->extra && path->extra->num_labels) {
10247 bgp_evpn_label2str(path->extra->label,
10248 path->extra->num_labels, tag_buf,
10249 sizeof(tag_buf));
10250 }
10251 if (safi == SAFI_EVPN) {
10252 if (!json_paths) {
10253 if (tag_buf[0] != '\0')
10254 vty_out(vty, " VNI %s", tag_buf);
10255 } else {
10256 if (tag_buf[0]) {
10257 json_object_string_add(json_path, "VNI",
10258 tag_buf);
10259 json_object_string_add(json_path, "vni",
10260 tag_buf);
10261 }
10262 }
10263 }
10264 }
10265
10266 if (safi == SAFI_EVPN
10267 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10268 char gwip_buf[INET6_ADDRSTRLEN];
10269
10270 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10271 sizeof(gwip_buf));
10272
10273 if (json_paths)
10274 json_object_string_add(json_path, "gatewayIP",
10275 gwip_buf);
10276 else
10277 vty_out(vty, " Gateway IP %s", gwip_buf);
10278 }
10279
10280 if (safi == SAFI_EVPN && !json_path)
10281 vty_out(vty, "\n");
10282
10283
10284 if (path->extra && path->extra->parent && !json_paths) {
10285 struct bgp_path_info *parent_ri;
10286 struct bgp_dest *dest, *pdest;
10287
10288 parent_ri = (struct bgp_path_info *)path->extra->parent;
10289 dest = parent_ri->net;
10290 if (dest && dest->pdest) {
10291 pdest = dest->pdest;
10292 if (is_pi_family_evpn(parent_ri)) {
10293 vty_out(vty,
10294 " Imported from %pRD:%pFX, VNI %s",
10295 (struct prefix_rd *)bgp_dest_get_prefix(
10296 pdest),
10297 (struct prefix_evpn *)
10298 bgp_dest_get_prefix(dest),
10299 tag_buf);
10300 if (CHECK_FLAG(attr->es_flags, ATTR_ES_L3_NHG))
10301 vty_out(vty, ", L3NHG %s",
10302 CHECK_FLAG(
10303 attr->es_flags,
10304 ATTR_ES_L3_NHG_ACTIVE)
10305 ? "active"
10306 : "inactive");
10307 vty_out(vty, "\n");
10308
10309 } else
10310 vty_out(vty, " Imported from %pRD:%pFX\n",
10311 (struct prefix_rd *)bgp_dest_get_prefix(
10312 pdest),
10313 (struct prefix_evpn *)
10314 bgp_dest_get_prefix(dest));
10315 }
10316 }
10317
10318 /* Line1 display AS-path, Aggregator */
10319 if (attr->aspath) {
10320 if (json_paths) {
10321 if (!attr->aspath->json)
10322 aspath_str_update(attr->aspath, true);
10323 json_object_lock(attr->aspath->json);
10324 json_object_object_add(json_path, "aspath",
10325 attr->aspath->json);
10326 } else {
10327 if (attr->aspath->segments)
10328 aspath_print_vty(vty, " %s", attr->aspath, "");
10329 else
10330 vty_out(vty, " Local");
10331 }
10332 }
10333
10334 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10335 if (json_paths)
10336 json_object_boolean_true_add(json_path, "removed");
10337 else
10338 vty_out(vty, ", (removed)");
10339 }
10340
10341 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10342 if (json_paths)
10343 json_object_boolean_true_add(json_path, "stale");
10344 else
10345 vty_out(vty, ", (stale)");
10346 }
10347
10348 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10349 if (json_paths) {
10350 json_object_int_add(json_path, "aggregatorAs",
10351 attr->aggregator_as);
10352 json_object_string_addf(json_path, "aggregatorId",
10353 "%pI4", &attr->aggregator_addr);
10354 } else {
10355 vty_out(vty, ", (aggregated by %u %pI4)",
10356 attr->aggregator_as, &attr->aggregator_addr);
10357 }
10358 }
10359
10360 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10361 PEER_FLAG_REFLECTOR_CLIENT)) {
10362 if (json_paths)
10363 json_object_boolean_true_add(json_path,
10364 "rxedFromRrClient");
10365 else
10366 vty_out(vty, ", (Received from a RR-client)");
10367 }
10368
10369 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10370 PEER_FLAG_RSERVER_CLIENT)) {
10371 if (json_paths)
10372 json_object_boolean_true_add(json_path,
10373 "rxedFromRsClient");
10374 else
10375 vty_out(vty, ", (Received from a RS-client)");
10376 }
10377
10378 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10379 if (json_paths)
10380 json_object_boolean_true_add(json_path,
10381 "dampeningHistoryEntry");
10382 else
10383 vty_out(vty, ", (history entry)");
10384 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10385 if (json_paths)
10386 json_object_boolean_true_add(json_path,
10387 "dampeningSuppressed");
10388 else
10389 vty_out(vty, ", (suppressed due to dampening)");
10390 }
10391
10392 if (!json_paths)
10393 vty_out(vty, "\n");
10394
10395 /* Line2 display Next-hop, Neighbor, Router-id */
10396 /* Display the nexthop */
10397
10398 if ((p->family == AF_INET || p->family == AF_ETHERNET ||
10399 p->family == AF_EVPN) &&
10400 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10401 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10402 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10403 || safi == SAFI_EVPN) {
10404 if (json_paths) {
10405 json_object_string_addf(
10406 json_nexthop_global, "ip", "%pI4",
10407 &attr->mp_nexthop_global_in);
10408
10409 if (path->peer->hostname)
10410 json_object_string_add(
10411 json_nexthop_global, "hostname",
10412 path->peer->hostname);
10413 } else {
10414 if (nexthop_hostname)
10415 vty_out(vty, " %pI4(%s)",
10416 &attr->mp_nexthop_global_in,
10417 nexthop_hostname);
10418 else
10419 vty_out(vty, " %pI4",
10420 &attr->mp_nexthop_global_in);
10421 }
10422 } else {
10423 if (json_paths) {
10424 json_object_string_addf(json_nexthop_global,
10425 "ip", "%pI4",
10426 &attr->nexthop);
10427
10428 if (path->peer->hostname)
10429 json_object_string_add(
10430 json_nexthop_global, "hostname",
10431 path->peer->hostname);
10432 } else {
10433 if (nexthop_hostname)
10434 vty_out(vty, " %pI4(%s)",
10435 &attr->nexthop,
10436 nexthop_hostname);
10437 else
10438 vty_out(vty, " %pI4",
10439 &attr->nexthop);
10440 }
10441 }
10442
10443 if (json_paths)
10444 json_object_string_add(json_nexthop_global, "afi",
10445 "ipv4");
10446 } else {
10447 if (json_paths) {
10448 json_object_string_addf(json_nexthop_global, "ip",
10449 "%pI6",
10450 &attr->mp_nexthop_global);
10451
10452 if (path->peer->hostname)
10453 json_object_string_add(json_nexthop_global,
10454 "hostname",
10455 path->peer->hostname);
10456
10457 json_object_string_add(json_nexthop_global, "afi",
10458 "ipv6");
10459 json_object_string_add(json_nexthop_global, "scope",
10460 "global");
10461 } else {
10462 if (nexthop_hostname)
10463 vty_out(vty, " %pI6(%s)",
10464 &attr->mp_nexthop_global,
10465 nexthop_hostname);
10466 else
10467 vty_out(vty, " %pI6",
10468 &attr->mp_nexthop_global);
10469 }
10470 }
10471
10472 /* Display the IGP cost or 'inaccessible' */
10473 if (!CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_VALID)) {
10474 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10475
10476 if (json_paths) {
10477 json_object_boolean_false_add(json_nexthop_global,
10478 "accessible");
10479 json_object_boolean_add(json_nexthop_global,
10480 "importCheckEnabled", import);
10481 } else {
10482 vty_out(vty, " (inaccessible%s)",
10483 import ? ", import-check enabled" : "");
10484 }
10485 } else {
10486 if (bpi_ultimate->extra && bpi_ultimate->extra->igpmetric) {
10487 if (json_paths)
10488 json_object_int_add(
10489 json_nexthop_global, "metric",
10490 bpi_ultimate->extra->igpmetric);
10491 else
10492 vty_out(vty, " (metric %u)",
10493 bpi_ultimate->extra->igpmetric);
10494 }
10495
10496 /* IGP cost is 0, display this only for json */
10497 else {
10498 if (json_paths)
10499 json_object_int_add(json_nexthop_global,
10500 "metric", 0);
10501 }
10502
10503 if (json_paths)
10504 json_object_boolean_true_add(json_nexthop_global,
10505 "accessible");
10506 }
10507
10508 /* Display peer "from" output */
10509 /* This path was originated locally */
10510 if (path->peer == bgp->peer_self) {
10511
10512 if (safi == SAFI_EVPN || (p->family == AF_INET &&
10513 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10514 if (json_paths)
10515 json_object_string_add(json_peer, "peerId",
10516 "0.0.0.0");
10517 else
10518 vty_out(vty, " from 0.0.0.0 ");
10519 } else {
10520 if (json_paths)
10521 json_object_string_add(json_peer, "peerId",
10522 "::");
10523 else
10524 vty_out(vty, " from :: ");
10525 }
10526
10527 if (json_paths)
10528 json_object_string_addf(json_peer, "routerId", "%pI4",
10529 &bgp->router_id);
10530 else
10531 vty_out(vty, "(%pI4)", &bgp->router_id);
10532 }
10533
10534 /* We RXed this path from one of our peers */
10535 else {
10536
10537 if (json_paths) {
10538 json_object_string_addf(json_peer, "peerId", "%pSU",
10539 &path->peer->su);
10540 json_object_string_addf(json_peer, "routerId", "%pI4",
10541 &path->peer->remote_id);
10542
10543 if (path->peer->hostname)
10544 json_object_string_add(json_peer, "hostname",
10545 path->peer->hostname);
10546
10547 if (path->peer->domainname)
10548 json_object_string_add(json_peer, "domainname",
10549 path->peer->domainname);
10550
10551 if (path->peer->conf_if)
10552 json_object_string_add(json_peer, "interface",
10553 path->peer->conf_if);
10554 } else {
10555 if (path->peer->conf_if) {
10556 if (path->peer->hostname
10557 && CHECK_FLAG(path->peer->bgp->flags,
10558 BGP_FLAG_SHOW_HOSTNAME))
10559 vty_out(vty, " from %s(%s)",
10560 path->peer->hostname,
10561 path->peer->conf_if);
10562 else
10563 vty_out(vty, " from %s",
10564 path->peer->conf_if);
10565 } else {
10566 if (path->peer->hostname
10567 && CHECK_FLAG(path->peer->bgp->flags,
10568 BGP_FLAG_SHOW_HOSTNAME))
10569 vty_out(vty, " from %s(%s)",
10570 path->peer->hostname,
10571 path->peer->host);
10572 else
10573 vty_out(vty, " from %pSU",
10574 &path->peer->su);
10575 }
10576
10577 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10578 vty_out(vty, " (%pI4)", &attr->originator_id);
10579 else
10580 vty_out(vty, " (%pI4)", &path->peer->remote_id);
10581 }
10582 }
10583
10584 /*
10585 * Note when vrfid of nexthop is different from that of prefix
10586 */
10587 if (path->extra && path->extra->bgp_orig) {
10588 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10589
10590 if (json_paths) {
10591 const char *vn;
10592
10593 if (path->extra->bgp_orig->inst_type
10594 == BGP_INSTANCE_TYPE_DEFAULT)
10595 vn = VRF_DEFAULT_NAME;
10596 else
10597 vn = path->extra->bgp_orig->name;
10598
10599 json_object_string_add(json_path, "nhVrfName", vn);
10600
10601 if (nexthop_vrfid == VRF_UNKNOWN) {
10602 json_object_int_add(json_path, "nhVrfId", -1);
10603 } else {
10604 json_object_int_add(json_path, "nhVrfId",
10605 (int)nexthop_vrfid);
10606 }
10607 } else {
10608 if (nexthop_vrfid == VRF_UNKNOWN)
10609 vty_out(vty, " vrf ?");
10610 else {
10611 struct vrf *vrf;
10612
10613 vrf = vrf_lookup_by_id(nexthop_vrfid);
10614 vty_out(vty, " vrf %s(%u)",
10615 VRF_LOGNAME(vrf), nexthop_vrfid);
10616 }
10617 }
10618 }
10619
10620 if (nexthop_self) {
10621 if (json_paths) {
10622 json_object_boolean_true_add(json_path,
10623 "announceNexthopSelf");
10624 } else {
10625 vty_out(vty, " announce-nh-self");
10626 }
10627 }
10628
10629 if (!json_paths)
10630 vty_out(vty, "\n");
10631
10632 /* display the link-local nexthop */
10633 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10634 if (json_paths) {
10635 json_nexthop_ll = json_object_new_object();
10636 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10637 &attr->mp_nexthop_local);
10638
10639 if (path->peer->hostname)
10640 json_object_string_add(json_nexthop_ll,
10641 "hostname",
10642 path->peer->hostname);
10643
10644 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10645 json_object_string_add(json_nexthop_ll, "scope",
10646 "link-local");
10647
10648 json_object_boolean_true_add(json_nexthop_ll,
10649 "accessible");
10650
10651 if (!attr->mp_nexthop_prefer_global)
10652 json_object_boolean_true_add(json_nexthop_ll,
10653 "used");
10654 else
10655 json_object_boolean_true_add(
10656 json_nexthop_global, "used");
10657 } else {
10658 vty_out(vty, " (%s) %s\n",
10659 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10660 buf, INET6_ADDRSTRLEN),
10661 attr->mp_nexthop_prefer_global
10662 ? "(prefer-global)"
10663 : "(used)");
10664 }
10665 }
10666 /* If we do not have a link-local nexthop then we must flag the
10667 global as "used" */
10668 else {
10669 if (json_paths)
10670 json_object_boolean_true_add(json_nexthop_global,
10671 "used");
10672 }
10673
10674 if (safi == SAFI_EVPN &&
10675 bgp_evpn_is_esi_valid(&attr->esi)) {
10676 route_vty_out_detail_es_info(vty, path, attr, json_path);
10677 }
10678
10679 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10680 * Int/Ext/Local, Atomic, best */
10681 if (json_paths)
10682 json_object_string_add(json_path, "origin",
10683 bgp_origin_long_str[attr->origin]);
10684 else
10685 vty_out(vty, " Origin %s",
10686 bgp_origin_long_str[attr->origin]);
10687
10688 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10689 if (json_paths)
10690 json_object_int_add(json_path, "metric", attr->med);
10691 else
10692 vty_out(vty, ", metric %u", attr->med);
10693 }
10694
10695 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10696 if (json_paths)
10697 json_object_int_add(json_path, "locPrf",
10698 attr->local_pref);
10699 else
10700 vty_out(vty, ", localpref %u", attr->local_pref);
10701 }
10702
10703 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
10704 if (json_paths)
10705 json_object_int_add(json_path, "aigpMetric",
10706 bgp_attr_get_aigp_metric(attr));
10707 else
10708 vty_out(vty, ", aigp-metric %" PRIu64,
10709 bgp_attr_get_aigp_metric(attr));
10710 }
10711
10712 if (attr->weight != 0) {
10713 if (json_paths)
10714 json_object_int_add(json_path, "weight", attr->weight);
10715 else
10716 vty_out(vty, ", weight %u", attr->weight);
10717 }
10718
10719 if (attr->tag != 0) {
10720 if (json_paths)
10721 json_object_int_add(json_path, "tag", attr->tag);
10722 else
10723 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10724 }
10725
10726 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10727 if (json_paths)
10728 json_object_boolean_false_add(json_path, "valid");
10729 else
10730 vty_out(vty, ", invalid");
10731 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10732 if (json_paths)
10733 json_object_boolean_true_add(json_path, "valid");
10734 else
10735 vty_out(vty, ", valid");
10736 }
10737
10738 if (json_paths)
10739 json_object_int_add(json_path, "version", bn->version);
10740
10741 if (path->peer != bgp->peer_self) {
10742 if (path->peer->as == path->peer->local_as) {
10743 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10744 if (json_paths)
10745 json_object_string_add(
10746 json_peer, "type",
10747 "confed-internal");
10748 else
10749 vty_out(vty, ", confed-internal");
10750 } else {
10751 if (json_paths)
10752 json_object_string_add(
10753 json_peer, "type", "internal");
10754 else
10755 vty_out(vty, ", internal");
10756 }
10757 } else {
10758 if (bgp_confederation_peers_check(bgp,
10759 path->peer->as)) {
10760 if (json_paths)
10761 json_object_string_add(
10762 json_peer, "type",
10763 "confed-external");
10764 else
10765 vty_out(vty, ", confed-external");
10766 } else {
10767 if (json_paths)
10768 json_object_string_add(
10769 json_peer, "type", "external");
10770 else
10771 vty_out(vty, ", external");
10772 }
10773 }
10774 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10775 if (json_paths) {
10776 json_object_boolean_true_add(json_path, "aggregated");
10777 json_object_boolean_true_add(json_path, "local");
10778 } else {
10779 vty_out(vty, ", aggregated, local");
10780 }
10781 } else if (path->type != ZEBRA_ROUTE_BGP) {
10782 if (json_paths)
10783 json_object_boolean_true_add(json_path, "sourced");
10784 else
10785 vty_out(vty, ", sourced");
10786 } else {
10787 if (json_paths) {
10788 json_object_boolean_true_add(json_path, "sourced");
10789 json_object_boolean_true_add(json_path, "local");
10790 } else {
10791 vty_out(vty, ", sourced, local");
10792 }
10793 }
10794
10795 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10796 if (json_paths)
10797 json_object_boolean_true_add(json_path,
10798 "atomicAggregate");
10799 else
10800 vty_out(vty, ", atomic-aggregate");
10801 }
10802
10803 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10804 if (json_paths)
10805 json_object_int_add(json_path, "otc", attr->otc);
10806 else
10807 vty_out(vty, ", otc %u", attr->otc);
10808 }
10809
10810 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10811 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10812 && bgp_path_info_mpath_count(path))) {
10813 if (json_paths)
10814 json_object_boolean_true_add(json_path, "multipath");
10815 else
10816 vty_out(vty, ", multipath");
10817 }
10818
10819 // Mark the bestpath(s)
10820 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10821 first_as = aspath_get_first_as(attr->aspath);
10822
10823 if (json_paths) {
10824 if (!json_bestpath)
10825 json_bestpath = json_object_new_object();
10826 json_object_int_add(json_bestpath, "bestpathFromAs",
10827 first_as);
10828 } else {
10829 if (first_as)
10830 vty_out(vty, ", bestpath-from-AS %u", first_as);
10831 else
10832 vty_out(vty, ", bestpath-from-AS Local");
10833 }
10834 }
10835
10836 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10837 if (json_paths) {
10838 if (!json_bestpath)
10839 json_bestpath = json_object_new_object();
10840 json_object_boolean_true_add(json_bestpath, "overall");
10841 json_object_string_add(
10842 json_bestpath, "selectionReason",
10843 bgp_path_selection_reason2str(bn->reason));
10844 } else {
10845 vty_out(vty, ", best");
10846 vty_out(vty, " (%s)",
10847 bgp_path_selection_reason2str(bn->reason));
10848 }
10849 }
10850
10851 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10852 if (json_paths)
10853 json_object_string_add(
10854 json_path, "rpkiValidationState",
10855 bgp_rpki_validation2str(rpki_curr_state));
10856 else
10857 vty_out(vty, ", rpki validation-state: %s",
10858 bgp_rpki_validation2str(rpki_curr_state));
10859 }
10860
10861 if (json_bestpath)
10862 json_object_object_add(json_path, "bestpath", json_bestpath);
10863
10864 if (!json_paths)
10865 vty_out(vty, "\n");
10866
10867 /* Line 4 display Community */
10868 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10869 if (json_paths) {
10870 if (!bgp_attr_get_community(attr)->json)
10871 community_str(bgp_attr_get_community(attr),
10872 true, true);
10873 json_object_lock(bgp_attr_get_community(attr)->json);
10874 json_object_object_add(
10875 json_path, "community",
10876 bgp_attr_get_community(attr)->json);
10877 } else {
10878 vty_out(vty, " Community: %s\n",
10879 bgp_attr_get_community(attr)->str);
10880 }
10881 }
10882
10883 /* Line 5 display Extended-community */
10884 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10885 if (json_paths) {
10886 json_ext_community = json_object_new_object();
10887 json_object_string_add(
10888 json_ext_community, "string",
10889 bgp_attr_get_ecommunity(attr)->str);
10890 json_object_object_add(json_path, "extendedCommunity",
10891 json_ext_community);
10892 } else {
10893 vty_out(vty, " Extended Community: %s\n",
10894 bgp_attr_get_ecommunity(attr)->str);
10895 }
10896 }
10897
10898 /* Line 6 display Large community */
10899 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10900 if (json_paths) {
10901 if (!bgp_attr_get_lcommunity(attr)->json)
10902 lcommunity_str(bgp_attr_get_lcommunity(attr),
10903 true, true);
10904 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10905 json_object_object_add(
10906 json_path, "largeCommunity",
10907 bgp_attr_get_lcommunity(attr)->json);
10908 } else {
10909 vty_out(vty, " Large Community: %s\n",
10910 bgp_attr_get_lcommunity(attr)->str);
10911 }
10912 }
10913
10914 /* Line 7 display Originator, Cluster-id */
10915 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10916 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10917 char buf[BUFSIZ] = {0};
10918
10919 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10920 if (json_paths)
10921 json_object_string_addf(json_path,
10922 "originatorId", "%pI4",
10923 &attr->originator_id);
10924 else
10925 vty_out(vty, " Originator: %pI4",
10926 &attr->originator_id);
10927 }
10928
10929 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10930 struct cluster_list *cluster =
10931 bgp_attr_get_cluster(attr);
10932 int i;
10933
10934 if (json_paths) {
10935 json_cluster_list = json_object_new_object();
10936 json_cluster_list_list =
10937 json_object_new_array();
10938
10939 for (i = 0; i < cluster->length / 4; i++) {
10940 json_string = json_object_new_string(
10941 inet_ntop(AF_INET,
10942 &cluster->list[i],
10943 buf, sizeof(buf)));
10944 json_object_array_add(
10945 json_cluster_list_list,
10946 json_string);
10947 }
10948
10949 /*
10950 * struct cluster_list does not have
10951 * "str" variable like aspath and community
10952 * do. Add this someday if someone asks
10953 * for it.
10954 * json_object_string_add(json_cluster_list,
10955 * "string", cluster->str);
10956 */
10957 json_object_object_add(json_cluster_list,
10958 "list",
10959 json_cluster_list_list);
10960 json_object_object_add(json_path, "clusterList",
10961 json_cluster_list);
10962 } else {
10963 vty_out(vty, ", Cluster list: ");
10964
10965 for (i = 0; i < cluster->length / 4; i++) {
10966 vty_out(vty, "%pI4 ",
10967 &cluster->list[i]);
10968 }
10969 }
10970 }
10971
10972 if (!json_paths)
10973 vty_out(vty, "\n");
10974 }
10975
10976 if (path->extra && path->extra->damp_info)
10977 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10978
10979 /* Remote Label */
10980 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10981 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10982 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
10983 &bos);
10984
10985 if (json_paths)
10986 json_object_int_add(json_path, "remoteLabel", label);
10987 else
10988 vty_out(vty, " Remote label: %d\n", label);
10989 }
10990
10991 /* Remote SID */
10992 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10993 if (json_paths)
10994 json_object_string_addf(json_path, "remoteSid", "%pI6",
10995 &path->extra->sid[0].sid);
10996 else
10997 vty_out(vty, " Remote SID: %pI6\n",
10998 &path->extra->sid[0].sid);
10999 }
11000
11001 /* Label Index */
11002 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
11003 if (json_paths)
11004 json_object_int_add(json_path, "labelIndex",
11005 attr->label_index);
11006 else
11007 vty_out(vty, " Label Index: %d\n",
11008 attr->label_index);
11009 }
11010
11011 /* Line 8 display Addpath IDs */
11012 if (path->addpath_rx_id
11013 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
11014 if (json_paths) {
11015 json_object_int_add(json_path, "addpathRxId",
11016 path->addpath_rx_id);
11017
11018 /* Keep backwards compatibility with the old API
11019 * by putting TX All's ID in the old field
11020 */
11021 json_object_int_add(
11022 json_path, "addpathTxId",
11023 path->tx_addpath
11024 .addpath_tx_id[BGP_ADDPATH_ALL]);
11025
11026 /* ... but create a specific field for each
11027 * strategy
11028 */
11029 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
11030 json_object_int_add(
11031 json_path,
11032 bgp_addpath_names(i)->id_json_name,
11033 path->tx_addpath.addpath_tx_id[i]);
11034 }
11035 } else {
11036 vty_out(vty, " AddPath ID: RX %u, ",
11037 path->addpath_rx_id);
11038
11039 route_vty_out_tx_ids(vty, &path->tx_addpath);
11040 }
11041 }
11042
11043 /* If we used addpath to TX a non-bestpath we need to display
11044 * "Advertised to" on a path-by-path basis
11045 */
11046 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11047 first = 1;
11048
11049 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11050 addpath_capable =
11051 bgp_addpath_encode_tx(peer, afi, safi);
11052 has_adj = bgp_adj_out_lookup(
11053 peer, path->net,
11054 bgp_addpath_id_for_peer(peer, afi, safi,
11055 &path->tx_addpath));
11056
11057 if ((addpath_capable && has_adj)
11058 || (!addpath_capable && has_adj
11059 && CHECK_FLAG(path->flags,
11060 BGP_PATH_SELECTED))) {
11061 if (json_path && !json_adv_to)
11062 json_adv_to = json_object_new_object();
11063
11064 route_vty_out_advertised_to(
11065 vty, peer, &first,
11066 " Advertised to:", json_adv_to);
11067 }
11068 }
11069
11070 if (json_path) {
11071 if (json_adv_to) {
11072 json_object_object_add(
11073 json_path, "advertisedTo", json_adv_to);
11074 }
11075 } else {
11076 if (!first) {
11077 vty_out(vty, "\n");
11078 }
11079 }
11080 }
11081
11082 /* Line 9 display Uptime */
11083 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11084 if (json_paths) {
11085 json_last_update = json_object_new_object();
11086 json_object_int_add(json_last_update, "epoch", tbuf);
11087 json_object_string_add(json_last_update, "string",
11088 ctime(&tbuf));
11089 json_object_object_add(json_path, "lastUpdate",
11090 json_last_update);
11091 } else
11092 vty_out(vty, " Last update: %s", ctime(&tbuf));
11093
11094 /* Line 10 display PMSI tunnel attribute, if present */
11095 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11096 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11097 bgp_attr_get_pmsi_tnl_type(attr),
11098 PMSI_TNLTYPE_STR_DEFAULT);
11099
11100 if (json_paths) {
11101 json_pmsi = json_object_new_object();
11102 json_object_string_add(json_pmsi, "tunnelType", str);
11103 json_object_int_add(json_pmsi, "label",
11104 label2vni(&attr->label));
11105 json_object_object_add(json_path, "pmsi", json_pmsi);
11106 } else
11107 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11108 str, label2vni(&attr->label));
11109 }
11110
11111 if (path->peer->t_gr_restart &&
11112 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11113 unsigned long gr_remaining =
11114 thread_timer_remain_second(path->peer->t_gr_restart);
11115
11116 if (json_paths) {
11117 json_object_int_add(json_path,
11118 "gracefulRestartSecondsRemaining",
11119 gr_remaining);
11120 } else
11121 vty_out(vty,
11122 " Time until Graceful Restart stale route deleted: %lu\n",
11123 gr_remaining);
11124 }
11125
11126 if (path->peer->t_llgr_stale[afi][safi] &&
11127 bgp_attr_get_community(attr) &&
11128 community_include(bgp_attr_get_community(attr),
11129 COMMUNITY_LLGR_STALE)) {
11130 unsigned long llgr_remaining = thread_timer_remain_second(
11131 path->peer->t_llgr_stale[afi][safi]);
11132
11133 if (json_paths) {
11134 json_object_int_add(json_path, "llgrSecondsRemaining",
11135 llgr_remaining);
11136 } else
11137 vty_out(vty,
11138 " Time until Long-lived stale route deleted: %lu\n",
11139 llgr_remaining);
11140 }
11141
11142 /* Output some debug about internal state of the dest flags */
11143 if (json_paths) {
11144 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11145 json_object_boolean_true_add(json_path, "processScheduled");
11146 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11147 json_object_boolean_true_add(json_path, "userCleared");
11148 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11149 json_object_boolean_true_add(json_path, "labelChanged");
11150 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11151 json_object_boolean_true_add(json_path, "registeredForLabel");
11152 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11153 json_object_boolean_true_add(json_path, "selectDefered");
11154 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11155 json_object_boolean_true_add(json_path, "fibInstalled");
11156 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11157 json_object_boolean_true_add(json_path, "fibPending");
11158
11159 if (json_nexthop_global || json_nexthop_ll) {
11160 json_nexthops = json_object_new_array();
11161
11162 if (json_nexthop_global)
11163 json_object_array_add(json_nexthops,
11164 json_nexthop_global);
11165
11166 if (json_nexthop_ll)
11167 json_object_array_add(json_nexthops,
11168 json_nexthop_ll);
11169
11170 json_object_object_add(json_path, "nexthops",
11171 json_nexthops);
11172 }
11173
11174 json_object_object_add(json_path, "peer", json_peer);
11175 json_object_array_add(json_paths, json_path);
11176 }
11177 }
11178
11179 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11180 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11181 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11182
11183 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11184 afi_t afi, safi_t safi, enum bgp_show_type type,
11185 bool use_json);
11186 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11187 const char *comstr, int exact, afi_t afi,
11188 safi_t safi, uint16_t show_flags);
11189
11190 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11191 struct bgp_table *table, enum bgp_show_type type,
11192 void *output_arg, const char *rd, int is_last,
11193 unsigned long *output_cum, unsigned long *total_cum,
11194 unsigned long *json_header_depth, uint16_t show_flags,
11195 enum rpki_states rpki_target_state)
11196 {
11197 struct bgp_path_info *pi;
11198 struct bgp_dest *dest;
11199 bool header = true;
11200 bool json_detail_header = false;
11201 int display;
11202 unsigned long output_count = 0;
11203 unsigned long total_count = 0;
11204 struct prefix *p;
11205 json_object *json_paths = NULL;
11206 int first = 1;
11207 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11208 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11209 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11210 bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
11211 bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
11212
11213 if (output_cum && *output_cum != 0)
11214 header = false;
11215
11216 if (use_json && !*json_header_depth) {
11217 if (all)
11218 *json_header_depth = 1;
11219 else {
11220 vty_out(vty, "{\n");
11221 *json_header_depth = 2;
11222 }
11223
11224 vty_out(vty,
11225 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11226 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11227 " \"localAS\": %u,\n \"routes\": { ",
11228 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11229 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11230 ? VRF_DEFAULT_NAME
11231 : bgp->name,
11232 table->version, &bgp->router_id,
11233 bgp->default_local_pref, bgp->as);
11234 if (rd) {
11235 vty_out(vty, " \"routeDistinguishers\" : {");
11236 ++*json_header_depth;
11237 }
11238 }
11239
11240 if (use_json && rd) {
11241 vty_out(vty, " \"%s\" : { ", rd);
11242 }
11243
11244 /* Check for 'json detail', where we need header output once per dest */
11245 if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
11246 type != bgp_show_type_damp_neighbor &&
11247 type != bgp_show_type_flap_statistics &&
11248 type != bgp_show_type_flap_neighbor)
11249 json_detail_header = true;
11250
11251 /* Start processing of routes. */
11252 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11253 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11254 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11255 bool json_detail = json_detail_header;
11256
11257 pi = bgp_dest_get_bgp_path_info(dest);
11258 if (pi == NULL)
11259 continue;
11260
11261 display = 0;
11262 if (use_json)
11263 json_paths = json_object_new_array();
11264 else
11265 json_paths = NULL;
11266
11267 for (; pi; pi = pi->next) {
11268 struct community *picomm = NULL;
11269
11270 picomm = bgp_attr_get_community(pi->attr);
11271
11272 total_count++;
11273
11274 if (type == bgp_show_type_prefix_version) {
11275 uint32_t version =
11276 strtoul(output_arg, NULL, 10);
11277 if (dest->version < version)
11278 continue;
11279 }
11280
11281 if (type == bgp_show_type_community_alias) {
11282 char *alias = output_arg;
11283 char **communities;
11284 int num;
11285 bool found = false;
11286
11287 if (picomm) {
11288 frrstr_split(picomm->str, " ",
11289 &communities, &num);
11290 for (int i = 0; i < num; i++) {
11291 const char *com2alias =
11292 bgp_community2alias(
11293 communities[i]);
11294 if (!found
11295 && strcmp(alias, com2alias)
11296 == 0)
11297 found = true;
11298 XFREE(MTYPE_TMP,
11299 communities[i]);
11300 }
11301 XFREE(MTYPE_TMP, communities);
11302 }
11303
11304 if (!found &&
11305 bgp_attr_get_lcommunity(pi->attr)) {
11306 frrstr_split(bgp_attr_get_lcommunity(
11307 pi->attr)
11308 ->str,
11309 " ", &communities, &num);
11310 for (int i = 0; i < num; i++) {
11311 const char *com2alias =
11312 bgp_community2alias(
11313 communities[i]);
11314 if (!found
11315 && strcmp(alias, com2alias)
11316 == 0)
11317 found = true;
11318 XFREE(MTYPE_TMP,
11319 communities[i]);
11320 }
11321 XFREE(MTYPE_TMP, communities);
11322 }
11323
11324 if (!found)
11325 continue;
11326 }
11327
11328 if (type == bgp_show_type_rpki) {
11329 if (dest_p->family == AF_INET
11330 || dest_p->family == AF_INET6)
11331 rpki_curr_state = hook_call(
11332 bgp_rpki_prefix_status,
11333 pi->peer, pi->attr, dest_p);
11334 if (rpki_target_state != RPKI_NOT_BEING_USED
11335 && rpki_curr_state != rpki_target_state)
11336 continue;
11337 }
11338
11339 if (type == bgp_show_type_flap_statistics
11340 || type == bgp_show_type_flap_neighbor
11341 || type == bgp_show_type_dampend_paths
11342 || type == bgp_show_type_damp_neighbor) {
11343 if (!(pi->extra && pi->extra->damp_info))
11344 continue;
11345 }
11346 if (type == bgp_show_type_regexp) {
11347 regex_t *regex = output_arg;
11348
11349 if (bgp_regexec(regex, pi->attr->aspath)
11350 == REG_NOMATCH)
11351 continue;
11352 }
11353 if (type == bgp_show_type_prefix_list) {
11354 struct prefix_list *plist = output_arg;
11355
11356 if (prefix_list_apply(plist, dest_p)
11357 != PREFIX_PERMIT)
11358 continue;
11359 }
11360 if (type == bgp_show_type_access_list) {
11361 struct access_list *alist = output_arg;
11362
11363 if (access_list_apply(alist, dest_p) !=
11364 FILTER_PERMIT)
11365 continue;
11366 }
11367 if (type == bgp_show_type_filter_list) {
11368 struct as_list *as_list = output_arg;
11369
11370 if (as_list_apply(as_list, pi->attr->aspath)
11371 != AS_FILTER_PERMIT)
11372 continue;
11373 }
11374 if (type == bgp_show_type_route_map) {
11375 struct route_map *rmap = output_arg;
11376 struct bgp_path_info path;
11377 struct bgp_path_info_extra extra;
11378 struct attr dummy_attr = {};
11379 route_map_result_t ret;
11380
11381 dummy_attr = *pi->attr;
11382
11383 prep_for_rmap_apply(&path, &extra, dest, pi,
11384 pi->peer, &dummy_attr);
11385
11386 ret = route_map_apply(rmap, dest_p, &path);
11387 bgp_attr_flush(&dummy_attr);
11388 if (ret == RMAP_DENYMATCH)
11389 continue;
11390 }
11391 if (type == bgp_show_type_neighbor
11392 || type == bgp_show_type_flap_neighbor
11393 || type == bgp_show_type_damp_neighbor) {
11394 union sockunion *su = output_arg;
11395
11396 if (pi->peer == NULL
11397 || pi->peer->su_remote == NULL
11398 || !sockunion_same(pi->peer->su_remote, su))
11399 continue;
11400 }
11401 if (type == bgp_show_type_cidr_only) {
11402 uint32_t destination;
11403
11404 destination = ntohl(dest_p->u.prefix4.s_addr);
11405 if (IN_CLASSC(destination)
11406 && dest_p->prefixlen == 24)
11407 continue;
11408 if (IN_CLASSB(destination)
11409 && dest_p->prefixlen == 16)
11410 continue;
11411 if (IN_CLASSA(destination)
11412 && dest_p->prefixlen == 8)
11413 continue;
11414 }
11415 if (type == bgp_show_type_prefix_longer) {
11416 p = output_arg;
11417 if (!prefix_match(p, dest_p))
11418 continue;
11419 }
11420 if (type == bgp_show_type_community_all) {
11421 if (!picomm)
11422 continue;
11423 }
11424 if (type == bgp_show_type_community) {
11425 struct community *com = output_arg;
11426
11427 if (!picomm || !community_match(picomm, com))
11428 continue;
11429 }
11430 if (type == bgp_show_type_community_exact) {
11431 struct community *com = output_arg;
11432
11433 if (!picomm || !community_cmp(picomm, com))
11434 continue;
11435 }
11436 if (type == bgp_show_type_community_list) {
11437 struct community_list *list = output_arg;
11438
11439 if (!community_list_match(picomm, list))
11440 continue;
11441 }
11442 if (type == bgp_show_type_community_list_exact) {
11443 struct community_list *list = output_arg;
11444
11445 if (!community_list_exact_match(picomm, list))
11446 continue;
11447 }
11448 if (type == bgp_show_type_lcommunity) {
11449 struct lcommunity *lcom = output_arg;
11450
11451 if (!bgp_attr_get_lcommunity(pi->attr) ||
11452 !lcommunity_match(
11453 bgp_attr_get_lcommunity(pi->attr),
11454 lcom))
11455 continue;
11456 }
11457
11458 if (type == bgp_show_type_lcommunity_exact) {
11459 struct lcommunity *lcom = output_arg;
11460
11461 if (!bgp_attr_get_lcommunity(pi->attr) ||
11462 !lcommunity_cmp(
11463 bgp_attr_get_lcommunity(pi->attr),
11464 lcom))
11465 continue;
11466 }
11467 if (type == bgp_show_type_lcommunity_list) {
11468 struct community_list *list = output_arg;
11469
11470 if (!lcommunity_list_match(
11471 bgp_attr_get_lcommunity(pi->attr),
11472 list))
11473 continue;
11474 }
11475 if (type
11476 == bgp_show_type_lcommunity_list_exact) {
11477 struct community_list *list = output_arg;
11478
11479 if (!lcommunity_list_exact_match(
11480 bgp_attr_get_lcommunity(pi->attr),
11481 list))
11482 continue;
11483 }
11484 if (type == bgp_show_type_lcommunity_all) {
11485 if (!bgp_attr_get_lcommunity(pi->attr))
11486 continue;
11487 }
11488 if (type == bgp_show_type_dampend_paths
11489 || type == bgp_show_type_damp_neighbor) {
11490 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11491 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11492 continue;
11493 }
11494
11495 if (!use_json && header) {
11496 vty_out(vty,
11497 "BGP table version is %" PRIu64
11498 ", local router ID is %pI4, vrf id ",
11499 table->version, &bgp->router_id);
11500 if (bgp->vrf_id == VRF_UNKNOWN)
11501 vty_out(vty, "%s", VRFID_NONE_STR);
11502 else
11503 vty_out(vty, "%u", bgp->vrf_id);
11504 vty_out(vty, "\n");
11505 vty_out(vty, "Default local pref %u, ",
11506 bgp->default_local_pref);
11507 vty_out(vty, "local AS %u\n", bgp->as);
11508 if (!detail_routes) {
11509 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11510 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11511 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11512 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11513 }
11514 if (type == bgp_show_type_dampend_paths
11515 || type == bgp_show_type_damp_neighbor)
11516 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11517 else if (type == bgp_show_type_flap_statistics
11518 || type == bgp_show_type_flap_neighbor)
11519 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11520 else if (!detail_routes)
11521 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11522 : BGP_SHOW_HEADER));
11523 header = false;
11524
11525 } else if (json_detail && json_paths != NULL) {
11526 const struct prefix_rd *prd;
11527 json_object *jtemp;
11528
11529 /* Use common detail header, for most types;
11530 * need a json 'object'.
11531 */
11532
11533 jtemp = json_object_new_object();
11534 prd = bgp_rd_from_dest(dest, safi);
11535
11536 route_vty_out_detail_header(
11537 vty, bgp, dest,
11538 bgp_dest_get_prefix(dest), prd,
11539 table->afi, safi, jtemp);
11540
11541 json_object_array_add(json_paths, jtemp);
11542
11543 json_detail = false;
11544 }
11545
11546 if (rd != NULL && !display && !output_count) {
11547 if (!use_json)
11548 vty_out(vty,
11549 "Route Distinguisher: %s\n",
11550 rd);
11551 }
11552 if (type == bgp_show_type_dampend_paths
11553 || type == bgp_show_type_damp_neighbor)
11554 damp_route_vty_out(vty, dest_p, pi, display,
11555 AFI_IP, safi, use_json,
11556 json_paths);
11557 else if (type == bgp_show_type_flap_statistics
11558 || type == bgp_show_type_flap_neighbor)
11559 flap_route_vty_out(vty, dest_p, pi, display,
11560 AFI_IP, safi, use_json,
11561 json_paths);
11562 else {
11563 if (detail_routes || detail_json) {
11564 const struct prefix_rd *prd = NULL;
11565
11566 if (dest->pdest)
11567 prd = bgp_rd_from_dest(
11568 dest->pdest, safi);
11569
11570 if (!use_json)
11571 route_vty_out_detail_header(
11572 vty, bgp, dest,
11573 bgp_dest_get_prefix(
11574 dest),
11575 prd, table->afi, safi,
11576 NULL);
11577
11578 route_vty_out_detail(
11579 vty, bgp, dest, dest_p, pi,
11580 family2afi(dest_p->family),
11581 safi, RPKI_NOT_BEING_USED,
11582 json_paths);
11583 } else {
11584 route_vty_out(vty, dest_p, pi, display,
11585 safi, json_paths, wide);
11586 }
11587 }
11588 display++;
11589 }
11590
11591 if (display) {
11592 output_count++;
11593 if (!use_json)
11594 continue;
11595
11596 /* encode prefix */
11597 if (dest_p->family == AF_FLOWSPEC) {
11598 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11599
11600
11601 bgp_fs_nlri_get_string(
11602 (unsigned char *)
11603 dest_p->u.prefix_flowspec.ptr,
11604 dest_p->u.prefix_flowspec.prefixlen,
11605 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11606 family2afi(dest_p->u
11607 .prefix_flowspec.family));
11608 if (first)
11609 vty_out(vty, "\"%s/%d\": ", retstr,
11610 dest_p->u.prefix_flowspec
11611 .prefixlen);
11612 else
11613 vty_out(vty, ",\"%s/%d\": ", retstr,
11614 dest_p->u.prefix_flowspec
11615 .prefixlen);
11616 } else {
11617 if (first)
11618 vty_out(vty, "\"%pFX\": ", dest_p);
11619 else
11620 vty_out(vty, ",\"%pFX\": ", dest_p);
11621 }
11622 vty_json(vty, json_paths);
11623 json_paths = NULL;
11624 first = 0;
11625 } else
11626 json_object_free(json_paths);
11627 }
11628
11629 if (output_cum) {
11630 output_count += *output_cum;
11631 *output_cum = output_count;
11632 }
11633 if (total_cum) {
11634 total_count += *total_cum;
11635 *total_cum = total_count;
11636 }
11637 if (use_json) {
11638 if (rd) {
11639 vty_out(vty, " }%s ", (is_last ? "" : ","));
11640 }
11641 if (is_last) {
11642 unsigned long i;
11643 for (i = 0; i < *json_header_depth; ++i)
11644 vty_out(vty, " } ");
11645 if (!all)
11646 vty_out(vty, "\n");
11647 }
11648 } else {
11649 if (is_last) {
11650 /* No route is displayed */
11651 if (output_count == 0) {
11652 if (type == bgp_show_type_normal)
11653 vty_out(vty,
11654 "No BGP prefixes displayed, %ld exist\n",
11655 total_count);
11656 } else
11657 vty_out(vty,
11658 "\nDisplayed %ld routes and %ld total paths\n",
11659 output_count, total_count);
11660 }
11661 }
11662
11663 return CMD_SUCCESS;
11664 }
11665
11666 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11667 struct bgp_table *table, struct prefix_rd *prd_match,
11668 enum bgp_show_type type, void *output_arg,
11669 uint16_t show_flags)
11670 {
11671 struct bgp_dest *dest, *next;
11672 unsigned long output_cum = 0;
11673 unsigned long total_cum = 0;
11674 unsigned long json_header_depth = 0;
11675 struct bgp_table *itable;
11676 bool show_msg;
11677 bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11678
11679 show_msg = (!use_json && type == bgp_show_type_normal);
11680
11681 for (dest = bgp_table_top(table); dest; dest = next) {
11682 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11683
11684 next = bgp_route_next(dest);
11685 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11686 continue;
11687
11688 itable = bgp_dest_get_bgp_table_info(dest);
11689 if (itable != NULL) {
11690 struct prefix_rd prd;
11691 char rd[RD_ADDRSTRLEN];
11692
11693 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11694 prefix_rd2str(&prd, rd, sizeof(rd));
11695 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11696 rd, next == NULL, &output_cum,
11697 &total_cum, &json_header_depth,
11698 show_flags, RPKI_NOT_BEING_USED);
11699 if (next == NULL)
11700 show_msg = false;
11701 }
11702 }
11703 if (show_msg) {
11704 if (output_cum == 0)
11705 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11706 total_cum);
11707 else
11708 vty_out(vty,
11709 "\nDisplayed %ld routes and %ld total paths\n",
11710 output_cum, total_cum);
11711 } else {
11712 if (use_json && output_cum == 0)
11713 vty_out(vty, "{}\n");
11714 }
11715 return CMD_SUCCESS;
11716 }
11717
11718 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11719 enum bgp_show_type type, void *output_arg,
11720 uint16_t show_flags, enum rpki_states rpki_target_state)
11721 {
11722 struct bgp_table *table;
11723 unsigned long json_header_depth = 0;
11724 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11725
11726 if (bgp == NULL) {
11727 bgp = bgp_get_default();
11728 }
11729
11730 if (bgp == NULL) {
11731 if (!use_json)
11732 vty_out(vty, "No BGP process is configured\n");
11733 else
11734 vty_out(vty, "{}\n");
11735 return CMD_WARNING;
11736 }
11737
11738 /* Labeled-unicast routes live in the unicast table. */
11739 if (safi == SAFI_LABELED_UNICAST)
11740 safi = SAFI_UNICAST;
11741
11742 table = bgp->rib[afi][safi];
11743 /* use MPLS and ENCAP specific shows until they are merged */
11744 if (safi == SAFI_MPLS_VPN) {
11745 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11746 output_arg, show_flags);
11747 }
11748
11749 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11750 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11751 output_arg, use_json,
11752 1, NULL, NULL);
11753 }
11754
11755 if (safi == SAFI_EVPN)
11756 return bgp_evpn_show_all_routes(vty, bgp, type, use_json, 0);
11757
11758 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11759 NULL, NULL, &json_header_depth, show_flags,
11760 rpki_target_state);
11761 }
11762
11763 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11764 safi_t safi, uint16_t show_flags)
11765 {
11766 struct listnode *node, *nnode;
11767 struct bgp *bgp;
11768 int is_first = 1;
11769 bool route_output = false;
11770 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11771
11772 if (use_json)
11773 vty_out(vty, "{\n");
11774
11775 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11776 route_output = true;
11777 if (use_json) {
11778 if (!is_first)
11779 vty_out(vty, ",\n");
11780 else
11781 is_first = 0;
11782
11783 vty_out(vty, "\"%s\":",
11784 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11785 ? VRF_DEFAULT_NAME
11786 : bgp->name);
11787 } else {
11788 vty_out(vty, "\nInstance %s:\n",
11789 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11790 ? VRF_DEFAULT_NAME
11791 : bgp->name);
11792 }
11793 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11794 show_flags, RPKI_NOT_BEING_USED);
11795 }
11796
11797 if (use_json)
11798 vty_out(vty, "}\n");
11799 else if (!route_output)
11800 vty_out(vty, "%% BGP instance not found\n");
11801 }
11802
11803 /* Header of detailed BGP route information */
11804 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11805 struct bgp_dest *dest, const struct prefix *p,
11806 const struct prefix_rd *prd, afi_t afi,
11807 safi_t safi, json_object *json)
11808 {
11809 struct bgp_path_info *pi;
11810 struct peer *peer;
11811 struct listnode *node, *nnode;
11812 char buf1[RD_ADDRSTRLEN];
11813 int count = 0;
11814 int best = 0;
11815 int suppress = 0;
11816 int accept_own = 0;
11817 int route_filter_translated_v4 = 0;
11818 int route_filter_v4 = 0;
11819 int route_filter_translated_v6 = 0;
11820 int route_filter_v6 = 0;
11821 int llgr_stale = 0;
11822 int no_llgr = 0;
11823 int accept_own_nexthop = 0;
11824 int blackhole = 0;
11825 int no_export = 0;
11826 int no_advertise = 0;
11827 int local_as = 0;
11828 int no_peer = 0;
11829 int first = 1;
11830 int has_valid_label = 0;
11831 mpls_label_t label = 0;
11832 json_object *json_adv_to = NULL;
11833 uint32_t ttl = 0;
11834 uint32_t bos = 0;
11835 uint32_t exp = 0;
11836
11837 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11838
11839 has_valid_label = bgp_is_valid_label(&label);
11840
11841 if (safi == SAFI_EVPN) {
11842 if (!json) {
11843 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11844 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
11845 : "",
11846 prd ? ":" : "", (struct prefix_evpn *)p);
11847 } else {
11848 json_object_string_add(json, "rd",
11849 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11850 "");
11851 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11852 }
11853 } else {
11854 if (!json) {
11855 vty_out(vty,
11856 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11857 "\n",
11858 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11859 ? prefix_rd2str(prd, buf1,
11860 sizeof(buf1))
11861 : ""),
11862 safi == SAFI_MPLS_VPN ? ":" : "", p,
11863 dest->version);
11864
11865 } else {
11866 json_object_string_addf(json, "prefix", "%pFX", p);
11867 json_object_int_add(json, "version", dest->version);
11868
11869 }
11870 }
11871
11872 if (has_valid_label) {
11873 if (json)
11874 json_object_int_add(json, "localLabel", label);
11875 else
11876 vty_out(vty, "Local label: %d\n", label);
11877 }
11878
11879 if (!json)
11880 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11881 vty_out(vty, "not allocated\n");
11882
11883 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11884 struct community *picomm = NULL;
11885
11886 picomm = bgp_attr_get_community(pi->attr);
11887
11888 count++;
11889 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11890 best = count;
11891 if (bgp_path_suppressed(pi))
11892 suppress = 1;
11893
11894 if (!picomm)
11895 continue;
11896
11897 no_advertise += community_include(
11898 picomm, COMMUNITY_NO_ADVERTISE);
11899 no_export +=
11900 community_include(picomm, COMMUNITY_NO_EXPORT);
11901 local_as +=
11902 community_include(picomm, COMMUNITY_LOCAL_AS);
11903 accept_own +=
11904 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11905 route_filter_translated_v4 += community_include(
11906 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11907 route_filter_translated_v6 += community_include(
11908 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11909 route_filter_v4 += community_include(
11910 picomm, COMMUNITY_ROUTE_FILTER_v4);
11911 route_filter_v6 += community_include(
11912 picomm, COMMUNITY_ROUTE_FILTER_v6);
11913 llgr_stale +=
11914 community_include(picomm, COMMUNITY_LLGR_STALE);
11915 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11916 accept_own_nexthop += community_include(
11917 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11918 blackhole +=
11919 community_include(picomm, COMMUNITY_BLACKHOLE);
11920 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11921 }
11922 }
11923
11924 if (!json) {
11925 vty_out(vty, "Paths: (%d available", count);
11926 if (best) {
11927 vty_out(vty, ", best #%d", best);
11928 if (safi == SAFI_UNICAST) {
11929 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11930 vty_out(vty, ", table %s",
11931 VRF_DEFAULT_NAME);
11932 else
11933 vty_out(vty, ", vrf %s",
11934 bgp->name);
11935 }
11936 } else
11937 vty_out(vty, ", no best path");
11938
11939 if (accept_own)
11940 vty_out(vty,
11941 ", accept own local route exported and imported in different VRF");
11942 else if (route_filter_translated_v4)
11943 vty_out(vty,
11944 ", mark translated RTs for VPNv4 route filtering");
11945 else if (route_filter_v4)
11946 vty_out(vty,
11947 ", attach RT as-is for VPNv4 route filtering");
11948 else if (route_filter_translated_v6)
11949 vty_out(vty,
11950 ", mark translated RTs for VPNv6 route filtering");
11951 else if (route_filter_v6)
11952 vty_out(vty,
11953 ", attach RT as-is for VPNv6 route filtering");
11954 else if (llgr_stale)
11955 vty_out(vty,
11956 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
11957 else if (no_llgr)
11958 vty_out(vty,
11959 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11960 else if (accept_own_nexthop)
11961 vty_out(vty,
11962 ", accept local nexthop");
11963 else if (blackhole)
11964 vty_out(vty, ", inform peer to blackhole prefix");
11965 else if (no_export)
11966 vty_out(vty, ", not advertised to EBGP peer");
11967 else if (no_advertise)
11968 vty_out(vty, ", not advertised to any peer");
11969 else if (local_as)
11970 vty_out(vty, ", not advertised outside local AS");
11971 else if (no_peer)
11972 vty_out(vty,
11973 ", inform EBGP peer not to advertise to their EBGP peers");
11974
11975 if (suppress)
11976 vty_out(vty,
11977 ", Advertisements suppressed by an aggregate.");
11978 vty_out(vty, ")\n");
11979 }
11980
11981 /* If we are not using addpath then we can display Advertised to and
11982 * that will
11983 * show what peers we advertised the bestpath to. If we are using
11984 * addpath
11985 * though then we must display Advertised to on a path-by-path basis. */
11986 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11987 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11988 if (bgp_adj_out_lookup(peer, dest, 0)) {
11989 if (json && !json_adv_to)
11990 json_adv_to = json_object_new_object();
11991
11992 route_vty_out_advertised_to(
11993 vty, peer, &first,
11994 " Advertised to non peer-group peers:\n ",
11995 json_adv_to);
11996 }
11997 }
11998
11999 if (json) {
12000 if (json_adv_to) {
12001 json_object_object_add(json, "advertisedTo",
12002 json_adv_to);
12003 }
12004 } else {
12005 if (first)
12006 vty_out(vty, " Not advertised to any peer");
12007 vty_out(vty, "\n");
12008 }
12009 }
12010 }
12011
12012 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
12013 struct bgp_dest *bgp_node, struct vty *vty,
12014 struct bgp *bgp, afi_t afi, safi_t safi,
12015 json_object *json, enum bgp_path_type pathtype,
12016 int *display, enum rpki_states rpki_target_state)
12017 {
12018 struct bgp_path_info *pi;
12019 int header = 1;
12020 json_object *json_header = NULL;
12021 json_object *json_paths = NULL;
12022 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
12023
12024 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
12025 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
12026
12027 if (p->family == AF_INET || p->family == AF_INET6)
12028 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
12029 pi->peer, pi->attr, p);
12030
12031 if (rpki_target_state != RPKI_NOT_BEING_USED
12032 && rpki_curr_state != rpki_target_state)
12033 continue;
12034
12035 if (json && !json_paths) {
12036 /* Instantiate json_paths only if path is valid */
12037 json_paths = json_object_new_array();
12038 if (pfx_rd)
12039 json_header = json_object_new_object();
12040 else
12041 json_header = json;
12042 }
12043
12044 if (header) {
12045 route_vty_out_detail_header(
12046 vty, bgp, bgp_node,
12047 bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP,
12048 safi, json_header);
12049 header = 0;
12050 }
12051 (*display)++;
12052
12053 if (pathtype == BGP_PATH_SHOW_ALL
12054 || (pathtype == BGP_PATH_SHOW_BESTPATH
12055 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12056 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12057 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12058 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12059 route_vty_out_detail(vty, bgp, bgp_node,
12060 bgp_dest_get_prefix(bgp_node), pi,
12061 AFI_IP, safi, rpki_curr_state,
12062 json_paths);
12063 }
12064
12065 if (json && json_paths) {
12066 json_object_object_add(json_header, "paths", json_paths);
12067
12068 if (pfx_rd)
12069 json_object_object_addf(json, json_header, "%pRD",
12070 pfx_rd);
12071 }
12072 }
12073
12074 /*
12075 * Return rd based on safi
12076 */
12077 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12078 safi_t safi)
12079 {
12080 switch (safi) {
12081 case SAFI_MPLS_VPN:
12082 case SAFI_ENCAP:
12083 case SAFI_EVPN:
12084 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12085 default:
12086 return NULL;
12087 }
12088 }
12089
12090 /* Display specified route of BGP table. */
12091 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12092 struct bgp_table *rib, const char *ip_str,
12093 afi_t afi, safi_t safi,
12094 enum rpki_states rpki_target_state,
12095 struct prefix_rd *prd, int prefix_check,
12096 enum bgp_path_type pathtype, bool use_json)
12097 {
12098 int ret;
12099 int display = 0;
12100 struct prefix match;
12101 struct bgp_dest *dest;
12102 struct bgp_dest *rm;
12103 struct bgp_table *table;
12104 json_object *json = NULL;
12105 json_object *json_paths = NULL;
12106
12107 /* Check IP address argument. */
12108 ret = str2prefix(ip_str, &match);
12109 if (!ret) {
12110 vty_out(vty, "address is malformed\n");
12111 return CMD_WARNING;
12112 }
12113
12114 match.family = afi2family(afi);
12115
12116 if (use_json)
12117 json = json_object_new_object();
12118
12119 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12120 for (dest = bgp_table_top(rib); dest;
12121 dest = bgp_route_next(dest)) {
12122 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12123
12124 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12125 continue;
12126 table = bgp_dest_get_bgp_table_info(dest);
12127 if (!table)
12128 continue;
12129
12130 rm = bgp_node_match(table, &match);
12131 if (rm == NULL)
12132 continue;
12133
12134 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12135 if (prefix_check
12136 && rm_p->prefixlen != match.prefixlen) {
12137 bgp_dest_unlock_node(rm);
12138 continue;
12139 }
12140
12141 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12142 bgp, afi, safi, json, pathtype,
12143 &display, rpki_target_state);
12144
12145 bgp_dest_unlock_node(rm);
12146 }
12147 } else if (safi == SAFI_EVPN) {
12148 struct bgp_dest *longest_pfx;
12149 bool is_exact_pfxlen_match = false;
12150
12151 for (dest = bgp_table_top(rib); dest;
12152 dest = bgp_route_next(dest)) {
12153 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12154
12155 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12156 continue;
12157 table = bgp_dest_get_bgp_table_info(dest);
12158 if (!table)
12159 continue;
12160
12161 longest_pfx = NULL;
12162 is_exact_pfxlen_match = false;
12163 /*
12164 * Search through all the prefixes for a match. The
12165 * pfx's are enumerated in ascending order of pfxlens.
12166 * So, the last pfx match is the longest match. Set
12167 * is_exact_pfxlen_match when we get exact pfxlen match
12168 */
12169 for (rm = bgp_table_top(table); rm;
12170 rm = bgp_route_next(rm)) {
12171 const struct prefix *rm_p =
12172 bgp_dest_get_prefix(rm);
12173 /*
12174 * Get prefixlen of the ip-prefix within type5
12175 * evpn route
12176 */
12177 if (evpn_type5_prefix_match(rm_p, &match)
12178 && rm->info) {
12179 longest_pfx = rm;
12180 int type5_pfxlen =
12181 bgp_evpn_get_type5_prefixlen(
12182 rm_p);
12183 if (type5_pfxlen == match.prefixlen) {
12184 is_exact_pfxlen_match = true;
12185 bgp_dest_unlock_node(rm);
12186 break;
12187 }
12188 }
12189 }
12190
12191 if (!longest_pfx)
12192 continue;
12193
12194 if (prefix_check && !is_exact_pfxlen_match)
12195 continue;
12196
12197 rm = longest_pfx;
12198 bgp_dest_lock_node(rm);
12199
12200 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12201 bgp, afi, safi, json, pathtype,
12202 &display, rpki_target_state);
12203
12204 bgp_dest_unlock_node(rm);
12205 }
12206 } else if (safi == SAFI_FLOWSPEC) {
12207 if (use_json)
12208 json_paths = json_object_new_array();
12209
12210 display = bgp_flowspec_display_match_per_ip(afi, rib,
12211 &match, prefix_check,
12212 vty,
12213 use_json,
12214 json_paths);
12215 if (use_json) {
12216 if (display)
12217 json_object_object_add(json, "paths",
12218 json_paths);
12219 else
12220 json_object_free(json_paths);
12221 }
12222 } else {
12223 dest = bgp_node_match(rib, &match);
12224 if (dest != NULL) {
12225 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12226 if (!prefix_check
12227 || dest_p->prefixlen == match.prefixlen) {
12228 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12229 safi, json, pathtype,
12230 &display, rpki_target_state);
12231 }
12232
12233 bgp_dest_unlock_node(dest);
12234 }
12235 }
12236
12237 if (use_json) {
12238 vty_json(vty, json);
12239 } else {
12240 if (!display) {
12241 vty_out(vty, "%% Network not in table\n");
12242 return CMD_WARNING;
12243 }
12244 }
12245
12246 return CMD_SUCCESS;
12247 }
12248
12249 /* Display specified route of Main RIB */
12250 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12251 afi_t afi, safi_t safi, struct prefix_rd *prd,
12252 int prefix_check, enum bgp_path_type pathtype,
12253 enum rpki_states rpki_target_state, bool use_json)
12254 {
12255 if (!bgp) {
12256 bgp = bgp_get_default();
12257 if (!bgp) {
12258 if (!use_json)
12259 vty_out(vty, "No BGP process is configured\n");
12260 else
12261 vty_out(vty, "{}\n");
12262 return CMD_WARNING;
12263 }
12264 }
12265
12266 /* labeled-unicast routes live in the unicast table */
12267 if (safi == SAFI_LABELED_UNICAST)
12268 safi = SAFI_UNICAST;
12269
12270 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12271 afi, safi, rpki_target_state, prd,
12272 prefix_check, pathtype, use_json);
12273 }
12274
12275 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12276 struct cmd_token **argv, bool exact, afi_t afi,
12277 safi_t safi, bool uj)
12278 {
12279 struct lcommunity *lcom;
12280 struct buffer *b;
12281 int i;
12282 char *str;
12283 int first = 0;
12284 uint16_t show_flags = 0;
12285 int ret;
12286
12287 if (uj)
12288 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12289
12290 b = buffer_new(1024);
12291 for (i = 0; i < argc; i++) {
12292 if (first)
12293 buffer_putc(b, ' ');
12294 else {
12295 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12296 first = 1;
12297 buffer_putstr(b, argv[i]->arg);
12298 }
12299 }
12300 }
12301 buffer_putc(b, '\0');
12302
12303 str = buffer_getstr(b);
12304 buffer_free(b);
12305
12306 lcom = lcommunity_str2com(str);
12307 XFREE(MTYPE_TMP, str);
12308 if (!lcom) {
12309 vty_out(vty, "%% Large-community malformed\n");
12310 return CMD_WARNING;
12311 }
12312
12313 ret = bgp_show(vty, bgp, afi, safi,
12314 (exact ? bgp_show_type_lcommunity_exact
12315 : bgp_show_type_lcommunity),
12316 lcom, show_flags, RPKI_NOT_BEING_USED);
12317
12318 lcommunity_free(&lcom);
12319 return ret;
12320 }
12321
12322 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12323 const char *lcom, bool exact, afi_t afi,
12324 safi_t safi, bool uj)
12325 {
12326 struct community_list *list;
12327 uint16_t show_flags = 0;
12328
12329 if (uj)
12330 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12331
12332
12333 list = community_list_lookup(bgp_clist, lcom, 0,
12334 LARGE_COMMUNITY_LIST_MASTER);
12335 if (list == NULL) {
12336 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12337 lcom);
12338 return CMD_WARNING;
12339 }
12340
12341 return bgp_show(vty, bgp, afi, safi,
12342 (exact ? bgp_show_type_lcommunity_list_exact
12343 : bgp_show_type_lcommunity_list),
12344 list, show_flags, RPKI_NOT_BEING_USED);
12345 }
12346
12347 DEFUN (show_ip_bgp_large_community_list,
12348 show_ip_bgp_large_community_list_cmd,
12349 "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]",
12350 SHOW_STR
12351 IP_STR
12352 BGP_STR
12353 BGP_INSTANCE_HELP_STR
12354 BGP_AFI_HELP_STR
12355 BGP_SAFI_WITH_LABEL_HELP_STR
12356 "Display routes matching the large-community-list\n"
12357 "large-community-list number\n"
12358 "large-community-list name\n"
12359 "Exact match of the large-communities\n"
12360 JSON_STR)
12361 {
12362 afi_t afi = AFI_IP6;
12363 safi_t safi = SAFI_UNICAST;
12364 int idx = 0;
12365 bool exact_match = 0;
12366 struct bgp *bgp = NULL;
12367 bool uj = use_json(argc, argv);
12368
12369 if (uj)
12370 argc--;
12371
12372 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12373 &bgp, uj);
12374 if (!idx)
12375 return CMD_WARNING;
12376
12377 argv_find(argv, argc, "large-community-list", &idx);
12378
12379 const char *clist_number_or_name = argv[++idx]->arg;
12380
12381 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12382 exact_match = 1;
12383
12384 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12385 exact_match, afi, safi, uj);
12386 }
12387 DEFUN (show_ip_bgp_large_community,
12388 show_ip_bgp_large_community_cmd,
12389 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12390 SHOW_STR
12391 IP_STR
12392 BGP_STR
12393 BGP_INSTANCE_HELP_STR
12394 BGP_AFI_HELP_STR
12395 BGP_SAFI_WITH_LABEL_HELP_STR
12396 "Display routes matching the large-communities\n"
12397 "List of large-community numbers\n"
12398 "Exact match of the large-communities\n"
12399 JSON_STR)
12400 {
12401 afi_t afi = AFI_IP6;
12402 safi_t safi = SAFI_UNICAST;
12403 int idx = 0;
12404 bool exact_match = 0;
12405 struct bgp *bgp = NULL;
12406 bool uj = use_json(argc, argv);
12407 uint16_t show_flags = 0;
12408
12409 if (uj) {
12410 argc--;
12411 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12412 }
12413
12414 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12415 &bgp, uj);
12416 if (!idx)
12417 return CMD_WARNING;
12418
12419 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12420 if (argv_find(argv, argc, "exact-match", &idx)) {
12421 argc--;
12422 exact_match = 1;
12423 }
12424 return bgp_show_lcommunity(vty, bgp, argc, argv,
12425 exact_match, afi, safi, uj);
12426 } else
12427 return bgp_show(vty, bgp, afi, safi,
12428 bgp_show_type_lcommunity_all, NULL, show_flags,
12429 RPKI_NOT_BEING_USED);
12430 }
12431
12432 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12433 safi_t safi, struct json_object *json_array);
12434 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12435 safi_t safi, struct json_object *json);
12436
12437
12438 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12439 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12440 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12441 "Display number of prefixes for all afi/safi\n" JSON_STR)
12442 {
12443 bool uj = use_json(argc, argv);
12444 struct bgp *bgp = NULL;
12445 safi_t safi = SAFI_UNICAST;
12446 afi_t afi = AFI_IP6;
12447 int idx = 0;
12448 struct json_object *json_all = NULL;
12449 struct json_object *json_afi_safi = NULL;
12450
12451 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12452 &bgp, false);
12453 if (!idx)
12454 return CMD_WARNING;
12455
12456 if (uj)
12457 json_all = json_object_new_object();
12458
12459 FOREACH_AFI_SAFI (afi, safi) {
12460 /*
12461 * So limit output to those afi/safi pairs that
12462 * actually have something interesting in them
12463 */
12464 if (strmatch(get_afi_safi_str(afi, safi, true),
12465 "Unknown")) {
12466 continue;
12467 }
12468 if (uj) {
12469 json_afi_safi = json_object_new_array();
12470 json_object_object_add(
12471 json_all,
12472 get_afi_safi_str(afi, safi, true),
12473 json_afi_safi);
12474 } else {
12475 json_afi_safi = NULL;
12476 }
12477
12478 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12479 }
12480
12481 if (uj)
12482 vty_json(vty, json_all);
12483
12484 return CMD_SUCCESS;
12485 }
12486
12487 /* BGP route print out function without JSON */
12488 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12489 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12490 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12491 SHOW_STR
12492 IP_STR
12493 BGP_STR
12494 BGP_INSTANCE_HELP_STR
12495 L2VPN_HELP_STR
12496 EVPN_HELP_STR
12497 "BGP RIB advertisement statistics\n"
12498 JSON_STR)
12499 {
12500 afi_t afi = AFI_IP6;
12501 safi_t safi = SAFI_UNICAST;
12502 struct bgp *bgp = NULL;
12503 int idx = 0, ret;
12504 bool uj = use_json(argc, argv);
12505 struct json_object *json_afi_safi = NULL, *json = NULL;
12506
12507 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12508 &bgp, false);
12509 if (!idx)
12510 return CMD_WARNING;
12511
12512 if (uj)
12513 json_afi_safi = json_object_new_array();
12514 else
12515 json_afi_safi = NULL;
12516
12517 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12518
12519 if (uj) {
12520 json = json_object_new_object();
12521 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12522 json_afi_safi);
12523 vty_json(vty, json);
12524 }
12525 return ret;
12526 }
12527
12528 /* BGP route print out function without JSON */
12529 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12530 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12531 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12532 "]]\
12533 statistics [json]",
12534 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12535 BGP_SAFI_WITH_LABEL_HELP_STR
12536 "BGP RIB advertisement statistics\n" JSON_STR)
12537 {
12538 afi_t afi = AFI_IP6;
12539 safi_t safi = SAFI_UNICAST;
12540 struct bgp *bgp = NULL;
12541 int idx = 0, ret;
12542 bool uj = use_json(argc, argv);
12543 struct json_object *json_afi_safi = NULL, *json = NULL;
12544
12545 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12546 &bgp, false);
12547 if (!idx)
12548 return CMD_WARNING;
12549
12550 if (uj)
12551 json_afi_safi = json_object_new_array();
12552 else
12553 json_afi_safi = NULL;
12554
12555 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12556
12557 if (uj) {
12558 json = json_object_new_object();
12559 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12560 json_afi_safi);
12561 vty_json(vty, json);
12562 }
12563 return ret;
12564 }
12565
12566 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12567 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12568 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12569 "]] [all$all] dampening parameters [json]",
12570 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12571 BGP_SAFI_WITH_LABEL_HELP_STR
12572 "Display the entries for all address families\n"
12573 "Display detailed information about dampening\n"
12574 "Display detail of configured dampening parameters\n"
12575 JSON_STR)
12576 {
12577 afi_t afi = AFI_IP6;
12578 safi_t safi = SAFI_UNICAST;
12579 struct bgp *bgp = NULL;
12580 int idx = 0;
12581 uint16_t show_flags = 0;
12582 bool uj = use_json(argc, argv);
12583
12584 if (uj) {
12585 argc--;
12586 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12587 }
12588
12589 /* [<ipv4|ipv6> [all]] */
12590 if (all) {
12591 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12592 if (argv_find(argv, argc, "ipv4", &idx))
12593 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12594
12595 if (argv_find(argv, argc, "ipv6", &idx))
12596 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12597 }
12598
12599 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12600 &bgp, false);
12601 if (!idx)
12602 return CMD_WARNING;
12603
12604 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12605 }
12606
12607 /* BGP route print out function */
12608 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12609 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12610 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12611 "]]\
12612 [all$all]\
12613 [cidr-only\
12614 |dampening <flap-statistics|dampened-paths>\
12615 |community [AA:NN|local-AS|no-advertise|no-export\
12616 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12617 |accept-own|accept-own-nexthop|route-filter-v6\
12618 |route-filter-v4|route-filter-translated-v6\
12619 |route-filter-translated-v4] [exact-match]\
12620 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12621 |filter-list AS_PATH_FILTER_NAME\
12622 |prefix-list WORD\
12623 |access-list ACCESSLIST_NAME\
12624 |route-map RMAP_NAME\
12625 |rpki <invalid|valid|notfound>\
12626 |version (1-4294967295)\
12627 |alias ALIAS_NAME\
12628 |A.B.C.D/M longer-prefixes\
12629 |X:X::X:X/M longer-prefixes\
12630 |detail-routes$detail_routes\
12631 ] [json$uj [detail$detail_json] | wide$wide]",
12632 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12633 BGP_SAFI_WITH_LABEL_HELP_STR
12634 "Display the entries for all address families\n"
12635 "Display only routes with non-natural netmasks\n"
12636 "Display detailed information about dampening\n"
12637 "Display flap statistics of routes\n"
12638 "Display paths suppressed due to dampening\n"
12639 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12640 "Do not send outside local AS (well-known community)\n"
12641 "Do not advertise to any peer (well-known community)\n"
12642 "Do not export to next AS (well-known community)\n"
12643 "Graceful shutdown (well-known community)\n"
12644 "Do not export to any peer (well-known community)\n"
12645 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12646 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12647 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12648 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12649 "Should accept VPN route with local nexthop (well-known community)\n"
12650 "RT VPNv6 route filtering (well-known community)\n"
12651 "RT VPNv4 route filtering (well-known community)\n"
12652 "RT translated VPNv6 route filtering (well-known community)\n"
12653 "RT translated VPNv4 route filtering (well-known community)\n"
12654 "Exact match of the communities\n"
12655 "Community-list number\n"
12656 "Community-list name\n"
12657 "Display routes matching the community-list\n"
12658 "Exact match of the communities\n"
12659 "Display routes conforming to the filter-list\n"
12660 "Regular expression access list name\n"
12661 "Display routes conforming to the prefix-list\n"
12662 "Prefix-list name\n"
12663 "Display routes conforming to the access-list\n"
12664 "Access-list name\n"
12665 "Display routes matching the route-map\n"
12666 "A route-map to match on\n"
12667 "RPKI route types\n"
12668 "A valid path as determined by rpki\n"
12669 "A invalid path as determined by rpki\n"
12670 "A path that has no rpki data\n"
12671 "Display prefixes with matching version numbers\n"
12672 "Version number and above\n"
12673 "Display prefixes with matching BGP community alias\n"
12674 "BGP community alias\n"
12675 "IPv4 prefix\n"
12676 "Display route and more specific routes\n"
12677 "IPv6 prefix\n"
12678 "Display route and more specific routes\n"
12679 "Display detailed version of all routes\n"
12680 JSON_STR
12681 "Display detailed version of JSON output\n"
12682 "Increase table width for longer prefixes\n")
12683 {
12684 afi_t afi = AFI_IP6;
12685 safi_t safi = SAFI_UNICAST;
12686 enum bgp_show_type sh_type = bgp_show_type_normal;
12687 void *output_arg = NULL;
12688 struct bgp *bgp = NULL;
12689 int idx = 0;
12690 int exact_match = 0;
12691 char *community = NULL;
12692 bool first = true;
12693 uint16_t show_flags = 0;
12694 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12695 struct prefix p;
12696
12697 if (uj) {
12698 argc--;
12699 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12700 }
12701
12702 if (detail_json)
12703 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
12704
12705 if (detail_routes)
12706 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
12707
12708 /* [<ipv4|ipv6> [all]] */
12709 if (all) {
12710 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12711
12712 if (argv_find(argv, argc, "ipv4", &idx))
12713 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12714
12715 if (argv_find(argv, argc, "ipv6", &idx))
12716 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12717 }
12718
12719 if (wide)
12720 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12721
12722 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12723 &bgp, uj);
12724 if (!idx)
12725 return CMD_WARNING;
12726
12727 if (argv_find(argv, argc, "cidr-only", &idx))
12728 sh_type = bgp_show_type_cidr_only;
12729
12730 if (argv_find(argv, argc, "dampening", &idx)) {
12731 if (argv_find(argv, argc, "dampened-paths", &idx))
12732 sh_type = bgp_show_type_dampend_paths;
12733 else if (argv_find(argv, argc, "flap-statistics", &idx))
12734 sh_type = bgp_show_type_flap_statistics;
12735 }
12736
12737 if (argv_find(argv, argc, "community", &idx)) {
12738 char *maybecomm = NULL;
12739
12740 if (idx + 1 < argc) {
12741 if (argv[idx + 1]->type == VARIABLE_TKN)
12742 maybecomm = argv[idx + 1]->arg;
12743 else
12744 maybecomm = argv[idx + 1]->text;
12745 }
12746
12747 if (maybecomm && !strmatch(maybecomm, "json")
12748 && !strmatch(maybecomm, "exact-match"))
12749 community = maybecomm;
12750
12751 if (argv_find(argv, argc, "exact-match", &idx))
12752 exact_match = 1;
12753
12754 if (!community)
12755 sh_type = bgp_show_type_community_all;
12756 }
12757
12758 if (argv_find(argv, argc, "community-list", &idx)) {
12759 const char *clist_number_or_name = argv[++idx]->arg;
12760 struct community_list *list;
12761
12762 if (argv_find(argv, argc, "exact-match", &idx))
12763 exact_match = 1;
12764
12765 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12766 COMMUNITY_LIST_MASTER);
12767 if (list == NULL) {
12768 vty_out(vty, "%% %s community-list not found\n",
12769 clist_number_or_name);
12770 return CMD_WARNING;
12771 }
12772
12773 if (exact_match)
12774 sh_type = bgp_show_type_community_list_exact;
12775 else
12776 sh_type = bgp_show_type_community_list;
12777 output_arg = list;
12778 }
12779
12780 if (argv_find(argv, argc, "filter-list", &idx)) {
12781 const char *filter = argv[++idx]->arg;
12782 struct as_list *as_list;
12783
12784 as_list = as_list_lookup(filter);
12785 if (as_list == NULL) {
12786 vty_out(vty, "%% %s AS-path access-list not found\n",
12787 filter);
12788 return CMD_WARNING;
12789 }
12790
12791 sh_type = bgp_show_type_filter_list;
12792 output_arg = as_list;
12793 }
12794
12795 if (argv_find(argv, argc, "prefix-list", &idx)) {
12796 const char *prefix_list_str = argv[++idx]->arg;
12797 struct prefix_list *plist;
12798
12799 plist = prefix_list_lookup(afi, prefix_list_str);
12800 if (plist == NULL) {
12801 vty_out(vty, "%% %s prefix-list not found\n",
12802 prefix_list_str);
12803 return CMD_WARNING;
12804 }
12805
12806 sh_type = bgp_show_type_prefix_list;
12807 output_arg = plist;
12808 }
12809
12810 if (argv_find(argv, argc, "access-list", &idx)) {
12811 const char *access_list_str = argv[++idx]->arg;
12812 struct access_list *alist;
12813
12814 alist = access_list_lookup(afi, access_list_str);
12815 if (!alist) {
12816 vty_out(vty, "%% %s access-list not found\n",
12817 access_list_str);
12818 return CMD_WARNING;
12819 }
12820
12821 sh_type = bgp_show_type_access_list;
12822 output_arg = alist;
12823 }
12824
12825 if (argv_find(argv, argc, "route-map", &idx)) {
12826 const char *rmap_str = argv[++idx]->arg;
12827 struct route_map *rmap;
12828
12829 rmap = route_map_lookup_by_name(rmap_str);
12830 if (!rmap) {
12831 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12832 return CMD_WARNING;
12833 }
12834
12835 sh_type = bgp_show_type_route_map;
12836 output_arg = rmap;
12837 }
12838
12839 if (argv_find(argv, argc, "rpki", &idx)) {
12840 sh_type = bgp_show_type_rpki;
12841 if (argv_find(argv, argc, "valid", &idx))
12842 rpki_target_state = RPKI_VALID;
12843 else if (argv_find(argv, argc, "invalid", &idx))
12844 rpki_target_state = RPKI_INVALID;
12845 }
12846
12847 /* Display prefixes with matching version numbers */
12848 if (argv_find(argv, argc, "version", &idx)) {
12849 sh_type = bgp_show_type_prefix_version;
12850 output_arg = argv[idx + 1]->arg;
12851 }
12852
12853 /* Display prefixes with matching BGP community alias */
12854 if (argv_find(argv, argc, "alias", &idx)) {
12855 sh_type = bgp_show_type_community_alias;
12856 output_arg = argv[idx + 1]->arg;
12857 }
12858
12859 /* prefix-longer */
12860 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12861 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12862 const char *prefix_str = argv[idx]->arg;
12863
12864 if (!str2prefix(prefix_str, &p)) {
12865 vty_out(vty, "%% Malformed Prefix\n");
12866 return CMD_WARNING;
12867 }
12868
12869 sh_type = bgp_show_type_prefix_longer;
12870 output_arg = &p;
12871 }
12872
12873 if (!all) {
12874 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12875 if (community)
12876 return bgp_show_community(vty, bgp, community,
12877 exact_match, afi, safi,
12878 show_flags);
12879 else
12880 return bgp_show(vty, bgp, afi, safi, sh_type,
12881 output_arg, show_flags,
12882 rpki_target_state);
12883 } else {
12884 struct listnode *node;
12885 struct bgp *abgp;
12886 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12887 * AFI_IP6 */
12888
12889 if (uj)
12890 vty_out(vty, "{\n");
12891
12892 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12893 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12894 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12895 ? AFI_IP
12896 : AFI_IP6;
12897 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12898 FOREACH_SAFI (safi) {
12899 if (!bgp_afi_safi_peer_exists(abgp, afi,
12900 safi))
12901 continue;
12902
12903 if (uj) {
12904 if (first)
12905 first = false;
12906 else
12907 vty_out(vty, ",\n");
12908 vty_out(vty, "\"%s\":{\n",
12909 get_afi_safi_str(afi,
12910 safi,
12911 true));
12912 } else
12913 vty_out(vty,
12914 "\nFor address family: %s\n",
12915 get_afi_safi_str(
12916 afi, safi,
12917 false));
12918
12919 if (community)
12920 bgp_show_community(
12921 vty, abgp, community,
12922 exact_match, afi, safi,
12923 show_flags);
12924 else
12925 bgp_show(vty, abgp, afi, safi,
12926 sh_type, output_arg,
12927 show_flags,
12928 rpki_target_state);
12929 if (uj)
12930 vty_out(vty, "}\n");
12931 }
12932 }
12933 } else {
12934 /* show <ip> bgp all: for each AFI and SAFI*/
12935 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12936 FOREACH_AFI_SAFI (afi, safi) {
12937 if (!bgp_afi_safi_peer_exists(abgp, afi,
12938 safi))
12939 continue;
12940
12941 if (uj) {
12942 if (first)
12943 first = false;
12944 else
12945 vty_out(vty, ",\n");
12946
12947 vty_out(vty, "\"%s\":{\n",
12948 get_afi_safi_str(afi,
12949 safi,
12950 true));
12951 } else
12952 vty_out(vty,
12953 "\nFor address family: %s\n",
12954 get_afi_safi_str(
12955 afi, safi,
12956 false));
12957
12958 if (community)
12959 bgp_show_community(
12960 vty, abgp, community,
12961 exact_match, afi, safi,
12962 show_flags);
12963 else
12964 bgp_show(vty, abgp, afi, safi,
12965 sh_type, output_arg,
12966 show_flags,
12967 rpki_target_state);
12968 if (uj)
12969 vty_out(vty, "}\n");
12970 }
12971 }
12972 }
12973 if (uj)
12974 vty_out(vty, "}\n");
12975 }
12976 return CMD_SUCCESS;
12977 }
12978
12979 DEFUN (show_ip_bgp_route,
12980 show_ip_bgp_route_cmd,
12981 "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]",
12982 SHOW_STR
12983 IP_STR
12984 BGP_STR
12985 BGP_INSTANCE_HELP_STR
12986 BGP_AFI_HELP_STR
12987 BGP_SAFI_WITH_LABEL_HELP_STR
12988 "Network in the BGP routing table to display\n"
12989 "IPv4 prefix\n"
12990 "Network in the BGP routing table to display\n"
12991 "IPv6 prefix\n"
12992 "Display only the bestpath\n"
12993 "Display only multipaths\n"
12994 "Display only paths that match the specified rpki state\n"
12995 "A valid path as determined by rpki\n"
12996 "A invalid path as determined by rpki\n"
12997 "A path that has no rpki data\n"
12998 JSON_STR)
12999 {
13000 int prefix_check = 0;
13001
13002 afi_t afi = AFI_IP6;
13003 safi_t safi = SAFI_UNICAST;
13004 char *prefix = NULL;
13005 struct bgp *bgp = NULL;
13006 enum bgp_path_type path_type;
13007 bool uj = use_json(argc, argv);
13008
13009 int idx = 0;
13010
13011 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13012 &bgp, uj);
13013 if (!idx)
13014 return CMD_WARNING;
13015
13016 if (!bgp) {
13017 vty_out(vty,
13018 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
13019 return CMD_WARNING;
13020 }
13021
13022 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
13023 if (argv_find(argv, argc, "A.B.C.D", &idx)
13024 || argv_find(argv, argc, "X:X::X:X", &idx))
13025 prefix_check = 0;
13026 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
13027 || argv_find(argv, argc, "X:X::X:X/M", &idx))
13028 prefix_check = 1;
13029
13030 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
13031 && afi != AFI_IP6) {
13032 vty_out(vty,
13033 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
13034 return CMD_WARNING;
13035 }
13036 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
13037 && afi != AFI_IP) {
13038 vty_out(vty,
13039 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13040 return CMD_WARNING;
13041 }
13042
13043 prefix = argv[idx]->arg;
13044
13045 /* [<bestpath|multipath>] */
13046 if (argv_find(argv, argc, "bestpath", &idx))
13047 path_type = BGP_PATH_SHOW_BESTPATH;
13048 else if (argv_find(argv, argc, "multipath", &idx))
13049 path_type = BGP_PATH_SHOW_MULTIPATH;
13050 else
13051 path_type = BGP_PATH_SHOW_ALL;
13052
13053 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13054 path_type, RPKI_NOT_BEING_USED, uj);
13055 }
13056
13057 DEFUN (show_ip_bgp_regexp,
13058 show_ip_bgp_regexp_cmd,
13059 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13060 SHOW_STR
13061 IP_STR
13062 BGP_STR
13063 BGP_INSTANCE_HELP_STR
13064 BGP_AFI_HELP_STR
13065 BGP_SAFI_WITH_LABEL_HELP_STR
13066 "Display routes matching the AS path regular expression\n"
13067 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13068 JSON_STR)
13069 {
13070 afi_t afi = AFI_IP6;
13071 safi_t safi = SAFI_UNICAST;
13072 struct bgp *bgp = NULL;
13073 bool uj = use_json(argc, argv);
13074 char *regstr = NULL;
13075
13076 int idx = 0;
13077 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13078 &bgp, false);
13079 if (!idx)
13080 return CMD_WARNING;
13081
13082 // get index of regex
13083 if (argv_find(argv, argc, "REGEX", &idx))
13084 regstr = argv[idx]->arg;
13085
13086 assert(regstr);
13087 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13088 bgp_show_type_regexp, uj);
13089 }
13090
13091 DEFPY (show_ip_bgp_instance_all,
13092 show_ip_bgp_instance_all_cmd,
13093 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13094 SHOW_STR
13095 IP_STR
13096 BGP_STR
13097 BGP_INSTANCE_ALL_HELP_STR
13098 BGP_AFI_HELP_STR
13099 BGP_SAFI_WITH_LABEL_HELP_STR
13100 JSON_STR
13101 "Increase table width for longer prefixes\n")
13102 {
13103 afi_t afi = AFI_IP6;
13104 safi_t safi = SAFI_UNICAST;
13105 struct bgp *bgp = NULL;
13106 int idx = 0;
13107 uint16_t show_flags = 0;
13108
13109 if (uj) {
13110 argc--;
13111 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13112 }
13113
13114 if (wide)
13115 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13116
13117 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13118 &bgp, uj);
13119 if (!idx)
13120 return CMD_WARNING;
13121
13122 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13123 return CMD_SUCCESS;
13124 }
13125
13126 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13127 afi_t afi, safi_t safi, enum bgp_show_type type,
13128 bool use_json)
13129 {
13130 regex_t *regex;
13131 int rc;
13132 uint16_t show_flags = 0;
13133
13134 if (use_json)
13135 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13136
13137 if (!config_bgp_aspath_validate(regstr)) {
13138 vty_out(vty, "Invalid character in REGEX %s\n",
13139 regstr);
13140 return CMD_WARNING_CONFIG_FAILED;
13141 }
13142
13143 regex = bgp_regcomp(regstr);
13144 if (!regex) {
13145 vty_out(vty, "Can't compile regexp %s\n", regstr);
13146 return CMD_WARNING;
13147 }
13148
13149 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13150 RPKI_NOT_BEING_USED);
13151 bgp_regex_free(regex);
13152 return rc;
13153 }
13154
13155 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13156 const char *comstr, int exact, afi_t afi,
13157 safi_t safi, uint16_t show_flags)
13158 {
13159 struct community *com;
13160 int ret = 0;
13161
13162 com = community_str2com(comstr);
13163 if (!com) {
13164 vty_out(vty, "%% Community malformed: %s\n", comstr);
13165 return CMD_WARNING;
13166 }
13167
13168 ret = bgp_show(vty, bgp, afi, safi,
13169 (exact ? bgp_show_type_community_exact
13170 : bgp_show_type_community),
13171 com, show_flags, RPKI_NOT_BEING_USED);
13172 community_free(&com);
13173
13174 return ret;
13175 }
13176
13177 enum bgp_stats {
13178 BGP_STATS_MAXBITLEN = 0,
13179 BGP_STATS_RIB,
13180 BGP_STATS_PREFIXES,
13181 BGP_STATS_TOTPLEN,
13182 BGP_STATS_UNAGGREGATEABLE,
13183 BGP_STATS_MAX_AGGREGATEABLE,
13184 BGP_STATS_AGGREGATES,
13185 BGP_STATS_SPACE,
13186 BGP_STATS_ASPATH_COUNT,
13187 BGP_STATS_ASPATH_MAXHOPS,
13188 BGP_STATS_ASPATH_TOTHOPS,
13189 BGP_STATS_ASPATH_MAXSIZE,
13190 BGP_STATS_ASPATH_TOTSIZE,
13191 BGP_STATS_ASN_HIGHEST,
13192 BGP_STATS_MAX,
13193 };
13194
13195 #define TABLE_STATS_IDX_VTY 0
13196 #define TABLE_STATS_IDX_JSON 1
13197
13198 static const char *table_stats_strs[][2] = {
13199 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13200 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13201 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13202 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13203 "unaggregateablePrefixes"},
13204 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13205 "maximumAggregateablePrefixes"},
13206 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13207 "bgpAggregateAdvertisements"},
13208 [BGP_STATS_SPACE] = {"Address space advertised",
13209 "addressSpaceAdvertised"},
13210 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13211 "advertisementsWithPaths"},
13212 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13213 "longestAsPath"},
13214 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13215 "largestAsPath"},
13216 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13217 "averageAsPathLengthHops"},
13218 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13219 "averageAsPathSizeBytes"},
13220 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13221 [BGP_STATS_MAX] = {NULL, NULL}
13222 };
13223
13224 struct bgp_table_stats {
13225 struct bgp_table *table;
13226 unsigned long long counts[BGP_STATS_MAX];
13227
13228 unsigned long long
13229 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13230 1];
13231
13232 double total_space;
13233 };
13234
13235 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13236 struct bgp_table_stats *ts, unsigned int space)
13237 {
13238 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13239 struct bgp_path_info *pi;
13240 const struct prefix *rn_p;
13241
13242 if (!bgp_dest_has_bgp_path_info_data(dest))
13243 return;
13244
13245 rn_p = bgp_dest_get_prefix(dest);
13246 ts->counts[BGP_STATS_PREFIXES]++;
13247 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13248
13249 ts->prefix_len_count[rn_p->prefixlen]++;
13250 /* check if the prefix is included by any other announcements */
13251 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13252 pdest = bgp_dest_parent_nolock(pdest);
13253
13254 if (pdest == NULL || pdest == top) {
13255 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13256 /* announced address space */
13257 if (space)
13258 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13259 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13260 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13261
13262
13263 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13264 ts->counts[BGP_STATS_RIB]++;
13265
13266 if (CHECK_FLAG(pi->attr->flag,
13267 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13268 ts->counts[BGP_STATS_AGGREGATES]++;
13269
13270 /* as-path stats */
13271 if (pi->attr->aspath) {
13272 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13273 unsigned int size = aspath_size(pi->attr->aspath);
13274 as_t highest = aspath_highest(pi->attr->aspath);
13275
13276 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13277
13278 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13279 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13280
13281 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13282 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13283
13284 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13285 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13286 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13287 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13288 }
13289 }
13290 }
13291
13292 static void bgp_table_stats_walker(struct thread *t)
13293 {
13294 struct bgp_dest *dest, *ndest;
13295 struct bgp_dest *top;
13296 struct bgp_table_stats *ts = THREAD_ARG(t);
13297 unsigned int space = 0;
13298
13299 if (!(top = bgp_table_top(ts->table)))
13300 return;
13301
13302 switch (ts->table->afi) {
13303 case AFI_IP:
13304 space = IPV4_MAX_BITLEN;
13305 break;
13306 case AFI_IP6:
13307 space = IPV6_MAX_BITLEN;
13308 break;
13309 case AFI_L2VPN:
13310 space = EVPN_ROUTE_PREFIXLEN;
13311 break;
13312 default:
13313 return;
13314 }
13315
13316 ts->counts[BGP_STATS_MAXBITLEN] = space;
13317
13318 for (dest = top; dest; dest = bgp_route_next(dest)) {
13319 if (ts->table->safi == SAFI_MPLS_VPN
13320 || ts->table->safi == SAFI_ENCAP
13321 || ts->table->safi == SAFI_EVPN) {
13322 struct bgp_table *table;
13323
13324 table = bgp_dest_get_bgp_table_info(dest);
13325 if (!table)
13326 continue;
13327
13328 top = bgp_table_top(table);
13329 for (ndest = bgp_table_top(table); ndest;
13330 ndest = bgp_route_next(ndest))
13331 bgp_table_stats_rn(ndest, top, ts, space);
13332 } else {
13333 bgp_table_stats_rn(dest, top, ts, space);
13334 }
13335 }
13336 }
13337
13338 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13339 struct json_object *json_array)
13340 {
13341 struct listnode *node, *nnode;
13342 struct bgp *bgp;
13343
13344 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13345 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13346 }
13347
13348 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13349 safi_t safi, struct json_object *json_array)
13350 {
13351 struct bgp_table_stats ts;
13352 unsigned int i;
13353 int ret = CMD_SUCCESS;
13354 char temp_buf[20];
13355 struct json_object *json = NULL;
13356 uint32_t bitlen = 0;
13357 struct json_object *json_bitlen;
13358
13359 if (json_array)
13360 json = json_object_new_object();
13361
13362 if (!bgp->rib[afi][safi]) {
13363 char warning_msg[50];
13364
13365 snprintf(warning_msg, sizeof(warning_msg),
13366 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13367 safi);
13368
13369 if (!json)
13370 vty_out(vty, "%s\n", warning_msg);
13371 else
13372 json_object_string_add(json, "warning", warning_msg);
13373
13374 ret = CMD_WARNING;
13375 goto end_table_stats;
13376 }
13377
13378 if (!json)
13379 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13380 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13381 else
13382 json_object_string_add(json, "instance", bgp->name_pretty);
13383
13384 /* labeled-unicast routes live in the unicast table */
13385 if (safi == SAFI_LABELED_UNICAST)
13386 safi = SAFI_UNICAST;
13387
13388 memset(&ts, 0, sizeof(ts));
13389 ts.table = bgp->rib[afi][safi];
13390 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13391
13392 for (i = 0; i < BGP_STATS_MAX; i++) {
13393 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13394 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13395 continue;
13396
13397 switch (i) {
13398 case BGP_STATS_ASPATH_TOTHOPS:
13399 case BGP_STATS_ASPATH_TOTSIZE:
13400 if (!json) {
13401 snprintf(
13402 temp_buf, sizeof(temp_buf), "%12.2f",
13403 ts.counts[i]
13404 ? (float)ts.counts[i]
13405 / (float)ts.counts
13406 [BGP_STATS_ASPATH_COUNT]
13407 : 0);
13408 vty_out(vty, "%-30s: %s",
13409 table_stats_strs[i]
13410 [TABLE_STATS_IDX_VTY],
13411 temp_buf);
13412 } else {
13413 json_object_double_add(
13414 json,
13415 table_stats_strs[i]
13416 [TABLE_STATS_IDX_JSON],
13417 ts.counts[i]
13418 ? (double)ts.counts[i]
13419 / (double)ts.counts
13420 [BGP_STATS_ASPATH_COUNT]
13421 : 0);
13422 }
13423 break;
13424 case BGP_STATS_TOTPLEN:
13425 if (!json) {
13426 snprintf(
13427 temp_buf, sizeof(temp_buf), "%12.2f",
13428 ts.counts[i]
13429 ? (float)ts.counts[i]
13430 / (float)ts.counts
13431 [BGP_STATS_PREFIXES]
13432 : 0);
13433 vty_out(vty, "%-30s: %s",
13434 table_stats_strs[i]
13435 [TABLE_STATS_IDX_VTY],
13436 temp_buf);
13437 } else {
13438 json_object_double_add(
13439 json,
13440 table_stats_strs[i]
13441 [TABLE_STATS_IDX_JSON],
13442 ts.counts[i]
13443 ? (double)ts.counts[i]
13444 / (double)ts.counts
13445 [BGP_STATS_PREFIXES]
13446 : 0);
13447 }
13448 break;
13449 case BGP_STATS_SPACE:
13450 if (!json) {
13451 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13452 ts.total_space);
13453 vty_out(vty, "%-30s: %s\n",
13454 table_stats_strs[i]
13455 [TABLE_STATS_IDX_VTY],
13456 temp_buf);
13457 } else {
13458 json_object_double_add(
13459 json,
13460 table_stats_strs[i]
13461 [TABLE_STATS_IDX_JSON],
13462 (double)ts.total_space);
13463 }
13464 if (afi == AFI_IP6) {
13465 if (!json) {
13466 snprintf(temp_buf, sizeof(temp_buf),
13467 "%12g",
13468 ts.total_space
13469 * pow(2.0, -128 + 32));
13470 vty_out(vty, "%30s: %s\n",
13471 "/32 equivalent %s\n",
13472 temp_buf);
13473 } else {
13474 json_object_double_add(
13475 json, "/32equivalent",
13476 (double)(ts.total_space
13477 * pow(2.0,
13478 -128 + 32)));
13479 }
13480 if (!json) {
13481 snprintf(temp_buf, sizeof(temp_buf),
13482 "%12g",
13483 ts.total_space
13484 * pow(2.0, -128 + 48));
13485 vty_out(vty, "%30s: %s\n",
13486 "/48 equivalent %s\n",
13487 temp_buf);
13488 } else {
13489 json_object_double_add(
13490 json, "/48equivalent",
13491 (double)(ts.total_space
13492 * pow(2.0,
13493 -128 + 48)));
13494 }
13495 } else {
13496 if (!json) {
13497 snprintf(temp_buf, sizeof(temp_buf),
13498 "%12.2f",
13499 ts.total_space * 100.
13500 * pow(2.0, -32));
13501 vty_out(vty, "%30s: %s\n",
13502 "% announced ", temp_buf);
13503 } else {
13504 json_object_double_add(
13505 json, "%announced",
13506 (double)(ts.total_space * 100.
13507 * pow(2.0, -32)));
13508 }
13509 if (!json) {
13510 snprintf(temp_buf, sizeof(temp_buf),
13511 "%12.2f",
13512 ts.total_space
13513 * pow(2.0, -32 + 8));
13514 vty_out(vty, "%30s: %s\n",
13515 "/8 equivalent ", temp_buf);
13516 } else {
13517 json_object_double_add(
13518 json, "/8equivalent",
13519 (double)(ts.total_space
13520 * pow(2.0, -32 + 8)));
13521 }
13522 if (!json) {
13523 snprintf(temp_buf, sizeof(temp_buf),
13524 "%12.2f",
13525 ts.total_space
13526 * pow(2.0, -32 + 24));
13527 vty_out(vty, "%30s: %s\n",
13528 "/24 equivalent ", temp_buf);
13529 } else {
13530 json_object_double_add(
13531 json, "/24equivalent",
13532 (double)(ts.total_space
13533 * pow(2.0, -32 + 24)));
13534 }
13535 }
13536 break;
13537 default:
13538 if (!json) {
13539 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13540 ts.counts[i]);
13541 vty_out(vty, "%-30s: %s",
13542 table_stats_strs[i]
13543 [TABLE_STATS_IDX_VTY],
13544 temp_buf);
13545 } else {
13546 json_object_int_add(
13547 json,
13548 table_stats_strs[i]
13549 [TABLE_STATS_IDX_JSON],
13550 ts.counts[i]);
13551 }
13552 }
13553 if (!json)
13554 vty_out(vty, "\n");
13555 }
13556
13557 switch (afi) {
13558 case AFI_IP:
13559 bitlen = IPV4_MAX_BITLEN;
13560 break;
13561 case AFI_IP6:
13562 bitlen = IPV6_MAX_BITLEN;
13563 break;
13564 case AFI_L2VPN:
13565 bitlen = EVPN_ROUTE_PREFIXLEN;
13566 break;
13567 default:
13568 break;
13569 }
13570
13571 if (json) {
13572 json_bitlen = json_object_new_array();
13573
13574 for (i = 0; i <= bitlen; i++) {
13575 struct json_object *ind_bit = json_object_new_object();
13576
13577 if (!ts.prefix_len_count[i])
13578 continue;
13579
13580 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13581 json_object_int_add(ind_bit, temp_buf,
13582 ts.prefix_len_count[i]);
13583 json_object_array_add(json_bitlen, ind_bit);
13584 }
13585 json_object_object_add(json, "prefixLength", json_bitlen);
13586 }
13587
13588 end_table_stats:
13589 if (json)
13590 json_object_array_add(json_array, json);
13591 return ret;
13592 }
13593
13594 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13595 safi_t safi, struct json_object *json_array)
13596 {
13597 if (!bgp) {
13598 bgp_table_stats_all(vty, afi, safi, json_array);
13599 return CMD_SUCCESS;
13600 }
13601
13602 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13603 }
13604
13605 enum bgp_pcounts {
13606 PCOUNT_ADJ_IN = 0,
13607 PCOUNT_DAMPED,
13608 PCOUNT_REMOVED,
13609 PCOUNT_HISTORY,
13610 PCOUNT_STALE,
13611 PCOUNT_VALID,
13612 PCOUNT_ALL,
13613 PCOUNT_COUNTED,
13614 PCOUNT_BPATH_SELECTED,
13615 PCOUNT_PFCNT, /* the figure we display to users */
13616 PCOUNT_MAX,
13617 };
13618
13619 static const char *const pcount_strs[] = {
13620 [PCOUNT_ADJ_IN] = "Adj-in",
13621 [PCOUNT_DAMPED] = "Damped",
13622 [PCOUNT_REMOVED] = "Removed",
13623 [PCOUNT_HISTORY] = "History",
13624 [PCOUNT_STALE] = "Stale",
13625 [PCOUNT_VALID] = "Valid",
13626 [PCOUNT_ALL] = "All RIB",
13627 [PCOUNT_COUNTED] = "PfxCt counted",
13628 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13629 [PCOUNT_PFCNT] = "Useable",
13630 [PCOUNT_MAX] = NULL,
13631 };
13632
13633 struct peer_pcounts {
13634 unsigned int count[PCOUNT_MAX];
13635 const struct peer *peer;
13636 const struct bgp_table *table;
13637 safi_t safi;
13638 };
13639
13640 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13641 {
13642 const struct bgp_adj_in *ain;
13643 const struct bgp_path_info *pi;
13644 const struct peer *peer = pc->peer;
13645
13646 for (ain = rn->adj_in; ain; ain = ain->next)
13647 if (ain->peer == peer)
13648 pc->count[PCOUNT_ADJ_IN]++;
13649
13650 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13651
13652 if (pi->peer != peer)
13653 continue;
13654
13655 pc->count[PCOUNT_ALL]++;
13656
13657 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13658 pc->count[PCOUNT_DAMPED]++;
13659 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13660 pc->count[PCOUNT_HISTORY]++;
13661 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13662 pc->count[PCOUNT_REMOVED]++;
13663 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13664 pc->count[PCOUNT_STALE]++;
13665 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13666 pc->count[PCOUNT_VALID]++;
13667 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13668 pc->count[PCOUNT_PFCNT]++;
13669 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13670 pc->count[PCOUNT_BPATH_SELECTED]++;
13671
13672 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13673 pc->count[PCOUNT_COUNTED]++;
13674 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13675 flog_err(
13676 EC_LIB_DEVELOPMENT,
13677 "Attempting to count but flags say it is unusable");
13678 } else {
13679 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13680 flog_err(
13681 EC_LIB_DEVELOPMENT,
13682 "Not counted but flags say we should");
13683 }
13684 }
13685 }
13686
13687 static void bgp_peer_count_walker(struct thread *t)
13688 {
13689 struct bgp_dest *rn, *rm;
13690 const struct bgp_table *table;
13691 struct peer_pcounts *pc = THREAD_ARG(t);
13692
13693 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13694 || pc->safi == SAFI_EVPN) {
13695 /* Special handling for 2-level routing tables. */
13696 for (rn = bgp_table_top(pc->table); rn;
13697 rn = bgp_route_next(rn)) {
13698 table = bgp_dest_get_bgp_table_info(rn);
13699 if (table != NULL)
13700 for (rm = bgp_table_top(table); rm;
13701 rm = bgp_route_next(rm))
13702 bgp_peer_count_proc(rm, pc);
13703 }
13704 } else
13705 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13706 bgp_peer_count_proc(rn, pc);
13707 }
13708
13709 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13710 safi_t safi, bool use_json)
13711 {
13712 struct peer_pcounts pcounts = {.peer = peer};
13713 unsigned int i;
13714 json_object *json = NULL;
13715 json_object *json_loop = NULL;
13716
13717 if (use_json) {
13718 json = json_object_new_object();
13719 json_loop = json_object_new_object();
13720 }
13721
13722 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13723 || !peer->bgp->rib[afi][safi]) {
13724 if (use_json) {
13725 json_object_string_add(
13726 json, "warning",
13727 "No such neighbor or address family");
13728 vty_out(vty, "%s\n", json_object_to_json_string(json));
13729 json_object_free(json);
13730 json_object_free(json_loop);
13731 } else
13732 vty_out(vty, "%% No such neighbor or address family\n");
13733
13734 return CMD_WARNING;
13735 }
13736
13737 memset(&pcounts, 0, sizeof(pcounts));
13738 pcounts.peer = peer;
13739 pcounts.table = peer->bgp->rib[afi][safi];
13740 pcounts.safi = safi;
13741
13742 /* in-place call via thread subsystem so as to record execution time
13743 * stats for the thread-walk (i.e. ensure this can't be blamed on
13744 * on just vty_read()).
13745 */
13746 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13747
13748 if (use_json) {
13749 json_object_string_add(json, "prefixCountsFor", peer->host);
13750 json_object_string_add(json, "multiProtocol",
13751 get_afi_safi_str(afi, safi, true));
13752 json_object_int_add(json, "pfxCounter",
13753 peer->pcount[afi][safi]);
13754
13755 for (i = 0; i < PCOUNT_MAX; i++)
13756 json_object_int_add(json_loop, pcount_strs[i],
13757 pcounts.count[i]);
13758
13759 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13760
13761 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13762 json_object_string_add(json, "pfxctDriftFor",
13763 peer->host);
13764 json_object_string_add(
13765 json, "recommended",
13766 "Please report this bug, with the above command output");
13767 }
13768 vty_json(vty, json);
13769 } else {
13770
13771 if (peer->hostname
13772 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13773 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13774 peer->hostname, peer->host,
13775 get_afi_safi_str(afi, safi, false));
13776 } else {
13777 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13778 get_afi_safi_str(afi, safi, false));
13779 }
13780
13781 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13782 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13783
13784 for (i = 0; i < PCOUNT_MAX; i++)
13785 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13786 pcounts.count[i]);
13787
13788 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13789 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13790 vty_out(vty,
13791 "Please report this bug, with the above command output\n");
13792 }
13793 }
13794
13795 return CMD_SUCCESS;
13796 }
13797
13798 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13799 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13800 "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]",
13801 SHOW_STR
13802 IP_STR
13803 BGP_STR
13804 BGP_INSTANCE_HELP_STR
13805 BGP_AFI_HELP_STR
13806 BGP_SAFI_HELP_STR
13807 "Detailed information on TCP and BGP neighbor connections\n"
13808 "Neighbor to display information about\n"
13809 "Neighbor to display information about\n"
13810 "Neighbor on BGP configured interface\n"
13811 "Display detailed prefix count information\n"
13812 JSON_STR)
13813 {
13814 afi_t afi = AFI_IP6;
13815 safi_t safi = SAFI_UNICAST;
13816 struct peer *peer;
13817 int idx = 0;
13818 struct bgp *bgp = NULL;
13819 bool uj = use_json(argc, argv);
13820
13821 if (uj)
13822 argc--;
13823
13824 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13825 &bgp, uj);
13826 if (!idx)
13827 return CMD_WARNING;
13828
13829 argv_find(argv, argc, "neighbors", &idx);
13830 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13831 if (!peer)
13832 return CMD_WARNING;
13833
13834 return bgp_peer_counts(vty, peer, afi, safi, uj);
13835 }
13836
13837 #ifdef KEEP_OLD_VPN_COMMANDS
13838 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13839 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13840 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13841 SHOW_STR
13842 IP_STR
13843 BGP_STR
13844 BGP_VPNVX_HELP_STR
13845 "Display information about all VPNv4 NLRIs\n"
13846 "Detailed information on TCP and BGP neighbor connections\n"
13847 "Neighbor to display information about\n"
13848 "Neighbor to display information about\n"
13849 "Neighbor on BGP configured interface\n"
13850 "Display detailed prefix count information\n"
13851 JSON_STR)
13852 {
13853 int idx_peer = 6;
13854 struct peer *peer;
13855 bool uj = use_json(argc, argv);
13856
13857 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13858 if (!peer)
13859 return CMD_WARNING;
13860
13861 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13862 }
13863
13864 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13865 show_ip_bgp_vpn_all_route_prefix_cmd,
13866 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13867 SHOW_STR
13868 IP_STR
13869 BGP_STR
13870 BGP_VPNVX_HELP_STR
13871 "Display information about all VPNv4 NLRIs\n"
13872 "Network in the BGP routing table to display\n"
13873 "Network in the BGP routing table to display\n"
13874 JSON_STR)
13875 {
13876 int idx = 0;
13877 char *network = NULL;
13878 struct bgp *bgp = bgp_get_default();
13879 if (!bgp) {
13880 vty_out(vty, "Can't find default instance\n");
13881 return CMD_WARNING;
13882 }
13883
13884 if (argv_find(argv, argc, "A.B.C.D", &idx))
13885 network = argv[idx]->arg;
13886 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13887 network = argv[idx]->arg;
13888 else {
13889 vty_out(vty, "Unable to figure out Network\n");
13890 return CMD_WARNING;
13891 }
13892
13893 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13894 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13895 use_json(argc, argv));
13896 }
13897 #endif /* KEEP_OLD_VPN_COMMANDS */
13898
13899 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13900 show_bgp_l2vpn_evpn_route_prefix_cmd,
13901 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13902 SHOW_STR
13903 BGP_STR
13904 L2VPN_HELP_STR
13905 EVPN_HELP_STR
13906 "Network in the BGP routing table to display\n"
13907 "Network in the BGP routing table to display\n"
13908 "Network in the BGP routing table to display\n"
13909 "Network in the BGP routing table to display\n"
13910 JSON_STR)
13911 {
13912 int idx = 0;
13913 char *network = NULL;
13914 int prefix_check = 0;
13915
13916 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13917 argv_find(argv, argc, "X:X::X:X", &idx))
13918 network = argv[idx]->arg;
13919 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13920 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13921 network = argv[idx]->arg;
13922 prefix_check = 1;
13923 } else {
13924 vty_out(vty, "Unable to figure out Network\n");
13925 return CMD_WARNING;
13926 }
13927 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13928 prefix_check, BGP_PATH_SHOW_ALL,
13929 RPKI_NOT_BEING_USED, use_json(argc, argv));
13930 }
13931
13932 static void show_adj_route_header(struct vty *vty, struct peer *peer,
13933 struct bgp_table *table, int *header1,
13934 int *header2, json_object *json,
13935 json_object *json_scode,
13936 json_object *json_ocode, bool wide,
13937 bool detail)
13938 {
13939 uint64_t version = table ? table->version : 0;
13940
13941 if (*header1) {
13942 if (json) {
13943 json_object_int_add(json, "bgpTableVersion", version);
13944 json_object_string_addf(json, "bgpLocalRouterId",
13945 "%pI4", &peer->bgp->router_id);
13946 json_object_int_add(json, "defaultLocPrf",
13947 peer->bgp->default_local_pref);
13948 json_object_int_add(json, "localAS",
13949 peer->change_local_as
13950 ? peer->change_local_as
13951 : peer->local_as);
13952 json_object_object_add(json, "bgpStatusCodes",
13953 json_scode);
13954 json_object_object_add(json, "bgpOriginCodes",
13955 json_ocode);
13956 } else {
13957 vty_out(vty,
13958 "BGP table version is %" PRIu64
13959 ", local router ID is %pI4, vrf id ",
13960 version, &peer->bgp->router_id);
13961 if (peer->bgp->vrf_id == VRF_UNKNOWN)
13962 vty_out(vty, "%s", VRFID_NONE_STR);
13963 else
13964 vty_out(vty, "%u", peer->bgp->vrf_id);
13965 vty_out(vty, "\n");
13966 vty_out(vty, "Default local pref %u, ",
13967 peer->bgp->default_local_pref);
13968 vty_out(vty, "local AS %u\n",
13969 peer->change_local_as ? peer->change_local_as
13970 : peer->local_as);
13971 if (!detail) {
13972 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13973 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13974 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13975 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13976 }
13977 }
13978 *header1 = 0;
13979 }
13980 if (*header2) {
13981 if (!json && !detail)
13982 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
13983 : BGP_SHOW_HEADER));
13984 *header2 = 0;
13985 }
13986 }
13987
13988 static void
13989 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
13990 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
13991 const char *rmap_name, json_object *json, json_object *json_ar,
13992 json_object *json_scode, json_object *json_ocode,
13993 uint16_t show_flags, int *header1, int *header2, char *rd_str,
13994 unsigned long *output_count, unsigned long *filtered_count)
13995 {
13996 struct bgp_adj_in *ain;
13997 struct bgp_adj_out *adj;
13998 struct bgp_dest *dest;
13999 struct bgp *bgp;
14000 struct attr attr;
14001 int ret;
14002 struct update_subgroup *subgrp;
14003 struct peer_af *paf;
14004 bool route_filtered;
14005 bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14006 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14007 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14008 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14009 || (safi == SAFI_EVPN))
14010 ? true
14011 : false;
14012 int display = 0;
14013 json_object *json_net = NULL;
14014
14015 bgp = peer->bgp;
14016
14017 subgrp = peer_subgroup(peer, afi, safi);
14018
14019 if (type == bgp_show_adj_route_advertised && subgrp
14020 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
14021 if (use_json) {
14022 json_object_int_add(json, "bgpTableVersion",
14023 table->version);
14024 json_object_string_addf(json, "bgpLocalRouterId",
14025 "%pI4", &bgp->router_id);
14026 json_object_int_add(json, "defaultLocPrf",
14027 bgp->default_local_pref);
14028 json_object_int_add(json, "localAS",
14029 peer->change_local_as
14030 ? peer->change_local_as
14031 : peer->local_as);
14032 json_object_object_add(json, "bgpStatusCodes",
14033 json_scode);
14034 json_object_object_add(json, "bgpOriginCodes",
14035 json_ocode);
14036 json_object_string_add(
14037 json, "bgpOriginatingDefaultNetwork",
14038 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14039 } else {
14040 vty_out(vty,
14041 "BGP table version is %" PRIu64
14042 ", local router ID is %pI4, vrf id ",
14043 table->version, &bgp->router_id);
14044 if (bgp->vrf_id == VRF_UNKNOWN)
14045 vty_out(vty, "%s", VRFID_NONE_STR);
14046 else
14047 vty_out(vty, "%u", bgp->vrf_id);
14048 vty_out(vty, "\n");
14049 vty_out(vty, "Default local pref %u, ",
14050 bgp->default_local_pref);
14051 vty_out(vty, "local AS %u\n",
14052 peer->change_local_as ? peer->change_local_as
14053 : peer->local_as);
14054 if (!detail) {
14055 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14056 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14057 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14058 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14059 }
14060
14061 vty_out(vty, "Originating default network %s\n\n",
14062 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14063 }
14064 (*output_count)++;
14065 *header1 = 0;
14066 }
14067
14068 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14069 if (type == bgp_show_adj_route_received
14070 || type == bgp_show_adj_route_filtered) {
14071 for (ain = dest->adj_in; ain; ain = ain->next) {
14072 if (ain->peer != peer)
14073 continue;
14074
14075 show_adj_route_header(vty, peer, table, header1,
14076 header2, json, json_scode,
14077 json_ocode, wide, detail);
14078
14079 if ((safi == SAFI_MPLS_VPN)
14080 || (safi == SAFI_ENCAP)
14081 || (safi == SAFI_EVPN)) {
14082 if (use_json)
14083 json_object_string_add(
14084 json_ar, "rd", rd_str);
14085 else if (show_rd && rd_str) {
14086 vty_out(vty,
14087 "Route Distinguisher: %s\n",
14088 rd_str);
14089 show_rd = false;
14090 }
14091 }
14092
14093 attr = *ain->attr;
14094 route_filtered = false;
14095
14096 /* Filter prefix using distribute list,
14097 * filter list or prefix list
14098 */
14099 const struct prefix *rn_p =
14100 bgp_dest_get_prefix(dest);
14101 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14102 safi))
14103 == FILTER_DENY)
14104 route_filtered = true;
14105
14106 /* Filter prefix using route-map */
14107 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14108 safi, rmap_name, NULL,
14109 0, NULL);
14110
14111 if (type == bgp_show_adj_route_filtered &&
14112 !route_filtered && ret != RMAP_DENY) {
14113 bgp_attr_flush(&attr);
14114 continue;
14115 }
14116
14117 if (type == bgp_show_adj_route_received
14118 && (route_filtered || ret == RMAP_DENY))
14119 (*filtered_count)++;
14120
14121 if (detail) {
14122 if (use_json)
14123 json_net =
14124 json_object_new_object();
14125 bgp_show_path_info(
14126 NULL /* prefix_rd */, dest, vty,
14127 bgp, afi, safi, json_net,
14128 BGP_PATH_SHOW_ALL, &display,
14129 RPKI_NOT_BEING_USED);
14130 if (use_json)
14131 json_object_object_addf(
14132 json_ar, json_net,
14133 "%pFX", rn_p);
14134 } else
14135 route_vty_out_tmp(vty, dest, rn_p,
14136 &attr, safi, use_json,
14137 json_ar, wide);
14138 bgp_attr_flush(&attr);
14139 (*output_count)++;
14140 }
14141 } else if (type == bgp_show_adj_route_advertised) {
14142 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14143 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14144 if (paf->peer != peer || !adj->attr)
14145 continue;
14146
14147 show_adj_route_header(
14148 vty, peer, table, header1,
14149 header2, json, json_scode,
14150 json_ocode, wide, detail);
14151
14152 const struct prefix *rn_p =
14153 bgp_dest_get_prefix(dest);
14154
14155 attr = *adj->attr;
14156 ret = bgp_output_modifier(
14157 peer, rn_p, &attr, afi, safi,
14158 rmap_name);
14159
14160 if (ret != RMAP_DENY) {
14161 if ((safi == SAFI_MPLS_VPN)
14162 || (safi == SAFI_ENCAP)
14163 || (safi == SAFI_EVPN)) {
14164 if (use_json)
14165 json_object_string_add(
14166 json_ar,
14167 "rd",
14168 rd_str);
14169 else if (show_rd
14170 && rd_str) {
14171 vty_out(vty,
14172 "Route Distinguisher: %s\n",
14173 rd_str);
14174 show_rd = false;
14175 }
14176 }
14177 if (detail) {
14178 if (use_json)
14179 json_net =
14180 json_object_new_object();
14181 bgp_show_path_info(
14182 NULL /* prefix_rd
14183 */
14184 ,
14185 dest, vty, bgp,
14186 afi, safi,
14187 json_net,
14188 BGP_PATH_SHOW_ALL,
14189 &display,
14190 RPKI_NOT_BEING_USED);
14191 if (use_json)
14192 json_object_object_addf(
14193 json_ar,
14194 json_net,
14195 "%pFX",
14196 rn_p);
14197 } else
14198 route_vty_out_tmp(
14199 vty, dest, rn_p,
14200 &attr, safi,
14201 use_json,
14202 json_ar, wide);
14203 (*output_count)++;
14204 } else {
14205 (*filtered_count)++;
14206 }
14207
14208 bgp_attr_flush(&attr);
14209 }
14210 } else if (type == bgp_show_adj_route_bestpath) {
14211 struct bgp_path_info *pi;
14212
14213 show_adj_route_header(vty, peer, table, header1,
14214 header2, json, json_scode,
14215 json_ocode, wide, detail);
14216
14217 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14218 pi = pi->next) {
14219 if (pi->peer != peer)
14220 continue;
14221
14222 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14223 continue;
14224
14225 route_vty_out_tmp(vty, dest,
14226 bgp_dest_get_prefix(dest),
14227 pi->attr, safi, use_json,
14228 json_ar, wide);
14229 (*output_count)++;
14230 }
14231 }
14232 }
14233 }
14234
14235 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14236 safi_t safi, enum bgp_show_adj_route_type type,
14237 const char *rmap_name, uint16_t show_flags)
14238 {
14239 struct bgp *bgp;
14240 struct bgp_table *table;
14241 json_object *json = NULL;
14242 json_object *json_scode = NULL;
14243 json_object *json_ocode = NULL;
14244 json_object *json_ar = NULL;
14245 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14246
14247 /* Init BGP headers here so they're only displayed once
14248 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14249 */
14250 int header1 = 1;
14251 int header2 = 1;
14252
14253 /*
14254 * Initialize variables for each RD
14255 * All prefixes under an RD is aggregated within "json_routes"
14256 */
14257 char rd_str[BUFSIZ] = {0};
14258 json_object *json_routes = NULL;
14259
14260
14261 /* For 2-tier tables, prefix counts need to be
14262 * maintained across multiple runs of show_adj_route()
14263 */
14264 unsigned long output_count_per_rd;
14265 unsigned long filtered_count_per_rd;
14266 unsigned long output_count = 0;
14267 unsigned long filtered_count = 0;
14268
14269 if (use_json) {
14270 json = json_object_new_object();
14271 json_ar = json_object_new_object();
14272 json_scode = json_object_new_object();
14273 json_ocode = json_object_new_object();
14274 #if CONFDATE > 20231208
14275 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
14276 #endif
14277 json_object_string_add(json_scode, "suppressed", "s");
14278 json_object_string_add(json_scode, "damped", "d");
14279 json_object_string_add(json_scode, "history", "h");
14280 json_object_string_add(json_scode, "valid", "*");
14281 json_object_string_add(json_scode, "best", ">");
14282 json_object_string_add(json_scode, "multipath", "=");
14283 json_object_string_add(json_scode, "internal", "i");
14284 json_object_string_add(json_scode, "ribFailure", "r");
14285 json_object_string_add(json_scode, "stale", "S");
14286 json_object_string_add(json_scode, "removed", "R");
14287
14288 #if CONFDATE > 20231208
14289 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
14290 #endif
14291 json_object_string_add(json_ocode, "igp", "i");
14292 json_object_string_add(json_ocode, "egp", "e");
14293 json_object_string_add(json_ocode, "incomplete", "?");
14294 }
14295
14296 if (!peer || !peer->afc[afi][safi]) {
14297 if (use_json) {
14298 json_object_string_add(
14299 json, "warning",
14300 "No such neighbor or address family");
14301 vty_out(vty, "%s\n", json_object_to_json_string(json));
14302 json_object_free(json);
14303 json_object_free(json_ar);
14304 json_object_free(json_scode);
14305 json_object_free(json_ocode);
14306 } else
14307 vty_out(vty, "%% No such neighbor or address family\n");
14308
14309 return CMD_WARNING;
14310 }
14311
14312 if ((type == bgp_show_adj_route_received
14313 || type == bgp_show_adj_route_filtered)
14314 && !CHECK_FLAG(peer->af_flags[afi][safi],
14315 PEER_FLAG_SOFT_RECONFIG)) {
14316 if (use_json) {
14317 json_object_string_add(
14318 json, "warning",
14319 "Inbound soft reconfiguration not enabled");
14320 vty_out(vty, "%s\n", json_object_to_json_string(json));
14321 json_object_free(json);
14322 json_object_free(json_ar);
14323 json_object_free(json_scode);
14324 json_object_free(json_ocode);
14325 } else
14326 vty_out(vty,
14327 "%% Inbound soft reconfiguration not enabled\n");
14328
14329 return CMD_WARNING;
14330 }
14331
14332 bgp = peer->bgp;
14333
14334 /* labeled-unicast routes live in the unicast table */
14335 if (safi == SAFI_LABELED_UNICAST)
14336 table = bgp->rib[afi][SAFI_UNICAST];
14337 else
14338 table = bgp->rib[afi][safi];
14339
14340 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14341 || (safi == SAFI_EVPN)) {
14342
14343 struct bgp_dest *dest;
14344
14345 for (dest = bgp_table_top(table); dest;
14346 dest = bgp_route_next(dest)) {
14347 table = bgp_dest_get_bgp_table_info(dest);
14348 if (!table)
14349 continue;
14350
14351 output_count_per_rd = 0;
14352 filtered_count_per_rd = 0;
14353
14354 if (use_json)
14355 json_routes = json_object_new_object();
14356
14357 const struct prefix_rd *prd;
14358 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14359 dest);
14360
14361 prefix_rd2str(prd, rd_str, sizeof(rd_str));
14362
14363 show_adj_route(vty, peer, table, afi, safi, type,
14364 rmap_name, json, json_routes, json_scode,
14365 json_ocode, show_flags, &header1,
14366 &header2, rd_str, &output_count_per_rd,
14367 &filtered_count_per_rd);
14368
14369 /* Don't include an empty RD in the output! */
14370 if (json_routes && (output_count_per_rd > 0))
14371 json_object_object_add(json_ar, rd_str,
14372 json_routes);
14373
14374 output_count += output_count_per_rd;
14375 filtered_count += filtered_count_per_rd;
14376 }
14377 } else
14378 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14379 json, json_ar, json_scode, json_ocode,
14380 show_flags, &header1, &header2, rd_str,
14381 &output_count, &filtered_count);
14382
14383 if (use_json) {
14384 if (type == bgp_show_adj_route_advertised)
14385 json_object_object_add(json, "advertisedRoutes",
14386 json_ar);
14387 else
14388 json_object_object_add(json, "receivedRoutes", json_ar);
14389 json_object_int_add(json, "totalPrefixCounter", output_count);
14390 json_object_int_add(json, "filteredPrefixCounter",
14391 filtered_count);
14392
14393 /*
14394 * These fields only give up ownership to `json` when `header1`
14395 * is used (set to zero). See code in `show_adj_route` and
14396 * `show_adj_route_header`.
14397 */
14398 if (header1 == 1) {
14399 json_object_free(json_scode);
14400 json_object_free(json_ocode);
14401 }
14402
14403 vty_json(vty, json);
14404 } else if (output_count > 0) {
14405 if (filtered_count > 0)
14406 vty_out(vty,
14407 "\nTotal number of prefixes %ld (%ld filtered)\n",
14408 output_count, filtered_count);
14409 else
14410 vty_out(vty, "\nTotal number of prefixes %ld\n",
14411 output_count);
14412 }
14413
14414 return CMD_SUCCESS;
14415 }
14416
14417 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14418 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14419 "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]",
14420 SHOW_STR
14421 IP_STR
14422 BGP_STR
14423 BGP_INSTANCE_HELP_STR
14424 BGP_AFI_HELP_STR
14425 BGP_SAFI_WITH_LABEL_HELP_STR
14426 "Detailed information on TCP and BGP neighbor connections\n"
14427 "Neighbor to display information about\n"
14428 "Neighbor to display information about\n"
14429 "Neighbor on BGP configured interface\n"
14430 "Display the routes selected by best path\n"
14431 JSON_STR
14432 "Increase table width for longer prefixes\n")
14433 {
14434 afi_t afi = AFI_IP6;
14435 safi_t safi = SAFI_UNICAST;
14436 char *rmap_name = NULL;
14437 char *peerstr = NULL;
14438 struct bgp *bgp = NULL;
14439 struct peer *peer;
14440 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14441 int idx = 0;
14442 uint16_t show_flags = 0;
14443
14444 if (uj)
14445 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14446
14447 if (wide)
14448 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14449
14450 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14451 &bgp, uj);
14452
14453 if (!idx)
14454 return CMD_WARNING;
14455
14456 argv_find(argv, argc, "neighbors", &idx);
14457 peerstr = argv[++idx]->arg;
14458
14459 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14460 if (!peer)
14461 return CMD_WARNING;
14462
14463 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14464 show_flags);
14465 }
14466
14467 DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
14468 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14469 "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]",
14470 SHOW_STR
14471 IP_STR
14472 BGP_STR
14473 BGP_INSTANCE_HELP_STR
14474 BGP_AFI_HELP_STR
14475 BGP_SAFI_WITH_LABEL_HELP_STR
14476 "Display the entries for all address families\n"
14477 "Detailed information on TCP and BGP neighbor connections\n"
14478 "Neighbor to display information about\n"
14479 "Neighbor to display information about\n"
14480 "Neighbor on BGP configured interface\n"
14481 "Display the routes advertised to a BGP neighbor\n"
14482 "Display the received routes from neighbor\n"
14483 "Display the filtered routes received from neighbor\n"
14484 "Route-map to modify the attributes\n"
14485 "Name of the route map\n"
14486 "Display detailed version of routes\n"
14487 JSON_STR
14488 "Increase table width for longer prefixes\n")
14489 {
14490 afi_t afi = AFI_IP6;
14491 safi_t safi = SAFI_UNICAST;
14492 char *peerstr = NULL;
14493 struct bgp *bgp = NULL;
14494 struct peer *peer;
14495 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14496 int idx = 0;
14497 bool first = true;
14498 uint16_t show_flags = 0;
14499 struct listnode *node;
14500 struct bgp *abgp;
14501
14502 if (detail)
14503 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14504
14505 if (uj) {
14506 argc--;
14507 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14508 }
14509
14510 if (all) {
14511 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14512 if (argv_find(argv, argc, "ipv4", &idx))
14513 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14514
14515 if (argv_find(argv, argc, "ipv6", &idx))
14516 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14517 }
14518
14519 if (wide)
14520 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14521
14522 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14523 &bgp, uj);
14524 if (!idx)
14525 return CMD_WARNING;
14526
14527 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14528 argv_find(argv, argc, "neighbors", &idx);
14529 peerstr = argv[++idx]->arg;
14530
14531 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14532 if (!peer)
14533 return CMD_WARNING;
14534
14535 if (argv_find(argv, argc, "advertised-routes", &idx))
14536 type = bgp_show_adj_route_advertised;
14537 else if (argv_find(argv, argc, "received-routes", &idx))
14538 type = bgp_show_adj_route_received;
14539 else if (argv_find(argv, argc, "filtered-routes", &idx))
14540 type = bgp_show_adj_route_filtered;
14541
14542 if (!all)
14543 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14544 show_flags);
14545 if (uj)
14546 vty_out(vty, "{\n");
14547
14548 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14549 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14550 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14551 : AFI_IP6;
14552 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14553 FOREACH_SAFI (safi) {
14554 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14555 continue;
14556
14557 if (uj) {
14558 if (first)
14559 first = false;
14560 else
14561 vty_out(vty, ",\n");
14562 vty_out(vty, "\"%s\":",
14563 get_afi_safi_str(afi, safi,
14564 true));
14565 } else
14566 vty_out(vty,
14567 "\nFor address family: %s\n",
14568 get_afi_safi_str(afi, safi,
14569 false));
14570
14571 peer_adj_routes(vty, peer, afi, safi, type,
14572 route_map, show_flags);
14573 }
14574 }
14575 } else {
14576 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14577 FOREACH_AFI_SAFI (afi, safi) {
14578 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14579 continue;
14580
14581 if (uj) {
14582 if (first)
14583 first = false;
14584 else
14585 vty_out(vty, ",\n");
14586 vty_out(vty, "\"%s\":",
14587 get_afi_safi_str(afi, safi,
14588 true));
14589 } else
14590 vty_out(vty,
14591 "\nFor address family: %s\n",
14592 get_afi_safi_str(afi, safi,
14593 false));
14594
14595 peer_adj_routes(vty, peer, afi, safi, type,
14596 route_map, show_flags);
14597 }
14598 }
14599 }
14600 if (uj)
14601 vty_out(vty, "}\n");
14602
14603 return CMD_SUCCESS;
14604 }
14605
14606 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14607 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14608 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14609 SHOW_STR
14610 IP_STR
14611 BGP_STR
14612 BGP_INSTANCE_HELP_STR
14613 BGP_AF_STR
14614 BGP_AF_STR
14615 BGP_AF_MODIFIER_STR
14616 "Detailed information on TCP and BGP neighbor connections\n"
14617 "Neighbor to display information about\n"
14618 "Neighbor to display information about\n"
14619 "Neighbor on BGP configured interface\n"
14620 "Display information received from a BGP neighbor\n"
14621 "Display the prefixlist filter\n"
14622 JSON_STR)
14623 {
14624 afi_t afi = AFI_IP6;
14625 safi_t safi = SAFI_UNICAST;
14626 char *peerstr = NULL;
14627 char name[BUFSIZ];
14628 struct peer *peer;
14629 int count;
14630 int idx = 0;
14631 struct bgp *bgp = NULL;
14632 bool uj = use_json(argc, argv);
14633
14634 if (uj)
14635 argc--;
14636
14637 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14638 &bgp, uj);
14639 if (!idx)
14640 return CMD_WARNING;
14641
14642 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14643 argv_find(argv, argc, "neighbors", &idx);
14644 peerstr = argv[++idx]->arg;
14645
14646 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14647 if (!peer)
14648 return CMD_WARNING;
14649
14650 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14651 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14652 if (count) {
14653 if (!uj)
14654 vty_out(vty, "Address Family: %s\n",
14655 get_afi_safi_str(afi, safi, false));
14656 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14657 } else {
14658 if (uj)
14659 vty_out(vty, "{}\n");
14660 else
14661 vty_out(vty, "No functional output\n");
14662 }
14663
14664 return CMD_SUCCESS;
14665 }
14666
14667 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14668 afi_t afi, safi_t safi,
14669 enum bgp_show_type type, bool use_json)
14670 {
14671 uint16_t show_flags = 0;
14672
14673 if (use_json)
14674 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14675
14676 if (!peer || !peer->afc[afi][safi]) {
14677 if (use_json) {
14678 json_object *json_no = NULL;
14679 json_no = json_object_new_object();
14680 json_object_string_add(
14681 json_no, "warning",
14682 "No such neighbor or address family");
14683 vty_out(vty, "%s\n",
14684 json_object_to_json_string(json_no));
14685 json_object_free(json_no);
14686 } else
14687 vty_out(vty, "%% No such neighbor or address family\n");
14688 return CMD_WARNING;
14689 }
14690
14691 /* labeled-unicast routes live in the unicast table */
14692 if (safi == SAFI_LABELED_UNICAST)
14693 safi = SAFI_UNICAST;
14694
14695 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14696 RPKI_NOT_BEING_USED);
14697 }
14698
14699 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14700 show_ip_bgp_flowspec_routes_detailed_cmd,
14701 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14702 SHOW_STR
14703 IP_STR
14704 BGP_STR
14705 BGP_INSTANCE_HELP_STR
14706 BGP_AFI_HELP_STR
14707 "SAFI Flowspec\n"
14708 "Detailed information on flowspec entries\n"
14709 JSON_STR)
14710 {
14711 afi_t afi = AFI_IP6;
14712 safi_t safi = SAFI_UNICAST;
14713 struct bgp *bgp = NULL;
14714 int idx = 0;
14715 bool uj = use_json(argc, argv);
14716 uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
14717
14718 if (uj) {
14719 argc--;
14720 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14721 }
14722
14723 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14724 &bgp, uj);
14725 if (!idx)
14726 return CMD_WARNING;
14727
14728 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14729 show_flags, RPKI_NOT_BEING_USED);
14730 }
14731
14732 DEFUN (show_ip_bgp_neighbor_routes,
14733 show_ip_bgp_neighbor_routes_cmd,
14734 "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]",
14735 SHOW_STR
14736 IP_STR
14737 BGP_STR
14738 BGP_INSTANCE_HELP_STR
14739 BGP_AFI_HELP_STR
14740 BGP_SAFI_WITH_LABEL_HELP_STR
14741 "Detailed information on TCP and BGP neighbor connections\n"
14742 "Neighbor to display information about\n"
14743 "Neighbor to display information about\n"
14744 "Neighbor on BGP configured interface\n"
14745 "Display flap statistics of the routes learned from neighbor\n"
14746 "Display the dampened routes received from neighbor\n"
14747 "Display routes learned from neighbor\n"
14748 JSON_STR)
14749 {
14750 char *peerstr = NULL;
14751 struct bgp *bgp = NULL;
14752 afi_t afi = AFI_IP6;
14753 safi_t safi = SAFI_UNICAST;
14754 struct peer *peer;
14755 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14756 int idx = 0;
14757 bool uj = use_json(argc, argv);
14758
14759 if (uj)
14760 argc--;
14761
14762 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14763 &bgp, uj);
14764 if (!idx)
14765 return CMD_WARNING;
14766
14767 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14768 argv_find(argv, argc, "neighbors", &idx);
14769 peerstr = argv[++idx]->arg;
14770
14771 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14772 if (!peer)
14773 return CMD_WARNING;
14774
14775 if (argv_find(argv, argc, "flap-statistics", &idx))
14776 sh_type = bgp_show_type_flap_neighbor;
14777 else if (argv_find(argv, argc, "dampened-routes", &idx))
14778 sh_type = bgp_show_type_damp_neighbor;
14779 else if (argv_find(argv, argc, "routes", &idx))
14780 sh_type = bgp_show_type_neighbor;
14781
14782 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14783 }
14784
14785 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14786
14787 struct bgp_distance {
14788 /* Distance value for the IP source prefix. */
14789 uint8_t distance;
14790
14791 /* Name of the access-list to be matched. */
14792 char *access_list;
14793 };
14794
14795 DEFUN (show_bgp_afi_vpn_rd_route,
14796 show_bgp_afi_vpn_rd_route_cmd,
14797 "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]",
14798 SHOW_STR
14799 BGP_STR
14800 BGP_AFI_HELP_STR
14801 BGP_AF_MODIFIER_STR
14802 "Display information for a route distinguisher\n"
14803 "Route Distinguisher\n"
14804 "All Route Distinguishers\n"
14805 "Network in the BGP routing table to display\n"
14806 "Network in the BGP routing table to display\n"
14807 JSON_STR)
14808 {
14809 int ret;
14810 struct prefix_rd prd;
14811 afi_t afi = AFI_MAX;
14812 int idx = 0;
14813
14814 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14815 vty_out(vty, "%% Malformed Address Family\n");
14816 return CMD_WARNING;
14817 }
14818
14819 if (!strcmp(argv[5]->arg, "all"))
14820 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14821 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14822 RPKI_NOT_BEING_USED,
14823 use_json(argc, argv));
14824
14825 ret = str2prefix_rd(argv[5]->arg, &prd);
14826 if (!ret) {
14827 vty_out(vty, "%% Malformed Route Distinguisher\n");
14828 return CMD_WARNING;
14829 }
14830
14831 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14832 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14833 use_json(argc, argv));
14834 }
14835
14836 static struct bgp_distance *bgp_distance_new(void)
14837 {
14838 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14839 }
14840
14841 static void bgp_distance_free(struct bgp_distance *bdistance)
14842 {
14843 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14844 }
14845
14846 static int bgp_distance_set(struct vty *vty, const char *distance_str,
14847 const char *ip_str, const char *access_list_str)
14848 {
14849 int ret;
14850 afi_t afi;
14851 safi_t safi;
14852 struct prefix p;
14853 uint8_t distance;
14854 struct bgp_dest *dest;
14855 struct bgp_distance *bdistance;
14856
14857 afi = bgp_node_afi(vty);
14858 safi = bgp_node_safi(vty);
14859
14860 ret = str2prefix(ip_str, &p);
14861 if (ret == 0) {
14862 vty_out(vty, "Malformed prefix\n");
14863 return CMD_WARNING_CONFIG_FAILED;
14864 }
14865
14866 distance = atoi(distance_str);
14867
14868 /* Get BGP distance node. */
14869 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
14870 bdistance = bgp_dest_get_bgp_distance_info(dest);
14871 if (bdistance)
14872 bgp_dest_unlock_node(dest);
14873 else {
14874 bdistance = bgp_distance_new();
14875 bgp_dest_set_bgp_distance_info(dest, bdistance);
14876 }
14877
14878 /* Set distance value. */
14879 bdistance->distance = distance;
14880
14881 /* Reset access-list configuration. */
14882 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14883 if (access_list_str)
14884 bdistance->access_list =
14885 XSTRDUP(MTYPE_AS_LIST, access_list_str);
14886
14887 return CMD_SUCCESS;
14888 }
14889
14890 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
14891 const char *ip_str, const char *access_list_str)
14892 {
14893 int ret;
14894 afi_t afi;
14895 safi_t safi;
14896 struct prefix p;
14897 int distance;
14898 struct bgp_dest *dest;
14899 struct bgp_distance *bdistance;
14900
14901 afi = bgp_node_afi(vty);
14902 safi = bgp_node_safi(vty);
14903
14904 ret = str2prefix(ip_str, &p);
14905 if (ret == 0) {
14906 vty_out(vty, "Malformed prefix\n");
14907 return CMD_WARNING_CONFIG_FAILED;
14908 }
14909
14910 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
14911 if (!dest) {
14912 vty_out(vty, "Can't find specified prefix\n");
14913 return CMD_WARNING_CONFIG_FAILED;
14914 }
14915
14916 bdistance = bgp_dest_get_bgp_distance_info(dest);
14917 distance = atoi(distance_str);
14918
14919 if (bdistance->distance != distance) {
14920 vty_out(vty, "Distance does not match configured\n");
14921 bgp_dest_unlock_node(dest);
14922 return CMD_WARNING_CONFIG_FAILED;
14923 }
14924
14925 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14926 bgp_distance_free(bdistance);
14927
14928 bgp_dest_set_bgp_path_info(dest, NULL);
14929 bgp_dest_unlock_node(dest);
14930 bgp_dest_unlock_node(dest);
14931
14932 return CMD_SUCCESS;
14933 }
14934
14935 /* Apply BGP information to distance method. */
14936 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
14937 afi_t afi, safi_t safi, struct bgp *bgp)
14938 {
14939 struct bgp_dest *dest;
14940 struct prefix q = {0};
14941 struct peer *peer;
14942 struct bgp_distance *bdistance;
14943 struct access_list *alist;
14944 struct bgp_static *bgp_static;
14945 struct bgp_path_info *bpi_ultimate;
14946
14947 if (!bgp)
14948 return 0;
14949
14950 peer = pinfo->peer;
14951
14952 if (pinfo->attr->distance)
14953 return pinfo->attr->distance;
14954
14955 /* get peer origin to calculate appropriate distance */
14956 if (pinfo->sub_type == BGP_ROUTE_IMPORTED) {
14957 bpi_ultimate = bgp_get_imported_bpi_ultimate(pinfo);
14958 peer = bpi_ultimate->peer;
14959 }
14960
14961 /* Check source address.
14962 * Note: for aggregate route, peer can have unspec af type.
14963 */
14964 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
14965 && !sockunion2hostprefix(&peer->su, &q))
14966 return 0;
14967
14968 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
14969 if (dest) {
14970 bdistance = bgp_dest_get_bgp_distance_info(dest);
14971 bgp_dest_unlock_node(dest);
14972
14973 if (bdistance->access_list) {
14974 alist = access_list_lookup(afi, bdistance->access_list);
14975 if (alist
14976 && access_list_apply(alist, p) == FILTER_PERMIT)
14977 return bdistance->distance;
14978 } else
14979 return bdistance->distance;
14980 }
14981
14982 /* Backdoor check. */
14983 dest = bgp_node_lookup(bgp->route[afi][safi], p);
14984 if (dest) {
14985 bgp_static = bgp_dest_get_bgp_static_info(dest);
14986 bgp_dest_unlock_node(dest);
14987
14988 if (bgp_static->backdoor) {
14989 if (bgp->distance_local[afi][safi])
14990 return bgp->distance_local[afi][safi];
14991 else
14992 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14993 }
14994 }
14995
14996 if (peer->sort == BGP_PEER_EBGP) {
14997 if (bgp->distance_ebgp[afi][safi])
14998 return bgp->distance_ebgp[afi][safi];
14999 return ZEBRA_EBGP_DISTANCE_DEFAULT;
15000 } else if (peer->sort == BGP_PEER_IBGP) {
15001 if (bgp->distance_ibgp[afi][safi])
15002 return bgp->distance_ibgp[afi][safi];
15003 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15004 } else {
15005 if (bgp->distance_local[afi][safi])
15006 return bgp->distance_local[afi][safi];
15007 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15008 }
15009 }
15010
15011 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
15012 * we should tell ZEBRA update the routes for a specific
15013 * AFI/SAFI to reflect changes in RIB.
15014 */
15015 static void bgp_announce_routes_distance_update(struct bgp *bgp,
15016 afi_t update_afi,
15017 safi_t update_safi)
15018 {
15019 afi_t afi;
15020 safi_t safi;
15021
15022 FOREACH_AFI_SAFI (afi, safi) {
15023 if (!bgp_fibupd_safi(safi))
15024 continue;
15025
15026 if (afi != update_afi && safi != update_safi)
15027 continue;
15028
15029 if (BGP_DEBUG(zebra, ZEBRA))
15030 zlog_debug(
15031 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
15032 __func__, afi, safi);
15033 bgp_zebra_announce_table(bgp, afi, safi);
15034 }
15035 }
15036
15037 DEFUN (bgp_distance,
15038 bgp_distance_cmd,
15039 "distance bgp (1-255) (1-255) (1-255)",
15040 "Define an administrative distance\n"
15041 "BGP distance\n"
15042 "Distance for routes external to the AS\n"
15043 "Distance for routes internal to the AS\n"
15044 "Distance for local routes\n")
15045 {
15046 VTY_DECLVAR_CONTEXT(bgp, bgp);
15047 int idx_number = 2;
15048 int idx_number_2 = 3;
15049 int idx_number_3 = 4;
15050 int distance_ebgp = atoi(argv[idx_number]->arg);
15051 int distance_ibgp = atoi(argv[idx_number_2]->arg);
15052 int distance_local = atoi(argv[idx_number_3]->arg);
15053 afi_t afi;
15054 safi_t safi;
15055
15056 afi = bgp_node_afi(vty);
15057 safi = bgp_node_safi(vty);
15058
15059 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
15060 || bgp->distance_ibgp[afi][safi] != distance_ibgp
15061 || bgp->distance_local[afi][safi] != distance_local) {
15062 bgp->distance_ebgp[afi][safi] = distance_ebgp;
15063 bgp->distance_ibgp[afi][safi] = distance_ibgp;
15064 bgp->distance_local[afi][safi] = distance_local;
15065 bgp_announce_routes_distance_update(bgp, afi, safi);
15066 }
15067 return CMD_SUCCESS;
15068 }
15069
15070 DEFUN (no_bgp_distance,
15071 no_bgp_distance_cmd,
15072 "no distance bgp [(1-255) (1-255) (1-255)]",
15073 NO_STR
15074 "Define an administrative distance\n"
15075 "BGP distance\n"
15076 "Distance for routes external to the AS\n"
15077 "Distance for routes internal to the AS\n"
15078 "Distance for local routes\n")
15079 {
15080 VTY_DECLVAR_CONTEXT(bgp, bgp);
15081 afi_t afi;
15082 safi_t safi;
15083
15084 afi = bgp_node_afi(vty);
15085 safi = bgp_node_safi(vty);
15086
15087 if (bgp->distance_ebgp[afi][safi] != 0
15088 || bgp->distance_ibgp[afi][safi] != 0
15089 || bgp->distance_local[afi][safi] != 0) {
15090 bgp->distance_ebgp[afi][safi] = 0;
15091 bgp->distance_ibgp[afi][safi] = 0;
15092 bgp->distance_local[afi][safi] = 0;
15093 bgp_announce_routes_distance_update(bgp, afi, safi);
15094 }
15095 return CMD_SUCCESS;
15096 }
15097
15098
15099 DEFUN (bgp_distance_source,
15100 bgp_distance_source_cmd,
15101 "distance (1-255) A.B.C.D/M",
15102 "Define an administrative distance\n"
15103 "Administrative distance\n"
15104 "IP source prefix\n")
15105 {
15106 int idx_number = 1;
15107 int idx_ipv4_prefixlen = 2;
15108 bgp_distance_set(vty, argv[idx_number]->arg,
15109 argv[idx_ipv4_prefixlen]->arg, NULL);
15110 return CMD_SUCCESS;
15111 }
15112
15113 DEFUN (no_bgp_distance_source,
15114 no_bgp_distance_source_cmd,
15115 "no distance (1-255) A.B.C.D/M",
15116 NO_STR
15117 "Define an administrative distance\n"
15118 "Administrative distance\n"
15119 "IP source prefix\n")
15120 {
15121 int idx_number = 2;
15122 int idx_ipv4_prefixlen = 3;
15123 bgp_distance_unset(vty, argv[idx_number]->arg,
15124 argv[idx_ipv4_prefixlen]->arg, NULL);
15125 return CMD_SUCCESS;
15126 }
15127
15128 DEFUN (bgp_distance_source_access_list,
15129 bgp_distance_source_access_list_cmd,
15130 "distance (1-255) A.B.C.D/M WORD",
15131 "Define an administrative distance\n"
15132 "Administrative distance\n"
15133 "IP source prefix\n"
15134 "Access list name\n")
15135 {
15136 int idx_number = 1;
15137 int idx_ipv4_prefixlen = 2;
15138 int idx_word = 3;
15139 bgp_distance_set(vty, argv[idx_number]->arg,
15140 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15141 return CMD_SUCCESS;
15142 }
15143
15144 DEFUN (no_bgp_distance_source_access_list,
15145 no_bgp_distance_source_access_list_cmd,
15146 "no distance (1-255) A.B.C.D/M WORD",
15147 NO_STR
15148 "Define an administrative distance\n"
15149 "Administrative distance\n"
15150 "IP source prefix\n"
15151 "Access list name\n")
15152 {
15153 int idx_number = 2;
15154 int idx_ipv4_prefixlen = 3;
15155 int idx_word = 4;
15156 bgp_distance_unset(vty, argv[idx_number]->arg,
15157 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15158 return CMD_SUCCESS;
15159 }
15160
15161 DEFUN (ipv6_bgp_distance_source,
15162 ipv6_bgp_distance_source_cmd,
15163 "distance (1-255) X:X::X:X/M",
15164 "Define an administrative distance\n"
15165 "Administrative distance\n"
15166 "IP source prefix\n")
15167 {
15168 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15169 return CMD_SUCCESS;
15170 }
15171
15172 DEFUN (no_ipv6_bgp_distance_source,
15173 no_ipv6_bgp_distance_source_cmd,
15174 "no distance (1-255) X:X::X:X/M",
15175 NO_STR
15176 "Define an administrative distance\n"
15177 "Administrative distance\n"
15178 "IP source prefix\n")
15179 {
15180 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15181 return CMD_SUCCESS;
15182 }
15183
15184 DEFUN (ipv6_bgp_distance_source_access_list,
15185 ipv6_bgp_distance_source_access_list_cmd,
15186 "distance (1-255) X:X::X:X/M WORD",
15187 "Define an administrative distance\n"
15188 "Administrative distance\n"
15189 "IP source prefix\n"
15190 "Access list name\n")
15191 {
15192 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15193 return CMD_SUCCESS;
15194 }
15195
15196 DEFUN (no_ipv6_bgp_distance_source_access_list,
15197 no_ipv6_bgp_distance_source_access_list_cmd,
15198 "no distance (1-255) X:X::X:X/M WORD",
15199 NO_STR
15200 "Define an administrative distance\n"
15201 "Administrative distance\n"
15202 "IP source prefix\n"
15203 "Access list name\n")
15204 {
15205 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15206 return CMD_SUCCESS;
15207 }
15208
15209 DEFUN (bgp_damp_set,
15210 bgp_damp_set_cmd,
15211 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15212 "BGP Specific commands\n"
15213 "Enable route-flap dampening\n"
15214 "Half-life time for the penalty\n"
15215 "Value to start reusing a route\n"
15216 "Value to start suppressing a route\n"
15217 "Maximum duration to suppress a stable route\n")
15218 {
15219 VTY_DECLVAR_CONTEXT(bgp, bgp);
15220 int idx_half_life = 2;
15221 int idx_reuse = 3;
15222 int idx_suppress = 4;
15223 int idx_max_suppress = 5;
15224 int half = DEFAULT_HALF_LIFE * 60;
15225 int reuse = DEFAULT_REUSE;
15226 int suppress = DEFAULT_SUPPRESS;
15227 int max = 4 * half;
15228
15229 if (argc == 6) {
15230 half = atoi(argv[idx_half_life]->arg) * 60;
15231 reuse = atoi(argv[idx_reuse]->arg);
15232 suppress = atoi(argv[idx_suppress]->arg);
15233 max = atoi(argv[idx_max_suppress]->arg) * 60;
15234 } else if (argc == 3) {
15235 half = atoi(argv[idx_half_life]->arg) * 60;
15236 max = 4 * half;
15237 }
15238
15239 /*
15240 * These can't be 0 but our SA doesn't understand the
15241 * way our cli is constructed
15242 */
15243 assert(reuse);
15244 assert(half);
15245 if (suppress < reuse) {
15246 vty_out(vty,
15247 "Suppress value cannot be less than reuse value \n");
15248 return 0;
15249 }
15250
15251 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15252 reuse, suppress, max);
15253 }
15254
15255 DEFUN (bgp_damp_unset,
15256 bgp_damp_unset_cmd,
15257 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15258 NO_STR
15259 "BGP Specific commands\n"
15260 "Enable route-flap dampening\n"
15261 "Half-life time for the penalty\n"
15262 "Value to start reusing a route\n"
15263 "Value to start suppressing a route\n"
15264 "Maximum duration to suppress a stable route\n")
15265 {
15266 VTY_DECLVAR_CONTEXT(bgp, bgp);
15267 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15268 }
15269
15270 /* Display specified route of BGP table. */
15271 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15272 const char *ip_str, afi_t afi, safi_t safi,
15273 struct prefix_rd *prd, int prefix_check)
15274 {
15275 int ret;
15276 struct prefix match;
15277 struct bgp_dest *dest;
15278 struct bgp_dest *rm;
15279 struct bgp_path_info *pi;
15280 struct bgp_path_info *pi_temp;
15281 struct bgp *bgp;
15282 struct bgp_table *table;
15283
15284 /* BGP structure lookup. */
15285 if (view_name) {
15286 bgp = bgp_lookup_by_name(view_name);
15287 if (bgp == NULL) {
15288 vty_out(vty, "%% Can't find BGP instance %s\n",
15289 view_name);
15290 return CMD_WARNING;
15291 }
15292 } else {
15293 bgp = bgp_get_default();
15294 if (bgp == NULL) {
15295 vty_out(vty, "%% No BGP process is configured\n");
15296 return CMD_WARNING;
15297 }
15298 }
15299
15300 /* Check IP address argument. */
15301 ret = str2prefix(ip_str, &match);
15302 if (!ret) {
15303 vty_out(vty, "%% address is malformed\n");
15304 return CMD_WARNING;
15305 }
15306
15307 match.family = afi2family(afi);
15308
15309 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15310 || (safi == SAFI_EVPN)) {
15311 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15312 dest = bgp_route_next(dest)) {
15313 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15314
15315 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15316 continue;
15317 table = bgp_dest_get_bgp_table_info(dest);
15318 if (!table)
15319 continue;
15320 rm = bgp_node_match(table, &match);
15321 if (rm == NULL)
15322 continue;
15323
15324 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15325
15326 if (!prefix_check
15327 || rm_p->prefixlen == match.prefixlen) {
15328 pi = bgp_dest_get_bgp_path_info(rm);
15329 while (pi) {
15330 if (pi->extra && pi->extra->damp_info) {
15331 pi_temp = pi->next;
15332 bgp_damp_info_free(
15333 pi->extra->damp_info,
15334 1, afi, safi);
15335 pi = pi_temp;
15336 } else
15337 pi = pi->next;
15338 }
15339 }
15340
15341 bgp_dest_unlock_node(rm);
15342 }
15343 } else {
15344 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15345 if (dest != NULL) {
15346 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15347
15348 if (!prefix_check
15349 || dest_p->prefixlen == match.prefixlen) {
15350 pi = bgp_dest_get_bgp_path_info(dest);
15351 while (pi) {
15352 if (pi->extra && pi->extra->damp_info) {
15353 pi_temp = pi->next;
15354 bgp_damp_info_free(
15355 pi->extra->damp_info,
15356 1, afi, safi);
15357 pi = pi_temp;
15358 } else
15359 pi = pi->next;
15360 }
15361 }
15362
15363 bgp_dest_unlock_node(dest);
15364 }
15365 }
15366
15367 return CMD_SUCCESS;
15368 }
15369
15370 DEFUN (clear_ip_bgp_dampening,
15371 clear_ip_bgp_dampening_cmd,
15372 "clear ip bgp dampening",
15373 CLEAR_STR
15374 IP_STR
15375 BGP_STR
15376 "Clear route flap dampening information\n")
15377 {
15378 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15379 return CMD_SUCCESS;
15380 }
15381
15382 DEFUN (clear_ip_bgp_dampening_prefix,
15383 clear_ip_bgp_dampening_prefix_cmd,
15384 "clear ip bgp dampening A.B.C.D/M",
15385 CLEAR_STR
15386 IP_STR
15387 BGP_STR
15388 "Clear route flap dampening information\n"
15389 "IPv4 prefix\n")
15390 {
15391 int idx_ipv4_prefixlen = 4;
15392 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15393 AFI_IP, SAFI_UNICAST, NULL, 1);
15394 }
15395
15396 DEFUN (clear_ip_bgp_dampening_address,
15397 clear_ip_bgp_dampening_address_cmd,
15398 "clear ip bgp dampening A.B.C.D",
15399 CLEAR_STR
15400 IP_STR
15401 BGP_STR
15402 "Clear route flap dampening information\n"
15403 "Network to clear damping information\n")
15404 {
15405 int idx_ipv4 = 4;
15406 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15407 SAFI_UNICAST, NULL, 0);
15408 }
15409
15410 DEFUN (clear_ip_bgp_dampening_address_mask,
15411 clear_ip_bgp_dampening_address_mask_cmd,
15412 "clear ip bgp dampening A.B.C.D A.B.C.D",
15413 CLEAR_STR
15414 IP_STR
15415 BGP_STR
15416 "Clear route flap dampening information\n"
15417 "Network to clear damping information\n"
15418 "Network mask\n")
15419 {
15420 int idx_ipv4 = 4;
15421 int idx_ipv4_2 = 5;
15422 int ret;
15423 char prefix_str[BUFSIZ];
15424
15425 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15426 prefix_str, sizeof(prefix_str));
15427 if (!ret) {
15428 vty_out(vty, "%% Inconsistent address and mask\n");
15429 return CMD_WARNING;
15430 }
15431
15432 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15433 NULL, 0);
15434 }
15435
15436 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15437 {
15438 struct vty *vty = arg;
15439 struct peer *peer = bucket->data;
15440
15441 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15442 }
15443
15444 DEFUN (show_bgp_listeners,
15445 show_bgp_listeners_cmd,
15446 "show bgp listeners",
15447 SHOW_STR
15448 BGP_STR
15449 "Display Listen Sockets and who created them\n")
15450 {
15451 bgp_dump_listener_info(vty);
15452
15453 return CMD_SUCCESS;
15454 }
15455
15456 DEFUN (show_bgp_peerhash,
15457 show_bgp_peerhash_cmd,
15458 "show bgp peerhash",
15459 SHOW_STR
15460 BGP_STR
15461 "Display information about the BGP peerhash\n")
15462 {
15463 struct list *instances = bm->bgp;
15464 struct listnode *node;
15465 struct bgp *bgp;
15466
15467 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15468 vty_out(vty, "BGP: %s\n", bgp->name);
15469 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15470 vty);
15471 }
15472
15473 return CMD_SUCCESS;
15474 }
15475
15476 /* also used for encap safi */
15477 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15478 afi_t afi, safi_t safi)
15479 {
15480 struct bgp_dest *pdest;
15481 struct bgp_dest *dest;
15482 struct bgp_table *table;
15483 const struct prefix *p;
15484 const struct prefix_rd *prd;
15485 struct bgp_static *bgp_static;
15486 mpls_label_t label;
15487
15488 /* Network configuration. */
15489 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15490 pdest = bgp_route_next(pdest)) {
15491 table = bgp_dest_get_bgp_table_info(pdest);
15492 if (!table)
15493 continue;
15494
15495 for (dest = bgp_table_top(table); dest;
15496 dest = bgp_route_next(dest)) {
15497 bgp_static = bgp_dest_get_bgp_static_info(dest);
15498 if (bgp_static == NULL)
15499 continue;
15500
15501 p = bgp_dest_get_prefix(dest);
15502 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
15503 pdest);
15504
15505 /* "network" configuration display. */
15506 label = decode_label(&bgp_static->label);
15507
15508 vty_out(vty, " network %pFX rd %pRD", p, prd);
15509 if (safi == SAFI_MPLS_VPN)
15510 vty_out(vty, " label %u", label);
15511
15512 if (bgp_static->rmap.name)
15513 vty_out(vty, " route-map %s",
15514 bgp_static->rmap.name);
15515
15516 if (bgp_static->backdoor)
15517 vty_out(vty, " backdoor");
15518
15519 vty_out(vty, "\n");
15520 }
15521 }
15522 }
15523
15524 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15525 afi_t afi, safi_t safi)
15526 {
15527 struct bgp_dest *pdest;
15528 struct bgp_dest *dest;
15529 struct bgp_table *table;
15530 const struct prefix *p;
15531 const struct prefix_rd *prd;
15532 struct bgp_static *bgp_static;
15533 char buf[PREFIX_STRLEN * 2];
15534 char buf2[SU_ADDRSTRLEN];
15535 char esi_buf[ESI_STR_LEN];
15536
15537 /* Network configuration. */
15538 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15539 pdest = bgp_route_next(pdest)) {
15540 table = bgp_dest_get_bgp_table_info(pdest);
15541 if (!table)
15542 continue;
15543
15544 for (dest = bgp_table_top(table); dest;
15545 dest = bgp_route_next(dest)) {
15546 bgp_static = bgp_dest_get_bgp_static_info(dest);
15547 if (bgp_static == NULL)
15548 continue;
15549
15550 char *macrouter = NULL;
15551
15552 if (bgp_static->router_mac)
15553 macrouter = prefix_mac2str(
15554 bgp_static->router_mac, NULL, 0);
15555 if (bgp_static->eth_s_id)
15556 esi_to_str(bgp_static->eth_s_id,
15557 esi_buf, sizeof(esi_buf));
15558 p = bgp_dest_get_prefix(dest);
15559 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
15560
15561 /* "network" configuration display. */
15562 if (p->u.prefix_evpn.route_type == 5) {
15563 char local_buf[PREFIX_STRLEN];
15564
15565 uint8_t family = is_evpn_prefix_ipaddr_v4((
15566 struct prefix_evpn *)p)
15567 ? AF_INET
15568 : AF_INET6;
15569 inet_ntop(family,
15570 &p->u.prefix_evpn.prefix_addr.ip.ip
15571 .addr,
15572 local_buf, sizeof(local_buf));
15573 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15574 p->u.prefix_evpn.prefix_addr
15575 .ip_prefix_length);
15576 } else {
15577 prefix2str(p, buf, sizeof(buf));
15578 }
15579
15580 if (bgp_static->gatewayIp.family == AF_INET
15581 || bgp_static->gatewayIp.family == AF_INET6)
15582 inet_ntop(bgp_static->gatewayIp.family,
15583 &bgp_static->gatewayIp.u.prefix, buf2,
15584 sizeof(buf2));
15585 vty_out(vty,
15586 " network %s rd %pRD ethtag %u label %u esi %s gwip %s routermac %s\n",
15587 buf, prd, p->u.prefix_evpn.prefix_addr.eth_tag,
15588 decode_label(&bgp_static->label), esi_buf, buf2,
15589 macrouter);
15590
15591 XFREE(MTYPE_TMP, macrouter);
15592 }
15593 }
15594 }
15595
15596 /* Configuration of static route announcement and aggregate
15597 information. */
15598 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15599 safi_t safi)
15600 {
15601 struct bgp_dest *dest;
15602 const struct prefix *p;
15603 struct bgp_static *bgp_static;
15604 struct bgp_aggregate *bgp_aggregate;
15605
15606 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15607 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15608 return;
15609 }
15610
15611 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15612 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15613 return;
15614 }
15615
15616 /* Network configuration. */
15617 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15618 dest = bgp_route_next(dest)) {
15619 bgp_static = bgp_dest_get_bgp_static_info(dest);
15620 if (bgp_static == NULL)
15621 continue;
15622
15623 p = bgp_dest_get_prefix(dest);
15624
15625 vty_out(vty, " network %pFX", p);
15626
15627 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15628 vty_out(vty, " label-index %u",
15629 bgp_static->label_index);
15630
15631 if (bgp_static->rmap.name)
15632 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15633
15634 if (bgp_static->backdoor)
15635 vty_out(vty, " backdoor");
15636
15637 vty_out(vty, "\n");
15638 }
15639
15640 /* Aggregate-address configuration. */
15641 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15642 dest = bgp_route_next(dest)) {
15643 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15644 if (bgp_aggregate == NULL)
15645 continue;
15646
15647 p = bgp_dest_get_prefix(dest);
15648
15649 vty_out(vty, " aggregate-address %pFX", p);
15650
15651 if (bgp_aggregate->as_set)
15652 vty_out(vty, " as-set");
15653
15654 if (bgp_aggregate->summary_only)
15655 vty_out(vty, " summary-only");
15656
15657 if (bgp_aggregate->rmap.name)
15658 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15659
15660 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15661 vty_out(vty, " origin %s",
15662 bgp_origin2str(bgp_aggregate->origin));
15663
15664 if (bgp_aggregate->match_med)
15665 vty_out(vty, " matching-MED-only");
15666
15667 if (bgp_aggregate->suppress_map_name)
15668 vty_out(vty, " suppress-map %s",
15669 bgp_aggregate->suppress_map_name);
15670
15671 vty_out(vty, "\n");
15672 }
15673 }
15674
15675 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15676 safi_t safi)
15677 {
15678 struct bgp_dest *dest;
15679 struct bgp_distance *bdistance;
15680
15681 /* Distance configuration. */
15682 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15683 && bgp->distance_local[afi][safi]
15684 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15685 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15686 || bgp->distance_local[afi][safi]
15687 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15688 vty_out(vty, " distance bgp %d %d %d\n",
15689 bgp->distance_ebgp[afi][safi],
15690 bgp->distance_ibgp[afi][safi],
15691 bgp->distance_local[afi][safi]);
15692 }
15693
15694 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15695 dest = bgp_route_next(dest)) {
15696 bdistance = bgp_dest_get_bgp_distance_info(dest);
15697 if (bdistance != NULL)
15698 vty_out(vty, " distance %d %pBD %s\n",
15699 bdistance->distance, dest,
15700 bdistance->access_list ? bdistance->access_list
15701 : "");
15702 }
15703 }
15704
15705 /* Allocate routing table structure and install commands. */
15706 void bgp_route_init(void)
15707 {
15708 afi_t afi;
15709 safi_t safi;
15710
15711 /* Init BGP distance table. */
15712 FOREACH_AFI_SAFI (afi, safi)
15713 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15714
15715 /* IPv4 BGP commands. */
15716 install_element(BGP_NODE, &bgp_table_map_cmd);
15717 install_element(BGP_NODE, &bgp_network_cmd);
15718 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15719
15720 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15721
15722 /* IPv4 unicast configuration. */
15723 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15724 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15725 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15726
15727 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15728
15729 /* IPv4 multicast configuration. */
15730 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15731 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15732 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15733 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15734
15735 /* IPv4 labeled-unicast configuration. */
15736 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15737 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15738
15739 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15740 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15741 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15742 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15743 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15744 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15745 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15746 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15747
15748 install_element(VIEW_NODE,
15749 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15750 install_element(VIEW_NODE,
15751 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15752 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15753 install_element(VIEW_NODE,
15754 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15755 #ifdef KEEP_OLD_VPN_COMMANDS
15756 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15757 #endif /* KEEP_OLD_VPN_COMMANDS */
15758 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15759 install_element(VIEW_NODE,
15760 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15761
15762 /* BGP dampening clear commands */
15763 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15764 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15765
15766 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15767 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15768
15769 /* prefix count */
15770 install_element(ENABLE_NODE,
15771 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15772 #ifdef KEEP_OLD_VPN_COMMANDS
15773 install_element(ENABLE_NODE,
15774 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15775 #endif /* KEEP_OLD_VPN_COMMANDS */
15776
15777 /* New config IPv6 BGP commands. */
15778 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15779 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15780 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15781
15782 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15783
15784 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15785
15786 /* IPv6 labeled unicast address family. */
15787 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15788 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15789
15790 install_element(BGP_NODE, &bgp_distance_cmd);
15791 install_element(BGP_NODE, &no_bgp_distance_cmd);
15792 install_element(BGP_NODE, &bgp_distance_source_cmd);
15793 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15794 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15795 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15796 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15797 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15798 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15799 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15800 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15801 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15802 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15803 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15804 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15805 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15806 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15807 install_element(BGP_IPV4M_NODE,
15808 &no_bgp_distance_source_access_list_cmd);
15809 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15810 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15811 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15812 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15813 install_element(BGP_IPV6_NODE,
15814 &ipv6_bgp_distance_source_access_list_cmd);
15815 install_element(BGP_IPV6_NODE,
15816 &no_ipv6_bgp_distance_source_access_list_cmd);
15817 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15818 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15819 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15820 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15821 install_element(BGP_IPV6M_NODE,
15822 &ipv6_bgp_distance_source_access_list_cmd);
15823 install_element(BGP_IPV6M_NODE,
15824 &no_ipv6_bgp_distance_source_access_list_cmd);
15825
15826 /* BGP dampening */
15827 install_element(BGP_NODE, &bgp_damp_set_cmd);
15828 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15829 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15830 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15831 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15832 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15833 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15834 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15835 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15836 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15837 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15838 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15839 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15840 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15841
15842 /* Large Communities */
15843 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15844 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15845
15846 /* show bgp ipv4 flowspec detailed */
15847 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15848
15849 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15850 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15851 }
15852
15853 void bgp_route_finish(void)
15854 {
15855 afi_t afi;
15856 safi_t safi;
15857
15858 FOREACH_AFI_SAFI (afi, safi) {
15859 bgp_table_unlock(bgp_distance_table[afi][safi]);
15860 bgp_distance_table[afi][safi] = NULL;
15861 }
15862 }