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