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