]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
a2792b9b795ef233773f1e6951ff9f775cd54a4c
[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 #include "bgpd/bgp_route_clippy.c"
94
95 DEFINE_HOOK(bgp_snmp_update_stats,
96 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
97 (rn, pi, added));
98
99 DEFINE_HOOK(bgp_rpki_prefix_status,
100 (struct peer *peer, struct attr *attr,
101 const struct prefix *prefix),
102 (peer, attr, prefix));
103
104 /* Extern from bgp_dump.c */
105 extern const char *bgp_origin_str[];
106 extern const char *bgp_origin_long_str[];
107
108 /* PMSI strings. */
109 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
110 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
111 static const struct message bgp_pmsi_tnltype_str[] = {
112 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
113 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
114 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
115 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
116 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
117 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
118 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
119 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
120 {0}
121 };
122
123 #define VRFID_NONE_STR "-"
124 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
125
126 DEFINE_HOOK(bgp_process,
127 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
128 struct peer *peer, bool withdraw),
129 (bgp, afi, safi, bn, peer, withdraw));
130
131 /** Test if path is suppressed. */
132 static bool bgp_path_suppressed(struct bgp_path_info *pi)
133 {
134 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
135 return false;
136
137 return listcount(pi->extra->aggr_suppressors) > 0;
138 }
139
140 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
141 safi_t safi, const struct prefix *p,
142 struct prefix_rd *prd)
143 {
144 struct bgp_dest *dest;
145 struct bgp_dest *pdest = NULL;
146
147 assert(table);
148
149 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
150 || (safi == SAFI_EVPN)) {
151 pdest = bgp_node_get(table, (struct prefix *)prd);
152
153 if (!bgp_dest_has_bgp_path_info_data(pdest))
154 bgp_dest_set_bgp_table_info(
155 pdest, bgp_table_init(table->bgp, afi, safi));
156 else
157 bgp_dest_unlock_node(pdest);
158 table = bgp_dest_get_bgp_table_info(pdest);
159 }
160
161 dest = bgp_node_get(table, p);
162
163 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
164 || (safi == SAFI_EVPN))
165 dest->pdest = pdest;
166
167 return dest;
168 }
169
170 struct bgp_dest *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
171 safi_t safi, const struct prefix *p,
172 struct prefix_rd *prd)
173 {
174 struct bgp_dest *dest;
175 struct bgp_dest *pdest = NULL;
176
177 if (!table)
178 return NULL;
179
180 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
181 || (safi == SAFI_EVPN)) {
182 pdest = bgp_node_lookup(table, (struct prefix *)prd);
183 if (!pdest)
184 return NULL;
185
186 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
187 bgp_dest_unlock_node(pdest);
188 return NULL;
189 }
190
191 table = bgp_dest_get_bgp_table_info(pdest);
192 }
193
194 dest = bgp_node_lookup(table, p);
195
196 return dest;
197 }
198
199 /* Allocate bgp_path_info_extra */
200 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
201 {
202 struct bgp_path_info_extra *new;
203 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
204 sizeof(struct bgp_path_info_extra));
205 new->label[0] = MPLS_INVALID_LABEL;
206 new->num_labels = 0;
207 new->bgp_fs_pbr = NULL;
208 new->bgp_fs_iprule = NULL;
209 return new;
210 }
211
212 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
213 {
214 struct bgp_path_info_extra *e;
215
216 if (!extra || !*extra)
217 return;
218
219 e = *extra;
220 if (e->damp_info)
221 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
222 e->damp_info->safi);
223
224 e->damp_info = NULL;
225 if (e->parent) {
226 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
227
228 if (bpi->net) {
229 /* FIXME: since multiple e may have the same e->parent
230 * and e->parent->net is holding a refcount for each
231 * of them, we need to do some fudging here.
232 *
233 * WARNING: if bpi->net->lock drops to 0, bpi may be
234 * freed as well (because bpi->net was holding the
235 * last reference to bpi) => write after free!
236 */
237 unsigned refcount;
238
239 bpi = bgp_path_info_lock(bpi);
240 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
241 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
242 if (!refcount)
243 bpi->net = NULL;
244 bgp_path_info_unlock(bpi);
245 }
246 bgp_path_info_unlock(e->parent);
247 e->parent = NULL;
248 }
249
250 if (e->bgp_orig)
251 bgp_unlock(e->bgp_orig);
252
253 if (e->peer_orig)
254 peer_unlock(e->peer_orig);
255
256 if (e->aggr_suppressors)
257 list_delete(&e->aggr_suppressors);
258
259 if (e->mh_info)
260 bgp_evpn_path_mh_info_free(e->mh_info);
261
262 if ((*extra)->bgp_fs_iprule)
263 list_delete(&((*extra)->bgp_fs_iprule));
264 if ((*extra)->bgp_fs_pbr)
265 list_delete(&((*extra)->bgp_fs_pbr));
266 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
267 }
268
269 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
270 * allocated if required.
271 */
272 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
273 {
274 if (!pi->extra)
275 pi->extra = bgp_path_info_extra_new();
276 return pi->extra;
277 }
278
279 /* Free bgp route information. */
280 void bgp_path_info_free_with_caller(const char *name,
281 struct bgp_path_info *path)
282 {
283 frrtrace(2, frr_bgp, bgp_path_info_free, path, name);
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_with_caller(const char *name, struct bgp_dest *dest,
395 struct bgp_path_info *pi)
396 {
397 frrtrace(3, frr_bgp, bgp_path_info_add, dest, pi, name);
398 struct bgp_path_info *top;
399
400 top = bgp_dest_get_bgp_path_info(dest);
401
402 pi->next = top;
403 pi->prev = NULL;
404 if (top)
405 top->prev = pi;
406 bgp_dest_set_bgp_path_info(dest, pi);
407
408 bgp_path_info_lock(pi);
409 bgp_dest_lock_node(dest);
410 peer_lock(pi->peer); /* bgp_path_info peer reference */
411 bgp_dest_set_defer_flag(dest, false);
412 hook_call(bgp_snmp_update_stats, dest, pi, true);
413 }
414
415 /* Do the actual removal of info from RIB, for use by bgp_process
416 completion callback *only* */
417 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
418 {
419 if (pi->next)
420 pi->next->prev = pi->prev;
421 if (pi->prev)
422 pi->prev->next = pi->next;
423 else
424 bgp_dest_set_bgp_path_info(dest, pi->next);
425
426 bgp_path_info_mpath_dequeue(pi);
427 bgp_path_info_unlock(pi);
428 hook_call(bgp_snmp_update_stats, dest, pi, false);
429 bgp_dest_unlock_node(dest);
430 }
431
432 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
433 {
434 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
435 /* set of previous already took care of pcount */
436 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
437 }
438
439 /* undo the effects of a previous call to bgp_path_info_delete; typically
440 called when a route is deleted and then quickly re-added before the
441 deletion has been processed */
442 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
443 {
444 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
445 /* unset of previous already took care of pcount */
446 SET_FLAG(pi->flags, BGP_PATH_VALID);
447 }
448
449 /* Adjust pcount as required */
450 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
451 {
452 struct bgp_table *table;
453
454 assert(dest && bgp_dest_table(dest));
455 assert(pi && pi->peer && pi->peer->bgp);
456
457 table = bgp_dest_table(dest);
458
459 if (pi->peer == pi->peer->bgp->peer_self)
460 return;
461
462 if (!BGP_PATH_COUNTABLE(pi)
463 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
464
465 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
466
467 /* slight hack, but more robust against errors. */
468 if (pi->peer->pcount[table->afi][table->safi])
469 pi->peer->pcount[table->afi][table->safi]--;
470 else
471 flog_err(EC_LIB_DEVELOPMENT,
472 "Asked to decrement 0 prefix count for peer");
473 } else if (BGP_PATH_COUNTABLE(pi)
474 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
475 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
476 pi->peer->pcount[table->afi][table->safi]++;
477 }
478 }
479
480 static int bgp_label_index_differs(struct bgp_path_info *pi1,
481 struct bgp_path_info *pi2)
482 {
483 return (!(pi1->attr->label_index == pi2->attr->label_index));
484 }
485
486 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
487 * This is here primarily to keep prefix-count in check.
488 */
489 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
490 uint32_t flag)
491 {
492 SET_FLAG(pi->flags, flag);
493
494 /* early bath if we know it's not a flag that changes countability state
495 */
496 if (!CHECK_FLAG(flag,
497 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
498 return;
499
500 bgp_pcount_adjust(dest, pi);
501 }
502
503 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
504 uint32_t flag)
505 {
506 UNSET_FLAG(pi->flags, flag);
507
508 /* early bath if we know it's not a flag that changes countability state
509 */
510 if (!CHECK_FLAG(flag,
511 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
512 return;
513
514 bgp_pcount_adjust(dest, pi);
515 }
516
517 /* Get MED value. If MED value is missing and "bgp bestpath
518 missing-as-worst" is specified, treat it as the worst value. */
519 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
520 {
521 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
522 return attr->med;
523 else {
524 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
525 return BGP_MED_MAX;
526 else
527 return 0;
528 }
529 }
530
531 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
532 size_t buf_len)
533 {
534 if (pi->addpath_rx_id)
535 snprintf(buf, buf_len, "path %s (addpath rxid %d)",
536 pi->peer->host, pi->addpath_rx_id);
537 else
538 snprintf(buf, buf_len, "path %s", pi->peer->host);
539 }
540
541
542 /*
543 * Get the ultimate path info.
544 */
545 struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
546 {
547 struct bgp_path_info *bpi_ultimate;
548
549 if (info->sub_type != BGP_ROUTE_IMPORTED)
550 return info;
551
552 for (bpi_ultimate = info;
553 bpi_ultimate->extra && bpi_ultimate->extra->parent;
554 bpi_ultimate = bpi_ultimate->extra->parent)
555 ;
556
557 return bpi_ultimate;
558 }
559
560 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
561 */
562 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
563 struct bgp_path_info *exist, int *paths_eq,
564 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
565 char *pfx_buf, afi_t afi, safi_t safi,
566 enum bgp_path_selection_reason *reason)
567 {
568 const struct prefix *new_p;
569 struct prefix exist_p;
570 struct attr *newattr, *existattr;
571 enum bgp_peer_sort new_sort;
572 enum bgp_peer_sort exist_sort;
573 uint32_t new_pref;
574 uint32_t exist_pref;
575 uint32_t new_med;
576 uint32_t exist_med;
577 uint32_t new_weight;
578 uint32_t exist_weight;
579 uint32_t newm, existm;
580 struct in_addr new_id;
581 struct in_addr exist_id;
582 int new_cluster;
583 int exist_cluster;
584 int internal_as_route;
585 int confed_as_route;
586 int ret = 0;
587 int igp_metric_ret = 0;
588 int peer_sort_ret = -1;
589 char new_buf[PATH_ADDPATH_STR_BUFFER];
590 char exist_buf[PATH_ADDPATH_STR_BUFFER];
591 uint32_t new_mm_seq;
592 uint32_t exist_mm_seq;
593 int nh_cmp;
594 esi_t *exist_esi;
595 esi_t *new_esi;
596 bool same_esi;
597 bool old_proxy;
598 bool new_proxy;
599 bool new_origin, exist_origin;
600 struct bgp_path_info *bpi_ultimate;
601
602 struct bgp_orr_group *orr_group = NULL;
603 struct listnode *node;
604 struct bgp_orr_igp_metric *igp_metric = NULL;
605 struct list *orr_group_igp_metric_info = NULL;
606
607 *paths_eq = 0;
608
609 /* 0. Null check. */
610 if (new == NULL) {
611 *reason = bgp_path_selection_none;
612 if (debug)
613 zlog_debug("%s: new is NULL", pfx_buf);
614 return 0;
615 }
616
617 if (debug) {
618 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
619 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, new_buf,
620 sizeof(new_buf));
621 }
622
623 if (exist == NULL) {
624 *reason = bgp_path_selection_first;
625 if (debug)
626 zlog_debug("%s(%s): %s is the initial bestpath",
627 pfx_buf, bgp->name_pretty, new_buf);
628 return 1;
629 }
630
631 if (debug) {
632 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
633 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, exist_buf,
634 sizeof(exist_buf));
635 zlog_debug("%s(%s): Comparing %s flags 0x%x with %s flags 0x%x",
636 pfx_buf, bgp->name_pretty, new_buf, new->flags,
637 exist_buf, exist->flags);
638 }
639
640 newattr = new->attr;
641 existattr = exist->attr;
642
643 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
644 * Capability" to a neighbor MUST perform the following upon receiving
645 * a route from that neighbor with the "LLGR_STALE" community, or upon
646 * attaching the "LLGR_STALE" community itself per Section 4.2:
647 *
648 * Treat the route as the least-preferred in route selection (see
649 * below). See the Risks of Depreferencing Routes section (Section 5.2)
650 * for a discussion of potential risks inherent in doing this.
651 */
652 if (bgp_attr_get_community(newattr) &&
653 community_include(bgp_attr_get_community(newattr),
654 COMMUNITY_LLGR_STALE)) {
655 if (debug)
656 zlog_debug(
657 "%s: %s wins over %s due to LLGR_STALE community",
658 pfx_buf, new_buf, exist_buf);
659 return 0;
660 }
661
662 if (bgp_attr_get_community(existattr) &&
663 community_include(bgp_attr_get_community(existattr),
664 COMMUNITY_LLGR_STALE)) {
665 if (debug)
666 zlog_debug(
667 "%s: %s loses to %s due to LLGR_STALE community",
668 pfx_buf, new_buf, exist_buf);
669 return 1;
670 }
671
672 new_p = bgp_dest_get_prefix(new->net);
673
674 /* For EVPN routes, we cannot just go by local vs remote, we have to
675 * look at the MAC mobility sequence number, if present.
676 */
677 if ((safi == SAFI_EVPN)
678 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
679 /* This is an error condition described in RFC 7432 Section
680 * 15.2. The RFC
681 * states that in this scenario "the PE MUST alert the operator"
682 * but it
683 * does not state what other action to take. In order to provide
684 * some
685 * consistency in this scenario we are going to prefer the path
686 * with the
687 * sticky flag.
688 */
689 if (newattr->sticky != existattr->sticky) {
690 if (!debug) {
691 prefix2str(new_p, pfx_buf,
692 sizeof(*pfx_buf)
693 * PREFIX2STR_BUFFER);
694 bgp_path_info_path_with_addpath_rx_str(
695 new, new_buf, sizeof(new_buf));
696 bgp_path_info_path_with_addpath_rx_str(
697 exist, exist_buf, sizeof(exist_buf));
698 }
699
700 if (newattr->sticky && !existattr->sticky) {
701 *reason = bgp_path_selection_evpn_sticky_mac;
702 if (debug)
703 zlog_debug(
704 "%s: %s wins over %s due to sticky MAC flag",
705 pfx_buf, new_buf, exist_buf);
706 return 1;
707 }
708
709 if (!newattr->sticky && existattr->sticky) {
710 *reason = bgp_path_selection_evpn_sticky_mac;
711 if (debug)
712 zlog_debug(
713 "%s: %s loses to %s due to sticky MAC flag",
714 pfx_buf, new_buf, exist_buf);
715 return 0;
716 }
717 }
718
719 new_esi = bgp_evpn_attr_get_esi(newattr);
720 exist_esi = bgp_evpn_attr_get_esi(existattr);
721 if (bgp_evpn_is_esi_valid(new_esi) &&
722 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
723 same_esi = true;
724 } else {
725 same_esi = false;
726 }
727
728 /* If both paths have the same non-zero ES and
729 * one path is local it wins.
730 * PS: Note the local path wins even if the remote
731 * has the higher MM seq. The local path's
732 * MM seq will be fixed up to match the highest
733 * rem seq, subsequently.
734 */
735 if (same_esi) {
736 char esi_buf[ESI_STR_LEN];
737
738 if (bgp_evpn_is_path_local(bgp, new)) {
739 *reason = bgp_path_selection_evpn_local_path;
740 if (debug)
741 zlog_debug(
742 "%s: %s wins over %s as ES %s is same and local",
743 pfx_buf, new_buf, exist_buf,
744 esi_to_str(new_esi, esi_buf,
745 sizeof(esi_buf)));
746 return 1;
747 }
748 if (bgp_evpn_is_path_local(bgp, exist)) {
749 *reason = bgp_path_selection_evpn_local_path;
750 if (debug)
751 zlog_debug(
752 "%s: %s loses to %s as ES %s is same and local",
753 pfx_buf, new_buf, exist_buf,
754 esi_to_str(new_esi, esi_buf,
755 sizeof(esi_buf)));
756 return 0;
757 }
758 }
759
760 new_mm_seq = mac_mobility_seqnum(newattr);
761 exist_mm_seq = mac_mobility_seqnum(existattr);
762
763 if (new_mm_seq > exist_mm_seq) {
764 *reason = bgp_path_selection_evpn_seq;
765 if (debug)
766 zlog_debug(
767 "%s: %s wins over %s due to MM seq %u > %u",
768 pfx_buf, new_buf, exist_buf, new_mm_seq,
769 exist_mm_seq);
770 return 1;
771 }
772
773 if (new_mm_seq < exist_mm_seq) {
774 *reason = bgp_path_selection_evpn_seq;
775 if (debug)
776 zlog_debug(
777 "%s: %s loses to %s due to MM seq %u < %u",
778 pfx_buf, new_buf, exist_buf, new_mm_seq,
779 exist_mm_seq);
780 return 0;
781 }
782
783 /* if the sequence numbers and ESI are the same and one path
784 * is non-proxy it wins (over proxy)
785 */
786 new_proxy = bgp_evpn_attr_is_proxy(newattr);
787 old_proxy = bgp_evpn_attr_is_proxy(existattr);
788 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
789 old_proxy != new_proxy) {
790 if (!new_proxy) {
791 *reason = bgp_path_selection_evpn_non_proxy;
792 if (debug)
793 zlog_debug(
794 "%s: %s wins over %s, same seq/es and non-proxy",
795 pfx_buf, new_buf, exist_buf);
796 return 1;
797 }
798
799 *reason = bgp_path_selection_evpn_non_proxy;
800 if (debug)
801 zlog_debug(
802 "%s: %s loses to %s, same seq/es and non-proxy",
803 pfx_buf, new_buf, exist_buf);
804 return 0;
805 }
806
807 /*
808 * if sequence numbers are the same path with the lowest IP
809 * wins
810 */
811 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
812 if (nh_cmp < 0) {
813 *reason = bgp_path_selection_evpn_lower_ip;
814 if (debug)
815 zlog_debug(
816 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
817 pfx_buf, new_buf, exist_buf, new_mm_seq,
818 &new->attr->nexthop);
819 return 1;
820 }
821 if (nh_cmp > 0) {
822 *reason = bgp_path_selection_evpn_lower_ip;
823 if (debug)
824 zlog_debug(
825 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
826 pfx_buf, new_buf, exist_buf, new_mm_seq,
827 &new->attr->nexthop);
828 return 0;
829 }
830 }
831
832 /* 1. Weight check. */
833 new_weight = newattr->weight;
834 exist_weight = existattr->weight;
835
836 if (new_weight > exist_weight) {
837 *reason = bgp_path_selection_weight;
838 if (debug)
839 zlog_debug("%s: %s wins over %s due to weight %d > %d",
840 pfx_buf, new_buf, exist_buf, new_weight,
841 exist_weight);
842 return 1;
843 }
844
845 if (new_weight < exist_weight) {
846 *reason = bgp_path_selection_weight;
847 if (debug)
848 zlog_debug("%s: %s loses to %s due to weight %d < %d",
849 pfx_buf, new_buf, exist_buf, new_weight,
850 exist_weight);
851 return 0;
852 }
853
854 /* 2. Local preference check. */
855 new_pref = exist_pref = bgp->default_local_pref;
856
857 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
858 new_pref = newattr->local_pref;
859 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
860 exist_pref = existattr->local_pref;
861
862 if (new_pref > exist_pref) {
863 *reason = bgp_path_selection_local_pref;
864 if (debug)
865 zlog_debug(
866 "%s: %s wins over %s due to localpref %d > %d",
867 pfx_buf, new_buf, exist_buf, new_pref,
868 exist_pref);
869 return 1;
870 }
871
872 if (new_pref < exist_pref) {
873 *reason = bgp_path_selection_local_pref;
874 if (debug)
875 zlog_debug(
876 "%s: %s loses to %s due to localpref %d < %d",
877 pfx_buf, new_buf, exist_buf, new_pref,
878 exist_pref);
879 return 0;
880 }
881
882 /* If a BGP speaker supports ACCEPT_OWN and is configured for the
883 * extensions defined in this document, the following step is inserted
884 * after the LOCAL_PREF comparison step in the BGP decision process:
885 * When comparing a pair of routes for a BGP destination, the
886 * route with the ACCEPT_OWN community attached is preferred over
887 * the route that does not have the community.
888 * This extra step MUST only be invoked during the best path selection
889 * process of VPN-IP routes.
890 */
891 if (safi == SAFI_MPLS_VPN &&
892 (CHECK_FLAG(new->peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN) ||
893 CHECK_FLAG(exist->peer->af_flags[afi][safi],
894 PEER_FLAG_ACCEPT_OWN))) {
895 bool new_accept_own = false;
896 bool exist_accept_own = false;
897 uint32_t accept_own = COMMUNITY_ACCEPT_OWN;
898
899 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
900 new_accept_own = community_include(
901 bgp_attr_get_community(newattr), accept_own);
902 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
903 exist_accept_own = community_include(
904 bgp_attr_get_community(existattr), accept_own);
905
906 if (new_accept_own && !exist_accept_own) {
907 *reason = bgp_path_selection_accept_own;
908 if (debug)
909 zlog_debug(
910 "%s: %s wins over %s due to accept-own",
911 pfx_buf, new_buf, exist_buf);
912 return 1;
913 }
914
915 if (!new_accept_own && exist_accept_own) {
916 *reason = bgp_path_selection_accept_own;
917 if (debug)
918 zlog_debug(
919 "%s: %s loses to %s due to accept-own",
920 pfx_buf, new_buf, exist_buf);
921 return 0;
922 }
923 }
924
925 /* Tie-breaker - AIGP (Metric TLV) attribute */
926 if (CHECK_FLAG(newattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
927 CHECK_FLAG(existattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
928 CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_AIGP)) {
929 uint64_t new_aigp = bgp_attr_get_aigp_metric(newattr);
930 uint64_t exist_aigp = bgp_attr_get_aigp_metric(existattr);
931
932 if (new_aigp < exist_aigp) {
933 *reason = bgp_path_selection_aigp;
934 if (debug)
935 zlog_debug(
936 "%s: %s wins over %s due to AIGP %" PRIu64
937 " < %" PRIu64,
938 pfx_buf, new_buf, exist_buf, new_aigp,
939 exist_aigp);
940 return 1;
941 }
942
943 if (new_aigp > exist_aigp) {
944 *reason = bgp_path_selection_aigp;
945 if (debug)
946 zlog_debug(
947 "%s: %s loses to %s due to AIGP %" PRIu64
948 " > %" PRIu64,
949 pfx_buf, new_buf, exist_buf, new_aigp,
950 exist_aigp);
951 return 0;
952 }
953 }
954
955 /* 3. Local route check. We prefer:
956 * - BGP_ROUTE_STATIC
957 * - BGP_ROUTE_AGGREGATE
958 * - BGP_ROUTE_REDISTRIBUTE
959 */
960 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
961 new->sub_type == BGP_ROUTE_IMPORTED);
962 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
963 exist->sub_type == BGP_ROUTE_IMPORTED);
964
965 if (new_origin && !exist_origin) {
966 *reason = bgp_path_selection_local_route;
967 if (debug)
968 zlog_debug(
969 "%s: %s wins over %s due to preferred BGP_ROUTE type",
970 pfx_buf, new_buf, exist_buf);
971 return 1;
972 }
973
974 if (!new_origin && exist_origin) {
975 *reason = bgp_path_selection_local_route;
976 if (debug)
977 zlog_debug(
978 "%s: %s loses to %s due to preferred BGP_ROUTE type",
979 pfx_buf, new_buf, exist_buf);
980 return 0;
981 }
982
983 /* Here if these are imported routes then get ultimate pi for
984 * path compare.
985 */
986 new = bgp_get_imported_bpi_ultimate(new);
987 exist = bgp_get_imported_bpi_ultimate(exist);
988 newattr = new->attr;
989 existattr = exist->attr;
990
991 /* 4. AS path length check. */
992 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
993 int exist_hops = aspath_count_hops(existattr->aspath);
994 int exist_confeds = aspath_count_confeds(existattr->aspath);
995
996 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
997 int aspath_hops;
998
999 aspath_hops = aspath_count_hops(newattr->aspath);
1000 aspath_hops += aspath_count_confeds(newattr->aspath);
1001
1002 if (aspath_hops < (exist_hops + exist_confeds)) {
1003 *reason = bgp_path_selection_confed_as_path;
1004 if (debug)
1005 zlog_debug(
1006 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
1007 pfx_buf, new_buf, exist_buf,
1008 aspath_hops,
1009 (exist_hops + exist_confeds));
1010 return 1;
1011 }
1012
1013 if (aspath_hops > (exist_hops + exist_confeds)) {
1014 *reason = bgp_path_selection_confed_as_path;
1015 if (debug)
1016 zlog_debug(
1017 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
1018 pfx_buf, new_buf, exist_buf,
1019 aspath_hops,
1020 (exist_hops + exist_confeds));
1021 return 0;
1022 }
1023 } else {
1024 int newhops = aspath_count_hops(newattr->aspath);
1025
1026 if (newhops < exist_hops) {
1027 *reason = bgp_path_selection_as_path;
1028 if (debug)
1029 zlog_debug(
1030 "%s: %s wins over %s due to aspath hopcount %d < %d",
1031 pfx_buf, new_buf, exist_buf,
1032 newhops, exist_hops);
1033 return 1;
1034 }
1035
1036 if (newhops > exist_hops) {
1037 *reason = bgp_path_selection_as_path;
1038 if (debug)
1039 zlog_debug(
1040 "%s: %s loses to %s due to aspath hopcount %d > %d",
1041 pfx_buf, new_buf, exist_buf,
1042 newhops, exist_hops);
1043 return 0;
1044 }
1045 }
1046 }
1047
1048 /* 5. Origin check. */
1049 if (newattr->origin < existattr->origin) {
1050 *reason = bgp_path_selection_origin;
1051 if (debug)
1052 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
1053 pfx_buf, new_buf, exist_buf,
1054 bgp_origin_long_str[newattr->origin],
1055 bgp_origin_long_str[existattr->origin]);
1056 return 1;
1057 }
1058
1059 if (newattr->origin > existattr->origin) {
1060 *reason = bgp_path_selection_origin;
1061 if (debug)
1062 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
1063 pfx_buf, new_buf, exist_buf,
1064 bgp_origin_long_str[newattr->origin],
1065 bgp_origin_long_str[existattr->origin]);
1066 return 0;
1067 }
1068
1069 /* 6. MED check. */
1070 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
1071 && aspath_count_hops(existattr->aspath) == 0);
1072 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
1073 && aspath_count_confeds(existattr->aspath) > 0
1074 && aspath_count_hops(newattr->aspath) == 0
1075 && aspath_count_hops(existattr->aspath) == 0);
1076
1077 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
1078 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
1079 || aspath_cmp_left(newattr->aspath, existattr->aspath)
1080 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
1081 || internal_as_route) {
1082 new_med = bgp_med_value(new->attr, bgp);
1083 exist_med = bgp_med_value(exist->attr, bgp);
1084
1085 if (new_med < exist_med) {
1086 *reason = bgp_path_selection_med;
1087 if (debug)
1088 zlog_debug(
1089 "%s: %s wins over %s due to MED %d < %d",
1090 pfx_buf, new_buf, exist_buf, new_med,
1091 exist_med);
1092 return 1;
1093 }
1094
1095 if (new_med > exist_med) {
1096 *reason = bgp_path_selection_med;
1097 if (debug)
1098 zlog_debug(
1099 "%s: %s loses to %s due to MED %d > %d",
1100 pfx_buf, new_buf, exist_buf, new_med,
1101 exist_med);
1102 return 0;
1103 }
1104 }
1105
1106 /* 7. Peer type check. */
1107 new_sort = new->peer->sort;
1108 exist_sort = exist->peer->sort;
1109
1110 if (new_sort == BGP_PEER_EBGP
1111 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1112 *reason = bgp_path_selection_peer;
1113 if (debug)
1114 zlog_debug(
1115 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1116 pfx_buf, new_buf, exist_buf);
1117 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1118 return 1;
1119 peer_sort_ret = 1;
1120 }
1121
1122 if (exist_sort == BGP_PEER_EBGP
1123 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1124 *reason = bgp_path_selection_peer;
1125 if (debug)
1126 zlog_debug(
1127 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1128 pfx_buf, new_buf, exist_buf);
1129 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1130 return 0;
1131 peer_sort_ret = 0;
1132 }
1133
1134 /* 8. IGP metric check. */
1135 newm = existm = 0;
1136
1137 if (new->extra)
1138 newm = new->extra->igpmetric;
1139 if (exist->extra)
1140 existm = exist->extra->igpmetric;
1141
1142 if (new->peer->orr_group_name[afi][safi]) {
1143 ret = str2prefix(new->peer->host, &exist_p);
1144 orr_group = bgp_orr_group_lookup_by_name(
1145 bgp, afi, safi, new->peer->orr_group_name[afi][safi]);
1146 if (orr_group) {
1147 orr_group_igp_metric_info = orr_group->igp_metric_info;
1148 if (orr_group_igp_metric_info) {
1149 for (ALL_LIST_ELEMENTS_RO(
1150 orr_group_igp_metric_info, node,
1151 igp_metric)) {
1152 if (ret &&
1153 prefix_cmp(&exist_p,
1154 &igp_metric->prefix) ==
1155 0) {
1156 newm = igp_metric->igp_metric;
1157 break;
1158 }
1159 }
1160 }
1161 }
1162 }
1163 if (exist->peer->orr_group_name[afi][safi]) {
1164 ret = str2prefix(exist->peer->host, &exist_p);
1165 orr_group = bgp_orr_group_lookup_by_name(
1166 bgp, afi, safi, exist->peer->orr_group_name[afi][safi]);
1167 if (orr_group) {
1168 orr_group_igp_metric_info = orr_group->igp_metric_info;
1169 if (orr_group_igp_metric_info) {
1170 for (ALL_LIST_ELEMENTS_RO(
1171 orr_group_igp_metric_info, node,
1172 igp_metric)) {
1173 if (ret &&
1174 prefix_cmp(&exist_p,
1175 &igp_metric->prefix) ==
1176 0) {
1177 existm = igp_metric->igp_metric;
1178 break;
1179 }
1180 }
1181 }
1182 }
1183 }
1184
1185 if (newm < existm) {
1186 if (debug && peer_sort_ret < 0)
1187 zlog_debug(
1188 "%s: %s wins over %s due to IGP metric %u < %u",
1189 pfx_buf, new_buf, exist_buf, newm, existm);
1190 igp_metric_ret = 1;
1191 }
1192
1193 if (newm > existm) {
1194 if (debug && peer_sort_ret < 0)
1195 zlog_debug(
1196 "%s: %s loses to %s due to IGP metric %u > %u",
1197 pfx_buf, new_buf, exist_buf, newm, existm);
1198 igp_metric_ret = 0;
1199 }
1200
1201 /* 9. Same IGP metric. Compare the cluster list length as
1202 representative of IGP hops metric. Rewrite the metric value
1203 pair (newm, existm) with the cluster list length. Prefer the
1204 path with smaller cluster list length. */
1205 if (newm == existm) {
1206 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP &&
1207 peer_sort_lookup(exist->peer) == BGP_PEER_IBGP &&
1208 (mpath_cfg == NULL || mpath_cfg->same_clusterlen)) {
1209 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1210 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1211
1212 if (newm < existm) {
1213 if (debug && peer_sort_ret < 0)
1214 zlog_debug(
1215 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1216 pfx_buf, new_buf, exist_buf,
1217 newm, existm);
1218 igp_metric_ret = 1;
1219 }
1220
1221 if (newm > existm) {
1222 if (debug && peer_sort_ret < 0)
1223 zlog_debug(
1224 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1225 pfx_buf, new_buf, exist_buf,
1226 newm, existm);
1227 igp_metric_ret = 0;
1228 }
1229 }
1230 }
1231
1232 /* 10. confed-external vs. confed-internal */
1233 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1234 if (new_sort == BGP_PEER_CONFED
1235 && exist_sort == BGP_PEER_IBGP) {
1236 *reason = bgp_path_selection_confed;
1237 if (debug)
1238 zlog_debug(
1239 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1240 pfx_buf, new_buf, exist_buf);
1241 if (!CHECK_FLAG(bgp->flags,
1242 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1243 return 1;
1244 peer_sort_ret = 1;
1245 }
1246
1247 if (exist_sort == BGP_PEER_CONFED
1248 && new_sort == BGP_PEER_IBGP) {
1249 *reason = bgp_path_selection_confed;
1250 if (debug)
1251 zlog_debug(
1252 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1253 pfx_buf, new_buf, exist_buf);
1254 if (!CHECK_FLAG(bgp->flags,
1255 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1256 return 0;
1257 peer_sort_ret = 0;
1258 }
1259 }
1260
1261 /* 11. Maximum path check. */
1262 if (newm == existm) {
1263 /* If one path has a label but the other does not, do not treat
1264 * them as equals for multipath
1265 */
1266 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1267 != (exist->extra
1268 && bgp_is_valid_label(&exist->extra->label[0]))) {
1269 if (debug)
1270 zlog_debug(
1271 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1272 pfx_buf, new_buf, exist_buf);
1273 } else if (CHECK_FLAG(bgp->flags,
1274 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1275
1276 /*
1277 * For the two paths, all comparison steps till IGP
1278 * metric
1279 * have succeeded - including AS_PATH hop count. Since
1280 * 'bgp
1281 * bestpath as-path multipath-relax' knob is on, we
1282 * don't need
1283 * an exact match of AS_PATH. Thus, mark the paths are
1284 * equal.
1285 * That will trigger both these paths to get into the
1286 * multipath
1287 * array.
1288 */
1289 *paths_eq = 1;
1290
1291 if (debug)
1292 zlog_debug(
1293 "%s: %s and %s are equal via multipath-relax",
1294 pfx_buf, new_buf, exist_buf);
1295 } else if (new->peer->sort == BGP_PEER_IBGP) {
1296 if (aspath_cmp(new->attr->aspath,
1297 exist->attr->aspath)) {
1298 *paths_eq = 1;
1299
1300 if (debug)
1301 zlog_debug(
1302 "%s: %s and %s are equal via matching aspaths",
1303 pfx_buf, new_buf, exist_buf);
1304 }
1305 } else if (new->peer->as == exist->peer->as) {
1306 *paths_eq = 1;
1307
1308 if (debug)
1309 zlog_debug(
1310 "%s: %s and %s are equal via same remote-as",
1311 pfx_buf, new_buf, exist_buf);
1312 }
1313 } else {
1314 /*
1315 * TODO: If unequal cost ibgp multipath is enabled we can
1316 * mark the paths as equal here instead of returning
1317 */
1318
1319 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1320 * if either step 7 or 10 (peer type checks) yielded a winner,
1321 * that result was returned immediately. Returning from step 10
1322 * ignored the return value computed in steps 8 and 9 (IGP
1323 * metric checks). In order to preserve that behavior, if
1324 * peer_sort_ret is set, return that rather than igp_metric_ret.
1325 */
1326 ret = peer_sort_ret;
1327 if (peer_sort_ret < 0) {
1328 ret = igp_metric_ret;
1329 if (debug) {
1330 if (ret == 1)
1331 zlog_debug(
1332 "%s: %s wins over %s after IGP metric comparison",
1333 pfx_buf, new_buf, exist_buf);
1334 else
1335 zlog_debug(
1336 "%s: %s loses to %s after IGP metric comparison",
1337 pfx_buf, new_buf, exist_buf);
1338 }
1339 *reason = bgp_path_selection_igp_metric;
1340 }
1341 return ret;
1342 }
1343
1344 /*
1345 * At this point, the decision whether to set *paths_eq = 1 has been
1346 * completed. If we deferred returning because of bestpath peer-type
1347 * relax configuration, return now.
1348 */
1349 if (peer_sort_ret >= 0)
1350 return peer_sort_ret;
1351
1352 /* 12. If both paths are external, prefer the path that was received
1353 first (the oldest one). This step minimizes route-flap, since a
1354 newer path won't displace an older one, even if it was the
1355 preferred route based on the additional decision criteria below. */
1356 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1357 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1358 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1359 *reason = bgp_path_selection_older;
1360 if (debug)
1361 zlog_debug(
1362 "%s: %s wins over %s due to oldest external",
1363 pfx_buf, new_buf, exist_buf);
1364 return 1;
1365 }
1366
1367 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1368 *reason = bgp_path_selection_older;
1369 if (debug)
1370 zlog_debug(
1371 "%s: %s loses to %s due to oldest external",
1372 pfx_buf, new_buf, exist_buf);
1373 return 0;
1374 }
1375 }
1376
1377 /* 13. Router-ID comparison. */
1378 /* If one of the paths is "stale", the corresponding peer router-id will
1379 * be 0 and would always win over the other path. If originator id is
1380 * used for the comparison, it will decide which path is better.
1381 */
1382 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1383 new_id.s_addr = newattr->originator_id.s_addr;
1384 else
1385 new_id.s_addr = new->peer->remote_id.s_addr;
1386 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1387 exist_id.s_addr = existattr->originator_id.s_addr;
1388 else
1389 exist_id.s_addr = exist->peer->remote_id.s_addr;
1390
1391 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1392 *reason = bgp_path_selection_router_id;
1393 if (debug)
1394 zlog_debug(
1395 "%s: %s wins over %s due to Router-ID comparison",
1396 pfx_buf, new_buf, exist_buf);
1397 return 1;
1398 }
1399
1400 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1401 *reason = bgp_path_selection_router_id;
1402 if (debug)
1403 zlog_debug(
1404 "%s: %s loses to %s due to Router-ID comparison",
1405 pfx_buf, new_buf, exist_buf);
1406 return 0;
1407 }
1408
1409 /* 14. Cluster length comparison. */
1410 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1411 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1412
1413 if (new_cluster < exist_cluster) {
1414 *reason = bgp_path_selection_cluster_length;
1415 if (debug)
1416 zlog_debug(
1417 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1418 pfx_buf, new_buf, exist_buf, new_cluster,
1419 exist_cluster);
1420 return 1;
1421 }
1422
1423 if (new_cluster > exist_cluster) {
1424 *reason = bgp_path_selection_cluster_length;
1425 if (debug)
1426 zlog_debug(
1427 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1428 pfx_buf, new_buf, exist_buf, new_cluster,
1429 exist_cluster);
1430 return 0;
1431 }
1432
1433 /* 15. Neighbor address comparison. */
1434 /* Do this only if neither path is "stale" as stale paths do not have
1435 * valid peer information (as the connection may or may not be up).
1436 */
1437 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1438 *reason = bgp_path_selection_stale;
1439 if (debug)
1440 zlog_debug(
1441 "%s: %s wins over %s due to latter path being STALE",
1442 pfx_buf, new_buf, exist_buf);
1443 return 1;
1444 }
1445
1446 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1447 *reason = bgp_path_selection_stale;
1448 if (debug)
1449 zlog_debug(
1450 "%s: %s loses to %s due to former path being STALE",
1451 pfx_buf, new_buf, exist_buf);
1452 return 0;
1453 }
1454
1455 /* locally configured routes to advertise do not have su_remote */
1456 if (new->peer->su_remote == NULL) {
1457 *reason = bgp_path_selection_local_configured;
1458 return 0;
1459 }
1460 if (exist->peer->su_remote == NULL) {
1461 *reason = bgp_path_selection_local_configured;
1462 return 1;
1463 }
1464
1465 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1466
1467 if (ret == 1) {
1468 *reason = bgp_path_selection_neighbor_ip;
1469 if (debug)
1470 zlog_debug(
1471 "%s: %s loses to %s due to Neighor IP comparison",
1472 pfx_buf, new_buf, exist_buf);
1473 return 0;
1474 }
1475
1476 if (ret == -1) {
1477 *reason = bgp_path_selection_neighbor_ip;
1478 if (debug)
1479 zlog_debug(
1480 "%s: %s wins over %s due to Neighor IP comparison",
1481 pfx_buf, new_buf, exist_buf);
1482 return 1;
1483 }
1484
1485 *reason = bgp_path_selection_default;
1486 if (debug)
1487 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1488 pfx_buf, new_buf, exist_buf);
1489
1490 return 1;
1491 }
1492
1493
1494 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1495 struct bgp_path_info *exist, int *paths_eq)
1496 {
1497 enum bgp_path_selection_reason reason;
1498 char pfx_buf[PREFIX2STR_BUFFER];
1499
1500 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1501 AFI_L2VPN, SAFI_EVPN, &reason);
1502 }
1503
1504 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1505 * is preferred, or 0 if they are the same (usually will only occur if
1506 * multipath is enabled
1507 * This version is compatible with */
1508 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1509 struct bgp_path_info *exist, char *pfx_buf,
1510 afi_t afi, safi_t safi,
1511 enum bgp_path_selection_reason *reason)
1512 {
1513 int paths_eq;
1514 int ret;
1515 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1516 afi, safi, reason);
1517
1518 if (paths_eq)
1519 ret = 0;
1520 else {
1521 if (ret == 1)
1522 ret = -1;
1523 else
1524 ret = 1;
1525 }
1526 return ret;
1527 }
1528
1529 static enum filter_type bgp_input_filter(struct peer *peer,
1530 const struct prefix *p,
1531 struct attr *attr, afi_t afi,
1532 safi_t safi)
1533 {
1534 struct bgp_filter *filter;
1535 enum filter_type ret = FILTER_PERMIT;
1536
1537 filter = &peer->filter[afi][safi];
1538
1539 #define FILTER_EXIST_WARN(F, f, filter) \
1540 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1541 zlog_debug("%s: Could not find configured input %s-list %s!", \
1542 peer->host, #f, F##_IN_NAME(filter));
1543
1544 if (DISTRIBUTE_IN_NAME(filter)) {
1545 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1546
1547 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1548 == FILTER_DENY) {
1549 ret = FILTER_DENY;
1550 goto done;
1551 }
1552 }
1553
1554 if (PREFIX_LIST_IN_NAME(filter)) {
1555 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1556
1557 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1558 == PREFIX_DENY) {
1559 ret = FILTER_DENY;
1560 goto done;
1561 }
1562 }
1563
1564 if (FILTER_LIST_IN_NAME(filter)) {
1565 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1566
1567 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1568 == AS_FILTER_DENY) {
1569 ret = FILTER_DENY;
1570 goto done;
1571 }
1572 }
1573
1574 done:
1575 if (frrtrace_enabled(frr_bgp, input_filter)) {
1576 char pfxprint[PREFIX2STR_BUFFER];
1577
1578 prefix2str(p, pfxprint, sizeof(pfxprint));
1579 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1580 ret == FILTER_PERMIT ? "permit" : "deny");
1581 }
1582
1583 return ret;
1584 #undef FILTER_EXIST_WARN
1585 }
1586
1587 static enum filter_type bgp_output_filter(struct peer *peer,
1588 const struct prefix *p,
1589 struct attr *attr, afi_t afi,
1590 safi_t safi)
1591 {
1592 struct bgp_filter *filter;
1593 enum filter_type ret = FILTER_PERMIT;
1594
1595 filter = &peer->filter[afi][safi];
1596
1597 #define FILTER_EXIST_WARN(F, f, filter) \
1598 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1599 zlog_debug("%s: Could not find configured output %s-list %s!", \
1600 peer->host, #f, F##_OUT_NAME(filter));
1601
1602 if (DISTRIBUTE_OUT_NAME(filter)) {
1603 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1604
1605 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1606 == FILTER_DENY) {
1607 ret = FILTER_DENY;
1608 goto done;
1609 }
1610 }
1611
1612 if (PREFIX_LIST_OUT_NAME(filter)) {
1613 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1614
1615 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1616 == PREFIX_DENY) {
1617 ret = FILTER_DENY;
1618 goto done;
1619 }
1620 }
1621
1622 if (FILTER_LIST_OUT_NAME(filter)) {
1623 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1624
1625 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1626 == AS_FILTER_DENY) {
1627 ret = FILTER_DENY;
1628 goto done;
1629 }
1630 }
1631
1632 if (frrtrace_enabled(frr_bgp, output_filter)) {
1633 char pfxprint[PREFIX2STR_BUFFER];
1634
1635 prefix2str(p, pfxprint, sizeof(pfxprint));
1636 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1637 ret == FILTER_PERMIT ? "permit" : "deny");
1638 }
1639
1640 done:
1641 return ret;
1642 #undef FILTER_EXIST_WARN
1643 }
1644
1645 /* If community attribute includes no_export then return 1. */
1646 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1647 {
1648 if (bgp_attr_get_community(attr)) {
1649 /* NO_ADVERTISE check. */
1650 if (community_include(bgp_attr_get_community(attr),
1651 COMMUNITY_NO_ADVERTISE))
1652 return true;
1653
1654 /* NO_EXPORT check. */
1655 if (peer->sort == BGP_PEER_EBGP &&
1656 community_include(bgp_attr_get_community(attr),
1657 COMMUNITY_NO_EXPORT))
1658 return true;
1659
1660 /* NO_EXPORT_SUBCONFED check. */
1661 if (peer->sort == BGP_PEER_EBGP
1662 || peer->sort == BGP_PEER_CONFED)
1663 if (community_include(bgp_attr_get_community(attr),
1664 COMMUNITY_NO_EXPORT_SUBCONFED))
1665 return true;
1666 }
1667 return false;
1668 }
1669
1670 /* Route reflection loop check. */
1671 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1672 {
1673 struct in_addr cluster_id;
1674 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1675
1676 if (cluster) {
1677 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1678 cluster_id = peer->bgp->cluster_id;
1679 else
1680 cluster_id = peer->bgp->router_id;
1681
1682 if (cluster_loop_check(cluster, cluster_id))
1683 return true;
1684 }
1685 return false;
1686 }
1687
1688 static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
1689 {
1690 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1691 if (peer->local_role == ROLE_PROVIDER ||
1692 peer->local_role == ROLE_RS_SERVER)
1693 return true;
1694 if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
1695 return true;
1696 return false;
1697 }
1698 if (peer->local_role == ROLE_CUSTOMER ||
1699 peer->local_role == ROLE_PEER ||
1700 peer->local_role == ROLE_RS_CLIENT) {
1701 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1702 attr->otc = peer->as;
1703 }
1704 return false;
1705 }
1706
1707 static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
1708 {
1709 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1710 if (peer->local_role == ROLE_CUSTOMER ||
1711 peer->local_role == ROLE_RS_CLIENT ||
1712 peer->local_role == ROLE_PEER)
1713 return true;
1714 return false;
1715 }
1716 if (peer->local_role == ROLE_PROVIDER ||
1717 peer->local_role == ROLE_PEER ||
1718 peer->local_role == ROLE_RS_SERVER) {
1719 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1720 attr->otc = peer->bgp->as;
1721 }
1722 return false;
1723 }
1724
1725 static bool bgp_check_role_applicability(afi_t afi, safi_t safi)
1726 {
1727 return ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST);
1728 }
1729
1730 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1731 struct attr *attr, afi_t afi, safi_t safi,
1732 const char *rmap_name, mpls_label_t *label,
1733 uint32_t num_labels, struct bgp_dest *dest)
1734 {
1735 struct bgp_filter *filter;
1736 struct bgp_path_info rmap_path = { 0 };
1737 struct bgp_path_info_extra extra = { 0 };
1738 route_map_result_t ret;
1739 struct route_map *rmap = NULL;
1740
1741 filter = &peer->filter[afi][safi];
1742
1743 /* Apply default weight value. */
1744 if (peer->weight[afi][safi])
1745 attr->weight = peer->weight[afi][safi];
1746
1747 if (rmap_name) {
1748 rmap = route_map_lookup_by_name(rmap_name);
1749
1750 if (rmap == NULL)
1751 return RMAP_DENY;
1752 } else {
1753 if (ROUTE_MAP_IN_NAME(filter)) {
1754 rmap = ROUTE_MAP_IN(filter);
1755
1756 if (rmap == NULL)
1757 return RMAP_DENY;
1758 }
1759 }
1760
1761 /* Route map apply. */
1762 if (rmap) {
1763 memset(&rmap_path, 0, sizeof(rmap_path));
1764 /* Duplicate current value to new structure for modification. */
1765 rmap_path.peer = peer;
1766 rmap_path.attr = attr;
1767 rmap_path.extra = &extra;
1768 rmap_path.net = dest;
1769
1770 extra.num_labels = num_labels;
1771 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1772 memcpy(extra.label, label,
1773 num_labels * sizeof(mpls_label_t));
1774
1775 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1776
1777 /* Apply BGP route map to the attribute. */
1778 ret = route_map_apply(rmap, p, &rmap_path);
1779
1780 peer->rmap_type = 0;
1781
1782 if (ret == RMAP_DENYMATCH)
1783 return RMAP_DENY;
1784 }
1785 return RMAP_PERMIT;
1786 }
1787
1788 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1789 struct attr *attr, afi_t afi, safi_t safi,
1790 const char *rmap_name)
1791 {
1792 struct bgp_path_info rmap_path;
1793 route_map_result_t ret;
1794 struct route_map *rmap = NULL;
1795 uint8_t rmap_type;
1796
1797 /*
1798 * So if we get to this point and have no rmap_name
1799 * we want to just show the output as it currently
1800 * exists.
1801 */
1802 if (!rmap_name)
1803 return RMAP_PERMIT;
1804
1805 /* Apply default weight value. */
1806 if (peer->weight[afi][safi])
1807 attr->weight = peer->weight[afi][safi];
1808
1809 rmap = route_map_lookup_by_name(rmap_name);
1810
1811 /*
1812 * If we have a route map name and we do not find
1813 * the routemap that means we have an implicit
1814 * deny.
1815 */
1816 if (rmap == NULL)
1817 return RMAP_DENY;
1818
1819 memset(&rmap_path, 0, sizeof(rmap_path));
1820 /* Route map apply. */
1821 /* Duplicate current value to new structure for modification. */
1822 rmap_path.peer = peer;
1823 rmap_path.attr = attr;
1824
1825 rmap_type = peer->rmap_type;
1826 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1827
1828 /* Apply BGP route map to the attribute. */
1829 ret = route_map_apply(rmap, p, &rmap_path);
1830
1831 peer->rmap_type = rmap_type;
1832
1833 if (ret == RMAP_DENYMATCH)
1834 /*
1835 * caller has multiple error paths with bgp_attr_flush()
1836 */
1837 return RMAP_DENY;
1838
1839 return RMAP_PERMIT;
1840 }
1841
1842 /* If this is an EBGP peer with remove-private-AS */
1843 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1844 struct peer *peer, struct attr *attr)
1845 {
1846 if (peer->sort == BGP_PEER_EBGP
1847 && (peer_af_flag_check(peer, afi, safi,
1848 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1849 || peer_af_flag_check(peer, afi, safi,
1850 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1851 || peer_af_flag_check(peer, afi, safi,
1852 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1853 || peer_af_flag_check(peer, afi, safi,
1854 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1855 // Take action on the entire aspath
1856 if (peer_af_flag_check(peer, afi, safi,
1857 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1858 || peer_af_flag_check(peer, afi, safi,
1859 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1860 if (peer_af_flag_check(
1861 peer, afi, safi,
1862 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1863 attr->aspath = aspath_replace_private_asns(
1864 attr->aspath, bgp->as, peer->as);
1865
1866 /*
1867 * Even if the aspath consists of just private ASNs we
1868 * need to walk the AS-Path to maintain all instances
1869 * of the peer's ASN to break possible loops.
1870 */
1871 else
1872 attr->aspath = aspath_remove_private_asns(
1873 attr->aspath, peer->as);
1874 }
1875
1876 // 'all' was not specified so the entire aspath must be private
1877 // ASNs
1878 // for us to do anything
1879 else if (aspath_private_as_check(attr->aspath)) {
1880 if (peer_af_flag_check(
1881 peer, afi, safi,
1882 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1883 attr->aspath = aspath_replace_private_asns(
1884 attr->aspath, bgp->as, peer->as);
1885 else
1886 /*
1887 * Walk the aspath to retain any instances of
1888 * the peer_asn
1889 */
1890 attr->aspath = aspath_remove_private_asns(
1891 attr->aspath, peer->as);
1892 }
1893 }
1894 }
1895
1896 /* If this is an EBGP peer with as-override */
1897 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1898 struct peer *peer, struct attr *attr)
1899 {
1900 struct aspath *aspath;
1901
1902 if (peer->sort == BGP_PEER_EBGP &&
1903 peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1904 if (attr->aspath->refcnt)
1905 aspath = aspath_dup(attr->aspath);
1906 else
1907 aspath = attr->aspath;
1908
1909 attr->aspath = aspath_intern(
1910 aspath_replace_specific_asn(aspath, peer->as, bgp->as));
1911
1912 aspath_free(aspath);
1913 }
1914 }
1915
1916 void bgp_attr_add_llgr_community(struct attr *attr)
1917 {
1918 struct community *old;
1919 struct community *new;
1920 struct community *merge;
1921 struct community *llgr;
1922
1923 old = bgp_attr_get_community(attr);
1924 llgr = community_str2com("llgr-stale");
1925
1926 assert(llgr);
1927
1928 if (old) {
1929 merge = community_merge(community_dup(old), llgr);
1930
1931 if (old->refcnt == 0)
1932 community_free(&old);
1933
1934 new = community_uniq_sort(merge);
1935 community_free(&merge);
1936 } else {
1937 new = community_dup(llgr);
1938 }
1939
1940 community_free(&llgr);
1941
1942 bgp_attr_set_community(attr, new);
1943 }
1944
1945 void bgp_attr_add_gshut_community(struct attr *attr)
1946 {
1947 struct community *old;
1948 struct community *new;
1949 struct community *merge;
1950 struct community *gshut;
1951
1952 old = bgp_attr_get_community(attr);
1953 gshut = community_str2com("graceful-shutdown");
1954
1955 assert(gshut);
1956
1957 if (old) {
1958 merge = community_merge(community_dup(old), gshut);
1959
1960 if (old->refcnt == 0)
1961 community_free(&old);
1962
1963 new = community_uniq_sort(merge);
1964 community_free(&merge);
1965 } else {
1966 new = community_dup(gshut);
1967 }
1968
1969 community_free(&gshut);
1970 bgp_attr_set_community(attr, new);
1971
1972 /* When we add the graceful-shutdown community we must also
1973 * lower the local-preference */
1974 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1975 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1976 }
1977
1978
1979 /* Notify BGP Conditional advertisement scanner process. */
1980 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1981 {
1982 struct peer *peer = SUBGRP_PEER(subgrp);
1983 afi_t afi = SUBGRP_AFI(subgrp);
1984 safi_t safi = SUBGRP_SAFI(subgrp);
1985 struct bgp_filter *filter = &peer->filter[afi][safi];
1986
1987 if (!ADVERTISE_MAP_NAME(filter))
1988 return;
1989
1990 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1991 return;
1992
1993 peer->advmap_table_change = true;
1994 }
1995
1996
1997 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1998 {
1999 if (family == AF_INET) {
2000 attr->nexthop.s_addr = INADDR_ANY;
2001 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
2002 }
2003 if (family == AF_INET6)
2004 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
2005 if (family == AF_EVPN)
2006 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
2007 }
2008
2009 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
2010 struct update_subgroup *subgrp,
2011 const struct prefix *p, struct attr *attr,
2012 struct attr *post_attr)
2013 {
2014 struct bgp_filter *filter;
2015 struct peer *from;
2016 struct peer *peer;
2017 struct peer *onlypeer;
2018 struct bgp *bgp;
2019 struct attr *piattr;
2020 route_map_result_t ret;
2021 int transparent;
2022 int reflect;
2023 afi_t afi;
2024 safi_t safi;
2025 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
2026 bool nh_reset = false;
2027 uint64_t cum_bw;
2028
2029 if (DISABLE_BGP_ANNOUNCE)
2030 return false;
2031
2032 afi = SUBGRP_AFI(subgrp);
2033 safi = SUBGRP_SAFI(subgrp);
2034 peer = SUBGRP_PEER(subgrp);
2035 onlypeer = NULL;
2036 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
2037 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
2038
2039 from = pi->peer;
2040 filter = &peer->filter[afi][safi];
2041 bgp = SUBGRP_INST(subgrp);
2042 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
2043 : pi->attr;
2044
2045 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
2046 peer->pmax_out[afi][safi] != 0 &&
2047 subgrp->pscount >= peer->pmax_out[afi][safi]) {
2048 if (BGP_DEBUG(update, UPDATE_OUT) ||
2049 BGP_DEBUG(update, UPDATE_PREFIX)) {
2050 zlog_debug("%s reached maximum prefix to be send (%u)",
2051 peer->host, peer->pmax_out[afi][safi]);
2052 }
2053 return false;
2054 }
2055
2056 #ifdef ENABLE_BGP_VNC
2057 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
2058 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
2059 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
2060
2061 /*
2062 * direct and direct_ext type routes originate internally even
2063 * though they can have peer pointers that reference other
2064 * systems
2065 */
2066 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
2067 __func__, p);
2068 samepeer_safe = 1;
2069 }
2070 #endif
2071
2072 if (((afi == AFI_IP) || (afi == AFI_IP6))
2073 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
2074 && (pi->type == ZEBRA_ROUTE_BGP)
2075 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
2076
2077 /* Applies to routes leaked vpn->vrf and vrf->vpn */
2078
2079 samepeer_safe = 1;
2080 }
2081
2082 /* With addpath we may be asked to TX all kinds of paths so make sure
2083 * pi is valid */
2084 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
2085 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
2086 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
2087 return false;
2088 }
2089
2090 /* If this is not the bestpath then check to see if there is an enabled
2091 * addpath
2092 * feature that requires us to advertise it */
2093 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2094 if (!bgp_addpath_capable(pi, peer, afi, safi))
2095 return false;
2096
2097 /* Aggregate-address suppress check. */
2098 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
2099 return false;
2100
2101 /*
2102 * If we are doing VRF 2 VRF leaking via the import
2103 * statement, we want to prevent the route going
2104 * off box as that the RT and RD created are localy
2105 * significant and globaly useless.
2106 */
2107 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
2108 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
2109 return false;
2110
2111 /* If it's labeled safi, make sure the route has a valid label. */
2112 if (safi == SAFI_LABELED_UNICAST) {
2113 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
2114 if (!bgp_is_valid_label(&label)) {
2115 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2116 zlog_debug("u%" PRIu64 ":s%" PRIu64
2117 " %pFX is filtered - no label (%p)",
2118 subgrp->update_group->id, subgrp->id,
2119 p, &label);
2120 return false;
2121 }
2122 }
2123
2124 /* Do not send back route to sender. */
2125 if (onlypeer && from == onlypeer) {
2126 return false;
2127 }
2128
2129 /* Do not send the default route in the BGP table if the neighbor is
2130 * configured for default-originate */
2131 if (CHECK_FLAG(peer->af_flags[afi][safi],
2132 PEER_FLAG_DEFAULT_ORIGINATE)) {
2133 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
2134 return false;
2135 else if (p->family == AF_INET6 && p->prefixlen == 0)
2136 return false;
2137 }
2138
2139 /* Transparency check. */
2140 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
2141 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
2142 transparent = 1;
2143 else
2144 transparent = 0;
2145
2146 /* If community is not disabled check the no-export and local. */
2147 if (!transparent && bgp_community_filter(peer, piattr)) {
2148 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2149 zlog_debug("%s: community filter check fail for %pFX",
2150 __func__, p);
2151 return false;
2152 }
2153
2154 /* If the attribute has originator-id and it is same as remote
2155 peer's id. */
2156 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
2157 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
2158 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2159 zlog_debug(
2160 "%pBP [Update:SEND] %pFX originator-id is same as remote router-id",
2161 onlypeer, p);
2162 return false;
2163 }
2164
2165 /* ORF prefix-list filter check */
2166 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
2167 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
2168 || CHECK_FLAG(peer->af_cap[afi][safi],
2169 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2170 if (peer->orf_plist[afi][safi]) {
2171 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2172 == PREFIX_DENY) {
2173 if (bgp_debug_update(NULL, p,
2174 subgrp->update_group, 0))
2175 zlog_debug(
2176 "%pBP [Update:SEND] %pFX is filtered via ORF",
2177 peer, p);
2178 return false;
2179 }
2180 }
2181
2182 /* Output filter check. */
2183 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2184 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2185 zlog_debug("%pBP [Update:SEND] %pFX is filtered", peer,
2186 p);
2187 return false;
2188 }
2189
2190 /* AS path loop check. */
2191 if (onlypeer && onlypeer->as_path_loop_detection
2192 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
2193 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2194 zlog_debug(
2195 "%pBP [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2196 onlypeer, onlypeer->as);
2197 return false;
2198 }
2199
2200 /* If we're a CONFED we need to loop check the CONFED ID too */
2201 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2202 if (aspath_loop_check_confed(piattr->aspath, bgp->confed_id)) {
2203 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2204 zlog_debug(
2205 "%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
2206 peer, bgp->confed_id);
2207 return false;
2208 }
2209 }
2210
2211 /* Route-Reflect check. */
2212 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2213 reflect = 1;
2214 else
2215 reflect = 0;
2216
2217 /* IBGP reflection check. */
2218 if (reflect && !samepeer_safe) {
2219 /* A route from a Client peer. */
2220 if (CHECK_FLAG(from->af_flags[afi][safi],
2221 PEER_FLAG_REFLECTOR_CLIENT)) {
2222 /* Reflect to all the Non-Client peers and also to the
2223 Client peers other than the originator. Originator
2224 check
2225 is already done. So there is noting to do. */
2226 /* no bgp client-to-client reflection check. */
2227 if (CHECK_FLAG(bgp->flags,
2228 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2229 if (CHECK_FLAG(peer->af_flags[afi][safi],
2230 PEER_FLAG_REFLECTOR_CLIENT))
2231 return false;
2232 } else {
2233 /* A route from a Non-client peer. Reflect to all other
2234 clients. */
2235 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2236 PEER_FLAG_REFLECTOR_CLIENT))
2237 return false;
2238 }
2239 }
2240
2241 /* For modify attribute, copy it to temporary structure.
2242 * post_attr comes from BGP conditional advertisements, where
2243 * attributes are already processed by advertise-map route-map,
2244 * and this needs to be saved instead of overwriting from the
2245 * path attributes.
2246 */
2247 if (post_attr)
2248 *attr = *post_attr;
2249 else
2250 *attr = *piattr;
2251
2252 /* If local-preference is not set. */
2253 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2254 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2255 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2256 attr->local_pref = bgp->default_local_pref;
2257 }
2258
2259 /* If originator-id is not set and the route is to be reflected,
2260 set the originator id */
2261 if (reflect
2262 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2263 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2264 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2265 }
2266
2267 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2268 */
2269 if (peer->sort == BGP_PEER_EBGP
2270 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2271 if (from != bgp->peer_self && !transparent
2272 && !CHECK_FLAG(peer->af_flags[afi][safi],
2273 PEER_FLAG_MED_UNCHANGED))
2274 attr->flag &=
2275 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2276 }
2277
2278 /* Since the nexthop attribute can vary per peer, it is not explicitly
2279 * set
2280 * in announce check, only certain flags and length (or number of
2281 * nexthops
2282 * -- for IPv6/MP_REACH) are set here in order to guide the update
2283 * formation
2284 * code in setting the nexthop(s) on a per peer basis in
2285 * reformat_peer().
2286 * Typically, the source nexthop in the attribute is preserved but in
2287 * the
2288 * scenarios where we know it will always be overwritten, we reset the
2289 * nexthop to "0" in an attempt to achieve better Update packing. An
2290 * example of this is when a prefix from each of 2 IBGP peers needs to
2291 * be
2292 * announced to an EBGP peer (and they have the same attributes barring
2293 * their nexthop).
2294 */
2295 if (reflect)
2296 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2297
2298 #define NEXTHOP_IS_V6 \
2299 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2300 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2301 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2302 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2303
2304 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2305 * if
2306 * the peer (group) is configured to receive link-local nexthop
2307 * unchanged
2308 * and it is available in the prefix OR we're not reflecting the route,
2309 * link-local nexthop address is valid and
2310 * the peer (group) to whom we're going to announce is on a shared
2311 * network
2312 * and this is either a self-originated route or the peer is EBGP.
2313 * By checking if nexthop LL address is valid we are sure that
2314 * we do not announce LL address as `::`.
2315 */
2316 if (NEXTHOP_IS_V6) {
2317 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2318 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2319 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2320 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2321 || (!reflect && !transparent
2322 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2323 && peer->shared_network
2324 && (from == bgp->peer_self
2325 || peer->sort == BGP_PEER_EBGP))) {
2326 attr->mp_nexthop_len =
2327 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2328 }
2329
2330 /* Clear off link-local nexthop in source, whenever it is not
2331 * needed to
2332 * ensure more prefixes share the same attribute for
2333 * announcement.
2334 */
2335 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2336 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2337 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2338 }
2339
2340 if (bgp_check_role_applicability(afi, safi) &&
2341 bgp_otc_egress(peer, attr))
2342 return false;
2343
2344 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2345 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2346
2347 if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
2348 filter->advmap.aname &&
2349 route_map_lookup_by_name(filter->advmap.aname)) {
2350 struct bgp_path_info rmap_path = {0};
2351 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2352 struct attr dummy_attr = *attr;
2353
2354 /* Fill temp path_info */
2355 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2356 pi, peer, &dummy_attr);
2357
2358 struct route_map *amap =
2359 route_map_lookup_by_name(filter->advmap.aname);
2360
2361 ret = route_map_apply(amap, p, &rmap_path);
2362
2363 bgp_attr_flush(&dummy_attr);
2364
2365 /*
2366 * The conditional advertisement mode is Withdraw and this
2367 * prefix is a conditional prefix. Don't advertise it
2368 */
2369 if (ret == RMAP_PERMITMATCH)
2370 return false;
2371 }
2372
2373 /* Route map & unsuppress-map apply. */
2374 if (!post_attr &&
2375 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2376 struct bgp_path_info rmap_path = {0};
2377 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2378 struct attr dummy_attr = {0};
2379
2380 /* Fill temp path_info */
2381 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2382 pi, peer, attr);
2383
2384 /* don't confuse inbound and outbound setting */
2385 RESET_FLAG(attr->rmap_change_flags);
2386
2387 /*
2388 * The route reflector is not allowed to modify the attributes
2389 * of the reflected IBGP routes unless explicitly allowed.
2390 */
2391 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2392 && !CHECK_FLAG(bgp->flags,
2393 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2394 dummy_attr = *attr;
2395 rmap_path.attr = &dummy_attr;
2396 }
2397
2398 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2399
2400 if (bgp_path_suppressed(pi))
2401 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2402 &rmap_path);
2403 else
2404 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2405 &rmap_path);
2406
2407 bgp_attr_flush(&dummy_attr);
2408 peer->rmap_type = 0;
2409
2410 if (ret == RMAP_DENYMATCH) {
2411 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2412 zlog_debug(
2413 "%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
2414 peer, p, ROUTE_MAP_OUT_NAME(filter));
2415 bgp_attr_flush(rmap_path.attr);
2416 return false;
2417 }
2418 }
2419
2420 /* RFC 8212 to prevent route leaks.
2421 * This specification intends to improve this situation by requiring the
2422 * explicit configuration of both BGP Import and Export Policies for any
2423 * External BGP (EBGP) session such as customers, peers, or
2424 * confederation boundaries for all enabled address families. Through
2425 * codification of the aforementioned requirement, operators will
2426 * benefit from consistent behavior across different BGP
2427 * implementations.
2428 */
2429 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2430 if (!bgp_outbound_policy_exists(peer, filter)) {
2431 if (monotime_since(&bgp->ebgprequirespolicywarning,
2432 NULL) > FIFTEENMINUTE2USEC ||
2433 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2434 zlog_warn(
2435 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2436 monotime(&bgp->ebgprequirespolicywarning);
2437 }
2438 return false;
2439 }
2440
2441 /* draft-ietf-idr-deprecate-as-set-confed-set
2442 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2443 * Eventually, This document (if approved) updates RFC 4271
2444 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2445 * and obsoletes RFC 6472.
2446 */
2447 if (peer->bgp->reject_as_sets)
2448 if (aspath_check_as_sets(attr->aspath))
2449 return false;
2450
2451 /* If neighbor soo is configured, then check if the route has
2452 * SoO extended community and validate against the configured
2453 * one. If they match, do not announce, to prevent routing
2454 * loops.
2455 */
2456 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2457 peer->soo[afi][safi]) {
2458 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2459 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2460
2461 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2462 ECOMMUNITY_SITE_ORIGIN) ||
2463 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2464 ECOMMUNITY_SITE_ORIGIN) ||
2465 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
2466 ECOMMUNITY_SITE_ORIGIN)) &&
2467 ecommunity_include(ecomm, ecomm_soo)) {
2468 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2469 zlog_debug(
2470 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2471 peer, p, ecommunity_str(ecomm_soo));
2472 return false;
2473 }
2474 }
2475
2476 /* Codification of AS 0 Processing */
2477 if (aspath_check_as_zero(attr->aspath))
2478 return false;
2479
2480 if (bgp_in_graceful_shutdown(bgp)) {
2481 if (peer->sort == BGP_PEER_IBGP
2482 || peer->sort == BGP_PEER_CONFED) {
2483 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2484 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2485 } else {
2486 bgp_attr_add_gshut_community(attr);
2487 }
2488 }
2489
2490 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2491 * Capability" to a neighbor MUST perform the following upon receiving
2492 * a route from that neighbor with the "LLGR_STALE" community, or upon
2493 * attaching the "LLGR_STALE" community itself per Section 4.2:
2494 *
2495 * The route SHOULD NOT be advertised to any neighbor from which the
2496 * Long-lived Graceful Restart Capability has not been received.
2497 */
2498 if (bgp_attr_get_community(attr) &&
2499 community_include(bgp_attr_get_community(attr),
2500 COMMUNITY_LLGR_STALE) &&
2501 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2502 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2503 return false;
2504
2505 /* After route-map has been applied, we check to see if the nexthop to
2506 * be carried in the attribute (that is used for the announcement) can
2507 * be cleared off or not. We do this in all cases where we would be
2508 * setting the nexthop to "ourselves". For IPv6, we only need to
2509 * consider
2510 * the global nexthop here; the link-local nexthop would have been
2511 * cleared
2512 * already, and if not, it is required by the update formation code.
2513 * Also see earlier comments in this function.
2514 */
2515 /*
2516 * If route-map has performed some operation on the nexthop or the peer
2517 * configuration says to pass it unchanged, we cannot reset the nexthop
2518 * here, so only attempt to do it if these aren't true. Note that the
2519 * route-map handler itself might have cleared the nexthop, if for
2520 * example,
2521 * it is configured as 'peer-address'.
2522 */
2523 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2524 piattr->rmap_change_flags)
2525 && !transparent
2526 && !CHECK_FLAG(peer->af_flags[afi][safi],
2527 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2528 /* We can reset the nexthop, if setting (or forcing) it to
2529 * 'self' */
2530 if (CHECK_FLAG(peer->af_flags[afi][safi],
2531 PEER_FLAG_NEXTHOP_SELF)
2532 || CHECK_FLAG(peer->af_flags[afi][safi],
2533 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2534 if (!reflect
2535 || CHECK_FLAG(peer->af_flags[afi][safi],
2536 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2537 subgroup_announce_reset_nhop(
2538 (peer_cap_enhe(peer, afi, safi)
2539 ? AF_INET6
2540 : p->family),
2541 attr);
2542 nh_reset = true;
2543 }
2544 } else if (peer->sort == BGP_PEER_EBGP) {
2545 /* Can also reset the nexthop if announcing to EBGP, but
2546 * only if
2547 * no peer in the subgroup is on a shared subnet.
2548 * Note: 3rd party nexthop currently implemented for
2549 * IPv4 only.
2550 */
2551 if ((p->family == AF_INET) &&
2552 (!bgp_subgrp_multiaccess_check_v4(
2553 piattr->nexthop,
2554 subgrp, from))) {
2555 subgroup_announce_reset_nhop(
2556 (peer_cap_enhe(peer, afi, safi)
2557 ? AF_INET6
2558 : p->family),
2559 attr);
2560 nh_reset = true;
2561 }
2562
2563 if ((p->family == AF_INET6) &&
2564 (!bgp_subgrp_multiaccess_check_v6(
2565 piattr->mp_nexthop_global,
2566 subgrp, from))) {
2567 subgroup_announce_reset_nhop(
2568 (peer_cap_enhe(peer, afi, safi)
2569 ? AF_INET6
2570 : p->family),
2571 attr);
2572 nh_reset = true;
2573 }
2574
2575
2576
2577 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2578 /*
2579 * This flag is used for leaked vpn-vrf routes
2580 */
2581 int family = p->family;
2582
2583 if (peer_cap_enhe(peer, afi, safi))
2584 family = AF_INET6;
2585
2586 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2587 zlog_debug(
2588 "%s: %pFX BGP_PATH_ANNC_NH_SELF, family=%s",
2589 __func__, p, family2str(family));
2590 subgroup_announce_reset_nhop(family, attr);
2591 nh_reset = true;
2592 }
2593 }
2594
2595 /* If IPv6/MP and nexthop does not have any override and happens
2596 * to
2597 * be a link-local address, reset it so that we don't pass along
2598 * the
2599 * source's link-local IPv6 address to recipients who may not be
2600 * on
2601 * the same interface.
2602 */
2603 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2604 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2605 subgroup_announce_reset_nhop(AF_INET6, attr);
2606 nh_reset = true;
2607 }
2608 }
2609
2610 /* If this is an iBGP, send Origin Validation State (OVS)
2611 * extended community (rfc8097).
2612 */
2613 if (peer->sort == BGP_PEER_IBGP) {
2614 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2615
2616 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2617
2618 if (rpki_state != RPKI_NOT_BEING_USED)
2619 bgp_attr_set_ecommunity(
2620 attr, ecommunity_add_origin_validation_state(
2621 rpki_state,
2622 bgp_attr_get_ecommunity(attr)));
2623 }
2624
2625 /*
2626 * When the next hop is set to ourselves, if all multipaths have
2627 * link-bandwidth announce the cumulative bandwidth as that makes
2628 * the most sense. However, don't modify if the link-bandwidth has
2629 * been explicitly set by user policy.
2630 */
2631 if (nh_reset &&
2632 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2633 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2634 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2635 bgp_attr_set_ecommunity(
2636 attr,
2637 ecommunity_replace_linkbw(
2638 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2639 CHECK_FLAG(
2640 peer->flags,
2641 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2642
2643 return true;
2644 }
2645
2646 static void bgp_route_select_timer_expire(struct thread *thread)
2647 {
2648 struct afi_safi_info *info;
2649 afi_t afi;
2650 safi_t safi;
2651 struct bgp *bgp;
2652
2653 info = THREAD_ARG(thread);
2654 afi = info->afi;
2655 safi = info->safi;
2656 bgp = info->bgp;
2657
2658 bgp->gr_info[afi][safi].t_route_select = NULL;
2659 XFREE(MTYPE_TMP, info);
2660
2661 /* Best path selection */
2662 bgp_best_path_select_defer(bgp, afi, safi);
2663 }
2664
2665 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2666 struct bgp_maxpaths_cfg *mpath_cfg,
2667 struct bgp_path_info_pair *result, afi_t afi,
2668 safi_t safi)
2669 {
2670 struct bgp_path_info *new_select;
2671 struct bgp_path_info *old_select;
2672 struct bgp_path_info *pi;
2673 struct bgp_path_info *pi1;
2674 struct bgp_path_info *pi2;
2675 struct bgp_path_info *nextpi = NULL;
2676 int paths_eq, do_mpath, debug;
2677 struct list mp_list;
2678 char pfx_buf[PREFIX2STR_BUFFER];
2679 char path_buf[PATH_ADDPATH_STR_BUFFER];
2680
2681 bgp_mp_list_init(&mp_list);
2682 do_mpath =
2683 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2684
2685 debug = bgp_debug_bestpath(dest);
2686
2687 if (debug)
2688 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2689
2690 dest->reason = bgp_path_selection_none;
2691 /* bgp deterministic-med */
2692 new_select = NULL;
2693 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2694
2695 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2696 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2697 pi1 = pi1->next)
2698 bgp_path_info_unset_flag(dest, pi1,
2699 BGP_PATH_DMED_SELECTED);
2700
2701 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2702 pi1 = pi1->next) {
2703 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2704 continue;
2705 if (BGP_PATH_HOLDDOWN(pi1))
2706 continue;
2707 if (pi1->peer != bgp->peer_self)
2708 if (!peer_established(pi1->peer))
2709 continue;
2710
2711 new_select = pi1;
2712 if (pi1->next) {
2713 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2714 if (CHECK_FLAG(pi2->flags,
2715 BGP_PATH_DMED_CHECK))
2716 continue;
2717 if (BGP_PATH_HOLDDOWN(pi2))
2718 continue;
2719 if (pi2->peer != bgp->peer_self
2720 && !CHECK_FLAG(
2721 pi2->peer->sflags,
2722 PEER_STATUS_NSF_WAIT))
2723 if (pi2->peer->status
2724 != Established)
2725 continue;
2726
2727 if (!aspath_cmp_left(pi1->attr->aspath,
2728 pi2->attr->aspath)
2729 && !aspath_cmp_left_confed(
2730 pi1->attr->aspath,
2731 pi2->attr->aspath))
2732 continue;
2733
2734 if (bgp_path_info_cmp(
2735 bgp, pi2, new_select,
2736 &paths_eq, mpath_cfg, debug,
2737 pfx_buf, afi, safi,
2738 &dest->reason)) {
2739 bgp_path_info_unset_flag(
2740 dest, new_select,
2741 BGP_PATH_DMED_SELECTED);
2742 new_select = pi2;
2743 }
2744
2745 bgp_path_info_set_flag(
2746 dest, pi2, BGP_PATH_DMED_CHECK);
2747 }
2748 }
2749 bgp_path_info_set_flag(dest, new_select,
2750 BGP_PATH_DMED_CHECK);
2751 bgp_path_info_set_flag(dest, new_select,
2752 BGP_PATH_DMED_SELECTED);
2753
2754 if (debug) {
2755 bgp_path_info_path_with_addpath_rx_str(
2756 new_select, path_buf, sizeof(path_buf));
2757 zlog_debug(
2758 "%pBD(%s): %s is the bestpath from AS %u",
2759 dest, bgp->name_pretty, path_buf,
2760 aspath_get_first_as(
2761 new_select->attr->aspath));
2762 }
2763 }
2764 }
2765
2766 /* Check old selected route and new selected route. */
2767 old_select = NULL;
2768 new_select = NULL;
2769 for (pi = bgp_dest_get_bgp_path_info(dest);
2770 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2771 enum bgp_path_selection_reason reason;
2772
2773 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2774 old_select = pi;
2775
2776 if (BGP_PATH_HOLDDOWN(pi)) {
2777 /* reap REMOVED routes, if needs be
2778 * selected route must stay for a while longer though
2779 */
2780 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2781 && (pi != old_select))
2782 bgp_path_info_reap(dest, pi);
2783
2784 if (debug)
2785 zlog_debug("%s: pi %p in holddown", __func__,
2786 pi);
2787
2788 continue;
2789 }
2790
2791 if (pi->peer && pi->peer != bgp->peer_self
2792 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2793 if (!peer_established(pi->peer)) {
2794
2795 if (debug)
2796 zlog_debug(
2797 "%s: pi %p non self peer %s not estab state",
2798 __func__, pi, pi->peer->host);
2799
2800 continue;
2801 }
2802
2803 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2804 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2805 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2806 if (debug)
2807 zlog_debug("%s: pi %p dmed", __func__, pi);
2808 continue;
2809 }
2810
2811 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2812
2813 reason = dest->reason;
2814 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2815 debug, pfx_buf, afi, safi,
2816 &dest->reason)) {
2817 if (new_select == NULL &&
2818 reason != bgp_path_selection_none)
2819 dest->reason = reason;
2820 new_select = pi;
2821 }
2822 }
2823
2824 /* Now that we know which path is the bestpath see if any of the other
2825 * paths
2826 * qualify as multipaths
2827 */
2828 if (debug) {
2829 if (new_select)
2830 bgp_path_info_path_with_addpath_rx_str(
2831 new_select, path_buf, sizeof(path_buf));
2832 else
2833 snprintf(path_buf, sizeof(path_buf), "NONE");
2834 zlog_debug(
2835 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2836 dest, bgp->name_pretty, path_buf,
2837 old_select ? old_select->peer->host : "NONE");
2838 }
2839
2840 if (do_mpath && new_select) {
2841 for (pi = bgp_dest_get_bgp_path_info(dest);
2842 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2843
2844 if (debug)
2845 bgp_path_info_path_with_addpath_rx_str(
2846 pi, path_buf, sizeof(path_buf));
2847
2848 if (pi == new_select) {
2849 if (debug)
2850 zlog_debug(
2851 "%pBD(%s): %s is the bestpath, add to the multipath list",
2852 dest, bgp->name_pretty,
2853 path_buf);
2854 bgp_mp_list_add(&mp_list, pi);
2855 continue;
2856 }
2857
2858 if (BGP_PATH_HOLDDOWN(pi))
2859 continue;
2860
2861 if (pi->peer && pi->peer != bgp->peer_self
2862 && !CHECK_FLAG(pi->peer->sflags,
2863 PEER_STATUS_NSF_WAIT))
2864 if (!peer_established(pi->peer))
2865 continue;
2866
2867 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2868 if (debug)
2869 zlog_debug(
2870 "%pBD: %s has the same nexthop as the bestpath, skip it",
2871 dest, path_buf);
2872 continue;
2873 }
2874
2875 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2876 mpath_cfg, debug, pfx_buf, afi, safi,
2877 &dest->reason);
2878
2879 if (paths_eq) {
2880 if (debug)
2881 zlog_debug(
2882 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2883 dest, path_buf);
2884 bgp_mp_list_add(&mp_list, pi);
2885 }
2886 }
2887 }
2888
2889 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2890 mpath_cfg);
2891 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2892 bgp_mp_list_clear(&mp_list);
2893
2894 bgp_addpath_update_ids(bgp, dest, afi, safi);
2895
2896 result->old = old_select;
2897 result->new = new_select;
2898
2899 return;
2900 }
2901
2902 /*
2903 * A new route/change in bestpath of an existing route. Evaluate the path
2904 * for advertisement to the subgroup.
2905 */
2906 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2907 struct bgp_path_info *selected,
2908 struct bgp_dest *dest,
2909 uint32_t addpath_tx_id)
2910 {
2911 const struct prefix *p;
2912 struct peer *onlypeer;
2913 struct attr attr;
2914 afi_t afi;
2915 safi_t safi;
2916 struct bgp *bgp;
2917 bool advertise;
2918
2919 p = bgp_dest_get_prefix(dest);
2920 afi = SUBGRP_AFI(subgrp);
2921 safi = SUBGRP_SAFI(subgrp);
2922 bgp = SUBGRP_INST(subgrp);
2923 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2924 : NULL);
2925
2926 if (BGP_DEBUG(update, UPDATE_OUT))
2927 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2928
2929 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2930 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2931 PEER_STATUS_ORF_WAIT_REFRESH))
2932 return;
2933
2934 memset(&attr, 0, sizeof(attr));
2935 /* It's initialized in bgp_announce_check() */
2936
2937 /* Announcement to the subgroup. If the route is filtered withdraw it.
2938 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2939 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2940 * route
2941 */
2942 advertise = bgp_check_advertise(bgp, dest);
2943
2944 if (selected) {
2945 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2946 NULL)) {
2947 /* Route is selected, if the route is already installed
2948 * in FIB, then it is advertised
2949 */
2950 if (advertise) {
2951 if (!bgp_check_withdrawal(bgp, dest))
2952 bgp_adj_out_set_subgroup(
2953 dest, subgrp, &attr, selected);
2954 else
2955 bgp_adj_out_unset_subgroup(
2956 dest, subgrp, 1, addpath_tx_id);
2957 }
2958 } else
2959 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2960 addpath_tx_id);
2961 }
2962
2963 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2964 else {
2965 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2966 }
2967 }
2968
2969 /*
2970 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2971 * This is called at the end of route processing.
2972 */
2973 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2974 {
2975 struct bgp_path_info *pi;
2976
2977 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2978 if (BGP_PATH_HOLDDOWN(pi))
2979 continue;
2980 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2981 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2982 }
2983 }
2984
2985 /*
2986 * Has the route changed from the RIB's perspective? This is invoked only
2987 * if the route selection returns the same best route as earlier - to
2988 * determine if we need to update zebra or not.
2989 */
2990 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2991 {
2992 struct bgp_path_info *mpinfo;
2993
2994 /* If this is multipath, check all selected paths for any nexthop
2995 * change or attribute change. Some attribute changes (e.g., community)
2996 * aren't of relevance to the RIB, but we'll update zebra to ensure
2997 * we handle the case of BGP nexthop change. This is the behavior
2998 * when the best path has an attribute change anyway.
2999 */
3000 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
3001 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
3002 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
3003 return true;
3004
3005 /*
3006 * If this is multipath, check all selected paths for any nexthop change
3007 */
3008 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
3009 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
3010 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
3011 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
3012 return true;
3013 }
3014
3015 /* Nothing has changed from the RIB's perspective. */
3016 return false;
3017 }
3018
3019 struct bgp_process_queue {
3020 struct bgp *bgp;
3021 STAILQ_HEAD(, bgp_dest) pqueue;
3022 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
3023 unsigned int flags;
3024 unsigned int queued;
3025 };
3026
3027 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
3028 safi_t safi, struct bgp_dest *dest,
3029 struct bgp_path_info *new_select,
3030 struct bgp_path_info *old_select)
3031 {
3032 const struct prefix *p = bgp_dest_get_prefix(dest);
3033
3034 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
3035 return;
3036
3037 if (advertise_type5_routes(bgp, afi) && new_select
3038 && is_route_injectable_into_evpn(new_select)) {
3039
3040 /* apply the route-map */
3041 if (bgp->adv_cmd_rmap[afi][safi].map) {
3042 route_map_result_t ret;
3043 struct bgp_path_info rmap_path;
3044 struct bgp_path_info_extra rmap_path_extra;
3045 struct attr dummy_attr;
3046
3047 dummy_attr = *new_select->attr;
3048
3049 /* Fill temp path_info */
3050 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
3051 new_select, new_select->peer,
3052 &dummy_attr);
3053
3054 RESET_FLAG(dummy_attr.rmap_change_flags);
3055
3056 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
3057 p, &rmap_path);
3058
3059 if (ret == RMAP_DENYMATCH) {
3060 bgp_attr_flush(&dummy_attr);
3061 bgp_evpn_withdraw_type5_route(bgp, p, afi,
3062 safi);
3063 } else
3064 bgp_evpn_advertise_type5_route(
3065 bgp, p, &dummy_attr, afi, safi);
3066 } else {
3067 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
3068 afi, safi);
3069 }
3070 } else if (advertise_type5_routes(bgp, afi) && old_select
3071 && is_route_injectable_into_evpn(old_select))
3072 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
3073 }
3074
3075 /*
3076 * Utility to determine whether a particular path_info should use
3077 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
3078 * in a path where we basically _know_ this is a BGP-LU route.
3079 */
3080 static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
3081 {
3082 /* Certain types get imp null; so do paths where the nexthop is
3083 * not labeled.
3084 */
3085 if (new_select->sub_type == BGP_ROUTE_STATIC
3086 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3087 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
3088 return true;
3089 else if (new_select->extra == NULL ||
3090 !bgp_is_valid_label(&new_select->extra->label[0]))
3091 /* TODO -- should be configurable? */
3092 return true;
3093 else
3094 return false;
3095 }
3096
3097 /*
3098 * old_select = The old best path
3099 * new_select = the new best path
3100 *
3101 * if (!old_select && new_select)
3102 * We are sending new information on.
3103 *
3104 * if (old_select && new_select) {
3105 * if (new_select != old_select)
3106 * We have a new best path send a change
3107 * else
3108 * We've received a update with new attributes that needs
3109 * to be passed on.
3110 * }
3111 *
3112 * if (old_select && !new_select)
3113 * We have no eligible route that we can announce or the rn
3114 * is being removed.
3115 */
3116 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3117 afi_t afi, safi_t safi)
3118 {
3119 struct bgp_path_info *new_select;
3120 struct bgp_path_info *old_select;
3121 struct bgp_path_info_pair old_and_new;
3122 int debug = 0;
3123
3124 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3125 if (dest)
3126 debug = bgp_debug_bestpath(dest);
3127 if (debug)
3128 zlog_debug(
3129 "%s: bgp delete in progress, ignoring event, p=%pBD",
3130 __func__, dest);
3131 return;
3132 }
3133 /* Is it end of initial update? (after startup) */
3134 if (!dest) {
3135 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3136 sizeof(bgp->update_delay_zebra_resume_time));
3137
3138 bgp->main_zebra_update_hold = 0;
3139 FOREACH_AFI_SAFI (afi, safi) {
3140 if (bgp_fibupd_safi(safi))
3141 bgp_zebra_announce_table(bgp, afi, safi);
3142 }
3143 bgp->main_peers_update_hold = 0;
3144
3145 bgp_start_routeadv(bgp);
3146 return;
3147 }
3148
3149 const struct prefix *p = bgp_dest_get_prefix(dest);
3150
3151 debug = bgp_debug_bestpath(dest);
3152 if (debug)
3153 zlog_debug("%s: p=%pBDi(%s) afi=%s, safi=%s start", __func__,
3154 dest, bgp->name_pretty, afi2str(afi),
3155 safi2str(safi));
3156
3157 /* The best path calculation for the route is deferred if
3158 * BGP_NODE_SELECT_DEFER is set
3159 */
3160 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3161 if (BGP_DEBUG(update, UPDATE_OUT))
3162 zlog_debug("SELECT_DEFER flag set for route %p", dest);
3163 return;
3164 }
3165
3166 /* Best path selection. */
3167 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3168 afi, safi);
3169 old_select = old_and_new.old;
3170 new_select = old_and_new.new;
3171
3172 /* Do we need to allocate or free labels?
3173 * Right now, since we only deal with per-prefix labels, it is not
3174 * necessary to do this upon changes to best path. Exceptions:
3175 * - label index has changed -> recalculate resulting label
3176 * - path_info sub_type changed -> switch to/from implicit-null
3177 * - no valid label (due to removed static label binding) -> get new one
3178 */
3179 if (bgp->allocate_mpls_labels[afi][safi]) {
3180 if (new_select) {
3181 if (!old_select
3182 || bgp_label_index_differs(new_select, old_select)
3183 || new_select->sub_type != old_select->sub_type
3184 || !bgp_is_valid_label(&dest->local_label)) {
3185 /* Enforced penultimate hop popping:
3186 * implicit-null for local routes, aggregate
3187 * and redistributed routes
3188 */
3189 if (bgp_lu_need_imp_null(new_select)) {
3190 if (CHECK_FLAG(
3191 dest->flags,
3192 BGP_NODE_REGISTERED_FOR_LABEL)
3193 || CHECK_FLAG(
3194 dest->flags,
3195 BGP_NODE_LABEL_REQUESTED))
3196 bgp_unregister_for_label(dest);
3197 dest->local_label = mpls_lse_encode(
3198 MPLS_LABEL_IMPLICIT_NULL, 0, 0,
3199 1);
3200 bgp_set_valid_label(&dest->local_label);
3201 } else
3202 bgp_register_for_label(dest,
3203 new_select);
3204 }
3205 } else if (CHECK_FLAG(dest->flags,
3206 BGP_NODE_REGISTERED_FOR_LABEL)
3207 || CHECK_FLAG(dest->flags,
3208 BGP_NODE_LABEL_REQUESTED)) {
3209 bgp_unregister_for_label(dest);
3210 }
3211 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3212 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3213 bgp_unregister_for_label(dest);
3214 }
3215
3216 if (debug)
3217 zlog_debug(
3218 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3219 __func__, dest, bgp->name_pretty, afi2str(afi),
3220 safi2str(safi), old_select, new_select);
3221
3222 /* If best route remains the same and this is not due to user-initiated
3223 * clear, see exactly what needs to be done.
3224 */
3225 if (old_select && old_select == new_select
3226 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3227 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3228 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3229 if (bgp_zebra_has_route_changed(old_select)) {
3230 #ifdef ENABLE_BGP_VNC
3231 vnc_import_bgp_add_route(bgp, p, old_select);
3232 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3233 #endif
3234 if (bgp_fibupd_safi(safi)
3235 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3236
3237 if (BGP_SUPPRESS_FIB_ENABLED(bgp)
3238 && new_select->sub_type == BGP_ROUTE_NORMAL)
3239 SET_FLAG(dest->flags,
3240 BGP_NODE_FIB_INSTALL_PENDING);
3241
3242 if (new_select->type == ZEBRA_ROUTE_BGP
3243 && (new_select->sub_type == BGP_ROUTE_NORMAL
3244 || new_select->sub_type
3245 == BGP_ROUTE_IMPORTED))
3246
3247 bgp_zebra_announce(dest, p, old_select,
3248 bgp, afi, safi);
3249 }
3250 }
3251
3252 /* If there is a change of interest to peers, reannounce the
3253 * route. */
3254 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3255 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3256 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3257 group_announce_route(bgp, afi, safi, dest, new_select);
3258
3259 /* unicast routes must also be annouced to
3260 * labeled-unicast update-groups */
3261 if (safi == SAFI_UNICAST)
3262 group_announce_route(bgp, afi,
3263 SAFI_LABELED_UNICAST, dest,
3264 new_select);
3265
3266 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3267 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3268 }
3269
3270 /* advertise/withdraw type-5 routes */
3271 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3272 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3273 bgp_process_evpn_route_injection(
3274 bgp, afi, safi, dest, old_select, old_select);
3275
3276 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3277 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3278 bgp_zebra_clear_route_change_flags(dest);
3279 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3280 return;
3281 }
3282
3283 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3284 */
3285 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3286
3287 /* bestpath has changed; bump version */
3288 if (old_select || new_select) {
3289 bgp_bump_version(dest);
3290
3291 if (!bgp->t_rmap_def_originate_eval) {
3292 bgp_lock(bgp);
3293 thread_add_timer(
3294 bm->master,
3295 update_group_refresh_default_originate_route_map,
3296 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3297 &bgp->t_rmap_def_originate_eval);
3298 }
3299 }
3300
3301 if (old_select)
3302 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3303 if (new_select) {
3304 if (debug)
3305 zlog_debug("%s: setting SELECTED flag", __func__);
3306 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3307 bgp_path_info_unset_flag(dest, new_select,
3308 BGP_PATH_ATTR_CHANGED);
3309 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3310 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3311 }
3312
3313 #ifdef ENABLE_BGP_VNC
3314 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3315 if (old_select != new_select) {
3316 if (old_select) {
3317 vnc_import_bgp_exterior_del_route(bgp, p,
3318 old_select);
3319 vnc_import_bgp_del_route(bgp, p, old_select);
3320 }
3321 if (new_select) {
3322 vnc_import_bgp_exterior_add_route(bgp, p,
3323 new_select);
3324 vnc_import_bgp_add_route(bgp, p, new_select);
3325 }
3326 }
3327 }
3328 #endif
3329
3330 group_announce_route(bgp, afi, safi, dest, new_select);
3331
3332 /* unicast routes must also be annouced to labeled-unicast update-groups
3333 */
3334 if (safi == SAFI_UNICAST)
3335 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3336 new_select);
3337
3338 /* FIB update. */
3339 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3340 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3341
3342 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3343 && (new_select->sub_type == BGP_ROUTE_NORMAL
3344 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3345 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3346
3347 if (BGP_SUPPRESS_FIB_ENABLED(bgp))
3348 SET_FLAG(dest->flags,
3349 BGP_NODE_FIB_INSTALL_PENDING);
3350
3351 /* if this is an evpn imported type-5 prefix,
3352 * we need to withdraw the route first to clear
3353 * the nh neigh and the RMAC entry.
3354 */
3355 if (old_select &&
3356 is_route_parent_evpn(old_select))
3357 bgp_zebra_withdraw(p, old_select, bgp, safi);
3358
3359 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3360 } else {
3361 /* Withdraw the route from the kernel. */
3362 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3363 && (old_select->sub_type == BGP_ROUTE_NORMAL
3364 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3365 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3366
3367 bgp_zebra_withdraw(p, old_select, bgp, safi);
3368 }
3369 }
3370
3371 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3372 old_select);
3373
3374 /* Clear any route change flags. */
3375 bgp_zebra_clear_route_change_flags(dest);
3376
3377 /* Reap old select bgp_path_info, if it has been removed */
3378 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3379 bgp_path_info_reap(dest, old_select);
3380
3381 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3382 return;
3383 }
3384
3385 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3386 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3387 {
3388 struct bgp_dest *dest;
3389 int cnt = 0;
3390 struct afi_safi_info *thread_info;
3391
3392 if (bgp->gr_info[afi][safi].t_route_select) {
3393 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
3394
3395 thread_info = THREAD_ARG(t);
3396 XFREE(MTYPE_TMP, thread_info);
3397 THREAD_OFF(bgp->gr_info[afi][safi].t_route_select);
3398 }
3399
3400 if (BGP_DEBUG(update, UPDATE_OUT)) {
3401 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3402 get_afi_safi_str(afi, safi, false),
3403 bgp->gr_info[afi][safi].gr_deferred);
3404 }
3405
3406 /* Process the route list */
3407 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3408 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3409 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3410 dest = bgp_route_next(dest)) {
3411 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3412 continue;
3413
3414 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3415 bgp->gr_info[afi][safi].gr_deferred--;
3416 bgp_process_main_one(bgp, dest, afi, safi);
3417 cnt++;
3418 }
3419 /* If iteration stopped before the entire table was traversed then the
3420 * node needs to be unlocked.
3421 */
3422 if (dest) {
3423 bgp_dest_unlock_node(dest);
3424 dest = NULL;
3425 }
3426
3427 /* Send EOR message when all routes are processed */
3428 if (!bgp->gr_info[afi][safi].gr_deferred) {
3429 bgp_send_delayed_eor(bgp);
3430 /* Send route processing complete message to RIB */
3431 bgp_zebra_update(afi, safi, bgp->vrf_id,
3432 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3433 return;
3434 }
3435
3436 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3437
3438 thread_info->afi = afi;
3439 thread_info->safi = safi;
3440 thread_info->bgp = bgp;
3441
3442 /* If there are more routes to be processed, start the
3443 * selection timer
3444 */
3445 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3446 BGP_ROUTE_SELECT_DELAY,
3447 &bgp->gr_info[afi][safi].t_route_select);
3448 }
3449
3450 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3451 {
3452 struct bgp_process_queue *pqnode = data;
3453 struct bgp *bgp = pqnode->bgp;
3454 struct bgp_table *table;
3455 struct bgp_dest *dest;
3456
3457 /* eoiu marker */
3458 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3459 bgp_process_main_one(bgp, NULL, 0, 0);
3460 /* should always have dedicated wq call */
3461 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3462 return WQ_SUCCESS;
3463 }
3464
3465 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3466 dest = STAILQ_FIRST(&pqnode->pqueue);
3467 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3468 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3469 table = bgp_dest_table(dest);
3470 /* note, new DESTs may be added as part of processing */
3471 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3472
3473 bgp_dest_unlock_node(dest);
3474 bgp_table_unlock(table);
3475 }
3476
3477 return WQ_SUCCESS;
3478 }
3479
3480 static void bgp_processq_del(struct work_queue *wq, void *data)
3481 {
3482 struct bgp_process_queue *pqnode = data;
3483
3484 bgp_unlock(pqnode->bgp);
3485
3486 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3487 }
3488
3489 void bgp_process_queue_init(struct bgp *bgp)
3490 {
3491 if (!bgp->process_queue) {
3492 char name[BUFSIZ];
3493
3494 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3495 bgp->process_queue = work_queue_new(bm->master, name);
3496 }
3497
3498 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3499 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3500 bgp->process_queue->spec.max_retries = 0;
3501 bgp->process_queue->spec.hold = 50;
3502 /* Use a higher yield value of 50ms for main queue processing */
3503 bgp->process_queue->spec.yield = 50 * 1000L;
3504 }
3505
3506 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3507 {
3508 struct bgp_process_queue *pqnode;
3509
3510 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3511 sizeof(struct bgp_process_queue));
3512
3513 /* unlocked in bgp_processq_del */
3514 pqnode->bgp = bgp_lock(bgp);
3515 STAILQ_INIT(&pqnode->pqueue);
3516
3517 return pqnode;
3518 }
3519
3520 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3521 {
3522 #define ARBITRARY_PROCESS_QLEN 10000
3523 struct work_queue *wq = bgp->process_queue;
3524 struct bgp_process_queue *pqnode;
3525 int pqnode_reuse = 0;
3526
3527 /* already scheduled for processing? */
3528 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3529 return;
3530
3531 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3532 * the workqueue
3533 */
3534 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3535 if (BGP_DEBUG(update, UPDATE_OUT))
3536 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3537 dest);
3538 return;
3539 }
3540
3541 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3542 if (BGP_DEBUG(update, UPDATE_OUT))
3543 zlog_debug(
3544 "Soft reconfigure table in progress for route %p",
3545 dest);
3546 return;
3547 }
3548
3549 if (wq == NULL)
3550 return;
3551
3552 /* Add route nodes to an existing work queue item until reaching the
3553 limit only if is from the same BGP view and it's not an EOIU marker
3554 */
3555 if (work_queue_item_count(wq)) {
3556 struct work_queue_item *item = work_queue_last_item(wq);
3557 pqnode = item->data;
3558
3559 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3560 || pqnode->bgp != bgp
3561 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3562 pqnode = bgp_processq_alloc(bgp);
3563 else
3564 pqnode_reuse = 1;
3565 } else
3566 pqnode = bgp_processq_alloc(bgp);
3567 /* all unlocked in bgp_process_wq */
3568 bgp_table_lock(bgp_dest_table(dest));
3569
3570 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3571 bgp_dest_lock_node(dest);
3572
3573 /* can't be enqueued twice */
3574 assert(STAILQ_NEXT(dest, pq) == NULL);
3575 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3576 pqnode->queued++;
3577
3578 if (!pqnode_reuse)
3579 work_queue_add(wq, pqnode);
3580
3581 return;
3582 }
3583
3584 void bgp_add_eoiu_mark(struct bgp *bgp)
3585 {
3586 struct bgp_process_queue *pqnode;
3587
3588 if (bgp->process_queue == NULL)
3589 return;
3590
3591 pqnode = bgp_processq_alloc(bgp);
3592
3593 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3594 work_queue_add(bgp->process_queue, pqnode);
3595 }
3596
3597 static void bgp_maximum_prefix_restart_timer(struct thread *thread)
3598 {
3599 struct peer *peer;
3600
3601 peer = THREAD_ARG(thread);
3602 peer->t_pmax_restart = NULL;
3603
3604 if (bgp_debug_neighbor_events(peer))
3605 zlog_debug(
3606 "%s Maximum-prefix restart timer expired, restore peering",
3607 peer->host);
3608
3609 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3610 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3611 }
3612
3613 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3614 safi_t safi)
3615 {
3616 uint32_t count = 0;
3617 bool filtered = false;
3618 struct bgp_dest *dest;
3619 struct bgp_adj_in *ain;
3620 struct attr attr = {};
3621 struct bgp_table *table = peer->bgp->rib[afi][safi];
3622
3623 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3624 for (ain = dest->adj_in; ain; ain = ain->next) {
3625 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3626
3627 attr = *ain->attr;
3628
3629 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3630 == FILTER_DENY)
3631 filtered = true;
3632
3633 if (bgp_input_modifier(
3634 peer, rn_p, &attr, afi, safi,
3635 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3636 NULL, 0, NULL)
3637 == RMAP_DENY)
3638 filtered = true;
3639
3640 if (filtered)
3641 count++;
3642
3643 bgp_attr_flush(&attr);
3644 }
3645 }
3646
3647 return count;
3648 }
3649
3650 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3651 int always)
3652 {
3653 iana_afi_t pkt_afi;
3654 iana_safi_t pkt_safi;
3655 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3656 PEER_FLAG_MAX_PREFIX_FORCE))
3657 ? bgp_filtered_routes_count(peer, afi, safi)
3658 + peer->pcount[afi][safi]
3659 : peer->pcount[afi][safi];
3660
3661 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3662 return false;
3663
3664 if (pcount > peer->pmax[afi][safi]) {
3665 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3666 PEER_STATUS_PREFIX_LIMIT)
3667 && !always)
3668 return false;
3669
3670 zlog_info(
3671 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3672 get_afi_safi_str(afi, safi, false), peer, pcount,
3673 peer->pmax[afi][safi]);
3674 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3675
3676 if (CHECK_FLAG(peer->af_flags[afi][safi],
3677 PEER_FLAG_MAX_PREFIX_WARNING))
3678 return false;
3679
3680 /* Convert AFI, SAFI to values for packet. */
3681 pkt_afi = afi_int2iana(afi);
3682 pkt_safi = safi_int2iana(safi);
3683 {
3684 uint8_t ndata[7];
3685
3686 ndata[0] = (pkt_afi >> 8);
3687 ndata[1] = pkt_afi;
3688 ndata[2] = pkt_safi;
3689 ndata[3] = (peer->pmax[afi][safi] >> 24);
3690 ndata[4] = (peer->pmax[afi][safi] >> 16);
3691 ndata[5] = (peer->pmax[afi][safi] >> 8);
3692 ndata[6] = (peer->pmax[afi][safi]);
3693
3694 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3695 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3696 BGP_NOTIFY_CEASE_MAX_PREFIX,
3697 ndata, 7);
3698 }
3699
3700 /* Dynamic peers will just close their connection. */
3701 if (peer_dynamic_neighbor(peer))
3702 return true;
3703
3704 /* restart timer start */
3705 if (peer->pmax_restart[afi][safi]) {
3706 peer->v_pmax_restart =
3707 peer->pmax_restart[afi][safi] * 60;
3708
3709 if (bgp_debug_neighbor_events(peer))
3710 zlog_debug(
3711 "%pBP Maximum-prefix restart timer started for %d secs",
3712 peer, peer->v_pmax_restart);
3713
3714 BGP_TIMER_ON(peer->t_pmax_restart,
3715 bgp_maximum_prefix_restart_timer,
3716 peer->v_pmax_restart);
3717 }
3718
3719 return true;
3720 } else
3721 UNSET_FLAG(peer->af_sflags[afi][safi],
3722 PEER_STATUS_PREFIX_LIMIT);
3723
3724 if (pcount
3725 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3726 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3727 PEER_STATUS_PREFIX_THRESHOLD)
3728 && !always)
3729 return false;
3730
3731 zlog_info(
3732 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3733 get_afi_safi_str(afi, safi, false), peer, pcount,
3734 peer->pmax[afi][safi]);
3735 SET_FLAG(peer->af_sflags[afi][safi],
3736 PEER_STATUS_PREFIX_THRESHOLD);
3737 } else
3738 UNSET_FLAG(peer->af_sflags[afi][safi],
3739 PEER_STATUS_PREFIX_THRESHOLD);
3740 return false;
3741 }
3742
3743 /* Unconditionally remove the route from the RIB, without taking
3744 * damping into consideration (eg, because the session went down)
3745 */
3746 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3747 struct peer *peer, afi_t afi, safi_t safi)
3748 {
3749
3750 struct bgp *bgp = NULL;
3751 bool delete_route = false;
3752
3753 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3754 safi);
3755
3756 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3757 bgp_path_info_delete(dest, pi); /* keep historical info */
3758
3759 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3760 * flag
3761 */
3762 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3763 delete_route = true;
3764 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3765 delete_route = true;
3766 if (delete_route) {
3767 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3768 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3769 bgp = pi->peer->bgp;
3770 bgp->gr_info[afi][safi].gr_deferred--;
3771 }
3772 }
3773 }
3774
3775 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3776 bgp_process(peer->bgp, dest, afi, safi);
3777 }
3778
3779 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3780 struct peer *peer, afi_t afi, safi_t safi,
3781 struct prefix_rd *prd)
3782 {
3783 const struct prefix *p = bgp_dest_get_prefix(dest);
3784
3785 /* apply dampening, if result is suppressed, we'll be retaining
3786 * the bgp_path_info in the RIB for historical reference.
3787 */
3788 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3789 && peer->sort == BGP_PEER_EBGP)
3790 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3791 == BGP_DAMP_SUPPRESSED) {
3792 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3793 safi);
3794 return;
3795 }
3796
3797 #ifdef ENABLE_BGP_VNC
3798 if (safi == SAFI_MPLS_VPN) {
3799 struct bgp_dest *pdest = NULL;
3800 struct bgp_table *table = NULL;
3801
3802 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3803 (struct prefix *)prd);
3804 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3805 table = bgp_dest_get_bgp_table_info(pdest);
3806
3807 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3808 peer->bgp, prd, table, p, pi);
3809 }
3810 bgp_dest_unlock_node(pdest);
3811 }
3812 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3813 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3814
3815 vnc_import_bgp_del_route(peer->bgp, p, pi);
3816 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3817 }
3818 }
3819 #endif
3820
3821 /* If this is an EVPN route, process for un-import. */
3822 if (safi == SAFI_EVPN)
3823 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3824
3825 bgp_rib_remove(dest, pi, peer, afi, safi);
3826 }
3827
3828 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3829 struct peer *peer, struct attr *attr,
3830 struct bgp_dest *dest)
3831 {
3832 struct bgp_path_info *new;
3833
3834 /* Make new BGP info. */
3835 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3836 new->type = type;
3837 new->instance = instance;
3838 new->sub_type = sub_type;
3839 new->peer = peer;
3840 new->attr = attr;
3841 new->uptime = monotime(NULL);
3842 new->net = dest;
3843 return new;
3844 }
3845
3846 /* Check if received nexthop is valid or not. */
3847 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3848 uint8_t type, uint8_t stype, struct attr *attr,
3849 struct bgp_dest *dest)
3850 {
3851 bool ret = false;
3852 bool is_bgp_static_route =
3853 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3854 : false;
3855
3856 /*
3857 * Only validated for unicast and multicast currently.
3858 * Also valid for EVPN where the nexthop is an IP address.
3859 * If we are a bgp static route being checked then there is
3860 * no need to check to see if the nexthop is martian as
3861 * that it should be ok.
3862 */
3863 if (is_bgp_static_route ||
3864 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3865 return false;
3866
3867 /* If NEXT_HOP is present, validate it. */
3868 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3869 if (attr->nexthop.s_addr == INADDR_ANY ||
3870 !ipv4_unicast_valid(&attr->nexthop) ||
3871 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3872 return true;
3873 }
3874
3875 /* If MP_NEXTHOP is present, validate it. */
3876 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3877 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3878 * it is not an IPv6 link-local address.
3879 *
3880 * If we receive an UPDATE with nexthop length set to 32 bytes
3881 * we shouldn't discard an UPDATE if it's set to (::).
3882 * The link-local (2st) is validated along the code path later.
3883 */
3884 if (attr->mp_nexthop_len) {
3885 switch (attr->mp_nexthop_len) {
3886 case BGP_ATTR_NHLEN_IPV4:
3887 case BGP_ATTR_NHLEN_VPNV4:
3888 ret = (attr->mp_nexthop_global_in.s_addr ==
3889 INADDR_ANY ||
3890 !ipv4_unicast_valid(
3891 &attr->mp_nexthop_global_in) ||
3892 bgp_nexthop_self(bgp, afi, type, stype, attr,
3893 dest));
3894 break;
3895
3896 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3897 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3898 ret = (IN6_IS_ADDR_UNSPECIFIED(
3899 &attr->mp_nexthop_global)
3900 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3901 || IN6_IS_ADDR_MULTICAST(
3902 &attr->mp_nexthop_global)
3903 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3904 dest));
3905 break;
3906 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3907 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3908 || IN6_IS_ADDR_MULTICAST(
3909 &attr->mp_nexthop_global)
3910 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3911 dest));
3912 break;
3913
3914 default:
3915 ret = true;
3916 break;
3917 }
3918 }
3919
3920 return ret;
3921 }
3922
3923 static void bgp_attr_add_no_export_community(struct attr *attr)
3924 {
3925 struct community *old;
3926 struct community *new;
3927 struct community *merge;
3928 struct community *no_export;
3929
3930 old = bgp_attr_get_community(attr);
3931 no_export = community_str2com("no-export");
3932
3933 assert(no_export);
3934
3935 if (old) {
3936 merge = community_merge(community_dup(old), no_export);
3937
3938 if (!old->refcnt)
3939 community_free(&old);
3940
3941 new = community_uniq_sort(merge);
3942 community_free(&merge);
3943 } else {
3944 new = community_dup(no_export);
3945 }
3946
3947 community_free(&no_export);
3948
3949 bgp_attr_set_community(attr, new);
3950 }
3951
3952 static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi,
3953 struct attr *attr, const struct prefix *prefix,
3954 int *sub_type)
3955 {
3956 struct listnode *node, *nnode;
3957 struct bgp *bgp;
3958 bool accept_own_found = false;
3959
3960 if (safi != SAFI_MPLS_VPN)
3961 return false;
3962
3963 /* Processing of the ACCEPT_OWN community is enabled by configuration */
3964 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN))
3965 return false;
3966
3967 /* The route in question carries the ACCEPT_OWN community */
3968 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3969 struct community *comm = bgp_attr_get_community(attr);
3970
3971 if (community_include(comm, COMMUNITY_ACCEPT_OWN))
3972 accept_own_found = true;
3973 }
3974
3975 /* The route in question is targeted to one or more destination VRFs
3976 * on the router (as determined by inspecting the Route Target(s)).
3977 */
3978 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3979 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3980 continue;
3981
3982 if (accept_own_found &&
3983 ecommunity_include(
3984 bgp->vpn_policy[afi]
3985 .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
3986 bgp_attr_get_ecommunity(attr))) {
3987 if (bgp_debug_update(peer, prefix, NULL, 1))
3988 zlog_debug(
3989 "%pBP prefix %pFX has ORIGINATOR_ID, but it's accepted due to ACCEPT_OWN",
3990 peer, prefix);
3991
3992 /* Treat this route as imported, because it's leaked
3993 * already from another VRF, and we got an updated
3994 * version from route-reflector with ACCEPT_OWN
3995 * community.
3996 */
3997 *sub_type = BGP_ROUTE_IMPORTED;
3998
3999 return true;
4000 }
4001 }
4002
4003 return false;
4004 }
4005
4006 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4007 struct attr *attr, afi_t afi, safi_t safi, int type,
4008 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4009 uint32_t num_labels, int soft_reconfig,
4010 struct bgp_route_evpn *evpn)
4011 {
4012 int ret;
4013 int aspath_loop_count = 0;
4014 struct bgp_dest *dest;
4015 struct bgp *bgp;
4016 struct attr new_attr;
4017 struct attr *attr_new;
4018 struct bgp_path_info *pi;
4019 struct bgp_path_info *new = NULL;
4020 struct bgp_path_info_extra *extra;
4021 const char *reason;
4022 char pfx_buf[BGP_PRD_PATH_STRLEN];
4023 int connected = 0;
4024 int do_loop_check = 1;
4025 int has_valid_label = 0;
4026 afi_t nh_afi;
4027 bool force_evpn_import = false;
4028 safi_t orig_safi = safi;
4029 bool leak_success = true;
4030 int allowas_in = 0;
4031
4032 if (frrtrace_enabled(frr_bgp, process_update)) {
4033 char pfxprint[PREFIX2STR_BUFFER];
4034
4035 prefix2str(p, pfxprint, sizeof(pfxprint));
4036 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
4037 afi, safi, attr);
4038 }
4039
4040 #ifdef ENABLE_BGP_VNC
4041 int vnc_implicit_withdraw = 0;
4042 #endif
4043 int same_attr = 0;
4044 const struct prefix *bgp_nht_param_prefix;
4045
4046 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
4047 if (orig_safi == SAFI_LABELED_UNICAST)
4048 safi = SAFI_UNICAST;
4049
4050 memset(&new_attr, 0, sizeof(new_attr));
4051 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4052 new_attr.label = MPLS_INVALID_LABEL;
4053
4054 bgp = peer->bgp;
4055 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4056 /* TODO: Check to see if we can get rid of "is_valid_label" */
4057 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4058 has_valid_label = (num_labels > 0) ? 1 : 0;
4059 else
4060 has_valid_label = bgp_is_valid_label(label);
4061
4062 if (has_valid_label)
4063 assert(label != NULL);
4064
4065 /* Update overlay index of the attribute */
4066 if (afi == AFI_L2VPN && evpn)
4067 memcpy(&attr->evpn_overlay, evpn,
4068 sizeof(struct bgp_route_evpn));
4069
4070 /* When peer's soft reconfiguration enabled. Record input packet in
4071 Adj-RIBs-In. */
4072 if (!soft_reconfig
4073 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4074 && peer != bgp->peer_self)
4075 bgp_adj_in_set(dest, peer, attr, addpath_id);
4076
4077 /* Update permitted loop count */
4078 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
4079 allowas_in = peer->allowas_in[afi][safi];
4080
4081 /* Check previously received route. */
4082 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4083 if (pi->peer == peer && pi->type == type
4084 && pi->sub_type == sub_type
4085 && pi->addpath_rx_id == addpath_id)
4086 break;
4087
4088 /* AS path local-as loop check. */
4089 if (peer->change_local_as) {
4090 if (allowas_in)
4091 aspath_loop_count = allowas_in;
4092 else if (!CHECK_FLAG(peer->flags,
4093 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4094 aspath_loop_count = 1;
4095
4096 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4097 > aspath_loop_count) {
4098 peer->stat_pfx_aspath_loop++;
4099 reason = "as-path contains our own AS;";
4100 goto filtered;
4101 }
4102 }
4103
4104 /* If the peer is configured for "allowas-in origin" and the last ASN in
4105 * the
4106 * as-path is our ASN then we do not need to call aspath_loop_check
4107 */
4108 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4109 if (aspath_get_last_as(attr->aspath) == bgp->as)
4110 do_loop_check = 0;
4111
4112 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
4113 bgp_nht_param_prefix = NULL;
4114 else
4115 bgp_nht_param_prefix = p;
4116
4117 /* AS path loop check. */
4118 if (do_loop_check) {
4119 if (aspath_loop_check(attr->aspath, bgp->as) >
4120 peer->allowas_in[afi][safi]) {
4121 peer->stat_pfx_aspath_loop++;
4122 reason = "as-path contains our own AS;";
4123 goto filtered;
4124 }
4125 }
4126
4127 /* If we're a CONFED we need to loop check the CONFED ID too */
4128 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check)
4129 if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) >
4130 peer->allowas_in[afi][safi]) {
4131 peer->stat_pfx_aspath_loop++;
4132 reason = "as-path contains our own confed AS;";
4133 goto filtered;
4134 }
4135
4136 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4137 * enabled, then take care of that too.
4138 */
4139 bool accept_own = false;
4140
4141 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4142 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4143 accept_own =
4144 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4145 if (!accept_own) {
4146 peer->stat_pfx_originator_loop++;
4147 reason = "originator is us;";
4148 goto filtered;
4149 }
4150 }
4151
4152 /* Route reflector cluster ID check. */
4153 if (bgp_cluster_filter(peer, attr)) {
4154 peer->stat_pfx_cluster_loop++;
4155 reason = "reflected from the same cluster;";
4156 goto filtered;
4157 }
4158
4159 /* Apply incoming filter. */
4160 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4161 peer->stat_pfx_filter++;
4162 reason = "filter;";
4163 goto filtered;
4164 }
4165
4166 /* RFC 8212 to prevent route leaks.
4167 * This specification intends to improve this situation by requiring the
4168 * explicit configuration of both BGP Import and Export Policies for any
4169 * External BGP (EBGP) session such as customers, peers, or
4170 * confederation boundaries for all enabled address families. Through
4171 * codification of the aforementioned requirement, operators will
4172 * benefit from consistent behavior across different BGP
4173 * implementations.
4174 */
4175 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4176 if (!bgp_inbound_policy_exists(peer,
4177 &peer->filter[afi][safi])) {
4178 reason = "inbound policy missing";
4179 if (monotime_since(&bgp->ebgprequirespolicywarning,
4180 NULL) > FIFTEENMINUTE2USEC ||
4181 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4182 zlog_warn(
4183 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4184 monotime(&bgp->ebgprequirespolicywarning);
4185 }
4186 goto filtered;
4187 }
4188
4189 /* draft-ietf-idr-deprecate-as-set-confed-set
4190 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4191 * Eventually, This document (if approved) updates RFC 4271
4192 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4193 * and obsoletes RFC 6472.
4194 */
4195 if (peer->bgp->reject_as_sets)
4196 if (aspath_check_as_sets(attr->aspath)) {
4197 reason =
4198 "as-path contains AS_SET or AS_CONFED_SET type;";
4199 goto filtered;
4200 }
4201
4202 new_attr = *attr;
4203
4204 /* Apply incoming route-map.
4205 * NB: new_attr may now contain newly allocated values from route-map
4206 * "set"
4207 * commands, so we need bgp_attr_flush in the error paths, until we
4208 * intern
4209 * the attr (which takes over the memory references) */
4210 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4211 num_labels, dest)
4212 == RMAP_DENY) {
4213 peer->stat_pfx_filter++;
4214 reason = "route-map;";
4215 bgp_attr_flush(&new_attr);
4216 goto filtered;
4217 }
4218
4219 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4220 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4221 /* remove from RIB previous entry */
4222 bgp_zebra_withdraw(p, pi, bgp, safi);
4223 }
4224
4225 if (peer->sort == BGP_PEER_EBGP) {
4226
4227 /* rfc7999:
4228 * A BGP speaker receiving an announcement tagged with the
4229 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4230 * NO_EXPORT community as defined in RFC1997, or a
4231 * similar community, to prevent propagation of the
4232 * prefix outside the local AS. The community to prevent
4233 * propagation SHOULD be chosen according to the operator's
4234 * routing policy.
4235 */
4236 if (bgp_attr_get_community(&new_attr) &&
4237 community_include(bgp_attr_get_community(&new_attr),
4238 COMMUNITY_BLACKHOLE))
4239 bgp_attr_add_no_export_community(&new_attr);
4240
4241 /* If we receive the graceful-shutdown community from an eBGP
4242 * peer we must lower local-preference */
4243 if (bgp_attr_get_community(&new_attr) &&
4244 community_include(bgp_attr_get_community(&new_attr),
4245 COMMUNITY_GSHUT)) {
4246 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4247 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4248
4249 /* If graceful-shutdown is configured globally or
4250 * per neighbor, then add the GSHUT community to
4251 * all paths received from eBGP peers. */
4252 } else if (bgp_in_graceful_shutdown(peer->bgp) ||
4253 CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_SHUTDOWN))
4254 bgp_attr_add_gshut_community(&new_attr);
4255 }
4256
4257 /* next hop check. */
4258 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4259 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4260 &new_attr, dest)) {
4261 peer->stat_pfx_nh_invalid++;
4262 reason = "martian or self next-hop;";
4263 bgp_attr_flush(&new_attr);
4264 goto filtered;
4265 }
4266
4267 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4268 peer->stat_pfx_nh_invalid++;
4269 reason = "self mac;";
4270 bgp_attr_flush(&new_attr);
4271 goto filtered;
4272 }
4273
4274 if (bgp_check_role_applicability(afi, safi) &&
4275 bgp_otc_filter(peer, &new_attr)) {
4276 reason = "failing otc validation";
4277 bgp_attr_flush(&new_attr);
4278 goto filtered;
4279 }
4280 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
4281 * condition :
4282 * Suppress fib is enabled
4283 * BGP_OPT_NO_FIB is not enabled
4284 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
4285 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
4286 */
4287 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
4288 && (sub_type == BGP_ROUTE_NORMAL)
4289 && (!bgp_option_check(BGP_OPT_NO_FIB))
4290 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
4291 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
4292
4293 /* If neighbor soo is configured, tag all incoming routes with
4294 * this SoO tag and then filter out advertisements in
4295 * subgroup_announce_check() if it matches the configured SoO
4296 * on the other peer.
4297 */
4298 if (peer->soo[afi][safi]) {
4299 struct ecommunity *old_ecomm =
4300 bgp_attr_get_ecommunity(&new_attr);
4301 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4302 struct ecommunity *new_ecomm;
4303
4304 if (old_ecomm) {
4305 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4306 ecomm_soo);
4307
4308 if (!old_ecomm->refcnt)
4309 ecommunity_free(&old_ecomm);
4310 } else {
4311 new_ecomm = ecommunity_dup(ecomm_soo);
4312 }
4313
4314 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4315 }
4316
4317 attr_new = bgp_attr_intern(&new_attr);
4318
4319 /* If the update is implicit withdraw. */
4320 if (pi) {
4321 pi->uptime = monotime(NULL);
4322 same_attr = attrhash_cmp(pi->attr, attr_new);
4323
4324 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4325
4326 /* Same attribute comes in. */
4327 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4328 && same_attr
4329 && (!has_valid_label
4330 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4331 num_labels * sizeof(mpls_label_t))
4332 == 0)) {
4333 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4334 BGP_CONFIG_DAMPENING)
4335 && peer->sort == BGP_PEER_EBGP
4336 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4337 if (bgp_debug_update(peer, p, NULL, 1)) {
4338 bgp_debug_rdpfxpath2str(
4339 afi, safi, prd, p, label,
4340 num_labels, addpath_id ? 1 : 0,
4341 addpath_id, evpn, pfx_buf,
4342 sizeof(pfx_buf));
4343 zlog_debug("%pBP rcvd %s", peer,
4344 pfx_buf);
4345 }
4346
4347 if (bgp_damp_update(pi, dest, afi, safi)
4348 != BGP_DAMP_SUPPRESSED) {
4349 bgp_aggregate_increment(bgp, p, pi, afi,
4350 safi);
4351 bgp_process(bgp, dest, afi, safi);
4352 }
4353 } else /* Duplicate - odd */
4354 {
4355 if (bgp_debug_update(peer, p, NULL, 1)) {
4356 if (!peer->rcvd_attr_printed) {
4357 zlog_debug(
4358 "%pBP rcvd UPDATE w/ attr: %s",
4359 peer,
4360 peer->rcvd_attr_str);
4361 peer->rcvd_attr_printed = 1;
4362 }
4363
4364 bgp_debug_rdpfxpath2str(
4365 afi, safi, prd, p, label,
4366 num_labels, addpath_id ? 1 : 0,
4367 addpath_id, evpn, pfx_buf,
4368 sizeof(pfx_buf));
4369 zlog_debug(
4370 "%pBP rcvd %s...duplicate ignored",
4371 peer, pfx_buf);
4372 }
4373
4374 /* graceful restart STALE flag unset. */
4375 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4376 bgp_path_info_unset_flag(
4377 dest, pi, BGP_PATH_STALE);
4378 bgp_dest_set_defer_flag(dest, false);
4379 bgp_process(bgp, dest, afi, safi);
4380 }
4381 }
4382
4383 bgp_dest_unlock_node(dest);
4384 bgp_attr_unintern(&attr_new);
4385
4386 return 0;
4387 }
4388
4389 /* Withdraw/Announce before we fully processed the withdraw */
4390 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4391 if (bgp_debug_update(peer, p, NULL, 1)) {
4392 bgp_debug_rdpfxpath2str(
4393 afi, safi, prd, p, label, num_labels,
4394 addpath_id ? 1 : 0, addpath_id, evpn,
4395 pfx_buf, sizeof(pfx_buf));
4396 zlog_debug(
4397 "%pBP rcvd %s, flapped quicker than processing",
4398 peer, pfx_buf);
4399 }
4400
4401 bgp_path_info_restore(dest, pi);
4402
4403 /*
4404 * If the BGP_PATH_REMOVED flag is set, then EVPN
4405 * routes would have been unimported already when a
4406 * prior BGP withdraw processing happened. Such routes
4407 * need to be imported again, so flag accordingly.
4408 */
4409 force_evpn_import = true;
4410 } else {
4411 /* implicit withdraw, decrement aggregate and pcount
4412 * here. only if update is accepted, they'll increment
4413 * below.
4414 */
4415 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4416 }
4417
4418 /* Received Logging. */
4419 if (bgp_debug_update(peer, p, NULL, 1)) {
4420 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4421 num_labels, addpath_id ? 1 : 0,
4422 addpath_id, evpn, pfx_buf,
4423 sizeof(pfx_buf));
4424 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4425 }
4426
4427 /* graceful restart STALE flag unset. */
4428 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4429 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4430 bgp_dest_set_defer_flag(dest, false);
4431 }
4432
4433 /* The attribute is changed. */
4434 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4435
4436 /* Update bgp route dampening information. */
4437 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4438 && peer->sort == BGP_PEER_EBGP) {
4439 /* This is implicit withdraw so we should update
4440 dampening
4441 information. */
4442 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4443 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4444 }
4445 #ifdef ENABLE_BGP_VNC
4446 if (safi == SAFI_MPLS_VPN) {
4447 struct bgp_dest *pdest = NULL;
4448 struct bgp_table *table = NULL;
4449
4450 pdest = bgp_node_get(bgp->rib[afi][safi],
4451 (struct prefix *)prd);
4452 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4453 table = bgp_dest_get_bgp_table_info(pdest);
4454
4455 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4456 bgp, prd, table, p, pi);
4457 }
4458 bgp_dest_unlock_node(pdest);
4459 }
4460 if ((afi == AFI_IP || afi == AFI_IP6)
4461 && (safi == SAFI_UNICAST)) {
4462 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4463 /*
4464 * Implicit withdraw case.
4465 */
4466 ++vnc_implicit_withdraw;
4467 vnc_import_bgp_del_route(bgp, p, pi);
4468 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4469 }
4470 }
4471 #endif
4472
4473 /* Special handling for EVPN update of an existing route. If the
4474 * extended community attribute has changed, we need to
4475 * un-import
4476 * the route using its existing extended community. It will be
4477 * subsequently processed for import with the new extended
4478 * community.
4479 */
4480 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4481 && !same_attr) {
4482 if ((pi->attr->flag
4483 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4484 && (attr_new->flag
4485 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4486 int cmp;
4487
4488 cmp = ecommunity_cmp(
4489 bgp_attr_get_ecommunity(pi->attr),
4490 bgp_attr_get_ecommunity(attr_new));
4491 if (!cmp) {
4492 if (bgp_debug_update(peer, p, NULL, 1))
4493 zlog_debug(
4494 "Change in EXT-COMM, existing %s new %s",
4495 ecommunity_str(
4496 bgp_attr_get_ecommunity(
4497 pi->attr)),
4498 ecommunity_str(
4499 bgp_attr_get_ecommunity(
4500 attr_new)));
4501 if (safi == SAFI_EVPN)
4502 bgp_evpn_unimport_route(
4503 bgp, afi, safi, p, pi);
4504 else /* SAFI_MPLS_VPN */
4505 vpn_leak_to_vrf_withdraw(bgp,
4506 pi);
4507 }
4508 }
4509 }
4510
4511 /* Update to new attribute. */
4512 bgp_attr_unintern(&pi->attr);
4513 pi->attr = attr_new;
4514
4515 /* Update MPLS label */
4516 if (has_valid_label) {
4517 extra = bgp_path_info_extra_get(pi);
4518 if (extra->label != label) {
4519 memcpy(&extra->label, label,
4520 num_labels * sizeof(mpls_label_t));
4521 extra->num_labels = num_labels;
4522 }
4523 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4524 bgp_set_valid_label(&extra->label[0]);
4525 }
4526
4527 /* Update SRv6 SID */
4528 if (attr->srv6_l3vpn) {
4529 extra = bgp_path_info_extra_get(pi);
4530 if (sid_diff(&extra->sid[0].sid,
4531 &attr->srv6_l3vpn->sid)) {
4532 sid_copy(&extra->sid[0].sid,
4533 &attr->srv6_l3vpn->sid);
4534 extra->num_sids = 1;
4535
4536 extra->sid[0].loc_block_len = 0;
4537 extra->sid[0].loc_node_len = 0;
4538 extra->sid[0].func_len = 0;
4539 extra->sid[0].arg_len = 0;
4540 extra->sid[0].transposition_len = 0;
4541 extra->sid[0].transposition_offset = 0;
4542
4543 if (attr->srv6_l3vpn->loc_block_len != 0) {
4544 extra->sid[0].loc_block_len =
4545 attr->srv6_l3vpn->loc_block_len;
4546 extra->sid[0].loc_node_len =
4547 attr->srv6_l3vpn->loc_node_len;
4548 extra->sid[0].func_len =
4549 attr->srv6_l3vpn->func_len;
4550 extra->sid[0].arg_len =
4551 attr->srv6_l3vpn->arg_len;
4552 extra->sid[0].transposition_len =
4553 attr->srv6_l3vpn
4554 ->transposition_len;
4555 extra->sid[0].transposition_offset =
4556 attr->srv6_l3vpn
4557 ->transposition_offset;
4558 }
4559 }
4560 } else if (attr->srv6_vpn) {
4561 extra = bgp_path_info_extra_get(pi);
4562 if (sid_diff(&extra->sid[0].sid,
4563 &attr->srv6_vpn->sid)) {
4564 sid_copy(&extra->sid[0].sid,
4565 &attr->srv6_vpn->sid);
4566 extra->num_sids = 1;
4567 }
4568 }
4569
4570 #ifdef ENABLE_BGP_VNC
4571 if ((afi == AFI_IP || afi == AFI_IP6)
4572 && (safi == SAFI_UNICAST)) {
4573 if (vnc_implicit_withdraw) {
4574 /*
4575 * Add back the route with its new attributes
4576 * (e.g., nexthop).
4577 * The route is still selected, until the route
4578 * selection
4579 * queued by bgp_process actually runs. We have
4580 * to make this
4581 * update to the VNC side immediately to avoid
4582 * racing against
4583 * configuration changes (e.g., route-map
4584 * changes) which
4585 * trigger re-importation of the entire RIB.
4586 */
4587 vnc_import_bgp_add_route(bgp, p, pi);
4588 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4589 }
4590 }
4591 #endif
4592
4593 /* Update bgp route dampening information. */
4594 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4595 && peer->sort == BGP_PEER_EBGP) {
4596 /* Now we do normal update dampening. */
4597 ret = bgp_damp_update(pi, dest, afi, safi);
4598 if (ret == BGP_DAMP_SUPPRESSED) {
4599 bgp_dest_unlock_node(dest);
4600 return 0;
4601 }
4602 }
4603
4604 /* Nexthop reachability check - for unicast and
4605 * labeled-unicast.. */
4606 if (((afi == AFI_IP || afi == AFI_IP6)
4607 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4608 || (safi == SAFI_EVPN &&
4609 bgp_evpn_is_prefix_nht_supported(p))) {
4610 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4611 && peer->ttl == BGP_DEFAULT_TTL
4612 && !CHECK_FLAG(peer->flags,
4613 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4614 && !CHECK_FLAG(bgp->flags,
4615 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4616 connected = 1;
4617 else
4618 connected = 0;
4619
4620 struct bgp *bgp_nexthop = bgp;
4621
4622 if (pi->extra && pi->extra->bgp_orig)
4623 bgp_nexthop = pi->extra->bgp_orig;
4624
4625 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4626
4627 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4628 safi, pi, NULL, connected,
4629 bgp_nht_param_prefix) ||
4630 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4631 bgp_path_info_set_flag(dest, pi,
4632 BGP_PATH_VALID);
4633 else {
4634 if (BGP_DEBUG(nht, NHT)) {
4635 zlog_debug("%s(%pI4): NH unresolved",
4636 __func__,
4637 (in_addr_t *)&attr_new->nexthop);
4638 }
4639 bgp_path_info_unset_flag(dest, pi,
4640 BGP_PATH_VALID);
4641 }
4642 } else {
4643 if (accept_own)
4644 bgp_path_info_set_flag(dest, pi,
4645 BGP_PATH_ACCEPT_OWN);
4646
4647 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4648 }
4649
4650 #ifdef ENABLE_BGP_VNC
4651 if (safi == SAFI_MPLS_VPN) {
4652 struct bgp_dest *pdest = NULL;
4653 struct bgp_table *table = NULL;
4654
4655 pdest = bgp_node_get(bgp->rib[afi][safi],
4656 (struct prefix *)prd);
4657 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4658 table = bgp_dest_get_bgp_table_info(pdest);
4659
4660 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4661 bgp, prd, table, p, pi);
4662 }
4663 bgp_dest_unlock_node(pdest);
4664 }
4665 #endif
4666
4667 /* If this is an EVPN route and some attribute has changed,
4668 * or we are explicitly told to perform a route import, process
4669 * route for import. If the extended community has changed, we
4670 * would
4671 * have done the un-import earlier and the import would result
4672 * in the
4673 * route getting injected into appropriate L2 VNIs. If it is
4674 * just
4675 * some other attribute change, the import will result in
4676 * updating
4677 * the attributes for the route in the VNI(s).
4678 */
4679 if (safi == SAFI_EVPN &&
4680 (!same_attr || force_evpn_import) &&
4681 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4682 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4683
4684 /* Process change. */
4685 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4686
4687 bgp_process(bgp, dest, afi, safi);
4688 bgp_dest_unlock_node(dest);
4689
4690 if (SAFI_UNICAST == safi
4691 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4692 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4693
4694 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4695 }
4696 if ((SAFI_MPLS_VPN == safi)
4697 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4698 leak_success = vpn_leak_to_vrf_update(bgp, pi, prd);
4699 }
4700
4701 #ifdef ENABLE_BGP_VNC
4702 if (SAFI_MPLS_VPN == safi) {
4703 mpls_label_t label_decoded = decode_label(label);
4704
4705 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4706 type, sub_type, &label_decoded);
4707 }
4708 if (SAFI_ENCAP == safi) {
4709 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4710 type, sub_type, NULL);
4711 }
4712 #endif
4713 if ((safi == SAFI_MPLS_VPN) &&
4714 !CHECK_FLAG(bgp->af_flags[afi][safi],
4715 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4716 !leak_success) {
4717 bgp_unlink_nexthop(pi);
4718 bgp_path_info_delete(dest, pi);
4719 }
4720 return 0;
4721 } // End of implicit withdraw
4722
4723 /* Received Logging. */
4724 if (bgp_debug_update(peer, p, NULL, 1)) {
4725 if (!peer->rcvd_attr_printed) {
4726 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4727 peer->rcvd_attr_str);
4728 peer->rcvd_attr_printed = 1;
4729 }
4730
4731 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4732 addpath_id ? 1 : 0, addpath_id, evpn,
4733 pfx_buf, sizeof(pfx_buf));
4734 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4735 }
4736
4737 /* Make new BGP info. */
4738 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4739
4740 /* Update MPLS label */
4741 if (has_valid_label) {
4742 extra = bgp_path_info_extra_get(new);
4743 if (extra->label != label) {
4744 memcpy(&extra->label, label,
4745 num_labels * sizeof(mpls_label_t));
4746 extra->num_labels = num_labels;
4747 }
4748 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4749 bgp_set_valid_label(&extra->label[0]);
4750 }
4751
4752 /* Update SRv6 SID */
4753 if (safi == SAFI_MPLS_VPN) {
4754 extra = bgp_path_info_extra_get(new);
4755 if (attr->srv6_l3vpn) {
4756 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4757 extra->num_sids = 1;
4758
4759 extra->sid[0].loc_block_len =
4760 attr->srv6_l3vpn->loc_block_len;
4761 extra->sid[0].loc_node_len =
4762 attr->srv6_l3vpn->loc_node_len;
4763 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4764 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4765 extra->sid[0].transposition_len =
4766 attr->srv6_l3vpn->transposition_len;
4767 extra->sid[0].transposition_offset =
4768 attr->srv6_l3vpn->transposition_offset;
4769 } else if (attr->srv6_vpn) {
4770 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4771 extra->num_sids = 1;
4772 }
4773 }
4774
4775 /* Nexthop reachability check. */
4776 if (((afi == AFI_IP || afi == AFI_IP6)
4777 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4778 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4779 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4780 && peer->ttl == BGP_DEFAULT_TTL
4781 && !CHECK_FLAG(peer->flags,
4782 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4783 && !CHECK_FLAG(bgp->flags,
4784 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4785 connected = 1;
4786 else
4787 connected = 0;
4788
4789 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4790
4791 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4792 connected, bgp_nht_param_prefix) ||
4793 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4794 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4795 else {
4796 if (BGP_DEBUG(nht, NHT))
4797 zlog_debug("%s(%pI4): NH unresolved", __func__,
4798 &attr_new->nexthop);
4799 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4800 }
4801 } else {
4802 if (accept_own)
4803 bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
4804
4805 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4806 }
4807
4808 /* If maximum prefix count is configured and current prefix
4809 * count exeed it.
4810 */
4811 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4812 reason = "maximum-prefix overflow";
4813 bgp_attr_flush(&new_attr);
4814 goto filtered;
4815 }
4816
4817 /* Addpath ID */
4818 new->addpath_rx_id = addpath_id;
4819
4820 /* Increment prefix */
4821 bgp_aggregate_increment(bgp, p, new, afi, safi);
4822
4823 /* Register new BGP information. */
4824 bgp_path_info_add(dest, new);
4825
4826 /* route_node_get lock */
4827 bgp_dest_unlock_node(dest);
4828
4829 #ifdef ENABLE_BGP_VNC
4830 if (safi == SAFI_MPLS_VPN) {
4831 struct bgp_dest *pdest = NULL;
4832 struct bgp_table *table = NULL;
4833
4834 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4835 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4836 table = bgp_dest_get_bgp_table_info(pdest);
4837
4838 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4839 bgp, prd, table, p, new);
4840 }
4841 bgp_dest_unlock_node(pdest);
4842 }
4843 #endif
4844
4845 /* If this is an EVPN route, process for import. */
4846 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4847 bgp_evpn_import_route(bgp, afi, safi, p, new);
4848
4849 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4850
4851 /* Process change. */
4852 bgp_process(bgp, dest, afi, safi);
4853
4854 if (SAFI_UNICAST == safi
4855 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4856 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4857 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4858 }
4859 if ((SAFI_MPLS_VPN == safi)
4860 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4861 leak_success = vpn_leak_to_vrf_update(bgp, new, prd);
4862 }
4863 #ifdef ENABLE_BGP_VNC
4864 if (SAFI_MPLS_VPN == safi) {
4865 mpls_label_t label_decoded = decode_label(label);
4866
4867 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4868 sub_type, &label_decoded);
4869 }
4870 if (SAFI_ENCAP == safi) {
4871 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4872 sub_type, NULL);
4873 }
4874 #endif
4875 if ((safi == SAFI_MPLS_VPN) &&
4876 !CHECK_FLAG(bgp->af_flags[afi][safi],
4877 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4878 !leak_success) {
4879 bgp_unlink_nexthop(new);
4880 bgp_path_info_delete(dest, new);
4881 }
4882
4883 return 0;
4884
4885 /* This BGP update is filtered. Log the reason then update BGP
4886 entry. */
4887 filtered:
4888 if (new) {
4889 bgp_unlink_nexthop(new);
4890 bgp_path_info_delete(dest, new);
4891 bgp_path_info_extra_free(&new->extra);
4892 XFREE(MTYPE_BGP_ROUTE, new);
4893 }
4894
4895 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4896
4897 if (bgp_debug_update(peer, p, NULL, 1)) {
4898 if (!peer->rcvd_attr_printed) {
4899 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4900 peer->rcvd_attr_str);
4901 peer->rcvd_attr_printed = 1;
4902 }
4903
4904 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4905 addpath_id ? 1 : 0, addpath_id, evpn,
4906 pfx_buf, sizeof(pfx_buf));
4907 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4908 peer, pfx_buf, reason);
4909 }
4910
4911 if (pi) {
4912 /* If this is an EVPN route, un-import it as it is now filtered.
4913 */
4914 if (safi == SAFI_EVPN)
4915 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4916
4917 if (SAFI_UNICAST == safi
4918 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4919 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4920
4921 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4922 }
4923 if ((SAFI_MPLS_VPN == safi)
4924 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4925
4926 vpn_leak_to_vrf_withdraw(bgp, pi);
4927 }
4928
4929 bgp_rib_remove(dest, pi, peer, afi, safi);
4930 }
4931
4932 bgp_dest_unlock_node(dest);
4933
4934 #ifdef ENABLE_BGP_VNC
4935 /*
4936 * Filtered update is treated as an implicit withdrawal (see
4937 * bgp_rib_remove()
4938 * a few lines above)
4939 */
4940 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4941 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4942 0);
4943 }
4944 #endif
4945
4946 return 0;
4947 }
4948
4949 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4950 struct attr *attr, afi_t afi, safi_t safi, int type,
4951 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4952 uint32_t num_labels, struct bgp_route_evpn *evpn)
4953 {
4954 struct bgp *bgp;
4955 char pfx_buf[BGP_PRD_PATH_STRLEN];
4956 struct bgp_dest *dest;
4957 struct bgp_path_info *pi;
4958
4959 #ifdef ENABLE_BGP_VNC
4960 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4961 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4962 0);
4963 }
4964 #endif
4965
4966 bgp = peer->bgp;
4967
4968 /* Lookup node. */
4969 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4970
4971 /* If peer is soft reconfiguration enabled. Record input packet for
4972 * further calculation.
4973 *
4974 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4975 * routes that are filtered. This tanks out Quagga RS pretty badly due
4976 * to
4977 * the iteration over all RS clients.
4978 * Since we need to remove the entry from adj_in anyway, do that first
4979 * and
4980 * if there was no entry, we don't need to do anything more.
4981 */
4982 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4983 && peer != bgp->peer_self)
4984 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4985 peer->stat_pfx_dup_withdraw++;
4986
4987 if (bgp_debug_update(peer, p, NULL, 1)) {
4988 bgp_debug_rdpfxpath2str(
4989 afi, safi, prd, p, label, num_labels,
4990 addpath_id ? 1 : 0, addpath_id, NULL,
4991 pfx_buf, sizeof(pfx_buf));
4992 zlog_debug(
4993 "%s withdrawing route %s not in adj-in",
4994 peer->host, pfx_buf);
4995 }
4996 bgp_dest_unlock_node(dest);
4997 return 0;
4998 }
4999
5000 /* Lookup withdrawn route. */
5001 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5002 if (pi->peer == peer && pi->type == type
5003 && pi->sub_type == sub_type
5004 && pi->addpath_rx_id == addpath_id)
5005 break;
5006
5007 /* Logging. */
5008 if (bgp_debug_update(peer, p, NULL, 1)) {
5009 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
5010 addpath_id ? 1 : 0, addpath_id, NULL,
5011 pfx_buf, sizeof(pfx_buf));
5012 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
5013 pfx_buf);
5014 }
5015
5016 /* Withdraw specified route from routing table. */
5017 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
5018 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
5019 if (SAFI_UNICAST == safi
5020 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5021 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5022 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5023 }
5024 if ((SAFI_MPLS_VPN == safi)
5025 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5026
5027 vpn_leak_to_vrf_withdraw(bgp, pi);
5028 }
5029 } else if (bgp_debug_update(peer, p, NULL, 1)) {
5030 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
5031 addpath_id ? 1 : 0, addpath_id, NULL,
5032 pfx_buf, sizeof(pfx_buf));
5033 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
5034 }
5035
5036 /* Unlock bgp_node_get() lock. */
5037 bgp_dest_unlock_node(dest);
5038
5039 return 0;
5040 }
5041
5042 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
5043 int withdraw)
5044 {
5045 struct update_subgroup *subgrp;
5046 subgrp = peer_subgroup(peer, afi, safi);
5047 subgroup_default_originate(subgrp, withdraw);
5048 }
5049
5050
5051 /*
5052 * bgp_stop_announce_route_timer
5053 */
5054 void bgp_stop_announce_route_timer(struct peer_af *paf)
5055 {
5056 if (!paf->t_announce_route)
5057 return;
5058
5059 THREAD_OFF(paf->t_announce_route);
5060 }
5061
5062 /*
5063 * bgp_announce_route_timer_expired
5064 *
5065 * Callback that is invoked when the route announcement timer for a
5066 * peer_af expires.
5067 */
5068 static void bgp_announce_route_timer_expired(struct thread *t)
5069 {
5070 struct peer_af *paf;
5071 struct peer *peer;
5072
5073 paf = THREAD_ARG(t);
5074 peer = paf->peer;
5075
5076 if (!peer_established(peer))
5077 return;
5078
5079 if (!peer->afc_nego[paf->afi][paf->safi])
5080 return;
5081
5082 peer_af_announce_route(paf, 1);
5083
5084 /* Notify BGP conditional advertisement scanner percess */
5085 peer->advmap_config_change[paf->afi][paf->safi] = true;
5086 }
5087
5088 /*
5089 * bgp_announce_route
5090 *
5091 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
5092 *
5093 * if force is true we will force an update even if the update
5094 * limiting code is attempted to kick in.
5095 */
5096 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
5097 {
5098 struct peer_af *paf;
5099 struct update_subgroup *subgrp;
5100
5101 paf = peer_af_find(peer, afi, safi);
5102 if (!paf)
5103 return;
5104 subgrp = PAF_SUBGRP(paf);
5105
5106 /*
5107 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
5108 * or a refresh has already been triggered.
5109 */
5110 if (!subgrp || paf->t_announce_route)
5111 return;
5112
5113 if (force)
5114 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
5115
5116 /*
5117 * Start a timer to stagger/delay the announce. This serves
5118 * two purposes - announcement can potentially be combined for
5119 * multiple peers and the announcement doesn't happen in the
5120 * vty context.
5121 */
5122 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
5123 (subgrp->peer_count == 1)
5124 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
5125 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
5126 &paf->t_announce_route);
5127 }
5128
5129 /*
5130 * Announce routes from all AF tables to a peer.
5131 *
5132 * This should ONLY be called when there is a need to refresh the
5133 * routes to the peer based on a policy change for this peer alone
5134 * or a route refresh request received from the peer.
5135 * The operation will result in splitting the peer from its existing
5136 * subgroups and putting it in new subgroups.
5137 */
5138 void bgp_announce_route_all(struct peer *peer)
5139 {
5140 afi_t afi;
5141 safi_t safi;
5142
5143 FOREACH_AFI_SAFI (afi, safi)
5144 bgp_announce_route(peer, afi, safi, false);
5145 }
5146
5147 /* Flag or unflag bgp_dest to determine whether it should be treated by
5148 * bgp_soft_reconfig_table_task.
5149 * Flag if flag is true. Unflag if flag is false.
5150 */
5151 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
5152 {
5153 struct bgp_dest *dest;
5154 struct bgp_adj_in *ain;
5155
5156 if (!table)
5157 return;
5158
5159 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5160 for (ain = dest->adj_in; ain; ain = ain->next) {
5161 if (ain->peer != NULL)
5162 break;
5163 }
5164 if (flag && ain != NULL && ain->peer != NULL)
5165 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5166 else
5167 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5168 }
5169 }
5170
5171 static int bgp_soft_reconfig_table_update(struct peer *peer,
5172 struct bgp_dest *dest,
5173 struct bgp_adj_in *ain, afi_t afi,
5174 safi_t safi, struct prefix_rd *prd)
5175 {
5176 struct bgp_path_info *pi;
5177 uint32_t num_labels = 0;
5178 mpls_label_t *label_pnt = NULL;
5179 struct bgp_route_evpn evpn;
5180
5181 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5182 if (pi->peer == peer)
5183 break;
5184
5185 if (pi && pi->extra)
5186 num_labels = pi->extra->num_labels;
5187 if (num_labels)
5188 label_pnt = &pi->extra->label[0];
5189 if (pi)
5190 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
5191 sizeof(evpn));
5192 else
5193 memset(&evpn, 0, sizeof(evpn));
5194
5195 return bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
5196 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
5197 BGP_ROUTE_NORMAL, prd, label_pnt, num_labels, 1,
5198 &evpn);
5199 }
5200
5201 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5202 struct bgp_table *table,
5203 struct prefix_rd *prd)
5204 {
5205 int ret;
5206 struct bgp_dest *dest;
5207 struct bgp_adj_in *ain;
5208
5209 if (!table)
5210 table = peer->bgp->rib[afi][safi];
5211
5212 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5213 for (ain = dest->adj_in; ain; ain = ain->next) {
5214 if (ain->peer != peer)
5215 continue;
5216
5217 ret = bgp_soft_reconfig_table_update(peer, dest, ain,
5218 afi, safi, prd);
5219
5220 if (ret < 0) {
5221 bgp_dest_unlock_node(dest);
5222 return;
5223 }
5224 }
5225 }
5226
5227 /* Do soft reconfig table per bgp table.
5228 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5229 * when BGP_NODE_SOFT_RECONFIG is set,
5230 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5231 * Schedule a new thread to continue the job.
5232 * Without splitting the full job into several part,
5233 * vtysh waits for the job to finish before responding to a BGP command
5234 */
5235 static void bgp_soft_reconfig_table_task(struct thread *thread)
5236 {
5237 uint32_t iter, max_iter;
5238 int ret;
5239 struct bgp_dest *dest;
5240 struct bgp_adj_in *ain;
5241 struct peer *peer;
5242 struct bgp_table *table;
5243 struct prefix_rd *prd;
5244 struct listnode *node, *nnode;
5245
5246 table = THREAD_ARG(thread);
5247 prd = NULL;
5248
5249 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5250 if (table->soft_reconfig_init) {
5251 /* first call of the function with a new srta structure.
5252 * Don't do any treatment this time on nodes
5253 * in order vtysh to respond quickly
5254 */
5255 max_iter = 0;
5256 }
5257
5258 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5259 dest = bgp_route_next(dest)) {
5260 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5261 continue;
5262
5263 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5264
5265 for (ain = dest->adj_in; ain; ain = ain->next) {
5266 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5267 nnode, peer)) {
5268 if (ain->peer != peer)
5269 continue;
5270
5271 ret = bgp_soft_reconfig_table_update(
5272 peer, dest, ain, table->afi,
5273 table->safi, prd);
5274 iter++;
5275
5276 if (ret < 0) {
5277 bgp_dest_unlock_node(dest);
5278 listnode_delete(
5279 table->soft_reconfig_peers,
5280 peer);
5281 bgp_announce_route(peer, table->afi,
5282 table->safi, false);
5283 if (list_isempty(
5284 table->soft_reconfig_peers)) {
5285 list_delete(
5286 &table->soft_reconfig_peers);
5287 bgp_soft_reconfig_table_flag(
5288 table, false);
5289 return;
5290 }
5291 }
5292 }
5293 }
5294 }
5295
5296 /* we're either starting the initial iteration,
5297 * or we're going to continue an ongoing iteration
5298 */
5299 if (dest || table->soft_reconfig_init) {
5300 table->soft_reconfig_init = false;
5301 thread_add_event(bm->master, bgp_soft_reconfig_table_task,
5302 table, 0, &table->soft_reconfig_thread);
5303 return;
5304 }
5305 /* we're done, clean up the background iteration context info and
5306 schedule route annoucement
5307 */
5308 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5309 listnode_delete(table->soft_reconfig_peers, peer);
5310 bgp_announce_route(peer, table->afi, table->safi, false);
5311 }
5312
5313 list_delete(&table->soft_reconfig_peers);
5314 }
5315
5316
5317 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5318 * and peer.
5319 * - bgp cannot be NULL
5320 * - if table and peer are NULL, cancel all threads within the bgp instance
5321 * - if table is NULL and peer is not,
5322 * remove peer in all threads within the bgp instance
5323 * - if peer is NULL, cancel all threads matching table within the bgp instance
5324 */
5325 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5326 const struct bgp_table *table,
5327 const struct peer *peer)
5328 {
5329 struct peer *npeer;
5330 struct listnode *node, *nnode;
5331 int afi, safi;
5332 struct bgp_table *ntable;
5333
5334 if (!bgp)
5335 return;
5336
5337 FOREACH_AFI_SAFI (afi, safi) {
5338 ntable = bgp->rib[afi][safi];
5339 if (!ntable)
5340 continue;
5341 if (table && table != ntable)
5342 continue;
5343
5344 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5345 npeer)) {
5346 if (peer && peer != npeer)
5347 continue;
5348 listnode_delete(ntable->soft_reconfig_peers, npeer);
5349 }
5350
5351 if (!ntable->soft_reconfig_peers
5352 || !list_isempty(ntable->soft_reconfig_peers))
5353 continue;
5354
5355 list_delete(&ntable->soft_reconfig_peers);
5356 bgp_soft_reconfig_table_flag(ntable, false);
5357 THREAD_OFF(ntable->soft_reconfig_thread);
5358 }
5359 }
5360
5361 /*
5362 * Returns false if the peer is not configured for soft reconfig in
5363 */
5364 bool bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5365 {
5366 struct bgp_dest *dest;
5367 struct bgp_table *table;
5368 struct listnode *node, *nnode;
5369 struct peer *npeer;
5370 struct peer_af *paf;
5371
5372 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5373 return false;
5374
5375 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5376 && (safi != SAFI_EVPN)) {
5377 table = peer->bgp->rib[afi][safi];
5378 if (!table)
5379 return true;
5380
5381 table->soft_reconfig_init = true;
5382
5383 if (!table->soft_reconfig_peers)
5384 table->soft_reconfig_peers = list_new();
5385 npeer = NULL;
5386 /* add peer to the table soft_reconfig_peers if not already
5387 * there
5388 */
5389 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5390 npeer)) {
5391 if (peer == npeer)
5392 break;
5393 }
5394 if (peer != npeer)
5395 listnode_add(table->soft_reconfig_peers, peer);
5396
5397 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5398 * on table would start back at the beginning.
5399 */
5400 bgp_soft_reconfig_table_flag(table, true);
5401
5402 if (!table->soft_reconfig_thread)
5403 thread_add_event(bm->master,
5404 bgp_soft_reconfig_table_task, table, 0,
5405 &table->soft_reconfig_thread);
5406 /* Cancel bgp_announce_route_timer_expired threads.
5407 * bgp_announce_route_timer_expired threads have been scheduled
5408 * to announce routes as soon as the soft_reconfigure process
5409 * finishes.
5410 * In this case, soft_reconfigure is also scheduled by using
5411 * a thread but is planned after the
5412 * bgp_announce_route_timer_expired threads. It means that,
5413 * without cancelling the threads, the route announcement task
5414 * would run before the soft reconfiguration one. That would
5415 * useless and would block vtysh during several seconds. Route
5416 * announcements are rescheduled as soon as the soft_reconfigure
5417 * process finishes.
5418 */
5419 paf = peer_af_find(peer, afi, safi);
5420 if (paf)
5421 bgp_stop_announce_route_timer(paf);
5422 } else
5423 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5424 dest = bgp_route_next(dest)) {
5425 table = bgp_dest_get_bgp_table_info(dest);
5426
5427 if (table == NULL)
5428 continue;
5429
5430 const struct prefix *p = bgp_dest_get_prefix(dest);
5431 struct prefix_rd prd;
5432
5433 prd.family = AF_UNSPEC;
5434 prd.prefixlen = 64;
5435 memcpy(&prd.val, p->u.val, 8);
5436
5437 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5438 }
5439
5440 return true;
5441 }
5442
5443
5444 struct bgp_clear_node_queue {
5445 struct bgp_dest *dest;
5446 };
5447
5448 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5449 {
5450 struct bgp_clear_node_queue *cnq = data;
5451 struct bgp_dest *dest = cnq->dest;
5452 struct peer *peer = wq->spec.data;
5453 struct bgp_path_info *pi;
5454 struct bgp *bgp;
5455 afi_t afi = bgp_dest_table(dest)->afi;
5456 safi_t safi = bgp_dest_table(dest)->safi;
5457
5458 assert(dest && peer);
5459 bgp = peer->bgp;
5460
5461 /* It is possible that we have multiple paths for a prefix from a peer
5462 * if that peer is using AddPath.
5463 */
5464 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5465 if (pi->peer != peer)
5466 continue;
5467
5468 /* graceful restart STALE flag set. */
5469 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5470 && peer->nsf[afi][safi])
5471 || CHECK_FLAG(peer->af_sflags[afi][safi],
5472 PEER_STATUS_ENHANCED_REFRESH))
5473 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5474 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5475 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5476 else {
5477 /* If this is an EVPN route, process for
5478 * un-import. */
5479 if (safi == SAFI_EVPN)
5480 bgp_evpn_unimport_route(
5481 bgp, afi, safi,
5482 bgp_dest_get_prefix(dest), pi);
5483 /* Handle withdraw for VRF route-leaking and L3VPN */
5484 if (SAFI_UNICAST == safi
5485 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5486 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5487 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5488 bgp, pi);
5489 }
5490 if (SAFI_MPLS_VPN == safi &&
5491 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5492 vpn_leak_to_vrf_withdraw(bgp, pi);
5493 }
5494
5495 bgp_rib_remove(dest, pi, peer, afi, safi);
5496 }
5497 }
5498 return WQ_SUCCESS;
5499 }
5500
5501 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5502 {
5503 struct bgp_clear_node_queue *cnq = data;
5504 struct bgp_dest *dest = cnq->dest;
5505 struct bgp_table *table = bgp_dest_table(dest);
5506
5507 bgp_dest_unlock_node(dest);
5508 bgp_table_unlock(table);
5509 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5510 }
5511
5512 static void bgp_clear_node_complete(struct work_queue *wq)
5513 {
5514 struct peer *peer = wq->spec.data;
5515
5516 /* Tickle FSM to start moving again */
5517 BGP_EVENT_ADD(peer, Clearing_Completed);
5518
5519 peer_unlock(peer); /* bgp_clear_route */
5520 }
5521
5522 static void bgp_clear_node_queue_init(struct peer *peer)
5523 {
5524 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5525
5526 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5527 #undef CLEAR_QUEUE_NAME_LEN
5528
5529 peer->clear_node_queue = work_queue_new(bm->master, wname);
5530 peer->clear_node_queue->spec.hold = 10;
5531 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5532 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5533 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5534 peer->clear_node_queue->spec.max_retries = 0;
5535
5536 /* we only 'lock' this peer reference when the queue is actually active
5537 */
5538 peer->clear_node_queue->spec.data = peer;
5539 }
5540
5541 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5542 struct bgp_table *table)
5543 {
5544 struct bgp_dest *dest;
5545 int force = peer->bgp->process_queue ? 0 : 1;
5546
5547 if (!table)
5548 table = peer->bgp->rib[afi][safi];
5549
5550 /* If still no table => afi/safi isn't configured at all or smth. */
5551 if (!table)
5552 return;
5553
5554 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5555 struct bgp_path_info *pi, *next;
5556 struct bgp_adj_in *ain;
5557 struct bgp_adj_in *ain_next;
5558
5559 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5560 * queued for every clearing peer, regardless of whether it is
5561 * relevant to the peer at hand.
5562 *
5563 * Overview: There are 3 different indices which need to be
5564 * scrubbed, potentially, when a peer is removed:
5565 *
5566 * 1 peer's routes visible via the RIB (ie accepted routes)
5567 * 2 peer's routes visible by the (optional) peer's adj-in index
5568 * 3 other routes visible by the peer's adj-out index
5569 *
5570 * 3 there is no hurry in scrubbing, once the struct peer is
5571 * removed from bgp->peer, we could just GC such deleted peer's
5572 * adj-outs at our leisure.
5573 *
5574 * 1 and 2 must be 'scrubbed' in some way, at least made
5575 * invisible via RIB index before peer session is allowed to be
5576 * brought back up. So one needs to know when such a 'search' is
5577 * complete.
5578 *
5579 * Ideally:
5580 *
5581 * - there'd be a single global queue or a single RIB walker
5582 * - rather than tracking which route_nodes still need to be
5583 * examined on a peer basis, we'd track which peers still
5584 * aren't cleared
5585 *
5586 * Given that our per-peer prefix-counts now should be reliable,
5587 * this may actually be achievable. It doesn't seem to be a huge
5588 * problem at this time,
5589 *
5590 * It is possible that we have multiple paths for a prefix from
5591 * a peer
5592 * if that peer is using AddPath.
5593 */
5594 ain = dest->adj_in;
5595 while (ain) {
5596 ain_next = ain->next;
5597
5598 if (ain->peer == peer)
5599 bgp_adj_in_remove(dest, ain);
5600
5601 ain = ain_next;
5602 }
5603
5604 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5605 next = pi->next;
5606 if (pi->peer != peer)
5607 continue;
5608
5609 if (force)
5610 bgp_path_info_reap(dest, pi);
5611 else {
5612 struct bgp_clear_node_queue *cnq;
5613
5614 /* both unlocked in bgp_clear_node_queue_del */
5615 bgp_table_lock(bgp_dest_table(dest));
5616 bgp_dest_lock_node(dest);
5617 cnq = XCALLOC(
5618 MTYPE_BGP_CLEAR_NODE_QUEUE,
5619 sizeof(struct bgp_clear_node_queue));
5620 cnq->dest = dest;
5621 work_queue_add(peer->clear_node_queue, cnq);
5622 break;
5623 }
5624 }
5625 }
5626 return;
5627 }
5628
5629 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5630 {
5631 struct bgp_dest *dest;
5632 struct bgp_table *table;
5633
5634 if (peer->clear_node_queue == NULL)
5635 bgp_clear_node_queue_init(peer);
5636
5637 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5638 * Idle until it receives a Clearing_Completed event. This protects
5639 * against peers which flap faster than we can we clear, which could
5640 * lead to:
5641 *
5642 * a) race with routes from the new session being installed before
5643 * clear_route_node visits the node (to delete the route of that
5644 * peer)
5645 * b) resource exhaustion, clear_route_node likely leads to an entry
5646 * on the process_main queue. Fast-flapping could cause that queue
5647 * to grow and grow.
5648 */
5649
5650 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5651 * the unlock will happen upon work-queue completion; other wise, the
5652 * unlock happens at the end of this function.
5653 */
5654 if (!peer->clear_node_queue->thread)
5655 peer_lock(peer);
5656
5657 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5658 bgp_clear_route_table(peer, afi, safi, NULL);
5659 else
5660 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5661 dest = bgp_route_next(dest)) {
5662 table = bgp_dest_get_bgp_table_info(dest);
5663 if (!table)
5664 continue;
5665
5666 bgp_clear_route_table(peer, afi, safi, table);
5667 }
5668
5669 /* unlock if no nodes got added to the clear-node-queue. */
5670 if (!peer->clear_node_queue->thread)
5671 peer_unlock(peer);
5672 }
5673
5674 void bgp_clear_route_all(struct peer *peer)
5675 {
5676 afi_t afi;
5677 safi_t safi;
5678
5679 FOREACH_AFI_SAFI (afi, safi)
5680 bgp_clear_route(peer, afi, safi);
5681
5682 #ifdef ENABLE_BGP_VNC
5683 rfapiProcessPeerDown(peer);
5684 #endif
5685 }
5686
5687 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5688 {
5689 struct bgp_table *table;
5690 struct bgp_dest *dest;
5691 struct bgp_adj_in *ain;
5692 struct bgp_adj_in *ain_next;
5693
5694 table = peer->bgp->rib[afi][safi];
5695
5696 /* It is possible that we have multiple paths for a prefix from a peer
5697 * if that peer is using AddPath.
5698 */
5699 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5700 ain = dest->adj_in;
5701
5702 while (ain) {
5703 ain_next = ain->next;
5704
5705 if (ain->peer == peer)
5706 bgp_adj_in_remove(dest, ain);
5707
5708 ain = ain_next;
5709 }
5710 }
5711 }
5712
5713 /* If any of the routes from the peer have been marked with the NO_LLGR
5714 * community, either as sent by the peer, or as the result of a configured
5715 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5716 * operation of [RFC4271].
5717 */
5718 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5719 {
5720 struct bgp_dest *dest;
5721 struct bgp_path_info *pi;
5722 struct bgp_table *table;
5723
5724 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5725 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5726 dest = bgp_route_next(dest)) {
5727 struct bgp_dest *rm;
5728
5729 /* look for neighbor in tables */
5730 table = bgp_dest_get_bgp_table_info(dest);
5731 if (!table)
5732 continue;
5733
5734 for (rm = bgp_table_top(table); rm;
5735 rm = bgp_route_next(rm))
5736 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5737 pi = pi->next) {
5738 if (pi->peer != peer)
5739 continue;
5740 if (CHECK_FLAG(
5741 peer->af_sflags[afi][safi],
5742 PEER_STATUS_LLGR_WAIT) &&
5743 bgp_attr_get_community(pi->attr) &&
5744 !community_include(
5745 bgp_attr_get_community(
5746 pi->attr),
5747 COMMUNITY_NO_LLGR))
5748 continue;
5749 if (!CHECK_FLAG(pi->flags,
5750 BGP_PATH_STALE))
5751 continue;
5752
5753 /*
5754 * If this is VRF leaked route
5755 * process for withdraw.
5756 */
5757 if (pi->sub_type ==
5758 BGP_ROUTE_IMPORTED &&
5759 peer->bgp->inst_type ==
5760 BGP_INSTANCE_TYPE_DEFAULT)
5761 vpn_leak_to_vrf_withdraw(
5762 peer->bgp, pi);
5763
5764 bgp_rib_remove(rm, pi, peer, afi, safi);
5765 break;
5766 }
5767 }
5768 } else {
5769 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5770 dest = bgp_route_next(dest))
5771 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5772 pi = pi->next) {
5773 if (pi->peer != peer)
5774 continue;
5775 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5776 PEER_STATUS_LLGR_WAIT) &&
5777 bgp_attr_get_community(pi->attr) &&
5778 !community_include(
5779 bgp_attr_get_community(pi->attr),
5780 COMMUNITY_NO_LLGR))
5781 continue;
5782 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5783 continue;
5784 if (safi == SAFI_UNICAST &&
5785 (peer->bgp->inst_type ==
5786 BGP_INSTANCE_TYPE_VRF ||
5787 peer->bgp->inst_type ==
5788 BGP_INSTANCE_TYPE_DEFAULT))
5789 vpn_leak_from_vrf_withdraw(
5790 bgp_get_default(), peer->bgp,
5791 pi);
5792
5793 bgp_rib_remove(dest, pi, peer, afi, safi);
5794 break;
5795 }
5796 }
5797 }
5798
5799 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5800 {
5801 struct bgp_dest *dest, *ndest;
5802 struct bgp_path_info *pi;
5803 struct bgp_table *table;
5804
5805 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5806 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5807 dest = bgp_route_next(dest)) {
5808 table = bgp_dest_get_bgp_table_info(dest);
5809 if (!table)
5810 continue;
5811
5812 for (ndest = bgp_table_top(table); ndest;
5813 ndest = bgp_route_next(ndest)) {
5814 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5815 pi = pi->next) {
5816 if (pi->peer != peer)
5817 continue;
5818
5819 if ((CHECK_FLAG(
5820 peer->af_sflags[afi][safi],
5821 PEER_STATUS_ENHANCED_REFRESH))
5822 && !CHECK_FLAG(pi->flags,
5823 BGP_PATH_STALE)
5824 && !CHECK_FLAG(
5825 pi->flags,
5826 BGP_PATH_UNUSEABLE)) {
5827 if (bgp_debug_neighbor_events(
5828 peer))
5829 zlog_debug(
5830 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5831 peer,
5832 afi2str(afi),
5833 safi2str(safi),
5834 bgp_dest_get_prefix(
5835 ndest));
5836
5837 bgp_path_info_set_flag(
5838 ndest, pi,
5839 BGP_PATH_STALE);
5840 }
5841 }
5842 }
5843 }
5844 } else {
5845 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5846 dest = bgp_route_next(dest)) {
5847 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5848 pi = pi->next) {
5849 if (pi->peer != peer)
5850 continue;
5851
5852 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5853 PEER_STATUS_ENHANCED_REFRESH))
5854 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5855 && !CHECK_FLAG(pi->flags,
5856 BGP_PATH_UNUSEABLE)) {
5857 if (bgp_debug_neighbor_events(peer))
5858 zlog_debug(
5859 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5860 peer, afi2str(afi),
5861 safi2str(safi),
5862 bgp_dest_get_prefix(
5863 dest));
5864
5865 bgp_path_info_set_flag(dest, pi,
5866 BGP_PATH_STALE);
5867 }
5868 }
5869 }
5870 }
5871 }
5872
5873 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5874 {
5875 if (peer->sort == BGP_PEER_IBGP)
5876 return true;
5877
5878 if (peer->sort == BGP_PEER_EBGP
5879 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5880 || FILTER_LIST_OUT_NAME(filter)
5881 || DISTRIBUTE_OUT_NAME(filter)))
5882 return true;
5883 return false;
5884 }
5885
5886 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5887 {
5888 if (peer->sort == BGP_PEER_IBGP)
5889 return true;
5890
5891 if (peer->sort == BGP_PEER_EBGP
5892 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5893 || FILTER_LIST_IN_NAME(filter)
5894 || DISTRIBUTE_IN_NAME(filter)))
5895 return true;
5896 return false;
5897 }
5898
5899 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5900 safi_t safi)
5901 {
5902 struct bgp_dest *dest;
5903 struct bgp_path_info *pi;
5904 struct bgp_path_info *next;
5905
5906 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5907 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5908 const struct prefix *p = bgp_dest_get_prefix(dest);
5909
5910 next = pi->next;
5911
5912 /* Unimport EVPN routes from VRFs */
5913 if (safi == SAFI_EVPN)
5914 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5915 SAFI_EVPN, p, pi);
5916
5917 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5918 && pi->type == ZEBRA_ROUTE_BGP
5919 && (pi->sub_type == BGP_ROUTE_NORMAL
5920 || pi->sub_type == BGP_ROUTE_AGGREGATE
5921 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5922
5923 if (bgp_fibupd_safi(safi))
5924 bgp_zebra_withdraw(p, pi, bgp, safi);
5925 }
5926
5927 bgp_path_info_reap(dest, pi);
5928 }
5929 }
5930
5931 /* Delete all kernel routes. */
5932 void bgp_cleanup_routes(struct bgp *bgp)
5933 {
5934 afi_t afi;
5935 struct bgp_dest *dest;
5936 struct bgp_table *table;
5937
5938 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5939 if (afi == AFI_L2VPN)
5940 continue;
5941 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5942 SAFI_UNICAST);
5943 /*
5944 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5945 */
5946 if (afi != AFI_L2VPN) {
5947 safi_t safi;
5948 safi = SAFI_MPLS_VPN;
5949 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5950 dest = bgp_route_next(dest)) {
5951 table = bgp_dest_get_bgp_table_info(dest);
5952 if (table != NULL) {
5953 bgp_cleanup_table(bgp, table, safi);
5954 bgp_table_finish(&table);
5955 bgp_dest_set_bgp_table_info(dest, NULL);
5956 bgp_dest_unlock_node(dest);
5957 }
5958 }
5959 safi = SAFI_ENCAP;
5960 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5961 dest = bgp_route_next(dest)) {
5962 table = bgp_dest_get_bgp_table_info(dest);
5963 if (table != NULL) {
5964 bgp_cleanup_table(bgp, table, safi);
5965 bgp_table_finish(&table);
5966 bgp_dest_set_bgp_table_info(dest, NULL);
5967 bgp_dest_unlock_node(dest);
5968 }
5969 }
5970 }
5971 }
5972 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5973 dest = bgp_route_next(dest)) {
5974 table = bgp_dest_get_bgp_table_info(dest);
5975 if (table != NULL) {
5976 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5977 bgp_table_finish(&table);
5978 bgp_dest_set_bgp_table_info(dest, NULL);
5979 bgp_dest_unlock_node(dest);
5980 }
5981 }
5982 }
5983
5984 void bgp_reset(void)
5985 {
5986 vty_reset();
5987 bgp_zclient_reset();
5988 access_list_reset();
5989 prefix_list_reset();
5990 }
5991
5992 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5993 {
5994 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5995 && CHECK_FLAG(peer->af_cap[afi][safi],
5996 PEER_CAP_ADDPATH_AF_TX_RCV));
5997 }
5998
5999 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
6000 value. */
6001 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
6002 struct bgp_nlri *packet)
6003 {
6004 uint8_t *pnt;
6005 uint8_t *lim;
6006 struct prefix p;
6007 int psize;
6008 int ret;
6009 afi_t afi;
6010 safi_t safi;
6011 bool addpath_capable;
6012 uint32_t addpath_id;
6013
6014 pnt = packet->nlri;
6015 lim = pnt + packet->length;
6016 afi = packet->afi;
6017 safi = packet->safi;
6018 addpath_id = 0;
6019 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
6020
6021 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
6022 syntactic validity. If the field is syntactically incorrect,
6023 then the Error Subcode is set to Invalid Network Field. */
6024 for (; pnt < lim; pnt += psize) {
6025 /* Clear prefix structure. */
6026 memset(&p, 0, sizeof(p));
6027
6028 if (addpath_capable) {
6029
6030 /* When packet overflow occurs return immediately. */
6031 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
6032 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6033
6034 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
6035 addpath_id = ntohl(addpath_id);
6036 pnt += BGP_ADDPATH_ID_LEN;
6037 }
6038
6039 /* Fetch prefix length. */
6040 p.prefixlen = *pnt++;
6041 /* afi/safi validity already verified by caller,
6042 * bgp_update_receive */
6043 p.family = afi2family(afi);
6044
6045 /* Prefix length check. */
6046 if (p.prefixlen > prefix_blen(&p) * 8) {
6047 flog_err(
6048 EC_BGP_UPDATE_RCV,
6049 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
6050 peer->host, p.prefixlen, packet->afi);
6051 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
6052 }
6053
6054 /* Packet size overflow check. */
6055 psize = PSIZE(p.prefixlen);
6056
6057 /* When packet overflow occur return immediately. */
6058 if (pnt + psize > lim) {
6059 flog_err(
6060 EC_BGP_UPDATE_RCV,
6061 "%s [Error] Update packet error (prefix length %d overflows packet)",
6062 peer->host, p.prefixlen);
6063 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6064 }
6065
6066 /* Defensive coding, double-check the psize fits in a struct
6067 * prefix for the v4 and v6 afi's and unicast/multicast */
6068 if (psize > (ssize_t)sizeof(p.u.val)) {
6069 flog_err(
6070 EC_BGP_UPDATE_RCV,
6071 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
6072 peer->host, p.prefixlen, sizeof(p.u.val));
6073 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6074 }
6075
6076 /* Fetch prefix from NLRI packet. */
6077 memcpy(p.u.val, pnt, psize);
6078
6079 /* Check address. */
6080 if (afi == AFI_IP && safi == SAFI_UNICAST) {
6081 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
6082 /* From RFC4271 Section 6.3:
6083 *
6084 * If a prefix in the NLRI field is semantically
6085 * incorrect
6086 * (e.g., an unexpected multicast IP address),
6087 * an error SHOULD
6088 * be logged locally, and the prefix SHOULD be
6089 * ignored.
6090 */
6091 flog_err(
6092 EC_BGP_UPDATE_RCV,
6093 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
6094 peer->host, &p.u.prefix4);
6095 continue;
6096 }
6097 }
6098
6099 /* Check address. */
6100 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
6101 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6102 flog_err(
6103 EC_BGP_UPDATE_RCV,
6104 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
6105 peer->host, &p.u.prefix6);
6106
6107 continue;
6108 }
6109 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
6110 flog_err(
6111 EC_BGP_UPDATE_RCV,
6112 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
6113 peer->host, &p.u.prefix6);
6114
6115 continue;
6116 }
6117 }
6118
6119 /* Normal process. */
6120 if (attr)
6121 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
6122 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
6123 NULL, NULL, 0, 0, NULL);
6124 else
6125 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
6126 safi, ZEBRA_ROUTE_BGP,
6127 BGP_ROUTE_NORMAL, NULL, NULL, 0,
6128 NULL);
6129
6130 /* Do not send BGP notification twice when maximum-prefix count
6131 * overflow. */
6132 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
6133 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
6134
6135 /* Address family configuration mismatch. */
6136 if (ret < 0)
6137 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
6138 }
6139
6140 /* Packet length consistency check. */
6141 if (pnt != lim) {
6142 flog_err(
6143 EC_BGP_UPDATE_RCV,
6144 "%s [Error] Update packet error (prefix length mismatch with total length)",
6145 peer->host);
6146 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6147 }
6148
6149 return BGP_NLRI_PARSE_OK;
6150 }
6151
6152 static struct bgp_static *bgp_static_new(void)
6153 {
6154 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
6155 }
6156
6157 static void bgp_static_free(struct bgp_static *bgp_static)
6158 {
6159 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6160 route_map_counter_decrement(bgp_static->rmap.map);
6161
6162 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
6163 XFREE(MTYPE_BGP_STATIC, bgp_static);
6164 }
6165
6166 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
6167 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
6168 {
6169 struct bgp_dest *dest;
6170 struct bgp_path_info *pi;
6171 struct bgp_path_info *new;
6172 struct bgp_path_info rmap_path;
6173 struct attr attr;
6174 struct attr *attr_new;
6175 route_map_result_t ret;
6176 #ifdef ENABLE_BGP_VNC
6177 int vnc_implicit_withdraw = 0;
6178 #endif
6179
6180 assert(bgp_static);
6181
6182 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6183
6184 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6185
6186 attr.nexthop = bgp_static->igpnexthop;
6187 attr.med = bgp_static->igpmetric;
6188 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6189
6190 if (afi == AFI_IP)
6191 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
6192
6193 if (bgp_static->igpmetric)
6194 bgp_attr_set_aigp_metric(&attr, bgp_static->igpmetric);
6195
6196 if (bgp_static->atomic)
6197 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
6198
6199 /* Store label index, if required. */
6200 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
6201 attr.label_index = bgp_static->label_index;
6202 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
6203 }
6204
6205 /* Apply route-map. */
6206 if (bgp_static->rmap.name) {
6207 struct attr attr_tmp = attr;
6208
6209 memset(&rmap_path, 0, sizeof(rmap_path));
6210 rmap_path.peer = bgp->peer_self;
6211 rmap_path.attr = &attr_tmp;
6212
6213 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6214
6215 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6216
6217 bgp->peer_self->rmap_type = 0;
6218
6219 if (ret == RMAP_DENYMATCH) {
6220 /* Free uninterned attribute. */
6221 bgp_attr_flush(&attr_tmp);
6222
6223 /* Unintern original. */
6224 aspath_unintern(&attr.aspath);
6225 bgp_static_withdraw(bgp, p, afi, safi);
6226 bgp_dest_unlock_node(dest);
6227 return;
6228 }
6229
6230 if (bgp_in_graceful_shutdown(bgp))
6231 bgp_attr_add_gshut_community(&attr_tmp);
6232
6233 attr_new = bgp_attr_intern(&attr_tmp);
6234 } else {
6235
6236 if (bgp_in_graceful_shutdown(bgp))
6237 bgp_attr_add_gshut_community(&attr);
6238
6239 attr_new = bgp_attr_intern(&attr);
6240 }
6241
6242 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6243 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6244 && pi->sub_type == BGP_ROUTE_STATIC)
6245 break;
6246
6247 if (pi) {
6248 if (attrhash_cmp(pi->attr, attr_new)
6249 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6250 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6251 bgp_dest_unlock_node(dest);
6252 bgp_attr_unintern(&attr_new);
6253 aspath_unintern(&attr.aspath);
6254 return;
6255 } else {
6256 /* The attribute is changed. */
6257 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6258
6259 /* Rewrite BGP route information. */
6260 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6261 bgp_path_info_restore(dest, pi);
6262 else
6263 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6264 #ifdef ENABLE_BGP_VNC
6265 if ((afi == AFI_IP || afi == AFI_IP6)
6266 && (safi == SAFI_UNICAST)) {
6267 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6268 /*
6269 * Implicit withdraw case.
6270 * We have to do this before pi is
6271 * changed
6272 */
6273 ++vnc_implicit_withdraw;
6274 vnc_import_bgp_del_route(bgp, p, pi);
6275 vnc_import_bgp_exterior_del_route(
6276 bgp, p, pi);
6277 }
6278 }
6279 #endif
6280 bgp_attr_unintern(&pi->attr);
6281 pi->attr = attr_new;
6282 pi->uptime = monotime(NULL);
6283 #ifdef ENABLE_BGP_VNC
6284 if ((afi == AFI_IP || afi == AFI_IP6)
6285 && (safi == SAFI_UNICAST)) {
6286 if (vnc_implicit_withdraw) {
6287 vnc_import_bgp_add_route(bgp, p, pi);
6288 vnc_import_bgp_exterior_add_route(
6289 bgp, p, pi);
6290 }
6291 }
6292 #endif
6293
6294 /* Nexthop reachability check. */
6295 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6296 && (safi == SAFI_UNICAST
6297 || safi == SAFI_LABELED_UNICAST)) {
6298
6299 struct bgp *bgp_nexthop = bgp;
6300
6301 if (pi->extra && pi->extra->bgp_orig)
6302 bgp_nexthop = pi->extra->bgp_orig;
6303
6304 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6305 afi, safi, pi, NULL,
6306 0, p))
6307 bgp_path_info_set_flag(dest, pi,
6308 BGP_PATH_VALID);
6309 else {
6310 if (BGP_DEBUG(nht, NHT)) {
6311 char buf1[INET6_ADDRSTRLEN];
6312 inet_ntop(p->family,
6313 &p->u.prefix, buf1,
6314 sizeof(buf1));
6315 zlog_debug(
6316 "%s(%s): Route not in table, not advertising",
6317 __func__, buf1);
6318 }
6319 bgp_path_info_unset_flag(
6320 dest, pi, BGP_PATH_VALID);
6321 }
6322 } else {
6323 /* Delete the NHT structure if any, if we're
6324 * toggling between
6325 * enabling/disabling import check. We
6326 * deregister the route
6327 * from NHT to avoid overloading NHT and the
6328 * process interaction
6329 */
6330 bgp_unlink_nexthop(pi);
6331 bgp_path_info_set_flag(dest, pi,
6332 BGP_PATH_VALID);
6333 }
6334 /* Process change. */
6335 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6336 bgp_process(bgp, dest, afi, safi);
6337
6338 if (SAFI_UNICAST == safi
6339 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6340 || bgp->inst_type
6341 == BGP_INSTANCE_TYPE_DEFAULT)) {
6342 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6343 pi);
6344 }
6345
6346 bgp_dest_unlock_node(dest);
6347 aspath_unintern(&attr.aspath);
6348 return;
6349 }
6350 }
6351
6352 /* Make new BGP info. */
6353 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6354 attr_new, dest);
6355 /* Nexthop reachability check. */
6356 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6357 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6358 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6359 p))
6360 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6361 else {
6362 if (BGP_DEBUG(nht, NHT)) {
6363 char buf1[INET6_ADDRSTRLEN];
6364
6365 inet_ntop(p->family, &p->u.prefix, buf1,
6366 sizeof(buf1));
6367 zlog_debug(
6368 "%s(%s): Route not in table, not advertising",
6369 __func__, buf1);
6370 }
6371 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6372 }
6373 } else {
6374 /* Delete the NHT structure if any, if we're toggling between
6375 * enabling/disabling import check. We deregister the route
6376 * from NHT to avoid overloading NHT and the process interaction
6377 */
6378 bgp_unlink_nexthop(new);
6379
6380 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6381 }
6382
6383 /* Aggregate address increment. */
6384 bgp_aggregate_increment(bgp, p, new, afi, safi);
6385
6386 /* Register new BGP information. */
6387 bgp_path_info_add(dest, new);
6388
6389 /* route_node_get lock */
6390 bgp_dest_unlock_node(dest);
6391
6392 /* Process change. */
6393 bgp_process(bgp, dest, afi, safi);
6394
6395 if (SAFI_UNICAST == safi
6396 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6397 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6398 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6399 }
6400
6401 /* Unintern original. */
6402 aspath_unintern(&attr.aspath);
6403 }
6404
6405 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6406 safi_t safi)
6407 {
6408 struct bgp_dest *dest;
6409 struct bgp_path_info *pi;
6410
6411 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6412
6413 /* Check selected route and self inserted route. */
6414 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6415 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6416 && pi->sub_type == BGP_ROUTE_STATIC)
6417 break;
6418
6419 /* Withdraw static BGP route from routing table. */
6420 if (pi) {
6421 if (SAFI_UNICAST == safi
6422 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6423 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6424 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6425 }
6426 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6427 bgp_unlink_nexthop(pi);
6428 bgp_path_info_delete(dest, pi);
6429 bgp_process(bgp, dest, afi, safi);
6430 }
6431
6432 /* Unlock bgp_node_lookup. */
6433 bgp_dest_unlock_node(dest);
6434 }
6435
6436 /*
6437 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6438 */
6439 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6440 afi_t afi, safi_t safi,
6441 struct prefix_rd *prd)
6442 {
6443 struct bgp_dest *dest;
6444 struct bgp_path_info *pi;
6445
6446 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6447
6448 /* Check selected route and self inserted route. */
6449 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6450 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6451 && pi->sub_type == BGP_ROUTE_STATIC)
6452 break;
6453
6454 /* Withdraw static BGP route from routing table. */
6455 if (pi) {
6456 #ifdef ENABLE_BGP_VNC
6457 rfapiProcessWithdraw(
6458 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6459 1); /* Kill, since it is an administrative change */
6460 #endif
6461 if (SAFI_MPLS_VPN == safi
6462 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6463 vpn_leak_to_vrf_withdraw(bgp, pi);
6464 }
6465 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6466 bgp_path_info_delete(dest, pi);
6467 bgp_process(bgp, dest, afi, safi);
6468 }
6469
6470 /* Unlock bgp_node_lookup. */
6471 bgp_dest_unlock_node(dest);
6472 }
6473
6474 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6475 struct bgp_static *bgp_static, afi_t afi,
6476 safi_t safi)
6477 {
6478 struct bgp_dest *dest;
6479 struct bgp_path_info *new;
6480 struct attr *attr_new;
6481 struct attr attr = {0};
6482 struct bgp_path_info *pi;
6483 #ifdef ENABLE_BGP_VNC
6484 mpls_label_t label = 0;
6485 #endif
6486 uint32_t num_labels = 0;
6487
6488 assert(bgp_static);
6489
6490 if (bgp_static->label != MPLS_INVALID_LABEL)
6491 num_labels = 1;
6492 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6493 &bgp_static->prd);
6494
6495 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6496
6497 attr.nexthop = bgp_static->igpnexthop;
6498 attr.med = bgp_static->igpmetric;
6499 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6500
6501 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6502 || (safi == SAFI_ENCAP)) {
6503 if (afi == AFI_IP) {
6504 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6505 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6506 }
6507 }
6508 if (afi == AFI_L2VPN) {
6509 if (bgp_static->gatewayIp.family == AF_INET) {
6510 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6511 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6512 &bgp_static->gatewayIp.u.prefix4,
6513 IPV4_MAX_BYTELEN);
6514 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6515 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6516 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6517 &bgp_static->gatewayIp.u.prefix6,
6518 IPV6_MAX_BYTELEN);
6519 }
6520 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6521 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6522 struct bgp_encap_type_vxlan bet;
6523 memset(&bet, 0, sizeof(bet));
6524 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6525 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6526 }
6527 if (bgp_static->router_mac) {
6528 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6529 }
6530 }
6531 /* Apply route-map. */
6532 if (bgp_static->rmap.name) {
6533 struct attr attr_tmp = attr;
6534 struct bgp_path_info rmap_path;
6535 route_map_result_t ret;
6536
6537 rmap_path.peer = bgp->peer_self;
6538 rmap_path.attr = &attr_tmp;
6539
6540 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6541
6542 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6543
6544 bgp->peer_self->rmap_type = 0;
6545
6546 if (ret == RMAP_DENYMATCH) {
6547 /* Free uninterned attribute. */
6548 bgp_attr_flush(&attr_tmp);
6549
6550 /* Unintern original. */
6551 aspath_unintern(&attr.aspath);
6552 bgp_static_withdraw_safi(bgp, p, afi, safi,
6553 &bgp_static->prd);
6554 bgp_dest_unlock_node(dest);
6555 return;
6556 }
6557
6558 attr_new = bgp_attr_intern(&attr_tmp);
6559 } else {
6560 attr_new = bgp_attr_intern(&attr);
6561 }
6562
6563 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6564 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6565 && pi->sub_type == BGP_ROUTE_STATIC)
6566 break;
6567
6568 if (pi) {
6569 if (attrhash_cmp(pi->attr, attr_new)
6570 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6571 bgp_dest_unlock_node(dest);
6572 bgp_attr_unintern(&attr_new);
6573 aspath_unintern(&attr.aspath);
6574 return;
6575 } else {
6576 /* The attribute is changed. */
6577 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6578
6579 /* Rewrite BGP route information. */
6580 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6581 bgp_path_info_restore(dest, pi);
6582 else
6583 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6584 bgp_attr_unintern(&pi->attr);
6585 pi->attr = attr_new;
6586 pi->uptime = monotime(NULL);
6587 #ifdef ENABLE_BGP_VNC
6588 if (pi->extra)
6589 label = decode_label(&pi->extra->label[0]);
6590 #endif
6591
6592 /* Process change. */
6593 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6594 bgp_process(bgp, dest, afi, safi);
6595
6596 if (SAFI_MPLS_VPN == safi
6597 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6598 vpn_leak_to_vrf_update(bgp, pi,
6599 &bgp_static->prd);
6600 }
6601 #ifdef ENABLE_BGP_VNC
6602 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6603 pi->attr, afi, safi, pi->type,
6604 pi->sub_type, &label);
6605 #endif
6606 bgp_dest_unlock_node(dest);
6607 aspath_unintern(&attr.aspath);
6608 return;
6609 }
6610 }
6611
6612
6613 /* Make new BGP info. */
6614 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6615 attr_new, dest);
6616 SET_FLAG(new->flags, BGP_PATH_VALID);
6617 bgp_path_info_extra_get(new);
6618 if (num_labels) {
6619 new->extra->label[0] = bgp_static->label;
6620 new->extra->num_labels = num_labels;
6621 }
6622 #ifdef ENABLE_BGP_VNC
6623 label = decode_label(&bgp_static->label);
6624 #endif
6625
6626 /* Aggregate address increment. */
6627 bgp_aggregate_increment(bgp, p, new, afi, safi);
6628
6629 /* Register new BGP information. */
6630 bgp_path_info_add(dest, new);
6631 /* route_node_get lock */
6632 bgp_dest_unlock_node(dest);
6633
6634 /* Process change. */
6635 bgp_process(bgp, dest, afi, safi);
6636
6637 if (SAFI_MPLS_VPN == safi
6638 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6639 vpn_leak_to_vrf_update(bgp, new, &bgp_static->prd);
6640 }
6641 #ifdef ENABLE_BGP_VNC
6642 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6643 safi, new->type, new->sub_type, &label);
6644 #endif
6645
6646 /* Unintern original. */
6647 aspath_unintern(&attr.aspath);
6648 }
6649
6650 /* Configure static BGP network. When user don't run zebra, static
6651 route should be installed as valid. */
6652 static int bgp_static_set(struct vty *vty, const char *negate,
6653 const char *ip_str, afi_t afi, safi_t safi,
6654 const char *rmap, int backdoor, uint32_t label_index)
6655 {
6656 VTY_DECLVAR_CONTEXT(bgp, bgp);
6657 int ret;
6658 struct prefix p;
6659 struct bgp_static *bgp_static;
6660 struct bgp_dest *dest;
6661 uint8_t need_update = 0;
6662
6663 /* Convert IP prefix string to struct prefix. */
6664 ret = str2prefix(ip_str, &p);
6665 if (!ret) {
6666 vty_out(vty, "%% Malformed prefix\n");
6667 return CMD_WARNING_CONFIG_FAILED;
6668 }
6669 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6670 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6671 return CMD_WARNING_CONFIG_FAILED;
6672 }
6673
6674 apply_mask(&p);
6675
6676 if (negate) {
6677
6678 /* Set BGP static route configuration. */
6679 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6680
6681 if (!dest) {
6682 vty_out(vty, "%% Can't find static route specified\n");
6683 return CMD_WARNING_CONFIG_FAILED;
6684 }
6685
6686 bgp_static = bgp_dest_get_bgp_static_info(dest);
6687
6688 if ((label_index != BGP_INVALID_LABEL_INDEX)
6689 && (label_index != bgp_static->label_index)) {
6690 vty_out(vty,
6691 "%% label-index doesn't match static route\n");
6692 bgp_dest_unlock_node(dest);
6693 return CMD_WARNING_CONFIG_FAILED;
6694 }
6695
6696 if ((rmap && bgp_static->rmap.name)
6697 && strcmp(rmap, bgp_static->rmap.name)) {
6698 vty_out(vty,
6699 "%% route-map name doesn't match static route\n");
6700 bgp_dest_unlock_node(dest);
6701 return CMD_WARNING_CONFIG_FAILED;
6702 }
6703
6704 /* Update BGP RIB. */
6705 if (!bgp_static->backdoor)
6706 bgp_static_withdraw(bgp, &p, afi, safi);
6707
6708 /* Clear configuration. */
6709 bgp_static_free(bgp_static);
6710 bgp_dest_set_bgp_static_info(dest, NULL);
6711 bgp_dest_unlock_node(dest);
6712 bgp_dest_unlock_node(dest);
6713 } else {
6714
6715 /* Set BGP static route configuration. */
6716 dest = bgp_node_get(bgp->route[afi][safi], &p);
6717 bgp_static = bgp_dest_get_bgp_static_info(dest);
6718 if (bgp_static) {
6719 /* Configuration change. */
6720 /* Label index cannot be changed. */
6721 if (bgp_static->label_index != label_index) {
6722 vty_out(vty, "%% cannot change label-index\n");
6723 bgp_dest_unlock_node(dest);
6724 return CMD_WARNING_CONFIG_FAILED;
6725 }
6726
6727 /* Check previous routes are installed into BGP. */
6728 if (bgp_static->valid
6729 && bgp_static->backdoor != backdoor)
6730 need_update = 1;
6731
6732 bgp_static->backdoor = backdoor;
6733
6734 if (rmap) {
6735 XFREE(MTYPE_ROUTE_MAP_NAME,
6736 bgp_static->rmap.name);
6737 route_map_counter_decrement(
6738 bgp_static->rmap.map);
6739 bgp_static->rmap.name =
6740 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6741 bgp_static->rmap.map =
6742 route_map_lookup_by_name(rmap);
6743 route_map_counter_increment(
6744 bgp_static->rmap.map);
6745 } else {
6746 XFREE(MTYPE_ROUTE_MAP_NAME,
6747 bgp_static->rmap.name);
6748 route_map_counter_decrement(
6749 bgp_static->rmap.map);
6750 bgp_static->rmap.map = NULL;
6751 bgp_static->valid = 0;
6752 }
6753 bgp_dest_unlock_node(dest);
6754 } else {
6755 /* New configuration. */
6756 bgp_static = bgp_static_new();
6757 bgp_static->backdoor = backdoor;
6758 bgp_static->valid = 0;
6759 bgp_static->igpmetric = 0;
6760 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6761 bgp_static->label_index = label_index;
6762
6763 if (rmap) {
6764 XFREE(MTYPE_ROUTE_MAP_NAME,
6765 bgp_static->rmap.name);
6766 route_map_counter_decrement(
6767 bgp_static->rmap.map);
6768 bgp_static->rmap.name =
6769 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6770 bgp_static->rmap.map =
6771 route_map_lookup_by_name(rmap);
6772 route_map_counter_increment(
6773 bgp_static->rmap.map);
6774 }
6775 bgp_dest_set_bgp_static_info(dest, bgp_static);
6776 }
6777
6778 bgp_static->valid = 1;
6779 if (need_update)
6780 bgp_static_withdraw(bgp, &p, afi, safi);
6781
6782 if (!bgp_static->backdoor)
6783 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6784 }
6785
6786 return CMD_SUCCESS;
6787 }
6788
6789 void bgp_static_add(struct bgp *bgp)
6790 {
6791 afi_t afi;
6792 safi_t safi;
6793 struct bgp_dest *dest;
6794 struct bgp_dest *rm;
6795 struct bgp_table *table;
6796 struct bgp_static *bgp_static;
6797
6798 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6799 FOREACH_AFI_SAFI (afi, safi)
6800 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6801 dest = bgp_route_next(dest)) {
6802 if (!bgp_dest_has_bgp_path_info_data(dest))
6803 continue;
6804
6805 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6806 || (safi == SAFI_EVPN)) {
6807 table = bgp_dest_get_bgp_table_info(dest);
6808
6809 for (rm = bgp_table_top(table); rm;
6810 rm = bgp_route_next(rm)) {
6811 bgp_static =
6812 bgp_dest_get_bgp_static_info(
6813 rm);
6814 bgp_static_update_safi(
6815 bgp, bgp_dest_get_prefix(rm),
6816 bgp_static, afi, safi);
6817 }
6818 } else {
6819 bgp_static_update(
6820 bgp, bgp_dest_get_prefix(dest),
6821 bgp_dest_get_bgp_static_info(dest), afi,
6822 safi);
6823 }
6824 }
6825 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6826 }
6827
6828 /* Called from bgp_delete(). Delete all static routes from the BGP
6829 instance. */
6830 void bgp_static_delete(struct bgp *bgp)
6831 {
6832 afi_t afi;
6833 safi_t safi;
6834 struct bgp_dest *dest;
6835 struct bgp_dest *rm;
6836 struct bgp_table *table;
6837 struct bgp_static *bgp_static;
6838
6839 FOREACH_AFI_SAFI (afi, safi)
6840 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6841 dest = bgp_route_next(dest)) {
6842 if (!bgp_dest_has_bgp_path_info_data(dest))
6843 continue;
6844
6845 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6846 || (safi == SAFI_EVPN)) {
6847 table = bgp_dest_get_bgp_table_info(dest);
6848
6849 for (rm = bgp_table_top(table); rm;
6850 rm = bgp_route_next(rm)) {
6851 bgp_static =
6852 bgp_dest_get_bgp_static_info(
6853 rm);
6854 if (!bgp_static)
6855 continue;
6856
6857 bgp_static_withdraw_safi(
6858 bgp, bgp_dest_get_prefix(rm),
6859 AFI_IP, safi,
6860 (struct prefix_rd *)
6861 bgp_dest_get_prefix(
6862 dest));
6863 bgp_static_free(bgp_static);
6864 bgp_dest_set_bgp_static_info(rm,
6865 NULL);
6866 bgp_dest_unlock_node(rm);
6867 }
6868 } else {
6869 bgp_static = bgp_dest_get_bgp_static_info(dest);
6870 bgp_static_withdraw(bgp,
6871 bgp_dest_get_prefix(dest),
6872 afi, safi);
6873 bgp_static_free(bgp_static);
6874 bgp_dest_set_bgp_static_info(dest, NULL);
6875 bgp_dest_unlock_node(dest);
6876 }
6877 }
6878 }
6879
6880 void bgp_static_redo_import_check(struct bgp *bgp)
6881 {
6882 afi_t afi;
6883 safi_t safi;
6884 struct bgp_dest *dest;
6885 struct bgp_dest *rm;
6886 struct bgp_table *table;
6887 struct bgp_static *bgp_static;
6888
6889 /* Use this flag to force reprocessing of the route */
6890 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6891 FOREACH_AFI_SAFI (afi, safi) {
6892 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6893 dest = bgp_route_next(dest)) {
6894 if (!bgp_dest_has_bgp_path_info_data(dest))
6895 continue;
6896
6897 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6898 || (safi == SAFI_EVPN)) {
6899 table = bgp_dest_get_bgp_table_info(dest);
6900
6901 for (rm = bgp_table_top(table); rm;
6902 rm = bgp_route_next(rm)) {
6903 bgp_static =
6904 bgp_dest_get_bgp_static_info(
6905 rm);
6906 bgp_static_update_safi(
6907 bgp, bgp_dest_get_prefix(rm),
6908 bgp_static, afi, safi);
6909 }
6910 } else {
6911 bgp_static = bgp_dest_get_bgp_static_info(dest);
6912 bgp_static_update(bgp,
6913 bgp_dest_get_prefix(dest),
6914 bgp_static, afi, safi);
6915 }
6916 }
6917 }
6918 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6919 }
6920
6921 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6922 safi_t safi)
6923 {
6924 struct bgp_table *table;
6925 struct bgp_dest *dest;
6926 struct bgp_path_info *pi;
6927
6928 /* Do not install the aggregate route if BGP is in the
6929 * process of termination.
6930 */
6931 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6932 || (bgp->peer_self == NULL))
6933 return;
6934
6935 table = bgp->rib[afi][safi];
6936 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6937 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6938 if (pi->peer == bgp->peer_self
6939 && ((pi->type == ZEBRA_ROUTE_BGP
6940 && pi->sub_type == BGP_ROUTE_STATIC)
6941 || (pi->type != ZEBRA_ROUTE_BGP
6942 && pi->sub_type
6943 == BGP_ROUTE_REDISTRIBUTE))) {
6944 bgp_aggregate_decrement(
6945 bgp, bgp_dest_get_prefix(dest), pi, afi,
6946 safi);
6947 bgp_unlink_nexthop(pi);
6948 bgp_path_info_delete(dest, pi);
6949 bgp_process(bgp, dest, afi, safi);
6950 }
6951 }
6952 }
6953 }
6954
6955 /*
6956 * Purge all networks and redistributed routes from routing table.
6957 * Invoked upon the instance going down.
6958 */
6959 void bgp_purge_static_redist_routes(struct bgp *bgp)
6960 {
6961 afi_t afi;
6962 safi_t safi;
6963
6964 FOREACH_AFI_SAFI (afi, safi)
6965 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6966 }
6967
6968 /*
6969 * gpz 110624
6970 * Currently this is used to set static routes for VPN and ENCAP.
6971 * I think it can probably be factored with bgp_static_set.
6972 */
6973 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6974 const char *ip_str, const char *rd_str,
6975 const char *label_str, const char *rmap_str,
6976 int evpn_type, const char *esi, const char *gwip,
6977 const char *ethtag, const char *routermac)
6978 {
6979 VTY_DECLVAR_CONTEXT(bgp, bgp);
6980 int ret;
6981 struct prefix p;
6982 struct prefix_rd prd;
6983 struct bgp_dest *pdest;
6984 struct bgp_dest *dest;
6985 struct bgp_table *table;
6986 struct bgp_static *bgp_static;
6987 mpls_label_t label = MPLS_INVALID_LABEL;
6988 struct prefix gw_ip;
6989
6990 /* validate ip prefix */
6991 ret = str2prefix(ip_str, &p);
6992 if (!ret) {
6993 vty_out(vty, "%% Malformed prefix\n");
6994 return CMD_WARNING_CONFIG_FAILED;
6995 }
6996 apply_mask(&p);
6997 if ((afi == AFI_L2VPN)
6998 && (bgp_build_evpn_prefix(evpn_type,
6999 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7000 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7001 return CMD_WARNING_CONFIG_FAILED;
7002 }
7003
7004 ret = str2prefix_rd(rd_str, &prd);
7005 if (!ret) {
7006 vty_out(vty, "%% Malformed rd\n");
7007 return CMD_WARNING_CONFIG_FAILED;
7008 }
7009
7010 if (label_str) {
7011 unsigned long label_val;
7012 label_val = strtoul(label_str, NULL, 10);
7013 encode_label(label_val, &label);
7014 }
7015
7016 if (safi == SAFI_EVPN) {
7017 if (esi && str2esi(esi, NULL) == 0) {
7018 vty_out(vty, "%% Malformed ESI\n");
7019 return CMD_WARNING_CONFIG_FAILED;
7020 }
7021 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
7022 vty_out(vty, "%% Malformed Router MAC\n");
7023 return CMD_WARNING_CONFIG_FAILED;
7024 }
7025 if (gwip) {
7026 memset(&gw_ip, 0, sizeof(gw_ip));
7027 ret = str2prefix(gwip, &gw_ip);
7028 if (!ret) {
7029 vty_out(vty, "%% Malformed GatewayIp\n");
7030 return CMD_WARNING_CONFIG_FAILED;
7031 }
7032 if ((gw_ip.family == AF_INET
7033 && is_evpn_prefix_ipaddr_v6(
7034 (struct prefix_evpn *)&p))
7035 || (gw_ip.family == AF_INET6
7036 && is_evpn_prefix_ipaddr_v4(
7037 (struct prefix_evpn *)&p))) {
7038 vty_out(vty,
7039 "%% GatewayIp family differs with IP prefix\n");
7040 return CMD_WARNING_CONFIG_FAILED;
7041 }
7042 }
7043 }
7044 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7045 if (!bgp_dest_has_bgp_path_info_data(pdest))
7046 bgp_dest_set_bgp_table_info(pdest,
7047 bgp_table_init(bgp, afi, safi));
7048 table = bgp_dest_get_bgp_table_info(pdest);
7049
7050 dest = bgp_node_get(table, &p);
7051
7052 if (bgp_dest_has_bgp_path_info_data(dest)) {
7053 vty_out(vty, "%% Same network configuration exists\n");
7054 bgp_dest_unlock_node(dest);
7055 } else {
7056 /* New configuration. */
7057 bgp_static = bgp_static_new();
7058 bgp_static->backdoor = 0;
7059 bgp_static->valid = 0;
7060 bgp_static->igpmetric = 0;
7061 bgp_static->igpnexthop.s_addr = INADDR_ANY;
7062 bgp_static->label = label;
7063 bgp_static->prd = prd;
7064
7065 if (rmap_str) {
7066 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
7067 route_map_counter_decrement(bgp_static->rmap.map);
7068 bgp_static->rmap.name =
7069 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
7070 bgp_static->rmap.map =
7071 route_map_lookup_by_name(rmap_str);
7072 route_map_counter_increment(bgp_static->rmap.map);
7073 }
7074
7075 if (safi == SAFI_EVPN) {
7076 if (esi) {
7077 bgp_static->eth_s_id =
7078 XCALLOC(MTYPE_ATTR,
7079 sizeof(esi_t));
7080 str2esi(esi, bgp_static->eth_s_id);
7081 }
7082 if (routermac) {
7083 bgp_static->router_mac =
7084 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
7085 (void)prefix_str2mac(routermac,
7086 bgp_static->router_mac);
7087 }
7088 if (gwip)
7089 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
7090 }
7091 bgp_dest_set_bgp_static_info(dest, bgp_static);
7092
7093 bgp_static->valid = 1;
7094 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
7095 }
7096
7097 return CMD_SUCCESS;
7098 }
7099
7100 /* Configure static BGP network. */
7101 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
7102 const char *ip_str, const char *rd_str,
7103 const char *label_str, int evpn_type, const char *esi,
7104 const char *gwip, const char *ethtag)
7105 {
7106 VTY_DECLVAR_CONTEXT(bgp, bgp);
7107 int ret;
7108 struct prefix p;
7109 struct prefix_rd prd;
7110 struct bgp_dest *pdest;
7111 struct bgp_dest *dest;
7112 struct bgp_table *table;
7113 struct bgp_static *bgp_static;
7114 mpls_label_t label = MPLS_INVALID_LABEL;
7115
7116 /* Convert IP prefix string to struct prefix. */
7117 ret = str2prefix(ip_str, &p);
7118 if (!ret) {
7119 vty_out(vty, "%% Malformed prefix\n");
7120 return CMD_WARNING_CONFIG_FAILED;
7121 }
7122 apply_mask(&p);
7123 if ((afi == AFI_L2VPN)
7124 && (bgp_build_evpn_prefix(evpn_type,
7125 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7126 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7127 return CMD_WARNING_CONFIG_FAILED;
7128 }
7129 ret = str2prefix_rd(rd_str, &prd);
7130 if (!ret) {
7131 vty_out(vty, "%% Malformed rd\n");
7132 return CMD_WARNING_CONFIG_FAILED;
7133 }
7134
7135 if (label_str) {
7136 unsigned long label_val;
7137 label_val = strtoul(label_str, NULL, 10);
7138 encode_label(label_val, &label);
7139 }
7140
7141 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7142 if (!bgp_dest_has_bgp_path_info_data(pdest))
7143 bgp_dest_set_bgp_table_info(pdest,
7144 bgp_table_init(bgp, afi, safi));
7145 else
7146 bgp_dest_unlock_node(pdest);
7147 table = bgp_dest_get_bgp_table_info(pdest);
7148
7149 dest = bgp_node_lookup(table, &p);
7150
7151 if (dest) {
7152 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
7153
7154 bgp_static = bgp_dest_get_bgp_static_info(dest);
7155 bgp_static_free(bgp_static);
7156 bgp_dest_set_bgp_static_info(dest, NULL);
7157 bgp_dest_unlock_node(dest);
7158 bgp_dest_unlock_node(dest);
7159 } else
7160 vty_out(vty, "%% Can't find the route\n");
7161
7162 return CMD_SUCCESS;
7163 }
7164
7165 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
7166 const char *rmap_name)
7167 {
7168 VTY_DECLVAR_CONTEXT(bgp, bgp);
7169 struct bgp_rmap *rmap;
7170
7171 rmap = &bgp->table_map[afi][safi];
7172 if (rmap_name) {
7173 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7174 route_map_counter_decrement(rmap->map);
7175 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
7176 rmap->map = route_map_lookup_by_name(rmap_name);
7177 route_map_counter_increment(rmap->map);
7178 } else {
7179 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7180 route_map_counter_decrement(rmap->map);
7181 rmap->map = NULL;
7182 }
7183
7184 if (bgp_fibupd_safi(safi))
7185 bgp_zebra_announce_table(bgp, afi, safi);
7186
7187 return CMD_SUCCESS;
7188 }
7189
7190 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
7191 const char *rmap_name)
7192 {
7193 VTY_DECLVAR_CONTEXT(bgp, bgp);
7194 struct bgp_rmap *rmap;
7195
7196 rmap = &bgp->table_map[afi][safi];
7197 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7198 route_map_counter_decrement(rmap->map);
7199 rmap->map = NULL;
7200
7201 if (bgp_fibupd_safi(safi))
7202 bgp_zebra_announce_table(bgp, afi, safi);
7203
7204 return CMD_SUCCESS;
7205 }
7206
7207 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
7208 safi_t safi)
7209 {
7210 if (bgp->table_map[afi][safi].name) {
7211 vty_out(vty, " table-map %s\n",
7212 bgp->table_map[afi][safi].name);
7213 }
7214 }
7215
7216 DEFUN (bgp_table_map,
7217 bgp_table_map_cmd,
7218 "table-map WORD",
7219 "BGP table to RIB route download filter\n"
7220 "Name of the route map\n")
7221 {
7222 int idx_word = 1;
7223 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7224 argv[idx_word]->arg);
7225 }
7226 DEFUN (no_bgp_table_map,
7227 no_bgp_table_map_cmd,
7228 "no table-map WORD",
7229 NO_STR
7230 "BGP table to RIB route download filter\n"
7231 "Name of the route map\n")
7232 {
7233 int idx_word = 2;
7234 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7235 argv[idx_word]->arg);
7236 }
7237
7238 DEFPY(bgp_network,
7239 bgp_network_cmd,
7240 "[no] network \
7241 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7242 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7243 backdoor$backdoor}]",
7244 NO_STR
7245 "Specify a network to announce via BGP\n"
7246 "IPv4 prefix\n"
7247 "Network number\n"
7248 "Network mask\n"
7249 "Network mask\n"
7250 "Route-map to modify the attributes\n"
7251 "Name of the route map\n"
7252 "Label index to associate with the prefix\n"
7253 "Label index value\n"
7254 "Specify a BGP backdoor route\n")
7255 {
7256 char addr_prefix_str[BUFSIZ];
7257
7258 if (address_str) {
7259 int ret;
7260
7261 ret = netmask_str2prefix_str(address_str, netmask_str,
7262 addr_prefix_str,
7263 sizeof(addr_prefix_str));
7264 if (!ret) {
7265 vty_out(vty, "%% Inconsistent address and mask\n");
7266 return CMD_WARNING_CONFIG_FAILED;
7267 }
7268 }
7269
7270 return bgp_static_set(
7271 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7272 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7273 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7274 }
7275
7276 DEFPY(ipv6_bgp_network,
7277 ipv6_bgp_network_cmd,
7278 "[no] network X:X::X:X/M$prefix \
7279 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7280 NO_STR
7281 "Specify a network to announce via BGP\n"
7282 "IPv6 prefix\n"
7283 "Route-map to modify the attributes\n"
7284 "Name of the route map\n"
7285 "Label index to associate with the prefix\n"
7286 "Label index value\n")
7287 {
7288 return bgp_static_set(
7289 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7290 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7291 }
7292
7293 static struct bgp_aggregate *bgp_aggregate_new(void)
7294 {
7295 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7296 }
7297
7298 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7299 {
7300 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7301 route_map_counter_decrement(aggregate->suppress_map);
7302 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7303 route_map_counter_decrement(aggregate->rmap.map);
7304 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7305 }
7306
7307 /**
7308 * Helper function to avoid repeated code: prepare variables for a
7309 * `route_map_apply` call.
7310 *
7311 * \returns `true` on route map match, otherwise `false`.
7312 */
7313 static bool aggr_suppress_map_test(struct bgp *bgp,
7314 struct bgp_aggregate *aggregate,
7315 struct bgp_path_info *pi)
7316 {
7317 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7318 route_map_result_t rmr = RMAP_DENYMATCH;
7319 struct bgp_path_info rmap_path = {};
7320 struct attr attr = {};
7321
7322 /* No route map entries created, just don't match. */
7323 if (aggregate->suppress_map == NULL)
7324 return false;
7325
7326 /* Call route map matching and return result. */
7327 attr.aspath = aspath_empty();
7328 rmap_path.peer = bgp->peer_self;
7329 rmap_path.attr = &attr;
7330
7331 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7332 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7333 bgp->peer_self->rmap_type = 0;
7334
7335 bgp_attr_flush(&attr);
7336 aspath_unintern(&attr.aspath);
7337
7338 return rmr == RMAP_PERMITMATCH;
7339 }
7340
7341 /** Test whether the aggregation has suppressed this path or not. */
7342 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7343 struct bgp_path_info *pi)
7344 {
7345 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7346 return false;
7347
7348 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7349 }
7350
7351 /**
7352 * Suppress this path and keep the reference.
7353 *
7354 * \returns `true` if needs processing otherwise `false`.
7355 */
7356 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7357 struct bgp_path_info *pi)
7358 {
7359 struct bgp_path_info_extra *pie;
7360
7361 /* Path is already suppressed by this aggregation. */
7362 if (aggr_suppress_exists(aggregate, pi))
7363 return false;
7364
7365 pie = bgp_path_info_extra_get(pi);
7366
7367 /* This is the first suppression, allocate memory and list it. */
7368 if (pie->aggr_suppressors == NULL)
7369 pie->aggr_suppressors = list_new();
7370
7371 listnode_add(pie->aggr_suppressors, aggregate);
7372
7373 /* Only mark for processing if suppressed. */
7374 if (listcount(pie->aggr_suppressors) == 1) {
7375 if (BGP_DEBUG(update, UPDATE_OUT))
7376 zlog_debug("aggregate-address suppressing: %pFX",
7377 bgp_dest_get_prefix(pi->net));
7378
7379 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7380 return true;
7381 }
7382
7383 return false;
7384 }
7385
7386 /**
7387 * Unsuppress this path and remove the reference.
7388 *
7389 * \returns `true` if needs processing otherwise `false`.
7390 */
7391 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7392 struct bgp_path_info *pi)
7393 {
7394 /* Path wasn't suppressed. */
7395 if (!aggr_suppress_exists(aggregate, pi))
7396 return false;
7397
7398 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7399
7400 /* Unsuppress and free extra memory if last item. */
7401 if (listcount(pi->extra->aggr_suppressors) == 0) {
7402 if (BGP_DEBUG(update, UPDATE_OUT))
7403 zlog_debug("aggregate-address unsuppressing: %pFX",
7404 bgp_dest_get_prefix(pi->net));
7405
7406 list_delete(&pi->extra->aggr_suppressors);
7407 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7408 return true;
7409 }
7410
7411 return false;
7412 }
7413
7414 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7415 struct aspath *aspath,
7416 struct community *comm,
7417 struct ecommunity *ecomm,
7418 struct lcommunity *lcomm)
7419 {
7420 static struct aspath *ae = NULL;
7421
7422 if (!ae)
7423 ae = aspath_empty();
7424
7425 if (!pi)
7426 return false;
7427
7428 if (origin != pi->attr->origin)
7429 return false;
7430
7431 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7432 return false;
7433
7434 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7435 return false;
7436
7437 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7438 return false;
7439
7440 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7441 return false;
7442
7443 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7444 return false;
7445
7446 return true;
7447 }
7448
7449 static void bgp_aggregate_install(
7450 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7451 uint8_t origin, struct aspath *aspath, struct community *community,
7452 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7453 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7454 {
7455 struct bgp_dest *dest;
7456 struct bgp_table *table;
7457 struct bgp_path_info *pi, *orig, *new;
7458 struct attr *attr;
7459
7460 table = bgp->rib[afi][safi];
7461
7462 dest = bgp_node_get(table, p);
7463
7464 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7465 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7466 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7467 break;
7468
7469 /*
7470 * If we have paths with different MEDs, then don't install
7471 * (or uninstall) the aggregate route.
7472 */
7473 if (aggregate->match_med && aggregate->med_mismatched)
7474 goto uninstall_aggregate_route;
7475
7476 if (aggregate->count > 0) {
7477 /*
7478 * If the aggregate information has not changed
7479 * no need to re-install it again.
7480 */
7481 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7482 ecommunity, lcommunity)) {
7483 bgp_dest_unlock_node(dest);
7484
7485 if (aspath)
7486 aspath_free(aspath);
7487 if (community)
7488 community_free(&community);
7489 if (ecommunity)
7490 ecommunity_free(&ecommunity);
7491 if (lcommunity)
7492 lcommunity_free(&lcommunity);
7493
7494 return;
7495 }
7496
7497 /*
7498 * Mark the old as unusable
7499 */
7500 if (pi)
7501 bgp_path_info_delete(dest, pi);
7502
7503 attr = bgp_attr_aggregate_intern(
7504 bgp, origin, aspath, community, ecommunity, lcommunity,
7505 aggregate, atomic_aggregate, p);
7506
7507 if (!attr) {
7508 bgp_dest_unlock_node(dest);
7509 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7510 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7511 zlog_debug("%s: %pFX null attribute", __func__,
7512 p);
7513 return;
7514 }
7515
7516 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7517 bgp->peer_self, attr, dest);
7518
7519 SET_FLAG(new->flags, BGP_PATH_VALID);
7520
7521 bgp_path_info_add(dest, new);
7522 bgp_process(bgp, dest, afi, safi);
7523 } else {
7524 uninstall_aggregate_route:
7525 for (pi = orig; pi; pi = pi->next)
7526 if (pi->peer == bgp->peer_self
7527 && pi->type == ZEBRA_ROUTE_BGP
7528 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7529 break;
7530
7531 /* Withdraw static BGP route from routing table. */
7532 if (pi) {
7533 bgp_path_info_delete(dest, pi);
7534 bgp_process(bgp, dest, afi, safi);
7535 }
7536 }
7537
7538 bgp_dest_unlock_node(dest);
7539 }
7540
7541 /**
7542 * Check if the current path has different MED than other known paths.
7543 *
7544 * \returns `true` if the MED matched the others else `false`.
7545 */
7546 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7547 struct bgp *bgp, struct bgp_path_info *pi)
7548 {
7549 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7550
7551 /* This is the first route being analyzed. */
7552 if (!aggregate->med_initialized) {
7553 aggregate->med_initialized = true;
7554 aggregate->med_mismatched = false;
7555 aggregate->med_matched_value = cur_med;
7556 } else {
7557 /* Check if routes with different MED showed up. */
7558 if (cur_med != aggregate->med_matched_value)
7559 aggregate->med_mismatched = true;
7560 }
7561
7562 return !aggregate->med_mismatched;
7563 }
7564
7565 /**
7566 * Initializes and tests all routes in the aggregate address path for MED
7567 * values.
7568 *
7569 * \returns `true` if all MEDs are the same otherwise `false`.
7570 */
7571 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7572 struct bgp *bgp, const struct prefix *p,
7573 afi_t afi, safi_t safi)
7574 {
7575 struct bgp_table *table = bgp->rib[afi][safi];
7576 const struct prefix *dest_p;
7577 struct bgp_dest *dest, *top;
7578 struct bgp_path_info *pi;
7579 bool med_matched = true;
7580
7581 aggregate->med_initialized = false;
7582
7583 top = bgp_node_get(table, p);
7584 for (dest = bgp_node_get(table, p); dest;
7585 dest = bgp_route_next_until(dest, top)) {
7586 dest_p = bgp_dest_get_prefix(dest);
7587 if (dest_p->prefixlen <= p->prefixlen)
7588 continue;
7589
7590 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7591 if (BGP_PATH_HOLDDOWN(pi))
7592 continue;
7593 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7594 continue;
7595 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7596 med_matched = false;
7597 break;
7598 }
7599 }
7600 if (!med_matched)
7601 break;
7602 }
7603 bgp_dest_unlock_node(top);
7604
7605 return med_matched;
7606 }
7607
7608 /**
7609 * Toggles the route suppression status for this aggregate address
7610 * configuration.
7611 */
7612 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7613 struct bgp *bgp, const struct prefix *p,
7614 afi_t afi, safi_t safi, bool suppress)
7615 {
7616 struct bgp_table *table = bgp->rib[afi][safi];
7617 const struct prefix *dest_p;
7618 struct bgp_dest *dest, *top;
7619 struct bgp_path_info *pi;
7620 bool toggle_suppression;
7621
7622 /* We've found a different MED we must revert any suppressed routes. */
7623 top = bgp_node_get(table, p);
7624 for (dest = bgp_node_get(table, p); dest;
7625 dest = bgp_route_next_until(dest, top)) {
7626 dest_p = bgp_dest_get_prefix(dest);
7627 if (dest_p->prefixlen <= p->prefixlen)
7628 continue;
7629
7630 toggle_suppression = false;
7631 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7632 if (BGP_PATH_HOLDDOWN(pi))
7633 continue;
7634 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7635 continue;
7636
7637 /* We are toggling suppression back. */
7638 if (suppress) {
7639 /* Suppress route if not suppressed already. */
7640 if (aggr_suppress_path(aggregate, pi))
7641 toggle_suppression = true;
7642 continue;
7643 }
7644
7645 /* Install route if there is no more suppression. */
7646 if (aggr_unsuppress_path(aggregate, pi))
7647 toggle_suppression = true;
7648 }
7649
7650 if (toggle_suppression)
7651 bgp_process(bgp, dest, afi, safi);
7652 }
7653 bgp_dest_unlock_node(top);
7654 }
7655
7656 /**
7657 * Aggregate address MED matching incremental test: this function is called
7658 * when the initial aggregation occurred and we are only testing a single
7659 * new path.
7660 *
7661 * In addition to testing and setting the MED validity it also installs back
7662 * suppressed routes (if summary is configured).
7663 *
7664 * Must not be called in `bgp_aggregate_route`.
7665 */
7666 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7667 struct bgp *bgp, const struct prefix *p,
7668 afi_t afi, safi_t safi,
7669 struct bgp_path_info *pi)
7670 {
7671 /* MED matching disabled. */
7672 if (!aggregate->match_med)
7673 return;
7674
7675 /* Aggregation with different MED, recheck if we have got equal MEDs
7676 * now.
7677 */
7678 if (aggregate->med_mismatched &&
7679 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7680 aggregate->summary_only)
7681 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7682 true);
7683 else
7684 bgp_aggregate_med_match(aggregate, bgp, pi);
7685
7686 /* No mismatches, just quit. */
7687 if (!aggregate->med_mismatched)
7688 return;
7689
7690 /* Route summarization is disabled. */
7691 if (!aggregate->summary_only)
7692 return;
7693
7694 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7695 }
7696
7697 /* Update an aggregate as routes are added/removed from the BGP table */
7698 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7699 safi_t safi, struct bgp_aggregate *aggregate)
7700 {
7701 struct bgp_table *table;
7702 struct bgp_dest *top;
7703 struct bgp_dest *dest;
7704 uint8_t origin;
7705 struct aspath *aspath = NULL;
7706 struct community *community = NULL;
7707 struct ecommunity *ecommunity = NULL;
7708 struct lcommunity *lcommunity = NULL;
7709 struct bgp_path_info *pi;
7710 unsigned long match = 0;
7711 uint8_t atomic_aggregate = 0;
7712
7713 /* If the bgp instance is being deleted or self peer is deleted
7714 * then do not create aggregate route
7715 */
7716 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7717 || (bgp->peer_self == NULL))
7718 return;
7719
7720 /* Initialize and test routes for MED difference. */
7721 if (aggregate->match_med)
7722 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7723
7724 /*
7725 * Reset aggregate count: we might've been called from route map
7726 * update so in that case we must retest all more specific routes.
7727 *
7728 * \see `bgp_route_map_process_update`.
7729 */
7730 aggregate->count = 0;
7731 aggregate->incomplete_origin_count = 0;
7732 aggregate->incomplete_origin_count = 0;
7733 aggregate->egp_origin_count = 0;
7734
7735 /* ORIGIN attribute: If at least one route among routes that are
7736 aggregated has ORIGIN with the value INCOMPLETE, then the
7737 aggregated route must have the ORIGIN attribute with the value
7738 INCOMPLETE. Otherwise, if at least one route among routes that
7739 are aggregated has ORIGIN with the value EGP, then the aggregated
7740 route must have the origin attribute with the value EGP. In all
7741 other case the value of the ORIGIN attribute of the aggregated
7742 route is INTERNAL. */
7743 origin = BGP_ORIGIN_IGP;
7744
7745 table = bgp->rib[afi][safi];
7746
7747 top = bgp_node_get(table, p);
7748 for (dest = bgp_node_get(table, p); dest;
7749 dest = bgp_route_next_until(dest, top)) {
7750 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7751
7752 if (dest_p->prefixlen <= p->prefixlen)
7753 continue;
7754
7755 /* If suppress fib is enabled and route not installed
7756 * in FIB, skip the route
7757 */
7758 if (!bgp_check_advertise(bgp, dest))
7759 continue;
7760
7761 match = 0;
7762
7763 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7764 if (BGP_PATH_HOLDDOWN(pi))
7765 continue;
7766
7767 if (pi->attr->flag
7768 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7769 atomic_aggregate = 1;
7770
7771 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7772 continue;
7773
7774 /*
7775 * summary-only aggregate route suppress
7776 * aggregated route announcements.
7777 *
7778 * MED matching:
7779 * Don't create summaries if MED didn't match
7780 * otherwise neither the specific routes and the
7781 * aggregation will be announced.
7782 */
7783 if (aggregate->summary_only
7784 && AGGREGATE_MED_VALID(aggregate)) {
7785 if (aggr_suppress_path(aggregate, pi))
7786 match++;
7787 }
7788
7789 /*
7790 * Suppress more specific routes that match the route
7791 * map results.
7792 *
7793 * MED matching:
7794 * Don't suppress routes if MED matching is enabled and
7795 * it mismatched otherwise we might end up with no
7796 * routes for this path.
7797 */
7798 if (aggregate->suppress_map_name
7799 && AGGREGATE_MED_VALID(aggregate)
7800 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7801 if (aggr_suppress_path(aggregate, pi))
7802 match++;
7803 }
7804
7805 aggregate->count++;
7806
7807 /*
7808 * If at least one route among routes that are
7809 * aggregated has ORIGIN with the value INCOMPLETE,
7810 * then the aggregated route MUST have the ORIGIN
7811 * attribute with the value INCOMPLETE. Otherwise, if
7812 * at least one route among routes that are aggregated
7813 * has ORIGIN with the value EGP, then the aggregated
7814 * route MUST have the ORIGIN attribute with the value
7815 * EGP.
7816 */
7817 switch (pi->attr->origin) {
7818 case BGP_ORIGIN_INCOMPLETE:
7819 aggregate->incomplete_origin_count++;
7820 break;
7821 case BGP_ORIGIN_EGP:
7822 aggregate->egp_origin_count++;
7823 break;
7824 default:
7825 /*Do nothing.
7826 */
7827 break;
7828 }
7829
7830 if (!aggregate->as_set)
7831 continue;
7832
7833 /*
7834 * as-set aggregate route generate origin, as path,
7835 * and community aggregation.
7836 */
7837 /* Compute aggregate route's as-path.
7838 */
7839 bgp_compute_aggregate_aspath_hash(aggregate,
7840 pi->attr->aspath);
7841
7842 /* Compute aggregate route's community.
7843 */
7844 if (bgp_attr_get_community(pi->attr))
7845 bgp_compute_aggregate_community_hash(
7846 aggregate,
7847 bgp_attr_get_community(pi->attr));
7848
7849 /* Compute aggregate route's extended community.
7850 */
7851 if (bgp_attr_get_ecommunity(pi->attr))
7852 bgp_compute_aggregate_ecommunity_hash(
7853 aggregate,
7854 bgp_attr_get_ecommunity(pi->attr));
7855
7856 /* Compute aggregate route's large community.
7857 */
7858 if (bgp_attr_get_lcommunity(pi->attr))
7859 bgp_compute_aggregate_lcommunity_hash(
7860 aggregate,
7861 bgp_attr_get_lcommunity(pi->attr));
7862 }
7863 if (match)
7864 bgp_process(bgp, dest, afi, safi);
7865 }
7866 if (aggregate->as_set) {
7867 bgp_compute_aggregate_aspath_val(aggregate);
7868 bgp_compute_aggregate_community_val(aggregate);
7869 bgp_compute_aggregate_ecommunity_val(aggregate);
7870 bgp_compute_aggregate_lcommunity_val(aggregate);
7871 }
7872
7873
7874 bgp_dest_unlock_node(top);
7875
7876
7877 if (aggregate->incomplete_origin_count > 0)
7878 origin = BGP_ORIGIN_INCOMPLETE;
7879 else if (aggregate->egp_origin_count > 0)
7880 origin = BGP_ORIGIN_EGP;
7881
7882 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7883 origin = aggregate->origin;
7884
7885 if (aggregate->as_set) {
7886 if (aggregate->aspath)
7887 /* Retrieve aggregate route's as-path.
7888 */
7889 aspath = aspath_dup(aggregate->aspath);
7890
7891 if (aggregate->community)
7892 /* Retrieve aggregate route's community.
7893 */
7894 community = community_dup(aggregate->community);
7895
7896 if (aggregate->ecommunity)
7897 /* Retrieve aggregate route's ecommunity.
7898 */
7899 ecommunity = ecommunity_dup(aggregate->ecommunity);
7900
7901 if (aggregate->lcommunity)
7902 /* Retrieve aggregate route's lcommunity.
7903 */
7904 lcommunity = lcommunity_dup(aggregate->lcommunity);
7905 }
7906
7907 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7908 ecommunity, lcommunity, atomic_aggregate,
7909 aggregate);
7910 }
7911
7912 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7913 safi_t safi, struct bgp_aggregate *aggregate)
7914 {
7915 struct bgp_table *table;
7916 struct bgp_dest *top;
7917 struct bgp_dest *dest;
7918 struct bgp_path_info *pi;
7919 unsigned long match;
7920
7921 table = bgp->rib[afi][safi];
7922
7923 /* If routes exists below this node, generate aggregate routes. */
7924 top = bgp_node_get(table, p);
7925 for (dest = bgp_node_get(table, p); dest;
7926 dest = bgp_route_next_until(dest, top)) {
7927 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7928
7929 if (dest_p->prefixlen <= p->prefixlen)
7930 continue;
7931 match = 0;
7932
7933 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7934 if (BGP_PATH_HOLDDOWN(pi))
7935 continue;
7936
7937 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7938 continue;
7939
7940 /*
7941 * This route is suppressed: attempt to unsuppress it.
7942 *
7943 * `aggr_unsuppress_path` will fail if this particular
7944 * aggregate route was not the suppressor.
7945 */
7946 if (pi->extra && pi->extra->aggr_suppressors &&
7947 listcount(pi->extra->aggr_suppressors)) {
7948 if (aggr_unsuppress_path(aggregate, pi))
7949 match++;
7950 }
7951
7952 aggregate->count--;
7953
7954 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7955 aggregate->incomplete_origin_count--;
7956 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7957 aggregate->egp_origin_count--;
7958
7959 if (aggregate->as_set) {
7960 /* Remove as-path from aggregate.
7961 */
7962 bgp_remove_aspath_from_aggregate_hash(
7963 aggregate,
7964 pi->attr->aspath);
7965
7966 if (bgp_attr_get_community(pi->attr))
7967 /* Remove community from aggregate.
7968 */
7969 bgp_remove_comm_from_aggregate_hash(
7970 aggregate,
7971 bgp_attr_get_community(
7972 pi->attr));
7973
7974 if (bgp_attr_get_ecommunity(pi->attr))
7975 /* Remove ecommunity from aggregate.
7976 */
7977 bgp_remove_ecomm_from_aggregate_hash(
7978 aggregate,
7979 bgp_attr_get_ecommunity(
7980 pi->attr));
7981
7982 if (bgp_attr_get_lcommunity(pi->attr))
7983 /* Remove lcommunity from aggregate.
7984 */
7985 bgp_remove_lcomm_from_aggregate_hash(
7986 aggregate,
7987 bgp_attr_get_lcommunity(
7988 pi->attr));
7989 }
7990 }
7991
7992 /* If this node was suppressed, process the change. */
7993 if (match)
7994 bgp_process(bgp, dest, afi, safi);
7995 }
7996 if (aggregate->as_set) {
7997 aspath_free(aggregate->aspath);
7998 aggregate->aspath = NULL;
7999 if (aggregate->community)
8000 community_free(&aggregate->community);
8001 if (aggregate->ecommunity)
8002 ecommunity_free(&aggregate->ecommunity);
8003 if (aggregate->lcommunity)
8004 lcommunity_free(&aggregate->lcommunity);
8005 }
8006
8007 bgp_dest_unlock_node(top);
8008 }
8009
8010 static void bgp_add_route_to_aggregate(struct bgp *bgp,
8011 const struct prefix *aggr_p,
8012 struct bgp_path_info *pinew, afi_t afi,
8013 safi_t safi,
8014 struct bgp_aggregate *aggregate)
8015 {
8016 uint8_t origin;
8017 struct aspath *aspath = NULL;
8018 uint8_t atomic_aggregate = 0;
8019 struct community *community = NULL;
8020 struct ecommunity *ecommunity = NULL;
8021 struct lcommunity *lcommunity = NULL;
8022
8023 /* If the bgp instance is being deleted or self peer is deleted
8024 * then do not create aggregate route
8025 */
8026 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8027 || (bgp->peer_self == NULL))
8028 return;
8029
8030 /* ORIGIN attribute: If at least one route among routes that are
8031 * aggregated has ORIGIN with the value INCOMPLETE, then the
8032 * aggregated route must have the ORIGIN attribute with the value
8033 * INCOMPLETE. Otherwise, if at least one route among routes that
8034 * are aggregated has ORIGIN with the value EGP, then the aggregated
8035 * route must have the origin attribute with the value EGP. In all
8036 * other case the value of the ORIGIN attribute of the aggregated
8037 * route is INTERNAL.
8038 */
8039 origin = BGP_ORIGIN_IGP;
8040
8041 aggregate->count++;
8042
8043 /*
8044 * This must be called before `summary` check to avoid
8045 * "suppressing" twice.
8046 */
8047 if (aggregate->match_med)
8048 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
8049 pinew);
8050
8051 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8052 aggr_suppress_path(aggregate, pinew);
8053
8054 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8055 && aggr_suppress_map_test(bgp, aggregate, pinew))
8056 aggr_suppress_path(aggregate, pinew);
8057
8058 switch (pinew->attr->origin) {
8059 case BGP_ORIGIN_INCOMPLETE:
8060 aggregate->incomplete_origin_count++;
8061 break;
8062 case BGP_ORIGIN_EGP:
8063 aggregate->egp_origin_count++;
8064 break;
8065 default:
8066 /* Do nothing.
8067 */
8068 break;
8069 }
8070
8071 if (aggregate->incomplete_origin_count > 0)
8072 origin = BGP_ORIGIN_INCOMPLETE;
8073 else if (aggregate->egp_origin_count > 0)
8074 origin = BGP_ORIGIN_EGP;
8075
8076 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8077 origin = aggregate->origin;
8078
8079 if (aggregate->as_set) {
8080 /* Compute aggregate route's as-path.
8081 */
8082 bgp_compute_aggregate_aspath(aggregate,
8083 pinew->attr->aspath);
8084
8085 /* Compute aggregate route's community.
8086 */
8087 if (bgp_attr_get_community(pinew->attr))
8088 bgp_compute_aggregate_community(
8089 aggregate, bgp_attr_get_community(pinew->attr));
8090
8091 /* Compute aggregate route's extended community.
8092 */
8093 if (bgp_attr_get_ecommunity(pinew->attr))
8094 bgp_compute_aggregate_ecommunity(
8095 aggregate,
8096 bgp_attr_get_ecommunity(pinew->attr));
8097
8098 /* Compute aggregate route's large community.
8099 */
8100 if (bgp_attr_get_lcommunity(pinew->attr))
8101 bgp_compute_aggregate_lcommunity(
8102 aggregate,
8103 bgp_attr_get_lcommunity(pinew->attr));
8104
8105 /* Retrieve aggregate route's as-path.
8106 */
8107 if (aggregate->aspath)
8108 aspath = aspath_dup(aggregate->aspath);
8109
8110 /* Retrieve aggregate route's community.
8111 */
8112 if (aggregate->community)
8113 community = community_dup(aggregate->community);
8114
8115 /* Retrieve aggregate route's ecommunity.
8116 */
8117 if (aggregate->ecommunity)
8118 ecommunity = ecommunity_dup(aggregate->ecommunity);
8119
8120 /* Retrieve aggregate route's lcommunity.
8121 */
8122 if (aggregate->lcommunity)
8123 lcommunity = lcommunity_dup(aggregate->lcommunity);
8124 }
8125
8126 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8127 aspath, community, ecommunity,
8128 lcommunity, atomic_aggregate, aggregate);
8129 }
8130
8131 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
8132 safi_t safi,
8133 struct bgp_path_info *pi,
8134 struct bgp_aggregate *aggregate,
8135 const struct prefix *aggr_p)
8136 {
8137 uint8_t origin;
8138 struct aspath *aspath = NULL;
8139 uint8_t atomic_aggregate = 0;
8140 struct community *community = NULL;
8141 struct ecommunity *ecommunity = NULL;
8142 struct lcommunity *lcommunity = NULL;
8143 unsigned long match = 0;
8144
8145 /* If the bgp instance is being deleted or self peer is deleted
8146 * then do not create aggregate route
8147 */
8148 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8149 || (bgp->peer_self == NULL))
8150 return;
8151
8152 if (BGP_PATH_HOLDDOWN(pi))
8153 return;
8154
8155 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
8156 return;
8157
8158 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8159 if (aggr_unsuppress_path(aggregate, pi))
8160 match++;
8161
8162 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8163 && aggr_suppress_map_test(bgp, aggregate, pi))
8164 if (aggr_unsuppress_path(aggregate, pi))
8165 match++;
8166
8167 /*
8168 * This must be called after `summary`, `suppress-map` check to avoid
8169 * "unsuppressing" twice.
8170 */
8171 if (aggregate->match_med)
8172 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
8173
8174 if (aggregate->count > 0)
8175 aggregate->count--;
8176
8177 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
8178 aggregate->incomplete_origin_count--;
8179 else if (pi->attr->origin == BGP_ORIGIN_EGP)
8180 aggregate->egp_origin_count--;
8181
8182 if (aggregate->as_set) {
8183 /* Remove as-path from aggregate.
8184 */
8185 bgp_remove_aspath_from_aggregate(aggregate,
8186 pi->attr->aspath);
8187
8188 if (bgp_attr_get_community(pi->attr))
8189 /* Remove community from aggregate.
8190 */
8191 bgp_remove_community_from_aggregate(
8192 aggregate, bgp_attr_get_community(pi->attr));
8193
8194 if (bgp_attr_get_ecommunity(pi->attr))
8195 /* Remove ecommunity from aggregate.
8196 */
8197 bgp_remove_ecommunity_from_aggregate(
8198 aggregate, bgp_attr_get_ecommunity(pi->attr));
8199
8200 if (bgp_attr_get_lcommunity(pi->attr))
8201 /* Remove lcommunity from aggregate.
8202 */
8203 bgp_remove_lcommunity_from_aggregate(
8204 aggregate, bgp_attr_get_lcommunity(pi->attr));
8205 }
8206
8207 /* If this node was suppressed, process the change. */
8208 if (match)
8209 bgp_process(bgp, pi->net, afi, safi);
8210
8211 origin = BGP_ORIGIN_IGP;
8212 if (aggregate->incomplete_origin_count > 0)
8213 origin = BGP_ORIGIN_INCOMPLETE;
8214 else if (aggregate->egp_origin_count > 0)
8215 origin = BGP_ORIGIN_EGP;
8216
8217 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8218 origin = aggregate->origin;
8219
8220 if (aggregate->as_set) {
8221 /* Retrieve aggregate route's as-path.
8222 */
8223 if (aggregate->aspath)
8224 aspath = aspath_dup(aggregate->aspath);
8225
8226 /* Retrieve aggregate route's community.
8227 */
8228 if (aggregate->community)
8229 community = community_dup(aggregate->community);
8230
8231 /* Retrieve aggregate route's ecommunity.
8232 */
8233 if (aggregate->ecommunity)
8234 ecommunity = ecommunity_dup(aggregate->ecommunity);
8235
8236 /* Retrieve aggregate route's lcommunity.
8237 */
8238 if (aggregate->lcommunity)
8239 lcommunity = lcommunity_dup(aggregate->lcommunity);
8240 }
8241
8242 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8243 aspath, community, ecommunity,
8244 lcommunity, atomic_aggregate, aggregate);
8245 }
8246
8247 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8248 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8249 {
8250 struct bgp_dest *child;
8251 struct bgp_dest *dest;
8252 struct bgp_aggregate *aggregate;
8253 struct bgp_table *table;
8254
8255 table = bgp->aggregate[afi][safi];
8256
8257 /* No aggregates configured. */
8258 if (bgp_table_top_nolock(table) == NULL)
8259 return;
8260
8261 if (p->prefixlen == 0)
8262 return;
8263
8264 if (BGP_PATH_HOLDDOWN(pi))
8265 return;
8266
8267 /* If suppress fib is enabled and route not installed
8268 * in FIB, do not update the aggregate route
8269 */
8270 if (!bgp_check_advertise(bgp, pi->net))
8271 return;
8272
8273 child = bgp_node_get(table, p);
8274
8275 /* Aggregate address configuration check. */
8276 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8277 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8278
8279 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8280 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8281 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8282 aggregate);
8283 }
8284 }
8285 bgp_dest_unlock_node(child);
8286 }
8287
8288 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8289 struct bgp_path_info *del, afi_t afi, safi_t safi)
8290 {
8291 struct bgp_dest *child;
8292 struct bgp_dest *dest;
8293 struct bgp_aggregate *aggregate;
8294 struct bgp_table *table;
8295
8296 table = bgp->aggregate[afi][safi];
8297
8298 /* No aggregates configured. */
8299 if (bgp_table_top_nolock(table) == NULL)
8300 return;
8301
8302 if (p->prefixlen == 0)
8303 return;
8304
8305 child = bgp_node_get(table, p);
8306
8307 /* Aggregate address configuration check. */
8308 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8309 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8310
8311 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8312 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8313 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8314 aggregate, dest_p);
8315 }
8316 }
8317 bgp_dest_unlock_node(child);
8318 }
8319
8320 /* Aggregate route attribute. */
8321 #define AGGREGATE_SUMMARY_ONLY 1
8322 #define AGGREGATE_AS_SET 1
8323 #define AGGREGATE_AS_UNSET 0
8324
8325 static const char *bgp_origin2str(uint8_t origin)
8326 {
8327 switch (origin) {
8328 case BGP_ORIGIN_IGP:
8329 return "igp";
8330 case BGP_ORIGIN_EGP:
8331 return "egp";
8332 case BGP_ORIGIN_INCOMPLETE:
8333 return "incomplete";
8334 }
8335 return "n/a";
8336 }
8337
8338 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8339 {
8340 switch (v_state) {
8341 case RPKI_NOT_BEING_USED:
8342 return "not used";
8343 case RPKI_VALID:
8344 return "valid";
8345 case RPKI_NOTFOUND:
8346 return "not found";
8347 case RPKI_INVALID:
8348 return "invalid";
8349 }
8350
8351 assert(!"We should never get here this is a dev escape");
8352 return "ERROR";
8353 }
8354
8355 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8356 afi_t afi, safi_t safi)
8357 {
8358 VTY_DECLVAR_CONTEXT(bgp, bgp);
8359 int ret;
8360 struct prefix p;
8361 struct bgp_dest *dest;
8362 struct bgp_aggregate *aggregate;
8363
8364 /* Convert string to prefix structure. */
8365 ret = str2prefix(prefix_str, &p);
8366 if (!ret) {
8367 vty_out(vty, "Malformed prefix\n");
8368 return CMD_WARNING_CONFIG_FAILED;
8369 }
8370 apply_mask(&p);
8371
8372 /* Old configuration check. */
8373 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8374 if (!dest) {
8375 vty_out(vty,
8376 "%% There is no aggregate-address configuration.\n");
8377 return CMD_WARNING_CONFIG_FAILED;
8378 }
8379
8380 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8381 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8382 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8383 NULL, NULL, 0, aggregate);
8384
8385 /* Unlock aggregate address configuration. */
8386 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8387
8388 if (aggregate->community)
8389 community_free(&aggregate->community);
8390
8391 if (aggregate->community_hash) {
8392 /* Delete all communities in the hash.
8393 */
8394 hash_clean(aggregate->community_hash,
8395 bgp_aggr_community_remove);
8396 /* Free up the community_hash.
8397 */
8398 hash_free(aggregate->community_hash);
8399 }
8400
8401 if (aggregate->ecommunity)
8402 ecommunity_free(&aggregate->ecommunity);
8403
8404 if (aggregate->ecommunity_hash) {
8405 /* Delete all ecommunities in the hash.
8406 */
8407 hash_clean(aggregate->ecommunity_hash,
8408 bgp_aggr_ecommunity_remove);
8409 /* Free up the ecommunity_hash.
8410 */
8411 hash_free(aggregate->ecommunity_hash);
8412 }
8413
8414 if (aggregate->lcommunity)
8415 lcommunity_free(&aggregate->lcommunity);
8416
8417 if (aggregate->lcommunity_hash) {
8418 /* Delete all lcommunities in the hash.
8419 */
8420 hash_clean(aggregate->lcommunity_hash,
8421 bgp_aggr_lcommunity_remove);
8422 /* Free up the lcommunity_hash.
8423 */
8424 hash_free(aggregate->lcommunity_hash);
8425 }
8426
8427 if (aggregate->aspath)
8428 aspath_free(aggregate->aspath);
8429
8430 if (aggregate->aspath_hash) {
8431 /* Delete all as-paths in the hash.
8432 */
8433 hash_clean(aggregate->aspath_hash,
8434 bgp_aggr_aspath_remove);
8435 /* Free up the aspath_hash.
8436 */
8437 hash_free(aggregate->aspath_hash);
8438 }
8439
8440 bgp_aggregate_free(aggregate);
8441 bgp_dest_unlock_node(dest);
8442 bgp_dest_unlock_node(dest);
8443
8444 return CMD_SUCCESS;
8445 }
8446
8447 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8448 safi_t safi, const char *rmap,
8449 uint8_t summary_only, uint8_t as_set,
8450 uint8_t origin, bool match_med,
8451 const char *suppress_map)
8452 {
8453 VTY_DECLVAR_CONTEXT(bgp, bgp);
8454 int ret;
8455 struct prefix p;
8456 struct bgp_dest *dest;
8457 struct bgp_aggregate *aggregate;
8458 uint8_t as_set_new = as_set;
8459
8460 if (suppress_map && summary_only) {
8461 vty_out(vty,
8462 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8463 return CMD_WARNING_CONFIG_FAILED;
8464 }
8465
8466 /* Convert string to prefix structure. */
8467 ret = str2prefix(prefix_str, &p);
8468 if (!ret) {
8469 vty_out(vty, "Malformed prefix\n");
8470 return CMD_WARNING_CONFIG_FAILED;
8471 }
8472 apply_mask(&p);
8473
8474 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8475 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8476 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8477 prefix_str);
8478 return CMD_WARNING_CONFIG_FAILED;
8479 }
8480
8481 /* Old configuration check. */
8482 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8483 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8484
8485 if (aggregate) {
8486 vty_out(vty, "There is already same aggregate network.\n");
8487 /* try to remove the old entry */
8488 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8489 if (ret) {
8490 vty_out(vty, "Error deleting aggregate.\n");
8491 bgp_dest_unlock_node(dest);
8492 return CMD_WARNING_CONFIG_FAILED;
8493 }
8494 }
8495
8496 /* Make aggregate address structure. */
8497 aggregate = bgp_aggregate_new();
8498 aggregate->summary_only = summary_only;
8499 aggregate->match_med = match_med;
8500
8501 /* Network operators MUST NOT locally generate any new
8502 * announcements containing AS_SET or AS_CONFED_SET. If they have
8503 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8504 * SHOULD withdraw those routes and re-announce routes for the
8505 * aggregate or component prefixes (i.e., the more-specific routes
8506 * subsumed by the previously aggregated route) without AS_SET
8507 * or AS_CONFED_SET in the updates.
8508 */
8509 if (bgp->reject_as_sets) {
8510 if (as_set == AGGREGATE_AS_SET) {
8511 as_set_new = AGGREGATE_AS_UNSET;
8512 zlog_warn(
8513 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8514 __func__);
8515 vty_out(vty,
8516 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8517 }
8518 }
8519
8520 aggregate->as_set = as_set_new;
8521 aggregate->safi = safi;
8522 /* Override ORIGIN attribute if defined.
8523 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8524 * to IGP which is not what rfc4271 says.
8525 * This enables the same behavior, optionally.
8526 */
8527 aggregate->origin = origin;
8528
8529 if (rmap) {
8530 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8531 route_map_counter_decrement(aggregate->rmap.map);
8532 aggregate->rmap.name =
8533 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8534 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8535 route_map_counter_increment(aggregate->rmap.map);
8536 }
8537
8538 if (suppress_map) {
8539 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8540 route_map_counter_decrement(aggregate->suppress_map);
8541
8542 aggregate->suppress_map_name =
8543 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8544 aggregate->suppress_map =
8545 route_map_lookup_by_name(aggregate->suppress_map_name);
8546 route_map_counter_increment(aggregate->suppress_map);
8547 }
8548
8549 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8550
8551 /* Aggregate address insert into BGP routing table. */
8552 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
8553
8554 return CMD_SUCCESS;
8555 }
8556
8557 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8558 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8559 "as-set$as_set_s"
8560 "|summary-only$summary_only"
8561 "|route-map RMAP_NAME$rmap_name"
8562 "|origin <egp|igp|incomplete>$origin_s"
8563 "|matching-MED-only$match_med"
8564 "|suppress-map RMAP_NAME$suppress_map"
8565 "}]",
8566 NO_STR
8567 "Configure BGP aggregate entries\n"
8568 "Aggregate prefix\n"
8569 "Aggregate address\n"
8570 "Aggregate mask\n"
8571 "Generate AS set path information\n"
8572 "Filter more specific routes from updates\n"
8573 "Apply route map to aggregate network\n"
8574 "Route map name\n"
8575 "BGP origin code\n"
8576 "Remote EGP\n"
8577 "Local IGP\n"
8578 "Unknown heritage\n"
8579 "Only aggregate routes with matching MED\n"
8580 "Suppress the selected more specific routes\n"
8581 "Route map with the route selectors\n")
8582 {
8583 const char *prefix_s = NULL;
8584 safi_t safi = bgp_node_safi(vty);
8585 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8586 int as_set = AGGREGATE_AS_UNSET;
8587 char prefix_buf[PREFIX2STR_BUFFER];
8588
8589 if (addr_str) {
8590 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8591 sizeof(prefix_buf))
8592 == 0) {
8593 vty_out(vty, "%% Inconsistent address and mask\n");
8594 return CMD_WARNING_CONFIG_FAILED;
8595 }
8596 prefix_s = prefix_buf;
8597 } else
8598 prefix_s = prefix_str;
8599
8600 if (origin_s) {
8601 if (strcmp(origin_s, "egp") == 0)
8602 origin = BGP_ORIGIN_EGP;
8603 else if (strcmp(origin_s, "igp") == 0)
8604 origin = BGP_ORIGIN_IGP;
8605 else if (strcmp(origin_s, "incomplete") == 0)
8606 origin = BGP_ORIGIN_INCOMPLETE;
8607 }
8608
8609 if (as_set_s)
8610 as_set = AGGREGATE_AS_SET;
8611
8612 /* Handle configuration removal, otherwise installation. */
8613 if (no)
8614 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8615
8616 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8617 summary_only != NULL, as_set, origin,
8618 match_med != NULL, suppress_map);
8619 }
8620
8621 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8622 "[no] aggregate-address X:X::X:X/M$prefix [{"
8623 "as-set$as_set_s"
8624 "|summary-only$summary_only"
8625 "|route-map RMAP_NAME$rmap_name"
8626 "|origin <egp|igp|incomplete>$origin_s"
8627 "|matching-MED-only$match_med"
8628 "|suppress-map RMAP_NAME$suppress_map"
8629 "}]",
8630 NO_STR
8631 "Configure BGP aggregate entries\n"
8632 "Aggregate prefix\n"
8633 "Generate AS set path information\n"
8634 "Filter more specific routes from updates\n"
8635 "Apply route map to aggregate network\n"
8636 "Route map name\n"
8637 "BGP origin code\n"
8638 "Remote EGP\n"
8639 "Local IGP\n"
8640 "Unknown heritage\n"
8641 "Only aggregate routes with matching MED\n"
8642 "Suppress the selected more specific routes\n"
8643 "Route map with the route selectors\n")
8644 {
8645 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8646 int as_set = AGGREGATE_AS_UNSET;
8647
8648 if (origin_s) {
8649 if (strcmp(origin_s, "egp") == 0)
8650 origin = BGP_ORIGIN_EGP;
8651 else if (strcmp(origin_s, "igp") == 0)
8652 origin = BGP_ORIGIN_IGP;
8653 else if (strcmp(origin_s, "incomplete") == 0)
8654 origin = BGP_ORIGIN_INCOMPLETE;
8655 }
8656
8657 if (as_set_s)
8658 as_set = AGGREGATE_AS_SET;
8659
8660 /* Handle configuration removal, otherwise installation. */
8661 if (no)
8662 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8663 SAFI_UNICAST);
8664
8665 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8666 rmap_name, summary_only != NULL, as_set,
8667 origin, match_med != NULL, suppress_map);
8668 }
8669
8670 /* Redistribute route treatment. */
8671 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8672 const union g_addr *nexthop, ifindex_t ifindex,
8673 enum nexthop_types_t nhtype, uint8_t distance,
8674 enum blackhole_type bhtype, uint32_t metric,
8675 uint8_t type, unsigned short instance,
8676 route_tag_t tag)
8677 {
8678 struct bgp_path_info *new;
8679 struct bgp_path_info *bpi;
8680 struct bgp_path_info rmap_path;
8681 struct bgp_dest *bn;
8682 struct attr attr;
8683 struct attr *new_attr;
8684 afi_t afi;
8685 route_map_result_t ret;
8686 struct bgp_redist *red;
8687 struct interface *ifp;
8688
8689 /* Make default attribute. */
8690 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8691 /*
8692 * This must not be NULL to satisfy Coverity SA
8693 */
8694 assert(attr.aspath);
8695
8696 switch (nhtype) {
8697 case NEXTHOP_TYPE_IFINDEX:
8698 switch (p->family) {
8699 case AF_INET:
8700 attr.nexthop.s_addr = INADDR_ANY;
8701 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8702 break;
8703 case AF_INET6:
8704 memset(&attr.mp_nexthop_global, 0,
8705 sizeof(attr.mp_nexthop_global));
8706 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8707 break;
8708 }
8709 break;
8710 case NEXTHOP_TYPE_IPV4:
8711 case NEXTHOP_TYPE_IPV4_IFINDEX:
8712 attr.nexthop = nexthop->ipv4;
8713 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8714 break;
8715 case NEXTHOP_TYPE_IPV6:
8716 case NEXTHOP_TYPE_IPV6_IFINDEX:
8717 attr.mp_nexthop_global = nexthop->ipv6;
8718 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8719 break;
8720 case NEXTHOP_TYPE_BLACKHOLE:
8721 switch (p->family) {
8722 case AF_INET:
8723 attr.nexthop.s_addr = INADDR_ANY;
8724 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8725 break;
8726 case AF_INET6:
8727 memset(&attr.mp_nexthop_global, 0,
8728 sizeof(attr.mp_nexthop_global));
8729 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8730 break;
8731 }
8732 attr.bh_type = bhtype;
8733 break;
8734 }
8735 attr.nh_type = nhtype;
8736 attr.nh_ifindex = ifindex;
8737 ifp = if_lookup_by_index(ifindex, bgp->vrf_id);
8738 if (ifp && if_is_operative(ifp))
8739 SET_FLAG(attr.nh_flag, BGP_ATTR_NH_IF_OPERSTATE);
8740 else
8741 UNSET_FLAG(attr.nh_flag, BGP_ATTR_NH_IF_OPERSTATE);
8742
8743 attr.med = metric;
8744 attr.distance = distance;
8745 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8746 attr.tag = tag;
8747
8748 if (metric)
8749 bgp_attr_set_aigp_metric(&attr, metric);
8750
8751 afi = family2afi(p->family);
8752
8753 red = bgp_redist_lookup(bgp, afi, type, instance);
8754 if (red) {
8755 struct attr attr_new;
8756
8757 /* Copy attribute for modification. */
8758 attr_new = attr;
8759
8760 if (red->redist_metric_flag) {
8761 attr_new.med = red->redist_metric;
8762 bgp_attr_set_aigp_metric(&attr_new, red->redist_metric);
8763 }
8764
8765 /* Apply route-map. */
8766 if (red->rmap.name) {
8767 memset(&rmap_path, 0, sizeof(rmap_path));
8768 rmap_path.peer = bgp->peer_self;
8769 rmap_path.attr = &attr_new;
8770
8771 SET_FLAG(bgp->peer_self->rmap_type,
8772 PEER_RMAP_TYPE_REDISTRIBUTE);
8773
8774 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8775
8776 bgp->peer_self->rmap_type = 0;
8777
8778 if (ret == RMAP_DENYMATCH) {
8779 /* Free uninterned attribute. */
8780 bgp_attr_flush(&attr_new);
8781
8782 /* Unintern original. */
8783 aspath_unintern(&attr.aspath);
8784 bgp_redistribute_delete(bgp, p, type, instance);
8785 return;
8786 }
8787 }
8788
8789 if (bgp_in_graceful_shutdown(bgp))
8790 bgp_attr_add_gshut_community(&attr_new);
8791
8792 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8793 SAFI_UNICAST, p, NULL);
8794
8795 new_attr = bgp_attr_intern(&attr_new);
8796
8797 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8798 if (bpi->peer == bgp->peer_self
8799 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8800 break;
8801
8802 if (bpi) {
8803 /* Ensure the (source route) type is updated. */
8804 bpi->type = type;
8805 if (attrhash_cmp(bpi->attr, new_attr)
8806 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8807 bgp_attr_unintern(&new_attr);
8808 aspath_unintern(&attr.aspath);
8809 bgp_dest_unlock_node(bn);
8810 return;
8811 } else {
8812 /* The attribute is changed. */
8813 bgp_path_info_set_flag(bn, bpi,
8814 BGP_PATH_ATTR_CHANGED);
8815
8816 /* Rewrite BGP route information. */
8817 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8818 bgp_path_info_restore(bn, bpi);
8819 else
8820 bgp_aggregate_decrement(
8821 bgp, p, bpi, afi, SAFI_UNICAST);
8822 bgp_attr_unintern(&bpi->attr);
8823 bpi->attr = new_attr;
8824 bpi->uptime = monotime(NULL);
8825
8826 /* Process change. */
8827 bgp_aggregate_increment(bgp, p, bpi, afi,
8828 SAFI_UNICAST);
8829 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8830 bgp_dest_unlock_node(bn);
8831 aspath_unintern(&attr.aspath);
8832
8833 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8834 || (bgp->inst_type
8835 == BGP_INSTANCE_TYPE_DEFAULT)) {
8836
8837 vpn_leak_from_vrf_update(
8838 bgp_get_default(), bgp, bpi);
8839 }
8840 return;
8841 }
8842 }
8843
8844 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8845 bgp->peer_self, new_attr, bn);
8846 SET_FLAG(new->flags, BGP_PATH_VALID);
8847
8848 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8849 bgp_path_info_add(bn, new);
8850 bgp_dest_unlock_node(bn);
8851 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8852 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8853
8854 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8855 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8856
8857 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8858 }
8859 }
8860
8861 /* Unintern original. */
8862 aspath_unintern(&attr.aspath);
8863 }
8864
8865 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8866 unsigned short instance)
8867 {
8868 afi_t afi;
8869 struct bgp_dest *dest;
8870 struct bgp_path_info *pi;
8871 struct bgp_redist *red;
8872
8873 afi = family2afi(p->family);
8874
8875 red = bgp_redist_lookup(bgp, afi, type, instance);
8876 if (red) {
8877 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8878 SAFI_UNICAST, p, NULL);
8879
8880 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8881 if (pi->peer == bgp->peer_self && pi->type == type)
8882 break;
8883
8884 if (pi) {
8885 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8886 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8887
8888 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8889 bgp, pi);
8890 }
8891 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8892 bgp_path_info_delete(dest, pi);
8893 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8894 }
8895 bgp_dest_unlock_node(dest);
8896 }
8897 }
8898
8899 /* Withdraw specified route type's route. */
8900 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8901 unsigned short instance)
8902 {
8903 struct bgp_dest *dest;
8904 struct bgp_path_info *pi;
8905 struct bgp_table *table;
8906
8907 table = bgp->rib[afi][SAFI_UNICAST];
8908
8909 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8910 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8911 if (pi->peer == bgp->peer_self && pi->type == type
8912 && pi->instance == instance)
8913 break;
8914
8915 if (pi) {
8916 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8917 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8918
8919 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8920 bgp, pi);
8921 }
8922 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8923 pi, afi, SAFI_UNICAST);
8924 bgp_path_info_delete(dest, pi);
8925 if (!CHECK_FLAG(bgp->flags,
8926 BGP_FLAG_DELETE_IN_PROGRESS))
8927 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8928 else
8929 bgp_path_info_reap(dest, pi);
8930 }
8931 }
8932 }
8933
8934 /* Static function to display route. */
8935 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8936 struct vty *vty, json_object *json, bool wide)
8937 {
8938 int len = 0;
8939 char buf[INET6_ADDRSTRLEN];
8940
8941 if (p->family == AF_INET) {
8942 if (!json) {
8943 len = vty_out(vty, "%pFX", p);
8944 } else {
8945 json_object_string_add(json, "prefix",
8946 inet_ntop(p->family,
8947 &p->u.prefix, buf,
8948 sizeof(buf)));
8949 json_object_int_add(json, "prefixLen", p->prefixlen);
8950 json_object_string_addf(json, "network", "%pFX", p);
8951 json_object_int_add(json, "version", dest->version);
8952 }
8953 } else if (p->family == AF_ETHERNET) {
8954 len = vty_out(vty, "%pFX", p);
8955 } else if (p->family == AF_EVPN) {
8956 if (!json)
8957 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8958 else
8959 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8960 } else if (p->family == AF_FLOWSPEC) {
8961 route_vty_out_flowspec(vty, p, NULL,
8962 json ?
8963 NLRI_STRING_FORMAT_JSON_SIMPLE :
8964 NLRI_STRING_FORMAT_MIN, json);
8965 } else {
8966 if (!json)
8967 len = vty_out(vty, "%pFX", p);
8968 else {
8969 json_object_string_add(json, "prefix",
8970 inet_ntop(p->family,
8971 &p->u.prefix, buf,
8972 sizeof(buf)));
8973 json_object_int_add(json, "prefixLen", p->prefixlen);
8974 json_object_string_addf(json, "network", "%pFX", p);
8975 json_object_int_add(json, "version", dest->version);
8976 }
8977 }
8978
8979 if (!json) {
8980 len = wide ? (45 - len) : (17 - len);
8981 if (len < 1)
8982 vty_out(vty, "\n%*s", 20, " ");
8983 else
8984 vty_out(vty, "%*s", len, " ");
8985 }
8986 }
8987
8988 enum bgp_display_type {
8989 normal_list,
8990 };
8991
8992 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8993 {
8994 switch (reason) {
8995 case bgp_path_selection_none:
8996 return "Nothing to Select";
8997 case bgp_path_selection_first:
8998 return "First path received";
8999 case bgp_path_selection_evpn_sticky_mac:
9000 return "EVPN Sticky Mac";
9001 case bgp_path_selection_evpn_seq:
9002 return "EVPN sequence number";
9003 case bgp_path_selection_evpn_lower_ip:
9004 return "EVPN lower IP";
9005 case bgp_path_selection_evpn_local_path:
9006 return "EVPN local ES path";
9007 case bgp_path_selection_evpn_non_proxy:
9008 return "EVPN non proxy";
9009 case bgp_path_selection_weight:
9010 return "Weight";
9011 case bgp_path_selection_local_pref:
9012 return "Local Pref";
9013 case bgp_path_selection_accept_own:
9014 return "Accept Own";
9015 case bgp_path_selection_local_route:
9016 return "Local Route";
9017 case bgp_path_selection_aigp:
9018 return "AIGP";
9019 case bgp_path_selection_confed_as_path:
9020 return "Confederation based AS Path";
9021 case bgp_path_selection_as_path:
9022 return "AS Path";
9023 case bgp_path_selection_origin:
9024 return "Origin";
9025 case bgp_path_selection_med:
9026 return "MED";
9027 case bgp_path_selection_peer:
9028 return "Peer Type";
9029 case bgp_path_selection_confed:
9030 return "Confed Peer Type";
9031 case bgp_path_selection_igp_metric:
9032 return "IGP Metric";
9033 case bgp_path_selection_older:
9034 return "Older Path";
9035 case bgp_path_selection_router_id:
9036 return "Router ID";
9037 case bgp_path_selection_cluster_length:
9038 return "Cluster length";
9039 case bgp_path_selection_stale:
9040 return "Path Staleness";
9041 case bgp_path_selection_local_configured:
9042 return "Locally configured route";
9043 case bgp_path_selection_neighbor_ip:
9044 return "Neighbor IP";
9045 case bgp_path_selection_default:
9046 return "Nothing left to compare";
9047 }
9048 return "Invalid (internal error)";
9049 }
9050
9051 /* Print the short form route status for a bgp_path_info */
9052 static void route_vty_short_status_out(struct vty *vty,
9053 struct bgp_path_info *path,
9054 const struct prefix *p,
9055 json_object *json_path)
9056 {
9057 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
9058
9059 if (json_path) {
9060
9061 /* Route status display. */
9062 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9063 json_object_boolean_true_add(json_path, "removed");
9064
9065 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9066 json_object_boolean_true_add(json_path, "stale");
9067
9068 if (path->extra && bgp_path_suppressed(path))
9069 json_object_boolean_true_add(json_path, "suppressed");
9070
9071 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9072 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9073 json_object_boolean_true_add(json_path, "valid");
9074
9075 /* Selected */
9076 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9077 json_object_boolean_true_add(json_path, "history");
9078
9079 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9080 json_object_boolean_true_add(json_path, "damped");
9081
9082 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9083 json_object_boolean_true_add(json_path, "bestpath");
9084 json_object_string_add(json_path, "selectionReason",
9085 bgp_path_selection_reason2str(
9086 path->net->reason));
9087 }
9088
9089 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9090 json_object_boolean_true_add(json_path, "multipath");
9091
9092 /* Internal route. */
9093 if ((path->peer->as)
9094 && (path->peer->as == path->peer->local_as))
9095 json_object_string_add(json_path, "pathFrom",
9096 "internal");
9097 else
9098 json_object_string_add(json_path, "pathFrom",
9099 "external");
9100
9101 return;
9102 }
9103
9104 /* RPKI validation state */
9105 rpki_state =
9106 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9107
9108 if (rpki_state == RPKI_VALID)
9109 vty_out(vty, "V");
9110 else if (rpki_state == RPKI_INVALID)
9111 vty_out(vty, "I");
9112 else if (rpki_state == RPKI_NOTFOUND)
9113 vty_out(vty, "N");
9114 else
9115 vty_out(vty, " ");
9116
9117 /* Route status display. */
9118 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9119 vty_out(vty, "R");
9120 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9121 vty_out(vty, "S");
9122 else if (bgp_path_suppressed(path))
9123 vty_out(vty, "s");
9124 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9125 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9126 vty_out(vty, "*");
9127 else
9128 vty_out(vty, " ");
9129
9130 /* Selected */
9131 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9132 vty_out(vty, "h");
9133 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9134 vty_out(vty, "d");
9135 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9136 vty_out(vty, ">");
9137 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9138 vty_out(vty, "=");
9139 else
9140 vty_out(vty, " ");
9141
9142 /* Internal route. */
9143 if (path->peer && (path->peer->as)
9144 && (path->peer->as == path->peer->local_as))
9145 vty_out(vty, "i");
9146 else
9147 vty_out(vty, " ");
9148 }
9149
9150 static char *bgp_nexthop_hostname(struct peer *peer,
9151 struct bgp_nexthop_cache *bnc)
9152 {
9153 if (peer->hostname
9154 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9155 return peer->hostname;
9156 return NULL;
9157 }
9158
9159 /* called from terminal list command */
9160 void route_vty_out(struct vty *vty, const struct prefix *p,
9161 struct bgp_path_info *path, int display, safi_t safi,
9162 json_object *json_paths, bool wide)
9163 {
9164 int len;
9165 struct attr *attr = path->attr;
9166 json_object *json_path = NULL;
9167 json_object *json_nexthops = NULL;
9168 json_object *json_nexthop_global = NULL;
9169 json_object *json_nexthop_ll = NULL;
9170 json_object *json_ext_community = NULL;
9171 char vrf_id_str[VRF_NAMSIZ] = {0};
9172 bool nexthop_self =
9173 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9174 bool nexthop_othervrf = false;
9175 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9176 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9177 char *nexthop_hostname =
9178 bgp_nexthop_hostname(path->peer, path->nexthop);
9179 char esi_buf[ESI_STR_LEN];
9180
9181 if (json_paths)
9182 json_path = json_object_new_object();
9183
9184 /* short status lead text */
9185 route_vty_short_status_out(vty, path, p, json_path);
9186
9187 if (!json_paths) {
9188 /* print prefix and mask */
9189 if (!display)
9190 route_vty_out_route(path->net, p, vty, json_path, wide);
9191 else
9192 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9193 } else {
9194 route_vty_out_route(path->net, p, vty, json_path, wide);
9195 }
9196
9197 /*
9198 * If vrf id of nexthop is different from that of prefix,
9199 * set up printable string to append
9200 */
9201 if (path->extra && path->extra->bgp_orig) {
9202 const char *self = "";
9203
9204 if (nexthop_self)
9205 self = "<";
9206
9207 nexthop_othervrf = true;
9208 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9209
9210 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9211 snprintf(vrf_id_str, sizeof(vrf_id_str),
9212 "@%s%s", VRFID_NONE_STR, self);
9213 else
9214 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9215 path->extra->bgp_orig->vrf_id, self);
9216
9217 if (path->extra->bgp_orig->inst_type
9218 != BGP_INSTANCE_TYPE_DEFAULT)
9219
9220 nexthop_vrfname = path->extra->bgp_orig->name;
9221 } else {
9222 const char *self = "";
9223
9224 if (nexthop_self)
9225 self = "<";
9226
9227 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9228 }
9229
9230 /*
9231 * For ENCAP and EVPN routes, nexthop address family is not
9232 * neccessarily the same as the prefix address family.
9233 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9234 * EVPN routes are also exchanged with a MP nexthop. Currently,
9235 * this
9236 * is only IPv4, the value will be present in either
9237 * attr->nexthop or
9238 * attr->mp_nexthop_global_in
9239 */
9240 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9241 char nexthop[128];
9242 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9243
9244 switch (af) {
9245 case AF_INET:
9246 snprintfrr(nexthop, sizeof(nexthop), "%pI4",
9247 &attr->mp_nexthop_global_in);
9248 break;
9249 case AF_INET6:
9250 snprintfrr(nexthop, sizeof(nexthop), "%pI6",
9251 &attr->mp_nexthop_global);
9252 break;
9253 default:
9254 snprintf(nexthop, sizeof(nexthop), "?");
9255 break;
9256 }
9257
9258 if (json_paths) {
9259 json_nexthop_global = json_object_new_object();
9260
9261 json_object_string_add(json_nexthop_global, "ip",
9262 nexthop);
9263
9264 if (path->peer->hostname)
9265 json_object_string_add(json_nexthop_global,
9266 "hostname",
9267 path->peer->hostname);
9268
9269 json_object_string_add(json_nexthop_global, "afi",
9270 (af == AF_INET) ? "ipv4"
9271 : "ipv6");
9272 json_object_boolean_true_add(json_nexthop_global,
9273 "used");
9274 } else {
9275 if (nexthop_hostname)
9276 len = vty_out(vty, "%s(%s)%s", nexthop,
9277 nexthop_hostname, vrf_id_str);
9278 else
9279 len = vty_out(vty, "%s%s", nexthop, 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 } else if (safi == SAFI_EVPN) {
9288 if (json_paths) {
9289 json_nexthop_global = json_object_new_object();
9290
9291 json_object_string_addf(json_nexthop_global, "ip",
9292 "%pI4",
9293 &attr->mp_nexthop_global_in);
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",
9307 &attr->mp_nexthop_global_in,
9308 nexthop_hostname, vrf_id_str);
9309 else
9310 len = vty_out(vty, "%pI4%s",
9311 &attr->mp_nexthop_global_in,
9312 vrf_id_str);
9313
9314 len = wide ? (41 - len) : (16 - len);
9315 if (len < 1)
9316 vty_out(vty, "\n%*s", 36, " ");
9317 else
9318 vty_out(vty, "%*s", len, " ");
9319 }
9320 } else if (safi == SAFI_FLOWSPEC) {
9321 if (attr->nexthop.s_addr != INADDR_ANY) {
9322 if (json_paths) {
9323 json_nexthop_global = json_object_new_object();
9324
9325 json_object_string_add(json_nexthop_global,
9326 "afi", "ipv4");
9327 json_object_string_addf(json_nexthop_global,
9328 "ip", "%pI4",
9329 &attr->nexthop);
9330
9331 if (path->peer->hostname)
9332 json_object_string_add(
9333 json_nexthop_global, "hostname",
9334 path->peer->hostname);
9335
9336 json_object_boolean_true_add(
9337 json_nexthop_global,
9338 "used");
9339 } else {
9340 if (nexthop_hostname)
9341 len = vty_out(vty, "%pI4(%s)%s",
9342 &attr->nexthop,
9343 nexthop_hostname,
9344 vrf_id_str);
9345 else
9346 len = vty_out(vty, "%pI4%s",
9347 &attr->nexthop,
9348 vrf_id_str);
9349
9350 len = wide ? (41 - len) : (16 - len);
9351 if (len < 1)
9352 vty_out(vty, "\n%*s", 36, " ");
9353 else
9354 vty_out(vty, "%*s", len, " ");
9355 }
9356 }
9357 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9358 if (json_paths) {
9359 json_nexthop_global = json_object_new_object();
9360
9361 json_object_string_addf(json_nexthop_global, "ip",
9362 "%pI4", &attr->nexthop);
9363
9364 if (path->peer->hostname)
9365 json_object_string_add(json_nexthop_global,
9366 "hostname",
9367 path->peer->hostname);
9368
9369 json_object_string_add(json_nexthop_global, "afi",
9370 "ipv4");
9371 json_object_boolean_true_add(json_nexthop_global,
9372 "used");
9373 } else {
9374 if (nexthop_hostname)
9375 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9376 nexthop_hostname, vrf_id_str);
9377 else
9378 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9379 vrf_id_str);
9380
9381 len = wide ? (41 - len) : (16 - len);
9382 if (len < 1)
9383 vty_out(vty, "\n%*s", 36, " ");
9384 else
9385 vty_out(vty, "%*s", len, " ");
9386 }
9387 }
9388
9389 /* IPv6 Next Hop */
9390 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9391 if (json_paths) {
9392 json_nexthop_global = json_object_new_object();
9393 json_object_string_addf(json_nexthop_global, "ip",
9394 "%pI6",
9395 &attr->mp_nexthop_global);
9396
9397 if (path->peer->hostname)
9398 json_object_string_add(json_nexthop_global,
9399 "hostname",
9400 path->peer->hostname);
9401
9402 json_object_string_add(json_nexthop_global, "afi",
9403 "ipv6");
9404 json_object_string_add(json_nexthop_global, "scope",
9405 "global");
9406
9407 /* We display both LL & GL if both have been
9408 * received */
9409 if ((attr->mp_nexthop_len
9410 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9411 || (path->peer->conf_if)) {
9412 json_nexthop_ll = json_object_new_object();
9413 json_object_string_addf(
9414 json_nexthop_ll, "ip", "%pI6",
9415 &attr->mp_nexthop_local);
9416
9417 if (path->peer->hostname)
9418 json_object_string_add(
9419 json_nexthop_ll, "hostname",
9420 path->peer->hostname);
9421
9422 json_object_string_add(json_nexthop_ll, "afi",
9423 "ipv6");
9424 json_object_string_add(json_nexthop_ll, "scope",
9425 "link-local");
9426
9427 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9428 &attr->mp_nexthop_local) !=
9429 0) &&
9430 !CHECK_FLAG(attr->nh_flag,
9431 BGP_ATTR_NH_MP_PREFER_GLOBAL))
9432 json_object_boolean_true_add(
9433 json_nexthop_ll, "used");
9434 else
9435 json_object_boolean_true_add(
9436 json_nexthop_global, "used");
9437 } else
9438 json_object_boolean_true_add(
9439 json_nexthop_global, "used");
9440 } else {
9441 /* Display LL if LL/Global both in table unless
9442 * prefer-global is set */
9443 if (((attr->mp_nexthop_len ==
9444 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) &&
9445 !CHECK_FLAG(attr->nh_flag,
9446 BGP_ATTR_NH_MP_PREFER_GLOBAL)) ||
9447 (path->peer->conf_if)) {
9448 if (path->peer->conf_if) {
9449 len = vty_out(vty, "%s",
9450 path->peer->conf_if);
9451 /* len of IPv6 addr + max len of def
9452 * ifname */
9453 len = wide ? (41 - len) : (16 - len);
9454
9455 if (len < 1)
9456 vty_out(vty, "\n%*s", 36, " ");
9457 else
9458 vty_out(vty, "%*s", len, " ");
9459 } else {
9460 if (nexthop_hostname)
9461 len = vty_out(
9462 vty, "%pI6(%s)%s",
9463 &attr->mp_nexthop_local,
9464 nexthop_hostname,
9465 vrf_id_str);
9466 else
9467 len = vty_out(
9468 vty, "%pI6%s",
9469 &attr->mp_nexthop_local,
9470 vrf_id_str);
9471
9472 len = wide ? (41 - len) : (16 - len);
9473
9474 if (len < 1)
9475 vty_out(vty, "\n%*s", 36, " ");
9476 else
9477 vty_out(vty, "%*s", len, " ");
9478 }
9479 } else {
9480 if (nexthop_hostname)
9481 len = vty_out(vty, "%pI6(%s)%s",
9482 &attr->mp_nexthop_global,
9483 nexthop_hostname,
9484 vrf_id_str);
9485 else
9486 len = vty_out(vty, "%pI6%s",
9487 &attr->mp_nexthop_global,
9488 vrf_id_str);
9489
9490 len = wide ? (41 - len) : (16 - len);
9491
9492 if (len < 1)
9493 vty_out(vty, "\n%*s", 36, " ");
9494 else
9495 vty_out(vty, "%*s", len, " ");
9496 }
9497 }
9498 }
9499
9500 /* MED/Metric */
9501 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9502 if (json_paths)
9503 json_object_int_add(json_path, "metric", attr->med);
9504 else if (wide)
9505 vty_out(vty, "%7u", attr->med);
9506 else
9507 vty_out(vty, "%10u", attr->med);
9508 else if (!json_paths) {
9509 if (wide)
9510 vty_out(vty, "%*s", 7, " ");
9511 else
9512 vty_out(vty, "%*s", 10, " ");
9513 }
9514
9515 /* Local Pref */
9516 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9517 if (json_paths)
9518 json_object_int_add(json_path, "locPrf",
9519 attr->local_pref);
9520 else
9521 vty_out(vty, "%7u", attr->local_pref);
9522 else if (!json_paths)
9523 vty_out(vty, " ");
9524
9525 if (json_paths)
9526 json_object_int_add(json_path, "weight", attr->weight);
9527 else
9528 vty_out(vty, "%7u ", attr->weight);
9529
9530 if (json_paths)
9531 json_object_string_addf(json_path, "peerId", "%pSU",
9532 &path->peer->su);
9533
9534 /* Print aspath */
9535 if (attr->aspath) {
9536 if (json_paths)
9537 json_object_string_add(json_path, "path",
9538 attr->aspath->str);
9539 else
9540 aspath_print_vty(vty, "%s", attr->aspath, " ");
9541 }
9542
9543 /* Print origin */
9544 if (json_paths)
9545 json_object_string_add(json_path, "origin",
9546 bgp_origin_long_str[attr->origin]);
9547 else
9548 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9549
9550 if (json_paths) {
9551 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9552 json_object_string_add(json_path, "esi",
9553 esi_to_str(&attr->esi,
9554 esi_buf, sizeof(esi_buf)));
9555 }
9556 if (safi == SAFI_EVPN &&
9557 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9558 json_ext_community = json_object_new_object();
9559 json_object_string_add(
9560 json_ext_community, "string",
9561 bgp_attr_get_ecommunity(attr)->str);
9562 json_object_object_add(json_path,
9563 "extendedCommunity",
9564 json_ext_community);
9565 }
9566
9567 if (nexthop_self)
9568 json_object_boolean_true_add(json_path,
9569 "announceNexthopSelf");
9570 if (nexthop_othervrf) {
9571 json_object_string_add(json_path, "nhVrfName",
9572 nexthop_vrfname);
9573
9574 json_object_int_add(json_path, "nhVrfId",
9575 ((nexthop_vrfid == VRF_UNKNOWN)
9576 ? -1
9577 : (int)nexthop_vrfid));
9578 }
9579 }
9580
9581 if (json_paths) {
9582 if (json_nexthop_global || json_nexthop_ll) {
9583 json_nexthops = json_object_new_array();
9584
9585 if (json_nexthop_global)
9586 json_object_array_add(json_nexthops,
9587 json_nexthop_global);
9588
9589 if (json_nexthop_ll)
9590 json_object_array_add(json_nexthops,
9591 json_nexthop_ll);
9592
9593 json_object_object_add(json_path, "nexthops",
9594 json_nexthops);
9595 }
9596
9597 json_object_array_add(json_paths, json_path);
9598 } else {
9599 vty_out(vty, "\n");
9600
9601 if (safi == SAFI_EVPN) {
9602 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9603 /* XXX - add these params to the json out */
9604 vty_out(vty, "%*s", 20, " ");
9605 vty_out(vty, "ESI:%s",
9606 esi_to_str(&attr->esi, esi_buf,
9607 sizeof(esi_buf)));
9608
9609 vty_out(vty, "\n");
9610 }
9611 if (attr->flag &
9612 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9613 vty_out(vty, "%*s", 20, " ");
9614 vty_out(vty, "%s\n",
9615 bgp_attr_get_ecommunity(attr)->str);
9616 }
9617 }
9618
9619 #ifdef ENABLE_BGP_VNC
9620 /* prints an additional line, indented, with VNC info, if
9621 * present */
9622 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9623 rfapi_vty_out_vncinfo(vty, p, path, safi);
9624 #endif
9625 }
9626 }
9627
9628 /* called from terminal list command */
9629 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9630 const struct prefix *p, struct attr *attr, safi_t safi,
9631 bool use_json, json_object *json_ar, bool wide)
9632 {
9633 json_object *json_status = NULL;
9634 json_object *json_net = NULL;
9635 int len;
9636 char buff[BUFSIZ];
9637
9638 /* Route status display. */
9639 if (use_json) {
9640 json_status = json_object_new_object();
9641 json_net = json_object_new_object();
9642 } else {
9643 vty_out(vty, " *");
9644 vty_out(vty, ">");
9645 vty_out(vty, " ");
9646 }
9647
9648 /* print prefix and mask */
9649 if (use_json) {
9650 if (safi == SAFI_EVPN)
9651 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9652 else if (p->family == AF_INET || p->family == AF_INET6) {
9653 json_object_string_add(
9654 json_net, "addrPrefix",
9655 inet_ntop(p->family, &p->u.prefix, buff,
9656 BUFSIZ));
9657 json_object_int_add(json_net, "prefixLen",
9658 p->prefixlen);
9659 json_object_string_addf(json_net, "network", "%pFX", p);
9660 }
9661 } else
9662 route_vty_out_route(dest, p, vty, NULL, wide);
9663
9664 /* Print attribute */
9665 if (attr) {
9666 if (use_json) {
9667 if (p->family == AF_INET &&
9668 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9669 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9670 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9671 json_object_string_addf(
9672 json_net, "nextHop", "%pI4",
9673 &attr->mp_nexthop_global_in);
9674 else
9675 json_object_string_addf(
9676 json_net, "nextHop", "%pI4",
9677 &attr->nexthop);
9678 } else if (p->family == AF_INET6 ||
9679 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9680 json_object_string_addf(
9681 json_net, "nextHopGlobal", "%pI6",
9682 &attr->mp_nexthop_global);
9683 } else if (p->family == AF_EVPN &&
9684 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9685 json_object_string_addf(
9686 json_net, "nextHop", "%pI4",
9687 &attr->mp_nexthop_global_in);
9688 }
9689
9690 if (attr->flag
9691 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9692 json_object_int_add(json_net, "metric",
9693 attr->med);
9694
9695 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9696 json_object_int_add(json_net, "locPrf",
9697 attr->local_pref);
9698
9699 json_object_int_add(json_net, "weight", attr->weight);
9700
9701 /* Print aspath */
9702 if (attr->aspath)
9703 json_object_string_add(json_net, "path",
9704 attr->aspath->str);
9705
9706 /* Print origin */
9707 #if CONFDATE > 20231208
9708 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
9709 #endif
9710 json_object_string_add(json_net, "bgpOriginCode",
9711 bgp_origin_str[attr->origin]);
9712 json_object_string_add(
9713 json_net, "origin",
9714 bgp_origin_long_str[attr->origin]);
9715 } else {
9716 if (p->family == AF_INET &&
9717 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9718 safi == SAFI_EVPN ||
9719 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9720 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9721 || safi == SAFI_EVPN)
9722 vty_out(vty, "%-16pI4",
9723 &attr->mp_nexthop_global_in);
9724 else if (wide)
9725 vty_out(vty, "%-41pI4", &attr->nexthop);
9726 else
9727 vty_out(vty, "%-16pI4", &attr->nexthop);
9728 } else if (p->family == AF_INET6 ||
9729 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9730 len = vty_out(vty, "%pI6",
9731 &attr->mp_nexthop_global);
9732 len = wide ? (41 - len) : (16 - len);
9733 if (len < 1)
9734 vty_out(vty, "\n%*s", 36, " ");
9735 else
9736 vty_out(vty, "%*s", len, " ");
9737 }
9738 if (attr->flag
9739 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9740 if (wide)
9741 vty_out(vty, "%7u", attr->med);
9742 else
9743 vty_out(vty, "%10u", attr->med);
9744 else if (wide)
9745 vty_out(vty, " ");
9746 else
9747 vty_out(vty, " ");
9748
9749 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9750 vty_out(vty, "%7u", attr->local_pref);
9751 else
9752 vty_out(vty, " ");
9753
9754 vty_out(vty, "%7u ", attr->weight);
9755
9756 /* Print aspath */
9757 if (attr->aspath)
9758 aspath_print_vty(vty, "%s", attr->aspath, " ");
9759
9760 /* Print origin */
9761 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9762 }
9763 }
9764 if (use_json) {
9765 struct bgp_path_info *bpi = bgp_dest_get_bgp_path_info(dest);
9766
9767 #if CONFDATE > 20231208
9768 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
9769 #endif
9770 json_object_boolean_true_add(json_status, "*");
9771 json_object_boolean_true_add(json_status, ">");
9772 json_object_boolean_true_add(json_net, "valid");
9773 json_object_boolean_true_add(json_net, "best");
9774
9775 if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_MULTIPATH)) {
9776 json_object_boolean_true_add(json_status, "=");
9777 json_object_boolean_true_add(json_net, "multipath");
9778 }
9779 json_object_object_add(json_net, "appliedStatusSymbols",
9780 json_status);
9781 json_object_object_addf(json_ar, json_net, "%pFX", p);
9782 } else
9783 vty_out(vty, "\n");
9784 }
9785
9786 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9787 struct bgp_path_info *path, int display, safi_t safi,
9788 json_object *json)
9789 {
9790 json_object *json_out = NULL;
9791 struct attr *attr;
9792 mpls_label_t label = MPLS_INVALID_LABEL;
9793
9794 if (!path->extra)
9795 return;
9796
9797 if (json)
9798 json_out = json_object_new_object();
9799
9800 /* short status lead text */
9801 route_vty_short_status_out(vty, path, p, json_out);
9802
9803 /* print prefix and mask */
9804 if (json == NULL) {
9805 if (!display)
9806 route_vty_out_route(path->net, p, vty, NULL, false);
9807 else
9808 vty_out(vty, "%*s", 17, " ");
9809 }
9810
9811 /* Print attribute */
9812 attr = path->attr;
9813 if (((p->family == AF_INET) &&
9814 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9815 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9816 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9817 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9818 || safi == SAFI_EVPN) {
9819 if (json)
9820 json_object_string_addf(
9821 json_out, "mpNexthopGlobalIn", "%pI4",
9822 &attr->mp_nexthop_global_in);
9823 else
9824 vty_out(vty, "%-16pI4",
9825 &attr->mp_nexthop_global_in);
9826 } else {
9827 if (json)
9828 json_object_string_addf(json_out, "nexthop",
9829 "%pI4", &attr->nexthop);
9830 else
9831 vty_out(vty, "%-16pI4", &attr->nexthop);
9832 }
9833 } else if (((p->family == AF_INET6) &&
9834 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9835 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9836 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9837 char buf_a[512];
9838
9839 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9840 if (json)
9841 json_object_string_addf(
9842 json_out, "mpNexthopGlobalIn", "%pI6",
9843 &attr->mp_nexthop_global);
9844 else
9845 vty_out(vty, "%s",
9846 inet_ntop(AF_INET6,
9847 &attr->mp_nexthop_global,
9848 buf_a, sizeof(buf_a)));
9849 } else if (attr->mp_nexthop_len
9850 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9851 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9852 &attr->mp_nexthop_global,
9853 &attr->mp_nexthop_local);
9854 if (json)
9855 json_object_string_add(json_out,
9856 "mpNexthopGlobalLocal",
9857 buf_a);
9858 else
9859 vty_out(vty, "%s", buf_a);
9860 }
9861 }
9862
9863 label = decode_label(&path->extra->label[0]);
9864
9865 if (bgp_is_valid_label(&label)) {
9866 if (json) {
9867 json_object_int_add(json_out, "notag", label);
9868 json_object_array_add(json, json_out);
9869 } else {
9870 vty_out(vty, "notag/%d", label);
9871 vty_out(vty, "\n");
9872 }
9873 } else if (!json)
9874 vty_out(vty, "\n");
9875 }
9876
9877 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9878 struct bgp_path_info *path, int display,
9879 json_object *json_paths)
9880 {
9881 struct attr *attr;
9882 json_object *json_path = NULL;
9883 json_object *json_nexthop = NULL;
9884 json_object *json_overlay = NULL;
9885
9886 if (!path->extra)
9887 return;
9888
9889 if (json_paths) {
9890 json_path = json_object_new_object();
9891 json_overlay = json_object_new_object();
9892 json_nexthop = json_object_new_object();
9893 }
9894
9895 /* short status lead text */
9896 route_vty_short_status_out(vty, path, p, json_path);
9897
9898 /* print prefix and mask */
9899 if (!display)
9900 route_vty_out_route(path->net, p, vty, json_path, false);
9901 else
9902 vty_out(vty, "%*s", 17, " ");
9903
9904 /* Print attribute */
9905 attr = path->attr;
9906 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9907
9908 switch (af) {
9909 case AF_INET:
9910 if (!json_path) {
9911 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9912 } else {
9913 json_object_string_addf(json_nexthop, "ip", "%pI4",
9914 &attr->mp_nexthop_global_in);
9915
9916 json_object_string_add(json_nexthop, "afi", "ipv4");
9917
9918 json_object_object_add(json_path, "nexthop",
9919 json_nexthop);
9920 }
9921 break;
9922 case AF_INET6:
9923 if (!json_path) {
9924 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9925 &attr->mp_nexthop_local);
9926 } else {
9927 json_object_string_addf(json_nexthop, "ipv6Global",
9928 "%pI6",
9929 &attr->mp_nexthop_global);
9930
9931 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9932 "%pI6",
9933 &attr->mp_nexthop_local);
9934
9935 json_object_string_add(json_nexthop, "afi", "ipv6");
9936
9937 json_object_object_add(json_path, "nexthop",
9938 json_nexthop);
9939 }
9940 break;
9941 default:
9942 if (!json_path) {
9943 vty_out(vty, "?");
9944 } else {
9945 json_object_string_add(json_nexthop, "Error",
9946 "Unsupported address-family");
9947 json_object_string_add(json_nexthop, "error",
9948 "Unsupported address-family");
9949 }
9950 }
9951
9952 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9953
9954 if (!json_path)
9955 vty_out(vty, "/%pIA", &eo->gw_ip);
9956 else
9957 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9958
9959 if (bgp_attr_get_ecommunity(attr)) {
9960 char *mac = NULL;
9961 struct ecommunity_val *routermac = ecommunity_lookup(
9962 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9963 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9964
9965 if (routermac)
9966 mac = ecom_mac2str((char *)routermac->val);
9967 if (mac) {
9968 if (!json_path) {
9969 vty_out(vty, "/%s", mac);
9970 } else {
9971 json_object_string_add(json_overlay, "rmac",
9972 mac);
9973 }
9974 XFREE(MTYPE_TMP, mac);
9975 }
9976 }
9977
9978 if (!json_path) {
9979 vty_out(vty, "\n");
9980 } else {
9981 json_object_object_add(json_path, "overlay", json_overlay);
9982
9983 json_object_array_add(json_paths, json_path);
9984 }
9985 }
9986
9987 /* dampening route */
9988 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9989 struct bgp_path_info *path, int display,
9990 afi_t afi, safi_t safi, bool use_json,
9991 json_object *json_paths)
9992 {
9993 struct attr *attr = path->attr;
9994 int len;
9995 char timebuf[BGP_UPTIME_LEN];
9996 json_object *json_path = NULL;
9997
9998 if (use_json)
9999 json_path = json_object_new_object();
10000
10001 /* short status lead text */
10002 route_vty_short_status_out(vty, path, p, json_path);
10003
10004 /* print prefix and mask */
10005 if (!use_json) {
10006 if (!display)
10007 route_vty_out_route(path->net, p, vty, NULL, false);
10008 else
10009 vty_out(vty, "%*s", 17, " ");
10010
10011 len = vty_out(vty, "%s", path->peer->host);
10012 len = 17 - len;
10013
10014 if (len < 1)
10015 vty_out(vty, "\n%*s", 34, " ");
10016 else
10017 vty_out(vty, "%*s", len, " ");
10018
10019 vty_out(vty, "%s ",
10020 bgp_damp_reuse_time_vty(vty, path, timebuf,
10021 BGP_UPTIME_LEN, afi, safi,
10022 use_json, NULL));
10023
10024 if (attr->aspath)
10025 aspath_print_vty(vty, "%s", attr->aspath, " ");
10026
10027 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10028
10029 vty_out(vty, "\n");
10030 } else {
10031 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
10032 safi, use_json, json_path);
10033
10034 if (attr->aspath)
10035 json_object_string_add(json_path, "asPath",
10036 attr->aspath->str);
10037
10038 json_object_string_add(json_path, "origin",
10039 bgp_origin_str[attr->origin]);
10040 json_object_string_add(json_path, "peerHost", path->peer->host);
10041
10042 json_object_array_add(json_paths, json_path);
10043 }
10044 }
10045
10046 /* flap route */
10047 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
10048 struct bgp_path_info *path, int display,
10049 afi_t afi, safi_t safi, bool use_json,
10050 json_object *json_paths)
10051 {
10052 struct attr *attr = path->attr;
10053 struct bgp_damp_info *bdi;
10054 char timebuf[BGP_UPTIME_LEN];
10055 int len;
10056 json_object *json_path = NULL;
10057
10058 if (!path->extra)
10059 return;
10060
10061 if (use_json)
10062 json_path = json_object_new_object();
10063
10064 bdi = path->extra->damp_info;
10065
10066 /* short status lead text */
10067 route_vty_short_status_out(vty, path, p, json_path);
10068
10069 if (!use_json) {
10070 if (!display)
10071 route_vty_out_route(path->net, p, vty, NULL, false);
10072 else
10073 vty_out(vty, "%*s", 17, " ");
10074
10075 len = vty_out(vty, "%s", path->peer->host);
10076 len = 16 - len;
10077 if (len < 1)
10078 vty_out(vty, "\n%*s", 33, " ");
10079 else
10080 vty_out(vty, "%*s", len, " ");
10081
10082 len = vty_out(vty, "%d", bdi->flap);
10083 len = 5 - len;
10084 if (len < 1)
10085 vty_out(vty, " ");
10086 else
10087 vty_out(vty, "%*s", len, " ");
10088
10089 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10090 BGP_UPTIME_LEN, 0, NULL));
10091
10092 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10093 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10094 vty_out(vty, "%s ",
10095 bgp_damp_reuse_time_vty(vty, path, timebuf,
10096 BGP_UPTIME_LEN, afi,
10097 safi, use_json, NULL));
10098 else
10099 vty_out(vty, "%*s ", 8, " ");
10100
10101 if (attr->aspath)
10102 aspath_print_vty(vty, "%s", attr->aspath, " ");
10103
10104 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10105
10106 vty_out(vty, "\n");
10107 } else {
10108 json_object_string_add(json_path, "peerHost", path->peer->host);
10109 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10110
10111 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10112 json_path);
10113
10114 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10115 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10116 bgp_damp_reuse_time_vty(vty, path, timebuf,
10117 BGP_UPTIME_LEN, afi, safi,
10118 use_json, json_path);
10119
10120 if (attr->aspath)
10121 json_object_string_add(json_path, "asPath",
10122 attr->aspath->str);
10123
10124 json_object_string_add(json_path, "origin",
10125 bgp_origin_str[attr->origin]);
10126
10127 json_object_array_add(json_paths, json_path);
10128 }
10129 }
10130
10131 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10132 int *first, const char *header,
10133 json_object *json_adv_to)
10134 {
10135 json_object *json_peer = NULL;
10136
10137 if (json_adv_to) {
10138 /* 'advertised-to' is a dictionary of peers we have advertised
10139 * this
10140 * prefix too. The key is the peer's IP or swpX, the value is
10141 * the
10142 * hostname if we know it and "" if not.
10143 */
10144 json_peer = json_object_new_object();
10145
10146 if (peer->hostname)
10147 json_object_string_add(json_peer, "hostname",
10148 peer->hostname);
10149
10150 if (peer->conf_if)
10151 json_object_object_add(json_adv_to, peer->conf_if,
10152 json_peer);
10153 else
10154 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10155 &peer->su);
10156 } else {
10157 if (*first) {
10158 vty_out(vty, "%s", header);
10159 *first = 0;
10160 }
10161
10162 if (peer->hostname
10163 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10164 if (peer->conf_if)
10165 vty_out(vty, " %s(%s)", peer->hostname,
10166 peer->conf_if);
10167 else
10168 vty_out(vty, " %s(%pSU)", peer->hostname,
10169 &peer->su);
10170 } else {
10171 if (peer->conf_if)
10172 vty_out(vty, " %s", peer->conf_if);
10173 else
10174 vty_out(vty, " %pSU", &peer->su);
10175 }
10176 }
10177 }
10178
10179 static void route_vty_out_tx_ids(struct vty *vty,
10180 struct bgp_addpath_info_data *d)
10181 {
10182 int i;
10183
10184 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10185 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10186 d->addpath_tx_id[i],
10187 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10188 }
10189 }
10190
10191 static void route_vty_out_detail_es_info(struct vty *vty,
10192 struct bgp_path_info *pi,
10193 struct attr *attr,
10194 json_object *json_path)
10195 {
10196 char esi_buf[ESI_STR_LEN];
10197 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10198 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10199 ATTR_ES_PEER_ROUTER);
10200 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10201 ATTR_ES_PEER_ACTIVE);
10202 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10203 ATTR_ES_PEER_PROXY);
10204 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10205 if (json_path) {
10206 json_object *json_es_info = NULL;
10207
10208 json_object_string_add(
10209 json_path, "esi",
10210 esi_buf);
10211 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10212 json_es_info = json_object_new_object();
10213 if (es_local)
10214 json_object_boolean_true_add(
10215 json_es_info, "localEs");
10216 if (peer_active)
10217 json_object_boolean_true_add(
10218 json_es_info, "peerActive");
10219 if (peer_proxy)
10220 json_object_boolean_true_add(
10221 json_es_info, "peerProxy");
10222 if (peer_router)
10223 json_object_boolean_true_add(
10224 json_es_info, "peerRouter");
10225 if (attr->mm_sync_seqnum)
10226 json_object_int_add(
10227 json_es_info, "peerSeq",
10228 attr->mm_sync_seqnum);
10229 json_object_object_add(
10230 json_path, "es_info",
10231 json_es_info);
10232 }
10233 } else {
10234 if (bgp_evpn_attr_is_sync(attr))
10235 vty_out(vty,
10236 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10237 esi_buf,
10238 es_local ? "local-es":"",
10239 peer_proxy ? "proxy " : "",
10240 peer_active ? "active ":"",
10241 peer_router ? "router ":"",
10242 attr->mm_sync_seqnum);
10243 else
10244 vty_out(vty, " ESI %s %s\n",
10245 esi_buf,
10246 es_local ? "local-es":"");
10247 }
10248 }
10249
10250 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10251 const struct prefix *p, struct bgp_path_info *path,
10252 afi_t afi, safi_t safi,
10253 enum rpki_states rpki_curr_state,
10254 json_object *json_paths)
10255 {
10256 char buf[INET6_ADDRSTRLEN];
10257 char tag_buf[30];
10258 struct attr *attr = path->attr;
10259 time_t tbuf;
10260 json_object *json_bestpath = NULL;
10261 json_object *json_cluster_list = NULL;
10262 json_object *json_cluster_list_list = NULL;
10263 json_object *json_ext_community = NULL;
10264 json_object *json_last_update = NULL;
10265 json_object *json_pmsi = NULL;
10266 json_object *json_nexthop_global = NULL;
10267 json_object *json_nexthop_ll = NULL;
10268 json_object *json_nexthops = NULL;
10269 json_object *json_path = NULL;
10270 json_object *json_peer = NULL;
10271 json_object *json_string = NULL;
10272 json_object *json_adv_to = NULL;
10273 int first = 0;
10274 struct listnode *node, *nnode;
10275 struct peer *peer;
10276 bool addpath_capable;
10277 int has_adj;
10278 unsigned int first_as;
10279 bool nexthop_self =
10280 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10281 int i;
10282 char *nexthop_hostname =
10283 bgp_nexthop_hostname(path->peer, path->nexthop);
10284 uint32_t ttl = 0;
10285 uint32_t bos = 0;
10286 uint32_t exp = 0;
10287 mpls_label_t label = MPLS_INVALID_LABEL;
10288 tag_buf[0] = '\0';
10289 struct bgp_path_info *bpi_ultimate =
10290 bgp_get_imported_bpi_ultimate(path);
10291
10292 if (json_paths) {
10293 json_path = json_object_new_object();
10294 json_peer = json_object_new_object();
10295 json_nexthop_global = json_object_new_object();
10296 }
10297
10298 if (safi == SAFI_EVPN) {
10299 if (!json_paths)
10300 vty_out(vty, " Route %pFX", p);
10301 }
10302
10303 if (path->extra) {
10304 if (path->extra && path->extra->num_labels) {
10305 bgp_evpn_label2str(path->extra->label,
10306 path->extra->num_labels, tag_buf,
10307 sizeof(tag_buf));
10308 }
10309 if (safi == SAFI_EVPN) {
10310 if (!json_paths) {
10311 if (tag_buf[0] != '\0')
10312 vty_out(vty, " VNI %s", tag_buf);
10313 } else {
10314 if (tag_buf[0]) {
10315 json_object_string_add(json_path, "VNI",
10316 tag_buf);
10317 json_object_string_add(json_path, "vni",
10318 tag_buf);
10319 }
10320 }
10321 }
10322 }
10323
10324 if (safi == SAFI_EVPN
10325 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10326 char gwip_buf[INET6_ADDRSTRLEN];
10327
10328 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10329 sizeof(gwip_buf));
10330
10331 if (json_paths)
10332 json_object_string_add(json_path, "gatewayIP",
10333 gwip_buf);
10334 else
10335 vty_out(vty, " Gateway IP %s", gwip_buf);
10336 }
10337
10338 if (safi == SAFI_EVPN && !json_path)
10339 vty_out(vty, "\n");
10340
10341
10342 if (path->extra && path->extra->parent && !json_paths) {
10343 struct bgp_path_info *parent_ri;
10344 struct bgp_dest *dest, *pdest;
10345
10346 parent_ri = (struct bgp_path_info *)path->extra->parent;
10347 dest = parent_ri->net;
10348 if (dest && dest->pdest) {
10349 pdest = dest->pdest;
10350 if (is_pi_family_evpn(parent_ri)) {
10351 vty_out(vty,
10352 " Imported from %pRD:%pFX, VNI %s",
10353 (struct prefix_rd *)bgp_dest_get_prefix(
10354 pdest),
10355 (struct prefix_evpn *)
10356 bgp_dest_get_prefix(dest),
10357 tag_buf);
10358 if (CHECK_FLAG(attr->es_flags, ATTR_ES_L3_NHG))
10359 vty_out(vty, ", L3NHG %s",
10360 CHECK_FLAG(
10361 attr->es_flags,
10362 ATTR_ES_L3_NHG_ACTIVE)
10363 ? "active"
10364 : "inactive");
10365 vty_out(vty, "\n");
10366
10367 } else
10368 vty_out(vty, " Imported from %pRD:%pFX\n",
10369 (struct prefix_rd *)bgp_dest_get_prefix(
10370 pdest),
10371 (struct prefix_evpn *)
10372 bgp_dest_get_prefix(dest));
10373 }
10374 }
10375
10376 /* Line1 display AS-path, Aggregator */
10377 if (attr->aspath) {
10378 if (json_paths) {
10379 if (!attr->aspath->json)
10380 aspath_str_update(attr->aspath, true);
10381 json_object_lock(attr->aspath->json);
10382 json_object_object_add(json_path, "aspath",
10383 attr->aspath->json);
10384 } else {
10385 if (attr->aspath->segments)
10386 aspath_print_vty(vty, " %s", attr->aspath, "");
10387 else
10388 vty_out(vty, " Local");
10389 }
10390 }
10391
10392 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10393 if (json_paths)
10394 json_object_boolean_true_add(json_path, "removed");
10395 else
10396 vty_out(vty, ", (removed)");
10397 }
10398
10399 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10400 if (json_paths)
10401 json_object_boolean_true_add(json_path, "stale");
10402 else
10403 vty_out(vty, ", (stale)");
10404 }
10405
10406 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10407 if (json_paths) {
10408 json_object_int_add(json_path, "aggregatorAs",
10409 attr->aggregator_as);
10410 json_object_string_addf(json_path, "aggregatorId",
10411 "%pI4", &attr->aggregator_addr);
10412 } else {
10413 vty_out(vty, ", (aggregated by %u %pI4)",
10414 attr->aggregator_as, &attr->aggregator_addr);
10415 }
10416 }
10417
10418 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10419 PEER_FLAG_REFLECTOR_CLIENT)) {
10420 if (json_paths)
10421 json_object_boolean_true_add(json_path,
10422 "rxedFromRrClient");
10423 else
10424 vty_out(vty, ", (Received from a RR-client)");
10425 }
10426
10427 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10428 PEER_FLAG_RSERVER_CLIENT)) {
10429 if (json_paths)
10430 json_object_boolean_true_add(json_path,
10431 "rxedFromRsClient");
10432 else
10433 vty_out(vty, ", (Received from a RS-client)");
10434 }
10435
10436 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10437 if (json_paths)
10438 json_object_boolean_true_add(json_path,
10439 "dampeningHistoryEntry");
10440 else
10441 vty_out(vty, ", (history entry)");
10442 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10443 if (json_paths)
10444 json_object_boolean_true_add(json_path,
10445 "dampeningSuppressed");
10446 else
10447 vty_out(vty, ", (suppressed due to dampening)");
10448 }
10449
10450 if (!json_paths)
10451 vty_out(vty, "\n");
10452
10453 /* Line2 display Next-hop, Neighbor, Router-id */
10454 /* Display the nexthop */
10455
10456 if ((p->family == AF_INET || p->family == AF_ETHERNET ||
10457 p->family == AF_EVPN) &&
10458 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10459 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10460 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10461 || safi == SAFI_EVPN) {
10462 if (json_paths) {
10463 json_object_string_addf(
10464 json_nexthop_global, "ip", "%pI4",
10465 &attr->mp_nexthop_global_in);
10466
10467 if (path->peer->hostname)
10468 json_object_string_add(
10469 json_nexthop_global, "hostname",
10470 path->peer->hostname);
10471 } else {
10472 if (nexthop_hostname)
10473 vty_out(vty, " %pI4(%s)",
10474 &attr->mp_nexthop_global_in,
10475 nexthop_hostname);
10476 else
10477 vty_out(vty, " %pI4",
10478 &attr->mp_nexthop_global_in);
10479 }
10480 } else {
10481 if (json_paths) {
10482 json_object_string_addf(json_nexthop_global,
10483 "ip", "%pI4",
10484 &attr->nexthop);
10485
10486 if (path->peer->hostname)
10487 json_object_string_add(
10488 json_nexthop_global, "hostname",
10489 path->peer->hostname);
10490 } else {
10491 if (nexthop_hostname)
10492 vty_out(vty, " %pI4(%s)",
10493 &attr->nexthop,
10494 nexthop_hostname);
10495 else
10496 vty_out(vty, " %pI4",
10497 &attr->nexthop);
10498 }
10499 }
10500
10501 if (json_paths)
10502 json_object_string_add(json_nexthop_global, "afi",
10503 "ipv4");
10504 } else {
10505 if (json_paths) {
10506 json_object_string_addf(json_nexthop_global, "ip",
10507 "%pI6",
10508 &attr->mp_nexthop_global);
10509
10510 if (path->peer->hostname)
10511 json_object_string_add(json_nexthop_global,
10512 "hostname",
10513 path->peer->hostname);
10514
10515 json_object_string_add(json_nexthop_global, "afi",
10516 "ipv6");
10517 json_object_string_add(json_nexthop_global, "scope",
10518 "global");
10519 } else {
10520 if (nexthop_hostname)
10521 vty_out(vty, " %pI6(%s)",
10522 &attr->mp_nexthop_global,
10523 nexthop_hostname);
10524 else
10525 vty_out(vty, " %pI6",
10526 &attr->mp_nexthop_global);
10527 }
10528 }
10529
10530 /* Display the IGP cost or 'inaccessible' */
10531 if (!CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_VALID)) {
10532 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10533
10534 if (json_paths) {
10535 json_object_boolean_false_add(json_nexthop_global,
10536 "accessible");
10537 json_object_boolean_add(json_nexthop_global,
10538 "importCheckEnabled", import);
10539 } else {
10540 vty_out(vty, " (inaccessible%s)",
10541 import ? ", import-check enabled" : "");
10542 }
10543 } else {
10544 if (bpi_ultimate->extra && bpi_ultimate->extra->igpmetric) {
10545 if (json_paths)
10546 json_object_int_add(
10547 json_nexthop_global, "metric",
10548 bpi_ultimate->extra->igpmetric);
10549 else
10550 vty_out(vty, " (metric %u)",
10551 bpi_ultimate->extra->igpmetric);
10552 }
10553
10554 /* IGP cost is 0, display this only for json */
10555 else {
10556 if (json_paths)
10557 json_object_int_add(json_nexthop_global,
10558 "metric", 0);
10559 }
10560
10561 if (json_paths)
10562 json_object_boolean_true_add(json_nexthop_global,
10563 "accessible");
10564 }
10565
10566 /* Display peer "from" output */
10567 /* This path was originated locally */
10568 if (path->peer == bgp->peer_self) {
10569
10570 if (safi == SAFI_EVPN || (p->family == AF_INET &&
10571 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10572 if (json_paths)
10573 json_object_string_add(json_peer, "peerId",
10574 "0.0.0.0");
10575 else
10576 vty_out(vty, " from 0.0.0.0 ");
10577 } else {
10578 if (json_paths)
10579 json_object_string_add(json_peer, "peerId",
10580 "::");
10581 else
10582 vty_out(vty, " from :: ");
10583 }
10584
10585 if (json_paths)
10586 json_object_string_addf(json_peer, "routerId", "%pI4",
10587 &bgp->router_id);
10588 else
10589 vty_out(vty, "(%pI4)", &bgp->router_id);
10590 }
10591
10592 /* We RXed this path from one of our peers */
10593 else {
10594
10595 if (json_paths) {
10596 json_object_string_addf(json_peer, "peerId", "%pSU",
10597 &path->peer->su);
10598 json_object_string_addf(json_peer, "routerId", "%pI4",
10599 &path->peer->remote_id);
10600
10601 if (path->peer->hostname)
10602 json_object_string_add(json_peer, "hostname",
10603 path->peer->hostname);
10604
10605 if (path->peer->domainname)
10606 json_object_string_add(json_peer, "domainname",
10607 path->peer->domainname);
10608
10609 if (path->peer->conf_if)
10610 json_object_string_add(json_peer, "interface",
10611 path->peer->conf_if);
10612 } else {
10613 if (path->peer->conf_if) {
10614 if (path->peer->hostname
10615 && CHECK_FLAG(path->peer->bgp->flags,
10616 BGP_FLAG_SHOW_HOSTNAME))
10617 vty_out(vty, " from %s(%s)",
10618 path->peer->hostname,
10619 path->peer->conf_if);
10620 else
10621 vty_out(vty, " from %s",
10622 path->peer->conf_if);
10623 } else {
10624 if (path->peer->hostname
10625 && CHECK_FLAG(path->peer->bgp->flags,
10626 BGP_FLAG_SHOW_HOSTNAME))
10627 vty_out(vty, " from %s(%s)",
10628 path->peer->hostname,
10629 path->peer->host);
10630 else
10631 vty_out(vty, " from %pSU",
10632 &path->peer->su);
10633 }
10634
10635 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10636 vty_out(vty, " (%pI4)", &attr->originator_id);
10637 else
10638 vty_out(vty, " (%pI4)", &path->peer->remote_id);
10639 }
10640 }
10641
10642 /*
10643 * Note when vrfid of nexthop is different from that of prefix
10644 */
10645 if (path->extra && path->extra->bgp_orig) {
10646 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10647
10648 if (json_paths) {
10649 const char *vn;
10650
10651 if (path->extra->bgp_orig->inst_type
10652 == BGP_INSTANCE_TYPE_DEFAULT)
10653 vn = VRF_DEFAULT_NAME;
10654 else
10655 vn = path->extra->bgp_orig->name;
10656
10657 json_object_string_add(json_path, "nhVrfName", vn);
10658
10659 if (nexthop_vrfid == VRF_UNKNOWN) {
10660 json_object_int_add(json_path, "nhVrfId", -1);
10661 } else {
10662 json_object_int_add(json_path, "nhVrfId",
10663 (int)nexthop_vrfid);
10664 }
10665 } else {
10666 if (nexthop_vrfid == VRF_UNKNOWN)
10667 vty_out(vty, " vrf ?");
10668 else {
10669 struct vrf *vrf;
10670
10671 vrf = vrf_lookup_by_id(nexthop_vrfid);
10672 vty_out(vty, " vrf %s(%u)",
10673 VRF_LOGNAME(vrf), nexthop_vrfid);
10674 }
10675 }
10676 }
10677
10678 if (nexthop_self) {
10679 if (json_paths) {
10680 json_object_boolean_true_add(json_path,
10681 "announceNexthopSelf");
10682 } else {
10683 vty_out(vty, " announce-nh-self");
10684 }
10685 }
10686
10687 if (!json_paths)
10688 vty_out(vty, "\n");
10689
10690 /* display the link-local nexthop */
10691 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10692 if (json_paths) {
10693 json_nexthop_ll = json_object_new_object();
10694 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10695 &attr->mp_nexthop_local);
10696
10697 if (path->peer->hostname)
10698 json_object_string_add(json_nexthop_ll,
10699 "hostname",
10700 path->peer->hostname);
10701
10702 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10703 json_object_string_add(json_nexthop_ll, "scope",
10704 "link-local");
10705
10706 json_object_boolean_true_add(json_nexthop_ll,
10707 "accessible");
10708
10709 if (!CHECK_FLAG(attr->nh_flag,
10710 BGP_ATTR_NH_MP_PREFER_GLOBAL))
10711 json_object_boolean_true_add(json_nexthop_ll,
10712 "used");
10713 else
10714 json_object_boolean_true_add(
10715 json_nexthop_global, "used");
10716 } else {
10717 vty_out(vty, " (%s) %s\n",
10718 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10719 buf, INET6_ADDRSTRLEN),
10720 CHECK_FLAG(attr->nh_flag,
10721 BGP_ATTR_NH_MP_PREFER_GLOBAL)
10722 ? "(prefer-global)"
10723 : "(used)");
10724 }
10725 }
10726 /* If we do not have a link-local nexthop then we must flag the
10727 global as "used" */
10728 else {
10729 if (json_paths)
10730 json_object_boolean_true_add(json_nexthop_global,
10731 "used");
10732 }
10733
10734 if (safi == SAFI_EVPN &&
10735 bgp_evpn_is_esi_valid(&attr->esi)) {
10736 route_vty_out_detail_es_info(vty, path, attr, json_path);
10737 }
10738
10739 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10740 * Int/Ext/Local, Atomic, best */
10741 if (json_paths)
10742 json_object_string_add(json_path, "origin",
10743 bgp_origin_long_str[attr->origin]);
10744 else
10745 vty_out(vty, " Origin %s",
10746 bgp_origin_long_str[attr->origin]);
10747
10748 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10749 if (json_paths)
10750 json_object_int_add(json_path, "metric", attr->med);
10751 else
10752 vty_out(vty, ", metric %u", attr->med);
10753 }
10754
10755 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10756 if (json_paths)
10757 json_object_int_add(json_path, "locPrf",
10758 attr->local_pref);
10759 else
10760 vty_out(vty, ", localpref %u", attr->local_pref);
10761 }
10762
10763 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
10764 if (json_paths)
10765 json_object_int_add(json_path, "aigpMetric",
10766 bgp_attr_get_aigp_metric(attr));
10767 else
10768 vty_out(vty, ", aigp-metric %" PRIu64,
10769 bgp_attr_get_aigp_metric(attr));
10770 }
10771
10772 if (attr->weight != 0) {
10773 if (json_paths)
10774 json_object_int_add(json_path, "weight", attr->weight);
10775 else
10776 vty_out(vty, ", weight %u", attr->weight);
10777 }
10778
10779 if (attr->tag != 0) {
10780 if (json_paths)
10781 json_object_int_add(json_path, "tag", attr->tag);
10782 else
10783 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10784 }
10785
10786 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10787 if (json_paths)
10788 json_object_boolean_false_add(json_path, "valid");
10789 else
10790 vty_out(vty, ", invalid");
10791 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10792 if (json_paths)
10793 json_object_boolean_true_add(json_path, "valid");
10794 else
10795 vty_out(vty, ", valid");
10796 }
10797
10798 if (json_paths)
10799 json_object_int_add(json_path, "version", bn->version);
10800
10801 if (path->peer != bgp->peer_self) {
10802 if (path->peer->as == path->peer->local_as) {
10803 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10804 if (json_paths)
10805 json_object_string_add(
10806 json_peer, "type",
10807 "confed-internal");
10808 else
10809 vty_out(vty, ", confed-internal");
10810 } else {
10811 if (json_paths)
10812 json_object_string_add(
10813 json_peer, "type", "internal");
10814 else
10815 vty_out(vty, ", internal");
10816 }
10817 } else {
10818 if (bgp_confederation_peers_check(bgp,
10819 path->peer->as)) {
10820 if (json_paths)
10821 json_object_string_add(
10822 json_peer, "type",
10823 "confed-external");
10824 else
10825 vty_out(vty, ", confed-external");
10826 } else {
10827 if (json_paths)
10828 json_object_string_add(
10829 json_peer, "type", "external");
10830 else
10831 vty_out(vty, ", external");
10832 }
10833 }
10834 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10835 if (json_paths) {
10836 json_object_boolean_true_add(json_path, "aggregated");
10837 json_object_boolean_true_add(json_path, "local");
10838 } else {
10839 vty_out(vty, ", aggregated, local");
10840 }
10841 } else if (path->type != ZEBRA_ROUTE_BGP) {
10842 if (json_paths)
10843 json_object_boolean_true_add(json_path, "sourced");
10844 else
10845 vty_out(vty, ", sourced");
10846 } else {
10847 if (json_paths) {
10848 json_object_boolean_true_add(json_path, "sourced");
10849 json_object_boolean_true_add(json_path, "local");
10850 } else {
10851 vty_out(vty, ", sourced, local");
10852 }
10853 }
10854
10855 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10856 if (json_paths)
10857 json_object_boolean_true_add(json_path,
10858 "atomicAggregate");
10859 else
10860 vty_out(vty, ", atomic-aggregate");
10861 }
10862
10863 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10864 if (json_paths)
10865 json_object_int_add(json_path, "otc", attr->otc);
10866 else
10867 vty_out(vty, ", otc %u", attr->otc);
10868 }
10869
10870 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10871 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10872 && bgp_path_info_mpath_count(path))) {
10873 if (json_paths)
10874 json_object_boolean_true_add(json_path, "multipath");
10875 else
10876 vty_out(vty, ", multipath");
10877 }
10878
10879 // Mark the bestpath(s)
10880 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10881 first_as = aspath_get_first_as(attr->aspath);
10882
10883 if (json_paths) {
10884 if (!json_bestpath)
10885 json_bestpath = json_object_new_object();
10886 json_object_int_add(json_bestpath, "bestpathFromAs",
10887 first_as);
10888 } else {
10889 if (first_as)
10890 vty_out(vty, ", bestpath-from-AS %u", first_as);
10891 else
10892 vty_out(vty, ", bestpath-from-AS Local");
10893 }
10894 }
10895
10896 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10897 if (json_paths) {
10898 if (!json_bestpath)
10899 json_bestpath = json_object_new_object();
10900 json_object_boolean_true_add(json_bestpath, "overall");
10901 json_object_string_add(
10902 json_bestpath, "selectionReason",
10903 bgp_path_selection_reason2str(bn->reason));
10904 } else {
10905 vty_out(vty, ", best");
10906 vty_out(vty, " (%s)",
10907 bgp_path_selection_reason2str(bn->reason));
10908 }
10909 }
10910
10911 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10912 if (json_paths)
10913 json_object_string_add(
10914 json_path, "rpkiValidationState",
10915 bgp_rpki_validation2str(rpki_curr_state));
10916 else
10917 vty_out(vty, ", rpki validation-state: %s",
10918 bgp_rpki_validation2str(rpki_curr_state));
10919 }
10920
10921 if (json_bestpath)
10922 json_object_object_add(json_path, "bestpath", json_bestpath);
10923
10924 if (!json_paths)
10925 vty_out(vty, "\n");
10926
10927 /* Line 4 display Community */
10928 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10929 if (json_paths) {
10930 if (!bgp_attr_get_community(attr)->json)
10931 community_str(bgp_attr_get_community(attr),
10932 true, true);
10933 json_object_lock(bgp_attr_get_community(attr)->json);
10934 json_object_object_add(
10935 json_path, "community",
10936 bgp_attr_get_community(attr)->json);
10937 } else {
10938 vty_out(vty, " Community: %s\n",
10939 bgp_attr_get_community(attr)->str);
10940 }
10941 }
10942
10943 /* Line 5 display Extended-community */
10944 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10945 if (json_paths) {
10946 json_ext_community = json_object_new_object();
10947 json_object_string_add(
10948 json_ext_community, "string",
10949 bgp_attr_get_ecommunity(attr)->str);
10950 json_object_object_add(json_path, "extendedCommunity",
10951 json_ext_community);
10952 } else {
10953 vty_out(vty, " Extended Community: %s\n",
10954 bgp_attr_get_ecommunity(attr)->str);
10955 }
10956 }
10957
10958 /* Line 6 display Large community */
10959 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10960 if (json_paths) {
10961 if (!bgp_attr_get_lcommunity(attr)->json)
10962 lcommunity_str(bgp_attr_get_lcommunity(attr),
10963 true, true);
10964 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10965 json_object_object_add(
10966 json_path, "largeCommunity",
10967 bgp_attr_get_lcommunity(attr)->json);
10968 } else {
10969 vty_out(vty, " Large Community: %s\n",
10970 bgp_attr_get_lcommunity(attr)->str);
10971 }
10972 }
10973
10974 /* Line 7 display Originator, Cluster-id */
10975 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10976 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10977 char buf[BUFSIZ] = {0};
10978
10979 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10980 if (json_paths)
10981 json_object_string_addf(json_path,
10982 "originatorId", "%pI4",
10983 &attr->originator_id);
10984 else
10985 vty_out(vty, " Originator: %pI4",
10986 &attr->originator_id);
10987 }
10988
10989 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10990 struct cluster_list *cluster =
10991 bgp_attr_get_cluster(attr);
10992 int i;
10993
10994 if (json_paths) {
10995 json_cluster_list = json_object_new_object();
10996 json_cluster_list_list =
10997 json_object_new_array();
10998
10999 for (i = 0; i < cluster->length / 4; i++) {
11000 json_string = json_object_new_string(
11001 inet_ntop(AF_INET,
11002 &cluster->list[i],
11003 buf, sizeof(buf)));
11004 json_object_array_add(
11005 json_cluster_list_list,
11006 json_string);
11007 }
11008
11009 /*
11010 * struct cluster_list does not have
11011 * "str" variable like aspath and community
11012 * do. Add this someday if someone asks
11013 * for it.
11014 * json_object_string_add(json_cluster_list,
11015 * "string", cluster->str);
11016 */
11017 json_object_object_add(json_cluster_list,
11018 "list",
11019 json_cluster_list_list);
11020 json_object_object_add(json_path, "clusterList",
11021 json_cluster_list);
11022 } else {
11023 vty_out(vty, ", Cluster list: ");
11024
11025 for (i = 0; i < cluster->length / 4; i++) {
11026 vty_out(vty, "%pI4 ",
11027 &cluster->list[i]);
11028 }
11029 }
11030 }
11031
11032 if (!json_paths)
11033 vty_out(vty, "\n");
11034 }
11035
11036 if (path->extra && path->extra->damp_info)
11037 bgp_damp_info_vty(vty, path, afi, safi, json_path);
11038
11039 /* Remote Label */
11040 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
11041 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
11042 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
11043 &bos);
11044
11045 if (json_paths)
11046 json_object_int_add(json_path, "remoteLabel", label);
11047 else
11048 vty_out(vty, " Remote label: %d\n", label);
11049 }
11050
11051 /* Remote SID */
11052 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
11053 if (json_paths)
11054 json_object_string_addf(json_path, "remoteSid", "%pI6",
11055 &path->extra->sid[0].sid);
11056 else
11057 vty_out(vty, " Remote SID: %pI6\n",
11058 &path->extra->sid[0].sid);
11059 }
11060
11061 /* Label Index */
11062 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
11063 if (json_paths)
11064 json_object_int_add(json_path, "labelIndex",
11065 attr->label_index);
11066 else
11067 vty_out(vty, " Label Index: %d\n",
11068 attr->label_index);
11069 }
11070
11071 /* Line 8 display Addpath IDs */
11072 if (path->addpath_rx_id
11073 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
11074 if (json_paths) {
11075 json_object_int_add(json_path, "addpathRxId",
11076 path->addpath_rx_id);
11077
11078 /* Keep backwards compatibility with the old API
11079 * by putting TX All's ID in the old field
11080 */
11081 json_object_int_add(
11082 json_path, "addpathTxId",
11083 path->tx_addpath
11084 .addpath_tx_id[BGP_ADDPATH_ALL]);
11085
11086 /* ... but create a specific field for each
11087 * strategy
11088 */
11089 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
11090 json_object_int_add(
11091 json_path,
11092 bgp_addpath_names(i)->id_json_name,
11093 path->tx_addpath.addpath_tx_id[i]);
11094 }
11095 } else {
11096 vty_out(vty, " AddPath ID: RX %u, ",
11097 path->addpath_rx_id);
11098
11099 route_vty_out_tx_ids(vty, &path->tx_addpath);
11100 }
11101 }
11102
11103 /* If we used addpath to TX a non-bestpath we need to display
11104 * "Advertised to" on a path-by-path basis
11105 */
11106 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11107 first = 1;
11108
11109 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11110 addpath_capable =
11111 bgp_addpath_encode_tx(peer, afi, safi);
11112 has_adj = bgp_adj_out_lookup(
11113 peer, path->net,
11114 bgp_addpath_id_for_peer(peer, afi, safi,
11115 &path->tx_addpath));
11116
11117 if ((addpath_capable && has_adj)
11118 || (!addpath_capable && has_adj
11119 && CHECK_FLAG(path->flags,
11120 BGP_PATH_SELECTED))) {
11121 if (json_path && !json_adv_to)
11122 json_adv_to = json_object_new_object();
11123
11124 route_vty_out_advertised_to(
11125 vty, peer, &first,
11126 " Advertised to:", json_adv_to);
11127 }
11128 }
11129
11130 if (json_path) {
11131 if (json_adv_to) {
11132 json_object_object_add(
11133 json_path, "advertisedTo", json_adv_to);
11134 }
11135 } else {
11136 if (!first) {
11137 vty_out(vty, "\n");
11138 }
11139 }
11140 }
11141
11142 /* Line 9 display Uptime */
11143 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11144 if (json_paths) {
11145 json_last_update = json_object_new_object();
11146 json_object_int_add(json_last_update, "epoch", tbuf);
11147 json_object_string_add(json_last_update, "string",
11148 ctime(&tbuf));
11149 json_object_object_add(json_path, "lastUpdate",
11150 json_last_update);
11151 } else
11152 vty_out(vty, " Last update: %s", ctime(&tbuf));
11153
11154 /* Line 10 display PMSI tunnel attribute, if present */
11155 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11156 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11157 bgp_attr_get_pmsi_tnl_type(attr),
11158 PMSI_TNLTYPE_STR_DEFAULT);
11159
11160 if (json_paths) {
11161 json_pmsi = json_object_new_object();
11162 json_object_string_add(json_pmsi, "tunnelType", str);
11163 json_object_int_add(json_pmsi, "label",
11164 label2vni(&attr->label));
11165 json_object_object_add(json_path, "pmsi", json_pmsi);
11166 } else
11167 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11168 str, label2vni(&attr->label));
11169 }
11170
11171 if (path->peer->t_gr_restart &&
11172 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11173 unsigned long gr_remaining =
11174 thread_timer_remain_second(path->peer->t_gr_restart);
11175
11176 if (json_paths) {
11177 json_object_int_add(json_path,
11178 "gracefulRestartSecondsRemaining",
11179 gr_remaining);
11180 } else
11181 vty_out(vty,
11182 " Time until Graceful Restart stale route deleted: %lu\n",
11183 gr_remaining);
11184 }
11185
11186 if (path->peer->t_llgr_stale[afi][safi] &&
11187 bgp_attr_get_community(attr) &&
11188 community_include(bgp_attr_get_community(attr),
11189 COMMUNITY_LLGR_STALE)) {
11190 unsigned long llgr_remaining = thread_timer_remain_second(
11191 path->peer->t_llgr_stale[afi][safi]);
11192
11193 if (json_paths) {
11194 json_object_int_add(json_path, "llgrSecondsRemaining",
11195 llgr_remaining);
11196 } else
11197 vty_out(vty,
11198 " Time until Long-lived stale route deleted: %lu\n",
11199 llgr_remaining);
11200 }
11201
11202 /* Output some debug about internal state of the dest flags */
11203 if (json_paths) {
11204 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11205 json_object_boolean_true_add(json_path, "processScheduled");
11206 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11207 json_object_boolean_true_add(json_path, "userCleared");
11208 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11209 json_object_boolean_true_add(json_path, "labelChanged");
11210 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11211 json_object_boolean_true_add(json_path, "registeredForLabel");
11212 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11213 json_object_boolean_true_add(json_path, "selectDefered");
11214 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11215 json_object_boolean_true_add(json_path, "fibInstalled");
11216 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11217 json_object_boolean_true_add(json_path, "fibPending");
11218
11219 if (json_nexthop_global || json_nexthop_ll) {
11220 json_nexthops = json_object_new_array();
11221
11222 if (json_nexthop_global)
11223 json_object_array_add(json_nexthops,
11224 json_nexthop_global);
11225
11226 if (json_nexthop_ll)
11227 json_object_array_add(json_nexthops,
11228 json_nexthop_ll);
11229
11230 json_object_object_add(json_path, "nexthops",
11231 json_nexthops);
11232 }
11233
11234 json_object_object_add(json_path, "peer", json_peer);
11235 json_object_array_add(json_paths, json_path);
11236 }
11237 }
11238
11239 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11240 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11241 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11242
11243 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11244 afi_t afi, safi_t safi, enum bgp_show_type type,
11245 bool use_json);
11246 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11247 const char *comstr, int exact, afi_t afi,
11248 safi_t safi, uint16_t show_flags);
11249
11250 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11251 struct bgp_table *table, enum bgp_show_type type,
11252 void *output_arg, const char *rd, int is_last,
11253 unsigned long *output_cum, unsigned long *total_cum,
11254 unsigned long *json_header_depth, uint16_t show_flags,
11255 enum rpki_states rpki_target_state)
11256 {
11257 struct bgp_path_info *pi;
11258 struct bgp_dest *dest;
11259 bool header = true;
11260 bool json_detail_header = false;
11261 int display;
11262 unsigned long output_count = 0;
11263 unsigned long total_count = 0;
11264 struct prefix *p;
11265 json_object *json_paths = NULL;
11266 int first = 1;
11267 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11268 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11269 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11270 bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
11271 bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
11272
11273 if (output_cum && *output_cum != 0)
11274 header = false;
11275
11276 if (use_json && !*json_header_depth) {
11277 if (all)
11278 *json_header_depth = 1;
11279 else {
11280 vty_out(vty, "{\n");
11281 *json_header_depth = 2;
11282 }
11283
11284 vty_out(vty,
11285 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11286 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11287 " \"localAS\": %u,\n \"routes\": { ",
11288 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11289 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11290 ? VRF_DEFAULT_NAME
11291 : bgp->name,
11292 table->version, &bgp->router_id,
11293 bgp->default_local_pref, bgp->as);
11294 if (rd) {
11295 vty_out(vty, " \"routeDistinguishers\" : {");
11296 ++*json_header_depth;
11297 }
11298 }
11299
11300 if (use_json && rd) {
11301 vty_out(vty, " \"%s\" : { ", rd);
11302 }
11303
11304 /* Check for 'json detail', where we need header output once per dest */
11305 if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
11306 type != bgp_show_type_damp_neighbor &&
11307 type != bgp_show_type_flap_statistics &&
11308 type != bgp_show_type_flap_neighbor)
11309 json_detail_header = true;
11310
11311 /* Start processing of routes. */
11312 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11313 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11314 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11315 bool json_detail = json_detail_header;
11316
11317 pi = bgp_dest_get_bgp_path_info(dest);
11318 if (pi == NULL)
11319 continue;
11320
11321 display = 0;
11322 if (use_json)
11323 json_paths = json_object_new_array();
11324 else
11325 json_paths = NULL;
11326
11327 for (; pi; pi = pi->next) {
11328 struct community *picomm = NULL;
11329
11330 picomm = bgp_attr_get_community(pi->attr);
11331
11332 total_count++;
11333
11334 if (type == bgp_show_type_prefix_version) {
11335 uint32_t version =
11336 strtoul(output_arg, NULL, 10);
11337 if (dest->version < version)
11338 continue;
11339 }
11340
11341 if (type == bgp_show_type_community_alias) {
11342 char *alias = output_arg;
11343 char **communities;
11344 int num;
11345 bool found = false;
11346
11347 if (picomm) {
11348 frrstr_split(picomm->str, " ",
11349 &communities, &num);
11350 for (int i = 0; i < num; i++) {
11351 const char *com2alias =
11352 bgp_community2alias(
11353 communities[i]);
11354 if (!found
11355 && strcmp(alias, com2alias)
11356 == 0)
11357 found = true;
11358 XFREE(MTYPE_TMP,
11359 communities[i]);
11360 }
11361 XFREE(MTYPE_TMP, communities);
11362 }
11363
11364 if (!found &&
11365 bgp_attr_get_lcommunity(pi->attr)) {
11366 frrstr_split(bgp_attr_get_lcommunity(
11367 pi->attr)
11368 ->str,
11369 " ", &communities, &num);
11370 for (int i = 0; i < num; i++) {
11371 const char *com2alias =
11372 bgp_community2alias(
11373 communities[i]);
11374 if (!found
11375 && strcmp(alias, com2alias)
11376 == 0)
11377 found = true;
11378 XFREE(MTYPE_TMP,
11379 communities[i]);
11380 }
11381 XFREE(MTYPE_TMP, communities);
11382 }
11383
11384 if (!found)
11385 continue;
11386 }
11387
11388 if (type == bgp_show_type_rpki) {
11389 if (dest_p->family == AF_INET
11390 || dest_p->family == AF_INET6)
11391 rpki_curr_state = hook_call(
11392 bgp_rpki_prefix_status,
11393 pi->peer, pi->attr, dest_p);
11394 if (rpki_target_state != RPKI_NOT_BEING_USED
11395 && rpki_curr_state != rpki_target_state)
11396 continue;
11397 }
11398
11399 if (type == bgp_show_type_flap_statistics
11400 || type == bgp_show_type_flap_neighbor
11401 || type == bgp_show_type_dampend_paths
11402 || type == bgp_show_type_damp_neighbor) {
11403 if (!(pi->extra && pi->extra->damp_info))
11404 continue;
11405 }
11406 if (type == bgp_show_type_regexp) {
11407 regex_t *regex = output_arg;
11408
11409 if (bgp_regexec(regex, pi->attr->aspath)
11410 == REG_NOMATCH)
11411 continue;
11412 }
11413 if (type == bgp_show_type_prefix_list) {
11414 struct prefix_list *plist = output_arg;
11415
11416 if (prefix_list_apply(plist, dest_p)
11417 != PREFIX_PERMIT)
11418 continue;
11419 }
11420 if (type == bgp_show_type_access_list) {
11421 struct access_list *alist = output_arg;
11422
11423 if (access_list_apply(alist, dest_p) !=
11424 FILTER_PERMIT)
11425 continue;
11426 }
11427 if (type == bgp_show_type_filter_list) {
11428 struct as_list *as_list = output_arg;
11429
11430 if (as_list_apply(as_list, pi->attr->aspath)
11431 != AS_FILTER_PERMIT)
11432 continue;
11433 }
11434 if (type == bgp_show_type_route_map) {
11435 struct route_map *rmap = output_arg;
11436 struct bgp_path_info path;
11437 struct bgp_path_info_extra extra;
11438 struct attr dummy_attr = {};
11439 route_map_result_t ret;
11440
11441 dummy_attr = *pi->attr;
11442
11443 prep_for_rmap_apply(&path, &extra, dest, pi,
11444 pi->peer, &dummy_attr);
11445
11446 ret = route_map_apply(rmap, dest_p, &path);
11447 bgp_attr_flush(&dummy_attr);
11448 if (ret == RMAP_DENYMATCH)
11449 continue;
11450 }
11451 if (type == bgp_show_type_neighbor
11452 || type == bgp_show_type_flap_neighbor
11453 || type == bgp_show_type_damp_neighbor) {
11454 union sockunion *su = output_arg;
11455
11456 if (pi->peer == NULL
11457 || pi->peer->su_remote == NULL
11458 || !sockunion_same(pi->peer->su_remote, su))
11459 continue;
11460 }
11461 if (type == bgp_show_type_cidr_only) {
11462 uint32_t destination;
11463
11464 destination = ntohl(dest_p->u.prefix4.s_addr);
11465 if (IN_CLASSC(destination)
11466 && dest_p->prefixlen == 24)
11467 continue;
11468 if (IN_CLASSB(destination)
11469 && dest_p->prefixlen == 16)
11470 continue;
11471 if (IN_CLASSA(destination)
11472 && dest_p->prefixlen == 8)
11473 continue;
11474 }
11475 if (type == bgp_show_type_prefix_longer) {
11476 p = output_arg;
11477 if (!prefix_match(p, dest_p))
11478 continue;
11479 }
11480 if (type == bgp_show_type_community_all) {
11481 if (!picomm)
11482 continue;
11483 }
11484 if (type == bgp_show_type_community) {
11485 struct community *com = output_arg;
11486
11487 if (!picomm || !community_match(picomm, com))
11488 continue;
11489 }
11490 if (type == bgp_show_type_community_exact) {
11491 struct community *com = output_arg;
11492
11493 if (!picomm || !community_cmp(picomm, com))
11494 continue;
11495 }
11496 if (type == bgp_show_type_community_list) {
11497 struct community_list *list = output_arg;
11498
11499 if (!community_list_match(picomm, list))
11500 continue;
11501 }
11502 if (type == bgp_show_type_community_list_exact) {
11503 struct community_list *list = output_arg;
11504
11505 if (!community_list_exact_match(picomm, list))
11506 continue;
11507 }
11508 if (type == bgp_show_type_lcommunity) {
11509 struct lcommunity *lcom = output_arg;
11510
11511 if (!bgp_attr_get_lcommunity(pi->attr) ||
11512 !lcommunity_match(
11513 bgp_attr_get_lcommunity(pi->attr),
11514 lcom))
11515 continue;
11516 }
11517
11518 if (type == bgp_show_type_lcommunity_exact) {
11519 struct lcommunity *lcom = output_arg;
11520
11521 if (!bgp_attr_get_lcommunity(pi->attr) ||
11522 !lcommunity_cmp(
11523 bgp_attr_get_lcommunity(pi->attr),
11524 lcom))
11525 continue;
11526 }
11527 if (type == bgp_show_type_lcommunity_list) {
11528 struct community_list *list = output_arg;
11529
11530 if (!lcommunity_list_match(
11531 bgp_attr_get_lcommunity(pi->attr),
11532 list))
11533 continue;
11534 }
11535 if (type
11536 == bgp_show_type_lcommunity_list_exact) {
11537 struct community_list *list = output_arg;
11538
11539 if (!lcommunity_list_exact_match(
11540 bgp_attr_get_lcommunity(pi->attr),
11541 list))
11542 continue;
11543 }
11544 if (type == bgp_show_type_lcommunity_all) {
11545 if (!bgp_attr_get_lcommunity(pi->attr))
11546 continue;
11547 }
11548 if (type == bgp_show_type_dampend_paths
11549 || type == bgp_show_type_damp_neighbor) {
11550 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11551 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11552 continue;
11553 }
11554
11555 if (!use_json && header) {
11556 vty_out(vty,
11557 "BGP table version is %" PRIu64
11558 ", local router ID is %pI4, vrf id ",
11559 table->version, &bgp->router_id);
11560 if (bgp->vrf_id == VRF_UNKNOWN)
11561 vty_out(vty, "%s", VRFID_NONE_STR);
11562 else
11563 vty_out(vty, "%u", bgp->vrf_id);
11564 vty_out(vty, "\n");
11565 vty_out(vty, "Default local pref %u, ",
11566 bgp->default_local_pref);
11567 vty_out(vty, "local AS %u\n", bgp->as);
11568 if (!detail_routes) {
11569 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11570 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11571 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11572 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11573 }
11574 if (type == bgp_show_type_dampend_paths
11575 || type == bgp_show_type_damp_neighbor)
11576 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11577 else if (type == bgp_show_type_flap_statistics
11578 || type == bgp_show_type_flap_neighbor)
11579 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11580 else if (!detail_routes)
11581 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11582 : BGP_SHOW_HEADER));
11583 header = false;
11584
11585 } else if (json_detail && json_paths != NULL) {
11586 const struct prefix_rd *prd;
11587 json_object *jtemp;
11588
11589 /* Use common detail header, for most types;
11590 * need a json 'object'.
11591 */
11592
11593 jtemp = json_object_new_object();
11594 prd = bgp_rd_from_dest(dest, safi);
11595
11596 route_vty_out_detail_header(
11597 vty, bgp, dest,
11598 bgp_dest_get_prefix(dest), prd,
11599 table->afi, safi, jtemp);
11600
11601 json_object_array_add(json_paths, jtemp);
11602
11603 json_detail = false;
11604 }
11605
11606 if (rd != NULL && !display && !output_count) {
11607 if (!use_json)
11608 vty_out(vty,
11609 "Route Distinguisher: %s\n",
11610 rd);
11611 }
11612 if (type == bgp_show_type_dampend_paths
11613 || type == bgp_show_type_damp_neighbor)
11614 damp_route_vty_out(vty, dest_p, pi, display,
11615 AFI_IP, safi, use_json,
11616 json_paths);
11617 else if (type == bgp_show_type_flap_statistics
11618 || type == bgp_show_type_flap_neighbor)
11619 flap_route_vty_out(vty, dest_p, pi, display,
11620 AFI_IP, safi, use_json,
11621 json_paths);
11622 else {
11623 if (detail_routes || detail_json) {
11624 const struct prefix_rd *prd = NULL;
11625
11626 if (dest->pdest)
11627 prd = bgp_rd_from_dest(
11628 dest->pdest, safi);
11629
11630 if (!use_json)
11631 route_vty_out_detail_header(
11632 vty, bgp, dest,
11633 bgp_dest_get_prefix(
11634 dest),
11635 prd, table->afi, safi,
11636 NULL);
11637
11638 route_vty_out_detail(
11639 vty, bgp, dest, dest_p, pi,
11640 family2afi(dest_p->family),
11641 safi, RPKI_NOT_BEING_USED,
11642 json_paths);
11643 } else {
11644 route_vty_out(vty, dest_p, pi, display,
11645 safi, json_paths, wide);
11646 }
11647 }
11648 display++;
11649 }
11650
11651 if (display) {
11652 output_count++;
11653 if (!use_json)
11654 continue;
11655
11656 /* encode prefix */
11657 if (dest_p->family == AF_FLOWSPEC) {
11658 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11659
11660
11661 bgp_fs_nlri_get_string(
11662 (unsigned char *)
11663 dest_p->u.prefix_flowspec.ptr,
11664 dest_p->u.prefix_flowspec.prefixlen,
11665 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11666 family2afi(dest_p->u
11667 .prefix_flowspec.family));
11668 if (first)
11669 vty_out(vty, "\"%s/%d\": ", retstr,
11670 dest_p->u.prefix_flowspec
11671 .prefixlen);
11672 else
11673 vty_out(vty, ",\"%s/%d\": ", retstr,
11674 dest_p->u.prefix_flowspec
11675 .prefixlen);
11676 } else {
11677 if (first)
11678 vty_out(vty, "\"%pFX\": ", dest_p);
11679 else
11680 vty_out(vty, ",\"%pFX\": ", dest_p);
11681 }
11682 vty_json(vty, json_paths);
11683 json_paths = NULL;
11684 first = 0;
11685 } else
11686 json_object_free(json_paths);
11687 }
11688
11689 if (output_cum) {
11690 output_count += *output_cum;
11691 *output_cum = output_count;
11692 }
11693 if (total_cum) {
11694 total_count += *total_cum;
11695 *total_cum = total_count;
11696 }
11697 if (use_json) {
11698 if (rd) {
11699 vty_out(vty, " }%s ", (is_last ? "" : ","));
11700 }
11701 if (is_last) {
11702 unsigned long i;
11703 for (i = 0; i < *json_header_depth; ++i)
11704 vty_out(vty, " } ");
11705 if (!all)
11706 vty_out(vty, "\n");
11707 }
11708 } else {
11709 if (is_last) {
11710 /* No route is displayed */
11711 if (output_count == 0) {
11712 if (type == bgp_show_type_normal)
11713 vty_out(vty,
11714 "No BGP prefixes displayed, %ld exist\n",
11715 total_count);
11716 } else
11717 vty_out(vty,
11718 "\nDisplayed %ld routes and %ld total paths\n",
11719 output_count, total_count);
11720 }
11721 }
11722
11723 return CMD_SUCCESS;
11724 }
11725
11726 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11727 struct bgp_table *table, struct prefix_rd *prd_match,
11728 enum bgp_show_type type, void *output_arg,
11729 uint16_t show_flags)
11730 {
11731 struct bgp_dest *dest, *next;
11732 unsigned long output_cum = 0;
11733 unsigned long total_cum = 0;
11734 unsigned long json_header_depth = 0;
11735 struct bgp_table *itable;
11736 bool show_msg;
11737 bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11738
11739 show_msg = (!use_json && type == bgp_show_type_normal);
11740
11741 for (dest = bgp_table_top(table); dest; dest = next) {
11742 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11743
11744 next = bgp_route_next(dest);
11745 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11746 continue;
11747
11748 itable = bgp_dest_get_bgp_table_info(dest);
11749 if (itable != NULL) {
11750 struct prefix_rd prd;
11751 char rd[RD_ADDRSTRLEN];
11752
11753 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11754 prefix_rd2str(&prd, rd, sizeof(rd));
11755 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11756 rd, next == NULL, &output_cum,
11757 &total_cum, &json_header_depth,
11758 show_flags, RPKI_NOT_BEING_USED);
11759 if (next == NULL)
11760 show_msg = false;
11761 }
11762 }
11763 if (show_msg) {
11764 if (output_cum == 0)
11765 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11766 total_cum);
11767 else
11768 vty_out(vty,
11769 "\nDisplayed %ld routes and %ld total paths\n",
11770 output_cum, total_cum);
11771 } else {
11772 if (use_json && output_cum == 0)
11773 vty_out(vty, "{}\n");
11774 }
11775 return CMD_SUCCESS;
11776 }
11777
11778 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11779 enum bgp_show_type type, void *output_arg,
11780 uint16_t show_flags, enum rpki_states rpki_target_state)
11781 {
11782 struct bgp_table *table;
11783 unsigned long json_header_depth = 0;
11784 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11785
11786 if (bgp == NULL) {
11787 bgp = bgp_get_default();
11788 }
11789
11790 if (bgp == NULL) {
11791 if (!use_json)
11792 vty_out(vty, "No BGP process is configured\n");
11793 else
11794 vty_out(vty, "{}\n");
11795 return CMD_WARNING;
11796 }
11797
11798 /* Labeled-unicast routes live in the unicast table. */
11799 if (safi == SAFI_LABELED_UNICAST)
11800 safi = SAFI_UNICAST;
11801
11802 table = bgp->rib[afi][safi];
11803 /* use MPLS and ENCAP specific shows until they are merged */
11804 if (safi == SAFI_MPLS_VPN) {
11805 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11806 output_arg, show_flags);
11807 }
11808
11809 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11810 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11811 output_arg, use_json,
11812 1, NULL, NULL);
11813 }
11814
11815 if (safi == SAFI_EVPN)
11816 return bgp_evpn_show_all_routes(vty, bgp, type, use_json, 0);
11817
11818 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11819 NULL, NULL, &json_header_depth, show_flags,
11820 rpki_target_state);
11821 }
11822
11823 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11824 safi_t safi, uint16_t show_flags)
11825 {
11826 struct listnode *node, *nnode;
11827 struct bgp *bgp;
11828 int is_first = 1;
11829 bool route_output = false;
11830 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11831
11832 if (use_json)
11833 vty_out(vty, "{\n");
11834
11835 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11836 route_output = true;
11837 if (use_json) {
11838 if (!is_first)
11839 vty_out(vty, ",\n");
11840 else
11841 is_first = 0;
11842
11843 vty_out(vty, "\"%s\":",
11844 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11845 ? VRF_DEFAULT_NAME
11846 : bgp->name);
11847 } else {
11848 vty_out(vty, "\nInstance %s:\n",
11849 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11850 ? VRF_DEFAULT_NAME
11851 : bgp->name);
11852 }
11853 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11854 show_flags, RPKI_NOT_BEING_USED);
11855 }
11856
11857 if (use_json)
11858 vty_out(vty, "}\n");
11859 else if (!route_output)
11860 vty_out(vty, "%% BGP instance not found\n");
11861 }
11862
11863 /* Header of detailed BGP route information */
11864 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11865 struct bgp_dest *dest, const struct prefix *p,
11866 const struct prefix_rd *prd, afi_t afi,
11867 safi_t safi, json_object *json)
11868 {
11869 struct bgp_path_info *pi;
11870 struct peer *peer;
11871 struct listnode *node, *nnode;
11872 char buf1[RD_ADDRSTRLEN];
11873 int count = 0;
11874 int best = 0;
11875 int suppress = 0;
11876 int accept_own = 0;
11877 int route_filter_translated_v4 = 0;
11878 int route_filter_v4 = 0;
11879 int route_filter_translated_v6 = 0;
11880 int route_filter_v6 = 0;
11881 int llgr_stale = 0;
11882 int no_llgr = 0;
11883 int accept_own_nexthop = 0;
11884 int blackhole = 0;
11885 int no_export = 0;
11886 int no_advertise = 0;
11887 int local_as = 0;
11888 int no_peer = 0;
11889 int first = 1;
11890 int has_valid_label = 0;
11891 mpls_label_t label = 0;
11892 json_object *json_adv_to = NULL;
11893 uint32_t ttl = 0;
11894 uint32_t bos = 0;
11895 uint32_t exp = 0;
11896
11897 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11898
11899 has_valid_label = bgp_is_valid_label(&label);
11900
11901 if (safi == SAFI_EVPN) {
11902 if (!json) {
11903 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11904 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
11905 : "",
11906 prd ? ":" : "", (struct prefix_evpn *)p);
11907 } else {
11908 json_object_string_add(json, "rd",
11909 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11910 "");
11911 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11912 }
11913 } else {
11914 if (!json) {
11915 vty_out(vty,
11916 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11917 "\n",
11918 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11919 ? prefix_rd2str(prd, buf1,
11920 sizeof(buf1))
11921 : ""),
11922 safi == SAFI_MPLS_VPN ? ":" : "", p,
11923 dest->version);
11924
11925 } else {
11926 json_object_string_addf(json, "prefix", "%pFX", p);
11927 json_object_int_add(json, "version", dest->version);
11928
11929 }
11930 }
11931
11932 if (has_valid_label) {
11933 if (json)
11934 json_object_int_add(json, "localLabel", label);
11935 else
11936 vty_out(vty, "Local label: %d\n", label);
11937 }
11938
11939 if (!json)
11940 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11941 vty_out(vty, "not allocated\n");
11942
11943 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11944 struct community *picomm = NULL;
11945
11946 picomm = bgp_attr_get_community(pi->attr);
11947
11948 count++;
11949 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11950 best = count;
11951 if (bgp_path_suppressed(pi))
11952 suppress = 1;
11953
11954 if (!picomm)
11955 continue;
11956
11957 no_advertise += community_include(
11958 picomm, COMMUNITY_NO_ADVERTISE);
11959 no_export +=
11960 community_include(picomm, COMMUNITY_NO_EXPORT);
11961 local_as +=
11962 community_include(picomm, COMMUNITY_LOCAL_AS);
11963 accept_own +=
11964 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11965 route_filter_translated_v4 += community_include(
11966 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11967 route_filter_translated_v6 += community_include(
11968 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11969 route_filter_v4 += community_include(
11970 picomm, COMMUNITY_ROUTE_FILTER_v4);
11971 route_filter_v6 += community_include(
11972 picomm, COMMUNITY_ROUTE_FILTER_v6);
11973 llgr_stale +=
11974 community_include(picomm, COMMUNITY_LLGR_STALE);
11975 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11976 accept_own_nexthop += community_include(
11977 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11978 blackhole +=
11979 community_include(picomm, COMMUNITY_BLACKHOLE);
11980 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11981 }
11982 }
11983
11984 if (!json) {
11985 vty_out(vty, "Paths: (%d available", count);
11986 if (best) {
11987 vty_out(vty, ", best #%d", best);
11988 if (safi == SAFI_UNICAST) {
11989 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11990 vty_out(vty, ", table %s",
11991 VRF_DEFAULT_NAME);
11992 else
11993 vty_out(vty, ", vrf %s",
11994 bgp->name);
11995 }
11996 } else
11997 vty_out(vty, ", no best path");
11998
11999 if (accept_own)
12000 vty_out(vty,
12001 ", accept own local route exported and imported in different VRF");
12002 else if (route_filter_translated_v4)
12003 vty_out(vty,
12004 ", mark translated RTs for VPNv4 route filtering");
12005 else if (route_filter_v4)
12006 vty_out(vty,
12007 ", attach RT as-is for VPNv4 route filtering");
12008 else if (route_filter_translated_v6)
12009 vty_out(vty,
12010 ", mark translated RTs for VPNv6 route filtering");
12011 else if (route_filter_v6)
12012 vty_out(vty,
12013 ", attach RT as-is for VPNv6 route filtering");
12014 else if (llgr_stale)
12015 vty_out(vty,
12016 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
12017 else if (no_llgr)
12018 vty_out(vty,
12019 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
12020 else if (accept_own_nexthop)
12021 vty_out(vty,
12022 ", accept local nexthop");
12023 else if (blackhole)
12024 vty_out(vty, ", inform peer to blackhole prefix");
12025 else if (no_export)
12026 vty_out(vty, ", not advertised to EBGP peer");
12027 else if (no_advertise)
12028 vty_out(vty, ", not advertised to any peer");
12029 else if (local_as)
12030 vty_out(vty, ", not advertised outside local AS");
12031 else if (no_peer)
12032 vty_out(vty,
12033 ", inform EBGP peer not to advertise to their EBGP peers");
12034
12035 if (suppress)
12036 vty_out(vty,
12037 ", Advertisements suppressed by an aggregate.");
12038 vty_out(vty, ")\n");
12039 }
12040
12041 /* If we are not using addpath then we can display Advertised to and
12042 * that will
12043 * show what peers we advertised the bestpath to. If we are using
12044 * addpath
12045 * though then we must display Advertised to on a path-by-path basis. */
12046 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
12047 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
12048 if (bgp_adj_out_lookup(peer, dest, 0)) {
12049 if (json && !json_adv_to)
12050 json_adv_to = json_object_new_object();
12051
12052 route_vty_out_advertised_to(
12053 vty, peer, &first,
12054 " Advertised to non peer-group peers:\n ",
12055 json_adv_to);
12056 }
12057 }
12058
12059 if (json) {
12060 if (json_adv_to) {
12061 json_object_object_add(json, "advertisedTo",
12062 json_adv_to);
12063 }
12064 } else {
12065 if (first)
12066 vty_out(vty, " Not advertised to any peer");
12067 vty_out(vty, "\n");
12068 }
12069 }
12070 }
12071
12072 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
12073 struct bgp_dest *bgp_node, struct vty *vty,
12074 struct bgp *bgp, afi_t afi, safi_t safi,
12075 json_object *json, enum bgp_path_type pathtype,
12076 int *display, enum rpki_states rpki_target_state)
12077 {
12078 struct bgp_path_info *pi;
12079 int header = 1;
12080 json_object *json_header = NULL;
12081 json_object *json_paths = NULL;
12082 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
12083
12084 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
12085 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
12086
12087 if (p->family == AF_INET || p->family == AF_INET6)
12088 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
12089 pi->peer, pi->attr, p);
12090
12091 if (rpki_target_state != RPKI_NOT_BEING_USED
12092 && rpki_curr_state != rpki_target_state)
12093 continue;
12094
12095 if (json && !json_paths) {
12096 /* Instantiate json_paths only if path is valid */
12097 json_paths = json_object_new_array();
12098 if (pfx_rd)
12099 json_header = json_object_new_object();
12100 else
12101 json_header = json;
12102 }
12103
12104 if (header) {
12105 route_vty_out_detail_header(
12106 vty, bgp, bgp_node,
12107 bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP,
12108 safi, json_header);
12109 header = 0;
12110 }
12111 (*display)++;
12112
12113 if (pathtype == BGP_PATH_SHOW_ALL
12114 || (pathtype == BGP_PATH_SHOW_BESTPATH
12115 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12116 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12117 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12118 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12119 route_vty_out_detail(vty, bgp, bgp_node,
12120 bgp_dest_get_prefix(bgp_node), pi,
12121 AFI_IP, safi, rpki_curr_state,
12122 json_paths);
12123 }
12124
12125 if (json && json_paths) {
12126 json_object_object_add(json_header, "paths", json_paths);
12127
12128 if (pfx_rd)
12129 json_object_object_addf(json, json_header, "%pRD",
12130 pfx_rd);
12131 }
12132 }
12133
12134 /*
12135 * Return rd based on safi
12136 */
12137 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12138 safi_t safi)
12139 {
12140 switch (safi) {
12141 case SAFI_MPLS_VPN:
12142 case SAFI_ENCAP:
12143 case SAFI_EVPN:
12144 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12145 default:
12146 return NULL;
12147 }
12148 }
12149
12150 /* Display specified route of BGP table. */
12151 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12152 struct bgp_table *rib, const char *ip_str,
12153 afi_t afi, safi_t safi,
12154 enum rpki_states rpki_target_state,
12155 struct prefix_rd *prd, int prefix_check,
12156 enum bgp_path_type pathtype, bool use_json)
12157 {
12158 int ret;
12159 int display = 0;
12160 struct prefix match;
12161 struct bgp_dest *dest;
12162 struct bgp_dest *rm;
12163 struct bgp_table *table;
12164 json_object *json = NULL;
12165 json_object *json_paths = NULL;
12166
12167 /* Check IP address argument. */
12168 ret = str2prefix(ip_str, &match);
12169 if (!ret) {
12170 vty_out(vty, "address is malformed\n");
12171 return CMD_WARNING;
12172 }
12173
12174 match.family = afi2family(afi);
12175
12176 if (use_json)
12177 json = json_object_new_object();
12178
12179 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12180 for (dest = bgp_table_top(rib); dest;
12181 dest = bgp_route_next(dest)) {
12182 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12183
12184 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12185 continue;
12186 table = bgp_dest_get_bgp_table_info(dest);
12187 if (!table)
12188 continue;
12189
12190 rm = bgp_node_match(table, &match);
12191 if (rm == NULL)
12192 continue;
12193
12194 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12195 if (prefix_check
12196 && rm_p->prefixlen != match.prefixlen) {
12197 bgp_dest_unlock_node(rm);
12198 continue;
12199 }
12200
12201 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12202 bgp, afi, safi, json, pathtype,
12203 &display, rpki_target_state);
12204
12205 bgp_dest_unlock_node(rm);
12206 }
12207 } else if (safi == SAFI_EVPN) {
12208 struct bgp_dest *longest_pfx;
12209 bool is_exact_pfxlen_match = false;
12210
12211 for (dest = bgp_table_top(rib); dest;
12212 dest = bgp_route_next(dest)) {
12213 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12214
12215 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12216 continue;
12217 table = bgp_dest_get_bgp_table_info(dest);
12218 if (!table)
12219 continue;
12220
12221 longest_pfx = NULL;
12222 is_exact_pfxlen_match = false;
12223 /*
12224 * Search through all the prefixes for a match. The
12225 * pfx's are enumerated in ascending order of pfxlens.
12226 * So, the last pfx match is the longest match. Set
12227 * is_exact_pfxlen_match when we get exact pfxlen match
12228 */
12229 for (rm = bgp_table_top(table); rm;
12230 rm = bgp_route_next(rm)) {
12231 const struct prefix *rm_p =
12232 bgp_dest_get_prefix(rm);
12233 /*
12234 * Get prefixlen of the ip-prefix within type5
12235 * evpn route
12236 */
12237 if (evpn_type5_prefix_match(rm_p, &match)
12238 && rm->info) {
12239 longest_pfx = rm;
12240 int type5_pfxlen =
12241 bgp_evpn_get_type5_prefixlen(
12242 rm_p);
12243 if (type5_pfxlen == match.prefixlen) {
12244 is_exact_pfxlen_match = true;
12245 bgp_dest_unlock_node(rm);
12246 break;
12247 }
12248 }
12249 }
12250
12251 if (!longest_pfx)
12252 continue;
12253
12254 if (prefix_check && !is_exact_pfxlen_match)
12255 continue;
12256
12257 rm = longest_pfx;
12258 bgp_dest_lock_node(rm);
12259
12260 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12261 bgp, afi, safi, json, pathtype,
12262 &display, rpki_target_state);
12263
12264 bgp_dest_unlock_node(rm);
12265 }
12266 } else if (safi == SAFI_FLOWSPEC) {
12267 if (use_json)
12268 json_paths = json_object_new_array();
12269
12270 display = bgp_flowspec_display_match_per_ip(afi, rib,
12271 &match, prefix_check,
12272 vty,
12273 use_json,
12274 json_paths);
12275 if (use_json) {
12276 if (display)
12277 json_object_object_add(json, "paths",
12278 json_paths);
12279 else
12280 json_object_free(json_paths);
12281 }
12282 } else {
12283 dest = bgp_node_match(rib, &match);
12284 if (dest != NULL) {
12285 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12286 if (!prefix_check
12287 || dest_p->prefixlen == match.prefixlen) {
12288 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12289 safi, json, pathtype,
12290 &display, rpki_target_state);
12291 }
12292
12293 bgp_dest_unlock_node(dest);
12294 }
12295 }
12296
12297 if (use_json) {
12298 vty_json(vty, json);
12299 } else {
12300 if (!display) {
12301 vty_out(vty, "%% Network not in table\n");
12302 return CMD_WARNING;
12303 }
12304 }
12305
12306 return CMD_SUCCESS;
12307 }
12308
12309 /* Display specified route of Main RIB */
12310 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12311 afi_t afi, safi_t safi, struct prefix_rd *prd,
12312 int prefix_check, enum bgp_path_type pathtype,
12313 enum rpki_states rpki_target_state, bool use_json)
12314 {
12315 if (!bgp) {
12316 bgp = bgp_get_default();
12317 if (!bgp) {
12318 if (!use_json)
12319 vty_out(vty, "No BGP process is configured\n");
12320 else
12321 vty_out(vty, "{}\n");
12322 return CMD_WARNING;
12323 }
12324 }
12325
12326 /* labeled-unicast routes live in the unicast table */
12327 if (safi == SAFI_LABELED_UNICAST)
12328 safi = SAFI_UNICAST;
12329
12330 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12331 afi, safi, rpki_target_state, prd,
12332 prefix_check, pathtype, use_json);
12333 }
12334
12335 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12336 struct cmd_token **argv, bool exact, afi_t afi,
12337 safi_t safi, bool uj)
12338 {
12339 struct lcommunity *lcom;
12340 struct buffer *b;
12341 int i;
12342 char *str;
12343 int first = 0;
12344 uint16_t show_flags = 0;
12345 int ret;
12346
12347 if (uj)
12348 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12349
12350 b = buffer_new(1024);
12351 for (i = 0; i < argc; i++) {
12352 if (first)
12353 buffer_putc(b, ' ');
12354 else {
12355 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12356 first = 1;
12357 buffer_putstr(b, argv[i]->arg);
12358 }
12359 }
12360 }
12361 buffer_putc(b, '\0');
12362
12363 str = buffer_getstr(b);
12364 buffer_free(b);
12365
12366 lcom = lcommunity_str2com(str);
12367 XFREE(MTYPE_TMP, str);
12368 if (!lcom) {
12369 vty_out(vty, "%% Large-community malformed\n");
12370 return CMD_WARNING;
12371 }
12372
12373 ret = bgp_show(vty, bgp, afi, safi,
12374 (exact ? bgp_show_type_lcommunity_exact
12375 : bgp_show_type_lcommunity),
12376 lcom, show_flags, RPKI_NOT_BEING_USED);
12377
12378 lcommunity_free(&lcom);
12379 return ret;
12380 }
12381
12382 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12383 const char *lcom, bool exact, afi_t afi,
12384 safi_t safi, bool uj)
12385 {
12386 struct community_list *list;
12387 uint16_t show_flags = 0;
12388
12389 if (uj)
12390 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12391
12392
12393 list = community_list_lookup(bgp_clist, lcom, 0,
12394 LARGE_COMMUNITY_LIST_MASTER);
12395 if (list == NULL) {
12396 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12397 lcom);
12398 return CMD_WARNING;
12399 }
12400
12401 return bgp_show(vty, bgp, afi, safi,
12402 (exact ? bgp_show_type_lcommunity_list_exact
12403 : bgp_show_type_lcommunity_list),
12404 list, show_flags, RPKI_NOT_BEING_USED);
12405 }
12406
12407 DEFUN (show_ip_bgp_large_community_list,
12408 show_ip_bgp_large_community_list_cmd,
12409 "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]",
12410 SHOW_STR
12411 IP_STR
12412 BGP_STR
12413 BGP_INSTANCE_HELP_STR
12414 BGP_AFI_HELP_STR
12415 BGP_SAFI_WITH_LABEL_HELP_STR
12416 "Display routes matching the large-community-list\n"
12417 "large-community-list number\n"
12418 "large-community-list name\n"
12419 "Exact match of the large-communities\n"
12420 JSON_STR)
12421 {
12422 afi_t afi = AFI_IP6;
12423 safi_t safi = SAFI_UNICAST;
12424 int idx = 0;
12425 bool exact_match = 0;
12426 struct bgp *bgp = NULL;
12427 bool uj = use_json(argc, argv);
12428
12429 if (uj)
12430 argc--;
12431
12432 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12433 &bgp, uj);
12434 if (!idx)
12435 return CMD_WARNING;
12436
12437 argv_find(argv, argc, "large-community-list", &idx);
12438
12439 const char *clist_number_or_name = argv[++idx]->arg;
12440
12441 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12442 exact_match = 1;
12443
12444 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12445 exact_match, afi, safi, uj);
12446 }
12447 DEFUN (show_ip_bgp_large_community,
12448 show_ip_bgp_large_community_cmd,
12449 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12450 SHOW_STR
12451 IP_STR
12452 BGP_STR
12453 BGP_INSTANCE_HELP_STR
12454 BGP_AFI_HELP_STR
12455 BGP_SAFI_WITH_LABEL_HELP_STR
12456 "Display routes matching the large-communities\n"
12457 "List of large-community numbers\n"
12458 "Exact match of the large-communities\n"
12459 JSON_STR)
12460 {
12461 afi_t afi = AFI_IP6;
12462 safi_t safi = SAFI_UNICAST;
12463 int idx = 0;
12464 bool exact_match = 0;
12465 struct bgp *bgp = NULL;
12466 bool uj = use_json(argc, argv);
12467 uint16_t show_flags = 0;
12468
12469 if (uj) {
12470 argc--;
12471 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12472 }
12473
12474 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12475 &bgp, uj);
12476 if (!idx)
12477 return CMD_WARNING;
12478
12479 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12480 if (argv_find(argv, argc, "exact-match", &idx)) {
12481 argc--;
12482 exact_match = 1;
12483 }
12484 return bgp_show_lcommunity(vty, bgp, argc, argv,
12485 exact_match, afi, safi, uj);
12486 } else
12487 return bgp_show(vty, bgp, afi, safi,
12488 bgp_show_type_lcommunity_all, NULL, show_flags,
12489 RPKI_NOT_BEING_USED);
12490 }
12491
12492 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12493 safi_t safi, struct json_object *json_array);
12494 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12495 safi_t safi, struct json_object *json);
12496
12497
12498 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12499 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12500 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12501 "Display number of prefixes for all afi/safi\n" JSON_STR)
12502 {
12503 bool uj = use_json(argc, argv);
12504 struct bgp *bgp = NULL;
12505 safi_t safi = SAFI_UNICAST;
12506 afi_t afi = AFI_IP6;
12507 int idx = 0;
12508 struct json_object *json_all = NULL;
12509 struct json_object *json_afi_safi = NULL;
12510
12511 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12512 &bgp, false);
12513 if (!idx)
12514 return CMD_WARNING;
12515
12516 if (uj)
12517 json_all = json_object_new_object();
12518
12519 FOREACH_AFI_SAFI (afi, safi) {
12520 /*
12521 * So limit output to those afi/safi pairs that
12522 * actually have something interesting in them
12523 */
12524 if (strmatch(get_afi_safi_str(afi, safi, true),
12525 "Unknown")) {
12526 continue;
12527 }
12528 if (uj) {
12529 json_afi_safi = json_object_new_array();
12530 json_object_object_add(
12531 json_all,
12532 get_afi_safi_str(afi, safi, true),
12533 json_afi_safi);
12534 } else {
12535 json_afi_safi = NULL;
12536 }
12537
12538 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12539 }
12540
12541 if (uj)
12542 vty_json(vty, json_all);
12543
12544 return CMD_SUCCESS;
12545 }
12546
12547 /* BGP route print out function without JSON */
12548 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12549 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12550 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12551 SHOW_STR
12552 IP_STR
12553 BGP_STR
12554 BGP_INSTANCE_HELP_STR
12555 L2VPN_HELP_STR
12556 EVPN_HELP_STR
12557 "BGP RIB advertisement statistics\n"
12558 JSON_STR)
12559 {
12560 afi_t afi = AFI_IP6;
12561 safi_t safi = SAFI_UNICAST;
12562 struct bgp *bgp = NULL;
12563 int idx = 0, ret;
12564 bool uj = use_json(argc, argv);
12565 struct json_object *json_afi_safi = NULL, *json = NULL;
12566
12567 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12568 &bgp, false);
12569 if (!idx)
12570 return CMD_WARNING;
12571
12572 if (uj)
12573 json_afi_safi = json_object_new_array();
12574 else
12575 json_afi_safi = NULL;
12576
12577 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12578
12579 if (uj) {
12580 json = json_object_new_object();
12581 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12582 json_afi_safi);
12583 vty_json(vty, json);
12584 }
12585 return ret;
12586 }
12587
12588 /* BGP route print out function without JSON */
12589 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12590 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12591 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12592 "]]\
12593 statistics [json]",
12594 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12595 BGP_SAFI_WITH_LABEL_HELP_STR
12596 "BGP RIB advertisement statistics\n" JSON_STR)
12597 {
12598 afi_t afi = AFI_IP6;
12599 safi_t safi = SAFI_UNICAST;
12600 struct bgp *bgp = NULL;
12601 int idx = 0, ret;
12602 bool uj = use_json(argc, argv);
12603 struct json_object *json_afi_safi = NULL, *json = NULL;
12604
12605 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12606 &bgp, false);
12607 if (!idx)
12608 return CMD_WARNING;
12609
12610 if (uj)
12611 json_afi_safi = json_object_new_array();
12612 else
12613 json_afi_safi = NULL;
12614
12615 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12616
12617 if (uj) {
12618 json = json_object_new_object();
12619 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12620 json_afi_safi);
12621 vty_json(vty, json);
12622 }
12623 return ret;
12624 }
12625
12626 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12627 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12628 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12629 "]] [all$all] dampening parameters [json]",
12630 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12631 BGP_SAFI_WITH_LABEL_HELP_STR
12632 "Display the entries for all address families\n"
12633 "Display detailed information about dampening\n"
12634 "Display detail of configured dampening parameters\n"
12635 JSON_STR)
12636 {
12637 afi_t afi = AFI_IP6;
12638 safi_t safi = SAFI_UNICAST;
12639 struct bgp *bgp = NULL;
12640 int idx = 0;
12641 uint16_t show_flags = 0;
12642 bool uj = use_json(argc, argv);
12643
12644 if (uj) {
12645 argc--;
12646 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12647 }
12648
12649 /* [<ipv4|ipv6> [all]] */
12650 if (all) {
12651 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12652 if (argv_find(argv, argc, "ipv4", &idx))
12653 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12654
12655 if (argv_find(argv, argc, "ipv6", &idx))
12656 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12657 }
12658
12659 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12660 &bgp, false);
12661 if (!idx)
12662 return CMD_WARNING;
12663
12664 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12665 }
12666
12667 /* BGP route print out function */
12668 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12669 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12670 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12671 "]]\
12672 [all$all]\
12673 [cidr-only\
12674 |dampening <flap-statistics|dampened-paths>\
12675 |community [AA:NN|local-AS|no-advertise|no-export\
12676 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12677 |accept-own|accept-own-nexthop|route-filter-v6\
12678 |route-filter-v4|route-filter-translated-v6\
12679 |route-filter-translated-v4] [exact-match]\
12680 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12681 |filter-list AS_PATH_FILTER_NAME\
12682 |prefix-list WORD\
12683 |access-list ACCESSLIST_NAME\
12684 |route-map RMAP_NAME\
12685 |rpki <invalid|valid|notfound>\
12686 |version (1-4294967295)\
12687 |alias ALIAS_NAME\
12688 |A.B.C.D/M longer-prefixes\
12689 |X:X::X:X/M longer-prefixes\
12690 |optimal-route-reflection [WORD$orr_group_name]\
12691 |detail-routes$detail_routes\
12692 ] [json$uj [detail$detail_json] | wide$wide]",
12693 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12694 BGP_SAFI_WITH_LABEL_HELP_STR
12695 "Display the entries for all address families\n"
12696 "Display only routes with non-natural netmasks\n"
12697 "Display detailed information about dampening\n"
12698 "Display flap statistics of routes\n"
12699 "Display paths suppressed due to dampening\n"
12700 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12701 "Do not send outside local AS (well-known community)\n"
12702 "Do not advertise to any peer (well-known community)\n"
12703 "Do not export to next AS (well-known community)\n"
12704 "Graceful shutdown (well-known community)\n"
12705 "Do not export to any peer (well-known community)\n"
12706 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12707 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12708 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12709 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12710 "Should accept VPN route with local nexthop (well-known community)\n"
12711 "RT VPNv6 route filtering (well-known community)\n"
12712 "RT VPNv4 route filtering (well-known community)\n"
12713 "RT translated VPNv6 route filtering (well-known community)\n"
12714 "RT translated VPNv4 route filtering (well-known community)\n"
12715 "Exact match of the communities\n"
12716 "Community-list number\n"
12717 "Community-list name\n"
12718 "Display routes matching the community-list\n"
12719 "Exact match of the communities\n"
12720 "Display routes conforming to the filter-list\n"
12721 "Regular expression access list name\n"
12722 "Display routes conforming to the prefix-list\n"
12723 "Prefix-list name\n"
12724 "Display routes conforming to the access-list\n"
12725 "Access-list name\n"
12726 "Display routes matching the route-map\n"
12727 "A route-map to match on\n"
12728 "RPKI route types\n"
12729 "A valid path as determined by rpki\n"
12730 "A invalid path as determined by rpki\n"
12731 "A path that has no rpki data\n"
12732 "Display prefixes with matching version numbers\n"
12733 "Version number and above\n"
12734 "Display prefixes with matching BGP community alias\n"
12735 "BGP community alias\n"
12736 "IPv4 prefix\n"
12737 "Display route and more specific routes\n"
12738 "IPv6 prefix\n"
12739 "Display route and more specific routes\n"
12740 "Display Optimal Route Reflection RR Clients\n"
12741 "ORR Group name\n"
12742 "Display detailed version of all routes\n"
12743 JSON_STR
12744 "Display detailed version of JSON output\n"
12745 "Increase table width for longer prefixes\n")
12746 {
12747 afi_t afi = AFI_IP6;
12748 safi_t safi = SAFI_UNICAST;
12749 enum bgp_show_type sh_type = bgp_show_type_normal;
12750 void *output_arg = NULL;
12751 struct bgp *bgp = NULL;
12752 int idx = 0;
12753 int exact_match = 0;
12754 char *community = NULL;
12755 bool first = true;
12756 uint16_t show_flags = 0;
12757 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12758 struct prefix p;
12759 bool orr_group = false;
12760
12761 if (uj) {
12762 argc--;
12763 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12764 }
12765
12766 if (detail_json)
12767 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
12768
12769 if (detail_routes)
12770 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
12771
12772 /* [<ipv4|ipv6> [all]] */
12773 if (all) {
12774 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12775
12776 if (argv_find(argv, argc, "ipv4", &idx))
12777 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12778
12779 if (argv_find(argv, argc, "ipv6", &idx))
12780 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12781 }
12782
12783 if (wide)
12784 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12785
12786 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12787 &bgp, uj);
12788 if (!idx)
12789 return CMD_WARNING;
12790
12791 if (argv_find(argv, argc, "cidr-only", &idx))
12792 sh_type = bgp_show_type_cidr_only;
12793
12794 if (argv_find(argv, argc, "dampening", &idx)) {
12795 if (argv_find(argv, argc, "dampened-paths", &idx))
12796 sh_type = bgp_show_type_dampend_paths;
12797 else if (argv_find(argv, argc, "flap-statistics", &idx))
12798 sh_type = bgp_show_type_flap_statistics;
12799 }
12800
12801 if (argv_find(argv, argc, "community", &idx)) {
12802 char *maybecomm = NULL;
12803
12804 if (idx + 1 < argc) {
12805 if (argv[idx + 1]->type == VARIABLE_TKN)
12806 maybecomm = argv[idx + 1]->arg;
12807 else
12808 maybecomm = argv[idx + 1]->text;
12809 }
12810
12811 if (maybecomm && !strmatch(maybecomm, "json")
12812 && !strmatch(maybecomm, "exact-match"))
12813 community = maybecomm;
12814
12815 if (argv_find(argv, argc, "exact-match", &idx))
12816 exact_match = 1;
12817
12818 if (!community)
12819 sh_type = bgp_show_type_community_all;
12820 }
12821
12822 if (argv_find(argv, argc, "community-list", &idx)) {
12823 const char *clist_number_or_name = argv[++idx]->arg;
12824 struct community_list *list;
12825
12826 if (argv_find(argv, argc, "exact-match", &idx))
12827 exact_match = 1;
12828
12829 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12830 COMMUNITY_LIST_MASTER);
12831 if (list == NULL) {
12832 vty_out(vty, "%% %s community-list not found\n",
12833 clist_number_or_name);
12834 return CMD_WARNING;
12835 }
12836
12837 if (exact_match)
12838 sh_type = bgp_show_type_community_list_exact;
12839 else
12840 sh_type = bgp_show_type_community_list;
12841 output_arg = list;
12842 }
12843
12844 if (argv_find(argv, argc, "filter-list", &idx)) {
12845 const char *filter = argv[++idx]->arg;
12846 struct as_list *as_list;
12847
12848 as_list = as_list_lookup(filter);
12849 if (as_list == NULL) {
12850 vty_out(vty, "%% %s AS-path access-list not found\n",
12851 filter);
12852 return CMD_WARNING;
12853 }
12854
12855 sh_type = bgp_show_type_filter_list;
12856 output_arg = as_list;
12857 }
12858
12859 if (argv_find(argv, argc, "prefix-list", &idx)) {
12860 const char *prefix_list_str = argv[++idx]->arg;
12861 struct prefix_list *plist;
12862
12863 plist = prefix_list_lookup(afi, prefix_list_str);
12864 if (plist == NULL) {
12865 vty_out(vty, "%% %s prefix-list not found\n",
12866 prefix_list_str);
12867 return CMD_WARNING;
12868 }
12869
12870 sh_type = bgp_show_type_prefix_list;
12871 output_arg = plist;
12872 }
12873
12874 if (argv_find(argv, argc, "access-list", &idx)) {
12875 const char *access_list_str = argv[++idx]->arg;
12876 struct access_list *alist;
12877
12878 alist = access_list_lookup(afi, access_list_str);
12879 if (!alist) {
12880 vty_out(vty, "%% %s access-list not found\n",
12881 access_list_str);
12882 return CMD_WARNING;
12883 }
12884
12885 sh_type = bgp_show_type_access_list;
12886 output_arg = alist;
12887 }
12888
12889 if (argv_find(argv, argc, "route-map", &idx)) {
12890 const char *rmap_str = argv[++idx]->arg;
12891 struct route_map *rmap;
12892
12893 rmap = route_map_lookup_by_name(rmap_str);
12894 if (!rmap) {
12895 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12896 return CMD_WARNING;
12897 }
12898
12899 sh_type = bgp_show_type_route_map;
12900 output_arg = rmap;
12901 }
12902
12903 if (argv_find(argv, argc, "rpki", &idx)) {
12904 sh_type = bgp_show_type_rpki;
12905 if (argv_find(argv, argc, "valid", &idx))
12906 rpki_target_state = RPKI_VALID;
12907 else if (argv_find(argv, argc, "invalid", &idx))
12908 rpki_target_state = RPKI_INVALID;
12909 }
12910
12911 /* Display prefixes with matching version numbers */
12912 if (argv_find(argv, argc, "version", &idx)) {
12913 sh_type = bgp_show_type_prefix_version;
12914 output_arg = argv[idx + 1]->arg;
12915 }
12916
12917 /* Display prefixes with matching BGP community alias */
12918 if (argv_find(argv, argc, "alias", &idx)) {
12919 sh_type = bgp_show_type_community_alias;
12920 output_arg = argv[idx + 1]->arg;
12921 }
12922
12923 /* prefix-longer */
12924 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12925 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12926 const char *prefix_str = argv[idx]->arg;
12927
12928 if (!str2prefix(prefix_str, &p)) {
12929 vty_out(vty, "%% Malformed Prefix\n");
12930 return CMD_WARNING;
12931 }
12932
12933 sh_type = bgp_show_type_prefix_longer;
12934 output_arg = &p;
12935 }
12936
12937 if (argv_find(argv, argc, "optimal-route-reflection", &idx))
12938 orr_group = true;
12939
12940 if (!all) {
12941 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12942 if (community)
12943 return bgp_show_community(vty, bgp, community,
12944 exact_match, afi, safi,
12945 show_flags);
12946 else if (orr_group)
12947 return bgp_show_orr(vty, bgp, afi, safi, orr_group_name,
12948 show_flags);
12949 else
12950 return bgp_show(vty, bgp, afi, safi, sh_type,
12951 output_arg, show_flags,
12952 rpki_target_state);
12953 } else {
12954 struct listnode *node;
12955 struct bgp *abgp;
12956 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12957 * AFI_IP6 */
12958
12959 if (uj)
12960 vty_out(vty, "{\n");
12961
12962 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12963 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12964 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12965 ? AFI_IP
12966 : AFI_IP6;
12967 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12968 FOREACH_SAFI (safi) {
12969 if (!bgp_afi_safi_peer_exists(abgp, afi,
12970 safi))
12971 continue;
12972
12973 if (uj) {
12974 if (first)
12975 first = false;
12976 else
12977 vty_out(vty, ",\n");
12978 vty_out(vty, "\"%s\":{\n",
12979 get_afi_safi_str(afi,
12980 safi,
12981 true));
12982 } else
12983 vty_out(vty,
12984 "\nFor address family: %s\n",
12985 get_afi_safi_str(
12986 afi, safi,
12987 false));
12988
12989 if (community)
12990 bgp_show_community(
12991 vty, abgp, community,
12992 exact_match, afi, safi,
12993 show_flags);
12994 else if (orr_group)
12995 bgp_show_orr(vty, bgp, afi,
12996 safi,
12997 orr_group_name,
12998 show_flags);
12999 else
13000 bgp_show(vty, abgp, afi, safi,
13001 sh_type, output_arg,
13002 show_flags,
13003 rpki_target_state);
13004 if (uj)
13005 vty_out(vty, "}\n");
13006 }
13007 }
13008 } else {
13009 /* show <ip> bgp all: for each AFI and SAFI*/
13010 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
13011 FOREACH_AFI_SAFI (afi, safi) {
13012 if (!bgp_afi_safi_peer_exists(abgp, afi,
13013 safi))
13014 continue;
13015
13016 if (uj) {
13017 if (first)
13018 first = false;
13019 else
13020 vty_out(vty, ",\n");
13021
13022 vty_out(vty, "\"%s\":{\n",
13023 get_afi_safi_str(afi,
13024 safi,
13025 true));
13026 } else
13027 vty_out(vty,
13028 "\nFor address family: %s\n",
13029 get_afi_safi_str(
13030 afi, safi,
13031 false));
13032
13033 if (community)
13034 bgp_show_community(
13035 vty, abgp, community,
13036 exact_match, afi, safi,
13037 show_flags);
13038 else if (orr_group)
13039 bgp_show_orr(vty, bgp, afi,
13040 safi,
13041 orr_group_name,
13042 show_flags);
13043 else
13044 bgp_show(vty, abgp, afi, safi,
13045 sh_type, output_arg,
13046 show_flags,
13047 rpki_target_state);
13048 if (uj)
13049 vty_out(vty, "}\n");
13050 }
13051 }
13052 }
13053 if (uj)
13054 vty_out(vty, "}\n");
13055 }
13056 return CMD_SUCCESS;
13057 }
13058
13059 DEFUN (show_ip_bgp_route,
13060 show_ip_bgp_route_cmd,
13061 "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]",
13062 SHOW_STR
13063 IP_STR
13064 BGP_STR
13065 BGP_INSTANCE_HELP_STR
13066 BGP_AFI_HELP_STR
13067 BGP_SAFI_WITH_LABEL_HELP_STR
13068 "Network in the BGP routing table to display\n"
13069 "IPv4 prefix\n"
13070 "Network in the BGP routing table to display\n"
13071 "IPv6 prefix\n"
13072 "Display only the bestpath\n"
13073 "Display only multipaths\n"
13074 "Display only paths that match the specified rpki state\n"
13075 "A valid path as determined by rpki\n"
13076 "A invalid path as determined by rpki\n"
13077 "A path that has no rpki data\n"
13078 JSON_STR)
13079 {
13080 int prefix_check = 0;
13081
13082 afi_t afi = AFI_IP6;
13083 safi_t safi = SAFI_UNICAST;
13084 char *prefix = NULL;
13085 struct bgp *bgp = NULL;
13086 enum bgp_path_type path_type;
13087 bool uj = use_json(argc, argv);
13088
13089 int idx = 0;
13090
13091 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13092 &bgp, uj);
13093 if (!idx)
13094 return CMD_WARNING;
13095
13096 if (!bgp) {
13097 vty_out(vty,
13098 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
13099 return CMD_WARNING;
13100 }
13101
13102 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
13103 if (argv_find(argv, argc, "A.B.C.D", &idx)
13104 || argv_find(argv, argc, "X:X::X:X", &idx))
13105 prefix_check = 0;
13106 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
13107 || argv_find(argv, argc, "X:X::X:X/M", &idx))
13108 prefix_check = 1;
13109
13110 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
13111 && afi != AFI_IP6) {
13112 vty_out(vty,
13113 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
13114 return CMD_WARNING;
13115 }
13116 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
13117 && afi != AFI_IP) {
13118 vty_out(vty,
13119 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13120 return CMD_WARNING;
13121 }
13122
13123 prefix = argv[idx]->arg;
13124
13125 /* [<bestpath|multipath>] */
13126 if (argv_find(argv, argc, "bestpath", &idx))
13127 path_type = BGP_PATH_SHOW_BESTPATH;
13128 else if (argv_find(argv, argc, "multipath", &idx))
13129 path_type = BGP_PATH_SHOW_MULTIPATH;
13130 else
13131 path_type = BGP_PATH_SHOW_ALL;
13132
13133 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13134 path_type, RPKI_NOT_BEING_USED, uj);
13135 }
13136
13137 DEFUN (show_ip_bgp_regexp,
13138 show_ip_bgp_regexp_cmd,
13139 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13140 SHOW_STR
13141 IP_STR
13142 BGP_STR
13143 BGP_INSTANCE_HELP_STR
13144 BGP_AFI_HELP_STR
13145 BGP_SAFI_WITH_LABEL_HELP_STR
13146 "Display routes matching the AS path regular expression\n"
13147 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13148 JSON_STR)
13149 {
13150 afi_t afi = AFI_IP6;
13151 safi_t safi = SAFI_UNICAST;
13152 struct bgp *bgp = NULL;
13153 bool uj = use_json(argc, argv);
13154 char *regstr = NULL;
13155
13156 int idx = 0;
13157 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13158 &bgp, false);
13159 if (!idx)
13160 return CMD_WARNING;
13161
13162 // get index of regex
13163 if (argv_find(argv, argc, "REGEX", &idx))
13164 regstr = argv[idx]->arg;
13165
13166 assert(regstr);
13167 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13168 bgp_show_type_regexp, uj);
13169 }
13170
13171 DEFPY (show_ip_bgp_instance_all,
13172 show_ip_bgp_instance_all_cmd,
13173 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13174 SHOW_STR
13175 IP_STR
13176 BGP_STR
13177 BGP_INSTANCE_ALL_HELP_STR
13178 BGP_AFI_HELP_STR
13179 BGP_SAFI_WITH_LABEL_HELP_STR
13180 JSON_STR
13181 "Increase table width for longer prefixes\n")
13182 {
13183 afi_t afi = AFI_IP6;
13184 safi_t safi = SAFI_UNICAST;
13185 struct bgp *bgp = NULL;
13186 int idx = 0;
13187 uint16_t show_flags = 0;
13188
13189 if (uj) {
13190 argc--;
13191 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13192 }
13193
13194 if (wide)
13195 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13196
13197 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13198 &bgp, uj);
13199 if (!idx)
13200 return CMD_WARNING;
13201
13202 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13203 return CMD_SUCCESS;
13204 }
13205
13206 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13207 afi_t afi, safi_t safi, enum bgp_show_type type,
13208 bool use_json)
13209 {
13210 regex_t *regex;
13211 int rc;
13212 uint16_t show_flags = 0;
13213
13214 if (use_json)
13215 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13216
13217 if (!config_bgp_aspath_validate(regstr)) {
13218 vty_out(vty, "Invalid character in REGEX %s\n",
13219 regstr);
13220 return CMD_WARNING_CONFIG_FAILED;
13221 }
13222
13223 regex = bgp_regcomp(regstr);
13224 if (!regex) {
13225 vty_out(vty, "Can't compile regexp %s\n", regstr);
13226 return CMD_WARNING;
13227 }
13228
13229 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13230 RPKI_NOT_BEING_USED);
13231 bgp_regex_free(regex);
13232 return rc;
13233 }
13234
13235 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13236 const char *comstr, int exact, afi_t afi,
13237 safi_t safi, uint16_t show_flags)
13238 {
13239 struct community *com;
13240 int ret = 0;
13241
13242 com = community_str2com(comstr);
13243 if (!com) {
13244 vty_out(vty, "%% Community malformed: %s\n", comstr);
13245 return CMD_WARNING;
13246 }
13247
13248 ret = bgp_show(vty, bgp, afi, safi,
13249 (exact ? bgp_show_type_community_exact
13250 : bgp_show_type_community),
13251 com, show_flags, RPKI_NOT_BEING_USED);
13252 community_free(&com);
13253
13254 return ret;
13255 }
13256
13257 enum bgp_stats {
13258 BGP_STATS_MAXBITLEN = 0,
13259 BGP_STATS_RIB,
13260 BGP_STATS_PREFIXES,
13261 BGP_STATS_TOTPLEN,
13262 BGP_STATS_UNAGGREGATEABLE,
13263 BGP_STATS_MAX_AGGREGATEABLE,
13264 BGP_STATS_AGGREGATES,
13265 BGP_STATS_SPACE,
13266 BGP_STATS_ASPATH_COUNT,
13267 BGP_STATS_ASPATH_MAXHOPS,
13268 BGP_STATS_ASPATH_TOTHOPS,
13269 BGP_STATS_ASPATH_MAXSIZE,
13270 BGP_STATS_ASPATH_TOTSIZE,
13271 BGP_STATS_ASN_HIGHEST,
13272 BGP_STATS_MAX,
13273 };
13274
13275 #define TABLE_STATS_IDX_VTY 0
13276 #define TABLE_STATS_IDX_JSON 1
13277
13278 static const char *table_stats_strs[][2] = {
13279 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13280 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13281 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13282 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13283 "unaggregateablePrefixes"},
13284 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13285 "maximumAggregateablePrefixes"},
13286 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13287 "bgpAggregateAdvertisements"},
13288 [BGP_STATS_SPACE] = {"Address space advertised",
13289 "addressSpaceAdvertised"},
13290 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13291 "advertisementsWithPaths"},
13292 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13293 "longestAsPath"},
13294 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13295 "largestAsPath"},
13296 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13297 "averageAsPathLengthHops"},
13298 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13299 "averageAsPathSizeBytes"},
13300 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13301 [BGP_STATS_MAX] = {NULL, NULL}
13302 };
13303
13304 struct bgp_table_stats {
13305 struct bgp_table *table;
13306 unsigned long long counts[BGP_STATS_MAX];
13307
13308 unsigned long long
13309 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13310 1];
13311
13312 double total_space;
13313 };
13314
13315 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13316 struct bgp_table_stats *ts, unsigned int space)
13317 {
13318 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13319 struct bgp_path_info *pi;
13320 const struct prefix *rn_p;
13321
13322 if (!bgp_dest_has_bgp_path_info_data(dest))
13323 return;
13324
13325 rn_p = bgp_dest_get_prefix(dest);
13326 ts->counts[BGP_STATS_PREFIXES]++;
13327 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13328
13329 ts->prefix_len_count[rn_p->prefixlen]++;
13330 /* check if the prefix is included by any other announcements */
13331 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13332 pdest = bgp_dest_parent_nolock(pdest);
13333
13334 if (pdest == NULL || pdest == top) {
13335 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13336 /* announced address space */
13337 if (space)
13338 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13339 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13340 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13341
13342
13343 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13344 ts->counts[BGP_STATS_RIB]++;
13345
13346 if (CHECK_FLAG(pi->attr->flag,
13347 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13348 ts->counts[BGP_STATS_AGGREGATES]++;
13349
13350 /* as-path stats */
13351 if (pi->attr->aspath) {
13352 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13353 unsigned int size = aspath_size(pi->attr->aspath);
13354 as_t highest = aspath_highest(pi->attr->aspath);
13355
13356 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13357
13358 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13359 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13360
13361 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13362 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13363
13364 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13365 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13366 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13367 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13368 }
13369 }
13370 }
13371
13372 static void bgp_table_stats_walker(struct thread *t)
13373 {
13374 struct bgp_dest *dest, *ndest;
13375 struct bgp_dest *top;
13376 struct bgp_table_stats *ts = THREAD_ARG(t);
13377 unsigned int space = 0;
13378
13379 if (!(top = bgp_table_top(ts->table)))
13380 return;
13381
13382 switch (ts->table->afi) {
13383 case AFI_IP:
13384 space = IPV4_MAX_BITLEN;
13385 break;
13386 case AFI_IP6:
13387 space = IPV6_MAX_BITLEN;
13388 break;
13389 case AFI_L2VPN:
13390 space = EVPN_ROUTE_PREFIXLEN;
13391 break;
13392 default:
13393 return;
13394 }
13395
13396 ts->counts[BGP_STATS_MAXBITLEN] = space;
13397
13398 for (dest = top; dest; dest = bgp_route_next(dest)) {
13399 if (ts->table->safi == SAFI_MPLS_VPN
13400 || ts->table->safi == SAFI_ENCAP
13401 || ts->table->safi == SAFI_EVPN) {
13402 struct bgp_table *table;
13403
13404 table = bgp_dest_get_bgp_table_info(dest);
13405 if (!table)
13406 continue;
13407
13408 top = bgp_table_top(table);
13409 for (ndest = bgp_table_top(table); ndest;
13410 ndest = bgp_route_next(ndest))
13411 bgp_table_stats_rn(ndest, top, ts, space);
13412 } else {
13413 bgp_table_stats_rn(dest, top, ts, space);
13414 }
13415 }
13416 }
13417
13418 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13419 struct json_object *json_array)
13420 {
13421 struct listnode *node, *nnode;
13422 struct bgp *bgp;
13423
13424 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13425 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13426 }
13427
13428 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13429 safi_t safi, struct json_object *json_array)
13430 {
13431 struct bgp_table_stats ts;
13432 unsigned int i;
13433 int ret = CMD_SUCCESS;
13434 char temp_buf[20];
13435 struct json_object *json = NULL;
13436 uint32_t bitlen = 0;
13437 struct json_object *json_bitlen;
13438
13439 if (json_array)
13440 json = json_object_new_object();
13441
13442 if (!bgp->rib[afi][safi]) {
13443 char warning_msg[50];
13444
13445 snprintf(warning_msg, sizeof(warning_msg),
13446 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13447 safi);
13448
13449 if (!json)
13450 vty_out(vty, "%s\n", warning_msg);
13451 else
13452 json_object_string_add(json, "warning", warning_msg);
13453
13454 ret = CMD_WARNING;
13455 goto end_table_stats;
13456 }
13457
13458 if (!json)
13459 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13460 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13461 else
13462 json_object_string_add(json, "instance", bgp->name_pretty);
13463
13464 /* labeled-unicast routes live in the unicast table */
13465 if (safi == SAFI_LABELED_UNICAST)
13466 safi = SAFI_UNICAST;
13467
13468 memset(&ts, 0, sizeof(ts));
13469 ts.table = bgp->rib[afi][safi];
13470 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13471
13472 for (i = 0; i < BGP_STATS_MAX; i++) {
13473 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13474 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13475 continue;
13476
13477 switch (i) {
13478 case BGP_STATS_ASPATH_TOTHOPS:
13479 case BGP_STATS_ASPATH_TOTSIZE:
13480 if (!json) {
13481 snprintf(
13482 temp_buf, sizeof(temp_buf), "%12.2f",
13483 ts.counts[i]
13484 ? (float)ts.counts[i]
13485 / (float)ts.counts
13486 [BGP_STATS_ASPATH_COUNT]
13487 : 0);
13488 vty_out(vty, "%-30s: %s",
13489 table_stats_strs[i]
13490 [TABLE_STATS_IDX_VTY],
13491 temp_buf);
13492 } else {
13493 json_object_double_add(
13494 json,
13495 table_stats_strs[i]
13496 [TABLE_STATS_IDX_JSON],
13497 ts.counts[i]
13498 ? (double)ts.counts[i]
13499 / (double)ts.counts
13500 [BGP_STATS_ASPATH_COUNT]
13501 : 0);
13502 }
13503 break;
13504 case BGP_STATS_TOTPLEN:
13505 if (!json) {
13506 snprintf(
13507 temp_buf, sizeof(temp_buf), "%12.2f",
13508 ts.counts[i]
13509 ? (float)ts.counts[i]
13510 / (float)ts.counts
13511 [BGP_STATS_PREFIXES]
13512 : 0);
13513 vty_out(vty, "%-30s: %s",
13514 table_stats_strs[i]
13515 [TABLE_STATS_IDX_VTY],
13516 temp_buf);
13517 } else {
13518 json_object_double_add(
13519 json,
13520 table_stats_strs[i]
13521 [TABLE_STATS_IDX_JSON],
13522 ts.counts[i]
13523 ? (double)ts.counts[i]
13524 / (double)ts.counts
13525 [BGP_STATS_PREFIXES]
13526 : 0);
13527 }
13528 break;
13529 case BGP_STATS_SPACE:
13530 if (!json) {
13531 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13532 ts.total_space);
13533 vty_out(vty, "%-30s: %s\n",
13534 table_stats_strs[i]
13535 [TABLE_STATS_IDX_VTY],
13536 temp_buf);
13537 } else {
13538 json_object_double_add(
13539 json,
13540 table_stats_strs[i]
13541 [TABLE_STATS_IDX_JSON],
13542 (double)ts.total_space);
13543 }
13544 if (afi == AFI_IP6) {
13545 if (!json) {
13546 snprintf(temp_buf, sizeof(temp_buf),
13547 "%12g",
13548 ts.total_space
13549 * pow(2.0, -128 + 32));
13550 vty_out(vty, "%30s: %s\n",
13551 "/32 equivalent %s\n",
13552 temp_buf);
13553 } else {
13554 json_object_double_add(
13555 json, "/32equivalent",
13556 (double)(ts.total_space
13557 * pow(2.0,
13558 -128 + 32)));
13559 }
13560 if (!json) {
13561 snprintf(temp_buf, sizeof(temp_buf),
13562 "%12g",
13563 ts.total_space
13564 * pow(2.0, -128 + 48));
13565 vty_out(vty, "%30s: %s\n",
13566 "/48 equivalent %s\n",
13567 temp_buf);
13568 } else {
13569 json_object_double_add(
13570 json, "/48equivalent",
13571 (double)(ts.total_space
13572 * pow(2.0,
13573 -128 + 48)));
13574 }
13575 } else {
13576 if (!json) {
13577 snprintf(temp_buf, sizeof(temp_buf),
13578 "%12.2f",
13579 ts.total_space * 100.
13580 * pow(2.0, -32));
13581 vty_out(vty, "%30s: %s\n",
13582 "% announced ", temp_buf);
13583 } else {
13584 json_object_double_add(
13585 json, "%announced",
13586 (double)(ts.total_space * 100.
13587 * pow(2.0, -32)));
13588 }
13589 if (!json) {
13590 snprintf(temp_buf, sizeof(temp_buf),
13591 "%12.2f",
13592 ts.total_space
13593 * pow(2.0, -32 + 8));
13594 vty_out(vty, "%30s: %s\n",
13595 "/8 equivalent ", temp_buf);
13596 } else {
13597 json_object_double_add(
13598 json, "/8equivalent",
13599 (double)(ts.total_space
13600 * pow(2.0, -32 + 8)));
13601 }
13602 if (!json) {
13603 snprintf(temp_buf, sizeof(temp_buf),
13604 "%12.2f",
13605 ts.total_space
13606 * pow(2.0, -32 + 24));
13607 vty_out(vty, "%30s: %s\n",
13608 "/24 equivalent ", temp_buf);
13609 } else {
13610 json_object_double_add(
13611 json, "/24equivalent",
13612 (double)(ts.total_space
13613 * pow(2.0, -32 + 24)));
13614 }
13615 }
13616 break;
13617 default:
13618 if (!json) {
13619 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13620 ts.counts[i]);
13621 vty_out(vty, "%-30s: %s",
13622 table_stats_strs[i]
13623 [TABLE_STATS_IDX_VTY],
13624 temp_buf);
13625 } else {
13626 json_object_int_add(
13627 json,
13628 table_stats_strs[i]
13629 [TABLE_STATS_IDX_JSON],
13630 ts.counts[i]);
13631 }
13632 }
13633 if (!json)
13634 vty_out(vty, "\n");
13635 }
13636
13637 switch (afi) {
13638 case AFI_IP:
13639 bitlen = IPV4_MAX_BITLEN;
13640 break;
13641 case AFI_IP6:
13642 bitlen = IPV6_MAX_BITLEN;
13643 break;
13644 case AFI_L2VPN:
13645 bitlen = EVPN_ROUTE_PREFIXLEN;
13646 break;
13647 default:
13648 break;
13649 }
13650
13651 if (json) {
13652 json_bitlen = json_object_new_array();
13653
13654 for (i = 0; i <= bitlen; i++) {
13655 struct json_object *ind_bit = json_object_new_object();
13656
13657 if (!ts.prefix_len_count[i])
13658 continue;
13659
13660 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13661 json_object_int_add(ind_bit, temp_buf,
13662 ts.prefix_len_count[i]);
13663 json_object_array_add(json_bitlen, ind_bit);
13664 }
13665 json_object_object_add(json, "prefixLength", json_bitlen);
13666 }
13667
13668 end_table_stats:
13669 if (json)
13670 json_object_array_add(json_array, json);
13671 return ret;
13672 }
13673
13674 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13675 safi_t safi, struct json_object *json_array)
13676 {
13677 if (!bgp) {
13678 bgp_table_stats_all(vty, afi, safi, json_array);
13679 return CMD_SUCCESS;
13680 }
13681
13682 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13683 }
13684
13685 enum bgp_pcounts {
13686 PCOUNT_ADJ_IN = 0,
13687 PCOUNT_DAMPED,
13688 PCOUNT_REMOVED,
13689 PCOUNT_HISTORY,
13690 PCOUNT_STALE,
13691 PCOUNT_VALID,
13692 PCOUNT_ALL,
13693 PCOUNT_COUNTED,
13694 PCOUNT_BPATH_SELECTED,
13695 PCOUNT_PFCNT, /* the figure we display to users */
13696 PCOUNT_MAX,
13697 };
13698
13699 static const char *const pcount_strs[] = {
13700 [PCOUNT_ADJ_IN] = "Adj-in",
13701 [PCOUNT_DAMPED] = "Damped",
13702 [PCOUNT_REMOVED] = "Removed",
13703 [PCOUNT_HISTORY] = "History",
13704 [PCOUNT_STALE] = "Stale",
13705 [PCOUNT_VALID] = "Valid",
13706 [PCOUNT_ALL] = "All RIB",
13707 [PCOUNT_COUNTED] = "PfxCt counted",
13708 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13709 [PCOUNT_PFCNT] = "Useable",
13710 [PCOUNT_MAX] = NULL,
13711 };
13712
13713 struct peer_pcounts {
13714 unsigned int count[PCOUNT_MAX];
13715 const struct peer *peer;
13716 const struct bgp_table *table;
13717 safi_t safi;
13718 };
13719
13720 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13721 {
13722 const struct bgp_adj_in *ain;
13723 const struct bgp_path_info *pi;
13724 const struct peer *peer = pc->peer;
13725
13726 for (ain = rn->adj_in; ain; ain = ain->next)
13727 if (ain->peer == peer)
13728 pc->count[PCOUNT_ADJ_IN]++;
13729
13730 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13731
13732 if (pi->peer != peer)
13733 continue;
13734
13735 pc->count[PCOUNT_ALL]++;
13736
13737 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13738 pc->count[PCOUNT_DAMPED]++;
13739 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13740 pc->count[PCOUNT_HISTORY]++;
13741 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13742 pc->count[PCOUNT_REMOVED]++;
13743 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13744 pc->count[PCOUNT_STALE]++;
13745 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13746 pc->count[PCOUNT_VALID]++;
13747 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13748 pc->count[PCOUNT_PFCNT]++;
13749 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13750 pc->count[PCOUNT_BPATH_SELECTED]++;
13751
13752 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13753 pc->count[PCOUNT_COUNTED]++;
13754 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13755 flog_err(
13756 EC_LIB_DEVELOPMENT,
13757 "Attempting to count but flags say it is unusable");
13758 } else {
13759 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13760 flog_err(
13761 EC_LIB_DEVELOPMENT,
13762 "Not counted but flags say we should");
13763 }
13764 }
13765 }
13766
13767 static void bgp_peer_count_walker(struct thread *t)
13768 {
13769 struct bgp_dest *rn, *rm;
13770 const struct bgp_table *table;
13771 struct peer_pcounts *pc = THREAD_ARG(t);
13772
13773 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13774 || pc->safi == SAFI_EVPN) {
13775 /* Special handling for 2-level routing tables. */
13776 for (rn = bgp_table_top(pc->table); rn;
13777 rn = bgp_route_next(rn)) {
13778 table = bgp_dest_get_bgp_table_info(rn);
13779 if (table != NULL)
13780 for (rm = bgp_table_top(table); rm;
13781 rm = bgp_route_next(rm))
13782 bgp_peer_count_proc(rm, pc);
13783 }
13784 } else
13785 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13786 bgp_peer_count_proc(rn, pc);
13787 }
13788
13789 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13790 safi_t safi, bool use_json)
13791 {
13792 struct peer_pcounts pcounts = {.peer = peer};
13793 unsigned int i;
13794 json_object *json = NULL;
13795 json_object *json_loop = NULL;
13796
13797 if (use_json) {
13798 json = json_object_new_object();
13799 json_loop = json_object_new_object();
13800 }
13801
13802 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13803 || !peer->bgp->rib[afi][safi]) {
13804 if (use_json) {
13805 json_object_string_add(
13806 json, "warning",
13807 "No such neighbor or address family");
13808 vty_out(vty, "%s\n", json_object_to_json_string(json));
13809 json_object_free(json);
13810 json_object_free(json_loop);
13811 } else
13812 vty_out(vty, "%% No such neighbor or address family\n");
13813
13814 return CMD_WARNING;
13815 }
13816
13817 memset(&pcounts, 0, sizeof(pcounts));
13818 pcounts.peer = peer;
13819 pcounts.table = peer->bgp->rib[afi][safi];
13820 pcounts.safi = safi;
13821
13822 /* in-place call via thread subsystem so as to record execution time
13823 * stats for the thread-walk (i.e. ensure this can't be blamed on
13824 * on just vty_read()).
13825 */
13826 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13827
13828 if (use_json) {
13829 json_object_string_add(json, "prefixCountsFor", peer->host);
13830 json_object_string_add(json, "multiProtocol",
13831 get_afi_safi_str(afi, safi, true));
13832 json_object_int_add(json, "pfxCounter",
13833 peer->pcount[afi][safi]);
13834
13835 for (i = 0; i < PCOUNT_MAX; i++)
13836 json_object_int_add(json_loop, pcount_strs[i],
13837 pcounts.count[i]);
13838
13839 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13840
13841 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13842 json_object_string_add(json, "pfxctDriftFor",
13843 peer->host);
13844 json_object_string_add(
13845 json, "recommended",
13846 "Please report this bug, with the above command output");
13847 }
13848 vty_json(vty, json);
13849 } else {
13850
13851 if (peer->hostname
13852 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13853 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13854 peer->hostname, peer->host,
13855 get_afi_safi_str(afi, safi, false));
13856 } else {
13857 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13858 get_afi_safi_str(afi, safi, false));
13859 }
13860
13861 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13862 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13863
13864 for (i = 0; i < PCOUNT_MAX; i++)
13865 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13866 pcounts.count[i]);
13867
13868 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13869 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13870 vty_out(vty,
13871 "Please report this bug, with the above command output\n");
13872 }
13873 }
13874
13875 return CMD_SUCCESS;
13876 }
13877
13878 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13879 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13880 "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]",
13881 SHOW_STR
13882 IP_STR
13883 BGP_STR
13884 BGP_INSTANCE_HELP_STR
13885 BGP_AFI_HELP_STR
13886 BGP_SAFI_HELP_STR
13887 "Detailed information on TCP and BGP neighbor connections\n"
13888 "Neighbor to display information about\n"
13889 "Neighbor to display information about\n"
13890 "Neighbor on BGP configured interface\n"
13891 "Display detailed prefix count information\n"
13892 JSON_STR)
13893 {
13894 afi_t afi = AFI_IP6;
13895 safi_t safi = SAFI_UNICAST;
13896 struct peer *peer;
13897 int idx = 0;
13898 struct bgp *bgp = NULL;
13899 bool uj = use_json(argc, argv);
13900
13901 if (uj)
13902 argc--;
13903
13904 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13905 &bgp, uj);
13906 if (!idx)
13907 return CMD_WARNING;
13908
13909 argv_find(argv, argc, "neighbors", &idx);
13910 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13911 if (!peer)
13912 return CMD_WARNING;
13913
13914 return bgp_peer_counts(vty, peer, afi, safi, uj);
13915 }
13916
13917 #ifdef KEEP_OLD_VPN_COMMANDS
13918 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13919 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13920 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13921 SHOW_STR
13922 IP_STR
13923 BGP_STR
13924 BGP_VPNVX_HELP_STR
13925 "Display information about all VPNv4 NLRIs\n"
13926 "Detailed information on TCP and BGP neighbor connections\n"
13927 "Neighbor to display information about\n"
13928 "Neighbor to display information about\n"
13929 "Neighbor on BGP configured interface\n"
13930 "Display detailed prefix count information\n"
13931 JSON_STR)
13932 {
13933 int idx_peer = 6;
13934 struct peer *peer;
13935 bool uj = use_json(argc, argv);
13936
13937 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13938 if (!peer)
13939 return CMD_WARNING;
13940
13941 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13942 }
13943
13944 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13945 show_ip_bgp_vpn_all_route_prefix_cmd,
13946 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13947 SHOW_STR
13948 IP_STR
13949 BGP_STR
13950 BGP_VPNVX_HELP_STR
13951 "Display information about all VPNv4 NLRIs\n"
13952 "Network in the BGP routing table to display\n"
13953 "Network in the BGP routing table to display\n"
13954 JSON_STR)
13955 {
13956 int idx = 0;
13957 char *network = NULL;
13958 struct bgp *bgp = bgp_get_default();
13959 if (!bgp) {
13960 vty_out(vty, "Can't find default instance\n");
13961 return CMD_WARNING;
13962 }
13963
13964 if (argv_find(argv, argc, "A.B.C.D", &idx))
13965 network = argv[idx]->arg;
13966 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13967 network = argv[idx]->arg;
13968 else {
13969 vty_out(vty, "Unable to figure out Network\n");
13970 return CMD_WARNING;
13971 }
13972
13973 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13974 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13975 use_json(argc, argv));
13976 }
13977 #endif /* KEEP_OLD_VPN_COMMANDS */
13978
13979 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13980 show_bgp_l2vpn_evpn_route_prefix_cmd,
13981 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13982 SHOW_STR
13983 BGP_STR
13984 L2VPN_HELP_STR
13985 EVPN_HELP_STR
13986 "Network in the BGP routing table to display\n"
13987 "Network in the BGP routing table to display\n"
13988 "Network in the BGP routing table to display\n"
13989 "Network in the BGP routing table to display\n"
13990 JSON_STR)
13991 {
13992 int idx = 0;
13993 char *network = NULL;
13994 int prefix_check = 0;
13995
13996 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13997 argv_find(argv, argc, "X:X::X:X", &idx))
13998 network = argv[idx]->arg;
13999 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
14000 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
14001 network = argv[idx]->arg;
14002 prefix_check = 1;
14003 } else {
14004 vty_out(vty, "Unable to figure out Network\n");
14005 return CMD_WARNING;
14006 }
14007 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
14008 prefix_check, BGP_PATH_SHOW_ALL,
14009 RPKI_NOT_BEING_USED, use_json(argc, argv));
14010 }
14011
14012 static void show_adj_route_header(struct vty *vty, struct peer *peer,
14013 struct bgp_table *table, int *header1,
14014 int *header2, json_object *json,
14015 json_object *json_scode,
14016 json_object *json_ocode, bool wide,
14017 bool detail)
14018 {
14019 uint64_t version = table ? table->version : 0;
14020
14021 if (*header1) {
14022 if (json) {
14023 json_object_int_add(json, "bgpTableVersion", version);
14024 json_object_string_addf(json, "bgpLocalRouterId",
14025 "%pI4", &peer->bgp->router_id);
14026 json_object_int_add(json, "defaultLocPrf",
14027 peer->bgp->default_local_pref);
14028 json_object_int_add(json, "localAS",
14029 peer->change_local_as
14030 ? peer->change_local_as
14031 : peer->local_as);
14032 json_object_object_add(json, "bgpStatusCodes",
14033 json_scode);
14034 json_object_object_add(json, "bgpOriginCodes",
14035 json_ocode);
14036 } else {
14037 vty_out(vty,
14038 "BGP table version is %" PRIu64
14039 ", local router ID is %pI4, vrf id ",
14040 version, &peer->bgp->router_id);
14041 if (peer->bgp->vrf_id == VRF_UNKNOWN)
14042 vty_out(vty, "%s", VRFID_NONE_STR);
14043 else
14044 vty_out(vty, "%u", peer->bgp->vrf_id);
14045 vty_out(vty, "\n");
14046 vty_out(vty, "Default local pref %u, ",
14047 peer->bgp->default_local_pref);
14048 vty_out(vty, "local AS %u\n",
14049 peer->change_local_as ? peer->change_local_as
14050 : peer->local_as);
14051 if (!detail) {
14052 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14053 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14054 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14055 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14056 }
14057 }
14058 *header1 = 0;
14059 }
14060 if (*header2) {
14061 if (!json && !detail)
14062 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
14063 : BGP_SHOW_HEADER));
14064 *header2 = 0;
14065 }
14066 }
14067
14068 static void
14069 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
14070 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
14071 const char *rmap_name, json_object *json, json_object *json_ar,
14072 json_object *json_scode, json_object *json_ocode,
14073 uint16_t show_flags, int *header1, int *header2, char *rd_str,
14074 unsigned long *output_count, unsigned long *filtered_count)
14075 {
14076 struct bgp_adj_in *ain;
14077 struct bgp_adj_out *adj;
14078 struct bgp_dest *dest;
14079 struct bgp *bgp;
14080 struct attr attr;
14081 int ret;
14082 struct update_subgroup *subgrp;
14083 struct peer_af *paf;
14084 bool route_filtered;
14085 bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14086 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14087 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14088 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14089 || (safi == SAFI_EVPN))
14090 ? true
14091 : false;
14092 int display = 0;
14093 json_object *json_net = NULL;
14094
14095 bgp = peer->bgp;
14096
14097 subgrp = peer_subgroup(peer, afi, safi);
14098
14099 if (type == bgp_show_adj_route_advertised && subgrp
14100 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
14101 if (use_json) {
14102 json_object_int_add(json, "bgpTableVersion",
14103 table->version);
14104 json_object_string_addf(json, "bgpLocalRouterId",
14105 "%pI4", &bgp->router_id);
14106 json_object_int_add(json, "defaultLocPrf",
14107 bgp->default_local_pref);
14108 json_object_int_add(json, "localAS",
14109 peer->change_local_as
14110 ? peer->change_local_as
14111 : peer->local_as);
14112 json_object_object_add(json, "bgpStatusCodes",
14113 json_scode);
14114 json_object_object_add(json, "bgpOriginCodes",
14115 json_ocode);
14116 json_object_string_add(
14117 json, "bgpOriginatingDefaultNetwork",
14118 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14119 } else {
14120 vty_out(vty,
14121 "BGP table version is %" PRIu64
14122 ", local router ID is %pI4, vrf id ",
14123 table->version, &bgp->router_id);
14124 if (bgp->vrf_id == VRF_UNKNOWN)
14125 vty_out(vty, "%s", VRFID_NONE_STR);
14126 else
14127 vty_out(vty, "%u", bgp->vrf_id);
14128 vty_out(vty, "\n");
14129 vty_out(vty, "Default local pref %u, ",
14130 bgp->default_local_pref);
14131 vty_out(vty, "local AS %u\n",
14132 peer->change_local_as ? peer->change_local_as
14133 : peer->local_as);
14134 if (!detail) {
14135 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14136 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14137 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14138 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14139 }
14140
14141 vty_out(vty, "Originating default network %s\n\n",
14142 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14143 }
14144 (*output_count)++;
14145 *header1 = 0;
14146 }
14147
14148 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14149 if (type == bgp_show_adj_route_received
14150 || type == bgp_show_adj_route_filtered) {
14151 for (ain = dest->adj_in; ain; ain = ain->next) {
14152 if (ain->peer != peer)
14153 continue;
14154
14155 show_adj_route_header(vty, peer, table, header1,
14156 header2, json, json_scode,
14157 json_ocode, wide, detail);
14158
14159 if ((safi == SAFI_MPLS_VPN)
14160 || (safi == SAFI_ENCAP)
14161 || (safi == SAFI_EVPN)) {
14162 if (use_json)
14163 json_object_string_add(
14164 json_ar, "rd", rd_str);
14165 else if (show_rd && rd_str) {
14166 vty_out(vty,
14167 "Route Distinguisher: %s\n",
14168 rd_str);
14169 show_rd = false;
14170 }
14171 }
14172
14173 attr = *ain->attr;
14174 route_filtered = false;
14175
14176 /* Filter prefix using distribute list,
14177 * filter list or prefix list
14178 */
14179 const struct prefix *rn_p =
14180 bgp_dest_get_prefix(dest);
14181 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14182 safi))
14183 == FILTER_DENY)
14184 route_filtered = true;
14185
14186 /* Filter prefix using route-map */
14187 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14188 safi, rmap_name, NULL,
14189 0, NULL);
14190
14191 if (type == bgp_show_adj_route_filtered &&
14192 !route_filtered && ret != RMAP_DENY) {
14193 bgp_attr_flush(&attr);
14194 continue;
14195 }
14196
14197 if (type == bgp_show_adj_route_received
14198 && (route_filtered || ret == RMAP_DENY))
14199 (*filtered_count)++;
14200
14201 if (detail) {
14202 if (use_json)
14203 json_net =
14204 json_object_new_object();
14205 bgp_show_path_info(
14206 NULL /* prefix_rd */, dest, vty,
14207 bgp, afi, safi, json_net,
14208 BGP_PATH_SHOW_ALL, &display,
14209 RPKI_NOT_BEING_USED);
14210 if (use_json)
14211 json_object_object_addf(
14212 json_ar, json_net,
14213 "%pFX", rn_p);
14214 } else
14215 route_vty_out_tmp(vty, dest, rn_p,
14216 &attr, safi, use_json,
14217 json_ar, wide);
14218 bgp_attr_flush(&attr);
14219 (*output_count)++;
14220 }
14221 } else if (type == bgp_show_adj_route_advertised) {
14222 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14223 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14224 if (paf->peer != peer || !adj->attr)
14225 continue;
14226
14227 show_adj_route_header(
14228 vty, peer, table, header1,
14229 header2, json, json_scode,
14230 json_ocode, wide, detail);
14231
14232 const struct prefix *rn_p =
14233 bgp_dest_get_prefix(dest);
14234
14235 attr = *adj->attr;
14236 ret = bgp_output_modifier(
14237 peer, rn_p, &attr, afi, safi,
14238 rmap_name);
14239
14240 if (ret != RMAP_DENY) {
14241 if ((safi == SAFI_MPLS_VPN)
14242 || (safi == SAFI_ENCAP)
14243 || (safi == SAFI_EVPN)) {
14244 if (use_json)
14245 json_object_string_add(
14246 json_ar,
14247 "rd",
14248 rd_str);
14249 else if (show_rd
14250 && rd_str) {
14251 vty_out(vty,
14252 "Route Distinguisher: %s\n",
14253 rd_str);
14254 show_rd = false;
14255 }
14256 }
14257 if (detail) {
14258 if (use_json)
14259 json_net =
14260 json_object_new_object();
14261 bgp_show_path_info(
14262 NULL /* prefix_rd
14263 */
14264 ,
14265 dest, vty, bgp,
14266 afi, safi,
14267 json_net,
14268 BGP_PATH_SHOW_ALL,
14269 &display,
14270 RPKI_NOT_BEING_USED);
14271 if (use_json)
14272 json_object_object_addf(
14273 json_ar,
14274 json_net,
14275 "%pFX",
14276 rn_p);
14277 } else
14278 route_vty_out_tmp(
14279 vty, dest, rn_p,
14280 &attr, safi,
14281 use_json,
14282 json_ar, wide);
14283 (*output_count)++;
14284 } else {
14285 (*filtered_count)++;
14286 }
14287
14288 bgp_attr_flush(&attr);
14289 }
14290 } else if (type == bgp_show_adj_route_bestpath) {
14291 struct bgp_path_info *pi;
14292
14293 show_adj_route_header(vty, peer, table, header1,
14294 header2, json, json_scode,
14295 json_ocode, wide, detail);
14296
14297 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14298 pi = pi->next) {
14299 if (pi->peer != peer)
14300 continue;
14301
14302 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14303 continue;
14304
14305 route_vty_out_tmp(vty, dest,
14306 bgp_dest_get_prefix(dest),
14307 pi->attr, safi, use_json,
14308 json_ar, wide);
14309 (*output_count)++;
14310 }
14311 }
14312 }
14313 }
14314
14315 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14316 safi_t safi, enum bgp_show_adj_route_type type,
14317 const char *rmap_name, uint16_t show_flags)
14318 {
14319 struct bgp *bgp;
14320 struct bgp_table *table;
14321 json_object *json = NULL;
14322 json_object *json_scode = NULL;
14323 json_object *json_ocode = NULL;
14324 json_object *json_ar = NULL;
14325 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14326
14327 /* Init BGP headers here so they're only displayed once
14328 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14329 */
14330 int header1 = 1;
14331 int header2 = 1;
14332
14333 /*
14334 * Initialize variables for each RD
14335 * All prefixes under an RD is aggregated within "json_routes"
14336 */
14337 char rd_str[BUFSIZ] = {0};
14338 json_object *json_routes = NULL;
14339
14340
14341 /* For 2-tier tables, prefix counts need to be
14342 * maintained across multiple runs of show_adj_route()
14343 */
14344 unsigned long output_count_per_rd;
14345 unsigned long filtered_count_per_rd;
14346 unsigned long output_count = 0;
14347 unsigned long filtered_count = 0;
14348
14349 if (use_json) {
14350 json = json_object_new_object();
14351 json_ar = json_object_new_object();
14352 json_scode = json_object_new_object();
14353 json_ocode = json_object_new_object();
14354 #if CONFDATE > 20231208
14355 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
14356 #endif
14357 json_object_string_add(json_scode, "suppressed", "s");
14358 json_object_string_add(json_scode, "damped", "d");
14359 json_object_string_add(json_scode, "history", "h");
14360 json_object_string_add(json_scode, "valid", "*");
14361 json_object_string_add(json_scode, "best", ">");
14362 json_object_string_add(json_scode, "multipath", "=");
14363 json_object_string_add(json_scode, "internal", "i");
14364 json_object_string_add(json_scode, "ribFailure", "r");
14365 json_object_string_add(json_scode, "stale", "S");
14366 json_object_string_add(json_scode, "removed", "R");
14367
14368 #if CONFDATE > 20231208
14369 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
14370 #endif
14371 json_object_string_add(json_ocode, "igp", "i");
14372 json_object_string_add(json_ocode, "egp", "e");
14373 json_object_string_add(json_ocode, "incomplete", "?");
14374 }
14375
14376 if (!peer || !peer->afc[afi][safi]) {
14377 if (use_json) {
14378 json_object_string_add(
14379 json, "warning",
14380 "No such neighbor or address family");
14381 vty_out(vty, "%s\n", json_object_to_json_string(json));
14382 json_object_free(json);
14383 json_object_free(json_ar);
14384 json_object_free(json_scode);
14385 json_object_free(json_ocode);
14386 } else
14387 vty_out(vty, "%% No such neighbor or address family\n");
14388
14389 return CMD_WARNING;
14390 }
14391
14392 if ((type == bgp_show_adj_route_received
14393 || type == bgp_show_adj_route_filtered)
14394 && !CHECK_FLAG(peer->af_flags[afi][safi],
14395 PEER_FLAG_SOFT_RECONFIG)) {
14396 if (use_json) {
14397 json_object_string_add(
14398 json, "warning",
14399 "Inbound soft reconfiguration not enabled");
14400 vty_out(vty, "%s\n", json_object_to_json_string(json));
14401 json_object_free(json);
14402 json_object_free(json_ar);
14403 json_object_free(json_scode);
14404 json_object_free(json_ocode);
14405 } else
14406 vty_out(vty,
14407 "%% Inbound soft reconfiguration not enabled\n");
14408
14409 return CMD_WARNING;
14410 }
14411
14412 bgp = peer->bgp;
14413
14414 /* labeled-unicast routes live in the unicast table */
14415 if (safi == SAFI_LABELED_UNICAST)
14416 table = bgp->rib[afi][SAFI_UNICAST];
14417 else
14418 table = bgp->rib[afi][safi];
14419
14420 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14421 || (safi == SAFI_EVPN)) {
14422
14423 struct bgp_dest *dest;
14424
14425 for (dest = bgp_table_top(table); dest;
14426 dest = bgp_route_next(dest)) {
14427 table = bgp_dest_get_bgp_table_info(dest);
14428 if (!table)
14429 continue;
14430
14431 output_count_per_rd = 0;
14432 filtered_count_per_rd = 0;
14433
14434 if (use_json)
14435 json_routes = json_object_new_object();
14436
14437 const struct prefix_rd *prd;
14438 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14439 dest);
14440
14441 prefix_rd2str(prd, rd_str, sizeof(rd_str));
14442
14443 show_adj_route(vty, peer, table, afi, safi, type,
14444 rmap_name, json, json_routes, json_scode,
14445 json_ocode, show_flags, &header1,
14446 &header2, rd_str, &output_count_per_rd,
14447 &filtered_count_per_rd);
14448
14449 /* Don't include an empty RD in the output! */
14450 if (json_routes && (output_count_per_rd > 0))
14451 json_object_object_add(json_ar, rd_str,
14452 json_routes);
14453
14454 output_count += output_count_per_rd;
14455 filtered_count += filtered_count_per_rd;
14456 }
14457 } else
14458 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14459 json, json_ar, json_scode, json_ocode,
14460 show_flags, &header1, &header2, rd_str,
14461 &output_count, &filtered_count);
14462
14463 if (use_json) {
14464 if (type == bgp_show_adj_route_advertised)
14465 json_object_object_add(json, "advertisedRoutes",
14466 json_ar);
14467 else
14468 json_object_object_add(json, "receivedRoutes", json_ar);
14469 json_object_int_add(json, "totalPrefixCounter", output_count);
14470 json_object_int_add(json, "filteredPrefixCounter",
14471 filtered_count);
14472
14473 /*
14474 * These fields only give up ownership to `json` when `header1`
14475 * is used (set to zero). See code in `show_adj_route` and
14476 * `show_adj_route_header`.
14477 */
14478 if (header1 == 1) {
14479 json_object_free(json_scode);
14480 json_object_free(json_ocode);
14481 }
14482
14483 vty_json(vty, json);
14484 } else if (output_count > 0) {
14485 if (filtered_count > 0)
14486 vty_out(vty,
14487 "\nTotal number of prefixes %ld (%ld filtered)\n",
14488 output_count, filtered_count);
14489 else
14490 vty_out(vty, "\nTotal number of prefixes %ld\n",
14491 output_count);
14492 }
14493
14494 return CMD_SUCCESS;
14495 }
14496
14497 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14498 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14499 "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]",
14500 SHOW_STR
14501 IP_STR
14502 BGP_STR
14503 BGP_INSTANCE_HELP_STR
14504 BGP_AFI_HELP_STR
14505 BGP_SAFI_WITH_LABEL_HELP_STR
14506 "Detailed information on TCP and BGP neighbor connections\n"
14507 "Neighbor to display information about\n"
14508 "Neighbor to display information about\n"
14509 "Neighbor on BGP configured interface\n"
14510 "Display the routes selected by best path\n"
14511 JSON_STR
14512 "Increase table width for longer prefixes\n")
14513 {
14514 afi_t afi = AFI_IP6;
14515 safi_t safi = SAFI_UNICAST;
14516 char *rmap_name = NULL;
14517 char *peerstr = NULL;
14518 struct bgp *bgp = NULL;
14519 struct peer *peer;
14520 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14521 int idx = 0;
14522 uint16_t show_flags = 0;
14523
14524 if (uj)
14525 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14526
14527 if (wide)
14528 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14529
14530 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14531 &bgp, uj);
14532
14533 if (!idx)
14534 return CMD_WARNING;
14535
14536 argv_find(argv, argc, "neighbors", &idx);
14537 peerstr = argv[++idx]->arg;
14538
14539 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14540 if (!peer)
14541 return CMD_WARNING;
14542
14543 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14544 show_flags);
14545 }
14546
14547 DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
14548 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14549 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR " [" BGP_SAFI_WITH_LABEL_CMD_STR "]] [all$all] neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map RMAP_NAME$route_map] [detail$detail] [json$uj | wide$wide]",
14550 SHOW_STR
14551 IP_STR
14552 BGP_STR
14553 BGP_INSTANCE_HELP_STR
14554 BGP_AFI_HELP_STR
14555 BGP_SAFI_WITH_LABEL_HELP_STR
14556 "Display the entries for all address families\n"
14557 "Detailed information on TCP and BGP neighbor connections\n"
14558 "Neighbor to display information about\n"
14559 "Neighbor to display information about\n"
14560 "Neighbor on BGP configured interface\n"
14561 "Display the routes advertised to a BGP neighbor\n"
14562 "Display the received routes from neighbor\n"
14563 "Display the filtered routes received from neighbor\n"
14564 "Route-map to modify the attributes\n"
14565 "Name of the route map\n"
14566 "Display detailed version of routes\n"
14567 JSON_STR
14568 "Increase table width for longer prefixes\n")
14569 {
14570 afi_t afi = AFI_IP6;
14571 safi_t safi = SAFI_UNICAST;
14572 char *peerstr = NULL;
14573 struct bgp *bgp = NULL;
14574 struct peer *peer;
14575 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14576 int idx = 0;
14577 bool first = true;
14578 uint16_t show_flags = 0;
14579 struct listnode *node;
14580 struct bgp *abgp;
14581
14582 if (detail)
14583 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14584
14585 if (uj) {
14586 argc--;
14587 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14588 }
14589
14590 if (all) {
14591 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14592 if (argv_find(argv, argc, "ipv4", &idx))
14593 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14594
14595 if (argv_find(argv, argc, "ipv6", &idx))
14596 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14597 }
14598
14599 if (wide)
14600 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14601
14602 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14603 &bgp, uj);
14604 if (!idx)
14605 return CMD_WARNING;
14606
14607 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14608 argv_find(argv, argc, "neighbors", &idx);
14609 peerstr = argv[++idx]->arg;
14610
14611 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14612 if (!peer)
14613 return CMD_WARNING;
14614
14615 if (argv_find(argv, argc, "advertised-routes", &idx))
14616 type = bgp_show_adj_route_advertised;
14617 else if (argv_find(argv, argc, "received-routes", &idx))
14618 type = bgp_show_adj_route_received;
14619 else if (argv_find(argv, argc, "filtered-routes", &idx))
14620 type = bgp_show_adj_route_filtered;
14621
14622 if (!all)
14623 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14624 show_flags);
14625 if (uj)
14626 vty_out(vty, "{\n");
14627
14628 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14629 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14630 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14631 : AFI_IP6;
14632 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14633 FOREACH_SAFI (safi) {
14634 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14635 continue;
14636
14637 if (uj) {
14638 if (first)
14639 first = false;
14640 else
14641 vty_out(vty, ",\n");
14642 vty_out(vty, "\"%s\":",
14643 get_afi_safi_str(afi, safi,
14644 true));
14645 } else
14646 vty_out(vty,
14647 "\nFor address family: %s\n",
14648 get_afi_safi_str(afi, safi,
14649 false));
14650
14651 peer_adj_routes(vty, peer, afi, safi, type,
14652 route_map, show_flags);
14653 }
14654 }
14655 } else {
14656 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14657 FOREACH_AFI_SAFI (afi, safi) {
14658 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14659 continue;
14660
14661 if (uj) {
14662 if (first)
14663 first = false;
14664 else
14665 vty_out(vty, ",\n");
14666 vty_out(vty, "\"%s\":",
14667 get_afi_safi_str(afi, safi,
14668 true));
14669 } else
14670 vty_out(vty,
14671 "\nFor address family: %s\n",
14672 get_afi_safi_str(afi, safi,
14673 false));
14674
14675 peer_adj_routes(vty, peer, afi, safi, type,
14676 route_map, show_flags);
14677 }
14678 }
14679 }
14680 if (uj)
14681 vty_out(vty, "}\n");
14682
14683 return CMD_SUCCESS;
14684 }
14685
14686 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14687 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14688 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14689 SHOW_STR
14690 IP_STR
14691 BGP_STR
14692 BGP_INSTANCE_HELP_STR
14693 BGP_AF_STR
14694 BGP_AF_STR
14695 BGP_AF_MODIFIER_STR
14696 "Detailed information on TCP and BGP neighbor connections\n"
14697 "Neighbor to display information about\n"
14698 "Neighbor to display information about\n"
14699 "Neighbor on BGP configured interface\n"
14700 "Display information received from a BGP neighbor\n"
14701 "Display the prefixlist filter\n"
14702 JSON_STR)
14703 {
14704 afi_t afi = AFI_IP6;
14705 safi_t safi = SAFI_UNICAST;
14706 char *peerstr = NULL;
14707 char name[BUFSIZ];
14708 struct peer *peer;
14709 int count;
14710 int idx = 0;
14711 struct bgp *bgp = NULL;
14712 bool uj = use_json(argc, argv);
14713
14714 if (uj)
14715 argc--;
14716
14717 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14718 &bgp, uj);
14719 if (!idx)
14720 return CMD_WARNING;
14721
14722 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14723 argv_find(argv, argc, "neighbors", &idx);
14724 peerstr = argv[++idx]->arg;
14725
14726 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14727 if (!peer)
14728 return CMD_WARNING;
14729
14730 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14731 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14732 if (count) {
14733 if (!uj)
14734 vty_out(vty, "Address Family: %s\n",
14735 get_afi_safi_str(afi, safi, false));
14736 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14737 } else {
14738 if (uj)
14739 vty_out(vty, "{}\n");
14740 else
14741 vty_out(vty, "No functional output\n");
14742 }
14743
14744 return CMD_SUCCESS;
14745 }
14746
14747 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14748 afi_t afi, safi_t safi,
14749 enum bgp_show_type type, bool use_json)
14750 {
14751 uint16_t show_flags = 0;
14752
14753 if (use_json)
14754 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14755
14756 if (!peer || !peer->afc[afi][safi]) {
14757 if (use_json) {
14758 json_object *json_no = NULL;
14759 json_no = json_object_new_object();
14760 json_object_string_add(
14761 json_no, "warning",
14762 "No such neighbor or address family");
14763 vty_out(vty, "%s\n",
14764 json_object_to_json_string(json_no));
14765 json_object_free(json_no);
14766 } else
14767 vty_out(vty, "%% No such neighbor or address family\n");
14768 return CMD_WARNING;
14769 }
14770
14771 /* labeled-unicast routes live in the unicast table */
14772 if (safi == SAFI_LABELED_UNICAST)
14773 safi = SAFI_UNICAST;
14774
14775 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14776 RPKI_NOT_BEING_USED);
14777 }
14778
14779 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14780 show_ip_bgp_flowspec_routes_detailed_cmd,
14781 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14782 SHOW_STR
14783 IP_STR
14784 BGP_STR
14785 BGP_INSTANCE_HELP_STR
14786 BGP_AFI_HELP_STR
14787 "SAFI Flowspec\n"
14788 "Detailed information on flowspec entries\n"
14789 JSON_STR)
14790 {
14791 afi_t afi = AFI_IP6;
14792 safi_t safi = SAFI_UNICAST;
14793 struct bgp *bgp = NULL;
14794 int idx = 0;
14795 bool uj = use_json(argc, argv);
14796 uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
14797
14798 if (uj) {
14799 argc--;
14800 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14801 }
14802
14803 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14804 &bgp, uj);
14805 if (!idx)
14806 return CMD_WARNING;
14807
14808 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14809 show_flags, RPKI_NOT_BEING_USED);
14810 }
14811
14812 DEFUN (show_ip_bgp_neighbor_routes,
14813 show_ip_bgp_neighbor_routes_cmd,
14814 "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]",
14815 SHOW_STR
14816 IP_STR
14817 BGP_STR
14818 BGP_INSTANCE_HELP_STR
14819 BGP_AFI_HELP_STR
14820 BGP_SAFI_WITH_LABEL_HELP_STR
14821 "Detailed information on TCP and BGP neighbor connections\n"
14822 "Neighbor to display information about\n"
14823 "Neighbor to display information about\n"
14824 "Neighbor on BGP configured interface\n"
14825 "Display flap statistics of the routes learned from neighbor\n"
14826 "Display the dampened routes received from neighbor\n"
14827 "Display routes learned from neighbor\n"
14828 JSON_STR)
14829 {
14830 char *peerstr = NULL;
14831 struct bgp *bgp = NULL;
14832 afi_t afi = AFI_IP6;
14833 safi_t safi = SAFI_UNICAST;
14834 struct peer *peer;
14835 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14836 int idx = 0;
14837 bool uj = use_json(argc, argv);
14838
14839 if (uj)
14840 argc--;
14841
14842 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14843 &bgp, uj);
14844 if (!idx)
14845 return CMD_WARNING;
14846
14847 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14848 argv_find(argv, argc, "neighbors", &idx);
14849 peerstr = argv[++idx]->arg;
14850
14851 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14852 if (!peer)
14853 return CMD_WARNING;
14854
14855 if (argv_find(argv, argc, "flap-statistics", &idx))
14856 sh_type = bgp_show_type_flap_neighbor;
14857 else if (argv_find(argv, argc, "dampened-routes", &idx))
14858 sh_type = bgp_show_type_damp_neighbor;
14859 else if (argv_find(argv, argc, "routes", &idx))
14860 sh_type = bgp_show_type_neighbor;
14861
14862 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14863 }
14864
14865 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14866
14867 struct bgp_distance {
14868 /* Distance value for the IP source prefix. */
14869 uint8_t distance;
14870
14871 /* Name of the access-list to be matched. */
14872 char *access_list;
14873 };
14874
14875 DEFUN (show_bgp_afi_vpn_rd_route,
14876 show_bgp_afi_vpn_rd_route_cmd,
14877 "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]",
14878 SHOW_STR
14879 BGP_STR
14880 BGP_AFI_HELP_STR
14881 BGP_AF_MODIFIER_STR
14882 "Display information for a route distinguisher\n"
14883 "Route Distinguisher\n"
14884 "All Route Distinguishers\n"
14885 "Network in the BGP routing table to display\n"
14886 "Network in the BGP routing table to display\n"
14887 JSON_STR)
14888 {
14889 int ret;
14890 struct prefix_rd prd;
14891 afi_t afi = AFI_MAX;
14892 int idx = 0;
14893
14894 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14895 vty_out(vty, "%% Malformed Address Family\n");
14896 return CMD_WARNING;
14897 }
14898
14899 if (!strcmp(argv[5]->arg, "all"))
14900 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14901 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14902 RPKI_NOT_BEING_USED,
14903 use_json(argc, argv));
14904
14905 ret = str2prefix_rd(argv[5]->arg, &prd);
14906 if (!ret) {
14907 vty_out(vty, "%% Malformed Route Distinguisher\n");
14908 return CMD_WARNING;
14909 }
14910
14911 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14912 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14913 use_json(argc, argv));
14914 }
14915
14916 static struct bgp_distance *bgp_distance_new(void)
14917 {
14918 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14919 }
14920
14921 static void bgp_distance_free(struct bgp_distance *bdistance)
14922 {
14923 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14924 }
14925
14926 static int bgp_distance_set(struct vty *vty, const char *distance_str,
14927 const char *ip_str, const char *access_list_str)
14928 {
14929 int ret;
14930 afi_t afi;
14931 safi_t safi;
14932 struct prefix p;
14933 uint8_t distance;
14934 struct bgp_dest *dest;
14935 struct bgp_distance *bdistance;
14936
14937 afi = bgp_node_afi(vty);
14938 safi = bgp_node_safi(vty);
14939
14940 ret = str2prefix(ip_str, &p);
14941 if (ret == 0) {
14942 vty_out(vty, "Malformed prefix\n");
14943 return CMD_WARNING_CONFIG_FAILED;
14944 }
14945
14946 distance = atoi(distance_str);
14947
14948 /* Get BGP distance node. */
14949 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
14950 bdistance = bgp_dest_get_bgp_distance_info(dest);
14951 if (bdistance)
14952 bgp_dest_unlock_node(dest);
14953 else {
14954 bdistance = bgp_distance_new();
14955 bgp_dest_set_bgp_distance_info(dest, bdistance);
14956 }
14957
14958 /* Set distance value. */
14959 bdistance->distance = distance;
14960
14961 /* Reset access-list configuration. */
14962 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14963 if (access_list_str)
14964 bdistance->access_list =
14965 XSTRDUP(MTYPE_AS_LIST, access_list_str);
14966
14967 return CMD_SUCCESS;
14968 }
14969
14970 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
14971 const char *ip_str, const char *access_list_str)
14972 {
14973 int ret;
14974 afi_t afi;
14975 safi_t safi;
14976 struct prefix p;
14977 int distance;
14978 struct bgp_dest *dest;
14979 struct bgp_distance *bdistance;
14980
14981 afi = bgp_node_afi(vty);
14982 safi = bgp_node_safi(vty);
14983
14984 ret = str2prefix(ip_str, &p);
14985 if (ret == 0) {
14986 vty_out(vty, "Malformed prefix\n");
14987 return CMD_WARNING_CONFIG_FAILED;
14988 }
14989
14990 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
14991 if (!dest) {
14992 vty_out(vty, "Can't find specified prefix\n");
14993 return CMD_WARNING_CONFIG_FAILED;
14994 }
14995
14996 bdistance = bgp_dest_get_bgp_distance_info(dest);
14997 distance = atoi(distance_str);
14998
14999 if (bdistance->distance != distance) {
15000 vty_out(vty, "Distance does not match configured\n");
15001 bgp_dest_unlock_node(dest);
15002 return CMD_WARNING_CONFIG_FAILED;
15003 }
15004
15005 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15006 bgp_distance_free(bdistance);
15007
15008 bgp_dest_set_bgp_path_info(dest, NULL);
15009 bgp_dest_unlock_node(dest);
15010 bgp_dest_unlock_node(dest);
15011
15012 return CMD_SUCCESS;
15013 }
15014
15015 /* Apply BGP information to distance method. */
15016 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
15017 afi_t afi, safi_t safi, struct bgp *bgp)
15018 {
15019 struct bgp_dest *dest;
15020 struct prefix q = {0};
15021 struct peer *peer;
15022 struct bgp_distance *bdistance;
15023 struct access_list *alist;
15024 struct bgp_static *bgp_static;
15025
15026 if (!bgp)
15027 return 0;
15028
15029 peer = pinfo->peer;
15030
15031 if (pinfo->attr->distance)
15032 return pinfo->attr->distance;
15033
15034 /* Check source address.
15035 * Note: for aggregate route, peer can have unspec af type.
15036 */
15037 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
15038 && !sockunion2hostprefix(&peer->su, &q))
15039 return 0;
15040
15041 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
15042 if (dest) {
15043 bdistance = bgp_dest_get_bgp_distance_info(dest);
15044 bgp_dest_unlock_node(dest);
15045
15046 if (bdistance->access_list) {
15047 alist = access_list_lookup(afi, bdistance->access_list);
15048 if (alist
15049 && access_list_apply(alist, p) == FILTER_PERMIT)
15050 return bdistance->distance;
15051 } else
15052 return bdistance->distance;
15053 }
15054
15055 /* Backdoor check. */
15056 dest = bgp_node_lookup(bgp->route[afi][safi], p);
15057 if (dest) {
15058 bgp_static = bgp_dest_get_bgp_static_info(dest);
15059 bgp_dest_unlock_node(dest);
15060
15061 if (bgp_static->backdoor) {
15062 if (bgp->distance_local[afi][safi])
15063 return bgp->distance_local[afi][safi];
15064 else
15065 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15066 }
15067 }
15068
15069 if (peer->sort == BGP_PEER_EBGP) {
15070 if (bgp->distance_ebgp[afi][safi])
15071 return bgp->distance_ebgp[afi][safi];
15072 return ZEBRA_EBGP_DISTANCE_DEFAULT;
15073 } else if (peer->sort == BGP_PEER_IBGP) {
15074 if (bgp->distance_ibgp[afi][safi])
15075 return bgp->distance_ibgp[afi][safi];
15076 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15077 } else {
15078 if (bgp->distance_local[afi][safi])
15079 return bgp->distance_local[afi][safi];
15080 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15081 }
15082 }
15083
15084 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
15085 * we should tell ZEBRA update the routes for a specific
15086 * AFI/SAFI to reflect changes in RIB.
15087 */
15088 static void bgp_announce_routes_distance_update(struct bgp *bgp,
15089 afi_t update_afi,
15090 safi_t update_safi)
15091 {
15092 afi_t afi;
15093 safi_t safi;
15094
15095 FOREACH_AFI_SAFI (afi, safi) {
15096 if (!bgp_fibupd_safi(safi))
15097 continue;
15098
15099 if (afi != update_afi && safi != update_safi)
15100 continue;
15101
15102 if (BGP_DEBUG(zebra, ZEBRA))
15103 zlog_debug(
15104 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
15105 __func__, afi, safi);
15106 bgp_zebra_announce_table(bgp, afi, safi);
15107 }
15108 }
15109
15110 DEFUN (bgp_distance,
15111 bgp_distance_cmd,
15112 "distance bgp (1-255) (1-255) (1-255)",
15113 "Define an administrative distance\n"
15114 "BGP distance\n"
15115 "Distance for routes external to the AS\n"
15116 "Distance for routes internal to the AS\n"
15117 "Distance for local routes\n")
15118 {
15119 VTY_DECLVAR_CONTEXT(bgp, bgp);
15120 int idx_number = 2;
15121 int idx_number_2 = 3;
15122 int idx_number_3 = 4;
15123 int distance_ebgp = atoi(argv[idx_number]->arg);
15124 int distance_ibgp = atoi(argv[idx_number_2]->arg);
15125 int distance_local = atoi(argv[idx_number_3]->arg);
15126 afi_t afi;
15127 safi_t safi;
15128
15129 afi = bgp_node_afi(vty);
15130 safi = bgp_node_safi(vty);
15131
15132 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
15133 || bgp->distance_ibgp[afi][safi] != distance_ibgp
15134 || bgp->distance_local[afi][safi] != distance_local) {
15135 bgp->distance_ebgp[afi][safi] = distance_ebgp;
15136 bgp->distance_ibgp[afi][safi] = distance_ibgp;
15137 bgp->distance_local[afi][safi] = distance_local;
15138 bgp_announce_routes_distance_update(bgp, afi, safi);
15139 }
15140 return CMD_SUCCESS;
15141 }
15142
15143 DEFUN (no_bgp_distance,
15144 no_bgp_distance_cmd,
15145 "no distance bgp [(1-255) (1-255) (1-255)]",
15146 NO_STR
15147 "Define an administrative distance\n"
15148 "BGP distance\n"
15149 "Distance for routes external to the AS\n"
15150 "Distance for routes internal to the AS\n"
15151 "Distance for local routes\n")
15152 {
15153 VTY_DECLVAR_CONTEXT(bgp, bgp);
15154 afi_t afi;
15155 safi_t safi;
15156
15157 afi = bgp_node_afi(vty);
15158 safi = bgp_node_safi(vty);
15159
15160 if (bgp->distance_ebgp[afi][safi] != 0
15161 || bgp->distance_ibgp[afi][safi] != 0
15162 || bgp->distance_local[afi][safi] != 0) {
15163 bgp->distance_ebgp[afi][safi] = 0;
15164 bgp->distance_ibgp[afi][safi] = 0;
15165 bgp->distance_local[afi][safi] = 0;
15166 bgp_announce_routes_distance_update(bgp, afi, safi);
15167 }
15168 return CMD_SUCCESS;
15169 }
15170
15171
15172 DEFUN (bgp_distance_source,
15173 bgp_distance_source_cmd,
15174 "distance (1-255) A.B.C.D/M",
15175 "Define an administrative distance\n"
15176 "Administrative distance\n"
15177 "IP source prefix\n")
15178 {
15179 int idx_number = 1;
15180 int idx_ipv4_prefixlen = 2;
15181 bgp_distance_set(vty, argv[idx_number]->arg,
15182 argv[idx_ipv4_prefixlen]->arg, NULL);
15183 return CMD_SUCCESS;
15184 }
15185
15186 DEFUN (no_bgp_distance_source,
15187 no_bgp_distance_source_cmd,
15188 "no distance (1-255) A.B.C.D/M",
15189 NO_STR
15190 "Define an administrative distance\n"
15191 "Administrative distance\n"
15192 "IP source prefix\n")
15193 {
15194 int idx_number = 2;
15195 int idx_ipv4_prefixlen = 3;
15196 bgp_distance_unset(vty, argv[idx_number]->arg,
15197 argv[idx_ipv4_prefixlen]->arg, NULL);
15198 return CMD_SUCCESS;
15199 }
15200
15201 DEFUN (bgp_distance_source_access_list,
15202 bgp_distance_source_access_list_cmd,
15203 "distance (1-255) A.B.C.D/M WORD",
15204 "Define an administrative distance\n"
15205 "Administrative distance\n"
15206 "IP source prefix\n"
15207 "Access list name\n")
15208 {
15209 int idx_number = 1;
15210 int idx_ipv4_prefixlen = 2;
15211 int idx_word = 3;
15212 bgp_distance_set(vty, argv[idx_number]->arg,
15213 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15214 return CMD_SUCCESS;
15215 }
15216
15217 DEFUN (no_bgp_distance_source_access_list,
15218 no_bgp_distance_source_access_list_cmd,
15219 "no distance (1-255) A.B.C.D/M WORD",
15220 NO_STR
15221 "Define an administrative distance\n"
15222 "Administrative distance\n"
15223 "IP source prefix\n"
15224 "Access list name\n")
15225 {
15226 int idx_number = 2;
15227 int idx_ipv4_prefixlen = 3;
15228 int idx_word = 4;
15229 bgp_distance_unset(vty, argv[idx_number]->arg,
15230 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15231 return CMD_SUCCESS;
15232 }
15233
15234 DEFUN (ipv6_bgp_distance_source,
15235 ipv6_bgp_distance_source_cmd,
15236 "distance (1-255) X:X::X:X/M",
15237 "Define an administrative distance\n"
15238 "Administrative distance\n"
15239 "IP source prefix\n")
15240 {
15241 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15242 return CMD_SUCCESS;
15243 }
15244
15245 DEFUN (no_ipv6_bgp_distance_source,
15246 no_ipv6_bgp_distance_source_cmd,
15247 "no distance (1-255) X:X::X:X/M",
15248 NO_STR
15249 "Define an administrative distance\n"
15250 "Administrative distance\n"
15251 "IP source prefix\n")
15252 {
15253 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15254 return CMD_SUCCESS;
15255 }
15256
15257 DEFUN (ipv6_bgp_distance_source_access_list,
15258 ipv6_bgp_distance_source_access_list_cmd,
15259 "distance (1-255) X:X::X:X/M WORD",
15260 "Define an administrative distance\n"
15261 "Administrative distance\n"
15262 "IP source prefix\n"
15263 "Access list name\n")
15264 {
15265 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15266 return CMD_SUCCESS;
15267 }
15268
15269 DEFUN (no_ipv6_bgp_distance_source_access_list,
15270 no_ipv6_bgp_distance_source_access_list_cmd,
15271 "no distance (1-255) X:X::X:X/M WORD",
15272 NO_STR
15273 "Define an administrative distance\n"
15274 "Administrative distance\n"
15275 "IP source prefix\n"
15276 "Access list name\n")
15277 {
15278 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15279 return CMD_SUCCESS;
15280 }
15281
15282 DEFUN (bgp_damp_set,
15283 bgp_damp_set_cmd,
15284 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15285 "BGP Specific commands\n"
15286 "Enable route-flap dampening\n"
15287 "Half-life time for the penalty\n"
15288 "Value to start reusing a route\n"
15289 "Value to start suppressing a route\n"
15290 "Maximum duration to suppress a stable route\n")
15291 {
15292 VTY_DECLVAR_CONTEXT(bgp, bgp);
15293 int idx_half_life = 2;
15294 int idx_reuse = 3;
15295 int idx_suppress = 4;
15296 int idx_max_suppress = 5;
15297 int half = DEFAULT_HALF_LIFE * 60;
15298 int reuse = DEFAULT_REUSE;
15299 int suppress = DEFAULT_SUPPRESS;
15300 int max = 4 * half;
15301
15302 if (argc == 6) {
15303 half = atoi(argv[idx_half_life]->arg) * 60;
15304 reuse = atoi(argv[idx_reuse]->arg);
15305 suppress = atoi(argv[idx_suppress]->arg);
15306 max = atoi(argv[idx_max_suppress]->arg) * 60;
15307 } else if (argc == 3) {
15308 half = atoi(argv[idx_half_life]->arg) * 60;
15309 max = 4 * half;
15310 }
15311
15312 /*
15313 * These can't be 0 but our SA doesn't understand the
15314 * way our cli is constructed
15315 */
15316 assert(reuse);
15317 assert(half);
15318 if (suppress < reuse) {
15319 vty_out(vty,
15320 "Suppress value cannot be less than reuse value \n");
15321 return 0;
15322 }
15323
15324 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15325 reuse, suppress, max);
15326 }
15327
15328 DEFUN (bgp_damp_unset,
15329 bgp_damp_unset_cmd,
15330 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15331 NO_STR
15332 "BGP Specific commands\n"
15333 "Enable route-flap dampening\n"
15334 "Half-life time for the penalty\n"
15335 "Value to start reusing a route\n"
15336 "Value to start suppressing a route\n"
15337 "Maximum duration to suppress a stable route\n")
15338 {
15339 VTY_DECLVAR_CONTEXT(bgp, bgp);
15340 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15341 }
15342
15343 /* Display specified route of BGP table. */
15344 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15345 const char *ip_str, afi_t afi, safi_t safi,
15346 struct prefix_rd *prd, int prefix_check)
15347 {
15348 int ret;
15349 struct prefix match;
15350 struct bgp_dest *dest;
15351 struct bgp_dest *rm;
15352 struct bgp_path_info *pi;
15353 struct bgp_path_info *pi_temp;
15354 struct bgp *bgp;
15355 struct bgp_table *table;
15356
15357 /* BGP structure lookup. */
15358 if (view_name) {
15359 bgp = bgp_lookup_by_name(view_name);
15360 if (bgp == NULL) {
15361 vty_out(vty, "%% Can't find BGP instance %s\n",
15362 view_name);
15363 return CMD_WARNING;
15364 }
15365 } else {
15366 bgp = bgp_get_default();
15367 if (bgp == NULL) {
15368 vty_out(vty, "%% No BGP process is configured\n");
15369 return CMD_WARNING;
15370 }
15371 }
15372
15373 /* Check IP address argument. */
15374 ret = str2prefix(ip_str, &match);
15375 if (!ret) {
15376 vty_out(vty, "%% address is malformed\n");
15377 return CMD_WARNING;
15378 }
15379
15380 match.family = afi2family(afi);
15381
15382 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15383 || (safi == SAFI_EVPN)) {
15384 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15385 dest = bgp_route_next(dest)) {
15386 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15387
15388 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15389 continue;
15390 table = bgp_dest_get_bgp_table_info(dest);
15391 if (!table)
15392 continue;
15393 rm = bgp_node_match(table, &match);
15394 if (rm == NULL)
15395 continue;
15396
15397 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15398
15399 if (!prefix_check
15400 || rm_p->prefixlen == match.prefixlen) {
15401 pi = bgp_dest_get_bgp_path_info(rm);
15402 while (pi) {
15403 if (pi->extra && pi->extra->damp_info) {
15404 pi_temp = pi->next;
15405 bgp_damp_info_free(
15406 pi->extra->damp_info,
15407 1, afi, safi);
15408 pi = pi_temp;
15409 } else
15410 pi = pi->next;
15411 }
15412 }
15413
15414 bgp_dest_unlock_node(rm);
15415 }
15416 } else {
15417 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15418 if (dest != NULL) {
15419 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15420
15421 if (!prefix_check
15422 || dest_p->prefixlen == match.prefixlen) {
15423 pi = bgp_dest_get_bgp_path_info(dest);
15424 while (pi) {
15425 if (pi->extra && pi->extra->damp_info) {
15426 pi_temp = pi->next;
15427 bgp_damp_info_free(
15428 pi->extra->damp_info,
15429 1, afi, safi);
15430 pi = pi_temp;
15431 } else
15432 pi = pi->next;
15433 }
15434 }
15435
15436 bgp_dest_unlock_node(dest);
15437 }
15438 }
15439
15440 return CMD_SUCCESS;
15441 }
15442
15443 DEFUN (clear_ip_bgp_dampening,
15444 clear_ip_bgp_dampening_cmd,
15445 "clear ip bgp dampening",
15446 CLEAR_STR
15447 IP_STR
15448 BGP_STR
15449 "Clear route flap dampening information\n")
15450 {
15451 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15452 return CMD_SUCCESS;
15453 }
15454
15455 DEFUN (clear_ip_bgp_dampening_prefix,
15456 clear_ip_bgp_dampening_prefix_cmd,
15457 "clear ip bgp dampening A.B.C.D/M",
15458 CLEAR_STR
15459 IP_STR
15460 BGP_STR
15461 "Clear route flap dampening information\n"
15462 "IPv4 prefix\n")
15463 {
15464 int idx_ipv4_prefixlen = 4;
15465 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15466 AFI_IP, SAFI_UNICAST, NULL, 1);
15467 }
15468
15469 DEFUN (clear_ip_bgp_dampening_address,
15470 clear_ip_bgp_dampening_address_cmd,
15471 "clear ip bgp dampening A.B.C.D",
15472 CLEAR_STR
15473 IP_STR
15474 BGP_STR
15475 "Clear route flap dampening information\n"
15476 "Network to clear damping information\n")
15477 {
15478 int idx_ipv4 = 4;
15479 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15480 SAFI_UNICAST, NULL, 0);
15481 }
15482
15483 DEFUN (clear_ip_bgp_dampening_address_mask,
15484 clear_ip_bgp_dampening_address_mask_cmd,
15485 "clear ip bgp dampening A.B.C.D A.B.C.D",
15486 CLEAR_STR
15487 IP_STR
15488 BGP_STR
15489 "Clear route flap dampening information\n"
15490 "Network to clear damping information\n"
15491 "Network mask\n")
15492 {
15493 int idx_ipv4 = 4;
15494 int idx_ipv4_2 = 5;
15495 int ret;
15496 char prefix_str[BUFSIZ];
15497
15498 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15499 prefix_str, sizeof(prefix_str));
15500 if (!ret) {
15501 vty_out(vty, "%% Inconsistent address and mask\n");
15502 return CMD_WARNING;
15503 }
15504
15505 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15506 NULL, 0);
15507 }
15508
15509 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15510 {
15511 struct vty *vty = arg;
15512 struct peer *peer = bucket->data;
15513
15514 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15515 }
15516
15517 DEFUN (show_bgp_listeners,
15518 show_bgp_listeners_cmd,
15519 "show bgp listeners",
15520 SHOW_STR
15521 BGP_STR
15522 "Display Listen Sockets and who created them\n")
15523 {
15524 bgp_dump_listener_info(vty);
15525
15526 return CMD_SUCCESS;
15527 }
15528
15529 DEFUN (show_bgp_peerhash,
15530 show_bgp_peerhash_cmd,
15531 "show bgp peerhash",
15532 SHOW_STR
15533 BGP_STR
15534 "Display information about the BGP peerhash\n")
15535 {
15536 struct list *instances = bm->bgp;
15537 struct listnode *node;
15538 struct bgp *bgp;
15539
15540 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15541 vty_out(vty, "BGP: %s\n", bgp->name);
15542 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15543 vty);
15544 }
15545
15546 return CMD_SUCCESS;
15547 }
15548
15549 /* also used for encap safi */
15550 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15551 afi_t afi, safi_t safi)
15552 {
15553 struct bgp_dest *pdest;
15554 struct bgp_dest *dest;
15555 struct bgp_table *table;
15556 const struct prefix *p;
15557 const struct prefix_rd *prd;
15558 struct bgp_static *bgp_static;
15559 mpls_label_t label;
15560
15561 /* Network configuration. */
15562 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15563 pdest = bgp_route_next(pdest)) {
15564 table = bgp_dest_get_bgp_table_info(pdest);
15565 if (!table)
15566 continue;
15567
15568 for (dest = bgp_table_top(table); dest;
15569 dest = bgp_route_next(dest)) {
15570 bgp_static = bgp_dest_get_bgp_static_info(dest);
15571 if (bgp_static == NULL)
15572 continue;
15573
15574 p = bgp_dest_get_prefix(dest);
15575 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
15576 pdest);
15577
15578 /* "network" configuration display. */
15579 label = decode_label(&bgp_static->label);
15580
15581 vty_out(vty, " network %pFX rd %pRD", p, prd);
15582 if (safi == SAFI_MPLS_VPN)
15583 vty_out(vty, " label %u", label);
15584
15585 if (bgp_static->rmap.name)
15586 vty_out(vty, " route-map %s",
15587 bgp_static->rmap.name);
15588
15589 if (bgp_static->backdoor)
15590 vty_out(vty, " backdoor");
15591
15592 vty_out(vty, "\n");
15593 }
15594 }
15595 }
15596
15597 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15598 afi_t afi, safi_t safi)
15599 {
15600 struct bgp_dest *pdest;
15601 struct bgp_dest *dest;
15602 struct bgp_table *table;
15603 const struct prefix *p;
15604 const struct prefix_rd *prd;
15605 struct bgp_static *bgp_static;
15606 char buf[PREFIX_STRLEN * 2];
15607 char buf2[SU_ADDRSTRLEN];
15608 char esi_buf[ESI_STR_LEN];
15609
15610 /* Network configuration. */
15611 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15612 pdest = bgp_route_next(pdest)) {
15613 table = bgp_dest_get_bgp_table_info(pdest);
15614 if (!table)
15615 continue;
15616
15617 for (dest = bgp_table_top(table); dest;
15618 dest = bgp_route_next(dest)) {
15619 bgp_static = bgp_dest_get_bgp_static_info(dest);
15620 if (bgp_static == NULL)
15621 continue;
15622
15623 char *macrouter = NULL;
15624
15625 if (bgp_static->router_mac)
15626 macrouter = prefix_mac2str(
15627 bgp_static->router_mac, NULL, 0);
15628 if (bgp_static->eth_s_id)
15629 esi_to_str(bgp_static->eth_s_id,
15630 esi_buf, sizeof(esi_buf));
15631 p = bgp_dest_get_prefix(dest);
15632 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
15633
15634 /* "network" configuration display. */
15635 if (p->u.prefix_evpn.route_type == 5) {
15636 char local_buf[PREFIX_STRLEN];
15637
15638 uint8_t family = is_evpn_prefix_ipaddr_v4((
15639 struct prefix_evpn *)p)
15640 ? AF_INET
15641 : AF_INET6;
15642 inet_ntop(family,
15643 &p->u.prefix_evpn.prefix_addr.ip.ip
15644 .addr,
15645 local_buf, sizeof(local_buf));
15646 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15647 p->u.prefix_evpn.prefix_addr
15648 .ip_prefix_length);
15649 } else {
15650 prefix2str(p, buf, sizeof(buf));
15651 }
15652
15653 if (bgp_static->gatewayIp.family == AF_INET
15654 || bgp_static->gatewayIp.family == AF_INET6)
15655 inet_ntop(bgp_static->gatewayIp.family,
15656 &bgp_static->gatewayIp.u.prefix, buf2,
15657 sizeof(buf2));
15658 vty_out(vty,
15659 " network %s rd %pRD ethtag %u label %u esi %s gwip %s routermac %s\n",
15660 buf, prd, p->u.prefix_evpn.prefix_addr.eth_tag,
15661 decode_label(&bgp_static->label), esi_buf, buf2,
15662 macrouter);
15663
15664 XFREE(MTYPE_TMP, macrouter);
15665 }
15666 }
15667 }
15668
15669 /* Configuration of static route announcement and aggregate
15670 information. */
15671 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15672 safi_t safi)
15673 {
15674 struct bgp_dest *dest;
15675 const struct prefix *p;
15676 struct bgp_static *bgp_static;
15677 struct bgp_aggregate *bgp_aggregate;
15678
15679 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15680 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15681 return;
15682 }
15683
15684 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15685 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15686 return;
15687 }
15688
15689 /* Network configuration. */
15690 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15691 dest = bgp_route_next(dest)) {
15692 bgp_static = bgp_dest_get_bgp_static_info(dest);
15693 if (bgp_static == NULL)
15694 continue;
15695
15696 p = bgp_dest_get_prefix(dest);
15697
15698 vty_out(vty, " network %pFX", p);
15699
15700 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15701 vty_out(vty, " label-index %u",
15702 bgp_static->label_index);
15703
15704 if (bgp_static->rmap.name)
15705 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15706
15707 if (bgp_static->backdoor)
15708 vty_out(vty, " backdoor");
15709
15710 vty_out(vty, "\n");
15711 }
15712
15713 /* Aggregate-address configuration. */
15714 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15715 dest = bgp_route_next(dest)) {
15716 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15717 if (bgp_aggregate == NULL)
15718 continue;
15719
15720 p = bgp_dest_get_prefix(dest);
15721
15722 vty_out(vty, " aggregate-address %pFX", p);
15723
15724 if (bgp_aggregate->as_set)
15725 vty_out(vty, " as-set");
15726
15727 if (bgp_aggregate->summary_only)
15728 vty_out(vty, " summary-only");
15729
15730 if (bgp_aggregate->rmap.name)
15731 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15732
15733 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15734 vty_out(vty, " origin %s",
15735 bgp_origin2str(bgp_aggregate->origin));
15736
15737 if (bgp_aggregate->match_med)
15738 vty_out(vty, " matching-MED-only");
15739
15740 if (bgp_aggregate->suppress_map_name)
15741 vty_out(vty, " suppress-map %s",
15742 bgp_aggregate->suppress_map_name);
15743
15744 vty_out(vty, "\n");
15745 }
15746 }
15747
15748 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15749 safi_t safi)
15750 {
15751 struct bgp_dest *dest;
15752 struct bgp_distance *bdistance;
15753
15754 /* Distance configuration. */
15755 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15756 && bgp->distance_local[afi][safi]
15757 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15758 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15759 || bgp->distance_local[afi][safi]
15760 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15761 vty_out(vty, " distance bgp %d %d %d\n",
15762 bgp->distance_ebgp[afi][safi],
15763 bgp->distance_ibgp[afi][safi],
15764 bgp->distance_local[afi][safi]);
15765 }
15766
15767 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15768 dest = bgp_route_next(dest)) {
15769 bdistance = bgp_dest_get_bgp_distance_info(dest);
15770 if (bdistance != NULL)
15771 vty_out(vty, " distance %d %pBD %s\n",
15772 bdistance->distance, dest,
15773 bdistance->access_list ? bdistance->access_list
15774 : "");
15775 }
15776 }
15777
15778 /* Allocate routing table structure and install commands. */
15779 void bgp_route_init(void)
15780 {
15781 afi_t afi;
15782 safi_t safi;
15783
15784 /* Init BGP distance table. */
15785 FOREACH_AFI_SAFI (afi, safi)
15786 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15787
15788 /* IPv4 BGP commands. */
15789 install_element(BGP_NODE, &bgp_table_map_cmd);
15790 install_element(BGP_NODE, &bgp_network_cmd);
15791 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15792
15793 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15794
15795 /* IPv4 unicast configuration. */
15796 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15797 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15798 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15799
15800 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15801
15802 /* IPv4 multicast configuration. */
15803 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15804 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15805 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15806 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15807
15808 /* IPv4 labeled-unicast configuration. */
15809 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15810 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15811
15812 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15813 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15814 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15815 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15816 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15817 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15818 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15819 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15820
15821 install_element(VIEW_NODE,
15822 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15823 install_element(VIEW_NODE,
15824 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15825 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15826 install_element(VIEW_NODE,
15827 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15828 #ifdef KEEP_OLD_VPN_COMMANDS
15829 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15830 #endif /* KEEP_OLD_VPN_COMMANDS */
15831 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15832 install_element(VIEW_NODE,
15833 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15834
15835 /* BGP dampening clear commands */
15836 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15837 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15838
15839 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15840 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15841
15842 /* prefix count */
15843 install_element(ENABLE_NODE,
15844 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15845 #ifdef KEEP_OLD_VPN_COMMANDS
15846 install_element(ENABLE_NODE,
15847 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15848 #endif /* KEEP_OLD_VPN_COMMANDS */
15849
15850 /* New config IPv6 BGP commands. */
15851 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15852 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15853 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15854
15855 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15856
15857 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15858
15859 /* IPv6 labeled unicast address family. */
15860 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15861 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15862
15863 install_element(BGP_NODE, &bgp_distance_cmd);
15864 install_element(BGP_NODE, &no_bgp_distance_cmd);
15865 install_element(BGP_NODE, &bgp_distance_source_cmd);
15866 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15867 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15868 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15869 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15870 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15871 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15872 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15873 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15874 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15875 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15876 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15877 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15878 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15879 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15880 install_element(BGP_IPV4M_NODE,
15881 &no_bgp_distance_source_access_list_cmd);
15882 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15883 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15884 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15885 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15886 install_element(BGP_IPV6_NODE,
15887 &ipv6_bgp_distance_source_access_list_cmd);
15888 install_element(BGP_IPV6_NODE,
15889 &no_ipv6_bgp_distance_source_access_list_cmd);
15890 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15891 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15892 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15893 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15894 install_element(BGP_IPV6M_NODE,
15895 &ipv6_bgp_distance_source_access_list_cmd);
15896 install_element(BGP_IPV6M_NODE,
15897 &no_ipv6_bgp_distance_source_access_list_cmd);
15898
15899 /* BGP dampening */
15900 install_element(BGP_NODE, &bgp_damp_set_cmd);
15901 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15902 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15903 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15904 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15905 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15906 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15907 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15908 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15909 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15910 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15911 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15912 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15913 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15914
15915 /* Large Communities */
15916 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15917 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15918
15919 /* show bgp ipv4 flowspec detailed */
15920 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15921
15922 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15923 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15924 }
15925
15926 void bgp_route_finish(void)
15927 {
15928 afi_t afi;
15929 safi_t safi;
15930
15931 FOREACH_AFI_SAFI (afi, safi) {
15932 bgp_table_unlock(bgp_distance_table[afi][safi]);
15933 bgp_distance_table[afi][safi] = NULL;
15934 }
15935 }