]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[mirror_frr.git] / bgpd / bgp_route.c
1 /* BGP routing information
2 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 * Copyright (C) 2016 Job Snijders <job@instituut.net>
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <zebra.h>
23 #include <math.h>
24
25 #include "printfrr.h"
26 #include "frrstr.h"
27 #include "prefix.h"
28 #include "linklist.h"
29 #include "memory.h"
30 #include "command.h"
31 #include "stream.h"
32 #include "filter.h"
33 #include "log.h"
34 #include "routemap.h"
35 #include "buffer.h"
36 #include "sockunion.h"
37 #include "plist.h"
38 #include "thread.h"
39 #include "workqueue.h"
40 #include "queue.h"
41 #include "memory.h"
42 #include "srv6.h"
43 #include "lib/json.h"
44 #include "lib_errors.h"
45 #include "zclient.h"
46 #include "bgpd/bgpd.h"
47 #include "bgpd/bgp_table.h"
48 #include "bgpd/bgp_route.h"
49 #include "bgpd/bgp_attr.h"
50 #include "bgpd/bgp_debug.h"
51 #include "bgpd/bgp_errors.h"
52 #include "bgpd/bgp_aspath.h"
53 #include "bgpd/bgp_regex.h"
54 #include "bgpd/bgp_community.h"
55 #include "bgpd/bgp_community_alias.h"
56 #include "bgpd/bgp_ecommunity.h"
57 #include "bgpd/bgp_lcommunity.h"
58 #include "bgpd/bgp_clist.h"
59 #include "bgpd/bgp_packet.h"
60 #include "bgpd/bgp_filter.h"
61 #include "bgpd/bgp_fsm.h"
62 #include "bgpd/bgp_mplsvpn.h"
63 #include "bgpd/bgp_nexthop.h"
64 #include "bgpd/bgp_damp.h"
65 #include "bgpd/bgp_advertise.h"
66 #include "bgpd/bgp_zebra.h"
67 #include "bgpd/bgp_vty.h"
68 #include "bgpd/bgp_mpath.h"
69 #include "bgpd/bgp_nht.h"
70 #include "bgpd/bgp_updgrp.h"
71 #include "bgpd/bgp_label.h"
72 #include "bgpd/bgp_addpath.h"
73 #include "bgpd/bgp_mac.h"
74 #include "bgpd/bgp_network.h"
75 #include "bgpd/bgp_trace.h"
76 #include "bgpd/bgp_rpki.h"
77
78 #ifdef ENABLE_BGP_VNC
79 #include "bgpd/rfapi/rfapi_backend.h"
80 #include "bgpd/rfapi/vnc_import_bgp.h"
81 #include "bgpd/rfapi/vnc_export_bgp.h"
82 #endif
83 #include "bgpd/bgp_encap_types.h"
84 #include "bgpd/bgp_encap_tlv.h"
85 #include "bgpd/bgp_evpn.h"
86 #include "bgpd/bgp_evpn_mh.h"
87 #include "bgpd/bgp_evpn_vty.h"
88 #include "bgpd/bgp_flowspec.h"
89 #include "bgpd/bgp_flowspec_util.h"
90 #include "bgpd/bgp_pbr.h"
91
92 #include "bgpd/bgp_route_clippy.c"
93
94 DEFINE_HOOK(bgp_snmp_update_stats,
95 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
96 (rn, pi, added));
97
98 DEFINE_HOOK(bgp_rpki_prefix_status,
99 (struct peer *peer, struct attr *attr,
100 const struct prefix *prefix),
101 (peer, attr, prefix));
102
103 /* Extern from bgp_dump.c */
104 extern const char *bgp_origin_str[];
105 extern const char *bgp_origin_long_str[];
106
107 /* PMSI strings. */
108 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
109 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
110 static const struct message bgp_pmsi_tnltype_str[] = {
111 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
112 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
113 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
114 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
115 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
116 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
117 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
118 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
119 {0}
120 };
121
122 #define VRFID_NONE_STR "-"
123 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
124
125 DEFINE_HOOK(bgp_process,
126 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
127 struct peer *peer, bool withdraw),
128 (bgp, afi, safi, bn, peer, withdraw));
129
130 /** Test if path is suppressed. */
131 static bool bgp_path_suppressed(struct bgp_path_info *pi)
132 {
133 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
134 return false;
135
136 return listcount(pi->extra->aggr_suppressors) > 0;
137 }
138
139 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
140 safi_t safi, const struct prefix *p,
141 struct prefix_rd *prd)
142 {
143 struct bgp_dest *dest;
144 struct bgp_dest *pdest = NULL;
145
146 assert(table);
147
148 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
149 || (safi == SAFI_EVPN)) {
150 pdest = bgp_node_get(table, (struct prefix *)prd);
151
152 if (!bgp_dest_has_bgp_path_info_data(pdest))
153 bgp_dest_set_bgp_table_info(
154 pdest, bgp_table_init(table->bgp, afi, safi));
155 else
156 bgp_dest_unlock_node(pdest);
157 table = bgp_dest_get_bgp_table_info(pdest);
158 }
159
160 dest = bgp_node_get(table, p);
161
162 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
163 || (safi == SAFI_EVPN))
164 dest->pdest = pdest;
165
166 return dest;
167 }
168
169 struct bgp_dest *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
170 safi_t safi, const struct prefix *p,
171 struct prefix_rd *prd)
172 {
173 struct bgp_dest *dest;
174 struct bgp_dest *pdest = NULL;
175
176 if (!table)
177 return NULL;
178
179 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
180 || (safi == SAFI_EVPN)) {
181 pdest = bgp_node_lookup(table, (struct prefix *)prd);
182 if (!pdest)
183 return NULL;
184
185 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
186 bgp_dest_unlock_node(pdest);
187 return NULL;
188 }
189
190 table = bgp_dest_get_bgp_table_info(pdest);
191 }
192
193 dest = bgp_node_lookup(table, p);
194
195 return dest;
196 }
197
198 /* Allocate bgp_path_info_extra */
199 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
200 {
201 struct bgp_path_info_extra *new;
202 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
203 sizeof(struct bgp_path_info_extra));
204 new->label[0] = MPLS_INVALID_LABEL;
205 new->num_labels = 0;
206 new->bgp_fs_pbr = NULL;
207 new->bgp_fs_iprule = NULL;
208 return new;
209 }
210
211 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
212 {
213 struct bgp_path_info_extra *e;
214
215 if (!extra || !*extra)
216 return;
217
218 e = *extra;
219 if (e->damp_info)
220 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
221 e->damp_info->safi);
222
223 e->damp_info = NULL;
224 if (e->parent) {
225 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
226
227 if (bpi->net) {
228 /* FIXME: since multiple e may have the same e->parent
229 * and e->parent->net is holding a refcount for each
230 * of them, we need to do some fudging here.
231 *
232 * WARNING: if bpi->net->lock drops to 0, bpi may be
233 * freed as well (because bpi->net was holding the
234 * last reference to bpi) => write after free!
235 */
236 unsigned refcount;
237
238 bpi = bgp_path_info_lock(bpi);
239 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
240 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
241 if (!refcount)
242 bpi->net = NULL;
243 bgp_path_info_unlock(bpi);
244 }
245 bgp_path_info_unlock(e->parent);
246 e->parent = NULL;
247 }
248
249 if (e->bgp_orig)
250 bgp_unlock(e->bgp_orig);
251
252 if (e->peer_orig)
253 peer_unlock(e->peer_orig);
254
255 if (e->aggr_suppressors)
256 list_delete(&e->aggr_suppressors);
257
258 if (e->mh_info)
259 bgp_evpn_path_mh_info_free(e->mh_info);
260
261 if ((*extra)->bgp_fs_iprule)
262 list_delete(&((*extra)->bgp_fs_iprule));
263 if ((*extra)->bgp_fs_pbr)
264 list_delete(&((*extra)->bgp_fs_pbr));
265 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
266 }
267
268 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
269 * allocated if required.
270 */
271 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
272 {
273 if (!pi->extra)
274 pi->extra = bgp_path_info_extra_new();
275 return pi->extra;
276 }
277
278 /* Free bgp route information. */
279 void bgp_path_info_free_with_caller(const char *name,
280 struct bgp_path_info *path)
281 {
282 frrtrace(2, frr_bgp, bgp_path_info_free, path, name);
283 bgp_attr_unintern(&path->attr);
284
285 bgp_unlink_nexthop(path);
286 bgp_path_info_extra_free(&path->extra);
287 bgp_path_info_mpath_free(&path->mpath);
288 if (path->net)
289 bgp_addpath_free_info_data(&path->tx_addpath,
290 &path->net->tx_addpath);
291
292 peer_unlock(path->peer); /* bgp_path_info peer reference */
293
294 XFREE(MTYPE_BGP_ROUTE, path);
295 }
296
297 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
298 {
299 path->lock++;
300 return path;
301 }
302
303 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
304 {
305 assert(path && path->lock > 0);
306 path->lock--;
307
308 if (path->lock == 0) {
309 bgp_path_info_free(path);
310 return NULL;
311 }
312
313 return path;
314 }
315
316 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
317 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
318 {
319 struct peer *peer;
320 struct bgp_path_info *old_pi, *nextpi;
321 bool set_flag = false;
322 struct bgp *bgp = NULL;
323 struct bgp_table *table = NULL;
324 afi_t afi = 0;
325 safi_t safi = 0;
326
327 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
328 * then the route selection is deferred
329 */
330 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
331 return 0;
332
333 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
334 if (BGP_DEBUG(update, UPDATE_OUT))
335 zlog_debug(
336 "Route %pBD is in workqueue and being processed, not deferred.",
337 dest);
338
339 return 0;
340 }
341
342 table = bgp_dest_table(dest);
343 if (table) {
344 bgp = table->bgp;
345 afi = table->afi;
346 safi = table->safi;
347 }
348
349 for (old_pi = bgp_dest_get_bgp_path_info(dest);
350 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
351 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
352 continue;
353
354 /* Route selection is deferred if there is a stale path which
355 * which indicates peer is in restart mode
356 */
357 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
358 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
359 set_flag = true;
360 } else {
361 /* If the peer is graceful restart capable and peer is
362 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
363 */
364 peer = old_pi->peer;
365 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
366 && BGP_PEER_RESTARTING_MODE(peer)
367 && (old_pi
368 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
369 set_flag = true;
370 }
371 }
372 if (set_flag)
373 break;
374 }
375
376 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
377 * is active
378 */
379 if (set_flag && table) {
380 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
381 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
382 bgp->gr_info[afi][safi].gr_deferred++;
383 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
384 if (BGP_DEBUG(update, UPDATE_OUT))
385 zlog_debug("DEFER route %pBD, dest %p", dest,
386 dest);
387 return 0;
388 }
389 }
390 return -1;
391 }
392
393 void bgp_path_info_add_with_caller(const char *name, struct bgp_dest *dest,
394 struct bgp_path_info *pi)
395 {
396 frrtrace(3, frr_bgp, bgp_path_info_add, dest, pi, name);
397 struct bgp_path_info *top;
398
399 top = bgp_dest_get_bgp_path_info(dest);
400
401 pi->next = top;
402 pi->prev = NULL;
403 if (top)
404 top->prev = pi;
405 bgp_dest_set_bgp_path_info(dest, pi);
406
407 bgp_path_info_lock(pi);
408 bgp_dest_lock_node(dest);
409 peer_lock(pi->peer); /* bgp_path_info peer reference */
410 bgp_dest_set_defer_flag(dest, false);
411 hook_call(bgp_snmp_update_stats, dest, pi, true);
412 }
413
414 /* Do the actual removal of info from RIB, for use by bgp_process
415 completion callback *only* */
416 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
417 {
418 if (pi->next)
419 pi->next->prev = pi->prev;
420 if (pi->prev)
421 pi->prev->next = pi->next;
422 else
423 bgp_dest_set_bgp_path_info(dest, pi->next);
424
425 bgp_path_info_mpath_dequeue(pi);
426 bgp_path_info_unlock(pi);
427 hook_call(bgp_snmp_update_stats, dest, pi, false);
428 bgp_dest_unlock_node(dest);
429 }
430
431 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
432 {
433 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
434 /* set of previous already took care of pcount */
435 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
436 }
437
438 /* undo the effects of a previous call to bgp_path_info_delete; typically
439 called when a route is deleted and then quickly re-added before the
440 deletion has been processed */
441 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
442 {
443 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
444 /* unset of previous already took care of pcount */
445 SET_FLAG(pi->flags, BGP_PATH_VALID);
446 }
447
448 /* Adjust pcount as required */
449 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
450 {
451 struct bgp_table *table;
452
453 assert(dest && bgp_dest_table(dest));
454 assert(pi && pi->peer && pi->peer->bgp);
455
456 table = bgp_dest_table(dest);
457
458 if (pi->peer == pi->peer->bgp->peer_self)
459 return;
460
461 if (!BGP_PATH_COUNTABLE(pi)
462 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
463
464 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
465
466 /* slight hack, but more robust against errors. */
467 if (pi->peer->pcount[table->afi][table->safi])
468 pi->peer->pcount[table->afi][table->safi]--;
469 else
470 flog_err(EC_LIB_DEVELOPMENT,
471 "Asked to decrement 0 prefix count for peer");
472 } else if (BGP_PATH_COUNTABLE(pi)
473 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
474 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
475 pi->peer->pcount[table->afi][table->safi]++;
476 }
477 }
478
479 static int bgp_label_index_differs(struct bgp_path_info *pi1,
480 struct bgp_path_info *pi2)
481 {
482 return (!(pi1->attr->label_index == pi2->attr->label_index));
483 }
484
485 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
486 * This is here primarily to keep prefix-count in check.
487 */
488 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
489 uint32_t flag)
490 {
491 SET_FLAG(pi->flags, flag);
492
493 /* early bath if we know it's not a flag that changes countability state
494 */
495 if (!CHECK_FLAG(flag,
496 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
497 return;
498
499 bgp_pcount_adjust(dest, pi);
500 }
501
502 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
503 uint32_t flag)
504 {
505 UNSET_FLAG(pi->flags, flag);
506
507 /* early bath if we know it's not a flag that changes countability state
508 */
509 if (!CHECK_FLAG(flag,
510 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
511 return;
512
513 bgp_pcount_adjust(dest, pi);
514 }
515
516 /* Get MED value. If MED value is missing and "bgp bestpath
517 missing-as-worst" is specified, treat it as the worst value. */
518 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
519 {
520 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
521 return attr->med;
522 else {
523 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
524 return BGP_MED_MAX;
525 else
526 return 0;
527 }
528 }
529
530 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
531 size_t buf_len)
532 {
533 if (pi->addpath_rx_id)
534 snprintf(buf, buf_len, "path %s (addpath rxid %d)",
535 pi->peer->host, pi->addpath_rx_id);
536 else
537 snprintf(buf, buf_len, "path %s", pi->peer->host);
538 }
539
540
541 /*
542 * Get the ultimate path info.
543 */
544 struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
545 {
546 struct bgp_path_info *bpi_ultimate;
547
548 if (info->sub_type != BGP_ROUTE_IMPORTED)
549 return info;
550
551 for (bpi_ultimate = info;
552 bpi_ultimate->extra && bpi_ultimate->extra->parent;
553 bpi_ultimate = bpi_ultimate->extra->parent)
554 ;
555
556 return bpi_ultimate;
557 }
558
559 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
560 */
561 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
562 struct bgp_path_info *exist, int *paths_eq,
563 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
564 char *pfx_buf, afi_t afi, safi_t safi,
565 enum bgp_path_selection_reason *reason)
566 {
567 const struct prefix *new_p;
568 struct attr *newattr, *existattr;
569 enum bgp_peer_sort new_sort;
570 enum bgp_peer_sort exist_sort;
571 uint32_t new_pref;
572 uint32_t exist_pref;
573 uint32_t new_med;
574 uint32_t exist_med;
575 uint32_t new_weight;
576 uint32_t exist_weight;
577 uint32_t newm, existm;
578 struct in_addr new_id;
579 struct in_addr exist_id;
580 int new_cluster;
581 int exist_cluster;
582 int internal_as_route;
583 int confed_as_route;
584 int ret = 0;
585 int igp_metric_ret = 0;
586 int peer_sort_ret = -1;
587 char new_buf[PATH_ADDPATH_STR_BUFFER];
588 char exist_buf[PATH_ADDPATH_STR_BUFFER];
589 uint32_t new_mm_seq;
590 uint32_t exist_mm_seq;
591 int nh_cmp;
592 esi_t *exist_esi;
593 esi_t *new_esi;
594 bool same_esi;
595 bool old_proxy;
596 bool new_proxy;
597 bool new_origin, exist_origin;
598 struct bgp_path_info *bpi_ultimate;
599
600 *paths_eq = 0;
601
602 /* 0. Null check. */
603 if (new == NULL) {
604 *reason = bgp_path_selection_none;
605 if (debug)
606 zlog_debug("%s: new is NULL", pfx_buf);
607 return 0;
608 }
609
610 if (debug) {
611 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
612 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, new_buf,
613 sizeof(new_buf));
614 }
615
616 if (exist == NULL) {
617 *reason = bgp_path_selection_first;
618 if (debug)
619 zlog_debug("%s(%s): %s is the initial bestpath",
620 pfx_buf, bgp->name_pretty, new_buf);
621 return 1;
622 }
623
624 if (debug) {
625 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
626 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, exist_buf,
627 sizeof(exist_buf));
628 zlog_debug("%s(%s): Comparing %s flags 0x%x with %s flags 0x%x",
629 pfx_buf, bgp->name_pretty, new_buf, new->flags,
630 exist_buf, exist->flags);
631 }
632
633 newattr = new->attr;
634 existattr = exist->attr;
635
636 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
637 * Capability" to a neighbor MUST perform the following upon receiving
638 * a route from that neighbor with the "LLGR_STALE" community, or upon
639 * attaching the "LLGR_STALE" community itself per Section 4.2:
640 *
641 * Treat the route as the least-preferred in route selection (see
642 * below). See the Risks of Depreferencing Routes section (Section 5.2)
643 * for a discussion of potential risks inherent in doing this.
644 */
645 if (bgp_attr_get_community(newattr) &&
646 community_include(bgp_attr_get_community(newattr),
647 COMMUNITY_LLGR_STALE)) {
648 if (debug)
649 zlog_debug(
650 "%s: %s wins over %s due to LLGR_STALE community",
651 pfx_buf, new_buf, exist_buf);
652 return 0;
653 }
654
655 if (bgp_attr_get_community(existattr) &&
656 community_include(bgp_attr_get_community(existattr),
657 COMMUNITY_LLGR_STALE)) {
658 if (debug)
659 zlog_debug(
660 "%s: %s loses to %s due to LLGR_STALE community",
661 pfx_buf, new_buf, exist_buf);
662 return 1;
663 }
664
665 new_p = bgp_dest_get_prefix(new->net);
666
667 /* For EVPN routes, we cannot just go by local vs remote, we have to
668 * look at the MAC mobility sequence number, if present.
669 */
670 if ((safi == SAFI_EVPN)
671 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
672 /* This is an error condition described in RFC 7432 Section
673 * 15.2. The RFC
674 * states that in this scenario "the PE MUST alert the operator"
675 * but it
676 * does not state what other action to take. In order to provide
677 * some
678 * consistency in this scenario we are going to prefer the path
679 * with the
680 * sticky flag.
681 */
682 if (newattr->sticky != existattr->sticky) {
683 if (!debug) {
684 prefix2str(new_p, pfx_buf,
685 sizeof(*pfx_buf)
686 * PREFIX2STR_BUFFER);
687 bgp_path_info_path_with_addpath_rx_str(
688 new, new_buf, sizeof(new_buf));
689 bgp_path_info_path_with_addpath_rx_str(
690 exist, exist_buf, sizeof(exist_buf));
691 }
692
693 if (newattr->sticky && !existattr->sticky) {
694 *reason = bgp_path_selection_evpn_sticky_mac;
695 if (debug)
696 zlog_debug(
697 "%s: %s wins over %s due to sticky MAC flag",
698 pfx_buf, new_buf, exist_buf);
699 return 1;
700 }
701
702 if (!newattr->sticky && existattr->sticky) {
703 *reason = bgp_path_selection_evpn_sticky_mac;
704 if (debug)
705 zlog_debug(
706 "%s: %s loses to %s due to sticky MAC flag",
707 pfx_buf, new_buf, exist_buf);
708 return 0;
709 }
710 }
711
712 new_esi = bgp_evpn_attr_get_esi(newattr);
713 exist_esi = bgp_evpn_attr_get_esi(existattr);
714 if (bgp_evpn_is_esi_valid(new_esi) &&
715 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
716 same_esi = true;
717 } else {
718 same_esi = false;
719 }
720
721 /* If both paths have the same non-zero ES and
722 * one path is local it wins.
723 * PS: Note the local path wins even if the remote
724 * has the higher MM seq. The local path's
725 * MM seq will be fixed up to match the highest
726 * rem seq, subsequently.
727 */
728 if (same_esi) {
729 char esi_buf[ESI_STR_LEN];
730
731 if (bgp_evpn_is_path_local(bgp, new)) {
732 *reason = bgp_path_selection_evpn_local_path;
733 if (debug)
734 zlog_debug(
735 "%s: %s wins over %s as ES %s is same and local",
736 pfx_buf, new_buf, exist_buf,
737 esi_to_str(new_esi, esi_buf,
738 sizeof(esi_buf)));
739 return 1;
740 }
741 if (bgp_evpn_is_path_local(bgp, exist)) {
742 *reason = bgp_path_selection_evpn_local_path;
743 if (debug)
744 zlog_debug(
745 "%s: %s loses to %s as ES %s is same and local",
746 pfx_buf, new_buf, exist_buf,
747 esi_to_str(new_esi, esi_buf,
748 sizeof(esi_buf)));
749 return 0;
750 }
751 }
752
753 new_mm_seq = mac_mobility_seqnum(newattr);
754 exist_mm_seq = mac_mobility_seqnum(existattr);
755
756 if (new_mm_seq > exist_mm_seq) {
757 *reason = bgp_path_selection_evpn_seq;
758 if (debug)
759 zlog_debug(
760 "%s: %s wins over %s due to MM seq %u > %u",
761 pfx_buf, new_buf, exist_buf, new_mm_seq,
762 exist_mm_seq);
763 return 1;
764 }
765
766 if (new_mm_seq < exist_mm_seq) {
767 *reason = bgp_path_selection_evpn_seq;
768 if (debug)
769 zlog_debug(
770 "%s: %s loses to %s due to MM seq %u < %u",
771 pfx_buf, new_buf, exist_buf, new_mm_seq,
772 exist_mm_seq);
773 return 0;
774 }
775
776 /* if the sequence numbers and ESI are the same and one path
777 * is non-proxy it wins (over proxy)
778 */
779 new_proxy = bgp_evpn_attr_is_proxy(newattr);
780 old_proxy = bgp_evpn_attr_is_proxy(existattr);
781 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
782 old_proxy != new_proxy) {
783 if (!new_proxy) {
784 *reason = bgp_path_selection_evpn_non_proxy;
785 if (debug)
786 zlog_debug(
787 "%s: %s wins over %s, same seq/es and non-proxy",
788 pfx_buf, new_buf, exist_buf);
789 return 1;
790 }
791
792 *reason = bgp_path_selection_evpn_non_proxy;
793 if (debug)
794 zlog_debug(
795 "%s: %s loses to %s, same seq/es and non-proxy",
796 pfx_buf, new_buf, exist_buf);
797 return 0;
798 }
799
800 /*
801 * if sequence numbers are the same path with the lowest IP
802 * wins
803 */
804 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
805 if (nh_cmp < 0) {
806 *reason = bgp_path_selection_evpn_lower_ip;
807 if (debug)
808 zlog_debug(
809 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
810 pfx_buf, new_buf, exist_buf, new_mm_seq,
811 &new->attr->nexthop);
812 return 1;
813 }
814 if (nh_cmp > 0) {
815 *reason = bgp_path_selection_evpn_lower_ip;
816 if (debug)
817 zlog_debug(
818 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
819 pfx_buf, new_buf, exist_buf, new_mm_seq,
820 &new->attr->nexthop);
821 return 0;
822 }
823 }
824
825 /* 1. Weight check. */
826 new_weight = newattr->weight;
827 exist_weight = existattr->weight;
828
829 if (new_weight > exist_weight) {
830 *reason = bgp_path_selection_weight;
831 if (debug)
832 zlog_debug("%s: %s wins over %s due to weight %d > %d",
833 pfx_buf, new_buf, exist_buf, new_weight,
834 exist_weight);
835 return 1;
836 }
837
838 if (new_weight < exist_weight) {
839 *reason = bgp_path_selection_weight;
840 if (debug)
841 zlog_debug("%s: %s loses to %s due to weight %d < %d",
842 pfx_buf, new_buf, exist_buf, new_weight,
843 exist_weight);
844 return 0;
845 }
846
847 /* 2. Local preference check. */
848 new_pref = exist_pref = bgp->default_local_pref;
849
850 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
851 new_pref = newattr->local_pref;
852 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
853 exist_pref = existattr->local_pref;
854
855 if (new_pref > exist_pref) {
856 *reason = bgp_path_selection_local_pref;
857 if (debug)
858 zlog_debug(
859 "%s: %s wins over %s due to localpref %d > %d",
860 pfx_buf, new_buf, exist_buf, new_pref,
861 exist_pref);
862 return 1;
863 }
864
865 if (new_pref < exist_pref) {
866 *reason = bgp_path_selection_local_pref;
867 if (debug)
868 zlog_debug(
869 "%s: %s loses to %s due to localpref %d < %d",
870 pfx_buf, new_buf, exist_buf, new_pref,
871 exist_pref);
872 return 0;
873 }
874
875 /* If a BGP speaker supports ACCEPT_OWN and is configured for the
876 * extensions defined in this document, the following step is inserted
877 * after the LOCAL_PREF comparison step in the BGP decision process:
878 * When comparing a pair of routes for a BGP destination, the
879 * route with the ACCEPT_OWN community attached is preferred over
880 * the route that does not have the community.
881 * This extra step MUST only be invoked during the best path selection
882 * process of VPN-IP routes.
883 */
884 if (safi == SAFI_MPLS_VPN &&
885 (CHECK_FLAG(new->peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN) ||
886 CHECK_FLAG(exist->peer->af_flags[afi][safi],
887 PEER_FLAG_ACCEPT_OWN))) {
888 bool new_accept_own = false;
889 bool exist_accept_own = false;
890 uint32_t accept_own = COMMUNITY_ACCEPT_OWN;
891
892 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
893 new_accept_own = community_include(
894 bgp_attr_get_community(newattr), accept_own);
895 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
896 exist_accept_own = community_include(
897 bgp_attr_get_community(existattr), accept_own);
898
899 if (new_accept_own && !exist_accept_own) {
900 *reason = bgp_path_selection_accept_own;
901 if (debug)
902 zlog_debug(
903 "%s: %s wins over %s due to accept-own",
904 pfx_buf, new_buf, exist_buf);
905 return 1;
906 }
907
908 if (!new_accept_own && exist_accept_own) {
909 *reason = bgp_path_selection_accept_own;
910 if (debug)
911 zlog_debug(
912 "%s: %s loses to %s due to accept-own",
913 pfx_buf, new_buf, exist_buf);
914 return 0;
915 }
916 }
917
918 /* Tie-breaker - AIGP (Metric TLV) attribute */
919 if (CHECK_FLAG(newattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
920 CHECK_FLAG(existattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
921 CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_AIGP)) {
922 uint64_t new_aigp = bgp_attr_get_aigp_metric(newattr);
923 uint64_t exist_aigp = bgp_attr_get_aigp_metric(existattr);
924
925 if (new_aigp < exist_aigp) {
926 *reason = bgp_path_selection_aigp;
927 if (debug)
928 zlog_debug(
929 "%s: %s wins over %s due to AIGP %" PRIu64
930 " < %" PRIu64,
931 pfx_buf, new_buf, exist_buf, new_aigp,
932 exist_aigp);
933 return 1;
934 }
935
936 if (new_aigp > exist_aigp) {
937 *reason = bgp_path_selection_aigp;
938 if (debug)
939 zlog_debug(
940 "%s: %s loses to %s due to AIGP %" PRIu64
941 " > %" PRIu64,
942 pfx_buf, new_buf, exist_buf, new_aigp,
943 exist_aigp);
944 return 0;
945 }
946 }
947
948 /* 3. Local route check. We prefer:
949 * - BGP_ROUTE_STATIC
950 * - BGP_ROUTE_AGGREGATE
951 * - BGP_ROUTE_REDISTRIBUTE
952 */
953 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
954 new->sub_type == BGP_ROUTE_IMPORTED);
955 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
956 exist->sub_type == BGP_ROUTE_IMPORTED);
957
958 if (new_origin && !exist_origin) {
959 *reason = bgp_path_selection_local_route;
960 if (debug)
961 zlog_debug(
962 "%s: %s wins over %s due to preferred BGP_ROUTE type",
963 pfx_buf, new_buf, exist_buf);
964 return 1;
965 }
966
967 if (!new_origin && exist_origin) {
968 *reason = bgp_path_selection_local_route;
969 if (debug)
970 zlog_debug(
971 "%s: %s loses to %s due to preferred BGP_ROUTE type",
972 pfx_buf, new_buf, exist_buf);
973 return 0;
974 }
975
976 /* Here if these are imported routes then get ultimate pi for
977 * path compare.
978 */
979 new = bgp_get_imported_bpi_ultimate(new);
980 exist = bgp_get_imported_bpi_ultimate(exist);
981 newattr = new->attr;
982 existattr = exist->attr;
983
984 /* 4. AS path length check. */
985 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
986 int exist_hops = aspath_count_hops(existattr->aspath);
987 int exist_confeds = aspath_count_confeds(existattr->aspath);
988
989 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
990 int aspath_hops;
991
992 aspath_hops = aspath_count_hops(newattr->aspath);
993 aspath_hops += aspath_count_confeds(newattr->aspath);
994
995 if (aspath_hops < (exist_hops + exist_confeds)) {
996 *reason = bgp_path_selection_confed_as_path;
997 if (debug)
998 zlog_debug(
999 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
1000 pfx_buf, new_buf, exist_buf,
1001 aspath_hops,
1002 (exist_hops + exist_confeds));
1003 return 1;
1004 }
1005
1006 if (aspath_hops > (exist_hops + exist_confeds)) {
1007 *reason = bgp_path_selection_confed_as_path;
1008 if (debug)
1009 zlog_debug(
1010 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
1011 pfx_buf, new_buf, exist_buf,
1012 aspath_hops,
1013 (exist_hops + exist_confeds));
1014 return 0;
1015 }
1016 } else {
1017 int newhops = aspath_count_hops(newattr->aspath);
1018
1019 if (newhops < exist_hops) {
1020 *reason = bgp_path_selection_as_path;
1021 if (debug)
1022 zlog_debug(
1023 "%s: %s wins over %s due to aspath hopcount %d < %d",
1024 pfx_buf, new_buf, exist_buf,
1025 newhops, exist_hops);
1026 return 1;
1027 }
1028
1029 if (newhops > exist_hops) {
1030 *reason = bgp_path_selection_as_path;
1031 if (debug)
1032 zlog_debug(
1033 "%s: %s loses to %s due to aspath hopcount %d > %d",
1034 pfx_buf, new_buf, exist_buf,
1035 newhops, exist_hops);
1036 return 0;
1037 }
1038 }
1039 }
1040
1041 /* 5. Origin check. */
1042 if (newattr->origin < existattr->origin) {
1043 *reason = bgp_path_selection_origin;
1044 if (debug)
1045 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
1046 pfx_buf, new_buf, exist_buf,
1047 bgp_origin_long_str[newattr->origin],
1048 bgp_origin_long_str[existattr->origin]);
1049 return 1;
1050 }
1051
1052 if (newattr->origin > existattr->origin) {
1053 *reason = bgp_path_selection_origin;
1054 if (debug)
1055 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
1056 pfx_buf, new_buf, exist_buf,
1057 bgp_origin_long_str[newattr->origin],
1058 bgp_origin_long_str[existattr->origin]);
1059 return 0;
1060 }
1061
1062 /* 6. MED check. */
1063 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
1064 && aspath_count_hops(existattr->aspath) == 0);
1065 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
1066 && aspath_count_confeds(existattr->aspath) > 0
1067 && aspath_count_hops(newattr->aspath) == 0
1068 && aspath_count_hops(existattr->aspath) == 0);
1069
1070 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
1071 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
1072 || aspath_cmp_left(newattr->aspath, existattr->aspath)
1073 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
1074 || internal_as_route) {
1075 new_med = bgp_med_value(new->attr, bgp);
1076 exist_med = bgp_med_value(exist->attr, bgp);
1077
1078 if (new_med < exist_med) {
1079 *reason = bgp_path_selection_med;
1080 if (debug)
1081 zlog_debug(
1082 "%s: %s wins over %s due to MED %d < %d",
1083 pfx_buf, new_buf, exist_buf, new_med,
1084 exist_med);
1085 return 1;
1086 }
1087
1088 if (new_med > exist_med) {
1089 *reason = bgp_path_selection_med;
1090 if (debug)
1091 zlog_debug(
1092 "%s: %s loses to %s due to MED %d > %d",
1093 pfx_buf, new_buf, exist_buf, new_med,
1094 exist_med);
1095 return 0;
1096 }
1097 }
1098
1099 /* 7. Peer type check. */
1100 new_sort = new->peer->sort;
1101 exist_sort = exist->peer->sort;
1102
1103 if (new_sort == BGP_PEER_EBGP
1104 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1105 *reason = bgp_path_selection_peer;
1106 if (debug)
1107 zlog_debug(
1108 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1109 pfx_buf, new_buf, exist_buf);
1110 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1111 return 1;
1112 peer_sort_ret = 1;
1113 }
1114
1115 if (exist_sort == BGP_PEER_EBGP
1116 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1117 *reason = bgp_path_selection_peer;
1118 if (debug)
1119 zlog_debug(
1120 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1121 pfx_buf, new_buf, exist_buf);
1122 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1123 return 0;
1124 peer_sort_ret = 0;
1125 }
1126
1127 /* 8. IGP metric check. */
1128 newm = existm = 0;
1129
1130 if (new->extra)
1131 newm = new->extra->igpmetric;
1132 if (exist->extra)
1133 existm = exist->extra->igpmetric;
1134
1135 if (newm < existm) {
1136 if (debug && peer_sort_ret < 0)
1137 zlog_debug(
1138 "%s: %s wins over %s due to IGP metric %u < %u",
1139 pfx_buf, new_buf, exist_buf, newm, existm);
1140 igp_metric_ret = 1;
1141 }
1142
1143 if (newm > existm) {
1144 if (debug && peer_sort_ret < 0)
1145 zlog_debug(
1146 "%s: %s loses to %s due to IGP metric %u > %u",
1147 pfx_buf, new_buf, exist_buf, newm, existm);
1148 igp_metric_ret = 0;
1149 }
1150
1151 /* 9. Same IGP metric. Compare the cluster list length as
1152 representative of IGP hops metric. Rewrite the metric value
1153 pair (newm, existm) with the cluster list length. Prefer the
1154 path with smaller cluster list length. */
1155 if (newm == existm) {
1156 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP &&
1157 peer_sort_lookup(exist->peer) == BGP_PEER_IBGP &&
1158 (mpath_cfg == NULL || mpath_cfg->same_clusterlen)) {
1159 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1160 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1161
1162 if (newm < existm) {
1163 if (debug && peer_sort_ret < 0)
1164 zlog_debug(
1165 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1166 pfx_buf, new_buf, exist_buf,
1167 newm, existm);
1168 igp_metric_ret = 1;
1169 }
1170
1171 if (newm > existm) {
1172 if (debug && peer_sort_ret < 0)
1173 zlog_debug(
1174 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1175 pfx_buf, new_buf, exist_buf,
1176 newm, existm);
1177 igp_metric_ret = 0;
1178 }
1179 }
1180 }
1181
1182 /* 10. confed-external vs. confed-internal */
1183 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1184 if (new_sort == BGP_PEER_CONFED
1185 && exist_sort == BGP_PEER_IBGP) {
1186 *reason = bgp_path_selection_confed;
1187 if (debug)
1188 zlog_debug(
1189 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1190 pfx_buf, new_buf, exist_buf);
1191 if (!CHECK_FLAG(bgp->flags,
1192 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1193 return 1;
1194 peer_sort_ret = 1;
1195 }
1196
1197 if (exist_sort == BGP_PEER_CONFED
1198 && new_sort == BGP_PEER_IBGP) {
1199 *reason = bgp_path_selection_confed;
1200 if (debug)
1201 zlog_debug(
1202 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1203 pfx_buf, new_buf, exist_buf);
1204 if (!CHECK_FLAG(bgp->flags,
1205 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1206 return 0;
1207 peer_sort_ret = 0;
1208 }
1209 }
1210
1211 /* 11. Maximum path check. */
1212 if (newm == existm) {
1213 /* If one path has a label but the other does not, do not treat
1214 * them as equals for multipath
1215 */
1216 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1217 != (exist->extra
1218 && bgp_is_valid_label(&exist->extra->label[0]))) {
1219 if (debug)
1220 zlog_debug(
1221 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1222 pfx_buf, new_buf, exist_buf);
1223 } else if (CHECK_FLAG(bgp->flags,
1224 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1225
1226 /*
1227 * For the two paths, all comparison steps till IGP
1228 * metric
1229 * have succeeded - including AS_PATH hop count. Since
1230 * 'bgp
1231 * bestpath as-path multipath-relax' knob is on, we
1232 * don't need
1233 * an exact match of AS_PATH. Thus, mark the paths are
1234 * equal.
1235 * That will trigger both these paths to get into the
1236 * multipath
1237 * array.
1238 */
1239 *paths_eq = 1;
1240
1241 if (debug)
1242 zlog_debug(
1243 "%s: %s and %s are equal via multipath-relax",
1244 pfx_buf, new_buf, exist_buf);
1245 } else if (new->peer->sort == BGP_PEER_IBGP) {
1246 if (aspath_cmp(new->attr->aspath,
1247 exist->attr->aspath)) {
1248 *paths_eq = 1;
1249
1250 if (debug)
1251 zlog_debug(
1252 "%s: %s and %s are equal via matching aspaths",
1253 pfx_buf, new_buf, exist_buf);
1254 }
1255 } else if (new->peer->as == exist->peer->as) {
1256 *paths_eq = 1;
1257
1258 if (debug)
1259 zlog_debug(
1260 "%s: %s and %s are equal via same remote-as",
1261 pfx_buf, new_buf, exist_buf);
1262 }
1263 } else {
1264 /*
1265 * TODO: If unequal cost ibgp multipath is enabled we can
1266 * mark the paths as equal here instead of returning
1267 */
1268
1269 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1270 * if either step 7 or 10 (peer type checks) yielded a winner,
1271 * that result was returned immediately. Returning from step 10
1272 * ignored the return value computed in steps 8 and 9 (IGP
1273 * metric checks). In order to preserve that behavior, if
1274 * peer_sort_ret is set, return that rather than igp_metric_ret.
1275 */
1276 ret = peer_sort_ret;
1277 if (peer_sort_ret < 0) {
1278 ret = igp_metric_ret;
1279 if (debug) {
1280 if (ret == 1)
1281 zlog_debug(
1282 "%s: %s wins over %s after IGP metric comparison",
1283 pfx_buf, new_buf, exist_buf);
1284 else
1285 zlog_debug(
1286 "%s: %s loses to %s after IGP metric comparison",
1287 pfx_buf, new_buf, exist_buf);
1288 }
1289 *reason = bgp_path_selection_igp_metric;
1290 }
1291 return ret;
1292 }
1293
1294 /*
1295 * At this point, the decision whether to set *paths_eq = 1 has been
1296 * completed. If we deferred returning because of bestpath peer-type
1297 * relax configuration, return now.
1298 */
1299 if (peer_sort_ret >= 0)
1300 return peer_sort_ret;
1301
1302 /* 12. If both paths are external, prefer the path that was received
1303 first (the oldest one). This step minimizes route-flap, since a
1304 newer path won't displace an older one, even if it was the
1305 preferred route based on the additional decision criteria below. */
1306 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1307 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1308 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1309 *reason = bgp_path_selection_older;
1310 if (debug)
1311 zlog_debug(
1312 "%s: %s wins over %s due to oldest external",
1313 pfx_buf, new_buf, exist_buf);
1314 return 1;
1315 }
1316
1317 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1318 *reason = bgp_path_selection_older;
1319 if (debug)
1320 zlog_debug(
1321 "%s: %s loses to %s due to oldest external",
1322 pfx_buf, new_buf, exist_buf);
1323 return 0;
1324 }
1325 }
1326
1327 /* 13. Router-ID comparison. */
1328 /* If one of the paths is "stale", the corresponding peer router-id will
1329 * be 0 and would always win over the other path. If originator id is
1330 * used for the comparison, it will decide which path is better.
1331 */
1332 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1333 new_id.s_addr = newattr->originator_id.s_addr;
1334 else
1335 new_id.s_addr = new->peer->remote_id.s_addr;
1336 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1337 exist_id.s_addr = existattr->originator_id.s_addr;
1338 else
1339 exist_id.s_addr = exist->peer->remote_id.s_addr;
1340
1341 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1342 *reason = bgp_path_selection_router_id;
1343 if (debug)
1344 zlog_debug(
1345 "%s: %s wins over %s due to Router-ID comparison",
1346 pfx_buf, new_buf, exist_buf);
1347 return 1;
1348 }
1349
1350 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1351 *reason = bgp_path_selection_router_id;
1352 if (debug)
1353 zlog_debug(
1354 "%s: %s loses to %s due to Router-ID comparison",
1355 pfx_buf, new_buf, exist_buf);
1356 return 0;
1357 }
1358
1359 /* 14. Cluster length comparison. */
1360 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1361 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1362
1363 if (new_cluster < exist_cluster) {
1364 *reason = bgp_path_selection_cluster_length;
1365 if (debug)
1366 zlog_debug(
1367 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1368 pfx_buf, new_buf, exist_buf, new_cluster,
1369 exist_cluster);
1370 return 1;
1371 }
1372
1373 if (new_cluster > exist_cluster) {
1374 *reason = bgp_path_selection_cluster_length;
1375 if (debug)
1376 zlog_debug(
1377 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1378 pfx_buf, new_buf, exist_buf, new_cluster,
1379 exist_cluster);
1380 return 0;
1381 }
1382
1383 /* 15. Neighbor address comparison. */
1384 /* Do this only if neither path is "stale" as stale paths do not have
1385 * valid peer information (as the connection may or may not be up).
1386 */
1387 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1388 *reason = bgp_path_selection_stale;
1389 if (debug)
1390 zlog_debug(
1391 "%s: %s wins over %s due to latter path being STALE",
1392 pfx_buf, new_buf, exist_buf);
1393 return 1;
1394 }
1395
1396 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1397 *reason = bgp_path_selection_stale;
1398 if (debug)
1399 zlog_debug(
1400 "%s: %s loses to %s due to former path being STALE",
1401 pfx_buf, new_buf, exist_buf);
1402 return 0;
1403 }
1404
1405 /* locally configured routes to advertise do not have su_remote */
1406 if (new->peer->su_remote == NULL) {
1407 *reason = bgp_path_selection_local_configured;
1408 return 0;
1409 }
1410 if (exist->peer->su_remote == NULL) {
1411 *reason = bgp_path_selection_local_configured;
1412 return 1;
1413 }
1414
1415 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1416
1417 if (ret == 1) {
1418 *reason = bgp_path_selection_neighbor_ip;
1419 if (debug)
1420 zlog_debug(
1421 "%s: %s loses to %s due to Neighor IP comparison",
1422 pfx_buf, new_buf, exist_buf);
1423 return 0;
1424 }
1425
1426 if (ret == -1) {
1427 *reason = bgp_path_selection_neighbor_ip;
1428 if (debug)
1429 zlog_debug(
1430 "%s: %s wins over %s due to Neighor IP comparison",
1431 pfx_buf, new_buf, exist_buf);
1432 return 1;
1433 }
1434
1435 *reason = bgp_path_selection_default;
1436 if (debug)
1437 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1438 pfx_buf, new_buf, exist_buf);
1439
1440 return 1;
1441 }
1442
1443
1444 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1445 struct bgp_path_info *exist, int *paths_eq)
1446 {
1447 enum bgp_path_selection_reason reason;
1448 char pfx_buf[PREFIX2STR_BUFFER];
1449
1450 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1451 AFI_L2VPN, SAFI_EVPN, &reason);
1452 }
1453
1454 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1455 * is preferred, or 0 if they are the same (usually will only occur if
1456 * multipath is enabled
1457 * This version is compatible with */
1458 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1459 struct bgp_path_info *exist, char *pfx_buf,
1460 afi_t afi, safi_t safi,
1461 enum bgp_path_selection_reason *reason)
1462 {
1463 int paths_eq;
1464 int ret;
1465 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1466 afi, safi, reason);
1467
1468 if (paths_eq)
1469 ret = 0;
1470 else {
1471 if (ret == 1)
1472 ret = -1;
1473 else
1474 ret = 1;
1475 }
1476 return ret;
1477 }
1478
1479 static enum filter_type bgp_input_filter(struct peer *peer,
1480 const struct prefix *p,
1481 struct attr *attr, afi_t afi,
1482 safi_t safi)
1483 {
1484 struct bgp_filter *filter;
1485 enum filter_type ret = FILTER_PERMIT;
1486
1487 filter = &peer->filter[afi][safi];
1488
1489 #define FILTER_EXIST_WARN(F, f, filter) \
1490 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1491 zlog_debug("%s: Could not find configured input %s-list %s!", \
1492 peer->host, #f, F##_IN_NAME(filter));
1493
1494 if (DISTRIBUTE_IN_NAME(filter)) {
1495 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1496
1497 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1498 == FILTER_DENY) {
1499 ret = FILTER_DENY;
1500 goto done;
1501 }
1502 }
1503
1504 if (PREFIX_LIST_IN_NAME(filter)) {
1505 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1506
1507 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1508 == PREFIX_DENY) {
1509 ret = FILTER_DENY;
1510 goto done;
1511 }
1512 }
1513
1514 if (FILTER_LIST_IN_NAME(filter)) {
1515 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1516
1517 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1518 == AS_FILTER_DENY) {
1519 ret = FILTER_DENY;
1520 goto done;
1521 }
1522 }
1523
1524 done:
1525 if (frrtrace_enabled(frr_bgp, input_filter)) {
1526 char pfxprint[PREFIX2STR_BUFFER];
1527
1528 prefix2str(p, pfxprint, sizeof(pfxprint));
1529 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1530 ret == FILTER_PERMIT ? "permit" : "deny");
1531 }
1532
1533 return ret;
1534 #undef FILTER_EXIST_WARN
1535 }
1536
1537 static enum filter_type bgp_output_filter(struct peer *peer,
1538 const struct prefix *p,
1539 struct attr *attr, afi_t afi,
1540 safi_t safi)
1541 {
1542 struct bgp_filter *filter;
1543 enum filter_type ret = FILTER_PERMIT;
1544
1545 filter = &peer->filter[afi][safi];
1546
1547 #define FILTER_EXIST_WARN(F, f, filter) \
1548 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1549 zlog_debug("%s: Could not find configured output %s-list %s!", \
1550 peer->host, #f, F##_OUT_NAME(filter));
1551
1552 if (DISTRIBUTE_OUT_NAME(filter)) {
1553 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1554
1555 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1556 == FILTER_DENY) {
1557 ret = FILTER_DENY;
1558 goto done;
1559 }
1560 }
1561
1562 if (PREFIX_LIST_OUT_NAME(filter)) {
1563 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1564
1565 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1566 == PREFIX_DENY) {
1567 ret = FILTER_DENY;
1568 goto done;
1569 }
1570 }
1571
1572 if (FILTER_LIST_OUT_NAME(filter)) {
1573 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1574
1575 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1576 == AS_FILTER_DENY) {
1577 ret = FILTER_DENY;
1578 goto done;
1579 }
1580 }
1581
1582 if (frrtrace_enabled(frr_bgp, output_filter)) {
1583 char pfxprint[PREFIX2STR_BUFFER];
1584
1585 prefix2str(p, pfxprint, sizeof(pfxprint));
1586 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1587 ret == FILTER_PERMIT ? "permit" : "deny");
1588 }
1589
1590 done:
1591 return ret;
1592 #undef FILTER_EXIST_WARN
1593 }
1594
1595 /* If community attribute includes no_export then return 1. */
1596 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1597 {
1598 if (bgp_attr_get_community(attr)) {
1599 /* NO_ADVERTISE check. */
1600 if (community_include(bgp_attr_get_community(attr),
1601 COMMUNITY_NO_ADVERTISE))
1602 return true;
1603
1604 /* NO_EXPORT check. */
1605 if (peer->sort == BGP_PEER_EBGP &&
1606 community_include(bgp_attr_get_community(attr),
1607 COMMUNITY_NO_EXPORT))
1608 return true;
1609
1610 /* NO_EXPORT_SUBCONFED check. */
1611 if (peer->sort == BGP_PEER_EBGP
1612 || peer->sort == BGP_PEER_CONFED)
1613 if (community_include(bgp_attr_get_community(attr),
1614 COMMUNITY_NO_EXPORT_SUBCONFED))
1615 return true;
1616 }
1617 return false;
1618 }
1619
1620 /* Route reflection loop check. */
1621 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1622 {
1623 struct in_addr cluster_id;
1624 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1625
1626 if (cluster) {
1627 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1628 cluster_id = peer->bgp->cluster_id;
1629 else
1630 cluster_id = peer->bgp->router_id;
1631
1632 if (cluster_loop_check(cluster, cluster_id))
1633 return true;
1634 }
1635 return false;
1636 }
1637
1638 static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
1639 {
1640 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1641 if (peer->local_role == ROLE_PROVIDER ||
1642 peer->local_role == ROLE_RS_SERVER)
1643 return true;
1644 if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
1645 return true;
1646 return false;
1647 }
1648 if (peer->local_role == ROLE_CUSTOMER ||
1649 peer->local_role == ROLE_PEER ||
1650 peer->local_role == ROLE_RS_CLIENT) {
1651 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1652 attr->otc = peer->as;
1653 }
1654 return false;
1655 }
1656
1657 static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
1658 {
1659 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1660 if (peer->local_role == ROLE_CUSTOMER ||
1661 peer->local_role == ROLE_RS_CLIENT ||
1662 peer->local_role == ROLE_PEER)
1663 return true;
1664 return false;
1665 }
1666 if (peer->local_role == ROLE_PROVIDER ||
1667 peer->local_role == ROLE_PEER ||
1668 peer->local_role == ROLE_RS_SERVER) {
1669 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1670 attr->otc = peer->bgp->as;
1671 }
1672 return false;
1673 }
1674
1675 static bool bgp_check_role_applicability(afi_t afi, safi_t safi)
1676 {
1677 return ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST);
1678 }
1679
1680 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1681 struct attr *attr, afi_t afi, safi_t safi,
1682 const char *rmap_name, mpls_label_t *label,
1683 uint32_t num_labels, struct bgp_dest *dest)
1684 {
1685 struct bgp_filter *filter;
1686 struct bgp_path_info rmap_path = { 0 };
1687 struct bgp_path_info_extra extra = { 0 };
1688 route_map_result_t ret;
1689 struct route_map *rmap = NULL;
1690
1691 filter = &peer->filter[afi][safi];
1692
1693 /* Apply default weight value. */
1694 if (peer->weight[afi][safi])
1695 attr->weight = peer->weight[afi][safi];
1696
1697 if (rmap_name) {
1698 rmap = route_map_lookup_by_name(rmap_name);
1699
1700 if (rmap == NULL)
1701 return RMAP_DENY;
1702 } else {
1703 if (ROUTE_MAP_IN_NAME(filter)) {
1704 rmap = ROUTE_MAP_IN(filter);
1705
1706 if (rmap == NULL)
1707 return RMAP_DENY;
1708 }
1709 }
1710
1711 /* Route map apply. */
1712 if (rmap) {
1713 memset(&rmap_path, 0, sizeof(rmap_path));
1714 /* Duplicate current value to new structure for modification. */
1715 rmap_path.peer = peer;
1716 rmap_path.attr = attr;
1717 rmap_path.extra = &extra;
1718 rmap_path.net = dest;
1719
1720 extra.num_labels = num_labels;
1721 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1722 memcpy(extra.label, label,
1723 num_labels * sizeof(mpls_label_t));
1724
1725 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1726
1727 /* Apply BGP route map to the attribute. */
1728 ret = route_map_apply(rmap, p, &rmap_path);
1729
1730 peer->rmap_type = 0;
1731
1732 if (ret == RMAP_DENYMATCH)
1733 return RMAP_DENY;
1734 }
1735 return RMAP_PERMIT;
1736 }
1737
1738 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1739 struct attr *attr, afi_t afi, safi_t safi,
1740 const char *rmap_name)
1741 {
1742 struct bgp_path_info rmap_path;
1743 route_map_result_t ret;
1744 struct route_map *rmap = NULL;
1745 uint8_t rmap_type;
1746
1747 /*
1748 * So if we get to this point and have no rmap_name
1749 * we want to just show the output as it currently
1750 * exists.
1751 */
1752 if (!rmap_name)
1753 return RMAP_PERMIT;
1754
1755 /* Apply default weight value. */
1756 if (peer->weight[afi][safi])
1757 attr->weight = peer->weight[afi][safi];
1758
1759 rmap = route_map_lookup_by_name(rmap_name);
1760
1761 /*
1762 * If we have a route map name and we do not find
1763 * the routemap that means we have an implicit
1764 * deny.
1765 */
1766 if (rmap == NULL)
1767 return RMAP_DENY;
1768
1769 memset(&rmap_path, 0, sizeof(rmap_path));
1770 /* Route map apply. */
1771 /* Duplicate current value to new structure for modification. */
1772 rmap_path.peer = peer;
1773 rmap_path.attr = attr;
1774
1775 rmap_type = peer->rmap_type;
1776 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1777
1778 /* Apply BGP route map to the attribute. */
1779 ret = route_map_apply(rmap, p, &rmap_path);
1780
1781 peer->rmap_type = rmap_type;
1782
1783 if (ret == RMAP_DENYMATCH)
1784 /*
1785 * caller has multiple error paths with bgp_attr_flush()
1786 */
1787 return RMAP_DENY;
1788
1789 return RMAP_PERMIT;
1790 }
1791
1792 /* If this is an EBGP peer with remove-private-AS */
1793 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1794 struct peer *peer, struct attr *attr)
1795 {
1796 if (peer->sort == BGP_PEER_EBGP
1797 && (peer_af_flag_check(peer, afi, safi,
1798 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1799 || peer_af_flag_check(peer, afi, safi,
1800 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1801 || peer_af_flag_check(peer, afi, safi,
1802 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1803 || peer_af_flag_check(peer, afi, safi,
1804 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1805 // Take action on the entire aspath
1806 if (peer_af_flag_check(peer, afi, safi,
1807 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1808 || peer_af_flag_check(peer, afi, safi,
1809 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1810 if (peer_af_flag_check(
1811 peer, afi, safi,
1812 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1813 attr->aspath = aspath_replace_private_asns(
1814 attr->aspath, bgp->as, peer->as);
1815
1816 /*
1817 * Even if the aspath consists of just private ASNs we
1818 * need to walk the AS-Path to maintain all instances
1819 * of the peer's ASN to break possible loops.
1820 */
1821 else
1822 attr->aspath = aspath_remove_private_asns(
1823 attr->aspath, peer->as);
1824 }
1825
1826 // 'all' was not specified so the entire aspath must be private
1827 // ASNs
1828 // for us to do anything
1829 else if (aspath_private_as_check(attr->aspath)) {
1830 if (peer_af_flag_check(
1831 peer, afi, safi,
1832 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1833 attr->aspath = aspath_replace_private_asns(
1834 attr->aspath, bgp->as, peer->as);
1835 else
1836 /*
1837 * Walk the aspath to retain any instances of
1838 * the peer_asn
1839 */
1840 attr->aspath = aspath_remove_private_asns(
1841 attr->aspath, peer->as);
1842 }
1843 }
1844 }
1845
1846 /* If this is an EBGP peer with as-override */
1847 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1848 struct peer *peer, struct attr *attr)
1849 {
1850 struct aspath *aspath;
1851
1852 if (peer->sort == BGP_PEER_EBGP &&
1853 peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1854 if (attr->aspath->refcnt)
1855 aspath = aspath_dup(attr->aspath);
1856 else
1857 aspath = attr->aspath;
1858
1859 attr->aspath = aspath_intern(
1860 aspath_replace_specific_asn(aspath, peer->as, bgp->as));
1861
1862 aspath_free(aspath);
1863 }
1864 }
1865
1866 void bgp_attr_add_llgr_community(struct attr *attr)
1867 {
1868 struct community *old;
1869 struct community *new;
1870 struct community *merge;
1871 struct community *llgr;
1872
1873 old = bgp_attr_get_community(attr);
1874 llgr = community_str2com("llgr-stale");
1875
1876 assert(llgr);
1877
1878 if (old) {
1879 merge = community_merge(community_dup(old), llgr);
1880
1881 if (old->refcnt == 0)
1882 community_free(&old);
1883
1884 new = community_uniq_sort(merge);
1885 community_free(&merge);
1886 } else {
1887 new = community_dup(llgr);
1888 }
1889
1890 community_free(&llgr);
1891
1892 bgp_attr_set_community(attr, new);
1893 }
1894
1895 void bgp_attr_add_gshut_community(struct attr *attr)
1896 {
1897 struct community *old;
1898 struct community *new;
1899 struct community *merge;
1900 struct community *gshut;
1901
1902 old = bgp_attr_get_community(attr);
1903 gshut = community_str2com("graceful-shutdown");
1904
1905 assert(gshut);
1906
1907 if (old) {
1908 merge = community_merge(community_dup(old), gshut);
1909
1910 if (old->refcnt == 0)
1911 community_free(&old);
1912
1913 new = community_uniq_sort(merge);
1914 community_free(&merge);
1915 } else {
1916 new = community_dup(gshut);
1917 }
1918
1919 community_free(&gshut);
1920 bgp_attr_set_community(attr, new);
1921
1922 /* When we add the graceful-shutdown community we must also
1923 * lower the local-preference */
1924 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1925 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1926 }
1927
1928
1929 /* Notify BGP Conditional advertisement scanner process. */
1930 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1931 {
1932 struct peer *peer = SUBGRP_PEER(subgrp);
1933 afi_t afi = SUBGRP_AFI(subgrp);
1934 safi_t safi = SUBGRP_SAFI(subgrp);
1935 struct bgp_filter *filter = &peer->filter[afi][safi];
1936
1937 if (!ADVERTISE_MAP_NAME(filter))
1938 return;
1939
1940 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1941 return;
1942
1943 peer->advmap_table_change = true;
1944 }
1945
1946
1947 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1948 {
1949 if (family == AF_INET) {
1950 attr->nexthop.s_addr = INADDR_ANY;
1951 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1952 }
1953 if (family == AF_INET6)
1954 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1955 if (family == AF_EVPN)
1956 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1957 }
1958
1959 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1960 struct update_subgroup *subgrp,
1961 const struct prefix *p, struct attr *attr,
1962 struct attr *post_attr)
1963 {
1964 struct bgp_filter *filter;
1965 struct peer *from;
1966 struct peer *peer;
1967 struct peer *onlypeer;
1968 struct bgp *bgp;
1969 struct attr *piattr;
1970 route_map_result_t ret;
1971 int transparent;
1972 int reflect;
1973 afi_t afi;
1974 safi_t safi;
1975 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1976 bool nh_reset = false;
1977 uint64_t cum_bw;
1978
1979 if (DISABLE_BGP_ANNOUNCE)
1980 return false;
1981
1982 afi = SUBGRP_AFI(subgrp);
1983 safi = SUBGRP_SAFI(subgrp);
1984 peer = SUBGRP_PEER(subgrp);
1985 onlypeer = NULL;
1986 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1987 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1988
1989 from = pi->peer;
1990 filter = &peer->filter[afi][safi];
1991 bgp = SUBGRP_INST(subgrp);
1992 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
1993 : pi->attr;
1994
1995 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
1996 peer->pmax_out[afi][safi] != 0 &&
1997 subgrp->pscount >= peer->pmax_out[afi][safi]) {
1998 if (BGP_DEBUG(update, UPDATE_OUT) ||
1999 BGP_DEBUG(update, UPDATE_PREFIX)) {
2000 zlog_debug("%s reached maximum prefix to be send (%u)",
2001 peer->host, peer->pmax_out[afi][safi]);
2002 }
2003 return false;
2004 }
2005
2006 #ifdef ENABLE_BGP_VNC
2007 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
2008 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
2009 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
2010
2011 /*
2012 * direct and direct_ext type routes originate internally even
2013 * though they can have peer pointers that reference other
2014 * systems
2015 */
2016 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
2017 __func__, p);
2018 samepeer_safe = 1;
2019 }
2020 #endif
2021
2022 if (((afi == AFI_IP) || (afi == AFI_IP6))
2023 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
2024 && (pi->type == ZEBRA_ROUTE_BGP)
2025 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
2026
2027 /* Applies to routes leaked vpn->vrf and vrf->vpn */
2028
2029 samepeer_safe = 1;
2030 }
2031
2032 /* With addpath we may be asked to TX all kinds of paths so make sure
2033 * pi is valid */
2034 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
2035 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
2036 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
2037 return false;
2038 }
2039
2040 /* If this is not the bestpath then check to see if there is an enabled
2041 * addpath
2042 * feature that requires us to advertise it */
2043 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2044 if (!bgp_addpath_capable(pi, peer, afi, safi))
2045 return false;
2046
2047 /* Aggregate-address suppress check. */
2048 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
2049 return false;
2050
2051 /*
2052 * If we are doing VRF 2 VRF leaking via the import
2053 * statement, we want to prevent the route going
2054 * off box as that the RT and RD created are localy
2055 * significant and globaly useless.
2056 */
2057 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
2058 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
2059 return false;
2060
2061 /* If it's labeled safi, make sure the route has a valid label. */
2062 if (safi == SAFI_LABELED_UNICAST) {
2063 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
2064 if (!bgp_is_valid_label(&label)) {
2065 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2066 zlog_debug("u%" PRIu64 ":s%" PRIu64
2067 " %pFX is filtered - no label (%p)",
2068 subgrp->update_group->id, subgrp->id,
2069 p, &label);
2070 return false;
2071 }
2072 }
2073
2074 /* Do not send back route to sender. */
2075 if (onlypeer && from == onlypeer) {
2076 return false;
2077 }
2078
2079 /* Do not send the default route in the BGP table if the neighbor is
2080 * configured for default-originate */
2081 if (CHECK_FLAG(peer->af_flags[afi][safi],
2082 PEER_FLAG_DEFAULT_ORIGINATE)) {
2083 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
2084 return false;
2085 else if (p->family == AF_INET6 && p->prefixlen == 0)
2086 return false;
2087 }
2088
2089 /* Transparency check. */
2090 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
2091 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
2092 transparent = 1;
2093 else
2094 transparent = 0;
2095
2096 /* If community is not disabled check the no-export and local. */
2097 if (!transparent && bgp_community_filter(peer, piattr)) {
2098 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2099 zlog_debug("%s: community filter check fail for %pFX",
2100 __func__, p);
2101 return false;
2102 }
2103
2104 /* If the attribute has originator-id and it is same as remote
2105 peer's id. */
2106 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
2107 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
2108 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2109 zlog_debug(
2110 "%pBP [Update:SEND] %pFX originator-id is same as remote router-id",
2111 onlypeer, p);
2112 return false;
2113 }
2114
2115 /* ORF prefix-list filter check */
2116 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
2117 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
2118 || CHECK_FLAG(peer->af_cap[afi][safi],
2119 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2120 if (peer->orf_plist[afi][safi]) {
2121 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2122 == PREFIX_DENY) {
2123 if (bgp_debug_update(NULL, p,
2124 subgrp->update_group, 0))
2125 zlog_debug(
2126 "%pBP [Update:SEND] %pFX is filtered via ORF",
2127 peer, p);
2128 return false;
2129 }
2130 }
2131
2132 /* Output filter check. */
2133 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2134 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2135 zlog_debug("%pBP [Update:SEND] %pFX is filtered", peer,
2136 p);
2137 return false;
2138 }
2139
2140 /* AS path loop check. */
2141 if (peer->as_path_loop_detection &&
2142 aspath_loop_check(piattr->aspath, peer->as)) {
2143 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2144 zlog_debug(
2145 "%pBP [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2146 peer, peer->as);
2147 return false;
2148 }
2149
2150 /* If we're a CONFED we need to loop check the CONFED ID too */
2151 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2152 if (aspath_loop_check_confed(piattr->aspath, bgp->confed_id)) {
2153 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2154 zlog_debug(
2155 "%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
2156 peer, bgp->confed_id);
2157 return false;
2158 }
2159 }
2160
2161 /* Route-Reflect check. */
2162 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2163 reflect = 1;
2164 else
2165 reflect = 0;
2166
2167 /* IBGP reflection check. */
2168 if (reflect && !samepeer_safe) {
2169 /* A route from a Client peer. */
2170 if (CHECK_FLAG(from->af_flags[afi][safi],
2171 PEER_FLAG_REFLECTOR_CLIENT)) {
2172 /* Reflect to all the Non-Client peers and also to the
2173 Client peers other than the originator. Originator
2174 check
2175 is already done. So there is noting to do. */
2176 /* no bgp client-to-client reflection check. */
2177 if (CHECK_FLAG(bgp->flags,
2178 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2179 if (CHECK_FLAG(peer->af_flags[afi][safi],
2180 PEER_FLAG_REFLECTOR_CLIENT))
2181 return false;
2182 } else {
2183 /* A route from a Non-client peer. Reflect to all other
2184 clients. */
2185 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2186 PEER_FLAG_REFLECTOR_CLIENT))
2187 return false;
2188 }
2189 }
2190
2191 /* For modify attribute, copy it to temporary structure.
2192 * post_attr comes from BGP conditional advertisements, where
2193 * attributes are already processed by advertise-map route-map,
2194 * and this needs to be saved instead of overwriting from the
2195 * path attributes.
2196 */
2197 if (post_attr)
2198 *attr = *post_attr;
2199 else
2200 *attr = *piattr;
2201
2202 /* If local-preference is not set. */
2203 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2204 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2205 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2206 attr->local_pref = bgp->default_local_pref;
2207 }
2208
2209 /* If originator-id is not set and the route is to be reflected,
2210 set the originator id */
2211 if (reflect
2212 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2213 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2214 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2215 }
2216
2217 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2218 */
2219 if (peer->sort == BGP_PEER_EBGP
2220 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2221 if (from != bgp->peer_self && !transparent
2222 && !CHECK_FLAG(peer->af_flags[afi][safi],
2223 PEER_FLAG_MED_UNCHANGED))
2224 attr->flag &=
2225 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2226 }
2227
2228 /* Since the nexthop attribute can vary per peer, it is not explicitly
2229 * set
2230 * in announce check, only certain flags and length (or number of
2231 * nexthops
2232 * -- for IPv6/MP_REACH) are set here in order to guide the update
2233 * formation
2234 * code in setting the nexthop(s) on a per peer basis in
2235 * reformat_peer().
2236 * Typically, the source nexthop in the attribute is preserved but in
2237 * the
2238 * scenarios where we know it will always be overwritten, we reset the
2239 * nexthop to "0" in an attempt to achieve better Update packing. An
2240 * example of this is when a prefix from each of 2 IBGP peers needs to
2241 * be
2242 * announced to an EBGP peer (and they have the same attributes barring
2243 * their nexthop).
2244 */
2245 if (reflect)
2246 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2247
2248 #define NEXTHOP_IS_V6 \
2249 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2250 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2251 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2252 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2253
2254 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2255 * if
2256 * the peer (group) is configured to receive link-local nexthop
2257 * unchanged
2258 * and it is available in the prefix OR we're not reflecting the route,
2259 * link-local nexthop address is valid and
2260 * the peer (group) to whom we're going to announce is on a shared
2261 * network
2262 * and this is either a self-originated route or the peer is EBGP.
2263 * By checking if nexthop LL address is valid we are sure that
2264 * we do not announce LL address as `::`.
2265 */
2266 if (NEXTHOP_IS_V6) {
2267 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2268 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2269 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2270 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2271 || (!reflect && !transparent
2272 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2273 && peer->shared_network
2274 && (from == bgp->peer_self
2275 || peer->sort == BGP_PEER_EBGP))) {
2276 if (safi == SAFI_MPLS_VPN)
2277 attr->mp_nexthop_len =
2278 BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL;
2279 else
2280 attr->mp_nexthop_len =
2281 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2282 }
2283
2284 /* Clear off link-local nexthop in source, whenever it is not
2285 * needed to
2286 * ensure more prefixes share the same attribute for
2287 * announcement.
2288 */
2289 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2290 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2291 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2292 }
2293
2294 if (bgp_check_role_applicability(afi, safi) &&
2295 bgp_otc_egress(peer, attr))
2296 return false;
2297
2298 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2299 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2300
2301 if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
2302 filter->advmap.aname &&
2303 route_map_lookup_by_name(filter->advmap.aname)) {
2304 struct bgp_path_info rmap_path = {0};
2305 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2306 struct attr dummy_attr = *attr;
2307
2308 /* Fill temp path_info */
2309 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2310 pi, peer, &dummy_attr);
2311
2312 struct route_map *amap =
2313 route_map_lookup_by_name(filter->advmap.aname);
2314
2315 ret = route_map_apply(amap, p, &rmap_path);
2316
2317 bgp_attr_flush(&dummy_attr);
2318
2319 /*
2320 * The conditional advertisement mode is Withdraw and this
2321 * prefix is a conditional prefix. Don't advertise it
2322 */
2323 if (ret == RMAP_PERMITMATCH)
2324 return false;
2325 }
2326
2327 /* Route map & unsuppress-map apply. */
2328 if (!post_attr &&
2329 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2330 struct bgp_path_info rmap_path = {0};
2331 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2332 struct attr dummy_attr = {0};
2333
2334 /* Fill temp path_info */
2335 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2336 pi, peer, attr);
2337
2338 /* don't confuse inbound and outbound setting */
2339 RESET_FLAG(attr->rmap_change_flags);
2340
2341 /*
2342 * The route reflector is not allowed to modify the attributes
2343 * of the reflected IBGP routes unless explicitly allowed.
2344 */
2345 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2346 && !CHECK_FLAG(bgp->flags,
2347 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2348 dummy_attr = *attr;
2349 rmap_path.attr = &dummy_attr;
2350 }
2351
2352 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2353
2354 if (bgp_path_suppressed(pi))
2355 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2356 &rmap_path);
2357 else
2358 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2359 &rmap_path);
2360
2361 bgp_attr_flush(&dummy_attr);
2362 peer->rmap_type = 0;
2363
2364 if (ret == RMAP_DENYMATCH) {
2365 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2366 zlog_debug(
2367 "%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
2368 peer, p, ROUTE_MAP_OUT_NAME(filter));
2369 bgp_attr_flush(rmap_path.attr);
2370 return false;
2371 }
2372 }
2373
2374 /* RFC 8212 to prevent route leaks.
2375 * This specification intends to improve this situation by requiring the
2376 * explicit configuration of both BGP Import and Export Policies for any
2377 * External BGP (EBGP) session such as customers, peers, or
2378 * confederation boundaries for all enabled address families. Through
2379 * codification of the aforementioned requirement, operators will
2380 * benefit from consistent behavior across different BGP
2381 * implementations.
2382 */
2383 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2384 if (!bgp_outbound_policy_exists(peer, filter)) {
2385 if (monotime_since(&bgp->ebgprequirespolicywarning,
2386 NULL) > FIFTEENMINUTE2USEC ||
2387 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2388 zlog_warn(
2389 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2390 monotime(&bgp->ebgprequirespolicywarning);
2391 }
2392 return false;
2393 }
2394
2395 /* draft-ietf-idr-deprecate-as-set-confed-set
2396 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2397 * Eventually, This document (if approved) updates RFC 4271
2398 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2399 * and obsoletes RFC 6472.
2400 */
2401 if (peer->bgp->reject_as_sets)
2402 if (aspath_check_as_sets(attr->aspath))
2403 return false;
2404
2405 /* If neighbor soo is configured, then check if the route has
2406 * SoO extended community and validate against the configured
2407 * one. If they match, do not announce, to prevent routing
2408 * loops.
2409 */
2410 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2411 peer->soo[afi][safi]) {
2412 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2413 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2414
2415 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2416 ECOMMUNITY_SITE_ORIGIN) ||
2417 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2418 ECOMMUNITY_SITE_ORIGIN) ||
2419 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
2420 ECOMMUNITY_SITE_ORIGIN)) &&
2421 ecommunity_include(ecomm, ecomm_soo)) {
2422 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2423 zlog_debug(
2424 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2425 peer, p, ecommunity_str(ecomm_soo));
2426 return false;
2427 }
2428 }
2429
2430 /* Codification of AS 0 Processing */
2431 if (aspath_check_as_zero(attr->aspath))
2432 return false;
2433
2434 if (bgp_in_graceful_shutdown(bgp)) {
2435 if (peer->sort == BGP_PEER_IBGP
2436 || peer->sort == BGP_PEER_CONFED) {
2437 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2438 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2439 } else {
2440 bgp_attr_add_gshut_community(attr);
2441 }
2442 }
2443
2444 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2445 * Capability" to a neighbor MUST perform the following upon receiving
2446 * a route from that neighbor with the "LLGR_STALE" community, or upon
2447 * attaching the "LLGR_STALE" community itself per Section 4.2:
2448 *
2449 * The route SHOULD NOT be advertised to any neighbor from which the
2450 * Long-lived Graceful Restart Capability has not been received.
2451 */
2452 if (bgp_attr_get_community(attr) &&
2453 community_include(bgp_attr_get_community(attr),
2454 COMMUNITY_LLGR_STALE) &&
2455 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2456 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2457 return false;
2458
2459 /* After route-map has been applied, we check to see if the nexthop to
2460 * be carried in the attribute (that is used for the announcement) can
2461 * be cleared off or not. We do this in all cases where we would be
2462 * setting the nexthop to "ourselves". For IPv6, we only need to
2463 * consider
2464 * the global nexthop here; the link-local nexthop would have been
2465 * cleared
2466 * already, and if not, it is required by the update formation code.
2467 * Also see earlier comments in this function.
2468 */
2469 /*
2470 * If route-map has performed some operation on the nexthop or the peer
2471 * configuration says to pass it unchanged, we cannot reset the nexthop
2472 * here, so only attempt to do it if these aren't true. Note that the
2473 * route-map handler itself might have cleared the nexthop, if for
2474 * example,
2475 * it is configured as 'peer-address'.
2476 */
2477 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2478 piattr->rmap_change_flags)
2479 && !transparent
2480 && !CHECK_FLAG(peer->af_flags[afi][safi],
2481 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2482 /* We can reset the nexthop, if setting (or forcing) it to
2483 * 'self' */
2484 if (CHECK_FLAG(peer->af_flags[afi][safi],
2485 PEER_FLAG_NEXTHOP_SELF)
2486 || CHECK_FLAG(peer->af_flags[afi][safi],
2487 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2488 if (!reflect
2489 || CHECK_FLAG(peer->af_flags[afi][safi],
2490 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2491 subgroup_announce_reset_nhop(
2492 (peer_cap_enhe(peer, afi, safi)
2493 ? AF_INET6
2494 : p->family),
2495 attr);
2496 nh_reset = true;
2497 }
2498 } else if (peer->sort == BGP_PEER_EBGP) {
2499 /* Can also reset the nexthop if announcing to EBGP, but
2500 * only if
2501 * no peer in the subgroup is on a shared subnet.
2502 * Note: 3rd party nexthop currently implemented for
2503 * IPv4 only.
2504 */
2505 if ((p->family == AF_INET) &&
2506 (!bgp_subgrp_multiaccess_check_v4(
2507 piattr->nexthop,
2508 subgrp, from))) {
2509 subgroup_announce_reset_nhop(
2510 (peer_cap_enhe(peer, afi, safi)
2511 ? AF_INET6
2512 : p->family),
2513 attr);
2514 nh_reset = true;
2515 }
2516
2517 if ((p->family == AF_INET6) &&
2518 (!bgp_subgrp_multiaccess_check_v6(
2519 piattr->mp_nexthop_global,
2520 subgrp, from))) {
2521 subgroup_announce_reset_nhop(
2522 (peer_cap_enhe(peer, afi, safi)
2523 ? AF_INET6
2524 : p->family),
2525 attr);
2526 nh_reset = true;
2527 }
2528
2529
2530
2531 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2532 /*
2533 * This flag is used for leaked vpn-vrf routes
2534 */
2535 int family = p->family;
2536
2537 if (peer_cap_enhe(peer, afi, safi))
2538 family = AF_INET6;
2539
2540 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2541 zlog_debug(
2542 "%s: %pFX BGP_PATH_ANNC_NH_SELF, family=%s",
2543 __func__, p, family2str(family));
2544 subgroup_announce_reset_nhop(family, attr);
2545 nh_reset = true;
2546 }
2547 }
2548
2549 /* If IPv6/MP and nexthop does not have any override and happens
2550 * to
2551 * be a link-local address, reset it so that we don't pass along
2552 * the
2553 * source's link-local IPv6 address to recipients who may not be
2554 * on
2555 * the same interface.
2556 */
2557 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2558 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2559 subgroup_announce_reset_nhop(AF_INET6, attr);
2560 nh_reset = true;
2561 }
2562 }
2563
2564 /* If this is an iBGP, send Origin Validation State (OVS)
2565 * extended community (rfc8097).
2566 */
2567 if (peer->sort == BGP_PEER_IBGP) {
2568 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2569
2570 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2571
2572 if (rpki_state != RPKI_NOT_BEING_USED)
2573 bgp_attr_set_ecommunity(
2574 attr, ecommunity_add_origin_validation_state(
2575 rpki_state,
2576 bgp_attr_get_ecommunity(attr)));
2577 }
2578
2579 /*
2580 * When the next hop is set to ourselves, if all multipaths have
2581 * link-bandwidth announce the cumulative bandwidth as that makes
2582 * the most sense. However, don't modify if the link-bandwidth has
2583 * been explicitly set by user policy.
2584 */
2585 if (nh_reset &&
2586 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2587 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2588 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2589 bgp_attr_set_ecommunity(
2590 attr,
2591 ecommunity_replace_linkbw(
2592 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2593 CHECK_FLAG(
2594 peer->flags,
2595 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2596
2597 return true;
2598 }
2599
2600 static void bgp_route_select_timer_expire(struct thread *thread)
2601 {
2602 struct afi_safi_info *info;
2603 afi_t afi;
2604 safi_t safi;
2605 struct bgp *bgp;
2606
2607 info = THREAD_ARG(thread);
2608 afi = info->afi;
2609 safi = info->safi;
2610 bgp = info->bgp;
2611
2612 bgp->gr_info[afi][safi].t_route_select = NULL;
2613 XFREE(MTYPE_TMP, info);
2614
2615 /* Best path selection */
2616 bgp_best_path_select_defer(bgp, afi, safi);
2617 }
2618
2619 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2620 struct bgp_maxpaths_cfg *mpath_cfg,
2621 struct bgp_path_info_pair *result, afi_t afi,
2622 safi_t safi)
2623 {
2624 struct bgp_path_info *new_select;
2625 struct bgp_path_info *old_select;
2626 struct bgp_path_info *pi;
2627 struct bgp_path_info *pi1;
2628 struct bgp_path_info *pi2;
2629 struct bgp_path_info *nextpi = NULL;
2630 int paths_eq, do_mpath, debug;
2631 struct list mp_list;
2632 char pfx_buf[PREFIX2STR_BUFFER];
2633 char path_buf[PATH_ADDPATH_STR_BUFFER];
2634
2635 bgp_mp_list_init(&mp_list);
2636 do_mpath =
2637 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2638
2639 debug = bgp_debug_bestpath(dest);
2640
2641 if (debug)
2642 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2643
2644 dest->reason = bgp_path_selection_none;
2645 /* bgp deterministic-med */
2646 new_select = NULL;
2647 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2648
2649 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2650 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2651 pi1 = pi1->next)
2652 bgp_path_info_unset_flag(dest, pi1,
2653 BGP_PATH_DMED_SELECTED);
2654
2655 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2656 pi1 = pi1->next) {
2657 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2658 continue;
2659 if (BGP_PATH_HOLDDOWN(pi1))
2660 continue;
2661 if (pi1->peer != bgp->peer_self)
2662 if (!peer_established(pi1->peer))
2663 continue;
2664
2665 new_select = pi1;
2666 if (pi1->next) {
2667 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2668 if (CHECK_FLAG(pi2->flags,
2669 BGP_PATH_DMED_CHECK))
2670 continue;
2671 if (BGP_PATH_HOLDDOWN(pi2))
2672 continue;
2673 if (pi2->peer != bgp->peer_self
2674 && !CHECK_FLAG(
2675 pi2->peer->sflags,
2676 PEER_STATUS_NSF_WAIT))
2677 if (pi2->peer->status
2678 != Established)
2679 continue;
2680
2681 if (!aspath_cmp_left(pi1->attr->aspath,
2682 pi2->attr->aspath)
2683 && !aspath_cmp_left_confed(
2684 pi1->attr->aspath,
2685 pi2->attr->aspath))
2686 continue;
2687
2688 if (bgp_path_info_cmp(
2689 bgp, pi2, new_select,
2690 &paths_eq, mpath_cfg, debug,
2691 pfx_buf, afi, safi,
2692 &dest->reason)) {
2693 bgp_path_info_unset_flag(
2694 dest, new_select,
2695 BGP_PATH_DMED_SELECTED);
2696 new_select = pi2;
2697 }
2698
2699 bgp_path_info_set_flag(
2700 dest, pi2, BGP_PATH_DMED_CHECK);
2701 }
2702 }
2703 bgp_path_info_set_flag(dest, new_select,
2704 BGP_PATH_DMED_CHECK);
2705 bgp_path_info_set_flag(dest, new_select,
2706 BGP_PATH_DMED_SELECTED);
2707
2708 if (debug) {
2709 bgp_path_info_path_with_addpath_rx_str(
2710 new_select, path_buf, sizeof(path_buf));
2711 zlog_debug(
2712 "%pBD(%s): %s is the bestpath from AS %u",
2713 dest, bgp->name_pretty, path_buf,
2714 aspath_get_first_as(
2715 new_select->attr->aspath));
2716 }
2717 }
2718 }
2719
2720 /* Check old selected route and new selected route. */
2721 old_select = NULL;
2722 new_select = NULL;
2723 for (pi = bgp_dest_get_bgp_path_info(dest);
2724 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2725 enum bgp_path_selection_reason reason;
2726
2727 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2728 old_select = pi;
2729
2730 if (BGP_PATH_HOLDDOWN(pi)) {
2731 /* reap REMOVED routes, if needs be
2732 * selected route must stay for a while longer though
2733 */
2734 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2735 && (pi != old_select))
2736 bgp_path_info_reap(dest, pi);
2737
2738 if (debug)
2739 zlog_debug("%s: pi %p in holddown", __func__,
2740 pi);
2741
2742 continue;
2743 }
2744
2745 if (pi->peer && pi->peer != bgp->peer_self
2746 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2747 if (!peer_established(pi->peer)) {
2748
2749 if (debug)
2750 zlog_debug(
2751 "%s: pi %p non self peer %s not estab state",
2752 __func__, pi, pi->peer->host);
2753
2754 continue;
2755 }
2756
2757 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2758 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2759 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2760 if (debug)
2761 zlog_debug("%s: pi %p dmed", __func__, pi);
2762 continue;
2763 }
2764
2765 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2766
2767 reason = dest->reason;
2768 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2769 debug, pfx_buf, afi, safi,
2770 &dest->reason)) {
2771 if (new_select == NULL &&
2772 reason != bgp_path_selection_none)
2773 dest->reason = reason;
2774 new_select = pi;
2775 }
2776 }
2777
2778 /* Now that we know which path is the bestpath see if any of the other
2779 * paths
2780 * qualify as multipaths
2781 */
2782 if (debug) {
2783 if (new_select)
2784 bgp_path_info_path_with_addpath_rx_str(
2785 new_select, path_buf, sizeof(path_buf));
2786 else
2787 snprintf(path_buf, sizeof(path_buf), "NONE");
2788 zlog_debug(
2789 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2790 dest, bgp->name_pretty, path_buf,
2791 old_select ? old_select->peer->host : "NONE");
2792 }
2793
2794 if (do_mpath && new_select) {
2795 for (pi = bgp_dest_get_bgp_path_info(dest);
2796 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2797
2798 if (debug)
2799 bgp_path_info_path_with_addpath_rx_str(
2800 pi, path_buf, sizeof(path_buf));
2801
2802 if (pi == new_select) {
2803 if (debug)
2804 zlog_debug(
2805 "%pBD(%s): %s is the bestpath, add to the multipath list",
2806 dest, bgp->name_pretty,
2807 path_buf);
2808 bgp_mp_list_add(&mp_list, pi);
2809 continue;
2810 }
2811
2812 if (BGP_PATH_HOLDDOWN(pi))
2813 continue;
2814
2815 if (pi->peer && pi->peer != bgp->peer_self
2816 && !CHECK_FLAG(pi->peer->sflags,
2817 PEER_STATUS_NSF_WAIT))
2818 if (!peer_established(pi->peer))
2819 continue;
2820
2821 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2822 if (debug)
2823 zlog_debug(
2824 "%pBD: %s has the same nexthop as the bestpath, skip it",
2825 dest, path_buf);
2826 continue;
2827 }
2828
2829 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2830 mpath_cfg, debug, pfx_buf, afi, safi,
2831 &dest->reason);
2832
2833 if (paths_eq) {
2834 if (debug)
2835 zlog_debug(
2836 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2837 dest, path_buf);
2838 bgp_mp_list_add(&mp_list, pi);
2839 }
2840 }
2841 }
2842
2843 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2844 mpath_cfg);
2845 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2846 bgp_mp_list_clear(&mp_list);
2847
2848 bgp_addpath_update_ids(bgp, dest, afi, safi);
2849
2850 result->old = old_select;
2851 result->new = new_select;
2852
2853 return;
2854 }
2855
2856 /*
2857 * A new route/change in bestpath of an existing route. Evaluate the path
2858 * for advertisement to the subgroup.
2859 */
2860 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2861 struct bgp_path_info *selected,
2862 struct bgp_dest *dest,
2863 uint32_t addpath_tx_id)
2864 {
2865 const struct prefix *p;
2866 struct peer *onlypeer;
2867 struct attr attr;
2868 afi_t afi;
2869 safi_t safi;
2870 struct bgp *bgp;
2871 bool advertise;
2872
2873 p = bgp_dest_get_prefix(dest);
2874 afi = SUBGRP_AFI(subgrp);
2875 safi = SUBGRP_SAFI(subgrp);
2876 bgp = SUBGRP_INST(subgrp);
2877 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2878 : NULL);
2879
2880 if (BGP_DEBUG(update, UPDATE_OUT))
2881 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2882
2883 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2884 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2885 PEER_STATUS_ORF_WAIT_REFRESH))
2886 return;
2887
2888 memset(&attr, 0, sizeof(attr));
2889 /* It's initialized in bgp_announce_check() */
2890
2891 /* Announcement to the subgroup. If the route is filtered withdraw it.
2892 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2893 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2894 * route
2895 */
2896 advertise = bgp_check_advertise(bgp, dest);
2897
2898 if (selected) {
2899 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2900 NULL)) {
2901 /* Route is selected, if the route is already installed
2902 * in FIB, then it is advertised
2903 */
2904 if (advertise) {
2905 if (!bgp_check_withdrawal(bgp, dest))
2906 bgp_adj_out_set_subgroup(
2907 dest, subgrp, &attr, selected);
2908 else
2909 bgp_adj_out_unset_subgroup(
2910 dest, subgrp, 1, addpath_tx_id);
2911 }
2912 } else
2913 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2914 addpath_tx_id);
2915 }
2916
2917 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2918 else {
2919 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2920 }
2921 }
2922
2923 /*
2924 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2925 * This is called at the end of route processing.
2926 */
2927 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2928 {
2929 struct bgp_path_info *pi;
2930
2931 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2932 if (BGP_PATH_HOLDDOWN(pi))
2933 continue;
2934 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2935 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2936 }
2937 }
2938
2939 /*
2940 * Has the route changed from the RIB's perspective? This is invoked only
2941 * if the route selection returns the same best route as earlier - to
2942 * determine if we need to update zebra or not.
2943 */
2944 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2945 {
2946 struct bgp_path_info *mpinfo;
2947
2948 /* If this is multipath, check all selected paths for any nexthop
2949 * change or attribute change. Some attribute changes (e.g., community)
2950 * aren't of relevance to the RIB, but we'll update zebra to ensure
2951 * we handle the case of BGP nexthop change. This is the behavior
2952 * when the best path has an attribute change anyway.
2953 */
2954 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2955 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2956 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2957 return true;
2958
2959 /*
2960 * If this is multipath, check all selected paths for any nexthop change
2961 */
2962 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2963 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2964 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2965 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2966 return true;
2967 }
2968
2969 /* Nothing has changed from the RIB's perspective. */
2970 return false;
2971 }
2972
2973 struct bgp_process_queue {
2974 struct bgp *bgp;
2975 STAILQ_HEAD(, bgp_dest) pqueue;
2976 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2977 unsigned int flags;
2978 unsigned int queued;
2979 };
2980
2981 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
2982 safi_t safi, struct bgp_dest *dest,
2983 struct bgp_path_info *new_select,
2984 struct bgp_path_info *old_select)
2985 {
2986 const struct prefix *p = bgp_dest_get_prefix(dest);
2987
2988 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
2989 return;
2990
2991 if (advertise_type5_routes(bgp, afi) && new_select
2992 && is_route_injectable_into_evpn(new_select)) {
2993
2994 /* apply the route-map */
2995 if (bgp->adv_cmd_rmap[afi][safi].map) {
2996 route_map_result_t ret;
2997 struct bgp_path_info rmap_path;
2998 struct bgp_path_info_extra rmap_path_extra;
2999 struct attr dummy_attr;
3000
3001 dummy_attr = *new_select->attr;
3002
3003 /* Fill temp path_info */
3004 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
3005 new_select, new_select->peer,
3006 &dummy_attr);
3007
3008 RESET_FLAG(dummy_attr.rmap_change_flags);
3009
3010 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
3011 p, &rmap_path);
3012
3013 if (ret == RMAP_DENYMATCH) {
3014 bgp_attr_flush(&dummy_attr);
3015 bgp_evpn_withdraw_type5_route(bgp, p, afi,
3016 safi);
3017 } else
3018 bgp_evpn_advertise_type5_route(
3019 bgp, p, &dummy_attr, afi, safi);
3020 } else {
3021 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
3022 afi, safi);
3023 }
3024 } else if (advertise_type5_routes(bgp, afi) && old_select
3025 && is_route_injectable_into_evpn(old_select))
3026 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
3027 }
3028
3029 /*
3030 * Utility to determine whether a particular path_info should use
3031 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
3032 * in a path where we basically _know_ this is a BGP-LU route.
3033 */
3034 static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
3035 {
3036 /* Certain types get imp null; so do paths where the nexthop is
3037 * not labeled.
3038 */
3039 if (new_select->sub_type == BGP_ROUTE_STATIC
3040 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3041 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
3042 return true;
3043 else if (new_select->extra == NULL ||
3044 !bgp_is_valid_label(&new_select->extra->label[0]))
3045 /* TODO -- should be configurable? */
3046 return true;
3047 else
3048 return false;
3049 }
3050
3051 /*
3052 * old_select = The old best path
3053 * new_select = the new best path
3054 *
3055 * if (!old_select && new_select)
3056 * We are sending new information on.
3057 *
3058 * if (old_select && new_select) {
3059 * if (new_select != old_select)
3060 * We have a new best path send a change
3061 * else
3062 * We've received a update with new attributes that needs
3063 * to be passed on.
3064 * }
3065 *
3066 * if (old_select && !new_select)
3067 * We have no eligible route that we can announce or the rn
3068 * is being removed.
3069 */
3070 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3071 afi_t afi, safi_t safi)
3072 {
3073 struct bgp_path_info *new_select;
3074 struct bgp_path_info *old_select;
3075 struct bgp_path_info_pair old_and_new;
3076 int debug = 0;
3077
3078 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3079 if (dest)
3080 debug = bgp_debug_bestpath(dest);
3081 if (debug)
3082 zlog_debug(
3083 "%s: bgp delete in progress, ignoring event, p=%pBD",
3084 __func__, dest);
3085 return;
3086 }
3087 /* Is it end of initial update? (after startup) */
3088 if (!dest) {
3089 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3090 sizeof(bgp->update_delay_zebra_resume_time));
3091
3092 bgp->main_zebra_update_hold = 0;
3093 FOREACH_AFI_SAFI (afi, safi) {
3094 if (bgp_fibupd_safi(safi))
3095 bgp_zebra_announce_table(bgp, afi, safi);
3096 }
3097 bgp->main_peers_update_hold = 0;
3098
3099 bgp_start_routeadv(bgp);
3100 return;
3101 }
3102
3103 const struct prefix *p = bgp_dest_get_prefix(dest);
3104
3105 debug = bgp_debug_bestpath(dest);
3106 if (debug)
3107 zlog_debug("%s: p=%pBDi(%s) afi=%s, safi=%s start", __func__,
3108 dest, bgp->name_pretty, afi2str(afi),
3109 safi2str(safi));
3110
3111 /* The best path calculation for the route is deferred if
3112 * BGP_NODE_SELECT_DEFER is set
3113 */
3114 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3115 if (BGP_DEBUG(update, UPDATE_OUT))
3116 zlog_debug("SELECT_DEFER flag set for route %p", dest);
3117 return;
3118 }
3119
3120 /* Best path selection. */
3121 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3122 afi, safi);
3123 old_select = old_and_new.old;
3124 new_select = old_and_new.new;
3125
3126 /* Do we need to allocate or free labels?
3127 * Right now, since we only deal with per-prefix labels, it is not
3128 * necessary to do this upon changes to best path. Exceptions:
3129 * - label index has changed -> recalculate resulting label
3130 * - path_info sub_type changed -> switch to/from implicit-null
3131 * - no valid label (due to removed static label binding) -> get new one
3132 */
3133 if (bgp->allocate_mpls_labels[afi][safi]) {
3134 if (new_select) {
3135 if (!old_select
3136 || bgp_label_index_differs(new_select, old_select)
3137 || new_select->sub_type != old_select->sub_type
3138 || !bgp_is_valid_label(&dest->local_label)) {
3139 /* Enforced penultimate hop popping:
3140 * implicit-null for local routes, aggregate
3141 * and redistributed routes
3142 */
3143 if (bgp_lu_need_imp_null(new_select)) {
3144 if (CHECK_FLAG(
3145 dest->flags,
3146 BGP_NODE_REGISTERED_FOR_LABEL)
3147 || CHECK_FLAG(
3148 dest->flags,
3149 BGP_NODE_LABEL_REQUESTED))
3150 bgp_unregister_for_label(dest);
3151 dest->local_label = mpls_lse_encode(
3152 MPLS_LABEL_IMPLICIT_NULL, 0, 0,
3153 1);
3154 bgp_set_valid_label(&dest->local_label);
3155 } else
3156 bgp_register_for_label(dest,
3157 new_select);
3158 }
3159 } else if (CHECK_FLAG(dest->flags,
3160 BGP_NODE_REGISTERED_FOR_LABEL)
3161 || CHECK_FLAG(dest->flags,
3162 BGP_NODE_LABEL_REQUESTED)) {
3163 bgp_unregister_for_label(dest);
3164 }
3165 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3166 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3167 bgp_unregister_for_label(dest);
3168 }
3169
3170 if (debug)
3171 zlog_debug(
3172 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3173 __func__, dest, bgp->name_pretty, afi2str(afi),
3174 safi2str(safi), old_select, new_select);
3175
3176 /* If best route remains the same and this is not due to user-initiated
3177 * clear, see exactly what needs to be done.
3178 */
3179 if (old_select && old_select == new_select
3180 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3181 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3182 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3183 if (bgp_zebra_has_route_changed(old_select)) {
3184 #ifdef ENABLE_BGP_VNC
3185 vnc_import_bgp_add_route(bgp, p, old_select);
3186 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3187 #endif
3188 if (bgp_fibupd_safi(safi)
3189 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3190
3191 if (BGP_SUPPRESS_FIB_ENABLED(bgp)
3192 && new_select->sub_type == BGP_ROUTE_NORMAL)
3193 SET_FLAG(dest->flags,
3194 BGP_NODE_FIB_INSTALL_PENDING);
3195
3196 if (new_select->type == ZEBRA_ROUTE_BGP
3197 && (new_select->sub_type == BGP_ROUTE_NORMAL
3198 || new_select->sub_type
3199 == BGP_ROUTE_IMPORTED))
3200
3201 bgp_zebra_announce(dest, p, old_select,
3202 bgp, afi, safi);
3203 }
3204 }
3205
3206 /* If there is a change of interest to peers, reannounce the
3207 * route. */
3208 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3209 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3210 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3211 group_announce_route(bgp, afi, safi, dest, new_select);
3212
3213 /* unicast routes must also be annouced to
3214 * labeled-unicast update-groups */
3215 if (safi == SAFI_UNICAST)
3216 group_announce_route(bgp, afi,
3217 SAFI_LABELED_UNICAST, dest,
3218 new_select);
3219
3220 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3221 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3222 }
3223
3224 /* advertise/withdraw type-5 routes */
3225 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3226 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3227 bgp_process_evpn_route_injection(
3228 bgp, afi, safi, dest, old_select, old_select);
3229
3230 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3231 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3232 bgp_zebra_clear_route_change_flags(dest);
3233 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3234 return;
3235 }
3236
3237 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3238 */
3239 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3240
3241 /* bestpath has changed; bump version */
3242 if (old_select || new_select) {
3243 bgp_bump_version(dest);
3244
3245 if (!bgp->t_rmap_def_originate_eval) {
3246 bgp_lock(bgp);
3247 thread_add_timer(
3248 bm->master,
3249 update_group_refresh_default_originate_route_map,
3250 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3251 &bgp->t_rmap_def_originate_eval);
3252 }
3253 }
3254
3255 if (old_select)
3256 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3257 if (new_select) {
3258 if (debug)
3259 zlog_debug("%s: setting SELECTED flag", __func__);
3260 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3261 bgp_path_info_unset_flag(dest, new_select,
3262 BGP_PATH_ATTR_CHANGED);
3263 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3264 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3265 }
3266
3267 #ifdef ENABLE_BGP_VNC
3268 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3269 if (old_select != new_select) {
3270 if (old_select) {
3271 vnc_import_bgp_exterior_del_route(bgp, p,
3272 old_select);
3273 vnc_import_bgp_del_route(bgp, p, old_select);
3274 }
3275 if (new_select) {
3276 vnc_import_bgp_exterior_add_route(bgp, p,
3277 new_select);
3278 vnc_import_bgp_add_route(bgp, p, new_select);
3279 }
3280 }
3281 }
3282 #endif
3283
3284 group_announce_route(bgp, afi, safi, dest, new_select);
3285
3286 /* unicast routes must also be annouced to labeled-unicast update-groups
3287 */
3288 if (safi == SAFI_UNICAST)
3289 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3290 new_select);
3291
3292 /* FIB update. */
3293 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3294 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3295
3296 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3297 && (new_select->sub_type == BGP_ROUTE_NORMAL
3298 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3299 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3300
3301 if (BGP_SUPPRESS_FIB_ENABLED(bgp))
3302 SET_FLAG(dest->flags,
3303 BGP_NODE_FIB_INSTALL_PENDING);
3304
3305 /* if this is an evpn imported type-5 prefix,
3306 * we need to withdraw the route first to clear
3307 * the nh neigh and the RMAC entry.
3308 */
3309 if (old_select &&
3310 is_route_parent_evpn(old_select))
3311 bgp_zebra_withdraw(p, old_select, bgp, safi);
3312
3313 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3314 } else {
3315 /* Withdraw the route from the kernel. */
3316 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3317 && (old_select->sub_type == BGP_ROUTE_NORMAL
3318 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3319 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3320
3321 bgp_zebra_withdraw(p, old_select, bgp, safi);
3322 }
3323 }
3324
3325 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3326 old_select);
3327
3328 /* Clear any route change flags. */
3329 bgp_zebra_clear_route_change_flags(dest);
3330
3331 /* Reap old select bgp_path_info, if it has been removed */
3332 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3333 bgp_path_info_reap(dest, old_select);
3334
3335 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3336 return;
3337 }
3338
3339 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3340 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3341 {
3342 struct bgp_dest *dest;
3343 int cnt = 0;
3344 struct afi_safi_info *thread_info;
3345
3346 if (bgp->gr_info[afi][safi].t_route_select) {
3347 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
3348
3349 thread_info = THREAD_ARG(t);
3350 XFREE(MTYPE_TMP, thread_info);
3351 THREAD_OFF(bgp->gr_info[afi][safi].t_route_select);
3352 }
3353
3354 if (BGP_DEBUG(update, UPDATE_OUT)) {
3355 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3356 get_afi_safi_str(afi, safi, false),
3357 bgp->gr_info[afi][safi].gr_deferred);
3358 }
3359
3360 /* Process the route list */
3361 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3362 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3363 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3364 dest = bgp_route_next(dest)) {
3365 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3366 continue;
3367
3368 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3369 bgp->gr_info[afi][safi].gr_deferred--;
3370 bgp_process_main_one(bgp, dest, afi, safi);
3371 cnt++;
3372 }
3373 /* If iteration stopped before the entire table was traversed then the
3374 * node needs to be unlocked.
3375 */
3376 if (dest) {
3377 bgp_dest_unlock_node(dest);
3378 dest = NULL;
3379 }
3380
3381 /* Send EOR message when all routes are processed */
3382 if (!bgp->gr_info[afi][safi].gr_deferred) {
3383 bgp_send_delayed_eor(bgp);
3384 /* Send route processing complete message to RIB */
3385 bgp_zebra_update(afi, safi, bgp->vrf_id,
3386 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3387 return;
3388 }
3389
3390 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3391
3392 thread_info->afi = afi;
3393 thread_info->safi = safi;
3394 thread_info->bgp = bgp;
3395
3396 /* If there are more routes to be processed, start the
3397 * selection timer
3398 */
3399 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3400 BGP_ROUTE_SELECT_DELAY,
3401 &bgp->gr_info[afi][safi].t_route_select);
3402 }
3403
3404 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3405 {
3406 struct bgp_process_queue *pqnode = data;
3407 struct bgp *bgp = pqnode->bgp;
3408 struct bgp_table *table;
3409 struct bgp_dest *dest;
3410
3411 /* eoiu marker */
3412 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3413 bgp_process_main_one(bgp, NULL, 0, 0);
3414 /* should always have dedicated wq call */
3415 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3416 return WQ_SUCCESS;
3417 }
3418
3419 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3420 dest = STAILQ_FIRST(&pqnode->pqueue);
3421 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3422 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3423 table = bgp_dest_table(dest);
3424 /* note, new DESTs may be added as part of processing */
3425 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3426
3427 bgp_dest_unlock_node(dest);
3428 bgp_table_unlock(table);
3429 }
3430
3431 return WQ_SUCCESS;
3432 }
3433
3434 static void bgp_processq_del(struct work_queue *wq, void *data)
3435 {
3436 struct bgp_process_queue *pqnode = data;
3437
3438 bgp_unlock(pqnode->bgp);
3439
3440 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3441 }
3442
3443 void bgp_process_queue_init(struct bgp *bgp)
3444 {
3445 if (!bgp->process_queue) {
3446 char name[BUFSIZ];
3447
3448 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3449 bgp->process_queue = work_queue_new(bm->master, name);
3450 }
3451
3452 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3453 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3454 bgp->process_queue->spec.max_retries = 0;
3455 bgp->process_queue->spec.hold = 50;
3456 /* Use a higher yield value of 50ms for main queue processing */
3457 bgp->process_queue->spec.yield = 50 * 1000L;
3458 }
3459
3460 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3461 {
3462 struct bgp_process_queue *pqnode;
3463
3464 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3465 sizeof(struct bgp_process_queue));
3466
3467 /* unlocked in bgp_processq_del */
3468 pqnode->bgp = bgp_lock(bgp);
3469 STAILQ_INIT(&pqnode->pqueue);
3470
3471 return pqnode;
3472 }
3473
3474 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3475 {
3476 #define ARBITRARY_PROCESS_QLEN 10000
3477 struct work_queue *wq = bgp->process_queue;
3478 struct bgp_process_queue *pqnode;
3479 int pqnode_reuse = 0;
3480
3481 /* already scheduled for processing? */
3482 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3483 return;
3484
3485 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3486 * the workqueue
3487 */
3488 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3489 if (BGP_DEBUG(update, UPDATE_OUT))
3490 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3491 dest);
3492 return;
3493 }
3494
3495 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3496 if (BGP_DEBUG(update, UPDATE_OUT))
3497 zlog_debug(
3498 "Soft reconfigure table in progress for route %p",
3499 dest);
3500 return;
3501 }
3502
3503 if (wq == NULL)
3504 return;
3505
3506 /* Add route nodes to an existing work queue item until reaching the
3507 limit only if is from the same BGP view and it's not an EOIU marker
3508 */
3509 if (work_queue_item_count(wq)) {
3510 struct work_queue_item *item = work_queue_last_item(wq);
3511 pqnode = item->data;
3512
3513 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3514 || pqnode->bgp != bgp
3515 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3516 pqnode = bgp_processq_alloc(bgp);
3517 else
3518 pqnode_reuse = 1;
3519 } else
3520 pqnode = bgp_processq_alloc(bgp);
3521 /* all unlocked in bgp_process_wq */
3522 bgp_table_lock(bgp_dest_table(dest));
3523
3524 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3525 bgp_dest_lock_node(dest);
3526
3527 /* can't be enqueued twice */
3528 assert(STAILQ_NEXT(dest, pq) == NULL);
3529 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3530 pqnode->queued++;
3531
3532 if (!pqnode_reuse)
3533 work_queue_add(wq, pqnode);
3534
3535 return;
3536 }
3537
3538 void bgp_add_eoiu_mark(struct bgp *bgp)
3539 {
3540 struct bgp_process_queue *pqnode;
3541
3542 if (bgp->process_queue == NULL)
3543 return;
3544
3545 pqnode = bgp_processq_alloc(bgp);
3546
3547 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3548 work_queue_add(bgp->process_queue, pqnode);
3549 }
3550
3551 static void bgp_maximum_prefix_restart_timer(struct thread *thread)
3552 {
3553 struct peer *peer;
3554
3555 peer = THREAD_ARG(thread);
3556 peer->t_pmax_restart = NULL;
3557
3558 if (bgp_debug_neighbor_events(peer))
3559 zlog_debug(
3560 "%s Maximum-prefix restart timer expired, restore peering",
3561 peer->host);
3562
3563 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3564 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3565 }
3566
3567 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3568 safi_t safi)
3569 {
3570 uint32_t count = 0;
3571 bool filtered = false;
3572 struct bgp_dest *dest;
3573 struct bgp_adj_in *ain;
3574 struct attr attr = {};
3575 struct bgp_table *table = peer->bgp->rib[afi][safi];
3576
3577 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3578 for (ain = dest->adj_in; ain; ain = ain->next) {
3579 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3580
3581 attr = *ain->attr;
3582
3583 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3584 == FILTER_DENY)
3585 filtered = true;
3586
3587 if (bgp_input_modifier(
3588 peer, rn_p, &attr, afi, safi,
3589 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3590 NULL, 0, NULL)
3591 == RMAP_DENY)
3592 filtered = true;
3593
3594 if (filtered)
3595 count++;
3596
3597 bgp_attr_flush(&attr);
3598 }
3599 }
3600
3601 return count;
3602 }
3603
3604 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3605 int always)
3606 {
3607 iana_afi_t pkt_afi;
3608 iana_safi_t pkt_safi;
3609 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3610 PEER_FLAG_MAX_PREFIX_FORCE))
3611 ? bgp_filtered_routes_count(peer, afi, safi)
3612 + peer->pcount[afi][safi]
3613 : peer->pcount[afi][safi];
3614
3615 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3616 return false;
3617
3618 if (pcount > peer->pmax[afi][safi]) {
3619 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3620 PEER_STATUS_PREFIX_LIMIT)
3621 && !always)
3622 return false;
3623
3624 zlog_info(
3625 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3626 get_afi_safi_str(afi, safi, false), peer, pcount,
3627 peer->pmax[afi][safi]);
3628 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3629
3630 if (CHECK_FLAG(peer->af_flags[afi][safi],
3631 PEER_FLAG_MAX_PREFIX_WARNING))
3632 return false;
3633
3634 /* Convert AFI, SAFI to values for packet. */
3635 pkt_afi = afi_int2iana(afi);
3636 pkt_safi = safi_int2iana(safi);
3637 {
3638 uint8_t ndata[7];
3639
3640 ndata[0] = (pkt_afi >> 8);
3641 ndata[1] = pkt_afi;
3642 ndata[2] = pkt_safi;
3643 ndata[3] = (peer->pmax[afi][safi] >> 24);
3644 ndata[4] = (peer->pmax[afi][safi] >> 16);
3645 ndata[5] = (peer->pmax[afi][safi] >> 8);
3646 ndata[6] = (peer->pmax[afi][safi]);
3647
3648 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3649 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3650 BGP_NOTIFY_CEASE_MAX_PREFIX,
3651 ndata, 7);
3652 }
3653
3654 /* Dynamic peers will just close their connection. */
3655 if (peer_dynamic_neighbor(peer))
3656 return true;
3657
3658 /* restart timer start */
3659 if (peer->pmax_restart[afi][safi]) {
3660 peer->v_pmax_restart =
3661 peer->pmax_restart[afi][safi] * 60;
3662
3663 if (bgp_debug_neighbor_events(peer))
3664 zlog_debug(
3665 "%pBP Maximum-prefix restart timer started for %d secs",
3666 peer, peer->v_pmax_restart);
3667
3668 BGP_TIMER_ON(peer->t_pmax_restart,
3669 bgp_maximum_prefix_restart_timer,
3670 peer->v_pmax_restart);
3671 }
3672
3673 return true;
3674 } else
3675 UNSET_FLAG(peer->af_sflags[afi][safi],
3676 PEER_STATUS_PREFIX_LIMIT);
3677
3678 if (pcount
3679 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3680 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3681 PEER_STATUS_PREFIX_THRESHOLD)
3682 && !always)
3683 return false;
3684
3685 zlog_info(
3686 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3687 get_afi_safi_str(afi, safi, false), peer, pcount,
3688 peer->pmax[afi][safi]);
3689 SET_FLAG(peer->af_sflags[afi][safi],
3690 PEER_STATUS_PREFIX_THRESHOLD);
3691 } else
3692 UNSET_FLAG(peer->af_sflags[afi][safi],
3693 PEER_STATUS_PREFIX_THRESHOLD);
3694 return false;
3695 }
3696
3697 /* Unconditionally remove the route from the RIB, without taking
3698 * damping into consideration (eg, because the session went down)
3699 */
3700 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3701 struct peer *peer, afi_t afi, safi_t safi)
3702 {
3703
3704 struct bgp *bgp = NULL;
3705 bool delete_route = false;
3706
3707 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3708 safi);
3709
3710 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3711 bgp_path_info_delete(dest, pi); /* keep historical info */
3712
3713 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3714 * flag
3715 */
3716 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3717 delete_route = true;
3718 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3719 delete_route = true;
3720 if (delete_route) {
3721 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3722 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3723 bgp = pi->peer->bgp;
3724 bgp->gr_info[afi][safi].gr_deferred--;
3725 }
3726 }
3727 }
3728
3729 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3730 bgp_process(peer->bgp, dest, afi, safi);
3731 }
3732
3733 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3734 struct peer *peer, afi_t afi, safi_t safi,
3735 struct prefix_rd *prd)
3736 {
3737 const struct prefix *p = bgp_dest_get_prefix(dest);
3738
3739 /* apply dampening, if result is suppressed, we'll be retaining
3740 * the bgp_path_info in the RIB for historical reference.
3741 */
3742 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3743 && peer->sort == BGP_PEER_EBGP)
3744 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3745 == BGP_DAMP_SUPPRESSED) {
3746 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3747 safi);
3748 return;
3749 }
3750
3751 #ifdef ENABLE_BGP_VNC
3752 if (safi == SAFI_MPLS_VPN) {
3753 struct bgp_dest *pdest = NULL;
3754 struct bgp_table *table = NULL;
3755
3756 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3757 (struct prefix *)prd);
3758 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3759 table = bgp_dest_get_bgp_table_info(pdest);
3760
3761 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3762 peer->bgp, prd, table, p, pi);
3763 }
3764 bgp_dest_unlock_node(pdest);
3765 }
3766 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3767 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3768
3769 vnc_import_bgp_del_route(peer->bgp, p, pi);
3770 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3771 }
3772 }
3773 #endif
3774
3775 /* If this is an EVPN route, process for un-import. */
3776 if (safi == SAFI_EVPN)
3777 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3778
3779 bgp_rib_remove(dest, pi, peer, afi, safi);
3780 }
3781
3782 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3783 struct peer *peer, struct attr *attr,
3784 struct bgp_dest *dest)
3785 {
3786 struct bgp_path_info *new;
3787
3788 /* Make new BGP info. */
3789 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3790 new->type = type;
3791 new->instance = instance;
3792 new->sub_type = sub_type;
3793 new->peer = peer;
3794 new->attr = attr;
3795 new->uptime = monotime(NULL);
3796 new->net = dest;
3797 return new;
3798 }
3799
3800 /* Check if received nexthop is valid or not. */
3801 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3802 uint8_t type, uint8_t stype, struct attr *attr,
3803 struct bgp_dest *dest)
3804 {
3805 bool ret = false;
3806 bool is_bgp_static_route =
3807 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3808 : false;
3809
3810 /*
3811 * Only validated for unicast and multicast currently.
3812 * Also valid for EVPN where the nexthop is an IP address.
3813 * If we are a bgp static route being checked then there is
3814 * no need to check to see if the nexthop is martian as
3815 * that it should be ok.
3816 */
3817 if (is_bgp_static_route ||
3818 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3819 return false;
3820
3821 /* If NEXT_HOP is present, validate it. */
3822 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3823 if (attr->nexthop.s_addr == INADDR_ANY ||
3824 !ipv4_unicast_valid(&attr->nexthop) ||
3825 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3826 return true;
3827 }
3828
3829 /* If MP_NEXTHOP is present, validate it. */
3830 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3831 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3832 * it is not an IPv6 link-local address.
3833 *
3834 * If we receive an UPDATE with nexthop length set to 32 bytes
3835 * we shouldn't discard an UPDATE if it's set to (::).
3836 * The link-local (2st) is validated along the code path later.
3837 */
3838 if (attr->mp_nexthop_len) {
3839 switch (attr->mp_nexthop_len) {
3840 case BGP_ATTR_NHLEN_IPV4:
3841 case BGP_ATTR_NHLEN_VPNV4:
3842 ret = (attr->mp_nexthop_global_in.s_addr ==
3843 INADDR_ANY ||
3844 !ipv4_unicast_valid(
3845 &attr->mp_nexthop_global_in) ||
3846 bgp_nexthop_self(bgp, afi, type, stype, attr,
3847 dest));
3848 break;
3849
3850 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3851 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3852 ret = (IN6_IS_ADDR_UNSPECIFIED(
3853 &attr->mp_nexthop_global)
3854 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3855 || IN6_IS_ADDR_MULTICAST(
3856 &attr->mp_nexthop_global)
3857 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3858 dest));
3859 break;
3860 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3861 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3862 || IN6_IS_ADDR_MULTICAST(
3863 &attr->mp_nexthop_global)
3864 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3865 dest));
3866 break;
3867
3868 default:
3869 ret = true;
3870 break;
3871 }
3872 }
3873
3874 return ret;
3875 }
3876
3877 static void bgp_attr_add_no_export_community(struct attr *attr)
3878 {
3879 struct community *old;
3880 struct community *new;
3881 struct community *merge;
3882 struct community *no_export;
3883
3884 old = bgp_attr_get_community(attr);
3885 no_export = community_str2com("no-export");
3886
3887 assert(no_export);
3888
3889 if (old) {
3890 merge = community_merge(community_dup(old), no_export);
3891
3892 if (!old->refcnt)
3893 community_free(&old);
3894
3895 new = community_uniq_sort(merge);
3896 community_free(&merge);
3897 } else {
3898 new = community_dup(no_export);
3899 }
3900
3901 community_free(&no_export);
3902
3903 bgp_attr_set_community(attr, new);
3904 }
3905
3906 static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi,
3907 struct attr *attr, const struct prefix *prefix,
3908 int *sub_type)
3909 {
3910 struct listnode *node, *nnode;
3911 struct bgp *bgp;
3912 bool accept_own_found = false;
3913
3914 if (safi != SAFI_MPLS_VPN)
3915 return false;
3916
3917 /* Processing of the ACCEPT_OWN community is enabled by configuration */
3918 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN))
3919 return false;
3920
3921 /* The route in question carries the ACCEPT_OWN community */
3922 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3923 struct community *comm = bgp_attr_get_community(attr);
3924
3925 if (community_include(comm, COMMUNITY_ACCEPT_OWN))
3926 accept_own_found = true;
3927 }
3928
3929 /* The route in question is targeted to one or more destination VRFs
3930 * on the router (as determined by inspecting the Route Target(s)).
3931 */
3932 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3933 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3934 continue;
3935
3936 if (accept_own_found &&
3937 ecommunity_include(
3938 bgp->vpn_policy[afi]
3939 .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
3940 bgp_attr_get_ecommunity(attr))) {
3941 if (bgp_debug_update(peer, prefix, NULL, 1))
3942 zlog_debug(
3943 "%pBP prefix %pFX has ORIGINATOR_ID, but it's accepted due to ACCEPT_OWN",
3944 peer, prefix);
3945
3946 /* Treat this route as imported, because it's leaked
3947 * already from another VRF, and we got an updated
3948 * version from route-reflector with ACCEPT_OWN
3949 * community.
3950 */
3951 *sub_type = BGP_ROUTE_IMPORTED;
3952
3953 return true;
3954 }
3955 }
3956
3957 return false;
3958 }
3959
3960 void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3961 struct attr *attr, afi_t afi, safi_t safi, int type,
3962 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3963 uint32_t num_labels, int soft_reconfig,
3964 struct bgp_route_evpn *evpn)
3965 {
3966 int ret;
3967 int aspath_loop_count = 0;
3968 struct bgp_dest *dest;
3969 struct bgp *bgp;
3970 struct attr new_attr;
3971 struct attr *attr_new;
3972 struct bgp_path_info *pi;
3973 struct bgp_path_info *new = NULL;
3974 struct bgp_path_info_extra *extra;
3975 const char *reason;
3976 char pfx_buf[BGP_PRD_PATH_STRLEN];
3977 int connected = 0;
3978 int do_loop_check = 1;
3979 int has_valid_label = 0;
3980 afi_t nh_afi;
3981 bool force_evpn_import = false;
3982 safi_t orig_safi = safi;
3983 bool leak_success = true;
3984 int allowas_in = 0;
3985
3986 if (frrtrace_enabled(frr_bgp, process_update)) {
3987 char pfxprint[PREFIX2STR_BUFFER];
3988
3989 prefix2str(p, pfxprint, sizeof(pfxprint));
3990 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
3991 afi, safi, attr);
3992 }
3993
3994 #ifdef ENABLE_BGP_VNC
3995 int vnc_implicit_withdraw = 0;
3996 #endif
3997 int same_attr = 0;
3998 const struct prefix *bgp_nht_param_prefix;
3999
4000 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
4001 if (orig_safi == SAFI_LABELED_UNICAST)
4002 safi = SAFI_UNICAST;
4003
4004 memset(&new_attr, 0, sizeof(new_attr));
4005 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4006 new_attr.label = MPLS_INVALID_LABEL;
4007
4008 bgp = peer->bgp;
4009 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4010 /* TODO: Check to see if we can get rid of "is_valid_label" */
4011 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4012 has_valid_label = (num_labels > 0) ? 1 : 0;
4013 else
4014 has_valid_label = bgp_is_valid_label(label);
4015
4016 if (has_valid_label)
4017 assert(label != NULL);
4018
4019 /* Update overlay index of the attribute */
4020 if (afi == AFI_L2VPN && evpn)
4021 memcpy(&attr->evpn_overlay, evpn,
4022 sizeof(struct bgp_route_evpn));
4023
4024 /* When peer's soft reconfiguration enabled. Record input packet in
4025 Adj-RIBs-In. */
4026 if (!soft_reconfig
4027 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4028 && peer != bgp->peer_self)
4029 bgp_adj_in_set(dest, peer, attr, addpath_id);
4030
4031 /* Update permitted loop count */
4032 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
4033 allowas_in = peer->allowas_in[afi][safi];
4034
4035 /* Check previously received route. */
4036 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4037 if (pi->peer == peer && pi->type == type
4038 && pi->sub_type == sub_type
4039 && pi->addpath_rx_id == addpath_id)
4040 break;
4041
4042 /* AS path local-as loop check. */
4043 if (peer->change_local_as) {
4044 if (allowas_in)
4045 aspath_loop_count = allowas_in;
4046 else if (!CHECK_FLAG(peer->flags,
4047 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4048 aspath_loop_count = 1;
4049
4050 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4051 > aspath_loop_count) {
4052 peer->stat_pfx_aspath_loop++;
4053 reason = "as-path contains our own AS;";
4054 goto filtered;
4055 }
4056 }
4057
4058 /* If the peer is configured for "allowas-in origin" and the last ASN in
4059 * the
4060 * as-path is our ASN then we do not need to call aspath_loop_check
4061 */
4062 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4063 if (aspath_get_last_as(attr->aspath) == bgp->as)
4064 do_loop_check = 0;
4065
4066 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
4067 bgp_nht_param_prefix = NULL;
4068 else
4069 bgp_nht_param_prefix = p;
4070
4071 /* AS path loop check. */
4072 if (do_loop_check) {
4073 if (aspath_loop_check(attr->aspath, bgp->as) >
4074 peer->allowas_in[afi][safi]) {
4075 peer->stat_pfx_aspath_loop++;
4076 reason = "as-path contains our own AS;";
4077 goto filtered;
4078 }
4079 }
4080
4081 /* If we're a CONFED we need to loop check the CONFED ID too */
4082 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check)
4083 if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) >
4084 peer->allowas_in[afi][safi]) {
4085 peer->stat_pfx_aspath_loop++;
4086 reason = "as-path contains our own confed AS;";
4087 goto filtered;
4088 }
4089
4090 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4091 * enabled, then take care of that too.
4092 */
4093 bool accept_own = false;
4094
4095 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4096 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4097 accept_own =
4098 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4099 if (!accept_own) {
4100 peer->stat_pfx_originator_loop++;
4101 reason = "originator is us;";
4102 goto filtered;
4103 }
4104 }
4105
4106 /* Route reflector cluster ID check. */
4107 if (bgp_cluster_filter(peer, attr)) {
4108 peer->stat_pfx_cluster_loop++;
4109 reason = "reflected from the same cluster;";
4110 goto filtered;
4111 }
4112
4113 /* Apply incoming filter. */
4114 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4115 peer->stat_pfx_filter++;
4116 reason = "filter;";
4117 goto filtered;
4118 }
4119
4120 /* RFC 8212 to prevent route leaks.
4121 * This specification intends to improve this situation by requiring the
4122 * explicit configuration of both BGP Import and Export Policies for any
4123 * External BGP (EBGP) session such as customers, peers, or
4124 * confederation boundaries for all enabled address families. Through
4125 * codification of the aforementioned requirement, operators will
4126 * benefit from consistent behavior across different BGP
4127 * implementations.
4128 */
4129 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4130 if (!bgp_inbound_policy_exists(peer,
4131 &peer->filter[afi][safi])) {
4132 reason = "inbound policy missing";
4133 if (monotime_since(&bgp->ebgprequirespolicywarning,
4134 NULL) > FIFTEENMINUTE2USEC ||
4135 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4136 zlog_warn(
4137 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4138 monotime(&bgp->ebgprequirespolicywarning);
4139 }
4140 goto filtered;
4141 }
4142
4143 /* draft-ietf-idr-deprecate-as-set-confed-set
4144 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4145 * Eventually, This document (if approved) updates RFC 4271
4146 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4147 * and obsoletes RFC 6472.
4148 */
4149 if (peer->bgp->reject_as_sets)
4150 if (aspath_check_as_sets(attr->aspath)) {
4151 reason =
4152 "as-path contains AS_SET or AS_CONFED_SET type;";
4153 goto filtered;
4154 }
4155
4156 new_attr = *attr;
4157
4158 /* Apply incoming route-map.
4159 * NB: new_attr may now contain newly allocated values from route-map
4160 * "set"
4161 * commands, so we need bgp_attr_flush in the error paths, until we
4162 * intern
4163 * the attr (which takes over the memory references) */
4164 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4165 num_labels, dest)
4166 == RMAP_DENY) {
4167 peer->stat_pfx_filter++;
4168 reason = "route-map;";
4169 bgp_attr_flush(&new_attr);
4170 goto filtered;
4171 }
4172
4173 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4174 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4175 /* remove from RIB previous entry */
4176 bgp_zebra_withdraw(p, pi, bgp, safi);
4177 }
4178
4179 if (peer->sort == BGP_PEER_EBGP) {
4180
4181 /* rfc7999:
4182 * A BGP speaker receiving an announcement tagged with the
4183 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4184 * NO_EXPORT community as defined in RFC1997, or a
4185 * similar community, to prevent propagation of the
4186 * prefix outside the local AS. The community to prevent
4187 * propagation SHOULD be chosen according to the operator's
4188 * routing policy.
4189 */
4190 if (bgp_attr_get_community(&new_attr) &&
4191 community_include(bgp_attr_get_community(&new_attr),
4192 COMMUNITY_BLACKHOLE))
4193 bgp_attr_add_no_export_community(&new_attr);
4194
4195 /* If we receive the graceful-shutdown community from an eBGP
4196 * peer we must lower local-preference */
4197 if (bgp_attr_get_community(&new_attr) &&
4198 community_include(bgp_attr_get_community(&new_attr),
4199 COMMUNITY_GSHUT)) {
4200 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4201 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4202
4203 /* If graceful-shutdown is configured globally or
4204 * per neighbor, then add the GSHUT community to
4205 * all paths received from eBGP peers. */
4206 } else if (bgp_in_graceful_shutdown(peer->bgp) ||
4207 CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_SHUTDOWN))
4208 bgp_attr_add_gshut_community(&new_attr);
4209 }
4210
4211 /* next hop check. */
4212 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4213 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4214 &new_attr, dest)) {
4215 peer->stat_pfx_nh_invalid++;
4216 reason = "martian or self next-hop;";
4217 bgp_attr_flush(&new_attr);
4218 goto filtered;
4219 }
4220
4221 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4222 peer->stat_pfx_nh_invalid++;
4223 reason = "self mac;";
4224 bgp_attr_flush(&new_attr);
4225 goto filtered;
4226 }
4227
4228 if (bgp_check_role_applicability(afi, safi) &&
4229 bgp_otc_filter(peer, &new_attr)) {
4230 reason = "failing otc validation";
4231 bgp_attr_flush(&new_attr);
4232 goto filtered;
4233 }
4234 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
4235 * condition :
4236 * Suppress fib is enabled
4237 * BGP_OPT_NO_FIB is not enabled
4238 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
4239 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
4240 */
4241 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
4242 && (sub_type == BGP_ROUTE_NORMAL)
4243 && (!bgp_option_check(BGP_OPT_NO_FIB))
4244 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
4245 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
4246
4247 /* If neighbor soo is configured, tag all incoming routes with
4248 * this SoO tag and then filter out advertisements in
4249 * subgroup_announce_check() if it matches the configured SoO
4250 * on the other peer.
4251 */
4252 if (peer->soo[afi][safi]) {
4253 struct ecommunity *old_ecomm =
4254 bgp_attr_get_ecommunity(&new_attr);
4255 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4256 struct ecommunity *new_ecomm;
4257
4258 if (old_ecomm) {
4259 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4260 ecomm_soo);
4261
4262 if (!old_ecomm->refcnt)
4263 ecommunity_free(&old_ecomm);
4264 } else {
4265 new_ecomm = ecommunity_dup(ecomm_soo);
4266 }
4267
4268 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4269 }
4270
4271 attr_new = bgp_attr_intern(&new_attr);
4272
4273 /* If the update is implicit withdraw. */
4274 if (pi) {
4275 pi->uptime = monotime(NULL);
4276 same_attr = attrhash_cmp(pi->attr, attr_new);
4277
4278 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4279
4280 /* Same attribute comes in. */
4281 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4282 && same_attr
4283 && (!has_valid_label
4284 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4285 num_labels * sizeof(mpls_label_t))
4286 == 0)) {
4287 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4288 BGP_CONFIG_DAMPENING)
4289 && peer->sort == BGP_PEER_EBGP
4290 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4291 if (bgp_debug_update(peer, p, NULL, 1)) {
4292 bgp_debug_rdpfxpath2str(
4293 afi, safi, prd, p, label,
4294 num_labels, addpath_id ? 1 : 0,
4295 addpath_id, evpn, pfx_buf,
4296 sizeof(pfx_buf));
4297 zlog_debug("%pBP rcvd %s", peer,
4298 pfx_buf);
4299 }
4300
4301 if (bgp_damp_update(pi, dest, afi, safi)
4302 != BGP_DAMP_SUPPRESSED) {
4303 bgp_aggregate_increment(bgp, p, pi, afi,
4304 safi);
4305 bgp_process(bgp, dest, afi, safi);
4306 }
4307 } else /* Duplicate - odd */
4308 {
4309 if (bgp_debug_update(peer, p, NULL, 1)) {
4310 if (!peer->rcvd_attr_printed) {
4311 zlog_debug(
4312 "%pBP rcvd UPDATE w/ attr: %s",
4313 peer,
4314 peer->rcvd_attr_str);
4315 peer->rcvd_attr_printed = 1;
4316 }
4317
4318 bgp_debug_rdpfxpath2str(
4319 afi, safi, prd, p, label,
4320 num_labels, addpath_id ? 1 : 0,
4321 addpath_id, evpn, pfx_buf,
4322 sizeof(pfx_buf));
4323 zlog_debug(
4324 "%pBP rcvd %s...duplicate ignored",
4325 peer, pfx_buf);
4326 }
4327
4328 /* graceful restart STALE flag unset. */
4329 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4330 bgp_path_info_unset_flag(
4331 dest, pi, BGP_PATH_STALE);
4332 bgp_dest_set_defer_flag(dest, false);
4333 bgp_process(bgp, dest, afi, safi);
4334 }
4335 }
4336
4337 bgp_dest_unlock_node(dest);
4338 bgp_attr_unintern(&attr_new);
4339
4340 return;
4341 }
4342
4343 /* Withdraw/Announce before we fully processed the withdraw */
4344 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4345 if (bgp_debug_update(peer, p, NULL, 1)) {
4346 bgp_debug_rdpfxpath2str(
4347 afi, safi, prd, p, label, num_labels,
4348 addpath_id ? 1 : 0, addpath_id, evpn,
4349 pfx_buf, sizeof(pfx_buf));
4350 zlog_debug(
4351 "%pBP rcvd %s, flapped quicker than processing",
4352 peer, pfx_buf);
4353 }
4354
4355 bgp_path_info_restore(dest, pi);
4356
4357 /*
4358 * If the BGP_PATH_REMOVED flag is set, then EVPN
4359 * routes would have been unimported already when a
4360 * prior BGP withdraw processing happened. Such routes
4361 * need to be imported again, so flag accordingly.
4362 */
4363 force_evpn_import = true;
4364 } else {
4365 /* implicit withdraw, decrement aggregate and pcount
4366 * here. only if update is accepted, they'll increment
4367 * below.
4368 */
4369 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4370 }
4371
4372 /* Received Logging. */
4373 if (bgp_debug_update(peer, p, NULL, 1)) {
4374 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4375 num_labels, addpath_id ? 1 : 0,
4376 addpath_id, evpn, pfx_buf,
4377 sizeof(pfx_buf));
4378 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4379 }
4380
4381 /* graceful restart STALE flag unset. */
4382 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4383 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4384 bgp_dest_set_defer_flag(dest, false);
4385 }
4386
4387 /* The attribute is changed. */
4388 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4389
4390 /* Update bgp route dampening information. */
4391 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4392 && peer->sort == BGP_PEER_EBGP) {
4393 /* This is implicit withdraw so we should update
4394 dampening
4395 information. */
4396 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4397 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4398 }
4399 #ifdef ENABLE_BGP_VNC
4400 if (safi == SAFI_MPLS_VPN) {
4401 struct bgp_dest *pdest = NULL;
4402 struct bgp_table *table = NULL;
4403
4404 pdest = bgp_node_get(bgp->rib[afi][safi],
4405 (struct prefix *)prd);
4406 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4407 table = bgp_dest_get_bgp_table_info(pdest);
4408
4409 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4410 bgp, prd, table, p, pi);
4411 }
4412 bgp_dest_unlock_node(pdest);
4413 }
4414 if ((afi == AFI_IP || afi == AFI_IP6)
4415 && (safi == SAFI_UNICAST)) {
4416 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4417 /*
4418 * Implicit withdraw case.
4419 */
4420 ++vnc_implicit_withdraw;
4421 vnc_import_bgp_del_route(bgp, p, pi);
4422 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4423 }
4424 }
4425 #endif
4426
4427 /* Special handling for EVPN update of an existing route. If the
4428 * extended community attribute has changed, we need to
4429 * un-import
4430 * the route using its existing extended community. It will be
4431 * subsequently processed for import with the new extended
4432 * community.
4433 */
4434 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4435 && !same_attr) {
4436 if ((pi->attr->flag
4437 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4438 && (attr_new->flag
4439 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4440 int cmp;
4441
4442 cmp = ecommunity_cmp(
4443 bgp_attr_get_ecommunity(pi->attr),
4444 bgp_attr_get_ecommunity(attr_new));
4445 if (!cmp) {
4446 if (bgp_debug_update(peer, p, NULL, 1))
4447 zlog_debug(
4448 "Change in EXT-COMM, existing %s new %s",
4449 ecommunity_str(
4450 bgp_attr_get_ecommunity(
4451 pi->attr)),
4452 ecommunity_str(
4453 bgp_attr_get_ecommunity(
4454 attr_new)));
4455 if (safi == SAFI_EVPN)
4456 bgp_evpn_unimport_route(
4457 bgp, afi, safi, p, pi);
4458 else /* SAFI_MPLS_VPN */
4459 vpn_leak_to_vrf_withdraw(pi);
4460 }
4461 }
4462 }
4463
4464 /* Update to new attribute. */
4465 bgp_attr_unintern(&pi->attr);
4466 pi->attr = attr_new;
4467
4468 /* Update MPLS label */
4469 if (has_valid_label) {
4470 extra = bgp_path_info_extra_get(pi);
4471 if (extra->label != label) {
4472 memcpy(&extra->label, label,
4473 num_labels * sizeof(mpls_label_t));
4474 extra->num_labels = num_labels;
4475 }
4476 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4477 bgp_set_valid_label(&extra->label[0]);
4478 }
4479
4480 /* Update SRv6 SID */
4481 if (attr->srv6_l3vpn) {
4482 extra = bgp_path_info_extra_get(pi);
4483 if (sid_diff(&extra->sid[0].sid,
4484 &attr->srv6_l3vpn->sid)) {
4485 sid_copy(&extra->sid[0].sid,
4486 &attr->srv6_l3vpn->sid);
4487 extra->num_sids = 1;
4488
4489 extra->sid[0].loc_block_len = 0;
4490 extra->sid[0].loc_node_len = 0;
4491 extra->sid[0].func_len = 0;
4492 extra->sid[0].arg_len = 0;
4493 extra->sid[0].transposition_len = 0;
4494 extra->sid[0].transposition_offset = 0;
4495
4496 if (attr->srv6_l3vpn->loc_block_len != 0) {
4497 extra->sid[0].loc_block_len =
4498 attr->srv6_l3vpn->loc_block_len;
4499 extra->sid[0].loc_node_len =
4500 attr->srv6_l3vpn->loc_node_len;
4501 extra->sid[0].func_len =
4502 attr->srv6_l3vpn->func_len;
4503 extra->sid[0].arg_len =
4504 attr->srv6_l3vpn->arg_len;
4505 extra->sid[0].transposition_len =
4506 attr->srv6_l3vpn
4507 ->transposition_len;
4508 extra->sid[0].transposition_offset =
4509 attr->srv6_l3vpn
4510 ->transposition_offset;
4511 }
4512 }
4513 } else if (attr->srv6_vpn) {
4514 extra = bgp_path_info_extra_get(pi);
4515 if (sid_diff(&extra->sid[0].sid,
4516 &attr->srv6_vpn->sid)) {
4517 sid_copy(&extra->sid[0].sid,
4518 &attr->srv6_vpn->sid);
4519 extra->num_sids = 1;
4520 }
4521 }
4522
4523 #ifdef ENABLE_BGP_VNC
4524 if ((afi == AFI_IP || afi == AFI_IP6)
4525 && (safi == SAFI_UNICAST)) {
4526 if (vnc_implicit_withdraw) {
4527 /*
4528 * Add back the route with its new attributes
4529 * (e.g., nexthop).
4530 * The route is still selected, until the route
4531 * selection
4532 * queued by bgp_process actually runs. We have
4533 * to make this
4534 * update to the VNC side immediately to avoid
4535 * racing against
4536 * configuration changes (e.g., route-map
4537 * changes) which
4538 * trigger re-importation of the entire RIB.
4539 */
4540 vnc_import_bgp_add_route(bgp, p, pi);
4541 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4542 }
4543 }
4544 #endif
4545
4546 /* Update bgp route dampening information. */
4547 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4548 && peer->sort == BGP_PEER_EBGP) {
4549 /* Now we do normal update dampening. */
4550 ret = bgp_damp_update(pi, dest, afi, safi);
4551 if (ret == BGP_DAMP_SUPPRESSED) {
4552 bgp_dest_unlock_node(dest);
4553 return;
4554 }
4555 }
4556
4557 /* Nexthop reachability check - for unicast and
4558 * labeled-unicast.. */
4559 if (((afi == AFI_IP || afi == AFI_IP6)
4560 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4561 || (safi == SAFI_EVPN &&
4562 bgp_evpn_is_prefix_nht_supported(p))) {
4563 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4564 && peer->ttl == BGP_DEFAULT_TTL
4565 && !CHECK_FLAG(peer->flags,
4566 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4567 && !CHECK_FLAG(bgp->flags,
4568 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4569 connected = 1;
4570 else
4571 connected = 0;
4572
4573 struct bgp *bgp_nexthop = bgp;
4574
4575 if (pi->extra && pi->extra->bgp_orig)
4576 bgp_nexthop = pi->extra->bgp_orig;
4577
4578 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4579
4580 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4581 safi, pi, NULL, connected,
4582 bgp_nht_param_prefix) ||
4583 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4584 bgp_path_info_set_flag(dest, pi,
4585 BGP_PATH_VALID);
4586 else {
4587 if (BGP_DEBUG(nht, NHT)) {
4588 zlog_debug("%s(%pI4): NH unresolved",
4589 __func__,
4590 (in_addr_t *)&attr_new->nexthop);
4591 }
4592 bgp_path_info_unset_flag(dest, pi,
4593 BGP_PATH_VALID);
4594 }
4595 } else {
4596 if (accept_own)
4597 bgp_path_info_set_flag(dest, pi,
4598 BGP_PATH_ACCEPT_OWN);
4599
4600 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4601 }
4602
4603 #ifdef ENABLE_BGP_VNC
4604 if (safi == SAFI_MPLS_VPN) {
4605 struct bgp_dest *pdest = NULL;
4606 struct bgp_table *table = NULL;
4607
4608 pdest = bgp_node_get(bgp->rib[afi][safi],
4609 (struct prefix *)prd);
4610 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4611 table = bgp_dest_get_bgp_table_info(pdest);
4612
4613 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4614 bgp, prd, table, p, pi);
4615 }
4616 bgp_dest_unlock_node(pdest);
4617 }
4618 #endif
4619
4620 /* If this is an EVPN route and some attribute has changed,
4621 * or we are explicitly told to perform a route import, process
4622 * route for import. If the extended community has changed, we
4623 * would
4624 * have done the un-import earlier and the import would result
4625 * in the
4626 * route getting injected into appropriate L2 VNIs. If it is
4627 * just
4628 * some other attribute change, the import will result in
4629 * updating
4630 * the attributes for the route in the VNI(s).
4631 */
4632 if (safi == SAFI_EVPN &&
4633 (!same_attr || force_evpn_import) &&
4634 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4635 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4636
4637 /* Process change. */
4638 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4639
4640 bgp_process(bgp, dest, afi, safi);
4641 bgp_dest_unlock_node(dest);
4642
4643 if (SAFI_UNICAST == safi
4644 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4645 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4646
4647 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4648 }
4649 if ((SAFI_MPLS_VPN == safi)
4650 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4651 leak_success = vpn_leak_to_vrf_update(bgp, pi, prd);
4652 }
4653
4654 #ifdef ENABLE_BGP_VNC
4655 if (SAFI_MPLS_VPN == safi) {
4656 mpls_label_t label_decoded = decode_label(label);
4657
4658 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4659 type, sub_type, &label_decoded);
4660 }
4661 if (SAFI_ENCAP == safi) {
4662 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4663 type, sub_type, NULL);
4664 }
4665 #endif
4666 if ((safi == SAFI_MPLS_VPN) &&
4667 !CHECK_FLAG(bgp->af_flags[afi][safi],
4668 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4669 !leak_success) {
4670 bgp_unlink_nexthop(pi);
4671 bgp_path_info_delete(dest, pi);
4672 }
4673 return;
4674 } // End of implicit withdraw
4675
4676 /* Received Logging. */
4677 if (bgp_debug_update(peer, p, NULL, 1)) {
4678 if (!peer->rcvd_attr_printed) {
4679 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4680 peer->rcvd_attr_str);
4681 peer->rcvd_attr_printed = 1;
4682 }
4683
4684 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4685 addpath_id ? 1 : 0, addpath_id, evpn,
4686 pfx_buf, sizeof(pfx_buf));
4687 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4688 }
4689
4690 /* Make new BGP info. */
4691 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4692
4693 /* Update MPLS label */
4694 if (has_valid_label) {
4695 extra = bgp_path_info_extra_get(new);
4696 if (extra->label != label) {
4697 memcpy(&extra->label, label,
4698 num_labels * sizeof(mpls_label_t));
4699 extra->num_labels = num_labels;
4700 }
4701 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4702 bgp_set_valid_label(&extra->label[0]);
4703 }
4704
4705 /* Update SRv6 SID */
4706 if (safi == SAFI_MPLS_VPN) {
4707 extra = bgp_path_info_extra_get(new);
4708 if (attr->srv6_l3vpn) {
4709 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4710 extra->num_sids = 1;
4711
4712 extra->sid[0].loc_block_len =
4713 attr->srv6_l3vpn->loc_block_len;
4714 extra->sid[0].loc_node_len =
4715 attr->srv6_l3vpn->loc_node_len;
4716 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4717 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4718 extra->sid[0].transposition_len =
4719 attr->srv6_l3vpn->transposition_len;
4720 extra->sid[0].transposition_offset =
4721 attr->srv6_l3vpn->transposition_offset;
4722 } else if (attr->srv6_vpn) {
4723 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4724 extra->num_sids = 1;
4725 }
4726 }
4727
4728 /* Nexthop reachability check. */
4729 if (((afi == AFI_IP || afi == AFI_IP6)
4730 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4731 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4732 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4733 && peer->ttl == BGP_DEFAULT_TTL
4734 && !CHECK_FLAG(peer->flags,
4735 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4736 && !CHECK_FLAG(bgp->flags,
4737 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4738 connected = 1;
4739 else
4740 connected = 0;
4741
4742 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4743
4744 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4745 connected, bgp_nht_param_prefix) ||
4746 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4747 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4748 else {
4749 if (BGP_DEBUG(nht, NHT))
4750 zlog_debug("%s(%pI4): NH unresolved", __func__,
4751 &attr_new->nexthop);
4752 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4753 }
4754 } else {
4755 if (accept_own)
4756 bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
4757
4758 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4759 }
4760
4761 /* If maximum prefix count is configured and current prefix
4762 * count exeed it.
4763 */
4764 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4765 reason = "maximum-prefix overflow";
4766 bgp_attr_flush(&new_attr);
4767 goto filtered;
4768 }
4769
4770 /* Addpath ID */
4771 new->addpath_rx_id = addpath_id;
4772
4773 /* Increment prefix */
4774 bgp_aggregate_increment(bgp, p, new, afi, safi);
4775
4776 /* Register new BGP information. */
4777 bgp_path_info_add(dest, new);
4778
4779 /* route_node_get lock */
4780 bgp_dest_unlock_node(dest);
4781
4782 #ifdef ENABLE_BGP_VNC
4783 if (safi == SAFI_MPLS_VPN) {
4784 struct bgp_dest *pdest = NULL;
4785 struct bgp_table *table = NULL;
4786
4787 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4788 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4789 table = bgp_dest_get_bgp_table_info(pdest);
4790
4791 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4792 bgp, prd, table, p, new);
4793 }
4794 bgp_dest_unlock_node(pdest);
4795 }
4796 #endif
4797
4798 /* If this is an EVPN route, process for import. */
4799 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4800 bgp_evpn_import_route(bgp, afi, safi, p, new);
4801
4802 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4803
4804 /* Process change. */
4805 bgp_process(bgp, dest, afi, safi);
4806
4807 if (SAFI_UNICAST == safi
4808 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4809 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4810 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4811 }
4812 if ((SAFI_MPLS_VPN == safi)
4813 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4814 leak_success = vpn_leak_to_vrf_update(bgp, new, prd);
4815 }
4816 #ifdef ENABLE_BGP_VNC
4817 if (SAFI_MPLS_VPN == safi) {
4818 mpls_label_t label_decoded = decode_label(label);
4819
4820 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4821 sub_type, &label_decoded);
4822 }
4823 if (SAFI_ENCAP == safi) {
4824 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4825 sub_type, NULL);
4826 }
4827 #endif
4828 if ((safi == SAFI_MPLS_VPN) &&
4829 !CHECK_FLAG(bgp->af_flags[afi][safi],
4830 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4831 !leak_success) {
4832 bgp_unlink_nexthop(new);
4833 bgp_path_info_delete(dest, new);
4834 }
4835
4836 return;
4837
4838 /* This BGP update is filtered. Log the reason then update BGP
4839 entry. */
4840 filtered:
4841 if (new) {
4842 bgp_unlink_nexthop(new);
4843 bgp_path_info_delete(dest, new);
4844 bgp_path_info_extra_free(&new->extra);
4845 XFREE(MTYPE_BGP_ROUTE, new);
4846 }
4847
4848 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4849
4850 if (bgp_debug_update(peer, p, NULL, 1)) {
4851 if (!peer->rcvd_attr_printed) {
4852 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4853 peer->rcvd_attr_str);
4854 peer->rcvd_attr_printed = 1;
4855 }
4856
4857 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4858 addpath_id ? 1 : 0, addpath_id, evpn,
4859 pfx_buf, sizeof(pfx_buf));
4860 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4861 peer, pfx_buf, reason);
4862 }
4863
4864 if (pi) {
4865 /* If this is an EVPN route, un-import it as it is now filtered.
4866 */
4867 if (safi == SAFI_EVPN)
4868 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4869
4870 if (SAFI_UNICAST == safi
4871 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4872 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4873
4874 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4875 }
4876 if ((SAFI_MPLS_VPN == safi)
4877 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4878
4879 vpn_leak_to_vrf_withdraw(pi);
4880 }
4881
4882 bgp_rib_remove(dest, pi, peer, afi, safi);
4883 }
4884
4885 bgp_dest_unlock_node(dest);
4886
4887 #ifdef ENABLE_BGP_VNC
4888 /*
4889 * Filtered update is treated as an implicit withdrawal (see
4890 * bgp_rib_remove()
4891 * a few lines above)
4892 */
4893 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4894 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4895 0);
4896 }
4897 #endif
4898
4899 return;
4900 }
4901
4902 void bgp_withdraw(struct peer *peer, const struct prefix *p,
4903 uint32_t addpath_id, struct attr *attr, afi_t afi,
4904 safi_t safi, int type, int sub_type, struct prefix_rd *prd,
4905 mpls_label_t *label, uint32_t num_labels,
4906 struct bgp_route_evpn *evpn)
4907 {
4908 struct bgp *bgp;
4909 char pfx_buf[BGP_PRD_PATH_STRLEN];
4910 struct bgp_dest *dest;
4911 struct bgp_path_info *pi;
4912
4913 #ifdef ENABLE_BGP_VNC
4914 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4915 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4916 0);
4917 }
4918 #endif
4919
4920 bgp = peer->bgp;
4921
4922 /* Lookup node. */
4923 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4924
4925 /* If peer is soft reconfiguration enabled. Record input packet for
4926 * further calculation.
4927 *
4928 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4929 * routes that are filtered. This tanks out Quagga RS pretty badly due
4930 * to
4931 * the iteration over all RS clients.
4932 * Since we need to remove the entry from adj_in anyway, do that first
4933 * and
4934 * if there was no entry, we don't need to do anything more.
4935 */
4936 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4937 && peer != bgp->peer_self)
4938 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4939 peer->stat_pfx_dup_withdraw++;
4940
4941 if (bgp_debug_update(peer, p, NULL, 1)) {
4942 bgp_debug_rdpfxpath2str(
4943 afi, safi, prd, p, label, num_labels,
4944 addpath_id ? 1 : 0, addpath_id, NULL,
4945 pfx_buf, sizeof(pfx_buf));
4946 zlog_debug(
4947 "%s withdrawing route %s not in adj-in",
4948 peer->host, pfx_buf);
4949 }
4950 bgp_dest_unlock_node(dest);
4951 return;
4952 }
4953
4954 /* Lookup withdrawn route. */
4955 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4956 if (pi->peer == peer && pi->type == type
4957 && pi->sub_type == sub_type
4958 && pi->addpath_rx_id == addpath_id)
4959 break;
4960
4961 /* Logging. */
4962 if (bgp_debug_update(peer, p, NULL, 1)) {
4963 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4964 addpath_id ? 1 : 0, addpath_id, NULL,
4965 pfx_buf, sizeof(pfx_buf));
4966 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
4967 pfx_buf);
4968 }
4969
4970 /* Withdraw specified route from routing table. */
4971 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4972 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4973 if (SAFI_UNICAST == safi
4974 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4975 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4976 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4977 }
4978 if ((SAFI_MPLS_VPN == safi)
4979 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4980
4981 vpn_leak_to_vrf_withdraw(pi);
4982 }
4983 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4984 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4985 addpath_id ? 1 : 0, addpath_id, NULL,
4986 pfx_buf, sizeof(pfx_buf));
4987 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4988 }
4989
4990 /* Unlock bgp_node_get() lock. */
4991 bgp_dest_unlock_node(dest);
4992
4993 return;
4994 }
4995
4996 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4997 int withdraw)
4998 {
4999 struct update_subgroup *subgrp;
5000 subgrp = peer_subgroup(peer, afi, safi);
5001 subgroup_default_originate(subgrp, withdraw);
5002 }
5003
5004
5005 /*
5006 * bgp_stop_announce_route_timer
5007 */
5008 void bgp_stop_announce_route_timer(struct peer_af *paf)
5009 {
5010 if (!paf->t_announce_route)
5011 return;
5012
5013 THREAD_OFF(paf->t_announce_route);
5014 }
5015
5016 /*
5017 * bgp_announce_route_timer_expired
5018 *
5019 * Callback that is invoked when the route announcement timer for a
5020 * peer_af expires.
5021 */
5022 static void bgp_announce_route_timer_expired(struct thread *t)
5023 {
5024 struct peer_af *paf;
5025 struct peer *peer;
5026
5027 paf = THREAD_ARG(t);
5028 peer = paf->peer;
5029
5030 if (!peer_established(peer))
5031 return;
5032
5033 if (!peer->afc_nego[paf->afi][paf->safi])
5034 return;
5035
5036 peer_af_announce_route(paf, 1);
5037
5038 /* Notify BGP conditional advertisement scanner percess */
5039 peer->advmap_config_change[paf->afi][paf->safi] = true;
5040 }
5041
5042 /*
5043 * bgp_announce_route
5044 *
5045 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
5046 *
5047 * if force is true we will force an update even if the update
5048 * limiting code is attempted to kick in.
5049 */
5050 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
5051 {
5052 struct peer_af *paf;
5053 struct update_subgroup *subgrp;
5054
5055 paf = peer_af_find(peer, afi, safi);
5056 if (!paf)
5057 return;
5058 subgrp = PAF_SUBGRP(paf);
5059
5060 /*
5061 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
5062 * or a refresh has already been triggered.
5063 */
5064 if (!subgrp || paf->t_announce_route)
5065 return;
5066
5067 if (force)
5068 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
5069
5070 /*
5071 * Start a timer to stagger/delay the announce. This serves
5072 * two purposes - announcement can potentially be combined for
5073 * multiple peers and the announcement doesn't happen in the
5074 * vty context.
5075 */
5076 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
5077 (subgrp->peer_count == 1)
5078 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
5079 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
5080 &paf->t_announce_route);
5081 }
5082
5083 /*
5084 * Announce routes from all AF tables to a peer.
5085 *
5086 * This should ONLY be called when there is a need to refresh the
5087 * routes to the peer based on a policy change for this peer alone
5088 * or a route refresh request received from the peer.
5089 * The operation will result in splitting the peer from its existing
5090 * subgroups and putting it in new subgroups.
5091 */
5092 void bgp_announce_route_all(struct peer *peer)
5093 {
5094 afi_t afi;
5095 safi_t safi;
5096
5097 FOREACH_AFI_SAFI (afi, safi)
5098 bgp_announce_route(peer, afi, safi, false);
5099 }
5100
5101 /* Flag or unflag bgp_dest to determine whether it should be treated by
5102 * bgp_soft_reconfig_table_task.
5103 * Flag if flag is true. Unflag if flag is false.
5104 */
5105 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
5106 {
5107 struct bgp_dest *dest;
5108 struct bgp_adj_in *ain;
5109
5110 if (!table)
5111 return;
5112
5113 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5114 for (ain = dest->adj_in; ain; ain = ain->next) {
5115 if (ain->peer != NULL)
5116 break;
5117 }
5118 if (flag && ain != NULL && ain->peer != NULL)
5119 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5120 else
5121 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5122 }
5123 }
5124
5125 static void bgp_soft_reconfig_table_update(struct peer *peer,
5126 struct bgp_dest *dest,
5127 struct bgp_adj_in *ain, afi_t afi,
5128 safi_t safi, struct prefix_rd *prd)
5129 {
5130 struct bgp_path_info *pi;
5131 uint32_t num_labels = 0;
5132 mpls_label_t *label_pnt = NULL;
5133 struct bgp_route_evpn evpn;
5134
5135 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5136 if (pi->peer == peer)
5137 break;
5138
5139 if (pi && pi->extra)
5140 num_labels = pi->extra->num_labels;
5141 if (num_labels)
5142 label_pnt = &pi->extra->label[0];
5143 if (pi)
5144 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
5145 sizeof(evpn));
5146 else
5147 memset(&evpn, 0, sizeof(evpn));
5148
5149 bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
5150 ain->attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, prd,
5151 label_pnt, num_labels, 1, &evpn);
5152 }
5153
5154 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5155 struct bgp_table *table,
5156 struct prefix_rd *prd)
5157 {
5158 struct bgp_dest *dest;
5159 struct bgp_adj_in *ain;
5160
5161 if (!table)
5162 table = peer->bgp->rib[afi][safi];
5163
5164 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5165 for (ain = dest->adj_in; ain; ain = ain->next) {
5166 if (ain->peer != peer)
5167 continue;
5168
5169 bgp_soft_reconfig_table_update(peer, dest, ain, afi,
5170 safi, prd);
5171 }
5172 }
5173
5174 /* Do soft reconfig table per bgp table.
5175 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5176 * when BGP_NODE_SOFT_RECONFIG is set,
5177 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5178 * Schedule a new thread to continue the job.
5179 * Without splitting the full job into several part,
5180 * vtysh waits for the job to finish before responding to a BGP command
5181 */
5182 static void bgp_soft_reconfig_table_task(struct thread *thread)
5183 {
5184 uint32_t iter, max_iter;
5185 struct bgp_dest *dest;
5186 struct bgp_adj_in *ain;
5187 struct peer *peer;
5188 struct bgp_table *table;
5189 struct prefix_rd *prd;
5190 struct listnode *node, *nnode;
5191
5192 table = THREAD_ARG(thread);
5193 prd = NULL;
5194
5195 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5196 if (table->soft_reconfig_init) {
5197 /* first call of the function with a new srta structure.
5198 * Don't do any treatment this time on nodes
5199 * in order vtysh to respond quickly
5200 */
5201 max_iter = 0;
5202 }
5203
5204 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5205 dest = bgp_route_next(dest)) {
5206 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5207 continue;
5208
5209 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5210
5211 for (ain = dest->adj_in; ain; ain = ain->next) {
5212 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5213 nnode, peer)) {
5214 if (ain->peer != peer)
5215 continue;
5216
5217 bgp_soft_reconfig_table_update(
5218 peer, dest, ain, table->afi,
5219 table->safi, prd);
5220 iter++;
5221 }
5222 }
5223 }
5224
5225 /* we're either starting the initial iteration,
5226 * or we're going to continue an ongoing iteration
5227 */
5228 if (dest || table->soft_reconfig_init) {
5229 table->soft_reconfig_init = false;
5230 thread_add_event(bm->master, bgp_soft_reconfig_table_task,
5231 table, 0, &table->soft_reconfig_thread);
5232 return;
5233 }
5234 /* we're done, clean up the background iteration context info and
5235 schedule route annoucement
5236 */
5237 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5238 listnode_delete(table->soft_reconfig_peers, peer);
5239 bgp_announce_route(peer, table->afi, table->safi, false);
5240 }
5241
5242 list_delete(&table->soft_reconfig_peers);
5243 }
5244
5245
5246 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5247 * and peer.
5248 * - bgp cannot be NULL
5249 * - if table and peer are NULL, cancel all threads within the bgp instance
5250 * - if table is NULL and peer is not,
5251 * remove peer in all threads within the bgp instance
5252 * - if peer is NULL, cancel all threads matching table within the bgp instance
5253 */
5254 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5255 const struct bgp_table *table,
5256 const struct peer *peer)
5257 {
5258 struct peer *npeer;
5259 struct listnode *node, *nnode;
5260 int afi, safi;
5261 struct bgp_table *ntable;
5262
5263 if (!bgp)
5264 return;
5265
5266 FOREACH_AFI_SAFI (afi, safi) {
5267 ntable = bgp->rib[afi][safi];
5268 if (!ntable)
5269 continue;
5270 if (table && table != ntable)
5271 continue;
5272
5273 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5274 npeer)) {
5275 if (peer && peer != npeer)
5276 continue;
5277 listnode_delete(ntable->soft_reconfig_peers, npeer);
5278 }
5279
5280 if (!ntable->soft_reconfig_peers
5281 || !list_isempty(ntable->soft_reconfig_peers))
5282 continue;
5283
5284 list_delete(&ntable->soft_reconfig_peers);
5285 bgp_soft_reconfig_table_flag(ntable, false);
5286 THREAD_OFF(ntable->soft_reconfig_thread);
5287 }
5288 }
5289
5290 /*
5291 * Returns false if the peer is not configured for soft reconfig in
5292 */
5293 bool bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5294 {
5295 struct bgp_dest *dest;
5296 struct bgp_table *table;
5297 struct listnode *node, *nnode;
5298 struct peer *npeer;
5299 struct peer_af *paf;
5300
5301 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5302 return false;
5303
5304 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5305 && (safi != SAFI_EVPN)) {
5306 table = peer->bgp->rib[afi][safi];
5307 if (!table)
5308 return true;
5309
5310 table->soft_reconfig_init = true;
5311
5312 if (!table->soft_reconfig_peers)
5313 table->soft_reconfig_peers = list_new();
5314 npeer = NULL;
5315 /* add peer to the table soft_reconfig_peers if not already
5316 * there
5317 */
5318 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5319 npeer)) {
5320 if (peer == npeer)
5321 break;
5322 }
5323 if (peer != npeer)
5324 listnode_add(table->soft_reconfig_peers, peer);
5325
5326 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5327 * on table would start back at the beginning.
5328 */
5329 bgp_soft_reconfig_table_flag(table, true);
5330
5331 if (!table->soft_reconfig_thread)
5332 thread_add_event(bm->master,
5333 bgp_soft_reconfig_table_task, table, 0,
5334 &table->soft_reconfig_thread);
5335 /* Cancel bgp_announce_route_timer_expired threads.
5336 * bgp_announce_route_timer_expired threads have been scheduled
5337 * to announce routes as soon as the soft_reconfigure process
5338 * finishes.
5339 * In this case, soft_reconfigure is also scheduled by using
5340 * a thread but is planned after the
5341 * bgp_announce_route_timer_expired threads. It means that,
5342 * without cancelling the threads, the route announcement task
5343 * would run before the soft reconfiguration one. That would
5344 * useless and would block vtysh during several seconds. Route
5345 * announcements are rescheduled as soon as the soft_reconfigure
5346 * process finishes.
5347 */
5348 paf = peer_af_find(peer, afi, safi);
5349 if (paf)
5350 bgp_stop_announce_route_timer(paf);
5351 } else
5352 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5353 dest = bgp_route_next(dest)) {
5354 table = bgp_dest_get_bgp_table_info(dest);
5355
5356 if (table == NULL)
5357 continue;
5358
5359 const struct prefix *p = bgp_dest_get_prefix(dest);
5360 struct prefix_rd prd;
5361
5362 prd.family = AF_UNSPEC;
5363 prd.prefixlen = 64;
5364 memcpy(&prd.val, p->u.val, 8);
5365
5366 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5367 }
5368
5369 return true;
5370 }
5371
5372
5373 struct bgp_clear_node_queue {
5374 struct bgp_dest *dest;
5375 };
5376
5377 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5378 {
5379 struct bgp_clear_node_queue *cnq = data;
5380 struct bgp_dest *dest = cnq->dest;
5381 struct peer *peer = wq->spec.data;
5382 struct bgp_path_info *pi;
5383 struct bgp *bgp;
5384 afi_t afi = bgp_dest_table(dest)->afi;
5385 safi_t safi = bgp_dest_table(dest)->safi;
5386
5387 assert(dest && peer);
5388 bgp = peer->bgp;
5389
5390 /* It is possible that we have multiple paths for a prefix from a peer
5391 * if that peer is using AddPath.
5392 */
5393 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5394 if (pi->peer != peer)
5395 continue;
5396
5397 /* graceful restart STALE flag set. */
5398 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5399 && peer->nsf[afi][safi])
5400 || CHECK_FLAG(peer->af_sflags[afi][safi],
5401 PEER_STATUS_ENHANCED_REFRESH))
5402 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5403 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5404 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5405 else {
5406 /* If this is an EVPN route, process for
5407 * un-import. */
5408 if (safi == SAFI_EVPN)
5409 bgp_evpn_unimport_route(
5410 bgp, afi, safi,
5411 bgp_dest_get_prefix(dest), pi);
5412 /* Handle withdraw for VRF route-leaking and L3VPN */
5413 if (SAFI_UNICAST == safi
5414 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5415 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5416 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5417 bgp, pi);
5418 }
5419 if (SAFI_MPLS_VPN == safi &&
5420 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5421 vpn_leak_to_vrf_withdraw(pi);
5422 }
5423
5424 bgp_rib_remove(dest, pi, peer, afi, safi);
5425 }
5426 }
5427 return WQ_SUCCESS;
5428 }
5429
5430 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5431 {
5432 struct bgp_clear_node_queue *cnq = data;
5433 struct bgp_dest *dest = cnq->dest;
5434 struct bgp_table *table = bgp_dest_table(dest);
5435
5436 bgp_dest_unlock_node(dest);
5437 bgp_table_unlock(table);
5438 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5439 }
5440
5441 static void bgp_clear_node_complete(struct work_queue *wq)
5442 {
5443 struct peer *peer = wq->spec.data;
5444
5445 /* Tickle FSM to start moving again */
5446 BGP_EVENT_ADD(peer, Clearing_Completed);
5447
5448 peer_unlock(peer); /* bgp_clear_route */
5449 }
5450
5451 static void bgp_clear_node_queue_init(struct peer *peer)
5452 {
5453 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5454
5455 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5456 #undef CLEAR_QUEUE_NAME_LEN
5457
5458 peer->clear_node_queue = work_queue_new(bm->master, wname);
5459 peer->clear_node_queue->spec.hold = 10;
5460 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5461 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5462 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5463 peer->clear_node_queue->spec.max_retries = 0;
5464
5465 /* we only 'lock' this peer reference when the queue is actually active
5466 */
5467 peer->clear_node_queue->spec.data = peer;
5468 }
5469
5470 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5471 struct bgp_table *table)
5472 {
5473 struct bgp_dest *dest;
5474 int force = peer->bgp->process_queue ? 0 : 1;
5475
5476 if (!table)
5477 table = peer->bgp->rib[afi][safi];
5478
5479 /* If still no table => afi/safi isn't configured at all or smth. */
5480 if (!table)
5481 return;
5482
5483 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5484 struct bgp_path_info *pi, *next;
5485 struct bgp_adj_in *ain;
5486 struct bgp_adj_in *ain_next;
5487
5488 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5489 * queued for every clearing peer, regardless of whether it is
5490 * relevant to the peer at hand.
5491 *
5492 * Overview: There are 3 different indices which need to be
5493 * scrubbed, potentially, when a peer is removed:
5494 *
5495 * 1 peer's routes visible via the RIB (ie accepted routes)
5496 * 2 peer's routes visible by the (optional) peer's adj-in index
5497 * 3 other routes visible by the peer's adj-out index
5498 *
5499 * 3 there is no hurry in scrubbing, once the struct peer is
5500 * removed from bgp->peer, we could just GC such deleted peer's
5501 * adj-outs at our leisure.
5502 *
5503 * 1 and 2 must be 'scrubbed' in some way, at least made
5504 * invisible via RIB index before peer session is allowed to be
5505 * brought back up. So one needs to know when such a 'search' is
5506 * complete.
5507 *
5508 * Ideally:
5509 *
5510 * - there'd be a single global queue or a single RIB walker
5511 * - rather than tracking which route_nodes still need to be
5512 * examined on a peer basis, we'd track which peers still
5513 * aren't cleared
5514 *
5515 * Given that our per-peer prefix-counts now should be reliable,
5516 * this may actually be achievable. It doesn't seem to be a huge
5517 * problem at this time,
5518 *
5519 * It is possible that we have multiple paths for a prefix from
5520 * a peer
5521 * if that peer is using AddPath.
5522 */
5523 ain = dest->adj_in;
5524 while (ain) {
5525 ain_next = ain->next;
5526
5527 if (ain->peer == peer)
5528 bgp_adj_in_remove(dest, ain);
5529
5530 ain = ain_next;
5531 }
5532
5533 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5534 next = pi->next;
5535 if (pi->peer != peer)
5536 continue;
5537
5538 if (force)
5539 bgp_path_info_reap(dest, pi);
5540 else {
5541 struct bgp_clear_node_queue *cnq;
5542
5543 /* both unlocked in bgp_clear_node_queue_del */
5544 bgp_table_lock(bgp_dest_table(dest));
5545 bgp_dest_lock_node(dest);
5546 cnq = XCALLOC(
5547 MTYPE_BGP_CLEAR_NODE_QUEUE,
5548 sizeof(struct bgp_clear_node_queue));
5549 cnq->dest = dest;
5550 work_queue_add(peer->clear_node_queue, cnq);
5551 break;
5552 }
5553 }
5554 }
5555 return;
5556 }
5557
5558 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5559 {
5560 struct bgp_dest *dest;
5561 struct bgp_table *table;
5562
5563 if (peer->clear_node_queue == NULL)
5564 bgp_clear_node_queue_init(peer);
5565
5566 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5567 * Idle until it receives a Clearing_Completed event. This protects
5568 * against peers which flap faster than we can we clear, which could
5569 * lead to:
5570 *
5571 * a) race with routes from the new session being installed before
5572 * clear_route_node visits the node (to delete the route of that
5573 * peer)
5574 * b) resource exhaustion, clear_route_node likely leads to an entry
5575 * on the process_main queue. Fast-flapping could cause that queue
5576 * to grow and grow.
5577 */
5578
5579 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5580 * the unlock will happen upon work-queue completion; other wise, the
5581 * unlock happens at the end of this function.
5582 */
5583 if (!peer->clear_node_queue->thread)
5584 peer_lock(peer);
5585
5586 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5587 bgp_clear_route_table(peer, afi, safi, NULL);
5588 else
5589 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5590 dest = bgp_route_next(dest)) {
5591 table = bgp_dest_get_bgp_table_info(dest);
5592 if (!table)
5593 continue;
5594
5595 bgp_clear_route_table(peer, afi, safi, table);
5596 }
5597
5598 /* unlock if no nodes got added to the clear-node-queue. */
5599 if (!peer->clear_node_queue->thread)
5600 peer_unlock(peer);
5601 }
5602
5603 void bgp_clear_route_all(struct peer *peer)
5604 {
5605 afi_t afi;
5606 safi_t safi;
5607
5608 FOREACH_AFI_SAFI (afi, safi)
5609 bgp_clear_route(peer, afi, safi);
5610
5611 #ifdef ENABLE_BGP_VNC
5612 rfapiProcessPeerDown(peer);
5613 #endif
5614 }
5615
5616 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5617 {
5618 struct bgp_table *table;
5619 struct bgp_dest *dest;
5620 struct bgp_adj_in *ain;
5621 struct bgp_adj_in *ain_next;
5622
5623 table = peer->bgp->rib[afi][safi];
5624
5625 /* It is possible that we have multiple paths for a prefix from a peer
5626 * if that peer is using AddPath.
5627 */
5628 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5629 ain = dest->adj_in;
5630
5631 while (ain) {
5632 ain_next = ain->next;
5633
5634 if (ain->peer == peer)
5635 bgp_adj_in_remove(dest, ain);
5636
5637 ain = ain_next;
5638 }
5639 }
5640 }
5641
5642 /* If any of the routes from the peer have been marked with the NO_LLGR
5643 * community, either as sent by the peer, or as the result of a configured
5644 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5645 * operation of [RFC4271].
5646 */
5647 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5648 {
5649 struct bgp_dest *dest;
5650 struct bgp_path_info *pi;
5651 struct bgp_table *table;
5652
5653 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5654 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5655 dest = bgp_route_next(dest)) {
5656 struct bgp_dest *rm;
5657
5658 /* look for neighbor in tables */
5659 table = bgp_dest_get_bgp_table_info(dest);
5660 if (!table)
5661 continue;
5662
5663 for (rm = bgp_table_top(table); rm;
5664 rm = bgp_route_next(rm))
5665 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5666 pi = pi->next) {
5667 if (pi->peer != peer)
5668 continue;
5669 if (CHECK_FLAG(
5670 peer->af_sflags[afi][safi],
5671 PEER_STATUS_LLGR_WAIT) &&
5672 bgp_attr_get_community(pi->attr) &&
5673 !community_include(
5674 bgp_attr_get_community(
5675 pi->attr),
5676 COMMUNITY_NO_LLGR))
5677 continue;
5678 if (!CHECK_FLAG(pi->flags,
5679 BGP_PATH_STALE))
5680 continue;
5681
5682 /*
5683 * If this is VRF leaked route
5684 * process for withdraw.
5685 */
5686 if (pi->sub_type ==
5687 BGP_ROUTE_IMPORTED &&
5688 peer->bgp->inst_type ==
5689 BGP_INSTANCE_TYPE_DEFAULT)
5690 vpn_leak_to_vrf_withdraw(pi);
5691
5692 bgp_rib_remove(rm, pi, peer, afi, safi);
5693 break;
5694 }
5695 }
5696 } else {
5697 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5698 dest = bgp_route_next(dest))
5699 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5700 pi = pi->next) {
5701 if (pi->peer != peer)
5702 continue;
5703 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5704 PEER_STATUS_LLGR_WAIT) &&
5705 bgp_attr_get_community(pi->attr) &&
5706 !community_include(
5707 bgp_attr_get_community(pi->attr),
5708 COMMUNITY_NO_LLGR))
5709 continue;
5710 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5711 continue;
5712 if (safi == SAFI_UNICAST &&
5713 (peer->bgp->inst_type ==
5714 BGP_INSTANCE_TYPE_VRF ||
5715 peer->bgp->inst_type ==
5716 BGP_INSTANCE_TYPE_DEFAULT))
5717 vpn_leak_from_vrf_withdraw(
5718 bgp_get_default(), peer->bgp,
5719 pi);
5720
5721 bgp_rib_remove(dest, pi, peer, afi, safi);
5722 break;
5723 }
5724 }
5725 }
5726
5727 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5728 {
5729 struct bgp_dest *dest, *ndest;
5730 struct bgp_path_info *pi;
5731 struct bgp_table *table;
5732
5733 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5734 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5735 dest = bgp_route_next(dest)) {
5736 table = bgp_dest_get_bgp_table_info(dest);
5737 if (!table)
5738 continue;
5739
5740 for (ndest = bgp_table_top(table); ndest;
5741 ndest = bgp_route_next(ndest)) {
5742 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5743 pi = pi->next) {
5744 if (pi->peer != peer)
5745 continue;
5746
5747 if ((CHECK_FLAG(
5748 peer->af_sflags[afi][safi],
5749 PEER_STATUS_ENHANCED_REFRESH))
5750 && !CHECK_FLAG(pi->flags,
5751 BGP_PATH_STALE)
5752 && !CHECK_FLAG(
5753 pi->flags,
5754 BGP_PATH_UNUSEABLE)) {
5755 if (bgp_debug_neighbor_events(
5756 peer))
5757 zlog_debug(
5758 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5759 peer,
5760 afi2str(afi),
5761 safi2str(safi),
5762 bgp_dest_get_prefix(
5763 ndest));
5764
5765 bgp_path_info_set_flag(
5766 ndest, pi,
5767 BGP_PATH_STALE);
5768 }
5769 }
5770 }
5771 }
5772 } else {
5773 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5774 dest = bgp_route_next(dest)) {
5775 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5776 pi = pi->next) {
5777 if (pi->peer != peer)
5778 continue;
5779
5780 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5781 PEER_STATUS_ENHANCED_REFRESH))
5782 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5783 && !CHECK_FLAG(pi->flags,
5784 BGP_PATH_UNUSEABLE)) {
5785 if (bgp_debug_neighbor_events(peer))
5786 zlog_debug(
5787 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5788 peer, afi2str(afi),
5789 safi2str(safi),
5790 bgp_dest_get_prefix(
5791 dest));
5792
5793 bgp_path_info_set_flag(dest, pi,
5794 BGP_PATH_STALE);
5795 }
5796 }
5797 }
5798 }
5799 }
5800
5801 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5802 {
5803 if (peer->sort == BGP_PEER_IBGP)
5804 return true;
5805
5806 if (peer->sort == BGP_PEER_EBGP
5807 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5808 || FILTER_LIST_OUT_NAME(filter)
5809 || DISTRIBUTE_OUT_NAME(filter)))
5810 return true;
5811 return false;
5812 }
5813
5814 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5815 {
5816 if (peer->sort == BGP_PEER_IBGP)
5817 return true;
5818
5819 if (peer->sort == BGP_PEER_EBGP
5820 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5821 || FILTER_LIST_IN_NAME(filter)
5822 || DISTRIBUTE_IN_NAME(filter)))
5823 return true;
5824 return false;
5825 }
5826
5827 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5828 safi_t safi)
5829 {
5830 struct bgp_dest *dest;
5831 struct bgp_path_info *pi;
5832 struct bgp_path_info *next;
5833
5834 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5835 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5836 const struct prefix *p = bgp_dest_get_prefix(dest);
5837
5838 next = pi->next;
5839
5840 /* Unimport EVPN routes from VRFs */
5841 if (safi == SAFI_EVPN)
5842 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5843 SAFI_EVPN, p, pi);
5844
5845 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5846 && pi->type == ZEBRA_ROUTE_BGP
5847 && (pi->sub_type == BGP_ROUTE_NORMAL
5848 || pi->sub_type == BGP_ROUTE_AGGREGATE
5849 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5850
5851 if (bgp_fibupd_safi(safi))
5852 bgp_zebra_withdraw(p, pi, bgp, safi);
5853 }
5854
5855 bgp_path_info_reap(dest, pi);
5856 }
5857 }
5858
5859 /* Delete all kernel routes. */
5860 void bgp_cleanup_routes(struct bgp *bgp)
5861 {
5862 afi_t afi;
5863 struct bgp_dest *dest;
5864 struct bgp_table *table;
5865
5866 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5867 if (afi == AFI_L2VPN)
5868 continue;
5869 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5870 SAFI_UNICAST);
5871 /*
5872 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5873 */
5874 if (afi != AFI_L2VPN) {
5875 safi_t safi;
5876 safi = SAFI_MPLS_VPN;
5877 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5878 dest = bgp_route_next(dest)) {
5879 table = bgp_dest_get_bgp_table_info(dest);
5880 if (table != NULL) {
5881 bgp_cleanup_table(bgp, table, safi);
5882 bgp_table_finish(&table);
5883 bgp_dest_set_bgp_table_info(dest, NULL);
5884 bgp_dest_unlock_node(dest);
5885 }
5886 }
5887 safi = SAFI_ENCAP;
5888 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5889 dest = bgp_route_next(dest)) {
5890 table = bgp_dest_get_bgp_table_info(dest);
5891 if (table != NULL) {
5892 bgp_cleanup_table(bgp, table, safi);
5893 bgp_table_finish(&table);
5894 bgp_dest_set_bgp_table_info(dest, NULL);
5895 bgp_dest_unlock_node(dest);
5896 }
5897 }
5898 }
5899 }
5900 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5901 dest = bgp_route_next(dest)) {
5902 table = bgp_dest_get_bgp_table_info(dest);
5903 if (table != NULL) {
5904 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5905 bgp_table_finish(&table);
5906 bgp_dest_set_bgp_table_info(dest, NULL);
5907 bgp_dest_unlock_node(dest);
5908 }
5909 }
5910 }
5911
5912 void bgp_reset(void)
5913 {
5914 vty_reset();
5915 bgp_zclient_reset();
5916 access_list_reset();
5917 prefix_list_reset();
5918 }
5919
5920 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5921 {
5922 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5923 && CHECK_FLAG(peer->af_cap[afi][safi],
5924 PEER_CAP_ADDPATH_AF_TX_RCV));
5925 }
5926
5927 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5928 value. */
5929 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5930 struct bgp_nlri *packet)
5931 {
5932 uint8_t *pnt;
5933 uint8_t *lim;
5934 struct prefix p;
5935 int psize;
5936 afi_t afi;
5937 safi_t safi;
5938 bool addpath_capable;
5939 uint32_t addpath_id;
5940
5941 pnt = packet->nlri;
5942 lim = pnt + packet->length;
5943 afi = packet->afi;
5944 safi = packet->safi;
5945 addpath_id = 0;
5946 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
5947
5948 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5949 syntactic validity. If the field is syntactically incorrect,
5950 then the Error Subcode is set to Invalid Network Field. */
5951 for (; pnt < lim; pnt += psize) {
5952 /* Clear prefix structure. */
5953 memset(&p, 0, sizeof(p));
5954
5955 if (addpath_capable) {
5956
5957 /* When packet overflow occurs return immediately. */
5958 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5959 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5960
5961 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5962 addpath_id = ntohl(addpath_id);
5963 pnt += BGP_ADDPATH_ID_LEN;
5964 }
5965
5966 /* Fetch prefix length. */
5967 p.prefixlen = *pnt++;
5968 /* afi/safi validity already verified by caller,
5969 * bgp_update_receive */
5970 p.family = afi2family(afi);
5971
5972 /* Prefix length check. */
5973 if (p.prefixlen > prefix_blen(&p) * 8) {
5974 flog_err(
5975 EC_BGP_UPDATE_RCV,
5976 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
5977 peer->host, p.prefixlen, packet->afi);
5978 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
5979 }
5980
5981 /* Packet size overflow check. */
5982 psize = PSIZE(p.prefixlen);
5983
5984 /* When packet overflow occur return immediately. */
5985 if (pnt + psize > lim) {
5986 flog_err(
5987 EC_BGP_UPDATE_RCV,
5988 "%s [Error] Update packet error (prefix length %d overflows packet)",
5989 peer->host, p.prefixlen);
5990 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5991 }
5992
5993 /* Defensive coding, double-check the psize fits in a struct
5994 * prefix for the v4 and v6 afi's and unicast/multicast */
5995 if (psize > (ssize_t)sizeof(p.u.val)) {
5996 flog_err(
5997 EC_BGP_UPDATE_RCV,
5998 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
5999 peer->host, p.prefixlen, sizeof(p.u.val));
6000 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6001 }
6002
6003 /* Fetch prefix from NLRI packet. */
6004 memcpy(p.u.val, pnt, psize);
6005
6006 /* Check address. */
6007 if (afi == AFI_IP && safi == SAFI_UNICAST) {
6008 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
6009 /* From RFC4271 Section 6.3:
6010 *
6011 * If a prefix in the NLRI field is semantically
6012 * incorrect
6013 * (e.g., an unexpected multicast IP address),
6014 * an error SHOULD
6015 * be logged locally, and the prefix SHOULD be
6016 * ignored.
6017 */
6018 flog_err(
6019 EC_BGP_UPDATE_RCV,
6020 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
6021 peer->host, &p.u.prefix4);
6022 continue;
6023 }
6024 }
6025
6026 /* Check address. */
6027 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
6028 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6029 flog_err(
6030 EC_BGP_UPDATE_RCV,
6031 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
6032 peer->host, &p.u.prefix6);
6033
6034 continue;
6035 }
6036 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
6037 flog_err(
6038 EC_BGP_UPDATE_RCV,
6039 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
6040 peer->host, &p.u.prefix6);
6041
6042 continue;
6043 }
6044 }
6045
6046 /* Normal process. */
6047 if (attr)
6048 bgp_update(peer, &p, addpath_id, attr, afi, safi,
6049 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6050 NULL, 0, 0, NULL);
6051 else
6052 bgp_withdraw(peer, &p, addpath_id, attr, afi, safi,
6053 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6054 NULL, 0, NULL);
6055
6056 /* Do not send BGP notification twice when maximum-prefix count
6057 * overflow. */
6058 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
6059 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
6060 }
6061
6062 /* Packet length consistency check. */
6063 if (pnt != lim) {
6064 flog_err(
6065 EC_BGP_UPDATE_RCV,
6066 "%s [Error] Update packet error (prefix length mismatch with total length)",
6067 peer->host);
6068 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6069 }
6070
6071 return BGP_NLRI_PARSE_OK;
6072 }
6073
6074 static struct bgp_static *bgp_static_new(void)
6075 {
6076 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
6077 }
6078
6079 static void bgp_static_free(struct bgp_static *bgp_static)
6080 {
6081 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6082 route_map_counter_decrement(bgp_static->rmap.map);
6083
6084 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
6085 XFREE(MTYPE_BGP_STATIC, bgp_static);
6086 }
6087
6088 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
6089 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
6090 {
6091 struct bgp_dest *dest;
6092 struct bgp_path_info *pi;
6093 struct bgp_path_info *new;
6094 struct bgp_path_info rmap_path;
6095 struct attr attr;
6096 struct attr *attr_new;
6097 route_map_result_t ret;
6098 #ifdef ENABLE_BGP_VNC
6099 int vnc_implicit_withdraw = 0;
6100 #endif
6101
6102 assert(bgp_static);
6103
6104 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6105
6106 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6107
6108 attr.nexthop = bgp_static->igpnexthop;
6109 attr.med = bgp_static->igpmetric;
6110 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6111
6112 if (afi == AFI_IP)
6113 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
6114
6115 if (bgp_static->igpmetric)
6116 bgp_attr_set_aigp_metric(&attr, bgp_static->igpmetric);
6117
6118 if (bgp_static->atomic)
6119 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
6120
6121 /* Store label index, if required. */
6122 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
6123 attr.label_index = bgp_static->label_index;
6124 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
6125 }
6126
6127 /* Apply route-map. */
6128 if (bgp_static->rmap.name) {
6129 struct attr attr_tmp = attr;
6130
6131 memset(&rmap_path, 0, sizeof(rmap_path));
6132 rmap_path.peer = bgp->peer_self;
6133 rmap_path.attr = &attr_tmp;
6134
6135 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6136
6137 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6138
6139 bgp->peer_self->rmap_type = 0;
6140
6141 if (ret == RMAP_DENYMATCH) {
6142 /* Free uninterned attribute. */
6143 bgp_attr_flush(&attr_tmp);
6144
6145 /* Unintern original. */
6146 aspath_unintern(&attr.aspath);
6147 bgp_static_withdraw(bgp, p, afi, safi);
6148 bgp_dest_unlock_node(dest);
6149 return;
6150 }
6151
6152 if (bgp_in_graceful_shutdown(bgp))
6153 bgp_attr_add_gshut_community(&attr_tmp);
6154
6155 attr_new = bgp_attr_intern(&attr_tmp);
6156 } else {
6157
6158 if (bgp_in_graceful_shutdown(bgp))
6159 bgp_attr_add_gshut_community(&attr);
6160
6161 attr_new = bgp_attr_intern(&attr);
6162 }
6163
6164 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6165 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6166 && pi->sub_type == BGP_ROUTE_STATIC)
6167 break;
6168
6169 if (pi) {
6170 if (attrhash_cmp(pi->attr, attr_new)
6171 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6172 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6173 bgp_dest_unlock_node(dest);
6174 bgp_attr_unintern(&attr_new);
6175 aspath_unintern(&attr.aspath);
6176 return;
6177 } else {
6178 /* The attribute is changed. */
6179 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6180
6181 /* Rewrite BGP route information. */
6182 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6183 bgp_path_info_restore(dest, pi);
6184 else
6185 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6186 #ifdef ENABLE_BGP_VNC
6187 if ((afi == AFI_IP || afi == AFI_IP6)
6188 && (safi == SAFI_UNICAST)) {
6189 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6190 /*
6191 * Implicit withdraw case.
6192 * We have to do this before pi is
6193 * changed
6194 */
6195 ++vnc_implicit_withdraw;
6196 vnc_import_bgp_del_route(bgp, p, pi);
6197 vnc_import_bgp_exterior_del_route(
6198 bgp, p, pi);
6199 }
6200 }
6201 #endif
6202 bgp_attr_unintern(&pi->attr);
6203 pi->attr = attr_new;
6204 pi->uptime = monotime(NULL);
6205 #ifdef ENABLE_BGP_VNC
6206 if ((afi == AFI_IP || afi == AFI_IP6)
6207 && (safi == SAFI_UNICAST)) {
6208 if (vnc_implicit_withdraw) {
6209 vnc_import_bgp_add_route(bgp, p, pi);
6210 vnc_import_bgp_exterior_add_route(
6211 bgp, p, pi);
6212 }
6213 }
6214 #endif
6215
6216 /* Nexthop reachability check. */
6217 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6218 && (safi == SAFI_UNICAST
6219 || safi == SAFI_LABELED_UNICAST)) {
6220
6221 struct bgp *bgp_nexthop = bgp;
6222
6223 if (pi->extra && pi->extra->bgp_orig)
6224 bgp_nexthop = pi->extra->bgp_orig;
6225
6226 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6227 afi, safi, pi, NULL,
6228 0, p))
6229 bgp_path_info_set_flag(dest, pi,
6230 BGP_PATH_VALID);
6231 else {
6232 if (BGP_DEBUG(nht, NHT)) {
6233 char buf1[INET6_ADDRSTRLEN];
6234 inet_ntop(p->family,
6235 &p->u.prefix, buf1,
6236 sizeof(buf1));
6237 zlog_debug(
6238 "%s(%s): Route not in table, not advertising",
6239 __func__, buf1);
6240 }
6241 bgp_path_info_unset_flag(
6242 dest, pi, BGP_PATH_VALID);
6243 }
6244 } else {
6245 /* Delete the NHT structure if any, if we're
6246 * toggling between
6247 * enabling/disabling import check. We
6248 * deregister the route
6249 * from NHT to avoid overloading NHT and the
6250 * process interaction
6251 */
6252 bgp_unlink_nexthop(pi);
6253 bgp_path_info_set_flag(dest, pi,
6254 BGP_PATH_VALID);
6255 }
6256 /* Process change. */
6257 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6258 bgp_process(bgp, dest, afi, safi);
6259
6260 if (SAFI_UNICAST == safi
6261 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6262 || bgp->inst_type
6263 == BGP_INSTANCE_TYPE_DEFAULT)) {
6264 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6265 pi);
6266 }
6267
6268 bgp_dest_unlock_node(dest);
6269 aspath_unintern(&attr.aspath);
6270 return;
6271 }
6272 }
6273
6274 /* Make new BGP info. */
6275 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6276 attr_new, dest);
6277 /* Nexthop reachability check. */
6278 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6279 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6280 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6281 p))
6282 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6283 else {
6284 if (BGP_DEBUG(nht, NHT)) {
6285 char buf1[INET6_ADDRSTRLEN];
6286
6287 inet_ntop(p->family, &p->u.prefix, buf1,
6288 sizeof(buf1));
6289 zlog_debug(
6290 "%s(%s): Route not in table, not advertising",
6291 __func__, buf1);
6292 }
6293 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6294 }
6295 } else {
6296 /* Delete the NHT structure if any, if we're toggling between
6297 * enabling/disabling import check. We deregister the route
6298 * from NHT to avoid overloading NHT and the process interaction
6299 */
6300 bgp_unlink_nexthop(new);
6301
6302 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6303 }
6304
6305 /* Aggregate address increment. */
6306 bgp_aggregate_increment(bgp, p, new, afi, safi);
6307
6308 /* Register new BGP information. */
6309 bgp_path_info_add(dest, new);
6310
6311 /* route_node_get lock */
6312 bgp_dest_unlock_node(dest);
6313
6314 /* Process change. */
6315 bgp_process(bgp, dest, afi, safi);
6316
6317 if (SAFI_UNICAST == safi
6318 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6319 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6320 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6321 }
6322
6323 /* Unintern original. */
6324 aspath_unintern(&attr.aspath);
6325 }
6326
6327 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6328 safi_t safi)
6329 {
6330 struct bgp_dest *dest;
6331 struct bgp_path_info *pi;
6332
6333 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6334
6335 /* Check selected route and self inserted route. */
6336 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6337 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6338 && pi->sub_type == BGP_ROUTE_STATIC)
6339 break;
6340
6341 /* Withdraw static BGP route from routing table. */
6342 if (pi) {
6343 if (SAFI_UNICAST == safi
6344 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6345 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6346 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6347 }
6348 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6349 bgp_unlink_nexthop(pi);
6350 bgp_path_info_delete(dest, pi);
6351 bgp_process(bgp, dest, afi, safi);
6352 }
6353
6354 /* Unlock bgp_node_lookup. */
6355 bgp_dest_unlock_node(dest);
6356 }
6357
6358 /*
6359 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6360 */
6361 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6362 afi_t afi, safi_t safi,
6363 struct prefix_rd *prd)
6364 {
6365 struct bgp_dest *dest;
6366 struct bgp_path_info *pi;
6367
6368 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6369
6370 /* Check selected route and self inserted route. */
6371 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6372 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6373 && pi->sub_type == BGP_ROUTE_STATIC)
6374 break;
6375
6376 /* Withdraw static BGP route from routing table. */
6377 if (pi) {
6378 #ifdef ENABLE_BGP_VNC
6379 rfapiProcessWithdraw(
6380 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6381 1); /* Kill, since it is an administrative change */
6382 #endif
6383 if (SAFI_MPLS_VPN == safi
6384 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6385 vpn_leak_to_vrf_withdraw(pi);
6386 }
6387 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6388 bgp_path_info_delete(dest, pi);
6389 bgp_process(bgp, dest, afi, safi);
6390 }
6391
6392 /* Unlock bgp_node_lookup. */
6393 bgp_dest_unlock_node(dest);
6394 }
6395
6396 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6397 struct bgp_static *bgp_static, afi_t afi,
6398 safi_t safi)
6399 {
6400 struct bgp_dest *dest;
6401 struct bgp_path_info *new;
6402 struct attr *attr_new;
6403 struct attr attr = {0};
6404 struct bgp_path_info *pi;
6405 #ifdef ENABLE_BGP_VNC
6406 mpls_label_t label = 0;
6407 #endif
6408 uint32_t num_labels = 0;
6409
6410 assert(bgp_static);
6411
6412 if (bgp_static->label != MPLS_INVALID_LABEL)
6413 num_labels = 1;
6414 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6415 &bgp_static->prd);
6416
6417 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6418
6419 attr.nexthop = bgp_static->igpnexthop;
6420 attr.med = bgp_static->igpmetric;
6421 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6422
6423 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6424 || (safi == SAFI_ENCAP)) {
6425 if (afi == AFI_IP) {
6426 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6427 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6428 }
6429 }
6430 if (afi == AFI_L2VPN) {
6431 if (bgp_static->gatewayIp.family == AF_INET) {
6432 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6433 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6434 &bgp_static->gatewayIp.u.prefix4,
6435 IPV4_MAX_BYTELEN);
6436 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6437 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6438 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6439 &bgp_static->gatewayIp.u.prefix6,
6440 IPV6_MAX_BYTELEN);
6441 }
6442 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6443 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6444 struct bgp_encap_type_vxlan bet;
6445 memset(&bet, 0, sizeof(bet));
6446 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6447 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6448 }
6449 if (bgp_static->router_mac) {
6450 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6451 }
6452 }
6453 /* Apply route-map. */
6454 if (bgp_static->rmap.name) {
6455 struct attr attr_tmp = attr;
6456 struct bgp_path_info rmap_path;
6457 route_map_result_t ret;
6458
6459 rmap_path.peer = bgp->peer_self;
6460 rmap_path.attr = &attr_tmp;
6461
6462 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6463
6464 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6465
6466 bgp->peer_self->rmap_type = 0;
6467
6468 if (ret == RMAP_DENYMATCH) {
6469 /* Free uninterned attribute. */
6470 bgp_attr_flush(&attr_tmp);
6471
6472 /* Unintern original. */
6473 aspath_unintern(&attr.aspath);
6474 bgp_static_withdraw_safi(bgp, p, afi, safi,
6475 &bgp_static->prd);
6476 bgp_dest_unlock_node(dest);
6477 return;
6478 }
6479
6480 attr_new = bgp_attr_intern(&attr_tmp);
6481 } else {
6482 attr_new = bgp_attr_intern(&attr);
6483 }
6484
6485 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6486 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6487 && pi->sub_type == BGP_ROUTE_STATIC)
6488 break;
6489
6490 if (pi) {
6491 if (attrhash_cmp(pi->attr, attr_new)
6492 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6493 bgp_dest_unlock_node(dest);
6494 bgp_attr_unintern(&attr_new);
6495 aspath_unintern(&attr.aspath);
6496 return;
6497 } else {
6498 /* The attribute is changed. */
6499 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6500
6501 /* Rewrite BGP route information. */
6502 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6503 bgp_path_info_restore(dest, pi);
6504 else
6505 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6506 bgp_attr_unintern(&pi->attr);
6507 pi->attr = attr_new;
6508 pi->uptime = monotime(NULL);
6509 #ifdef ENABLE_BGP_VNC
6510 if (pi->extra)
6511 label = decode_label(&pi->extra->label[0]);
6512 #endif
6513
6514 /* Process change. */
6515 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6516 bgp_process(bgp, dest, afi, safi);
6517
6518 if (SAFI_MPLS_VPN == safi
6519 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6520 vpn_leak_to_vrf_update(bgp, pi,
6521 &bgp_static->prd);
6522 }
6523 #ifdef ENABLE_BGP_VNC
6524 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6525 pi->attr, afi, safi, pi->type,
6526 pi->sub_type, &label);
6527 #endif
6528 bgp_dest_unlock_node(dest);
6529 aspath_unintern(&attr.aspath);
6530 return;
6531 }
6532 }
6533
6534
6535 /* Make new BGP info. */
6536 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6537 attr_new, dest);
6538 SET_FLAG(new->flags, BGP_PATH_VALID);
6539 bgp_path_info_extra_get(new);
6540 if (num_labels) {
6541 new->extra->label[0] = bgp_static->label;
6542 new->extra->num_labels = num_labels;
6543 }
6544 #ifdef ENABLE_BGP_VNC
6545 label = decode_label(&bgp_static->label);
6546 #endif
6547
6548 /* Aggregate address increment. */
6549 bgp_aggregate_increment(bgp, p, new, afi, safi);
6550
6551 /* Register new BGP information. */
6552 bgp_path_info_add(dest, new);
6553 /* route_node_get lock */
6554 bgp_dest_unlock_node(dest);
6555
6556 /* Process change. */
6557 bgp_process(bgp, dest, afi, safi);
6558
6559 if (SAFI_MPLS_VPN == safi
6560 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6561 vpn_leak_to_vrf_update(bgp, new, &bgp_static->prd);
6562 }
6563 #ifdef ENABLE_BGP_VNC
6564 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6565 safi, new->type, new->sub_type, &label);
6566 #endif
6567
6568 /* Unintern original. */
6569 aspath_unintern(&attr.aspath);
6570 }
6571
6572 /* Configure static BGP network. When user don't run zebra, static
6573 route should be installed as valid. */
6574 static int bgp_static_set(struct vty *vty, const char *negate,
6575 const char *ip_str, afi_t afi, safi_t safi,
6576 const char *rmap, int backdoor, uint32_t label_index)
6577 {
6578 VTY_DECLVAR_CONTEXT(bgp, bgp);
6579 int ret;
6580 struct prefix p;
6581 struct bgp_static *bgp_static;
6582 struct bgp_dest *dest;
6583 uint8_t need_update = 0;
6584
6585 /* Convert IP prefix string to struct prefix. */
6586 ret = str2prefix(ip_str, &p);
6587 if (!ret) {
6588 vty_out(vty, "%% Malformed prefix\n");
6589 return CMD_WARNING_CONFIG_FAILED;
6590 }
6591 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6592 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6593 return CMD_WARNING_CONFIG_FAILED;
6594 }
6595
6596 apply_mask(&p);
6597
6598 if (negate) {
6599
6600 /* Set BGP static route configuration. */
6601 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6602
6603 if (!dest) {
6604 vty_out(vty, "%% Can't find static route specified\n");
6605 return CMD_WARNING_CONFIG_FAILED;
6606 }
6607
6608 bgp_static = bgp_dest_get_bgp_static_info(dest);
6609
6610 if ((label_index != BGP_INVALID_LABEL_INDEX)
6611 && (label_index != bgp_static->label_index)) {
6612 vty_out(vty,
6613 "%% label-index doesn't match static route\n");
6614 bgp_dest_unlock_node(dest);
6615 return CMD_WARNING_CONFIG_FAILED;
6616 }
6617
6618 if ((rmap && bgp_static->rmap.name)
6619 && strcmp(rmap, bgp_static->rmap.name)) {
6620 vty_out(vty,
6621 "%% route-map name doesn't match static route\n");
6622 bgp_dest_unlock_node(dest);
6623 return CMD_WARNING_CONFIG_FAILED;
6624 }
6625
6626 /* Update BGP RIB. */
6627 if (!bgp_static->backdoor)
6628 bgp_static_withdraw(bgp, &p, afi, safi);
6629
6630 /* Clear configuration. */
6631 bgp_static_free(bgp_static);
6632 bgp_dest_set_bgp_static_info(dest, NULL);
6633 bgp_dest_unlock_node(dest);
6634 bgp_dest_unlock_node(dest);
6635 } else {
6636
6637 /* Set BGP static route configuration. */
6638 dest = bgp_node_get(bgp->route[afi][safi], &p);
6639 bgp_static = bgp_dest_get_bgp_static_info(dest);
6640 if (bgp_static) {
6641 /* Configuration change. */
6642 /* Label index cannot be changed. */
6643 if (bgp_static->label_index != label_index) {
6644 vty_out(vty, "%% cannot change label-index\n");
6645 bgp_dest_unlock_node(dest);
6646 return CMD_WARNING_CONFIG_FAILED;
6647 }
6648
6649 /* Check previous routes are installed into BGP. */
6650 if (bgp_static->valid
6651 && bgp_static->backdoor != backdoor)
6652 need_update = 1;
6653
6654 bgp_static->backdoor = backdoor;
6655
6656 if (rmap) {
6657 XFREE(MTYPE_ROUTE_MAP_NAME,
6658 bgp_static->rmap.name);
6659 route_map_counter_decrement(
6660 bgp_static->rmap.map);
6661 bgp_static->rmap.name =
6662 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6663 bgp_static->rmap.map =
6664 route_map_lookup_by_name(rmap);
6665 route_map_counter_increment(
6666 bgp_static->rmap.map);
6667 } else {
6668 XFREE(MTYPE_ROUTE_MAP_NAME,
6669 bgp_static->rmap.name);
6670 route_map_counter_decrement(
6671 bgp_static->rmap.map);
6672 bgp_static->rmap.map = NULL;
6673 bgp_static->valid = 0;
6674 }
6675 bgp_dest_unlock_node(dest);
6676 } else {
6677 /* New configuration. */
6678 bgp_static = bgp_static_new();
6679 bgp_static->backdoor = backdoor;
6680 bgp_static->valid = 0;
6681 bgp_static->igpmetric = 0;
6682 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6683 bgp_static->label_index = label_index;
6684
6685 if (rmap) {
6686 XFREE(MTYPE_ROUTE_MAP_NAME,
6687 bgp_static->rmap.name);
6688 route_map_counter_decrement(
6689 bgp_static->rmap.map);
6690 bgp_static->rmap.name =
6691 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6692 bgp_static->rmap.map =
6693 route_map_lookup_by_name(rmap);
6694 route_map_counter_increment(
6695 bgp_static->rmap.map);
6696 }
6697 bgp_dest_set_bgp_static_info(dest, bgp_static);
6698 }
6699
6700 bgp_static->valid = 1;
6701 if (need_update)
6702 bgp_static_withdraw(bgp, &p, afi, safi);
6703
6704 if (!bgp_static->backdoor)
6705 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6706 }
6707
6708 return CMD_SUCCESS;
6709 }
6710
6711 void bgp_static_add(struct bgp *bgp)
6712 {
6713 afi_t afi;
6714 safi_t safi;
6715 struct bgp_dest *dest;
6716 struct bgp_dest *rm;
6717 struct bgp_table *table;
6718 struct bgp_static *bgp_static;
6719
6720 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6721 FOREACH_AFI_SAFI (afi, safi)
6722 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6723 dest = bgp_route_next(dest)) {
6724 if (!bgp_dest_has_bgp_path_info_data(dest))
6725 continue;
6726
6727 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6728 || (safi == SAFI_EVPN)) {
6729 table = bgp_dest_get_bgp_table_info(dest);
6730
6731 for (rm = bgp_table_top(table); rm;
6732 rm = bgp_route_next(rm)) {
6733 bgp_static =
6734 bgp_dest_get_bgp_static_info(
6735 rm);
6736 bgp_static_update_safi(
6737 bgp, bgp_dest_get_prefix(rm),
6738 bgp_static, afi, safi);
6739 }
6740 } else {
6741 bgp_static_update(
6742 bgp, bgp_dest_get_prefix(dest),
6743 bgp_dest_get_bgp_static_info(dest), afi,
6744 safi);
6745 }
6746 }
6747 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6748 }
6749
6750 /* Called from bgp_delete(). Delete all static routes from the BGP
6751 instance. */
6752 void bgp_static_delete(struct bgp *bgp)
6753 {
6754 afi_t afi;
6755 safi_t safi;
6756 struct bgp_dest *dest;
6757 struct bgp_dest *rm;
6758 struct bgp_table *table;
6759 struct bgp_static *bgp_static;
6760
6761 FOREACH_AFI_SAFI (afi, safi)
6762 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6763 dest = bgp_route_next(dest)) {
6764 if (!bgp_dest_has_bgp_path_info_data(dest))
6765 continue;
6766
6767 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6768 || (safi == SAFI_EVPN)) {
6769 table = bgp_dest_get_bgp_table_info(dest);
6770
6771 for (rm = bgp_table_top(table); rm;
6772 rm = bgp_route_next(rm)) {
6773 bgp_static =
6774 bgp_dest_get_bgp_static_info(
6775 rm);
6776 if (!bgp_static)
6777 continue;
6778
6779 bgp_static_withdraw_safi(
6780 bgp, bgp_dest_get_prefix(rm),
6781 AFI_IP, safi,
6782 (struct prefix_rd *)
6783 bgp_dest_get_prefix(
6784 dest));
6785 bgp_static_free(bgp_static);
6786 bgp_dest_set_bgp_static_info(rm,
6787 NULL);
6788 bgp_dest_unlock_node(rm);
6789 }
6790 } else {
6791 bgp_static = bgp_dest_get_bgp_static_info(dest);
6792 bgp_static_withdraw(bgp,
6793 bgp_dest_get_prefix(dest),
6794 afi, safi);
6795 bgp_static_free(bgp_static);
6796 bgp_dest_set_bgp_static_info(dest, NULL);
6797 bgp_dest_unlock_node(dest);
6798 }
6799 }
6800 }
6801
6802 void bgp_static_redo_import_check(struct bgp *bgp)
6803 {
6804 afi_t afi;
6805 safi_t safi;
6806 struct bgp_dest *dest;
6807 struct bgp_dest *rm;
6808 struct bgp_table *table;
6809 struct bgp_static *bgp_static;
6810
6811 /* Use this flag to force reprocessing of the route */
6812 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6813 FOREACH_AFI_SAFI (afi, safi) {
6814 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6815 dest = bgp_route_next(dest)) {
6816 if (!bgp_dest_has_bgp_path_info_data(dest))
6817 continue;
6818
6819 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6820 || (safi == SAFI_EVPN)) {
6821 table = bgp_dest_get_bgp_table_info(dest);
6822
6823 for (rm = bgp_table_top(table); rm;
6824 rm = bgp_route_next(rm)) {
6825 bgp_static =
6826 bgp_dest_get_bgp_static_info(
6827 rm);
6828 bgp_static_update_safi(
6829 bgp, bgp_dest_get_prefix(rm),
6830 bgp_static, afi, safi);
6831 }
6832 } else {
6833 bgp_static = bgp_dest_get_bgp_static_info(dest);
6834 bgp_static_update(bgp,
6835 bgp_dest_get_prefix(dest),
6836 bgp_static, afi, safi);
6837 }
6838 }
6839 }
6840 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6841 }
6842
6843 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6844 safi_t safi)
6845 {
6846 struct bgp_table *table;
6847 struct bgp_dest *dest;
6848 struct bgp_path_info *pi;
6849
6850 /* Do not install the aggregate route if BGP is in the
6851 * process of termination.
6852 */
6853 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6854 || (bgp->peer_self == NULL))
6855 return;
6856
6857 table = bgp->rib[afi][safi];
6858 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6859 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6860 if (pi->peer == bgp->peer_self
6861 && ((pi->type == ZEBRA_ROUTE_BGP
6862 && pi->sub_type == BGP_ROUTE_STATIC)
6863 || (pi->type != ZEBRA_ROUTE_BGP
6864 && pi->sub_type
6865 == BGP_ROUTE_REDISTRIBUTE))) {
6866 bgp_aggregate_decrement(
6867 bgp, bgp_dest_get_prefix(dest), pi, afi,
6868 safi);
6869 bgp_unlink_nexthop(pi);
6870 bgp_path_info_delete(dest, pi);
6871 bgp_process(bgp, dest, afi, safi);
6872 }
6873 }
6874 }
6875 }
6876
6877 /*
6878 * Purge all networks and redistributed routes from routing table.
6879 * Invoked upon the instance going down.
6880 */
6881 void bgp_purge_static_redist_routes(struct bgp *bgp)
6882 {
6883 afi_t afi;
6884 safi_t safi;
6885
6886 FOREACH_AFI_SAFI (afi, safi)
6887 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6888 }
6889
6890 /*
6891 * gpz 110624
6892 * Currently this is used to set static routes for VPN and ENCAP.
6893 * I think it can probably be factored with bgp_static_set.
6894 */
6895 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6896 const char *ip_str, const char *rd_str,
6897 const char *label_str, const char *rmap_str,
6898 int evpn_type, const char *esi, const char *gwip,
6899 const char *ethtag, const char *routermac)
6900 {
6901 VTY_DECLVAR_CONTEXT(bgp, bgp);
6902 int ret;
6903 struct prefix p;
6904 struct prefix_rd prd;
6905 struct bgp_dest *pdest;
6906 struct bgp_dest *dest;
6907 struct bgp_table *table;
6908 struct bgp_static *bgp_static;
6909 mpls_label_t label = MPLS_INVALID_LABEL;
6910 struct prefix gw_ip;
6911
6912 /* validate ip prefix */
6913 ret = str2prefix(ip_str, &p);
6914 if (!ret) {
6915 vty_out(vty, "%% Malformed prefix\n");
6916 return CMD_WARNING_CONFIG_FAILED;
6917 }
6918 apply_mask(&p);
6919 if ((afi == AFI_L2VPN)
6920 && (bgp_build_evpn_prefix(evpn_type,
6921 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6922 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6923 return CMD_WARNING_CONFIG_FAILED;
6924 }
6925
6926 ret = str2prefix_rd(rd_str, &prd);
6927 if (!ret) {
6928 vty_out(vty, "%% Malformed rd\n");
6929 return CMD_WARNING_CONFIG_FAILED;
6930 }
6931
6932 if (label_str) {
6933 unsigned long label_val;
6934 label_val = strtoul(label_str, NULL, 10);
6935 encode_label(label_val, &label);
6936 }
6937
6938 if (safi == SAFI_EVPN) {
6939 if (esi && str2esi(esi, NULL) == 0) {
6940 vty_out(vty, "%% Malformed ESI\n");
6941 return CMD_WARNING_CONFIG_FAILED;
6942 }
6943 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6944 vty_out(vty, "%% Malformed Router MAC\n");
6945 return CMD_WARNING_CONFIG_FAILED;
6946 }
6947 if (gwip) {
6948 memset(&gw_ip, 0, sizeof(gw_ip));
6949 ret = str2prefix(gwip, &gw_ip);
6950 if (!ret) {
6951 vty_out(vty, "%% Malformed GatewayIp\n");
6952 return CMD_WARNING_CONFIG_FAILED;
6953 }
6954 if ((gw_ip.family == AF_INET
6955 && is_evpn_prefix_ipaddr_v6(
6956 (struct prefix_evpn *)&p))
6957 || (gw_ip.family == AF_INET6
6958 && is_evpn_prefix_ipaddr_v4(
6959 (struct prefix_evpn *)&p))) {
6960 vty_out(vty,
6961 "%% GatewayIp family differs with IP prefix\n");
6962 return CMD_WARNING_CONFIG_FAILED;
6963 }
6964 }
6965 }
6966 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6967 if (!bgp_dest_has_bgp_path_info_data(pdest))
6968 bgp_dest_set_bgp_table_info(pdest,
6969 bgp_table_init(bgp, afi, safi));
6970 table = bgp_dest_get_bgp_table_info(pdest);
6971
6972 dest = bgp_node_get(table, &p);
6973
6974 if (bgp_dest_has_bgp_path_info_data(dest)) {
6975 vty_out(vty, "%% Same network configuration exists\n");
6976 bgp_dest_unlock_node(dest);
6977 } else {
6978 /* New configuration. */
6979 bgp_static = bgp_static_new();
6980 bgp_static->backdoor = 0;
6981 bgp_static->valid = 0;
6982 bgp_static->igpmetric = 0;
6983 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6984 bgp_static->label = label;
6985 bgp_static->prd = prd;
6986
6987 if (rmap_str) {
6988 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6989 route_map_counter_decrement(bgp_static->rmap.map);
6990 bgp_static->rmap.name =
6991 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
6992 bgp_static->rmap.map =
6993 route_map_lookup_by_name(rmap_str);
6994 route_map_counter_increment(bgp_static->rmap.map);
6995 }
6996
6997 if (safi == SAFI_EVPN) {
6998 if (esi) {
6999 bgp_static->eth_s_id =
7000 XCALLOC(MTYPE_ATTR,
7001 sizeof(esi_t));
7002 str2esi(esi, bgp_static->eth_s_id);
7003 }
7004 if (routermac) {
7005 bgp_static->router_mac =
7006 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
7007 (void)prefix_str2mac(routermac,
7008 bgp_static->router_mac);
7009 }
7010 if (gwip)
7011 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
7012 }
7013 bgp_dest_set_bgp_static_info(dest, bgp_static);
7014
7015 bgp_static->valid = 1;
7016 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
7017 }
7018
7019 return CMD_SUCCESS;
7020 }
7021
7022 /* Configure static BGP network. */
7023 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
7024 const char *ip_str, const char *rd_str,
7025 const char *label_str, int evpn_type, const char *esi,
7026 const char *gwip, const char *ethtag)
7027 {
7028 VTY_DECLVAR_CONTEXT(bgp, bgp);
7029 int ret;
7030 struct prefix p;
7031 struct prefix_rd prd;
7032 struct bgp_dest *pdest;
7033 struct bgp_dest *dest;
7034 struct bgp_table *table;
7035 struct bgp_static *bgp_static;
7036 mpls_label_t label = MPLS_INVALID_LABEL;
7037
7038 /* Convert IP prefix string to struct prefix. */
7039 ret = str2prefix(ip_str, &p);
7040 if (!ret) {
7041 vty_out(vty, "%% Malformed prefix\n");
7042 return CMD_WARNING_CONFIG_FAILED;
7043 }
7044 apply_mask(&p);
7045 if ((afi == AFI_L2VPN)
7046 && (bgp_build_evpn_prefix(evpn_type,
7047 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7048 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7049 return CMD_WARNING_CONFIG_FAILED;
7050 }
7051 ret = str2prefix_rd(rd_str, &prd);
7052 if (!ret) {
7053 vty_out(vty, "%% Malformed rd\n");
7054 return CMD_WARNING_CONFIG_FAILED;
7055 }
7056
7057 if (label_str) {
7058 unsigned long label_val;
7059 label_val = strtoul(label_str, NULL, 10);
7060 encode_label(label_val, &label);
7061 }
7062
7063 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7064 if (!bgp_dest_has_bgp_path_info_data(pdest))
7065 bgp_dest_set_bgp_table_info(pdest,
7066 bgp_table_init(bgp, afi, safi));
7067 else
7068 bgp_dest_unlock_node(pdest);
7069 table = bgp_dest_get_bgp_table_info(pdest);
7070
7071 dest = bgp_node_lookup(table, &p);
7072
7073 if (dest) {
7074 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
7075
7076 bgp_static = bgp_dest_get_bgp_static_info(dest);
7077 bgp_static_free(bgp_static);
7078 bgp_dest_set_bgp_static_info(dest, NULL);
7079 bgp_dest_unlock_node(dest);
7080 bgp_dest_unlock_node(dest);
7081 } else
7082 vty_out(vty, "%% Can't find the route\n");
7083
7084 return CMD_SUCCESS;
7085 }
7086
7087 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
7088 const char *rmap_name)
7089 {
7090 VTY_DECLVAR_CONTEXT(bgp, bgp);
7091 struct bgp_rmap *rmap;
7092
7093 rmap = &bgp->table_map[afi][safi];
7094 if (rmap_name) {
7095 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7096 route_map_counter_decrement(rmap->map);
7097 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
7098 rmap->map = route_map_lookup_by_name(rmap_name);
7099 route_map_counter_increment(rmap->map);
7100 } else {
7101 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7102 route_map_counter_decrement(rmap->map);
7103 rmap->map = NULL;
7104 }
7105
7106 if (bgp_fibupd_safi(safi))
7107 bgp_zebra_announce_table(bgp, afi, safi);
7108
7109 return CMD_SUCCESS;
7110 }
7111
7112 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
7113 const char *rmap_name)
7114 {
7115 VTY_DECLVAR_CONTEXT(bgp, bgp);
7116 struct bgp_rmap *rmap;
7117
7118 rmap = &bgp->table_map[afi][safi];
7119 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7120 route_map_counter_decrement(rmap->map);
7121 rmap->map = NULL;
7122
7123 if (bgp_fibupd_safi(safi))
7124 bgp_zebra_announce_table(bgp, afi, safi);
7125
7126 return CMD_SUCCESS;
7127 }
7128
7129 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
7130 safi_t safi)
7131 {
7132 if (bgp->table_map[afi][safi].name) {
7133 vty_out(vty, " table-map %s\n",
7134 bgp->table_map[afi][safi].name);
7135 }
7136 }
7137
7138 DEFUN (bgp_table_map,
7139 bgp_table_map_cmd,
7140 "table-map WORD",
7141 "BGP table to RIB route download filter\n"
7142 "Name of the route map\n")
7143 {
7144 int idx_word = 1;
7145 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7146 argv[idx_word]->arg);
7147 }
7148 DEFUN (no_bgp_table_map,
7149 no_bgp_table_map_cmd,
7150 "no table-map WORD",
7151 NO_STR
7152 "BGP table to RIB route download filter\n"
7153 "Name of the route map\n")
7154 {
7155 int idx_word = 2;
7156 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7157 argv[idx_word]->arg);
7158 }
7159
7160 DEFPY(bgp_network,
7161 bgp_network_cmd,
7162 "[no] network \
7163 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7164 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7165 backdoor$backdoor}]",
7166 NO_STR
7167 "Specify a network to announce via BGP\n"
7168 "IPv4 prefix\n"
7169 "Network number\n"
7170 "Network mask\n"
7171 "Network mask\n"
7172 "Route-map to modify the attributes\n"
7173 "Name of the route map\n"
7174 "Label index to associate with the prefix\n"
7175 "Label index value\n"
7176 "Specify a BGP backdoor route\n")
7177 {
7178 char addr_prefix_str[BUFSIZ];
7179
7180 if (address_str) {
7181 int ret;
7182
7183 ret = netmask_str2prefix_str(address_str, netmask_str,
7184 addr_prefix_str,
7185 sizeof(addr_prefix_str));
7186 if (!ret) {
7187 vty_out(vty, "%% Inconsistent address and mask\n");
7188 return CMD_WARNING_CONFIG_FAILED;
7189 }
7190 }
7191
7192 return bgp_static_set(
7193 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7194 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7195 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7196 }
7197
7198 DEFPY(ipv6_bgp_network,
7199 ipv6_bgp_network_cmd,
7200 "[no] network X:X::X:X/M$prefix \
7201 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7202 NO_STR
7203 "Specify a network to announce via BGP\n"
7204 "IPv6 prefix\n"
7205 "Route-map to modify the attributes\n"
7206 "Name of the route map\n"
7207 "Label index to associate with the prefix\n"
7208 "Label index value\n")
7209 {
7210 return bgp_static_set(
7211 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7212 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7213 }
7214
7215 static struct bgp_aggregate *bgp_aggregate_new(void)
7216 {
7217 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7218 }
7219
7220 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7221 {
7222 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7223 route_map_counter_decrement(aggregate->suppress_map);
7224 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7225 route_map_counter_decrement(aggregate->rmap.map);
7226 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7227 }
7228
7229 /**
7230 * Helper function to avoid repeated code: prepare variables for a
7231 * `route_map_apply` call.
7232 *
7233 * \returns `true` on route map match, otherwise `false`.
7234 */
7235 static bool aggr_suppress_map_test(struct bgp *bgp,
7236 struct bgp_aggregate *aggregate,
7237 struct bgp_path_info *pi)
7238 {
7239 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7240 route_map_result_t rmr = RMAP_DENYMATCH;
7241 struct bgp_path_info rmap_path = {};
7242 struct attr attr = {};
7243
7244 /* No route map entries created, just don't match. */
7245 if (aggregate->suppress_map == NULL)
7246 return false;
7247
7248 /* Call route map matching and return result. */
7249 attr.aspath = aspath_empty();
7250 rmap_path.peer = bgp->peer_self;
7251 rmap_path.attr = &attr;
7252
7253 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7254 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7255 bgp->peer_self->rmap_type = 0;
7256
7257 bgp_attr_flush(&attr);
7258 aspath_unintern(&attr.aspath);
7259
7260 return rmr == RMAP_PERMITMATCH;
7261 }
7262
7263 /** Test whether the aggregation has suppressed this path or not. */
7264 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7265 struct bgp_path_info *pi)
7266 {
7267 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7268 return false;
7269
7270 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7271 }
7272
7273 /**
7274 * Suppress this path and keep the reference.
7275 *
7276 * \returns `true` if needs processing otherwise `false`.
7277 */
7278 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7279 struct bgp_path_info *pi)
7280 {
7281 struct bgp_path_info_extra *pie;
7282
7283 /* Path is already suppressed by this aggregation. */
7284 if (aggr_suppress_exists(aggregate, pi))
7285 return false;
7286
7287 pie = bgp_path_info_extra_get(pi);
7288
7289 /* This is the first suppression, allocate memory and list it. */
7290 if (pie->aggr_suppressors == NULL)
7291 pie->aggr_suppressors = list_new();
7292
7293 listnode_add(pie->aggr_suppressors, aggregate);
7294
7295 /* Only mark for processing if suppressed. */
7296 if (listcount(pie->aggr_suppressors) == 1) {
7297 if (BGP_DEBUG(update, UPDATE_OUT))
7298 zlog_debug("aggregate-address suppressing: %pFX",
7299 bgp_dest_get_prefix(pi->net));
7300
7301 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7302 return true;
7303 }
7304
7305 return false;
7306 }
7307
7308 /**
7309 * Unsuppress this path and remove the reference.
7310 *
7311 * \returns `true` if needs processing otherwise `false`.
7312 */
7313 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7314 struct bgp_path_info *pi)
7315 {
7316 /* Path wasn't suppressed. */
7317 if (!aggr_suppress_exists(aggregate, pi))
7318 return false;
7319
7320 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7321
7322 /* Unsuppress and free extra memory if last item. */
7323 if (listcount(pi->extra->aggr_suppressors) == 0) {
7324 if (BGP_DEBUG(update, UPDATE_OUT))
7325 zlog_debug("aggregate-address unsuppressing: %pFX",
7326 bgp_dest_get_prefix(pi->net));
7327
7328 list_delete(&pi->extra->aggr_suppressors);
7329 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7330 return true;
7331 }
7332
7333 return false;
7334 }
7335
7336 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7337 struct aspath *aspath,
7338 struct community *comm,
7339 struct ecommunity *ecomm,
7340 struct lcommunity *lcomm)
7341 {
7342 static struct aspath *ae = NULL;
7343
7344 if (!ae)
7345 ae = aspath_empty();
7346
7347 if (!pi)
7348 return false;
7349
7350 if (origin != pi->attr->origin)
7351 return false;
7352
7353 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7354 return false;
7355
7356 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7357 return false;
7358
7359 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7360 return false;
7361
7362 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7363 return false;
7364
7365 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7366 return false;
7367
7368 return true;
7369 }
7370
7371 static void bgp_aggregate_install(
7372 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7373 uint8_t origin, struct aspath *aspath, struct community *community,
7374 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7375 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7376 {
7377 struct bgp_dest *dest;
7378 struct bgp_table *table;
7379 struct bgp_path_info *pi, *orig, *new;
7380 struct attr *attr;
7381
7382 table = bgp->rib[afi][safi];
7383
7384 dest = bgp_node_get(table, p);
7385
7386 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7387 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7388 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7389 break;
7390
7391 /*
7392 * If we have paths with different MEDs, then don't install
7393 * (or uninstall) the aggregate route.
7394 */
7395 if (aggregate->match_med && aggregate->med_mismatched)
7396 goto uninstall_aggregate_route;
7397
7398 if (aggregate->count > 0) {
7399 /*
7400 * If the aggregate information has not changed
7401 * no need to re-install it again.
7402 */
7403 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7404 ecommunity, lcommunity)) {
7405 bgp_dest_unlock_node(dest);
7406
7407 if (aspath)
7408 aspath_free(aspath);
7409 if (community)
7410 community_free(&community);
7411 if (ecommunity)
7412 ecommunity_free(&ecommunity);
7413 if (lcommunity)
7414 lcommunity_free(&lcommunity);
7415
7416 return;
7417 }
7418
7419 /*
7420 * Mark the old as unusable
7421 */
7422 if (pi)
7423 bgp_path_info_delete(dest, pi);
7424
7425 attr = bgp_attr_aggregate_intern(
7426 bgp, origin, aspath, community, ecommunity, lcommunity,
7427 aggregate, atomic_aggregate, p);
7428
7429 if (!attr) {
7430 bgp_dest_unlock_node(dest);
7431 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7432 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7433 zlog_debug("%s: %pFX null attribute", __func__,
7434 p);
7435 return;
7436 }
7437
7438 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7439 bgp->peer_self, attr, dest);
7440
7441 SET_FLAG(new->flags, BGP_PATH_VALID);
7442
7443 bgp_path_info_add(dest, new);
7444 bgp_process(bgp, dest, afi, safi);
7445 } else {
7446 uninstall_aggregate_route:
7447 for (pi = orig; pi; pi = pi->next)
7448 if (pi->peer == bgp->peer_self
7449 && pi->type == ZEBRA_ROUTE_BGP
7450 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7451 break;
7452
7453 /* Withdraw static BGP route from routing table. */
7454 if (pi) {
7455 bgp_path_info_delete(dest, pi);
7456 bgp_process(bgp, dest, afi, safi);
7457 }
7458 }
7459
7460 bgp_dest_unlock_node(dest);
7461 }
7462
7463 /**
7464 * Check if the current path has different MED than other known paths.
7465 *
7466 * \returns `true` if the MED matched the others else `false`.
7467 */
7468 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7469 struct bgp *bgp, struct bgp_path_info *pi)
7470 {
7471 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7472
7473 /* This is the first route being analyzed. */
7474 if (!aggregate->med_initialized) {
7475 aggregate->med_initialized = true;
7476 aggregate->med_mismatched = false;
7477 aggregate->med_matched_value = cur_med;
7478 } else {
7479 /* Check if routes with different MED showed up. */
7480 if (cur_med != aggregate->med_matched_value)
7481 aggregate->med_mismatched = true;
7482 }
7483
7484 return !aggregate->med_mismatched;
7485 }
7486
7487 /**
7488 * Initializes and tests all routes in the aggregate address path for MED
7489 * values.
7490 *
7491 * \returns `true` if all MEDs are the same otherwise `false`.
7492 */
7493 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7494 struct bgp *bgp, const struct prefix *p,
7495 afi_t afi, safi_t safi)
7496 {
7497 struct bgp_table *table = bgp->rib[afi][safi];
7498 const struct prefix *dest_p;
7499 struct bgp_dest *dest, *top;
7500 struct bgp_path_info *pi;
7501 bool med_matched = true;
7502
7503 aggregate->med_initialized = false;
7504
7505 top = bgp_node_get(table, p);
7506 for (dest = bgp_node_get(table, p); dest;
7507 dest = bgp_route_next_until(dest, top)) {
7508 dest_p = bgp_dest_get_prefix(dest);
7509 if (dest_p->prefixlen <= p->prefixlen)
7510 continue;
7511
7512 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7513 if (BGP_PATH_HOLDDOWN(pi))
7514 continue;
7515 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7516 continue;
7517 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7518 med_matched = false;
7519 break;
7520 }
7521 }
7522 if (!med_matched)
7523 break;
7524 }
7525 bgp_dest_unlock_node(top);
7526
7527 return med_matched;
7528 }
7529
7530 /**
7531 * Toggles the route suppression status for this aggregate address
7532 * configuration.
7533 */
7534 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7535 struct bgp *bgp, const struct prefix *p,
7536 afi_t afi, safi_t safi, bool suppress)
7537 {
7538 struct bgp_table *table = bgp->rib[afi][safi];
7539 const struct prefix *dest_p;
7540 struct bgp_dest *dest, *top;
7541 struct bgp_path_info *pi;
7542 bool toggle_suppression;
7543
7544 /* We've found a different MED we must revert any suppressed routes. */
7545 top = bgp_node_get(table, p);
7546 for (dest = bgp_node_get(table, p); dest;
7547 dest = bgp_route_next_until(dest, top)) {
7548 dest_p = bgp_dest_get_prefix(dest);
7549 if (dest_p->prefixlen <= p->prefixlen)
7550 continue;
7551
7552 toggle_suppression = false;
7553 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7554 if (BGP_PATH_HOLDDOWN(pi))
7555 continue;
7556 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7557 continue;
7558
7559 /* We are toggling suppression back. */
7560 if (suppress) {
7561 /* Suppress route if not suppressed already. */
7562 if (aggr_suppress_path(aggregate, pi))
7563 toggle_suppression = true;
7564 continue;
7565 }
7566
7567 /* Install route if there is no more suppression. */
7568 if (aggr_unsuppress_path(aggregate, pi))
7569 toggle_suppression = true;
7570 }
7571
7572 if (toggle_suppression)
7573 bgp_process(bgp, dest, afi, safi);
7574 }
7575 bgp_dest_unlock_node(top);
7576 }
7577
7578 /**
7579 * Aggregate address MED matching incremental test: this function is called
7580 * when the initial aggregation occurred and we are only testing a single
7581 * new path.
7582 *
7583 * In addition to testing and setting the MED validity it also installs back
7584 * suppressed routes (if summary is configured).
7585 *
7586 * Must not be called in `bgp_aggregate_route`.
7587 */
7588 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7589 struct bgp *bgp, const struct prefix *p,
7590 afi_t afi, safi_t safi,
7591 struct bgp_path_info *pi)
7592 {
7593 /* MED matching disabled. */
7594 if (!aggregate->match_med)
7595 return;
7596
7597 /* Aggregation with different MED, recheck if we have got equal MEDs
7598 * now.
7599 */
7600 if (aggregate->med_mismatched &&
7601 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7602 aggregate->summary_only)
7603 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7604 true);
7605 else
7606 bgp_aggregate_med_match(aggregate, bgp, pi);
7607
7608 /* No mismatches, just quit. */
7609 if (!aggregate->med_mismatched)
7610 return;
7611
7612 /* Route summarization is disabled. */
7613 if (!aggregate->summary_only)
7614 return;
7615
7616 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7617 }
7618
7619 /* Update an aggregate as routes are added/removed from the BGP table */
7620 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7621 safi_t safi, struct bgp_aggregate *aggregate)
7622 {
7623 struct bgp_table *table;
7624 struct bgp_dest *top;
7625 struct bgp_dest *dest;
7626 uint8_t origin;
7627 struct aspath *aspath = NULL;
7628 struct community *community = NULL;
7629 struct ecommunity *ecommunity = NULL;
7630 struct lcommunity *lcommunity = NULL;
7631 struct bgp_path_info *pi;
7632 unsigned long match = 0;
7633 uint8_t atomic_aggregate = 0;
7634
7635 /* If the bgp instance is being deleted or self peer is deleted
7636 * then do not create aggregate route
7637 */
7638 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7639 || (bgp->peer_self == NULL))
7640 return;
7641
7642 /* Initialize and test routes for MED difference. */
7643 if (aggregate->match_med)
7644 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7645
7646 /*
7647 * Reset aggregate count: we might've been called from route map
7648 * update so in that case we must retest all more specific routes.
7649 *
7650 * \see `bgp_route_map_process_update`.
7651 */
7652 aggregate->count = 0;
7653 aggregate->incomplete_origin_count = 0;
7654 aggregate->incomplete_origin_count = 0;
7655 aggregate->egp_origin_count = 0;
7656
7657 /* ORIGIN attribute: If at least one route among routes that are
7658 aggregated has ORIGIN with the value INCOMPLETE, then the
7659 aggregated route must have the ORIGIN attribute with the value
7660 INCOMPLETE. Otherwise, if at least one route among routes that
7661 are aggregated has ORIGIN with the value EGP, then the aggregated
7662 route must have the origin attribute with the value EGP. In all
7663 other case the value of the ORIGIN attribute of the aggregated
7664 route is INTERNAL. */
7665 origin = BGP_ORIGIN_IGP;
7666
7667 table = bgp->rib[afi][safi];
7668
7669 top = bgp_node_get(table, p);
7670 for (dest = bgp_node_get(table, p); dest;
7671 dest = bgp_route_next_until(dest, top)) {
7672 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7673
7674 if (dest_p->prefixlen <= p->prefixlen)
7675 continue;
7676
7677 /* If suppress fib is enabled and route not installed
7678 * in FIB, skip the route
7679 */
7680 if (!bgp_check_advertise(bgp, dest))
7681 continue;
7682
7683 match = 0;
7684
7685 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7686 if (BGP_PATH_HOLDDOWN(pi))
7687 continue;
7688
7689 if (pi->attr->flag
7690 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7691 atomic_aggregate = 1;
7692
7693 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7694 continue;
7695
7696 /*
7697 * summary-only aggregate route suppress
7698 * aggregated route announcements.
7699 *
7700 * MED matching:
7701 * Don't create summaries if MED didn't match
7702 * otherwise neither the specific routes and the
7703 * aggregation will be announced.
7704 */
7705 if (aggregate->summary_only
7706 && AGGREGATE_MED_VALID(aggregate)) {
7707 if (aggr_suppress_path(aggregate, pi))
7708 match++;
7709 }
7710
7711 /*
7712 * Suppress more specific routes that match the route
7713 * map results.
7714 *
7715 * MED matching:
7716 * Don't suppress routes if MED matching is enabled and
7717 * it mismatched otherwise we might end up with no
7718 * routes for this path.
7719 */
7720 if (aggregate->suppress_map_name
7721 && AGGREGATE_MED_VALID(aggregate)
7722 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7723 if (aggr_suppress_path(aggregate, pi))
7724 match++;
7725 }
7726
7727 aggregate->count++;
7728
7729 /*
7730 * If at least one route among routes that are
7731 * aggregated has ORIGIN with the value INCOMPLETE,
7732 * then the aggregated route MUST have the ORIGIN
7733 * attribute with the value INCOMPLETE. Otherwise, if
7734 * at least one route among routes that are aggregated
7735 * has ORIGIN with the value EGP, then the aggregated
7736 * route MUST have the ORIGIN attribute with the value
7737 * EGP.
7738 */
7739 switch (pi->attr->origin) {
7740 case BGP_ORIGIN_INCOMPLETE:
7741 aggregate->incomplete_origin_count++;
7742 break;
7743 case BGP_ORIGIN_EGP:
7744 aggregate->egp_origin_count++;
7745 break;
7746 default:
7747 /*Do nothing.
7748 */
7749 break;
7750 }
7751
7752 if (!aggregate->as_set)
7753 continue;
7754
7755 /*
7756 * as-set aggregate route generate origin, as path,
7757 * and community aggregation.
7758 */
7759 /* Compute aggregate route's as-path.
7760 */
7761 bgp_compute_aggregate_aspath_hash(aggregate,
7762 pi->attr->aspath);
7763
7764 /* Compute aggregate route's community.
7765 */
7766 if (bgp_attr_get_community(pi->attr))
7767 bgp_compute_aggregate_community_hash(
7768 aggregate,
7769 bgp_attr_get_community(pi->attr));
7770
7771 /* Compute aggregate route's extended community.
7772 */
7773 if (bgp_attr_get_ecommunity(pi->attr))
7774 bgp_compute_aggregate_ecommunity_hash(
7775 aggregate,
7776 bgp_attr_get_ecommunity(pi->attr));
7777
7778 /* Compute aggregate route's large community.
7779 */
7780 if (bgp_attr_get_lcommunity(pi->attr))
7781 bgp_compute_aggregate_lcommunity_hash(
7782 aggregate,
7783 bgp_attr_get_lcommunity(pi->attr));
7784 }
7785 if (match)
7786 bgp_process(bgp, dest, afi, safi);
7787 }
7788 if (aggregate->as_set) {
7789 bgp_compute_aggregate_aspath_val(aggregate);
7790 bgp_compute_aggregate_community_val(aggregate);
7791 bgp_compute_aggregate_ecommunity_val(aggregate);
7792 bgp_compute_aggregate_lcommunity_val(aggregate);
7793 }
7794
7795
7796 bgp_dest_unlock_node(top);
7797
7798
7799 if (aggregate->incomplete_origin_count > 0)
7800 origin = BGP_ORIGIN_INCOMPLETE;
7801 else if (aggregate->egp_origin_count > 0)
7802 origin = BGP_ORIGIN_EGP;
7803
7804 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7805 origin = aggregate->origin;
7806
7807 if (aggregate->as_set) {
7808 if (aggregate->aspath)
7809 /* Retrieve aggregate route's as-path.
7810 */
7811 aspath = aspath_dup(aggregate->aspath);
7812
7813 if (aggregate->community)
7814 /* Retrieve aggregate route's community.
7815 */
7816 community = community_dup(aggregate->community);
7817
7818 if (aggregate->ecommunity)
7819 /* Retrieve aggregate route's ecommunity.
7820 */
7821 ecommunity = ecommunity_dup(aggregate->ecommunity);
7822
7823 if (aggregate->lcommunity)
7824 /* Retrieve aggregate route's lcommunity.
7825 */
7826 lcommunity = lcommunity_dup(aggregate->lcommunity);
7827 }
7828
7829 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7830 ecommunity, lcommunity, atomic_aggregate,
7831 aggregate);
7832 }
7833
7834 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7835 safi_t safi, struct bgp_aggregate *aggregate)
7836 {
7837 struct bgp_table *table;
7838 struct bgp_dest *top;
7839 struct bgp_dest *dest;
7840 struct bgp_path_info *pi;
7841 unsigned long match;
7842
7843 table = bgp->rib[afi][safi];
7844
7845 /* If routes exists below this node, generate aggregate routes. */
7846 top = bgp_node_get(table, p);
7847 for (dest = bgp_node_get(table, p); dest;
7848 dest = bgp_route_next_until(dest, top)) {
7849 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7850
7851 if (dest_p->prefixlen <= p->prefixlen)
7852 continue;
7853 match = 0;
7854
7855 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7856 if (BGP_PATH_HOLDDOWN(pi))
7857 continue;
7858
7859 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7860 continue;
7861
7862 /*
7863 * This route is suppressed: attempt to unsuppress it.
7864 *
7865 * `aggr_unsuppress_path` will fail if this particular
7866 * aggregate route was not the suppressor.
7867 */
7868 if (pi->extra && pi->extra->aggr_suppressors &&
7869 listcount(pi->extra->aggr_suppressors)) {
7870 if (aggr_unsuppress_path(aggregate, pi))
7871 match++;
7872 }
7873
7874 aggregate->count--;
7875
7876 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7877 aggregate->incomplete_origin_count--;
7878 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7879 aggregate->egp_origin_count--;
7880
7881 if (aggregate->as_set) {
7882 /* Remove as-path from aggregate.
7883 */
7884 bgp_remove_aspath_from_aggregate_hash(
7885 aggregate,
7886 pi->attr->aspath);
7887
7888 if (bgp_attr_get_community(pi->attr))
7889 /* Remove community from aggregate.
7890 */
7891 bgp_remove_comm_from_aggregate_hash(
7892 aggregate,
7893 bgp_attr_get_community(
7894 pi->attr));
7895
7896 if (bgp_attr_get_ecommunity(pi->attr))
7897 /* Remove ecommunity from aggregate.
7898 */
7899 bgp_remove_ecomm_from_aggregate_hash(
7900 aggregate,
7901 bgp_attr_get_ecommunity(
7902 pi->attr));
7903
7904 if (bgp_attr_get_lcommunity(pi->attr))
7905 /* Remove lcommunity from aggregate.
7906 */
7907 bgp_remove_lcomm_from_aggregate_hash(
7908 aggregate,
7909 bgp_attr_get_lcommunity(
7910 pi->attr));
7911 }
7912 }
7913
7914 /* If this node was suppressed, process the change. */
7915 if (match)
7916 bgp_process(bgp, dest, afi, safi);
7917 }
7918 if (aggregate->as_set) {
7919 aspath_free(aggregate->aspath);
7920 aggregate->aspath = NULL;
7921 if (aggregate->community)
7922 community_free(&aggregate->community);
7923 if (aggregate->ecommunity)
7924 ecommunity_free(&aggregate->ecommunity);
7925 if (aggregate->lcommunity)
7926 lcommunity_free(&aggregate->lcommunity);
7927 }
7928
7929 bgp_dest_unlock_node(top);
7930 }
7931
7932 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7933 const struct prefix *aggr_p,
7934 struct bgp_path_info *pinew, afi_t afi,
7935 safi_t safi,
7936 struct bgp_aggregate *aggregate)
7937 {
7938 uint8_t origin;
7939 struct aspath *aspath = NULL;
7940 uint8_t atomic_aggregate = 0;
7941 struct community *community = NULL;
7942 struct ecommunity *ecommunity = NULL;
7943 struct lcommunity *lcommunity = NULL;
7944
7945 /* If the bgp instance is being deleted or self peer is deleted
7946 * then do not create aggregate route
7947 */
7948 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7949 || (bgp->peer_self == NULL))
7950 return;
7951
7952 /* ORIGIN attribute: If at least one route among routes that are
7953 * aggregated has ORIGIN with the value INCOMPLETE, then the
7954 * aggregated route must have the ORIGIN attribute with the value
7955 * INCOMPLETE. Otherwise, if at least one route among routes that
7956 * are aggregated has ORIGIN with the value EGP, then the aggregated
7957 * route must have the origin attribute with the value EGP. In all
7958 * other case the value of the ORIGIN attribute of the aggregated
7959 * route is INTERNAL.
7960 */
7961 origin = BGP_ORIGIN_IGP;
7962
7963 aggregate->count++;
7964
7965 /*
7966 * This must be called before `summary` check to avoid
7967 * "suppressing" twice.
7968 */
7969 if (aggregate->match_med)
7970 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
7971 pinew);
7972
7973 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7974 aggr_suppress_path(aggregate, pinew);
7975
7976 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7977 && aggr_suppress_map_test(bgp, aggregate, pinew))
7978 aggr_suppress_path(aggregate, pinew);
7979
7980 switch (pinew->attr->origin) {
7981 case BGP_ORIGIN_INCOMPLETE:
7982 aggregate->incomplete_origin_count++;
7983 break;
7984 case BGP_ORIGIN_EGP:
7985 aggregate->egp_origin_count++;
7986 break;
7987 default:
7988 /* Do nothing.
7989 */
7990 break;
7991 }
7992
7993 if (aggregate->incomplete_origin_count > 0)
7994 origin = BGP_ORIGIN_INCOMPLETE;
7995 else if (aggregate->egp_origin_count > 0)
7996 origin = BGP_ORIGIN_EGP;
7997
7998 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7999 origin = aggregate->origin;
8000
8001 if (aggregate->as_set) {
8002 /* Compute aggregate route's as-path.
8003 */
8004 bgp_compute_aggregate_aspath(aggregate,
8005 pinew->attr->aspath);
8006
8007 /* Compute aggregate route's community.
8008 */
8009 if (bgp_attr_get_community(pinew->attr))
8010 bgp_compute_aggregate_community(
8011 aggregate, bgp_attr_get_community(pinew->attr));
8012
8013 /* Compute aggregate route's extended community.
8014 */
8015 if (bgp_attr_get_ecommunity(pinew->attr))
8016 bgp_compute_aggregate_ecommunity(
8017 aggregate,
8018 bgp_attr_get_ecommunity(pinew->attr));
8019
8020 /* Compute aggregate route's large community.
8021 */
8022 if (bgp_attr_get_lcommunity(pinew->attr))
8023 bgp_compute_aggregate_lcommunity(
8024 aggregate,
8025 bgp_attr_get_lcommunity(pinew->attr));
8026
8027 /* Retrieve aggregate route's as-path.
8028 */
8029 if (aggregate->aspath)
8030 aspath = aspath_dup(aggregate->aspath);
8031
8032 /* Retrieve aggregate route's community.
8033 */
8034 if (aggregate->community)
8035 community = community_dup(aggregate->community);
8036
8037 /* Retrieve aggregate route's ecommunity.
8038 */
8039 if (aggregate->ecommunity)
8040 ecommunity = ecommunity_dup(aggregate->ecommunity);
8041
8042 /* Retrieve aggregate route's lcommunity.
8043 */
8044 if (aggregate->lcommunity)
8045 lcommunity = lcommunity_dup(aggregate->lcommunity);
8046 }
8047
8048 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8049 aspath, community, ecommunity,
8050 lcommunity, atomic_aggregate, aggregate);
8051 }
8052
8053 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
8054 safi_t safi,
8055 struct bgp_path_info *pi,
8056 struct bgp_aggregate *aggregate,
8057 const struct prefix *aggr_p)
8058 {
8059 uint8_t origin;
8060 struct aspath *aspath = NULL;
8061 uint8_t atomic_aggregate = 0;
8062 struct community *community = NULL;
8063 struct ecommunity *ecommunity = NULL;
8064 struct lcommunity *lcommunity = NULL;
8065 unsigned long match = 0;
8066
8067 /* If the bgp instance is being deleted or self peer is deleted
8068 * then do not create aggregate route
8069 */
8070 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8071 || (bgp->peer_self == NULL))
8072 return;
8073
8074 if (BGP_PATH_HOLDDOWN(pi))
8075 return;
8076
8077 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
8078 return;
8079
8080 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8081 if (aggr_unsuppress_path(aggregate, pi))
8082 match++;
8083
8084 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8085 && aggr_suppress_map_test(bgp, aggregate, pi))
8086 if (aggr_unsuppress_path(aggregate, pi))
8087 match++;
8088
8089 /*
8090 * This must be called after `summary`, `suppress-map` check to avoid
8091 * "unsuppressing" twice.
8092 */
8093 if (aggregate->match_med)
8094 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
8095
8096 if (aggregate->count > 0)
8097 aggregate->count--;
8098
8099 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
8100 aggregate->incomplete_origin_count--;
8101 else if (pi->attr->origin == BGP_ORIGIN_EGP)
8102 aggregate->egp_origin_count--;
8103
8104 if (aggregate->as_set) {
8105 /* Remove as-path from aggregate.
8106 */
8107 bgp_remove_aspath_from_aggregate(aggregate,
8108 pi->attr->aspath);
8109
8110 if (bgp_attr_get_community(pi->attr))
8111 /* Remove community from aggregate.
8112 */
8113 bgp_remove_community_from_aggregate(
8114 aggregate, bgp_attr_get_community(pi->attr));
8115
8116 if (bgp_attr_get_ecommunity(pi->attr))
8117 /* Remove ecommunity from aggregate.
8118 */
8119 bgp_remove_ecommunity_from_aggregate(
8120 aggregate, bgp_attr_get_ecommunity(pi->attr));
8121
8122 if (bgp_attr_get_lcommunity(pi->attr))
8123 /* Remove lcommunity from aggregate.
8124 */
8125 bgp_remove_lcommunity_from_aggregate(
8126 aggregate, bgp_attr_get_lcommunity(pi->attr));
8127 }
8128
8129 /* If this node was suppressed, process the change. */
8130 if (match)
8131 bgp_process(bgp, pi->net, afi, safi);
8132
8133 origin = BGP_ORIGIN_IGP;
8134 if (aggregate->incomplete_origin_count > 0)
8135 origin = BGP_ORIGIN_INCOMPLETE;
8136 else if (aggregate->egp_origin_count > 0)
8137 origin = BGP_ORIGIN_EGP;
8138
8139 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8140 origin = aggregate->origin;
8141
8142 if (aggregate->as_set) {
8143 /* Retrieve aggregate route's as-path.
8144 */
8145 if (aggregate->aspath)
8146 aspath = aspath_dup(aggregate->aspath);
8147
8148 /* Retrieve aggregate route's community.
8149 */
8150 if (aggregate->community)
8151 community = community_dup(aggregate->community);
8152
8153 /* Retrieve aggregate route's ecommunity.
8154 */
8155 if (aggregate->ecommunity)
8156 ecommunity = ecommunity_dup(aggregate->ecommunity);
8157
8158 /* Retrieve aggregate route's lcommunity.
8159 */
8160 if (aggregate->lcommunity)
8161 lcommunity = lcommunity_dup(aggregate->lcommunity);
8162 }
8163
8164 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8165 aspath, community, ecommunity,
8166 lcommunity, atomic_aggregate, aggregate);
8167 }
8168
8169 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8170 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8171 {
8172 struct bgp_dest *child;
8173 struct bgp_dest *dest;
8174 struct bgp_aggregate *aggregate;
8175 struct bgp_table *table;
8176
8177 table = bgp->aggregate[afi][safi];
8178
8179 /* No aggregates configured. */
8180 if (bgp_table_top_nolock(table) == NULL)
8181 return;
8182
8183 if (p->prefixlen == 0)
8184 return;
8185
8186 if (BGP_PATH_HOLDDOWN(pi))
8187 return;
8188
8189 /* If suppress fib is enabled and route not installed
8190 * in FIB, do not update the aggregate route
8191 */
8192 if (!bgp_check_advertise(bgp, pi->net))
8193 return;
8194
8195 child = bgp_node_get(table, p);
8196
8197 /* Aggregate address configuration check. */
8198 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8199 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8200
8201 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8202 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8203 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8204 aggregate);
8205 }
8206 }
8207 bgp_dest_unlock_node(child);
8208 }
8209
8210 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8211 struct bgp_path_info *del, afi_t afi, safi_t safi)
8212 {
8213 struct bgp_dest *child;
8214 struct bgp_dest *dest;
8215 struct bgp_aggregate *aggregate;
8216 struct bgp_table *table;
8217
8218 table = bgp->aggregate[afi][safi];
8219
8220 /* No aggregates configured. */
8221 if (bgp_table_top_nolock(table) == NULL)
8222 return;
8223
8224 if (p->prefixlen == 0)
8225 return;
8226
8227 child = bgp_node_get(table, p);
8228
8229 /* Aggregate address configuration check. */
8230 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8231 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8232
8233 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8234 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8235 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8236 aggregate, dest_p);
8237 }
8238 }
8239 bgp_dest_unlock_node(child);
8240 }
8241
8242 /* Aggregate route attribute. */
8243 #define AGGREGATE_SUMMARY_ONLY 1
8244 #define AGGREGATE_AS_SET 1
8245 #define AGGREGATE_AS_UNSET 0
8246
8247 static const char *bgp_origin2str(uint8_t origin)
8248 {
8249 switch (origin) {
8250 case BGP_ORIGIN_IGP:
8251 return "igp";
8252 case BGP_ORIGIN_EGP:
8253 return "egp";
8254 case BGP_ORIGIN_INCOMPLETE:
8255 return "incomplete";
8256 }
8257 return "n/a";
8258 }
8259
8260 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8261 {
8262 switch (v_state) {
8263 case RPKI_NOT_BEING_USED:
8264 return "not used";
8265 case RPKI_VALID:
8266 return "valid";
8267 case RPKI_NOTFOUND:
8268 return "not found";
8269 case RPKI_INVALID:
8270 return "invalid";
8271 }
8272
8273 assert(!"We should never get here this is a dev escape");
8274 return "ERROR";
8275 }
8276
8277 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8278 afi_t afi, safi_t safi)
8279 {
8280 VTY_DECLVAR_CONTEXT(bgp, bgp);
8281 int ret;
8282 struct prefix p;
8283 struct bgp_dest *dest;
8284 struct bgp_aggregate *aggregate;
8285
8286 /* Convert string to prefix structure. */
8287 ret = str2prefix(prefix_str, &p);
8288 if (!ret) {
8289 vty_out(vty, "Malformed prefix\n");
8290 return CMD_WARNING_CONFIG_FAILED;
8291 }
8292 apply_mask(&p);
8293
8294 /* Old configuration check. */
8295 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8296 if (!dest) {
8297 vty_out(vty,
8298 "%% There is no aggregate-address configuration.\n");
8299 return CMD_WARNING_CONFIG_FAILED;
8300 }
8301
8302 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8303 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8304 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8305 NULL, NULL, 0, aggregate);
8306
8307 /* Unlock aggregate address configuration. */
8308 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8309
8310 if (aggregate->community)
8311 community_free(&aggregate->community);
8312
8313 if (aggregate->community_hash) {
8314 /* Delete all communities in the hash.
8315 */
8316 hash_clean(aggregate->community_hash,
8317 bgp_aggr_community_remove);
8318 /* Free up the community_hash.
8319 */
8320 hash_free(aggregate->community_hash);
8321 }
8322
8323 if (aggregate->ecommunity)
8324 ecommunity_free(&aggregate->ecommunity);
8325
8326 if (aggregate->ecommunity_hash) {
8327 /* Delete all ecommunities in the hash.
8328 */
8329 hash_clean(aggregate->ecommunity_hash,
8330 bgp_aggr_ecommunity_remove);
8331 /* Free up the ecommunity_hash.
8332 */
8333 hash_free(aggregate->ecommunity_hash);
8334 }
8335
8336 if (aggregate->lcommunity)
8337 lcommunity_free(&aggregate->lcommunity);
8338
8339 if (aggregate->lcommunity_hash) {
8340 /* Delete all lcommunities in the hash.
8341 */
8342 hash_clean(aggregate->lcommunity_hash,
8343 bgp_aggr_lcommunity_remove);
8344 /* Free up the lcommunity_hash.
8345 */
8346 hash_free(aggregate->lcommunity_hash);
8347 }
8348
8349 if (aggregate->aspath)
8350 aspath_free(aggregate->aspath);
8351
8352 if (aggregate->aspath_hash) {
8353 /* Delete all as-paths in the hash.
8354 */
8355 hash_clean(aggregate->aspath_hash,
8356 bgp_aggr_aspath_remove);
8357 /* Free up the aspath_hash.
8358 */
8359 hash_free(aggregate->aspath_hash);
8360 }
8361
8362 bgp_aggregate_free(aggregate);
8363 bgp_dest_unlock_node(dest);
8364 bgp_dest_unlock_node(dest);
8365
8366 return CMD_SUCCESS;
8367 }
8368
8369 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8370 safi_t safi, const char *rmap,
8371 uint8_t summary_only, uint8_t as_set,
8372 uint8_t origin, bool match_med,
8373 const char *suppress_map)
8374 {
8375 VTY_DECLVAR_CONTEXT(bgp, bgp);
8376 int ret;
8377 struct prefix p;
8378 struct bgp_dest *dest;
8379 struct bgp_aggregate *aggregate;
8380 uint8_t as_set_new = as_set;
8381
8382 if (suppress_map && summary_only) {
8383 vty_out(vty,
8384 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8385 return CMD_WARNING_CONFIG_FAILED;
8386 }
8387
8388 /* Convert string to prefix structure. */
8389 ret = str2prefix(prefix_str, &p);
8390 if (!ret) {
8391 vty_out(vty, "Malformed prefix\n");
8392 return CMD_WARNING_CONFIG_FAILED;
8393 }
8394 apply_mask(&p);
8395
8396 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8397 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8398 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8399 prefix_str);
8400 return CMD_WARNING_CONFIG_FAILED;
8401 }
8402
8403 /* Old configuration check. */
8404 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8405 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8406
8407 if (aggregate) {
8408 vty_out(vty, "There is already same aggregate network.\n");
8409 /* try to remove the old entry */
8410 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8411 if (ret) {
8412 vty_out(vty, "Error deleting aggregate.\n");
8413 bgp_dest_unlock_node(dest);
8414 return CMD_WARNING_CONFIG_FAILED;
8415 }
8416 }
8417
8418 /* Make aggregate address structure. */
8419 aggregate = bgp_aggregate_new();
8420 aggregate->summary_only = summary_only;
8421 aggregate->match_med = match_med;
8422
8423 /* Network operators MUST NOT locally generate any new
8424 * announcements containing AS_SET or AS_CONFED_SET. If they have
8425 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8426 * SHOULD withdraw those routes and re-announce routes for the
8427 * aggregate or component prefixes (i.e., the more-specific routes
8428 * subsumed by the previously aggregated route) without AS_SET
8429 * or AS_CONFED_SET in the updates.
8430 */
8431 if (bgp->reject_as_sets) {
8432 if (as_set == AGGREGATE_AS_SET) {
8433 as_set_new = AGGREGATE_AS_UNSET;
8434 zlog_warn(
8435 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8436 __func__);
8437 vty_out(vty,
8438 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8439 }
8440 }
8441
8442 aggregate->as_set = as_set_new;
8443 aggregate->safi = safi;
8444 /* Override ORIGIN attribute if defined.
8445 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8446 * to IGP which is not what rfc4271 says.
8447 * This enables the same behavior, optionally.
8448 */
8449 aggregate->origin = origin;
8450
8451 if (rmap) {
8452 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8453 route_map_counter_decrement(aggregate->rmap.map);
8454 aggregate->rmap.name =
8455 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8456 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8457 route_map_counter_increment(aggregate->rmap.map);
8458 }
8459
8460 if (suppress_map) {
8461 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8462 route_map_counter_decrement(aggregate->suppress_map);
8463
8464 aggregate->suppress_map_name =
8465 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8466 aggregate->suppress_map =
8467 route_map_lookup_by_name(aggregate->suppress_map_name);
8468 route_map_counter_increment(aggregate->suppress_map);
8469 }
8470
8471 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8472
8473 /* Aggregate address insert into BGP routing table. */
8474 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
8475
8476 return CMD_SUCCESS;
8477 }
8478
8479 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8480 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8481 "as-set$as_set_s"
8482 "|summary-only$summary_only"
8483 "|route-map RMAP_NAME$rmap_name"
8484 "|origin <egp|igp|incomplete>$origin_s"
8485 "|matching-MED-only$match_med"
8486 "|suppress-map RMAP_NAME$suppress_map"
8487 "}]",
8488 NO_STR
8489 "Configure BGP aggregate entries\n"
8490 "Aggregate prefix\n"
8491 "Aggregate address\n"
8492 "Aggregate mask\n"
8493 "Generate AS set path information\n"
8494 "Filter more specific routes from updates\n"
8495 "Apply route map to aggregate network\n"
8496 "Route map name\n"
8497 "BGP origin code\n"
8498 "Remote EGP\n"
8499 "Local IGP\n"
8500 "Unknown heritage\n"
8501 "Only aggregate routes with matching MED\n"
8502 "Suppress the selected more specific routes\n"
8503 "Route map with the route selectors\n")
8504 {
8505 const char *prefix_s = NULL;
8506 safi_t safi = bgp_node_safi(vty);
8507 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8508 int as_set = AGGREGATE_AS_UNSET;
8509 char prefix_buf[PREFIX2STR_BUFFER];
8510
8511 if (addr_str) {
8512 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8513 sizeof(prefix_buf))
8514 == 0) {
8515 vty_out(vty, "%% Inconsistent address and mask\n");
8516 return CMD_WARNING_CONFIG_FAILED;
8517 }
8518 prefix_s = prefix_buf;
8519 } else
8520 prefix_s = prefix_str;
8521
8522 if (origin_s) {
8523 if (strcmp(origin_s, "egp") == 0)
8524 origin = BGP_ORIGIN_EGP;
8525 else if (strcmp(origin_s, "igp") == 0)
8526 origin = BGP_ORIGIN_IGP;
8527 else if (strcmp(origin_s, "incomplete") == 0)
8528 origin = BGP_ORIGIN_INCOMPLETE;
8529 }
8530
8531 if (as_set_s)
8532 as_set = AGGREGATE_AS_SET;
8533
8534 /* Handle configuration removal, otherwise installation. */
8535 if (no)
8536 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8537
8538 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8539 summary_only != NULL, as_set, origin,
8540 match_med != NULL, suppress_map);
8541 }
8542
8543 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8544 "[no] aggregate-address X:X::X:X/M$prefix [{"
8545 "as-set$as_set_s"
8546 "|summary-only$summary_only"
8547 "|route-map RMAP_NAME$rmap_name"
8548 "|origin <egp|igp|incomplete>$origin_s"
8549 "|matching-MED-only$match_med"
8550 "|suppress-map RMAP_NAME$suppress_map"
8551 "}]",
8552 NO_STR
8553 "Configure BGP aggregate entries\n"
8554 "Aggregate prefix\n"
8555 "Generate AS set path information\n"
8556 "Filter more specific routes from updates\n"
8557 "Apply route map to aggregate network\n"
8558 "Route map name\n"
8559 "BGP origin code\n"
8560 "Remote EGP\n"
8561 "Local IGP\n"
8562 "Unknown heritage\n"
8563 "Only aggregate routes with matching MED\n"
8564 "Suppress the selected more specific routes\n"
8565 "Route map with the route selectors\n")
8566 {
8567 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8568 int as_set = AGGREGATE_AS_UNSET;
8569
8570 if (origin_s) {
8571 if (strcmp(origin_s, "egp") == 0)
8572 origin = BGP_ORIGIN_EGP;
8573 else if (strcmp(origin_s, "igp") == 0)
8574 origin = BGP_ORIGIN_IGP;
8575 else if (strcmp(origin_s, "incomplete") == 0)
8576 origin = BGP_ORIGIN_INCOMPLETE;
8577 }
8578
8579 if (as_set_s)
8580 as_set = AGGREGATE_AS_SET;
8581
8582 /* Handle configuration removal, otherwise installation. */
8583 if (no)
8584 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8585 SAFI_UNICAST);
8586
8587 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8588 rmap_name, summary_only != NULL, as_set,
8589 origin, match_med != NULL, suppress_map);
8590 }
8591
8592 /* Redistribute route treatment. */
8593 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8594 const union g_addr *nexthop, ifindex_t ifindex,
8595 enum nexthop_types_t nhtype, uint8_t distance,
8596 enum blackhole_type bhtype, uint32_t metric,
8597 uint8_t type, unsigned short instance,
8598 route_tag_t tag)
8599 {
8600 struct bgp_path_info *new;
8601 struct bgp_path_info *bpi;
8602 struct bgp_path_info rmap_path;
8603 struct bgp_dest *bn;
8604 struct attr attr;
8605 struct attr *new_attr;
8606 afi_t afi;
8607 route_map_result_t ret;
8608 struct bgp_redist *red;
8609
8610 /* Make default attribute. */
8611 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8612 /*
8613 * This must not be NULL to satisfy Coverity SA
8614 */
8615 assert(attr.aspath);
8616
8617 switch (nhtype) {
8618 case NEXTHOP_TYPE_IFINDEX:
8619 switch (p->family) {
8620 case AF_INET:
8621 attr.nexthop.s_addr = INADDR_ANY;
8622 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8623 break;
8624 case AF_INET6:
8625 memset(&attr.mp_nexthop_global, 0,
8626 sizeof(attr.mp_nexthop_global));
8627 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8628 break;
8629 }
8630 break;
8631 case NEXTHOP_TYPE_IPV4:
8632 case NEXTHOP_TYPE_IPV4_IFINDEX:
8633 attr.nexthop = nexthop->ipv4;
8634 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8635 break;
8636 case NEXTHOP_TYPE_IPV6:
8637 case NEXTHOP_TYPE_IPV6_IFINDEX:
8638 attr.mp_nexthop_global = nexthop->ipv6;
8639 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8640 break;
8641 case NEXTHOP_TYPE_BLACKHOLE:
8642 switch (p->family) {
8643 case AF_INET:
8644 attr.nexthop.s_addr = INADDR_ANY;
8645 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8646 break;
8647 case AF_INET6:
8648 memset(&attr.mp_nexthop_global, 0,
8649 sizeof(attr.mp_nexthop_global));
8650 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8651 break;
8652 }
8653 attr.bh_type = bhtype;
8654 break;
8655 }
8656 attr.nh_type = nhtype;
8657 attr.nh_ifindex = ifindex;
8658
8659 attr.med = metric;
8660 attr.distance = distance;
8661 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8662 attr.tag = tag;
8663
8664 if (metric)
8665 bgp_attr_set_aigp_metric(&attr, metric);
8666
8667 afi = family2afi(p->family);
8668
8669 red = bgp_redist_lookup(bgp, afi, type, instance);
8670 if (red) {
8671 struct attr attr_new;
8672
8673 /* Copy attribute for modification. */
8674 attr_new = attr;
8675
8676 if (red->redist_metric_flag) {
8677 attr_new.med = red->redist_metric;
8678 bgp_attr_set_aigp_metric(&attr_new, red->redist_metric);
8679 }
8680
8681 /* Apply route-map. */
8682 if (red->rmap.name) {
8683 memset(&rmap_path, 0, sizeof(rmap_path));
8684 rmap_path.peer = bgp->peer_self;
8685 rmap_path.attr = &attr_new;
8686
8687 SET_FLAG(bgp->peer_self->rmap_type,
8688 PEER_RMAP_TYPE_REDISTRIBUTE);
8689
8690 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8691
8692 bgp->peer_self->rmap_type = 0;
8693
8694 if (ret == RMAP_DENYMATCH) {
8695 /* Free uninterned attribute. */
8696 bgp_attr_flush(&attr_new);
8697
8698 /* Unintern original. */
8699 aspath_unintern(&attr.aspath);
8700 bgp_redistribute_delete(bgp, p, type, instance);
8701 return;
8702 }
8703 }
8704
8705 if (bgp_in_graceful_shutdown(bgp))
8706 bgp_attr_add_gshut_community(&attr_new);
8707
8708 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8709 SAFI_UNICAST, p, NULL);
8710
8711 new_attr = bgp_attr_intern(&attr_new);
8712
8713 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8714 if (bpi->peer == bgp->peer_self
8715 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8716 break;
8717
8718 if (bpi) {
8719 /* Ensure the (source route) type is updated. */
8720 bpi->type = type;
8721 if (attrhash_cmp(bpi->attr, new_attr)
8722 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8723 bgp_attr_unintern(&new_attr);
8724 aspath_unintern(&attr.aspath);
8725 bgp_dest_unlock_node(bn);
8726 return;
8727 } else {
8728 /* The attribute is changed. */
8729 bgp_path_info_set_flag(bn, bpi,
8730 BGP_PATH_ATTR_CHANGED);
8731
8732 /* Rewrite BGP route information. */
8733 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8734 bgp_path_info_restore(bn, bpi);
8735 else
8736 bgp_aggregate_decrement(
8737 bgp, p, bpi, afi, SAFI_UNICAST);
8738 bgp_attr_unintern(&bpi->attr);
8739 bpi->attr = new_attr;
8740 bpi->uptime = monotime(NULL);
8741
8742 /* Process change. */
8743 bgp_aggregate_increment(bgp, p, bpi, afi,
8744 SAFI_UNICAST);
8745 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8746 bgp_dest_unlock_node(bn);
8747 aspath_unintern(&attr.aspath);
8748
8749 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8750 || (bgp->inst_type
8751 == BGP_INSTANCE_TYPE_DEFAULT)) {
8752
8753 vpn_leak_from_vrf_update(
8754 bgp_get_default(), bgp, bpi);
8755 }
8756 return;
8757 }
8758 }
8759
8760 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8761 bgp->peer_self, new_attr, bn);
8762 SET_FLAG(new->flags, BGP_PATH_VALID);
8763
8764 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8765 bgp_path_info_add(bn, new);
8766 bgp_dest_unlock_node(bn);
8767 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8768 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8769
8770 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8771 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8772
8773 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8774 }
8775 }
8776
8777 /* Unintern original. */
8778 aspath_unintern(&attr.aspath);
8779 }
8780
8781 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8782 unsigned short instance)
8783 {
8784 afi_t afi;
8785 struct bgp_dest *dest;
8786 struct bgp_path_info *pi;
8787 struct bgp_redist *red;
8788
8789 afi = family2afi(p->family);
8790
8791 red = bgp_redist_lookup(bgp, afi, type, instance);
8792 if (red) {
8793 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8794 SAFI_UNICAST, p, NULL);
8795
8796 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8797 if (pi->peer == bgp->peer_self && pi->type == type)
8798 break;
8799
8800 if (pi) {
8801 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8802 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8803
8804 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8805 bgp, pi);
8806 }
8807 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8808 bgp_path_info_delete(dest, pi);
8809 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8810 }
8811 bgp_dest_unlock_node(dest);
8812 }
8813 }
8814
8815 /* Withdraw specified route type's route. */
8816 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8817 unsigned short instance)
8818 {
8819 struct bgp_dest *dest;
8820 struct bgp_path_info *pi;
8821 struct bgp_table *table;
8822
8823 table = bgp->rib[afi][SAFI_UNICAST];
8824
8825 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8826 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8827 if (pi->peer == bgp->peer_self && pi->type == type
8828 && pi->instance == instance)
8829 break;
8830
8831 if (pi) {
8832 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8833 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8834
8835 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8836 bgp, pi);
8837 }
8838 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8839 pi, afi, SAFI_UNICAST);
8840 bgp_path_info_delete(dest, pi);
8841 if (!CHECK_FLAG(bgp->flags,
8842 BGP_FLAG_DELETE_IN_PROGRESS))
8843 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8844 else
8845 bgp_path_info_reap(dest, pi);
8846 }
8847 }
8848 }
8849
8850 /* Static function to display route. */
8851 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8852 struct vty *vty, json_object *json, bool wide)
8853 {
8854 int len = 0;
8855 char buf[INET6_ADDRSTRLEN];
8856
8857 if (p->family == AF_INET) {
8858 if (!json) {
8859 len = vty_out(vty, "%pFX", p);
8860 } else {
8861 json_object_string_add(json, "prefix",
8862 inet_ntop(p->family,
8863 &p->u.prefix, buf,
8864 sizeof(buf)));
8865 json_object_int_add(json, "prefixLen", p->prefixlen);
8866 json_object_string_addf(json, "network", "%pFX", p);
8867 json_object_int_add(json, "version", dest->version);
8868 }
8869 } else if (p->family == AF_ETHERNET) {
8870 len = vty_out(vty, "%pFX", p);
8871 } else if (p->family == AF_EVPN) {
8872 if (!json)
8873 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8874 else
8875 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8876 } else if (p->family == AF_FLOWSPEC) {
8877 route_vty_out_flowspec(vty, p, NULL,
8878 json ?
8879 NLRI_STRING_FORMAT_JSON_SIMPLE :
8880 NLRI_STRING_FORMAT_MIN, json);
8881 } else {
8882 if (!json)
8883 len = vty_out(vty, "%pFX", p);
8884 else {
8885 json_object_string_add(json, "prefix",
8886 inet_ntop(p->family,
8887 &p->u.prefix, buf,
8888 sizeof(buf)));
8889 json_object_int_add(json, "prefixLen", p->prefixlen);
8890 json_object_string_addf(json, "network", "%pFX", p);
8891 json_object_int_add(json, "version", dest->version);
8892 }
8893 }
8894
8895 if (!json) {
8896 len = wide ? (45 - len) : (17 - len);
8897 if (len < 1)
8898 vty_out(vty, "\n%*s", 20, " ");
8899 else
8900 vty_out(vty, "%*s", len, " ");
8901 }
8902 }
8903
8904 enum bgp_display_type {
8905 normal_list,
8906 };
8907
8908 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8909 {
8910 switch (reason) {
8911 case bgp_path_selection_none:
8912 return "Nothing to Select";
8913 case bgp_path_selection_first:
8914 return "First path received";
8915 case bgp_path_selection_evpn_sticky_mac:
8916 return "EVPN Sticky Mac";
8917 case bgp_path_selection_evpn_seq:
8918 return "EVPN sequence number";
8919 case bgp_path_selection_evpn_lower_ip:
8920 return "EVPN lower IP";
8921 case bgp_path_selection_evpn_local_path:
8922 return "EVPN local ES path";
8923 case bgp_path_selection_evpn_non_proxy:
8924 return "EVPN non proxy";
8925 case bgp_path_selection_weight:
8926 return "Weight";
8927 case bgp_path_selection_local_pref:
8928 return "Local Pref";
8929 case bgp_path_selection_accept_own:
8930 return "Accept Own";
8931 case bgp_path_selection_local_route:
8932 return "Local Route";
8933 case bgp_path_selection_aigp:
8934 return "AIGP";
8935 case bgp_path_selection_confed_as_path:
8936 return "Confederation based AS Path";
8937 case bgp_path_selection_as_path:
8938 return "AS Path";
8939 case bgp_path_selection_origin:
8940 return "Origin";
8941 case bgp_path_selection_med:
8942 return "MED";
8943 case bgp_path_selection_peer:
8944 return "Peer Type";
8945 case bgp_path_selection_confed:
8946 return "Confed Peer Type";
8947 case bgp_path_selection_igp_metric:
8948 return "IGP Metric";
8949 case bgp_path_selection_older:
8950 return "Older Path";
8951 case bgp_path_selection_router_id:
8952 return "Router ID";
8953 case bgp_path_selection_cluster_length:
8954 return "Cluster length";
8955 case bgp_path_selection_stale:
8956 return "Path Staleness";
8957 case bgp_path_selection_local_configured:
8958 return "Locally configured route";
8959 case bgp_path_selection_neighbor_ip:
8960 return "Neighbor IP";
8961 case bgp_path_selection_default:
8962 return "Nothing left to compare";
8963 }
8964 return "Invalid (internal error)";
8965 }
8966
8967 /* Print the short form route status for a bgp_path_info */
8968 static void route_vty_short_status_out(struct vty *vty,
8969 struct bgp_path_info *path,
8970 const struct prefix *p,
8971 json_object *json_path)
8972 {
8973 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
8974
8975 if (json_path) {
8976
8977 /* Route status display. */
8978 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8979 json_object_boolean_true_add(json_path, "removed");
8980
8981 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8982 json_object_boolean_true_add(json_path, "stale");
8983
8984 if (path->extra && bgp_path_suppressed(path))
8985 json_object_boolean_true_add(json_path, "suppressed");
8986
8987 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8988 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8989 json_object_boolean_true_add(json_path, "valid");
8990
8991 /* Selected */
8992 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8993 json_object_boolean_true_add(json_path, "history");
8994
8995 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8996 json_object_boolean_true_add(json_path, "damped");
8997
8998 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
8999 json_object_boolean_true_add(json_path, "bestpath");
9000 json_object_string_add(json_path, "selectionReason",
9001 bgp_path_selection_reason2str(
9002 path->net->reason));
9003 }
9004
9005 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9006 json_object_boolean_true_add(json_path, "multipath");
9007
9008 /* Internal route. */
9009 if ((path->peer->as)
9010 && (path->peer->as == path->peer->local_as))
9011 json_object_string_add(json_path, "pathFrom",
9012 "internal");
9013 else
9014 json_object_string_add(json_path, "pathFrom",
9015 "external");
9016
9017 return;
9018 }
9019
9020 /* RPKI validation state */
9021 rpki_state =
9022 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9023
9024 if (rpki_state == RPKI_VALID)
9025 vty_out(vty, "V");
9026 else if (rpki_state == RPKI_INVALID)
9027 vty_out(vty, "I");
9028 else if (rpki_state == RPKI_NOTFOUND)
9029 vty_out(vty, "N");
9030 else
9031 vty_out(vty, " ");
9032
9033 /* Route status display. */
9034 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9035 vty_out(vty, "R");
9036 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9037 vty_out(vty, "S");
9038 else if (bgp_path_suppressed(path))
9039 vty_out(vty, "s");
9040 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9041 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9042 vty_out(vty, "*");
9043 else
9044 vty_out(vty, " ");
9045
9046 /* Selected */
9047 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9048 vty_out(vty, "h");
9049 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9050 vty_out(vty, "d");
9051 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9052 vty_out(vty, ">");
9053 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9054 vty_out(vty, "=");
9055 else
9056 vty_out(vty, " ");
9057
9058 /* Internal route. */
9059 if (path->peer && (path->peer->as)
9060 && (path->peer->as == path->peer->local_as))
9061 vty_out(vty, "i");
9062 else
9063 vty_out(vty, " ");
9064 }
9065
9066 static char *bgp_nexthop_hostname(struct peer *peer,
9067 struct bgp_nexthop_cache *bnc)
9068 {
9069 if (peer->hostname
9070 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9071 return peer->hostname;
9072 return NULL;
9073 }
9074
9075 /* called from terminal list command */
9076 void route_vty_out(struct vty *vty, const struct prefix *p,
9077 struct bgp_path_info *path, int display, safi_t safi,
9078 json_object *json_paths, bool wide)
9079 {
9080 int len;
9081 struct attr *attr = path->attr;
9082 json_object *json_path = NULL;
9083 json_object *json_nexthops = NULL;
9084 json_object *json_nexthop_global = NULL;
9085 json_object *json_nexthop_ll = NULL;
9086 json_object *json_ext_community = NULL;
9087 char vrf_id_str[VRF_NAMSIZ] = {0};
9088 bool nexthop_self =
9089 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9090 bool nexthop_othervrf = false;
9091 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9092 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9093 char *nexthop_hostname =
9094 bgp_nexthop_hostname(path->peer, path->nexthop);
9095 char esi_buf[ESI_STR_LEN];
9096
9097 if (json_paths)
9098 json_path = json_object_new_object();
9099
9100 /* short status lead text */
9101 route_vty_short_status_out(vty, path, p, json_path);
9102
9103 if (!json_paths) {
9104 /* print prefix and mask */
9105 if (!display)
9106 route_vty_out_route(path->net, p, vty, json_path, wide);
9107 else
9108 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9109 } else {
9110 route_vty_out_route(path->net, p, vty, json_path, wide);
9111 }
9112
9113 /*
9114 * If vrf id of nexthop is different from that of prefix,
9115 * set up printable string to append
9116 */
9117 if (path->extra && path->extra->bgp_orig) {
9118 const char *self = "";
9119
9120 if (nexthop_self)
9121 self = "<";
9122
9123 nexthop_othervrf = true;
9124 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9125
9126 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9127 snprintf(vrf_id_str, sizeof(vrf_id_str),
9128 "@%s%s", VRFID_NONE_STR, self);
9129 else
9130 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9131 path->extra->bgp_orig->vrf_id, self);
9132
9133 if (path->extra->bgp_orig->inst_type
9134 != BGP_INSTANCE_TYPE_DEFAULT)
9135
9136 nexthop_vrfname = path->extra->bgp_orig->name;
9137 } else {
9138 const char *self = "";
9139
9140 if (nexthop_self)
9141 self = "<";
9142
9143 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9144 }
9145
9146 /*
9147 * For ENCAP and EVPN routes, nexthop address family is not
9148 * neccessarily the same as the prefix address family.
9149 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9150 * EVPN routes are also exchanged with a MP nexthop. Currently,
9151 * this
9152 * is only IPv4, the value will be present in either
9153 * attr->nexthop or
9154 * attr->mp_nexthop_global_in
9155 */
9156 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9157 char nexthop[128];
9158 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9159
9160 switch (af) {
9161 case AF_INET:
9162 snprintfrr(nexthop, sizeof(nexthop), "%pI4",
9163 &attr->mp_nexthop_global_in);
9164 break;
9165 case AF_INET6:
9166 snprintfrr(nexthop, sizeof(nexthop), "%pI6",
9167 &attr->mp_nexthop_global);
9168 break;
9169 default:
9170 snprintf(nexthop, sizeof(nexthop), "?");
9171 break;
9172 }
9173
9174 if (json_paths) {
9175 json_nexthop_global = json_object_new_object();
9176
9177 json_object_string_add(json_nexthop_global, "ip",
9178 nexthop);
9179
9180 if (path->peer->hostname)
9181 json_object_string_add(json_nexthop_global,
9182 "hostname",
9183 path->peer->hostname);
9184
9185 json_object_string_add(json_nexthop_global, "afi",
9186 (af == AF_INET) ? "ipv4"
9187 : "ipv6");
9188 json_object_boolean_true_add(json_nexthop_global,
9189 "used");
9190 } else {
9191 if (nexthop_hostname)
9192 len = vty_out(vty, "%s(%s)%s", nexthop,
9193 nexthop_hostname, vrf_id_str);
9194 else
9195 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9196
9197 len = wide ? (41 - len) : (16 - len);
9198 if (len < 1)
9199 vty_out(vty, "\n%*s", 36, " ");
9200 else
9201 vty_out(vty, "%*s", len, " ");
9202 }
9203 } else if (safi == SAFI_EVPN) {
9204 if (json_paths) {
9205 json_nexthop_global = json_object_new_object();
9206
9207 json_object_string_addf(json_nexthop_global, "ip",
9208 "%pI4",
9209 &attr->mp_nexthop_global_in);
9210
9211 if (path->peer->hostname)
9212 json_object_string_add(json_nexthop_global,
9213 "hostname",
9214 path->peer->hostname);
9215
9216 json_object_string_add(json_nexthop_global, "afi",
9217 "ipv4");
9218 json_object_boolean_true_add(json_nexthop_global,
9219 "used");
9220 } else {
9221 if (nexthop_hostname)
9222 len = vty_out(vty, "%pI4(%s)%s",
9223 &attr->mp_nexthop_global_in,
9224 nexthop_hostname, vrf_id_str);
9225 else
9226 len = vty_out(vty, "%pI4%s",
9227 &attr->mp_nexthop_global_in,
9228 vrf_id_str);
9229
9230 len = wide ? (41 - len) : (16 - len);
9231 if (len < 1)
9232 vty_out(vty, "\n%*s", 36, " ");
9233 else
9234 vty_out(vty, "%*s", len, " ");
9235 }
9236 } else if (safi == SAFI_FLOWSPEC) {
9237 if (attr->nexthop.s_addr != INADDR_ANY) {
9238 if (json_paths) {
9239 json_nexthop_global = json_object_new_object();
9240
9241 json_object_string_add(json_nexthop_global,
9242 "afi", "ipv4");
9243 json_object_string_addf(json_nexthop_global,
9244 "ip", "%pI4",
9245 &attr->nexthop);
9246
9247 if (path->peer->hostname)
9248 json_object_string_add(
9249 json_nexthop_global, "hostname",
9250 path->peer->hostname);
9251
9252 json_object_boolean_true_add(
9253 json_nexthop_global,
9254 "used");
9255 } else {
9256 if (nexthop_hostname)
9257 len = vty_out(vty, "%pI4(%s)%s",
9258 &attr->nexthop,
9259 nexthop_hostname,
9260 vrf_id_str);
9261 else
9262 len = vty_out(vty, "%pI4%s",
9263 &attr->nexthop,
9264 vrf_id_str);
9265
9266 len = wide ? (41 - len) : (16 - len);
9267 if (len < 1)
9268 vty_out(vty, "\n%*s", 36, " ");
9269 else
9270 vty_out(vty, "%*s", len, " ");
9271 }
9272 }
9273 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9274 if (json_paths) {
9275 json_nexthop_global = json_object_new_object();
9276
9277 json_object_string_addf(json_nexthop_global, "ip",
9278 "%pI4", &attr->nexthop);
9279
9280 if (path->peer->hostname)
9281 json_object_string_add(json_nexthop_global,
9282 "hostname",
9283 path->peer->hostname);
9284
9285 json_object_string_add(json_nexthop_global, "afi",
9286 "ipv4");
9287 json_object_boolean_true_add(json_nexthop_global,
9288 "used");
9289 } else {
9290 if (nexthop_hostname)
9291 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9292 nexthop_hostname, vrf_id_str);
9293 else
9294 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9295 vrf_id_str);
9296
9297 len = wide ? (41 - len) : (16 - len);
9298 if (len < 1)
9299 vty_out(vty, "\n%*s", 36, " ");
9300 else
9301 vty_out(vty, "%*s", len, " ");
9302 }
9303 }
9304
9305 /* IPv6 Next Hop */
9306 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9307 if (json_paths) {
9308 json_nexthop_global = json_object_new_object();
9309 json_object_string_addf(json_nexthop_global, "ip",
9310 "%pI6",
9311 &attr->mp_nexthop_global);
9312
9313 if (path->peer->hostname)
9314 json_object_string_add(json_nexthop_global,
9315 "hostname",
9316 path->peer->hostname);
9317
9318 json_object_string_add(json_nexthop_global, "afi",
9319 "ipv6");
9320 json_object_string_add(json_nexthop_global, "scope",
9321 "global");
9322
9323 /* We display both LL & GL if both have been
9324 * received */
9325 if ((attr->mp_nexthop_len
9326 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9327 || (path->peer->conf_if)) {
9328 json_nexthop_ll = json_object_new_object();
9329 json_object_string_addf(
9330 json_nexthop_ll, "ip", "%pI6",
9331 &attr->mp_nexthop_local);
9332
9333 if (path->peer->hostname)
9334 json_object_string_add(
9335 json_nexthop_ll, "hostname",
9336 path->peer->hostname);
9337
9338 json_object_string_add(json_nexthop_ll, "afi",
9339 "ipv6");
9340 json_object_string_add(json_nexthop_ll, "scope",
9341 "link-local");
9342
9343 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9344 &attr->mp_nexthop_local)
9345 != 0)
9346 && !attr->mp_nexthop_prefer_global)
9347 json_object_boolean_true_add(
9348 json_nexthop_ll, "used");
9349 else
9350 json_object_boolean_true_add(
9351 json_nexthop_global, "used");
9352 } else
9353 json_object_boolean_true_add(
9354 json_nexthop_global, "used");
9355 } else {
9356 /* Display LL if LL/Global both in table unless
9357 * prefer-global is set */
9358 if (((attr->mp_nexthop_len
9359 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9360 && !attr->mp_nexthop_prefer_global)
9361 || (path->peer->conf_if)) {
9362 if (path->peer->conf_if) {
9363 len = vty_out(vty, "%s",
9364 path->peer->conf_if);
9365 /* len of IPv6 addr + max len of def
9366 * ifname */
9367 len = wide ? (41 - len) : (16 - len);
9368
9369 if (len < 1)
9370 vty_out(vty, "\n%*s", 36, " ");
9371 else
9372 vty_out(vty, "%*s", len, " ");
9373 } else {
9374 if (nexthop_hostname)
9375 len = vty_out(
9376 vty, "%pI6(%s)%s",
9377 &attr->mp_nexthop_local,
9378 nexthop_hostname,
9379 vrf_id_str);
9380 else
9381 len = vty_out(
9382 vty, "%pI6%s",
9383 &attr->mp_nexthop_local,
9384 vrf_id_str);
9385
9386 len = wide ? (41 - len) : (16 - len);
9387
9388 if (len < 1)
9389 vty_out(vty, "\n%*s", 36, " ");
9390 else
9391 vty_out(vty, "%*s", len, " ");
9392 }
9393 } else {
9394 if (nexthop_hostname)
9395 len = vty_out(vty, "%pI6(%s)%s",
9396 &attr->mp_nexthop_global,
9397 nexthop_hostname,
9398 vrf_id_str);
9399 else
9400 len = vty_out(vty, "%pI6%s",
9401 &attr->mp_nexthop_global,
9402 vrf_id_str);
9403
9404 len = wide ? (41 - len) : (16 - len);
9405
9406 if (len < 1)
9407 vty_out(vty, "\n%*s", 36, " ");
9408 else
9409 vty_out(vty, "%*s", len, " ");
9410 }
9411 }
9412 }
9413
9414 /* MED/Metric */
9415 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9416 if (json_paths)
9417 json_object_int_add(json_path, "metric", attr->med);
9418 else if (wide)
9419 vty_out(vty, "%7u", attr->med);
9420 else
9421 vty_out(vty, "%10u", attr->med);
9422 else if (!json_paths) {
9423 if (wide)
9424 vty_out(vty, "%*s", 7, " ");
9425 else
9426 vty_out(vty, "%*s", 10, " ");
9427 }
9428
9429 /* Local Pref */
9430 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9431 if (json_paths)
9432 json_object_int_add(json_path, "locPrf",
9433 attr->local_pref);
9434 else
9435 vty_out(vty, "%7u", attr->local_pref);
9436 else if (!json_paths)
9437 vty_out(vty, " ");
9438
9439 if (json_paths)
9440 json_object_int_add(json_path, "weight", attr->weight);
9441 else
9442 vty_out(vty, "%7u ", attr->weight);
9443
9444 if (json_paths)
9445 json_object_string_addf(json_path, "peerId", "%pSU",
9446 &path->peer->su);
9447
9448 /* Print aspath */
9449 if (attr->aspath) {
9450 if (json_paths)
9451 json_object_string_add(json_path, "path",
9452 attr->aspath->str);
9453 else
9454 aspath_print_vty(vty, attr->aspath);
9455 }
9456
9457 /* Print origin */
9458 if (json_paths)
9459 json_object_string_add(json_path, "origin",
9460 bgp_origin_long_str[attr->origin]);
9461 else
9462 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9463
9464 if (json_paths) {
9465 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9466 json_object_string_add(json_path, "esi",
9467 esi_to_str(&attr->esi,
9468 esi_buf, sizeof(esi_buf)));
9469 }
9470 if (safi == SAFI_EVPN &&
9471 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9472 json_ext_community = json_object_new_object();
9473 json_object_string_add(
9474 json_ext_community, "string",
9475 bgp_attr_get_ecommunity(attr)->str);
9476 json_object_object_add(json_path,
9477 "extendedCommunity",
9478 json_ext_community);
9479 }
9480
9481 if (nexthop_self)
9482 json_object_boolean_true_add(json_path,
9483 "announceNexthopSelf");
9484 if (nexthop_othervrf) {
9485 json_object_string_add(json_path, "nhVrfName",
9486 nexthop_vrfname);
9487
9488 json_object_int_add(json_path, "nhVrfId",
9489 ((nexthop_vrfid == VRF_UNKNOWN)
9490 ? -1
9491 : (int)nexthop_vrfid));
9492 }
9493 }
9494
9495 if (json_paths) {
9496 if (json_nexthop_global || json_nexthop_ll) {
9497 json_nexthops = json_object_new_array();
9498
9499 if (json_nexthop_global)
9500 json_object_array_add(json_nexthops,
9501 json_nexthop_global);
9502
9503 if (json_nexthop_ll)
9504 json_object_array_add(json_nexthops,
9505 json_nexthop_ll);
9506
9507 json_object_object_add(json_path, "nexthops",
9508 json_nexthops);
9509 }
9510
9511 json_object_array_add(json_paths, json_path);
9512 } else {
9513 vty_out(vty, "\n");
9514
9515 if (safi == SAFI_EVPN) {
9516 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9517 /* XXX - add these params to the json out */
9518 vty_out(vty, "%*s", 20, " ");
9519 vty_out(vty, "ESI:%s",
9520 esi_to_str(&attr->esi, esi_buf,
9521 sizeof(esi_buf)));
9522
9523 vty_out(vty, "\n");
9524 }
9525 if (attr->flag &
9526 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9527 vty_out(vty, "%*s", 20, " ");
9528 vty_out(vty, "%s\n",
9529 bgp_attr_get_ecommunity(attr)->str);
9530 }
9531 }
9532
9533 #ifdef ENABLE_BGP_VNC
9534 /* prints an additional line, indented, with VNC info, if
9535 * present */
9536 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9537 rfapi_vty_out_vncinfo(vty, p, path, safi);
9538 #endif
9539 }
9540 }
9541
9542 /* called from terminal list command */
9543 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9544 const struct prefix *p, struct attr *attr, safi_t safi,
9545 bool use_json, json_object *json_ar, bool wide)
9546 {
9547 json_object *json_status = NULL;
9548 json_object *json_net = NULL;
9549 int len;
9550 char buff[BUFSIZ];
9551
9552 /* Route status display. */
9553 if (use_json) {
9554 json_status = json_object_new_object();
9555 json_net = json_object_new_object();
9556 } else {
9557 vty_out(vty, " *");
9558 vty_out(vty, ">");
9559 vty_out(vty, " ");
9560 }
9561
9562 /* print prefix and mask */
9563 if (use_json) {
9564 if (safi == SAFI_EVPN)
9565 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9566 else if (p->family == AF_INET || p->family == AF_INET6) {
9567 json_object_string_add(
9568 json_net, "addrPrefix",
9569 inet_ntop(p->family, &p->u.prefix, buff,
9570 BUFSIZ));
9571 json_object_int_add(json_net, "prefixLen",
9572 p->prefixlen);
9573 json_object_string_addf(json_net, "network", "%pFX", p);
9574 }
9575 } else
9576 route_vty_out_route(dest, p, vty, NULL, wide);
9577
9578 /* Print attribute */
9579 if (attr) {
9580 if (use_json) {
9581 if (p->family == AF_INET &&
9582 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9583 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9584 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9585 json_object_string_addf(
9586 json_net, "nextHop", "%pI4",
9587 &attr->mp_nexthop_global_in);
9588 else
9589 json_object_string_addf(
9590 json_net, "nextHop", "%pI4",
9591 &attr->nexthop);
9592 } else if (p->family == AF_INET6 ||
9593 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9594 json_object_string_addf(
9595 json_net, "nextHopGlobal", "%pI6",
9596 &attr->mp_nexthop_global);
9597 } else if (p->family == AF_EVPN &&
9598 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9599 json_object_string_addf(
9600 json_net, "nextHop", "%pI4",
9601 &attr->mp_nexthop_global_in);
9602 }
9603
9604 if (attr->flag
9605 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9606 json_object_int_add(json_net, "metric",
9607 attr->med);
9608
9609 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9610 json_object_int_add(json_net, "locPrf",
9611 attr->local_pref);
9612
9613 json_object_int_add(json_net, "weight", attr->weight);
9614
9615 /* Print aspath */
9616 if (attr->aspath)
9617 json_object_string_add(json_net, "path",
9618 attr->aspath->str);
9619
9620 /* Print origin */
9621 #if CONFDATE > 20231208
9622 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
9623 #endif
9624 json_object_string_add(json_net, "bgpOriginCode",
9625 bgp_origin_str[attr->origin]);
9626 json_object_string_add(
9627 json_net, "origin",
9628 bgp_origin_long_str[attr->origin]);
9629 } else {
9630 if (p->family == AF_INET &&
9631 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9632 safi == SAFI_EVPN ||
9633 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9634 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9635 || safi == SAFI_EVPN)
9636 vty_out(vty, "%-16pI4",
9637 &attr->mp_nexthop_global_in);
9638 else if (wide)
9639 vty_out(vty, "%-41pI4", &attr->nexthop);
9640 else
9641 vty_out(vty, "%-16pI4", &attr->nexthop);
9642 } else if (p->family == AF_INET6 ||
9643 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9644 len = vty_out(vty, "%pI6",
9645 &attr->mp_nexthop_global);
9646 len = wide ? (41 - len) : (16 - len);
9647 if (len < 1)
9648 vty_out(vty, "\n%*s", 36, " ");
9649 else
9650 vty_out(vty, "%*s", len, " ");
9651 }
9652 if (attr->flag
9653 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9654 if (wide)
9655 vty_out(vty, "%7u", attr->med);
9656 else
9657 vty_out(vty, "%10u", attr->med);
9658 else if (wide)
9659 vty_out(vty, " ");
9660 else
9661 vty_out(vty, " ");
9662
9663 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9664 vty_out(vty, "%7u", attr->local_pref);
9665 else
9666 vty_out(vty, " ");
9667
9668 vty_out(vty, "%7u ", attr->weight);
9669
9670 /* Print aspath */
9671 if (attr->aspath)
9672 aspath_print_vty(vty, attr->aspath);
9673
9674 /* Print origin */
9675 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9676 }
9677 }
9678 if (use_json) {
9679 struct bgp_path_info *bpi = bgp_dest_get_bgp_path_info(dest);
9680
9681 #if CONFDATE > 20231208
9682 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
9683 #endif
9684 json_object_boolean_true_add(json_status, "*");
9685 json_object_boolean_true_add(json_status, ">");
9686 json_object_boolean_true_add(json_net, "valid");
9687 json_object_boolean_true_add(json_net, "best");
9688
9689 if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_MULTIPATH)) {
9690 json_object_boolean_true_add(json_status, "=");
9691 json_object_boolean_true_add(json_net, "multipath");
9692 }
9693 json_object_object_add(json_net, "appliedStatusSymbols",
9694 json_status);
9695 json_object_object_addf(json_ar, json_net, "%pFX", p);
9696 } else
9697 vty_out(vty, "\n");
9698 }
9699
9700 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9701 struct bgp_path_info *path, int display, safi_t safi,
9702 json_object *json)
9703 {
9704 json_object *json_out = NULL;
9705 struct attr *attr;
9706 mpls_label_t label = MPLS_INVALID_LABEL;
9707
9708 if (!path->extra)
9709 return;
9710
9711 if (json)
9712 json_out = json_object_new_object();
9713
9714 /* short status lead text */
9715 route_vty_short_status_out(vty, path, p, json_out);
9716
9717 /* print prefix and mask */
9718 if (json == NULL) {
9719 if (!display)
9720 route_vty_out_route(path->net, p, vty, NULL, false);
9721 else
9722 vty_out(vty, "%*s", 17, " ");
9723 }
9724
9725 /* Print attribute */
9726 attr = path->attr;
9727 if (((p->family == AF_INET) &&
9728 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9729 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9730 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9731 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9732 || safi == SAFI_EVPN) {
9733 if (json)
9734 json_object_string_addf(
9735 json_out, "mpNexthopGlobalIn", "%pI4",
9736 &attr->mp_nexthop_global_in);
9737 else
9738 vty_out(vty, "%-16pI4",
9739 &attr->mp_nexthop_global_in);
9740 } else {
9741 if (json)
9742 json_object_string_addf(json_out, "nexthop",
9743 "%pI4", &attr->nexthop);
9744 else
9745 vty_out(vty, "%-16pI4", &attr->nexthop);
9746 }
9747 } else if (((p->family == AF_INET6) &&
9748 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9749 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9750 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9751 char buf_a[512];
9752
9753 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9754 if (json)
9755 json_object_string_addf(
9756 json_out, "mpNexthopGlobalIn", "%pI6",
9757 &attr->mp_nexthop_global);
9758 else
9759 vty_out(vty, "%s",
9760 inet_ntop(AF_INET6,
9761 &attr->mp_nexthop_global,
9762 buf_a, sizeof(buf_a)));
9763 } else if (attr->mp_nexthop_len
9764 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9765 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9766 &attr->mp_nexthop_global,
9767 &attr->mp_nexthop_local);
9768 if (json)
9769 json_object_string_add(json_out,
9770 "mpNexthopGlobalLocal",
9771 buf_a);
9772 else
9773 vty_out(vty, "%s", buf_a);
9774 }
9775 }
9776
9777 label = decode_label(&path->extra->label[0]);
9778
9779 if (bgp_is_valid_label(&label)) {
9780 if (json) {
9781 json_object_int_add(json_out, "notag", label);
9782 json_object_array_add(json, json_out);
9783 } else {
9784 vty_out(vty, "notag/%d", label);
9785 vty_out(vty, "\n");
9786 }
9787 } else if (!json)
9788 vty_out(vty, "\n");
9789 }
9790
9791 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9792 struct bgp_path_info *path, int display,
9793 json_object *json_paths)
9794 {
9795 struct attr *attr;
9796 json_object *json_path = NULL;
9797 json_object *json_nexthop = NULL;
9798 json_object *json_overlay = NULL;
9799
9800 if (!path->extra)
9801 return;
9802
9803 if (json_paths) {
9804 json_path = json_object_new_object();
9805 json_overlay = json_object_new_object();
9806 json_nexthop = json_object_new_object();
9807 }
9808
9809 /* short status lead text */
9810 route_vty_short_status_out(vty, path, p, json_path);
9811
9812 /* print prefix and mask */
9813 if (!display)
9814 route_vty_out_route(path->net, p, vty, json_path, false);
9815 else
9816 vty_out(vty, "%*s", 17, " ");
9817
9818 /* Print attribute */
9819 attr = path->attr;
9820 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9821
9822 switch (af) {
9823 case AF_INET:
9824 if (!json_path) {
9825 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9826 } else {
9827 json_object_string_addf(json_nexthop, "ip", "%pI4",
9828 &attr->mp_nexthop_global_in);
9829
9830 json_object_string_add(json_nexthop, "afi", "ipv4");
9831
9832 json_object_object_add(json_path, "nexthop",
9833 json_nexthop);
9834 }
9835 break;
9836 case AF_INET6:
9837 if (!json_path) {
9838 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9839 &attr->mp_nexthop_local);
9840 } else {
9841 json_object_string_addf(json_nexthop, "ipv6Global",
9842 "%pI6",
9843 &attr->mp_nexthop_global);
9844
9845 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9846 "%pI6",
9847 &attr->mp_nexthop_local);
9848
9849 json_object_string_add(json_nexthop, "afi", "ipv6");
9850
9851 json_object_object_add(json_path, "nexthop",
9852 json_nexthop);
9853 }
9854 break;
9855 default:
9856 if (!json_path) {
9857 vty_out(vty, "?");
9858 } else {
9859 json_object_string_add(json_nexthop, "error",
9860 "Unsupported address-family");
9861 }
9862 }
9863
9864 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9865
9866 if (!json_path)
9867 vty_out(vty, "/%pIA", &eo->gw_ip);
9868 else
9869 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9870
9871 if (bgp_attr_get_ecommunity(attr)) {
9872 char *mac = NULL;
9873 struct ecommunity_val *routermac = ecommunity_lookup(
9874 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9875 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9876
9877 if (routermac)
9878 mac = ecom_mac2str((char *)routermac->val);
9879 if (mac) {
9880 if (!json_path) {
9881 vty_out(vty, "/%s", mac);
9882 } else {
9883 json_object_string_add(json_overlay, "rmac",
9884 mac);
9885 }
9886 XFREE(MTYPE_TMP, mac);
9887 }
9888 }
9889
9890 if (!json_path) {
9891 vty_out(vty, "\n");
9892 } else {
9893 json_object_object_add(json_path, "overlay", json_overlay);
9894
9895 json_object_array_add(json_paths, json_path);
9896 }
9897 }
9898
9899 /* dampening route */
9900 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9901 struct bgp_path_info *path, int display,
9902 afi_t afi, safi_t safi, bool use_json,
9903 json_object *json_paths)
9904 {
9905 struct attr *attr = path->attr;
9906 int len;
9907 char timebuf[BGP_UPTIME_LEN];
9908 json_object *json_path = NULL;
9909
9910 if (use_json)
9911 json_path = json_object_new_object();
9912
9913 /* short status lead text */
9914 route_vty_short_status_out(vty, path, p, json_path);
9915
9916 /* print prefix and mask */
9917 if (!use_json) {
9918 if (!display)
9919 route_vty_out_route(path->net, p, vty, NULL, false);
9920 else
9921 vty_out(vty, "%*s", 17, " ");
9922
9923 len = vty_out(vty, "%s", path->peer->host);
9924 len = 17 - len;
9925
9926 if (len < 1)
9927 vty_out(vty, "\n%*s", 34, " ");
9928 else
9929 vty_out(vty, "%*s", len, " ");
9930
9931 vty_out(vty, "%s ",
9932 bgp_damp_reuse_time_vty(vty, path, timebuf,
9933 BGP_UPTIME_LEN, afi, safi,
9934 use_json, NULL));
9935
9936 if (attr->aspath)
9937 aspath_print_vty(vty, attr->aspath);
9938
9939 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9940
9941 vty_out(vty, "\n");
9942 } else {
9943 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9944 safi, use_json, json_path);
9945
9946 if (attr->aspath)
9947 json_object_string_add(json_path, "asPath",
9948 attr->aspath->str);
9949
9950 json_object_string_add(json_path, "origin",
9951 bgp_origin_str[attr->origin]);
9952 json_object_string_add(json_path, "peerHost", path->peer->host);
9953
9954 json_object_array_add(json_paths, json_path);
9955 }
9956 }
9957
9958 /* flap route */
9959 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9960 struct bgp_path_info *path, int display,
9961 afi_t afi, safi_t safi, bool use_json,
9962 json_object *json_paths)
9963 {
9964 struct attr *attr = path->attr;
9965 struct bgp_damp_info *bdi;
9966 char timebuf[BGP_UPTIME_LEN];
9967 int len;
9968 json_object *json_path = NULL;
9969
9970 if (!path->extra)
9971 return;
9972
9973 if (use_json)
9974 json_path = json_object_new_object();
9975
9976 bdi = path->extra->damp_info;
9977
9978 /* short status lead text */
9979 route_vty_short_status_out(vty, path, p, json_path);
9980
9981 if (!use_json) {
9982 if (!display)
9983 route_vty_out_route(path->net, p, vty, NULL, false);
9984 else
9985 vty_out(vty, "%*s", 17, " ");
9986
9987 len = vty_out(vty, "%s", path->peer->host);
9988 len = 16 - len;
9989 if (len < 1)
9990 vty_out(vty, "\n%*s", 33, " ");
9991 else
9992 vty_out(vty, "%*s", len, " ");
9993
9994 len = vty_out(vty, "%d", bdi->flap);
9995 len = 5 - len;
9996 if (len < 1)
9997 vty_out(vty, " ");
9998 else
9999 vty_out(vty, "%*s", len, " ");
10000
10001 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10002 BGP_UPTIME_LEN, 0, NULL));
10003
10004 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10005 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10006 vty_out(vty, "%s ",
10007 bgp_damp_reuse_time_vty(vty, path, timebuf,
10008 BGP_UPTIME_LEN, afi,
10009 safi, use_json, NULL));
10010 else
10011 vty_out(vty, "%*s ", 8, " ");
10012
10013 if (attr->aspath)
10014 aspath_print_vty(vty, attr->aspath);
10015
10016 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10017
10018 vty_out(vty, "\n");
10019 } else {
10020 json_object_string_add(json_path, "peerHost", path->peer->host);
10021 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10022
10023 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10024 json_path);
10025
10026 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10027 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10028 bgp_damp_reuse_time_vty(vty, path, timebuf,
10029 BGP_UPTIME_LEN, afi, safi,
10030 use_json, json_path);
10031
10032 if (attr->aspath)
10033 json_object_string_add(json_path, "asPath",
10034 attr->aspath->str);
10035
10036 json_object_string_add(json_path, "origin",
10037 bgp_origin_str[attr->origin]);
10038
10039 json_object_array_add(json_paths, json_path);
10040 }
10041 }
10042
10043 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10044 int *first, const char *header,
10045 json_object *json_adv_to)
10046 {
10047 json_object *json_peer = NULL;
10048
10049 if (json_adv_to) {
10050 /* 'advertised-to' is a dictionary of peers we have advertised
10051 * this
10052 * prefix too. The key is the peer's IP or swpX, the value is
10053 * the
10054 * hostname if we know it and "" if not.
10055 */
10056 json_peer = json_object_new_object();
10057
10058 if (peer->hostname)
10059 json_object_string_add(json_peer, "hostname",
10060 peer->hostname);
10061
10062 if (peer->conf_if)
10063 json_object_object_add(json_adv_to, peer->conf_if,
10064 json_peer);
10065 else
10066 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10067 &peer->su);
10068 } else {
10069 if (*first) {
10070 vty_out(vty, "%s", header);
10071 *first = 0;
10072 }
10073
10074 if (peer->hostname
10075 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10076 if (peer->conf_if)
10077 vty_out(vty, " %s(%s)", peer->hostname,
10078 peer->conf_if);
10079 else
10080 vty_out(vty, " %s(%pSU)", peer->hostname,
10081 &peer->su);
10082 } else {
10083 if (peer->conf_if)
10084 vty_out(vty, " %s", peer->conf_if);
10085 else
10086 vty_out(vty, " %pSU", &peer->su);
10087 }
10088 }
10089 }
10090
10091 static void route_vty_out_tx_ids(struct vty *vty,
10092 struct bgp_addpath_info_data *d)
10093 {
10094 int i;
10095
10096 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10097 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10098 d->addpath_tx_id[i],
10099 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10100 }
10101 }
10102
10103 static void route_vty_out_detail_es_info(struct vty *vty,
10104 struct bgp_path_info *pi,
10105 struct attr *attr,
10106 json_object *json_path)
10107 {
10108 char esi_buf[ESI_STR_LEN];
10109 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10110 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10111 ATTR_ES_PEER_ROUTER);
10112 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10113 ATTR_ES_PEER_ACTIVE);
10114 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10115 ATTR_ES_PEER_PROXY);
10116 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10117 if (json_path) {
10118 json_object *json_es_info = NULL;
10119
10120 json_object_string_add(
10121 json_path, "esi",
10122 esi_buf);
10123 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10124 json_es_info = json_object_new_object();
10125 if (es_local)
10126 json_object_boolean_true_add(
10127 json_es_info, "localEs");
10128 if (peer_active)
10129 json_object_boolean_true_add(
10130 json_es_info, "peerActive");
10131 if (peer_proxy)
10132 json_object_boolean_true_add(
10133 json_es_info, "peerProxy");
10134 if (peer_router)
10135 json_object_boolean_true_add(
10136 json_es_info, "peerRouter");
10137 if (attr->mm_sync_seqnum)
10138 json_object_int_add(
10139 json_es_info, "peerSeq",
10140 attr->mm_sync_seqnum);
10141 json_object_object_add(
10142 json_path, "es_info",
10143 json_es_info);
10144 }
10145 } else {
10146 if (bgp_evpn_attr_is_sync(attr))
10147 vty_out(vty,
10148 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10149 esi_buf,
10150 es_local ? "local-es":"",
10151 peer_proxy ? "proxy " : "",
10152 peer_active ? "active ":"",
10153 peer_router ? "router ":"",
10154 attr->mm_sync_seqnum);
10155 else
10156 vty_out(vty, " ESI %s %s\n",
10157 esi_buf,
10158 es_local ? "local-es":"");
10159 }
10160 }
10161
10162 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10163 const struct prefix *p, struct bgp_path_info *path,
10164 afi_t afi, safi_t safi,
10165 enum rpki_states rpki_curr_state,
10166 json_object *json_paths)
10167 {
10168 char buf[INET6_ADDRSTRLEN];
10169 char tag_buf[30];
10170 struct attr *attr = path->attr;
10171 time_t tbuf;
10172 json_object *json_bestpath = NULL;
10173 json_object *json_cluster_list = NULL;
10174 json_object *json_cluster_list_list = NULL;
10175 json_object *json_ext_community = NULL;
10176 json_object *json_last_update = NULL;
10177 json_object *json_pmsi = NULL;
10178 json_object *json_nexthop_global = NULL;
10179 json_object *json_nexthop_ll = NULL;
10180 json_object *json_nexthops = NULL;
10181 json_object *json_path = NULL;
10182 json_object *json_peer = NULL;
10183 json_object *json_string = NULL;
10184 json_object *json_adv_to = NULL;
10185 int first = 0;
10186 struct listnode *node, *nnode;
10187 struct peer *peer;
10188 bool addpath_capable;
10189 int has_adj;
10190 unsigned int first_as;
10191 bool nexthop_self =
10192 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10193 int i;
10194 char *nexthop_hostname =
10195 bgp_nexthop_hostname(path->peer, path->nexthop);
10196 uint32_t ttl = 0;
10197 uint32_t bos = 0;
10198 uint32_t exp = 0;
10199 mpls_label_t label = MPLS_INVALID_LABEL;
10200 tag_buf[0] = '\0';
10201 struct bgp_path_info *bpi_ultimate =
10202 bgp_get_imported_bpi_ultimate(path);
10203
10204 if (json_paths) {
10205 json_path = json_object_new_object();
10206 json_peer = json_object_new_object();
10207 json_nexthop_global = json_object_new_object();
10208 }
10209
10210 if (safi == SAFI_EVPN) {
10211 if (!json_paths)
10212 vty_out(vty, " Route %pFX", p);
10213 }
10214
10215 if (path->extra) {
10216 if (path->extra && path->extra->num_labels) {
10217 bgp_evpn_label2str(path->extra->label,
10218 path->extra->num_labels, tag_buf,
10219 sizeof(tag_buf));
10220 }
10221 if (safi == SAFI_EVPN) {
10222 if (!json_paths) {
10223 if (tag_buf[0] != '\0')
10224 vty_out(vty, " VNI %s", tag_buf);
10225 } else {
10226 if (tag_buf[0])
10227 json_object_string_add(json_path, "vni",
10228 tag_buf);
10229 }
10230 }
10231 }
10232
10233 if (safi == SAFI_EVPN
10234 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10235 char gwip_buf[INET6_ADDRSTRLEN];
10236
10237 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10238 sizeof(gwip_buf));
10239
10240 if (json_paths)
10241 json_object_string_add(json_path, "gatewayIP",
10242 gwip_buf);
10243 else
10244 vty_out(vty, " Gateway IP %s", gwip_buf);
10245 }
10246
10247 if (safi == SAFI_EVPN && !json_path)
10248 vty_out(vty, "\n");
10249
10250
10251 if (path->extra && path->extra->parent && !json_paths) {
10252 struct bgp_path_info *parent_ri;
10253 struct bgp_dest *dest, *pdest;
10254
10255 parent_ri = (struct bgp_path_info *)path->extra->parent;
10256 dest = parent_ri->net;
10257 if (dest && dest->pdest) {
10258 pdest = dest->pdest;
10259 if (is_pi_family_evpn(parent_ri)) {
10260 vty_out(vty,
10261 " Imported from %pRD:%pFX, VNI %s",
10262 (struct prefix_rd *)bgp_dest_get_prefix(
10263 pdest),
10264 (struct prefix_evpn *)
10265 bgp_dest_get_prefix(dest),
10266 tag_buf);
10267 if (CHECK_FLAG(attr->es_flags, ATTR_ES_L3_NHG))
10268 vty_out(vty, ", L3NHG %s",
10269 CHECK_FLAG(
10270 attr->es_flags,
10271 ATTR_ES_L3_NHG_ACTIVE)
10272 ? "active"
10273 : "inactive");
10274 vty_out(vty, "\n");
10275
10276 } else
10277 vty_out(vty, " Imported from %pRD:%pFX\n",
10278 (struct prefix_rd *)bgp_dest_get_prefix(
10279 pdest),
10280 (struct prefix_evpn *)
10281 bgp_dest_get_prefix(dest));
10282 }
10283 }
10284
10285 /* Line1 display AS-path, Aggregator */
10286 if (attr->aspath) {
10287 if (json_paths) {
10288 if (!attr->aspath->json)
10289 aspath_str_update(attr->aspath, true);
10290 json_object_lock(attr->aspath->json);
10291 json_object_object_add(json_path, "aspath",
10292 attr->aspath->json);
10293 } else {
10294 if (attr->aspath->segments)
10295 vty_out(vty, " %s", attr->aspath->str);
10296 else
10297 vty_out(vty, " Local");
10298 }
10299 }
10300
10301 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10302 if (json_paths)
10303 json_object_boolean_true_add(json_path, "removed");
10304 else
10305 vty_out(vty, ", (removed)");
10306 }
10307
10308 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10309 if (json_paths)
10310 json_object_boolean_true_add(json_path, "stale");
10311 else
10312 vty_out(vty, ", (stale)");
10313 }
10314
10315 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10316 if (json_paths) {
10317 json_object_int_add(json_path, "aggregatorAs",
10318 attr->aggregator_as);
10319 json_object_string_addf(json_path, "aggregatorId",
10320 "%pI4", &attr->aggregator_addr);
10321 } else {
10322 vty_out(vty, ", (aggregated by %u %pI4)",
10323 attr->aggregator_as, &attr->aggregator_addr);
10324 }
10325 }
10326
10327 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10328 PEER_FLAG_REFLECTOR_CLIENT)) {
10329 if (json_paths)
10330 json_object_boolean_true_add(json_path,
10331 "rxedFromRrClient");
10332 else
10333 vty_out(vty, ", (Received from a RR-client)");
10334 }
10335
10336 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10337 PEER_FLAG_RSERVER_CLIENT)) {
10338 if (json_paths)
10339 json_object_boolean_true_add(json_path,
10340 "rxedFromRsClient");
10341 else
10342 vty_out(vty, ", (Received from a RS-client)");
10343 }
10344
10345 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10346 if (json_paths)
10347 json_object_boolean_true_add(json_path,
10348 "dampeningHistoryEntry");
10349 else
10350 vty_out(vty, ", (history entry)");
10351 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10352 if (json_paths)
10353 json_object_boolean_true_add(json_path,
10354 "dampeningSuppressed");
10355 else
10356 vty_out(vty, ", (suppressed due to dampening)");
10357 }
10358
10359 if (!json_paths)
10360 vty_out(vty, "\n");
10361
10362 /* Line2 display Next-hop, Neighbor, Router-id */
10363 /* Display the nexthop */
10364
10365 if ((p->family == AF_INET || p->family == AF_ETHERNET ||
10366 p->family == AF_EVPN) &&
10367 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10368 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10369 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10370 || safi == SAFI_EVPN) {
10371 if (json_paths) {
10372 json_object_string_addf(
10373 json_nexthop_global, "ip", "%pI4",
10374 &attr->mp_nexthop_global_in);
10375
10376 if (path->peer->hostname)
10377 json_object_string_add(
10378 json_nexthop_global, "hostname",
10379 path->peer->hostname);
10380 } else {
10381 if (nexthop_hostname)
10382 vty_out(vty, " %pI4(%s)",
10383 &attr->mp_nexthop_global_in,
10384 nexthop_hostname);
10385 else
10386 vty_out(vty, " %pI4",
10387 &attr->mp_nexthop_global_in);
10388 }
10389 } else {
10390 if (json_paths) {
10391 json_object_string_addf(json_nexthop_global,
10392 "ip", "%pI4",
10393 &attr->nexthop);
10394
10395 if (path->peer->hostname)
10396 json_object_string_add(
10397 json_nexthop_global, "hostname",
10398 path->peer->hostname);
10399 } else {
10400 if (nexthop_hostname)
10401 vty_out(vty, " %pI4(%s)",
10402 &attr->nexthop,
10403 nexthop_hostname);
10404 else
10405 vty_out(vty, " %pI4",
10406 &attr->nexthop);
10407 }
10408 }
10409
10410 if (json_paths)
10411 json_object_string_add(json_nexthop_global, "afi",
10412 "ipv4");
10413 } else {
10414 if (json_paths) {
10415 json_object_string_addf(json_nexthop_global, "ip",
10416 "%pI6",
10417 &attr->mp_nexthop_global);
10418
10419 if (path->peer->hostname)
10420 json_object_string_add(json_nexthop_global,
10421 "hostname",
10422 path->peer->hostname);
10423
10424 json_object_string_add(json_nexthop_global, "afi",
10425 "ipv6");
10426 json_object_string_add(json_nexthop_global, "scope",
10427 "global");
10428 } else {
10429 if (nexthop_hostname)
10430 vty_out(vty, " %pI6(%s)",
10431 &attr->mp_nexthop_global,
10432 nexthop_hostname);
10433 else
10434 vty_out(vty, " %pI6",
10435 &attr->mp_nexthop_global);
10436 }
10437 }
10438
10439 /* Display the IGP cost or 'inaccessible' */
10440 if (!CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_VALID)) {
10441 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10442
10443 if (json_paths) {
10444 json_object_boolean_false_add(json_nexthop_global,
10445 "accessible");
10446 json_object_boolean_add(json_nexthop_global,
10447 "importCheckEnabled", import);
10448 } else {
10449 vty_out(vty, " (inaccessible%s)",
10450 import ? ", import-check enabled" : "");
10451 }
10452 } else {
10453 if (bpi_ultimate->extra && bpi_ultimate->extra->igpmetric) {
10454 if (json_paths)
10455 json_object_int_add(
10456 json_nexthop_global, "metric",
10457 bpi_ultimate->extra->igpmetric);
10458 else
10459 vty_out(vty, " (metric %u)",
10460 bpi_ultimate->extra->igpmetric);
10461 }
10462
10463 /* IGP cost is 0, display this only for json */
10464 else {
10465 if (json_paths)
10466 json_object_int_add(json_nexthop_global,
10467 "metric", 0);
10468 }
10469
10470 if (json_paths)
10471 json_object_boolean_true_add(json_nexthop_global,
10472 "accessible");
10473 }
10474
10475 /* Display peer "from" output */
10476 /* This path was originated locally */
10477 if (path->peer == bgp->peer_self) {
10478
10479 if (safi == SAFI_EVPN || (p->family == AF_INET &&
10480 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10481 if (json_paths)
10482 json_object_string_add(json_peer, "peerId",
10483 "0.0.0.0");
10484 else
10485 vty_out(vty, " from 0.0.0.0 ");
10486 } else {
10487 if (json_paths)
10488 json_object_string_add(json_peer, "peerId",
10489 "::");
10490 else
10491 vty_out(vty, " from :: ");
10492 }
10493
10494 if (json_paths)
10495 json_object_string_addf(json_peer, "routerId", "%pI4",
10496 &bgp->router_id);
10497 else
10498 vty_out(vty, "(%pI4)", &bgp->router_id);
10499 }
10500
10501 /* We RXed this path from one of our peers */
10502 else {
10503
10504 if (json_paths) {
10505 json_object_string_addf(json_peer, "peerId", "%pSU",
10506 &path->peer->su);
10507 json_object_string_addf(json_peer, "routerId", "%pI4",
10508 &path->peer->remote_id);
10509
10510 if (path->peer->hostname)
10511 json_object_string_add(json_peer, "hostname",
10512 path->peer->hostname);
10513
10514 if (path->peer->domainname)
10515 json_object_string_add(json_peer, "domainname",
10516 path->peer->domainname);
10517
10518 if (path->peer->conf_if)
10519 json_object_string_add(json_peer, "interface",
10520 path->peer->conf_if);
10521 } else {
10522 if (path->peer->conf_if) {
10523 if (path->peer->hostname
10524 && CHECK_FLAG(path->peer->bgp->flags,
10525 BGP_FLAG_SHOW_HOSTNAME))
10526 vty_out(vty, " from %s(%s)",
10527 path->peer->hostname,
10528 path->peer->conf_if);
10529 else
10530 vty_out(vty, " from %s",
10531 path->peer->conf_if);
10532 } else {
10533 if (path->peer->hostname
10534 && CHECK_FLAG(path->peer->bgp->flags,
10535 BGP_FLAG_SHOW_HOSTNAME))
10536 vty_out(vty, " from %s(%s)",
10537 path->peer->hostname,
10538 path->peer->host);
10539 else
10540 vty_out(vty, " from %pSU",
10541 &path->peer->su);
10542 }
10543
10544 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10545 vty_out(vty, " (%pI4)", &attr->originator_id);
10546 else
10547 vty_out(vty, " (%pI4)", &path->peer->remote_id);
10548 }
10549 }
10550
10551 /*
10552 * Note when vrfid of nexthop is different from that of prefix
10553 */
10554 if (path->extra && path->extra->bgp_orig) {
10555 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10556
10557 if (json_paths) {
10558 const char *vn;
10559
10560 if (path->extra->bgp_orig->inst_type
10561 == BGP_INSTANCE_TYPE_DEFAULT)
10562 vn = VRF_DEFAULT_NAME;
10563 else
10564 vn = path->extra->bgp_orig->name;
10565
10566 json_object_string_add(json_path, "nhVrfName", vn);
10567
10568 if (nexthop_vrfid == VRF_UNKNOWN) {
10569 json_object_int_add(json_path, "nhVrfId", -1);
10570 } else {
10571 json_object_int_add(json_path, "nhVrfId",
10572 (int)nexthop_vrfid);
10573 }
10574 } else {
10575 if (nexthop_vrfid == VRF_UNKNOWN)
10576 vty_out(vty, " vrf ?");
10577 else {
10578 struct vrf *vrf;
10579
10580 vrf = vrf_lookup_by_id(nexthop_vrfid);
10581 vty_out(vty, " vrf %s(%u)",
10582 VRF_LOGNAME(vrf), nexthop_vrfid);
10583 }
10584 }
10585 }
10586
10587 if (nexthop_self) {
10588 if (json_paths) {
10589 json_object_boolean_true_add(json_path,
10590 "announceNexthopSelf");
10591 } else {
10592 vty_out(vty, " announce-nh-self");
10593 }
10594 }
10595
10596 if (!json_paths)
10597 vty_out(vty, "\n");
10598
10599 /* display the link-local nexthop */
10600 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10601 if (json_paths) {
10602 json_nexthop_ll = json_object_new_object();
10603 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10604 &attr->mp_nexthop_local);
10605
10606 if (path->peer->hostname)
10607 json_object_string_add(json_nexthop_ll,
10608 "hostname",
10609 path->peer->hostname);
10610
10611 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10612 json_object_string_add(json_nexthop_ll, "scope",
10613 "link-local");
10614
10615 json_object_boolean_true_add(json_nexthop_ll,
10616 "accessible");
10617
10618 if (!attr->mp_nexthop_prefer_global)
10619 json_object_boolean_true_add(json_nexthop_ll,
10620 "used");
10621 else
10622 json_object_boolean_true_add(
10623 json_nexthop_global, "used");
10624 } else {
10625 vty_out(vty, " (%s) %s\n",
10626 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10627 buf, INET6_ADDRSTRLEN),
10628 attr->mp_nexthop_prefer_global
10629 ? "(prefer-global)"
10630 : "(used)");
10631 }
10632 }
10633 /* If we do not have a link-local nexthop then we must flag the
10634 global as "used" */
10635 else {
10636 if (json_paths)
10637 json_object_boolean_true_add(json_nexthop_global,
10638 "used");
10639 }
10640
10641 if (safi == SAFI_EVPN &&
10642 bgp_evpn_is_esi_valid(&attr->esi)) {
10643 route_vty_out_detail_es_info(vty, path, attr, json_path);
10644 }
10645
10646 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10647 * Int/Ext/Local, Atomic, best */
10648 if (json_paths)
10649 json_object_string_add(json_path, "origin",
10650 bgp_origin_long_str[attr->origin]);
10651 else
10652 vty_out(vty, " Origin %s",
10653 bgp_origin_long_str[attr->origin]);
10654
10655 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10656 if (json_paths)
10657 json_object_int_add(json_path, "metric", attr->med);
10658 else
10659 vty_out(vty, ", metric %u", attr->med);
10660 }
10661
10662 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10663 if (json_paths)
10664 json_object_int_add(json_path, "locPrf",
10665 attr->local_pref);
10666 else
10667 vty_out(vty, ", localpref %u", attr->local_pref);
10668 }
10669
10670 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
10671 if (json_paths)
10672 json_object_int_add(json_path, "aigpMetric",
10673 bgp_attr_get_aigp_metric(attr));
10674 else
10675 vty_out(vty, ", aigp-metric %" PRIu64,
10676 bgp_attr_get_aigp_metric(attr));
10677 }
10678
10679 if (attr->weight != 0) {
10680 if (json_paths)
10681 json_object_int_add(json_path, "weight", attr->weight);
10682 else
10683 vty_out(vty, ", weight %u", attr->weight);
10684 }
10685
10686 if (attr->tag != 0) {
10687 if (json_paths)
10688 json_object_int_add(json_path, "tag", attr->tag);
10689 else
10690 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10691 }
10692
10693 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10694 if (json_paths)
10695 json_object_boolean_false_add(json_path, "valid");
10696 else
10697 vty_out(vty, ", invalid");
10698 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10699 if (json_paths)
10700 json_object_boolean_true_add(json_path, "valid");
10701 else
10702 vty_out(vty, ", valid");
10703 }
10704
10705 if (json_paths)
10706 json_object_int_add(json_path, "version", bn->version);
10707
10708 if (path->peer != bgp->peer_self) {
10709 if (path->peer->as == path->peer->local_as) {
10710 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10711 if (json_paths)
10712 json_object_string_add(
10713 json_peer, "type",
10714 "confed-internal");
10715 else
10716 vty_out(vty, ", confed-internal");
10717 } else {
10718 if (json_paths)
10719 json_object_string_add(
10720 json_peer, "type", "internal");
10721 else
10722 vty_out(vty, ", internal");
10723 }
10724 } else {
10725 if (bgp_confederation_peers_check(bgp,
10726 path->peer->as)) {
10727 if (json_paths)
10728 json_object_string_add(
10729 json_peer, "type",
10730 "confed-external");
10731 else
10732 vty_out(vty, ", confed-external");
10733 } else {
10734 if (json_paths)
10735 json_object_string_add(
10736 json_peer, "type", "external");
10737 else
10738 vty_out(vty, ", external");
10739 }
10740 }
10741 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10742 if (json_paths) {
10743 json_object_boolean_true_add(json_path, "aggregated");
10744 json_object_boolean_true_add(json_path, "local");
10745 } else {
10746 vty_out(vty, ", aggregated, local");
10747 }
10748 } else if (path->type != ZEBRA_ROUTE_BGP) {
10749 if (json_paths)
10750 json_object_boolean_true_add(json_path, "sourced");
10751 else
10752 vty_out(vty, ", sourced");
10753 } else {
10754 if (json_paths) {
10755 json_object_boolean_true_add(json_path, "sourced");
10756 json_object_boolean_true_add(json_path, "local");
10757 } else {
10758 vty_out(vty, ", sourced, local");
10759 }
10760 }
10761
10762 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10763 if (json_paths)
10764 json_object_boolean_true_add(json_path,
10765 "atomicAggregate");
10766 else
10767 vty_out(vty, ", atomic-aggregate");
10768 }
10769
10770 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10771 if (json_paths)
10772 json_object_int_add(json_path, "otc", attr->otc);
10773 else
10774 vty_out(vty, ", otc %u", attr->otc);
10775 }
10776
10777 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10778 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10779 && bgp_path_info_mpath_count(path))) {
10780 if (json_paths)
10781 json_object_boolean_true_add(json_path, "multipath");
10782 else
10783 vty_out(vty, ", multipath");
10784 }
10785
10786 // Mark the bestpath(s)
10787 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10788 first_as = aspath_get_first_as(attr->aspath);
10789
10790 if (json_paths) {
10791 if (!json_bestpath)
10792 json_bestpath = json_object_new_object();
10793 json_object_int_add(json_bestpath, "bestpathFromAs",
10794 first_as);
10795 } else {
10796 if (first_as)
10797 vty_out(vty, ", bestpath-from-AS %u", first_as);
10798 else
10799 vty_out(vty, ", bestpath-from-AS Local");
10800 }
10801 }
10802
10803 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10804 if (json_paths) {
10805 if (!json_bestpath)
10806 json_bestpath = json_object_new_object();
10807 json_object_boolean_true_add(json_bestpath, "overall");
10808 json_object_string_add(
10809 json_bestpath, "selectionReason",
10810 bgp_path_selection_reason2str(bn->reason));
10811 } else {
10812 vty_out(vty, ", best");
10813 vty_out(vty, " (%s)",
10814 bgp_path_selection_reason2str(bn->reason));
10815 }
10816 }
10817
10818 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10819 if (json_paths)
10820 json_object_string_add(
10821 json_path, "rpkiValidationState",
10822 bgp_rpki_validation2str(rpki_curr_state));
10823 else
10824 vty_out(vty, ", rpki validation-state: %s",
10825 bgp_rpki_validation2str(rpki_curr_state));
10826 }
10827
10828 if (json_bestpath)
10829 json_object_object_add(json_path, "bestpath", json_bestpath);
10830
10831 if (!json_paths)
10832 vty_out(vty, "\n");
10833
10834 /* Line 4 display Community */
10835 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10836 if (json_paths) {
10837 if (!bgp_attr_get_community(attr)->json)
10838 community_str(bgp_attr_get_community(attr),
10839 true, true);
10840 json_object_lock(bgp_attr_get_community(attr)->json);
10841 json_object_object_add(
10842 json_path, "community",
10843 bgp_attr_get_community(attr)->json);
10844 } else {
10845 vty_out(vty, " Community: %s\n",
10846 bgp_attr_get_community(attr)->str);
10847 }
10848 }
10849
10850 /* Line 5 display Extended-community */
10851 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10852 if (json_paths) {
10853 json_ext_community = json_object_new_object();
10854 json_object_string_add(
10855 json_ext_community, "string",
10856 bgp_attr_get_ecommunity(attr)->str);
10857 json_object_object_add(json_path, "extendedCommunity",
10858 json_ext_community);
10859 } else {
10860 vty_out(vty, " Extended Community: %s\n",
10861 bgp_attr_get_ecommunity(attr)->str);
10862 }
10863 }
10864
10865 /* Line 6 display Large community */
10866 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10867 if (json_paths) {
10868 if (!bgp_attr_get_lcommunity(attr)->json)
10869 lcommunity_str(bgp_attr_get_lcommunity(attr),
10870 true, true);
10871 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10872 json_object_object_add(
10873 json_path, "largeCommunity",
10874 bgp_attr_get_lcommunity(attr)->json);
10875 } else {
10876 vty_out(vty, " Large Community: %s\n",
10877 bgp_attr_get_lcommunity(attr)->str);
10878 }
10879 }
10880
10881 /* Line 7 display Originator, Cluster-id */
10882 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10883 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10884 char buf[BUFSIZ] = {0};
10885
10886 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10887 if (json_paths)
10888 json_object_string_addf(json_path,
10889 "originatorId", "%pI4",
10890 &attr->originator_id);
10891 else
10892 vty_out(vty, " Originator: %pI4",
10893 &attr->originator_id);
10894 }
10895
10896 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10897 struct cluster_list *cluster =
10898 bgp_attr_get_cluster(attr);
10899 int i;
10900
10901 if (json_paths) {
10902 json_cluster_list = json_object_new_object();
10903 json_cluster_list_list =
10904 json_object_new_array();
10905
10906 for (i = 0; i < cluster->length / 4; i++) {
10907 json_string = json_object_new_string(
10908 inet_ntop(AF_INET,
10909 &cluster->list[i],
10910 buf, sizeof(buf)));
10911 json_object_array_add(
10912 json_cluster_list_list,
10913 json_string);
10914 }
10915
10916 /*
10917 * struct cluster_list does not have
10918 * "str" variable like aspath and community
10919 * do. Add this someday if someone asks
10920 * for it.
10921 * json_object_string_add(json_cluster_list,
10922 * "string", cluster->str);
10923 */
10924 json_object_object_add(json_cluster_list,
10925 "list",
10926 json_cluster_list_list);
10927 json_object_object_add(json_path, "clusterList",
10928 json_cluster_list);
10929 } else {
10930 vty_out(vty, ", Cluster list: ");
10931
10932 for (i = 0; i < cluster->length / 4; i++) {
10933 vty_out(vty, "%pI4 ",
10934 &cluster->list[i]);
10935 }
10936 }
10937 }
10938
10939 if (!json_paths)
10940 vty_out(vty, "\n");
10941 }
10942
10943 if (path->extra && path->extra->damp_info)
10944 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10945
10946 /* Remote Label */
10947 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10948 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10949 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
10950 &bos);
10951
10952 if (json_paths)
10953 json_object_int_add(json_path, "remoteLabel", label);
10954 else
10955 vty_out(vty, " Remote label: %d\n", label);
10956 }
10957
10958 /* Remote SID */
10959 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10960 if (json_paths)
10961 json_object_string_addf(json_path, "remoteSid", "%pI6",
10962 &path->extra->sid[0].sid);
10963 else
10964 vty_out(vty, " Remote SID: %pI6\n",
10965 &path->extra->sid[0].sid);
10966 }
10967
10968 /* Label Index */
10969 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10970 if (json_paths)
10971 json_object_int_add(json_path, "labelIndex",
10972 attr->label_index);
10973 else
10974 vty_out(vty, " Label Index: %d\n",
10975 attr->label_index);
10976 }
10977
10978 /* Line 8 display Addpath IDs */
10979 if (path->addpath_rx_id
10980 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
10981 if (json_paths) {
10982 json_object_int_add(json_path, "addpathRxId",
10983 path->addpath_rx_id);
10984
10985 /* Keep backwards compatibility with the old API
10986 * by putting TX All's ID in the old field
10987 */
10988 json_object_int_add(
10989 json_path, "addpathTxId",
10990 path->tx_addpath
10991 .addpath_tx_id[BGP_ADDPATH_ALL]);
10992
10993 /* ... but create a specific field for each
10994 * strategy
10995 */
10996 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10997 json_object_int_add(
10998 json_path,
10999 bgp_addpath_names(i)->id_json_name,
11000 path->tx_addpath.addpath_tx_id[i]);
11001 }
11002 } else {
11003 vty_out(vty, " AddPath ID: RX %u, ",
11004 path->addpath_rx_id);
11005
11006 route_vty_out_tx_ids(vty, &path->tx_addpath);
11007 }
11008 }
11009
11010 /* If we used addpath to TX a non-bestpath we need to display
11011 * "Advertised to" on a path-by-path basis
11012 */
11013 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11014 first = 1;
11015
11016 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11017 addpath_capable =
11018 bgp_addpath_encode_tx(peer, afi, safi);
11019 has_adj = bgp_adj_out_lookup(
11020 peer, path->net,
11021 bgp_addpath_id_for_peer(peer, afi, safi,
11022 &path->tx_addpath));
11023
11024 if ((addpath_capable && has_adj)
11025 || (!addpath_capable && has_adj
11026 && CHECK_FLAG(path->flags,
11027 BGP_PATH_SELECTED))) {
11028 if (json_path && !json_adv_to)
11029 json_adv_to = json_object_new_object();
11030
11031 route_vty_out_advertised_to(
11032 vty, peer, &first,
11033 " Advertised to:", json_adv_to);
11034 }
11035 }
11036
11037 if (json_path) {
11038 if (json_adv_to) {
11039 json_object_object_add(
11040 json_path, "advertisedTo", json_adv_to);
11041 }
11042 } else {
11043 if (!first) {
11044 vty_out(vty, "\n");
11045 }
11046 }
11047 }
11048
11049 /* Line 9 display Uptime */
11050 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11051 if (json_paths) {
11052 json_last_update = json_object_new_object();
11053 json_object_int_add(json_last_update, "epoch", tbuf);
11054 json_object_string_add(json_last_update, "string",
11055 ctime(&tbuf));
11056 json_object_object_add(json_path, "lastUpdate",
11057 json_last_update);
11058 } else
11059 vty_out(vty, " Last update: %s", ctime(&tbuf));
11060
11061 /* Line 10 display PMSI tunnel attribute, if present */
11062 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11063 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11064 bgp_attr_get_pmsi_tnl_type(attr),
11065 PMSI_TNLTYPE_STR_DEFAULT);
11066
11067 if (json_paths) {
11068 json_pmsi = json_object_new_object();
11069 json_object_string_add(json_pmsi, "tunnelType", str);
11070 json_object_int_add(json_pmsi, "label",
11071 label2vni(&attr->label));
11072 json_object_object_add(json_path, "pmsi", json_pmsi);
11073 } else
11074 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11075 str, label2vni(&attr->label));
11076 }
11077
11078 if (path->peer->t_gr_restart &&
11079 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11080 unsigned long gr_remaining =
11081 thread_timer_remain_second(path->peer->t_gr_restart);
11082
11083 if (json_paths) {
11084 json_object_int_add(json_path,
11085 "gracefulRestartSecondsRemaining",
11086 gr_remaining);
11087 } else
11088 vty_out(vty,
11089 " Time until Graceful Restart stale route deleted: %lu\n",
11090 gr_remaining);
11091 }
11092
11093 if (path->peer->t_llgr_stale[afi][safi] &&
11094 bgp_attr_get_community(attr) &&
11095 community_include(bgp_attr_get_community(attr),
11096 COMMUNITY_LLGR_STALE)) {
11097 unsigned long llgr_remaining = thread_timer_remain_second(
11098 path->peer->t_llgr_stale[afi][safi]);
11099
11100 if (json_paths) {
11101 json_object_int_add(json_path, "llgrSecondsRemaining",
11102 llgr_remaining);
11103 } else
11104 vty_out(vty,
11105 " Time until Long-lived stale route deleted: %lu\n",
11106 llgr_remaining);
11107 }
11108
11109 /* Output some debug about internal state of the dest flags */
11110 if (json_paths) {
11111 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11112 json_object_boolean_true_add(json_path, "processScheduled");
11113 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11114 json_object_boolean_true_add(json_path, "userCleared");
11115 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11116 json_object_boolean_true_add(json_path, "labelChanged");
11117 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11118 json_object_boolean_true_add(json_path, "registeredForLabel");
11119 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11120 json_object_boolean_true_add(json_path, "selectDefered");
11121 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11122 json_object_boolean_true_add(json_path, "fibInstalled");
11123 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11124 json_object_boolean_true_add(json_path, "fibPending");
11125
11126 if (json_nexthop_global || json_nexthop_ll) {
11127 json_nexthops = json_object_new_array();
11128
11129 if (json_nexthop_global)
11130 json_object_array_add(json_nexthops,
11131 json_nexthop_global);
11132
11133 if (json_nexthop_ll)
11134 json_object_array_add(json_nexthops,
11135 json_nexthop_ll);
11136
11137 json_object_object_add(json_path, "nexthops",
11138 json_nexthops);
11139 }
11140
11141 json_object_object_add(json_path, "peer", json_peer);
11142 json_object_array_add(json_paths, json_path);
11143 }
11144 }
11145
11146 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11147 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11148 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11149
11150 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11151 afi_t afi, safi_t safi, enum bgp_show_type type,
11152 bool use_json);
11153 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11154 const char *comstr, int exact, afi_t afi,
11155 safi_t safi, uint16_t show_flags);
11156
11157 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11158 struct bgp_table *table, enum bgp_show_type type,
11159 void *output_arg, const char *rd, int is_last,
11160 unsigned long *output_cum, unsigned long *total_cum,
11161 unsigned long *json_header_depth, uint16_t show_flags,
11162 enum rpki_states rpki_target_state)
11163 {
11164 struct bgp_path_info *pi;
11165 struct bgp_dest *dest;
11166 bool header = true;
11167 bool json_detail_header = false;
11168 int display;
11169 unsigned long output_count = 0;
11170 unsigned long total_count = 0;
11171 struct prefix *p;
11172 json_object *json_paths = NULL;
11173 int first = 1;
11174 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11175 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11176 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11177 bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
11178 bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
11179
11180 if (output_cum && *output_cum != 0)
11181 header = false;
11182
11183 if (use_json && !*json_header_depth) {
11184 if (all)
11185 *json_header_depth = 1;
11186 else {
11187 vty_out(vty, "{\n");
11188 *json_header_depth = 2;
11189 }
11190
11191 vty_out(vty,
11192 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11193 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11194 " \"localAS\": %u,\n \"routes\": { ",
11195 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11196 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11197 ? VRF_DEFAULT_NAME
11198 : bgp->name,
11199 table->version, &bgp->router_id,
11200 bgp->default_local_pref, bgp->as);
11201 if (rd) {
11202 vty_out(vty, " \"routeDistinguishers\" : {");
11203 ++*json_header_depth;
11204 }
11205 }
11206
11207 if (use_json && rd) {
11208 vty_out(vty, " \"%s\" : { ", rd);
11209 }
11210
11211 /* Check for 'json detail', where we need header output once per dest */
11212 if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
11213 type != bgp_show_type_damp_neighbor &&
11214 type != bgp_show_type_flap_statistics &&
11215 type != bgp_show_type_flap_neighbor)
11216 json_detail_header = true;
11217
11218 /* Start processing of routes. */
11219 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11220 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11221 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11222 bool json_detail = json_detail_header;
11223
11224 pi = bgp_dest_get_bgp_path_info(dest);
11225 if (pi == NULL)
11226 continue;
11227
11228 display = 0;
11229 if (use_json)
11230 json_paths = json_object_new_array();
11231 else
11232 json_paths = NULL;
11233
11234 for (; pi; pi = pi->next) {
11235 struct community *picomm = NULL;
11236
11237 picomm = bgp_attr_get_community(pi->attr);
11238
11239 total_count++;
11240
11241 if (type == bgp_show_type_prefix_version) {
11242 uint32_t version =
11243 strtoul(output_arg, NULL, 10);
11244 if (dest->version < version)
11245 continue;
11246 }
11247
11248 if (type == bgp_show_type_community_alias) {
11249 char *alias = output_arg;
11250 char **communities;
11251 int num;
11252 bool found = false;
11253
11254 if (picomm) {
11255 frrstr_split(picomm->str, " ",
11256 &communities, &num);
11257 for (int i = 0; i < num; i++) {
11258 const char *com2alias =
11259 bgp_community2alias(
11260 communities[i]);
11261 if (!found
11262 && strcmp(alias, com2alias)
11263 == 0)
11264 found = true;
11265 XFREE(MTYPE_TMP,
11266 communities[i]);
11267 }
11268 XFREE(MTYPE_TMP, communities);
11269 }
11270
11271 if (!found &&
11272 bgp_attr_get_lcommunity(pi->attr)) {
11273 frrstr_split(bgp_attr_get_lcommunity(
11274 pi->attr)
11275 ->str,
11276 " ", &communities, &num);
11277 for (int i = 0; i < num; i++) {
11278 const char *com2alias =
11279 bgp_community2alias(
11280 communities[i]);
11281 if (!found
11282 && strcmp(alias, com2alias)
11283 == 0)
11284 found = true;
11285 XFREE(MTYPE_TMP,
11286 communities[i]);
11287 }
11288 XFREE(MTYPE_TMP, communities);
11289 }
11290
11291 if (!found)
11292 continue;
11293 }
11294
11295 if (type == bgp_show_type_rpki) {
11296 if (dest_p->family == AF_INET
11297 || dest_p->family == AF_INET6)
11298 rpki_curr_state = hook_call(
11299 bgp_rpki_prefix_status,
11300 pi->peer, pi->attr, dest_p);
11301 if (rpki_target_state != RPKI_NOT_BEING_USED
11302 && rpki_curr_state != rpki_target_state)
11303 continue;
11304 }
11305
11306 if (type == bgp_show_type_flap_statistics
11307 || type == bgp_show_type_flap_neighbor
11308 || type == bgp_show_type_dampend_paths
11309 || type == bgp_show_type_damp_neighbor) {
11310 if (!(pi->extra && pi->extra->damp_info))
11311 continue;
11312 }
11313 if (type == bgp_show_type_regexp) {
11314 regex_t *regex = output_arg;
11315
11316 if (bgp_regexec(regex, pi->attr->aspath)
11317 == REG_NOMATCH)
11318 continue;
11319 }
11320 if (type == bgp_show_type_prefix_list) {
11321 struct prefix_list *plist = output_arg;
11322
11323 if (prefix_list_apply(plist, dest_p)
11324 != PREFIX_PERMIT)
11325 continue;
11326 }
11327 if (type == bgp_show_type_access_list) {
11328 struct access_list *alist = output_arg;
11329
11330 if (access_list_apply(alist, dest_p) !=
11331 FILTER_PERMIT)
11332 continue;
11333 }
11334 if (type == bgp_show_type_filter_list) {
11335 struct as_list *as_list = output_arg;
11336
11337 if (as_list_apply(as_list, pi->attr->aspath)
11338 != AS_FILTER_PERMIT)
11339 continue;
11340 }
11341 if (type == bgp_show_type_route_map) {
11342 struct route_map *rmap = output_arg;
11343 struct bgp_path_info path;
11344 struct bgp_path_info_extra extra;
11345 struct attr dummy_attr = {};
11346 route_map_result_t ret;
11347
11348 dummy_attr = *pi->attr;
11349
11350 prep_for_rmap_apply(&path, &extra, dest, pi,
11351 pi->peer, &dummy_attr);
11352
11353 ret = route_map_apply(rmap, dest_p, &path);
11354 bgp_attr_flush(&dummy_attr);
11355 if (ret == RMAP_DENYMATCH)
11356 continue;
11357 }
11358 if (type == bgp_show_type_neighbor
11359 || type == bgp_show_type_flap_neighbor
11360 || type == bgp_show_type_damp_neighbor) {
11361 union sockunion *su = output_arg;
11362
11363 if (pi->peer == NULL
11364 || pi->peer->su_remote == NULL
11365 || !sockunion_same(pi->peer->su_remote, su))
11366 continue;
11367 }
11368 if (type == bgp_show_type_cidr_only) {
11369 uint32_t destination;
11370
11371 destination = ntohl(dest_p->u.prefix4.s_addr);
11372 if (IN_CLASSC(destination)
11373 && dest_p->prefixlen == 24)
11374 continue;
11375 if (IN_CLASSB(destination)
11376 && dest_p->prefixlen == 16)
11377 continue;
11378 if (IN_CLASSA(destination)
11379 && dest_p->prefixlen == 8)
11380 continue;
11381 }
11382 if (type == bgp_show_type_prefix_longer) {
11383 p = output_arg;
11384 if (!prefix_match(p, dest_p))
11385 continue;
11386 }
11387 if (type == bgp_show_type_community_all) {
11388 if (!picomm)
11389 continue;
11390 }
11391 if (type == bgp_show_type_community) {
11392 struct community *com = output_arg;
11393
11394 if (!picomm || !community_match(picomm, com))
11395 continue;
11396 }
11397 if (type == bgp_show_type_community_exact) {
11398 struct community *com = output_arg;
11399
11400 if (!picomm || !community_cmp(picomm, com))
11401 continue;
11402 }
11403 if (type == bgp_show_type_community_list) {
11404 struct community_list *list = output_arg;
11405
11406 if (!community_list_match(picomm, list))
11407 continue;
11408 }
11409 if (type == bgp_show_type_community_list_exact) {
11410 struct community_list *list = output_arg;
11411
11412 if (!community_list_exact_match(picomm, list))
11413 continue;
11414 }
11415 if (type == bgp_show_type_lcommunity) {
11416 struct lcommunity *lcom = output_arg;
11417
11418 if (!bgp_attr_get_lcommunity(pi->attr) ||
11419 !lcommunity_match(
11420 bgp_attr_get_lcommunity(pi->attr),
11421 lcom))
11422 continue;
11423 }
11424
11425 if (type == bgp_show_type_lcommunity_exact) {
11426 struct lcommunity *lcom = output_arg;
11427
11428 if (!bgp_attr_get_lcommunity(pi->attr) ||
11429 !lcommunity_cmp(
11430 bgp_attr_get_lcommunity(pi->attr),
11431 lcom))
11432 continue;
11433 }
11434 if (type == bgp_show_type_lcommunity_list) {
11435 struct community_list *list = output_arg;
11436
11437 if (!lcommunity_list_match(
11438 bgp_attr_get_lcommunity(pi->attr),
11439 list))
11440 continue;
11441 }
11442 if (type
11443 == bgp_show_type_lcommunity_list_exact) {
11444 struct community_list *list = output_arg;
11445
11446 if (!lcommunity_list_exact_match(
11447 bgp_attr_get_lcommunity(pi->attr),
11448 list))
11449 continue;
11450 }
11451 if (type == bgp_show_type_lcommunity_all) {
11452 if (!bgp_attr_get_lcommunity(pi->attr))
11453 continue;
11454 }
11455 if (type == bgp_show_type_dampend_paths
11456 || type == bgp_show_type_damp_neighbor) {
11457 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11458 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11459 continue;
11460 }
11461
11462 if (!use_json && header) {
11463 vty_out(vty,
11464 "BGP table version is %" PRIu64
11465 ", local router ID is %pI4, vrf id ",
11466 table->version, &bgp->router_id);
11467 if (bgp->vrf_id == VRF_UNKNOWN)
11468 vty_out(vty, "%s", VRFID_NONE_STR);
11469 else
11470 vty_out(vty, "%u", bgp->vrf_id);
11471 vty_out(vty, "\n");
11472 vty_out(vty, "Default local pref %u, ",
11473 bgp->default_local_pref);
11474 vty_out(vty, "local AS %u\n", bgp->as);
11475 if (!detail_routes) {
11476 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11477 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11478 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11479 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11480 }
11481 if (type == bgp_show_type_dampend_paths
11482 || type == bgp_show_type_damp_neighbor)
11483 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11484 else if (type == bgp_show_type_flap_statistics
11485 || type == bgp_show_type_flap_neighbor)
11486 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11487 else if (!detail_routes)
11488 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11489 : BGP_SHOW_HEADER));
11490 header = false;
11491
11492 } else if (json_detail && json_paths != NULL) {
11493 const struct prefix_rd *prd;
11494 json_object *jtemp;
11495
11496 /* Use common detail header, for most types;
11497 * need a json 'object'.
11498 */
11499
11500 jtemp = json_object_new_object();
11501 prd = bgp_rd_from_dest(dest, safi);
11502
11503 route_vty_out_detail_header(
11504 vty, bgp, dest,
11505 bgp_dest_get_prefix(dest), prd,
11506 table->afi, safi, jtemp);
11507
11508 json_object_array_add(json_paths, jtemp);
11509
11510 json_detail = false;
11511 }
11512
11513 if (rd != NULL && !display && !output_count) {
11514 if (!use_json)
11515 vty_out(vty,
11516 "Route Distinguisher: %s\n",
11517 rd);
11518 }
11519 if (type == bgp_show_type_dampend_paths
11520 || type == bgp_show_type_damp_neighbor)
11521 damp_route_vty_out(vty, dest_p, pi, display,
11522 AFI_IP, safi, use_json,
11523 json_paths);
11524 else if (type == bgp_show_type_flap_statistics
11525 || type == bgp_show_type_flap_neighbor)
11526 flap_route_vty_out(vty, dest_p, pi, display,
11527 AFI_IP, safi, use_json,
11528 json_paths);
11529 else {
11530 if (detail_routes || detail_json) {
11531 const struct prefix_rd *prd = NULL;
11532
11533 if (dest->pdest)
11534 prd = bgp_rd_from_dest(
11535 dest->pdest, safi);
11536
11537 if (!use_json)
11538 route_vty_out_detail_header(
11539 vty, bgp, dest,
11540 bgp_dest_get_prefix(
11541 dest),
11542 prd, table->afi, safi,
11543 NULL);
11544
11545 route_vty_out_detail(
11546 vty, bgp, dest, dest_p, pi,
11547 family2afi(dest_p->family),
11548 safi, RPKI_NOT_BEING_USED,
11549 json_paths);
11550 } else {
11551 route_vty_out(vty, dest_p, pi, display,
11552 safi, json_paths, wide);
11553 }
11554 }
11555 display++;
11556 }
11557
11558 if (display) {
11559 output_count++;
11560 if (!use_json)
11561 continue;
11562
11563 /* encode prefix */
11564 if (dest_p->family == AF_FLOWSPEC) {
11565 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11566
11567
11568 bgp_fs_nlri_get_string(
11569 (unsigned char *)
11570 dest_p->u.prefix_flowspec.ptr,
11571 dest_p->u.prefix_flowspec.prefixlen,
11572 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11573 family2afi(dest_p->u
11574 .prefix_flowspec.family));
11575 if (first)
11576 vty_out(vty, "\"%s/%d\": ", retstr,
11577 dest_p->u.prefix_flowspec
11578 .prefixlen);
11579 else
11580 vty_out(vty, ",\"%s/%d\": ", retstr,
11581 dest_p->u.prefix_flowspec
11582 .prefixlen);
11583 } else {
11584 if (first)
11585 vty_out(vty, "\"%pFX\": ", dest_p);
11586 else
11587 vty_out(vty, ",\"%pFX\": ", dest_p);
11588 }
11589 /*
11590 * We are using no_pretty here because under
11591 * extremely high settings( say lots and lots of
11592 * routes with lots and lots of ways to reach
11593 * that route via different paths ) this can
11594 * save several minutes of output when FRR
11595 * is run on older cpu's or more underperforming
11596 * routers out there
11597 */
11598 vty_json_no_pretty(vty, json_paths);
11599 json_paths = NULL;
11600 first = 0;
11601 } else
11602 json_object_free(json_paths);
11603 }
11604
11605 if (output_cum) {
11606 output_count += *output_cum;
11607 *output_cum = output_count;
11608 }
11609 if (total_cum) {
11610 total_count += *total_cum;
11611 *total_cum = total_count;
11612 }
11613 if (use_json) {
11614 if (rd) {
11615 vty_out(vty, " }%s ", (is_last ? "" : ","));
11616 }
11617 if (is_last) {
11618 unsigned long i;
11619 for (i = 0; i < *json_header_depth; ++i)
11620 vty_out(vty, " } ");
11621 if (!all)
11622 vty_out(vty, "\n");
11623 }
11624 } else {
11625 if (is_last) {
11626 /* No route is displayed */
11627 if (output_count == 0) {
11628 if (type == bgp_show_type_normal)
11629 vty_out(vty,
11630 "No BGP prefixes displayed, %ld exist\n",
11631 total_count);
11632 } else
11633 vty_out(vty,
11634 "\nDisplayed %ld routes and %ld total paths\n",
11635 output_count, total_count);
11636 }
11637 }
11638
11639 return CMD_SUCCESS;
11640 }
11641
11642 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11643 struct bgp_table *table, struct prefix_rd *prd_match,
11644 enum bgp_show_type type, void *output_arg,
11645 uint16_t show_flags)
11646 {
11647 struct bgp_dest *dest, *next;
11648 unsigned long output_cum = 0;
11649 unsigned long total_cum = 0;
11650 unsigned long json_header_depth = 0;
11651 struct bgp_table *itable;
11652 bool show_msg;
11653 bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11654
11655 show_msg = (!use_json && type == bgp_show_type_normal);
11656
11657 for (dest = bgp_table_top(table); dest; dest = next) {
11658 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11659
11660 next = bgp_route_next(dest);
11661 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11662 continue;
11663
11664 itable = bgp_dest_get_bgp_table_info(dest);
11665 if (itable != NULL) {
11666 struct prefix_rd prd;
11667 char rd[RD_ADDRSTRLEN];
11668
11669 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11670 prefix_rd2str(&prd, rd, sizeof(rd));
11671 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11672 rd, next == NULL, &output_cum,
11673 &total_cum, &json_header_depth,
11674 show_flags, RPKI_NOT_BEING_USED);
11675 if (next == NULL)
11676 show_msg = false;
11677 }
11678 }
11679 if (show_msg) {
11680 if (output_cum == 0)
11681 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11682 total_cum);
11683 else
11684 vty_out(vty,
11685 "\nDisplayed %ld routes and %ld total paths\n",
11686 output_cum, total_cum);
11687 } else {
11688 if (use_json && output_cum == 0)
11689 vty_out(vty, "{}\n");
11690 }
11691 return CMD_SUCCESS;
11692 }
11693
11694 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11695 enum bgp_show_type type, void *output_arg,
11696 uint16_t show_flags, enum rpki_states rpki_target_state)
11697 {
11698 struct bgp_table *table;
11699 unsigned long json_header_depth = 0;
11700 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11701
11702 if (bgp == NULL) {
11703 bgp = bgp_get_default();
11704 }
11705
11706 if (bgp == NULL) {
11707 if (!use_json)
11708 vty_out(vty, "No BGP process is configured\n");
11709 else
11710 vty_out(vty, "{}\n");
11711 return CMD_WARNING;
11712 }
11713
11714 /* Labeled-unicast routes live in the unicast table. */
11715 if (safi == SAFI_LABELED_UNICAST)
11716 safi = SAFI_UNICAST;
11717
11718 table = bgp->rib[afi][safi];
11719 /* use MPLS and ENCAP specific shows until they are merged */
11720 if (safi == SAFI_MPLS_VPN) {
11721 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11722 output_arg, show_flags);
11723 }
11724
11725 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11726 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11727 output_arg, use_json,
11728 1, NULL, NULL);
11729 }
11730
11731 if (safi == SAFI_EVPN)
11732 return bgp_evpn_show_all_routes(vty, bgp, type, use_json, 0);
11733
11734 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11735 NULL, NULL, &json_header_depth, show_flags,
11736 rpki_target_state);
11737 }
11738
11739 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11740 safi_t safi, uint16_t show_flags)
11741 {
11742 struct listnode *node, *nnode;
11743 struct bgp *bgp;
11744 int is_first = 1;
11745 bool route_output = false;
11746 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11747
11748 if (use_json)
11749 vty_out(vty, "{\n");
11750
11751 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11752 route_output = true;
11753 if (use_json) {
11754 if (!is_first)
11755 vty_out(vty, ",\n");
11756 else
11757 is_first = 0;
11758
11759 vty_out(vty, "\"%s\":",
11760 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11761 ? VRF_DEFAULT_NAME
11762 : bgp->name);
11763 } else {
11764 vty_out(vty, "\nInstance %s:\n",
11765 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11766 ? VRF_DEFAULT_NAME
11767 : bgp->name);
11768 }
11769 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11770 show_flags, RPKI_NOT_BEING_USED);
11771 }
11772
11773 if (use_json)
11774 vty_out(vty, "}\n");
11775 else if (!route_output)
11776 vty_out(vty, "%% BGP instance not found\n");
11777 }
11778
11779 /* Header of detailed BGP route information */
11780 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11781 struct bgp_dest *dest, const struct prefix *p,
11782 const struct prefix_rd *prd, afi_t afi,
11783 safi_t safi, json_object *json)
11784 {
11785 struct bgp_path_info *pi;
11786 struct peer *peer;
11787 struct listnode *node, *nnode;
11788 char buf1[RD_ADDRSTRLEN];
11789 int count = 0;
11790 int best = 0;
11791 int suppress = 0;
11792 int accept_own = 0;
11793 int route_filter_translated_v4 = 0;
11794 int route_filter_v4 = 0;
11795 int route_filter_translated_v6 = 0;
11796 int route_filter_v6 = 0;
11797 int llgr_stale = 0;
11798 int no_llgr = 0;
11799 int accept_own_nexthop = 0;
11800 int blackhole = 0;
11801 int no_export = 0;
11802 int no_advertise = 0;
11803 int local_as = 0;
11804 int no_peer = 0;
11805 int first = 1;
11806 int has_valid_label = 0;
11807 mpls_label_t label = 0;
11808 json_object *json_adv_to = NULL;
11809 uint32_t ttl = 0;
11810 uint32_t bos = 0;
11811 uint32_t exp = 0;
11812
11813 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11814
11815 has_valid_label = bgp_is_valid_label(&label);
11816
11817 if (safi == SAFI_EVPN) {
11818 if (!json) {
11819 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11820 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
11821 : "",
11822 prd ? ":" : "", (struct prefix_evpn *)p);
11823 } else {
11824 json_object_string_add(json, "rd",
11825 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11826 "");
11827 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11828 }
11829 } else {
11830 if (!json) {
11831 vty_out(vty,
11832 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11833 "\n",
11834 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11835 ? prefix_rd2str(prd, buf1,
11836 sizeof(buf1))
11837 : ""),
11838 safi == SAFI_MPLS_VPN ? ":" : "", p,
11839 dest->version);
11840
11841 } else {
11842 json_object_string_addf(json, "prefix", "%pFX", p);
11843 json_object_int_add(json, "version", dest->version);
11844
11845 }
11846 }
11847
11848 if (has_valid_label) {
11849 if (json)
11850 json_object_int_add(json, "localLabel", label);
11851 else
11852 vty_out(vty, "Local label: %d\n", label);
11853 }
11854
11855 if (!json)
11856 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11857 vty_out(vty, "not allocated\n");
11858
11859 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11860 struct community *picomm = NULL;
11861
11862 picomm = bgp_attr_get_community(pi->attr);
11863
11864 count++;
11865 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11866 best = count;
11867 if (bgp_path_suppressed(pi))
11868 suppress = 1;
11869
11870 if (!picomm)
11871 continue;
11872
11873 no_advertise += community_include(
11874 picomm, COMMUNITY_NO_ADVERTISE);
11875 no_export +=
11876 community_include(picomm, COMMUNITY_NO_EXPORT);
11877 local_as +=
11878 community_include(picomm, COMMUNITY_LOCAL_AS);
11879 accept_own +=
11880 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11881 route_filter_translated_v4 += community_include(
11882 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11883 route_filter_translated_v6 += community_include(
11884 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11885 route_filter_v4 += community_include(
11886 picomm, COMMUNITY_ROUTE_FILTER_v4);
11887 route_filter_v6 += community_include(
11888 picomm, COMMUNITY_ROUTE_FILTER_v6);
11889 llgr_stale +=
11890 community_include(picomm, COMMUNITY_LLGR_STALE);
11891 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11892 accept_own_nexthop += community_include(
11893 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11894 blackhole +=
11895 community_include(picomm, COMMUNITY_BLACKHOLE);
11896 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11897 }
11898 }
11899
11900 if (!json) {
11901 vty_out(vty, "Paths: (%d available", count);
11902 if (best) {
11903 vty_out(vty, ", best #%d", best);
11904 if (safi == SAFI_UNICAST) {
11905 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11906 vty_out(vty, ", table %s",
11907 VRF_DEFAULT_NAME);
11908 else
11909 vty_out(vty, ", vrf %s",
11910 bgp->name);
11911 }
11912 } else
11913 vty_out(vty, ", no best path");
11914
11915 if (accept_own)
11916 vty_out(vty,
11917 ", accept own local route exported and imported in different VRF");
11918 else if (route_filter_translated_v4)
11919 vty_out(vty,
11920 ", mark translated RTs for VPNv4 route filtering");
11921 else if (route_filter_v4)
11922 vty_out(vty,
11923 ", attach RT as-is for VPNv4 route filtering");
11924 else if (route_filter_translated_v6)
11925 vty_out(vty,
11926 ", mark translated RTs for VPNv6 route filtering");
11927 else if (route_filter_v6)
11928 vty_out(vty,
11929 ", attach RT as-is for VPNv6 route filtering");
11930 else if (llgr_stale)
11931 vty_out(vty,
11932 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
11933 else if (no_llgr)
11934 vty_out(vty,
11935 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11936 else if (accept_own_nexthop)
11937 vty_out(vty,
11938 ", accept local nexthop");
11939 else if (blackhole)
11940 vty_out(vty, ", inform peer to blackhole prefix");
11941 else if (no_export)
11942 vty_out(vty, ", not advertised to EBGP peer");
11943 else if (no_advertise)
11944 vty_out(vty, ", not advertised to any peer");
11945 else if (local_as)
11946 vty_out(vty, ", not advertised outside local AS");
11947 else if (no_peer)
11948 vty_out(vty,
11949 ", inform EBGP peer not to advertise to their EBGP peers");
11950
11951 if (suppress)
11952 vty_out(vty,
11953 ", Advertisements suppressed by an aggregate.");
11954 vty_out(vty, ")\n");
11955 }
11956
11957 /* If we are not using addpath then we can display Advertised to and
11958 * that will
11959 * show what peers we advertised the bestpath to. If we are using
11960 * addpath
11961 * though then we must display Advertised to on a path-by-path basis. */
11962 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11963 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11964 if (bgp_adj_out_lookup(peer, dest, 0)) {
11965 if (json && !json_adv_to)
11966 json_adv_to = json_object_new_object();
11967
11968 route_vty_out_advertised_to(
11969 vty, peer, &first,
11970 " Advertised to non peer-group peers:\n ",
11971 json_adv_to);
11972 }
11973 }
11974
11975 if (json) {
11976 if (json_adv_to) {
11977 json_object_object_add(json, "advertisedTo",
11978 json_adv_to);
11979 }
11980 } else {
11981 if (first)
11982 vty_out(vty, " Not advertised to any peer");
11983 vty_out(vty, "\n");
11984 }
11985 }
11986 }
11987
11988 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
11989 struct bgp_dest *bgp_node, struct vty *vty,
11990 struct bgp *bgp, afi_t afi, safi_t safi,
11991 json_object *json, enum bgp_path_type pathtype,
11992 int *display, enum rpki_states rpki_target_state)
11993 {
11994 struct bgp_path_info *pi;
11995 int header = 1;
11996 json_object *json_header = NULL;
11997 json_object *json_paths = NULL;
11998 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
11999
12000 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
12001 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
12002
12003 if (p->family == AF_INET || p->family == AF_INET6)
12004 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
12005 pi->peer, pi->attr, p);
12006
12007 if (rpki_target_state != RPKI_NOT_BEING_USED
12008 && rpki_curr_state != rpki_target_state)
12009 continue;
12010
12011 if (json && !json_paths) {
12012 /* Instantiate json_paths only if path is valid */
12013 json_paths = json_object_new_array();
12014 if (pfx_rd)
12015 json_header = json_object_new_object();
12016 else
12017 json_header = json;
12018 }
12019
12020 if (header) {
12021 route_vty_out_detail_header(
12022 vty, bgp, bgp_node,
12023 bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP,
12024 safi, json_header);
12025 header = 0;
12026 }
12027 (*display)++;
12028
12029 if (pathtype == BGP_PATH_SHOW_ALL
12030 || (pathtype == BGP_PATH_SHOW_BESTPATH
12031 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12032 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12033 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12034 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12035 route_vty_out_detail(vty, bgp, bgp_node,
12036 bgp_dest_get_prefix(bgp_node), pi,
12037 AFI_IP, safi, rpki_curr_state,
12038 json_paths);
12039 }
12040
12041 if (json && json_paths) {
12042 json_object_object_add(json_header, "paths", json_paths);
12043
12044 if (pfx_rd)
12045 json_object_object_addf(json, json_header, "%pRD",
12046 pfx_rd);
12047 }
12048 }
12049
12050 /*
12051 * Return rd based on safi
12052 */
12053 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12054 safi_t safi)
12055 {
12056 switch (safi) {
12057 case SAFI_MPLS_VPN:
12058 case SAFI_ENCAP:
12059 case SAFI_EVPN:
12060 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12061 case SAFI_UNSPEC:
12062 case SAFI_UNICAST:
12063 case SAFI_MULTICAST:
12064 case SAFI_LABELED_UNICAST:
12065 case SAFI_FLOWSPEC:
12066 case SAFI_MAX:
12067 return NULL;
12068 }
12069
12070 assert(!"Reached end of function when we were not expecting it");
12071 }
12072
12073 /* Display specified route of BGP table. */
12074 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12075 struct bgp_table *rib, const char *ip_str,
12076 afi_t afi, safi_t safi,
12077 enum rpki_states rpki_target_state,
12078 struct prefix_rd *prd, int prefix_check,
12079 enum bgp_path_type pathtype, bool use_json)
12080 {
12081 int ret;
12082 int display = 0;
12083 struct prefix match;
12084 struct bgp_dest *dest;
12085 struct bgp_dest *rm;
12086 struct bgp_table *table;
12087 json_object *json = NULL;
12088 json_object *json_paths = NULL;
12089
12090 /* Check IP address argument. */
12091 ret = str2prefix(ip_str, &match);
12092 if (!ret) {
12093 vty_out(vty, "address is malformed\n");
12094 return CMD_WARNING;
12095 }
12096
12097 match.family = afi2family(afi);
12098
12099 if (use_json)
12100 json = json_object_new_object();
12101
12102 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12103 for (dest = bgp_table_top(rib); dest;
12104 dest = bgp_route_next(dest)) {
12105 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12106
12107 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12108 continue;
12109 table = bgp_dest_get_bgp_table_info(dest);
12110 if (!table)
12111 continue;
12112
12113 rm = bgp_node_match(table, &match);
12114 if (rm == NULL)
12115 continue;
12116
12117 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12118 if (prefix_check
12119 && rm_p->prefixlen != match.prefixlen) {
12120 bgp_dest_unlock_node(rm);
12121 continue;
12122 }
12123
12124 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12125 bgp, afi, safi, json, pathtype,
12126 &display, rpki_target_state);
12127
12128 bgp_dest_unlock_node(rm);
12129 }
12130 } else if (safi == SAFI_EVPN) {
12131 struct bgp_dest *longest_pfx;
12132 bool is_exact_pfxlen_match = false;
12133
12134 for (dest = bgp_table_top(rib); dest;
12135 dest = bgp_route_next(dest)) {
12136 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12137
12138 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12139 continue;
12140 table = bgp_dest_get_bgp_table_info(dest);
12141 if (!table)
12142 continue;
12143
12144 longest_pfx = NULL;
12145 is_exact_pfxlen_match = false;
12146 /*
12147 * Search through all the prefixes for a match. The
12148 * pfx's are enumerated in ascending order of pfxlens.
12149 * So, the last pfx match is the longest match. Set
12150 * is_exact_pfxlen_match when we get exact pfxlen match
12151 */
12152 for (rm = bgp_table_top(table); rm;
12153 rm = bgp_route_next(rm)) {
12154 const struct prefix *rm_p =
12155 bgp_dest_get_prefix(rm);
12156 /*
12157 * Get prefixlen of the ip-prefix within type5
12158 * evpn route
12159 */
12160 if (evpn_type5_prefix_match(rm_p, &match)
12161 && rm->info) {
12162 longest_pfx = rm;
12163 int type5_pfxlen =
12164 bgp_evpn_get_type5_prefixlen(
12165 rm_p);
12166 if (type5_pfxlen == match.prefixlen) {
12167 is_exact_pfxlen_match = true;
12168 bgp_dest_unlock_node(rm);
12169 break;
12170 }
12171 }
12172 }
12173
12174 if (!longest_pfx)
12175 continue;
12176
12177 if (prefix_check && !is_exact_pfxlen_match)
12178 continue;
12179
12180 rm = longest_pfx;
12181 bgp_dest_lock_node(rm);
12182
12183 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12184 bgp, afi, safi, json, pathtype,
12185 &display, rpki_target_state);
12186
12187 bgp_dest_unlock_node(rm);
12188 }
12189 } else if (safi == SAFI_FLOWSPEC) {
12190 if (use_json)
12191 json_paths = json_object_new_array();
12192
12193 display = bgp_flowspec_display_match_per_ip(afi, rib,
12194 &match, prefix_check,
12195 vty,
12196 use_json,
12197 json_paths);
12198 if (use_json) {
12199 if (display)
12200 json_object_object_add(json, "paths",
12201 json_paths);
12202 else
12203 json_object_free(json_paths);
12204 }
12205 } else {
12206 dest = bgp_node_match(rib, &match);
12207 if (dest != NULL) {
12208 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12209 if (!prefix_check
12210 || dest_p->prefixlen == match.prefixlen) {
12211 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12212 safi, json, pathtype,
12213 &display, rpki_target_state);
12214 }
12215
12216 bgp_dest_unlock_node(dest);
12217 }
12218 }
12219
12220 if (use_json) {
12221 vty_json(vty, json);
12222 } else {
12223 if (!display) {
12224 vty_out(vty, "%% Network not in table\n");
12225 return CMD_WARNING;
12226 }
12227 }
12228
12229 return CMD_SUCCESS;
12230 }
12231
12232 /* Display specified route of Main RIB */
12233 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12234 afi_t afi, safi_t safi, struct prefix_rd *prd,
12235 int prefix_check, enum bgp_path_type pathtype,
12236 enum rpki_states rpki_target_state, bool use_json)
12237 {
12238 if (!bgp) {
12239 bgp = bgp_get_default();
12240 if (!bgp) {
12241 if (!use_json)
12242 vty_out(vty, "No BGP process is configured\n");
12243 else
12244 vty_out(vty, "{}\n");
12245 return CMD_WARNING;
12246 }
12247 }
12248
12249 /* labeled-unicast routes live in the unicast table */
12250 if (safi == SAFI_LABELED_UNICAST)
12251 safi = SAFI_UNICAST;
12252
12253 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12254 afi, safi, rpki_target_state, prd,
12255 prefix_check, pathtype, use_json);
12256 }
12257
12258 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12259 struct cmd_token **argv, bool exact, afi_t afi,
12260 safi_t safi, bool uj)
12261 {
12262 struct lcommunity *lcom;
12263 struct buffer *b;
12264 int i;
12265 char *str;
12266 int first = 0;
12267 uint16_t show_flags = 0;
12268 int ret;
12269
12270 if (uj)
12271 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12272
12273 b = buffer_new(1024);
12274 for (i = 0; i < argc; i++) {
12275 if (first)
12276 buffer_putc(b, ' ');
12277 else {
12278 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12279 first = 1;
12280 buffer_putstr(b, argv[i]->arg);
12281 }
12282 }
12283 }
12284 buffer_putc(b, '\0');
12285
12286 str = buffer_getstr(b);
12287 buffer_free(b);
12288
12289 lcom = lcommunity_str2com(str);
12290 XFREE(MTYPE_TMP, str);
12291 if (!lcom) {
12292 vty_out(vty, "%% Large-community malformed\n");
12293 return CMD_WARNING;
12294 }
12295
12296 ret = bgp_show(vty, bgp, afi, safi,
12297 (exact ? bgp_show_type_lcommunity_exact
12298 : bgp_show_type_lcommunity),
12299 lcom, show_flags, RPKI_NOT_BEING_USED);
12300
12301 lcommunity_free(&lcom);
12302 return ret;
12303 }
12304
12305 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12306 const char *lcom, bool exact, afi_t afi,
12307 safi_t safi, bool uj)
12308 {
12309 struct community_list *list;
12310 uint16_t show_flags = 0;
12311
12312 if (uj)
12313 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12314
12315
12316 list = community_list_lookup(bgp_clist, lcom, 0,
12317 LARGE_COMMUNITY_LIST_MASTER);
12318 if (list == NULL) {
12319 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12320 lcom);
12321 return CMD_WARNING;
12322 }
12323
12324 return bgp_show(vty, bgp, afi, safi,
12325 (exact ? bgp_show_type_lcommunity_list_exact
12326 : bgp_show_type_lcommunity_list),
12327 list, show_flags, RPKI_NOT_BEING_USED);
12328 }
12329
12330 DEFUN (show_ip_bgp_large_community_list,
12331 show_ip_bgp_large_community_list_cmd,
12332 "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]",
12333 SHOW_STR
12334 IP_STR
12335 BGP_STR
12336 BGP_INSTANCE_HELP_STR
12337 BGP_AFI_HELP_STR
12338 BGP_SAFI_WITH_LABEL_HELP_STR
12339 "Display routes matching the large-community-list\n"
12340 "large-community-list number\n"
12341 "large-community-list name\n"
12342 "Exact match of the large-communities\n"
12343 JSON_STR)
12344 {
12345 afi_t afi = AFI_IP6;
12346 safi_t safi = SAFI_UNICAST;
12347 int idx = 0;
12348 bool exact_match = 0;
12349 struct bgp *bgp = NULL;
12350 bool uj = use_json(argc, argv);
12351
12352 if (uj)
12353 argc--;
12354
12355 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12356 &bgp, uj);
12357 if (!idx)
12358 return CMD_WARNING;
12359
12360 argv_find(argv, argc, "large-community-list", &idx);
12361
12362 const char *clist_number_or_name = argv[++idx]->arg;
12363
12364 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12365 exact_match = 1;
12366
12367 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12368 exact_match, afi, safi, uj);
12369 }
12370 DEFUN (show_ip_bgp_large_community,
12371 show_ip_bgp_large_community_cmd,
12372 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12373 SHOW_STR
12374 IP_STR
12375 BGP_STR
12376 BGP_INSTANCE_HELP_STR
12377 BGP_AFI_HELP_STR
12378 BGP_SAFI_WITH_LABEL_HELP_STR
12379 "Display routes matching the large-communities\n"
12380 "List of large-community numbers\n"
12381 "Exact match of the large-communities\n"
12382 JSON_STR)
12383 {
12384 afi_t afi = AFI_IP6;
12385 safi_t safi = SAFI_UNICAST;
12386 int idx = 0;
12387 bool exact_match = 0;
12388 struct bgp *bgp = NULL;
12389 bool uj = use_json(argc, argv);
12390 uint16_t show_flags = 0;
12391
12392 if (uj) {
12393 argc--;
12394 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12395 }
12396
12397 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12398 &bgp, uj);
12399 if (!idx)
12400 return CMD_WARNING;
12401
12402 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12403 if (argv_find(argv, argc, "exact-match", &idx)) {
12404 argc--;
12405 exact_match = 1;
12406 }
12407 return bgp_show_lcommunity(vty, bgp, argc, argv,
12408 exact_match, afi, safi, uj);
12409 } else
12410 return bgp_show(vty, bgp, afi, safi,
12411 bgp_show_type_lcommunity_all, NULL, show_flags,
12412 RPKI_NOT_BEING_USED);
12413 }
12414
12415 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12416 safi_t safi, struct json_object *json_array);
12417 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12418 safi_t safi, struct json_object *json);
12419
12420
12421 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12422 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12423 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12424 "Display number of prefixes for all afi/safi\n" JSON_STR)
12425 {
12426 bool uj = use_json(argc, argv);
12427 struct bgp *bgp = NULL;
12428 safi_t safi = SAFI_UNICAST;
12429 afi_t afi = AFI_IP6;
12430 int idx = 0;
12431 struct json_object *json_all = NULL;
12432 struct json_object *json_afi_safi = NULL;
12433
12434 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12435 &bgp, false);
12436 if (!idx)
12437 return CMD_WARNING;
12438
12439 if (uj)
12440 json_all = json_object_new_object();
12441
12442 FOREACH_AFI_SAFI (afi, safi) {
12443 /*
12444 * So limit output to those afi/safi pairs that
12445 * actually have something interesting in them
12446 */
12447 if (strmatch(get_afi_safi_str(afi, safi, true),
12448 "Unknown")) {
12449 continue;
12450 }
12451 if (uj) {
12452 json_afi_safi = json_object_new_array();
12453 json_object_object_add(
12454 json_all,
12455 get_afi_safi_str(afi, safi, true),
12456 json_afi_safi);
12457 } else {
12458 json_afi_safi = NULL;
12459 }
12460
12461 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12462 }
12463
12464 if (uj)
12465 vty_json(vty, json_all);
12466
12467 return CMD_SUCCESS;
12468 }
12469
12470 /* BGP route print out function without JSON */
12471 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12472 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12473 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12474 SHOW_STR
12475 IP_STR
12476 BGP_STR
12477 BGP_INSTANCE_HELP_STR
12478 L2VPN_HELP_STR
12479 EVPN_HELP_STR
12480 "BGP RIB advertisement statistics\n"
12481 JSON_STR)
12482 {
12483 afi_t afi = AFI_IP6;
12484 safi_t safi = SAFI_UNICAST;
12485 struct bgp *bgp = NULL;
12486 int idx = 0, ret;
12487 bool uj = use_json(argc, argv);
12488 struct json_object *json_afi_safi = NULL, *json = NULL;
12489
12490 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12491 &bgp, false);
12492 if (!idx)
12493 return CMD_WARNING;
12494
12495 if (uj)
12496 json_afi_safi = json_object_new_array();
12497 else
12498 json_afi_safi = NULL;
12499
12500 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12501
12502 if (uj) {
12503 json = json_object_new_object();
12504 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12505 json_afi_safi);
12506 vty_json(vty, json);
12507 }
12508 return ret;
12509 }
12510
12511 /* BGP route print out function without JSON */
12512 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12513 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12514 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12515 "]]\
12516 statistics [json]",
12517 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12518 BGP_SAFI_WITH_LABEL_HELP_STR
12519 "BGP RIB advertisement statistics\n" JSON_STR)
12520 {
12521 afi_t afi = AFI_IP6;
12522 safi_t safi = SAFI_UNICAST;
12523 struct bgp *bgp = NULL;
12524 int idx = 0, ret;
12525 bool uj = use_json(argc, argv);
12526 struct json_object *json_afi_safi = NULL, *json = NULL;
12527
12528 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12529 &bgp, false);
12530 if (!idx)
12531 return CMD_WARNING;
12532
12533 if (uj)
12534 json_afi_safi = json_object_new_array();
12535 else
12536 json_afi_safi = NULL;
12537
12538 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12539
12540 if (uj) {
12541 json = json_object_new_object();
12542 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12543 json_afi_safi);
12544 vty_json(vty, json);
12545 }
12546 return ret;
12547 }
12548
12549 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12550 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12551 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12552 "]] [all$all] dampening parameters [json]",
12553 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12554 BGP_SAFI_WITH_LABEL_HELP_STR
12555 "Display the entries for all address families\n"
12556 "Display detailed information about dampening\n"
12557 "Display detail of configured dampening parameters\n"
12558 JSON_STR)
12559 {
12560 afi_t afi = AFI_IP6;
12561 safi_t safi = SAFI_UNICAST;
12562 struct bgp *bgp = NULL;
12563 int idx = 0;
12564 uint16_t show_flags = 0;
12565 bool uj = use_json(argc, argv);
12566
12567 if (uj) {
12568 argc--;
12569 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12570 }
12571
12572 /* [<ipv4|ipv6> [all]] */
12573 if (all) {
12574 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12575 if (argv_find(argv, argc, "ipv4", &idx))
12576 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12577
12578 if (argv_find(argv, argc, "ipv6", &idx))
12579 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12580 }
12581
12582 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12583 &bgp, false);
12584 if (!idx)
12585 return CMD_WARNING;
12586
12587 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12588 }
12589
12590 /* BGP route print out function */
12591 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12592 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12593 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12594 "]]\
12595 [all$all]\
12596 [cidr-only\
12597 |dampening <flap-statistics|dampened-paths>\
12598 |community [AA:NN|local-AS|no-advertise|no-export\
12599 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12600 |accept-own|accept-own-nexthop|route-filter-v6\
12601 |route-filter-v4|route-filter-translated-v6\
12602 |route-filter-translated-v4] [exact-match]\
12603 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12604 |filter-list AS_PATH_FILTER_NAME\
12605 |prefix-list WORD\
12606 |access-list ACCESSLIST_NAME\
12607 |route-map RMAP_NAME\
12608 |rpki <invalid|valid|notfound>\
12609 |version (1-4294967295)\
12610 |alias ALIAS_NAME\
12611 |A.B.C.D/M longer-prefixes\
12612 |X:X::X:X/M longer-prefixes\
12613 |detail-routes$detail_routes\
12614 ] [json$uj [detail$detail_json] | wide$wide]",
12615 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12616 BGP_SAFI_WITH_LABEL_HELP_STR
12617 "Display the entries for all address families\n"
12618 "Display only routes with non-natural netmasks\n"
12619 "Display detailed information about dampening\n"
12620 "Display flap statistics of routes\n"
12621 "Display paths suppressed due to dampening\n"
12622 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12623 "Do not send outside local AS (well-known community)\n"
12624 "Do not advertise to any peer (well-known community)\n"
12625 "Do not export to next AS (well-known community)\n"
12626 "Graceful shutdown (well-known community)\n"
12627 "Do not export to any peer (well-known community)\n"
12628 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12629 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12630 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12631 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12632 "Should accept VPN route with local nexthop (well-known community)\n"
12633 "RT VPNv6 route filtering (well-known community)\n"
12634 "RT VPNv4 route filtering (well-known community)\n"
12635 "RT translated VPNv6 route filtering (well-known community)\n"
12636 "RT translated VPNv4 route filtering (well-known community)\n"
12637 "Exact match of the communities\n"
12638 "Community-list number\n"
12639 "Community-list name\n"
12640 "Display routes matching the community-list\n"
12641 "Exact match of the communities\n"
12642 "Display routes conforming to the filter-list\n"
12643 "Regular expression access list name\n"
12644 "Display routes conforming to the prefix-list\n"
12645 "Prefix-list name\n"
12646 "Display routes conforming to the access-list\n"
12647 "Access-list name\n"
12648 "Display routes matching the route-map\n"
12649 "A route-map to match on\n"
12650 "RPKI route types\n"
12651 "A valid path as determined by rpki\n"
12652 "A invalid path as determined by rpki\n"
12653 "A path that has no rpki data\n"
12654 "Display prefixes with matching version numbers\n"
12655 "Version number and above\n"
12656 "Display prefixes with matching BGP community alias\n"
12657 "BGP community alias\n"
12658 "IPv4 prefix\n"
12659 "Display route and more specific routes\n"
12660 "IPv6 prefix\n"
12661 "Display route and more specific routes\n"
12662 "Display detailed version of all routes\n"
12663 JSON_STR
12664 "Display detailed version of JSON output\n"
12665 "Increase table width for longer prefixes\n")
12666 {
12667 afi_t afi = AFI_IP6;
12668 safi_t safi = SAFI_UNICAST;
12669 enum bgp_show_type sh_type = bgp_show_type_normal;
12670 void *output_arg = NULL;
12671 struct bgp *bgp = NULL;
12672 int idx = 0;
12673 int exact_match = 0;
12674 char *community = NULL;
12675 bool first = true;
12676 uint16_t show_flags = 0;
12677 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12678 struct prefix p;
12679
12680 if (uj) {
12681 argc--;
12682 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12683 }
12684
12685 if (detail_json)
12686 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
12687
12688 if (detail_routes)
12689 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
12690
12691 /* [<ipv4|ipv6> [all]] */
12692 if (all) {
12693 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12694
12695 if (argv_find(argv, argc, "ipv4", &idx))
12696 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12697
12698 if (argv_find(argv, argc, "ipv6", &idx))
12699 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12700 }
12701
12702 if (wide)
12703 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12704
12705 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12706 &bgp, uj);
12707 if (!idx)
12708 return CMD_WARNING;
12709
12710 if (argv_find(argv, argc, "cidr-only", &idx))
12711 sh_type = bgp_show_type_cidr_only;
12712
12713 if (argv_find(argv, argc, "dampening", &idx)) {
12714 if (argv_find(argv, argc, "dampened-paths", &idx))
12715 sh_type = bgp_show_type_dampend_paths;
12716 else if (argv_find(argv, argc, "flap-statistics", &idx))
12717 sh_type = bgp_show_type_flap_statistics;
12718 }
12719
12720 if (argv_find(argv, argc, "community", &idx)) {
12721 char *maybecomm = NULL;
12722
12723 if (idx + 1 < argc) {
12724 if (argv[idx + 1]->type == VARIABLE_TKN)
12725 maybecomm = argv[idx + 1]->arg;
12726 else
12727 maybecomm = argv[idx + 1]->text;
12728 }
12729
12730 if (maybecomm && !strmatch(maybecomm, "json")
12731 && !strmatch(maybecomm, "exact-match"))
12732 community = maybecomm;
12733
12734 if (argv_find(argv, argc, "exact-match", &idx))
12735 exact_match = 1;
12736
12737 if (!community)
12738 sh_type = bgp_show_type_community_all;
12739 }
12740
12741 if (argv_find(argv, argc, "community-list", &idx)) {
12742 const char *clist_number_or_name = argv[++idx]->arg;
12743 struct community_list *list;
12744
12745 if (argv_find(argv, argc, "exact-match", &idx))
12746 exact_match = 1;
12747
12748 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12749 COMMUNITY_LIST_MASTER);
12750 if (list == NULL) {
12751 vty_out(vty, "%% %s community-list not found\n",
12752 clist_number_or_name);
12753 return CMD_WARNING;
12754 }
12755
12756 if (exact_match)
12757 sh_type = bgp_show_type_community_list_exact;
12758 else
12759 sh_type = bgp_show_type_community_list;
12760 output_arg = list;
12761 }
12762
12763 if (argv_find(argv, argc, "filter-list", &idx)) {
12764 const char *filter = argv[++idx]->arg;
12765 struct as_list *as_list;
12766
12767 as_list = as_list_lookup(filter);
12768 if (as_list == NULL) {
12769 vty_out(vty, "%% %s AS-path access-list not found\n",
12770 filter);
12771 return CMD_WARNING;
12772 }
12773
12774 sh_type = bgp_show_type_filter_list;
12775 output_arg = as_list;
12776 }
12777
12778 if (argv_find(argv, argc, "prefix-list", &idx)) {
12779 const char *prefix_list_str = argv[++idx]->arg;
12780 struct prefix_list *plist;
12781
12782 plist = prefix_list_lookup(afi, prefix_list_str);
12783 if (plist == NULL) {
12784 vty_out(vty, "%% %s prefix-list not found\n",
12785 prefix_list_str);
12786 return CMD_WARNING;
12787 }
12788
12789 sh_type = bgp_show_type_prefix_list;
12790 output_arg = plist;
12791 }
12792
12793 if (argv_find(argv, argc, "access-list", &idx)) {
12794 const char *access_list_str = argv[++idx]->arg;
12795 struct access_list *alist;
12796
12797 alist = access_list_lookup(afi, access_list_str);
12798 if (!alist) {
12799 vty_out(vty, "%% %s access-list not found\n",
12800 access_list_str);
12801 return CMD_WARNING;
12802 }
12803
12804 sh_type = bgp_show_type_access_list;
12805 output_arg = alist;
12806 }
12807
12808 if (argv_find(argv, argc, "route-map", &idx)) {
12809 const char *rmap_str = argv[++idx]->arg;
12810 struct route_map *rmap;
12811
12812 rmap = route_map_lookup_by_name(rmap_str);
12813 if (!rmap) {
12814 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12815 return CMD_WARNING;
12816 }
12817
12818 sh_type = bgp_show_type_route_map;
12819 output_arg = rmap;
12820 }
12821
12822 if (argv_find(argv, argc, "rpki", &idx)) {
12823 sh_type = bgp_show_type_rpki;
12824 if (argv_find(argv, argc, "valid", &idx))
12825 rpki_target_state = RPKI_VALID;
12826 else if (argv_find(argv, argc, "invalid", &idx))
12827 rpki_target_state = RPKI_INVALID;
12828 }
12829
12830 /* Display prefixes with matching version numbers */
12831 if (argv_find(argv, argc, "version", &idx)) {
12832 sh_type = bgp_show_type_prefix_version;
12833 output_arg = argv[idx + 1]->arg;
12834 }
12835
12836 /* Display prefixes with matching BGP community alias */
12837 if (argv_find(argv, argc, "alias", &idx)) {
12838 sh_type = bgp_show_type_community_alias;
12839 output_arg = argv[idx + 1]->arg;
12840 }
12841
12842 /* prefix-longer */
12843 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12844 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12845 const char *prefix_str = argv[idx]->arg;
12846
12847 if (!str2prefix(prefix_str, &p)) {
12848 vty_out(vty, "%% Malformed Prefix\n");
12849 return CMD_WARNING;
12850 }
12851
12852 sh_type = bgp_show_type_prefix_longer;
12853 output_arg = &p;
12854 }
12855
12856 if (!all) {
12857 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12858 if (community)
12859 return bgp_show_community(vty, bgp, community,
12860 exact_match, afi, safi,
12861 show_flags);
12862 else
12863 return bgp_show(vty, bgp, afi, safi, sh_type,
12864 output_arg, show_flags,
12865 rpki_target_state);
12866 } else {
12867 struct listnode *node;
12868 struct bgp *abgp;
12869 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12870 * AFI_IP6 */
12871
12872 if (uj)
12873 vty_out(vty, "{\n");
12874
12875 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12876 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12877 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12878 ? AFI_IP
12879 : AFI_IP6;
12880 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12881 FOREACH_SAFI (safi) {
12882 if (!bgp_afi_safi_peer_exists(abgp, afi,
12883 safi))
12884 continue;
12885
12886 if (uj) {
12887 if (first)
12888 first = false;
12889 else
12890 vty_out(vty, ",\n");
12891 vty_out(vty, "\"%s\":{\n",
12892 get_afi_safi_str(afi,
12893 safi,
12894 true));
12895 } else
12896 vty_out(vty,
12897 "\nFor address family: %s\n",
12898 get_afi_safi_str(
12899 afi, safi,
12900 false));
12901
12902 if (community)
12903 bgp_show_community(
12904 vty, abgp, community,
12905 exact_match, afi, safi,
12906 show_flags);
12907 else
12908 bgp_show(vty, abgp, afi, safi,
12909 sh_type, output_arg,
12910 show_flags,
12911 rpki_target_state);
12912 if (uj)
12913 vty_out(vty, "}\n");
12914 }
12915 }
12916 } else {
12917 /* show <ip> bgp all: for each AFI and SAFI*/
12918 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12919 FOREACH_AFI_SAFI (afi, safi) {
12920 if (!bgp_afi_safi_peer_exists(abgp, afi,
12921 safi))
12922 continue;
12923
12924 if (uj) {
12925 if (first)
12926 first = false;
12927 else
12928 vty_out(vty, ",\n");
12929
12930 vty_out(vty, "\"%s\":{\n",
12931 get_afi_safi_str(afi,
12932 safi,
12933 true));
12934 } else
12935 vty_out(vty,
12936 "\nFor address family: %s\n",
12937 get_afi_safi_str(
12938 afi, safi,
12939 false));
12940
12941 if (community)
12942 bgp_show_community(
12943 vty, abgp, community,
12944 exact_match, afi, safi,
12945 show_flags);
12946 else
12947 bgp_show(vty, abgp, afi, safi,
12948 sh_type, output_arg,
12949 show_flags,
12950 rpki_target_state);
12951 if (uj)
12952 vty_out(vty, "}\n");
12953 }
12954 }
12955 }
12956 if (uj)
12957 vty_out(vty, "}\n");
12958 }
12959 return CMD_SUCCESS;
12960 }
12961
12962 DEFUN (show_ip_bgp_route,
12963 show_ip_bgp_route_cmd,
12964 "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]",
12965 SHOW_STR
12966 IP_STR
12967 BGP_STR
12968 BGP_INSTANCE_HELP_STR
12969 BGP_AFI_HELP_STR
12970 BGP_SAFI_WITH_LABEL_HELP_STR
12971 "Network in the BGP routing table to display\n"
12972 "IPv4 prefix\n"
12973 "Network in the BGP routing table to display\n"
12974 "IPv6 prefix\n"
12975 "Display only the bestpath\n"
12976 "Display only multipaths\n"
12977 "Display only paths that match the specified rpki state\n"
12978 "A valid path as determined by rpki\n"
12979 "A invalid path as determined by rpki\n"
12980 "A path that has no rpki data\n"
12981 JSON_STR)
12982 {
12983 int prefix_check = 0;
12984
12985 afi_t afi = AFI_IP6;
12986 safi_t safi = SAFI_UNICAST;
12987 char *prefix = NULL;
12988 struct bgp *bgp = NULL;
12989 enum bgp_path_type path_type;
12990 bool uj = use_json(argc, argv);
12991
12992 int idx = 0;
12993
12994 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12995 &bgp, uj);
12996 if (!idx)
12997 return CMD_WARNING;
12998
12999 if (!bgp) {
13000 vty_out(vty,
13001 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
13002 return CMD_WARNING;
13003 }
13004
13005 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
13006 if (argv_find(argv, argc, "A.B.C.D", &idx)
13007 || argv_find(argv, argc, "X:X::X:X", &idx))
13008 prefix_check = 0;
13009 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
13010 || argv_find(argv, argc, "X:X::X:X/M", &idx))
13011 prefix_check = 1;
13012
13013 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
13014 && afi != AFI_IP6) {
13015 vty_out(vty,
13016 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
13017 return CMD_WARNING;
13018 }
13019 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
13020 && afi != AFI_IP) {
13021 vty_out(vty,
13022 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13023 return CMD_WARNING;
13024 }
13025
13026 prefix = argv[idx]->arg;
13027
13028 /* [<bestpath|multipath>] */
13029 if (argv_find(argv, argc, "bestpath", &idx))
13030 path_type = BGP_PATH_SHOW_BESTPATH;
13031 else if (argv_find(argv, argc, "multipath", &idx))
13032 path_type = BGP_PATH_SHOW_MULTIPATH;
13033 else
13034 path_type = BGP_PATH_SHOW_ALL;
13035
13036 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13037 path_type, RPKI_NOT_BEING_USED, uj);
13038 }
13039
13040 DEFUN (show_ip_bgp_regexp,
13041 show_ip_bgp_regexp_cmd,
13042 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13043 SHOW_STR
13044 IP_STR
13045 BGP_STR
13046 BGP_INSTANCE_HELP_STR
13047 BGP_AFI_HELP_STR
13048 BGP_SAFI_WITH_LABEL_HELP_STR
13049 "Display routes matching the AS path regular expression\n"
13050 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13051 JSON_STR)
13052 {
13053 afi_t afi = AFI_IP6;
13054 safi_t safi = SAFI_UNICAST;
13055 struct bgp *bgp = NULL;
13056 bool uj = use_json(argc, argv);
13057 char *regstr = NULL;
13058
13059 int idx = 0;
13060 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13061 &bgp, false);
13062 if (!idx)
13063 return CMD_WARNING;
13064
13065 // get index of regex
13066 if (argv_find(argv, argc, "REGEX", &idx))
13067 regstr = argv[idx]->arg;
13068
13069 assert(regstr);
13070 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13071 bgp_show_type_regexp, uj);
13072 }
13073
13074 DEFPY (show_ip_bgp_instance_all,
13075 show_ip_bgp_instance_all_cmd,
13076 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13077 SHOW_STR
13078 IP_STR
13079 BGP_STR
13080 BGP_INSTANCE_ALL_HELP_STR
13081 BGP_AFI_HELP_STR
13082 BGP_SAFI_WITH_LABEL_HELP_STR
13083 JSON_STR
13084 "Increase table width for longer prefixes\n")
13085 {
13086 afi_t afi = AFI_IP6;
13087 safi_t safi = SAFI_UNICAST;
13088 struct bgp *bgp = NULL;
13089 int idx = 0;
13090 uint16_t show_flags = 0;
13091
13092 if (uj) {
13093 argc--;
13094 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13095 }
13096
13097 if (wide)
13098 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13099
13100 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13101 &bgp, uj);
13102 if (!idx)
13103 return CMD_WARNING;
13104
13105 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13106 return CMD_SUCCESS;
13107 }
13108
13109 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13110 afi_t afi, safi_t safi, enum bgp_show_type type,
13111 bool use_json)
13112 {
13113 regex_t *regex;
13114 int rc;
13115 uint16_t show_flags = 0;
13116
13117 if (use_json)
13118 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13119
13120 if (!config_bgp_aspath_validate(regstr)) {
13121 vty_out(vty, "Invalid character in REGEX %s\n",
13122 regstr);
13123 return CMD_WARNING_CONFIG_FAILED;
13124 }
13125
13126 regex = bgp_regcomp(regstr);
13127 if (!regex) {
13128 vty_out(vty, "Can't compile regexp %s\n", regstr);
13129 return CMD_WARNING;
13130 }
13131
13132 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13133 RPKI_NOT_BEING_USED);
13134 bgp_regex_free(regex);
13135 return rc;
13136 }
13137
13138 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13139 const char *comstr, int exact, afi_t afi,
13140 safi_t safi, uint16_t show_flags)
13141 {
13142 struct community *com;
13143 int ret = 0;
13144
13145 com = community_str2com(comstr);
13146 if (!com) {
13147 vty_out(vty, "%% Community malformed: %s\n", comstr);
13148 return CMD_WARNING;
13149 }
13150
13151 ret = bgp_show(vty, bgp, afi, safi,
13152 (exact ? bgp_show_type_community_exact
13153 : bgp_show_type_community),
13154 com, show_flags, RPKI_NOT_BEING_USED);
13155 community_free(&com);
13156
13157 return ret;
13158 }
13159
13160 enum bgp_stats {
13161 BGP_STATS_MAXBITLEN = 0,
13162 BGP_STATS_RIB,
13163 BGP_STATS_PREFIXES,
13164 BGP_STATS_TOTPLEN,
13165 BGP_STATS_UNAGGREGATEABLE,
13166 BGP_STATS_MAX_AGGREGATEABLE,
13167 BGP_STATS_AGGREGATES,
13168 BGP_STATS_SPACE,
13169 BGP_STATS_ASPATH_COUNT,
13170 BGP_STATS_ASPATH_MAXHOPS,
13171 BGP_STATS_ASPATH_TOTHOPS,
13172 BGP_STATS_ASPATH_MAXSIZE,
13173 BGP_STATS_ASPATH_TOTSIZE,
13174 BGP_STATS_ASN_HIGHEST,
13175 BGP_STATS_MAX,
13176 };
13177
13178 #define TABLE_STATS_IDX_VTY 0
13179 #define TABLE_STATS_IDX_JSON 1
13180
13181 static const char *table_stats_strs[][2] = {
13182 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13183 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13184 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13185 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13186 "unaggregateablePrefixes"},
13187 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13188 "maximumAggregateablePrefixes"},
13189 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13190 "bgpAggregateAdvertisements"},
13191 [BGP_STATS_SPACE] = {"Address space advertised",
13192 "addressSpaceAdvertised"},
13193 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13194 "advertisementsWithPaths"},
13195 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13196 "longestAsPath"},
13197 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13198 "largestAsPath"},
13199 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13200 "averageAsPathLengthHops"},
13201 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13202 "averageAsPathSizeBytes"},
13203 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13204 [BGP_STATS_MAX] = {NULL, NULL}
13205 };
13206
13207 struct bgp_table_stats {
13208 struct bgp_table *table;
13209 unsigned long long counts[BGP_STATS_MAX];
13210
13211 unsigned long long
13212 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13213 1];
13214
13215 double total_space;
13216 };
13217
13218 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13219 struct bgp_table_stats *ts, unsigned int space)
13220 {
13221 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13222 struct bgp_path_info *pi;
13223 const struct prefix *rn_p;
13224
13225 if (!bgp_dest_has_bgp_path_info_data(dest))
13226 return;
13227
13228 rn_p = bgp_dest_get_prefix(dest);
13229 ts->counts[BGP_STATS_PREFIXES]++;
13230 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13231
13232 ts->prefix_len_count[rn_p->prefixlen]++;
13233 /* check if the prefix is included by any other announcements */
13234 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13235 pdest = bgp_dest_parent_nolock(pdest);
13236
13237 if (pdest == NULL || pdest == top) {
13238 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13239 /* announced address space */
13240 if (space)
13241 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13242 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13243 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13244
13245
13246 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13247 ts->counts[BGP_STATS_RIB]++;
13248
13249 if (CHECK_FLAG(pi->attr->flag,
13250 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13251 ts->counts[BGP_STATS_AGGREGATES]++;
13252
13253 /* as-path stats */
13254 if (pi->attr->aspath) {
13255 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13256 unsigned int size = aspath_size(pi->attr->aspath);
13257 as_t highest = aspath_highest(pi->attr->aspath);
13258
13259 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13260
13261 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13262 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13263
13264 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13265 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13266
13267 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13268 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13269 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13270 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13271 }
13272 }
13273 }
13274
13275 static void bgp_table_stats_walker(struct thread *t)
13276 {
13277 struct bgp_dest *dest, *ndest;
13278 struct bgp_dest *top;
13279 struct bgp_table_stats *ts = THREAD_ARG(t);
13280 unsigned int space = 0;
13281
13282 if (!(top = bgp_table_top(ts->table)))
13283 return;
13284
13285 switch (ts->table->afi) {
13286 case AFI_IP:
13287 space = IPV4_MAX_BITLEN;
13288 break;
13289 case AFI_IP6:
13290 space = IPV6_MAX_BITLEN;
13291 break;
13292 case AFI_L2VPN:
13293 space = EVPN_ROUTE_PREFIXLEN;
13294 break;
13295 case AFI_UNSPEC:
13296 case AFI_MAX:
13297 return;
13298 }
13299
13300 ts->counts[BGP_STATS_MAXBITLEN] = space;
13301
13302 for (dest = top; dest; dest = bgp_route_next(dest)) {
13303 if (ts->table->safi == SAFI_MPLS_VPN
13304 || ts->table->safi == SAFI_ENCAP
13305 || ts->table->safi == SAFI_EVPN) {
13306 struct bgp_table *table;
13307
13308 table = bgp_dest_get_bgp_table_info(dest);
13309 if (!table)
13310 continue;
13311
13312 top = bgp_table_top(table);
13313 for (ndest = bgp_table_top(table); ndest;
13314 ndest = bgp_route_next(ndest))
13315 bgp_table_stats_rn(ndest, top, ts, space);
13316 } else {
13317 bgp_table_stats_rn(dest, top, ts, space);
13318 }
13319 }
13320 }
13321
13322 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13323 struct json_object *json_array)
13324 {
13325 struct listnode *node, *nnode;
13326 struct bgp *bgp;
13327
13328 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13329 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13330 }
13331
13332 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13333 safi_t safi, struct json_object *json_array)
13334 {
13335 struct bgp_table_stats ts;
13336 unsigned int i;
13337 int ret = CMD_SUCCESS;
13338 char temp_buf[20];
13339 struct json_object *json = NULL;
13340 uint32_t bitlen = 0;
13341 struct json_object *json_bitlen;
13342
13343 if (json_array)
13344 json = json_object_new_object();
13345
13346 if (!bgp->rib[afi][safi]) {
13347 char warning_msg[50];
13348
13349 snprintf(warning_msg, sizeof(warning_msg),
13350 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13351 safi);
13352
13353 if (!json)
13354 vty_out(vty, "%s\n", warning_msg);
13355 else
13356 json_object_string_add(json, "warning", warning_msg);
13357
13358 ret = CMD_WARNING;
13359 goto end_table_stats;
13360 }
13361
13362 if (!json)
13363 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13364 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13365 else
13366 json_object_string_add(json, "instance", bgp->name_pretty);
13367
13368 /* labeled-unicast routes live in the unicast table */
13369 if (safi == SAFI_LABELED_UNICAST)
13370 safi = SAFI_UNICAST;
13371
13372 memset(&ts, 0, sizeof(ts));
13373 ts.table = bgp->rib[afi][safi];
13374 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13375
13376 for (i = 0; i < BGP_STATS_MAX; i++) {
13377 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13378 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13379 continue;
13380
13381 switch (i) {
13382 case BGP_STATS_ASPATH_TOTHOPS:
13383 case BGP_STATS_ASPATH_TOTSIZE:
13384 if (!json) {
13385 snprintf(
13386 temp_buf, sizeof(temp_buf), "%12.2f",
13387 ts.counts[i]
13388 ? (float)ts.counts[i]
13389 / (float)ts.counts
13390 [BGP_STATS_ASPATH_COUNT]
13391 : 0);
13392 vty_out(vty, "%-30s: %s",
13393 table_stats_strs[i]
13394 [TABLE_STATS_IDX_VTY],
13395 temp_buf);
13396 } else {
13397 json_object_double_add(
13398 json,
13399 table_stats_strs[i]
13400 [TABLE_STATS_IDX_JSON],
13401 ts.counts[i]
13402 ? (double)ts.counts[i]
13403 / (double)ts.counts
13404 [BGP_STATS_ASPATH_COUNT]
13405 : 0);
13406 }
13407 break;
13408 case BGP_STATS_TOTPLEN:
13409 if (!json) {
13410 snprintf(
13411 temp_buf, sizeof(temp_buf), "%12.2f",
13412 ts.counts[i]
13413 ? (float)ts.counts[i]
13414 / (float)ts.counts
13415 [BGP_STATS_PREFIXES]
13416 : 0);
13417 vty_out(vty, "%-30s: %s",
13418 table_stats_strs[i]
13419 [TABLE_STATS_IDX_VTY],
13420 temp_buf);
13421 } else {
13422 json_object_double_add(
13423 json,
13424 table_stats_strs[i]
13425 [TABLE_STATS_IDX_JSON],
13426 ts.counts[i]
13427 ? (double)ts.counts[i]
13428 / (double)ts.counts
13429 [BGP_STATS_PREFIXES]
13430 : 0);
13431 }
13432 break;
13433 case BGP_STATS_SPACE:
13434 if (!json) {
13435 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13436 ts.total_space);
13437 vty_out(vty, "%-30s: %s\n",
13438 table_stats_strs[i]
13439 [TABLE_STATS_IDX_VTY],
13440 temp_buf);
13441 } else {
13442 json_object_double_add(
13443 json,
13444 table_stats_strs[i]
13445 [TABLE_STATS_IDX_JSON],
13446 (double)ts.total_space);
13447 }
13448 if (afi == AFI_IP6) {
13449 if (!json) {
13450 snprintf(temp_buf, sizeof(temp_buf),
13451 "%12g",
13452 ts.total_space
13453 * pow(2.0, -128 + 32));
13454 vty_out(vty, "%30s: %s\n",
13455 "/32 equivalent %s\n",
13456 temp_buf);
13457 } else {
13458 json_object_double_add(
13459 json, "/32equivalent",
13460 (double)(ts.total_space
13461 * pow(2.0,
13462 -128 + 32)));
13463 }
13464 if (!json) {
13465 snprintf(temp_buf, sizeof(temp_buf),
13466 "%12g",
13467 ts.total_space
13468 * pow(2.0, -128 + 48));
13469 vty_out(vty, "%30s: %s\n",
13470 "/48 equivalent %s\n",
13471 temp_buf);
13472 } else {
13473 json_object_double_add(
13474 json, "/48equivalent",
13475 (double)(ts.total_space
13476 * pow(2.0,
13477 -128 + 48)));
13478 }
13479 } else {
13480 if (!json) {
13481 snprintf(temp_buf, sizeof(temp_buf),
13482 "%12.2f",
13483 ts.total_space * 100.
13484 * pow(2.0, -32));
13485 vty_out(vty, "%30s: %s\n",
13486 "% announced ", temp_buf);
13487 } else {
13488 json_object_double_add(
13489 json, "%announced",
13490 (double)(ts.total_space * 100.
13491 * pow(2.0, -32)));
13492 }
13493 if (!json) {
13494 snprintf(temp_buf, sizeof(temp_buf),
13495 "%12.2f",
13496 ts.total_space
13497 * pow(2.0, -32 + 8));
13498 vty_out(vty, "%30s: %s\n",
13499 "/8 equivalent ", temp_buf);
13500 } else {
13501 json_object_double_add(
13502 json, "/8equivalent",
13503 (double)(ts.total_space
13504 * pow(2.0, -32 + 8)));
13505 }
13506 if (!json) {
13507 snprintf(temp_buf, sizeof(temp_buf),
13508 "%12.2f",
13509 ts.total_space
13510 * pow(2.0, -32 + 24));
13511 vty_out(vty, "%30s: %s\n",
13512 "/24 equivalent ", temp_buf);
13513 } else {
13514 json_object_double_add(
13515 json, "/24equivalent",
13516 (double)(ts.total_space
13517 * pow(2.0, -32 + 24)));
13518 }
13519 }
13520 break;
13521 default:
13522 if (!json) {
13523 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13524 ts.counts[i]);
13525 vty_out(vty, "%-30s: %s",
13526 table_stats_strs[i]
13527 [TABLE_STATS_IDX_VTY],
13528 temp_buf);
13529 } else {
13530 json_object_int_add(
13531 json,
13532 table_stats_strs[i]
13533 [TABLE_STATS_IDX_JSON],
13534 ts.counts[i]);
13535 }
13536 }
13537 if (!json)
13538 vty_out(vty, "\n");
13539 }
13540
13541 switch (afi) {
13542 case AFI_IP:
13543 bitlen = IPV4_MAX_BITLEN;
13544 break;
13545 case AFI_IP6:
13546 bitlen = IPV6_MAX_BITLEN;
13547 break;
13548 case AFI_L2VPN:
13549 bitlen = EVPN_ROUTE_PREFIXLEN;
13550 break;
13551 case AFI_UNSPEC:
13552 case AFI_MAX:
13553 break;
13554 }
13555
13556 if (json) {
13557 json_bitlen = json_object_new_array();
13558
13559 for (i = 0; i <= bitlen; i++) {
13560 struct json_object *ind_bit = json_object_new_object();
13561
13562 if (!ts.prefix_len_count[i])
13563 continue;
13564
13565 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13566 json_object_int_add(ind_bit, temp_buf,
13567 ts.prefix_len_count[i]);
13568 json_object_array_add(json_bitlen, ind_bit);
13569 }
13570 json_object_object_add(json, "prefixLength", json_bitlen);
13571 }
13572
13573 end_table_stats:
13574 if (json)
13575 json_object_array_add(json_array, json);
13576 return ret;
13577 }
13578
13579 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13580 safi_t safi, struct json_object *json_array)
13581 {
13582 if (!bgp) {
13583 bgp_table_stats_all(vty, afi, safi, json_array);
13584 return CMD_SUCCESS;
13585 }
13586
13587 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13588 }
13589
13590 enum bgp_pcounts {
13591 PCOUNT_ADJ_IN = 0,
13592 PCOUNT_DAMPED,
13593 PCOUNT_REMOVED,
13594 PCOUNT_HISTORY,
13595 PCOUNT_STALE,
13596 PCOUNT_VALID,
13597 PCOUNT_ALL,
13598 PCOUNT_COUNTED,
13599 PCOUNT_BPATH_SELECTED,
13600 PCOUNT_PFCNT, /* the figure we display to users */
13601 PCOUNT_MAX,
13602 };
13603
13604 static const char *const pcount_strs[] = {
13605 [PCOUNT_ADJ_IN] = "Adj-in",
13606 [PCOUNT_DAMPED] = "Damped",
13607 [PCOUNT_REMOVED] = "Removed",
13608 [PCOUNT_HISTORY] = "History",
13609 [PCOUNT_STALE] = "Stale",
13610 [PCOUNT_VALID] = "Valid",
13611 [PCOUNT_ALL] = "All RIB",
13612 [PCOUNT_COUNTED] = "PfxCt counted",
13613 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13614 [PCOUNT_PFCNT] = "Useable",
13615 [PCOUNT_MAX] = NULL,
13616 };
13617
13618 struct peer_pcounts {
13619 unsigned int count[PCOUNT_MAX];
13620 const struct peer *peer;
13621 const struct bgp_table *table;
13622 safi_t safi;
13623 };
13624
13625 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13626 {
13627 const struct bgp_adj_in *ain;
13628 const struct bgp_path_info *pi;
13629 const struct peer *peer = pc->peer;
13630
13631 for (ain = rn->adj_in; ain; ain = ain->next)
13632 if (ain->peer == peer)
13633 pc->count[PCOUNT_ADJ_IN]++;
13634
13635 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13636
13637 if (pi->peer != peer)
13638 continue;
13639
13640 pc->count[PCOUNT_ALL]++;
13641
13642 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13643 pc->count[PCOUNT_DAMPED]++;
13644 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13645 pc->count[PCOUNT_HISTORY]++;
13646 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13647 pc->count[PCOUNT_REMOVED]++;
13648 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13649 pc->count[PCOUNT_STALE]++;
13650 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13651 pc->count[PCOUNT_VALID]++;
13652 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13653 pc->count[PCOUNT_PFCNT]++;
13654 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13655 pc->count[PCOUNT_BPATH_SELECTED]++;
13656
13657 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13658 pc->count[PCOUNT_COUNTED]++;
13659 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13660 flog_err(
13661 EC_LIB_DEVELOPMENT,
13662 "Attempting to count but flags say it is unusable");
13663 } else {
13664 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13665 flog_err(
13666 EC_LIB_DEVELOPMENT,
13667 "Not counted but flags say we should");
13668 }
13669 }
13670 }
13671
13672 static void bgp_peer_count_walker(struct thread *t)
13673 {
13674 struct bgp_dest *rn, *rm;
13675 const struct bgp_table *table;
13676 struct peer_pcounts *pc = THREAD_ARG(t);
13677
13678 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13679 || pc->safi == SAFI_EVPN) {
13680 /* Special handling for 2-level routing tables. */
13681 for (rn = bgp_table_top(pc->table); rn;
13682 rn = bgp_route_next(rn)) {
13683 table = bgp_dest_get_bgp_table_info(rn);
13684 if (table != NULL)
13685 for (rm = bgp_table_top(table); rm;
13686 rm = bgp_route_next(rm))
13687 bgp_peer_count_proc(rm, pc);
13688 }
13689 } else
13690 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13691 bgp_peer_count_proc(rn, pc);
13692 }
13693
13694 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13695 safi_t safi, bool use_json)
13696 {
13697 struct peer_pcounts pcounts = {.peer = peer};
13698 unsigned int i;
13699 json_object *json = NULL;
13700 json_object *json_loop = NULL;
13701
13702 if (use_json) {
13703 json = json_object_new_object();
13704 json_loop = json_object_new_object();
13705 }
13706
13707 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13708 || !peer->bgp->rib[afi][safi]) {
13709 if (use_json) {
13710 json_object_string_add(
13711 json, "warning",
13712 "No such neighbor or address family");
13713 vty_out(vty, "%s\n", json_object_to_json_string(json));
13714 json_object_free(json);
13715 json_object_free(json_loop);
13716 } else
13717 vty_out(vty, "%% No such neighbor or address family\n");
13718
13719 return CMD_WARNING;
13720 }
13721
13722 memset(&pcounts, 0, sizeof(pcounts));
13723 pcounts.peer = peer;
13724 pcounts.table = peer->bgp->rib[afi][safi];
13725 pcounts.safi = safi;
13726
13727 /* in-place call via thread subsystem so as to record execution time
13728 * stats for the thread-walk (i.e. ensure this can't be blamed on
13729 * on just vty_read()).
13730 */
13731 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13732
13733 if (use_json) {
13734 json_object_string_add(json, "prefixCountsFor", peer->host);
13735 json_object_string_add(json, "multiProtocol",
13736 get_afi_safi_str(afi, safi, true));
13737 json_object_int_add(json, "pfxCounter",
13738 peer->pcount[afi][safi]);
13739
13740 for (i = 0; i < PCOUNT_MAX; i++)
13741 json_object_int_add(json_loop, pcount_strs[i],
13742 pcounts.count[i]);
13743
13744 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13745
13746 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13747 json_object_string_add(json, "pfxctDriftFor",
13748 peer->host);
13749 json_object_string_add(
13750 json, "recommended",
13751 "Please report this bug, with the above command output");
13752 }
13753 vty_json(vty, json);
13754 } else {
13755
13756 if (peer->hostname
13757 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13758 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13759 peer->hostname, peer->host,
13760 get_afi_safi_str(afi, safi, false));
13761 } else {
13762 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13763 get_afi_safi_str(afi, safi, false));
13764 }
13765
13766 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13767 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13768
13769 for (i = 0; i < PCOUNT_MAX; i++)
13770 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13771 pcounts.count[i]);
13772
13773 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13774 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13775 vty_out(vty,
13776 "Please report this bug, with the above command output\n");
13777 }
13778 }
13779
13780 return CMD_SUCCESS;
13781 }
13782
13783 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13784 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13785 "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]",
13786 SHOW_STR
13787 IP_STR
13788 BGP_STR
13789 BGP_INSTANCE_HELP_STR
13790 BGP_AFI_HELP_STR
13791 BGP_SAFI_HELP_STR
13792 "Detailed information on TCP and BGP neighbor connections\n"
13793 "Neighbor to display information about\n"
13794 "Neighbor to display information about\n"
13795 "Neighbor on BGP configured interface\n"
13796 "Display detailed prefix count information\n"
13797 JSON_STR)
13798 {
13799 afi_t afi = AFI_IP6;
13800 safi_t safi = SAFI_UNICAST;
13801 struct peer *peer;
13802 int idx = 0;
13803 struct bgp *bgp = NULL;
13804 bool uj = use_json(argc, argv);
13805
13806 if (uj)
13807 argc--;
13808
13809 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13810 &bgp, uj);
13811 if (!idx)
13812 return CMD_WARNING;
13813
13814 argv_find(argv, argc, "neighbors", &idx);
13815 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13816 if (!peer)
13817 return CMD_WARNING;
13818
13819 return bgp_peer_counts(vty, peer, afi, safi, uj);
13820 }
13821
13822 #ifdef KEEP_OLD_VPN_COMMANDS
13823 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13824 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13825 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13826 SHOW_STR
13827 IP_STR
13828 BGP_STR
13829 BGP_VPNVX_HELP_STR
13830 "Display information about all VPNv4 NLRIs\n"
13831 "Detailed information on TCP and BGP neighbor connections\n"
13832 "Neighbor to display information about\n"
13833 "Neighbor to display information about\n"
13834 "Neighbor on BGP configured interface\n"
13835 "Display detailed prefix count information\n"
13836 JSON_STR)
13837 {
13838 int idx_peer = 6;
13839 struct peer *peer;
13840 bool uj = use_json(argc, argv);
13841
13842 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13843 if (!peer)
13844 return CMD_WARNING;
13845
13846 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13847 }
13848
13849 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13850 show_ip_bgp_vpn_all_route_prefix_cmd,
13851 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13852 SHOW_STR
13853 IP_STR
13854 BGP_STR
13855 BGP_VPNVX_HELP_STR
13856 "Display information about all VPNv4 NLRIs\n"
13857 "Network in the BGP routing table to display\n"
13858 "Network in the BGP routing table to display\n"
13859 JSON_STR)
13860 {
13861 int idx = 0;
13862 char *network = NULL;
13863 struct bgp *bgp = bgp_get_default();
13864 if (!bgp) {
13865 vty_out(vty, "Can't find default instance\n");
13866 return CMD_WARNING;
13867 }
13868
13869 if (argv_find(argv, argc, "A.B.C.D", &idx))
13870 network = argv[idx]->arg;
13871 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13872 network = argv[idx]->arg;
13873 else {
13874 vty_out(vty, "Unable to figure out Network\n");
13875 return CMD_WARNING;
13876 }
13877
13878 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13879 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13880 use_json(argc, argv));
13881 }
13882 #endif /* KEEP_OLD_VPN_COMMANDS */
13883
13884 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13885 show_bgp_l2vpn_evpn_route_prefix_cmd,
13886 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13887 SHOW_STR
13888 BGP_STR
13889 L2VPN_HELP_STR
13890 EVPN_HELP_STR
13891 "Network in the BGP routing table to display\n"
13892 "Network in the BGP routing table to display\n"
13893 "Network in the BGP routing table to display\n"
13894 "Network in the BGP routing table to display\n"
13895 JSON_STR)
13896 {
13897 int idx = 0;
13898 char *network = NULL;
13899 int prefix_check = 0;
13900
13901 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13902 argv_find(argv, argc, "X:X::X:X", &idx))
13903 network = argv[idx]->arg;
13904 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13905 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13906 network = argv[idx]->arg;
13907 prefix_check = 1;
13908 } else {
13909 vty_out(vty, "Unable to figure out Network\n");
13910 return CMD_WARNING;
13911 }
13912 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13913 prefix_check, BGP_PATH_SHOW_ALL,
13914 RPKI_NOT_BEING_USED, use_json(argc, argv));
13915 }
13916
13917 static void show_adj_route_header(struct vty *vty, struct peer *peer,
13918 struct bgp_table *table, int *header1,
13919 int *header2, json_object *json,
13920 json_object *json_scode,
13921 json_object *json_ocode, bool wide,
13922 bool detail)
13923 {
13924 uint64_t version = table ? table->version : 0;
13925
13926 if (*header1) {
13927 if (json) {
13928 json_object_int_add(json, "bgpTableVersion", version);
13929 json_object_string_addf(json, "bgpLocalRouterId",
13930 "%pI4", &peer->bgp->router_id);
13931 json_object_int_add(json, "defaultLocPrf",
13932 peer->bgp->default_local_pref);
13933 json_object_int_add(json, "localAS",
13934 peer->change_local_as
13935 ? peer->change_local_as
13936 : peer->local_as);
13937 json_object_object_add(json, "bgpStatusCodes",
13938 json_scode);
13939 json_object_object_add(json, "bgpOriginCodes",
13940 json_ocode);
13941 } else {
13942 vty_out(vty,
13943 "BGP table version is %" PRIu64
13944 ", local router ID is %pI4, vrf id ",
13945 version, &peer->bgp->router_id);
13946 if (peer->bgp->vrf_id == VRF_UNKNOWN)
13947 vty_out(vty, "%s", VRFID_NONE_STR);
13948 else
13949 vty_out(vty, "%u", peer->bgp->vrf_id);
13950 vty_out(vty, "\n");
13951 vty_out(vty, "Default local pref %u, ",
13952 peer->bgp->default_local_pref);
13953 vty_out(vty, "local AS %u\n",
13954 peer->change_local_as ? peer->change_local_as
13955 : peer->local_as);
13956 if (!detail) {
13957 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13958 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13959 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13960 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13961 }
13962 }
13963 *header1 = 0;
13964 }
13965 if (*header2) {
13966 if (!json && !detail)
13967 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
13968 : BGP_SHOW_HEADER));
13969 *header2 = 0;
13970 }
13971 }
13972
13973 static void
13974 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
13975 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
13976 const char *rmap_name, json_object *json, json_object *json_ar,
13977 json_object *json_scode, json_object *json_ocode,
13978 uint16_t show_flags, int *header1, int *header2, char *rd_str,
13979 const struct prefix *match, unsigned long *output_count,
13980 unsigned long *filtered_count)
13981 {
13982 struct bgp_adj_in *ain = NULL;
13983 struct bgp_adj_out *adj = NULL;
13984 struct bgp_dest *dest;
13985 struct bgp *bgp;
13986 struct attr attr;
13987 int ret;
13988 struct update_subgroup *subgrp;
13989 struct peer_af *paf = NULL;
13990 bool route_filtered;
13991 bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
13992 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13993 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13994 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13995 || (safi == SAFI_EVPN))
13996 ? true
13997 : false;
13998 int display = 0;
13999 json_object *json_net = NULL;
14000
14001 bgp = peer->bgp;
14002
14003 /* If the user supplied a prefix, look for a matching route instead
14004 * of walking the whole table.
14005 */
14006 if (match) {
14007 dest = bgp_node_match(table, match);
14008 if (!dest) {
14009 if (!use_json)
14010 vty_out(vty, "Network not in table\n");
14011 return;
14012 }
14013
14014 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14015
14016 if (rn_p->prefixlen != match->prefixlen) {
14017 if (!use_json)
14018 vty_out(vty, "Network not in table\n");
14019 bgp_dest_unlock_node(dest);
14020 return;
14021 }
14022
14023 if (type == bgp_show_adj_route_received ||
14024 type == bgp_show_adj_route_filtered) {
14025 for (ain = dest->adj_in; ain; ain = ain->next) {
14026 if (ain->peer == peer) {
14027 attr = *ain->attr;
14028 break;
14029 }
14030 }
14031 /* bail out if if adj_out is empty, or
14032 * if the prefix isn't in this peer's
14033 * adj_in
14034 */
14035 if (!ain || ain->peer != peer) {
14036 if (!use_json)
14037 vty_out(vty, "Network not in table\n");
14038 bgp_dest_unlock_node(dest);
14039 return;
14040 }
14041 } else if (type == bgp_show_adj_route_advertised) {
14042 bool peer_found = false;
14043
14044 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out) {
14045 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14046 if (paf->peer == peer && adj->attr) {
14047 attr = *adj->attr;
14048 peer_found = true;
14049 break;
14050 }
14051 }
14052 if (peer_found)
14053 break;
14054 }
14055 /* bail out if if adj_out is empty, or
14056 * if the prefix isn't in this peer's
14057 * adj_out
14058 */
14059 if (!paf || !peer_found) {
14060 if (!use_json)
14061 vty_out(vty, "Network not in table\n");
14062 bgp_dest_unlock_node(dest);
14063 return;
14064 }
14065 }
14066
14067 ret = bgp_output_modifier(peer, rn_p, &attr, afi, safi,
14068 rmap_name);
14069
14070 if (ret != RMAP_DENY) {
14071 show_adj_route_header(vty, peer, table, header1,
14072 header2, json, json_scode,
14073 json_ocode, wide, detail);
14074
14075 if (use_json)
14076 json_net = json_object_new_object();
14077
14078 bgp_show_path_info(NULL /* prefix_rd */, dest, vty, bgp,
14079 afi, safi, json_net,
14080 BGP_PATH_SHOW_ALL, &display,
14081 RPKI_NOT_BEING_USED);
14082 if (use_json)
14083 json_object_object_addf(json_ar, json_net,
14084 "%pFX", rn_p);
14085 (*output_count)++;
14086 } else
14087 (*filtered_count)++;
14088
14089 bgp_attr_flush(&attr);
14090 bgp_dest_unlock_node(dest);
14091 return;
14092 }
14093
14094
14095 subgrp = peer_subgroup(peer, afi, safi);
14096
14097 if (type == bgp_show_adj_route_advertised && subgrp
14098 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
14099 if (use_json) {
14100 json_object_int_add(json, "bgpTableVersion",
14101 table->version);
14102 json_object_string_addf(json, "bgpLocalRouterId",
14103 "%pI4", &bgp->router_id);
14104 json_object_int_add(json, "defaultLocPrf",
14105 bgp->default_local_pref);
14106 json_object_int_add(json, "localAS",
14107 peer->change_local_as
14108 ? peer->change_local_as
14109 : peer->local_as);
14110 json_object_object_add(json, "bgpStatusCodes",
14111 json_scode);
14112 json_object_object_add(json, "bgpOriginCodes",
14113 json_ocode);
14114 json_object_string_add(
14115 json, "bgpOriginatingDefaultNetwork",
14116 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14117 } else {
14118 vty_out(vty,
14119 "BGP table version is %" PRIu64
14120 ", local router ID is %pI4, vrf id ",
14121 table->version, &bgp->router_id);
14122 if (bgp->vrf_id == VRF_UNKNOWN)
14123 vty_out(vty, "%s", VRFID_NONE_STR);
14124 else
14125 vty_out(vty, "%u", bgp->vrf_id);
14126 vty_out(vty, "\n");
14127 vty_out(vty, "Default local pref %u, ",
14128 bgp->default_local_pref);
14129 vty_out(vty, "local AS %u\n",
14130 peer->change_local_as ? peer->change_local_as
14131 : peer->local_as);
14132 if (!detail) {
14133 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14134 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14135 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14136 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14137 }
14138
14139 vty_out(vty, "Originating default network %s\n\n",
14140 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14141 }
14142 (*output_count)++;
14143 *header1 = 0;
14144 }
14145
14146 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14147 if (type == bgp_show_adj_route_received
14148 || type == bgp_show_adj_route_filtered) {
14149 for (ain = dest->adj_in; ain; ain = ain->next) {
14150 if (ain->peer != peer)
14151 continue;
14152
14153 show_adj_route_header(vty, peer, table, header1,
14154 header2, json, json_scode,
14155 json_ocode, wide, detail);
14156
14157 if ((safi == SAFI_MPLS_VPN)
14158 || (safi == SAFI_ENCAP)
14159 || (safi == SAFI_EVPN)) {
14160 if (use_json)
14161 json_object_string_add(
14162 json_ar, "rd", rd_str);
14163 else if (show_rd && rd_str) {
14164 vty_out(vty,
14165 "Route Distinguisher: %s\n",
14166 rd_str);
14167 show_rd = false;
14168 }
14169 }
14170
14171 attr = *ain->attr;
14172 route_filtered = false;
14173
14174 /* Filter prefix using distribute list,
14175 * filter list or prefix list
14176 */
14177 const struct prefix *rn_p =
14178 bgp_dest_get_prefix(dest);
14179 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14180 safi))
14181 == FILTER_DENY)
14182 route_filtered = true;
14183
14184 /* Filter prefix using route-map */
14185 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14186 safi, rmap_name, NULL,
14187 0, NULL);
14188
14189 if (type == bgp_show_adj_route_filtered &&
14190 !route_filtered && ret != RMAP_DENY) {
14191 bgp_attr_flush(&attr);
14192 continue;
14193 }
14194
14195 if (type == bgp_show_adj_route_received
14196 && (route_filtered || ret == RMAP_DENY))
14197 (*filtered_count)++;
14198
14199 if (detail) {
14200 if (use_json)
14201 json_net =
14202 json_object_new_object();
14203 bgp_show_path_info(
14204 NULL /* prefix_rd */, dest, vty,
14205 bgp, afi, safi, json_net,
14206 BGP_PATH_SHOW_ALL, &display,
14207 RPKI_NOT_BEING_USED);
14208 if (use_json)
14209 json_object_object_addf(
14210 json_ar, json_net,
14211 "%pFX", rn_p);
14212 } else
14213 route_vty_out_tmp(vty, dest, rn_p,
14214 &attr, safi, use_json,
14215 json_ar, wide);
14216 bgp_attr_flush(&attr);
14217 (*output_count)++;
14218 }
14219 } else if (type == bgp_show_adj_route_advertised) {
14220 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14221 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14222 if (paf->peer != peer || !adj->attr)
14223 continue;
14224
14225 show_adj_route_header(
14226 vty, peer, table, header1,
14227 header2, json, json_scode,
14228 json_ocode, wide, detail);
14229
14230 const struct prefix *rn_p =
14231 bgp_dest_get_prefix(dest);
14232
14233 attr = *adj->attr;
14234 ret = bgp_output_modifier(
14235 peer, rn_p, &attr, afi, safi,
14236 rmap_name);
14237
14238 if (ret != RMAP_DENY) {
14239 if ((safi == SAFI_MPLS_VPN)
14240 || (safi == SAFI_ENCAP)
14241 || (safi == SAFI_EVPN)) {
14242 if (use_json)
14243 json_object_string_add(
14244 json_ar,
14245 "rd",
14246 rd_str);
14247 else if (show_rd
14248 && rd_str) {
14249 vty_out(vty,
14250 "Route Distinguisher: %s\n",
14251 rd_str);
14252 show_rd = false;
14253 }
14254 }
14255 if (detail) {
14256 if (use_json)
14257 json_net =
14258 json_object_new_object();
14259 bgp_show_path_info(
14260 NULL /* prefix_rd
14261 */
14262 ,
14263 dest, vty, bgp,
14264 afi, safi,
14265 json_net,
14266 BGP_PATH_SHOW_ALL,
14267 &display,
14268 RPKI_NOT_BEING_USED);
14269 if (use_json)
14270 json_object_object_addf(
14271 json_ar,
14272 json_net,
14273 "%pFX",
14274 rn_p);
14275 } else
14276 route_vty_out_tmp(
14277 vty, dest, rn_p,
14278 &attr, safi,
14279 use_json,
14280 json_ar, wide);
14281 (*output_count)++;
14282 } else {
14283 (*filtered_count)++;
14284 }
14285
14286 bgp_attr_flush(&attr);
14287 }
14288 } else if (type == bgp_show_adj_route_bestpath) {
14289 struct bgp_path_info *pi;
14290
14291 show_adj_route_header(vty, peer, table, header1,
14292 header2, json, json_scode,
14293 json_ocode, wide, detail);
14294
14295 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14296
14297 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14298 pi = pi->next) {
14299 if (pi->peer != peer)
14300 continue;
14301
14302 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14303 continue;
14304
14305 if (detail) {
14306 if (use_json)
14307 json_net =
14308 json_object_new_object();
14309 bgp_show_path_info(
14310 NULL /* prefix_rd */, dest, vty,
14311 bgp, afi, safi, json_net,
14312 BGP_PATH_SHOW_BESTPATH,
14313 &display, RPKI_NOT_BEING_USED);
14314 if (use_json)
14315 json_object_object_addf(
14316 json_ar, json_net,
14317 "%pFX", rn_p);
14318 } else
14319 route_vty_out_tmp(
14320 vty, dest, rn_p, pi->attr, safi,
14321 use_json, json_ar, wide);
14322 (*output_count)++;
14323 }
14324 }
14325 }
14326 }
14327
14328 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14329 safi_t safi, enum bgp_show_adj_route_type type,
14330 const char *rmap_name, const struct prefix *match,
14331 uint16_t show_flags)
14332 {
14333 struct bgp *bgp;
14334 struct bgp_table *table;
14335 json_object *json = NULL;
14336 json_object *json_scode = NULL;
14337 json_object *json_ocode = NULL;
14338 json_object *json_ar = NULL;
14339 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14340
14341 /* Init BGP headers here so they're only displayed once
14342 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14343 */
14344 int header1 = 1;
14345 int header2 = 1;
14346
14347 /*
14348 * Initialize variables for each RD
14349 * All prefixes under an RD is aggregated within "json_routes"
14350 */
14351 char rd_str[BUFSIZ] = {0};
14352 json_object *json_routes = NULL;
14353
14354
14355 /* For 2-tier tables, prefix counts need to be
14356 * maintained across multiple runs of show_adj_route()
14357 */
14358 unsigned long output_count_per_rd;
14359 unsigned long filtered_count_per_rd;
14360 unsigned long output_count = 0;
14361 unsigned long filtered_count = 0;
14362
14363 if (use_json) {
14364 json = json_object_new_object();
14365 json_ar = json_object_new_object();
14366 json_scode = json_object_new_object();
14367 json_ocode = json_object_new_object();
14368 #if CONFDATE > 20231208
14369 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
14370 #endif
14371 json_object_string_add(json_scode, "suppressed", "s");
14372 json_object_string_add(json_scode, "damped", "d");
14373 json_object_string_add(json_scode, "history", "h");
14374 json_object_string_add(json_scode, "valid", "*");
14375 json_object_string_add(json_scode, "best", ">");
14376 json_object_string_add(json_scode, "multipath", "=");
14377 json_object_string_add(json_scode, "internal", "i");
14378 json_object_string_add(json_scode, "ribFailure", "r");
14379 json_object_string_add(json_scode, "stale", "S");
14380 json_object_string_add(json_scode, "removed", "R");
14381
14382 #if CONFDATE > 20231208
14383 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
14384 #endif
14385 json_object_string_add(json_ocode, "igp", "i");
14386 json_object_string_add(json_ocode, "egp", "e");
14387 json_object_string_add(json_ocode, "incomplete", "?");
14388 }
14389
14390 if (!peer || !peer->afc[afi][safi]) {
14391 if (use_json) {
14392 json_object_string_add(
14393 json, "warning",
14394 "No such neighbor or address family");
14395 vty_out(vty, "%s\n", json_object_to_json_string(json));
14396 json_object_free(json);
14397 json_object_free(json_ar);
14398 json_object_free(json_scode);
14399 json_object_free(json_ocode);
14400 } else
14401 vty_out(vty, "%% No such neighbor or address family\n");
14402
14403 return CMD_WARNING;
14404 }
14405
14406 if ((type == bgp_show_adj_route_received
14407 || type == bgp_show_adj_route_filtered)
14408 && !CHECK_FLAG(peer->af_flags[afi][safi],
14409 PEER_FLAG_SOFT_RECONFIG)) {
14410 if (use_json) {
14411 json_object_string_add(
14412 json, "warning",
14413 "Inbound soft reconfiguration not enabled");
14414 vty_out(vty, "%s\n", json_object_to_json_string(json));
14415 json_object_free(json);
14416 json_object_free(json_ar);
14417 json_object_free(json_scode);
14418 json_object_free(json_ocode);
14419 } else
14420 vty_out(vty,
14421 "%% Inbound soft reconfiguration not enabled\n");
14422
14423 return CMD_WARNING;
14424 }
14425
14426 bgp = peer->bgp;
14427
14428 /* labeled-unicast routes live in the unicast table */
14429 if (safi == SAFI_LABELED_UNICAST)
14430 table = bgp->rib[afi][SAFI_UNICAST];
14431 else
14432 table = bgp->rib[afi][safi];
14433
14434 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14435 || (safi == SAFI_EVPN)) {
14436
14437 struct bgp_dest *dest;
14438
14439 for (dest = bgp_table_top(table); dest;
14440 dest = bgp_route_next(dest)) {
14441 table = bgp_dest_get_bgp_table_info(dest);
14442 if (!table)
14443 continue;
14444
14445 output_count_per_rd = 0;
14446 filtered_count_per_rd = 0;
14447
14448 if (use_json)
14449 json_routes = json_object_new_object();
14450
14451 const struct prefix_rd *prd;
14452 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14453 dest);
14454
14455 prefix_rd2str(prd, rd_str, sizeof(rd_str));
14456
14457 show_adj_route(
14458 vty, peer, table, afi, safi, type, rmap_name,
14459 json, json_routes, json_scode, json_ocode,
14460 show_flags, &header1, &header2, rd_str, match,
14461 &output_count_per_rd, &filtered_count_per_rd);
14462
14463 /* Don't include an empty RD in the output! */
14464 if (json_routes && (output_count_per_rd > 0))
14465 json_object_object_add(json_ar, rd_str,
14466 json_routes);
14467
14468 output_count += output_count_per_rd;
14469 filtered_count += filtered_count_per_rd;
14470 }
14471 } else
14472 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14473 json, json_ar, json_scode, json_ocode,
14474 show_flags, &header1, &header2, rd_str, match,
14475 &output_count, &filtered_count);
14476
14477 if (use_json) {
14478 if (type == bgp_show_adj_route_advertised)
14479 json_object_object_add(json, "advertisedRoutes",
14480 json_ar);
14481 else
14482 json_object_object_add(json, "receivedRoutes", json_ar);
14483 json_object_int_add(json, "totalPrefixCounter", output_count);
14484 json_object_int_add(json, "filteredPrefixCounter",
14485 filtered_count);
14486
14487 /*
14488 * These fields only give up ownership to `json` when `header1`
14489 * is used (set to zero). See code in `show_adj_route` and
14490 * `show_adj_route_header`.
14491 */
14492 if (header1 == 1) {
14493 json_object_free(json_scode);
14494 json_object_free(json_ocode);
14495 }
14496
14497 vty_json(vty, json);
14498 } else if (output_count > 0) {
14499 if (!match && filtered_count > 0)
14500 vty_out(vty,
14501 "\nTotal number of prefixes %ld (%ld filtered)\n",
14502 output_count, filtered_count);
14503 else
14504 vty_out(vty, "\nTotal number of prefixes %ld\n",
14505 output_count);
14506 }
14507
14508 return CMD_SUCCESS;
14509 }
14510
14511 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14512 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14513 "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 [detail$detail] [json$uj | wide$wide]",
14514 SHOW_STR
14515 IP_STR
14516 BGP_STR
14517 BGP_INSTANCE_HELP_STR
14518 BGP_AFI_HELP_STR
14519 BGP_SAFI_WITH_LABEL_HELP_STR
14520 "Detailed information on TCP and BGP neighbor connections\n"
14521 "Neighbor to display information about\n"
14522 "Neighbor to display information about\n"
14523 "Neighbor on BGP configured interface\n"
14524 "Display the routes selected by best path\n"
14525 "Display detailed version of routes\n"
14526 JSON_STR
14527 "Increase table width for longer prefixes\n")
14528 {
14529 afi_t afi = AFI_IP6;
14530 safi_t safi = SAFI_UNICAST;
14531 char *rmap_name = NULL;
14532 char *peerstr = NULL;
14533 struct bgp *bgp = NULL;
14534 struct peer *peer;
14535 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14536 int idx = 0;
14537 uint16_t show_flags = 0;
14538
14539 if (detail)
14540 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14541
14542 if (uj)
14543 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14544
14545 if (wide)
14546 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14547
14548 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14549 &bgp, uj);
14550
14551 if (!idx)
14552 return CMD_WARNING;
14553
14554 argv_find(argv, argc, "neighbors", &idx);
14555 peerstr = argv[++idx]->arg;
14556
14557 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14558 if (!peer)
14559 return CMD_WARNING;
14560
14561 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, NULL,
14562 show_flags);
14563 }
14564
14565 DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
14566 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14567 "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] [<A.B.C.D/M|X:X::X:X/M>$prefix | detail$detail] [json$uj | wide$wide]",
14568 SHOW_STR
14569 IP_STR
14570 BGP_STR
14571 BGP_INSTANCE_HELP_STR
14572 BGP_AFI_HELP_STR
14573 BGP_SAFI_WITH_LABEL_HELP_STR
14574 "Display the entries for all address families\n"
14575 "Detailed information on TCP and BGP neighbor connections\n"
14576 "Neighbor to display information about\n"
14577 "Neighbor to display information about\n"
14578 "Neighbor on BGP configured interface\n"
14579 "Display the routes advertised to a BGP neighbor\n"
14580 "Display the received routes from neighbor\n"
14581 "Display the filtered routes received from neighbor\n"
14582 "Route-map to modify the attributes\n"
14583 "Name of the route map\n"
14584 "IPv4 prefix\n"
14585 "IPv6 prefix\n"
14586 "Display detailed version of routes\n"
14587 JSON_STR
14588 "Increase table width for longer prefixes\n")
14589 {
14590 afi_t afi = AFI_IP6;
14591 safi_t safi = SAFI_UNICAST;
14592 char *peerstr = NULL;
14593 struct bgp *bgp = NULL;
14594 struct peer *peer;
14595 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14596 int idx = 0;
14597 bool first = true;
14598 uint16_t show_flags = 0;
14599 struct listnode *node;
14600 struct bgp *abgp;
14601
14602 if (detail || prefix_str)
14603 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14604
14605 if (uj) {
14606 argc--;
14607 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14608 }
14609
14610 if (all) {
14611 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14612 if (argv_find(argv, argc, "ipv4", &idx))
14613 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14614
14615 if (argv_find(argv, argc, "ipv6", &idx))
14616 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14617 }
14618
14619 if (wide)
14620 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14621
14622 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14623 &bgp, uj);
14624 if (!idx)
14625 return CMD_WARNING;
14626
14627 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14628 argv_find(argv, argc, "neighbors", &idx);
14629 peerstr = argv[++idx]->arg;
14630
14631 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14632 if (!peer)
14633 return CMD_WARNING;
14634
14635 if (argv_find(argv, argc, "advertised-routes", &idx))
14636 type = bgp_show_adj_route_advertised;
14637 else if (argv_find(argv, argc, "received-routes", &idx))
14638 type = bgp_show_adj_route_received;
14639 else if (argv_find(argv, argc, "filtered-routes", &idx))
14640 type = bgp_show_adj_route_filtered;
14641
14642 if (!all)
14643 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14644 prefix_str ? prefix : NULL, show_flags);
14645 if (uj)
14646 vty_out(vty, "{\n");
14647
14648 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14649 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14650 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14651 : AFI_IP6;
14652 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14653 FOREACH_SAFI (safi) {
14654 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14655 continue;
14656
14657 if (uj) {
14658 if (first)
14659 first = false;
14660 else
14661 vty_out(vty, ",\n");
14662 vty_out(vty, "\"%s\":",
14663 get_afi_safi_str(afi, safi,
14664 true));
14665 } else
14666 vty_out(vty,
14667 "\nFor address family: %s\n",
14668 get_afi_safi_str(afi, safi,
14669 false));
14670
14671 peer_adj_routes(vty, peer, afi, safi, type,
14672 route_map, prefix, show_flags);
14673 }
14674 }
14675 } else {
14676 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14677 FOREACH_AFI_SAFI (afi, safi) {
14678 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14679 continue;
14680
14681 if (uj) {
14682 if (first)
14683 first = false;
14684 else
14685 vty_out(vty, ",\n");
14686 vty_out(vty, "\"%s\":",
14687 get_afi_safi_str(afi, safi,
14688 true));
14689 } else
14690 vty_out(vty,
14691 "\nFor address family: %s\n",
14692 get_afi_safi_str(afi, safi,
14693 false));
14694
14695 peer_adj_routes(vty, peer, afi, safi, type,
14696 route_map, prefix, show_flags);
14697 }
14698 }
14699 }
14700 if (uj)
14701 vty_out(vty, "}\n");
14702
14703 return CMD_SUCCESS;
14704 }
14705
14706 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14707 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14708 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14709 SHOW_STR
14710 IP_STR
14711 BGP_STR
14712 BGP_INSTANCE_HELP_STR
14713 BGP_AF_STR
14714 BGP_AF_STR
14715 BGP_AF_MODIFIER_STR
14716 "Detailed information on TCP and BGP neighbor connections\n"
14717 "Neighbor to display information about\n"
14718 "Neighbor to display information about\n"
14719 "Neighbor on BGP configured interface\n"
14720 "Display information received from a BGP neighbor\n"
14721 "Display the prefixlist filter\n"
14722 JSON_STR)
14723 {
14724 afi_t afi = AFI_IP6;
14725 safi_t safi = SAFI_UNICAST;
14726 char *peerstr = NULL;
14727 char name[BUFSIZ];
14728 struct peer *peer;
14729 int count;
14730 int idx = 0;
14731 struct bgp *bgp = NULL;
14732 bool uj = use_json(argc, argv);
14733
14734 if (uj)
14735 argc--;
14736
14737 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14738 &bgp, uj);
14739 if (!idx)
14740 return CMD_WARNING;
14741
14742 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14743 argv_find(argv, argc, "neighbors", &idx);
14744 peerstr = argv[++idx]->arg;
14745
14746 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14747 if (!peer)
14748 return CMD_WARNING;
14749
14750 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14751 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14752 if (count) {
14753 if (!uj)
14754 vty_out(vty, "Address Family: %s\n",
14755 get_afi_safi_str(afi, safi, false));
14756 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14757 } else {
14758 if (uj)
14759 vty_out(vty, "{}\n");
14760 else
14761 vty_out(vty, "No functional output\n");
14762 }
14763
14764 return CMD_SUCCESS;
14765 }
14766
14767 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14768 afi_t afi, safi_t safi,
14769 enum bgp_show_type type, bool use_json)
14770 {
14771 uint16_t show_flags = 0;
14772
14773 if (use_json)
14774 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14775
14776 if (!peer || !peer->afc[afi][safi]) {
14777 if (use_json) {
14778 json_object *json_no = NULL;
14779 json_no = json_object_new_object();
14780 json_object_string_add(
14781 json_no, "warning",
14782 "No such neighbor or address family");
14783 vty_out(vty, "%s\n",
14784 json_object_to_json_string(json_no));
14785 json_object_free(json_no);
14786 } else
14787 vty_out(vty, "%% No such neighbor or address family\n");
14788 return CMD_WARNING;
14789 }
14790
14791 /* labeled-unicast routes live in the unicast table */
14792 if (safi == SAFI_LABELED_UNICAST)
14793 safi = SAFI_UNICAST;
14794
14795 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14796 RPKI_NOT_BEING_USED);
14797 }
14798
14799 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14800 show_ip_bgp_flowspec_routes_detailed_cmd,
14801 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14802 SHOW_STR
14803 IP_STR
14804 BGP_STR
14805 BGP_INSTANCE_HELP_STR
14806 BGP_AFI_HELP_STR
14807 "SAFI Flowspec\n"
14808 "Detailed information on flowspec entries\n"
14809 JSON_STR)
14810 {
14811 afi_t afi = AFI_IP6;
14812 safi_t safi = SAFI_UNICAST;
14813 struct bgp *bgp = NULL;
14814 int idx = 0;
14815 bool uj = use_json(argc, argv);
14816 uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
14817
14818 if (uj) {
14819 argc--;
14820 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14821 }
14822
14823 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14824 &bgp, uj);
14825 if (!idx)
14826 return CMD_WARNING;
14827
14828 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14829 show_flags, RPKI_NOT_BEING_USED);
14830 }
14831
14832 DEFUN (show_ip_bgp_neighbor_routes,
14833 show_ip_bgp_neighbor_routes_cmd,
14834 "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]",
14835 SHOW_STR
14836 IP_STR
14837 BGP_STR
14838 BGP_INSTANCE_HELP_STR
14839 BGP_AFI_HELP_STR
14840 BGP_SAFI_WITH_LABEL_HELP_STR
14841 "Detailed information on TCP and BGP neighbor connections\n"
14842 "Neighbor to display information about\n"
14843 "Neighbor to display information about\n"
14844 "Neighbor on BGP configured interface\n"
14845 "Display flap statistics of the routes learned from neighbor\n"
14846 "Display the dampened routes received from neighbor\n"
14847 "Display routes learned from neighbor\n"
14848 JSON_STR)
14849 {
14850 char *peerstr = NULL;
14851 struct bgp *bgp = NULL;
14852 afi_t afi = AFI_IP6;
14853 safi_t safi = SAFI_UNICAST;
14854 struct peer *peer;
14855 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14856 int idx = 0;
14857 bool uj = use_json(argc, argv);
14858
14859 if (uj)
14860 argc--;
14861
14862 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14863 &bgp, uj);
14864 if (!idx)
14865 return CMD_WARNING;
14866
14867 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14868 argv_find(argv, argc, "neighbors", &idx);
14869 peerstr = argv[++idx]->arg;
14870
14871 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14872 if (!peer)
14873 return CMD_WARNING;
14874
14875 if (argv_find(argv, argc, "flap-statistics", &idx))
14876 sh_type = bgp_show_type_flap_neighbor;
14877 else if (argv_find(argv, argc, "dampened-routes", &idx))
14878 sh_type = bgp_show_type_damp_neighbor;
14879 else if (argv_find(argv, argc, "routes", &idx))
14880 sh_type = bgp_show_type_neighbor;
14881
14882 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14883 }
14884
14885 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14886
14887 struct bgp_distance {
14888 /* Distance value for the IP source prefix. */
14889 uint8_t distance;
14890
14891 /* Name of the access-list to be matched. */
14892 char *access_list;
14893 };
14894
14895 DEFUN (show_bgp_afi_vpn_rd_route,
14896 show_bgp_afi_vpn_rd_route_cmd,
14897 "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]",
14898 SHOW_STR
14899 BGP_STR
14900 BGP_AFI_HELP_STR
14901 BGP_AF_MODIFIER_STR
14902 "Display information for a route distinguisher\n"
14903 "Route Distinguisher\n"
14904 "All Route Distinguishers\n"
14905 "Network in the BGP routing table to display\n"
14906 "Network in the BGP routing table to display\n"
14907 JSON_STR)
14908 {
14909 int ret;
14910 struct prefix_rd prd;
14911 afi_t afi = AFI_MAX;
14912 int idx = 0;
14913
14914 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14915 vty_out(vty, "%% Malformed Address Family\n");
14916 return CMD_WARNING;
14917 }
14918
14919 if (!strcmp(argv[5]->arg, "all"))
14920 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14921 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14922 RPKI_NOT_BEING_USED,
14923 use_json(argc, argv));
14924
14925 ret = str2prefix_rd(argv[5]->arg, &prd);
14926 if (!ret) {
14927 vty_out(vty, "%% Malformed Route Distinguisher\n");
14928 return CMD_WARNING;
14929 }
14930
14931 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14932 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14933 use_json(argc, argv));
14934 }
14935
14936 static struct bgp_distance *bgp_distance_new(void)
14937 {
14938 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14939 }
14940
14941 static void bgp_distance_free(struct bgp_distance *bdistance)
14942 {
14943 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14944 }
14945
14946 static int bgp_distance_set(struct vty *vty, const char *distance_str,
14947 const char *ip_str, const char *access_list_str)
14948 {
14949 int ret;
14950 afi_t afi;
14951 safi_t safi;
14952 struct prefix p;
14953 uint8_t distance;
14954 struct bgp_dest *dest;
14955 struct bgp_distance *bdistance;
14956
14957 afi = bgp_node_afi(vty);
14958 safi = bgp_node_safi(vty);
14959
14960 ret = str2prefix(ip_str, &p);
14961 if (ret == 0) {
14962 vty_out(vty, "Malformed prefix\n");
14963 return CMD_WARNING_CONFIG_FAILED;
14964 }
14965
14966 distance = atoi(distance_str);
14967
14968 /* Get BGP distance node. */
14969 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
14970 bdistance = bgp_dest_get_bgp_distance_info(dest);
14971 if (bdistance)
14972 bgp_dest_unlock_node(dest);
14973 else {
14974 bdistance = bgp_distance_new();
14975 bgp_dest_set_bgp_distance_info(dest, bdistance);
14976 }
14977
14978 /* Set distance value. */
14979 bdistance->distance = distance;
14980
14981 /* Reset access-list configuration. */
14982 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14983 if (access_list_str)
14984 bdistance->access_list =
14985 XSTRDUP(MTYPE_AS_LIST, access_list_str);
14986
14987 return CMD_SUCCESS;
14988 }
14989
14990 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
14991 const char *ip_str, const char *access_list_str)
14992 {
14993 int ret;
14994 afi_t afi;
14995 safi_t safi;
14996 struct prefix p;
14997 int distance;
14998 struct bgp_dest *dest;
14999 struct bgp_distance *bdistance;
15000
15001 afi = bgp_node_afi(vty);
15002 safi = bgp_node_safi(vty);
15003
15004 ret = str2prefix(ip_str, &p);
15005 if (ret == 0) {
15006 vty_out(vty, "Malformed prefix\n");
15007 return CMD_WARNING_CONFIG_FAILED;
15008 }
15009
15010 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
15011 if (!dest) {
15012 vty_out(vty, "Can't find specified prefix\n");
15013 return CMD_WARNING_CONFIG_FAILED;
15014 }
15015
15016 bdistance = bgp_dest_get_bgp_distance_info(dest);
15017 distance = atoi(distance_str);
15018
15019 if (bdistance->distance != distance) {
15020 vty_out(vty, "Distance does not match configured\n");
15021 bgp_dest_unlock_node(dest);
15022 return CMD_WARNING_CONFIG_FAILED;
15023 }
15024
15025 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15026 bgp_distance_free(bdistance);
15027
15028 bgp_dest_set_bgp_path_info(dest, NULL);
15029 bgp_dest_unlock_node(dest);
15030 bgp_dest_unlock_node(dest);
15031
15032 return CMD_SUCCESS;
15033 }
15034
15035 /* Apply BGP information to distance method. */
15036 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
15037 afi_t afi, safi_t safi, struct bgp *bgp)
15038 {
15039 struct bgp_dest *dest;
15040 struct prefix q = {0};
15041 struct peer *peer;
15042 struct bgp_distance *bdistance;
15043 struct access_list *alist;
15044 struct bgp_static *bgp_static;
15045 struct bgp_path_info *bpi_ultimate;
15046
15047 if (!bgp)
15048 return 0;
15049
15050 peer = pinfo->peer;
15051
15052 if (pinfo->attr->distance)
15053 return pinfo->attr->distance;
15054
15055 /* get peer origin to calculate appropriate distance */
15056 if (pinfo->sub_type == BGP_ROUTE_IMPORTED) {
15057 bpi_ultimate = bgp_get_imported_bpi_ultimate(pinfo);
15058 peer = bpi_ultimate->peer;
15059 }
15060
15061 /* Check source address.
15062 * Note: for aggregate route, peer can have unspec af type.
15063 */
15064 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
15065 && !sockunion2hostprefix(&peer->su, &q))
15066 return 0;
15067
15068 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
15069 if (dest) {
15070 bdistance = bgp_dest_get_bgp_distance_info(dest);
15071 bgp_dest_unlock_node(dest);
15072
15073 if (bdistance->access_list) {
15074 alist = access_list_lookup(afi, bdistance->access_list);
15075 if (alist
15076 && access_list_apply(alist, p) == FILTER_PERMIT)
15077 return bdistance->distance;
15078 } else
15079 return bdistance->distance;
15080 }
15081
15082 /* Backdoor check. */
15083 dest = bgp_node_lookup(bgp->route[afi][safi], p);
15084 if (dest) {
15085 bgp_static = bgp_dest_get_bgp_static_info(dest);
15086 bgp_dest_unlock_node(dest);
15087
15088 if (bgp_static->backdoor) {
15089 if (bgp->distance_local[afi][safi])
15090 return bgp->distance_local[afi][safi];
15091 else
15092 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15093 }
15094 }
15095
15096 if (peer->sort == BGP_PEER_EBGP) {
15097 if (bgp->distance_ebgp[afi][safi])
15098 return bgp->distance_ebgp[afi][safi];
15099 return ZEBRA_EBGP_DISTANCE_DEFAULT;
15100 } else if (peer->sort == BGP_PEER_IBGP) {
15101 if (bgp->distance_ibgp[afi][safi])
15102 return bgp->distance_ibgp[afi][safi];
15103 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15104 } else {
15105 if (bgp->distance_local[afi][safi])
15106 return bgp->distance_local[afi][safi];
15107 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15108 }
15109 }
15110
15111 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
15112 * we should tell ZEBRA update the routes for a specific
15113 * AFI/SAFI to reflect changes in RIB.
15114 */
15115 static void bgp_announce_routes_distance_update(struct bgp *bgp,
15116 afi_t update_afi,
15117 safi_t update_safi)
15118 {
15119 afi_t afi;
15120 safi_t safi;
15121
15122 FOREACH_AFI_SAFI (afi, safi) {
15123 if (!bgp_fibupd_safi(safi))
15124 continue;
15125
15126 if (afi != update_afi && safi != update_safi)
15127 continue;
15128
15129 if (BGP_DEBUG(zebra, ZEBRA))
15130 zlog_debug(
15131 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
15132 __func__, afi, safi);
15133 bgp_zebra_announce_table(bgp, afi, safi);
15134 }
15135 }
15136
15137 DEFUN (bgp_distance,
15138 bgp_distance_cmd,
15139 "distance bgp (1-255) (1-255) (1-255)",
15140 "Define an administrative distance\n"
15141 "BGP distance\n"
15142 "Distance for routes external to the AS\n"
15143 "Distance for routes internal to the AS\n"
15144 "Distance for local routes\n")
15145 {
15146 VTY_DECLVAR_CONTEXT(bgp, bgp);
15147 int idx_number = 2;
15148 int idx_number_2 = 3;
15149 int idx_number_3 = 4;
15150 int distance_ebgp = atoi(argv[idx_number]->arg);
15151 int distance_ibgp = atoi(argv[idx_number_2]->arg);
15152 int distance_local = atoi(argv[idx_number_3]->arg);
15153 afi_t afi;
15154 safi_t safi;
15155
15156 afi = bgp_node_afi(vty);
15157 safi = bgp_node_safi(vty);
15158
15159 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
15160 || bgp->distance_ibgp[afi][safi] != distance_ibgp
15161 || bgp->distance_local[afi][safi] != distance_local) {
15162 bgp->distance_ebgp[afi][safi] = distance_ebgp;
15163 bgp->distance_ibgp[afi][safi] = distance_ibgp;
15164 bgp->distance_local[afi][safi] = distance_local;
15165 bgp_announce_routes_distance_update(bgp, afi, safi);
15166 }
15167 return CMD_SUCCESS;
15168 }
15169
15170 DEFUN (no_bgp_distance,
15171 no_bgp_distance_cmd,
15172 "no distance bgp [(1-255) (1-255) (1-255)]",
15173 NO_STR
15174 "Define an administrative distance\n"
15175 "BGP distance\n"
15176 "Distance for routes external to the AS\n"
15177 "Distance for routes internal to the AS\n"
15178 "Distance for local routes\n")
15179 {
15180 VTY_DECLVAR_CONTEXT(bgp, bgp);
15181 afi_t afi;
15182 safi_t safi;
15183
15184 afi = bgp_node_afi(vty);
15185 safi = bgp_node_safi(vty);
15186
15187 if (bgp->distance_ebgp[afi][safi] != 0
15188 || bgp->distance_ibgp[afi][safi] != 0
15189 || bgp->distance_local[afi][safi] != 0) {
15190 bgp->distance_ebgp[afi][safi] = 0;
15191 bgp->distance_ibgp[afi][safi] = 0;
15192 bgp->distance_local[afi][safi] = 0;
15193 bgp_announce_routes_distance_update(bgp, afi, safi);
15194 }
15195 return CMD_SUCCESS;
15196 }
15197
15198
15199 DEFUN (bgp_distance_source,
15200 bgp_distance_source_cmd,
15201 "distance (1-255) A.B.C.D/M",
15202 "Define an administrative distance\n"
15203 "Administrative distance\n"
15204 "IP source prefix\n")
15205 {
15206 int idx_number = 1;
15207 int idx_ipv4_prefixlen = 2;
15208 bgp_distance_set(vty, argv[idx_number]->arg,
15209 argv[idx_ipv4_prefixlen]->arg, NULL);
15210 return CMD_SUCCESS;
15211 }
15212
15213 DEFUN (no_bgp_distance_source,
15214 no_bgp_distance_source_cmd,
15215 "no distance (1-255) A.B.C.D/M",
15216 NO_STR
15217 "Define an administrative distance\n"
15218 "Administrative distance\n"
15219 "IP source prefix\n")
15220 {
15221 int idx_number = 2;
15222 int idx_ipv4_prefixlen = 3;
15223 bgp_distance_unset(vty, argv[idx_number]->arg,
15224 argv[idx_ipv4_prefixlen]->arg, NULL);
15225 return CMD_SUCCESS;
15226 }
15227
15228 DEFUN (bgp_distance_source_access_list,
15229 bgp_distance_source_access_list_cmd,
15230 "distance (1-255) A.B.C.D/M WORD",
15231 "Define an administrative distance\n"
15232 "Administrative distance\n"
15233 "IP source prefix\n"
15234 "Access list name\n")
15235 {
15236 int idx_number = 1;
15237 int idx_ipv4_prefixlen = 2;
15238 int idx_word = 3;
15239 bgp_distance_set(vty, argv[idx_number]->arg,
15240 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15241 return CMD_SUCCESS;
15242 }
15243
15244 DEFUN (no_bgp_distance_source_access_list,
15245 no_bgp_distance_source_access_list_cmd,
15246 "no distance (1-255) A.B.C.D/M WORD",
15247 NO_STR
15248 "Define an administrative distance\n"
15249 "Administrative distance\n"
15250 "IP source prefix\n"
15251 "Access list name\n")
15252 {
15253 int idx_number = 2;
15254 int idx_ipv4_prefixlen = 3;
15255 int idx_word = 4;
15256 bgp_distance_unset(vty, argv[idx_number]->arg,
15257 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15258 return CMD_SUCCESS;
15259 }
15260
15261 DEFUN (ipv6_bgp_distance_source,
15262 ipv6_bgp_distance_source_cmd,
15263 "distance (1-255) X:X::X:X/M",
15264 "Define an administrative distance\n"
15265 "Administrative distance\n"
15266 "IP source prefix\n")
15267 {
15268 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15269 return CMD_SUCCESS;
15270 }
15271
15272 DEFUN (no_ipv6_bgp_distance_source,
15273 no_ipv6_bgp_distance_source_cmd,
15274 "no distance (1-255) X:X::X:X/M",
15275 NO_STR
15276 "Define an administrative distance\n"
15277 "Administrative distance\n"
15278 "IP source prefix\n")
15279 {
15280 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15281 return CMD_SUCCESS;
15282 }
15283
15284 DEFUN (ipv6_bgp_distance_source_access_list,
15285 ipv6_bgp_distance_source_access_list_cmd,
15286 "distance (1-255) X:X::X:X/M WORD",
15287 "Define an administrative distance\n"
15288 "Administrative distance\n"
15289 "IP source prefix\n"
15290 "Access list name\n")
15291 {
15292 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15293 return CMD_SUCCESS;
15294 }
15295
15296 DEFUN (no_ipv6_bgp_distance_source_access_list,
15297 no_ipv6_bgp_distance_source_access_list_cmd,
15298 "no distance (1-255) X:X::X:X/M WORD",
15299 NO_STR
15300 "Define an administrative distance\n"
15301 "Administrative distance\n"
15302 "IP source prefix\n"
15303 "Access list name\n")
15304 {
15305 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15306 return CMD_SUCCESS;
15307 }
15308
15309 DEFUN (bgp_damp_set,
15310 bgp_damp_set_cmd,
15311 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15312 "BGP Specific commands\n"
15313 "Enable route-flap dampening\n"
15314 "Half-life time for the penalty\n"
15315 "Value to start reusing a route\n"
15316 "Value to start suppressing a route\n"
15317 "Maximum duration to suppress a stable route\n")
15318 {
15319 VTY_DECLVAR_CONTEXT(bgp, bgp);
15320 int idx_half_life = 2;
15321 int idx_reuse = 3;
15322 int idx_suppress = 4;
15323 int idx_max_suppress = 5;
15324 int half = DEFAULT_HALF_LIFE * 60;
15325 int reuse = DEFAULT_REUSE;
15326 int suppress = DEFAULT_SUPPRESS;
15327 int max = 4 * half;
15328
15329 if (argc == 6) {
15330 half = atoi(argv[idx_half_life]->arg) * 60;
15331 reuse = atoi(argv[idx_reuse]->arg);
15332 suppress = atoi(argv[idx_suppress]->arg);
15333 max = atoi(argv[idx_max_suppress]->arg) * 60;
15334 } else if (argc == 3) {
15335 half = atoi(argv[idx_half_life]->arg) * 60;
15336 max = 4 * half;
15337 }
15338
15339 /*
15340 * These can't be 0 but our SA doesn't understand the
15341 * way our cli is constructed
15342 */
15343 assert(reuse);
15344 assert(half);
15345 if (suppress < reuse) {
15346 vty_out(vty,
15347 "Suppress value cannot be less than reuse value \n");
15348 return 0;
15349 }
15350
15351 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15352 reuse, suppress, max);
15353 }
15354
15355 DEFUN (bgp_damp_unset,
15356 bgp_damp_unset_cmd,
15357 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15358 NO_STR
15359 "BGP Specific commands\n"
15360 "Enable route-flap dampening\n"
15361 "Half-life time for the penalty\n"
15362 "Value to start reusing a route\n"
15363 "Value to start suppressing a route\n"
15364 "Maximum duration to suppress a stable route\n")
15365 {
15366 VTY_DECLVAR_CONTEXT(bgp, bgp);
15367 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15368 }
15369
15370 /* Display specified route of BGP table. */
15371 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15372 const char *ip_str, afi_t afi, safi_t safi,
15373 struct prefix_rd *prd, int prefix_check)
15374 {
15375 int ret;
15376 struct prefix match;
15377 struct bgp_dest *dest;
15378 struct bgp_dest *rm;
15379 struct bgp_path_info *pi;
15380 struct bgp_path_info *pi_temp;
15381 struct bgp *bgp;
15382 struct bgp_table *table;
15383
15384 /* BGP structure lookup. */
15385 if (view_name) {
15386 bgp = bgp_lookup_by_name(view_name);
15387 if (bgp == NULL) {
15388 vty_out(vty, "%% Can't find BGP instance %s\n",
15389 view_name);
15390 return CMD_WARNING;
15391 }
15392 } else {
15393 bgp = bgp_get_default();
15394 if (bgp == NULL) {
15395 vty_out(vty, "%% No BGP process is configured\n");
15396 return CMD_WARNING;
15397 }
15398 }
15399
15400 /* Check IP address argument. */
15401 ret = str2prefix(ip_str, &match);
15402 if (!ret) {
15403 vty_out(vty, "%% address is malformed\n");
15404 return CMD_WARNING;
15405 }
15406
15407 match.family = afi2family(afi);
15408
15409 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15410 || (safi == SAFI_EVPN)) {
15411 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15412 dest = bgp_route_next(dest)) {
15413 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15414
15415 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15416 continue;
15417 table = bgp_dest_get_bgp_table_info(dest);
15418 if (!table)
15419 continue;
15420 rm = bgp_node_match(table, &match);
15421 if (rm == NULL)
15422 continue;
15423
15424 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15425
15426 if (!prefix_check
15427 || rm_p->prefixlen == match.prefixlen) {
15428 pi = bgp_dest_get_bgp_path_info(rm);
15429 while (pi) {
15430 if (pi->extra && pi->extra->damp_info) {
15431 pi_temp = pi->next;
15432 bgp_damp_info_free(
15433 pi->extra->damp_info,
15434 1, afi, safi);
15435 pi = pi_temp;
15436 } else
15437 pi = pi->next;
15438 }
15439 }
15440
15441 bgp_dest_unlock_node(rm);
15442 }
15443 } else {
15444 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15445 if (dest != NULL) {
15446 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15447
15448 if (!prefix_check
15449 || dest_p->prefixlen == match.prefixlen) {
15450 pi = bgp_dest_get_bgp_path_info(dest);
15451 while (pi) {
15452 if (pi->extra && pi->extra->damp_info) {
15453 pi_temp = pi->next;
15454 bgp_damp_info_free(
15455 pi->extra->damp_info,
15456 1, afi, safi);
15457 pi = pi_temp;
15458 } else
15459 pi = pi->next;
15460 }
15461 }
15462
15463 bgp_dest_unlock_node(dest);
15464 }
15465 }
15466
15467 return CMD_SUCCESS;
15468 }
15469
15470 DEFUN (clear_ip_bgp_dampening,
15471 clear_ip_bgp_dampening_cmd,
15472 "clear ip bgp dampening",
15473 CLEAR_STR
15474 IP_STR
15475 BGP_STR
15476 "Clear route flap dampening information\n")
15477 {
15478 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15479 return CMD_SUCCESS;
15480 }
15481
15482 DEFUN (clear_ip_bgp_dampening_prefix,
15483 clear_ip_bgp_dampening_prefix_cmd,
15484 "clear ip bgp dampening A.B.C.D/M",
15485 CLEAR_STR
15486 IP_STR
15487 BGP_STR
15488 "Clear route flap dampening information\n"
15489 "IPv4 prefix\n")
15490 {
15491 int idx_ipv4_prefixlen = 4;
15492 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15493 AFI_IP, SAFI_UNICAST, NULL, 1);
15494 }
15495
15496 DEFUN (clear_ip_bgp_dampening_address,
15497 clear_ip_bgp_dampening_address_cmd,
15498 "clear ip bgp dampening A.B.C.D",
15499 CLEAR_STR
15500 IP_STR
15501 BGP_STR
15502 "Clear route flap dampening information\n"
15503 "Network to clear damping information\n")
15504 {
15505 int idx_ipv4 = 4;
15506 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15507 SAFI_UNICAST, NULL, 0);
15508 }
15509
15510 DEFUN (clear_ip_bgp_dampening_address_mask,
15511 clear_ip_bgp_dampening_address_mask_cmd,
15512 "clear ip bgp dampening A.B.C.D A.B.C.D",
15513 CLEAR_STR
15514 IP_STR
15515 BGP_STR
15516 "Clear route flap dampening information\n"
15517 "Network to clear damping information\n"
15518 "Network mask\n")
15519 {
15520 int idx_ipv4 = 4;
15521 int idx_ipv4_2 = 5;
15522 int ret;
15523 char prefix_str[BUFSIZ];
15524
15525 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15526 prefix_str, sizeof(prefix_str));
15527 if (!ret) {
15528 vty_out(vty, "%% Inconsistent address and mask\n");
15529 return CMD_WARNING;
15530 }
15531
15532 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15533 NULL, 0);
15534 }
15535
15536 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15537 {
15538 struct vty *vty = arg;
15539 struct peer *peer = bucket->data;
15540
15541 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15542 }
15543
15544 DEFUN (show_bgp_listeners,
15545 show_bgp_listeners_cmd,
15546 "show bgp listeners",
15547 SHOW_STR
15548 BGP_STR
15549 "Display Listen Sockets and who created them\n")
15550 {
15551 bgp_dump_listener_info(vty);
15552
15553 return CMD_SUCCESS;
15554 }
15555
15556 DEFUN (show_bgp_peerhash,
15557 show_bgp_peerhash_cmd,
15558 "show bgp peerhash",
15559 SHOW_STR
15560 BGP_STR
15561 "Display information about the BGP peerhash\n")
15562 {
15563 struct list *instances = bm->bgp;
15564 struct listnode *node;
15565 struct bgp *bgp;
15566
15567 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15568 vty_out(vty, "BGP: %s\n", bgp->name);
15569 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15570 vty);
15571 }
15572
15573 return CMD_SUCCESS;
15574 }
15575
15576 /* also used for encap safi */
15577 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15578 afi_t afi, safi_t safi)
15579 {
15580 struct bgp_dest *pdest;
15581 struct bgp_dest *dest;
15582 struct bgp_table *table;
15583 const struct prefix *p;
15584 const struct prefix_rd *prd;
15585 struct bgp_static *bgp_static;
15586 mpls_label_t label;
15587
15588 /* Network configuration. */
15589 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15590 pdest = bgp_route_next(pdest)) {
15591 table = bgp_dest_get_bgp_table_info(pdest);
15592 if (!table)
15593 continue;
15594
15595 for (dest = bgp_table_top(table); dest;
15596 dest = bgp_route_next(dest)) {
15597 bgp_static = bgp_dest_get_bgp_static_info(dest);
15598 if (bgp_static == NULL)
15599 continue;
15600
15601 p = bgp_dest_get_prefix(dest);
15602 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
15603 pdest);
15604
15605 /* "network" configuration display. */
15606 label = decode_label(&bgp_static->label);
15607
15608 vty_out(vty, " network %pFX rd %pRD", p, prd);
15609 if (safi == SAFI_MPLS_VPN)
15610 vty_out(vty, " label %u", label);
15611
15612 if (bgp_static->rmap.name)
15613 vty_out(vty, " route-map %s",
15614 bgp_static->rmap.name);
15615
15616 if (bgp_static->backdoor)
15617 vty_out(vty, " backdoor");
15618
15619 vty_out(vty, "\n");
15620 }
15621 }
15622 }
15623
15624 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15625 afi_t afi, safi_t safi)
15626 {
15627 struct bgp_dest *pdest;
15628 struct bgp_dest *dest;
15629 struct bgp_table *table;
15630 const struct prefix *p;
15631 const struct prefix_rd *prd;
15632 struct bgp_static *bgp_static;
15633 char buf[PREFIX_STRLEN * 2];
15634 char buf2[SU_ADDRSTRLEN];
15635 char esi_buf[ESI_STR_LEN];
15636
15637 /* Network configuration. */
15638 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15639 pdest = bgp_route_next(pdest)) {
15640 table = bgp_dest_get_bgp_table_info(pdest);
15641 if (!table)
15642 continue;
15643
15644 for (dest = bgp_table_top(table); dest;
15645 dest = bgp_route_next(dest)) {
15646 bgp_static = bgp_dest_get_bgp_static_info(dest);
15647 if (bgp_static == NULL)
15648 continue;
15649
15650 char *macrouter = NULL;
15651
15652 if (bgp_static->router_mac)
15653 macrouter = prefix_mac2str(
15654 bgp_static->router_mac, NULL, 0);
15655 if (bgp_static->eth_s_id)
15656 esi_to_str(bgp_static->eth_s_id,
15657 esi_buf, sizeof(esi_buf));
15658 p = bgp_dest_get_prefix(dest);
15659 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
15660
15661 /* "network" configuration display. */
15662 if (p->u.prefix_evpn.route_type == 5) {
15663 char local_buf[PREFIX_STRLEN];
15664
15665 uint8_t family = is_evpn_prefix_ipaddr_v4((
15666 struct prefix_evpn *)p)
15667 ? AF_INET
15668 : AF_INET6;
15669 inet_ntop(family,
15670 &p->u.prefix_evpn.prefix_addr.ip.ip
15671 .addr,
15672 local_buf, sizeof(local_buf));
15673 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15674 p->u.prefix_evpn.prefix_addr
15675 .ip_prefix_length);
15676 } else {
15677 prefix2str(p, buf, sizeof(buf));
15678 }
15679
15680 if (bgp_static->gatewayIp.family == AF_INET
15681 || bgp_static->gatewayIp.family == AF_INET6)
15682 inet_ntop(bgp_static->gatewayIp.family,
15683 &bgp_static->gatewayIp.u.prefix, buf2,
15684 sizeof(buf2));
15685 vty_out(vty,
15686 " network %s rd %pRD ethtag %u label %u esi %s gwip %s routermac %s\n",
15687 buf, prd, p->u.prefix_evpn.prefix_addr.eth_tag,
15688 decode_label(&bgp_static->label), esi_buf, buf2,
15689 macrouter);
15690
15691 XFREE(MTYPE_TMP, macrouter);
15692 }
15693 }
15694 }
15695
15696 /* Configuration of static route announcement and aggregate
15697 information. */
15698 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15699 safi_t safi)
15700 {
15701 struct bgp_dest *dest;
15702 const struct prefix *p;
15703 struct bgp_static *bgp_static;
15704 struct bgp_aggregate *bgp_aggregate;
15705
15706 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15707 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15708 return;
15709 }
15710
15711 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15712 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15713 return;
15714 }
15715
15716 /* Network configuration. */
15717 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15718 dest = bgp_route_next(dest)) {
15719 bgp_static = bgp_dest_get_bgp_static_info(dest);
15720 if (bgp_static == NULL)
15721 continue;
15722
15723 p = bgp_dest_get_prefix(dest);
15724
15725 vty_out(vty, " network %pFX", p);
15726
15727 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15728 vty_out(vty, " label-index %u",
15729 bgp_static->label_index);
15730
15731 if (bgp_static->rmap.name)
15732 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15733
15734 if (bgp_static->backdoor)
15735 vty_out(vty, " backdoor");
15736
15737 vty_out(vty, "\n");
15738 }
15739
15740 /* Aggregate-address configuration. */
15741 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15742 dest = bgp_route_next(dest)) {
15743 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15744 if (bgp_aggregate == NULL)
15745 continue;
15746
15747 p = bgp_dest_get_prefix(dest);
15748
15749 vty_out(vty, " aggregate-address %pFX", p);
15750
15751 if (bgp_aggregate->as_set)
15752 vty_out(vty, " as-set");
15753
15754 if (bgp_aggregate->summary_only)
15755 vty_out(vty, " summary-only");
15756
15757 if (bgp_aggregate->rmap.name)
15758 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15759
15760 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15761 vty_out(vty, " origin %s",
15762 bgp_origin2str(bgp_aggregate->origin));
15763
15764 if (bgp_aggregate->match_med)
15765 vty_out(vty, " matching-MED-only");
15766
15767 if (bgp_aggregate->suppress_map_name)
15768 vty_out(vty, " suppress-map %s",
15769 bgp_aggregate->suppress_map_name);
15770
15771 vty_out(vty, "\n");
15772 }
15773 }
15774
15775 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15776 safi_t safi)
15777 {
15778 struct bgp_dest *dest;
15779 struct bgp_distance *bdistance;
15780
15781 /* Distance configuration. */
15782 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15783 && bgp->distance_local[afi][safi]
15784 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15785 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15786 || bgp->distance_local[afi][safi]
15787 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15788 vty_out(vty, " distance bgp %d %d %d\n",
15789 bgp->distance_ebgp[afi][safi],
15790 bgp->distance_ibgp[afi][safi],
15791 bgp->distance_local[afi][safi]);
15792 }
15793
15794 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15795 dest = bgp_route_next(dest)) {
15796 bdistance = bgp_dest_get_bgp_distance_info(dest);
15797 if (bdistance != NULL)
15798 vty_out(vty, " distance %d %pBD %s\n",
15799 bdistance->distance, dest,
15800 bdistance->access_list ? bdistance->access_list
15801 : "");
15802 }
15803 }
15804
15805 /* Allocate routing table structure and install commands. */
15806 void bgp_route_init(void)
15807 {
15808 afi_t afi;
15809 safi_t safi;
15810
15811 /* Init BGP distance table. */
15812 FOREACH_AFI_SAFI (afi, safi)
15813 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15814
15815 /* IPv4 BGP commands. */
15816 install_element(BGP_NODE, &bgp_table_map_cmd);
15817 install_element(BGP_NODE, &bgp_network_cmd);
15818 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15819
15820 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15821
15822 /* IPv4 unicast configuration. */
15823 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15824 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15825 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15826
15827 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15828
15829 /* IPv4 multicast configuration. */
15830 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15831 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15832 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15833 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15834
15835 /* IPv4 labeled-unicast configuration. */
15836 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15837 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15838
15839 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15840 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15841 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15842 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15843 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15844 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15845 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15846 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15847
15848 install_element(VIEW_NODE,
15849 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15850 install_element(VIEW_NODE,
15851 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15852 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15853 install_element(VIEW_NODE,
15854 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15855 #ifdef KEEP_OLD_VPN_COMMANDS
15856 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15857 #endif /* KEEP_OLD_VPN_COMMANDS */
15858 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15859 install_element(VIEW_NODE,
15860 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15861
15862 /* BGP dampening clear commands */
15863 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15864 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15865
15866 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15867 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15868
15869 /* prefix count */
15870 install_element(ENABLE_NODE,
15871 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15872 #ifdef KEEP_OLD_VPN_COMMANDS
15873 install_element(ENABLE_NODE,
15874 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15875 #endif /* KEEP_OLD_VPN_COMMANDS */
15876
15877 /* New config IPv6 BGP commands. */
15878 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15879 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15880 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15881
15882 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15883
15884 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15885
15886 /* IPv6 labeled unicast address family. */
15887 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15888 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15889
15890 install_element(BGP_NODE, &bgp_distance_cmd);
15891 install_element(BGP_NODE, &no_bgp_distance_cmd);
15892 install_element(BGP_NODE, &bgp_distance_source_cmd);
15893 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15894 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15895 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15896 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15897 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15898 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15899 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15900 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15901 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15902 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15903 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15904 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15905 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15906 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15907 install_element(BGP_IPV4M_NODE,
15908 &no_bgp_distance_source_access_list_cmd);
15909 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15910 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15911 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15912 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15913 install_element(BGP_IPV6_NODE,
15914 &ipv6_bgp_distance_source_access_list_cmd);
15915 install_element(BGP_IPV6_NODE,
15916 &no_ipv6_bgp_distance_source_access_list_cmd);
15917 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15918 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15919 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15920 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15921 install_element(BGP_IPV6M_NODE,
15922 &ipv6_bgp_distance_source_access_list_cmd);
15923 install_element(BGP_IPV6M_NODE,
15924 &no_ipv6_bgp_distance_source_access_list_cmd);
15925
15926 /* BGP dampening */
15927 install_element(BGP_NODE, &bgp_damp_set_cmd);
15928 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15929 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15930 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15931 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15932 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15933 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15934 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15935 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15936 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15937 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15938 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15939 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15940 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15941
15942 /* Large Communities */
15943 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15944 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15945
15946 /* show bgp ipv4 flowspec detailed */
15947 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15948
15949 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15950 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15951 }
15952
15953 void bgp_route_finish(void)
15954 {
15955 afi_t afi;
15956 safi_t safi;
15957
15958 FOREACH_AFI_SAFI (afi, safi) {
15959 bgp_table_unlock(bgp_distance_table[afi][safi]);
15960 bgp_distance_table[afi][safi] = NULL;
15961 }
15962 }