]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
693616e6d59fe7b7b104183f368dd5390745497c
[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_orr.h"
76 #include "bgpd/bgp_trace.h"
77 #include "bgpd/bgp_rpki.h"
78
79 #ifdef ENABLE_BGP_VNC
80 #include "bgpd/rfapi/rfapi_backend.h"
81 #include "bgpd/rfapi/vnc_import_bgp.h"
82 #include "bgpd/rfapi/vnc_export_bgp.h"
83 #endif
84 #include "bgpd/bgp_encap_types.h"
85 #include "bgpd/bgp_encap_tlv.h"
86 #include "bgpd/bgp_evpn.h"
87 #include "bgpd/bgp_evpn_mh.h"
88 #include "bgpd/bgp_evpn_vty.h"
89 #include "bgpd/bgp_flowspec.h"
90 #include "bgpd/bgp_flowspec_util.h"
91 #include "bgpd/bgp_pbr.h"
92
93 #ifndef VTYSH_EXTRACT_PL
94 #include "bgpd/bgp_route_clippy.c"
95 #endif
96
97 DEFINE_HOOK(bgp_snmp_update_stats,
98 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
99 (rn, pi, added));
100
101 DEFINE_HOOK(bgp_rpki_prefix_status,
102 (struct peer *peer, struct attr *attr,
103 const struct prefix *prefix),
104 (peer, attr, prefix));
105
106 /* Extern from bgp_dump.c */
107 extern const char *bgp_origin_str[];
108 extern const char *bgp_origin_long_str[];
109
110 /* PMSI strings. */
111 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
112 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
113 static const struct message bgp_pmsi_tnltype_str[] = {
114 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
115 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
116 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
117 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
118 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
119 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
120 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
121 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
122 {0}
123 };
124
125 #define VRFID_NONE_STR "-"
126 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
127
128 DEFINE_HOOK(bgp_process,
129 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
130 struct peer *peer, bool withdraw),
131 (bgp, afi, safi, bn, peer, withdraw));
132
133 /** Test if path is suppressed. */
134 static bool bgp_path_suppressed(struct bgp_path_info *pi)
135 {
136 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
137 return false;
138
139 return listcount(pi->extra->aggr_suppressors) > 0;
140 }
141
142 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
143 safi_t safi, const struct prefix *p,
144 struct prefix_rd *prd)
145 {
146 struct bgp_dest *dest;
147 struct bgp_dest *pdest = NULL;
148
149 assert(table);
150
151 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
152 || (safi == SAFI_EVPN)) {
153 pdest = bgp_node_get(table, (struct prefix *)prd);
154
155 if (!bgp_dest_has_bgp_path_info_data(pdest))
156 bgp_dest_set_bgp_table_info(
157 pdest, bgp_table_init(table->bgp, afi, safi));
158 else
159 bgp_dest_unlock_node(pdest);
160 table = bgp_dest_get_bgp_table_info(pdest);
161 }
162
163 dest = bgp_node_get(table, p);
164
165 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
166 || (safi == SAFI_EVPN))
167 dest->pdest = pdest;
168
169 return dest;
170 }
171
172 struct bgp_dest *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
173 safi_t safi, const struct prefix *p,
174 struct prefix_rd *prd)
175 {
176 struct bgp_dest *dest;
177 struct bgp_dest *pdest = NULL;
178
179 if (!table)
180 return NULL;
181
182 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
183 || (safi == SAFI_EVPN)) {
184 pdest = bgp_node_lookup(table, (struct prefix *)prd);
185 if (!pdest)
186 return NULL;
187
188 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
189 bgp_dest_unlock_node(pdest);
190 return NULL;
191 }
192
193 table = bgp_dest_get_bgp_table_info(pdest);
194 }
195
196 dest = bgp_node_lookup(table, p);
197
198 return dest;
199 }
200
201 /* Allocate bgp_path_info_extra */
202 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
203 {
204 struct bgp_path_info_extra *new;
205 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
206 sizeof(struct bgp_path_info_extra));
207 new->label[0] = MPLS_INVALID_LABEL;
208 new->num_labels = 0;
209 new->bgp_fs_pbr = NULL;
210 new->bgp_fs_iprule = NULL;
211 return new;
212 }
213
214 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
215 {
216 struct bgp_path_info_extra *e;
217
218 if (!extra || !*extra)
219 return;
220
221 e = *extra;
222 if (e->damp_info)
223 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
224 e->damp_info->safi);
225
226 e->damp_info = NULL;
227 if (e->parent) {
228 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
229
230 if (bpi->net) {
231 /* FIXME: since multiple e may have the same e->parent
232 * and e->parent->net is holding a refcount for each
233 * of them, we need to do some fudging here.
234 *
235 * WARNING: if bpi->net->lock drops to 0, bpi may be
236 * freed as well (because bpi->net was holding the
237 * last reference to bpi) => write after free!
238 */
239 unsigned refcount;
240
241 bpi = bgp_path_info_lock(bpi);
242 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
243 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
244 if (!refcount)
245 bpi->net = NULL;
246 bgp_path_info_unlock(bpi);
247 }
248 bgp_path_info_unlock(e->parent);
249 e->parent = NULL;
250 }
251
252 if (e->bgp_orig)
253 bgp_unlock(e->bgp_orig);
254
255 if (e->peer_orig)
256 peer_unlock(e->peer_orig);
257
258 if (e->aggr_suppressors)
259 list_delete(&e->aggr_suppressors);
260
261 if (e->mh_info)
262 bgp_evpn_path_mh_info_free(e->mh_info);
263
264 if ((*extra)->bgp_fs_iprule)
265 list_delete(&((*extra)->bgp_fs_iprule));
266 if ((*extra)->bgp_fs_pbr)
267 list_delete(&((*extra)->bgp_fs_pbr));
268 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
269 }
270
271 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
272 * allocated if required.
273 */
274 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
275 {
276 if (!pi->extra)
277 pi->extra = bgp_path_info_extra_new();
278 return pi->extra;
279 }
280
281 /* Free bgp route information. */
282 static void bgp_path_info_free(struct bgp_path_info *path)
283 {
284 bgp_attr_unintern(&path->attr);
285
286 bgp_unlink_nexthop(path);
287 bgp_path_info_extra_free(&path->extra);
288 bgp_path_info_mpath_free(&path->mpath);
289 if (path->net)
290 bgp_addpath_free_info_data(&path->tx_addpath,
291 &path->net->tx_addpath);
292
293 peer_unlock(path->peer); /* bgp_path_info peer reference */
294
295 XFREE(MTYPE_BGP_ROUTE, path);
296 }
297
298 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
299 {
300 path->lock++;
301 return path;
302 }
303
304 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
305 {
306 assert(path && path->lock > 0);
307 path->lock--;
308
309 if (path->lock == 0) {
310 bgp_path_info_free(path);
311 return NULL;
312 }
313
314 return path;
315 }
316
317 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
318 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
319 {
320 struct peer *peer;
321 struct bgp_path_info *old_pi, *nextpi;
322 bool set_flag = false;
323 struct bgp *bgp = NULL;
324 struct bgp_table *table = NULL;
325 afi_t afi = 0;
326 safi_t safi = 0;
327
328 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
329 * then the route selection is deferred
330 */
331 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
332 return 0;
333
334 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
335 if (BGP_DEBUG(update, UPDATE_OUT))
336 zlog_debug(
337 "Route %pBD is in workqueue and being processed, not deferred.",
338 dest);
339
340 return 0;
341 }
342
343 table = bgp_dest_table(dest);
344 if (table) {
345 bgp = table->bgp;
346 afi = table->afi;
347 safi = table->safi;
348 }
349
350 for (old_pi = bgp_dest_get_bgp_path_info(dest);
351 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
352 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
353 continue;
354
355 /* Route selection is deferred if there is a stale path which
356 * which indicates peer is in restart mode
357 */
358 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
359 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
360 set_flag = true;
361 } else {
362 /* If the peer is graceful restart capable and peer is
363 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
364 */
365 peer = old_pi->peer;
366 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
367 && BGP_PEER_RESTARTING_MODE(peer)
368 && (old_pi
369 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
370 set_flag = true;
371 }
372 }
373 if (set_flag)
374 break;
375 }
376
377 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
378 * is active
379 */
380 if (set_flag && table) {
381 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
382 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
383 bgp->gr_info[afi][safi].gr_deferred++;
384 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
385 if (BGP_DEBUG(update, UPDATE_OUT))
386 zlog_debug("DEFER route %pBD, dest %p", dest,
387 dest);
388 return 0;
389 }
390 }
391 return -1;
392 }
393
394 void bgp_path_info_add(struct bgp_dest *dest, struct bgp_path_info *pi)
395 {
396 struct bgp_path_info *top;
397
398 top = bgp_dest_get_bgp_path_info(dest);
399
400 pi->next = top;
401 pi->prev = NULL;
402 if (top)
403 top->prev = pi;
404 bgp_dest_set_bgp_path_info(dest, pi);
405
406 bgp_path_info_lock(pi);
407 bgp_dest_lock_node(dest);
408 peer_lock(pi->peer); /* bgp_path_info peer reference */
409 bgp_dest_set_defer_flag(dest, false);
410 hook_call(bgp_snmp_update_stats, dest, pi, true);
411 }
412
413 /* Do the actual removal of info from RIB, for use by bgp_process
414 completion callback *only* */
415 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
416 {
417 if (pi->next)
418 pi->next->prev = pi->prev;
419 if (pi->prev)
420 pi->prev->next = pi->next;
421 else
422 bgp_dest_set_bgp_path_info(dest, pi->next);
423
424 bgp_path_info_mpath_dequeue(pi);
425 bgp_path_info_unlock(pi);
426 hook_call(bgp_snmp_update_stats, dest, pi, false);
427 bgp_dest_unlock_node(dest);
428 }
429
430 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
431 {
432 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
433 /* set of previous already took care of pcount */
434 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
435 }
436
437 /* undo the effects of a previous call to bgp_path_info_delete; typically
438 called when a route is deleted and then quickly re-added before the
439 deletion has been processed */
440 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
441 {
442 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
443 /* unset of previous already took care of pcount */
444 SET_FLAG(pi->flags, BGP_PATH_VALID);
445 }
446
447 /* Adjust pcount as required */
448 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
449 {
450 struct bgp_table *table;
451
452 assert(dest && bgp_dest_table(dest));
453 assert(pi && pi->peer && pi->peer->bgp);
454
455 table = bgp_dest_table(dest);
456
457 if (pi->peer == pi->peer->bgp->peer_self)
458 return;
459
460 if (!BGP_PATH_COUNTABLE(pi)
461 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
462
463 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
464
465 /* slight hack, but more robust against errors. */
466 if (pi->peer->pcount[table->afi][table->safi])
467 pi->peer->pcount[table->afi][table->safi]--;
468 else
469 flog_err(EC_LIB_DEVELOPMENT,
470 "Asked to decrement 0 prefix count for peer");
471 } else if (BGP_PATH_COUNTABLE(pi)
472 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
473 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
474 pi->peer->pcount[table->afi][table->safi]++;
475 }
476 }
477
478 static int bgp_label_index_differs(struct bgp_path_info *pi1,
479 struct bgp_path_info *pi2)
480 {
481 return (!(pi1->attr->label_index == pi2->attr->label_index));
482 }
483
484 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
485 * This is here primarily to keep prefix-count in check.
486 */
487 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
488 uint32_t flag)
489 {
490 SET_FLAG(pi->flags, flag);
491
492 /* early bath if we know it's not a flag that changes countability state
493 */
494 if (!CHECK_FLAG(flag,
495 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
496 return;
497
498 bgp_pcount_adjust(dest, pi);
499 }
500
501 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
502 uint32_t flag)
503 {
504 UNSET_FLAG(pi->flags, flag);
505
506 /* early bath if we know it's not a flag that changes countability state
507 */
508 if (!CHECK_FLAG(flag,
509 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
510 return;
511
512 bgp_pcount_adjust(dest, pi);
513 }
514
515 /* Get MED value. If MED value is missing and "bgp bestpath
516 missing-as-worst" is specified, treat it as the worst value. */
517 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
518 {
519 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
520 return attr->med;
521 else {
522 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
523 return BGP_MED_MAX;
524 else
525 return 0;
526 }
527 }
528
529 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
530 size_t buf_len)
531 {
532 if (pi->addpath_rx_id)
533 snprintf(buf, buf_len, "path %s (addpath rxid %d)",
534 pi->peer->host, pi->addpath_rx_id);
535 else
536 snprintf(buf, buf_len, "path %s", pi->peer->host);
537 }
538
539
540 /*
541 * Get the ultimate path info.
542 */
543 struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
544 {
545 struct bgp_path_info *bpi_ultimate;
546
547 if (info->sub_type != BGP_ROUTE_IMPORTED)
548 return info;
549
550 for (bpi_ultimate = info;
551 bpi_ultimate->extra && bpi_ultimate->extra->parent;
552 bpi_ultimate = bpi_ultimate->extra->parent)
553 ;
554
555 return bpi_ultimate;
556 }
557
558 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
559 */
560 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
561 struct bgp_path_info *exist, int *paths_eq,
562 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
563 char *pfx_buf, afi_t afi, safi_t safi,
564 enum bgp_path_selection_reason *reason)
565 {
566 const struct prefix *new_p;
567 struct prefix exist_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 struct bgp_orr_group *orr_group = NULL;
601 struct listnode *node;
602 struct bgp_orr_igp_metric *igp_metric = NULL;
603 struct list *orr_group_igp_metric_info = NULL;
604
605 *paths_eq = 0;
606
607 /* 0. Null check. */
608 if (new == NULL) {
609 *reason = bgp_path_selection_none;
610 if (debug)
611 zlog_debug("%s: new is NULL", pfx_buf);
612 return 0;
613 }
614
615 if (debug) {
616 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
617 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, new_buf,
618 sizeof(new_buf));
619 }
620
621 if (exist == NULL) {
622 *reason = bgp_path_selection_first;
623 if (debug)
624 zlog_debug("%s(%s): %s is the initial bestpath",
625 pfx_buf, bgp->name_pretty, new_buf);
626 return 1;
627 }
628
629 if (debug) {
630 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
631 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, exist_buf,
632 sizeof(exist_buf));
633 zlog_debug("%s(%s): Comparing %s flags 0x%x with %s flags 0x%x",
634 pfx_buf, bgp->name_pretty, new_buf, new->flags,
635 exist_buf, exist->flags);
636 }
637
638 newattr = new->attr;
639 existattr = exist->attr;
640
641 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
642 * Capability" to a neighbor MUST perform the following upon receiving
643 * a route from that neighbor with the "LLGR_STALE" community, or upon
644 * attaching the "LLGR_STALE" community itself per Section 4.2:
645 *
646 * Treat the route as the least-preferred in route selection (see
647 * below). See the Risks of Depreferencing Routes section (Section 5.2)
648 * for a discussion of potential risks inherent in doing this.
649 */
650 if (bgp_attr_get_community(newattr) &&
651 community_include(bgp_attr_get_community(newattr),
652 COMMUNITY_LLGR_STALE)) {
653 if (debug)
654 zlog_debug(
655 "%s: %s wins over %s due to LLGR_STALE community",
656 pfx_buf, new_buf, exist_buf);
657 return 0;
658 }
659
660 if (bgp_attr_get_community(existattr) &&
661 community_include(bgp_attr_get_community(existattr),
662 COMMUNITY_LLGR_STALE)) {
663 if (debug)
664 zlog_debug(
665 "%s: %s loses to %s due to LLGR_STALE community",
666 pfx_buf, new_buf, exist_buf);
667 return 1;
668 }
669
670 new_p = bgp_dest_get_prefix(new->net);
671
672 /* For EVPN routes, we cannot just go by local vs remote, we have to
673 * look at the MAC mobility sequence number, if present.
674 */
675 if ((safi == SAFI_EVPN)
676 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
677 /* This is an error condition described in RFC 7432 Section
678 * 15.2. The RFC
679 * states that in this scenario "the PE MUST alert the operator"
680 * but it
681 * does not state what other action to take. In order to provide
682 * some
683 * consistency in this scenario we are going to prefer the path
684 * with the
685 * sticky flag.
686 */
687 if (newattr->sticky != existattr->sticky) {
688 if (!debug) {
689 prefix2str(new_p, pfx_buf,
690 sizeof(*pfx_buf)
691 * PREFIX2STR_BUFFER);
692 bgp_path_info_path_with_addpath_rx_str(
693 new, new_buf, sizeof(new_buf));
694 bgp_path_info_path_with_addpath_rx_str(
695 exist, exist_buf, sizeof(exist_buf));
696 }
697
698 if (newattr->sticky && !existattr->sticky) {
699 *reason = bgp_path_selection_evpn_sticky_mac;
700 if (debug)
701 zlog_debug(
702 "%s: %s wins over %s due to sticky MAC flag",
703 pfx_buf, new_buf, exist_buf);
704 return 1;
705 }
706
707 if (!newattr->sticky && existattr->sticky) {
708 *reason = bgp_path_selection_evpn_sticky_mac;
709 if (debug)
710 zlog_debug(
711 "%s: %s loses to %s due to sticky MAC flag",
712 pfx_buf, new_buf, exist_buf);
713 return 0;
714 }
715 }
716
717 new_esi = bgp_evpn_attr_get_esi(newattr);
718 exist_esi = bgp_evpn_attr_get_esi(existattr);
719 if (bgp_evpn_is_esi_valid(new_esi) &&
720 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
721 same_esi = true;
722 } else {
723 same_esi = false;
724 }
725
726 /* If both paths have the same non-zero ES and
727 * one path is local it wins.
728 * PS: Note the local path wins even if the remote
729 * has the higher MM seq. The local path's
730 * MM seq will be fixed up to match the highest
731 * rem seq, subsequently.
732 */
733 if (same_esi) {
734 char esi_buf[ESI_STR_LEN];
735
736 if (bgp_evpn_is_path_local(bgp, new)) {
737 *reason = bgp_path_selection_evpn_local_path;
738 if (debug)
739 zlog_debug(
740 "%s: %s wins over %s as ES %s is same and local",
741 pfx_buf, new_buf, exist_buf,
742 esi_to_str(new_esi, esi_buf,
743 sizeof(esi_buf)));
744 return 1;
745 }
746 if (bgp_evpn_is_path_local(bgp, exist)) {
747 *reason = bgp_path_selection_evpn_local_path;
748 if (debug)
749 zlog_debug(
750 "%s: %s loses to %s as ES %s is same and local",
751 pfx_buf, new_buf, exist_buf,
752 esi_to_str(new_esi, esi_buf,
753 sizeof(esi_buf)));
754 return 0;
755 }
756 }
757
758 new_mm_seq = mac_mobility_seqnum(newattr);
759 exist_mm_seq = mac_mobility_seqnum(existattr);
760
761 if (new_mm_seq > exist_mm_seq) {
762 *reason = bgp_path_selection_evpn_seq;
763 if (debug)
764 zlog_debug(
765 "%s: %s wins over %s due to MM seq %u > %u",
766 pfx_buf, new_buf, exist_buf, new_mm_seq,
767 exist_mm_seq);
768 return 1;
769 }
770
771 if (new_mm_seq < exist_mm_seq) {
772 *reason = bgp_path_selection_evpn_seq;
773 if (debug)
774 zlog_debug(
775 "%s: %s loses to %s due to MM seq %u < %u",
776 pfx_buf, new_buf, exist_buf, new_mm_seq,
777 exist_mm_seq);
778 return 0;
779 }
780
781 /* if the sequence numbers and ESI are the same and one path
782 * is non-proxy it wins (over proxy)
783 */
784 new_proxy = bgp_evpn_attr_is_proxy(newattr);
785 old_proxy = bgp_evpn_attr_is_proxy(existattr);
786 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
787 old_proxy != new_proxy) {
788 if (!new_proxy) {
789 *reason = bgp_path_selection_evpn_non_proxy;
790 if (debug)
791 zlog_debug(
792 "%s: %s wins over %s, same seq/es and non-proxy",
793 pfx_buf, new_buf, exist_buf);
794 return 1;
795 }
796
797 *reason = bgp_path_selection_evpn_non_proxy;
798 if (debug)
799 zlog_debug(
800 "%s: %s loses to %s, same seq/es and non-proxy",
801 pfx_buf, new_buf, exist_buf);
802 return 0;
803 }
804
805 /*
806 * if sequence numbers are the same path with the lowest IP
807 * wins
808 */
809 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
810 if (nh_cmp < 0) {
811 *reason = bgp_path_selection_evpn_lower_ip;
812 if (debug)
813 zlog_debug(
814 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
815 pfx_buf, new_buf, exist_buf, new_mm_seq,
816 &new->attr->nexthop);
817 return 1;
818 }
819 if (nh_cmp > 0) {
820 *reason = bgp_path_selection_evpn_lower_ip;
821 if (debug)
822 zlog_debug(
823 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
824 pfx_buf, new_buf, exist_buf, new_mm_seq,
825 &new->attr->nexthop);
826 return 0;
827 }
828 }
829
830 /* 1. Weight check. */
831 new_weight = newattr->weight;
832 exist_weight = existattr->weight;
833
834 if (new_weight > exist_weight) {
835 *reason = bgp_path_selection_weight;
836 if (debug)
837 zlog_debug("%s: %s wins over %s due to weight %d > %d",
838 pfx_buf, new_buf, exist_buf, new_weight,
839 exist_weight);
840 return 1;
841 }
842
843 if (new_weight < exist_weight) {
844 *reason = bgp_path_selection_weight;
845 if (debug)
846 zlog_debug("%s: %s loses to %s due to weight %d < %d",
847 pfx_buf, new_buf, exist_buf, new_weight,
848 exist_weight);
849 return 0;
850 }
851
852 /* 2. Local preference check. */
853 new_pref = exist_pref = bgp->default_local_pref;
854
855 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
856 new_pref = newattr->local_pref;
857 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
858 exist_pref = existattr->local_pref;
859
860 if (new_pref > exist_pref) {
861 *reason = bgp_path_selection_local_pref;
862 if (debug)
863 zlog_debug(
864 "%s: %s wins over %s due to localpref %d > %d",
865 pfx_buf, new_buf, exist_buf, new_pref,
866 exist_pref);
867 return 1;
868 }
869
870 if (new_pref < exist_pref) {
871 *reason = bgp_path_selection_local_pref;
872 if (debug)
873 zlog_debug(
874 "%s: %s loses to %s due to localpref %d < %d",
875 pfx_buf, new_buf, exist_buf, new_pref,
876 exist_pref);
877 return 0;
878 }
879
880 /* If a BGP speaker supports ACCEPT_OWN and is configured for the
881 * extensions defined in this document, the following step is inserted
882 * after the LOCAL_PREF comparison step in the BGP decision process:
883 * When comparing a pair of routes for a BGP destination, the
884 * route with the ACCEPT_OWN community attached is preferred over
885 * the route that does not have the community.
886 * This extra step MUST only be invoked during the best path selection
887 * process of VPN-IP routes.
888 */
889 if (safi == SAFI_MPLS_VPN &&
890 (CHECK_FLAG(new->peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN) ||
891 CHECK_FLAG(exist->peer->af_flags[afi][safi],
892 PEER_FLAG_ACCEPT_OWN))) {
893 bool new_accept_own = false;
894 bool exist_accept_own = false;
895 uint32_t accept_own = COMMUNITY_ACCEPT_OWN;
896
897 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
898 new_accept_own = community_include(
899 bgp_attr_get_community(newattr), accept_own);
900 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
901 exist_accept_own = community_include(
902 bgp_attr_get_community(existattr), accept_own);
903
904 if (new_accept_own && !exist_accept_own) {
905 *reason = bgp_path_selection_accept_own;
906 if (debug)
907 zlog_debug(
908 "%s: %s wins over %s due to accept-own",
909 pfx_buf, new_buf, exist_buf);
910 return 1;
911 }
912
913 if (!new_accept_own && exist_accept_own) {
914 *reason = bgp_path_selection_accept_own;
915 if (debug)
916 zlog_debug(
917 "%s: %s loses to %s due to accept-own",
918 pfx_buf, new_buf, exist_buf);
919 return 0;
920 }
921 }
922
923 /* 3. Local route check. We prefer:
924 * - BGP_ROUTE_STATIC
925 * - BGP_ROUTE_AGGREGATE
926 * - BGP_ROUTE_REDISTRIBUTE
927 */
928 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
929 new->sub_type == BGP_ROUTE_IMPORTED);
930 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
931 exist->sub_type == BGP_ROUTE_IMPORTED);
932
933 if (new_origin && !exist_origin) {
934 *reason = bgp_path_selection_local_route;
935 if (debug)
936 zlog_debug(
937 "%s: %s wins over %s due to preferred BGP_ROUTE type",
938 pfx_buf, new_buf, exist_buf);
939 return 1;
940 }
941
942 if (!new_origin && exist_origin) {
943 *reason = bgp_path_selection_local_route;
944 if (debug)
945 zlog_debug(
946 "%s: %s loses to %s due to preferred BGP_ROUTE type",
947 pfx_buf, new_buf, exist_buf);
948 return 0;
949 }
950
951 /* Here if these are imported routes then get ultimate pi for
952 * path compare.
953 */
954 new = bgp_get_imported_bpi_ultimate(new);
955 exist = bgp_get_imported_bpi_ultimate(exist);
956 newattr = new->attr;
957 existattr = exist->attr;
958
959 /* 4. AS path length check. */
960 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
961 int exist_hops = aspath_count_hops(existattr->aspath);
962 int exist_confeds = aspath_count_confeds(existattr->aspath);
963
964 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
965 int aspath_hops;
966
967 aspath_hops = aspath_count_hops(newattr->aspath);
968 aspath_hops += aspath_count_confeds(newattr->aspath);
969
970 if (aspath_hops < (exist_hops + exist_confeds)) {
971 *reason = bgp_path_selection_confed_as_path;
972 if (debug)
973 zlog_debug(
974 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
975 pfx_buf, new_buf, exist_buf,
976 aspath_hops,
977 (exist_hops + exist_confeds));
978 return 1;
979 }
980
981 if (aspath_hops > (exist_hops + exist_confeds)) {
982 *reason = bgp_path_selection_confed_as_path;
983 if (debug)
984 zlog_debug(
985 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
986 pfx_buf, new_buf, exist_buf,
987 aspath_hops,
988 (exist_hops + exist_confeds));
989 return 0;
990 }
991 } else {
992 int newhops = aspath_count_hops(newattr->aspath);
993
994 if (newhops < exist_hops) {
995 *reason = bgp_path_selection_as_path;
996 if (debug)
997 zlog_debug(
998 "%s: %s wins over %s due to aspath hopcount %d < %d",
999 pfx_buf, new_buf, exist_buf,
1000 newhops, exist_hops);
1001 return 1;
1002 }
1003
1004 if (newhops > exist_hops) {
1005 *reason = bgp_path_selection_as_path;
1006 if (debug)
1007 zlog_debug(
1008 "%s: %s loses to %s due to aspath hopcount %d > %d",
1009 pfx_buf, new_buf, exist_buf,
1010 newhops, exist_hops);
1011 return 0;
1012 }
1013 }
1014 }
1015
1016 /* 5. Origin check. */
1017 if (newattr->origin < existattr->origin) {
1018 *reason = bgp_path_selection_origin;
1019 if (debug)
1020 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
1021 pfx_buf, new_buf, exist_buf,
1022 bgp_origin_long_str[newattr->origin],
1023 bgp_origin_long_str[existattr->origin]);
1024 return 1;
1025 }
1026
1027 if (newattr->origin > existattr->origin) {
1028 *reason = bgp_path_selection_origin;
1029 if (debug)
1030 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
1031 pfx_buf, new_buf, exist_buf,
1032 bgp_origin_long_str[newattr->origin],
1033 bgp_origin_long_str[existattr->origin]);
1034 return 0;
1035 }
1036
1037 /* 6. MED check. */
1038 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
1039 && aspath_count_hops(existattr->aspath) == 0);
1040 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
1041 && aspath_count_confeds(existattr->aspath) > 0
1042 && aspath_count_hops(newattr->aspath) == 0
1043 && aspath_count_hops(existattr->aspath) == 0);
1044
1045 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
1046 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
1047 || aspath_cmp_left(newattr->aspath, existattr->aspath)
1048 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
1049 || internal_as_route) {
1050 new_med = bgp_med_value(new->attr, bgp);
1051 exist_med = bgp_med_value(exist->attr, bgp);
1052
1053 if (new_med < exist_med) {
1054 *reason = bgp_path_selection_med;
1055 if (debug)
1056 zlog_debug(
1057 "%s: %s wins over %s due to MED %d < %d",
1058 pfx_buf, new_buf, exist_buf, new_med,
1059 exist_med);
1060 return 1;
1061 }
1062
1063 if (new_med > exist_med) {
1064 *reason = bgp_path_selection_med;
1065 if (debug)
1066 zlog_debug(
1067 "%s: %s loses to %s due to MED %d > %d",
1068 pfx_buf, new_buf, exist_buf, new_med,
1069 exist_med);
1070 return 0;
1071 }
1072 }
1073
1074 /* 7. Peer type check. */
1075 new_sort = new->peer->sort;
1076 exist_sort = exist->peer->sort;
1077
1078 if (new_sort == BGP_PEER_EBGP
1079 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1080 *reason = bgp_path_selection_peer;
1081 if (debug)
1082 zlog_debug(
1083 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1084 pfx_buf, new_buf, exist_buf);
1085 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1086 return 1;
1087 peer_sort_ret = 1;
1088 }
1089
1090 if (exist_sort == BGP_PEER_EBGP
1091 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1092 *reason = bgp_path_selection_peer;
1093 if (debug)
1094 zlog_debug(
1095 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1096 pfx_buf, new_buf, exist_buf);
1097 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1098 return 0;
1099 peer_sort_ret = 0;
1100 }
1101
1102 /* 8. IGP metric check. */
1103 newm = existm = 0;
1104
1105 if (new->extra)
1106 newm = new->extra->igpmetric;
1107 if (exist->extra)
1108 existm = exist->extra->igpmetric;
1109
1110 if (new->peer->orr_group_name[afi][safi]) {
1111 ret = str2prefix(new->peer->host, &exist_p);
1112 orr_group = bgp_orr_group_lookup_by_name(
1113 bgp, afi, safi, new->peer->orr_group_name[afi][safi]);
1114 if (orr_group) {
1115 orr_group_igp_metric_info = orr_group->igp_metric_info;
1116 if (orr_group_igp_metric_info) {
1117 for (ALL_LIST_ELEMENTS_RO(
1118 orr_group_igp_metric_info, node,
1119 igp_metric)) {
1120 if (ret &&
1121 prefix_cmp(&exist_p,
1122 &igp_metric->prefix) ==
1123 0) {
1124 newm = igp_metric->igp_metric;
1125 break;
1126 }
1127 }
1128 }
1129 }
1130 }
1131 if (exist->peer->orr_group_name[afi][safi]) {
1132 ret = str2prefix(exist->peer->host, &exist_p);
1133 orr_group = bgp_orr_group_lookup_by_name(
1134 bgp, afi, safi, exist->peer->orr_group_name[afi][safi]);
1135 if (orr_group) {
1136 orr_group_igp_metric_info = orr_group->igp_metric_info;
1137 if (orr_group_igp_metric_info) {
1138 for (ALL_LIST_ELEMENTS_RO(
1139 orr_group_igp_metric_info, node,
1140 igp_metric)) {
1141 if (ret &&
1142 prefix_cmp(&exist_p,
1143 &igp_metric->prefix) ==
1144 0) {
1145 existm = igp_metric->igp_metric;
1146 break;
1147 }
1148 }
1149 }
1150 }
1151 }
1152
1153 if (newm < existm) {
1154 if (debug && peer_sort_ret < 0)
1155 zlog_debug(
1156 "%s: %s wins over %s due to IGP metric %u < %u",
1157 pfx_buf, new_buf, exist_buf, newm, existm);
1158 igp_metric_ret = 1;
1159 }
1160
1161 if (newm > existm) {
1162 if (debug && peer_sort_ret < 0)
1163 zlog_debug(
1164 "%s: %s loses to %s due to IGP metric %u > %u",
1165 pfx_buf, new_buf, exist_buf, newm, existm);
1166 igp_metric_ret = 0;
1167 }
1168
1169 /* 9. Same IGP metric. Compare the cluster list length as
1170 representative of IGP hops metric. Rewrite the metric value
1171 pair (newm, existm) with the cluster list length. Prefer the
1172 path with smaller cluster list length. */
1173 if (newm == existm) {
1174 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP &&
1175 peer_sort_lookup(exist->peer) == BGP_PEER_IBGP &&
1176 (mpath_cfg == NULL || mpath_cfg->same_clusterlen)) {
1177 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1178 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1179
1180 if (newm < existm) {
1181 if (debug && peer_sort_ret < 0)
1182 zlog_debug(
1183 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1184 pfx_buf, new_buf, exist_buf,
1185 newm, existm);
1186 igp_metric_ret = 1;
1187 }
1188
1189 if (newm > existm) {
1190 if (debug && peer_sort_ret < 0)
1191 zlog_debug(
1192 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1193 pfx_buf, new_buf, exist_buf,
1194 newm, existm);
1195 igp_metric_ret = 0;
1196 }
1197 }
1198 }
1199
1200 /* 10. confed-external vs. confed-internal */
1201 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1202 if (new_sort == BGP_PEER_CONFED
1203 && exist_sort == BGP_PEER_IBGP) {
1204 *reason = bgp_path_selection_confed;
1205 if (debug)
1206 zlog_debug(
1207 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1208 pfx_buf, new_buf, exist_buf);
1209 if (!CHECK_FLAG(bgp->flags,
1210 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1211 return 1;
1212 peer_sort_ret = 1;
1213 }
1214
1215 if (exist_sort == BGP_PEER_CONFED
1216 && new_sort == BGP_PEER_IBGP) {
1217 *reason = bgp_path_selection_confed;
1218 if (debug)
1219 zlog_debug(
1220 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1221 pfx_buf, new_buf, exist_buf);
1222 if (!CHECK_FLAG(bgp->flags,
1223 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1224 return 0;
1225 peer_sort_ret = 0;
1226 }
1227 }
1228
1229 /* 11. Maximum path check. */
1230 if (newm == existm) {
1231 /* If one path has a label but the other does not, do not treat
1232 * them as equals for multipath
1233 */
1234 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1235 != (exist->extra
1236 && bgp_is_valid_label(&exist->extra->label[0]))) {
1237 if (debug)
1238 zlog_debug(
1239 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1240 pfx_buf, new_buf, exist_buf);
1241 } else if (CHECK_FLAG(bgp->flags,
1242 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1243
1244 /*
1245 * For the two paths, all comparison steps till IGP
1246 * metric
1247 * have succeeded - including AS_PATH hop count. Since
1248 * 'bgp
1249 * bestpath as-path multipath-relax' knob is on, we
1250 * don't need
1251 * an exact match of AS_PATH. Thus, mark the paths are
1252 * equal.
1253 * That will trigger both these paths to get into the
1254 * multipath
1255 * array.
1256 */
1257 *paths_eq = 1;
1258
1259 if (debug)
1260 zlog_debug(
1261 "%s: %s and %s are equal via multipath-relax",
1262 pfx_buf, new_buf, exist_buf);
1263 } else if (new->peer->sort == BGP_PEER_IBGP) {
1264 if (aspath_cmp(new->attr->aspath,
1265 exist->attr->aspath)) {
1266 *paths_eq = 1;
1267
1268 if (debug)
1269 zlog_debug(
1270 "%s: %s and %s are equal via matching aspaths",
1271 pfx_buf, new_buf, exist_buf);
1272 }
1273 } else if (new->peer->as == exist->peer->as) {
1274 *paths_eq = 1;
1275
1276 if (debug)
1277 zlog_debug(
1278 "%s: %s and %s are equal via same remote-as",
1279 pfx_buf, new_buf, exist_buf);
1280 }
1281 } else {
1282 /*
1283 * TODO: If unequal cost ibgp multipath is enabled we can
1284 * mark the paths as equal here instead of returning
1285 */
1286
1287 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1288 * if either step 7 or 10 (peer type checks) yielded a winner,
1289 * that result was returned immediately. Returning from step 10
1290 * ignored the return value computed in steps 8 and 9 (IGP
1291 * metric checks). In order to preserve that behavior, if
1292 * peer_sort_ret is set, return that rather than igp_metric_ret.
1293 */
1294 ret = peer_sort_ret;
1295 if (peer_sort_ret < 0) {
1296 ret = igp_metric_ret;
1297 if (debug) {
1298 if (ret == 1)
1299 zlog_debug(
1300 "%s: %s wins over %s after IGP metric comparison",
1301 pfx_buf, new_buf, exist_buf);
1302 else
1303 zlog_debug(
1304 "%s: %s loses to %s after IGP metric comparison",
1305 pfx_buf, new_buf, exist_buf);
1306 }
1307 *reason = bgp_path_selection_igp_metric;
1308 }
1309 return ret;
1310 }
1311
1312 /*
1313 * At this point, the decision whether to set *paths_eq = 1 has been
1314 * completed. If we deferred returning because of bestpath peer-type
1315 * relax configuration, return now.
1316 */
1317 if (peer_sort_ret >= 0)
1318 return peer_sort_ret;
1319
1320 /* 12. If both paths are external, prefer the path that was received
1321 first (the oldest one). This step minimizes route-flap, since a
1322 newer path won't displace an older one, even if it was the
1323 preferred route based on the additional decision criteria below. */
1324 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1325 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1326 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1327 *reason = bgp_path_selection_older;
1328 if (debug)
1329 zlog_debug(
1330 "%s: %s wins over %s due to oldest external",
1331 pfx_buf, new_buf, exist_buf);
1332 return 1;
1333 }
1334
1335 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1336 *reason = bgp_path_selection_older;
1337 if (debug)
1338 zlog_debug(
1339 "%s: %s loses to %s due to oldest external",
1340 pfx_buf, new_buf, exist_buf);
1341 return 0;
1342 }
1343 }
1344
1345 /* 13. Router-ID comparison. */
1346 /* If one of the paths is "stale", the corresponding peer router-id will
1347 * be 0 and would always win over the other path. If originator id is
1348 * used for the comparison, it will decide which path is better.
1349 */
1350 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1351 new_id.s_addr = newattr->originator_id.s_addr;
1352 else
1353 new_id.s_addr = new->peer->remote_id.s_addr;
1354 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1355 exist_id.s_addr = existattr->originator_id.s_addr;
1356 else
1357 exist_id.s_addr = exist->peer->remote_id.s_addr;
1358
1359 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1360 *reason = bgp_path_selection_router_id;
1361 if (debug)
1362 zlog_debug(
1363 "%s: %s wins over %s due to Router-ID comparison",
1364 pfx_buf, new_buf, exist_buf);
1365 return 1;
1366 }
1367
1368 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1369 *reason = bgp_path_selection_router_id;
1370 if (debug)
1371 zlog_debug(
1372 "%s: %s loses to %s due to Router-ID comparison",
1373 pfx_buf, new_buf, exist_buf);
1374 return 0;
1375 }
1376
1377 /* 14. Cluster length comparison. */
1378 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1379 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1380
1381 if (new_cluster < exist_cluster) {
1382 *reason = bgp_path_selection_cluster_length;
1383 if (debug)
1384 zlog_debug(
1385 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1386 pfx_buf, new_buf, exist_buf, new_cluster,
1387 exist_cluster);
1388 return 1;
1389 }
1390
1391 if (new_cluster > exist_cluster) {
1392 *reason = bgp_path_selection_cluster_length;
1393 if (debug)
1394 zlog_debug(
1395 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1396 pfx_buf, new_buf, exist_buf, new_cluster,
1397 exist_cluster);
1398 return 0;
1399 }
1400
1401 /* 15. Neighbor address comparison. */
1402 /* Do this only if neither path is "stale" as stale paths do not have
1403 * valid peer information (as the connection may or may not be up).
1404 */
1405 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1406 *reason = bgp_path_selection_stale;
1407 if (debug)
1408 zlog_debug(
1409 "%s: %s wins over %s due to latter path being STALE",
1410 pfx_buf, new_buf, exist_buf);
1411 return 1;
1412 }
1413
1414 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1415 *reason = bgp_path_selection_stale;
1416 if (debug)
1417 zlog_debug(
1418 "%s: %s loses to %s due to former path being STALE",
1419 pfx_buf, new_buf, exist_buf);
1420 return 0;
1421 }
1422
1423 /* locally configured routes to advertise do not have su_remote */
1424 if (new->peer->su_remote == NULL) {
1425 *reason = bgp_path_selection_local_configured;
1426 return 0;
1427 }
1428 if (exist->peer->su_remote == NULL) {
1429 *reason = bgp_path_selection_local_configured;
1430 return 1;
1431 }
1432
1433 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1434
1435 if (ret == 1) {
1436 *reason = bgp_path_selection_neighbor_ip;
1437 if (debug)
1438 zlog_debug(
1439 "%s: %s loses to %s due to Neighor IP comparison",
1440 pfx_buf, new_buf, exist_buf);
1441 return 0;
1442 }
1443
1444 if (ret == -1) {
1445 *reason = bgp_path_selection_neighbor_ip;
1446 if (debug)
1447 zlog_debug(
1448 "%s: %s wins over %s due to Neighor IP comparison",
1449 pfx_buf, new_buf, exist_buf);
1450 return 1;
1451 }
1452
1453 *reason = bgp_path_selection_default;
1454 if (debug)
1455 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1456 pfx_buf, new_buf, exist_buf);
1457
1458 return 1;
1459 }
1460
1461
1462 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1463 struct bgp_path_info *exist, int *paths_eq)
1464 {
1465 enum bgp_path_selection_reason reason;
1466 char pfx_buf[PREFIX2STR_BUFFER];
1467
1468 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1469 AFI_L2VPN, SAFI_EVPN, &reason);
1470 }
1471
1472 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1473 * is preferred, or 0 if they are the same (usually will only occur if
1474 * multipath is enabled
1475 * This version is compatible with */
1476 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1477 struct bgp_path_info *exist, char *pfx_buf,
1478 afi_t afi, safi_t safi,
1479 enum bgp_path_selection_reason *reason)
1480 {
1481 int paths_eq;
1482 int ret;
1483 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1484 afi, safi, reason);
1485
1486 if (paths_eq)
1487 ret = 0;
1488 else {
1489 if (ret == 1)
1490 ret = -1;
1491 else
1492 ret = 1;
1493 }
1494 return ret;
1495 }
1496
1497 static enum filter_type bgp_input_filter(struct peer *peer,
1498 const struct prefix *p,
1499 struct attr *attr, afi_t afi,
1500 safi_t safi)
1501 {
1502 struct bgp_filter *filter;
1503 enum filter_type ret = FILTER_PERMIT;
1504
1505 filter = &peer->filter[afi][safi];
1506
1507 #define FILTER_EXIST_WARN(F, f, filter) \
1508 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1509 zlog_debug("%s: Could not find configured input %s-list %s!", \
1510 peer->host, #f, F##_IN_NAME(filter));
1511
1512 if (DISTRIBUTE_IN_NAME(filter)) {
1513 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1514
1515 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1516 == FILTER_DENY) {
1517 ret = FILTER_DENY;
1518 goto done;
1519 }
1520 }
1521
1522 if (PREFIX_LIST_IN_NAME(filter)) {
1523 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1524
1525 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1526 == PREFIX_DENY) {
1527 ret = FILTER_DENY;
1528 goto done;
1529 }
1530 }
1531
1532 if (FILTER_LIST_IN_NAME(filter)) {
1533 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1534
1535 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1536 == AS_FILTER_DENY) {
1537 ret = FILTER_DENY;
1538 goto done;
1539 }
1540 }
1541
1542 done:
1543 if (frrtrace_enabled(frr_bgp, input_filter)) {
1544 char pfxprint[PREFIX2STR_BUFFER];
1545
1546 prefix2str(p, pfxprint, sizeof(pfxprint));
1547 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1548 ret == FILTER_PERMIT ? "permit" : "deny");
1549 }
1550
1551 return ret;
1552 #undef FILTER_EXIST_WARN
1553 }
1554
1555 static enum filter_type bgp_output_filter(struct peer *peer,
1556 const struct prefix *p,
1557 struct attr *attr, afi_t afi,
1558 safi_t safi)
1559 {
1560 struct bgp_filter *filter;
1561 enum filter_type ret = FILTER_PERMIT;
1562
1563 filter = &peer->filter[afi][safi];
1564
1565 #define FILTER_EXIST_WARN(F, f, filter) \
1566 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1567 zlog_debug("%s: Could not find configured output %s-list %s!", \
1568 peer->host, #f, F##_OUT_NAME(filter));
1569
1570 if (DISTRIBUTE_OUT_NAME(filter)) {
1571 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1572
1573 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1574 == FILTER_DENY) {
1575 ret = FILTER_DENY;
1576 goto done;
1577 }
1578 }
1579
1580 if (PREFIX_LIST_OUT_NAME(filter)) {
1581 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1582
1583 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1584 == PREFIX_DENY) {
1585 ret = FILTER_DENY;
1586 goto done;
1587 }
1588 }
1589
1590 if (FILTER_LIST_OUT_NAME(filter)) {
1591 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1592
1593 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1594 == AS_FILTER_DENY) {
1595 ret = FILTER_DENY;
1596 goto done;
1597 }
1598 }
1599
1600 if (frrtrace_enabled(frr_bgp, output_filter)) {
1601 char pfxprint[PREFIX2STR_BUFFER];
1602
1603 prefix2str(p, pfxprint, sizeof(pfxprint));
1604 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1605 ret == FILTER_PERMIT ? "permit" : "deny");
1606 }
1607
1608 done:
1609 return ret;
1610 #undef FILTER_EXIST_WARN
1611 }
1612
1613 /* If community attribute includes no_export then return 1. */
1614 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1615 {
1616 if (bgp_attr_get_community(attr)) {
1617 /* NO_ADVERTISE check. */
1618 if (community_include(bgp_attr_get_community(attr),
1619 COMMUNITY_NO_ADVERTISE))
1620 return true;
1621
1622 /* NO_EXPORT check. */
1623 if (peer->sort == BGP_PEER_EBGP &&
1624 community_include(bgp_attr_get_community(attr),
1625 COMMUNITY_NO_EXPORT))
1626 return true;
1627
1628 /* NO_EXPORT_SUBCONFED check. */
1629 if (peer->sort == BGP_PEER_EBGP
1630 || peer->sort == BGP_PEER_CONFED)
1631 if (community_include(bgp_attr_get_community(attr),
1632 COMMUNITY_NO_EXPORT_SUBCONFED))
1633 return true;
1634 }
1635 return false;
1636 }
1637
1638 /* Route reflection loop check. */
1639 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1640 {
1641 struct in_addr cluster_id;
1642 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1643
1644 if (cluster) {
1645 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1646 cluster_id = peer->bgp->cluster_id;
1647 else
1648 cluster_id = peer->bgp->router_id;
1649
1650 if (cluster_loop_check(cluster, cluster_id))
1651 return true;
1652 }
1653 return false;
1654 }
1655
1656 static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
1657 {
1658 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1659 if (peer->local_role == ROLE_PROVIDER ||
1660 peer->local_role == ROLE_RS_SERVER)
1661 return true;
1662 if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
1663 return true;
1664 return false;
1665 }
1666 if (peer->local_role == ROLE_CUSTOMER ||
1667 peer->local_role == ROLE_PEER ||
1668 peer->local_role == ROLE_RS_CLIENT) {
1669 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1670 attr->otc = peer->as;
1671 }
1672 return false;
1673 }
1674
1675 static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
1676 {
1677 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1678 if (peer->local_role == ROLE_CUSTOMER ||
1679 peer->local_role == ROLE_RS_CLIENT ||
1680 peer->local_role == ROLE_PEER)
1681 return true;
1682 return false;
1683 }
1684 if (peer->local_role == ROLE_PROVIDER ||
1685 peer->local_role == ROLE_PEER ||
1686 peer->local_role == ROLE_RS_SERVER) {
1687 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1688 attr->otc = peer->bgp->as;
1689 }
1690 return false;
1691 }
1692
1693 static bool bgp_check_role_applicability(afi_t afi, safi_t safi)
1694 {
1695 return ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST);
1696 }
1697
1698 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1699 struct attr *attr, afi_t afi, safi_t safi,
1700 const char *rmap_name, mpls_label_t *label,
1701 uint32_t num_labels, struct bgp_dest *dest)
1702 {
1703 struct bgp_filter *filter;
1704 struct bgp_path_info rmap_path = { 0 };
1705 struct bgp_path_info_extra extra = { 0 };
1706 route_map_result_t ret;
1707 struct route_map *rmap = NULL;
1708
1709 filter = &peer->filter[afi][safi];
1710
1711 /* Apply default weight value. */
1712 if (peer->weight[afi][safi])
1713 attr->weight = peer->weight[afi][safi];
1714
1715 if (rmap_name) {
1716 rmap = route_map_lookup_by_name(rmap_name);
1717
1718 if (rmap == NULL)
1719 return RMAP_DENY;
1720 } else {
1721 if (ROUTE_MAP_IN_NAME(filter)) {
1722 rmap = ROUTE_MAP_IN(filter);
1723
1724 if (rmap == NULL)
1725 return RMAP_DENY;
1726 }
1727 }
1728
1729 /* Route map apply. */
1730 if (rmap) {
1731 memset(&rmap_path, 0, sizeof(rmap_path));
1732 /* Duplicate current value to new structure for modification. */
1733 rmap_path.peer = peer;
1734 rmap_path.attr = attr;
1735 rmap_path.extra = &extra;
1736 rmap_path.net = dest;
1737
1738 extra.num_labels = num_labels;
1739 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1740 memcpy(extra.label, label,
1741 num_labels * sizeof(mpls_label_t));
1742
1743 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1744
1745 /* Apply BGP route map to the attribute. */
1746 ret = route_map_apply(rmap, p, &rmap_path);
1747
1748 peer->rmap_type = 0;
1749
1750 if (ret == RMAP_DENYMATCH)
1751 return RMAP_DENY;
1752 }
1753 return RMAP_PERMIT;
1754 }
1755
1756 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1757 struct attr *attr, afi_t afi, safi_t safi,
1758 const char *rmap_name)
1759 {
1760 struct bgp_path_info rmap_path;
1761 route_map_result_t ret;
1762 struct route_map *rmap = NULL;
1763 uint8_t rmap_type;
1764
1765 /*
1766 * So if we get to this point and have no rmap_name
1767 * we want to just show the output as it currently
1768 * exists.
1769 */
1770 if (!rmap_name)
1771 return RMAP_PERMIT;
1772
1773 /* Apply default weight value. */
1774 if (peer->weight[afi][safi])
1775 attr->weight = peer->weight[afi][safi];
1776
1777 rmap = route_map_lookup_by_name(rmap_name);
1778
1779 /*
1780 * If we have a route map name and we do not find
1781 * the routemap that means we have an implicit
1782 * deny.
1783 */
1784 if (rmap == NULL)
1785 return RMAP_DENY;
1786
1787 memset(&rmap_path, 0, sizeof(rmap_path));
1788 /* Route map apply. */
1789 /* Duplicate current value to new structure for modification. */
1790 rmap_path.peer = peer;
1791 rmap_path.attr = attr;
1792
1793 rmap_type = peer->rmap_type;
1794 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1795
1796 /* Apply BGP route map to the attribute. */
1797 ret = route_map_apply(rmap, p, &rmap_path);
1798
1799 peer->rmap_type = rmap_type;
1800
1801 if (ret == RMAP_DENYMATCH)
1802 /*
1803 * caller has multiple error paths with bgp_attr_flush()
1804 */
1805 return RMAP_DENY;
1806
1807 return RMAP_PERMIT;
1808 }
1809
1810 /* If this is an EBGP peer with remove-private-AS */
1811 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1812 struct peer *peer, struct attr *attr)
1813 {
1814 if (peer->sort == BGP_PEER_EBGP
1815 && (peer_af_flag_check(peer, afi, safi,
1816 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1817 || peer_af_flag_check(peer, afi, safi,
1818 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1819 || peer_af_flag_check(peer, afi, safi,
1820 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1821 || peer_af_flag_check(peer, afi, safi,
1822 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1823 // Take action on the entire aspath
1824 if (peer_af_flag_check(peer, afi, safi,
1825 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1826 || peer_af_flag_check(peer, afi, safi,
1827 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1828 if (peer_af_flag_check(
1829 peer, afi, safi,
1830 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1831 attr->aspath = aspath_replace_private_asns(
1832 attr->aspath, bgp->as, peer->as);
1833
1834 /*
1835 * Even if the aspath consists of just private ASNs we
1836 * need to walk the AS-Path to maintain all instances
1837 * of the peer's ASN to break possible loops.
1838 */
1839 else
1840 attr->aspath = aspath_remove_private_asns(
1841 attr->aspath, peer->as);
1842 }
1843
1844 // 'all' was not specified so the entire aspath must be private
1845 // ASNs
1846 // for us to do anything
1847 else if (aspath_private_as_check(attr->aspath)) {
1848 if (peer_af_flag_check(
1849 peer, afi, safi,
1850 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1851 attr->aspath = aspath_replace_private_asns(
1852 attr->aspath, bgp->as, peer->as);
1853 else
1854 /*
1855 * Walk the aspath to retain any instances of
1856 * the peer_asn
1857 */
1858 attr->aspath = aspath_remove_private_asns(
1859 attr->aspath, peer->as);
1860 }
1861 }
1862 }
1863
1864 /* If this is an EBGP peer with as-override */
1865 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1866 struct peer *peer, struct attr *attr)
1867 {
1868 struct aspath *aspath;
1869
1870 if (peer->sort == BGP_PEER_EBGP &&
1871 peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1872 if (attr->aspath->refcnt)
1873 aspath = aspath_dup(attr->aspath);
1874 else
1875 aspath = attr->aspath;
1876
1877 attr->aspath = aspath_intern(
1878 aspath_replace_specific_asn(aspath, peer->as, bgp->as));
1879
1880 aspath_free(aspath);
1881 }
1882 }
1883
1884 void bgp_attr_add_llgr_community(struct attr *attr)
1885 {
1886 struct community *old;
1887 struct community *new;
1888 struct community *merge;
1889 struct community *llgr;
1890
1891 old = bgp_attr_get_community(attr);
1892 llgr = community_str2com("llgr-stale");
1893
1894 assert(llgr);
1895
1896 if (old) {
1897 merge = community_merge(community_dup(old), llgr);
1898
1899 if (old->refcnt == 0)
1900 community_free(&old);
1901
1902 new = community_uniq_sort(merge);
1903 community_free(&merge);
1904 } else {
1905 new = community_dup(llgr);
1906 }
1907
1908 community_free(&llgr);
1909
1910 bgp_attr_set_community(attr, new);
1911 }
1912
1913 void bgp_attr_add_gshut_community(struct attr *attr)
1914 {
1915 struct community *old;
1916 struct community *new;
1917 struct community *merge;
1918 struct community *gshut;
1919
1920 old = bgp_attr_get_community(attr);
1921 gshut = community_str2com("graceful-shutdown");
1922
1923 assert(gshut);
1924
1925 if (old) {
1926 merge = community_merge(community_dup(old), gshut);
1927
1928 if (old->refcnt == 0)
1929 community_free(&old);
1930
1931 new = community_uniq_sort(merge);
1932 community_free(&merge);
1933 } else {
1934 new = community_dup(gshut);
1935 }
1936
1937 community_free(&gshut);
1938 bgp_attr_set_community(attr, new);
1939
1940 /* When we add the graceful-shutdown community we must also
1941 * lower the local-preference */
1942 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1943 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1944 }
1945
1946
1947 /* Notify BGP Conditional advertisement scanner process. */
1948 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1949 {
1950 struct peer *peer = SUBGRP_PEER(subgrp);
1951 afi_t afi = SUBGRP_AFI(subgrp);
1952 safi_t safi = SUBGRP_SAFI(subgrp);
1953 struct bgp_filter *filter = &peer->filter[afi][safi];
1954
1955 if (!ADVERTISE_MAP_NAME(filter))
1956 return;
1957
1958 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1959 return;
1960
1961 peer->advmap_table_change = true;
1962 }
1963
1964
1965 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1966 {
1967 if (family == AF_INET) {
1968 attr->nexthop.s_addr = INADDR_ANY;
1969 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1970 }
1971 if (family == AF_INET6)
1972 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1973 if (family == AF_EVPN)
1974 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1975 }
1976
1977 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1978 struct update_subgroup *subgrp,
1979 const struct prefix *p, struct attr *attr,
1980 struct attr *post_attr)
1981 {
1982 struct bgp_filter *filter;
1983 struct peer *from;
1984 struct peer *peer;
1985 struct peer *onlypeer;
1986 struct bgp *bgp;
1987 struct attr *piattr;
1988 route_map_result_t ret;
1989 int transparent;
1990 int reflect;
1991 afi_t afi;
1992 safi_t safi;
1993 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1994 bool nh_reset = false;
1995 uint64_t cum_bw;
1996
1997 if (DISABLE_BGP_ANNOUNCE)
1998 return false;
1999
2000 afi = SUBGRP_AFI(subgrp);
2001 safi = SUBGRP_SAFI(subgrp);
2002 peer = SUBGRP_PEER(subgrp);
2003 onlypeer = NULL;
2004 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
2005 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
2006
2007 from = pi->peer;
2008 filter = &peer->filter[afi][safi];
2009 bgp = SUBGRP_INST(subgrp);
2010 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
2011 : pi->attr;
2012
2013 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
2014 peer->pmax_out[afi][safi] != 0 &&
2015 subgrp->pscount >= peer->pmax_out[afi][safi]) {
2016 if (BGP_DEBUG(update, UPDATE_OUT) ||
2017 BGP_DEBUG(update, UPDATE_PREFIX)) {
2018 zlog_debug("%s reached maximum prefix to be send (%u)",
2019 peer->host, peer->pmax_out[afi][safi]);
2020 }
2021 return false;
2022 }
2023
2024 #ifdef ENABLE_BGP_VNC
2025 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
2026 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
2027 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
2028
2029 /*
2030 * direct and direct_ext type routes originate internally even
2031 * though they can have peer pointers that reference other
2032 * systems
2033 */
2034 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
2035 __func__, p);
2036 samepeer_safe = 1;
2037 }
2038 #endif
2039
2040 if (((afi == AFI_IP) || (afi == AFI_IP6))
2041 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
2042 && (pi->type == ZEBRA_ROUTE_BGP)
2043 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
2044
2045 /* Applies to routes leaked vpn->vrf and vrf->vpn */
2046
2047 samepeer_safe = 1;
2048 }
2049
2050 /* With addpath we may be asked to TX all kinds of paths so make sure
2051 * pi is valid */
2052 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
2053 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
2054 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
2055 return false;
2056 }
2057
2058 /* If this is not the bestpath then check to see if there is an enabled
2059 * addpath
2060 * feature that requires us to advertise it */
2061 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
2062 if (!bgp_addpath_tx_path(peer->addpath_type[afi][safi], pi)) {
2063 return false;
2064 }
2065 }
2066
2067 /* Aggregate-address suppress check. */
2068 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
2069 return false;
2070
2071 /*
2072 * If we are doing VRF 2 VRF leaking via the import
2073 * statement, we want to prevent the route going
2074 * off box as that the RT and RD created are localy
2075 * significant and globaly useless.
2076 */
2077 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
2078 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
2079 return false;
2080
2081 /* If it's labeled safi, make sure the route has a valid label. */
2082 if (safi == SAFI_LABELED_UNICAST) {
2083 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
2084 if (!bgp_is_valid_label(&label)) {
2085 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2086 zlog_debug("u%" PRIu64 ":s%" PRIu64
2087 " %pFX is filtered - no label (%p)",
2088 subgrp->update_group->id, subgrp->id,
2089 p, &label);
2090 return false;
2091 }
2092 }
2093
2094 /* Do not send back route to sender. */
2095 if (onlypeer && from == onlypeer) {
2096 return false;
2097 }
2098
2099 /* Do not send the default route in the BGP table if the neighbor is
2100 * configured for default-originate */
2101 if (CHECK_FLAG(peer->af_flags[afi][safi],
2102 PEER_FLAG_DEFAULT_ORIGINATE)) {
2103 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
2104 return false;
2105 else if (p->family == AF_INET6 && p->prefixlen == 0)
2106 return false;
2107 }
2108
2109 /* Transparency check. */
2110 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
2111 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
2112 transparent = 1;
2113 else
2114 transparent = 0;
2115
2116 /* If community is not disabled check the no-export and local. */
2117 if (!transparent && bgp_community_filter(peer, piattr)) {
2118 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2119 zlog_debug("%s: community filter check fail for %pFX",
2120 __func__, p);
2121 return false;
2122 }
2123
2124 /* If the attribute has originator-id and it is same as remote
2125 peer's id. */
2126 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
2127 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
2128 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2129 zlog_debug(
2130 "%pBP [Update:SEND] %pFX originator-id is same as remote router-id",
2131 onlypeer, p);
2132 return false;
2133 }
2134
2135 /* ORF prefix-list filter check */
2136 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
2137 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
2138 || CHECK_FLAG(peer->af_cap[afi][safi],
2139 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2140 if (peer->orf_plist[afi][safi]) {
2141 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2142 == PREFIX_DENY) {
2143 if (bgp_debug_update(NULL, p,
2144 subgrp->update_group, 0))
2145 zlog_debug(
2146 "%pBP [Update:SEND] %pFX is filtered via ORF",
2147 peer, p);
2148 return false;
2149 }
2150 }
2151
2152 /* Output filter check. */
2153 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2154 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2155 zlog_debug("%pBP [Update:SEND] %pFX is filtered", peer,
2156 p);
2157 return false;
2158 }
2159
2160 /* AS path loop check. */
2161 if (onlypeer && onlypeer->as_path_loop_detection
2162 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
2163 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2164 zlog_debug(
2165 "%pBP [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2166 onlypeer, onlypeer->as);
2167 return false;
2168 }
2169
2170 /* If we're a CONFED we need to loop check the CONFED ID too */
2171 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2172 if (aspath_loop_check(piattr->aspath, bgp->confed_id)) {
2173 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2174 zlog_debug(
2175 "%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
2176 peer, bgp->confed_id);
2177 return false;
2178 }
2179 }
2180
2181 /* Route-Reflect check. */
2182 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2183 reflect = 1;
2184 else
2185 reflect = 0;
2186
2187 /* IBGP reflection check. */
2188 if (reflect && !samepeer_safe) {
2189 /* A route from a Client peer. */
2190 if (CHECK_FLAG(from->af_flags[afi][safi],
2191 PEER_FLAG_REFLECTOR_CLIENT)) {
2192 /* Reflect to all the Non-Client peers and also to the
2193 Client peers other than the originator. Originator
2194 check
2195 is already done. So there is noting to do. */
2196 /* no bgp client-to-client reflection check. */
2197 if (CHECK_FLAG(bgp->flags,
2198 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2199 if (CHECK_FLAG(peer->af_flags[afi][safi],
2200 PEER_FLAG_REFLECTOR_CLIENT))
2201 return false;
2202 } else {
2203 /* A route from a Non-client peer. Reflect to all other
2204 clients. */
2205 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2206 PEER_FLAG_REFLECTOR_CLIENT))
2207 return false;
2208 }
2209 }
2210
2211 /* For modify attribute, copy it to temporary structure.
2212 * post_attr comes from BGP conditional advertisements, where
2213 * attributes are already processed by advertise-map route-map,
2214 * and this needs to be saved instead of overwriting from the
2215 * path attributes.
2216 */
2217 if (post_attr)
2218 *attr = *post_attr;
2219 else
2220 *attr = *piattr;
2221
2222 /* If local-preference is not set. */
2223 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2224 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2225 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2226 attr->local_pref = bgp->default_local_pref;
2227 }
2228
2229 /* If originator-id is not set and the route is to be reflected,
2230 set the originator id */
2231 if (reflect
2232 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2233 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2234 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2235 }
2236
2237 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2238 */
2239 if (peer->sort == BGP_PEER_EBGP
2240 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2241 if (from != bgp->peer_self && !transparent
2242 && !CHECK_FLAG(peer->af_flags[afi][safi],
2243 PEER_FLAG_MED_UNCHANGED))
2244 attr->flag &=
2245 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2246 }
2247
2248 /* Since the nexthop attribute can vary per peer, it is not explicitly
2249 * set
2250 * in announce check, only certain flags and length (or number of
2251 * nexthops
2252 * -- for IPv6/MP_REACH) are set here in order to guide the update
2253 * formation
2254 * code in setting the nexthop(s) on a per peer basis in
2255 * reformat_peer().
2256 * Typically, the source nexthop in the attribute is preserved but in
2257 * the
2258 * scenarios where we know it will always be overwritten, we reset the
2259 * nexthop to "0" in an attempt to achieve better Update packing. An
2260 * example of this is when a prefix from each of 2 IBGP peers needs to
2261 * be
2262 * announced to an EBGP peer (and they have the same attributes barring
2263 * their nexthop).
2264 */
2265 if (reflect)
2266 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2267
2268 #define NEXTHOP_IS_V6 \
2269 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2270 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2271 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2272 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2273
2274 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2275 * if
2276 * the peer (group) is configured to receive link-local nexthop
2277 * unchanged
2278 * and it is available in the prefix OR we're not reflecting the route,
2279 * link-local nexthop address is valid and
2280 * the peer (group) to whom we're going to announce is on a shared
2281 * network
2282 * and this is either a self-originated route or the peer is EBGP.
2283 * By checking if nexthop LL address is valid we are sure that
2284 * we do not announce LL address as `::`.
2285 */
2286 if (NEXTHOP_IS_V6) {
2287 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2288 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2289 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2290 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2291 || (!reflect && !transparent
2292 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2293 && peer->shared_network
2294 && (from == bgp->peer_self
2295 || peer->sort == BGP_PEER_EBGP))) {
2296 attr->mp_nexthop_len =
2297 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2298 }
2299
2300 /* Clear off link-local nexthop in source, whenever it is not
2301 * needed to
2302 * ensure more prefixes share the same attribute for
2303 * announcement.
2304 */
2305 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2306 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2307 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2308 }
2309
2310 if (bgp_check_role_applicability(afi, safi) &&
2311 bgp_otc_egress(peer, attr))
2312 return false;
2313
2314 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2315 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2316
2317 if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
2318 filter->advmap.aname &&
2319 route_map_lookup_by_name(filter->advmap.aname)) {
2320 struct bgp_path_info rmap_path = {0};
2321 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2322 struct attr dummy_attr = *attr;
2323
2324 /* Fill temp path_info */
2325 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2326 pi, peer, &dummy_attr);
2327
2328 struct route_map *amap =
2329 route_map_lookup_by_name(filter->advmap.aname);
2330
2331 ret = route_map_apply(amap, p, &rmap_path);
2332
2333 bgp_attr_flush(&dummy_attr);
2334
2335 /*
2336 * The conditional advertisement mode is Withdraw and this
2337 * prefix is a conditional prefix. Don't advertise it
2338 */
2339 if (ret == RMAP_PERMITMATCH)
2340 return false;
2341 }
2342
2343 /* Route map & unsuppress-map apply. */
2344 if (!post_attr &&
2345 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2346 struct bgp_path_info rmap_path = {0};
2347 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2348 struct attr dummy_attr = {0};
2349
2350 /* Fill temp path_info */
2351 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2352 pi, peer, attr);
2353
2354 /* don't confuse inbound and outbound setting */
2355 RESET_FLAG(attr->rmap_change_flags);
2356
2357 /*
2358 * The route reflector is not allowed to modify the attributes
2359 * of the reflected IBGP routes unless explicitly allowed.
2360 */
2361 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2362 && !CHECK_FLAG(bgp->flags,
2363 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2364 dummy_attr = *attr;
2365 rmap_path.attr = &dummy_attr;
2366 }
2367
2368 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2369
2370 if (bgp_path_suppressed(pi))
2371 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2372 &rmap_path);
2373 else
2374 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2375 &rmap_path);
2376
2377 bgp_attr_flush(&dummy_attr);
2378 peer->rmap_type = 0;
2379
2380 if (ret == RMAP_DENYMATCH) {
2381 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2382 zlog_debug(
2383 "%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
2384 peer, p, ROUTE_MAP_OUT_NAME(filter));
2385 bgp_attr_flush(rmap_path.attr);
2386 return false;
2387 }
2388 }
2389
2390 /* RFC 8212 to prevent route leaks.
2391 * This specification intends to improve this situation by requiring the
2392 * explicit configuration of both BGP Import and Export Policies for any
2393 * External BGP (EBGP) session such as customers, peers, or
2394 * confederation boundaries for all enabled address families. Through
2395 * codification of the aforementioned requirement, operators will
2396 * benefit from consistent behavior across different BGP
2397 * implementations.
2398 */
2399 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2400 if (!bgp_outbound_policy_exists(peer, filter)) {
2401 if (monotime_since(&bgp->ebgprequirespolicywarning,
2402 NULL) > FIFTEENMINUTE2USEC ||
2403 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2404 zlog_warn(
2405 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2406 monotime(&bgp->ebgprequirespolicywarning);
2407 }
2408 return false;
2409 }
2410
2411 /* draft-ietf-idr-deprecate-as-set-confed-set
2412 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2413 * Eventually, This document (if approved) updates RFC 4271
2414 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2415 * and obsoletes RFC 6472.
2416 */
2417 if (peer->bgp->reject_as_sets)
2418 if (aspath_check_as_sets(attr->aspath))
2419 return false;
2420
2421 /* If neighbor sso is configured, then check if the route has
2422 * SoO extended community and validate against the configured
2423 * one. If they match, do not announce, to prevent routing
2424 * loops.
2425 */
2426 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2427 peer->soo[afi][safi]) {
2428 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2429 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2430
2431 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2432 ECOMMUNITY_SITE_ORIGIN) ||
2433 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2434 ECOMMUNITY_SITE_ORIGIN)) &&
2435 ecommunity_include(ecomm, ecomm_soo)) {
2436 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2437 zlog_debug(
2438 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2439 peer, p, ecommunity_str(ecomm_soo));
2440 return false;
2441 }
2442 }
2443
2444 /* Codification of AS 0 Processing */
2445 if (aspath_check_as_zero(attr->aspath))
2446 return false;
2447
2448 if (bgp_in_graceful_shutdown(bgp)) {
2449 if (peer->sort == BGP_PEER_IBGP
2450 || peer->sort == BGP_PEER_CONFED) {
2451 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2452 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2453 } else {
2454 bgp_attr_add_gshut_community(attr);
2455 }
2456 }
2457
2458 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2459 * Capability" to a neighbor MUST perform the following upon receiving
2460 * a route from that neighbor with the "LLGR_STALE" community, or upon
2461 * attaching the "LLGR_STALE" community itself per Section 4.2:
2462 *
2463 * The route SHOULD NOT be advertised to any neighbor from which the
2464 * Long-lived Graceful Restart Capability has not been received.
2465 */
2466 if (bgp_attr_get_community(attr) &&
2467 community_include(bgp_attr_get_community(attr),
2468 COMMUNITY_LLGR_STALE) &&
2469 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2470 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2471 return false;
2472
2473 /* After route-map has been applied, we check to see if the nexthop to
2474 * be carried in the attribute (that is used for the announcement) can
2475 * be cleared off or not. We do this in all cases where we would be
2476 * setting the nexthop to "ourselves". For IPv6, we only need to
2477 * consider
2478 * the global nexthop here; the link-local nexthop would have been
2479 * cleared
2480 * already, and if not, it is required by the update formation code.
2481 * Also see earlier comments in this function.
2482 */
2483 /*
2484 * If route-map has performed some operation on the nexthop or the peer
2485 * configuration says to pass it unchanged, we cannot reset the nexthop
2486 * here, so only attempt to do it if these aren't true. Note that the
2487 * route-map handler itself might have cleared the nexthop, if for
2488 * example,
2489 * it is configured as 'peer-address'.
2490 */
2491 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2492 piattr->rmap_change_flags)
2493 && !transparent
2494 && !CHECK_FLAG(peer->af_flags[afi][safi],
2495 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2496 /* We can reset the nexthop, if setting (or forcing) it to
2497 * 'self' */
2498 if (CHECK_FLAG(peer->af_flags[afi][safi],
2499 PEER_FLAG_NEXTHOP_SELF)
2500 || CHECK_FLAG(peer->af_flags[afi][safi],
2501 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2502 if (!reflect
2503 || CHECK_FLAG(peer->af_flags[afi][safi],
2504 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2505 subgroup_announce_reset_nhop(
2506 (peer_cap_enhe(peer, afi, safi)
2507 ? AF_INET6
2508 : p->family),
2509 attr);
2510 nh_reset = true;
2511 }
2512 } else if (peer->sort == BGP_PEER_EBGP) {
2513 /* Can also reset the nexthop if announcing to EBGP, but
2514 * only if
2515 * no peer in the subgroup is on a shared subnet.
2516 * Note: 3rd party nexthop currently implemented for
2517 * IPv4 only.
2518 */
2519 if ((p->family == AF_INET) &&
2520 (!bgp_subgrp_multiaccess_check_v4(
2521 piattr->nexthop,
2522 subgrp, from))) {
2523 subgroup_announce_reset_nhop(
2524 (peer_cap_enhe(peer, afi, safi)
2525 ? AF_INET6
2526 : p->family),
2527 attr);
2528 nh_reset = true;
2529 }
2530
2531 if ((p->family == AF_INET6) &&
2532 (!bgp_subgrp_multiaccess_check_v6(
2533 piattr->mp_nexthop_global,
2534 subgrp, from))) {
2535 subgroup_announce_reset_nhop(
2536 (peer_cap_enhe(peer, afi, safi)
2537 ? AF_INET6
2538 : p->family),
2539 attr);
2540 nh_reset = true;
2541 }
2542
2543
2544
2545 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2546 /*
2547 * This flag is used for leaked vpn-vrf routes
2548 */
2549 int family = p->family;
2550
2551 if (peer_cap_enhe(peer, afi, safi))
2552 family = AF_INET6;
2553
2554 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2555 zlog_debug(
2556 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
2557 __func__, family2str(family));
2558 subgroup_announce_reset_nhop(family, attr);
2559 nh_reset = true;
2560 }
2561 }
2562
2563 /* If IPv6/MP and nexthop does not have any override and happens
2564 * to
2565 * be a link-local address, reset it so that we don't pass along
2566 * the
2567 * source's link-local IPv6 address to recipients who may not be
2568 * on
2569 * the same interface.
2570 */
2571 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2572 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2573 subgroup_announce_reset_nhop(AF_INET6, attr);
2574 nh_reset = true;
2575 }
2576 }
2577
2578 /* If this is an iBGP, send Origin Validation State (OVS)
2579 * extended community (rfc8097).
2580 */
2581 if (peer->sort == BGP_PEER_IBGP) {
2582 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2583
2584 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2585
2586 if (rpki_state != RPKI_NOT_BEING_USED)
2587 bgp_attr_set_ecommunity(
2588 attr, ecommunity_add_origin_validation_state(
2589 rpki_state,
2590 bgp_attr_get_ecommunity(attr)));
2591 }
2592
2593 /*
2594 * When the next hop is set to ourselves, if all multipaths have
2595 * link-bandwidth announce the cumulative bandwidth as that makes
2596 * the most sense. However, don't modify if the link-bandwidth has
2597 * been explicitly set by user policy.
2598 */
2599 if (nh_reset &&
2600 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2601 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2602 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2603 bgp_attr_set_ecommunity(
2604 attr,
2605 ecommunity_replace_linkbw(
2606 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2607 CHECK_FLAG(
2608 peer->flags,
2609 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2610
2611 return true;
2612 }
2613
2614 static void bgp_route_select_timer_expire(struct thread *thread)
2615 {
2616 struct afi_safi_info *info;
2617 afi_t afi;
2618 safi_t safi;
2619 struct bgp *bgp;
2620
2621 info = THREAD_ARG(thread);
2622 afi = info->afi;
2623 safi = info->safi;
2624 bgp = info->bgp;
2625
2626 if (BGP_DEBUG(update, UPDATE_OUT))
2627 zlog_debug("afi %d, safi %d : route select timer expired", afi,
2628 safi);
2629
2630 bgp->gr_info[afi][safi].t_route_select = NULL;
2631
2632 XFREE(MTYPE_TMP, info);
2633
2634 /* Best path selection */
2635 bgp_best_path_select_defer(bgp, afi, safi);
2636 }
2637
2638 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2639 struct bgp_maxpaths_cfg *mpath_cfg,
2640 struct bgp_path_info_pair *result, afi_t afi,
2641 safi_t safi)
2642 {
2643 struct bgp_path_info *new_select;
2644 struct bgp_path_info *old_select;
2645 struct bgp_path_info *pi;
2646 struct bgp_path_info *pi1;
2647 struct bgp_path_info *pi2;
2648 struct bgp_path_info *nextpi = NULL;
2649 int paths_eq, do_mpath, debug;
2650 struct list mp_list;
2651 char pfx_buf[PREFIX2STR_BUFFER];
2652 char path_buf[PATH_ADDPATH_STR_BUFFER];
2653
2654 bgp_mp_list_init(&mp_list);
2655 do_mpath =
2656 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2657
2658 debug = bgp_debug_bestpath(dest);
2659
2660 if (debug)
2661 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2662
2663 dest->reason = bgp_path_selection_none;
2664 /* bgp deterministic-med */
2665 new_select = NULL;
2666 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2667
2668 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2669 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2670 pi1 = pi1->next)
2671 bgp_path_info_unset_flag(dest, pi1,
2672 BGP_PATH_DMED_SELECTED);
2673
2674 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2675 pi1 = pi1->next) {
2676 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2677 continue;
2678 if (BGP_PATH_HOLDDOWN(pi1))
2679 continue;
2680 if (pi1->peer != bgp->peer_self)
2681 if (!peer_established(pi1->peer))
2682 continue;
2683
2684 new_select = pi1;
2685 if (pi1->next) {
2686 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2687 if (CHECK_FLAG(pi2->flags,
2688 BGP_PATH_DMED_CHECK))
2689 continue;
2690 if (BGP_PATH_HOLDDOWN(pi2))
2691 continue;
2692 if (pi2->peer != bgp->peer_self
2693 && !CHECK_FLAG(
2694 pi2->peer->sflags,
2695 PEER_STATUS_NSF_WAIT))
2696 if (pi2->peer->status
2697 != Established)
2698 continue;
2699
2700 if (!aspath_cmp_left(pi1->attr->aspath,
2701 pi2->attr->aspath)
2702 && !aspath_cmp_left_confed(
2703 pi1->attr->aspath,
2704 pi2->attr->aspath))
2705 continue;
2706
2707 if (bgp_path_info_cmp(
2708 bgp, pi2, new_select,
2709 &paths_eq, mpath_cfg, debug,
2710 pfx_buf, afi, safi,
2711 &dest->reason)) {
2712 bgp_path_info_unset_flag(
2713 dest, new_select,
2714 BGP_PATH_DMED_SELECTED);
2715 new_select = pi2;
2716 }
2717
2718 bgp_path_info_set_flag(
2719 dest, pi2, BGP_PATH_DMED_CHECK);
2720 }
2721 }
2722 bgp_path_info_set_flag(dest, new_select,
2723 BGP_PATH_DMED_CHECK);
2724 bgp_path_info_set_flag(dest, new_select,
2725 BGP_PATH_DMED_SELECTED);
2726
2727 if (debug) {
2728 bgp_path_info_path_with_addpath_rx_str(
2729 new_select, path_buf, sizeof(path_buf));
2730 zlog_debug(
2731 "%pBD(%s): %s is the bestpath from AS %u",
2732 dest, bgp->name_pretty, path_buf,
2733 aspath_get_first_as(
2734 new_select->attr->aspath));
2735 }
2736 }
2737 }
2738
2739 /* Check old selected route and new selected route. */
2740 old_select = NULL;
2741 new_select = NULL;
2742 for (pi = bgp_dest_get_bgp_path_info(dest);
2743 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2744 enum bgp_path_selection_reason reason;
2745
2746 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2747 old_select = pi;
2748
2749 if (BGP_PATH_HOLDDOWN(pi)) {
2750 /* reap REMOVED routes, if needs be
2751 * selected route must stay for a while longer though
2752 */
2753 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2754 && (pi != old_select))
2755 bgp_path_info_reap(dest, pi);
2756
2757 if (debug)
2758 zlog_debug("%s: pi %p in holddown", __func__,
2759 pi);
2760
2761 continue;
2762 }
2763
2764 if (pi->peer && pi->peer != bgp->peer_self
2765 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2766 if (!peer_established(pi->peer)) {
2767
2768 if (debug)
2769 zlog_debug(
2770 "%s: pi %p non self peer %s not estab state",
2771 __func__, pi, pi->peer->host);
2772
2773 continue;
2774 }
2775
2776 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2777 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2778 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2779 if (debug)
2780 zlog_debug("%s: pi %p dmed", __func__, pi);
2781 continue;
2782 }
2783
2784 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2785
2786 reason = dest->reason;
2787 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2788 debug, pfx_buf, afi, safi,
2789 &dest->reason)) {
2790 if (new_select == NULL &&
2791 reason != bgp_path_selection_none)
2792 dest->reason = reason;
2793 new_select = pi;
2794 }
2795 }
2796
2797 /* Now that we know which path is the bestpath see if any of the other
2798 * paths
2799 * qualify as multipaths
2800 */
2801 if (debug) {
2802 if (new_select)
2803 bgp_path_info_path_with_addpath_rx_str(
2804 new_select, path_buf, sizeof(path_buf));
2805 else
2806 snprintf(path_buf, sizeof(path_buf), "NONE");
2807 zlog_debug(
2808 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2809 dest, bgp->name_pretty, path_buf,
2810 old_select ? old_select->peer->host : "NONE");
2811 }
2812
2813 if (do_mpath && new_select) {
2814 for (pi = bgp_dest_get_bgp_path_info(dest);
2815 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2816
2817 if (debug)
2818 bgp_path_info_path_with_addpath_rx_str(
2819 pi, path_buf, sizeof(path_buf));
2820
2821 if (pi == new_select) {
2822 if (debug)
2823 zlog_debug(
2824 "%pBD(%s): %s is the bestpath, add to the multipath list",
2825 dest, bgp->name_pretty,
2826 path_buf);
2827 bgp_mp_list_add(&mp_list, pi);
2828 continue;
2829 }
2830
2831 if (BGP_PATH_HOLDDOWN(pi))
2832 continue;
2833
2834 if (pi->peer && pi->peer != bgp->peer_self
2835 && !CHECK_FLAG(pi->peer->sflags,
2836 PEER_STATUS_NSF_WAIT))
2837 if (!peer_established(pi->peer))
2838 continue;
2839
2840 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2841 if (debug)
2842 zlog_debug(
2843 "%pBD: %s has the same nexthop as the bestpath, skip it",
2844 dest, path_buf);
2845 continue;
2846 }
2847
2848 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2849 mpath_cfg, debug, pfx_buf, afi, safi,
2850 &dest->reason);
2851
2852 if (paths_eq) {
2853 if (debug)
2854 zlog_debug(
2855 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2856 dest, path_buf);
2857 bgp_mp_list_add(&mp_list, pi);
2858 }
2859 }
2860 }
2861
2862 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2863 mpath_cfg);
2864 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2865 bgp_mp_list_clear(&mp_list);
2866
2867 bgp_addpath_update_ids(bgp, dest, afi, safi);
2868
2869 result->old = old_select;
2870 result->new = new_select;
2871
2872 return;
2873 }
2874
2875 /*
2876 * A new route/change in bestpath of an existing route. Evaluate the path
2877 * for advertisement to the subgroup.
2878 */
2879 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2880 struct bgp_path_info *selected,
2881 struct bgp_dest *dest,
2882 uint32_t addpath_tx_id)
2883 {
2884 const struct prefix *p;
2885 struct peer *onlypeer;
2886 struct attr attr;
2887 afi_t afi;
2888 safi_t safi;
2889 struct bgp *bgp;
2890 bool advertise;
2891
2892 p = bgp_dest_get_prefix(dest);
2893 afi = SUBGRP_AFI(subgrp);
2894 safi = SUBGRP_SAFI(subgrp);
2895 bgp = SUBGRP_INST(subgrp);
2896 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2897 : NULL);
2898
2899 if (BGP_DEBUG(update, UPDATE_OUT))
2900 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2901
2902 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2903 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2904 PEER_STATUS_ORF_WAIT_REFRESH))
2905 return;
2906
2907 memset(&attr, 0, sizeof(attr));
2908 /* It's initialized in bgp_announce_check() */
2909
2910 /* Announcement to the subgroup. If the route is filtered withdraw it.
2911 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2912 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2913 * route
2914 */
2915 advertise = bgp_check_advertise(bgp, dest);
2916
2917 if (selected) {
2918 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2919 NULL)) {
2920 /* Route is selected, if the route is already installed
2921 * in FIB, then it is advertised
2922 */
2923 if (advertise) {
2924 if (!bgp_check_withdrawal(bgp, dest))
2925 bgp_adj_out_set_subgroup(
2926 dest, subgrp, &attr, selected);
2927 else
2928 bgp_adj_out_unset_subgroup(
2929 dest, subgrp, 1, addpath_tx_id);
2930 }
2931 } else
2932 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2933 addpath_tx_id);
2934 }
2935
2936 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2937 else {
2938 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2939 }
2940 }
2941
2942 /*
2943 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2944 * This is called at the end of route processing.
2945 */
2946 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2947 {
2948 struct bgp_path_info *pi;
2949
2950 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2951 if (BGP_PATH_HOLDDOWN(pi))
2952 continue;
2953 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2954 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2955 }
2956 }
2957
2958 /*
2959 * Has the route changed from the RIB's perspective? This is invoked only
2960 * if the route selection returns the same best route as earlier - to
2961 * determine if we need to update zebra or not.
2962 */
2963 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2964 {
2965 struct bgp_path_info *mpinfo;
2966
2967 /* If this is multipath, check all selected paths for any nexthop
2968 * change or attribute change. Some attribute changes (e.g., community)
2969 * aren't of relevance to the RIB, but we'll update zebra to ensure
2970 * we handle the case of BGP nexthop change. This is the behavior
2971 * when the best path has an attribute change anyway.
2972 */
2973 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2974 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2975 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2976 return true;
2977
2978 /*
2979 * If this is multipath, check all selected paths for any nexthop change
2980 */
2981 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2982 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2983 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2984 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2985 return true;
2986 }
2987
2988 /* Nothing has changed from the RIB's perspective. */
2989 return false;
2990 }
2991
2992 struct bgp_process_queue {
2993 struct bgp *bgp;
2994 STAILQ_HEAD(, bgp_dest) pqueue;
2995 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2996 unsigned int flags;
2997 unsigned int queued;
2998 };
2999
3000 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
3001 safi_t safi, struct bgp_dest *dest,
3002 struct bgp_path_info *new_select,
3003 struct bgp_path_info *old_select)
3004 {
3005 const struct prefix *p = bgp_dest_get_prefix(dest);
3006
3007 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
3008 return;
3009
3010 if (advertise_type5_routes(bgp, afi) && new_select
3011 && is_route_injectable_into_evpn(new_select)) {
3012
3013 /* apply the route-map */
3014 if (bgp->adv_cmd_rmap[afi][safi].map) {
3015 route_map_result_t ret;
3016 struct bgp_path_info rmap_path;
3017 struct bgp_path_info_extra rmap_path_extra;
3018 struct attr dummy_attr;
3019
3020 dummy_attr = *new_select->attr;
3021
3022 /* Fill temp path_info */
3023 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
3024 new_select, new_select->peer,
3025 &dummy_attr);
3026
3027 RESET_FLAG(dummy_attr.rmap_change_flags);
3028
3029 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
3030 p, &rmap_path);
3031
3032 if (ret == RMAP_DENYMATCH) {
3033 bgp_attr_flush(&dummy_attr);
3034 bgp_evpn_withdraw_type5_route(bgp, p, afi,
3035 safi);
3036 } else
3037 bgp_evpn_advertise_type5_route(
3038 bgp, p, &dummy_attr, afi, safi);
3039 } else {
3040 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
3041 afi, safi);
3042 }
3043 } else if (advertise_type5_routes(bgp, afi) && old_select
3044 && is_route_injectable_into_evpn(old_select))
3045 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
3046 }
3047
3048 /*
3049 * Utility to determine whether a particular path_info should use
3050 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
3051 * in a path where we basically _know_ this is a BGP-LU route.
3052 */
3053 static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
3054 {
3055 /* Certain types get imp null; so do paths where the nexthop is
3056 * not labeled.
3057 */
3058 if (new_select->sub_type == BGP_ROUTE_STATIC
3059 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3060 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
3061 return true;
3062 else if (new_select->extra == NULL ||
3063 !bgp_is_valid_label(&new_select->extra->label[0]))
3064 /* TODO -- should be configurable? */
3065 return true;
3066 else
3067 return false;
3068 }
3069
3070 /*
3071 * old_select = The old best path
3072 * new_select = the new best path
3073 *
3074 * if (!old_select && new_select)
3075 * We are sending new information on.
3076 *
3077 * if (old_select && new_select) {
3078 * if (new_select != old_select)
3079 * We have a new best path send a change
3080 * else
3081 * We've received a update with new attributes that needs
3082 * to be passed on.
3083 * }
3084 *
3085 * if (old_select && !new_select)
3086 * We have no eligible route that we can announce or the rn
3087 * is being removed.
3088 */
3089 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3090 afi_t afi, safi_t safi)
3091 {
3092 struct bgp_path_info *new_select;
3093 struct bgp_path_info *old_select;
3094 struct bgp_path_info_pair old_and_new;
3095 int debug = 0;
3096
3097 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3098 if (dest)
3099 debug = bgp_debug_bestpath(dest);
3100 if (debug)
3101 zlog_debug(
3102 "%s: bgp delete in progress, ignoring event, p=%pBD",
3103 __func__, dest);
3104 return;
3105 }
3106 /* Is it end of initial update? (after startup) */
3107 if (!dest) {
3108 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3109 sizeof(bgp->update_delay_zebra_resume_time));
3110
3111 bgp->main_zebra_update_hold = 0;
3112 FOREACH_AFI_SAFI (afi, safi) {
3113 if (bgp_fibupd_safi(safi))
3114 bgp_zebra_announce_table(bgp, afi, safi);
3115 }
3116 bgp->main_peers_update_hold = 0;
3117
3118 bgp_start_routeadv(bgp);
3119 return;
3120 }
3121
3122 const struct prefix *p = bgp_dest_get_prefix(dest);
3123
3124 debug = bgp_debug_bestpath(dest);
3125 if (debug)
3126 zlog_debug("%s: p=%pBDi(%s) afi=%s, safi=%s start", __func__,
3127 dest, bgp->name_pretty, afi2str(afi),
3128 safi2str(safi));
3129
3130 /* The best path calculation for the route is deferred if
3131 * BGP_NODE_SELECT_DEFER is set
3132 */
3133 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3134 if (BGP_DEBUG(update, UPDATE_OUT))
3135 zlog_debug("SELECT_DEFER flag set for route %p", dest);
3136 return;
3137 }
3138
3139 /* Best path selection. */
3140 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3141 afi, safi);
3142 old_select = old_and_new.old;
3143 new_select = old_and_new.new;
3144
3145 /* Do we need to allocate or free labels?
3146 * Right now, since we only deal with per-prefix labels, it is not
3147 * necessary to do this upon changes to best path. Exceptions:
3148 * - label index has changed -> recalculate resulting label
3149 * - path_info sub_type changed -> switch to/from implicit-null
3150 * - no valid label (due to removed static label binding) -> get new one
3151 */
3152 if (bgp->allocate_mpls_labels[afi][safi]) {
3153 if (new_select) {
3154 if (!old_select
3155 || bgp_label_index_differs(new_select, old_select)
3156 || new_select->sub_type != old_select->sub_type
3157 || !bgp_is_valid_label(&dest->local_label)) {
3158 /* Enforced penultimate hop popping:
3159 * implicit-null for local routes, aggregate
3160 * and redistributed routes
3161 */
3162 if (bgp_lu_need_imp_null(new_select)) {
3163 if (CHECK_FLAG(
3164 dest->flags,
3165 BGP_NODE_REGISTERED_FOR_LABEL)
3166 || CHECK_FLAG(
3167 dest->flags,
3168 BGP_NODE_LABEL_REQUESTED))
3169 bgp_unregister_for_label(dest);
3170 dest->local_label = mpls_lse_encode(
3171 MPLS_LABEL_IMPLICIT_NULL, 0, 0,
3172 1);
3173 bgp_set_valid_label(&dest->local_label);
3174 } else
3175 bgp_register_for_label(dest,
3176 new_select);
3177 }
3178 } else if (CHECK_FLAG(dest->flags,
3179 BGP_NODE_REGISTERED_FOR_LABEL)
3180 || CHECK_FLAG(dest->flags,
3181 BGP_NODE_LABEL_REQUESTED)) {
3182 bgp_unregister_for_label(dest);
3183 }
3184 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3185 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3186 bgp_unregister_for_label(dest);
3187 }
3188
3189 if (debug)
3190 zlog_debug(
3191 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3192 __func__, dest, bgp->name_pretty, afi2str(afi),
3193 safi2str(safi), old_select, new_select);
3194
3195 /* If best route remains the same and this is not due to user-initiated
3196 * clear, see exactly what needs to be done.
3197 */
3198 if (old_select && old_select == new_select
3199 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3200 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3201 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3202 if (bgp_zebra_has_route_changed(old_select)) {
3203 #ifdef ENABLE_BGP_VNC
3204 vnc_import_bgp_add_route(bgp, p, old_select);
3205 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3206 #endif
3207 if (bgp_fibupd_safi(safi)
3208 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3209
3210 if (BGP_SUPPRESS_FIB_ENABLED(bgp)
3211 && new_select->sub_type == BGP_ROUTE_NORMAL)
3212 SET_FLAG(dest->flags,
3213 BGP_NODE_FIB_INSTALL_PENDING);
3214
3215 if (new_select->type == ZEBRA_ROUTE_BGP
3216 && (new_select->sub_type == BGP_ROUTE_NORMAL
3217 || new_select->sub_type
3218 == BGP_ROUTE_IMPORTED))
3219
3220 bgp_zebra_announce(dest, p, old_select,
3221 bgp, afi, safi);
3222 }
3223 }
3224
3225 /* If there is a change of interest to peers, reannounce the
3226 * route. */
3227 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3228 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3229 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3230 group_announce_route(bgp, afi, safi, dest, new_select);
3231
3232 /* unicast routes must also be annouced to
3233 * labeled-unicast update-groups */
3234 if (safi == SAFI_UNICAST)
3235 group_announce_route(bgp, afi,
3236 SAFI_LABELED_UNICAST, dest,
3237 new_select);
3238
3239 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3240 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3241 }
3242
3243 /* advertise/withdraw type-5 routes */
3244 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3245 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3246 bgp_process_evpn_route_injection(
3247 bgp, afi, safi, dest, old_select, old_select);
3248
3249 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3250 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3251 bgp_zebra_clear_route_change_flags(dest);
3252 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3253 return;
3254 }
3255
3256 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3257 */
3258 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3259
3260 /* bestpath has changed; bump version */
3261 if (old_select || new_select) {
3262 bgp_bump_version(dest);
3263
3264 if (!bgp->t_rmap_def_originate_eval) {
3265 bgp_lock(bgp);
3266 thread_add_timer(
3267 bm->master,
3268 update_group_refresh_default_originate_route_map,
3269 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3270 &bgp->t_rmap_def_originate_eval);
3271 }
3272 }
3273
3274 if (old_select)
3275 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3276 if (new_select) {
3277 if (debug)
3278 zlog_debug("%s: setting SELECTED flag", __func__);
3279 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3280 bgp_path_info_unset_flag(dest, new_select,
3281 BGP_PATH_ATTR_CHANGED);
3282 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3283 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3284 }
3285
3286 #ifdef ENABLE_BGP_VNC
3287 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3288 if (old_select != new_select) {
3289 if (old_select) {
3290 vnc_import_bgp_exterior_del_route(bgp, p,
3291 old_select);
3292 vnc_import_bgp_del_route(bgp, p, old_select);
3293 }
3294 if (new_select) {
3295 vnc_import_bgp_exterior_add_route(bgp, p,
3296 new_select);
3297 vnc_import_bgp_add_route(bgp, p, new_select);
3298 }
3299 }
3300 }
3301 #endif
3302
3303 group_announce_route(bgp, afi, safi, dest, new_select);
3304
3305 /* unicast routes must also be annouced to labeled-unicast update-groups
3306 */
3307 if (safi == SAFI_UNICAST)
3308 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3309 new_select);
3310
3311 /* FIB update. */
3312 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3313 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3314
3315 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3316 && (new_select->sub_type == BGP_ROUTE_NORMAL
3317 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3318 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3319
3320 if (BGP_SUPPRESS_FIB_ENABLED(bgp))
3321 SET_FLAG(dest->flags,
3322 BGP_NODE_FIB_INSTALL_PENDING);
3323
3324 /* if this is an evpn imported type-5 prefix,
3325 * we need to withdraw the route first to clear
3326 * the nh neigh and the RMAC entry.
3327 */
3328 if (old_select &&
3329 is_route_parent_evpn(old_select))
3330 bgp_zebra_withdraw(p, old_select, bgp, safi);
3331
3332 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3333 } else {
3334 /* Withdraw the route from the kernel. */
3335 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3336 && (old_select->sub_type == BGP_ROUTE_NORMAL
3337 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3338 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3339
3340 bgp_zebra_withdraw(p, old_select, bgp, safi);
3341 }
3342 }
3343
3344 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3345 old_select);
3346
3347 /* Clear any route change flags. */
3348 bgp_zebra_clear_route_change_flags(dest);
3349
3350 /* Reap old select bgp_path_info, if it has been removed */
3351 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3352 bgp_path_info_reap(dest, old_select);
3353
3354 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3355 return;
3356 }
3357
3358 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3359 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3360 {
3361 struct bgp_dest *dest;
3362 int cnt = 0;
3363 struct afi_safi_info *thread_info;
3364
3365 if (bgp->gr_info[afi][safi].t_route_select) {
3366 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
3367
3368 thread_info = THREAD_ARG(t);
3369 XFREE(MTYPE_TMP, thread_info);
3370 THREAD_OFF(bgp->gr_info[afi][safi].t_route_select);
3371 }
3372
3373 if (BGP_DEBUG(update, UPDATE_OUT)) {
3374 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3375 get_afi_safi_str(afi, safi, false),
3376 bgp->gr_info[afi][safi].gr_deferred);
3377 }
3378
3379 /* Process the route list */
3380 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3381 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3382 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3383 dest = bgp_route_next(dest)) {
3384 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3385 continue;
3386
3387 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3388 bgp->gr_info[afi][safi].gr_deferred--;
3389 bgp_process_main_one(bgp, dest, afi, safi);
3390 cnt++;
3391 }
3392 /* If iteration stopped before the entire table was traversed then the
3393 * node needs to be unlocked.
3394 */
3395 if (dest) {
3396 bgp_dest_unlock_node(dest);
3397 dest = NULL;
3398 }
3399
3400 /* Send EOR message when all routes are processed */
3401 if (!bgp->gr_info[afi][safi].gr_deferred) {
3402 bgp_send_delayed_eor(bgp);
3403 /* Send route processing complete message to RIB */
3404 bgp_zebra_update(afi, safi, bgp->vrf_id,
3405 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3406 return;
3407 }
3408
3409 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3410
3411 thread_info->afi = afi;
3412 thread_info->safi = safi;
3413 thread_info->bgp = bgp;
3414
3415 /* If there are more routes to be processed, start the
3416 * selection timer
3417 */
3418 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3419 BGP_ROUTE_SELECT_DELAY,
3420 &bgp->gr_info[afi][safi].t_route_select);
3421 }
3422
3423 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3424 {
3425 struct bgp_process_queue *pqnode = data;
3426 struct bgp *bgp = pqnode->bgp;
3427 struct bgp_table *table;
3428 struct bgp_dest *dest;
3429
3430 /* eoiu marker */
3431 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3432 bgp_process_main_one(bgp, NULL, 0, 0);
3433 /* should always have dedicated wq call */
3434 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3435 return WQ_SUCCESS;
3436 }
3437
3438 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3439 dest = STAILQ_FIRST(&pqnode->pqueue);
3440 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3441 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3442 table = bgp_dest_table(dest);
3443 /* note, new DESTs may be added as part of processing */
3444 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3445
3446 bgp_dest_unlock_node(dest);
3447 bgp_table_unlock(table);
3448 }
3449
3450 return WQ_SUCCESS;
3451 }
3452
3453 static void bgp_processq_del(struct work_queue *wq, void *data)
3454 {
3455 struct bgp_process_queue *pqnode = data;
3456
3457 bgp_unlock(pqnode->bgp);
3458
3459 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3460 }
3461
3462 void bgp_process_queue_init(struct bgp *bgp)
3463 {
3464 if (!bgp->process_queue) {
3465 char name[BUFSIZ];
3466
3467 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3468 bgp->process_queue = work_queue_new(bm->master, name);
3469 }
3470
3471 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3472 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3473 bgp->process_queue->spec.max_retries = 0;
3474 bgp->process_queue->spec.hold = 50;
3475 /* Use a higher yield value of 50ms for main queue processing */
3476 bgp->process_queue->spec.yield = 50 * 1000L;
3477 }
3478
3479 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3480 {
3481 struct bgp_process_queue *pqnode;
3482
3483 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3484 sizeof(struct bgp_process_queue));
3485
3486 /* unlocked in bgp_processq_del */
3487 pqnode->bgp = bgp_lock(bgp);
3488 STAILQ_INIT(&pqnode->pqueue);
3489
3490 return pqnode;
3491 }
3492
3493 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3494 {
3495 #define ARBITRARY_PROCESS_QLEN 10000
3496 struct work_queue *wq = bgp->process_queue;
3497 struct bgp_process_queue *pqnode;
3498 int pqnode_reuse = 0;
3499
3500 /* already scheduled for processing? */
3501 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3502 return;
3503
3504 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3505 * the workqueue
3506 */
3507 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3508 if (BGP_DEBUG(update, UPDATE_OUT))
3509 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3510 dest);
3511 return;
3512 }
3513
3514 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3515 if (BGP_DEBUG(update, UPDATE_OUT))
3516 zlog_debug(
3517 "Soft reconfigure table in progress for route %p",
3518 dest);
3519 return;
3520 }
3521
3522 if (wq == NULL)
3523 return;
3524
3525 /* Add route nodes to an existing work queue item until reaching the
3526 limit only if is from the same BGP view and it's not an EOIU marker
3527 */
3528 if (work_queue_item_count(wq)) {
3529 struct work_queue_item *item = work_queue_last_item(wq);
3530 pqnode = item->data;
3531
3532 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3533 || pqnode->bgp != bgp
3534 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3535 pqnode = bgp_processq_alloc(bgp);
3536 else
3537 pqnode_reuse = 1;
3538 } else
3539 pqnode = bgp_processq_alloc(bgp);
3540 /* all unlocked in bgp_process_wq */
3541 bgp_table_lock(bgp_dest_table(dest));
3542
3543 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3544 bgp_dest_lock_node(dest);
3545
3546 /* can't be enqueued twice */
3547 assert(STAILQ_NEXT(dest, pq) == NULL);
3548 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3549 pqnode->queued++;
3550
3551 if (!pqnode_reuse)
3552 work_queue_add(wq, pqnode);
3553
3554 return;
3555 }
3556
3557 void bgp_add_eoiu_mark(struct bgp *bgp)
3558 {
3559 struct bgp_process_queue *pqnode;
3560
3561 if (bgp->process_queue == NULL)
3562 return;
3563
3564 pqnode = bgp_processq_alloc(bgp);
3565
3566 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3567 work_queue_add(bgp->process_queue, pqnode);
3568 }
3569
3570 static void bgp_maximum_prefix_restart_timer(struct thread *thread)
3571 {
3572 struct peer *peer;
3573
3574 peer = THREAD_ARG(thread);
3575 peer->t_pmax_restart = NULL;
3576
3577 if (bgp_debug_neighbor_events(peer))
3578 zlog_debug(
3579 "%s Maximum-prefix restart timer expired, restore peering",
3580 peer->host);
3581
3582 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3583 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3584 }
3585
3586 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3587 safi_t safi)
3588 {
3589 uint32_t count = 0;
3590 bool filtered = false;
3591 struct bgp_dest *dest;
3592 struct bgp_adj_in *ain;
3593 struct attr attr = {};
3594 struct bgp_table *table = peer->bgp->rib[afi][safi];
3595
3596 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3597 for (ain = dest->adj_in; ain; ain = ain->next) {
3598 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3599
3600 attr = *ain->attr;
3601
3602 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3603 == FILTER_DENY)
3604 filtered = true;
3605
3606 if (bgp_input_modifier(
3607 peer, rn_p, &attr, afi, safi,
3608 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3609 NULL, 0, NULL)
3610 == RMAP_DENY)
3611 filtered = true;
3612
3613 if (filtered)
3614 count++;
3615
3616 bgp_attr_flush(&attr);
3617 }
3618 }
3619
3620 return count;
3621 }
3622
3623 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3624 int always)
3625 {
3626 iana_afi_t pkt_afi;
3627 iana_safi_t pkt_safi;
3628 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3629 PEER_FLAG_MAX_PREFIX_FORCE))
3630 ? bgp_filtered_routes_count(peer, afi, safi)
3631 + peer->pcount[afi][safi]
3632 : peer->pcount[afi][safi];
3633
3634 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3635 return false;
3636
3637 if (pcount > peer->pmax[afi][safi]) {
3638 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3639 PEER_STATUS_PREFIX_LIMIT)
3640 && !always)
3641 return false;
3642
3643 zlog_info(
3644 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3645 get_afi_safi_str(afi, safi, false), peer, pcount,
3646 peer->pmax[afi][safi]);
3647 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3648
3649 if (CHECK_FLAG(peer->af_flags[afi][safi],
3650 PEER_FLAG_MAX_PREFIX_WARNING))
3651 return false;
3652
3653 /* Convert AFI, SAFI to values for packet. */
3654 pkt_afi = afi_int2iana(afi);
3655 pkt_safi = safi_int2iana(safi);
3656 {
3657 uint8_t ndata[7];
3658
3659 ndata[0] = (pkt_afi >> 8);
3660 ndata[1] = pkt_afi;
3661 ndata[2] = pkt_safi;
3662 ndata[3] = (peer->pmax[afi][safi] >> 24);
3663 ndata[4] = (peer->pmax[afi][safi] >> 16);
3664 ndata[5] = (peer->pmax[afi][safi] >> 8);
3665 ndata[6] = (peer->pmax[afi][safi]);
3666
3667 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3668 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3669 BGP_NOTIFY_CEASE_MAX_PREFIX,
3670 ndata, 7);
3671 }
3672
3673 /* Dynamic peers will just close their connection. */
3674 if (peer_dynamic_neighbor(peer))
3675 return true;
3676
3677 /* restart timer start */
3678 if (peer->pmax_restart[afi][safi]) {
3679 peer->v_pmax_restart =
3680 peer->pmax_restart[afi][safi] * 60;
3681
3682 if (bgp_debug_neighbor_events(peer))
3683 zlog_debug(
3684 "%pBP Maximum-prefix restart timer started for %d secs",
3685 peer, peer->v_pmax_restart);
3686
3687 BGP_TIMER_ON(peer->t_pmax_restart,
3688 bgp_maximum_prefix_restart_timer,
3689 peer->v_pmax_restart);
3690 }
3691
3692 return true;
3693 } else
3694 UNSET_FLAG(peer->af_sflags[afi][safi],
3695 PEER_STATUS_PREFIX_LIMIT);
3696
3697 if (pcount
3698 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3699 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3700 PEER_STATUS_PREFIX_THRESHOLD)
3701 && !always)
3702 return false;
3703
3704 zlog_info(
3705 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3706 get_afi_safi_str(afi, safi, false), peer, pcount,
3707 peer->pmax[afi][safi]);
3708 SET_FLAG(peer->af_sflags[afi][safi],
3709 PEER_STATUS_PREFIX_THRESHOLD);
3710 } else
3711 UNSET_FLAG(peer->af_sflags[afi][safi],
3712 PEER_STATUS_PREFIX_THRESHOLD);
3713 return false;
3714 }
3715
3716 /* Unconditionally remove the route from the RIB, without taking
3717 * damping into consideration (eg, because the session went down)
3718 */
3719 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3720 struct peer *peer, afi_t afi, safi_t safi)
3721 {
3722
3723 struct bgp *bgp = NULL;
3724 bool delete_route = false;
3725
3726 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3727 safi);
3728
3729 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3730 bgp_path_info_delete(dest, pi); /* keep historical info */
3731
3732 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3733 * flag
3734 */
3735 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3736 delete_route = true;
3737 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3738 delete_route = true;
3739 if (delete_route) {
3740 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3741 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3742 bgp = pi->peer->bgp;
3743 bgp->gr_info[afi][safi].gr_deferred--;
3744 }
3745 }
3746 }
3747
3748 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3749 bgp_process(peer->bgp, dest, afi, safi);
3750 }
3751
3752 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3753 struct peer *peer, afi_t afi, safi_t safi,
3754 struct prefix_rd *prd)
3755 {
3756 const struct prefix *p = bgp_dest_get_prefix(dest);
3757
3758 /* apply dampening, if result is suppressed, we'll be retaining
3759 * the bgp_path_info in the RIB for historical reference.
3760 */
3761 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3762 && peer->sort == BGP_PEER_EBGP)
3763 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3764 == BGP_DAMP_SUPPRESSED) {
3765 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3766 safi);
3767 return;
3768 }
3769
3770 #ifdef ENABLE_BGP_VNC
3771 if (safi == SAFI_MPLS_VPN) {
3772 struct bgp_dest *pdest = NULL;
3773 struct bgp_table *table = NULL;
3774
3775 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3776 (struct prefix *)prd);
3777 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3778 table = bgp_dest_get_bgp_table_info(pdest);
3779
3780 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3781 peer->bgp, prd, table, p, pi);
3782 }
3783 bgp_dest_unlock_node(pdest);
3784 }
3785 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3786 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3787
3788 vnc_import_bgp_del_route(peer->bgp, p, pi);
3789 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3790 }
3791 }
3792 #endif
3793
3794 /* If this is an EVPN route, process for un-import. */
3795 if (safi == SAFI_EVPN)
3796 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3797
3798 bgp_rib_remove(dest, pi, peer, afi, safi);
3799 }
3800
3801 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3802 struct peer *peer, struct attr *attr,
3803 struct bgp_dest *dest)
3804 {
3805 struct bgp_path_info *new;
3806
3807 /* Make new BGP info. */
3808 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3809 new->type = type;
3810 new->instance = instance;
3811 new->sub_type = sub_type;
3812 new->peer = peer;
3813 new->attr = attr;
3814 new->uptime = monotime(NULL);
3815 new->net = dest;
3816 return new;
3817 }
3818
3819 /* Check if received nexthop is valid or not. */
3820 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3821 uint8_t type, uint8_t stype, struct attr *attr,
3822 struct bgp_dest *dest)
3823 {
3824 bool ret = false;
3825 bool is_bgp_static_route =
3826 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3827 : false;
3828
3829 /*
3830 * Only validated for unicast and multicast currently.
3831 * Also valid for EVPN where the nexthop is an IP address.
3832 * If we are a bgp static route being checked then there is
3833 * no need to check to see if the nexthop is martian as
3834 * that it should be ok.
3835 */
3836 if (is_bgp_static_route ||
3837 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3838 return false;
3839
3840 /* If NEXT_HOP is present, validate it. */
3841 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3842 if (attr->nexthop.s_addr == INADDR_ANY ||
3843 !ipv4_unicast_valid(&attr->nexthop) ||
3844 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3845 return true;
3846 }
3847
3848 /* If MP_NEXTHOP is present, validate it. */
3849 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3850 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3851 * it is not an IPv6 link-local address.
3852 *
3853 * If we receive an UPDATE with nexthop length set to 32 bytes
3854 * we shouldn't discard an UPDATE if it's set to (::).
3855 * The link-local (2st) is validated along the code path later.
3856 */
3857 if (attr->mp_nexthop_len) {
3858 switch (attr->mp_nexthop_len) {
3859 case BGP_ATTR_NHLEN_IPV4:
3860 case BGP_ATTR_NHLEN_VPNV4:
3861 ret = (attr->mp_nexthop_global_in.s_addr ==
3862 INADDR_ANY ||
3863 !ipv4_unicast_valid(
3864 &attr->mp_nexthop_global_in) ||
3865 bgp_nexthop_self(bgp, afi, type, stype, attr,
3866 dest));
3867 break;
3868
3869 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3870 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3871 ret = (IN6_IS_ADDR_UNSPECIFIED(
3872 &attr->mp_nexthop_global)
3873 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3874 || IN6_IS_ADDR_MULTICAST(
3875 &attr->mp_nexthop_global)
3876 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3877 dest));
3878 break;
3879 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3880 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3881 || IN6_IS_ADDR_MULTICAST(
3882 &attr->mp_nexthop_global)
3883 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3884 dest));
3885 break;
3886
3887 default:
3888 ret = true;
3889 break;
3890 }
3891 }
3892
3893 return ret;
3894 }
3895
3896 static void bgp_attr_add_no_export_community(struct attr *attr)
3897 {
3898 struct community *old;
3899 struct community *new;
3900 struct community *merge;
3901 struct community *no_export;
3902
3903 old = bgp_attr_get_community(attr);
3904 no_export = community_str2com("no-export");
3905
3906 assert(no_export);
3907
3908 if (old) {
3909 merge = community_merge(community_dup(old), no_export);
3910
3911 if (!old->refcnt)
3912 community_free(&old);
3913
3914 new = community_uniq_sort(merge);
3915 community_free(&merge);
3916 } else {
3917 new = community_dup(no_export);
3918 }
3919
3920 community_free(&no_export);
3921
3922 bgp_attr_set_community(attr, new);
3923 }
3924
3925 static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi,
3926 struct attr *attr, const struct prefix *prefix,
3927 int *sub_type)
3928 {
3929 struct listnode *node, *nnode;
3930 struct bgp *bgp;
3931 bool accept_own_found = false;
3932
3933 if (safi != SAFI_MPLS_VPN)
3934 return false;
3935
3936 /* Processing of the ACCEPT_OWN community is enabled by configuration */
3937 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN))
3938 return false;
3939
3940 /* The route in question carries the ACCEPT_OWN community */
3941 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3942 struct community *comm = bgp_attr_get_community(attr);
3943
3944 if (community_include(comm, COMMUNITY_ACCEPT_OWN))
3945 accept_own_found = true;
3946 }
3947
3948 /* The route in question is targeted to one or more destination VRFs
3949 * on the router (as determined by inspecting the Route Target(s)).
3950 */
3951 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3952 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3953 continue;
3954
3955 if (accept_own_found &&
3956 ecommunity_include(
3957 bgp->vpn_policy[afi]
3958 .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
3959 bgp_attr_get_ecommunity(attr))) {
3960 if (bgp_debug_update(peer, prefix, NULL, 1))
3961 zlog_debug(
3962 "%pBP prefix %pFX has ORIGINATOR_ID, but it's accepted due to ACCEPT_OWN",
3963 peer, prefix);
3964
3965 /* Treat this route as imported, because it's leaked
3966 * already from another VRF, and we got an updated
3967 * version from route-reflector with ACCEPT_OWN
3968 * community.
3969 */
3970 *sub_type = BGP_ROUTE_IMPORTED;
3971
3972 return true;
3973 }
3974 }
3975
3976 return false;
3977 }
3978
3979 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3980 struct attr *attr, afi_t afi, safi_t safi, int type,
3981 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3982 uint32_t num_labels, int soft_reconfig,
3983 struct bgp_route_evpn *evpn)
3984 {
3985 int ret;
3986 int aspath_loop_count = 0;
3987 struct bgp_dest *dest;
3988 struct bgp *bgp;
3989 struct attr new_attr;
3990 struct attr *attr_new;
3991 struct bgp_path_info *pi;
3992 struct bgp_path_info *new;
3993 struct bgp_path_info_extra *extra;
3994 const char *reason;
3995 char pfx_buf[BGP_PRD_PATH_STRLEN];
3996 int connected = 0;
3997 int do_loop_check = 1;
3998 int has_valid_label = 0;
3999 afi_t nh_afi;
4000 bool force_evpn_import = false;
4001 safi_t orig_safi = safi;
4002 bool leak_success = true;
4003 int allowas_in = 0;
4004
4005 if (frrtrace_enabled(frr_bgp, process_update)) {
4006 char pfxprint[PREFIX2STR_BUFFER];
4007
4008 prefix2str(p, pfxprint, sizeof(pfxprint));
4009 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
4010 afi, safi, attr);
4011 }
4012
4013 #ifdef ENABLE_BGP_VNC
4014 int vnc_implicit_withdraw = 0;
4015 #endif
4016 int same_attr = 0;
4017
4018 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
4019 if (orig_safi == SAFI_LABELED_UNICAST)
4020 safi = SAFI_UNICAST;
4021
4022 memset(&new_attr, 0, sizeof(new_attr));
4023 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4024 new_attr.label = MPLS_INVALID_LABEL;
4025
4026 bgp = peer->bgp;
4027 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4028 /* TODO: Check to see if we can get rid of "is_valid_label" */
4029 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4030 has_valid_label = (num_labels > 0) ? 1 : 0;
4031 else
4032 has_valid_label = bgp_is_valid_label(label);
4033
4034 if (has_valid_label)
4035 assert(label != NULL);
4036
4037 /* Update overlay index of the attribute */
4038 if (afi == AFI_L2VPN && evpn)
4039 memcpy(&attr->evpn_overlay, evpn,
4040 sizeof(struct bgp_route_evpn));
4041
4042 /* When peer's soft reconfiguration enabled. Record input packet in
4043 Adj-RIBs-In. */
4044 if (!soft_reconfig
4045 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4046 && peer != bgp->peer_self)
4047 bgp_adj_in_set(dest, peer, attr, addpath_id);
4048
4049 /* Update permitted loop count */
4050 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
4051 allowas_in = peer->allowas_in[afi][safi];
4052
4053 /* Check previously received route. */
4054 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4055 if (pi->peer == peer && pi->type == type
4056 && pi->sub_type == sub_type
4057 && pi->addpath_rx_id == addpath_id)
4058 break;
4059
4060 /* AS path local-as loop check. */
4061 if (peer->change_local_as) {
4062 if (allowas_in)
4063 aspath_loop_count = allowas_in;
4064 else if (!CHECK_FLAG(peer->flags,
4065 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4066 aspath_loop_count = 1;
4067
4068 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4069 > aspath_loop_count) {
4070 peer->stat_pfx_aspath_loop++;
4071 reason = "as-path contains our own AS;";
4072 goto filtered;
4073 }
4074 }
4075
4076 /* If the peer is configured for "allowas-in origin" and the last ASN in
4077 * the
4078 * as-path is our ASN then we do not need to call aspath_loop_check
4079 */
4080 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4081 if (aspath_get_last_as(attr->aspath) == bgp->as)
4082 do_loop_check = 0;
4083
4084 /* AS path loop check. */
4085 if (do_loop_check) {
4086 if (aspath_loop_check(attr->aspath, bgp->as) > allowas_in ||
4087 (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) &&
4088 (aspath_loop_check(attr->aspath, bgp->confed_id) >
4089 allowas_in))) {
4090 peer->stat_pfx_aspath_loop++;
4091 reason = "as-path contains our own AS;";
4092 goto filtered;
4093 }
4094 }
4095
4096 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4097 * enabled, then take care of that too.
4098 */
4099 bool accept_own = false;
4100
4101 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4102 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4103 accept_own =
4104 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4105 if (!accept_own) {
4106 peer->stat_pfx_originator_loop++;
4107 reason = "originator is us;";
4108 goto filtered;
4109 }
4110 }
4111
4112 /* Route reflector cluster ID check. */
4113 if (bgp_cluster_filter(peer, attr)) {
4114 peer->stat_pfx_cluster_loop++;
4115 reason = "reflected from the same cluster;";
4116 goto filtered;
4117 }
4118
4119 /* Apply incoming filter. */
4120 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4121 peer->stat_pfx_filter++;
4122 reason = "filter;";
4123 goto filtered;
4124 }
4125
4126 /* RFC 8212 to prevent route leaks.
4127 * This specification intends to improve this situation by requiring the
4128 * explicit configuration of both BGP Import and Export Policies for any
4129 * External BGP (EBGP) session such as customers, peers, or
4130 * confederation boundaries for all enabled address families. Through
4131 * codification of the aforementioned requirement, operators will
4132 * benefit from consistent behavior across different BGP
4133 * implementations.
4134 */
4135 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4136 if (!bgp_inbound_policy_exists(peer,
4137 &peer->filter[afi][safi])) {
4138 reason = "inbound policy missing";
4139 if (monotime_since(&bgp->ebgprequirespolicywarning,
4140 NULL) > FIFTEENMINUTE2USEC ||
4141 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4142 zlog_warn(
4143 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4144 monotime(&bgp->ebgprequirespolicywarning);
4145 }
4146 goto filtered;
4147 }
4148
4149 /* draft-ietf-idr-deprecate-as-set-confed-set
4150 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4151 * Eventually, This document (if approved) updates RFC 4271
4152 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4153 * and obsoletes RFC 6472.
4154 */
4155 if (peer->bgp->reject_as_sets)
4156 if (aspath_check_as_sets(attr->aspath)) {
4157 reason =
4158 "as-path contains AS_SET or AS_CONFED_SET type;";
4159 goto filtered;
4160 }
4161
4162 new_attr = *attr;
4163
4164 /* Apply incoming route-map.
4165 * NB: new_attr may now contain newly allocated values from route-map
4166 * "set"
4167 * commands, so we need bgp_attr_flush in the error paths, until we
4168 * intern
4169 * the attr (which takes over the memory references) */
4170 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4171 num_labels, dest)
4172 == RMAP_DENY) {
4173 peer->stat_pfx_filter++;
4174 reason = "route-map;";
4175 bgp_attr_flush(&new_attr);
4176 goto filtered;
4177 }
4178
4179 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4180 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4181 /* remove from RIB previous entry */
4182 bgp_zebra_withdraw(p, pi, bgp, safi);
4183 }
4184
4185 if (peer->sort == BGP_PEER_EBGP) {
4186
4187 /* rfc7999:
4188 * A BGP speaker receiving an announcement tagged with the
4189 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4190 * NO_EXPORT community as defined in RFC1997, or a
4191 * similar community, to prevent propagation of the
4192 * prefix outside the local AS. The community to prevent
4193 * propagation SHOULD be chosen according to the operator's
4194 * routing policy.
4195 */
4196 if (bgp_attr_get_community(&new_attr) &&
4197 community_include(bgp_attr_get_community(&new_attr),
4198 COMMUNITY_BLACKHOLE))
4199 bgp_attr_add_no_export_community(&new_attr);
4200
4201 /* If we receive the graceful-shutdown community from an eBGP
4202 * peer we must lower local-preference */
4203 if (bgp_attr_get_community(&new_attr) &&
4204 community_include(bgp_attr_get_community(&new_attr),
4205 COMMUNITY_GSHUT)) {
4206 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4207 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4208
4209 /* If graceful-shutdown is configured then add the GSHUT
4210 * community to all paths received from eBGP peers */
4211 } else if (bgp_in_graceful_shutdown(peer->bgp))
4212 bgp_attr_add_gshut_community(&new_attr);
4213 }
4214
4215 /* next hop check. */
4216 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4217 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4218 &new_attr, dest)) {
4219 peer->stat_pfx_nh_invalid++;
4220 reason = "martian or self next-hop;";
4221 bgp_attr_flush(&new_attr);
4222 goto filtered;
4223 }
4224
4225 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4226 peer->stat_pfx_nh_invalid++;
4227 reason = "self mac;";
4228 bgp_attr_flush(&new_attr);
4229 goto filtered;
4230 }
4231
4232 if (bgp_check_role_applicability(afi, safi) &&
4233 bgp_otc_filter(peer, &new_attr)) {
4234 reason = "failing otc validation";
4235 bgp_attr_flush(&new_attr);
4236 goto filtered;
4237 }
4238 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
4239 * condition :
4240 * Suppress fib is enabled
4241 * BGP_OPT_NO_FIB is not enabled
4242 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
4243 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
4244 */
4245 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
4246 && (sub_type == BGP_ROUTE_NORMAL)
4247 && (!bgp_option_check(BGP_OPT_NO_FIB))
4248 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
4249 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
4250
4251 /* If maximum prefix count is configured and current prefix
4252 * count exeed it.
4253 */
4254 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4255 bgp_attr_flush(&new_attr);
4256 return -1;
4257 }
4258
4259 /* If neighbor soo is configured, tag all incoming routes with
4260 * this SoO tag and then filter out advertisements in
4261 * subgroup_announce_check() if it matches the configured SoO
4262 * on the other peer.
4263 */
4264 if (peer->soo[afi][safi]) {
4265 struct ecommunity *old_ecomm =
4266 bgp_attr_get_ecommunity(&new_attr);
4267 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4268 struct ecommunity *new_ecomm;
4269
4270 if (old_ecomm) {
4271 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4272 ecomm_soo);
4273
4274 if (!old_ecomm->refcnt)
4275 ecommunity_free(&old_ecomm);
4276 } else {
4277 new_ecomm = ecommunity_dup(ecomm_soo);
4278 }
4279
4280 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4281 }
4282
4283 attr_new = bgp_attr_intern(&new_attr);
4284
4285 /* If the update is implicit withdraw. */
4286 if (pi) {
4287 pi->uptime = monotime(NULL);
4288 same_attr = attrhash_cmp(pi->attr, attr_new);
4289
4290 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4291
4292 /* Same attribute comes in. */
4293 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4294 && same_attr
4295 && (!has_valid_label
4296 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4297 num_labels * sizeof(mpls_label_t))
4298 == 0)) {
4299 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4300 BGP_CONFIG_DAMPENING)
4301 && peer->sort == BGP_PEER_EBGP
4302 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4303 if (bgp_debug_update(peer, p, NULL, 1)) {
4304 bgp_debug_rdpfxpath2str(
4305 afi, safi, prd, p, label,
4306 num_labels, addpath_id ? 1 : 0,
4307 addpath_id, evpn, pfx_buf,
4308 sizeof(pfx_buf));
4309 zlog_debug("%pBP rcvd %s", peer,
4310 pfx_buf);
4311 }
4312
4313 if (bgp_damp_update(pi, dest, afi, safi)
4314 != BGP_DAMP_SUPPRESSED) {
4315 bgp_aggregate_increment(bgp, p, pi, afi,
4316 safi);
4317 bgp_process(bgp, dest, afi, safi);
4318 }
4319 } else /* Duplicate - odd */
4320 {
4321 if (bgp_debug_update(peer, p, NULL, 1)) {
4322 if (!peer->rcvd_attr_printed) {
4323 zlog_debug(
4324 "%pBP rcvd UPDATE w/ attr: %s",
4325 peer,
4326 peer->rcvd_attr_str);
4327 peer->rcvd_attr_printed = 1;
4328 }
4329
4330 bgp_debug_rdpfxpath2str(
4331 afi, safi, prd, p, label,
4332 num_labels, addpath_id ? 1 : 0,
4333 addpath_id, evpn, pfx_buf,
4334 sizeof(pfx_buf));
4335 zlog_debug(
4336 "%pBP rcvd %s...duplicate ignored",
4337 peer, pfx_buf);
4338 }
4339
4340 /* graceful restart STALE flag unset. */
4341 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4342 bgp_path_info_unset_flag(
4343 dest, pi, BGP_PATH_STALE);
4344 bgp_dest_set_defer_flag(dest, false);
4345 bgp_process(bgp, dest, afi, safi);
4346 }
4347 }
4348
4349 bgp_dest_unlock_node(dest);
4350 bgp_attr_unintern(&attr_new);
4351
4352 return 0;
4353 }
4354
4355 /* Withdraw/Announce before we fully processed the withdraw */
4356 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4357 if (bgp_debug_update(peer, p, NULL, 1)) {
4358 bgp_debug_rdpfxpath2str(
4359 afi, safi, prd, p, label, num_labels,
4360 addpath_id ? 1 : 0, addpath_id, evpn,
4361 pfx_buf, sizeof(pfx_buf));
4362 zlog_debug(
4363 "%pBP rcvd %s, flapped quicker than processing",
4364 peer, pfx_buf);
4365 }
4366
4367 bgp_path_info_restore(dest, pi);
4368
4369 /*
4370 * If the BGP_PATH_REMOVED flag is set, then EVPN
4371 * routes would have been unimported already when a
4372 * prior BGP withdraw processing happened. Such routes
4373 * need to be imported again, so flag accordingly.
4374 */
4375 force_evpn_import = true;
4376 }
4377
4378 /* Received Logging. */
4379 if (bgp_debug_update(peer, p, NULL, 1)) {
4380 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4381 num_labels, addpath_id ? 1 : 0,
4382 addpath_id, evpn, pfx_buf,
4383 sizeof(pfx_buf));
4384 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4385 }
4386
4387 /* graceful restart STALE flag unset. */
4388 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4389 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4390 bgp_dest_set_defer_flag(dest, false);
4391 }
4392
4393 /* The attribute is changed. */
4394 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4395
4396 /* implicit withdraw, decrement aggregate and pcount here.
4397 * only if update is accepted, they'll increment below.
4398 */
4399 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4400
4401 /* Update bgp route dampening information. */
4402 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4403 && peer->sort == BGP_PEER_EBGP) {
4404 /* This is implicit withdraw so we should update
4405 dampening
4406 information. */
4407 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4408 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4409 }
4410 #ifdef ENABLE_BGP_VNC
4411 if (safi == SAFI_MPLS_VPN) {
4412 struct bgp_dest *pdest = NULL;
4413 struct bgp_table *table = NULL;
4414
4415 pdest = bgp_node_get(bgp->rib[afi][safi],
4416 (struct prefix *)prd);
4417 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4418 table = bgp_dest_get_bgp_table_info(pdest);
4419
4420 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4421 bgp, prd, table, p, pi);
4422 }
4423 bgp_dest_unlock_node(pdest);
4424 }
4425 if ((afi == AFI_IP || afi == AFI_IP6)
4426 && (safi == SAFI_UNICAST)) {
4427 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4428 /*
4429 * Implicit withdraw case.
4430 */
4431 ++vnc_implicit_withdraw;
4432 vnc_import_bgp_del_route(bgp, p, pi);
4433 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4434 }
4435 }
4436 #endif
4437
4438 /* Special handling for EVPN update of an existing route. If the
4439 * extended community attribute has changed, we need to
4440 * un-import
4441 * the route using its existing extended community. It will be
4442 * subsequently processed for import with the new extended
4443 * community.
4444 */
4445 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4446 && !same_attr) {
4447 if ((pi->attr->flag
4448 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4449 && (attr_new->flag
4450 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4451 int cmp;
4452
4453 cmp = ecommunity_cmp(
4454 bgp_attr_get_ecommunity(pi->attr),
4455 bgp_attr_get_ecommunity(attr_new));
4456 if (!cmp) {
4457 if (bgp_debug_update(peer, p, NULL, 1))
4458 zlog_debug(
4459 "Change in EXT-COMM, existing %s new %s",
4460 ecommunity_str(
4461 bgp_attr_get_ecommunity(
4462 pi->attr)),
4463 ecommunity_str(
4464 bgp_attr_get_ecommunity(
4465 attr_new)));
4466 if (safi == SAFI_EVPN)
4467 bgp_evpn_unimport_route(
4468 bgp, afi, safi, p, pi);
4469 else /* SAFI_MPLS_VPN */
4470 vpn_leak_to_vrf_withdraw(bgp,
4471 pi);
4472 }
4473 }
4474 }
4475
4476 /* Update to new attribute. */
4477 bgp_attr_unintern(&pi->attr);
4478 pi->attr = attr_new;
4479
4480 /* Update MPLS label */
4481 if (has_valid_label) {
4482 extra = bgp_path_info_extra_get(pi);
4483 if (extra->label != label) {
4484 memcpy(&extra->label, label,
4485 num_labels * sizeof(mpls_label_t));
4486 extra->num_labels = num_labels;
4487 }
4488 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4489 bgp_set_valid_label(&extra->label[0]);
4490 }
4491
4492 /* Update SRv6 SID */
4493 if (attr->srv6_l3vpn) {
4494 extra = bgp_path_info_extra_get(pi);
4495 if (sid_diff(&extra->sid[0].sid,
4496 &attr->srv6_l3vpn->sid)) {
4497 sid_copy(&extra->sid[0].sid,
4498 &attr->srv6_l3vpn->sid);
4499 extra->num_sids = 1;
4500
4501 extra->sid[0].loc_block_len = 0;
4502 extra->sid[0].loc_node_len = 0;
4503 extra->sid[0].func_len = 0;
4504 extra->sid[0].arg_len = 0;
4505 extra->sid[0].transposition_len = 0;
4506 extra->sid[0].transposition_offset = 0;
4507
4508 if (attr->srv6_l3vpn->loc_block_len != 0) {
4509 extra->sid[0].loc_block_len =
4510 attr->srv6_l3vpn->loc_block_len;
4511 extra->sid[0].loc_node_len =
4512 attr->srv6_l3vpn->loc_node_len;
4513 extra->sid[0].func_len =
4514 attr->srv6_l3vpn->func_len;
4515 extra->sid[0].arg_len =
4516 attr->srv6_l3vpn->arg_len;
4517 extra->sid[0].transposition_len =
4518 attr->srv6_l3vpn
4519 ->transposition_len;
4520 extra->sid[0].transposition_offset =
4521 attr->srv6_l3vpn
4522 ->transposition_offset;
4523 }
4524 }
4525 } else if (attr->srv6_vpn) {
4526 extra = bgp_path_info_extra_get(pi);
4527 if (sid_diff(&extra->sid[0].sid,
4528 &attr->srv6_vpn->sid)) {
4529 sid_copy(&extra->sid[0].sid,
4530 &attr->srv6_vpn->sid);
4531 extra->num_sids = 1;
4532 }
4533 }
4534
4535 #ifdef ENABLE_BGP_VNC
4536 if ((afi == AFI_IP || afi == AFI_IP6)
4537 && (safi == SAFI_UNICAST)) {
4538 if (vnc_implicit_withdraw) {
4539 /*
4540 * Add back the route with its new attributes
4541 * (e.g., nexthop).
4542 * The route is still selected, until the route
4543 * selection
4544 * queued by bgp_process actually runs. We have
4545 * to make this
4546 * update to the VNC side immediately to avoid
4547 * racing against
4548 * configuration changes (e.g., route-map
4549 * changes) which
4550 * trigger re-importation of the entire RIB.
4551 */
4552 vnc_import_bgp_add_route(bgp, p, pi);
4553 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4554 }
4555 }
4556 #endif
4557
4558 /* Update bgp route dampening information. */
4559 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4560 && peer->sort == BGP_PEER_EBGP) {
4561 /* Now we do normal update dampening. */
4562 ret = bgp_damp_update(pi, dest, afi, safi);
4563 if (ret == BGP_DAMP_SUPPRESSED) {
4564 bgp_dest_unlock_node(dest);
4565 return 0;
4566 }
4567 }
4568
4569 /* Nexthop reachability check - for unicast and
4570 * labeled-unicast.. */
4571 if (((afi == AFI_IP || afi == AFI_IP6)
4572 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4573 || (safi == SAFI_EVPN &&
4574 bgp_evpn_is_prefix_nht_supported(p))) {
4575 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4576 && peer->ttl == BGP_DEFAULT_TTL
4577 && !CHECK_FLAG(peer->flags,
4578 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4579 && !CHECK_FLAG(bgp->flags,
4580 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4581 connected = 1;
4582 else
4583 connected = 0;
4584
4585 struct bgp *bgp_nexthop = bgp;
4586
4587 if (pi->extra && pi->extra->bgp_orig)
4588 bgp_nexthop = pi->extra->bgp_orig;
4589
4590 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4591
4592 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4593 safi, pi, NULL, connected,
4594 p)
4595 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4596 bgp_path_info_set_flag(dest, pi,
4597 BGP_PATH_VALID);
4598 else {
4599 if (BGP_DEBUG(nht, NHT)) {
4600 zlog_debug("%s(%pI4): NH unresolved",
4601 __func__,
4602 (in_addr_t *)&attr_new->nexthop);
4603 }
4604 bgp_path_info_unset_flag(dest, pi,
4605 BGP_PATH_VALID);
4606 }
4607 } else {
4608 if (accept_own)
4609 bgp_path_info_set_flag(dest, pi,
4610 BGP_PATH_ACCEPT_OWN);
4611
4612 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4613 }
4614
4615 #ifdef ENABLE_BGP_VNC
4616 if (safi == SAFI_MPLS_VPN) {
4617 struct bgp_dest *pdest = NULL;
4618 struct bgp_table *table = NULL;
4619
4620 pdest = bgp_node_get(bgp->rib[afi][safi],
4621 (struct prefix *)prd);
4622 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4623 table = bgp_dest_get_bgp_table_info(pdest);
4624
4625 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4626 bgp, prd, table, p, pi);
4627 }
4628 bgp_dest_unlock_node(pdest);
4629 }
4630 #endif
4631
4632 /* If this is an EVPN route and some attribute has changed,
4633 * or we are explicitly told to perform a route import, process
4634 * route for import. If the extended community has changed, we
4635 * would
4636 * have done the un-import earlier and the import would result
4637 * in the
4638 * route getting injected into appropriate L2 VNIs. If it is
4639 * just
4640 * some other attribute change, the import will result in
4641 * updating
4642 * the attributes for the route in the VNI(s).
4643 */
4644 if (safi == SAFI_EVPN &&
4645 (!same_attr || force_evpn_import) &&
4646 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4647 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4648
4649 /* Process change. */
4650 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4651
4652 bgp_process(bgp, dest, afi, safi);
4653 bgp_dest_unlock_node(dest);
4654
4655 if (SAFI_UNICAST == safi
4656 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4657 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4658
4659 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4660 }
4661 if ((SAFI_MPLS_VPN == safi)
4662 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4663 leak_success = vpn_leak_to_vrf_update(bgp, pi, prd);
4664 }
4665
4666 #ifdef ENABLE_BGP_VNC
4667 if (SAFI_MPLS_VPN == safi) {
4668 mpls_label_t label_decoded = decode_label(label);
4669
4670 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4671 type, sub_type, &label_decoded);
4672 }
4673 if (SAFI_ENCAP == safi) {
4674 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4675 type, sub_type, NULL);
4676 }
4677 #endif
4678 if ((safi == SAFI_MPLS_VPN) &&
4679 !CHECK_FLAG(bgp->af_flags[afi][safi],
4680 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4681 !leak_success) {
4682 bgp_unlink_nexthop(pi);
4683 bgp_path_info_delete(dest, pi);
4684 }
4685 return 0;
4686 } // End of implicit withdraw
4687
4688 /* Received Logging. */
4689 if (bgp_debug_update(peer, p, NULL, 1)) {
4690 if (!peer->rcvd_attr_printed) {
4691 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4692 peer->rcvd_attr_str);
4693 peer->rcvd_attr_printed = 1;
4694 }
4695
4696 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4697 addpath_id ? 1 : 0, addpath_id, evpn,
4698 pfx_buf, sizeof(pfx_buf));
4699 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4700 }
4701
4702 /* Make new BGP info. */
4703 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4704
4705 /* Update MPLS label */
4706 if (has_valid_label) {
4707 extra = bgp_path_info_extra_get(new);
4708 if (extra->label != label) {
4709 memcpy(&extra->label, label,
4710 num_labels * sizeof(mpls_label_t));
4711 extra->num_labels = num_labels;
4712 }
4713 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4714 bgp_set_valid_label(&extra->label[0]);
4715 }
4716
4717 /* Update SRv6 SID */
4718 if (safi == SAFI_MPLS_VPN) {
4719 extra = bgp_path_info_extra_get(new);
4720 if (attr->srv6_l3vpn) {
4721 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4722 extra->num_sids = 1;
4723
4724 extra->sid[0].loc_block_len =
4725 attr->srv6_l3vpn->loc_block_len;
4726 extra->sid[0].loc_node_len =
4727 attr->srv6_l3vpn->loc_node_len;
4728 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4729 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4730 extra->sid[0].transposition_len =
4731 attr->srv6_l3vpn->transposition_len;
4732 extra->sid[0].transposition_offset =
4733 attr->srv6_l3vpn->transposition_offset;
4734 } else if (attr->srv6_vpn) {
4735 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4736 extra->num_sids = 1;
4737 }
4738 }
4739
4740 /* Nexthop reachability check. */
4741 if (((afi == AFI_IP || afi == AFI_IP6)
4742 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4743 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4744 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4745 && peer->ttl == BGP_DEFAULT_TTL
4746 && !CHECK_FLAG(peer->flags,
4747 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4748 && !CHECK_FLAG(bgp->flags,
4749 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4750 connected = 1;
4751 else
4752 connected = 0;
4753
4754 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4755
4756 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4757 connected, p)
4758 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4759 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4760 else {
4761 if (BGP_DEBUG(nht, NHT)) {
4762 char buf1[INET6_ADDRSTRLEN];
4763 inet_ntop(AF_INET,
4764 (const void *)&attr_new->nexthop,
4765 buf1, INET6_ADDRSTRLEN);
4766 zlog_debug("%s(%s): NH unresolved", __func__,
4767 buf1);
4768 }
4769 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4770 }
4771 } else {
4772 if (accept_own)
4773 bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
4774
4775 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4776 }
4777
4778 /* Addpath ID */
4779 new->addpath_rx_id = addpath_id;
4780
4781 /* Increment prefix */
4782 bgp_aggregate_increment(bgp, p, new, afi, safi);
4783
4784 /* Register new BGP information. */
4785 bgp_path_info_add(dest, new);
4786
4787 /* route_node_get lock */
4788 bgp_dest_unlock_node(dest);
4789
4790 #ifdef ENABLE_BGP_VNC
4791 if (safi == SAFI_MPLS_VPN) {
4792 struct bgp_dest *pdest = NULL;
4793 struct bgp_table *table = NULL;
4794
4795 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4796 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4797 table = bgp_dest_get_bgp_table_info(pdest);
4798
4799 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4800 bgp, prd, table, p, new);
4801 }
4802 bgp_dest_unlock_node(pdest);
4803 }
4804 #endif
4805
4806 /* If this is an EVPN route, process for import. */
4807 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4808 bgp_evpn_import_route(bgp, afi, safi, p, new);
4809
4810 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4811
4812 /* Process change. */
4813 bgp_process(bgp, dest, afi, safi);
4814
4815 if (SAFI_UNICAST == safi
4816 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4817 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4818 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4819 }
4820 if ((SAFI_MPLS_VPN == safi)
4821 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4822 leak_success = vpn_leak_to_vrf_update(bgp, new, prd);
4823 }
4824 #ifdef ENABLE_BGP_VNC
4825 if (SAFI_MPLS_VPN == safi) {
4826 mpls_label_t label_decoded = decode_label(label);
4827
4828 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4829 sub_type, &label_decoded);
4830 }
4831 if (SAFI_ENCAP == safi) {
4832 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4833 sub_type, NULL);
4834 }
4835 #endif
4836 if ((safi == SAFI_MPLS_VPN) &&
4837 !CHECK_FLAG(bgp->af_flags[afi][safi],
4838 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4839 !leak_success) {
4840 bgp_unlink_nexthop(new);
4841 bgp_path_info_delete(dest, new);
4842 }
4843
4844 return 0;
4845
4846 /* This BGP update is filtered. Log the reason then update BGP
4847 entry. */
4848 filtered:
4849 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4850
4851 if (bgp_debug_update(peer, p, NULL, 1)) {
4852 if (!peer->rcvd_attr_printed) {
4853 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4854 peer->rcvd_attr_str);
4855 peer->rcvd_attr_printed = 1;
4856 }
4857
4858 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4859 addpath_id ? 1 : 0, addpath_id, evpn,
4860 pfx_buf, sizeof(pfx_buf));
4861 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4862 peer, pfx_buf, reason);
4863 }
4864
4865 if (pi) {
4866 /* If this is an EVPN route, un-import it as it is now filtered.
4867 */
4868 if (safi == SAFI_EVPN)
4869 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4870
4871 if (SAFI_UNICAST == safi
4872 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4873 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4874
4875 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4876 }
4877 if ((SAFI_MPLS_VPN == safi)
4878 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4879
4880 vpn_leak_to_vrf_withdraw(bgp, pi);
4881 }
4882
4883 bgp_rib_remove(dest, pi, peer, afi, safi);
4884 }
4885
4886 bgp_dest_unlock_node(dest);
4887
4888 #ifdef ENABLE_BGP_VNC
4889 /*
4890 * Filtered update is treated as an implicit withdrawal (see
4891 * bgp_rib_remove()
4892 * a few lines above)
4893 */
4894 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4895 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4896 0);
4897 }
4898 #endif
4899
4900 return 0;
4901 }
4902
4903 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4904 struct attr *attr, afi_t afi, safi_t safi, int type,
4905 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4906 uint32_t num_labels, struct bgp_route_evpn *evpn)
4907 {
4908 struct bgp *bgp;
4909 char pfx_buf[BGP_PRD_PATH_STRLEN];
4910 struct bgp_dest *dest;
4911 struct bgp_path_info *pi;
4912
4913 #ifdef ENABLE_BGP_VNC
4914 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4915 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4916 0);
4917 }
4918 #endif
4919
4920 bgp = peer->bgp;
4921
4922 /* Lookup node. */
4923 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4924
4925 /* If peer is soft reconfiguration enabled. Record input packet for
4926 * further calculation.
4927 *
4928 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4929 * routes that are filtered. This tanks out Quagga RS pretty badly due
4930 * to
4931 * the iteration over all RS clients.
4932 * Since we need to remove the entry from adj_in anyway, do that first
4933 * and
4934 * if there was no entry, we don't need to do anything more.
4935 */
4936 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4937 && peer != bgp->peer_self)
4938 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4939 peer->stat_pfx_dup_withdraw++;
4940
4941 if (bgp_debug_update(peer, p, NULL, 1)) {
4942 bgp_debug_rdpfxpath2str(
4943 afi, safi, prd, p, label, num_labels,
4944 addpath_id ? 1 : 0, addpath_id, NULL,
4945 pfx_buf, sizeof(pfx_buf));
4946 zlog_debug(
4947 "%s withdrawing route %s not in adj-in",
4948 peer->host, pfx_buf);
4949 }
4950 bgp_dest_unlock_node(dest);
4951 return 0;
4952 }
4953
4954 /* Lookup withdrawn route. */
4955 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4956 if (pi->peer == peer && pi->type == type
4957 && pi->sub_type == sub_type
4958 && pi->addpath_rx_id == addpath_id)
4959 break;
4960
4961 /* Logging. */
4962 if (bgp_debug_update(peer, p, NULL, 1)) {
4963 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4964 addpath_id ? 1 : 0, addpath_id, NULL,
4965 pfx_buf, sizeof(pfx_buf));
4966 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
4967 pfx_buf);
4968 }
4969
4970 /* Withdraw specified route from routing table. */
4971 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4972 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4973 if (SAFI_UNICAST == safi
4974 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4975 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4976 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4977 }
4978 if ((SAFI_MPLS_VPN == safi)
4979 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4980
4981 vpn_leak_to_vrf_withdraw(bgp, pi);
4982 }
4983 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4984 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4985 addpath_id ? 1 : 0, addpath_id, NULL,
4986 pfx_buf, sizeof(pfx_buf));
4987 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4988 }
4989
4990 /* Unlock bgp_node_get() lock. */
4991 bgp_dest_unlock_node(dest);
4992
4993 return 0;
4994 }
4995
4996 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4997 int withdraw)
4998 {
4999 struct update_subgroup *subgrp;
5000 subgrp = peer_subgroup(peer, afi, safi);
5001 subgroup_default_originate(subgrp, withdraw);
5002 }
5003
5004
5005 /*
5006 * bgp_stop_announce_route_timer
5007 */
5008 void bgp_stop_announce_route_timer(struct peer_af *paf)
5009 {
5010 if (!paf->t_announce_route)
5011 return;
5012
5013 THREAD_OFF(paf->t_announce_route);
5014 }
5015
5016 /*
5017 * bgp_announce_route_timer_expired
5018 *
5019 * Callback that is invoked when the route announcement timer for a
5020 * peer_af expires.
5021 */
5022 static void bgp_announce_route_timer_expired(struct thread *t)
5023 {
5024 struct peer_af *paf;
5025 struct peer *peer;
5026
5027 paf = THREAD_ARG(t);
5028 peer = paf->peer;
5029
5030 if (!peer_established(peer))
5031 return;
5032
5033 if (!peer->afc_nego[paf->afi][paf->safi])
5034 return;
5035
5036 peer_af_announce_route(paf, 1);
5037
5038 /* Notify BGP conditional advertisement scanner percess */
5039 peer->advmap_config_change[paf->afi][paf->safi] = true;
5040 }
5041
5042 /*
5043 * bgp_announce_route
5044 *
5045 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
5046 *
5047 * if force is true we will force an update even if the update
5048 * limiting code is attempted to kick in.
5049 */
5050 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
5051 {
5052 struct peer_af *paf;
5053 struct update_subgroup *subgrp;
5054
5055 paf = peer_af_find(peer, afi, safi);
5056 if (!paf)
5057 return;
5058 subgrp = PAF_SUBGRP(paf);
5059
5060 /*
5061 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
5062 * or a refresh has already been triggered.
5063 */
5064 if (!subgrp || paf->t_announce_route)
5065 return;
5066
5067 if (force)
5068 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
5069
5070 /*
5071 * Start a timer to stagger/delay the announce. This serves
5072 * two purposes - announcement can potentially be combined for
5073 * multiple peers and the announcement doesn't happen in the
5074 * vty context.
5075 */
5076 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
5077 (subgrp->peer_count == 1)
5078 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
5079 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
5080 &paf->t_announce_route);
5081 }
5082
5083 /*
5084 * Announce routes from all AF tables to a peer.
5085 *
5086 * This should ONLY be called when there is a need to refresh the
5087 * routes to the peer based on a policy change for this peer alone
5088 * or a route refresh request received from the peer.
5089 * The operation will result in splitting the peer from its existing
5090 * subgroups and putting it in new subgroups.
5091 */
5092 void bgp_announce_route_all(struct peer *peer)
5093 {
5094 afi_t afi;
5095 safi_t safi;
5096
5097 FOREACH_AFI_SAFI (afi, safi)
5098 bgp_announce_route(peer, afi, safi, false);
5099 }
5100
5101 /* Flag or unflag bgp_dest to determine whether it should be treated by
5102 * bgp_soft_reconfig_table_task.
5103 * Flag if flag is true. Unflag if flag is false.
5104 */
5105 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
5106 {
5107 struct bgp_dest *dest;
5108 struct bgp_adj_in *ain;
5109
5110 if (!table)
5111 return;
5112
5113 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5114 for (ain = dest->adj_in; ain; ain = ain->next) {
5115 if (ain->peer != NULL)
5116 break;
5117 }
5118 if (flag && ain != NULL && ain->peer != NULL)
5119 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5120 else
5121 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5122 }
5123 }
5124
5125 static int bgp_soft_reconfig_table_update(struct peer *peer,
5126 struct bgp_dest *dest,
5127 struct bgp_adj_in *ain, afi_t afi,
5128 safi_t safi, struct prefix_rd *prd)
5129 {
5130 struct bgp_path_info *pi;
5131 uint32_t num_labels = 0;
5132 mpls_label_t *label_pnt = NULL;
5133 struct bgp_route_evpn evpn;
5134
5135 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5136 if (pi->peer == peer)
5137 break;
5138
5139 if (pi && pi->extra)
5140 num_labels = pi->extra->num_labels;
5141 if (num_labels)
5142 label_pnt = &pi->extra->label[0];
5143 if (pi)
5144 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
5145 sizeof(evpn));
5146 else
5147 memset(&evpn, 0, sizeof(evpn));
5148
5149 return bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
5150 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
5151 BGP_ROUTE_NORMAL, prd, label_pnt, num_labels, 1,
5152 &evpn);
5153 }
5154
5155 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5156 struct bgp_table *table,
5157 struct prefix_rd *prd)
5158 {
5159 int ret;
5160 struct bgp_dest *dest;
5161 struct bgp_adj_in *ain;
5162
5163 if (!table)
5164 table = peer->bgp->rib[afi][safi];
5165
5166 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5167 for (ain = dest->adj_in; ain; ain = ain->next) {
5168 if (ain->peer != peer)
5169 continue;
5170
5171 ret = bgp_soft_reconfig_table_update(peer, dest, ain,
5172 afi, safi, prd);
5173
5174 if (ret < 0) {
5175 bgp_dest_unlock_node(dest);
5176 return;
5177 }
5178 }
5179 }
5180
5181 /* Do soft reconfig table per bgp table.
5182 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5183 * when BGP_NODE_SOFT_RECONFIG is set,
5184 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5185 * Schedule a new thread to continue the job.
5186 * Without splitting the full job into several part,
5187 * vtysh waits for the job to finish before responding to a BGP command
5188 */
5189 static void bgp_soft_reconfig_table_task(struct thread *thread)
5190 {
5191 uint32_t iter, max_iter;
5192 int ret;
5193 struct bgp_dest *dest;
5194 struct bgp_adj_in *ain;
5195 struct peer *peer;
5196 struct bgp_table *table;
5197 struct prefix_rd *prd;
5198 struct listnode *node, *nnode;
5199
5200 table = THREAD_ARG(thread);
5201 prd = NULL;
5202
5203 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5204 if (table->soft_reconfig_init) {
5205 /* first call of the function with a new srta structure.
5206 * Don't do any treatment this time on nodes
5207 * in order vtysh to respond quickly
5208 */
5209 max_iter = 0;
5210 }
5211
5212 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5213 dest = bgp_route_next(dest)) {
5214 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5215 continue;
5216
5217 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5218
5219 for (ain = dest->adj_in; ain; ain = ain->next) {
5220 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5221 nnode, peer)) {
5222 if (ain->peer != peer)
5223 continue;
5224
5225 ret = bgp_soft_reconfig_table_update(
5226 peer, dest, ain, table->afi,
5227 table->safi, prd);
5228 iter++;
5229
5230 if (ret < 0) {
5231 bgp_dest_unlock_node(dest);
5232 listnode_delete(
5233 table->soft_reconfig_peers,
5234 peer);
5235 bgp_announce_route(peer, table->afi,
5236 table->safi, false);
5237 if (list_isempty(
5238 table->soft_reconfig_peers)) {
5239 list_delete(
5240 &table->soft_reconfig_peers);
5241 bgp_soft_reconfig_table_flag(
5242 table, false);
5243 return;
5244 }
5245 }
5246 }
5247 }
5248 }
5249
5250 /* we're either starting the initial iteration,
5251 * or we're going to continue an ongoing iteration
5252 */
5253 if (dest || table->soft_reconfig_init) {
5254 table->soft_reconfig_init = false;
5255 thread_add_event(bm->master, bgp_soft_reconfig_table_task,
5256 table, 0, &table->soft_reconfig_thread);
5257 return;
5258 }
5259 /* we're done, clean up the background iteration context info and
5260 schedule route annoucement
5261 */
5262 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5263 listnode_delete(table->soft_reconfig_peers, peer);
5264 bgp_announce_route(peer, table->afi, table->safi, false);
5265 }
5266
5267 list_delete(&table->soft_reconfig_peers);
5268 }
5269
5270
5271 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5272 * and peer.
5273 * - bgp cannot be NULL
5274 * - if table and peer are NULL, cancel all threads within the bgp instance
5275 * - if table is NULL and peer is not,
5276 * remove peer in all threads within the bgp instance
5277 * - if peer is NULL, cancel all threads matching table within the bgp instance
5278 */
5279 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5280 const struct bgp_table *table,
5281 const struct peer *peer)
5282 {
5283 struct peer *npeer;
5284 struct listnode *node, *nnode;
5285 int afi, safi;
5286 struct bgp_table *ntable;
5287
5288 if (!bgp)
5289 return;
5290
5291 FOREACH_AFI_SAFI (afi, safi) {
5292 ntable = bgp->rib[afi][safi];
5293 if (!ntable)
5294 continue;
5295 if (table && table != ntable)
5296 continue;
5297
5298 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5299 npeer)) {
5300 if (peer && peer != npeer)
5301 continue;
5302 listnode_delete(ntable->soft_reconfig_peers, npeer);
5303 }
5304
5305 if (!ntable->soft_reconfig_peers
5306 || !list_isempty(ntable->soft_reconfig_peers))
5307 continue;
5308
5309 list_delete(&ntable->soft_reconfig_peers);
5310 bgp_soft_reconfig_table_flag(ntable, false);
5311 THREAD_OFF(ntable->soft_reconfig_thread);
5312 }
5313 }
5314
5315 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5316 {
5317 struct bgp_dest *dest;
5318 struct bgp_table *table;
5319 struct listnode *node, *nnode;
5320 struct peer *npeer;
5321 struct peer_af *paf;
5322
5323 if (!peer_established(peer))
5324 return;
5325
5326 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5327 && (safi != SAFI_EVPN)) {
5328 table = peer->bgp->rib[afi][safi];
5329 if (!table)
5330 return;
5331
5332 table->soft_reconfig_init = true;
5333
5334 if (!table->soft_reconfig_peers)
5335 table->soft_reconfig_peers = list_new();
5336 npeer = NULL;
5337 /* add peer to the table soft_reconfig_peers if not already
5338 * there
5339 */
5340 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5341 npeer)) {
5342 if (peer == npeer)
5343 break;
5344 }
5345 if (peer != npeer)
5346 listnode_add(table->soft_reconfig_peers, peer);
5347
5348 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5349 * on table would start back at the beginning.
5350 */
5351 bgp_soft_reconfig_table_flag(table, true);
5352
5353 if (!table->soft_reconfig_thread)
5354 thread_add_event(bm->master,
5355 bgp_soft_reconfig_table_task, table, 0,
5356 &table->soft_reconfig_thread);
5357 /* Cancel bgp_announce_route_timer_expired threads.
5358 * bgp_announce_route_timer_expired threads have been scheduled
5359 * to announce routes as soon as the soft_reconfigure process
5360 * finishes.
5361 * In this case, soft_reconfigure is also scheduled by using
5362 * a thread but is planned after the
5363 * bgp_announce_route_timer_expired threads. It means that,
5364 * without cancelling the threads, the route announcement task
5365 * would run before the soft reconfiguration one. That would
5366 * useless and would block vtysh during several seconds. Route
5367 * announcements are rescheduled as soon as the soft_reconfigure
5368 * process finishes.
5369 */
5370 paf = peer_af_find(peer, afi, safi);
5371 if (paf)
5372 bgp_stop_announce_route_timer(paf);
5373 } else
5374 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5375 dest = bgp_route_next(dest)) {
5376 table = bgp_dest_get_bgp_table_info(dest);
5377
5378 if (table == NULL)
5379 continue;
5380
5381 const struct prefix *p = bgp_dest_get_prefix(dest);
5382 struct prefix_rd prd;
5383
5384 prd.family = AF_UNSPEC;
5385 prd.prefixlen = 64;
5386 memcpy(&prd.val, p->u.val, 8);
5387
5388 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5389 }
5390 }
5391
5392
5393 struct bgp_clear_node_queue {
5394 struct bgp_dest *dest;
5395 };
5396
5397 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5398 {
5399 struct bgp_clear_node_queue *cnq = data;
5400 struct bgp_dest *dest = cnq->dest;
5401 struct peer *peer = wq->spec.data;
5402 struct bgp_path_info *pi;
5403 struct bgp *bgp;
5404 afi_t afi = bgp_dest_table(dest)->afi;
5405 safi_t safi = bgp_dest_table(dest)->safi;
5406
5407 assert(dest && peer);
5408 bgp = peer->bgp;
5409
5410 /* It is possible that we have multiple paths for a prefix from a peer
5411 * if that peer is using AddPath.
5412 */
5413 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5414 if (pi->peer != peer)
5415 continue;
5416
5417 /* graceful restart STALE flag set. */
5418 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5419 && peer->nsf[afi][safi])
5420 || CHECK_FLAG(peer->af_sflags[afi][safi],
5421 PEER_STATUS_ENHANCED_REFRESH))
5422 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5423 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5424 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5425 else {
5426 /* If this is an EVPN route, process for
5427 * un-import. */
5428 if (safi == SAFI_EVPN)
5429 bgp_evpn_unimport_route(
5430 bgp, afi, safi,
5431 bgp_dest_get_prefix(dest), pi);
5432 /* Handle withdraw for VRF route-leaking and L3VPN */
5433 if (SAFI_UNICAST == safi
5434 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5435 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5436 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5437 bgp, pi);
5438 }
5439 if (SAFI_MPLS_VPN == safi &&
5440 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5441 vpn_leak_to_vrf_withdraw(bgp, pi);
5442 }
5443
5444 bgp_rib_remove(dest, pi, peer, afi, safi);
5445 }
5446 }
5447 return WQ_SUCCESS;
5448 }
5449
5450 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5451 {
5452 struct bgp_clear_node_queue *cnq = data;
5453 struct bgp_dest *dest = cnq->dest;
5454 struct bgp_table *table = bgp_dest_table(dest);
5455
5456 bgp_dest_unlock_node(dest);
5457 bgp_table_unlock(table);
5458 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5459 }
5460
5461 static void bgp_clear_node_complete(struct work_queue *wq)
5462 {
5463 struct peer *peer = wq->spec.data;
5464
5465 /* Tickle FSM to start moving again */
5466 BGP_EVENT_ADD(peer, Clearing_Completed);
5467
5468 peer_unlock(peer); /* bgp_clear_route */
5469 }
5470
5471 static void bgp_clear_node_queue_init(struct peer *peer)
5472 {
5473 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5474
5475 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5476 #undef CLEAR_QUEUE_NAME_LEN
5477
5478 peer->clear_node_queue = work_queue_new(bm->master, wname);
5479 peer->clear_node_queue->spec.hold = 10;
5480 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5481 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5482 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5483 peer->clear_node_queue->spec.max_retries = 0;
5484
5485 /* we only 'lock' this peer reference when the queue is actually active
5486 */
5487 peer->clear_node_queue->spec.data = peer;
5488 }
5489
5490 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5491 struct bgp_table *table)
5492 {
5493 struct bgp_dest *dest;
5494 int force = peer->bgp->process_queue ? 0 : 1;
5495
5496 if (!table)
5497 table = peer->bgp->rib[afi][safi];
5498
5499 /* If still no table => afi/safi isn't configured at all or smth. */
5500 if (!table)
5501 return;
5502
5503 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5504 struct bgp_path_info *pi, *next;
5505 struct bgp_adj_in *ain;
5506 struct bgp_adj_in *ain_next;
5507
5508 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5509 * queued for every clearing peer, regardless of whether it is
5510 * relevant to the peer at hand.
5511 *
5512 * Overview: There are 3 different indices which need to be
5513 * scrubbed, potentially, when a peer is removed:
5514 *
5515 * 1 peer's routes visible via the RIB (ie accepted routes)
5516 * 2 peer's routes visible by the (optional) peer's adj-in index
5517 * 3 other routes visible by the peer's adj-out index
5518 *
5519 * 3 there is no hurry in scrubbing, once the struct peer is
5520 * removed from bgp->peer, we could just GC such deleted peer's
5521 * adj-outs at our leisure.
5522 *
5523 * 1 and 2 must be 'scrubbed' in some way, at least made
5524 * invisible via RIB index before peer session is allowed to be
5525 * brought back up. So one needs to know when such a 'search' is
5526 * complete.
5527 *
5528 * Ideally:
5529 *
5530 * - there'd be a single global queue or a single RIB walker
5531 * - rather than tracking which route_nodes still need to be
5532 * examined on a peer basis, we'd track which peers still
5533 * aren't cleared
5534 *
5535 * Given that our per-peer prefix-counts now should be reliable,
5536 * this may actually be achievable. It doesn't seem to be a huge
5537 * problem at this time,
5538 *
5539 * It is possible that we have multiple paths for a prefix from
5540 * a peer
5541 * if that peer is using AddPath.
5542 */
5543 ain = dest->adj_in;
5544 while (ain) {
5545 ain_next = ain->next;
5546
5547 if (ain->peer == peer)
5548 bgp_adj_in_remove(dest, ain);
5549
5550 ain = ain_next;
5551 }
5552
5553 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5554 next = pi->next;
5555 if (pi->peer != peer)
5556 continue;
5557
5558 if (force)
5559 bgp_path_info_reap(dest, pi);
5560 else {
5561 struct bgp_clear_node_queue *cnq;
5562
5563 /* both unlocked in bgp_clear_node_queue_del */
5564 bgp_table_lock(bgp_dest_table(dest));
5565 bgp_dest_lock_node(dest);
5566 cnq = XCALLOC(
5567 MTYPE_BGP_CLEAR_NODE_QUEUE,
5568 sizeof(struct bgp_clear_node_queue));
5569 cnq->dest = dest;
5570 work_queue_add(peer->clear_node_queue, cnq);
5571 break;
5572 }
5573 }
5574 }
5575 return;
5576 }
5577
5578 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5579 {
5580 struct bgp_dest *dest;
5581 struct bgp_table *table;
5582
5583 if (peer->clear_node_queue == NULL)
5584 bgp_clear_node_queue_init(peer);
5585
5586 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5587 * Idle until it receives a Clearing_Completed event. This protects
5588 * against peers which flap faster than we can we clear, which could
5589 * lead to:
5590 *
5591 * a) race with routes from the new session being installed before
5592 * clear_route_node visits the node (to delete the route of that
5593 * peer)
5594 * b) resource exhaustion, clear_route_node likely leads to an entry
5595 * on the process_main queue. Fast-flapping could cause that queue
5596 * to grow and grow.
5597 */
5598
5599 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5600 * the unlock will happen upon work-queue completion; other wise, the
5601 * unlock happens at the end of this function.
5602 */
5603 if (!peer->clear_node_queue->thread)
5604 peer_lock(peer);
5605
5606 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5607 bgp_clear_route_table(peer, afi, safi, NULL);
5608 else
5609 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5610 dest = bgp_route_next(dest)) {
5611 table = bgp_dest_get_bgp_table_info(dest);
5612 if (!table)
5613 continue;
5614
5615 bgp_clear_route_table(peer, afi, safi, table);
5616 }
5617
5618 /* unlock if no nodes got added to the clear-node-queue. */
5619 if (!peer->clear_node_queue->thread)
5620 peer_unlock(peer);
5621 }
5622
5623 void bgp_clear_route_all(struct peer *peer)
5624 {
5625 afi_t afi;
5626 safi_t safi;
5627
5628 FOREACH_AFI_SAFI (afi, safi)
5629 bgp_clear_route(peer, afi, safi);
5630
5631 #ifdef ENABLE_BGP_VNC
5632 rfapiProcessPeerDown(peer);
5633 #endif
5634 }
5635
5636 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5637 {
5638 struct bgp_table *table;
5639 struct bgp_dest *dest;
5640 struct bgp_adj_in *ain;
5641 struct bgp_adj_in *ain_next;
5642
5643 table = peer->bgp->rib[afi][safi];
5644
5645 /* It is possible that we have multiple paths for a prefix from a peer
5646 * if that peer is using AddPath.
5647 */
5648 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5649 ain = dest->adj_in;
5650
5651 while (ain) {
5652 ain_next = ain->next;
5653
5654 if (ain->peer == peer)
5655 bgp_adj_in_remove(dest, ain);
5656
5657 ain = ain_next;
5658 }
5659 }
5660 }
5661
5662 /* If any of the routes from the peer have been marked with the NO_LLGR
5663 * community, either as sent by the peer, or as the result of a configured
5664 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5665 * operation of [RFC4271].
5666 */
5667 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5668 {
5669 struct bgp_dest *dest;
5670 struct bgp_path_info *pi;
5671 struct bgp_table *table;
5672
5673 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5674 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5675 dest = bgp_route_next(dest)) {
5676 struct bgp_dest *rm;
5677
5678 /* look for neighbor in tables */
5679 table = bgp_dest_get_bgp_table_info(dest);
5680 if (!table)
5681 continue;
5682
5683 for (rm = bgp_table_top(table); rm;
5684 rm = bgp_route_next(rm))
5685 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5686 pi = pi->next) {
5687 if (pi->peer != peer)
5688 continue;
5689 if (CHECK_FLAG(
5690 peer->af_sflags[afi][safi],
5691 PEER_STATUS_LLGR_WAIT) &&
5692 bgp_attr_get_community(pi->attr) &&
5693 !community_include(
5694 bgp_attr_get_community(
5695 pi->attr),
5696 COMMUNITY_NO_LLGR))
5697 continue;
5698 if (!CHECK_FLAG(pi->flags,
5699 BGP_PATH_STALE))
5700 continue;
5701
5702 /*
5703 * If this is VRF leaked route
5704 * process for withdraw.
5705 */
5706 if (pi->sub_type ==
5707 BGP_ROUTE_IMPORTED &&
5708 peer->bgp->inst_type ==
5709 BGP_INSTANCE_TYPE_DEFAULT)
5710 vpn_leak_to_vrf_withdraw(
5711 peer->bgp, pi);
5712
5713 bgp_rib_remove(rm, pi, peer, afi, safi);
5714 break;
5715 }
5716 }
5717 } else {
5718 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5719 dest = bgp_route_next(dest))
5720 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5721 pi = pi->next) {
5722 if (pi->peer != peer)
5723 continue;
5724 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5725 PEER_STATUS_LLGR_WAIT) &&
5726 bgp_attr_get_community(pi->attr) &&
5727 !community_include(
5728 bgp_attr_get_community(pi->attr),
5729 COMMUNITY_NO_LLGR))
5730 continue;
5731 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5732 continue;
5733 if (safi == SAFI_UNICAST &&
5734 (peer->bgp->inst_type ==
5735 BGP_INSTANCE_TYPE_VRF ||
5736 peer->bgp->inst_type ==
5737 BGP_INSTANCE_TYPE_DEFAULT))
5738 vpn_leak_from_vrf_withdraw(
5739 bgp_get_default(), peer->bgp,
5740 pi);
5741
5742 bgp_rib_remove(dest, pi, peer, afi, safi);
5743 break;
5744 }
5745 }
5746 }
5747
5748 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5749 {
5750 struct bgp_dest *dest, *ndest;
5751 struct bgp_path_info *pi;
5752 struct bgp_table *table;
5753
5754 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5755 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5756 dest = bgp_route_next(dest)) {
5757 table = bgp_dest_get_bgp_table_info(dest);
5758 if (!table)
5759 continue;
5760
5761 for (ndest = bgp_table_top(table); ndest;
5762 ndest = bgp_route_next(ndest)) {
5763 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5764 pi = pi->next) {
5765 if (pi->peer != peer)
5766 continue;
5767
5768 if ((CHECK_FLAG(
5769 peer->af_sflags[afi][safi],
5770 PEER_STATUS_ENHANCED_REFRESH))
5771 && !CHECK_FLAG(pi->flags,
5772 BGP_PATH_STALE)
5773 && !CHECK_FLAG(
5774 pi->flags,
5775 BGP_PATH_UNUSEABLE)) {
5776 if (bgp_debug_neighbor_events(
5777 peer))
5778 zlog_debug(
5779 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5780 peer,
5781 afi2str(afi),
5782 safi2str(safi),
5783 bgp_dest_get_prefix(
5784 ndest));
5785
5786 bgp_path_info_set_flag(
5787 ndest, pi,
5788 BGP_PATH_STALE);
5789 }
5790 }
5791 }
5792 }
5793 } else {
5794 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5795 dest = bgp_route_next(dest)) {
5796 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5797 pi = pi->next) {
5798 if (pi->peer != peer)
5799 continue;
5800
5801 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5802 PEER_STATUS_ENHANCED_REFRESH))
5803 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5804 && !CHECK_FLAG(pi->flags,
5805 BGP_PATH_UNUSEABLE)) {
5806 if (bgp_debug_neighbor_events(peer))
5807 zlog_debug(
5808 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5809 peer, afi2str(afi),
5810 safi2str(safi),
5811 bgp_dest_get_prefix(
5812 dest));
5813
5814 bgp_path_info_set_flag(dest, pi,
5815 BGP_PATH_STALE);
5816 }
5817 }
5818 }
5819 }
5820 }
5821
5822 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5823 {
5824 if (peer->sort == BGP_PEER_IBGP)
5825 return true;
5826
5827 if (peer->sort == BGP_PEER_EBGP
5828 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5829 || FILTER_LIST_OUT_NAME(filter)
5830 || DISTRIBUTE_OUT_NAME(filter)))
5831 return true;
5832 return false;
5833 }
5834
5835 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5836 {
5837 if (peer->sort == BGP_PEER_IBGP)
5838 return true;
5839
5840 if (peer->sort == BGP_PEER_EBGP
5841 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5842 || FILTER_LIST_IN_NAME(filter)
5843 || DISTRIBUTE_IN_NAME(filter)))
5844 return true;
5845 return false;
5846 }
5847
5848 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5849 safi_t safi)
5850 {
5851 struct bgp_dest *dest;
5852 struct bgp_path_info *pi;
5853 struct bgp_path_info *next;
5854
5855 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5856 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5857 const struct prefix *p = bgp_dest_get_prefix(dest);
5858
5859 next = pi->next;
5860
5861 /* Unimport EVPN routes from VRFs */
5862 if (safi == SAFI_EVPN)
5863 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5864 SAFI_EVPN, p, pi);
5865
5866 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5867 && pi->type == ZEBRA_ROUTE_BGP
5868 && (pi->sub_type == BGP_ROUTE_NORMAL
5869 || pi->sub_type == BGP_ROUTE_AGGREGATE
5870 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5871
5872 if (bgp_fibupd_safi(safi))
5873 bgp_zebra_withdraw(p, pi, bgp, safi);
5874 }
5875
5876 bgp_path_info_reap(dest, pi);
5877 }
5878 }
5879
5880 /* Delete all kernel routes. */
5881 void bgp_cleanup_routes(struct bgp *bgp)
5882 {
5883 afi_t afi;
5884 struct bgp_dest *dest;
5885 struct bgp_table *table;
5886
5887 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5888 if (afi == AFI_L2VPN)
5889 continue;
5890 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5891 SAFI_UNICAST);
5892 /*
5893 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5894 */
5895 if (afi != AFI_L2VPN) {
5896 safi_t safi;
5897 safi = SAFI_MPLS_VPN;
5898 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5899 dest = bgp_route_next(dest)) {
5900 table = bgp_dest_get_bgp_table_info(dest);
5901 if (table != NULL) {
5902 bgp_cleanup_table(bgp, table, safi);
5903 bgp_table_finish(&table);
5904 bgp_dest_set_bgp_table_info(dest, NULL);
5905 bgp_dest_unlock_node(dest);
5906 }
5907 }
5908 safi = SAFI_ENCAP;
5909 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5910 dest = bgp_route_next(dest)) {
5911 table = bgp_dest_get_bgp_table_info(dest);
5912 if (table != NULL) {
5913 bgp_cleanup_table(bgp, table, safi);
5914 bgp_table_finish(&table);
5915 bgp_dest_set_bgp_table_info(dest, NULL);
5916 bgp_dest_unlock_node(dest);
5917 }
5918 }
5919 }
5920 }
5921 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5922 dest = bgp_route_next(dest)) {
5923 table = bgp_dest_get_bgp_table_info(dest);
5924 if (table != NULL) {
5925 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5926 bgp_table_finish(&table);
5927 bgp_dest_set_bgp_table_info(dest, NULL);
5928 bgp_dest_unlock_node(dest);
5929 }
5930 }
5931 }
5932
5933 void bgp_reset(void)
5934 {
5935 vty_reset();
5936 bgp_zclient_reset();
5937 access_list_reset();
5938 prefix_list_reset();
5939 }
5940
5941 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5942 {
5943 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5944 && CHECK_FLAG(peer->af_cap[afi][safi],
5945 PEER_CAP_ADDPATH_AF_TX_RCV));
5946 }
5947
5948 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5949 value. */
5950 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5951 struct bgp_nlri *packet)
5952 {
5953 uint8_t *pnt;
5954 uint8_t *lim;
5955 struct prefix p;
5956 int psize;
5957 int ret;
5958 afi_t afi;
5959 safi_t safi;
5960 bool addpath_capable;
5961 uint32_t addpath_id;
5962
5963 pnt = packet->nlri;
5964 lim = pnt + packet->length;
5965 afi = packet->afi;
5966 safi = packet->safi;
5967 addpath_id = 0;
5968 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
5969
5970 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5971 syntactic validity. If the field is syntactically incorrect,
5972 then the Error Subcode is set to Invalid Network Field. */
5973 for (; pnt < lim; pnt += psize) {
5974 /* Clear prefix structure. */
5975 memset(&p, 0, sizeof(p));
5976
5977 if (addpath_capable) {
5978
5979 /* When packet overflow occurs return immediately. */
5980 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5981 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5982
5983 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5984 addpath_id = ntohl(addpath_id);
5985 pnt += BGP_ADDPATH_ID_LEN;
5986 }
5987
5988 /* Fetch prefix length. */
5989 p.prefixlen = *pnt++;
5990 /* afi/safi validity already verified by caller,
5991 * bgp_update_receive */
5992 p.family = afi2family(afi);
5993
5994 /* Prefix length check. */
5995 if (p.prefixlen > prefix_blen(&p) * 8) {
5996 flog_err(
5997 EC_BGP_UPDATE_RCV,
5998 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
5999 peer->host, p.prefixlen, packet->afi);
6000 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
6001 }
6002
6003 /* Packet size overflow check. */
6004 psize = PSIZE(p.prefixlen);
6005
6006 /* When packet overflow occur return immediately. */
6007 if (pnt + psize > lim) {
6008 flog_err(
6009 EC_BGP_UPDATE_RCV,
6010 "%s [Error] Update packet error (prefix length %d overflows packet)",
6011 peer->host, p.prefixlen);
6012 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6013 }
6014
6015 /* Defensive coding, double-check the psize fits in a struct
6016 * prefix for the v4 and v6 afi's and unicast/multicast */
6017 if (psize > (ssize_t)sizeof(p.u.val)) {
6018 flog_err(
6019 EC_BGP_UPDATE_RCV,
6020 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
6021 peer->host, p.prefixlen, sizeof(p.u.val));
6022 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6023 }
6024
6025 /* Fetch prefix from NLRI packet. */
6026 memcpy(p.u.val, pnt, psize);
6027
6028 /* Check address. */
6029 if (afi == AFI_IP && safi == SAFI_UNICAST) {
6030 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
6031 /* From RFC4271 Section 6.3:
6032 *
6033 * If a prefix in the NLRI field is semantically
6034 * incorrect
6035 * (e.g., an unexpected multicast IP address),
6036 * an error SHOULD
6037 * be logged locally, and the prefix SHOULD be
6038 * ignored.
6039 */
6040 flog_err(
6041 EC_BGP_UPDATE_RCV,
6042 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
6043 peer->host, &p.u.prefix4);
6044 continue;
6045 }
6046 }
6047
6048 /* Check address. */
6049 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
6050 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6051 flog_err(
6052 EC_BGP_UPDATE_RCV,
6053 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
6054 peer->host, &p.u.prefix6);
6055
6056 continue;
6057 }
6058 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
6059 flog_err(
6060 EC_BGP_UPDATE_RCV,
6061 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
6062 peer->host, &p.u.prefix6);
6063
6064 continue;
6065 }
6066 }
6067
6068 /* Normal process. */
6069 if (attr)
6070 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
6071 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
6072 NULL, NULL, 0, 0, NULL);
6073 else
6074 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
6075 safi, ZEBRA_ROUTE_BGP,
6076 BGP_ROUTE_NORMAL, NULL, NULL, 0,
6077 NULL);
6078
6079 /* Do not send BGP notification twice when maximum-prefix count
6080 * overflow. */
6081 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
6082 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
6083
6084 /* Address family configuration mismatch. */
6085 if (ret < 0)
6086 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
6087 }
6088
6089 /* Packet length consistency check. */
6090 if (pnt != lim) {
6091 flog_err(
6092 EC_BGP_UPDATE_RCV,
6093 "%s [Error] Update packet error (prefix length mismatch with total length)",
6094 peer->host);
6095 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6096 }
6097
6098 return BGP_NLRI_PARSE_OK;
6099 }
6100
6101 static struct bgp_static *bgp_static_new(void)
6102 {
6103 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
6104 }
6105
6106 static void bgp_static_free(struct bgp_static *bgp_static)
6107 {
6108 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6109 route_map_counter_decrement(bgp_static->rmap.map);
6110
6111 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
6112 XFREE(MTYPE_BGP_STATIC, bgp_static);
6113 }
6114
6115 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
6116 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
6117 {
6118 struct bgp_dest *dest;
6119 struct bgp_path_info *pi;
6120 struct bgp_path_info *new;
6121 struct bgp_path_info rmap_path;
6122 struct attr attr;
6123 struct attr *attr_new;
6124 route_map_result_t ret;
6125 #ifdef ENABLE_BGP_VNC
6126 int vnc_implicit_withdraw = 0;
6127 #endif
6128
6129 assert(bgp_static);
6130
6131 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6132
6133 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6134
6135 attr.nexthop = bgp_static->igpnexthop;
6136 attr.med = bgp_static->igpmetric;
6137 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6138
6139 if (afi == AFI_IP)
6140 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
6141
6142 if (bgp_static->atomic)
6143 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
6144
6145 /* Store label index, if required. */
6146 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
6147 attr.label_index = bgp_static->label_index;
6148 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
6149 }
6150
6151 /* Apply route-map. */
6152 if (bgp_static->rmap.name) {
6153 struct attr attr_tmp = attr;
6154
6155 memset(&rmap_path, 0, sizeof(rmap_path));
6156 rmap_path.peer = bgp->peer_self;
6157 rmap_path.attr = &attr_tmp;
6158
6159 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6160
6161 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6162
6163 bgp->peer_self->rmap_type = 0;
6164
6165 if (ret == RMAP_DENYMATCH) {
6166 /* Free uninterned attribute. */
6167 bgp_attr_flush(&attr_tmp);
6168
6169 /* Unintern original. */
6170 aspath_unintern(&attr.aspath);
6171 bgp_static_withdraw(bgp, p, afi, safi);
6172 bgp_dest_unlock_node(dest);
6173 return;
6174 }
6175
6176 if (bgp_in_graceful_shutdown(bgp))
6177 bgp_attr_add_gshut_community(&attr_tmp);
6178
6179 attr_new = bgp_attr_intern(&attr_tmp);
6180 } else {
6181
6182 if (bgp_in_graceful_shutdown(bgp))
6183 bgp_attr_add_gshut_community(&attr);
6184
6185 attr_new = bgp_attr_intern(&attr);
6186 }
6187
6188 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6189 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6190 && pi->sub_type == BGP_ROUTE_STATIC)
6191 break;
6192
6193 if (pi) {
6194 if (attrhash_cmp(pi->attr, attr_new)
6195 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6196 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6197 bgp_dest_unlock_node(dest);
6198 bgp_attr_unintern(&attr_new);
6199 aspath_unintern(&attr.aspath);
6200 return;
6201 } else {
6202 /* The attribute is changed. */
6203 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6204
6205 /* Rewrite BGP route information. */
6206 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6207 bgp_path_info_restore(dest, pi);
6208 else
6209 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6210 #ifdef ENABLE_BGP_VNC
6211 if ((afi == AFI_IP || afi == AFI_IP6)
6212 && (safi == SAFI_UNICAST)) {
6213 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6214 /*
6215 * Implicit withdraw case.
6216 * We have to do this before pi is
6217 * changed
6218 */
6219 ++vnc_implicit_withdraw;
6220 vnc_import_bgp_del_route(bgp, p, pi);
6221 vnc_import_bgp_exterior_del_route(
6222 bgp, p, pi);
6223 }
6224 }
6225 #endif
6226 bgp_attr_unintern(&pi->attr);
6227 pi->attr = attr_new;
6228 pi->uptime = monotime(NULL);
6229 #ifdef ENABLE_BGP_VNC
6230 if ((afi == AFI_IP || afi == AFI_IP6)
6231 && (safi == SAFI_UNICAST)) {
6232 if (vnc_implicit_withdraw) {
6233 vnc_import_bgp_add_route(bgp, p, pi);
6234 vnc_import_bgp_exterior_add_route(
6235 bgp, p, pi);
6236 }
6237 }
6238 #endif
6239
6240 /* Nexthop reachability check. */
6241 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6242 && (safi == SAFI_UNICAST
6243 || safi == SAFI_LABELED_UNICAST)) {
6244
6245 struct bgp *bgp_nexthop = bgp;
6246
6247 if (pi->extra && pi->extra->bgp_orig)
6248 bgp_nexthop = pi->extra->bgp_orig;
6249
6250 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6251 afi, safi, pi, NULL,
6252 0, p))
6253 bgp_path_info_set_flag(dest, pi,
6254 BGP_PATH_VALID);
6255 else {
6256 if (BGP_DEBUG(nht, NHT)) {
6257 char buf1[INET6_ADDRSTRLEN];
6258 inet_ntop(p->family,
6259 &p->u.prefix, buf1,
6260 INET6_ADDRSTRLEN);
6261 zlog_debug(
6262 "%s(%s): Route not in table, not advertising",
6263 __func__, buf1);
6264 }
6265 bgp_path_info_unset_flag(
6266 dest, pi, BGP_PATH_VALID);
6267 }
6268 } else {
6269 /* Delete the NHT structure if any, if we're
6270 * toggling between
6271 * enabling/disabling import check. We
6272 * deregister the route
6273 * from NHT to avoid overloading NHT and the
6274 * process interaction
6275 */
6276 bgp_unlink_nexthop(pi);
6277 bgp_path_info_set_flag(dest, pi,
6278 BGP_PATH_VALID);
6279 }
6280 /* Process change. */
6281 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6282 bgp_process(bgp, dest, afi, safi);
6283
6284 if (SAFI_UNICAST == safi
6285 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6286 || bgp->inst_type
6287 == BGP_INSTANCE_TYPE_DEFAULT)) {
6288 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6289 pi);
6290 }
6291
6292 bgp_dest_unlock_node(dest);
6293 aspath_unintern(&attr.aspath);
6294 return;
6295 }
6296 }
6297
6298 /* Make new BGP info. */
6299 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6300 attr_new, dest);
6301 /* Nexthop reachability check. */
6302 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6303 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6304 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6305 p))
6306 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6307 else {
6308 if (BGP_DEBUG(nht, NHT)) {
6309 char buf1[INET6_ADDRSTRLEN];
6310 inet_ntop(p->family, &p->u.prefix, buf1,
6311 INET6_ADDRSTRLEN);
6312 zlog_debug(
6313 "%s(%s): Route not in table, not advertising",
6314 __func__, buf1);
6315 }
6316 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6317 }
6318 } else {
6319 /* Delete the NHT structure if any, if we're toggling between
6320 * enabling/disabling import check. We deregister the route
6321 * from NHT to avoid overloading NHT and the process interaction
6322 */
6323 bgp_unlink_nexthop(new);
6324
6325 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6326 }
6327
6328 /* Aggregate address increment. */
6329 bgp_aggregate_increment(bgp, p, new, afi, safi);
6330
6331 /* Register new BGP information. */
6332 bgp_path_info_add(dest, new);
6333
6334 /* route_node_get lock */
6335 bgp_dest_unlock_node(dest);
6336
6337 /* Process change. */
6338 bgp_process(bgp, dest, afi, safi);
6339
6340 if (SAFI_UNICAST == safi
6341 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6342 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6343 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6344 }
6345
6346 /* Unintern original. */
6347 aspath_unintern(&attr.aspath);
6348 }
6349
6350 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6351 safi_t safi)
6352 {
6353 struct bgp_dest *dest;
6354 struct bgp_path_info *pi;
6355
6356 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6357
6358 /* Check selected route and self inserted route. */
6359 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6360 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6361 && pi->sub_type == BGP_ROUTE_STATIC)
6362 break;
6363
6364 /* Withdraw static BGP route from routing table. */
6365 if (pi) {
6366 if (SAFI_UNICAST == safi
6367 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6368 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6369 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6370 }
6371 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6372 bgp_unlink_nexthop(pi);
6373 bgp_path_info_delete(dest, pi);
6374 bgp_process(bgp, dest, afi, safi);
6375 }
6376
6377 /* Unlock bgp_node_lookup. */
6378 bgp_dest_unlock_node(dest);
6379 }
6380
6381 /*
6382 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6383 */
6384 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6385 afi_t afi, safi_t safi,
6386 struct prefix_rd *prd)
6387 {
6388 struct bgp_dest *dest;
6389 struct bgp_path_info *pi;
6390
6391 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6392
6393 /* Check selected route and self inserted route. */
6394 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6395 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6396 && pi->sub_type == BGP_ROUTE_STATIC)
6397 break;
6398
6399 /* Withdraw static BGP route from routing table. */
6400 if (pi) {
6401 #ifdef ENABLE_BGP_VNC
6402 rfapiProcessWithdraw(
6403 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6404 1); /* Kill, since it is an administrative change */
6405 #endif
6406 if (SAFI_MPLS_VPN == safi
6407 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6408 vpn_leak_to_vrf_withdraw(bgp, pi);
6409 }
6410 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6411 bgp_path_info_delete(dest, pi);
6412 bgp_process(bgp, dest, afi, safi);
6413 }
6414
6415 /* Unlock bgp_node_lookup. */
6416 bgp_dest_unlock_node(dest);
6417 }
6418
6419 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6420 struct bgp_static *bgp_static, afi_t afi,
6421 safi_t safi)
6422 {
6423 struct bgp_dest *dest;
6424 struct bgp_path_info *new;
6425 struct attr *attr_new;
6426 struct attr attr = {0};
6427 struct bgp_path_info *pi;
6428 #ifdef ENABLE_BGP_VNC
6429 mpls_label_t label = 0;
6430 #endif
6431 uint32_t num_labels = 0;
6432
6433 assert(bgp_static);
6434
6435 if (bgp_static->label != MPLS_INVALID_LABEL)
6436 num_labels = 1;
6437 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6438 &bgp_static->prd);
6439
6440 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6441
6442 attr.nexthop = bgp_static->igpnexthop;
6443 attr.med = bgp_static->igpmetric;
6444 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6445
6446 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6447 || (safi == SAFI_ENCAP)) {
6448 if (afi == AFI_IP) {
6449 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6450 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6451 }
6452 }
6453 if (afi == AFI_L2VPN) {
6454 if (bgp_static->gatewayIp.family == AF_INET) {
6455 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6456 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6457 &bgp_static->gatewayIp.u.prefix4,
6458 IPV4_MAX_BYTELEN);
6459 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6460 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6461 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6462 &bgp_static->gatewayIp.u.prefix6,
6463 IPV6_MAX_BYTELEN);
6464 }
6465 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6466 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6467 struct bgp_encap_type_vxlan bet;
6468 memset(&bet, 0, sizeof(bet));
6469 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6470 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6471 }
6472 if (bgp_static->router_mac) {
6473 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6474 }
6475 }
6476 /* Apply route-map. */
6477 if (bgp_static->rmap.name) {
6478 struct attr attr_tmp = attr;
6479 struct bgp_path_info rmap_path;
6480 route_map_result_t ret;
6481
6482 rmap_path.peer = bgp->peer_self;
6483 rmap_path.attr = &attr_tmp;
6484
6485 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6486
6487 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6488
6489 bgp->peer_self->rmap_type = 0;
6490
6491 if (ret == RMAP_DENYMATCH) {
6492 /* Free uninterned attribute. */
6493 bgp_attr_flush(&attr_tmp);
6494
6495 /* Unintern original. */
6496 aspath_unintern(&attr.aspath);
6497 bgp_static_withdraw_safi(bgp, p, afi, safi,
6498 &bgp_static->prd);
6499 bgp_dest_unlock_node(dest);
6500 return;
6501 }
6502
6503 attr_new = bgp_attr_intern(&attr_tmp);
6504 } else {
6505 attr_new = bgp_attr_intern(&attr);
6506 }
6507
6508 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6509 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6510 && pi->sub_type == BGP_ROUTE_STATIC)
6511 break;
6512
6513 if (pi) {
6514 if (attrhash_cmp(pi->attr, attr_new)
6515 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6516 bgp_dest_unlock_node(dest);
6517 bgp_attr_unintern(&attr_new);
6518 aspath_unintern(&attr.aspath);
6519 return;
6520 } else {
6521 /* The attribute is changed. */
6522 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6523
6524 /* Rewrite BGP route information. */
6525 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6526 bgp_path_info_restore(dest, pi);
6527 else
6528 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6529 bgp_attr_unintern(&pi->attr);
6530 pi->attr = attr_new;
6531 pi->uptime = monotime(NULL);
6532 #ifdef ENABLE_BGP_VNC
6533 if (pi->extra)
6534 label = decode_label(&pi->extra->label[0]);
6535 #endif
6536
6537 /* Process change. */
6538 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6539 bgp_process(bgp, dest, afi, safi);
6540
6541 if (SAFI_MPLS_VPN == safi
6542 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6543 vpn_leak_to_vrf_update(bgp, pi,
6544 &bgp_static->prd);
6545 }
6546 #ifdef ENABLE_BGP_VNC
6547 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6548 pi->attr, afi, safi, pi->type,
6549 pi->sub_type, &label);
6550 #endif
6551 bgp_dest_unlock_node(dest);
6552 aspath_unintern(&attr.aspath);
6553 return;
6554 }
6555 }
6556
6557
6558 /* Make new BGP info. */
6559 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6560 attr_new, dest);
6561 SET_FLAG(new->flags, BGP_PATH_VALID);
6562 bgp_path_info_extra_get(new);
6563 if (num_labels) {
6564 new->extra->label[0] = bgp_static->label;
6565 new->extra->num_labels = num_labels;
6566 }
6567 #ifdef ENABLE_BGP_VNC
6568 label = decode_label(&bgp_static->label);
6569 #endif
6570
6571 /* Aggregate address increment. */
6572 bgp_aggregate_increment(bgp, p, new, afi, safi);
6573
6574 /* Register new BGP information. */
6575 bgp_path_info_add(dest, new);
6576 /* route_node_get lock */
6577 bgp_dest_unlock_node(dest);
6578
6579 /* Process change. */
6580 bgp_process(bgp, dest, afi, safi);
6581
6582 if (SAFI_MPLS_VPN == safi
6583 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6584 vpn_leak_to_vrf_update(bgp, new, &bgp_static->prd);
6585 }
6586 #ifdef ENABLE_BGP_VNC
6587 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6588 safi, new->type, new->sub_type, &label);
6589 #endif
6590
6591 /* Unintern original. */
6592 aspath_unintern(&attr.aspath);
6593 }
6594
6595 /* Configure static BGP network. When user don't run zebra, static
6596 route should be installed as valid. */
6597 static int bgp_static_set(struct vty *vty, const char *negate,
6598 const char *ip_str, afi_t afi, safi_t safi,
6599 const char *rmap, int backdoor, uint32_t label_index)
6600 {
6601 VTY_DECLVAR_CONTEXT(bgp, bgp);
6602 int ret;
6603 struct prefix p;
6604 struct bgp_static *bgp_static;
6605 struct bgp_dest *dest;
6606 uint8_t need_update = 0;
6607
6608 /* Convert IP prefix string to struct prefix. */
6609 ret = str2prefix(ip_str, &p);
6610 if (!ret) {
6611 vty_out(vty, "%% Malformed prefix\n");
6612 return CMD_WARNING_CONFIG_FAILED;
6613 }
6614 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6615 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6616 return CMD_WARNING_CONFIG_FAILED;
6617 }
6618
6619 apply_mask(&p);
6620
6621 if (negate) {
6622
6623 /* Set BGP static route configuration. */
6624 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6625
6626 if (!dest) {
6627 vty_out(vty, "%% Can't find static route specified\n");
6628 return CMD_WARNING_CONFIG_FAILED;
6629 }
6630
6631 bgp_static = bgp_dest_get_bgp_static_info(dest);
6632
6633 if ((label_index != BGP_INVALID_LABEL_INDEX)
6634 && (label_index != bgp_static->label_index)) {
6635 vty_out(vty,
6636 "%% label-index doesn't match static route\n");
6637 bgp_dest_unlock_node(dest);
6638 return CMD_WARNING_CONFIG_FAILED;
6639 }
6640
6641 if ((rmap && bgp_static->rmap.name)
6642 && strcmp(rmap, bgp_static->rmap.name)) {
6643 vty_out(vty,
6644 "%% route-map name doesn't match static route\n");
6645 bgp_dest_unlock_node(dest);
6646 return CMD_WARNING_CONFIG_FAILED;
6647 }
6648
6649 /* Update BGP RIB. */
6650 if (!bgp_static->backdoor)
6651 bgp_static_withdraw(bgp, &p, afi, safi);
6652
6653 /* Clear configuration. */
6654 bgp_static_free(bgp_static);
6655 bgp_dest_set_bgp_static_info(dest, NULL);
6656 bgp_dest_unlock_node(dest);
6657 bgp_dest_unlock_node(dest);
6658 } else {
6659
6660 /* Set BGP static route configuration. */
6661 dest = bgp_node_get(bgp->route[afi][safi], &p);
6662 bgp_static = bgp_dest_get_bgp_static_info(dest);
6663 if (bgp_static) {
6664 /* Configuration change. */
6665 /* Label index cannot be changed. */
6666 if (bgp_static->label_index != label_index) {
6667 vty_out(vty, "%% cannot change label-index\n");
6668 bgp_dest_unlock_node(dest);
6669 return CMD_WARNING_CONFIG_FAILED;
6670 }
6671
6672 /* Check previous routes are installed into BGP. */
6673 if (bgp_static->valid
6674 && bgp_static->backdoor != backdoor)
6675 need_update = 1;
6676
6677 bgp_static->backdoor = backdoor;
6678
6679 if (rmap) {
6680 XFREE(MTYPE_ROUTE_MAP_NAME,
6681 bgp_static->rmap.name);
6682 route_map_counter_decrement(
6683 bgp_static->rmap.map);
6684 bgp_static->rmap.name =
6685 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6686 bgp_static->rmap.map =
6687 route_map_lookup_by_name(rmap);
6688 route_map_counter_increment(
6689 bgp_static->rmap.map);
6690 } else {
6691 XFREE(MTYPE_ROUTE_MAP_NAME,
6692 bgp_static->rmap.name);
6693 route_map_counter_decrement(
6694 bgp_static->rmap.map);
6695 bgp_static->rmap.map = NULL;
6696 bgp_static->valid = 0;
6697 }
6698 bgp_dest_unlock_node(dest);
6699 } else {
6700 /* New configuration. */
6701 bgp_static = bgp_static_new();
6702 bgp_static->backdoor = backdoor;
6703 bgp_static->valid = 0;
6704 bgp_static->igpmetric = 0;
6705 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6706 bgp_static->label_index = label_index;
6707
6708 if (rmap) {
6709 XFREE(MTYPE_ROUTE_MAP_NAME,
6710 bgp_static->rmap.name);
6711 route_map_counter_decrement(
6712 bgp_static->rmap.map);
6713 bgp_static->rmap.name =
6714 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6715 bgp_static->rmap.map =
6716 route_map_lookup_by_name(rmap);
6717 route_map_counter_increment(
6718 bgp_static->rmap.map);
6719 }
6720 bgp_dest_set_bgp_static_info(dest, bgp_static);
6721 }
6722
6723 bgp_static->valid = 1;
6724 if (need_update)
6725 bgp_static_withdraw(bgp, &p, afi, safi);
6726
6727 if (!bgp_static->backdoor)
6728 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6729 }
6730
6731 return CMD_SUCCESS;
6732 }
6733
6734 void bgp_static_add(struct bgp *bgp)
6735 {
6736 afi_t afi;
6737 safi_t safi;
6738 struct bgp_dest *dest;
6739 struct bgp_dest *rm;
6740 struct bgp_table *table;
6741 struct bgp_static *bgp_static;
6742
6743 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6744 FOREACH_AFI_SAFI (afi, safi)
6745 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6746 dest = bgp_route_next(dest)) {
6747 if (!bgp_dest_has_bgp_path_info_data(dest))
6748 continue;
6749
6750 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6751 || (safi == SAFI_EVPN)) {
6752 table = bgp_dest_get_bgp_table_info(dest);
6753
6754 for (rm = bgp_table_top(table); rm;
6755 rm = bgp_route_next(rm)) {
6756 bgp_static =
6757 bgp_dest_get_bgp_static_info(
6758 rm);
6759 bgp_static_update_safi(
6760 bgp, bgp_dest_get_prefix(rm),
6761 bgp_static, afi, safi);
6762 }
6763 } else {
6764 bgp_static_update(
6765 bgp, bgp_dest_get_prefix(dest),
6766 bgp_dest_get_bgp_static_info(dest), afi,
6767 safi);
6768 }
6769 }
6770 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6771 }
6772
6773 /* Called from bgp_delete(). Delete all static routes from the BGP
6774 instance. */
6775 void bgp_static_delete(struct bgp *bgp)
6776 {
6777 afi_t afi;
6778 safi_t safi;
6779 struct bgp_dest *dest;
6780 struct bgp_dest *rm;
6781 struct bgp_table *table;
6782 struct bgp_static *bgp_static;
6783
6784 FOREACH_AFI_SAFI (afi, safi)
6785 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6786 dest = bgp_route_next(dest)) {
6787 if (!bgp_dest_has_bgp_path_info_data(dest))
6788 continue;
6789
6790 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6791 || (safi == SAFI_EVPN)) {
6792 table = bgp_dest_get_bgp_table_info(dest);
6793
6794 for (rm = bgp_table_top(table); rm;
6795 rm = bgp_route_next(rm)) {
6796 bgp_static =
6797 bgp_dest_get_bgp_static_info(
6798 rm);
6799 if (!bgp_static)
6800 continue;
6801
6802 bgp_static_withdraw_safi(
6803 bgp, bgp_dest_get_prefix(rm),
6804 AFI_IP, safi,
6805 (struct prefix_rd *)
6806 bgp_dest_get_prefix(
6807 dest));
6808 bgp_static_free(bgp_static);
6809 bgp_dest_set_bgp_static_info(rm,
6810 NULL);
6811 bgp_dest_unlock_node(rm);
6812 }
6813 } else {
6814 bgp_static = bgp_dest_get_bgp_static_info(dest);
6815 bgp_static_withdraw(bgp,
6816 bgp_dest_get_prefix(dest),
6817 afi, safi);
6818 bgp_static_free(bgp_static);
6819 bgp_dest_set_bgp_static_info(dest, NULL);
6820 bgp_dest_unlock_node(dest);
6821 }
6822 }
6823 }
6824
6825 void bgp_static_redo_import_check(struct bgp *bgp)
6826 {
6827 afi_t afi;
6828 safi_t safi;
6829 struct bgp_dest *dest;
6830 struct bgp_dest *rm;
6831 struct bgp_table *table;
6832 struct bgp_static *bgp_static;
6833
6834 /* Use this flag to force reprocessing of the route */
6835 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6836 FOREACH_AFI_SAFI (afi, safi) {
6837 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6838 dest = bgp_route_next(dest)) {
6839 if (!bgp_dest_has_bgp_path_info_data(dest))
6840 continue;
6841
6842 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6843 || (safi == SAFI_EVPN)) {
6844 table = bgp_dest_get_bgp_table_info(dest);
6845
6846 for (rm = bgp_table_top(table); rm;
6847 rm = bgp_route_next(rm)) {
6848 bgp_static =
6849 bgp_dest_get_bgp_static_info(
6850 rm);
6851 bgp_static_update_safi(
6852 bgp, bgp_dest_get_prefix(rm),
6853 bgp_static, afi, safi);
6854 }
6855 } else {
6856 bgp_static = bgp_dest_get_bgp_static_info(dest);
6857 bgp_static_update(bgp,
6858 bgp_dest_get_prefix(dest),
6859 bgp_static, afi, safi);
6860 }
6861 }
6862 }
6863 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6864 }
6865
6866 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6867 safi_t safi)
6868 {
6869 struct bgp_table *table;
6870 struct bgp_dest *dest;
6871 struct bgp_path_info *pi;
6872
6873 /* Do not install the aggregate route if BGP is in the
6874 * process of termination.
6875 */
6876 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6877 || (bgp->peer_self == NULL))
6878 return;
6879
6880 table = bgp->rib[afi][safi];
6881 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6882 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6883 if (pi->peer == bgp->peer_self
6884 && ((pi->type == ZEBRA_ROUTE_BGP
6885 && pi->sub_type == BGP_ROUTE_STATIC)
6886 || (pi->type != ZEBRA_ROUTE_BGP
6887 && pi->sub_type
6888 == BGP_ROUTE_REDISTRIBUTE))) {
6889 bgp_aggregate_decrement(
6890 bgp, bgp_dest_get_prefix(dest), pi, afi,
6891 safi);
6892 bgp_unlink_nexthop(pi);
6893 bgp_path_info_delete(dest, pi);
6894 bgp_process(bgp, dest, afi, safi);
6895 }
6896 }
6897 }
6898 }
6899
6900 /*
6901 * Purge all networks and redistributed routes from routing table.
6902 * Invoked upon the instance going down.
6903 */
6904 void bgp_purge_static_redist_routes(struct bgp *bgp)
6905 {
6906 afi_t afi;
6907 safi_t safi;
6908
6909 FOREACH_AFI_SAFI (afi, safi)
6910 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6911 }
6912
6913 /*
6914 * gpz 110624
6915 * Currently this is used to set static routes for VPN and ENCAP.
6916 * I think it can probably be factored with bgp_static_set.
6917 */
6918 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6919 const char *ip_str, const char *rd_str,
6920 const char *label_str, const char *rmap_str,
6921 int evpn_type, const char *esi, const char *gwip,
6922 const char *ethtag, const char *routermac)
6923 {
6924 VTY_DECLVAR_CONTEXT(bgp, bgp);
6925 int ret;
6926 struct prefix p;
6927 struct prefix_rd prd;
6928 struct bgp_dest *pdest;
6929 struct bgp_dest *dest;
6930 struct bgp_table *table;
6931 struct bgp_static *bgp_static;
6932 mpls_label_t label = MPLS_INVALID_LABEL;
6933 struct prefix gw_ip;
6934
6935 /* validate ip prefix */
6936 ret = str2prefix(ip_str, &p);
6937 if (!ret) {
6938 vty_out(vty, "%% Malformed prefix\n");
6939 return CMD_WARNING_CONFIG_FAILED;
6940 }
6941 apply_mask(&p);
6942 if ((afi == AFI_L2VPN)
6943 && (bgp_build_evpn_prefix(evpn_type,
6944 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6945 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6946 return CMD_WARNING_CONFIG_FAILED;
6947 }
6948
6949 ret = str2prefix_rd(rd_str, &prd);
6950 if (!ret) {
6951 vty_out(vty, "%% Malformed rd\n");
6952 return CMD_WARNING_CONFIG_FAILED;
6953 }
6954
6955 if (label_str) {
6956 unsigned long label_val;
6957 label_val = strtoul(label_str, NULL, 10);
6958 encode_label(label_val, &label);
6959 }
6960
6961 if (safi == SAFI_EVPN) {
6962 if (esi && str2esi(esi, NULL) == 0) {
6963 vty_out(vty, "%% Malformed ESI\n");
6964 return CMD_WARNING_CONFIG_FAILED;
6965 }
6966 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6967 vty_out(vty, "%% Malformed Router MAC\n");
6968 return CMD_WARNING_CONFIG_FAILED;
6969 }
6970 if (gwip) {
6971 memset(&gw_ip, 0, sizeof(gw_ip));
6972 ret = str2prefix(gwip, &gw_ip);
6973 if (!ret) {
6974 vty_out(vty, "%% Malformed GatewayIp\n");
6975 return CMD_WARNING_CONFIG_FAILED;
6976 }
6977 if ((gw_ip.family == AF_INET
6978 && is_evpn_prefix_ipaddr_v6(
6979 (struct prefix_evpn *)&p))
6980 || (gw_ip.family == AF_INET6
6981 && is_evpn_prefix_ipaddr_v4(
6982 (struct prefix_evpn *)&p))) {
6983 vty_out(vty,
6984 "%% GatewayIp family differs with IP prefix\n");
6985 return CMD_WARNING_CONFIG_FAILED;
6986 }
6987 }
6988 }
6989 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6990 if (!bgp_dest_has_bgp_path_info_data(pdest))
6991 bgp_dest_set_bgp_table_info(pdest,
6992 bgp_table_init(bgp, afi, safi));
6993 table = bgp_dest_get_bgp_table_info(pdest);
6994
6995 dest = bgp_node_get(table, &p);
6996
6997 if (bgp_dest_has_bgp_path_info_data(dest)) {
6998 vty_out(vty, "%% Same network configuration exists\n");
6999 bgp_dest_unlock_node(dest);
7000 } else {
7001 /* New configuration. */
7002 bgp_static = bgp_static_new();
7003 bgp_static->backdoor = 0;
7004 bgp_static->valid = 0;
7005 bgp_static->igpmetric = 0;
7006 bgp_static->igpnexthop.s_addr = INADDR_ANY;
7007 bgp_static->label = label;
7008 bgp_static->prd = prd;
7009
7010 if (rmap_str) {
7011 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
7012 route_map_counter_decrement(bgp_static->rmap.map);
7013 bgp_static->rmap.name =
7014 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
7015 bgp_static->rmap.map =
7016 route_map_lookup_by_name(rmap_str);
7017 route_map_counter_increment(bgp_static->rmap.map);
7018 }
7019
7020 if (safi == SAFI_EVPN) {
7021 if (esi) {
7022 bgp_static->eth_s_id =
7023 XCALLOC(MTYPE_ATTR,
7024 sizeof(esi_t));
7025 str2esi(esi, bgp_static->eth_s_id);
7026 }
7027 if (routermac) {
7028 bgp_static->router_mac =
7029 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
7030 (void)prefix_str2mac(routermac,
7031 bgp_static->router_mac);
7032 }
7033 if (gwip)
7034 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
7035 }
7036 bgp_dest_set_bgp_static_info(dest, bgp_static);
7037
7038 bgp_static->valid = 1;
7039 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
7040 }
7041
7042 return CMD_SUCCESS;
7043 }
7044
7045 /* Configure static BGP network. */
7046 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
7047 const char *ip_str, const char *rd_str,
7048 const char *label_str, int evpn_type, const char *esi,
7049 const char *gwip, const char *ethtag)
7050 {
7051 VTY_DECLVAR_CONTEXT(bgp, bgp);
7052 int ret;
7053 struct prefix p;
7054 struct prefix_rd prd;
7055 struct bgp_dest *pdest;
7056 struct bgp_dest *dest;
7057 struct bgp_table *table;
7058 struct bgp_static *bgp_static;
7059 mpls_label_t label = MPLS_INVALID_LABEL;
7060
7061 /* Convert IP prefix string to struct prefix. */
7062 ret = str2prefix(ip_str, &p);
7063 if (!ret) {
7064 vty_out(vty, "%% Malformed prefix\n");
7065 return CMD_WARNING_CONFIG_FAILED;
7066 }
7067 apply_mask(&p);
7068 if ((afi == AFI_L2VPN)
7069 && (bgp_build_evpn_prefix(evpn_type,
7070 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7071 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7072 return CMD_WARNING_CONFIG_FAILED;
7073 }
7074 ret = str2prefix_rd(rd_str, &prd);
7075 if (!ret) {
7076 vty_out(vty, "%% Malformed rd\n");
7077 return CMD_WARNING_CONFIG_FAILED;
7078 }
7079
7080 if (label_str) {
7081 unsigned long label_val;
7082 label_val = strtoul(label_str, NULL, 10);
7083 encode_label(label_val, &label);
7084 }
7085
7086 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7087 if (!bgp_dest_has_bgp_path_info_data(pdest))
7088 bgp_dest_set_bgp_table_info(pdest,
7089 bgp_table_init(bgp, afi, safi));
7090 else
7091 bgp_dest_unlock_node(pdest);
7092 table = bgp_dest_get_bgp_table_info(pdest);
7093
7094 dest = bgp_node_lookup(table, &p);
7095
7096 if (dest) {
7097 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
7098
7099 bgp_static = bgp_dest_get_bgp_static_info(dest);
7100 bgp_static_free(bgp_static);
7101 bgp_dest_set_bgp_static_info(dest, NULL);
7102 bgp_dest_unlock_node(dest);
7103 bgp_dest_unlock_node(dest);
7104 } else
7105 vty_out(vty, "%% Can't find the route\n");
7106
7107 return CMD_SUCCESS;
7108 }
7109
7110 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
7111 const char *rmap_name)
7112 {
7113 VTY_DECLVAR_CONTEXT(bgp, bgp);
7114 struct bgp_rmap *rmap;
7115
7116 rmap = &bgp->table_map[afi][safi];
7117 if (rmap_name) {
7118 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7119 route_map_counter_decrement(rmap->map);
7120 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
7121 rmap->map = route_map_lookup_by_name(rmap_name);
7122 route_map_counter_increment(rmap->map);
7123 } else {
7124 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7125 route_map_counter_decrement(rmap->map);
7126 rmap->map = NULL;
7127 }
7128
7129 if (bgp_fibupd_safi(safi))
7130 bgp_zebra_announce_table(bgp, afi, safi);
7131
7132 return CMD_SUCCESS;
7133 }
7134
7135 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
7136 const char *rmap_name)
7137 {
7138 VTY_DECLVAR_CONTEXT(bgp, bgp);
7139 struct bgp_rmap *rmap;
7140
7141 rmap = &bgp->table_map[afi][safi];
7142 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7143 route_map_counter_decrement(rmap->map);
7144 rmap->map = NULL;
7145
7146 if (bgp_fibupd_safi(safi))
7147 bgp_zebra_announce_table(bgp, afi, safi);
7148
7149 return CMD_SUCCESS;
7150 }
7151
7152 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
7153 safi_t safi)
7154 {
7155 if (bgp->table_map[afi][safi].name) {
7156 vty_out(vty, " table-map %s\n",
7157 bgp->table_map[afi][safi].name);
7158 }
7159 }
7160
7161 DEFUN (bgp_table_map,
7162 bgp_table_map_cmd,
7163 "table-map WORD",
7164 "BGP table to RIB route download filter\n"
7165 "Name of the route map\n")
7166 {
7167 int idx_word = 1;
7168 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7169 argv[idx_word]->arg);
7170 }
7171 DEFUN (no_bgp_table_map,
7172 no_bgp_table_map_cmd,
7173 "no table-map WORD",
7174 NO_STR
7175 "BGP table to RIB route download filter\n"
7176 "Name of the route map\n")
7177 {
7178 int idx_word = 2;
7179 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7180 argv[idx_word]->arg);
7181 }
7182
7183 DEFPY(bgp_network,
7184 bgp_network_cmd,
7185 "[no] network \
7186 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7187 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7188 backdoor$backdoor}]",
7189 NO_STR
7190 "Specify a network to announce via BGP\n"
7191 "IPv4 prefix\n"
7192 "Network number\n"
7193 "Network mask\n"
7194 "Network mask\n"
7195 "Route-map to modify the attributes\n"
7196 "Name of the route map\n"
7197 "Label index to associate with the prefix\n"
7198 "Label index value\n"
7199 "Specify a BGP backdoor route\n")
7200 {
7201 char addr_prefix_str[BUFSIZ];
7202
7203 if (address_str) {
7204 int ret;
7205
7206 ret = netmask_str2prefix_str(address_str, netmask_str,
7207 addr_prefix_str,
7208 sizeof(addr_prefix_str));
7209 if (!ret) {
7210 vty_out(vty, "%% Inconsistent address and mask\n");
7211 return CMD_WARNING_CONFIG_FAILED;
7212 }
7213 }
7214
7215 return bgp_static_set(
7216 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7217 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7218 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7219 }
7220
7221 DEFPY(ipv6_bgp_network,
7222 ipv6_bgp_network_cmd,
7223 "[no] network X:X::X:X/M$prefix \
7224 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7225 NO_STR
7226 "Specify a network to announce via BGP\n"
7227 "IPv6 prefix\n"
7228 "Route-map to modify the attributes\n"
7229 "Name of the route map\n"
7230 "Label index to associate with the prefix\n"
7231 "Label index value\n")
7232 {
7233 return bgp_static_set(
7234 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7235 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7236 }
7237
7238 static struct bgp_aggregate *bgp_aggregate_new(void)
7239 {
7240 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7241 }
7242
7243 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7244 {
7245 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7246 route_map_counter_decrement(aggregate->suppress_map);
7247 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7248 route_map_counter_decrement(aggregate->rmap.map);
7249 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7250 }
7251
7252 /**
7253 * Helper function to avoid repeated code: prepare variables for a
7254 * `route_map_apply` call.
7255 *
7256 * \returns `true` on route map match, otherwise `false`.
7257 */
7258 static bool aggr_suppress_map_test(struct bgp *bgp,
7259 struct bgp_aggregate *aggregate,
7260 struct bgp_path_info *pi)
7261 {
7262 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7263 route_map_result_t rmr = RMAP_DENYMATCH;
7264 struct bgp_path_info rmap_path = {};
7265 struct attr attr = {};
7266
7267 /* No route map entries created, just don't match. */
7268 if (aggregate->suppress_map == NULL)
7269 return false;
7270
7271 /* Call route map matching and return result. */
7272 attr.aspath = aspath_empty();
7273 rmap_path.peer = bgp->peer_self;
7274 rmap_path.attr = &attr;
7275
7276 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7277 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7278 bgp->peer_self->rmap_type = 0;
7279
7280 bgp_attr_flush(&attr);
7281 aspath_unintern(&attr.aspath);
7282
7283 return rmr == RMAP_PERMITMATCH;
7284 }
7285
7286 /** Test whether the aggregation has suppressed this path or not. */
7287 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7288 struct bgp_path_info *pi)
7289 {
7290 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7291 return false;
7292
7293 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7294 }
7295
7296 /**
7297 * Suppress this path and keep the reference.
7298 *
7299 * \returns `true` if needs processing otherwise `false`.
7300 */
7301 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7302 struct bgp_path_info *pi)
7303 {
7304 struct bgp_path_info_extra *pie;
7305
7306 /* Path is already suppressed by this aggregation. */
7307 if (aggr_suppress_exists(aggregate, pi))
7308 return false;
7309
7310 pie = bgp_path_info_extra_get(pi);
7311
7312 /* This is the first suppression, allocate memory and list it. */
7313 if (pie->aggr_suppressors == NULL)
7314 pie->aggr_suppressors = list_new();
7315
7316 listnode_add(pie->aggr_suppressors, aggregate);
7317
7318 /* Only mark for processing if suppressed. */
7319 if (listcount(pie->aggr_suppressors) == 1) {
7320 if (BGP_DEBUG(update, UPDATE_OUT))
7321 zlog_debug("aggregate-address suppressing: %pFX",
7322 bgp_dest_get_prefix(pi->net));
7323
7324 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7325 return true;
7326 }
7327
7328 return false;
7329 }
7330
7331 /**
7332 * Unsuppress this path and remove the reference.
7333 *
7334 * \returns `true` if needs processing otherwise `false`.
7335 */
7336 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7337 struct bgp_path_info *pi)
7338 {
7339 /* Path wasn't suppressed. */
7340 if (!aggr_suppress_exists(aggregate, pi))
7341 return false;
7342
7343 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7344
7345 /* Unsuppress and free extra memory if last item. */
7346 if (listcount(pi->extra->aggr_suppressors) == 0) {
7347 if (BGP_DEBUG(update, UPDATE_OUT))
7348 zlog_debug("aggregate-address unsuppressing: %pFX",
7349 bgp_dest_get_prefix(pi->net));
7350
7351 list_delete(&pi->extra->aggr_suppressors);
7352 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7353 return true;
7354 }
7355
7356 return false;
7357 }
7358
7359 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7360 struct aspath *aspath,
7361 struct community *comm,
7362 struct ecommunity *ecomm,
7363 struct lcommunity *lcomm)
7364 {
7365 static struct aspath *ae = NULL;
7366
7367 if (!ae)
7368 ae = aspath_empty();
7369
7370 if (!pi)
7371 return false;
7372
7373 if (origin != pi->attr->origin)
7374 return false;
7375
7376 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7377 return false;
7378
7379 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7380 return false;
7381
7382 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7383 return false;
7384
7385 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7386 return false;
7387
7388 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7389 return false;
7390
7391 return true;
7392 }
7393
7394 static void bgp_aggregate_install(
7395 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7396 uint8_t origin, struct aspath *aspath, struct community *community,
7397 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7398 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7399 {
7400 struct bgp_dest *dest;
7401 struct bgp_table *table;
7402 struct bgp_path_info *pi, *orig, *new;
7403 struct attr *attr;
7404
7405 table = bgp->rib[afi][safi];
7406
7407 dest = bgp_node_get(table, p);
7408
7409 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7410 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7411 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7412 break;
7413
7414 /*
7415 * If we have paths with different MEDs, then don't install
7416 * (or uninstall) the aggregate route.
7417 */
7418 if (aggregate->match_med && aggregate->med_mismatched)
7419 goto uninstall_aggregate_route;
7420
7421 if (aggregate->count > 0) {
7422 /*
7423 * If the aggregate information has not changed
7424 * no need to re-install it again.
7425 */
7426 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7427 ecommunity, lcommunity)) {
7428 bgp_dest_unlock_node(dest);
7429
7430 if (aspath)
7431 aspath_free(aspath);
7432 if (community)
7433 community_free(&community);
7434 if (ecommunity)
7435 ecommunity_free(&ecommunity);
7436 if (lcommunity)
7437 lcommunity_free(&lcommunity);
7438
7439 return;
7440 }
7441
7442 /*
7443 * Mark the old as unusable
7444 */
7445 if (pi)
7446 bgp_path_info_delete(dest, pi);
7447
7448 attr = bgp_attr_aggregate_intern(
7449 bgp, origin, aspath, community, ecommunity, lcommunity,
7450 aggregate, atomic_aggregate, p);
7451
7452 if (!attr) {
7453 bgp_dest_unlock_node(dest);
7454 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7455 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7456 zlog_debug("%s: %pFX null attribute", __func__,
7457 p);
7458 return;
7459 }
7460
7461 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7462 bgp->peer_self, attr, dest);
7463
7464 SET_FLAG(new->flags, BGP_PATH_VALID);
7465
7466 bgp_path_info_add(dest, new);
7467 bgp_process(bgp, dest, afi, safi);
7468 } else {
7469 uninstall_aggregate_route:
7470 for (pi = orig; pi; pi = pi->next)
7471 if (pi->peer == bgp->peer_self
7472 && pi->type == ZEBRA_ROUTE_BGP
7473 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7474 break;
7475
7476 /* Withdraw static BGP route from routing table. */
7477 if (pi) {
7478 bgp_path_info_delete(dest, pi);
7479 bgp_process(bgp, dest, afi, safi);
7480 }
7481 }
7482
7483 bgp_dest_unlock_node(dest);
7484 }
7485
7486 /**
7487 * Check if the current path has different MED than other known paths.
7488 *
7489 * \returns `true` if the MED matched the others else `false`.
7490 */
7491 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7492 struct bgp *bgp, struct bgp_path_info *pi)
7493 {
7494 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7495
7496 /* This is the first route being analyzed. */
7497 if (!aggregate->med_initialized) {
7498 aggregate->med_initialized = true;
7499 aggregate->med_mismatched = false;
7500 aggregate->med_matched_value = cur_med;
7501 } else {
7502 /* Check if routes with different MED showed up. */
7503 if (cur_med != aggregate->med_matched_value)
7504 aggregate->med_mismatched = true;
7505 }
7506
7507 return !aggregate->med_mismatched;
7508 }
7509
7510 /**
7511 * Initializes and tests all routes in the aggregate address path for MED
7512 * values.
7513 *
7514 * \returns `true` if all MEDs are the same otherwise `false`.
7515 */
7516 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7517 struct bgp *bgp, const struct prefix *p,
7518 afi_t afi, safi_t safi)
7519 {
7520 struct bgp_table *table = bgp->rib[afi][safi];
7521 const struct prefix *dest_p;
7522 struct bgp_dest *dest, *top;
7523 struct bgp_path_info *pi;
7524 bool med_matched = true;
7525
7526 aggregate->med_initialized = false;
7527
7528 top = bgp_node_get(table, p);
7529 for (dest = bgp_node_get(table, p); dest;
7530 dest = bgp_route_next_until(dest, top)) {
7531 dest_p = bgp_dest_get_prefix(dest);
7532 if (dest_p->prefixlen <= p->prefixlen)
7533 continue;
7534
7535 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7536 if (BGP_PATH_HOLDDOWN(pi))
7537 continue;
7538 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7539 continue;
7540 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7541 med_matched = false;
7542 break;
7543 }
7544 }
7545 if (!med_matched)
7546 break;
7547 }
7548 bgp_dest_unlock_node(top);
7549
7550 return med_matched;
7551 }
7552
7553 /**
7554 * Toggles the route suppression status for this aggregate address
7555 * configuration.
7556 */
7557 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7558 struct bgp *bgp, const struct prefix *p,
7559 afi_t afi, safi_t safi, bool suppress)
7560 {
7561 struct bgp_table *table = bgp->rib[afi][safi];
7562 const struct prefix *dest_p;
7563 struct bgp_dest *dest, *top;
7564 struct bgp_path_info *pi;
7565 bool toggle_suppression;
7566
7567 /* We've found a different MED we must revert any suppressed routes. */
7568 top = bgp_node_get(table, p);
7569 for (dest = bgp_node_get(table, p); dest;
7570 dest = bgp_route_next_until(dest, top)) {
7571 dest_p = bgp_dest_get_prefix(dest);
7572 if (dest_p->prefixlen <= p->prefixlen)
7573 continue;
7574
7575 toggle_suppression = false;
7576 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7577 if (BGP_PATH_HOLDDOWN(pi))
7578 continue;
7579 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7580 continue;
7581
7582 /* We are toggling suppression back. */
7583 if (suppress) {
7584 /* Suppress route if not suppressed already. */
7585 if (aggr_suppress_path(aggregate, pi))
7586 toggle_suppression = true;
7587 continue;
7588 }
7589
7590 /* Install route if there is no more suppression. */
7591 if (aggr_unsuppress_path(aggregate, pi))
7592 toggle_suppression = true;
7593 }
7594
7595 if (toggle_suppression)
7596 bgp_process(bgp, dest, afi, safi);
7597 }
7598 bgp_dest_unlock_node(top);
7599 }
7600
7601 /**
7602 * Aggregate address MED matching incremental test: this function is called
7603 * when the initial aggregation occurred and we are only testing a single
7604 * new path.
7605 *
7606 * In addition to testing and setting the MED validity it also installs back
7607 * suppressed routes (if summary is configured).
7608 *
7609 * Must not be called in `bgp_aggregate_route`.
7610 */
7611 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7612 struct bgp *bgp, const struct prefix *p,
7613 afi_t afi, safi_t safi,
7614 struct bgp_path_info *pi)
7615 {
7616 /* MED matching disabled. */
7617 if (!aggregate->match_med)
7618 return;
7619
7620 /* Aggregation with different MED, recheck if we have got equal MEDs
7621 * now.
7622 */
7623 if (aggregate->med_mismatched &&
7624 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7625 aggregate->summary_only)
7626 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7627 true);
7628 else
7629 bgp_aggregate_med_match(aggregate, bgp, pi);
7630
7631 /* No mismatches, just quit. */
7632 if (!aggregate->med_mismatched)
7633 return;
7634
7635 /* Route summarization is disabled. */
7636 if (!aggregate->summary_only)
7637 return;
7638
7639 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7640 }
7641
7642 /* Update an aggregate as routes are added/removed from the BGP table */
7643 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7644 safi_t safi, struct bgp_aggregate *aggregate)
7645 {
7646 struct bgp_table *table;
7647 struct bgp_dest *top;
7648 struct bgp_dest *dest;
7649 uint8_t origin;
7650 struct aspath *aspath = NULL;
7651 struct community *community = NULL;
7652 struct ecommunity *ecommunity = NULL;
7653 struct lcommunity *lcommunity = NULL;
7654 struct bgp_path_info *pi;
7655 unsigned long match = 0;
7656 uint8_t atomic_aggregate = 0;
7657
7658 /* If the bgp instance is being deleted or self peer is deleted
7659 * then do not create aggregate route
7660 */
7661 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7662 || (bgp->peer_self == NULL))
7663 return;
7664
7665 /* Initialize and test routes for MED difference. */
7666 if (aggregate->match_med)
7667 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7668
7669 /*
7670 * Reset aggregate count: we might've been called from route map
7671 * update so in that case we must retest all more specific routes.
7672 *
7673 * \see `bgp_route_map_process_update`.
7674 */
7675 aggregate->count = 0;
7676 aggregate->incomplete_origin_count = 0;
7677 aggregate->incomplete_origin_count = 0;
7678 aggregate->egp_origin_count = 0;
7679
7680 /* ORIGIN attribute: If at least one route among routes that are
7681 aggregated has ORIGIN with the value INCOMPLETE, then the
7682 aggregated route must have the ORIGIN attribute with the value
7683 INCOMPLETE. Otherwise, if at least one route among routes that
7684 are aggregated has ORIGIN with the value EGP, then the aggregated
7685 route must have the origin attribute with the value EGP. In all
7686 other case the value of the ORIGIN attribute of the aggregated
7687 route is INTERNAL. */
7688 origin = BGP_ORIGIN_IGP;
7689
7690 table = bgp->rib[afi][safi];
7691
7692 top = bgp_node_get(table, p);
7693 for (dest = bgp_node_get(table, p); dest;
7694 dest = bgp_route_next_until(dest, top)) {
7695 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7696
7697 if (dest_p->prefixlen <= p->prefixlen)
7698 continue;
7699
7700 /* If suppress fib is enabled and route not installed
7701 * in FIB, skip the route
7702 */
7703 if (!bgp_check_advertise(bgp, dest))
7704 continue;
7705
7706 match = 0;
7707
7708 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7709 if (BGP_PATH_HOLDDOWN(pi))
7710 continue;
7711
7712 if (pi->attr->flag
7713 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7714 atomic_aggregate = 1;
7715
7716 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7717 continue;
7718
7719 /*
7720 * summary-only aggregate route suppress
7721 * aggregated route announcements.
7722 *
7723 * MED matching:
7724 * Don't create summaries if MED didn't match
7725 * otherwise neither the specific routes and the
7726 * aggregation will be announced.
7727 */
7728 if (aggregate->summary_only
7729 && AGGREGATE_MED_VALID(aggregate)) {
7730 if (aggr_suppress_path(aggregate, pi))
7731 match++;
7732 }
7733
7734 /*
7735 * Suppress more specific routes that match the route
7736 * map results.
7737 *
7738 * MED matching:
7739 * Don't suppress routes if MED matching is enabled and
7740 * it mismatched otherwise we might end up with no
7741 * routes for this path.
7742 */
7743 if (aggregate->suppress_map_name
7744 && AGGREGATE_MED_VALID(aggregate)
7745 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7746 if (aggr_suppress_path(aggregate, pi))
7747 match++;
7748 }
7749
7750 aggregate->count++;
7751
7752 /*
7753 * If at least one route among routes that are
7754 * aggregated has ORIGIN with the value INCOMPLETE,
7755 * then the aggregated route MUST have the ORIGIN
7756 * attribute with the value INCOMPLETE. Otherwise, if
7757 * at least one route among routes that are aggregated
7758 * has ORIGIN with the value EGP, then the aggregated
7759 * route MUST have the ORIGIN attribute with the value
7760 * EGP.
7761 */
7762 switch (pi->attr->origin) {
7763 case BGP_ORIGIN_INCOMPLETE:
7764 aggregate->incomplete_origin_count++;
7765 break;
7766 case BGP_ORIGIN_EGP:
7767 aggregate->egp_origin_count++;
7768 break;
7769 default:
7770 /*Do nothing.
7771 */
7772 break;
7773 }
7774
7775 if (!aggregate->as_set)
7776 continue;
7777
7778 /*
7779 * as-set aggregate route generate origin, as path,
7780 * and community aggregation.
7781 */
7782 /* Compute aggregate route's as-path.
7783 */
7784 bgp_compute_aggregate_aspath_hash(aggregate,
7785 pi->attr->aspath);
7786
7787 /* Compute aggregate route's community.
7788 */
7789 if (bgp_attr_get_community(pi->attr))
7790 bgp_compute_aggregate_community_hash(
7791 aggregate,
7792 bgp_attr_get_community(pi->attr));
7793
7794 /* Compute aggregate route's extended community.
7795 */
7796 if (bgp_attr_get_ecommunity(pi->attr))
7797 bgp_compute_aggregate_ecommunity_hash(
7798 aggregate,
7799 bgp_attr_get_ecommunity(pi->attr));
7800
7801 /* Compute aggregate route's large community.
7802 */
7803 if (bgp_attr_get_lcommunity(pi->attr))
7804 bgp_compute_aggregate_lcommunity_hash(
7805 aggregate,
7806 bgp_attr_get_lcommunity(pi->attr));
7807 }
7808 if (match)
7809 bgp_process(bgp, dest, afi, safi);
7810 }
7811 if (aggregate->as_set) {
7812 bgp_compute_aggregate_aspath_val(aggregate);
7813 bgp_compute_aggregate_community_val(aggregate);
7814 bgp_compute_aggregate_ecommunity_val(aggregate);
7815 bgp_compute_aggregate_lcommunity_val(aggregate);
7816 }
7817
7818
7819 bgp_dest_unlock_node(top);
7820
7821
7822 if (aggregate->incomplete_origin_count > 0)
7823 origin = BGP_ORIGIN_INCOMPLETE;
7824 else if (aggregate->egp_origin_count > 0)
7825 origin = BGP_ORIGIN_EGP;
7826
7827 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7828 origin = aggregate->origin;
7829
7830 if (aggregate->as_set) {
7831 if (aggregate->aspath)
7832 /* Retrieve aggregate route's as-path.
7833 */
7834 aspath = aspath_dup(aggregate->aspath);
7835
7836 if (aggregate->community)
7837 /* Retrieve aggregate route's community.
7838 */
7839 community = community_dup(aggregate->community);
7840
7841 if (aggregate->ecommunity)
7842 /* Retrieve aggregate route's ecommunity.
7843 */
7844 ecommunity = ecommunity_dup(aggregate->ecommunity);
7845
7846 if (aggregate->lcommunity)
7847 /* Retrieve aggregate route's lcommunity.
7848 */
7849 lcommunity = lcommunity_dup(aggregate->lcommunity);
7850 }
7851
7852 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7853 ecommunity, lcommunity, atomic_aggregate,
7854 aggregate);
7855 }
7856
7857 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7858 safi_t safi, struct bgp_aggregate *aggregate)
7859 {
7860 struct bgp_table *table;
7861 struct bgp_dest *top;
7862 struct bgp_dest *dest;
7863 struct bgp_path_info *pi;
7864 unsigned long match;
7865
7866 table = bgp->rib[afi][safi];
7867
7868 /* If routes exists below this node, generate aggregate routes. */
7869 top = bgp_node_get(table, p);
7870 for (dest = bgp_node_get(table, p); dest;
7871 dest = bgp_route_next_until(dest, top)) {
7872 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7873
7874 if (dest_p->prefixlen <= p->prefixlen)
7875 continue;
7876 match = 0;
7877
7878 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7879 if (BGP_PATH_HOLDDOWN(pi))
7880 continue;
7881
7882 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7883 continue;
7884
7885 /*
7886 * This route is suppressed: attempt to unsuppress it.
7887 *
7888 * `aggr_unsuppress_path` will fail if this particular
7889 * aggregate route was not the suppressor.
7890 */
7891 if (pi->extra && pi->extra->aggr_suppressors &&
7892 listcount(pi->extra->aggr_suppressors)) {
7893 if (aggr_unsuppress_path(aggregate, pi))
7894 match++;
7895 }
7896
7897 aggregate->count--;
7898
7899 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7900 aggregate->incomplete_origin_count--;
7901 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7902 aggregate->egp_origin_count--;
7903
7904 if (aggregate->as_set) {
7905 /* Remove as-path from aggregate.
7906 */
7907 bgp_remove_aspath_from_aggregate_hash(
7908 aggregate,
7909 pi->attr->aspath);
7910
7911 if (bgp_attr_get_community(pi->attr))
7912 /* Remove community from aggregate.
7913 */
7914 bgp_remove_comm_from_aggregate_hash(
7915 aggregate,
7916 bgp_attr_get_community(
7917 pi->attr));
7918
7919 if (bgp_attr_get_ecommunity(pi->attr))
7920 /* Remove ecommunity from aggregate.
7921 */
7922 bgp_remove_ecomm_from_aggregate_hash(
7923 aggregate,
7924 bgp_attr_get_ecommunity(
7925 pi->attr));
7926
7927 if (bgp_attr_get_lcommunity(pi->attr))
7928 /* Remove lcommunity from aggregate.
7929 */
7930 bgp_remove_lcomm_from_aggregate_hash(
7931 aggregate,
7932 bgp_attr_get_lcommunity(
7933 pi->attr));
7934 }
7935 }
7936
7937 /* If this node was suppressed, process the change. */
7938 if (match)
7939 bgp_process(bgp, dest, afi, safi);
7940 }
7941 if (aggregate->as_set) {
7942 aspath_free(aggregate->aspath);
7943 aggregate->aspath = NULL;
7944 if (aggregate->community)
7945 community_free(&aggregate->community);
7946 if (aggregate->ecommunity)
7947 ecommunity_free(&aggregate->ecommunity);
7948 if (aggregate->lcommunity)
7949 lcommunity_free(&aggregate->lcommunity);
7950 }
7951
7952 bgp_dest_unlock_node(top);
7953 }
7954
7955 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7956 const struct prefix *aggr_p,
7957 struct bgp_path_info *pinew, afi_t afi,
7958 safi_t safi,
7959 struct bgp_aggregate *aggregate)
7960 {
7961 uint8_t origin;
7962 struct aspath *aspath = NULL;
7963 uint8_t atomic_aggregate = 0;
7964 struct community *community = NULL;
7965 struct ecommunity *ecommunity = NULL;
7966 struct lcommunity *lcommunity = NULL;
7967
7968 /* If the bgp instance is being deleted or self peer is deleted
7969 * then do not create aggregate route
7970 */
7971 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7972 || (bgp->peer_self == NULL))
7973 return;
7974
7975 /* ORIGIN attribute: If at least one route among routes that are
7976 * aggregated has ORIGIN with the value INCOMPLETE, then the
7977 * aggregated route must have the ORIGIN attribute with the value
7978 * INCOMPLETE. Otherwise, if at least one route among routes that
7979 * are aggregated has ORIGIN with the value EGP, then the aggregated
7980 * route must have the origin attribute with the value EGP. In all
7981 * other case the value of the ORIGIN attribute of the aggregated
7982 * route is INTERNAL.
7983 */
7984 origin = BGP_ORIGIN_IGP;
7985
7986 aggregate->count++;
7987
7988 /*
7989 * This must be called before `summary` check to avoid
7990 * "suppressing" twice.
7991 */
7992 if (aggregate->match_med)
7993 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
7994 pinew);
7995
7996 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7997 aggr_suppress_path(aggregate, pinew);
7998
7999 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8000 && aggr_suppress_map_test(bgp, aggregate, pinew))
8001 aggr_suppress_path(aggregate, pinew);
8002
8003 switch (pinew->attr->origin) {
8004 case BGP_ORIGIN_INCOMPLETE:
8005 aggregate->incomplete_origin_count++;
8006 break;
8007 case BGP_ORIGIN_EGP:
8008 aggregate->egp_origin_count++;
8009 break;
8010 default:
8011 /* Do nothing.
8012 */
8013 break;
8014 }
8015
8016 if (aggregate->incomplete_origin_count > 0)
8017 origin = BGP_ORIGIN_INCOMPLETE;
8018 else if (aggregate->egp_origin_count > 0)
8019 origin = BGP_ORIGIN_EGP;
8020
8021 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8022 origin = aggregate->origin;
8023
8024 if (aggregate->as_set) {
8025 /* Compute aggregate route's as-path.
8026 */
8027 bgp_compute_aggregate_aspath(aggregate,
8028 pinew->attr->aspath);
8029
8030 /* Compute aggregate route's community.
8031 */
8032 if (bgp_attr_get_community(pinew->attr))
8033 bgp_compute_aggregate_community(
8034 aggregate, bgp_attr_get_community(pinew->attr));
8035
8036 /* Compute aggregate route's extended community.
8037 */
8038 if (bgp_attr_get_ecommunity(pinew->attr))
8039 bgp_compute_aggregate_ecommunity(
8040 aggregate,
8041 bgp_attr_get_ecommunity(pinew->attr));
8042
8043 /* Compute aggregate route's large community.
8044 */
8045 if (bgp_attr_get_lcommunity(pinew->attr))
8046 bgp_compute_aggregate_lcommunity(
8047 aggregate,
8048 bgp_attr_get_lcommunity(pinew->attr));
8049
8050 /* Retrieve aggregate route's as-path.
8051 */
8052 if (aggregate->aspath)
8053 aspath = aspath_dup(aggregate->aspath);
8054
8055 /* Retrieve aggregate route's community.
8056 */
8057 if (aggregate->community)
8058 community = community_dup(aggregate->community);
8059
8060 /* Retrieve aggregate route's ecommunity.
8061 */
8062 if (aggregate->ecommunity)
8063 ecommunity = ecommunity_dup(aggregate->ecommunity);
8064
8065 /* Retrieve aggregate route's lcommunity.
8066 */
8067 if (aggregate->lcommunity)
8068 lcommunity = lcommunity_dup(aggregate->lcommunity);
8069 }
8070
8071 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8072 aspath, community, ecommunity,
8073 lcommunity, atomic_aggregate, aggregate);
8074 }
8075
8076 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
8077 safi_t safi,
8078 struct bgp_path_info *pi,
8079 struct bgp_aggregate *aggregate,
8080 const struct prefix *aggr_p)
8081 {
8082 uint8_t origin;
8083 struct aspath *aspath = NULL;
8084 uint8_t atomic_aggregate = 0;
8085 struct community *community = NULL;
8086 struct ecommunity *ecommunity = NULL;
8087 struct lcommunity *lcommunity = NULL;
8088 unsigned long match = 0;
8089
8090 /* If the bgp instance is being deleted or self peer is deleted
8091 * then do not create aggregate route
8092 */
8093 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8094 || (bgp->peer_self == NULL))
8095 return;
8096
8097 if (BGP_PATH_HOLDDOWN(pi))
8098 return;
8099
8100 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
8101 return;
8102
8103 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8104 if (aggr_unsuppress_path(aggregate, pi))
8105 match++;
8106
8107 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8108 && aggr_suppress_map_test(bgp, aggregate, pi))
8109 if (aggr_unsuppress_path(aggregate, pi))
8110 match++;
8111
8112 /*
8113 * This must be called after `summary`, `suppress-map` check to avoid
8114 * "unsuppressing" twice.
8115 */
8116 if (aggregate->match_med)
8117 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
8118
8119 if (aggregate->count > 0)
8120 aggregate->count--;
8121
8122 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
8123 aggregate->incomplete_origin_count--;
8124 else if (pi->attr->origin == BGP_ORIGIN_EGP)
8125 aggregate->egp_origin_count--;
8126
8127 if (aggregate->as_set) {
8128 /* Remove as-path from aggregate.
8129 */
8130 bgp_remove_aspath_from_aggregate(aggregate,
8131 pi->attr->aspath);
8132
8133 if (bgp_attr_get_community(pi->attr))
8134 /* Remove community from aggregate.
8135 */
8136 bgp_remove_community_from_aggregate(
8137 aggregate, bgp_attr_get_community(pi->attr));
8138
8139 if (bgp_attr_get_ecommunity(pi->attr))
8140 /* Remove ecommunity from aggregate.
8141 */
8142 bgp_remove_ecommunity_from_aggregate(
8143 aggregate, bgp_attr_get_ecommunity(pi->attr));
8144
8145 if (bgp_attr_get_lcommunity(pi->attr))
8146 /* Remove lcommunity from aggregate.
8147 */
8148 bgp_remove_lcommunity_from_aggregate(
8149 aggregate, bgp_attr_get_lcommunity(pi->attr));
8150 }
8151
8152 /* If this node was suppressed, process the change. */
8153 if (match)
8154 bgp_process(bgp, pi->net, afi, safi);
8155
8156 origin = BGP_ORIGIN_IGP;
8157 if (aggregate->incomplete_origin_count > 0)
8158 origin = BGP_ORIGIN_INCOMPLETE;
8159 else if (aggregate->egp_origin_count > 0)
8160 origin = BGP_ORIGIN_EGP;
8161
8162 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8163 origin = aggregate->origin;
8164
8165 if (aggregate->as_set) {
8166 /* Retrieve aggregate route's as-path.
8167 */
8168 if (aggregate->aspath)
8169 aspath = aspath_dup(aggregate->aspath);
8170
8171 /* Retrieve aggregate route's community.
8172 */
8173 if (aggregate->community)
8174 community = community_dup(aggregate->community);
8175
8176 /* Retrieve aggregate route's ecommunity.
8177 */
8178 if (aggregate->ecommunity)
8179 ecommunity = ecommunity_dup(aggregate->ecommunity);
8180
8181 /* Retrieve aggregate route's lcommunity.
8182 */
8183 if (aggregate->lcommunity)
8184 lcommunity = lcommunity_dup(aggregate->lcommunity);
8185 }
8186
8187 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8188 aspath, community, ecommunity,
8189 lcommunity, atomic_aggregate, aggregate);
8190 }
8191
8192 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8193 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8194 {
8195 struct bgp_dest *child;
8196 struct bgp_dest *dest;
8197 struct bgp_aggregate *aggregate;
8198 struct bgp_table *table;
8199
8200 table = bgp->aggregate[afi][safi];
8201
8202 /* No aggregates configured. */
8203 if (bgp_table_top_nolock(table) == NULL)
8204 return;
8205
8206 if (p->prefixlen == 0)
8207 return;
8208
8209 if (BGP_PATH_HOLDDOWN(pi))
8210 return;
8211
8212 /* If suppress fib is enabled and route not installed
8213 * in FIB, do not update the aggregate route
8214 */
8215 if (!bgp_check_advertise(bgp, pi->net))
8216 return;
8217
8218 child = bgp_node_get(table, p);
8219
8220 /* Aggregate address configuration check. */
8221 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8222 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8223
8224 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8225 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8226 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8227 aggregate);
8228 }
8229 }
8230 bgp_dest_unlock_node(child);
8231 }
8232
8233 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8234 struct bgp_path_info *del, afi_t afi, safi_t safi)
8235 {
8236 struct bgp_dest *child;
8237 struct bgp_dest *dest;
8238 struct bgp_aggregate *aggregate;
8239 struct bgp_table *table;
8240
8241 table = bgp->aggregate[afi][safi];
8242
8243 /* No aggregates configured. */
8244 if (bgp_table_top_nolock(table) == NULL)
8245 return;
8246
8247 if (p->prefixlen == 0)
8248 return;
8249
8250 child = bgp_node_get(table, p);
8251
8252 /* Aggregate address configuration check. */
8253 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8254 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8255
8256 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8257 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8258 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8259 aggregate, dest_p);
8260 }
8261 }
8262 bgp_dest_unlock_node(child);
8263 }
8264
8265 /* Aggregate route attribute. */
8266 #define AGGREGATE_SUMMARY_ONLY 1
8267 #define AGGREGATE_AS_SET 1
8268 #define AGGREGATE_AS_UNSET 0
8269
8270 static const char *bgp_origin2str(uint8_t origin)
8271 {
8272 switch (origin) {
8273 case BGP_ORIGIN_IGP:
8274 return "igp";
8275 case BGP_ORIGIN_EGP:
8276 return "egp";
8277 case BGP_ORIGIN_INCOMPLETE:
8278 return "incomplete";
8279 }
8280 return "n/a";
8281 }
8282
8283 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8284 {
8285 switch (v_state) {
8286 case RPKI_NOT_BEING_USED:
8287 return "not used";
8288 case RPKI_VALID:
8289 return "valid";
8290 case RPKI_NOTFOUND:
8291 return "not found";
8292 case RPKI_INVALID:
8293 return "invalid";
8294 }
8295
8296 assert(!"We should never get here this is a dev escape");
8297 return "ERROR";
8298 }
8299
8300 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8301 afi_t afi, safi_t safi)
8302 {
8303 VTY_DECLVAR_CONTEXT(bgp, bgp);
8304 int ret;
8305 struct prefix p;
8306 struct bgp_dest *dest;
8307 struct bgp_aggregate *aggregate;
8308
8309 /* Convert string to prefix structure. */
8310 ret = str2prefix(prefix_str, &p);
8311 if (!ret) {
8312 vty_out(vty, "Malformed prefix\n");
8313 return CMD_WARNING_CONFIG_FAILED;
8314 }
8315 apply_mask(&p);
8316
8317 /* Old configuration check. */
8318 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8319 if (!dest) {
8320 vty_out(vty,
8321 "%% There is no aggregate-address configuration.\n");
8322 return CMD_WARNING_CONFIG_FAILED;
8323 }
8324
8325 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8326 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8327 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8328 NULL, NULL, 0, aggregate);
8329
8330 /* Unlock aggregate address configuration. */
8331 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8332
8333 if (aggregate->community)
8334 community_free(&aggregate->community);
8335
8336 if (aggregate->community_hash) {
8337 /* Delete all communities in the hash.
8338 */
8339 hash_clean(aggregate->community_hash,
8340 bgp_aggr_community_remove);
8341 /* Free up the community_hash.
8342 */
8343 hash_free(aggregate->community_hash);
8344 }
8345
8346 if (aggregate->ecommunity)
8347 ecommunity_free(&aggregate->ecommunity);
8348
8349 if (aggregate->ecommunity_hash) {
8350 /* Delete all ecommunities in the hash.
8351 */
8352 hash_clean(aggregate->ecommunity_hash,
8353 bgp_aggr_ecommunity_remove);
8354 /* Free up the ecommunity_hash.
8355 */
8356 hash_free(aggregate->ecommunity_hash);
8357 }
8358
8359 if (aggregate->lcommunity)
8360 lcommunity_free(&aggregate->lcommunity);
8361
8362 if (aggregate->lcommunity_hash) {
8363 /* Delete all lcommunities in the hash.
8364 */
8365 hash_clean(aggregate->lcommunity_hash,
8366 bgp_aggr_lcommunity_remove);
8367 /* Free up the lcommunity_hash.
8368 */
8369 hash_free(aggregate->lcommunity_hash);
8370 }
8371
8372 if (aggregate->aspath)
8373 aspath_free(aggregate->aspath);
8374
8375 if (aggregate->aspath_hash) {
8376 /* Delete all as-paths in the hash.
8377 */
8378 hash_clean(aggregate->aspath_hash,
8379 bgp_aggr_aspath_remove);
8380 /* Free up the aspath_hash.
8381 */
8382 hash_free(aggregate->aspath_hash);
8383 }
8384
8385 bgp_aggregate_free(aggregate);
8386 bgp_dest_unlock_node(dest);
8387 bgp_dest_unlock_node(dest);
8388
8389 return CMD_SUCCESS;
8390 }
8391
8392 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8393 safi_t safi, const char *rmap,
8394 uint8_t summary_only, uint8_t as_set,
8395 uint8_t origin, bool match_med,
8396 const char *suppress_map)
8397 {
8398 VTY_DECLVAR_CONTEXT(bgp, bgp);
8399 int ret;
8400 struct prefix p;
8401 struct bgp_dest *dest;
8402 struct bgp_aggregate *aggregate;
8403 uint8_t as_set_new = as_set;
8404
8405 if (suppress_map && summary_only) {
8406 vty_out(vty,
8407 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8408 return CMD_WARNING_CONFIG_FAILED;
8409 }
8410
8411 /* Convert string to prefix structure. */
8412 ret = str2prefix(prefix_str, &p);
8413 if (!ret) {
8414 vty_out(vty, "Malformed prefix\n");
8415 return CMD_WARNING_CONFIG_FAILED;
8416 }
8417 apply_mask(&p);
8418
8419 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8420 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8421 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8422 prefix_str);
8423 return CMD_WARNING_CONFIG_FAILED;
8424 }
8425
8426 /* Old configuration check. */
8427 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8428 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8429
8430 if (aggregate) {
8431 vty_out(vty, "There is already same aggregate network.\n");
8432 /* try to remove the old entry */
8433 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8434 if (ret) {
8435 vty_out(vty, "Error deleting aggregate.\n");
8436 bgp_dest_unlock_node(dest);
8437 return CMD_WARNING_CONFIG_FAILED;
8438 }
8439 }
8440
8441 /* Make aggregate address structure. */
8442 aggregate = bgp_aggregate_new();
8443 aggregate->summary_only = summary_only;
8444 aggregate->match_med = match_med;
8445
8446 /* Network operators MUST NOT locally generate any new
8447 * announcements containing AS_SET or AS_CONFED_SET. If they have
8448 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8449 * SHOULD withdraw those routes and re-announce routes for the
8450 * aggregate or component prefixes (i.e., the more-specific routes
8451 * subsumed by the previously aggregated route) without AS_SET
8452 * or AS_CONFED_SET in the updates.
8453 */
8454 if (bgp->reject_as_sets) {
8455 if (as_set == AGGREGATE_AS_SET) {
8456 as_set_new = AGGREGATE_AS_UNSET;
8457 zlog_warn(
8458 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8459 __func__);
8460 vty_out(vty,
8461 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8462 }
8463 }
8464
8465 aggregate->as_set = as_set_new;
8466 aggregate->safi = safi;
8467 /* Override ORIGIN attribute if defined.
8468 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8469 * to IGP which is not what rfc4271 says.
8470 * This enables the same behavior, optionally.
8471 */
8472 aggregate->origin = origin;
8473
8474 if (rmap) {
8475 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8476 route_map_counter_decrement(aggregate->rmap.map);
8477 aggregate->rmap.name =
8478 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8479 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8480 route_map_counter_increment(aggregate->rmap.map);
8481 }
8482
8483 if (suppress_map) {
8484 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8485 route_map_counter_decrement(aggregate->suppress_map);
8486
8487 aggregate->suppress_map_name =
8488 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8489 aggregate->suppress_map =
8490 route_map_lookup_by_name(aggregate->suppress_map_name);
8491 route_map_counter_increment(aggregate->suppress_map);
8492 }
8493
8494 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8495
8496 /* Aggregate address insert into BGP routing table. */
8497 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
8498
8499 return CMD_SUCCESS;
8500 }
8501
8502 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8503 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8504 "as-set$as_set_s"
8505 "|summary-only$summary_only"
8506 "|route-map RMAP_NAME$rmap_name"
8507 "|origin <egp|igp|incomplete>$origin_s"
8508 "|matching-MED-only$match_med"
8509 "|suppress-map RMAP_NAME$suppress_map"
8510 "}]",
8511 NO_STR
8512 "Configure BGP aggregate entries\n"
8513 "Aggregate prefix\n"
8514 "Aggregate address\n"
8515 "Aggregate mask\n"
8516 "Generate AS set path information\n"
8517 "Filter more specific routes from updates\n"
8518 "Apply route map to aggregate network\n"
8519 "Route map name\n"
8520 "BGP origin code\n"
8521 "Remote EGP\n"
8522 "Local IGP\n"
8523 "Unknown heritage\n"
8524 "Only aggregate routes with matching MED\n"
8525 "Suppress the selected more specific routes\n"
8526 "Route map with the route selectors\n")
8527 {
8528 const char *prefix_s = NULL;
8529 safi_t safi = bgp_node_safi(vty);
8530 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8531 int as_set = AGGREGATE_AS_UNSET;
8532 char prefix_buf[PREFIX2STR_BUFFER];
8533
8534 if (addr_str) {
8535 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8536 sizeof(prefix_buf))
8537 == 0) {
8538 vty_out(vty, "%% Inconsistent address and mask\n");
8539 return CMD_WARNING_CONFIG_FAILED;
8540 }
8541 prefix_s = prefix_buf;
8542 } else
8543 prefix_s = prefix_str;
8544
8545 if (origin_s) {
8546 if (strcmp(origin_s, "egp") == 0)
8547 origin = BGP_ORIGIN_EGP;
8548 else if (strcmp(origin_s, "igp") == 0)
8549 origin = BGP_ORIGIN_IGP;
8550 else if (strcmp(origin_s, "incomplete") == 0)
8551 origin = BGP_ORIGIN_INCOMPLETE;
8552 }
8553
8554 if (as_set_s)
8555 as_set = AGGREGATE_AS_SET;
8556
8557 /* Handle configuration removal, otherwise installation. */
8558 if (no)
8559 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8560
8561 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8562 summary_only != NULL, as_set, origin,
8563 match_med != NULL, suppress_map);
8564 }
8565
8566 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8567 "[no] aggregate-address X:X::X:X/M$prefix [{"
8568 "as-set$as_set_s"
8569 "|summary-only$summary_only"
8570 "|route-map RMAP_NAME$rmap_name"
8571 "|origin <egp|igp|incomplete>$origin_s"
8572 "|matching-MED-only$match_med"
8573 "|suppress-map RMAP_NAME$suppress_map"
8574 "}]",
8575 NO_STR
8576 "Configure BGP aggregate entries\n"
8577 "Aggregate prefix\n"
8578 "Generate AS set path information\n"
8579 "Filter more specific routes from updates\n"
8580 "Apply route map to aggregate network\n"
8581 "Route map name\n"
8582 "BGP origin code\n"
8583 "Remote EGP\n"
8584 "Local IGP\n"
8585 "Unknown heritage\n"
8586 "Only aggregate routes with matching MED\n"
8587 "Suppress the selected more specific routes\n"
8588 "Route map with the route selectors\n")
8589 {
8590 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8591 int as_set = AGGREGATE_AS_UNSET;
8592
8593 if (origin_s) {
8594 if (strcmp(origin_s, "egp") == 0)
8595 origin = BGP_ORIGIN_EGP;
8596 else if (strcmp(origin_s, "igp") == 0)
8597 origin = BGP_ORIGIN_IGP;
8598 else if (strcmp(origin_s, "incomplete") == 0)
8599 origin = BGP_ORIGIN_INCOMPLETE;
8600 }
8601
8602 if (as_set_s)
8603 as_set = AGGREGATE_AS_SET;
8604
8605 /* Handle configuration removal, otherwise installation. */
8606 if (no)
8607 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8608 SAFI_UNICAST);
8609
8610 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8611 rmap_name, summary_only != NULL, as_set,
8612 origin, match_med != NULL, suppress_map);
8613 }
8614
8615 /* Redistribute route treatment. */
8616 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8617 const union g_addr *nexthop, ifindex_t ifindex,
8618 enum nexthop_types_t nhtype, uint8_t distance,
8619 enum blackhole_type bhtype, uint32_t metric,
8620 uint8_t type, unsigned short instance,
8621 route_tag_t tag)
8622 {
8623 struct bgp_path_info *new;
8624 struct bgp_path_info *bpi;
8625 struct bgp_path_info rmap_path;
8626 struct bgp_dest *bn;
8627 struct attr attr;
8628 struct attr *new_attr;
8629 afi_t afi;
8630 route_map_result_t ret;
8631 struct bgp_redist *red;
8632
8633 /* Make default attribute. */
8634 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8635 /*
8636 * This must not be NULL to satisfy Coverity SA
8637 */
8638 assert(attr.aspath);
8639
8640 switch (nhtype) {
8641 case NEXTHOP_TYPE_IFINDEX:
8642 switch (p->family) {
8643 case AF_INET:
8644 attr.nexthop.s_addr = INADDR_ANY;
8645 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8646 break;
8647 case AF_INET6:
8648 memset(&attr.mp_nexthop_global, 0,
8649 sizeof(attr.mp_nexthop_global));
8650 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8651 break;
8652 }
8653 break;
8654 case NEXTHOP_TYPE_IPV4:
8655 case NEXTHOP_TYPE_IPV4_IFINDEX:
8656 attr.nexthop = nexthop->ipv4;
8657 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8658 break;
8659 case NEXTHOP_TYPE_IPV6:
8660 case NEXTHOP_TYPE_IPV6_IFINDEX:
8661 attr.mp_nexthop_global = nexthop->ipv6;
8662 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8663 break;
8664 case NEXTHOP_TYPE_BLACKHOLE:
8665 switch (p->family) {
8666 case AF_INET:
8667 attr.nexthop.s_addr = INADDR_ANY;
8668 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8669 break;
8670 case AF_INET6:
8671 memset(&attr.mp_nexthop_global, 0,
8672 sizeof(attr.mp_nexthop_global));
8673 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8674 break;
8675 }
8676 attr.bh_type = bhtype;
8677 break;
8678 }
8679 attr.nh_type = nhtype;
8680 attr.nh_ifindex = ifindex;
8681
8682 attr.med = metric;
8683 attr.distance = distance;
8684 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8685 attr.tag = tag;
8686
8687 afi = family2afi(p->family);
8688
8689 red = bgp_redist_lookup(bgp, afi, type, instance);
8690 if (red) {
8691 struct attr attr_new;
8692
8693 /* Copy attribute for modification. */
8694 attr_new = attr;
8695
8696 if (red->redist_metric_flag)
8697 attr_new.med = red->redist_metric;
8698
8699 /* Apply route-map. */
8700 if (red->rmap.name) {
8701 memset(&rmap_path, 0, sizeof(rmap_path));
8702 rmap_path.peer = bgp->peer_self;
8703 rmap_path.attr = &attr_new;
8704
8705 SET_FLAG(bgp->peer_self->rmap_type,
8706 PEER_RMAP_TYPE_REDISTRIBUTE);
8707
8708 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8709
8710 bgp->peer_self->rmap_type = 0;
8711
8712 if (ret == RMAP_DENYMATCH) {
8713 /* Free uninterned attribute. */
8714 bgp_attr_flush(&attr_new);
8715
8716 /* Unintern original. */
8717 aspath_unintern(&attr.aspath);
8718 bgp_redistribute_delete(bgp, p, type, instance);
8719 return;
8720 }
8721 }
8722
8723 if (bgp_in_graceful_shutdown(bgp))
8724 bgp_attr_add_gshut_community(&attr_new);
8725
8726 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8727 SAFI_UNICAST, p, NULL);
8728
8729 new_attr = bgp_attr_intern(&attr_new);
8730
8731 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8732 if (bpi->peer == bgp->peer_self
8733 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8734 break;
8735
8736 if (bpi) {
8737 /* Ensure the (source route) type is updated. */
8738 bpi->type = type;
8739 if (attrhash_cmp(bpi->attr, new_attr)
8740 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8741 bgp_attr_unintern(&new_attr);
8742 aspath_unintern(&attr.aspath);
8743 bgp_dest_unlock_node(bn);
8744 return;
8745 } else {
8746 /* The attribute is changed. */
8747 bgp_path_info_set_flag(bn, bpi,
8748 BGP_PATH_ATTR_CHANGED);
8749
8750 /* Rewrite BGP route information. */
8751 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8752 bgp_path_info_restore(bn, bpi);
8753 else
8754 bgp_aggregate_decrement(
8755 bgp, p, bpi, afi, SAFI_UNICAST);
8756 bgp_attr_unintern(&bpi->attr);
8757 bpi->attr = new_attr;
8758 bpi->uptime = monotime(NULL);
8759
8760 /* Process change. */
8761 bgp_aggregate_increment(bgp, p, bpi, afi,
8762 SAFI_UNICAST);
8763 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8764 bgp_dest_unlock_node(bn);
8765 aspath_unintern(&attr.aspath);
8766
8767 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8768 || (bgp->inst_type
8769 == BGP_INSTANCE_TYPE_DEFAULT)) {
8770
8771 vpn_leak_from_vrf_update(
8772 bgp_get_default(), bgp, bpi);
8773 }
8774 return;
8775 }
8776 }
8777
8778 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8779 bgp->peer_self, new_attr, bn);
8780 SET_FLAG(new->flags, BGP_PATH_VALID);
8781
8782 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8783 bgp_path_info_add(bn, new);
8784 bgp_dest_unlock_node(bn);
8785 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8786 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8787
8788 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8789 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8790
8791 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8792 }
8793 }
8794
8795 /* Unintern original. */
8796 aspath_unintern(&attr.aspath);
8797 }
8798
8799 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8800 unsigned short instance)
8801 {
8802 afi_t afi;
8803 struct bgp_dest *dest;
8804 struct bgp_path_info *pi;
8805 struct bgp_redist *red;
8806
8807 afi = family2afi(p->family);
8808
8809 red = bgp_redist_lookup(bgp, afi, type, instance);
8810 if (red) {
8811 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8812 SAFI_UNICAST, p, NULL);
8813
8814 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8815 if (pi->peer == bgp->peer_self && pi->type == type)
8816 break;
8817
8818 if (pi) {
8819 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8820 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8821
8822 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8823 bgp, pi);
8824 }
8825 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8826 bgp_path_info_delete(dest, pi);
8827 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8828 }
8829 bgp_dest_unlock_node(dest);
8830 }
8831 }
8832
8833 /* Withdraw specified route type's route. */
8834 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8835 unsigned short instance)
8836 {
8837 struct bgp_dest *dest;
8838 struct bgp_path_info *pi;
8839 struct bgp_table *table;
8840
8841 table = bgp->rib[afi][SAFI_UNICAST];
8842
8843 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8844 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8845 if (pi->peer == bgp->peer_self && pi->type == type
8846 && pi->instance == instance)
8847 break;
8848
8849 if (pi) {
8850 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8851 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8852
8853 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8854 bgp, pi);
8855 }
8856 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8857 pi, afi, SAFI_UNICAST);
8858 bgp_path_info_delete(dest, pi);
8859 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8860 }
8861 }
8862 }
8863
8864 /* Static function to display route. */
8865 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8866 struct vty *vty, json_object *json, bool wide)
8867 {
8868 int len = 0;
8869 char buf[BUFSIZ];
8870
8871 if (p->family == AF_INET) {
8872 if (!json) {
8873 len = vty_out(vty, "%pFX", p);
8874 } else {
8875 json_object_string_add(json, "prefix",
8876 inet_ntop(p->family,
8877 &p->u.prefix, buf,
8878 BUFSIZ));
8879 json_object_int_add(json, "prefixLen", p->prefixlen);
8880 json_object_string_addf(json, "network", "%pFX", p);
8881 json_object_int_add(json, "version", dest->version);
8882 }
8883 } else if (p->family == AF_ETHERNET) {
8884 len = vty_out(vty, "%pFX", p);
8885 } else if (p->family == AF_EVPN) {
8886 if (!json)
8887 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8888 else
8889 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8890 } else if (p->family == AF_FLOWSPEC) {
8891 route_vty_out_flowspec(vty, p, NULL,
8892 json ?
8893 NLRI_STRING_FORMAT_JSON_SIMPLE :
8894 NLRI_STRING_FORMAT_MIN, json);
8895 } else {
8896 if (!json)
8897 len = vty_out(vty, "%pFX", p);
8898 else {
8899 json_object_string_add(json, "prefix",
8900 inet_ntop(p->family,
8901 &p->u.prefix, buf,
8902 BUFSIZ));
8903 json_object_int_add(json, "prefixLen", p->prefixlen);
8904 json_object_string_addf(json, "network", "%pFX", p);
8905 json_object_int_add(json, "version", dest->version);
8906 }
8907 }
8908
8909 if (!json) {
8910 len = wide ? (45 - len) : (17 - len);
8911 if (len < 1)
8912 vty_out(vty, "\n%*s", 20, " ");
8913 else
8914 vty_out(vty, "%*s", len, " ");
8915 }
8916 }
8917
8918 enum bgp_display_type {
8919 normal_list,
8920 };
8921
8922 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8923 {
8924 switch (reason) {
8925 case bgp_path_selection_none:
8926 return "Nothing to Select";
8927 case bgp_path_selection_first:
8928 return "First path received";
8929 case bgp_path_selection_evpn_sticky_mac:
8930 return "EVPN Sticky Mac";
8931 case bgp_path_selection_evpn_seq:
8932 return "EVPN sequence number";
8933 case bgp_path_selection_evpn_lower_ip:
8934 return "EVPN lower IP";
8935 case bgp_path_selection_evpn_local_path:
8936 return "EVPN local ES path";
8937 case bgp_path_selection_evpn_non_proxy:
8938 return "EVPN non proxy";
8939 case bgp_path_selection_weight:
8940 return "Weight";
8941 case bgp_path_selection_local_pref:
8942 return "Local Pref";
8943 case bgp_path_selection_accept_own:
8944 return "Accept Own";
8945 case bgp_path_selection_local_route:
8946 return "Local Route";
8947 case bgp_path_selection_confed_as_path:
8948 return "Confederation based AS Path";
8949 case bgp_path_selection_as_path:
8950 return "AS Path";
8951 case bgp_path_selection_origin:
8952 return "Origin";
8953 case bgp_path_selection_med:
8954 return "MED";
8955 case bgp_path_selection_peer:
8956 return "Peer Type";
8957 case bgp_path_selection_confed:
8958 return "Confed Peer Type";
8959 case bgp_path_selection_igp_metric:
8960 return "IGP Metric";
8961 case bgp_path_selection_older:
8962 return "Older Path";
8963 case bgp_path_selection_router_id:
8964 return "Router ID";
8965 case bgp_path_selection_cluster_length:
8966 return "Cluster length";
8967 case bgp_path_selection_stale:
8968 return "Path Staleness";
8969 case bgp_path_selection_local_configured:
8970 return "Locally configured route";
8971 case bgp_path_selection_neighbor_ip:
8972 return "Neighbor IP";
8973 case bgp_path_selection_default:
8974 return "Nothing left to compare";
8975 }
8976 return "Invalid (internal error)";
8977 }
8978
8979 /* Print the short form route status for a bgp_path_info */
8980 static void route_vty_short_status_out(struct vty *vty,
8981 struct bgp_path_info *path,
8982 const struct prefix *p,
8983 json_object *json_path)
8984 {
8985 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
8986
8987 if (json_path) {
8988
8989 /* Route status display. */
8990 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8991 json_object_boolean_true_add(json_path, "removed");
8992
8993 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8994 json_object_boolean_true_add(json_path, "stale");
8995
8996 if (path->extra && bgp_path_suppressed(path))
8997 json_object_boolean_true_add(json_path, "suppressed");
8998
8999 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9000 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9001 json_object_boolean_true_add(json_path, "valid");
9002
9003 /* Selected */
9004 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9005 json_object_boolean_true_add(json_path, "history");
9006
9007 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9008 json_object_boolean_true_add(json_path, "damped");
9009
9010 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9011 json_object_boolean_true_add(json_path, "bestpath");
9012 json_object_string_add(json_path, "selectionReason",
9013 bgp_path_selection_reason2str(
9014 path->net->reason));
9015 }
9016
9017 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9018 json_object_boolean_true_add(json_path, "multipath");
9019
9020 /* Internal route. */
9021 if ((path->peer->as)
9022 && (path->peer->as == path->peer->local_as))
9023 json_object_string_add(json_path, "pathFrom",
9024 "internal");
9025 else
9026 json_object_string_add(json_path, "pathFrom",
9027 "external");
9028
9029 return;
9030 }
9031
9032 /* RPKI validation state */
9033 rpki_state =
9034 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9035
9036 if (rpki_state == RPKI_VALID)
9037 vty_out(vty, "V");
9038 else if (rpki_state == RPKI_INVALID)
9039 vty_out(vty, "I");
9040 else if (rpki_state == RPKI_NOTFOUND)
9041 vty_out(vty, "N");
9042 else
9043 vty_out(vty, " ");
9044
9045 /* Route status display. */
9046 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9047 vty_out(vty, "R");
9048 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9049 vty_out(vty, "S");
9050 else if (bgp_path_suppressed(path))
9051 vty_out(vty, "s");
9052 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9053 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9054 vty_out(vty, "*");
9055 else
9056 vty_out(vty, " ");
9057
9058 /* Selected */
9059 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9060 vty_out(vty, "h");
9061 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9062 vty_out(vty, "d");
9063 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9064 vty_out(vty, ">");
9065 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9066 vty_out(vty, "=");
9067 else
9068 vty_out(vty, " ");
9069
9070 /* Internal route. */
9071 if (path->peer && (path->peer->as)
9072 && (path->peer->as == path->peer->local_as))
9073 vty_out(vty, "i");
9074 else
9075 vty_out(vty, " ");
9076 }
9077
9078 static char *bgp_nexthop_hostname(struct peer *peer,
9079 struct bgp_nexthop_cache *bnc)
9080 {
9081 if (peer->hostname
9082 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9083 return peer->hostname;
9084 return NULL;
9085 }
9086
9087 /* called from terminal list command */
9088 void route_vty_out(struct vty *vty, const struct prefix *p,
9089 struct bgp_path_info *path, int display, safi_t safi,
9090 json_object *json_paths, bool wide)
9091 {
9092 int len;
9093 struct attr *attr = path->attr;
9094 json_object *json_path = NULL;
9095 json_object *json_nexthops = NULL;
9096 json_object *json_nexthop_global = NULL;
9097 json_object *json_nexthop_ll = NULL;
9098 json_object *json_ext_community = NULL;
9099 char vrf_id_str[VRF_NAMSIZ] = {0};
9100 bool nexthop_self =
9101 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9102 bool nexthop_othervrf = false;
9103 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9104 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9105 char *nexthop_hostname =
9106 bgp_nexthop_hostname(path->peer, path->nexthop);
9107 char esi_buf[ESI_STR_LEN];
9108
9109 if (json_paths)
9110 json_path = json_object_new_object();
9111
9112 /* short status lead text */
9113 route_vty_short_status_out(vty, path, p, json_path);
9114
9115 if (!json_paths) {
9116 /* print prefix and mask */
9117 if (!display)
9118 route_vty_out_route(path->net, p, vty, json_path, wide);
9119 else
9120 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9121 } else {
9122 route_vty_out_route(path->net, p, vty, json_path, wide);
9123 }
9124
9125 /*
9126 * If vrf id of nexthop is different from that of prefix,
9127 * set up printable string to append
9128 */
9129 if (path->extra && path->extra->bgp_orig) {
9130 const char *self = "";
9131
9132 if (nexthop_self)
9133 self = "<";
9134
9135 nexthop_othervrf = true;
9136 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9137
9138 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9139 snprintf(vrf_id_str, sizeof(vrf_id_str),
9140 "@%s%s", VRFID_NONE_STR, self);
9141 else
9142 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9143 path->extra->bgp_orig->vrf_id, self);
9144
9145 if (path->extra->bgp_orig->inst_type
9146 != BGP_INSTANCE_TYPE_DEFAULT)
9147
9148 nexthop_vrfname = path->extra->bgp_orig->name;
9149 } else {
9150 const char *self = "";
9151
9152 if (nexthop_self)
9153 self = "<";
9154
9155 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9156 }
9157
9158 /*
9159 * For ENCAP and EVPN routes, nexthop address family is not
9160 * neccessarily the same as the prefix address family.
9161 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9162 * EVPN routes are also exchanged with a MP nexthop. Currently,
9163 * this
9164 * is only IPv4, the value will be present in either
9165 * attr->nexthop or
9166 * attr->mp_nexthop_global_in
9167 */
9168 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9169 char buf[BUFSIZ];
9170 char nexthop[128];
9171 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9172
9173 switch (af) {
9174 case AF_INET:
9175 snprintf(nexthop, sizeof(nexthop), "%s",
9176 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
9177 BUFSIZ));
9178 break;
9179 case AF_INET6:
9180 snprintf(nexthop, sizeof(nexthop), "%s",
9181 inet_ntop(af, &attr->mp_nexthop_global, buf,
9182 BUFSIZ));
9183 break;
9184 default:
9185 snprintf(nexthop, sizeof(nexthop), "?");
9186 break;
9187 }
9188
9189 if (json_paths) {
9190 json_nexthop_global = json_object_new_object();
9191
9192 json_object_string_add(json_nexthop_global, "ip",
9193 nexthop);
9194
9195 if (path->peer->hostname)
9196 json_object_string_add(json_nexthop_global,
9197 "hostname",
9198 path->peer->hostname);
9199
9200 json_object_string_add(json_nexthop_global, "afi",
9201 (af == AF_INET) ? "ipv4"
9202 : "ipv6");
9203 json_object_boolean_true_add(json_nexthop_global,
9204 "used");
9205 } else {
9206 if (nexthop_hostname)
9207 len = vty_out(vty, "%s(%s)%s", nexthop,
9208 nexthop_hostname, vrf_id_str);
9209 else
9210 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9211
9212 len = wide ? (41 - len) : (16 - len);
9213 if (len < 1)
9214 vty_out(vty, "\n%*s", 36, " ");
9215 else
9216 vty_out(vty, "%*s", len, " ");
9217 }
9218 } else if (safi == SAFI_EVPN) {
9219 if (json_paths) {
9220 json_nexthop_global = json_object_new_object();
9221
9222 json_object_string_addf(json_nexthop_global, "ip",
9223 "%pI4",
9224 &attr->mp_nexthop_global_in);
9225
9226 if (path->peer->hostname)
9227 json_object_string_add(json_nexthop_global,
9228 "hostname",
9229 path->peer->hostname);
9230
9231 json_object_string_add(json_nexthop_global, "afi",
9232 "ipv4");
9233 json_object_boolean_true_add(json_nexthop_global,
9234 "used");
9235 } else {
9236 if (nexthop_hostname)
9237 len = vty_out(vty, "%pI4(%s)%s",
9238 &attr->mp_nexthop_global_in,
9239 nexthop_hostname, vrf_id_str);
9240 else
9241 len = vty_out(vty, "%pI4%s",
9242 &attr->mp_nexthop_global_in,
9243 vrf_id_str);
9244
9245 len = wide ? (41 - len) : (16 - len);
9246 if (len < 1)
9247 vty_out(vty, "\n%*s", 36, " ");
9248 else
9249 vty_out(vty, "%*s", len, " ");
9250 }
9251 } else if (safi == SAFI_FLOWSPEC) {
9252 if (attr->nexthop.s_addr != INADDR_ANY) {
9253 if (json_paths) {
9254 json_nexthop_global = json_object_new_object();
9255
9256 json_object_string_add(json_nexthop_global,
9257 "afi", "ipv4");
9258 json_object_string_addf(json_nexthop_global,
9259 "ip", "%pI4",
9260 &attr->nexthop);
9261
9262 if (path->peer->hostname)
9263 json_object_string_add(
9264 json_nexthop_global, "hostname",
9265 path->peer->hostname);
9266
9267 json_object_boolean_true_add(
9268 json_nexthop_global,
9269 "used");
9270 } else {
9271 if (nexthop_hostname)
9272 len = vty_out(vty, "%pI4(%s)%s",
9273 &attr->nexthop,
9274 nexthop_hostname,
9275 vrf_id_str);
9276 else
9277 len = vty_out(vty, "%pI4%s",
9278 &attr->nexthop,
9279 vrf_id_str);
9280
9281 len = wide ? (41 - len) : (16 - len);
9282 if (len < 1)
9283 vty_out(vty, "\n%*s", 36, " ");
9284 else
9285 vty_out(vty, "%*s", len, " ");
9286 }
9287 }
9288 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9289 if (json_paths) {
9290 json_nexthop_global = json_object_new_object();
9291
9292 json_object_string_addf(json_nexthop_global, "ip",
9293 "%pI4", &attr->nexthop);
9294
9295 if (path->peer->hostname)
9296 json_object_string_add(json_nexthop_global,
9297 "hostname",
9298 path->peer->hostname);
9299
9300 json_object_string_add(json_nexthop_global, "afi",
9301 "ipv4");
9302 json_object_boolean_true_add(json_nexthop_global,
9303 "used");
9304 } else {
9305 if (nexthop_hostname)
9306 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9307 nexthop_hostname, vrf_id_str);
9308 else
9309 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9310 vrf_id_str);
9311
9312 len = wide ? (41 - len) : (16 - len);
9313 if (len < 1)
9314 vty_out(vty, "\n%*s", 36, " ");
9315 else
9316 vty_out(vty, "%*s", len, " ");
9317 }
9318 }
9319
9320 /* IPv6 Next Hop */
9321 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9322 if (json_paths) {
9323 json_nexthop_global = json_object_new_object();
9324 json_object_string_addf(json_nexthop_global, "ip",
9325 "%pI6",
9326 &attr->mp_nexthop_global);
9327
9328 if (path->peer->hostname)
9329 json_object_string_add(json_nexthop_global,
9330 "hostname",
9331 path->peer->hostname);
9332
9333 json_object_string_add(json_nexthop_global, "afi",
9334 "ipv6");
9335 json_object_string_add(json_nexthop_global, "scope",
9336 "global");
9337
9338 /* We display both LL & GL if both have been
9339 * received */
9340 if ((attr->mp_nexthop_len
9341 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9342 || (path->peer->conf_if)) {
9343 json_nexthop_ll = json_object_new_object();
9344 json_object_string_addf(
9345 json_nexthop_ll, "ip", "%pI6",
9346 &attr->mp_nexthop_local);
9347
9348 if (path->peer->hostname)
9349 json_object_string_add(
9350 json_nexthop_ll, "hostname",
9351 path->peer->hostname);
9352
9353 json_object_string_add(json_nexthop_ll, "afi",
9354 "ipv6");
9355 json_object_string_add(json_nexthop_ll, "scope",
9356 "link-local");
9357
9358 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9359 &attr->mp_nexthop_local)
9360 != 0)
9361 && !attr->mp_nexthop_prefer_global)
9362 json_object_boolean_true_add(
9363 json_nexthop_ll, "used");
9364 else
9365 json_object_boolean_true_add(
9366 json_nexthop_global, "used");
9367 } else
9368 json_object_boolean_true_add(
9369 json_nexthop_global, "used");
9370 } else {
9371 /* Display LL if LL/Global both in table unless
9372 * prefer-global is set */
9373 if (((attr->mp_nexthop_len
9374 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9375 && !attr->mp_nexthop_prefer_global)
9376 || (path->peer->conf_if)) {
9377 if (path->peer->conf_if) {
9378 len = vty_out(vty, "%s",
9379 path->peer->conf_if);
9380 /* len of IPv6 addr + max len of def
9381 * ifname */
9382 len = wide ? (41 - len) : (16 - len);
9383
9384 if (len < 1)
9385 vty_out(vty, "\n%*s", 36, " ");
9386 else
9387 vty_out(vty, "%*s", len, " ");
9388 } else {
9389 if (nexthop_hostname)
9390 len = vty_out(
9391 vty, "%pI6(%s)%s",
9392 &attr->mp_nexthop_local,
9393 nexthop_hostname,
9394 vrf_id_str);
9395 else
9396 len = vty_out(
9397 vty, "%pI6%s",
9398 &attr->mp_nexthop_local,
9399 vrf_id_str);
9400
9401 len = wide ? (41 - len) : (16 - len);
9402
9403 if (len < 1)
9404 vty_out(vty, "\n%*s", 36, " ");
9405 else
9406 vty_out(vty, "%*s", len, " ");
9407 }
9408 } else {
9409 if (nexthop_hostname)
9410 len = vty_out(vty, "%pI6(%s)%s",
9411 &attr->mp_nexthop_global,
9412 nexthop_hostname,
9413 vrf_id_str);
9414 else
9415 len = vty_out(vty, "%pI6%s",
9416 &attr->mp_nexthop_global,
9417 vrf_id_str);
9418
9419 len = wide ? (41 - len) : (16 - len);
9420
9421 if (len < 1)
9422 vty_out(vty, "\n%*s", 36, " ");
9423 else
9424 vty_out(vty, "%*s", len, " ");
9425 }
9426 }
9427 }
9428
9429 /* MED/Metric */
9430 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9431 if (json_paths)
9432 json_object_int_add(json_path, "metric", attr->med);
9433 else if (wide)
9434 vty_out(vty, "%7u", attr->med);
9435 else
9436 vty_out(vty, "%10u", attr->med);
9437 else if (!json_paths) {
9438 if (wide)
9439 vty_out(vty, "%*s", 7, " ");
9440 else
9441 vty_out(vty, "%*s", 10, " ");
9442 }
9443
9444 /* Local Pref */
9445 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9446 if (json_paths)
9447 json_object_int_add(json_path, "locPrf",
9448 attr->local_pref);
9449 else
9450 vty_out(vty, "%7u", attr->local_pref);
9451 else if (!json_paths)
9452 vty_out(vty, " ");
9453
9454 if (json_paths)
9455 json_object_int_add(json_path, "weight", attr->weight);
9456 else
9457 vty_out(vty, "%7u ", attr->weight);
9458
9459 if (json_paths)
9460 json_object_string_addf(json_path, "peerId", "%pSU",
9461 &path->peer->su);
9462
9463 /* Print aspath */
9464 if (attr->aspath) {
9465 if (json_paths)
9466 json_object_string_add(json_path, "path",
9467 attr->aspath->str);
9468 else
9469 aspath_print_vty(vty, "%s", attr->aspath, " ");
9470 }
9471
9472 /* Print origin */
9473 if (json_paths)
9474 json_object_string_add(json_path, "origin",
9475 bgp_origin_long_str[attr->origin]);
9476 else
9477 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9478
9479 if (json_paths) {
9480 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9481 json_object_string_add(json_path, "esi",
9482 esi_to_str(&attr->esi,
9483 esi_buf, sizeof(esi_buf)));
9484 }
9485 if (safi == SAFI_EVPN &&
9486 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9487 json_ext_community = json_object_new_object();
9488 json_object_string_add(
9489 json_ext_community, "string",
9490 bgp_attr_get_ecommunity(attr)->str);
9491 json_object_object_add(json_path,
9492 "extendedCommunity",
9493 json_ext_community);
9494 }
9495
9496 if (nexthop_self)
9497 json_object_boolean_true_add(json_path,
9498 "announceNexthopSelf");
9499 if (nexthop_othervrf) {
9500 json_object_string_add(json_path, "nhVrfName",
9501 nexthop_vrfname);
9502
9503 json_object_int_add(json_path, "nhVrfId",
9504 ((nexthop_vrfid == VRF_UNKNOWN)
9505 ? -1
9506 : (int)nexthop_vrfid));
9507 }
9508 }
9509
9510 if (json_paths) {
9511 if (json_nexthop_global || json_nexthop_ll) {
9512 json_nexthops = json_object_new_array();
9513
9514 if (json_nexthop_global)
9515 json_object_array_add(json_nexthops,
9516 json_nexthop_global);
9517
9518 if (json_nexthop_ll)
9519 json_object_array_add(json_nexthops,
9520 json_nexthop_ll);
9521
9522 json_object_object_add(json_path, "nexthops",
9523 json_nexthops);
9524 }
9525
9526 json_object_array_add(json_paths, json_path);
9527 } else {
9528 vty_out(vty, "\n");
9529
9530 if (safi == SAFI_EVPN) {
9531 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9532 /* XXX - add these params to the json out */
9533 vty_out(vty, "%*s", 20, " ");
9534 vty_out(vty, "ESI:%s",
9535 esi_to_str(&attr->esi, esi_buf,
9536 sizeof(esi_buf)));
9537
9538 vty_out(vty, "\n");
9539 }
9540 if (attr->flag &
9541 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9542 vty_out(vty, "%*s", 20, " ");
9543 vty_out(vty, "%s\n",
9544 bgp_attr_get_ecommunity(attr)->str);
9545 }
9546 }
9547
9548 #ifdef ENABLE_BGP_VNC
9549 /* prints an additional line, indented, with VNC info, if
9550 * present */
9551 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9552 rfapi_vty_out_vncinfo(vty, p, path, safi);
9553 #endif
9554 }
9555 }
9556
9557 /* called from terminal list command */
9558 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9559 const struct prefix *p, struct attr *attr, safi_t safi,
9560 bool use_json, json_object *json_ar, bool wide)
9561 {
9562 json_object *json_status = NULL;
9563 json_object *json_net = NULL;
9564 int len;
9565 char buff[BUFSIZ];
9566
9567 /* Route status display. */
9568 if (use_json) {
9569 json_status = json_object_new_object();
9570 json_net = json_object_new_object();
9571 } else {
9572 vty_out(vty, "*");
9573 vty_out(vty, ">");
9574 vty_out(vty, " ");
9575 }
9576
9577 /* print prefix and mask */
9578 if (use_json) {
9579 if (safi == SAFI_EVPN)
9580 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9581 else if (p->family == AF_INET || p->family == AF_INET6) {
9582 json_object_string_add(
9583 json_net, "addrPrefix",
9584 inet_ntop(p->family, &p->u.prefix, buff,
9585 BUFSIZ));
9586 json_object_int_add(json_net, "prefixLen",
9587 p->prefixlen);
9588 json_object_string_addf(json_net, "network", "%pFX", p);
9589 }
9590 } else
9591 route_vty_out_route(dest, p, vty, NULL, wide);
9592
9593 /* Print attribute */
9594 if (attr) {
9595 if (use_json) {
9596 if (p->family == AF_INET &&
9597 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9598 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9599 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9600 json_object_string_addf(
9601 json_net, "nextHop", "%pI4",
9602 &attr->mp_nexthop_global_in);
9603 else
9604 json_object_string_addf(
9605 json_net, "nextHop", "%pI4",
9606 &attr->nexthop);
9607 } else if (p->family == AF_INET6 ||
9608 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9609 json_object_string_addf(
9610 json_net, "nextHopGlobal", "%pI6",
9611 &attr->mp_nexthop_global);
9612 } else if (p->family == AF_EVPN &&
9613 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9614 json_object_string_addf(
9615 json_net, "nextHop", "%pI4",
9616 &attr->mp_nexthop_global_in);
9617 }
9618
9619 if (attr->flag
9620 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9621 json_object_int_add(json_net, "metric",
9622 attr->med);
9623
9624 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9625 json_object_int_add(json_net, "locPrf",
9626 attr->local_pref);
9627
9628 json_object_int_add(json_net, "weight", attr->weight);
9629
9630 /* Print aspath */
9631 if (attr->aspath)
9632 json_object_string_add(json_net, "path",
9633 attr->aspath->str);
9634
9635 /* Print origin */
9636 json_object_string_add(json_net, "bgpOriginCode",
9637 bgp_origin_str[attr->origin]);
9638 } else {
9639 if (p->family == AF_INET &&
9640 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9641 safi == SAFI_EVPN ||
9642 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9643 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9644 || safi == SAFI_EVPN)
9645 vty_out(vty, "%-16pI4",
9646 &attr->mp_nexthop_global_in);
9647 else if (wide)
9648 vty_out(vty, "%-41pI4", &attr->nexthop);
9649 else
9650 vty_out(vty, "%-16pI4", &attr->nexthop);
9651 } else if (p->family == AF_INET6 ||
9652 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9653 char buf[BUFSIZ];
9654
9655 len = vty_out(
9656 vty, "%s",
9657 inet_ntop(AF_INET6,
9658 &attr->mp_nexthop_global, buf,
9659 BUFSIZ));
9660 len = wide ? (41 - len) : (16 - len);
9661 if (len < 1)
9662 vty_out(vty, "\n%*s", 36, " ");
9663 else
9664 vty_out(vty, "%*s", len, " ");
9665 }
9666 if (attr->flag
9667 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9668 if (wide)
9669 vty_out(vty, "%7u", attr->med);
9670 else
9671 vty_out(vty, "%10u", attr->med);
9672 else if (wide)
9673 vty_out(vty, " ");
9674 else
9675 vty_out(vty, " ");
9676
9677 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9678 vty_out(vty, "%7u", attr->local_pref);
9679 else
9680 vty_out(vty, " ");
9681
9682 vty_out(vty, "%7u ", attr->weight);
9683
9684 /* Print aspath */
9685 if (attr->aspath)
9686 aspath_print_vty(vty, "%s", attr->aspath, " ");
9687
9688 /* Print origin */
9689 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9690 }
9691 }
9692 if (use_json) {
9693 json_object_boolean_true_add(json_status, "*");
9694 json_object_boolean_true_add(json_status, ">");
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, "%s", 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, "%s", 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 struct bgp_path_info *path, afi_t afi, safi_t safi,
10168 enum rpki_states rpki_curr_state,
10169 json_object *json_paths)
10170 {
10171 char buf[INET6_ADDRSTRLEN];
10172 char buf1[BUFSIZ];
10173 struct attr *attr = path->attr;
10174 time_t tbuf;
10175 json_object *json_bestpath = NULL;
10176 json_object *json_cluster_list = NULL;
10177 json_object *json_cluster_list_list = NULL;
10178 json_object *json_ext_community = NULL;
10179 json_object *json_last_update = NULL;
10180 json_object *json_pmsi = NULL;
10181 json_object *json_nexthop_global = NULL;
10182 json_object *json_nexthop_ll = NULL;
10183 json_object *json_nexthops = NULL;
10184 json_object *json_path = NULL;
10185 json_object *json_peer = NULL;
10186 json_object *json_string = NULL;
10187 json_object *json_adv_to = NULL;
10188 int first = 0;
10189 struct listnode *node, *nnode;
10190 struct peer *peer;
10191 bool addpath_capable;
10192 int has_adj;
10193 unsigned int first_as;
10194 bool nexthop_self =
10195 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10196 int i;
10197 char *nexthop_hostname =
10198 bgp_nexthop_hostname(path->peer, path->nexthop);
10199 uint32_t ttl = 0;
10200 uint32_t bos = 0;
10201 uint32_t exp = 0;
10202 mpls_label_t label = MPLS_INVALID_LABEL;
10203
10204 if (json_paths) {
10205 json_path = json_object_new_object();
10206 json_peer = json_object_new_object();
10207 json_nexthop_global = json_object_new_object();
10208 }
10209
10210 if (safi == SAFI_EVPN) {
10211 if (!json_paths)
10212 vty_out(vty, " Route %pRN", bn);
10213 }
10214
10215 if (path->extra) {
10216 char tag_buf[30];
10217
10218 tag_buf[0] = '\0';
10219 if (path->extra && path->extra->num_labels) {
10220 bgp_evpn_label2str(path->extra->label,
10221 path->extra->num_labels, tag_buf,
10222 sizeof(tag_buf));
10223 }
10224 if (safi == SAFI_EVPN) {
10225 if (!json_paths) {
10226 if (tag_buf[0] != '\0')
10227 vty_out(vty, " VNI %s", tag_buf);
10228 } else {
10229 if (tag_buf[0]) {
10230 json_object_string_add(json_path, "VNI",
10231 tag_buf);
10232 json_object_string_add(json_path, "vni",
10233 tag_buf);
10234 }
10235 }
10236 }
10237
10238 if (path->extra && path->extra->parent && !json_paths) {
10239 struct bgp_path_info *parent_ri;
10240 struct bgp_dest *dest, *pdest;
10241
10242 parent_ri = (struct bgp_path_info *)path->extra->parent;
10243 dest = parent_ri->net;
10244 if (dest && dest->pdest) {
10245 pdest = dest->pdest;
10246 if (is_pi_family_evpn(parent_ri)) {
10247 vty_out(vty,
10248 " Imported from %pRD:%pFX, VNI %s",
10249 (struct prefix_rd *)
10250 bgp_dest_get_prefix(
10251 pdest),
10252 (struct prefix_evpn *)
10253 bgp_dest_get_prefix(
10254 dest),
10255 tag_buf);
10256 if (attr->es_flags & ATTR_ES_L3_NHG)
10257 vty_out(vty, ", L3NHG %s",
10258 (attr->es_flags
10259 & ATTR_ES_L3_NHG_ACTIVE)
10260 ? "active"
10261 : "inactive");
10262 vty_out(vty, "\n");
10263
10264 } else
10265 vty_out(vty,
10266 " Imported from %pRD:%pFX\n",
10267 (struct prefix_rd *)
10268 bgp_dest_get_prefix(
10269 pdest),
10270 (struct prefix_evpn *)
10271 bgp_dest_get_prefix(
10272 dest));
10273 }
10274 }
10275 }
10276
10277 if (safi == SAFI_EVPN
10278 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10279 char gwip_buf[INET6_ADDRSTRLEN];
10280
10281 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10282 sizeof(gwip_buf));
10283
10284 if (json_paths)
10285 json_object_string_add(json_path, "gatewayIP",
10286 gwip_buf);
10287 else
10288 vty_out(vty, " Gateway IP %s", gwip_buf);
10289 }
10290
10291 if (safi == SAFI_EVPN && !json_path)
10292 vty_out(vty, "\n");
10293
10294 /* Line1 display AS-path, Aggregator */
10295 if (attr->aspath) {
10296 if (json_paths) {
10297 if (!attr->aspath->json)
10298 aspath_str_update(attr->aspath, true);
10299 json_object_lock(attr->aspath->json);
10300 json_object_object_add(json_path, "aspath",
10301 attr->aspath->json);
10302 } else {
10303 if (attr->aspath->segments)
10304 aspath_print_vty(vty, " %s", attr->aspath, "");
10305 else
10306 vty_out(vty, " Local");
10307 }
10308 }
10309
10310 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10311 if (json_paths)
10312 json_object_boolean_true_add(json_path, "removed");
10313 else
10314 vty_out(vty, ", (removed)");
10315 }
10316
10317 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10318 if (json_paths)
10319 json_object_boolean_true_add(json_path, "stale");
10320 else
10321 vty_out(vty, ", (stale)");
10322 }
10323
10324 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10325 if (json_paths) {
10326 json_object_int_add(json_path, "aggregatorAs",
10327 attr->aggregator_as);
10328 json_object_string_addf(json_path, "aggregatorId",
10329 "%pI4", &attr->aggregator_addr);
10330 } else {
10331 vty_out(vty, ", (aggregated by %u %pI4)",
10332 attr->aggregator_as, &attr->aggregator_addr);
10333 }
10334 }
10335
10336 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10337 PEER_FLAG_REFLECTOR_CLIENT)) {
10338 if (json_paths)
10339 json_object_boolean_true_add(json_path,
10340 "rxedFromRrClient");
10341 else
10342 vty_out(vty, ", (Received from a RR-client)");
10343 }
10344
10345 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10346 PEER_FLAG_RSERVER_CLIENT)) {
10347 if (json_paths)
10348 json_object_boolean_true_add(json_path,
10349 "rxedFromRsClient");
10350 else
10351 vty_out(vty, ", (Received from a RS-client)");
10352 }
10353
10354 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10355 if (json_paths)
10356 json_object_boolean_true_add(json_path,
10357 "dampeningHistoryEntry");
10358 else
10359 vty_out(vty, ", (history entry)");
10360 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10361 if (json_paths)
10362 json_object_boolean_true_add(json_path,
10363 "dampeningSuppressed");
10364 else
10365 vty_out(vty, ", (suppressed due to dampening)");
10366 }
10367
10368 if (!json_paths)
10369 vty_out(vty, "\n");
10370
10371 /* Line2 display Next-hop, Neighbor, Router-id */
10372 /* Display the nexthop */
10373 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
10374
10375 if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET ||
10376 bn_p->family == AF_EVPN) &&
10377 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10378 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10379 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10380 || safi == SAFI_EVPN) {
10381 if (json_paths) {
10382 json_object_string_addf(
10383 json_nexthop_global, "ip", "%pI4",
10384 &attr->mp_nexthop_global_in);
10385
10386 if (path->peer->hostname)
10387 json_object_string_add(
10388 json_nexthop_global, "hostname",
10389 path->peer->hostname);
10390 } else {
10391 if (nexthop_hostname)
10392 vty_out(vty, " %pI4(%s)",
10393 &attr->mp_nexthop_global_in,
10394 nexthop_hostname);
10395 else
10396 vty_out(vty, " %pI4",
10397 &attr->mp_nexthop_global_in);
10398 }
10399 } else {
10400 if (json_paths) {
10401 json_object_string_addf(json_nexthop_global,
10402 "ip", "%pI4",
10403 &attr->nexthop);
10404
10405 if (path->peer->hostname)
10406 json_object_string_add(
10407 json_nexthop_global, "hostname",
10408 path->peer->hostname);
10409 } else {
10410 if (nexthop_hostname)
10411 vty_out(vty, " %pI4(%s)",
10412 &attr->nexthop,
10413 nexthop_hostname);
10414 else
10415 vty_out(vty, " %pI4",
10416 &attr->nexthop);
10417 }
10418 }
10419
10420 if (json_paths)
10421 json_object_string_add(json_nexthop_global, "afi",
10422 "ipv4");
10423 } else {
10424 if (json_paths) {
10425 json_object_string_addf(json_nexthop_global, "ip",
10426 "%pI6",
10427 &attr->mp_nexthop_global);
10428
10429 if (path->peer->hostname)
10430 json_object_string_add(json_nexthop_global,
10431 "hostname",
10432 path->peer->hostname);
10433
10434 json_object_string_add(json_nexthop_global, "afi",
10435 "ipv6");
10436 json_object_string_add(json_nexthop_global, "scope",
10437 "global");
10438 } else {
10439 if (nexthop_hostname)
10440 vty_out(vty, " %pI6(%s)",
10441 &attr->mp_nexthop_global,
10442 nexthop_hostname);
10443 else
10444 vty_out(vty, " %pI6",
10445 &attr->mp_nexthop_global);
10446 }
10447 }
10448
10449 /* Display the IGP cost or 'inaccessible' */
10450 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10451 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10452
10453 if (json_paths) {
10454 json_object_boolean_false_add(json_nexthop_global,
10455 "accessible");
10456 json_object_boolean_add(json_nexthop_global,
10457 "importCheckEnabled", import);
10458 } else {
10459 vty_out(vty, " (inaccessible%s)",
10460 import ? ", import-check enabled" : "");
10461 }
10462 } else {
10463 if (path->extra && path->extra->igpmetric) {
10464 if (json_paths)
10465 json_object_int_add(json_nexthop_global,
10466 "metric",
10467 path->extra->igpmetric);
10468 else
10469 vty_out(vty, " (metric %u)",
10470 path->extra->igpmetric);
10471 }
10472
10473 /* IGP cost is 0, display this only for json */
10474 else {
10475 if (json_paths)
10476 json_object_int_add(json_nexthop_global,
10477 "metric", 0);
10478 }
10479
10480 if (json_paths)
10481 json_object_boolean_true_add(json_nexthop_global,
10482 "accessible");
10483 }
10484
10485 /* Display peer "from" output */
10486 /* This path was originated locally */
10487 if (path->peer == bgp->peer_self) {
10488
10489 if (safi == SAFI_EVPN || (bn_p->family == AF_INET &&
10490 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10491 if (json_paths)
10492 json_object_string_add(json_peer, "peerId",
10493 "0.0.0.0");
10494 else
10495 vty_out(vty, " from 0.0.0.0 ");
10496 } else {
10497 if (json_paths)
10498 json_object_string_add(json_peer, "peerId",
10499 "::");
10500 else
10501 vty_out(vty, " from :: ");
10502 }
10503
10504 if (json_paths)
10505 json_object_string_addf(json_peer, "routerId", "%pI4",
10506 &bgp->router_id);
10507 else
10508 vty_out(vty, "(%pI4)", &bgp->router_id);
10509 }
10510
10511 /* We RXed this path from one of our peers */
10512 else {
10513
10514 if (json_paths) {
10515 json_object_string_addf(json_peer, "peerId", "%pSU",
10516 &path->peer->su);
10517 json_object_string_addf(json_peer, "routerId", "%pI4",
10518 &path->peer->remote_id);
10519
10520 if (path->peer->hostname)
10521 json_object_string_add(json_peer, "hostname",
10522 path->peer->hostname);
10523
10524 if (path->peer->domainname)
10525 json_object_string_add(json_peer, "domainname",
10526 path->peer->domainname);
10527
10528 if (path->peer->conf_if)
10529 json_object_string_add(json_peer, "interface",
10530 path->peer->conf_if);
10531 } else {
10532 if (path->peer->conf_if) {
10533 if (path->peer->hostname
10534 && CHECK_FLAG(path->peer->bgp->flags,
10535 BGP_FLAG_SHOW_HOSTNAME))
10536 vty_out(vty, " from %s(%s)",
10537 path->peer->hostname,
10538 path->peer->conf_if);
10539 else
10540 vty_out(vty, " from %s",
10541 path->peer->conf_if);
10542 } else {
10543 if (path->peer->hostname
10544 && CHECK_FLAG(path->peer->bgp->flags,
10545 BGP_FLAG_SHOW_HOSTNAME))
10546 vty_out(vty, " from %s(%s)",
10547 path->peer->hostname,
10548 path->peer->host);
10549 else
10550 vty_out(vty, " from %pSU",
10551 &path->peer->su);
10552 }
10553
10554 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10555 vty_out(vty, " (%pI4)", &attr->originator_id);
10556 else
10557 vty_out(vty, " (%s)",
10558 inet_ntop(AF_INET,
10559 &path->peer->remote_id, buf1,
10560 sizeof(buf1)));
10561 }
10562 }
10563
10564 /*
10565 * Note when vrfid of nexthop is different from that of prefix
10566 */
10567 if (path->extra && path->extra->bgp_orig) {
10568 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10569
10570 if (json_paths) {
10571 const char *vn;
10572
10573 if (path->extra->bgp_orig->inst_type
10574 == BGP_INSTANCE_TYPE_DEFAULT)
10575 vn = VRF_DEFAULT_NAME;
10576 else
10577 vn = path->extra->bgp_orig->name;
10578
10579 json_object_string_add(json_path, "nhVrfName", vn);
10580
10581 if (nexthop_vrfid == VRF_UNKNOWN) {
10582 json_object_int_add(json_path, "nhVrfId", -1);
10583 } else {
10584 json_object_int_add(json_path, "nhVrfId",
10585 (int)nexthop_vrfid);
10586 }
10587 } else {
10588 if (nexthop_vrfid == VRF_UNKNOWN)
10589 vty_out(vty, " vrf ?");
10590 else {
10591 struct vrf *vrf;
10592
10593 vrf = vrf_lookup_by_id(nexthop_vrfid);
10594 vty_out(vty, " vrf %s(%u)",
10595 VRF_LOGNAME(vrf), nexthop_vrfid);
10596 }
10597 }
10598 }
10599
10600 if (nexthop_self) {
10601 if (json_paths) {
10602 json_object_boolean_true_add(json_path,
10603 "announceNexthopSelf");
10604 } else {
10605 vty_out(vty, " announce-nh-self");
10606 }
10607 }
10608
10609 if (!json_paths)
10610 vty_out(vty, "\n");
10611
10612 /* display the link-local nexthop */
10613 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10614 if (json_paths) {
10615 json_nexthop_ll = json_object_new_object();
10616 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10617 &attr->mp_nexthop_local);
10618
10619 if (path->peer->hostname)
10620 json_object_string_add(json_nexthop_ll,
10621 "hostname",
10622 path->peer->hostname);
10623
10624 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10625 json_object_string_add(json_nexthop_ll, "scope",
10626 "link-local");
10627
10628 json_object_boolean_true_add(json_nexthop_ll,
10629 "accessible");
10630
10631 if (!attr->mp_nexthop_prefer_global)
10632 json_object_boolean_true_add(json_nexthop_ll,
10633 "used");
10634 else
10635 json_object_boolean_true_add(
10636 json_nexthop_global, "used");
10637 } else {
10638 vty_out(vty, " (%s) %s\n",
10639 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10640 buf, INET6_ADDRSTRLEN),
10641 attr->mp_nexthop_prefer_global
10642 ? "(prefer-global)"
10643 : "(used)");
10644 }
10645 }
10646 /* If we do not have a link-local nexthop then we must flag the
10647 global as "used" */
10648 else {
10649 if (json_paths)
10650 json_object_boolean_true_add(json_nexthop_global,
10651 "used");
10652 }
10653
10654 if (safi == SAFI_EVPN &&
10655 bgp_evpn_is_esi_valid(&attr->esi)) {
10656 route_vty_out_detail_es_info(vty, path, attr, json_path);
10657 }
10658
10659 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10660 * Int/Ext/Local, Atomic, best */
10661 if (json_paths)
10662 json_object_string_add(json_path, "origin",
10663 bgp_origin_long_str[attr->origin]);
10664 else
10665 vty_out(vty, " Origin %s",
10666 bgp_origin_long_str[attr->origin]);
10667
10668 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10669 if (json_paths)
10670 json_object_int_add(json_path, "metric", attr->med);
10671 else
10672 vty_out(vty, ", metric %u", attr->med);
10673 }
10674
10675 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10676 if (json_paths)
10677 json_object_int_add(json_path, "locPrf",
10678 attr->local_pref);
10679 else
10680 vty_out(vty, ", localpref %u", attr->local_pref);
10681 }
10682
10683 if (attr->weight != 0) {
10684 if (json_paths)
10685 json_object_int_add(json_path, "weight", attr->weight);
10686 else
10687 vty_out(vty, ", weight %u", attr->weight);
10688 }
10689
10690 if (attr->tag != 0) {
10691 if (json_paths)
10692 json_object_int_add(json_path, "tag", attr->tag);
10693 else
10694 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10695 }
10696
10697 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10698 if (json_paths)
10699 json_object_boolean_false_add(json_path, "valid");
10700 else
10701 vty_out(vty, ", invalid");
10702 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10703 if (json_paths)
10704 json_object_boolean_true_add(json_path, "valid");
10705 else
10706 vty_out(vty, ", valid");
10707 }
10708
10709 if (json_paths)
10710 json_object_int_add(json_path, "version", bn->version);
10711
10712 if (path->peer != bgp->peer_self) {
10713 if (path->peer->as == path->peer->local_as) {
10714 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10715 if (json_paths)
10716 json_object_string_add(
10717 json_peer, "type",
10718 "confed-internal");
10719 else
10720 vty_out(vty, ", confed-internal");
10721 } else {
10722 if (json_paths)
10723 json_object_string_add(
10724 json_peer, "type", "internal");
10725 else
10726 vty_out(vty, ", internal");
10727 }
10728 } else {
10729 if (bgp_confederation_peers_check(bgp,
10730 path->peer->as)) {
10731 if (json_paths)
10732 json_object_string_add(
10733 json_peer, "type",
10734 "confed-external");
10735 else
10736 vty_out(vty, ", confed-external");
10737 } else {
10738 if (json_paths)
10739 json_object_string_add(
10740 json_peer, "type", "external");
10741 else
10742 vty_out(vty, ", external");
10743 }
10744 }
10745 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10746 if (json_paths) {
10747 json_object_boolean_true_add(json_path, "aggregated");
10748 json_object_boolean_true_add(json_path, "local");
10749 } else {
10750 vty_out(vty, ", aggregated, local");
10751 }
10752 } else if (path->type != ZEBRA_ROUTE_BGP) {
10753 if (json_paths)
10754 json_object_boolean_true_add(json_path, "sourced");
10755 else
10756 vty_out(vty, ", sourced");
10757 } else {
10758 if (json_paths) {
10759 json_object_boolean_true_add(json_path, "sourced");
10760 json_object_boolean_true_add(json_path, "local");
10761 } else {
10762 vty_out(vty, ", sourced, local");
10763 }
10764 }
10765
10766 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10767 if (json_paths)
10768 json_object_boolean_true_add(json_path,
10769 "atomicAggregate");
10770 else
10771 vty_out(vty, ", atomic-aggregate");
10772 }
10773
10774 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10775 if (json_paths)
10776 json_object_int_add(json_path, "otc", attr->otc);
10777 else
10778 vty_out(vty, ", otc %u", attr->otc);
10779 }
10780
10781 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10782 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10783 && bgp_path_info_mpath_count(path))) {
10784 if (json_paths)
10785 json_object_boolean_true_add(json_path, "multipath");
10786 else
10787 vty_out(vty, ", multipath");
10788 }
10789
10790 // Mark the bestpath(s)
10791 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10792 first_as = aspath_get_first_as(attr->aspath);
10793
10794 if (json_paths) {
10795 if (!json_bestpath)
10796 json_bestpath = json_object_new_object();
10797 json_object_int_add(json_bestpath, "bestpathFromAs",
10798 first_as);
10799 } else {
10800 if (first_as)
10801 vty_out(vty, ", bestpath-from-AS %u", first_as);
10802 else
10803 vty_out(vty, ", bestpath-from-AS Local");
10804 }
10805 }
10806
10807 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10808 if (json_paths) {
10809 if (!json_bestpath)
10810 json_bestpath = json_object_new_object();
10811 json_object_boolean_true_add(json_bestpath, "overall");
10812 json_object_string_add(
10813 json_bestpath, "selectionReason",
10814 bgp_path_selection_reason2str(bn->reason));
10815 } else {
10816 vty_out(vty, ", best");
10817 vty_out(vty, " (%s)",
10818 bgp_path_selection_reason2str(bn->reason));
10819 }
10820 }
10821
10822 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10823 if (json_paths)
10824 json_object_string_add(
10825 json_path, "rpkiValidationState",
10826 bgp_rpki_validation2str(rpki_curr_state));
10827 else
10828 vty_out(vty, ", rpki validation-state: %s",
10829 bgp_rpki_validation2str(rpki_curr_state));
10830 }
10831
10832 if (json_bestpath)
10833 json_object_object_add(json_path, "bestpath", json_bestpath);
10834
10835 if (!json_paths)
10836 vty_out(vty, "\n");
10837
10838 /* Line 4 display Community */
10839 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10840 if (json_paths) {
10841 if (!bgp_attr_get_community(attr)->json)
10842 community_str(bgp_attr_get_community(attr),
10843 true, true);
10844 json_object_lock(bgp_attr_get_community(attr)->json);
10845 json_object_object_add(
10846 json_path, "community",
10847 bgp_attr_get_community(attr)->json);
10848 } else {
10849 vty_out(vty, " Community: %s\n",
10850 bgp_attr_get_community(attr)->str);
10851 }
10852 }
10853
10854 /* Line 5 display Extended-community */
10855 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10856 if (json_paths) {
10857 json_ext_community = json_object_new_object();
10858 json_object_string_add(
10859 json_ext_community, "string",
10860 bgp_attr_get_ecommunity(attr)->str);
10861 json_object_object_add(json_path, "extendedCommunity",
10862 json_ext_community);
10863 } else {
10864 vty_out(vty, " Extended Community: %s\n",
10865 bgp_attr_get_ecommunity(attr)->str);
10866 }
10867 }
10868
10869 /* Line 6 display Large community */
10870 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10871 if (json_paths) {
10872 if (!bgp_attr_get_lcommunity(attr)->json)
10873 lcommunity_str(bgp_attr_get_lcommunity(attr),
10874 true, true);
10875 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10876 json_object_object_add(
10877 json_path, "largeCommunity",
10878 bgp_attr_get_lcommunity(attr)->json);
10879 } else {
10880 vty_out(vty, " Large Community: %s\n",
10881 bgp_attr_get_lcommunity(attr)->str);
10882 }
10883 }
10884
10885 /* Line 7 display Originator, Cluster-id */
10886 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10887 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10888 char buf[BUFSIZ] = {0};
10889
10890 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10891 if (json_paths)
10892 json_object_string_addf(json_path,
10893 "originatorId", "%pI4",
10894 &attr->originator_id);
10895 else
10896 vty_out(vty, " Originator: %pI4",
10897 &attr->originator_id);
10898 }
10899
10900 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10901 struct cluster_list *cluster =
10902 bgp_attr_get_cluster(attr);
10903 int i;
10904
10905 if (json_paths) {
10906 json_cluster_list = json_object_new_object();
10907 json_cluster_list_list =
10908 json_object_new_array();
10909
10910 for (i = 0; i < cluster->length / 4; i++) {
10911 json_string = json_object_new_string(
10912 inet_ntop(AF_INET,
10913 &cluster->list[i],
10914 buf, sizeof(buf)));
10915 json_object_array_add(
10916 json_cluster_list_list,
10917 json_string);
10918 }
10919
10920 /*
10921 * struct cluster_list does not have
10922 * "str" variable like aspath and community
10923 * do. Add this someday if someone asks
10924 * for it.
10925 * json_object_string_add(json_cluster_list,
10926 * "string", cluster->str);
10927 */
10928 json_object_object_add(json_cluster_list,
10929 "list",
10930 json_cluster_list_list);
10931 json_object_object_add(json_path, "clusterList",
10932 json_cluster_list);
10933 } else {
10934 vty_out(vty, ", Cluster list: ");
10935
10936 for (i = 0; i < cluster->length / 4; i++) {
10937 vty_out(vty, "%pI4 ",
10938 &cluster->list[i]);
10939 }
10940 }
10941 }
10942
10943 if (!json_paths)
10944 vty_out(vty, "\n");
10945 }
10946
10947 if (path->extra && path->extra->damp_info)
10948 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10949
10950 /* Remote Label */
10951 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10952 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10953 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
10954 &bos);
10955
10956 if (json_paths)
10957 json_object_int_add(json_path, "remoteLabel", label);
10958 else
10959 vty_out(vty, " Remote label: %d\n", label);
10960 }
10961
10962 /* Remote SID */
10963 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10964 inet_ntop(AF_INET6, &path->extra->sid[0].sid, buf, sizeof(buf));
10965 if (json_paths)
10966 json_object_string_add(json_path, "remoteSid", buf);
10967 else
10968 vty_out(vty, " Remote SID: %s\n", buf);
10969 }
10970
10971 /* Label Index */
10972 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10973 if (json_paths)
10974 json_object_int_add(json_path, "labelIndex",
10975 attr->label_index);
10976 else
10977 vty_out(vty, " Label Index: %d\n",
10978 attr->label_index);
10979 }
10980
10981 /* Line 8 display Addpath IDs */
10982 if (path->addpath_rx_id
10983 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
10984 if (json_paths) {
10985 json_object_int_add(json_path, "addpathRxId",
10986 path->addpath_rx_id);
10987
10988 /* Keep backwards compatibility with the old API
10989 * by putting TX All's ID in the old field
10990 */
10991 json_object_int_add(
10992 json_path, "addpathTxId",
10993 path->tx_addpath
10994 .addpath_tx_id[BGP_ADDPATH_ALL]);
10995
10996 /* ... but create a specific field for each
10997 * strategy
10998 */
10999 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
11000 json_object_int_add(
11001 json_path,
11002 bgp_addpath_names(i)->id_json_name,
11003 path->tx_addpath.addpath_tx_id[i]);
11004 }
11005 } else {
11006 vty_out(vty, " AddPath ID: RX %u, ",
11007 path->addpath_rx_id);
11008
11009 route_vty_out_tx_ids(vty, &path->tx_addpath);
11010 }
11011 }
11012
11013 /* If we used addpath to TX a non-bestpath we need to display
11014 * "Advertised to" on a path-by-path basis
11015 */
11016 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11017 first = 1;
11018
11019 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11020 addpath_capable =
11021 bgp_addpath_encode_tx(peer, afi, safi);
11022 has_adj = bgp_adj_out_lookup(
11023 peer, path->net,
11024 bgp_addpath_id_for_peer(peer, afi, safi,
11025 &path->tx_addpath));
11026
11027 if ((addpath_capable && has_adj)
11028 || (!addpath_capable && has_adj
11029 && CHECK_FLAG(path->flags,
11030 BGP_PATH_SELECTED))) {
11031 if (json_path && !json_adv_to)
11032 json_adv_to = json_object_new_object();
11033
11034 route_vty_out_advertised_to(
11035 vty, peer, &first,
11036 " Advertised to:", json_adv_to);
11037 }
11038 }
11039
11040 if (json_path) {
11041 if (json_adv_to) {
11042 json_object_object_add(
11043 json_path, "advertisedTo", json_adv_to);
11044 }
11045 } else {
11046 if (!first) {
11047 vty_out(vty, "\n");
11048 }
11049 }
11050 }
11051
11052 /* Line 9 display Uptime */
11053 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11054 if (json_paths) {
11055 json_last_update = json_object_new_object();
11056 json_object_int_add(json_last_update, "epoch", tbuf);
11057 json_object_string_add(json_last_update, "string",
11058 ctime(&tbuf));
11059 json_object_object_add(json_path, "lastUpdate",
11060 json_last_update);
11061 } else
11062 vty_out(vty, " Last update: %s", ctime(&tbuf));
11063
11064 /* Line 10 display PMSI tunnel attribute, if present */
11065 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11066 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11067 bgp_attr_get_pmsi_tnl_type(attr),
11068 PMSI_TNLTYPE_STR_DEFAULT);
11069
11070 if (json_paths) {
11071 json_pmsi = json_object_new_object();
11072 json_object_string_add(json_pmsi, "tunnelType", str);
11073 json_object_int_add(json_pmsi, "label",
11074 label2vni(&attr->label));
11075 json_object_object_add(json_path, "pmsi", json_pmsi);
11076 } else
11077 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11078 str, label2vni(&attr->label));
11079 }
11080
11081 if (path->peer->t_gr_restart &&
11082 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11083 unsigned long gr_remaining =
11084 thread_timer_remain_second(path->peer->t_gr_restart);
11085
11086 if (json_paths) {
11087 json_object_int_add(json_path,
11088 "gracefulRestartSecondsRemaining",
11089 gr_remaining);
11090 } else
11091 vty_out(vty,
11092 " Time until Graceful Restart stale route deleted: %lu\n",
11093 gr_remaining);
11094 }
11095
11096 if (path->peer->t_llgr_stale[afi][safi] &&
11097 bgp_attr_get_community(attr) &&
11098 community_include(bgp_attr_get_community(attr),
11099 COMMUNITY_LLGR_STALE)) {
11100 unsigned long llgr_remaining = thread_timer_remain_second(
11101 path->peer->t_llgr_stale[afi][safi]);
11102
11103 if (json_paths) {
11104 json_object_int_add(json_path, "llgrSecondsRemaining",
11105 llgr_remaining);
11106 } else
11107 vty_out(vty,
11108 " Time until Long-lived stale route deleted: %lu\n",
11109 llgr_remaining);
11110 }
11111
11112 /* Output some debug about internal state of the dest flags */
11113 if (json_paths) {
11114 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11115 json_object_boolean_true_add(json_path, "processScheduled");
11116 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11117 json_object_boolean_true_add(json_path, "userCleared");
11118 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11119 json_object_boolean_true_add(json_path, "labelChanged");
11120 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11121 json_object_boolean_true_add(json_path, "registeredForLabel");
11122 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11123 json_object_boolean_true_add(json_path, "selectDefered");
11124 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11125 json_object_boolean_true_add(json_path, "fibInstalled");
11126 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11127 json_object_boolean_true_add(json_path, "fibPending");
11128
11129 if (json_nexthop_global || json_nexthop_ll) {
11130 json_nexthops = json_object_new_array();
11131
11132 if (json_nexthop_global)
11133 json_object_array_add(json_nexthops,
11134 json_nexthop_global);
11135
11136 if (json_nexthop_ll)
11137 json_object_array_add(json_nexthops,
11138 json_nexthop_ll);
11139
11140 json_object_object_add(json_path, "nexthops",
11141 json_nexthops);
11142 }
11143
11144 json_object_object_add(json_path, "peer", json_peer);
11145 json_object_array_add(json_paths, json_path);
11146 }
11147 }
11148
11149 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11150 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11151 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11152
11153 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11154 afi_t afi, safi_t safi, enum bgp_show_type type,
11155 bool use_json);
11156 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11157 const char *comstr, int exact, afi_t afi,
11158 safi_t safi, uint16_t show_flags);
11159
11160 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11161 struct bgp_table *table, enum bgp_show_type type,
11162 void *output_arg, const char *rd, int is_last,
11163 unsigned long *output_cum, unsigned long *total_cum,
11164 unsigned long *json_header_depth, uint16_t show_flags,
11165 enum rpki_states rpki_target_state)
11166 {
11167 struct bgp_path_info *pi;
11168 struct bgp_dest *dest;
11169 bool header = true;
11170 bool json_detail_header = false;
11171 int display;
11172 unsigned long output_count = 0;
11173 unsigned long total_count = 0;
11174 struct prefix *p;
11175 json_object *json_paths = NULL;
11176 int first = 1;
11177 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11178 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11179 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11180
11181 if (output_cum && *output_cum != 0)
11182 header = false;
11183
11184 if (use_json && !*json_header_depth) {
11185 if (all)
11186 *json_header_depth = 1;
11187 else {
11188 vty_out(vty, "{\n");
11189 *json_header_depth = 2;
11190 }
11191
11192 vty_out(vty,
11193 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11194 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11195 " \"localAS\": %u,\n \"routes\": { ",
11196 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11197 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11198 ? VRF_DEFAULT_NAME
11199 : bgp->name,
11200 table->version, &bgp->router_id,
11201 bgp->default_local_pref, bgp->as);
11202 if (rd) {
11203 vty_out(vty, " \"routeDistinguishers\" : {");
11204 ++*json_header_depth;
11205 }
11206 }
11207
11208 if (use_json && rd) {
11209 vty_out(vty, " \"%s\" : { ", rd);
11210 }
11211
11212 /* Check for 'json detail', where we need header output once per dest */
11213 if (use_json && CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL) &&
11214 type != bgp_show_type_dampend_paths &&
11215 type != bgp_show_type_damp_neighbor &&
11216 type != bgp_show_type_flap_statistics &&
11217 type != bgp_show_type_flap_neighbor)
11218 json_detail_header = true;
11219
11220 /* Start processing of routes. */
11221 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11222 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11223 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11224 bool json_detail = json_detail_header;
11225
11226 pi = bgp_dest_get_bgp_path_info(dest);
11227 if (pi == NULL)
11228 continue;
11229
11230 display = 0;
11231 if (use_json)
11232 json_paths = json_object_new_array();
11233 else
11234 json_paths = NULL;
11235
11236 for (; pi; pi = pi->next) {
11237 struct community *picomm = NULL;
11238
11239 picomm = bgp_attr_get_community(pi->attr);
11240
11241 total_count++;
11242
11243 if (type == bgp_show_type_prefix_version) {
11244 uint32_t version =
11245 strtoul(output_arg, NULL, 10);
11246 if (dest->version < version)
11247 continue;
11248 }
11249
11250 if (type == bgp_show_type_community_alias) {
11251 char *alias = output_arg;
11252 char **communities;
11253 int num;
11254 bool found = false;
11255
11256 if (picomm) {
11257 frrstr_split(picomm->str, " ",
11258 &communities, &num);
11259 for (int i = 0; i < num; i++) {
11260 const char *com2alias =
11261 bgp_community2alias(
11262 communities[i]);
11263 if (!found
11264 && strcmp(alias, com2alias)
11265 == 0)
11266 found = true;
11267 XFREE(MTYPE_TMP,
11268 communities[i]);
11269 }
11270 XFREE(MTYPE_TMP, communities);
11271 }
11272
11273 if (!found &&
11274 bgp_attr_get_lcommunity(pi->attr)) {
11275 frrstr_split(bgp_attr_get_lcommunity(
11276 pi->attr)
11277 ->str,
11278 " ", &communities, &num);
11279 for (int i = 0; i < num; i++) {
11280 const char *com2alias =
11281 bgp_community2alias(
11282 communities[i]);
11283 if (!found
11284 && strcmp(alias, com2alias)
11285 == 0)
11286 found = true;
11287 XFREE(MTYPE_TMP,
11288 communities[i]);
11289 }
11290 XFREE(MTYPE_TMP, communities);
11291 }
11292
11293 if (!found)
11294 continue;
11295 }
11296
11297 if (type == bgp_show_type_rpki) {
11298 if (dest_p->family == AF_INET
11299 || dest_p->family == AF_INET6)
11300 rpki_curr_state = hook_call(
11301 bgp_rpki_prefix_status,
11302 pi->peer, pi->attr, dest_p);
11303 if (rpki_target_state != RPKI_NOT_BEING_USED
11304 && rpki_curr_state != rpki_target_state)
11305 continue;
11306 }
11307
11308 if (type == bgp_show_type_flap_statistics
11309 || type == bgp_show_type_flap_neighbor
11310 || type == bgp_show_type_dampend_paths
11311 || type == bgp_show_type_damp_neighbor) {
11312 if (!(pi->extra && pi->extra->damp_info))
11313 continue;
11314 }
11315 if (type == bgp_show_type_regexp) {
11316 regex_t *regex = output_arg;
11317
11318 if (bgp_regexec(regex, pi->attr->aspath)
11319 == REG_NOMATCH)
11320 continue;
11321 }
11322 if (type == bgp_show_type_prefix_list) {
11323 struct prefix_list *plist = output_arg;
11324
11325 if (prefix_list_apply(plist, dest_p)
11326 != PREFIX_PERMIT)
11327 continue;
11328 }
11329 if (type == bgp_show_type_access_list) {
11330 struct access_list *alist = output_arg;
11331
11332 if (access_list_apply(alist, dest_p) !=
11333 FILTER_PERMIT)
11334 continue;
11335 }
11336 if (type == bgp_show_type_filter_list) {
11337 struct as_list *as_list = output_arg;
11338
11339 if (as_list_apply(as_list, pi->attr->aspath)
11340 != AS_FILTER_PERMIT)
11341 continue;
11342 }
11343 if (type == bgp_show_type_route_map) {
11344 struct route_map *rmap = output_arg;
11345 struct bgp_path_info path;
11346 struct bgp_path_info_extra extra;
11347 struct attr dummy_attr = {};
11348 route_map_result_t ret;
11349
11350 dummy_attr = *pi->attr;
11351
11352 prep_for_rmap_apply(&path, &extra, dest, pi,
11353 pi->peer, &dummy_attr);
11354
11355 ret = route_map_apply(rmap, dest_p, &path);
11356 bgp_attr_flush(&dummy_attr);
11357 if (ret == RMAP_DENYMATCH)
11358 continue;
11359 }
11360 if (type == bgp_show_type_neighbor
11361 || type == bgp_show_type_flap_neighbor
11362 || type == bgp_show_type_damp_neighbor) {
11363 union sockunion *su = output_arg;
11364
11365 if (pi->peer == NULL
11366 || pi->peer->su_remote == NULL
11367 || !sockunion_same(pi->peer->su_remote, su))
11368 continue;
11369 }
11370 if (type == bgp_show_type_cidr_only) {
11371 uint32_t destination;
11372
11373 destination = ntohl(dest_p->u.prefix4.s_addr);
11374 if (IN_CLASSC(destination)
11375 && dest_p->prefixlen == 24)
11376 continue;
11377 if (IN_CLASSB(destination)
11378 && dest_p->prefixlen == 16)
11379 continue;
11380 if (IN_CLASSA(destination)
11381 && dest_p->prefixlen == 8)
11382 continue;
11383 }
11384 if (type == bgp_show_type_prefix_longer) {
11385 p = output_arg;
11386 if (!prefix_match(p, dest_p))
11387 continue;
11388 }
11389 if (type == bgp_show_type_community_all) {
11390 if (!picomm)
11391 continue;
11392 }
11393 if (type == bgp_show_type_community) {
11394 struct community *com = output_arg;
11395
11396 if (!picomm || !community_match(picomm, com))
11397 continue;
11398 }
11399 if (type == bgp_show_type_community_exact) {
11400 struct community *com = output_arg;
11401
11402 if (!picomm || !community_cmp(picomm, com))
11403 continue;
11404 }
11405 if (type == bgp_show_type_community_list) {
11406 struct community_list *list = output_arg;
11407
11408 if (!community_list_match(picomm, list))
11409 continue;
11410 }
11411 if (type == bgp_show_type_community_list_exact) {
11412 struct community_list *list = output_arg;
11413
11414 if (!community_list_exact_match(picomm, list))
11415 continue;
11416 }
11417 if (type == bgp_show_type_lcommunity) {
11418 struct lcommunity *lcom = output_arg;
11419
11420 if (!bgp_attr_get_lcommunity(pi->attr) ||
11421 !lcommunity_match(
11422 bgp_attr_get_lcommunity(pi->attr),
11423 lcom))
11424 continue;
11425 }
11426
11427 if (type == bgp_show_type_lcommunity_exact) {
11428 struct lcommunity *lcom = output_arg;
11429
11430 if (!bgp_attr_get_lcommunity(pi->attr) ||
11431 !lcommunity_cmp(
11432 bgp_attr_get_lcommunity(pi->attr),
11433 lcom))
11434 continue;
11435 }
11436 if (type == bgp_show_type_lcommunity_list) {
11437 struct community_list *list = output_arg;
11438
11439 if (!lcommunity_list_match(
11440 bgp_attr_get_lcommunity(pi->attr),
11441 list))
11442 continue;
11443 }
11444 if (type
11445 == bgp_show_type_lcommunity_list_exact) {
11446 struct community_list *list = output_arg;
11447
11448 if (!lcommunity_list_exact_match(
11449 bgp_attr_get_lcommunity(pi->attr),
11450 list))
11451 continue;
11452 }
11453 if (type == bgp_show_type_lcommunity_all) {
11454 if (!bgp_attr_get_lcommunity(pi->attr))
11455 continue;
11456 }
11457 if (type == bgp_show_type_dampend_paths
11458 || type == bgp_show_type_damp_neighbor) {
11459 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11460 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11461 continue;
11462 }
11463
11464 if (!use_json && header) {
11465 vty_out(vty,
11466 "BGP table version is %" PRIu64
11467 ", local router ID is %pI4, vrf id ",
11468 table->version, &bgp->router_id);
11469 if (bgp->vrf_id == VRF_UNKNOWN)
11470 vty_out(vty, "%s", VRFID_NONE_STR);
11471 else
11472 vty_out(vty, "%u", bgp->vrf_id);
11473 vty_out(vty, "\n");
11474 vty_out(vty, "Default local pref %u, ",
11475 bgp->default_local_pref);
11476 vty_out(vty, "local AS %u\n", bgp->as);
11477 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11478 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11479 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11480 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11481 if (type == bgp_show_type_dampend_paths
11482 || type == bgp_show_type_damp_neighbor)
11483 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11484 else if (type == bgp_show_type_flap_statistics
11485 || type == bgp_show_type_flap_neighbor)
11486 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11487 else
11488 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11489 : BGP_SHOW_HEADER));
11490 header = false;
11491
11492 } else if (json_detail && json_paths != NULL) {
11493 const struct prefix_rd *prd;
11494 json_object *jtemp;
11495
11496 /* Use common detail header, for most types;
11497 * need a json 'object'.
11498 */
11499
11500 jtemp = json_object_new_object();
11501 prd = bgp_rd_from_dest(dest, safi);
11502
11503 route_vty_out_detail_header(
11504 vty, bgp, dest, prd, table->afi,
11505 safi, jtemp);
11506
11507 json_object_array_add(json_paths, jtemp);
11508
11509 json_detail = false;
11510 }
11511
11512 if (rd != NULL && !display && !output_count) {
11513 if (!use_json)
11514 vty_out(vty,
11515 "Route Distinguisher: %s\n",
11516 rd);
11517 }
11518 if (type == bgp_show_type_dampend_paths
11519 || type == bgp_show_type_damp_neighbor)
11520 damp_route_vty_out(vty, dest_p, pi, display,
11521 AFI_IP, safi, use_json,
11522 json_paths);
11523 else if (type == bgp_show_type_flap_statistics
11524 || type == bgp_show_type_flap_neighbor)
11525 flap_route_vty_out(vty, dest_p, pi, display,
11526 AFI_IP, safi, use_json,
11527 json_paths);
11528 else {
11529 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL))
11530 route_vty_out_detail(
11531 vty, bgp, dest, pi,
11532 family2afi(dest_p->family),
11533 safi, RPKI_NOT_BEING_USED,
11534 json_paths);
11535 else
11536 route_vty_out(vty, dest_p, pi, display,
11537 safi, json_paths, wide);
11538 }
11539 display++;
11540 }
11541
11542 if (display) {
11543 output_count++;
11544 if (!use_json)
11545 continue;
11546
11547 /* encode prefix */
11548 if (dest_p->family == AF_FLOWSPEC) {
11549 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11550
11551
11552 bgp_fs_nlri_get_string(
11553 (unsigned char *)
11554 dest_p->u.prefix_flowspec.ptr,
11555 dest_p->u.prefix_flowspec.prefixlen,
11556 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11557 family2afi(dest_p->u
11558 .prefix_flowspec.family));
11559 if (first)
11560 vty_out(vty, "\"%s/%d\": ", retstr,
11561 dest_p->u.prefix_flowspec
11562 .prefixlen);
11563 else
11564 vty_out(vty, ",\"%s/%d\": ", retstr,
11565 dest_p->u.prefix_flowspec
11566 .prefixlen);
11567 } else {
11568 if (first)
11569 vty_out(vty, "\"%pFX\": ", dest_p);
11570 else
11571 vty_out(vty, ",\"%pFX\": ", dest_p);
11572 }
11573 vty_json(vty, json_paths);
11574 json_paths = NULL;
11575 first = 0;
11576 } else
11577 json_object_free(json_paths);
11578 }
11579
11580 if (output_cum) {
11581 output_count += *output_cum;
11582 *output_cum = output_count;
11583 }
11584 if (total_cum) {
11585 total_count += *total_cum;
11586 *total_cum = total_count;
11587 }
11588 if (use_json) {
11589 if (rd) {
11590 vty_out(vty, " }%s ", (is_last ? "" : ","));
11591 }
11592 if (is_last) {
11593 unsigned long i;
11594 for (i = 0; i < *json_header_depth; ++i)
11595 vty_out(vty, " } ");
11596 if (!all)
11597 vty_out(vty, "\n");
11598 }
11599 } else {
11600 if (is_last) {
11601 /* No route is displayed */
11602 if (output_count == 0) {
11603 if (type == bgp_show_type_normal)
11604 vty_out(vty,
11605 "No BGP prefixes displayed, %ld exist\n",
11606 total_count);
11607 } else
11608 vty_out(vty,
11609 "\nDisplayed %ld routes and %ld total paths\n",
11610 output_count, total_count);
11611 }
11612 }
11613
11614 return CMD_SUCCESS;
11615 }
11616
11617 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11618 struct bgp_table *table, struct prefix_rd *prd_match,
11619 enum bgp_show_type type, void *output_arg, bool use_json)
11620 {
11621 struct bgp_dest *dest, *next;
11622 unsigned long output_cum = 0;
11623 unsigned long total_cum = 0;
11624 unsigned long json_header_depth = 0;
11625 struct bgp_table *itable;
11626 bool show_msg;
11627 uint16_t show_flags = 0;
11628
11629 show_msg = (!use_json && type == bgp_show_type_normal);
11630
11631 if (use_json)
11632 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11633
11634 for (dest = bgp_table_top(table); dest; dest = next) {
11635 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11636
11637 next = bgp_route_next(dest);
11638 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11639 continue;
11640
11641 itable = bgp_dest_get_bgp_table_info(dest);
11642 if (itable != NULL) {
11643 struct prefix_rd prd;
11644 char rd[RD_ADDRSTRLEN];
11645
11646 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11647 prefix_rd2str(&prd, rd, sizeof(rd));
11648 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11649 rd, next == NULL, &output_cum,
11650 &total_cum, &json_header_depth,
11651 show_flags, RPKI_NOT_BEING_USED);
11652 if (next == NULL)
11653 show_msg = false;
11654 }
11655 }
11656 if (show_msg) {
11657 if (output_cum == 0)
11658 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11659 total_cum);
11660 else
11661 vty_out(vty,
11662 "\nDisplayed %ld routes and %ld total paths\n",
11663 output_cum, total_cum);
11664 }
11665 return CMD_SUCCESS;
11666 }
11667
11668 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11669 enum bgp_show_type type, void *output_arg,
11670 uint16_t show_flags, enum rpki_states rpki_target_state)
11671 {
11672 struct bgp_table *table;
11673 unsigned long json_header_depth = 0;
11674 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11675
11676 if (bgp == NULL) {
11677 bgp = bgp_get_default();
11678 }
11679
11680 if (bgp == NULL) {
11681 if (!use_json)
11682 vty_out(vty, "No BGP process is configured\n");
11683 else
11684 vty_out(vty, "{}\n");
11685 return CMD_WARNING;
11686 }
11687
11688 /* Labeled-unicast routes live in the unicast table. */
11689 if (safi == SAFI_LABELED_UNICAST)
11690 safi = SAFI_UNICAST;
11691
11692 table = bgp->rib[afi][safi];
11693 /* use MPLS and ENCAP specific shows until they are merged */
11694 if (safi == SAFI_MPLS_VPN) {
11695 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11696 output_arg, use_json);
11697 }
11698
11699 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11700 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11701 output_arg, use_json,
11702 1, NULL, NULL);
11703 }
11704
11705 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11706 NULL, NULL, &json_header_depth, show_flags,
11707 rpki_target_state);
11708 }
11709
11710 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11711 safi_t safi, uint16_t show_flags)
11712 {
11713 struct listnode *node, *nnode;
11714 struct bgp *bgp;
11715 int is_first = 1;
11716 bool route_output = false;
11717 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11718
11719 if (use_json)
11720 vty_out(vty, "{\n");
11721
11722 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11723 route_output = true;
11724 if (use_json) {
11725 if (!is_first)
11726 vty_out(vty, ",\n");
11727 else
11728 is_first = 0;
11729
11730 vty_out(vty, "\"%s\":",
11731 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11732 ? VRF_DEFAULT_NAME
11733 : bgp->name);
11734 } else {
11735 vty_out(vty, "\nInstance %s:\n",
11736 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11737 ? VRF_DEFAULT_NAME
11738 : bgp->name);
11739 }
11740 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11741 show_flags, RPKI_NOT_BEING_USED);
11742 }
11743
11744 if (use_json)
11745 vty_out(vty, "}\n");
11746 else if (!route_output)
11747 vty_out(vty, "%% BGP instance not found\n");
11748 }
11749
11750 /* Header of detailed BGP route information */
11751 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11752 struct bgp_dest *dest,
11753 const struct prefix_rd *prd,
11754 afi_t afi, safi_t safi, json_object *json)
11755 {
11756 struct bgp_path_info *pi;
11757 const struct prefix *p;
11758 struct peer *peer;
11759 struct listnode *node, *nnode;
11760 char buf1[RD_ADDRSTRLEN];
11761 int count = 0;
11762 int best = 0;
11763 int suppress = 0;
11764 int accept_own = 0;
11765 int route_filter_translated_v4 = 0;
11766 int route_filter_v4 = 0;
11767 int route_filter_translated_v6 = 0;
11768 int route_filter_v6 = 0;
11769 int llgr_stale = 0;
11770 int no_llgr = 0;
11771 int accept_own_nexthop = 0;
11772 int blackhole = 0;
11773 int no_export = 0;
11774 int no_advertise = 0;
11775 int local_as = 0;
11776 int no_peer = 0;
11777 int first = 1;
11778 int has_valid_label = 0;
11779 mpls_label_t label = 0;
11780 json_object *json_adv_to = NULL;
11781 uint32_t ttl = 0;
11782 uint32_t bos = 0;
11783 uint32_t exp = 0;
11784
11785 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11786
11787 p = bgp_dest_get_prefix(dest);
11788 has_valid_label = bgp_is_valid_label(&label);
11789
11790 if (safi == SAFI_EVPN) {
11791 if (!json) {
11792 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11793 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
11794 : "",
11795 prd ? ":" : "", (struct prefix_evpn *)p);
11796 } else {
11797 json_object_string_add(json, "rd",
11798 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11799 "");
11800 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11801 }
11802 } else {
11803 if (!json) {
11804 vty_out(vty,
11805 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11806 "\n",
11807 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11808 ? prefix_rd2str(prd, buf1,
11809 sizeof(buf1))
11810 : ""),
11811 safi == SAFI_MPLS_VPN ? ":" : "", p,
11812 dest->version);
11813
11814 } else {
11815 json_object_string_addf(json, "prefix", "%pFX", p);
11816 json_object_int_add(json, "version", dest->version);
11817
11818 }
11819 }
11820
11821 if (has_valid_label) {
11822 if (json)
11823 json_object_int_add(json, "localLabel", label);
11824 else
11825 vty_out(vty, "Local label: %d\n", label);
11826 }
11827
11828 if (!json)
11829 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11830 vty_out(vty, "not allocated\n");
11831
11832 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11833 struct community *picomm = NULL;
11834
11835 picomm = bgp_attr_get_community(pi->attr);
11836
11837 count++;
11838 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11839 best = count;
11840 if (bgp_path_suppressed(pi))
11841 suppress = 1;
11842
11843 if (!picomm)
11844 continue;
11845
11846 no_advertise += community_include(
11847 picomm, COMMUNITY_NO_ADVERTISE);
11848 no_export +=
11849 community_include(picomm, COMMUNITY_NO_EXPORT);
11850 local_as +=
11851 community_include(picomm, COMMUNITY_LOCAL_AS);
11852 accept_own +=
11853 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11854 route_filter_translated_v4 += community_include(
11855 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11856 route_filter_translated_v6 += community_include(
11857 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11858 route_filter_v4 += community_include(
11859 picomm, COMMUNITY_ROUTE_FILTER_v4);
11860 route_filter_v6 += community_include(
11861 picomm, COMMUNITY_ROUTE_FILTER_v6);
11862 llgr_stale +=
11863 community_include(picomm, COMMUNITY_LLGR_STALE);
11864 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11865 accept_own_nexthop += community_include(
11866 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11867 blackhole +=
11868 community_include(picomm, COMMUNITY_BLACKHOLE);
11869 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11870 }
11871 }
11872
11873 if (!json) {
11874 vty_out(vty, "Paths: (%d available", count);
11875 if (best) {
11876 vty_out(vty, ", best #%d", best);
11877 if (safi == SAFI_UNICAST) {
11878 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11879 vty_out(vty, ", table %s",
11880 VRF_DEFAULT_NAME);
11881 else
11882 vty_out(vty, ", vrf %s",
11883 bgp->name);
11884 }
11885 } else
11886 vty_out(vty, ", no best path");
11887
11888 if (accept_own)
11889 vty_out(vty,
11890 ", accept own local route exported and imported in different VRF");
11891 else if (route_filter_translated_v4)
11892 vty_out(vty,
11893 ", mark translated RTs for VPNv4 route filtering");
11894 else if (route_filter_v4)
11895 vty_out(vty,
11896 ", attach RT as-is for VPNv4 route filtering");
11897 else if (route_filter_translated_v6)
11898 vty_out(vty,
11899 ", mark translated RTs for VPNv6 route filtering");
11900 else if (route_filter_v6)
11901 vty_out(vty,
11902 ", attach RT as-is for VPNv6 route filtering");
11903 else if (llgr_stale)
11904 vty_out(vty,
11905 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
11906 else if (no_llgr)
11907 vty_out(vty,
11908 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11909 else if (accept_own_nexthop)
11910 vty_out(vty,
11911 ", accept local nexthop");
11912 else if (blackhole)
11913 vty_out(vty, ", inform peer to blackhole prefix");
11914 else if (no_export)
11915 vty_out(vty, ", not advertised to EBGP peer");
11916 else if (no_advertise)
11917 vty_out(vty, ", not advertised to any peer");
11918 else if (local_as)
11919 vty_out(vty, ", not advertised outside local AS");
11920 else if (no_peer)
11921 vty_out(vty,
11922 ", inform EBGP peer not to advertise to their EBGP peers");
11923
11924 if (suppress)
11925 vty_out(vty,
11926 ", Advertisements suppressed by an aggregate.");
11927 vty_out(vty, ")\n");
11928 }
11929
11930 /* If we are not using addpath then we can display Advertised to and
11931 * that will
11932 * show what peers we advertised the bestpath to. If we are using
11933 * addpath
11934 * though then we must display Advertised to on a path-by-path basis. */
11935 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11936 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11937 if (bgp_adj_out_lookup(peer, dest, 0)) {
11938 if (json && !json_adv_to)
11939 json_adv_to = json_object_new_object();
11940
11941 route_vty_out_advertised_to(
11942 vty, peer, &first,
11943 " Advertised to non peer-group peers:\n ",
11944 json_adv_to);
11945 }
11946 }
11947
11948 if (json) {
11949 if (json_adv_to) {
11950 json_object_object_add(json, "advertisedTo",
11951 json_adv_to);
11952 }
11953 } else {
11954 if (first)
11955 vty_out(vty, " Not advertised to any peer");
11956 vty_out(vty, "\n");
11957 }
11958 }
11959 }
11960
11961 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
11962 struct bgp_dest *bgp_node, struct vty *vty,
11963 struct bgp *bgp, afi_t afi, safi_t safi,
11964 json_object *json, enum bgp_path_type pathtype,
11965 int *display, enum rpki_states rpki_target_state)
11966 {
11967 struct bgp_path_info *pi;
11968 int header = 1;
11969 json_object *json_header = NULL;
11970 json_object *json_paths = NULL;
11971 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
11972
11973 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
11974 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11975
11976 if (p->family == AF_INET || p->family == AF_INET6)
11977 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
11978 pi->peer, pi->attr, p);
11979
11980 if (rpki_target_state != RPKI_NOT_BEING_USED
11981 && rpki_curr_state != rpki_target_state)
11982 continue;
11983
11984 if (json && !json_paths) {
11985 /* Instantiate json_paths only if path is valid */
11986 json_paths = json_object_new_array();
11987 if (pfx_rd)
11988 json_header = json_object_new_object();
11989 else
11990 json_header = json;
11991 }
11992
11993 if (header) {
11994 route_vty_out_detail_header(
11995 vty, bgp, bgp_node, pfx_rd,
11996 AFI_IP, safi, json_header);
11997 header = 0;
11998 }
11999 (*display)++;
12000
12001 if (pathtype == BGP_PATH_SHOW_ALL
12002 || (pathtype == BGP_PATH_SHOW_BESTPATH
12003 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12004 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12005 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12006 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12007 route_vty_out_detail(vty, bgp, bgp_node, pi, AFI_IP,
12008 safi, rpki_curr_state, json_paths);
12009 }
12010
12011 if (json && json_paths) {
12012 json_object_object_add(json_header, "paths", json_paths);
12013
12014 if (pfx_rd)
12015 json_object_object_addf(json, json_header, "%pRD",
12016 pfx_rd);
12017 }
12018 }
12019
12020 /*
12021 * Return rd based on safi
12022 */
12023 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12024 safi_t safi)
12025 {
12026 switch (safi) {
12027 case SAFI_MPLS_VPN:
12028 case SAFI_ENCAP:
12029 case SAFI_EVPN:
12030 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12031 default:
12032 return NULL;
12033 }
12034 }
12035
12036 /* Display specified route of BGP table. */
12037 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12038 struct bgp_table *rib, const char *ip_str,
12039 afi_t afi, safi_t safi,
12040 enum rpki_states rpki_target_state,
12041 struct prefix_rd *prd, int prefix_check,
12042 enum bgp_path_type pathtype, bool use_json)
12043 {
12044 int ret;
12045 int display = 0;
12046 struct prefix match;
12047 struct bgp_dest *dest;
12048 struct bgp_dest *rm;
12049 struct bgp_table *table;
12050 json_object *json = NULL;
12051 json_object *json_paths = NULL;
12052
12053 /* Check IP address argument. */
12054 ret = str2prefix(ip_str, &match);
12055 if (!ret) {
12056 vty_out(vty, "address is malformed\n");
12057 return CMD_WARNING;
12058 }
12059
12060 match.family = afi2family(afi);
12061
12062 if (use_json)
12063 json = json_object_new_object();
12064
12065 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12066 for (dest = bgp_table_top(rib); dest;
12067 dest = bgp_route_next(dest)) {
12068 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12069
12070 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12071 continue;
12072 table = bgp_dest_get_bgp_table_info(dest);
12073 if (!table)
12074 continue;
12075
12076 rm = bgp_node_match(table, &match);
12077 if (rm == NULL)
12078 continue;
12079
12080 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12081 if (prefix_check
12082 && rm_p->prefixlen != match.prefixlen) {
12083 bgp_dest_unlock_node(rm);
12084 continue;
12085 }
12086
12087 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12088 bgp, afi, safi, json, pathtype,
12089 &display, rpki_target_state);
12090
12091 bgp_dest_unlock_node(rm);
12092 }
12093 } else if (safi == SAFI_EVPN) {
12094 struct bgp_dest *longest_pfx;
12095 bool is_exact_pfxlen_match = false;
12096
12097 for (dest = bgp_table_top(rib); dest;
12098 dest = bgp_route_next(dest)) {
12099 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12100
12101 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12102 continue;
12103 table = bgp_dest_get_bgp_table_info(dest);
12104 if (!table)
12105 continue;
12106
12107 longest_pfx = NULL;
12108 is_exact_pfxlen_match = false;
12109 /*
12110 * Search through all the prefixes for a match. The
12111 * pfx's are enumerated in ascending order of pfxlens.
12112 * So, the last pfx match is the longest match. Set
12113 * is_exact_pfxlen_match when we get exact pfxlen match
12114 */
12115 for (rm = bgp_table_top(table); rm;
12116 rm = bgp_route_next(rm)) {
12117 const struct prefix *rm_p =
12118 bgp_dest_get_prefix(rm);
12119 /*
12120 * Get prefixlen of the ip-prefix within type5
12121 * evpn route
12122 */
12123 if (evpn_type5_prefix_match(rm_p, &match)
12124 && rm->info) {
12125 longest_pfx = rm;
12126 int type5_pfxlen =
12127 bgp_evpn_get_type5_prefixlen(
12128 rm_p);
12129 if (type5_pfxlen == match.prefixlen) {
12130 is_exact_pfxlen_match = true;
12131 bgp_dest_unlock_node(rm);
12132 break;
12133 }
12134 }
12135 }
12136
12137 if (!longest_pfx)
12138 continue;
12139
12140 if (prefix_check && !is_exact_pfxlen_match)
12141 continue;
12142
12143 rm = longest_pfx;
12144 bgp_dest_lock_node(rm);
12145
12146 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12147 bgp, afi, safi, json, pathtype,
12148 &display, rpki_target_state);
12149
12150 bgp_dest_unlock_node(rm);
12151 }
12152 } else if (safi == SAFI_FLOWSPEC) {
12153 if (use_json)
12154 json_paths = json_object_new_array();
12155
12156 display = bgp_flowspec_display_match_per_ip(afi, rib,
12157 &match, prefix_check,
12158 vty,
12159 use_json,
12160 json_paths);
12161 if (use_json) {
12162 if (display)
12163 json_object_object_add(json, "paths",
12164 json_paths);
12165 else
12166 json_object_free(json_paths);
12167 }
12168 } else {
12169 dest = bgp_node_match(rib, &match);
12170 if (dest != NULL) {
12171 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12172 if (!prefix_check
12173 || dest_p->prefixlen == match.prefixlen) {
12174 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12175 safi, json, pathtype,
12176 &display, rpki_target_state);
12177 }
12178
12179 bgp_dest_unlock_node(dest);
12180 }
12181 }
12182
12183 if (use_json) {
12184 vty_json(vty, json);
12185 } else {
12186 if (!display) {
12187 vty_out(vty, "%% Network not in table\n");
12188 return CMD_WARNING;
12189 }
12190 }
12191
12192 return CMD_SUCCESS;
12193 }
12194
12195 /* Display specified route of Main RIB */
12196 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12197 afi_t afi, safi_t safi, struct prefix_rd *prd,
12198 int prefix_check, enum bgp_path_type pathtype,
12199 enum rpki_states rpki_target_state, bool use_json)
12200 {
12201 if (!bgp) {
12202 bgp = bgp_get_default();
12203 if (!bgp) {
12204 if (!use_json)
12205 vty_out(vty, "No BGP process is configured\n");
12206 else
12207 vty_out(vty, "{}\n");
12208 return CMD_WARNING;
12209 }
12210 }
12211
12212 /* labeled-unicast routes live in the unicast table */
12213 if (safi == SAFI_LABELED_UNICAST)
12214 safi = SAFI_UNICAST;
12215
12216 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12217 afi, safi, rpki_target_state, prd,
12218 prefix_check, pathtype, use_json);
12219 }
12220
12221 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12222 struct cmd_token **argv, bool exact, afi_t afi,
12223 safi_t safi, bool uj)
12224 {
12225 struct lcommunity *lcom;
12226 struct buffer *b;
12227 int i;
12228 char *str;
12229 int first = 0;
12230 uint16_t show_flags = 0;
12231 int ret;
12232
12233 if (uj)
12234 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12235
12236 b = buffer_new(1024);
12237 for (i = 0; i < argc; i++) {
12238 if (first)
12239 buffer_putc(b, ' ');
12240 else {
12241 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12242 first = 1;
12243 buffer_putstr(b, argv[i]->arg);
12244 }
12245 }
12246 }
12247 buffer_putc(b, '\0');
12248
12249 str = buffer_getstr(b);
12250 buffer_free(b);
12251
12252 lcom = lcommunity_str2com(str);
12253 XFREE(MTYPE_TMP, str);
12254 if (!lcom) {
12255 vty_out(vty, "%% Large-community malformed\n");
12256 return CMD_WARNING;
12257 }
12258
12259 ret = bgp_show(vty, bgp, afi, safi,
12260 (exact ? bgp_show_type_lcommunity_exact
12261 : bgp_show_type_lcommunity),
12262 lcom, show_flags, RPKI_NOT_BEING_USED);
12263
12264 lcommunity_free(&lcom);
12265 return ret;
12266 }
12267
12268 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12269 const char *lcom, bool exact, afi_t afi,
12270 safi_t safi, bool uj)
12271 {
12272 struct community_list *list;
12273 uint16_t show_flags = 0;
12274
12275 if (uj)
12276 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12277
12278
12279 list = community_list_lookup(bgp_clist, lcom, 0,
12280 LARGE_COMMUNITY_LIST_MASTER);
12281 if (list == NULL) {
12282 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12283 lcom);
12284 return CMD_WARNING;
12285 }
12286
12287 return bgp_show(vty, bgp, afi, safi,
12288 (exact ? bgp_show_type_lcommunity_list_exact
12289 : bgp_show_type_lcommunity_list),
12290 list, show_flags, RPKI_NOT_BEING_USED);
12291 }
12292
12293 DEFUN (show_ip_bgp_large_community_list,
12294 show_ip_bgp_large_community_list_cmd,
12295 "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]",
12296 SHOW_STR
12297 IP_STR
12298 BGP_STR
12299 BGP_INSTANCE_HELP_STR
12300 BGP_AFI_HELP_STR
12301 BGP_SAFI_WITH_LABEL_HELP_STR
12302 "Display routes matching the large-community-list\n"
12303 "large-community-list number\n"
12304 "large-community-list name\n"
12305 "Exact match of the large-communities\n"
12306 JSON_STR)
12307 {
12308 afi_t afi = AFI_IP6;
12309 safi_t safi = SAFI_UNICAST;
12310 int idx = 0;
12311 bool exact_match = 0;
12312 struct bgp *bgp = NULL;
12313 bool uj = use_json(argc, argv);
12314
12315 if (uj)
12316 argc--;
12317
12318 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12319 &bgp, uj);
12320 if (!idx)
12321 return CMD_WARNING;
12322
12323 argv_find(argv, argc, "large-community-list", &idx);
12324
12325 const char *clist_number_or_name = argv[++idx]->arg;
12326
12327 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12328 exact_match = 1;
12329
12330 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12331 exact_match, afi, safi, uj);
12332 }
12333 DEFUN (show_ip_bgp_large_community,
12334 show_ip_bgp_large_community_cmd,
12335 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12336 SHOW_STR
12337 IP_STR
12338 BGP_STR
12339 BGP_INSTANCE_HELP_STR
12340 BGP_AFI_HELP_STR
12341 BGP_SAFI_WITH_LABEL_HELP_STR
12342 "Display routes matching the large-communities\n"
12343 "List of large-community numbers\n"
12344 "Exact match of the large-communities\n"
12345 JSON_STR)
12346 {
12347 afi_t afi = AFI_IP6;
12348 safi_t safi = SAFI_UNICAST;
12349 int idx = 0;
12350 bool exact_match = 0;
12351 struct bgp *bgp = NULL;
12352 bool uj = use_json(argc, argv);
12353 uint16_t show_flags = 0;
12354
12355 if (uj) {
12356 argc--;
12357 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12358 }
12359
12360 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12361 &bgp, uj);
12362 if (!idx)
12363 return CMD_WARNING;
12364
12365 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12366 if (argv_find(argv, argc, "exact-match", &idx)) {
12367 argc--;
12368 exact_match = 1;
12369 }
12370 return bgp_show_lcommunity(vty, bgp, argc, argv,
12371 exact_match, afi, safi, uj);
12372 } else
12373 return bgp_show(vty, bgp, afi, safi,
12374 bgp_show_type_lcommunity_all, NULL, show_flags,
12375 RPKI_NOT_BEING_USED);
12376 }
12377
12378 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12379 safi_t safi, struct json_object *json_array);
12380 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12381 safi_t safi, struct json_object *json);
12382
12383
12384 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12385 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12386 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12387 "Display number of prefixes for all afi/safi\n" JSON_STR)
12388 {
12389 bool uj = use_json(argc, argv);
12390 struct bgp *bgp = NULL;
12391 safi_t safi = SAFI_UNICAST;
12392 afi_t afi = AFI_IP6;
12393 int idx = 0;
12394 struct json_object *json_all = NULL;
12395 struct json_object *json_afi_safi = NULL;
12396
12397 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12398 &bgp, false);
12399 if (!idx)
12400 return CMD_WARNING;
12401
12402 if (uj)
12403 json_all = json_object_new_object();
12404
12405 FOREACH_AFI_SAFI (afi, safi) {
12406 /*
12407 * So limit output to those afi/safi pairs that
12408 * actually have something interesting in them
12409 */
12410 if (strmatch(get_afi_safi_str(afi, safi, true),
12411 "Unknown")) {
12412 continue;
12413 }
12414 if (uj) {
12415 json_afi_safi = json_object_new_array();
12416 json_object_object_add(
12417 json_all,
12418 get_afi_safi_str(afi, safi, true),
12419 json_afi_safi);
12420 } else {
12421 json_afi_safi = NULL;
12422 }
12423
12424 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12425 }
12426
12427 if (uj)
12428 vty_json(vty, json_all);
12429
12430 return CMD_SUCCESS;
12431 }
12432
12433 /* BGP route print out function without JSON */
12434 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12435 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12436 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12437 SHOW_STR
12438 IP_STR
12439 BGP_STR
12440 BGP_INSTANCE_HELP_STR
12441 L2VPN_HELP_STR
12442 EVPN_HELP_STR
12443 "BGP RIB advertisement statistics\n"
12444 JSON_STR)
12445 {
12446 afi_t afi = AFI_IP6;
12447 safi_t safi = SAFI_UNICAST;
12448 struct bgp *bgp = NULL;
12449 int idx = 0, ret;
12450 bool uj = use_json(argc, argv);
12451 struct json_object *json_afi_safi = NULL, *json = NULL;
12452
12453 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12454 &bgp, false);
12455 if (!idx)
12456 return CMD_WARNING;
12457
12458 if (uj)
12459 json_afi_safi = json_object_new_array();
12460 else
12461 json_afi_safi = NULL;
12462
12463 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12464
12465 if (uj) {
12466 json = json_object_new_object();
12467 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12468 json_afi_safi);
12469 vty_json(vty, json);
12470 }
12471 return ret;
12472 }
12473
12474 /* BGP route print out function without JSON */
12475 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12476 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12477 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12478 "]]\
12479 statistics [json]",
12480 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12481 BGP_SAFI_WITH_LABEL_HELP_STR
12482 "BGP RIB advertisement statistics\n" JSON_STR)
12483 {
12484 afi_t afi = AFI_IP6;
12485 safi_t safi = SAFI_UNICAST;
12486 struct bgp *bgp = NULL;
12487 int idx = 0, ret;
12488 bool uj = use_json(argc, argv);
12489 struct json_object *json_afi_safi = NULL, *json = NULL;
12490
12491 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12492 &bgp, false);
12493 if (!idx)
12494 return CMD_WARNING;
12495
12496 if (uj)
12497 json_afi_safi = json_object_new_array();
12498 else
12499 json_afi_safi = NULL;
12500
12501 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12502
12503 if (uj) {
12504 json = json_object_new_object();
12505 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12506 json_afi_safi);
12507 vty_json(vty, json);
12508 }
12509 return ret;
12510 }
12511
12512 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12513 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12514 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12515 "]] [all$all] dampening parameters [json]",
12516 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12517 BGP_SAFI_WITH_LABEL_HELP_STR
12518 "Display the entries for all address families\n"
12519 "Display detailed information about dampening\n"
12520 "Display detail of configured dampening parameters\n"
12521 JSON_STR)
12522 {
12523 afi_t afi = AFI_IP6;
12524 safi_t safi = SAFI_UNICAST;
12525 struct bgp *bgp = NULL;
12526 int idx = 0;
12527 uint16_t show_flags = 0;
12528 bool uj = use_json(argc, argv);
12529
12530 if (uj) {
12531 argc--;
12532 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12533 }
12534
12535 /* [<ipv4|ipv6> [all]] */
12536 if (all) {
12537 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12538 if (argv_find(argv, argc, "ipv4", &idx))
12539 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12540
12541 if (argv_find(argv, argc, "ipv6", &idx))
12542 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12543 }
12544
12545 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12546 &bgp, false);
12547 if (!idx)
12548 return CMD_WARNING;
12549
12550 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12551 }
12552
12553 /* BGP route print out function */
12554 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12555 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12556 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12557 "]]\
12558 [all$all]\
12559 [cidr-only\
12560 |dampening <flap-statistics|dampened-paths>\
12561 |community [AA:NN|local-AS|no-advertise|no-export\
12562 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12563 |accept-own|accept-own-nexthop|route-filter-v6\
12564 |route-filter-v4|route-filter-translated-v6\
12565 |route-filter-translated-v4] [exact-match]\
12566 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12567 |filter-list AS_PATH_FILTER_NAME\
12568 |prefix-list WORD\
12569 |access-list ACCESSLIST_NAME\
12570 |route-map RMAP_NAME\
12571 |rpki <invalid|valid|notfound>\
12572 |version (1-4294967295)\
12573 |alias ALIAS_NAME\
12574 |A.B.C.D/M longer-prefixes\
12575 |X:X::X:X/M longer-prefixes\
12576 |optimal-route-reflection [WORD$orr_group_name]\
12577 ] [json$uj [detail$detail] | wide$wide]",
12578 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12579 BGP_SAFI_WITH_LABEL_HELP_STR
12580 "Display the entries for all address families\n"
12581 "Display only routes with non-natural netmasks\n"
12582 "Display detailed information about dampening\n"
12583 "Display flap statistics of routes\n"
12584 "Display paths suppressed due to dampening\n"
12585 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12586 "Do not send outside local AS (well-known community)\n"
12587 "Do not advertise to any peer (well-known community)\n"
12588 "Do not export to next AS (well-known community)\n"
12589 "Graceful shutdown (well-known community)\n"
12590 "Do not export to any peer (well-known community)\n"
12591 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12592 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12593 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12594 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12595 "Should accept VPN route with local nexthop (well-known community)\n"
12596 "RT VPNv6 route filtering (well-known community)\n"
12597 "RT VPNv4 route filtering (well-known community)\n"
12598 "RT translated VPNv6 route filtering (well-known community)\n"
12599 "RT translated VPNv4 route filtering (well-known community)\n"
12600 "Exact match of the communities\n"
12601 "Community-list number\n"
12602 "Community-list name\n"
12603 "Display routes matching the community-list\n"
12604 "Exact match of the communities\n"
12605 "Display routes conforming to the filter-list\n"
12606 "Regular expression access list name\n"
12607 "Display routes conforming to the prefix-list\n"
12608 "Prefix-list name\n"
12609 "Display routes conforming to the access-list\n"
12610 "Access-list name\n"
12611 "Display routes matching the route-map\n"
12612 "A route-map to match on\n"
12613 "RPKI route types\n"
12614 "A valid path as determined by rpki\n"
12615 "A invalid path as determined by rpki\n"
12616 "A path that has no rpki data\n"
12617 "Display prefixes with matching version numbers\n"
12618 "Version number and above\n"
12619 "Display prefixes with matching BGP community alias\n"
12620 "BGP community alias\n"
12621 "IPv4 prefix\n"
12622 "Display route and more specific routes\n"
12623 "IPv6 prefix\n"
12624 "Display route and more specific routes\n"
12625 "Display Optimal Route Reflection RR Clients\n"
12626 "ORR Group name\n"
12627 JSON_STR
12628 "Display detailed version of JSON output\n"
12629 "Increase table width for longer prefixes\n")
12630 {
12631 afi_t afi = AFI_IP6;
12632 safi_t safi = SAFI_UNICAST;
12633 enum bgp_show_type sh_type = bgp_show_type_normal;
12634 void *output_arg = NULL;
12635 struct bgp *bgp = NULL;
12636 int idx = 0;
12637 int exact_match = 0;
12638 char *community = NULL;
12639 bool first = true;
12640 uint16_t show_flags = 0;
12641 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12642 struct prefix p;
12643 bool orr_group = false;
12644
12645 if (uj) {
12646 argc--;
12647 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12648 }
12649
12650 if (detail)
12651 SET_FLAG(show_flags, BGP_SHOW_OPT_DETAIL);
12652
12653 /* [<ipv4|ipv6> [all]] */
12654 if (all) {
12655 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12656
12657 if (argv_find(argv, argc, "ipv4", &idx))
12658 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12659
12660 if (argv_find(argv, argc, "ipv6", &idx))
12661 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12662 }
12663
12664 if (wide)
12665 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12666
12667 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12668 &bgp, uj);
12669 if (!idx)
12670 return CMD_WARNING;
12671
12672 if (argv_find(argv, argc, "cidr-only", &idx))
12673 sh_type = bgp_show_type_cidr_only;
12674
12675 if (argv_find(argv, argc, "dampening", &idx)) {
12676 if (argv_find(argv, argc, "dampened-paths", &idx))
12677 sh_type = bgp_show_type_dampend_paths;
12678 else if (argv_find(argv, argc, "flap-statistics", &idx))
12679 sh_type = bgp_show_type_flap_statistics;
12680 }
12681
12682 if (argv_find(argv, argc, "community", &idx)) {
12683 char *maybecomm = NULL;
12684
12685 if (idx + 1 < argc) {
12686 if (argv[idx + 1]->type == VARIABLE_TKN)
12687 maybecomm = argv[idx + 1]->arg;
12688 else
12689 maybecomm = argv[idx + 1]->text;
12690 }
12691
12692 if (maybecomm && !strmatch(maybecomm, "json")
12693 && !strmatch(maybecomm, "exact-match"))
12694 community = maybecomm;
12695
12696 if (argv_find(argv, argc, "exact-match", &idx))
12697 exact_match = 1;
12698
12699 if (!community)
12700 sh_type = bgp_show_type_community_all;
12701 }
12702
12703 if (argv_find(argv, argc, "community-list", &idx)) {
12704 const char *clist_number_or_name = argv[++idx]->arg;
12705 struct community_list *list;
12706
12707 if (argv_find(argv, argc, "exact-match", &idx))
12708 exact_match = 1;
12709
12710 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12711 COMMUNITY_LIST_MASTER);
12712 if (list == NULL) {
12713 vty_out(vty, "%% %s community-list not found\n",
12714 clist_number_or_name);
12715 return CMD_WARNING;
12716 }
12717
12718 if (exact_match)
12719 sh_type = bgp_show_type_community_list_exact;
12720 else
12721 sh_type = bgp_show_type_community_list;
12722 output_arg = list;
12723 }
12724
12725 if (argv_find(argv, argc, "filter-list", &idx)) {
12726 const char *filter = argv[++idx]->arg;
12727 struct as_list *as_list;
12728
12729 as_list = as_list_lookup(filter);
12730 if (as_list == NULL) {
12731 vty_out(vty, "%% %s AS-path access-list not found\n",
12732 filter);
12733 return CMD_WARNING;
12734 }
12735
12736 sh_type = bgp_show_type_filter_list;
12737 output_arg = as_list;
12738 }
12739
12740 if (argv_find(argv, argc, "prefix-list", &idx)) {
12741 const char *prefix_list_str = argv[++idx]->arg;
12742 struct prefix_list *plist;
12743
12744 plist = prefix_list_lookup(afi, prefix_list_str);
12745 if (plist == NULL) {
12746 vty_out(vty, "%% %s prefix-list not found\n",
12747 prefix_list_str);
12748 return CMD_WARNING;
12749 }
12750
12751 sh_type = bgp_show_type_prefix_list;
12752 output_arg = plist;
12753 }
12754
12755 if (argv_find(argv, argc, "access-list", &idx)) {
12756 const char *access_list_str = argv[++idx]->arg;
12757 struct access_list *alist;
12758
12759 alist = access_list_lookup(afi, access_list_str);
12760 if (!alist) {
12761 vty_out(vty, "%% %s access-list not found\n",
12762 access_list_str);
12763 return CMD_WARNING;
12764 }
12765
12766 sh_type = bgp_show_type_access_list;
12767 output_arg = alist;
12768 }
12769
12770 if (argv_find(argv, argc, "route-map", &idx)) {
12771 const char *rmap_str = argv[++idx]->arg;
12772 struct route_map *rmap;
12773
12774 rmap = route_map_lookup_by_name(rmap_str);
12775 if (!rmap) {
12776 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12777 return CMD_WARNING;
12778 }
12779
12780 sh_type = bgp_show_type_route_map;
12781 output_arg = rmap;
12782 }
12783
12784 if (argv_find(argv, argc, "rpki", &idx)) {
12785 sh_type = bgp_show_type_rpki;
12786 if (argv_find(argv, argc, "valid", &idx))
12787 rpki_target_state = RPKI_VALID;
12788 else if (argv_find(argv, argc, "invalid", &idx))
12789 rpki_target_state = RPKI_INVALID;
12790 }
12791
12792 /* Display prefixes with matching version numbers */
12793 if (argv_find(argv, argc, "version", &idx)) {
12794 sh_type = bgp_show_type_prefix_version;
12795 output_arg = argv[idx + 1]->arg;
12796 }
12797
12798 /* Display prefixes with matching BGP community alias */
12799 if (argv_find(argv, argc, "alias", &idx)) {
12800 sh_type = bgp_show_type_community_alias;
12801 output_arg = argv[idx + 1]->arg;
12802 }
12803
12804 /* prefix-longer */
12805 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12806 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12807 const char *prefix_str = argv[idx]->arg;
12808
12809 if (!str2prefix(prefix_str, &p)) {
12810 vty_out(vty, "%% Malformed Prefix\n");
12811 return CMD_WARNING;
12812 }
12813
12814 sh_type = bgp_show_type_prefix_longer;
12815 output_arg = &p;
12816 }
12817
12818 if (argv_find(argv, argc, "optimal-route-reflection", &idx))
12819 orr_group = true;
12820
12821 if (!all) {
12822 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12823 if (community)
12824 return bgp_show_community(vty, bgp, community,
12825 exact_match, afi, safi,
12826 show_flags);
12827 else if (orr_group)
12828 return bgp_show_orr(vty, bgp, afi, safi, orr_group_name,
12829 show_flags);
12830 else
12831 return bgp_show(vty, bgp, afi, safi, sh_type,
12832 output_arg, show_flags,
12833 rpki_target_state);
12834 } else {
12835 struct listnode *node;
12836 struct bgp *abgp;
12837 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12838 * AFI_IP6 */
12839
12840 if (uj)
12841 vty_out(vty, "{\n");
12842
12843 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12844 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12845 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12846 ? AFI_IP
12847 : AFI_IP6;
12848 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12849 FOREACH_SAFI (safi) {
12850 if (!bgp_afi_safi_peer_exists(abgp, afi,
12851 safi))
12852 continue;
12853
12854 if (uj) {
12855 if (first)
12856 first = false;
12857 else
12858 vty_out(vty, ",\n");
12859 vty_out(vty, "\"%s\":{\n",
12860 get_afi_safi_str(afi,
12861 safi,
12862 true));
12863 } else
12864 vty_out(vty,
12865 "\nFor address family: %s\n",
12866 get_afi_safi_str(
12867 afi, safi,
12868 false));
12869
12870 if (community)
12871 bgp_show_community(
12872 vty, abgp, community,
12873 exact_match, afi, safi,
12874 show_flags);
12875 else if (orr_group)
12876 bgp_show_orr(vty, bgp, afi,
12877 safi,
12878 orr_group_name,
12879 show_flags);
12880 else
12881 bgp_show(vty, abgp, afi, safi,
12882 sh_type, output_arg,
12883 show_flags,
12884 rpki_target_state);
12885 if (uj)
12886 vty_out(vty, "}\n");
12887 }
12888 }
12889 } else {
12890 /* show <ip> bgp all: for each AFI and SAFI*/
12891 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12892 FOREACH_AFI_SAFI (afi, safi) {
12893 if (!bgp_afi_safi_peer_exists(abgp, afi,
12894 safi))
12895 continue;
12896
12897 if (uj) {
12898 if (first)
12899 first = false;
12900 else
12901 vty_out(vty, ",\n");
12902
12903 vty_out(vty, "\"%s\":{\n",
12904 get_afi_safi_str(afi,
12905 safi,
12906 true));
12907 } else
12908 vty_out(vty,
12909 "\nFor address family: %s\n",
12910 get_afi_safi_str(
12911 afi, safi,
12912 false));
12913
12914 if (community)
12915 bgp_show_community(
12916 vty, abgp, community,
12917 exact_match, afi, safi,
12918 show_flags);
12919 else if (orr_group)
12920 bgp_show_orr(vty, bgp, afi,
12921 safi,
12922 orr_group_name,
12923 show_flags);
12924 else
12925 bgp_show(vty, abgp, afi, safi,
12926 sh_type, output_arg,
12927 show_flags,
12928 rpki_target_state);
12929 if (uj)
12930 vty_out(vty, "}\n");
12931 }
12932 }
12933 }
12934 if (uj)
12935 vty_out(vty, "}\n");
12936 }
12937 return CMD_SUCCESS;
12938 }
12939
12940 DEFUN (show_ip_bgp_route,
12941 show_ip_bgp_route_cmd,
12942 "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]",
12943 SHOW_STR
12944 IP_STR
12945 BGP_STR
12946 BGP_INSTANCE_HELP_STR
12947 BGP_AFI_HELP_STR
12948 BGP_SAFI_WITH_LABEL_HELP_STR
12949 "Network in the BGP routing table to display\n"
12950 "IPv4 prefix\n"
12951 "Network in the BGP routing table to display\n"
12952 "IPv6 prefix\n"
12953 "Display only the bestpath\n"
12954 "Display only multipaths\n"
12955 "Display only paths that match the specified rpki state\n"
12956 "A valid path as determined by rpki\n"
12957 "A invalid path as determined by rpki\n"
12958 "A path that has no rpki data\n"
12959 JSON_STR)
12960 {
12961 int prefix_check = 0;
12962
12963 afi_t afi = AFI_IP6;
12964 safi_t safi = SAFI_UNICAST;
12965 char *prefix = NULL;
12966 struct bgp *bgp = NULL;
12967 enum bgp_path_type path_type;
12968 bool uj = use_json(argc, argv);
12969
12970 int idx = 0;
12971
12972 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12973 &bgp, uj);
12974 if (!idx)
12975 return CMD_WARNING;
12976
12977 if (!bgp) {
12978 vty_out(vty,
12979 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
12980 return CMD_WARNING;
12981 }
12982
12983 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
12984 if (argv_find(argv, argc, "A.B.C.D", &idx)
12985 || argv_find(argv, argc, "X:X::X:X", &idx))
12986 prefix_check = 0;
12987 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12988 || argv_find(argv, argc, "X:X::X:X/M", &idx))
12989 prefix_check = 1;
12990
12991 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
12992 && afi != AFI_IP6) {
12993 vty_out(vty,
12994 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
12995 return CMD_WARNING;
12996 }
12997 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
12998 && afi != AFI_IP) {
12999 vty_out(vty,
13000 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13001 return CMD_WARNING;
13002 }
13003
13004 prefix = argv[idx]->arg;
13005
13006 /* [<bestpath|multipath>] */
13007 if (argv_find(argv, argc, "bestpath", &idx))
13008 path_type = BGP_PATH_SHOW_BESTPATH;
13009 else if (argv_find(argv, argc, "multipath", &idx))
13010 path_type = BGP_PATH_SHOW_MULTIPATH;
13011 else
13012 path_type = BGP_PATH_SHOW_ALL;
13013
13014 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13015 path_type, RPKI_NOT_BEING_USED, uj);
13016 }
13017
13018 DEFUN (show_ip_bgp_regexp,
13019 show_ip_bgp_regexp_cmd,
13020 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13021 SHOW_STR
13022 IP_STR
13023 BGP_STR
13024 BGP_INSTANCE_HELP_STR
13025 BGP_AFI_HELP_STR
13026 BGP_SAFI_WITH_LABEL_HELP_STR
13027 "Display routes matching the AS path regular expression\n"
13028 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13029 JSON_STR)
13030 {
13031 afi_t afi = AFI_IP6;
13032 safi_t safi = SAFI_UNICAST;
13033 struct bgp *bgp = NULL;
13034 bool uj = use_json(argc, argv);
13035 char *regstr = NULL;
13036
13037 int idx = 0;
13038 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13039 &bgp, false);
13040 if (!idx)
13041 return CMD_WARNING;
13042
13043 // get index of regex
13044 if (argv_find(argv, argc, "REGEX", &idx))
13045 regstr = argv[idx]->arg;
13046
13047 assert(regstr);
13048 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13049 bgp_show_type_regexp, uj);
13050 }
13051
13052 DEFPY (show_ip_bgp_instance_all,
13053 show_ip_bgp_instance_all_cmd,
13054 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13055 SHOW_STR
13056 IP_STR
13057 BGP_STR
13058 BGP_INSTANCE_ALL_HELP_STR
13059 BGP_AFI_HELP_STR
13060 BGP_SAFI_WITH_LABEL_HELP_STR
13061 JSON_STR
13062 "Increase table width for longer prefixes\n")
13063 {
13064 afi_t afi = AFI_IP6;
13065 safi_t safi = SAFI_UNICAST;
13066 struct bgp *bgp = NULL;
13067 int idx = 0;
13068 uint16_t show_flags = 0;
13069
13070 if (uj) {
13071 argc--;
13072 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13073 }
13074
13075 if (wide)
13076 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13077
13078 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13079 &bgp, uj);
13080 if (!idx)
13081 return CMD_WARNING;
13082
13083 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13084 return CMD_SUCCESS;
13085 }
13086
13087 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13088 afi_t afi, safi_t safi, enum bgp_show_type type,
13089 bool use_json)
13090 {
13091 regex_t *regex;
13092 int rc;
13093 uint16_t show_flags = 0;
13094
13095 if (use_json)
13096 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13097
13098 if (!config_bgp_aspath_validate(regstr)) {
13099 vty_out(vty, "Invalid character in REGEX %s\n",
13100 regstr);
13101 return CMD_WARNING_CONFIG_FAILED;
13102 }
13103
13104 regex = bgp_regcomp(regstr);
13105 if (!regex) {
13106 vty_out(vty, "Can't compile regexp %s\n", regstr);
13107 return CMD_WARNING;
13108 }
13109
13110 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13111 RPKI_NOT_BEING_USED);
13112 bgp_regex_free(regex);
13113 return rc;
13114 }
13115
13116 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13117 const char *comstr, int exact, afi_t afi,
13118 safi_t safi, uint16_t show_flags)
13119 {
13120 struct community *com;
13121 int ret = 0;
13122
13123 com = community_str2com(comstr);
13124 if (!com) {
13125 vty_out(vty, "%% Community malformed: %s\n", comstr);
13126 return CMD_WARNING;
13127 }
13128
13129 ret = bgp_show(vty, bgp, afi, safi,
13130 (exact ? bgp_show_type_community_exact
13131 : bgp_show_type_community),
13132 com, show_flags, RPKI_NOT_BEING_USED);
13133 community_free(&com);
13134
13135 return ret;
13136 }
13137
13138 enum bgp_stats {
13139 BGP_STATS_MAXBITLEN = 0,
13140 BGP_STATS_RIB,
13141 BGP_STATS_PREFIXES,
13142 BGP_STATS_TOTPLEN,
13143 BGP_STATS_UNAGGREGATEABLE,
13144 BGP_STATS_MAX_AGGREGATEABLE,
13145 BGP_STATS_AGGREGATES,
13146 BGP_STATS_SPACE,
13147 BGP_STATS_ASPATH_COUNT,
13148 BGP_STATS_ASPATH_MAXHOPS,
13149 BGP_STATS_ASPATH_TOTHOPS,
13150 BGP_STATS_ASPATH_MAXSIZE,
13151 BGP_STATS_ASPATH_TOTSIZE,
13152 BGP_STATS_ASN_HIGHEST,
13153 BGP_STATS_MAX,
13154 };
13155
13156 #define TABLE_STATS_IDX_VTY 0
13157 #define TABLE_STATS_IDX_JSON 1
13158
13159 static const char *table_stats_strs[][2] = {
13160 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13161 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13162 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13163 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13164 "unaggregateablePrefixes"},
13165 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13166 "maximumAggregateablePrefixes"},
13167 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13168 "bgpAggregateAdvertisements"},
13169 [BGP_STATS_SPACE] = {"Address space advertised",
13170 "addressSpaceAdvertised"},
13171 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13172 "advertisementsWithPaths"},
13173 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13174 "longestAsPath"},
13175 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13176 "largestAsPath"},
13177 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13178 "averageAsPathLengthHops"},
13179 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13180 "averageAsPathSizeBytes"},
13181 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13182 [BGP_STATS_MAX] = {NULL, NULL}
13183 };
13184
13185 struct bgp_table_stats {
13186 struct bgp_table *table;
13187 unsigned long long counts[BGP_STATS_MAX];
13188
13189 unsigned long long
13190 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13191 1];
13192
13193 double total_space;
13194 };
13195
13196 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13197 struct bgp_table_stats *ts, unsigned int space)
13198 {
13199 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13200 struct bgp_path_info *pi;
13201 const struct prefix *rn_p;
13202
13203 if (!bgp_dest_has_bgp_path_info_data(dest))
13204 return;
13205
13206 rn_p = bgp_dest_get_prefix(dest);
13207 ts->counts[BGP_STATS_PREFIXES]++;
13208 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13209
13210 ts->prefix_len_count[rn_p->prefixlen]++;
13211 /* check if the prefix is included by any other announcements */
13212 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13213 pdest = bgp_dest_parent_nolock(pdest);
13214
13215 if (pdest == NULL || pdest == top) {
13216 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13217 /* announced address space */
13218 if (space)
13219 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13220 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13221 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13222
13223
13224 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13225 ts->counts[BGP_STATS_RIB]++;
13226
13227 if (CHECK_FLAG(pi->attr->flag,
13228 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13229 ts->counts[BGP_STATS_AGGREGATES]++;
13230
13231 /* as-path stats */
13232 if (pi->attr->aspath) {
13233 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13234 unsigned int size = aspath_size(pi->attr->aspath);
13235 as_t highest = aspath_highest(pi->attr->aspath);
13236
13237 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13238
13239 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13240 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13241
13242 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13243 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13244
13245 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13246 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13247 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13248 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13249 }
13250 }
13251 }
13252
13253 static void bgp_table_stats_walker(struct thread *t)
13254 {
13255 struct bgp_dest *dest, *ndest;
13256 struct bgp_dest *top;
13257 struct bgp_table_stats *ts = THREAD_ARG(t);
13258 unsigned int space = 0;
13259
13260 if (!(top = bgp_table_top(ts->table)))
13261 return;
13262
13263 switch (ts->table->afi) {
13264 case AFI_IP:
13265 space = IPV4_MAX_BITLEN;
13266 break;
13267 case AFI_IP6:
13268 space = IPV6_MAX_BITLEN;
13269 break;
13270 case AFI_L2VPN:
13271 space = EVPN_ROUTE_PREFIXLEN;
13272 break;
13273 default:
13274 return;
13275 }
13276
13277 ts->counts[BGP_STATS_MAXBITLEN] = space;
13278
13279 for (dest = top; dest; dest = bgp_route_next(dest)) {
13280 if (ts->table->safi == SAFI_MPLS_VPN
13281 || ts->table->safi == SAFI_ENCAP
13282 || ts->table->safi == SAFI_EVPN) {
13283 struct bgp_table *table;
13284
13285 table = bgp_dest_get_bgp_table_info(dest);
13286 if (!table)
13287 continue;
13288
13289 top = bgp_table_top(table);
13290 for (ndest = bgp_table_top(table); ndest;
13291 ndest = bgp_route_next(ndest))
13292 bgp_table_stats_rn(ndest, top, ts, space);
13293 } else {
13294 bgp_table_stats_rn(dest, top, ts, space);
13295 }
13296 }
13297 }
13298
13299 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13300 struct json_object *json_array)
13301 {
13302 struct listnode *node, *nnode;
13303 struct bgp *bgp;
13304
13305 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13306 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13307 }
13308
13309 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13310 safi_t safi, struct json_object *json_array)
13311 {
13312 struct bgp_table_stats ts;
13313 unsigned int i;
13314 int ret = CMD_SUCCESS;
13315 char temp_buf[20];
13316 struct json_object *json = NULL;
13317 uint32_t bitlen = 0;
13318 struct json_object *json_bitlen;
13319
13320 if (json_array)
13321 json = json_object_new_object();
13322
13323 if (!bgp->rib[afi][safi]) {
13324 char warning_msg[50];
13325
13326 snprintf(warning_msg, sizeof(warning_msg),
13327 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13328 safi);
13329
13330 if (!json)
13331 vty_out(vty, "%s\n", warning_msg);
13332 else
13333 json_object_string_add(json, "warning", warning_msg);
13334
13335 ret = CMD_WARNING;
13336 goto end_table_stats;
13337 }
13338
13339 if (!json)
13340 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13341 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13342 else
13343 json_object_string_add(json, "instance", bgp->name_pretty);
13344
13345 /* labeled-unicast routes live in the unicast table */
13346 if (safi == SAFI_LABELED_UNICAST)
13347 safi = SAFI_UNICAST;
13348
13349 memset(&ts, 0, sizeof(ts));
13350 ts.table = bgp->rib[afi][safi];
13351 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13352
13353 for (i = 0; i < BGP_STATS_MAX; i++) {
13354 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13355 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13356 continue;
13357
13358 switch (i) {
13359 case BGP_STATS_ASPATH_TOTHOPS:
13360 case BGP_STATS_ASPATH_TOTSIZE:
13361 if (!json) {
13362 snprintf(
13363 temp_buf, sizeof(temp_buf), "%12.2f",
13364 ts.counts[i]
13365 ? (float)ts.counts[i]
13366 / (float)ts.counts
13367 [BGP_STATS_ASPATH_COUNT]
13368 : 0);
13369 vty_out(vty, "%-30s: %s",
13370 table_stats_strs[i]
13371 [TABLE_STATS_IDX_VTY],
13372 temp_buf);
13373 } else {
13374 json_object_double_add(
13375 json,
13376 table_stats_strs[i]
13377 [TABLE_STATS_IDX_JSON],
13378 ts.counts[i]
13379 ? (double)ts.counts[i]
13380 / (double)ts.counts
13381 [BGP_STATS_ASPATH_COUNT]
13382 : 0);
13383 }
13384 break;
13385 case BGP_STATS_TOTPLEN:
13386 if (!json) {
13387 snprintf(
13388 temp_buf, sizeof(temp_buf), "%12.2f",
13389 ts.counts[i]
13390 ? (float)ts.counts[i]
13391 / (float)ts.counts
13392 [BGP_STATS_PREFIXES]
13393 : 0);
13394 vty_out(vty, "%-30s: %s",
13395 table_stats_strs[i]
13396 [TABLE_STATS_IDX_VTY],
13397 temp_buf);
13398 } else {
13399 json_object_double_add(
13400 json,
13401 table_stats_strs[i]
13402 [TABLE_STATS_IDX_JSON],
13403 ts.counts[i]
13404 ? (double)ts.counts[i]
13405 / (double)ts.counts
13406 [BGP_STATS_PREFIXES]
13407 : 0);
13408 }
13409 break;
13410 case BGP_STATS_SPACE:
13411 if (!json) {
13412 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13413 ts.total_space);
13414 vty_out(vty, "%-30s: %s\n",
13415 table_stats_strs[i]
13416 [TABLE_STATS_IDX_VTY],
13417 temp_buf);
13418 } else {
13419 json_object_double_add(
13420 json,
13421 table_stats_strs[i]
13422 [TABLE_STATS_IDX_JSON],
13423 (double)ts.total_space);
13424 }
13425 if (afi == AFI_IP6) {
13426 if (!json) {
13427 snprintf(temp_buf, sizeof(temp_buf),
13428 "%12g",
13429 ts.total_space
13430 * pow(2.0, -128 + 32));
13431 vty_out(vty, "%30s: %s\n",
13432 "/32 equivalent %s\n",
13433 temp_buf);
13434 } else {
13435 json_object_double_add(
13436 json, "/32equivalent",
13437 (double)(ts.total_space
13438 * pow(2.0,
13439 -128 + 32)));
13440 }
13441 if (!json) {
13442 snprintf(temp_buf, sizeof(temp_buf),
13443 "%12g",
13444 ts.total_space
13445 * pow(2.0, -128 + 48));
13446 vty_out(vty, "%30s: %s\n",
13447 "/48 equivalent %s\n",
13448 temp_buf);
13449 } else {
13450 json_object_double_add(
13451 json, "/48equivalent",
13452 (double)(ts.total_space
13453 * pow(2.0,
13454 -128 + 48)));
13455 }
13456 } else {
13457 if (!json) {
13458 snprintf(temp_buf, sizeof(temp_buf),
13459 "%12.2f",
13460 ts.total_space * 100.
13461 * pow(2.0, -32));
13462 vty_out(vty, "%30s: %s\n",
13463 "% announced ", temp_buf);
13464 } else {
13465 json_object_double_add(
13466 json, "%announced",
13467 (double)(ts.total_space * 100.
13468 * pow(2.0, -32)));
13469 }
13470 if (!json) {
13471 snprintf(temp_buf, sizeof(temp_buf),
13472 "%12.2f",
13473 ts.total_space
13474 * pow(2.0, -32 + 8));
13475 vty_out(vty, "%30s: %s\n",
13476 "/8 equivalent ", temp_buf);
13477 } else {
13478 json_object_double_add(
13479 json, "/8equivalent",
13480 (double)(ts.total_space
13481 * pow(2.0, -32 + 8)));
13482 }
13483 if (!json) {
13484 snprintf(temp_buf, sizeof(temp_buf),
13485 "%12.2f",
13486 ts.total_space
13487 * pow(2.0, -32 + 24));
13488 vty_out(vty, "%30s: %s\n",
13489 "/24 equivalent ", temp_buf);
13490 } else {
13491 json_object_double_add(
13492 json, "/24equivalent",
13493 (double)(ts.total_space
13494 * pow(2.0, -32 + 24)));
13495 }
13496 }
13497 break;
13498 default:
13499 if (!json) {
13500 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13501 ts.counts[i]);
13502 vty_out(vty, "%-30s: %s",
13503 table_stats_strs[i]
13504 [TABLE_STATS_IDX_VTY],
13505 temp_buf);
13506 } else {
13507 json_object_int_add(
13508 json,
13509 table_stats_strs[i]
13510 [TABLE_STATS_IDX_JSON],
13511 ts.counts[i]);
13512 }
13513 }
13514 if (!json)
13515 vty_out(vty, "\n");
13516 }
13517
13518 switch (afi) {
13519 case AFI_IP:
13520 bitlen = IPV4_MAX_BITLEN;
13521 break;
13522 case AFI_IP6:
13523 bitlen = IPV6_MAX_BITLEN;
13524 break;
13525 case AFI_L2VPN:
13526 bitlen = EVPN_ROUTE_PREFIXLEN;
13527 break;
13528 default:
13529 break;
13530 }
13531
13532 if (json) {
13533 json_bitlen = json_object_new_array();
13534
13535 for (i = 0; i <= bitlen; i++) {
13536 struct json_object *ind_bit = json_object_new_object();
13537
13538 if (!ts.prefix_len_count[i])
13539 continue;
13540
13541 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13542 json_object_int_add(ind_bit, temp_buf,
13543 ts.prefix_len_count[i]);
13544 json_object_array_add(json_bitlen, ind_bit);
13545 }
13546 json_object_object_add(json, "prefixLength", json_bitlen);
13547 }
13548
13549 end_table_stats:
13550 if (json)
13551 json_object_array_add(json_array, json);
13552 return ret;
13553 }
13554
13555 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13556 safi_t safi, struct json_object *json_array)
13557 {
13558 if (!bgp) {
13559 bgp_table_stats_all(vty, afi, safi, json_array);
13560 return CMD_SUCCESS;
13561 }
13562
13563 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13564 }
13565
13566 enum bgp_pcounts {
13567 PCOUNT_ADJ_IN = 0,
13568 PCOUNT_DAMPED,
13569 PCOUNT_REMOVED,
13570 PCOUNT_HISTORY,
13571 PCOUNT_STALE,
13572 PCOUNT_VALID,
13573 PCOUNT_ALL,
13574 PCOUNT_COUNTED,
13575 PCOUNT_BPATH_SELECTED,
13576 PCOUNT_PFCNT, /* the figure we display to users */
13577 PCOUNT_MAX,
13578 };
13579
13580 static const char *const pcount_strs[] = {
13581 [PCOUNT_ADJ_IN] = "Adj-in",
13582 [PCOUNT_DAMPED] = "Damped",
13583 [PCOUNT_REMOVED] = "Removed",
13584 [PCOUNT_HISTORY] = "History",
13585 [PCOUNT_STALE] = "Stale",
13586 [PCOUNT_VALID] = "Valid",
13587 [PCOUNT_ALL] = "All RIB",
13588 [PCOUNT_COUNTED] = "PfxCt counted",
13589 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13590 [PCOUNT_PFCNT] = "Useable",
13591 [PCOUNT_MAX] = NULL,
13592 };
13593
13594 struct peer_pcounts {
13595 unsigned int count[PCOUNT_MAX];
13596 const struct peer *peer;
13597 const struct bgp_table *table;
13598 safi_t safi;
13599 };
13600
13601 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13602 {
13603 const struct bgp_adj_in *ain;
13604 const struct bgp_path_info *pi;
13605 const struct peer *peer = pc->peer;
13606
13607 for (ain = rn->adj_in; ain; ain = ain->next)
13608 if (ain->peer == peer)
13609 pc->count[PCOUNT_ADJ_IN]++;
13610
13611 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13612
13613 if (pi->peer != peer)
13614 continue;
13615
13616 pc->count[PCOUNT_ALL]++;
13617
13618 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13619 pc->count[PCOUNT_DAMPED]++;
13620 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13621 pc->count[PCOUNT_HISTORY]++;
13622 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13623 pc->count[PCOUNT_REMOVED]++;
13624 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13625 pc->count[PCOUNT_STALE]++;
13626 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13627 pc->count[PCOUNT_VALID]++;
13628 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13629 pc->count[PCOUNT_PFCNT]++;
13630 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13631 pc->count[PCOUNT_BPATH_SELECTED]++;
13632
13633 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13634 pc->count[PCOUNT_COUNTED]++;
13635 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13636 flog_err(
13637 EC_LIB_DEVELOPMENT,
13638 "Attempting to count but flags say it is unusable");
13639 } else {
13640 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13641 flog_err(
13642 EC_LIB_DEVELOPMENT,
13643 "Not counted but flags say we should");
13644 }
13645 }
13646 }
13647
13648 static void bgp_peer_count_walker(struct thread *t)
13649 {
13650 struct bgp_dest *rn, *rm;
13651 const struct bgp_table *table;
13652 struct peer_pcounts *pc = THREAD_ARG(t);
13653
13654 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13655 || pc->safi == SAFI_EVPN) {
13656 /* Special handling for 2-level routing tables. */
13657 for (rn = bgp_table_top(pc->table); rn;
13658 rn = bgp_route_next(rn)) {
13659 table = bgp_dest_get_bgp_table_info(rn);
13660 if (table != NULL)
13661 for (rm = bgp_table_top(table); rm;
13662 rm = bgp_route_next(rm))
13663 bgp_peer_count_proc(rm, pc);
13664 }
13665 } else
13666 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13667 bgp_peer_count_proc(rn, pc);
13668 }
13669
13670 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13671 safi_t safi, bool use_json)
13672 {
13673 struct peer_pcounts pcounts = {.peer = peer};
13674 unsigned int i;
13675 json_object *json = NULL;
13676 json_object *json_loop = NULL;
13677
13678 if (use_json) {
13679 json = json_object_new_object();
13680 json_loop = json_object_new_object();
13681 }
13682
13683 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13684 || !peer->bgp->rib[afi][safi]) {
13685 if (use_json) {
13686 json_object_string_add(
13687 json, "warning",
13688 "No such neighbor or address family");
13689 vty_out(vty, "%s\n", json_object_to_json_string(json));
13690 json_object_free(json);
13691 json_object_free(json_loop);
13692 } else
13693 vty_out(vty, "%% No such neighbor or address family\n");
13694
13695 return CMD_WARNING;
13696 }
13697
13698 memset(&pcounts, 0, sizeof(pcounts));
13699 pcounts.peer = peer;
13700 pcounts.table = peer->bgp->rib[afi][safi];
13701 pcounts.safi = safi;
13702
13703 /* in-place call via thread subsystem so as to record execution time
13704 * stats for the thread-walk (i.e. ensure this can't be blamed on
13705 * on just vty_read()).
13706 */
13707 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13708
13709 if (use_json) {
13710 json_object_string_add(json, "prefixCountsFor", peer->host);
13711 json_object_string_add(json, "multiProtocol",
13712 get_afi_safi_str(afi, safi, true));
13713 json_object_int_add(json, "pfxCounter",
13714 peer->pcount[afi][safi]);
13715
13716 for (i = 0; i < PCOUNT_MAX; i++)
13717 json_object_int_add(json_loop, pcount_strs[i],
13718 pcounts.count[i]);
13719
13720 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13721
13722 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13723 json_object_string_add(json, "pfxctDriftFor",
13724 peer->host);
13725 json_object_string_add(
13726 json, "recommended",
13727 "Please report this bug, with the above command output");
13728 }
13729 vty_json(vty, json);
13730 } else {
13731
13732 if (peer->hostname
13733 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13734 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13735 peer->hostname, peer->host,
13736 get_afi_safi_str(afi, safi, false));
13737 } else {
13738 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13739 get_afi_safi_str(afi, safi, false));
13740 }
13741
13742 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13743 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13744
13745 for (i = 0; i < PCOUNT_MAX; i++)
13746 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13747 pcounts.count[i]);
13748
13749 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13750 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13751 vty_out(vty,
13752 "Please report this bug, with the above command output\n");
13753 }
13754 }
13755
13756 return CMD_SUCCESS;
13757 }
13758
13759 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13760 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13761 "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]",
13762 SHOW_STR
13763 IP_STR
13764 BGP_STR
13765 BGP_INSTANCE_HELP_STR
13766 BGP_AFI_HELP_STR
13767 BGP_SAFI_HELP_STR
13768 "Detailed information on TCP and BGP neighbor connections\n"
13769 "Neighbor to display information about\n"
13770 "Neighbor to display information about\n"
13771 "Neighbor on BGP configured interface\n"
13772 "Display detailed prefix count information\n"
13773 JSON_STR)
13774 {
13775 afi_t afi = AFI_IP6;
13776 safi_t safi = SAFI_UNICAST;
13777 struct peer *peer;
13778 int idx = 0;
13779 struct bgp *bgp = NULL;
13780 bool uj = use_json(argc, argv);
13781
13782 if (uj)
13783 argc--;
13784
13785 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13786 &bgp, uj);
13787 if (!idx)
13788 return CMD_WARNING;
13789
13790 argv_find(argv, argc, "neighbors", &idx);
13791 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13792 if (!peer)
13793 return CMD_WARNING;
13794
13795 return bgp_peer_counts(vty, peer, afi, safi, uj);
13796 }
13797
13798 #ifdef KEEP_OLD_VPN_COMMANDS
13799 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13800 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13801 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13802 SHOW_STR
13803 IP_STR
13804 BGP_STR
13805 BGP_VPNVX_HELP_STR
13806 "Display information about all VPNv4 NLRIs\n"
13807 "Detailed information on TCP and BGP neighbor connections\n"
13808 "Neighbor to display information about\n"
13809 "Neighbor to display information about\n"
13810 "Neighbor on BGP configured interface\n"
13811 "Display detailed prefix count information\n"
13812 JSON_STR)
13813 {
13814 int idx_peer = 6;
13815 struct peer *peer;
13816 bool uj = use_json(argc, argv);
13817
13818 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13819 if (!peer)
13820 return CMD_WARNING;
13821
13822 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13823 }
13824
13825 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13826 show_ip_bgp_vpn_all_route_prefix_cmd,
13827 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13828 SHOW_STR
13829 IP_STR
13830 BGP_STR
13831 BGP_VPNVX_HELP_STR
13832 "Display information about all VPNv4 NLRIs\n"
13833 "Network in the BGP routing table to display\n"
13834 "Network in the BGP routing table to display\n"
13835 JSON_STR)
13836 {
13837 int idx = 0;
13838 char *network = NULL;
13839 struct bgp *bgp = bgp_get_default();
13840 if (!bgp) {
13841 vty_out(vty, "Can't find default instance\n");
13842 return CMD_WARNING;
13843 }
13844
13845 if (argv_find(argv, argc, "A.B.C.D", &idx))
13846 network = argv[idx]->arg;
13847 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13848 network = argv[idx]->arg;
13849 else {
13850 vty_out(vty, "Unable to figure out Network\n");
13851 return CMD_WARNING;
13852 }
13853
13854 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13855 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13856 use_json(argc, argv));
13857 }
13858 #endif /* KEEP_OLD_VPN_COMMANDS */
13859
13860 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13861 show_bgp_l2vpn_evpn_route_prefix_cmd,
13862 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13863 SHOW_STR
13864 BGP_STR
13865 L2VPN_HELP_STR
13866 EVPN_HELP_STR
13867 "Network in the BGP routing table to display\n"
13868 "Network in the BGP routing table to display\n"
13869 "Network in the BGP routing table to display\n"
13870 "Network in the BGP routing table to display\n"
13871 JSON_STR)
13872 {
13873 int idx = 0;
13874 char *network = NULL;
13875 int prefix_check = 0;
13876
13877 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13878 argv_find(argv, argc, "X:X::X:X", &idx))
13879 network = argv[idx]->arg;
13880 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13881 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13882 network = argv[idx]->arg;
13883 prefix_check = 1;
13884 } else {
13885 vty_out(vty, "Unable to figure out Network\n");
13886 return CMD_WARNING;
13887 }
13888 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13889 prefix_check, BGP_PATH_SHOW_ALL,
13890 RPKI_NOT_BEING_USED, use_json(argc, argv));
13891 }
13892
13893 static void show_adj_route_header(struct vty *vty, struct peer *peer,
13894 struct bgp_table *table, int *header1,
13895 int *header2, json_object *json,
13896 json_object *json_scode,
13897 json_object *json_ocode, bool wide)
13898 {
13899 uint64_t version = table ? table->version : 0;
13900
13901 if (*header1) {
13902 if (json) {
13903 json_object_int_add(json, "bgpTableVersion", version);
13904 json_object_string_addf(json, "bgpLocalRouterId",
13905 "%pI4", &peer->bgp->router_id);
13906 json_object_int_add(json, "defaultLocPrf",
13907 peer->bgp->default_local_pref);
13908 json_object_int_add(json, "localAS",
13909 peer->change_local_as
13910 ? peer->change_local_as
13911 : peer->local_as);
13912 json_object_object_add(json, "bgpStatusCodes",
13913 json_scode);
13914 json_object_object_add(json, "bgpOriginCodes",
13915 json_ocode);
13916 } else {
13917 vty_out(vty,
13918 "BGP table version is %" PRIu64
13919 ", local router ID is %pI4, vrf id ",
13920 version, &peer->bgp->router_id);
13921 if (peer->bgp->vrf_id == VRF_UNKNOWN)
13922 vty_out(vty, "%s", VRFID_NONE_STR);
13923 else
13924 vty_out(vty, "%u", peer->bgp->vrf_id);
13925 vty_out(vty, "\n");
13926 vty_out(vty, "Default local pref %u, ",
13927 peer->bgp->default_local_pref);
13928 vty_out(vty, "local AS %u\n",
13929 peer->change_local_as ? peer->change_local_as
13930 : peer->local_as);
13931 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13932 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13933 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13934 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13935 }
13936 *header1 = 0;
13937 }
13938 if (*header2) {
13939 if (!json)
13940 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
13941 : BGP_SHOW_HEADER));
13942 *header2 = 0;
13943 }
13944 }
13945
13946 static void
13947 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
13948 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
13949 const char *rmap_name, json_object *json, json_object *json_ar,
13950 json_object *json_scode, json_object *json_ocode,
13951 uint16_t show_flags, int *header1, int *header2, char *rd_str,
13952 unsigned long *output_count, unsigned long *filtered_count)
13953 {
13954 struct bgp_adj_in *ain;
13955 struct bgp_adj_out *adj;
13956 struct bgp_dest *dest;
13957 struct bgp *bgp;
13958 struct attr attr;
13959 int ret;
13960 struct update_subgroup *subgrp;
13961 struct peer_af *paf;
13962 bool route_filtered;
13963 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13964 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13965 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13966 || (safi == SAFI_EVPN))
13967 ? true
13968 : false;
13969
13970 bgp = peer->bgp;
13971
13972 subgrp = peer_subgroup(peer, afi, safi);
13973
13974 if (type == bgp_show_adj_route_advertised && subgrp
13975 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
13976 if (use_json) {
13977 json_object_int_add(json, "bgpTableVersion",
13978 table->version);
13979 json_object_string_addf(json, "bgpLocalRouterId",
13980 "%pI4", &bgp->router_id);
13981 json_object_int_add(json, "defaultLocPrf",
13982 bgp->default_local_pref);
13983 json_object_int_add(json, "localAS",
13984 peer->change_local_as
13985 ? peer->change_local_as
13986 : peer->local_as);
13987 json_object_object_add(json, "bgpStatusCodes",
13988 json_scode);
13989 json_object_object_add(json, "bgpOriginCodes",
13990 json_ocode);
13991 json_object_string_add(
13992 json, "bgpOriginatingDefaultNetwork",
13993 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13994 } else {
13995 vty_out(vty,
13996 "BGP table version is %" PRIu64
13997 ", local router ID is %pI4, vrf id ",
13998 table->version, &bgp->router_id);
13999 if (bgp->vrf_id == VRF_UNKNOWN)
14000 vty_out(vty, "%s", VRFID_NONE_STR);
14001 else
14002 vty_out(vty, "%u", bgp->vrf_id);
14003 vty_out(vty, "\n");
14004 vty_out(vty, "Default local pref %u, ",
14005 bgp->default_local_pref);
14006 vty_out(vty, "local AS %u\n",
14007 peer->change_local_as ? peer->change_local_as
14008 : peer->local_as);
14009 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14010 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14011 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14012 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14013
14014 vty_out(vty, "Originating default network %s\n\n",
14015 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14016 }
14017 *header1 = 0;
14018 }
14019
14020 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14021 if (type == bgp_show_adj_route_received
14022 || type == bgp_show_adj_route_filtered) {
14023 for (ain = dest->adj_in; ain; ain = ain->next) {
14024 if (ain->peer != peer)
14025 continue;
14026
14027 show_adj_route_header(vty, peer, table, header1,
14028 header2, json, json_scode,
14029 json_ocode, wide);
14030
14031 if ((safi == SAFI_MPLS_VPN)
14032 || (safi == SAFI_ENCAP)
14033 || (safi == SAFI_EVPN)) {
14034 if (use_json)
14035 json_object_string_add(
14036 json_ar, "rd", rd_str);
14037 else if (show_rd && rd_str) {
14038 vty_out(vty,
14039 "Route Distinguisher: %s\n",
14040 rd_str);
14041 show_rd = false;
14042 }
14043 }
14044
14045 attr = *ain->attr;
14046 route_filtered = false;
14047
14048 /* Filter prefix using distribute list,
14049 * filter list or prefix list
14050 */
14051 const struct prefix *rn_p =
14052 bgp_dest_get_prefix(dest);
14053 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14054 safi))
14055 == FILTER_DENY)
14056 route_filtered = true;
14057
14058 /* Filter prefix using route-map */
14059 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14060 safi, rmap_name, NULL,
14061 0, NULL);
14062
14063 if (type == bgp_show_adj_route_filtered &&
14064 !route_filtered && ret != RMAP_DENY) {
14065 bgp_attr_flush(&attr);
14066 continue;
14067 }
14068
14069 if (type == bgp_show_adj_route_received
14070 && (route_filtered || ret == RMAP_DENY))
14071 (*filtered_count)++;
14072
14073 route_vty_out_tmp(vty, dest, rn_p, &attr, safi,
14074 use_json, json_ar, wide);
14075 bgp_attr_flush(&attr);
14076 (*output_count)++;
14077 }
14078 } else if (type == bgp_show_adj_route_advertised) {
14079 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14080 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14081 if (paf->peer != peer || !adj->attr)
14082 continue;
14083
14084 show_adj_route_header(vty, peer, table,
14085 header1, header2,
14086 json, json_scode,
14087 json_ocode, wide);
14088
14089 const struct prefix *rn_p =
14090 bgp_dest_get_prefix(dest);
14091
14092 attr = *adj->attr;
14093 ret = bgp_output_modifier(
14094 peer, rn_p, &attr, afi, safi,
14095 rmap_name);
14096
14097 if (ret != RMAP_DENY) {
14098 if ((safi == SAFI_MPLS_VPN)
14099 || (safi == SAFI_ENCAP)
14100 || (safi == SAFI_EVPN)) {
14101 if (use_json)
14102 json_object_string_add(
14103 json_ar,
14104 "rd",
14105 rd_str);
14106 else if (show_rd
14107 && rd_str) {
14108 vty_out(vty,
14109 "Route Distinguisher: %s\n",
14110 rd_str);
14111 show_rd = false;
14112 }
14113 }
14114 route_vty_out_tmp(
14115 vty, dest, rn_p, &attr,
14116 safi, use_json, json_ar,
14117 wide);
14118 (*output_count)++;
14119 } else {
14120 (*filtered_count)++;
14121 }
14122
14123 bgp_attr_flush(&attr);
14124 }
14125 } else if (type == bgp_show_adj_route_bestpath) {
14126 struct bgp_path_info *pi;
14127
14128 show_adj_route_header(vty, peer, table, header1,
14129 header2, json, json_scode,
14130 json_ocode, wide);
14131
14132 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14133 pi = pi->next) {
14134 if (pi->peer != peer)
14135 continue;
14136
14137 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14138 continue;
14139
14140 route_vty_out_tmp(vty, dest,
14141 bgp_dest_get_prefix(dest),
14142 pi->attr, safi, use_json,
14143 json_ar, wide);
14144 (*output_count)++;
14145 }
14146 }
14147 }
14148 }
14149
14150 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14151 safi_t safi, enum bgp_show_adj_route_type type,
14152 const char *rmap_name, uint16_t show_flags)
14153 {
14154 struct bgp *bgp;
14155 struct bgp_table *table;
14156 json_object *json = NULL;
14157 json_object *json_scode = NULL;
14158 json_object *json_ocode = NULL;
14159 json_object *json_ar = NULL;
14160 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14161
14162 /* Init BGP headers here so they're only displayed once
14163 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14164 */
14165 int header1 = 1;
14166 int header2 = 1;
14167
14168 /*
14169 * Initialize variables for each RD
14170 * All prefixes under an RD is aggregated within "json_routes"
14171 */
14172 char rd_str[BUFSIZ] = {0};
14173 json_object *json_routes = NULL;
14174
14175
14176 /* For 2-tier tables, prefix counts need to be
14177 * maintained across multiple runs of show_adj_route()
14178 */
14179 unsigned long output_count_per_rd;
14180 unsigned long filtered_count_per_rd;
14181 unsigned long output_count = 0;
14182 unsigned long filtered_count = 0;
14183
14184 if (use_json) {
14185 json = json_object_new_object();
14186 json_ar = json_object_new_object();
14187 json_scode = json_object_new_object();
14188 json_ocode = json_object_new_object();
14189
14190 json_object_string_add(json_scode, "suppressed", "s");
14191 json_object_string_add(json_scode, "damped", "d");
14192 json_object_string_add(json_scode, "history", "h");
14193 json_object_string_add(json_scode, "valid", "*");
14194 json_object_string_add(json_scode, "best", ">");
14195 json_object_string_add(json_scode, "multipath", "=");
14196 json_object_string_add(json_scode, "internal", "i");
14197 json_object_string_add(json_scode, "ribFailure", "r");
14198 json_object_string_add(json_scode, "stale", "S");
14199 json_object_string_add(json_scode, "removed", "R");
14200
14201 json_object_string_add(json_ocode, "igp", "i");
14202 json_object_string_add(json_ocode, "egp", "e");
14203 json_object_string_add(json_ocode, "incomplete", "?");
14204 }
14205
14206 if (!peer || !peer->afc[afi][safi]) {
14207 if (use_json) {
14208 json_object_string_add(
14209 json, "warning",
14210 "No such neighbor or address family");
14211 vty_out(vty, "%s\n", json_object_to_json_string(json));
14212 json_object_free(json);
14213 json_object_free(json_ar);
14214 json_object_free(json_scode);
14215 json_object_free(json_ocode);
14216 } else
14217 vty_out(vty, "%% No such neighbor or address family\n");
14218
14219 return CMD_WARNING;
14220 }
14221
14222 if ((type == bgp_show_adj_route_received
14223 || type == bgp_show_adj_route_filtered)
14224 && !CHECK_FLAG(peer->af_flags[afi][safi],
14225 PEER_FLAG_SOFT_RECONFIG)) {
14226 if (use_json) {
14227 json_object_string_add(
14228 json, "warning",
14229 "Inbound soft reconfiguration not enabled");
14230 vty_out(vty, "%s\n", json_object_to_json_string(json));
14231 json_object_free(json);
14232 json_object_free(json_ar);
14233 json_object_free(json_scode);
14234 json_object_free(json_ocode);
14235 } else
14236 vty_out(vty,
14237 "%% Inbound soft reconfiguration not enabled\n");
14238
14239 return CMD_WARNING;
14240 }
14241
14242 bgp = peer->bgp;
14243
14244 /* labeled-unicast routes live in the unicast table */
14245 if (safi == SAFI_LABELED_UNICAST)
14246 table = bgp->rib[afi][SAFI_UNICAST];
14247 else
14248 table = bgp->rib[afi][safi];
14249
14250 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14251 || (safi == SAFI_EVPN)) {
14252
14253 struct bgp_dest *dest;
14254
14255 for (dest = bgp_table_top(table); dest;
14256 dest = bgp_route_next(dest)) {
14257 table = bgp_dest_get_bgp_table_info(dest);
14258 if (!table)
14259 continue;
14260
14261 output_count_per_rd = 0;
14262 filtered_count_per_rd = 0;
14263
14264 if (use_json)
14265 json_routes = json_object_new_object();
14266
14267 const struct prefix_rd *prd;
14268 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14269 dest);
14270
14271 prefix_rd2str(prd, rd_str, sizeof(rd_str));
14272
14273 show_adj_route(vty, peer, table, afi, safi, type,
14274 rmap_name, json, json_routes, json_scode,
14275 json_ocode, show_flags, &header1,
14276 &header2, rd_str, &output_count_per_rd,
14277 &filtered_count_per_rd);
14278
14279 /* Don't include an empty RD in the output! */
14280 if (json_routes && (output_count_per_rd > 0))
14281 json_object_object_add(json_ar, rd_str,
14282 json_routes);
14283
14284 output_count += output_count_per_rd;
14285 filtered_count += filtered_count_per_rd;
14286 }
14287 } else
14288 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14289 json, json_ar, json_scode, json_ocode,
14290 show_flags, &header1, &header2, rd_str,
14291 &output_count, &filtered_count);
14292
14293 if (use_json) {
14294 if (type == bgp_show_adj_route_advertised)
14295 json_object_object_add(json, "advertisedRoutes",
14296 json_ar);
14297 else
14298 json_object_object_add(json, "receivedRoutes", json_ar);
14299 json_object_int_add(json, "totalPrefixCounter", output_count);
14300 json_object_int_add(json, "filteredPrefixCounter",
14301 filtered_count);
14302
14303 /*
14304 * These fields only give up ownership to `json` when `header1`
14305 * is used (set to zero). See code in `show_adj_route` and
14306 * `show_adj_route_header`.
14307 */
14308 if (header1 == 1) {
14309 json_object_free(json_scode);
14310 json_object_free(json_ocode);
14311 }
14312
14313 vty_json(vty, json);
14314 } else if (output_count > 0) {
14315 if (filtered_count > 0)
14316 vty_out(vty,
14317 "\nTotal number of prefixes %ld (%ld filtered)\n",
14318 output_count, filtered_count);
14319 else
14320 vty_out(vty, "\nTotal number of prefixes %ld\n",
14321 output_count);
14322 }
14323
14324 return CMD_SUCCESS;
14325 }
14326
14327 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14328 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14329 "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]",
14330 SHOW_STR
14331 IP_STR
14332 BGP_STR
14333 BGP_INSTANCE_HELP_STR
14334 BGP_AFI_HELP_STR
14335 BGP_SAFI_WITH_LABEL_HELP_STR
14336 "Detailed information on TCP and BGP neighbor connections\n"
14337 "Neighbor to display information about\n"
14338 "Neighbor to display information about\n"
14339 "Neighbor on BGP configured interface\n"
14340 "Display the routes selected by best path\n"
14341 JSON_STR
14342 "Increase table width for longer prefixes\n")
14343 {
14344 afi_t afi = AFI_IP6;
14345 safi_t safi = SAFI_UNICAST;
14346 char *rmap_name = NULL;
14347 char *peerstr = NULL;
14348 struct bgp *bgp = NULL;
14349 struct peer *peer;
14350 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14351 int idx = 0;
14352 uint16_t show_flags = 0;
14353
14354 if (uj)
14355 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14356
14357 if (wide)
14358 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14359
14360 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14361 &bgp, uj);
14362
14363 if (!idx)
14364 return CMD_WARNING;
14365
14366 argv_find(argv, argc, "neighbors", &idx);
14367 peerstr = argv[++idx]->arg;
14368
14369 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14370 if (!peer)
14371 return CMD_WARNING;
14372
14373 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14374 show_flags);
14375 }
14376
14377 DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
14378 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14379 "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] [json$uj | wide$wide]",
14380 SHOW_STR
14381 IP_STR
14382 BGP_STR
14383 BGP_INSTANCE_HELP_STR
14384 BGP_AFI_HELP_STR
14385 BGP_SAFI_WITH_LABEL_HELP_STR
14386 "Display the entries for all address families\n"
14387 "Detailed information on TCP and BGP neighbor connections\n"
14388 "Neighbor to display information about\n"
14389 "Neighbor to display information about\n"
14390 "Neighbor on BGP configured interface\n"
14391 "Display the routes advertised to a BGP neighbor\n"
14392 "Display the received routes from neighbor\n"
14393 "Display the filtered routes received from neighbor\n"
14394 "Route-map to modify the attributes\n"
14395 "Name of the route map\n"
14396 JSON_STR
14397 "Increase table width for longer prefixes\n")
14398 {
14399 afi_t afi = AFI_IP6;
14400 safi_t safi = SAFI_UNICAST;
14401 char *peerstr = NULL;
14402 struct bgp *bgp = NULL;
14403 struct peer *peer;
14404 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14405 int idx = 0;
14406 bool first = true;
14407 uint16_t show_flags = 0;
14408 struct listnode *node;
14409 struct bgp *abgp;
14410
14411 if (uj) {
14412 argc--;
14413 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14414 }
14415
14416 if (all) {
14417 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14418 if (argv_find(argv, argc, "ipv4", &idx))
14419 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14420
14421 if (argv_find(argv, argc, "ipv6", &idx))
14422 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14423 }
14424
14425 if (wide)
14426 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14427
14428 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14429 &bgp, uj);
14430 if (!idx)
14431 return CMD_WARNING;
14432
14433 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14434 argv_find(argv, argc, "neighbors", &idx);
14435 peerstr = argv[++idx]->arg;
14436
14437 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14438 if (!peer)
14439 return CMD_WARNING;
14440
14441 if (argv_find(argv, argc, "advertised-routes", &idx))
14442 type = bgp_show_adj_route_advertised;
14443 else if (argv_find(argv, argc, "received-routes", &idx))
14444 type = bgp_show_adj_route_received;
14445 else if (argv_find(argv, argc, "filtered-routes", &idx))
14446 type = bgp_show_adj_route_filtered;
14447
14448 if (!all)
14449 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14450 show_flags);
14451 if (uj)
14452 vty_out(vty, "{\n");
14453
14454 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14455 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14456 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14457 : AFI_IP6;
14458 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14459 FOREACH_SAFI (safi) {
14460 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14461 continue;
14462
14463 if (uj) {
14464 if (first)
14465 first = false;
14466 else
14467 vty_out(vty, ",\n");
14468 vty_out(vty, "\"%s\":",
14469 get_afi_safi_str(afi, safi,
14470 true));
14471 } else
14472 vty_out(vty,
14473 "\nFor address family: %s\n",
14474 get_afi_safi_str(afi, safi,
14475 false));
14476
14477 peer_adj_routes(vty, peer, afi, safi, type,
14478 route_map, show_flags);
14479 }
14480 }
14481 } else {
14482 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14483 FOREACH_AFI_SAFI (afi, safi) {
14484 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14485 continue;
14486
14487 if (uj) {
14488 if (first)
14489 first = false;
14490 else
14491 vty_out(vty, ",\n");
14492 vty_out(vty, "\"%s\":",
14493 get_afi_safi_str(afi, safi,
14494 true));
14495 } else
14496 vty_out(vty,
14497 "\nFor address family: %s\n",
14498 get_afi_safi_str(afi, safi,
14499 false));
14500
14501 peer_adj_routes(vty, peer, afi, safi, type,
14502 route_map, show_flags);
14503 }
14504 }
14505 }
14506 if (uj)
14507 vty_out(vty, "}\n");
14508
14509 return CMD_SUCCESS;
14510 }
14511
14512 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14513 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14514 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14515 SHOW_STR
14516 IP_STR
14517 BGP_STR
14518 BGP_INSTANCE_HELP_STR
14519 BGP_AF_STR
14520 BGP_AF_STR
14521 BGP_AF_MODIFIER_STR
14522 "Detailed information on TCP and BGP neighbor connections\n"
14523 "Neighbor to display information about\n"
14524 "Neighbor to display information about\n"
14525 "Neighbor on BGP configured interface\n"
14526 "Display information received from a BGP neighbor\n"
14527 "Display the prefixlist filter\n"
14528 JSON_STR)
14529 {
14530 afi_t afi = AFI_IP6;
14531 safi_t safi = SAFI_UNICAST;
14532 char *peerstr = NULL;
14533 char name[BUFSIZ];
14534 struct peer *peer;
14535 int count;
14536 int idx = 0;
14537 struct bgp *bgp = NULL;
14538 bool uj = use_json(argc, argv);
14539
14540 if (uj)
14541 argc--;
14542
14543 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14544 &bgp, uj);
14545 if (!idx)
14546 return CMD_WARNING;
14547
14548 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14549 argv_find(argv, argc, "neighbors", &idx);
14550 peerstr = argv[++idx]->arg;
14551
14552 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14553 if (!peer)
14554 return CMD_WARNING;
14555
14556 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14557 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14558 if (count) {
14559 if (!uj)
14560 vty_out(vty, "Address Family: %s\n",
14561 get_afi_safi_str(afi, safi, false));
14562 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14563 } else {
14564 if (uj)
14565 vty_out(vty, "{}\n");
14566 else
14567 vty_out(vty, "No functional output\n");
14568 }
14569
14570 return CMD_SUCCESS;
14571 }
14572
14573 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14574 afi_t afi, safi_t safi,
14575 enum bgp_show_type type, bool use_json)
14576 {
14577 uint16_t show_flags = 0;
14578
14579 if (use_json)
14580 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14581
14582 if (!peer || !peer->afc[afi][safi]) {
14583 if (use_json) {
14584 json_object *json_no = NULL;
14585 json_no = json_object_new_object();
14586 json_object_string_add(
14587 json_no, "warning",
14588 "No such neighbor or address family");
14589 vty_out(vty, "%s\n",
14590 json_object_to_json_string(json_no));
14591 json_object_free(json_no);
14592 } else
14593 vty_out(vty, "%% No such neighbor or address family\n");
14594 return CMD_WARNING;
14595 }
14596
14597 /* labeled-unicast routes live in the unicast table */
14598 if (safi == SAFI_LABELED_UNICAST)
14599 safi = SAFI_UNICAST;
14600
14601 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14602 RPKI_NOT_BEING_USED);
14603 }
14604
14605 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14606 show_ip_bgp_flowspec_routes_detailed_cmd,
14607 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14608 SHOW_STR
14609 IP_STR
14610 BGP_STR
14611 BGP_INSTANCE_HELP_STR
14612 BGP_AFI_HELP_STR
14613 "SAFI Flowspec\n"
14614 "Detailed information on flowspec entries\n"
14615 JSON_STR)
14616 {
14617 afi_t afi = AFI_IP6;
14618 safi_t safi = SAFI_UNICAST;
14619 struct bgp *bgp = NULL;
14620 int idx = 0;
14621 bool uj = use_json(argc, argv);
14622 uint16_t show_flags = BGP_SHOW_OPT_DETAIL;
14623
14624 if (uj) {
14625 argc--;
14626 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14627 }
14628
14629 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14630 &bgp, uj);
14631 if (!idx)
14632 return CMD_WARNING;
14633
14634 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14635 show_flags, RPKI_NOT_BEING_USED);
14636 }
14637
14638 DEFUN (show_ip_bgp_neighbor_routes,
14639 show_ip_bgp_neighbor_routes_cmd,
14640 "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]",
14641 SHOW_STR
14642 IP_STR
14643 BGP_STR
14644 BGP_INSTANCE_HELP_STR
14645 BGP_AFI_HELP_STR
14646 BGP_SAFI_WITH_LABEL_HELP_STR
14647 "Detailed information on TCP and BGP neighbor connections\n"
14648 "Neighbor to display information about\n"
14649 "Neighbor to display information about\n"
14650 "Neighbor on BGP configured interface\n"
14651 "Display flap statistics of the routes learned from neighbor\n"
14652 "Display the dampened routes received from neighbor\n"
14653 "Display routes learned from neighbor\n"
14654 JSON_STR)
14655 {
14656 char *peerstr = NULL;
14657 struct bgp *bgp = NULL;
14658 afi_t afi = AFI_IP6;
14659 safi_t safi = SAFI_UNICAST;
14660 struct peer *peer;
14661 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14662 int idx = 0;
14663 bool uj = use_json(argc, argv);
14664
14665 if (uj)
14666 argc--;
14667
14668 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14669 &bgp, uj);
14670 if (!idx)
14671 return CMD_WARNING;
14672
14673 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14674 argv_find(argv, argc, "neighbors", &idx);
14675 peerstr = argv[++idx]->arg;
14676
14677 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14678 if (!peer)
14679 return CMD_WARNING;
14680
14681 if (argv_find(argv, argc, "flap-statistics", &idx))
14682 sh_type = bgp_show_type_flap_neighbor;
14683 else if (argv_find(argv, argc, "dampened-routes", &idx))
14684 sh_type = bgp_show_type_damp_neighbor;
14685 else if (argv_find(argv, argc, "routes", &idx))
14686 sh_type = bgp_show_type_neighbor;
14687
14688 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14689 }
14690
14691 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14692
14693 struct bgp_distance {
14694 /* Distance value for the IP source prefix. */
14695 uint8_t distance;
14696
14697 /* Name of the access-list to be matched. */
14698 char *access_list;
14699 };
14700
14701 DEFUN (show_bgp_afi_vpn_rd_route,
14702 show_bgp_afi_vpn_rd_route_cmd,
14703 "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]",
14704 SHOW_STR
14705 BGP_STR
14706 BGP_AFI_HELP_STR
14707 BGP_AF_MODIFIER_STR
14708 "Display information for a route distinguisher\n"
14709 "Route Distinguisher\n"
14710 "All Route Distinguishers\n"
14711 "Network in the BGP routing table to display\n"
14712 "Network in the BGP routing table to display\n"
14713 JSON_STR)
14714 {
14715 int ret;
14716 struct prefix_rd prd;
14717 afi_t afi = AFI_MAX;
14718 int idx = 0;
14719
14720 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14721 vty_out(vty, "%% Malformed Address Family\n");
14722 return CMD_WARNING;
14723 }
14724
14725 if (!strcmp(argv[5]->arg, "all"))
14726 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14727 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14728 RPKI_NOT_BEING_USED,
14729 use_json(argc, argv));
14730
14731 ret = str2prefix_rd(argv[5]->arg, &prd);
14732 if (!ret) {
14733 vty_out(vty, "%% Malformed Route Distinguisher\n");
14734 return CMD_WARNING;
14735 }
14736
14737 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14738 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14739 use_json(argc, argv));
14740 }
14741
14742 static struct bgp_distance *bgp_distance_new(void)
14743 {
14744 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14745 }
14746
14747 static void bgp_distance_free(struct bgp_distance *bdistance)
14748 {
14749 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14750 }
14751
14752 static int bgp_distance_set(struct vty *vty, const char *distance_str,
14753 const char *ip_str, const char *access_list_str)
14754 {
14755 int ret;
14756 afi_t afi;
14757 safi_t safi;
14758 struct prefix p;
14759 uint8_t distance;
14760 struct bgp_dest *dest;
14761 struct bgp_distance *bdistance;
14762
14763 afi = bgp_node_afi(vty);
14764 safi = bgp_node_safi(vty);
14765
14766 ret = str2prefix(ip_str, &p);
14767 if (ret == 0) {
14768 vty_out(vty, "Malformed prefix\n");
14769 return CMD_WARNING_CONFIG_FAILED;
14770 }
14771
14772 distance = atoi(distance_str);
14773
14774 /* Get BGP distance node. */
14775 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
14776 bdistance = bgp_dest_get_bgp_distance_info(dest);
14777 if (bdistance)
14778 bgp_dest_unlock_node(dest);
14779 else {
14780 bdistance = bgp_distance_new();
14781 bgp_dest_set_bgp_distance_info(dest, bdistance);
14782 }
14783
14784 /* Set distance value. */
14785 bdistance->distance = distance;
14786
14787 /* Reset access-list configuration. */
14788 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14789 if (access_list_str)
14790 bdistance->access_list =
14791 XSTRDUP(MTYPE_AS_LIST, access_list_str);
14792
14793 return CMD_SUCCESS;
14794 }
14795
14796 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
14797 const char *ip_str, const char *access_list_str)
14798 {
14799 int ret;
14800 afi_t afi;
14801 safi_t safi;
14802 struct prefix p;
14803 int distance;
14804 struct bgp_dest *dest;
14805 struct bgp_distance *bdistance;
14806
14807 afi = bgp_node_afi(vty);
14808 safi = bgp_node_safi(vty);
14809
14810 ret = str2prefix(ip_str, &p);
14811 if (ret == 0) {
14812 vty_out(vty, "Malformed prefix\n");
14813 return CMD_WARNING_CONFIG_FAILED;
14814 }
14815
14816 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
14817 if (!dest) {
14818 vty_out(vty, "Can't find specified prefix\n");
14819 return CMD_WARNING_CONFIG_FAILED;
14820 }
14821
14822 bdistance = bgp_dest_get_bgp_distance_info(dest);
14823 distance = atoi(distance_str);
14824
14825 if (bdistance->distance != distance) {
14826 vty_out(vty, "Distance does not match configured\n");
14827 bgp_dest_unlock_node(dest);
14828 return CMD_WARNING_CONFIG_FAILED;
14829 }
14830
14831 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14832 bgp_distance_free(bdistance);
14833
14834 bgp_dest_set_bgp_path_info(dest, NULL);
14835 bgp_dest_unlock_node(dest);
14836 bgp_dest_unlock_node(dest);
14837
14838 return CMD_SUCCESS;
14839 }
14840
14841 /* Apply BGP information to distance method. */
14842 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
14843 afi_t afi, safi_t safi, struct bgp *bgp)
14844 {
14845 struct bgp_dest *dest;
14846 struct prefix q = {0};
14847 struct peer *peer;
14848 struct bgp_distance *bdistance;
14849 struct access_list *alist;
14850 struct bgp_static *bgp_static;
14851
14852 if (!bgp)
14853 return 0;
14854
14855 peer = pinfo->peer;
14856
14857 if (pinfo->attr->distance)
14858 return pinfo->attr->distance;
14859
14860 /* Check source address.
14861 * Note: for aggregate route, peer can have unspec af type.
14862 */
14863 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
14864 && !sockunion2hostprefix(&peer->su, &q))
14865 return 0;
14866
14867 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
14868 if (dest) {
14869 bdistance = bgp_dest_get_bgp_distance_info(dest);
14870 bgp_dest_unlock_node(dest);
14871
14872 if (bdistance->access_list) {
14873 alist = access_list_lookup(afi, bdistance->access_list);
14874 if (alist
14875 && access_list_apply(alist, p) == FILTER_PERMIT)
14876 return bdistance->distance;
14877 } else
14878 return bdistance->distance;
14879 }
14880
14881 /* Backdoor check. */
14882 dest = bgp_node_lookup(bgp->route[afi][safi], p);
14883 if (dest) {
14884 bgp_static = bgp_dest_get_bgp_static_info(dest);
14885 bgp_dest_unlock_node(dest);
14886
14887 if (bgp_static->backdoor) {
14888 if (bgp->distance_local[afi][safi])
14889 return bgp->distance_local[afi][safi];
14890 else
14891 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14892 }
14893 }
14894
14895 if (peer->sort == BGP_PEER_EBGP) {
14896 if (bgp->distance_ebgp[afi][safi])
14897 return bgp->distance_ebgp[afi][safi];
14898 return ZEBRA_EBGP_DISTANCE_DEFAULT;
14899 } else if (peer->sort == BGP_PEER_IBGP) {
14900 if (bgp->distance_ibgp[afi][safi])
14901 return bgp->distance_ibgp[afi][safi];
14902 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14903 } else {
14904 if (bgp->distance_local[afi][safi])
14905 return bgp->distance_local[afi][safi];
14906 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14907 }
14908 }
14909
14910 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
14911 * we should tell ZEBRA update the routes for a specific
14912 * AFI/SAFI to reflect changes in RIB.
14913 */
14914 static void bgp_announce_routes_distance_update(struct bgp *bgp,
14915 afi_t update_afi,
14916 safi_t update_safi)
14917 {
14918 afi_t afi;
14919 safi_t safi;
14920
14921 FOREACH_AFI_SAFI (afi, safi) {
14922 if (!bgp_fibupd_safi(safi))
14923 continue;
14924
14925 if (afi != update_afi && safi != update_safi)
14926 continue;
14927
14928 if (BGP_DEBUG(zebra, ZEBRA))
14929 zlog_debug(
14930 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
14931 __func__, afi, safi);
14932 bgp_zebra_announce_table(bgp, afi, safi);
14933 }
14934 }
14935
14936 DEFUN (bgp_distance,
14937 bgp_distance_cmd,
14938 "distance bgp (1-255) (1-255) (1-255)",
14939 "Define an administrative distance\n"
14940 "BGP distance\n"
14941 "Distance for routes external to the AS\n"
14942 "Distance for routes internal to the AS\n"
14943 "Distance for local routes\n")
14944 {
14945 VTY_DECLVAR_CONTEXT(bgp, bgp);
14946 int idx_number = 2;
14947 int idx_number_2 = 3;
14948 int idx_number_3 = 4;
14949 int distance_ebgp = atoi(argv[idx_number]->arg);
14950 int distance_ibgp = atoi(argv[idx_number_2]->arg);
14951 int distance_local = atoi(argv[idx_number_3]->arg);
14952 afi_t afi;
14953 safi_t safi;
14954
14955 afi = bgp_node_afi(vty);
14956 safi = bgp_node_safi(vty);
14957
14958 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
14959 || bgp->distance_ibgp[afi][safi] != distance_ibgp
14960 || bgp->distance_local[afi][safi] != distance_local) {
14961 bgp->distance_ebgp[afi][safi] = distance_ebgp;
14962 bgp->distance_ibgp[afi][safi] = distance_ibgp;
14963 bgp->distance_local[afi][safi] = distance_local;
14964 bgp_announce_routes_distance_update(bgp, afi, safi);
14965 }
14966 return CMD_SUCCESS;
14967 }
14968
14969 DEFUN (no_bgp_distance,
14970 no_bgp_distance_cmd,
14971 "no distance bgp [(1-255) (1-255) (1-255)]",
14972 NO_STR
14973 "Define an administrative distance\n"
14974 "BGP distance\n"
14975 "Distance for routes external to the AS\n"
14976 "Distance for routes internal to the AS\n"
14977 "Distance for local routes\n")
14978 {
14979 VTY_DECLVAR_CONTEXT(bgp, bgp);
14980 afi_t afi;
14981 safi_t safi;
14982
14983 afi = bgp_node_afi(vty);
14984 safi = bgp_node_safi(vty);
14985
14986 if (bgp->distance_ebgp[afi][safi] != 0
14987 || bgp->distance_ibgp[afi][safi] != 0
14988 || bgp->distance_local[afi][safi] != 0) {
14989 bgp->distance_ebgp[afi][safi] = 0;
14990 bgp->distance_ibgp[afi][safi] = 0;
14991 bgp->distance_local[afi][safi] = 0;
14992 bgp_announce_routes_distance_update(bgp, afi, safi);
14993 }
14994 return CMD_SUCCESS;
14995 }
14996
14997
14998 DEFUN (bgp_distance_source,
14999 bgp_distance_source_cmd,
15000 "distance (1-255) A.B.C.D/M",
15001 "Define an administrative distance\n"
15002 "Administrative distance\n"
15003 "IP source prefix\n")
15004 {
15005 int idx_number = 1;
15006 int idx_ipv4_prefixlen = 2;
15007 bgp_distance_set(vty, argv[idx_number]->arg,
15008 argv[idx_ipv4_prefixlen]->arg, NULL);
15009 return CMD_SUCCESS;
15010 }
15011
15012 DEFUN (no_bgp_distance_source,
15013 no_bgp_distance_source_cmd,
15014 "no distance (1-255) A.B.C.D/M",
15015 NO_STR
15016 "Define an administrative distance\n"
15017 "Administrative distance\n"
15018 "IP source prefix\n")
15019 {
15020 int idx_number = 2;
15021 int idx_ipv4_prefixlen = 3;
15022 bgp_distance_unset(vty, argv[idx_number]->arg,
15023 argv[idx_ipv4_prefixlen]->arg, NULL);
15024 return CMD_SUCCESS;
15025 }
15026
15027 DEFUN (bgp_distance_source_access_list,
15028 bgp_distance_source_access_list_cmd,
15029 "distance (1-255) A.B.C.D/M WORD",
15030 "Define an administrative distance\n"
15031 "Administrative distance\n"
15032 "IP source prefix\n"
15033 "Access list name\n")
15034 {
15035 int idx_number = 1;
15036 int idx_ipv4_prefixlen = 2;
15037 int idx_word = 3;
15038 bgp_distance_set(vty, argv[idx_number]->arg,
15039 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15040 return CMD_SUCCESS;
15041 }
15042
15043 DEFUN (no_bgp_distance_source_access_list,
15044 no_bgp_distance_source_access_list_cmd,
15045 "no distance (1-255) A.B.C.D/M WORD",
15046 NO_STR
15047 "Define an administrative distance\n"
15048 "Administrative distance\n"
15049 "IP source prefix\n"
15050 "Access list name\n")
15051 {
15052 int idx_number = 2;
15053 int idx_ipv4_prefixlen = 3;
15054 int idx_word = 4;
15055 bgp_distance_unset(vty, argv[idx_number]->arg,
15056 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15057 return CMD_SUCCESS;
15058 }
15059
15060 DEFUN (ipv6_bgp_distance_source,
15061 ipv6_bgp_distance_source_cmd,
15062 "distance (1-255) X:X::X:X/M",
15063 "Define an administrative distance\n"
15064 "Administrative distance\n"
15065 "IP source prefix\n")
15066 {
15067 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15068 return CMD_SUCCESS;
15069 }
15070
15071 DEFUN (no_ipv6_bgp_distance_source,
15072 no_ipv6_bgp_distance_source_cmd,
15073 "no distance (1-255) X:X::X:X/M",
15074 NO_STR
15075 "Define an administrative distance\n"
15076 "Administrative distance\n"
15077 "IP source prefix\n")
15078 {
15079 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15080 return CMD_SUCCESS;
15081 }
15082
15083 DEFUN (ipv6_bgp_distance_source_access_list,
15084 ipv6_bgp_distance_source_access_list_cmd,
15085 "distance (1-255) X:X::X:X/M WORD",
15086 "Define an administrative distance\n"
15087 "Administrative distance\n"
15088 "IP source prefix\n"
15089 "Access list name\n")
15090 {
15091 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15092 return CMD_SUCCESS;
15093 }
15094
15095 DEFUN (no_ipv6_bgp_distance_source_access_list,
15096 no_ipv6_bgp_distance_source_access_list_cmd,
15097 "no distance (1-255) X:X::X:X/M WORD",
15098 NO_STR
15099 "Define an administrative distance\n"
15100 "Administrative distance\n"
15101 "IP source prefix\n"
15102 "Access list name\n")
15103 {
15104 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15105 return CMD_SUCCESS;
15106 }
15107
15108 DEFUN (bgp_damp_set,
15109 bgp_damp_set_cmd,
15110 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15111 "BGP Specific commands\n"
15112 "Enable route-flap dampening\n"
15113 "Half-life time for the penalty\n"
15114 "Value to start reusing a route\n"
15115 "Value to start suppressing a route\n"
15116 "Maximum duration to suppress a stable route\n")
15117 {
15118 VTY_DECLVAR_CONTEXT(bgp, bgp);
15119 int idx_half_life = 2;
15120 int idx_reuse = 3;
15121 int idx_suppress = 4;
15122 int idx_max_suppress = 5;
15123 int half = DEFAULT_HALF_LIFE * 60;
15124 int reuse = DEFAULT_REUSE;
15125 int suppress = DEFAULT_SUPPRESS;
15126 int max = 4 * half;
15127
15128 if (argc == 6) {
15129 half = atoi(argv[idx_half_life]->arg) * 60;
15130 reuse = atoi(argv[idx_reuse]->arg);
15131 suppress = atoi(argv[idx_suppress]->arg);
15132 max = atoi(argv[idx_max_suppress]->arg) * 60;
15133 } else if (argc == 3) {
15134 half = atoi(argv[idx_half_life]->arg) * 60;
15135 max = 4 * half;
15136 }
15137
15138 /*
15139 * These can't be 0 but our SA doesn't understand the
15140 * way our cli is constructed
15141 */
15142 assert(reuse);
15143 assert(half);
15144 if (suppress < reuse) {
15145 vty_out(vty,
15146 "Suppress value cannot be less than reuse value \n");
15147 return 0;
15148 }
15149
15150 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15151 reuse, suppress, max);
15152 }
15153
15154 DEFUN (bgp_damp_unset,
15155 bgp_damp_unset_cmd,
15156 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15157 NO_STR
15158 "BGP Specific commands\n"
15159 "Enable route-flap dampening\n"
15160 "Half-life time for the penalty\n"
15161 "Value to start reusing a route\n"
15162 "Value to start suppressing a route\n"
15163 "Maximum duration to suppress a stable route\n")
15164 {
15165 VTY_DECLVAR_CONTEXT(bgp, bgp);
15166 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15167 }
15168
15169 /* Display specified route of BGP table. */
15170 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15171 const char *ip_str, afi_t afi, safi_t safi,
15172 struct prefix_rd *prd, int prefix_check)
15173 {
15174 int ret;
15175 struct prefix match;
15176 struct bgp_dest *dest;
15177 struct bgp_dest *rm;
15178 struct bgp_path_info *pi;
15179 struct bgp_path_info *pi_temp;
15180 struct bgp *bgp;
15181 struct bgp_table *table;
15182
15183 /* BGP structure lookup. */
15184 if (view_name) {
15185 bgp = bgp_lookup_by_name(view_name);
15186 if (bgp == NULL) {
15187 vty_out(vty, "%% Can't find BGP instance %s\n",
15188 view_name);
15189 return CMD_WARNING;
15190 }
15191 } else {
15192 bgp = bgp_get_default();
15193 if (bgp == NULL) {
15194 vty_out(vty, "%% No BGP process is configured\n");
15195 return CMD_WARNING;
15196 }
15197 }
15198
15199 /* Check IP address argument. */
15200 ret = str2prefix(ip_str, &match);
15201 if (!ret) {
15202 vty_out(vty, "%% address is malformed\n");
15203 return CMD_WARNING;
15204 }
15205
15206 match.family = afi2family(afi);
15207
15208 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15209 || (safi == SAFI_EVPN)) {
15210 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15211 dest = bgp_route_next(dest)) {
15212 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15213
15214 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15215 continue;
15216 table = bgp_dest_get_bgp_table_info(dest);
15217 if (!table)
15218 continue;
15219 rm = bgp_node_match(table, &match);
15220 if (rm == NULL)
15221 continue;
15222
15223 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15224
15225 if (!prefix_check
15226 || rm_p->prefixlen == match.prefixlen) {
15227 pi = bgp_dest_get_bgp_path_info(rm);
15228 while (pi) {
15229 if (pi->extra && pi->extra->damp_info) {
15230 pi_temp = pi->next;
15231 bgp_damp_info_free(
15232 pi->extra->damp_info,
15233 1, afi, safi);
15234 pi = pi_temp;
15235 } else
15236 pi = pi->next;
15237 }
15238 }
15239
15240 bgp_dest_unlock_node(rm);
15241 }
15242 } else {
15243 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15244 if (dest != NULL) {
15245 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15246
15247 if (!prefix_check
15248 || dest_p->prefixlen == match.prefixlen) {
15249 pi = bgp_dest_get_bgp_path_info(dest);
15250 while (pi) {
15251 if (pi->extra && pi->extra->damp_info) {
15252 pi_temp = pi->next;
15253 bgp_damp_info_free(
15254 pi->extra->damp_info,
15255 1, afi, safi);
15256 pi = pi_temp;
15257 } else
15258 pi = pi->next;
15259 }
15260 }
15261
15262 bgp_dest_unlock_node(dest);
15263 }
15264 }
15265
15266 return CMD_SUCCESS;
15267 }
15268
15269 DEFUN (clear_ip_bgp_dampening,
15270 clear_ip_bgp_dampening_cmd,
15271 "clear ip bgp dampening",
15272 CLEAR_STR
15273 IP_STR
15274 BGP_STR
15275 "Clear route flap dampening information\n")
15276 {
15277 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15278 return CMD_SUCCESS;
15279 }
15280
15281 DEFUN (clear_ip_bgp_dampening_prefix,
15282 clear_ip_bgp_dampening_prefix_cmd,
15283 "clear ip bgp dampening A.B.C.D/M",
15284 CLEAR_STR
15285 IP_STR
15286 BGP_STR
15287 "Clear route flap dampening information\n"
15288 "IPv4 prefix\n")
15289 {
15290 int idx_ipv4_prefixlen = 4;
15291 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15292 AFI_IP, SAFI_UNICAST, NULL, 1);
15293 }
15294
15295 DEFUN (clear_ip_bgp_dampening_address,
15296 clear_ip_bgp_dampening_address_cmd,
15297 "clear ip bgp dampening A.B.C.D",
15298 CLEAR_STR
15299 IP_STR
15300 BGP_STR
15301 "Clear route flap dampening information\n"
15302 "Network to clear damping information\n")
15303 {
15304 int idx_ipv4 = 4;
15305 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15306 SAFI_UNICAST, NULL, 0);
15307 }
15308
15309 DEFUN (clear_ip_bgp_dampening_address_mask,
15310 clear_ip_bgp_dampening_address_mask_cmd,
15311 "clear ip bgp dampening A.B.C.D A.B.C.D",
15312 CLEAR_STR
15313 IP_STR
15314 BGP_STR
15315 "Clear route flap dampening information\n"
15316 "Network to clear damping information\n"
15317 "Network mask\n")
15318 {
15319 int idx_ipv4 = 4;
15320 int idx_ipv4_2 = 5;
15321 int ret;
15322 char prefix_str[BUFSIZ];
15323
15324 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15325 prefix_str, sizeof(prefix_str));
15326 if (!ret) {
15327 vty_out(vty, "%% Inconsistent address and mask\n");
15328 return CMD_WARNING;
15329 }
15330
15331 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15332 NULL, 0);
15333 }
15334
15335 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15336 {
15337 struct vty *vty = arg;
15338 struct peer *peer = bucket->data;
15339
15340 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15341 }
15342
15343 DEFUN (show_bgp_listeners,
15344 show_bgp_listeners_cmd,
15345 "show bgp listeners",
15346 SHOW_STR
15347 BGP_STR
15348 "Display Listen Sockets and who created them\n")
15349 {
15350 bgp_dump_listener_info(vty);
15351
15352 return CMD_SUCCESS;
15353 }
15354
15355 DEFUN (show_bgp_peerhash,
15356 show_bgp_peerhash_cmd,
15357 "show bgp peerhash",
15358 SHOW_STR
15359 BGP_STR
15360 "Display information about the BGP peerhash\n")
15361 {
15362 struct list *instances = bm->bgp;
15363 struct listnode *node;
15364 struct bgp *bgp;
15365
15366 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15367 vty_out(vty, "BGP: %s\n", bgp->name);
15368 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15369 vty);
15370 }
15371
15372 return CMD_SUCCESS;
15373 }
15374
15375 /* also used for encap safi */
15376 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15377 afi_t afi, safi_t safi)
15378 {
15379 struct bgp_dest *pdest;
15380 struct bgp_dest *dest;
15381 struct bgp_table *table;
15382 const struct prefix *p;
15383 const struct prefix_rd *prd;
15384 struct bgp_static *bgp_static;
15385 mpls_label_t label;
15386
15387 /* Network configuration. */
15388 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15389 pdest = bgp_route_next(pdest)) {
15390 table = bgp_dest_get_bgp_table_info(pdest);
15391 if (!table)
15392 continue;
15393
15394 for (dest = bgp_table_top(table); dest;
15395 dest = bgp_route_next(dest)) {
15396 bgp_static = bgp_dest_get_bgp_static_info(dest);
15397 if (bgp_static == NULL)
15398 continue;
15399
15400 p = bgp_dest_get_prefix(dest);
15401 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
15402 pdest);
15403
15404 /* "network" configuration display. */
15405 label = decode_label(&bgp_static->label);
15406
15407 vty_out(vty, " network %pFX rd %pRD", p, prd);
15408 if (safi == SAFI_MPLS_VPN)
15409 vty_out(vty, " label %u", label);
15410
15411 if (bgp_static->rmap.name)
15412 vty_out(vty, " route-map %s",
15413 bgp_static->rmap.name);
15414
15415 if (bgp_static->backdoor)
15416 vty_out(vty, " backdoor");
15417
15418 vty_out(vty, "\n");
15419 }
15420 }
15421 }
15422
15423 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15424 afi_t afi, safi_t safi)
15425 {
15426 struct bgp_dest *pdest;
15427 struct bgp_dest *dest;
15428 struct bgp_table *table;
15429 const struct prefix *p;
15430 const struct prefix_rd *prd;
15431 struct bgp_static *bgp_static;
15432 char buf[PREFIX_STRLEN * 2];
15433 char buf2[SU_ADDRSTRLEN];
15434 char esi_buf[ESI_STR_LEN];
15435
15436 /* Network configuration. */
15437 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15438 pdest = bgp_route_next(pdest)) {
15439 table = bgp_dest_get_bgp_table_info(pdest);
15440 if (!table)
15441 continue;
15442
15443 for (dest = bgp_table_top(table); dest;
15444 dest = bgp_route_next(dest)) {
15445 bgp_static = bgp_dest_get_bgp_static_info(dest);
15446 if (bgp_static == NULL)
15447 continue;
15448
15449 char *macrouter = NULL;
15450
15451 if (bgp_static->router_mac)
15452 macrouter = prefix_mac2str(
15453 bgp_static->router_mac, NULL, 0);
15454 if (bgp_static->eth_s_id)
15455 esi_to_str(bgp_static->eth_s_id,
15456 esi_buf, sizeof(esi_buf));
15457 p = bgp_dest_get_prefix(dest);
15458 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
15459
15460 /* "network" configuration display. */
15461 if (p->u.prefix_evpn.route_type == 5) {
15462 char local_buf[PREFIX_STRLEN];
15463 uint8_t family = is_evpn_prefix_ipaddr_v4((
15464 struct prefix_evpn *)p)
15465 ? AF_INET
15466 : AF_INET6;
15467 inet_ntop(family,
15468 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
15469 local_buf, PREFIX_STRLEN);
15470 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15471 p->u.prefix_evpn.prefix_addr
15472 .ip_prefix_length);
15473 } else {
15474 prefix2str(p, buf, sizeof(buf));
15475 }
15476
15477 if (bgp_static->gatewayIp.family == AF_INET
15478 || bgp_static->gatewayIp.family == AF_INET6)
15479 inet_ntop(bgp_static->gatewayIp.family,
15480 &bgp_static->gatewayIp.u.prefix, buf2,
15481 sizeof(buf2));
15482 vty_out(vty,
15483 " network %s rd %pRD ethtag %u label %u esi %s gwip %s routermac %s\n",
15484 buf, prd, p->u.prefix_evpn.prefix_addr.eth_tag,
15485 decode_label(&bgp_static->label), esi_buf, buf2,
15486 macrouter);
15487
15488 XFREE(MTYPE_TMP, macrouter);
15489 }
15490 }
15491 }
15492
15493 /* Configuration of static route announcement and aggregate
15494 information. */
15495 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15496 safi_t safi)
15497 {
15498 struct bgp_dest *dest;
15499 const struct prefix *p;
15500 struct bgp_static *bgp_static;
15501 struct bgp_aggregate *bgp_aggregate;
15502
15503 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15504 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15505 return;
15506 }
15507
15508 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15509 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15510 return;
15511 }
15512
15513 /* Network configuration. */
15514 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15515 dest = bgp_route_next(dest)) {
15516 bgp_static = bgp_dest_get_bgp_static_info(dest);
15517 if (bgp_static == NULL)
15518 continue;
15519
15520 p = bgp_dest_get_prefix(dest);
15521
15522 vty_out(vty, " network %pFX", p);
15523
15524 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15525 vty_out(vty, " label-index %u",
15526 bgp_static->label_index);
15527
15528 if (bgp_static->rmap.name)
15529 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15530
15531 if (bgp_static->backdoor)
15532 vty_out(vty, " backdoor");
15533
15534 vty_out(vty, "\n");
15535 }
15536
15537 /* Aggregate-address configuration. */
15538 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15539 dest = bgp_route_next(dest)) {
15540 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15541 if (bgp_aggregate == NULL)
15542 continue;
15543
15544 p = bgp_dest_get_prefix(dest);
15545
15546 vty_out(vty, " aggregate-address %pFX", p);
15547
15548 if (bgp_aggregate->as_set)
15549 vty_out(vty, " as-set");
15550
15551 if (bgp_aggregate->summary_only)
15552 vty_out(vty, " summary-only");
15553
15554 if (bgp_aggregate->rmap.name)
15555 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15556
15557 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15558 vty_out(vty, " origin %s",
15559 bgp_origin2str(bgp_aggregate->origin));
15560
15561 if (bgp_aggregate->match_med)
15562 vty_out(vty, " matching-MED-only");
15563
15564 if (bgp_aggregate->suppress_map_name)
15565 vty_out(vty, " suppress-map %s",
15566 bgp_aggregate->suppress_map_name);
15567
15568 vty_out(vty, "\n");
15569 }
15570 }
15571
15572 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15573 safi_t safi)
15574 {
15575 struct bgp_dest *dest;
15576 struct bgp_distance *bdistance;
15577
15578 /* Distance configuration. */
15579 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15580 && bgp->distance_local[afi][safi]
15581 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15582 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15583 || bgp->distance_local[afi][safi]
15584 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15585 vty_out(vty, " distance bgp %d %d %d\n",
15586 bgp->distance_ebgp[afi][safi],
15587 bgp->distance_ibgp[afi][safi],
15588 bgp->distance_local[afi][safi]);
15589 }
15590
15591 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15592 dest = bgp_route_next(dest)) {
15593 bdistance = bgp_dest_get_bgp_distance_info(dest);
15594 if (bdistance != NULL)
15595 vty_out(vty, " distance %d %pBD %s\n",
15596 bdistance->distance, dest,
15597 bdistance->access_list ? bdistance->access_list
15598 : "");
15599 }
15600 }
15601
15602 /* Allocate routing table structure and install commands. */
15603 void bgp_route_init(void)
15604 {
15605 afi_t afi;
15606 safi_t safi;
15607
15608 /* Init BGP distance table. */
15609 FOREACH_AFI_SAFI (afi, safi)
15610 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15611
15612 /* IPv4 BGP commands. */
15613 install_element(BGP_NODE, &bgp_table_map_cmd);
15614 install_element(BGP_NODE, &bgp_network_cmd);
15615 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15616
15617 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15618
15619 /* IPv4 unicast configuration. */
15620 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15621 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15622 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15623
15624 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15625
15626 /* IPv4 multicast configuration. */
15627 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15628 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15629 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15630 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15631
15632 /* IPv4 labeled-unicast configuration. */
15633 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15634 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15635
15636 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15637 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15638 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15639 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15640 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15641 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15642 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15643 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15644
15645 install_element(VIEW_NODE,
15646 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15647 install_element(VIEW_NODE,
15648 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15649 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15650 install_element(VIEW_NODE,
15651 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15652 #ifdef KEEP_OLD_VPN_COMMANDS
15653 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15654 #endif /* KEEP_OLD_VPN_COMMANDS */
15655 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15656 install_element(VIEW_NODE,
15657 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15658
15659 /* BGP dampening clear commands */
15660 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15661 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15662
15663 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15664 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15665
15666 /* prefix count */
15667 install_element(ENABLE_NODE,
15668 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15669 #ifdef KEEP_OLD_VPN_COMMANDS
15670 install_element(ENABLE_NODE,
15671 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15672 #endif /* KEEP_OLD_VPN_COMMANDS */
15673
15674 /* New config IPv6 BGP commands. */
15675 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15676 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15677 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15678
15679 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15680
15681 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15682
15683 /* IPv6 labeled unicast address family. */
15684 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15685 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15686
15687 install_element(BGP_NODE, &bgp_distance_cmd);
15688 install_element(BGP_NODE, &no_bgp_distance_cmd);
15689 install_element(BGP_NODE, &bgp_distance_source_cmd);
15690 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15691 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15692 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15693 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15694 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15695 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15696 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15697 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15698 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15699 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15700 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15701 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15702 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15703 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15704 install_element(BGP_IPV4M_NODE,
15705 &no_bgp_distance_source_access_list_cmd);
15706 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15707 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15708 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15709 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15710 install_element(BGP_IPV6_NODE,
15711 &ipv6_bgp_distance_source_access_list_cmd);
15712 install_element(BGP_IPV6_NODE,
15713 &no_ipv6_bgp_distance_source_access_list_cmd);
15714 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15715 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15716 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15717 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15718 install_element(BGP_IPV6M_NODE,
15719 &ipv6_bgp_distance_source_access_list_cmd);
15720 install_element(BGP_IPV6M_NODE,
15721 &no_ipv6_bgp_distance_source_access_list_cmd);
15722
15723 /* BGP dampening */
15724 install_element(BGP_NODE, &bgp_damp_set_cmd);
15725 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15726 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15727 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15728 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15729 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15730 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15731 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15732 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15733 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15734 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15735 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15736 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15737 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15738
15739 /* Large Communities */
15740 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15741 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15742
15743 /* show bgp ipv4 flowspec detailed */
15744 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15745
15746 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15747 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15748 }
15749
15750 void bgp_route_finish(void)
15751 {
15752 afi_t afi;
15753 safi_t safi;
15754
15755 FOREACH_AFI_SAFI (afi, safi) {
15756 bgp_table_unlock(bgp_distance_table[afi][safi]);
15757 bgp_distance_table[afi][safi] = NULL;
15758 }
15759 }