]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #5809 from donaldsharp/vrf_name
[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 "prefix.h"
27 #include "linklist.h"
28 #include "memory.h"
29 #include "command.h"
30 #include "stream.h"
31 #include "filter.h"
32 #include "log.h"
33 #include "routemap.h"
34 #include "buffer.h"
35 #include "sockunion.h"
36 #include "plist.h"
37 #include "thread.h"
38 #include "workqueue.h"
39 #include "queue.h"
40 #include "memory.h"
41 #include "srv6.h"
42 #include "lib/json.h"
43 #include "lib_errors.h"
44 #include "zclient.h"
45 #include "bgpd/bgpd.h"
46 #include "bgpd/bgp_table.h"
47 #include "bgpd/bgp_route.h"
48 #include "bgpd/bgp_attr.h"
49 #include "bgpd/bgp_debug.h"
50 #include "bgpd/bgp_errors.h"
51 #include "bgpd/bgp_aspath.h"
52 #include "bgpd/bgp_regex.h"
53 #include "bgpd/bgp_community.h"
54 #include "bgpd/bgp_ecommunity.h"
55 #include "bgpd/bgp_lcommunity.h"
56 #include "bgpd/bgp_clist.h"
57 #include "bgpd/bgp_packet.h"
58 #include "bgpd/bgp_filter.h"
59 #include "bgpd/bgp_fsm.h"
60 #include "bgpd/bgp_mplsvpn.h"
61 #include "bgpd/bgp_nexthop.h"
62 #include "bgpd/bgp_damp.h"
63 #include "bgpd/bgp_advertise.h"
64 #include "bgpd/bgp_zebra.h"
65 #include "bgpd/bgp_vty.h"
66 #include "bgpd/bgp_mpath.h"
67 #include "bgpd/bgp_nht.h"
68 #include "bgpd/bgp_updgrp.h"
69 #include "bgpd/bgp_label.h"
70 #include "bgpd/bgp_addpath.h"
71 #include "bgpd/bgp_mac.h"
72
73 #if ENABLE_BGP_VNC
74 #include "bgpd/rfapi/rfapi_backend.h"
75 #include "bgpd/rfapi/vnc_import_bgp.h"
76 #include "bgpd/rfapi/vnc_export_bgp.h"
77 #endif
78 #include "bgpd/bgp_encap_types.h"
79 #include "bgpd/bgp_encap_tlv.h"
80 #include "bgpd/bgp_evpn.h"
81 #include "bgpd/bgp_evpn_vty.h"
82 #include "bgpd/bgp_flowspec.h"
83 #include "bgpd/bgp_flowspec_util.h"
84 #include "bgpd/bgp_pbr.h"
85
86 #ifndef VTYSH_EXTRACT_PL
87 #include "bgpd/bgp_route_clippy.c"
88 #endif
89
90 /* Extern from bgp_dump.c */
91 extern const char *bgp_origin_str[];
92 extern const char *bgp_origin_long_str[];
93 const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json);
94 /* PMSI strings. */
95 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
96 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
97 static const struct message bgp_pmsi_tnltype_str[] = {
98 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
99 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
100 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
101 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
102 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
103 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
104 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
105 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
106 {0}
107 };
108
109 #define VRFID_NONE_STR "-"
110
111 DEFINE_HOOK(bgp_process,
112 (struct bgp *bgp, afi_t afi, safi_t safi,
113 struct bgp_node *bn, struct peer *peer, bool withdraw),
114 (bgp, afi, safi, bn, peer, withdraw))
115
116
117 struct bgp_node *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
118 safi_t safi, struct prefix *p,
119 struct prefix_rd *prd)
120 {
121 struct bgp_node *rn;
122 struct bgp_node *prn = NULL;
123
124 assert(table);
125 if (!table)
126 return NULL;
127
128 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
129 || (safi == SAFI_EVPN)) {
130 prn = bgp_node_get(table, (struct prefix *)prd);
131
132 if (!bgp_node_has_bgp_path_info_data(prn))
133 bgp_node_set_bgp_table_info(
134 prn, bgp_table_init(table->bgp, afi, safi));
135 else
136 bgp_unlock_node(prn);
137 table = bgp_node_get_bgp_table_info(prn);
138 }
139
140 rn = bgp_node_get(table, p);
141
142 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
143 || (safi == SAFI_EVPN))
144 rn->prn = prn;
145
146 return rn;
147 }
148
149 struct bgp_node *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
150 safi_t safi, struct prefix *p,
151 struct prefix_rd *prd)
152 {
153 struct bgp_node *rn;
154 struct bgp_node *prn = NULL;
155
156 if (!table)
157 return NULL;
158
159 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
160 || (safi == SAFI_EVPN)) {
161 prn = bgp_node_lookup(table, (struct prefix *)prd);
162 if (!prn)
163 return NULL;
164
165 if (!bgp_node_has_bgp_path_info_data(prn)) {
166 bgp_unlock_node(prn);
167 return NULL;
168 }
169
170 table = bgp_node_get_bgp_table_info(prn);
171 }
172
173 rn = bgp_node_lookup(table, p);
174
175 return rn;
176 }
177
178 /* Allocate bgp_path_info_extra */
179 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
180 {
181 struct bgp_path_info_extra *new;
182 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
183 sizeof(struct bgp_path_info_extra));
184 new->label[0] = MPLS_INVALID_LABEL;
185 new->num_labels = 0;
186 new->bgp_fs_pbr = NULL;
187 new->bgp_fs_iprule = NULL;
188 return new;
189 }
190
191 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
192 {
193 struct bgp_path_info_extra *e;
194
195 if (!extra || !*extra)
196 return;
197
198 e = *extra;
199 if (e->damp_info)
200 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
201 e->damp_info->safi);
202
203 e->damp_info = NULL;
204 if (e->parent) {
205 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
206
207 if (bpi->net) {
208 /* FIXME: since multiple e may have the same e->parent
209 * and e->parent->net is holding a refcount for each
210 * of them, we need to do some fudging here.
211 *
212 * WARNING: if bpi->net->lock drops to 0, bpi may be
213 * freed as well (because bpi->net was holding the
214 * last reference to bpi) => write after free!
215 */
216 unsigned refcount;
217
218 bpi = bgp_path_info_lock(bpi);
219 refcount = bpi->net->lock - 1;
220 bgp_unlock_node((struct bgp_node *)bpi->net);
221 if (!refcount)
222 bpi->net = NULL;
223 bgp_path_info_unlock(bpi);
224 }
225 bgp_path_info_unlock(e->parent);
226 e->parent = NULL;
227 }
228
229 if (e->bgp_orig)
230 bgp_unlock(e->bgp_orig);
231
232 if ((*extra)->bgp_fs_iprule)
233 list_delete(&((*extra)->bgp_fs_iprule));
234 if ((*extra)->bgp_fs_pbr)
235 list_delete(&((*extra)->bgp_fs_pbr));
236 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
237 }
238
239 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
240 * allocated if required.
241 */
242 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
243 {
244 if (!pi->extra)
245 pi->extra = bgp_path_info_extra_new();
246 return pi->extra;
247 }
248
249 /* Free bgp route information. */
250 static void bgp_path_info_free(struct bgp_path_info *path)
251 {
252 bgp_attr_unintern(&path->attr);
253
254 bgp_unlink_nexthop(path);
255 bgp_path_info_extra_free(&path->extra);
256 bgp_path_info_mpath_free(&path->mpath);
257 if (path->net)
258 bgp_addpath_free_info_data(&path->tx_addpath,
259 &path->net->tx_addpath);
260
261 peer_unlock(path->peer); /* bgp_path_info peer reference */
262
263 XFREE(MTYPE_BGP_ROUTE, path);
264 }
265
266 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
267 {
268 path->lock++;
269 return path;
270 }
271
272 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
273 {
274 assert(path && path->lock > 0);
275 path->lock--;
276
277 if (path->lock == 0) {
278 #if 0
279 zlog_debug ("%s: unlocked and freeing", __func__);
280 zlog_backtrace (LOG_DEBUG);
281 #endif
282 bgp_path_info_free(path);
283 return NULL;
284 }
285
286 #if 0
287 if (path->lock == 1)
288 {
289 zlog_debug ("%s: unlocked to 1", __func__);
290 zlog_backtrace (LOG_DEBUG);
291 }
292 #endif
293
294 return path;
295 }
296
297 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
298 static int bgp_node_set_defer_flag(struct bgp_node *rn, bool delete)
299 {
300 struct peer *peer;
301 struct bgp_path_info *old_pi, *nextpi;
302 bool set_flag = 0;
303 struct bgp *bgp = NULL;
304 struct bgp_table *table = NULL;
305 afi_t afi = 0;
306 safi_t safi = 0;
307 char buf[PREFIX2STR_BUFFER];
308
309 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
310 * then the route selection is deferred
311 */
312 if (CHECK_FLAG(rn->flags, BGP_NODE_SELECT_DEFER) && (!delete))
313 return 0;
314
315 if (CHECK_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED)) {
316 if (BGP_DEBUG(update, UPDATE_OUT)) {
317 prefix2str(&rn->p, buf, PREFIX2STR_BUFFER);
318 zlog_debug(
319 "Route %s is in workqueue and being processed, not deferred.",
320 buf);
321 }
322 return 0;
323 }
324
325 table = bgp_node_table(rn);
326 if (table) {
327 bgp = table->bgp;
328 afi = table->afi;
329 safi = table->safi;
330 }
331
332 for (old_pi = bgp_node_get_bgp_path_info(rn);
333 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
334 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
335 continue;
336
337 /* Route selection is deferred if there is a stale path which
338 * which indicates peer is in restart mode
339 */
340 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
341 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
342 set_flag = 1;
343 } else {
344 /* If the peer is graceful restart capable and peer is
345 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
346 */
347 peer = old_pi->peer;
348 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
349 && BGP_PEER_RESTARTING_MODE(peer)
350 && (old_pi
351 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
352 set_flag = 1;
353 }
354 }
355 if (set_flag)
356 break;
357 }
358
359 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
360 * is active
361 */
362 if (set_flag && table) {
363 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
364 SET_FLAG(rn->flags, BGP_NODE_SELECT_DEFER);
365 prefix2str(&rn->p, buf, PREFIX2STR_BUFFER);
366 if (rn->rt_node == NULL)
367 rn->rt_node = listnode_add(
368 bgp->gr_info[afi][safi].route_list, rn);
369 if (BGP_DEBUG(update, UPDATE_OUT))
370 zlog_debug("DEFER route %s, rn %p, node %p",
371 buf, rn, rn->rt_node);
372 return 0;
373 }
374 }
375 return -1;
376 }
377
378 void bgp_path_info_add(struct bgp_node *rn, struct bgp_path_info *pi)
379 {
380 struct bgp_path_info *top;
381
382 top = bgp_node_get_bgp_path_info(rn);
383
384 pi->next = top;
385 pi->prev = NULL;
386 if (top)
387 top->prev = pi;
388 bgp_node_set_bgp_path_info(rn, pi);
389
390 bgp_path_info_lock(pi);
391 bgp_lock_node(rn);
392 peer_lock(pi->peer); /* bgp_path_info peer reference */
393 bgp_node_set_defer_flag(rn, false);
394 }
395
396 /* Do the actual removal of info from RIB, for use by bgp_process
397 completion callback *only* */
398 void bgp_path_info_reap(struct bgp_node *rn, struct bgp_path_info *pi)
399 {
400 if (pi->next)
401 pi->next->prev = pi->prev;
402 if (pi->prev)
403 pi->prev->next = pi->next;
404 else
405 bgp_node_set_bgp_path_info(rn, pi->next);
406
407 bgp_path_info_mpath_dequeue(pi);
408 bgp_path_info_unlock(pi);
409 bgp_unlock_node(rn);
410 }
411
412 void bgp_path_info_delete(struct bgp_node *rn, struct bgp_path_info *pi)
413 {
414 bgp_path_info_set_flag(rn, pi, BGP_PATH_REMOVED);
415 /* set of previous already took care of pcount */
416 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
417 }
418
419 /* undo the effects of a previous call to bgp_path_info_delete; typically
420 called when a route is deleted and then quickly re-added before the
421 deletion has been processed */
422 void bgp_path_info_restore(struct bgp_node *rn, struct bgp_path_info *pi)
423 {
424 bgp_path_info_unset_flag(rn, pi, BGP_PATH_REMOVED);
425 /* unset of previous already took care of pcount */
426 SET_FLAG(pi->flags, BGP_PATH_VALID);
427 }
428
429 /* Adjust pcount as required */
430 static void bgp_pcount_adjust(struct bgp_node *rn, struct bgp_path_info *pi)
431 {
432 struct bgp_table *table;
433
434 assert(rn && bgp_node_table(rn));
435 assert(pi && pi->peer && pi->peer->bgp);
436
437 table = bgp_node_table(rn);
438
439 if (pi->peer == pi->peer->bgp->peer_self)
440 return;
441
442 if (!BGP_PATH_COUNTABLE(pi)
443 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
444
445 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
446
447 /* slight hack, but more robust against errors. */
448 if (pi->peer->pcount[table->afi][table->safi])
449 pi->peer->pcount[table->afi][table->safi]--;
450 else
451 flog_err(EC_LIB_DEVELOPMENT,
452 "Asked to decrement 0 prefix count for peer");
453 } else if (BGP_PATH_COUNTABLE(pi)
454 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
455 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
456 pi->peer->pcount[table->afi][table->safi]++;
457 }
458 }
459
460 static int bgp_label_index_differs(struct bgp_path_info *pi1,
461 struct bgp_path_info *pi2)
462 {
463 return (!(pi1->attr->label_index == pi2->attr->label_index));
464 }
465
466 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
467 * This is here primarily to keep prefix-count in check.
468 */
469 void bgp_path_info_set_flag(struct bgp_node *rn, struct bgp_path_info *pi,
470 uint32_t flag)
471 {
472 SET_FLAG(pi->flags, flag);
473
474 /* early bath if we know it's not a flag that changes countability state
475 */
476 if (!CHECK_FLAG(flag,
477 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
478 return;
479
480 bgp_pcount_adjust(rn, pi);
481 }
482
483 void bgp_path_info_unset_flag(struct bgp_node *rn, struct bgp_path_info *pi,
484 uint32_t flag)
485 {
486 UNSET_FLAG(pi->flags, flag);
487
488 /* early bath if we know it's not a flag that changes countability state
489 */
490 if (!CHECK_FLAG(flag,
491 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
492 return;
493
494 bgp_pcount_adjust(rn, pi);
495 }
496
497 /* Get MED value. If MED value is missing and "bgp bestpath
498 missing-as-worst" is specified, treat it as the worst value. */
499 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
500 {
501 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
502 return attr->med;
503 else {
504 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
505 return BGP_MED_MAX;
506 else
507 return 0;
508 }
509 }
510
511 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf)
512 {
513 if (pi->addpath_rx_id)
514 sprintf(buf, "path %s (addpath rxid %d)", pi->peer->host,
515 pi->addpath_rx_id);
516 else
517 sprintf(buf, "path %s", pi->peer->host);
518 }
519
520 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
521 */
522 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
523 struct bgp_path_info *exist, int *paths_eq,
524 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
525 char *pfx_buf, afi_t afi, safi_t safi,
526 enum bgp_path_selection_reason *reason)
527 {
528 struct attr *newattr, *existattr;
529 bgp_peer_sort_t new_sort;
530 bgp_peer_sort_t exist_sort;
531 uint32_t new_pref;
532 uint32_t exist_pref;
533 uint32_t new_med;
534 uint32_t exist_med;
535 uint32_t new_weight;
536 uint32_t exist_weight;
537 uint32_t newm, existm;
538 struct in_addr new_id;
539 struct in_addr exist_id;
540 int new_cluster;
541 int exist_cluster;
542 int internal_as_route;
543 int confed_as_route;
544 int ret = 0;
545 char new_buf[PATH_ADDPATH_STR_BUFFER];
546 char exist_buf[PATH_ADDPATH_STR_BUFFER];
547 uint32_t new_mm_seq;
548 uint32_t exist_mm_seq;
549 int nh_cmp;
550
551 *paths_eq = 0;
552
553 /* 0. Null check. */
554 if (new == NULL) {
555 *reason = bgp_path_selection_none;
556 if (debug)
557 zlog_debug("%s: new is NULL", pfx_buf);
558 return 0;
559 }
560
561 if (debug)
562 bgp_path_info_path_with_addpath_rx_str(new, new_buf);
563
564 if (exist == NULL) {
565 *reason = bgp_path_selection_first;
566 if (debug)
567 zlog_debug("%s: %s is the initial bestpath", pfx_buf,
568 new_buf);
569 return 1;
570 }
571
572 if (debug) {
573 bgp_path_info_path_with_addpath_rx_str(exist, exist_buf);
574 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
575 pfx_buf, new_buf, new->flags, exist_buf,
576 exist->flags);
577 }
578
579 newattr = new->attr;
580 existattr = exist->attr;
581
582 /* For EVPN routes, we cannot just go by local vs remote, we have to
583 * look at the MAC mobility sequence number, if present.
584 */
585 if (safi == SAFI_EVPN) {
586 /* This is an error condition described in RFC 7432 Section
587 * 15.2. The RFC
588 * states that in this scenario "the PE MUST alert the operator"
589 * but it
590 * does not state what other action to take. In order to provide
591 * some
592 * consistency in this scenario we are going to prefer the path
593 * with the
594 * sticky flag.
595 */
596 if (newattr->sticky != existattr->sticky) {
597 if (!debug) {
598 prefix2str(&new->net->p, pfx_buf,
599 sizeof(*pfx_buf)
600 * PREFIX2STR_BUFFER);
601 bgp_path_info_path_with_addpath_rx_str(new,
602 new_buf);
603 bgp_path_info_path_with_addpath_rx_str(
604 exist, exist_buf);
605 }
606
607 if (newattr->sticky && !existattr->sticky) {
608 *reason = bgp_path_selection_evpn_sticky_mac;
609 if (debug)
610 zlog_debug(
611 "%s: %s wins over %s due to sticky MAC flag",
612 pfx_buf, new_buf, exist_buf);
613 return 1;
614 }
615
616 if (!newattr->sticky && existattr->sticky) {
617 *reason = bgp_path_selection_evpn_sticky_mac;
618 if (debug)
619 zlog_debug(
620 "%s: %s loses to %s due to sticky MAC flag",
621 pfx_buf, new_buf, exist_buf);
622 return 0;
623 }
624 }
625
626 new_mm_seq = mac_mobility_seqnum(newattr);
627 exist_mm_seq = mac_mobility_seqnum(existattr);
628
629 if (new_mm_seq > exist_mm_seq) {
630 *reason = bgp_path_selection_evpn_seq;
631 if (debug)
632 zlog_debug(
633 "%s: %s wins over %s due to MM seq %u > %u",
634 pfx_buf, new_buf, exist_buf, new_mm_seq,
635 exist_mm_seq);
636 return 1;
637 }
638
639 if (new_mm_seq < exist_mm_seq) {
640 *reason = bgp_path_selection_evpn_seq;
641 if (debug)
642 zlog_debug(
643 "%s: %s loses to %s due to MM seq %u < %u",
644 pfx_buf, new_buf, exist_buf, new_mm_seq,
645 exist_mm_seq);
646 return 0;
647 }
648
649 /*
650 * if sequence numbers are the same path with the lowest IP
651 * wins
652 */
653 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
654 if (nh_cmp < 0) {
655 *reason = bgp_path_selection_evpn_lower_ip;
656 if (debug)
657 zlog_debug(
658 "%s: %s wins over %s due to same MM seq %u and lower IP %s",
659 pfx_buf, new_buf, exist_buf, new_mm_seq,
660 inet_ntoa(new->attr->nexthop));
661 return 1;
662 }
663 if (nh_cmp > 0) {
664 *reason = bgp_path_selection_evpn_lower_ip;
665 if (debug)
666 zlog_debug(
667 "%s: %s loses to %s due to same MM seq %u and higher IP %s",
668 pfx_buf, new_buf, exist_buf, new_mm_seq,
669 inet_ntoa(new->attr->nexthop));
670 return 0;
671 }
672 }
673
674 /* 1. Weight check. */
675 new_weight = newattr->weight;
676 exist_weight = existattr->weight;
677
678 if (new_weight > exist_weight) {
679 *reason = bgp_path_selection_weight;
680 if (debug)
681 zlog_debug("%s: %s wins over %s due to weight %d > %d",
682 pfx_buf, new_buf, exist_buf, new_weight,
683 exist_weight);
684 return 1;
685 }
686
687 if (new_weight < exist_weight) {
688 *reason = bgp_path_selection_weight;
689 if (debug)
690 zlog_debug("%s: %s loses to %s due to weight %d < %d",
691 pfx_buf, new_buf, exist_buf, new_weight,
692 exist_weight);
693 return 0;
694 }
695
696 /* 2. Local preference check. */
697 new_pref = exist_pref = bgp->default_local_pref;
698
699 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
700 new_pref = newattr->local_pref;
701 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
702 exist_pref = existattr->local_pref;
703
704 if (new_pref > exist_pref) {
705 *reason = bgp_path_selection_local_pref;
706 if (debug)
707 zlog_debug(
708 "%s: %s wins over %s due to localpref %d > %d",
709 pfx_buf, new_buf, exist_buf, new_pref,
710 exist_pref);
711 return 1;
712 }
713
714 if (new_pref < exist_pref) {
715 *reason = bgp_path_selection_local_pref;
716 if (debug)
717 zlog_debug(
718 "%s: %s loses to %s due to localpref %d < %d",
719 pfx_buf, new_buf, exist_buf, new_pref,
720 exist_pref);
721 return 0;
722 }
723
724 /* 3. Local route check. We prefer:
725 * - BGP_ROUTE_STATIC
726 * - BGP_ROUTE_AGGREGATE
727 * - BGP_ROUTE_REDISTRIBUTE
728 */
729 if (!(new->sub_type == BGP_ROUTE_NORMAL ||
730 new->sub_type == BGP_ROUTE_IMPORTED)) {
731 *reason = bgp_path_selection_local_route;
732 if (debug)
733 zlog_debug(
734 "%s: %s wins over %s due to preferred BGP_ROUTE type",
735 pfx_buf, new_buf, exist_buf);
736 return 1;
737 }
738
739 if (!(exist->sub_type == BGP_ROUTE_NORMAL ||
740 exist->sub_type == BGP_ROUTE_IMPORTED)) {
741 *reason = bgp_path_selection_local_route;
742 if (debug)
743 zlog_debug(
744 "%s: %s loses to %s due to preferred BGP_ROUTE type",
745 pfx_buf, new_buf, exist_buf);
746 return 0;
747 }
748
749 /* 4. AS path length check. */
750 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
751 int exist_hops = aspath_count_hops(existattr->aspath);
752 int exist_confeds = aspath_count_confeds(existattr->aspath);
753
754 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
755 int aspath_hops;
756
757 aspath_hops = aspath_count_hops(newattr->aspath);
758 aspath_hops += aspath_count_confeds(newattr->aspath);
759
760 if (aspath_hops < (exist_hops + exist_confeds)) {
761 *reason = bgp_path_selection_confed_as_path;
762 if (debug)
763 zlog_debug(
764 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
765 pfx_buf, new_buf, exist_buf,
766 aspath_hops,
767 (exist_hops + exist_confeds));
768 return 1;
769 }
770
771 if (aspath_hops > (exist_hops + exist_confeds)) {
772 *reason = bgp_path_selection_confed_as_path;
773 if (debug)
774 zlog_debug(
775 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
776 pfx_buf, new_buf, exist_buf,
777 aspath_hops,
778 (exist_hops + exist_confeds));
779 return 0;
780 }
781 } else {
782 int newhops = aspath_count_hops(newattr->aspath);
783
784 if (newhops < exist_hops) {
785 *reason = bgp_path_selection_as_path;
786 if (debug)
787 zlog_debug(
788 "%s: %s wins over %s due to aspath hopcount %d < %d",
789 pfx_buf, new_buf, exist_buf,
790 newhops, exist_hops);
791 return 1;
792 }
793
794 if (newhops > exist_hops) {
795 *reason = bgp_path_selection_as_path;
796 if (debug)
797 zlog_debug(
798 "%s: %s loses to %s due to aspath hopcount %d > %d",
799 pfx_buf, new_buf, exist_buf,
800 newhops, exist_hops);
801 return 0;
802 }
803 }
804 }
805
806 /* 5. Origin check. */
807 if (newattr->origin < existattr->origin) {
808 *reason = bgp_path_selection_origin;
809 if (debug)
810 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
811 pfx_buf, new_buf, exist_buf,
812 bgp_origin_long_str[newattr->origin],
813 bgp_origin_long_str[existattr->origin]);
814 return 1;
815 }
816
817 if (newattr->origin > existattr->origin) {
818 *reason = bgp_path_selection_origin;
819 if (debug)
820 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
821 pfx_buf, new_buf, exist_buf,
822 bgp_origin_long_str[newattr->origin],
823 bgp_origin_long_str[existattr->origin]);
824 return 0;
825 }
826
827 /* 6. MED check. */
828 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
829 && aspath_count_hops(existattr->aspath) == 0);
830 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
831 && aspath_count_confeds(existattr->aspath) > 0
832 && aspath_count_hops(newattr->aspath) == 0
833 && aspath_count_hops(existattr->aspath) == 0);
834
835 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
836 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
837 || aspath_cmp_left(newattr->aspath, existattr->aspath)
838 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
839 || internal_as_route) {
840 new_med = bgp_med_value(new->attr, bgp);
841 exist_med = bgp_med_value(exist->attr, bgp);
842
843 if (new_med < exist_med) {
844 *reason = bgp_path_selection_med;
845 if (debug)
846 zlog_debug(
847 "%s: %s wins over %s due to MED %d < %d",
848 pfx_buf, new_buf, exist_buf, new_med,
849 exist_med);
850 return 1;
851 }
852
853 if (new_med > exist_med) {
854 *reason = bgp_path_selection_med;
855 if (debug)
856 zlog_debug(
857 "%s: %s loses to %s due to MED %d > %d",
858 pfx_buf, new_buf, exist_buf, new_med,
859 exist_med);
860 return 0;
861 }
862 }
863
864 /* 7. Peer type check. */
865 new_sort = new->peer->sort;
866 exist_sort = exist->peer->sort;
867
868 if (new_sort == BGP_PEER_EBGP
869 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
870 *reason = bgp_path_selection_peer;
871 if (debug)
872 zlog_debug(
873 "%s: %s wins over %s due to eBGP peer > iBGP peer",
874 pfx_buf, new_buf, exist_buf);
875 return 1;
876 }
877
878 if (exist_sort == BGP_PEER_EBGP
879 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
880 *reason = bgp_path_selection_peer;
881 if (debug)
882 zlog_debug(
883 "%s: %s loses to %s due to iBGP peer < eBGP peer",
884 pfx_buf, new_buf, exist_buf);
885 return 0;
886 }
887
888 /* 8. IGP metric check. */
889 newm = existm = 0;
890
891 if (new->extra)
892 newm = new->extra->igpmetric;
893 if (exist->extra)
894 existm = exist->extra->igpmetric;
895
896 if (newm < existm) {
897 if (debug)
898 zlog_debug(
899 "%s: %s wins over %s due to IGP metric %d < %d",
900 pfx_buf, new_buf, exist_buf, newm, existm);
901 ret = 1;
902 }
903
904 if (newm > existm) {
905 if (debug)
906 zlog_debug(
907 "%s: %s loses to %s due to IGP metric %d > %d",
908 pfx_buf, new_buf, exist_buf, newm, existm);
909 ret = 0;
910 }
911
912 /* 9. Same IGP metric. Compare the cluster list length as
913 representative of IGP hops metric. Rewrite the metric value
914 pair (newm, existm) with the cluster list length. Prefer the
915 path with smaller cluster list length. */
916 if (newm == existm) {
917 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP
918 && peer_sort_lookup(exist->peer) == BGP_PEER_IBGP
919 && (mpath_cfg == NULL
920 || CHECK_FLAG(
921 mpath_cfg->ibgp_flags,
922 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN))) {
923 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
924 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
925
926 if (newm < existm) {
927 if (debug)
928 zlog_debug(
929 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
930 pfx_buf, new_buf, exist_buf,
931 newm, existm);
932 ret = 1;
933 }
934
935 if (newm > existm) {
936 if (debug)
937 zlog_debug(
938 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
939 pfx_buf, new_buf, exist_buf,
940 newm, existm);
941 ret = 0;
942 }
943 }
944 }
945
946 /* 10. confed-external vs. confed-internal */
947 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
948 if (new_sort == BGP_PEER_CONFED
949 && exist_sort == BGP_PEER_IBGP) {
950 *reason = bgp_path_selection_confed;
951 if (debug)
952 zlog_debug(
953 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
954 pfx_buf, new_buf, exist_buf);
955 return 1;
956 }
957
958 if (exist_sort == BGP_PEER_CONFED
959 && new_sort == BGP_PEER_IBGP) {
960 *reason = bgp_path_selection_confed;
961 if (debug)
962 zlog_debug(
963 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
964 pfx_buf, new_buf, exist_buf);
965 return 0;
966 }
967 }
968
969 /* 11. Maximum path check. */
970 if (newm == existm) {
971 /* If one path has a label but the other does not, do not treat
972 * them as equals for multipath
973 */
974 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
975 != (exist->extra
976 && bgp_is_valid_label(&exist->extra->label[0]))) {
977 if (debug)
978 zlog_debug(
979 "%s: %s and %s cannot be multipath, one has a label while the other does not",
980 pfx_buf, new_buf, exist_buf);
981 } else if (CHECK_FLAG(bgp->flags,
982 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
983
984 /*
985 * For the two paths, all comparison steps till IGP
986 * metric
987 * have succeeded - including AS_PATH hop count. Since
988 * 'bgp
989 * bestpath as-path multipath-relax' knob is on, we
990 * don't need
991 * an exact match of AS_PATH. Thus, mark the paths are
992 * equal.
993 * That will trigger both these paths to get into the
994 * multipath
995 * array.
996 */
997 *paths_eq = 1;
998
999 if (debug)
1000 zlog_debug(
1001 "%s: %s and %s are equal via multipath-relax",
1002 pfx_buf, new_buf, exist_buf);
1003 } else if (new->peer->sort == BGP_PEER_IBGP) {
1004 if (aspath_cmp(new->attr->aspath,
1005 exist->attr->aspath)) {
1006 *paths_eq = 1;
1007
1008 if (debug)
1009 zlog_debug(
1010 "%s: %s and %s are equal via matching aspaths",
1011 pfx_buf, new_buf, exist_buf);
1012 }
1013 } else if (new->peer->as == exist->peer->as) {
1014 *paths_eq = 1;
1015
1016 if (debug)
1017 zlog_debug(
1018 "%s: %s and %s are equal via same remote-as",
1019 pfx_buf, new_buf, exist_buf);
1020 }
1021 } else {
1022 /*
1023 * TODO: If unequal cost ibgp multipath is enabled we can
1024 * mark the paths as equal here instead of returning
1025 */
1026 if (debug) {
1027 if (ret == 1)
1028 zlog_debug(
1029 "%s: %s wins over %s after IGP metric comparison",
1030 pfx_buf, new_buf, exist_buf);
1031 else
1032 zlog_debug(
1033 "%s: %s loses to %s after IGP metric comparison",
1034 pfx_buf, new_buf, exist_buf);
1035 }
1036 *reason = bgp_path_selection_igp_metric;
1037 return ret;
1038 }
1039
1040 /* 12. If both paths are external, prefer the path that was received
1041 first (the oldest one). This step minimizes route-flap, since a
1042 newer path won't displace an older one, even if it was the
1043 preferred route based on the additional decision criteria below. */
1044 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1045 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1046 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1047 *reason = bgp_path_selection_older;
1048 if (debug)
1049 zlog_debug(
1050 "%s: %s wins over %s due to oldest external",
1051 pfx_buf, new_buf, exist_buf);
1052 return 1;
1053 }
1054
1055 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1056 *reason = bgp_path_selection_older;
1057 if (debug)
1058 zlog_debug(
1059 "%s: %s loses to %s due to oldest external",
1060 pfx_buf, new_buf, exist_buf);
1061 return 0;
1062 }
1063 }
1064
1065 /* 13. Router-ID comparision. */
1066 /* If one of the paths is "stale", the corresponding peer router-id will
1067 * be 0 and would always win over the other path. If originator id is
1068 * used for the comparision, it will decide which path is better.
1069 */
1070 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1071 new_id.s_addr = newattr->originator_id.s_addr;
1072 else
1073 new_id.s_addr = new->peer->remote_id.s_addr;
1074 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1075 exist_id.s_addr = existattr->originator_id.s_addr;
1076 else
1077 exist_id.s_addr = exist->peer->remote_id.s_addr;
1078
1079 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1080 *reason = bgp_path_selection_router_id;
1081 if (debug)
1082 zlog_debug(
1083 "%s: %s wins over %s due to Router-ID comparison",
1084 pfx_buf, new_buf, exist_buf);
1085 return 1;
1086 }
1087
1088 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1089 *reason = bgp_path_selection_router_id;
1090 if (debug)
1091 zlog_debug(
1092 "%s: %s loses to %s due to Router-ID comparison",
1093 pfx_buf, new_buf, exist_buf);
1094 return 0;
1095 }
1096
1097 /* 14. Cluster length comparision. */
1098 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1099 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1100
1101 if (new_cluster < exist_cluster) {
1102 *reason = bgp_path_selection_cluster_length;
1103 if (debug)
1104 zlog_debug(
1105 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1106 pfx_buf, new_buf, exist_buf, new_cluster,
1107 exist_cluster);
1108 return 1;
1109 }
1110
1111 if (new_cluster > exist_cluster) {
1112 *reason = bgp_path_selection_cluster_length;
1113 if (debug)
1114 zlog_debug(
1115 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1116 pfx_buf, new_buf, exist_buf, new_cluster,
1117 exist_cluster);
1118 return 0;
1119 }
1120
1121 /* 15. Neighbor address comparision. */
1122 /* Do this only if neither path is "stale" as stale paths do not have
1123 * valid peer information (as the connection may or may not be up).
1124 */
1125 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1126 *reason = bgp_path_selection_stale;
1127 if (debug)
1128 zlog_debug(
1129 "%s: %s wins over %s due to latter path being STALE",
1130 pfx_buf, new_buf, exist_buf);
1131 return 1;
1132 }
1133
1134 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1135 *reason = bgp_path_selection_stale;
1136 if (debug)
1137 zlog_debug(
1138 "%s: %s loses to %s due to former path being STALE",
1139 pfx_buf, new_buf, exist_buf);
1140 return 0;
1141 }
1142
1143 /* locally configured routes to advertise do not have su_remote */
1144 if (new->peer->su_remote == NULL) {
1145 *reason = bgp_path_selection_local_configured;
1146 return 0;
1147 }
1148 if (exist->peer->su_remote == NULL) {
1149 *reason = bgp_path_selection_local_configured;
1150 return 1;
1151 }
1152
1153 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1154
1155 if (ret == 1) {
1156 *reason = bgp_path_selection_neighbor_ip;
1157 if (debug)
1158 zlog_debug(
1159 "%s: %s loses to %s due to Neighor IP comparison",
1160 pfx_buf, new_buf, exist_buf);
1161 return 0;
1162 }
1163
1164 if (ret == -1) {
1165 *reason = bgp_path_selection_neighbor_ip;
1166 if (debug)
1167 zlog_debug(
1168 "%s: %s wins over %s due to Neighor IP comparison",
1169 pfx_buf, new_buf, exist_buf);
1170 return 1;
1171 }
1172
1173 *reason = bgp_path_selection_default;
1174 if (debug)
1175 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1176 pfx_buf, new_buf, exist_buf);
1177
1178 return 1;
1179 }
1180
1181 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1182 * is preferred, or 0 if they are the same (usually will only occur if
1183 * multipath is enabled
1184 * This version is compatible with */
1185 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1186 struct bgp_path_info *exist, char *pfx_buf,
1187 afi_t afi, safi_t safi,
1188 enum bgp_path_selection_reason *reason)
1189 {
1190 int paths_eq;
1191 int ret;
1192 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1193 afi, safi, reason);
1194
1195 if (paths_eq)
1196 ret = 0;
1197 else {
1198 if (ret == 1)
1199 ret = -1;
1200 else
1201 ret = 1;
1202 }
1203 return ret;
1204 }
1205
1206 static enum filter_type bgp_input_filter(struct peer *peer, struct prefix *p,
1207 struct attr *attr, afi_t afi,
1208 safi_t safi)
1209 {
1210 struct bgp_filter *filter;
1211
1212 filter = &peer->filter[afi][safi];
1213
1214 #define FILTER_EXIST_WARN(F, f, filter) \
1215 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1216 zlog_debug("%s: Could not find configured input %s-list %s!", \
1217 peer->host, #f, F##_IN_NAME(filter));
1218
1219 if (DISTRIBUTE_IN_NAME(filter)) {
1220 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1221
1222 if (access_list_apply(DISTRIBUTE_IN(filter), p) == FILTER_DENY)
1223 return FILTER_DENY;
1224 }
1225
1226 if (PREFIX_LIST_IN_NAME(filter)) {
1227 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1228
1229 if (prefix_list_apply(PREFIX_LIST_IN(filter), p) == PREFIX_DENY)
1230 return FILTER_DENY;
1231 }
1232
1233 if (FILTER_LIST_IN_NAME(filter)) {
1234 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1235
1236 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1237 == AS_FILTER_DENY)
1238 return FILTER_DENY;
1239 }
1240
1241 return FILTER_PERMIT;
1242 #undef FILTER_EXIST_WARN
1243 }
1244
1245 static enum filter_type bgp_output_filter(struct peer *peer, struct prefix *p,
1246 struct attr *attr, afi_t afi,
1247 safi_t safi)
1248 {
1249 struct bgp_filter *filter;
1250
1251 filter = &peer->filter[afi][safi];
1252
1253 #define FILTER_EXIST_WARN(F, f, filter) \
1254 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1255 zlog_debug("%s: Could not find configured output %s-list %s!", \
1256 peer->host, #f, F##_OUT_NAME(filter));
1257
1258 if (DISTRIBUTE_OUT_NAME(filter)) {
1259 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1260
1261 if (access_list_apply(DISTRIBUTE_OUT(filter), p) == FILTER_DENY)
1262 return FILTER_DENY;
1263 }
1264
1265 if (PREFIX_LIST_OUT_NAME(filter)) {
1266 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1267
1268 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1269 == PREFIX_DENY)
1270 return FILTER_DENY;
1271 }
1272
1273 if (FILTER_LIST_OUT_NAME(filter)) {
1274 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1275
1276 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1277 == AS_FILTER_DENY)
1278 return FILTER_DENY;
1279 }
1280
1281 return FILTER_PERMIT;
1282 #undef FILTER_EXIST_WARN
1283 }
1284
1285 /* If community attribute includes no_export then return 1. */
1286 static int bgp_community_filter(struct peer *peer, struct attr *attr)
1287 {
1288 if (attr->community) {
1289 /* NO_ADVERTISE check. */
1290 if (community_include(attr->community, COMMUNITY_NO_ADVERTISE))
1291 return 1;
1292
1293 /* NO_EXPORT check. */
1294 if (peer->sort == BGP_PEER_EBGP
1295 && community_include(attr->community, COMMUNITY_NO_EXPORT))
1296 return 1;
1297
1298 /* NO_EXPORT_SUBCONFED check. */
1299 if (peer->sort == BGP_PEER_EBGP
1300 || peer->sort == BGP_PEER_CONFED)
1301 if (community_include(attr->community,
1302 COMMUNITY_NO_EXPORT_SUBCONFED))
1303 return 1;
1304 }
1305 return 0;
1306 }
1307
1308 /* Route reflection loop check. */
1309 static int bgp_cluster_filter(struct peer *peer, struct attr *attr)
1310 {
1311 struct in_addr cluster_id;
1312
1313 if (attr->cluster) {
1314 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1315 cluster_id = peer->bgp->cluster_id;
1316 else
1317 cluster_id = peer->bgp->router_id;
1318
1319 if (cluster_loop_check(attr->cluster, cluster_id))
1320 return 1;
1321 }
1322 return 0;
1323 }
1324
1325 static int bgp_input_modifier(struct peer *peer, struct prefix *p,
1326 struct attr *attr, afi_t afi, safi_t safi,
1327 const char *rmap_name, mpls_label_t *label,
1328 uint32_t num_labels, struct bgp_node *rn)
1329 {
1330 struct bgp_filter *filter;
1331 struct bgp_path_info rmap_path = { 0 };
1332 struct bgp_path_info_extra extra = { 0 };
1333 route_map_result_t ret;
1334 struct route_map *rmap = NULL;
1335
1336 filter = &peer->filter[afi][safi];
1337
1338 /* Apply default weight value. */
1339 if (peer->weight[afi][safi])
1340 attr->weight = peer->weight[afi][safi];
1341
1342 if (rmap_name) {
1343 rmap = route_map_lookup_by_name(rmap_name);
1344
1345 if (rmap == NULL)
1346 return RMAP_DENY;
1347 } else {
1348 if (ROUTE_MAP_IN_NAME(filter)) {
1349 rmap = ROUTE_MAP_IN(filter);
1350
1351 if (rmap == NULL)
1352 return RMAP_DENY;
1353 }
1354 }
1355
1356 /* Route map apply. */
1357 if (rmap) {
1358 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1359 /* Duplicate current value to new strucutre for modification. */
1360 rmap_path.peer = peer;
1361 rmap_path.attr = attr;
1362 rmap_path.extra = &extra;
1363 rmap_path.net = rn;
1364
1365 extra.num_labels = num_labels;
1366 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1367 memcpy(extra.label, label,
1368 num_labels * sizeof(mpls_label_t));
1369
1370 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1371
1372 /* Apply BGP route map to the attribute. */
1373 ret = route_map_apply(rmap, p, RMAP_BGP, &rmap_path);
1374
1375 peer->rmap_type = 0;
1376
1377 if (ret == RMAP_DENYMATCH)
1378 return RMAP_DENY;
1379 }
1380 return RMAP_PERMIT;
1381 }
1382
1383 static int bgp_output_modifier(struct peer *peer, struct prefix *p,
1384 struct attr *attr, afi_t afi, safi_t safi,
1385 const char *rmap_name)
1386 {
1387 struct bgp_path_info rmap_path;
1388 route_map_result_t ret;
1389 struct route_map *rmap = NULL;
1390 uint8_t rmap_type;
1391
1392 /*
1393 * So if we get to this point and have no rmap_name
1394 * we want to just show the output as it currently
1395 * exists.
1396 */
1397 if (!rmap_name)
1398 return RMAP_PERMIT;
1399
1400 /* Apply default weight value. */
1401 if (peer->weight[afi][safi])
1402 attr->weight = peer->weight[afi][safi];
1403
1404 rmap = route_map_lookup_by_name(rmap_name);
1405
1406 /*
1407 * If we have a route map name and we do not find
1408 * the routemap that means we have an implicit
1409 * deny.
1410 */
1411 if (rmap == NULL)
1412 return RMAP_DENY;
1413
1414 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1415 /* Route map apply. */
1416 /* Duplicate current value to new strucutre for modification. */
1417 rmap_path.peer = peer;
1418 rmap_path.attr = attr;
1419
1420 rmap_type = peer->rmap_type;
1421 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1422
1423 /* Apply BGP route map to the attribute. */
1424 ret = route_map_apply(rmap, p, RMAP_BGP, &rmap_path);
1425
1426 peer->rmap_type = rmap_type;
1427
1428 if (ret == RMAP_DENYMATCH)
1429 /*
1430 * caller has multiple error paths with bgp_attr_flush()
1431 */
1432 return RMAP_DENY;
1433
1434 return RMAP_PERMIT;
1435 }
1436
1437 /* If this is an EBGP peer with remove-private-AS */
1438 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1439 struct peer *peer, struct attr *attr)
1440 {
1441 if (peer->sort == BGP_PEER_EBGP
1442 && (peer_af_flag_check(peer, afi, safi,
1443 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1444 || peer_af_flag_check(peer, afi, safi,
1445 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1446 || peer_af_flag_check(peer, afi, safi,
1447 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1448 || peer_af_flag_check(peer, afi, safi,
1449 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1450 // Take action on the entire aspath
1451 if (peer_af_flag_check(peer, afi, safi,
1452 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1453 || peer_af_flag_check(peer, afi, safi,
1454 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1455 if (peer_af_flag_check(
1456 peer, afi, safi,
1457 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1458 attr->aspath = aspath_replace_private_asns(
1459 attr->aspath, bgp->as, peer->as);
1460
1461 // The entire aspath consists of private ASNs so create
1462 // an empty aspath
1463 else if (aspath_private_as_check(attr->aspath))
1464 attr->aspath = aspath_empty_get();
1465
1466 // There are some public and some private ASNs, remove
1467 // the private ASNs
1468 else
1469 attr->aspath = aspath_remove_private_asns(
1470 attr->aspath, peer->as);
1471 }
1472
1473 // 'all' was not specified so the entire aspath must be private
1474 // ASNs
1475 // for us to do anything
1476 else if (aspath_private_as_check(attr->aspath)) {
1477 if (peer_af_flag_check(
1478 peer, afi, safi,
1479 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1480 attr->aspath = aspath_replace_private_asns(
1481 attr->aspath, bgp->as, peer->as);
1482 else
1483 attr->aspath = aspath_empty_get();
1484 }
1485 }
1486 }
1487
1488 /* If this is an EBGP peer with as-override */
1489 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1490 struct peer *peer, struct attr *attr)
1491 {
1492 if (peer->sort == BGP_PEER_EBGP
1493 && peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1494 if (aspath_single_asn_check(attr->aspath, peer->as))
1495 attr->aspath = aspath_replace_specific_asn(
1496 attr->aspath, peer->as, bgp->as);
1497 }
1498 }
1499
1500 void bgp_attr_add_gshut_community(struct attr *attr)
1501 {
1502 struct community *old;
1503 struct community *new;
1504 struct community *merge;
1505 struct community *gshut;
1506
1507 old = attr->community;
1508 gshut = community_str2com("graceful-shutdown");
1509
1510 assert(gshut);
1511
1512 if (old) {
1513 merge = community_merge(community_dup(old), gshut);
1514
1515 if (old->refcnt == 0)
1516 community_free(&old);
1517
1518 new = community_uniq_sort(merge);
1519 community_free(&merge);
1520 } else {
1521 new = community_dup(gshut);
1522 }
1523
1524 community_free(&gshut);
1525 attr->community = new;
1526 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
1527
1528 /* When we add the graceful-shutdown community we must also
1529 * lower the local-preference */
1530 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1531 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1532 }
1533
1534
1535 static void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1536 {
1537 if (family == AF_INET) {
1538 attr->nexthop.s_addr = INADDR_ANY;
1539 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1540 }
1541 if (family == AF_INET6)
1542 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1543 if (family == AF_EVPN)
1544 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1545 }
1546
1547 int subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi,
1548 struct update_subgroup *subgrp, struct prefix *p,
1549 struct attr *attr)
1550 {
1551 struct bgp_filter *filter;
1552 struct peer *from;
1553 struct peer *peer;
1554 struct peer *onlypeer;
1555 struct bgp *bgp;
1556 struct attr *piattr;
1557 char buf[PREFIX_STRLEN];
1558 route_map_result_t ret;
1559 int transparent;
1560 int reflect;
1561 afi_t afi;
1562 safi_t safi;
1563 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1564
1565 if (DISABLE_BGP_ANNOUNCE)
1566 return 0;
1567
1568 afi = SUBGRP_AFI(subgrp);
1569 safi = SUBGRP_SAFI(subgrp);
1570 peer = SUBGRP_PEER(subgrp);
1571 onlypeer = NULL;
1572 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1573 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1574
1575 from = pi->peer;
1576 filter = &peer->filter[afi][safi];
1577 bgp = SUBGRP_INST(subgrp);
1578 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
1579 : pi->attr;
1580
1581 #if ENABLE_BGP_VNC
1582 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
1583 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
1584 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
1585
1586 /*
1587 * direct and direct_ext type routes originate internally even
1588 * though they can have peer pointers that reference other
1589 * systems
1590 */
1591 prefix2str(p, buf, PREFIX_STRLEN);
1592 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe",
1593 __func__, buf);
1594 samepeer_safe = 1;
1595 }
1596 #endif
1597
1598 if (((afi == AFI_IP) || (afi == AFI_IP6))
1599 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
1600 && (pi->type == ZEBRA_ROUTE_BGP)
1601 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
1602
1603 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1604
1605 samepeer_safe = 1;
1606 }
1607
1608 /* With addpath we may be asked to TX all kinds of paths so make sure
1609 * pi is valid */
1610 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
1611 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
1612 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
1613 return 0;
1614 }
1615
1616 /* If this is not the bestpath then check to see if there is an enabled
1617 * addpath
1618 * feature that requires us to advertise it */
1619 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
1620 if (!bgp_addpath_tx_path(peer->addpath_type[afi][safi], pi)) {
1621 return 0;
1622 }
1623 }
1624
1625 /* Aggregate-address suppress check. */
1626 if (pi->extra && pi->extra->suppress)
1627 if (!UNSUPPRESS_MAP_NAME(filter)) {
1628 return 0;
1629 }
1630
1631 /*
1632 * If we are doing VRF 2 VRF leaking via the import
1633 * statement, we want to prevent the route going
1634 * off box as that the RT and RD created are localy
1635 * significant and globaly useless.
1636 */
1637 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
1638 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
1639 return 0;
1640
1641 /* If it's labeled safi, make sure the route has a valid label. */
1642 if (safi == SAFI_LABELED_UNICAST) {
1643 mpls_label_t label = bgp_adv_label(rn, pi, peer, afi, safi);
1644 if (!bgp_is_valid_label(&label)) {
1645 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1646 zlog_debug("u%" PRIu64 ":s%" PRIu64
1647 " %s/%d is filtered - no label (%p)",
1648 subgrp->update_group->id, subgrp->id,
1649 inet_ntop(p->family, &p->u.prefix,
1650 buf, SU_ADDRSTRLEN),
1651 p->prefixlen, &label);
1652 return 0;
1653 }
1654 }
1655
1656 /* Do not send back route to sender. */
1657 if (onlypeer && from == onlypeer) {
1658 return 0;
1659 }
1660
1661 /* Do not send the default route in the BGP table if the neighbor is
1662 * configured for default-originate */
1663 if (CHECK_FLAG(peer->af_flags[afi][safi],
1664 PEER_FLAG_DEFAULT_ORIGINATE)) {
1665 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
1666 return 0;
1667 else if (p->family == AF_INET6 && p->prefixlen == 0)
1668 return 0;
1669 }
1670
1671 /* Transparency check. */
1672 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
1673 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1674 transparent = 1;
1675 else
1676 transparent = 0;
1677
1678 /* If community is not disabled check the no-export and local. */
1679 if (!transparent && bgp_community_filter(peer, piattr)) {
1680 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1681 zlog_debug(
1682 "subgrpannouncecheck: community filter check fail");
1683 return 0;
1684 }
1685
1686 /* If the attribute has originator-id and it is same as remote
1687 peer's id. */
1688 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
1689 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
1690 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1691 zlog_debug(
1692 "%s [Update:SEND] %s originator-id is same as "
1693 "remote router-id",
1694 onlypeer->host,
1695 prefix2str(p, buf, sizeof(buf)));
1696 return 0;
1697 }
1698
1699 /* ORF prefix-list filter check */
1700 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
1701 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
1702 || CHECK_FLAG(peer->af_cap[afi][safi],
1703 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
1704 if (peer->orf_plist[afi][safi]) {
1705 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
1706 == PREFIX_DENY) {
1707 if (bgp_debug_update(NULL, p,
1708 subgrp->update_group, 0))
1709 zlog_debug(
1710 "%s [Update:SEND] %s is filtered via ORF",
1711 peer->host,
1712 prefix2str(p, buf,
1713 sizeof(buf)));
1714 return 0;
1715 }
1716 }
1717
1718 /* Output filter check. */
1719 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
1720 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1721 zlog_debug("%s [Update:SEND] %s is filtered",
1722 peer->host, prefix2str(p, buf, sizeof(buf)));
1723 return 0;
1724 }
1725
1726 /* AS path loop check. */
1727 if (onlypeer && onlypeer->as_path_loop_detection
1728 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
1729 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1730 zlog_debug(
1731 "%s [Update:SEND] suppress announcement to peer AS %u "
1732 "that is part of AS path.",
1733 onlypeer->host, onlypeer->as);
1734 return 0;
1735 }
1736
1737 /* If we're a CONFED we need to loop check the CONFED ID too */
1738 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1739 if (aspath_loop_check(piattr->aspath, bgp->confed_id)) {
1740 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1741 zlog_debug(
1742 "%s [Update:SEND] suppress announcement to peer AS %u"
1743 " is AS path.",
1744 peer->host, bgp->confed_id);
1745 return 0;
1746 }
1747 }
1748
1749 /* Route-Reflect check. */
1750 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
1751 reflect = 1;
1752 else
1753 reflect = 0;
1754
1755 /* IBGP reflection check. */
1756 if (reflect && !samepeer_safe) {
1757 /* A route from a Client peer. */
1758 if (CHECK_FLAG(from->af_flags[afi][safi],
1759 PEER_FLAG_REFLECTOR_CLIENT)) {
1760 /* Reflect to all the Non-Client peers and also to the
1761 Client peers other than the originator. Originator
1762 check
1763 is already done. So there is noting to do. */
1764 /* no bgp client-to-client reflection check. */
1765 if (CHECK_FLAG(bgp->flags,
1766 BGP_FLAG_NO_CLIENT_TO_CLIENT))
1767 if (CHECK_FLAG(peer->af_flags[afi][safi],
1768 PEER_FLAG_REFLECTOR_CLIENT))
1769 return 0;
1770 } else {
1771 /* A route from a Non-client peer. Reflect to all other
1772 clients. */
1773 if (!CHECK_FLAG(peer->af_flags[afi][safi],
1774 PEER_FLAG_REFLECTOR_CLIENT))
1775 return 0;
1776 }
1777 }
1778
1779 /* For modify attribute, copy it to temporary structure. */
1780 *attr = *piattr;
1781
1782 /* If local-preference is not set. */
1783 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
1784 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
1785 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1786 attr->local_pref = bgp->default_local_pref;
1787 }
1788
1789 /* If originator-id is not set and the route is to be reflected,
1790 set the originator id */
1791 if (reflect
1792 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
1793 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
1794 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
1795 }
1796
1797 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
1798 */
1799 if (peer->sort == BGP_PEER_EBGP
1800 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
1801 if (from != bgp->peer_self && !transparent
1802 && !CHECK_FLAG(peer->af_flags[afi][safi],
1803 PEER_FLAG_MED_UNCHANGED))
1804 attr->flag &=
1805 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
1806 }
1807
1808 /* Since the nexthop attribute can vary per peer, it is not explicitly
1809 * set
1810 * in announce check, only certain flags and length (or number of
1811 * nexthops
1812 * -- for IPv6/MP_REACH) are set here in order to guide the update
1813 * formation
1814 * code in setting the nexthop(s) on a per peer basis in
1815 * reformat_peer().
1816 * Typically, the source nexthop in the attribute is preserved but in
1817 * the
1818 * scenarios where we know it will always be overwritten, we reset the
1819 * nexthop to "0" in an attempt to achieve better Update packing. An
1820 * example of this is when a prefix from each of 2 IBGP peers needs to
1821 * be
1822 * announced to an EBGP peer (and they have the same attributes barring
1823 * their nexthop).
1824 */
1825 if (reflect)
1826 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
1827
1828 #define NEXTHOP_IS_V6 \
1829 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
1830 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
1831 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
1832 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1833
1834 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
1835 * if
1836 * the peer (group) is configured to receive link-local nexthop
1837 * unchanged
1838 * and it is available in the prefix OR we're not reflecting the route,
1839 * link-local nexthop address is valid and
1840 * the peer (group) to whom we're going to announce is on a shared
1841 * network
1842 * and this is either a self-originated route or the peer is EBGP.
1843 * By checking if nexthop LL address is valid we are sure that
1844 * we do not announce LL address as `::`.
1845 */
1846 if (NEXTHOP_IS_V6) {
1847 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
1848 if ((CHECK_FLAG(peer->af_flags[afi][safi],
1849 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
1850 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
1851 || (!reflect
1852 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
1853 && peer->shared_network
1854 && (from == bgp->peer_self
1855 || peer->sort == BGP_PEER_EBGP))) {
1856 attr->mp_nexthop_len =
1857 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
1858 }
1859
1860 /* Clear off link-local nexthop in source, whenever it is not
1861 * needed to
1862 * ensure more prefixes share the same attribute for
1863 * announcement.
1864 */
1865 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
1866 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
1867 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
1868 }
1869
1870 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
1871 bgp_peer_as_override(bgp, afi, safi, peer, attr);
1872
1873 /* Route map & unsuppress-map apply. */
1874 if (ROUTE_MAP_OUT_NAME(filter) || (pi->extra && pi->extra->suppress)) {
1875 struct bgp_path_info rmap_path = {0};
1876 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
1877 struct attr dummy_attr = {0};
1878
1879 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1880 rmap_path.peer = peer;
1881 rmap_path.attr = attr;
1882 rmap_path.net = rn;
1883
1884 if (pi->extra) {
1885 memcpy(&dummy_rmap_path_extra, pi->extra,
1886 sizeof(struct bgp_path_info_extra));
1887 rmap_path.extra = &dummy_rmap_path_extra;
1888 }
1889
1890 /* don't confuse inbound and outbound setting */
1891 RESET_FLAG(attr->rmap_change_flags);
1892
1893 /*
1894 * The route reflector is not allowed to modify the attributes
1895 * of the reflected IBGP routes unless explicitly allowed.
1896 */
1897 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
1898 && !CHECK_FLAG(bgp->flags,
1899 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
1900 dummy_attr = *attr;
1901 rmap_path.attr = &dummy_attr;
1902 }
1903
1904 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1905
1906 if (pi->extra && pi->extra->suppress)
1907 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
1908 RMAP_BGP, &rmap_path);
1909 else
1910 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
1911 RMAP_BGP, &rmap_path);
1912
1913 peer->rmap_type = 0;
1914
1915 if (ret == RMAP_DENYMATCH) {
1916 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1917 zlog_debug("%s [Update:SEND] %s is filtered by route-map",
1918 peer->host, prefix2str(p, buf, sizeof(buf)));
1919
1920 bgp_attr_flush(attr);
1921 return 0;
1922 }
1923 }
1924
1925 /* RFC 8212 to prevent route leaks.
1926 * This specification intends to improve this situation by requiring the
1927 * explicit configuration of both BGP Import and Export Policies for any
1928 * External BGP (EBGP) session such as customers, peers, or
1929 * confederation boundaries for all enabled address families. Through
1930 * codification of the aforementioned requirement, operators will
1931 * benefit from consistent behavior across different BGP
1932 * implementations.
1933 */
1934 if (peer->bgp->ebgp_requires_policy
1935 == DEFAULT_EBGP_POLICY_ENABLED)
1936 if (!bgp_outbound_policy_exists(peer, filter))
1937 return 0;
1938
1939 /* draft-ietf-idr-deprecate-as-set-confed-set
1940 * Filter routes having AS_SET or AS_CONFED_SET in the path.
1941 * Eventually, This document (if approved) updates RFC 4271
1942 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
1943 * and obsoletes RFC 6472.
1944 */
1945 if (peer->bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED)
1946 if (aspath_check_as_sets(attr->aspath))
1947 return 0;
1948
1949 if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
1950 if (peer->sort == BGP_PEER_IBGP
1951 || peer->sort == BGP_PEER_CONFED) {
1952 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1953 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1954 } else {
1955 bgp_attr_add_gshut_community(attr);
1956 }
1957 }
1958
1959 /* After route-map has been applied, we check to see if the nexthop to
1960 * be carried in the attribute (that is used for the announcement) can
1961 * be cleared off or not. We do this in all cases where we would be
1962 * setting the nexthop to "ourselves". For IPv6, we only need to
1963 * consider
1964 * the global nexthop here; the link-local nexthop would have been
1965 * cleared
1966 * already, and if not, it is required by the update formation code.
1967 * Also see earlier comments in this function.
1968 */
1969 /*
1970 * If route-map has performed some operation on the nexthop or the peer
1971 * configuration says to pass it unchanged, we cannot reset the nexthop
1972 * here, so only attempt to do it if these aren't true. Note that the
1973 * route-map handler itself might have cleared the nexthop, if for
1974 * example,
1975 * it is configured as 'peer-address'.
1976 */
1977 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
1978 piattr->rmap_change_flags)
1979 && !transparent
1980 && !CHECK_FLAG(peer->af_flags[afi][safi],
1981 PEER_FLAG_NEXTHOP_UNCHANGED)) {
1982 /* We can reset the nexthop, if setting (or forcing) it to
1983 * 'self' */
1984 if (CHECK_FLAG(peer->af_flags[afi][safi],
1985 PEER_FLAG_NEXTHOP_SELF)
1986 || CHECK_FLAG(peer->af_flags[afi][safi],
1987 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
1988 if (!reflect
1989 || CHECK_FLAG(peer->af_flags[afi][safi],
1990 PEER_FLAG_FORCE_NEXTHOP_SELF))
1991 subgroup_announce_reset_nhop(
1992 (peer_cap_enhe(peer, afi, safi)
1993 ? AF_INET6
1994 : p->family),
1995 attr);
1996 } else if (peer->sort == BGP_PEER_EBGP) {
1997 /* Can also reset the nexthop if announcing to EBGP, but
1998 * only if
1999 * no peer in the subgroup is on a shared subnet.
2000 * Note: 3rd party nexthop currently implemented for
2001 * IPv4 only.
2002 */
2003 if ((p->family == AF_INET) &&
2004 (!bgp_subgrp_multiaccess_check_v4(
2005 piattr->nexthop,
2006 subgrp)))
2007 subgroup_announce_reset_nhop(
2008 (peer_cap_enhe(peer, afi, safi)
2009 ? AF_INET6
2010 : p->family),
2011 attr);
2012
2013 if ((p->family == AF_INET6) &&
2014 (!bgp_subgrp_multiaccess_check_v6(
2015 piattr->mp_nexthop_global,
2016 subgrp)))
2017 subgroup_announce_reset_nhop(
2018 (peer_cap_enhe(peer, afi, safi)
2019 ? AF_INET6
2020 : p->family),
2021 attr);
2022
2023
2024
2025 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2026 /*
2027 * This flag is used for leaked vpn-vrf routes
2028 */
2029 int family = p->family;
2030
2031 if (peer_cap_enhe(peer, afi, safi))
2032 family = AF_INET6;
2033
2034 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2035 zlog_debug(
2036 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
2037 __func__, family2str(family));
2038 subgroup_announce_reset_nhop(family, attr);
2039 }
2040 }
2041
2042 /* If IPv6/MP and nexthop does not have any override and happens
2043 * to
2044 * be a link-local address, reset it so that we don't pass along
2045 * the
2046 * source's link-local IPv6 address to recipients who may not be
2047 * on
2048 * the same interface.
2049 */
2050 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2051 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global))
2052 subgroup_announce_reset_nhop(AF_INET6, attr);
2053 }
2054
2055 return 1;
2056 }
2057
2058 static int bgp_route_select_timer_expire(struct thread *thread)
2059 {
2060 struct afi_safi_info *info;
2061 afi_t afi;
2062 safi_t safi;
2063 struct bgp *bgp;
2064
2065 info = THREAD_ARG(thread);
2066 afi = info->afi;
2067 safi = info->safi;
2068 bgp = info->bgp;
2069
2070 if (BGP_DEBUG(update, UPDATE_OUT))
2071 zlog_debug("afi %d, safi %d : route select timer expired", afi,
2072 safi);
2073
2074 bgp->gr_info[afi][safi].t_route_select = NULL;
2075
2076 XFREE(MTYPE_TMP, info);
2077
2078 /* Best path selection */
2079 return bgp_best_path_select_defer(bgp, afi, safi);
2080 }
2081
2082 void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
2083 struct bgp_maxpaths_cfg *mpath_cfg,
2084 struct bgp_path_info_pair *result, afi_t afi,
2085 safi_t safi)
2086 {
2087 struct bgp_path_info *new_select;
2088 struct bgp_path_info *old_select;
2089 struct bgp_path_info *pi;
2090 struct bgp_path_info *pi1;
2091 struct bgp_path_info *pi2;
2092 struct bgp_path_info *nextpi = NULL;
2093 int paths_eq, do_mpath, debug;
2094 struct list mp_list;
2095 char pfx_buf[PREFIX2STR_BUFFER];
2096 char path_buf[PATH_ADDPATH_STR_BUFFER];
2097
2098 bgp_mp_list_init(&mp_list);
2099 do_mpath =
2100 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2101
2102 debug = bgp_debug_bestpath(&rn->p);
2103
2104 if (debug)
2105 prefix2str(&rn->p, pfx_buf, sizeof(pfx_buf));
2106
2107 /* bgp deterministic-med */
2108 new_select = NULL;
2109 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2110
2111 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2112 for (pi1 = bgp_node_get_bgp_path_info(rn); pi1;
2113 pi1 = pi1->next)
2114 bgp_path_info_unset_flag(rn, pi1,
2115 BGP_PATH_DMED_SELECTED);
2116
2117 for (pi1 = bgp_node_get_bgp_path_info(rn); pi1;
2118 pi1 = pi1->next) {
2119 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2120 continue;
2121 if (BGP_PATH_HOLDDOWN(pi1))
2122 continue;
2123 if (pi1->peer != bgp->peer_self)
2124 if (pi1->peer->status != Established)
2125 continue;
2126
2127 new_select = pi1;
2128 if (pi1->next) {
2129 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2130 if (CHECK_FLAG(pi2->flags,
2131 BGP_PATH_DMED_CHECK))
2132 continue;
2133 if (BGP_PATH_HOLDDOWN(pi2))
2134 continue;
2135 if (pi2->peer != bgp->peer_self
2136 && !CHECK_FLAG(
2137 pi2->peer->sflags,
2138 PEER_STATUS_NSF_WAIT))
2139 if (pi2->peer->status
2140 != Established)
2141 continue;
2142
2143 if (!aspath_cmp_left(pi1->attr->aspath,
2144 pi2->attr->aspath)
2145 && !aspath_cmp_left_confed(
2146 pi1->attr->aspath,
2147 pi2->attr->aspath))
2148 continue;
2149
2150 if (bgp_path_info_cmp(
2151 bgp, pi2, new_select,
2152 &paths_eq, mpath_cfg, debug,
2153 pfx_buf, afi, safi,
2154 &rn->reason)) {
2155 bgp_path_info_unset_flag(
2156 rn, new_select,
2157 BGP_PATH_DMED_SELECTED);
2158 new_select = pi2;
2159 }
2160
2161 bgp_path_info_set_flag(
2162 rn, pi2, BGP_PATH_DMED_CHECK);
2163 }
2164 }
2165 bgp_path_info_set_flag(rn, new_select,
2166 BGP_PATH_DMED_CHECK);
2167 bgp_path_info_set_flag(rn, new_select,
2168 BGP_PATH_DMED_SELECTED);
2169
2170 if (debug) {
2171 bgp_path_info_path_with_addpath_rx_str(
2172 new_select, path_buf);
2173 zlog_debug("%s: %s is the bestpath from AS %u",
2174 pfx_buf, path_buf,
2175 aspath_get_first_as(
2176 new_select->attr->aspath));
2177 }
2178 }
2179 }
2180
2181 /* Check old selected route and new selected route. */
2182 old_select = NULL;
2183 new_select = NULL;
2184 for (pi = bgp_node_get_bgp_path_info(rn);
2185 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2186 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2187 old_select = pi;
2188
2189 if (BGP_PATH_HOLDDOWN(pi)) {
2190 /* reap REMOVED routes, if needs be
2191 * selected route must stay for a while longer though
2192 */
2193 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2194 && (pi != old_select))
2195 bgp_path_info_reap(rn, pi);
2196
2197 if (debug)
2198 zlog_debug("%s: pi %p in holddown", __func__,
2199 pi);
2200
2201 continue;
2202 }
2203
2204 if (pi->peer && pi->peer != bgp->peer_self
2205 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2206 if (pi->peer->status != Established) {
2207
2208 if (debug)
2209 zlog_debug(
2210 "%s: pi %p non self peer %s not estab state",
2211 __func__, pi, pi->peer->host);
2212
2213 continue;
2214 }
2215
2216 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2217 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2218 bgp_path_info_unset_flag(rn, pi, BGP_PATH_DMED_CHECK);
2219 if (debug)
2220 zlog_debug("%s: pi %p dmed", __func__, pi);
2221 continue;
2222 }
2223
2224 bgp_path_info_unset_flag(rn, pi, BGP_PATH_DMED_CHECK);
2225
2226 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2227 debug, pfx_buf, afi, safi, &rn->reason)) {
2228 new_select = pi;
2229 }
2230 }
2231
2232 /* Now that we know which path is the bestpath see if any of the other
2233 * paths
2234 * qualify as multipaths
2235 */
2236 if (debug) {
2237 if (new_select)
2238 bgp_path_info_path_with_addpath_rx_str(new_select,
2239 path_buf);
2240 else
2241 sprintf(path_buf, "NONE");
2242 zlog_debug(
2243 "%s: After path selection, newbest is %s oldbest was %s",
2244 pfx_buf, path_buf,
2245 old_select ? old_select->peer->host : "NONE");
2246 }
2247
2248 if (do_mpath && new_select) {
2249 for (pi = bgp_node_get_bgp_path_info(rn);
2250 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2251
2252 if (debug)
2253 bgp_path_info_path_with_addpath_rx_str(
2254 pi, path_buf);
2255
2256 if (pi == new_select) {
2257 if (debug)
2258 zlog_debug(
2259 "%s: %s is the bestpath, add to the multipath list",
2260 pfx_buf, path_buf);
2261 bgp_mp_list_add(&mp_list, pi);
2262 continue;
2263 }
2264
2265 if (BGP_PATH_HOLDDOWN(pi))
2266 continue;
2267
2268 if (pi->peer && pi->peer != bgp->peer_self
2269 && !CHECK_FLAG(pi->peer->sflags,
2270 PEER_STATUS_NSF_WAIT))
2271 if (pi->peer->status != Established)
2272 continue;
2273
2274 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2275 if (debug)
2276 zlog_debug(
2277 "%s: %s has the same nexthop as the bestpath, skip it",
2278 pfx_buf, path_buf);
2279 continue;
2280 }
2281
2282 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2283 mpath_cfg, debug, pfx_buf, afi, safi,
2284 &rn->reason);
2285
2286 if (paths_eq) {
2287 if (debug)
2288 zlog_debug(
2289 "%s: %s is equivalent to the bestpath, add to the multipath list",
2290 pfx_buf, path_buf);
2291 bgp_mp_list_add(&mp_list, pi);
2292 }
2293 }
2294 }
2295
2296 bgp_path_info_mpath_update(rn, new_select, old_select, &mp_list,
2297 mpath_cfg);
2298 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2299 bgp_mp_list_clear(&mp_list);
2300
2301 bgp_addpath_update_ids(bgp, rn, afi, safi);
2302
2303 result->old = old_select;
2304 result->new = new_select;
2305
2306 return;
2307 }
2308
2309 /*
2310 * A new route/change in bestpath of an existing route. Evaluate the path
2311 * for advertisement to the subgroup.
2312 */
2313 int subgroup_process_announce_selected(struct update_subgroup *subgrp,
2314 struct bgp_path_info *selected,
2315 struct bgp_node *rn,
2316 uint32_t addpath_tx_id)
2317 {
2318 struct prefix *p;
2319 struct peer *onlypeer;
2320 struct attr attr;
2321 afi_t afi;
2322 safi_t safi;
2323
2324 p = &rn->p;
2325 afi = SUBGRP_AFI(subgrp);
2326 safi = SUBGRP_SAFI(subgrp);
2327 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2328 : NULL);
2329
2330 if (BGP_DEBUG(update, UPDATE_OUT)) {
2331 char buf_prefix[PREFIX_STRLEN];
2332 prefix2str(p, buf_prefix, sizeof(buf_prefix));
2333 zlog_debug("%s: p=%s, selected=%p", __func__, buf_prefix,
2334 selected);
2335 }
2336
2337 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2338 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2339 PEER_STATUS_ORF_WAIT_REFRESH))
2340 return 0;
2341
2342 memset(&attr, 0, sizeof(struct attr));
2343 /* It's initialized in bgp_announce_check() */
2344
2345 /* Announcement to the subgroup. If the route is filtered withdraw it.
2346 */
2347 if (selected) {
2348 if (subgroup_announce_check(rn, selected, subgrp, p, &attr))
2349 bgp_adj_out_set_subgroup(rn, subgrp, &attr, selected);
2350 else
2351 bgp_adj_out_unset_subgroup(rn, subgrp, 1,
2352 addpath_tx_id);
2353 }
2354
2355 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2356 else {
2357 bgp_adj_out_unset_subgroup(rn, subgrp, 1, addpath_tx_id);
2358 }
2359
2360 return 0;
2361 }
2362
2363 /*
2364 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2365 * This is called at the end of route processing.
2366 */
2367 void bgp_zebra_clear_route_change_flags(struct bgp_node *rn)
2368 {
2369 struct bgp_path_info *pi;
2370
2371 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
2372 if (BGP_PATH_HOLDDOWN(pi))
2373 continue;
2374 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2375 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2376 }
2377 }
2378
2379 /*
2380 * Has the route changed from the RIB's perspective? This is invoked only
2381 * if the route selection returns the same best route as earlier - to
2382 * determine if we need to update zebra or not.
2383 */
2384 int bgp_zebra_has_route_changed(struct bgp_node *rn,
2385 struct bgp_path_info *selected)
2386 {
2387 struct bgp_path_info *mpinfo;
2388
2389 /* If this is multipath, check all selected paths for any nexthop
2390 * change or attribute change. Some attribute changes (e.g., community)
2391 * aren't of relevance to the RIB, but we'll update zebra to ensure
2392 * we handle the case of BGP nexthop change. This is the behavior
2393 * when the best path has an attribute change anyway.
2394 */
2395 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2396 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG))
2397 return 1;
2398
2399 /*
2400 * If this is multipath, check all selected paths for any nexthop change
2401 */
2402 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2403 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2404 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2405 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2406 return 1;
2407 }
2408
2409 /* Nothing has changed from the RIB's perspective. */
2410 return 0;
2411 }
2412
2413 struct bgp_process_queue {
2414 struct bgp *bgp;
2415 STAILQ_HEAD(, bgp_node) pqueue;
2416 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2417 unsigned int flags;
2418 unsigned int queued;
2419 };
2420
2421 /*
2422 * old_select = The old best path
2423 * new_select = the new best path
2424 *
2425 * if (!old_select && new_select)
2426 * We are sending new information on.
2427 *
2428 * if (old_select && new_select) {
2429 * if (new_select != old_select)
2430 * We have a new best path send a change
2431 * else
2432 * We've received a update with new attributes that needs
2433 * to be passed on.
2434 * }
2435 *
2436 * if (old_select && !new_select)
2437 * We have no eligible route that we can announce or the rn
2438 * is being removed.
2439 */
2440 static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
2441 afi_t afi, safi_t safi)
2442 {
2443 struct bgp_path_info *new_select;
2444 struct bgp_path_info *old_select;
2445 struct bgp_path_info_pair old_and_new;
2446 char pfx_buf[PREFIX2STR_BUFFER];
2447 int debug = 0;
2448
2449 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
2450 if (rn)
2451 debug = bgp_debug_bestpath(&rn->p);
2452 if (debug) {
2453 prefix2str(&rn->p, pfx_buf, sizeof(pfx_buf));
2454 zlog_debug(
2455 "%s: bgp delete in progress, ignoring event, p=%s",
2456 __func__, pfx_buf);
2457 }
2458 return;
2459 }
2460 /* Is it end of initial update? (after startup) */
2461 if (!rn) {
2462 quagga_timestamp(3, bgp->update_delay_zebra_resume_time,
2463 sizeof(bgp->update_delay_zebra_resume_time));
2464
2465 bgp->main_zebra_update_hold = 0;
2466 FOREACH_AFI_SAFI (afi, safi) {
2467 if (bgp_fibupd_safi(safi))
2468 bgp_zebra_announce_table(bgp, afi, safi);
2469 }
2470 bgp->main_peers_update_hold = 0;
2471
2472 bgp_start_routeadv(bgp);
2473 return;
2474 }
2475
2476 struct prefix *p = &rn->p;
2477
2478 debug = bgp_debug_bestpath(&rn->p);
2479 if (debug) {
2480 prefix2str(&rn->p, pfx_buf, sizeof(pfx_buf));
2481 zlog_debug("%s: p=%s afi=%s, safi=%s start", __func__, pfx_buf,
2482 afi2str(afi), safi2str(safi));
2483 }
2484
2485 /* The best path calculation for the route is deferred if
2486 * BGP_NODE_SELECT_DEFER is set
2487 */
2488 if (CHECK_FLAG(rn->flags, BGP_NODE_SELECT_DEFER)) {
2489 if (BGP_DEBUG(update, UPDATE_OUT))
2490 zlog_debug("SELECT_DEFER falg set for route %p", rn);
2491 return;
2492 }
2493
2494 /* Best path selection. */
2495 bgp_best_selection(bgp, rn, &bgp->maxpaths[afi][safi], &old_and_new,
2496 afi, safi);
2497 old_select = old_and_new.old;
2498 new_select = old_and_new.new;
2499
2500 /* Do we need to allocate or free labels?
2501 * Right now, since we only deal with per-prefix labels, it is not
2502 * necessary to do this upon changes to best path. Exceptions:
2503 * - label index has changed -> recalculate resulting label
2504 * - path_info sub_type changed -> switch to/from implicit-null
2505 * - no valid label (due to removed static label binding) -> get new one
2506 */
2507 if (bgp->allocate_mpls_labels[afi][safi]) {
2508 if (new_select) {
2509 if (!old_select
2510 || bgp_label_index_differs(new_select, old_select)
2511 || new_select->sub_type != old_select->sub_type
2512 || !bgp_is_valid_label(&rn->local_label)) {
2513 /* Enforced penultimate hop popping:
2514 * implicit-null for local routes, aggregate
2515 * and redistributed routes
2516 */
2517 if (new_select->sub_type == BGP_ROUTE_STATIC
2518 || new_select->sub_type
2519 == BGP_ROUTE_AGGREGATE
2520 || new_select->sub_type
2521 == BGP_ROUTE_REDISTRIBUTE) {
2522 if (CHECK_FLAG(
2523 rn->flags,
2524 BGP_NODE_REGISTERED_FOR_LABEL))
2525 bgp_unregister_for_label(rn);
2526 label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1,
2527 &rn->local_label);
2528 bgp_set_valid_label(&rn->local_label);
2529 } else
2530 bgp_register_for_label(rn, new_select);
2531 }
2532 } else if (CHECK_FLAG(rn->flags,
2533 BGP_NODE_REGISTERED_FOR_LABEL)) {
2534 bgp_unregister_for_label(rn);
2535 }
2536 } else if (CHECK_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) {
2537 bgp_unregister_for_label(rn);
2538 }
2539
2540 if (debug) {
2541 prefix2str(&rn->p, pfx_buf, sizeof(pfx_buf));
2542 zlog_debug(
2543 "%s: p=%s afi=%s, safi=%s, old_select=%p, new_select=%p",
2544 __func__, pfx_buf, afi2str(afi), safi2str(safi),
2545 old_select, new_select);
2546 }
2547
2548 /* If best route remains the same and this is not due to user-initiated
2549 * clear, see exactly what needs to be done.
2550 */
2551 if (old_select && old_select == new_select
2552 && !CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR)
2553 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2554 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
2555 if (bgp_zebra_has_route_changed(rn, old_select)) {
2556 #if ENABLE_BGP_VNC
2557 vnc_import_bgp_add_route(bgp, p, old_select);
2558 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
2559 #endif
2560 if (bgp_fibupd_safi(safi)
2561 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2562
2563 if (new_select->type == ZEBRA_ROUTE_BGP
2564 && (new_select->sub_type == BGP_ROUTE_NORMAL
2565 || new_select->sub_type
2566 == BGP_ROUTE_IMPORTED))
2567
2568 bgp_zebra_announce(rn, p, old_select,
2569 bgp, afi, safi);
2570 }
2571 }
2572 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
2573 bgp_zebra_clear_route_change_flags(rn);
2574
2575 /* If there is a change of interest to peers, reannounce the
2576 * route. */
2577 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2578 || CHECK_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED)) {
2579 group_announce_route(bgp, afi, safi, rn, new_select);
2580
2581 /* unicast routes must also be annouced to
2582 * labeled-unicast update-groups */
2583 if (safi == SAFI_UNICAST)
2584 group_announce_route(bgp, afi,
2585 SAFI_LABELED_UNICAST, rn,
2586 new_select);
2587
2588 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
2589 UNSET_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED);
2590 }
2591
2592 UNSET_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED);
2593 return;
2594 }
2595
2596 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2597 */
2598 UNSET_FLAG(rn->flags, BGP_NODE_USER_CLEAR);
2599
2600 /* bestpath has changed; bump version */
2601 if (old_select || new_select) {
2602 bgp_bump_version(rn);
2603
2604 if (!bgp->t_rmap_def_originate_eval) {
2605 bgp_lock(bgp);
2606 thread_add_timer(
2607 bm->master,
2608 update_group_refresh_default_originate_route_map,
2609 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
2610 &bgp->t_rmap_def_originate_eval);
2611 }
2612 }
2613
2614 if (old_select)
2615 bgp_path_info_unset_flag(rn, old_select, BGP_PATH_SELECTED);
2616 if (new_select) {
2617 if (debug)
2618 zlog_debug("%s: setting SELECTED flag", __func__);
2619 bgp_path_info_set_flag(rn, new_select, BGP_PATH_SELECTED);
2620 bgp_path_info_unset_flag(rn, new_select, BGP_PATH_ATTR_CHANGED);
2621 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
2622 }
2623
2624 #if ENABLE_BGP_VNC
2625 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
2626 if (old_select != new_select) {
2627 if (old_select) {
2628 vnc_import_bgp_exterior_del_route(bgp, p,
2629 old_select);
2630 vnc_import_bgp_del_route(bgp, p, old_select);
2631 }
2632 if (new_select) {
2633 vnc_import_bgp_exterior_add_route(bgp, p,
2634 new_select);
2635 vnc_import_bgp_add_route(bgp, p, new_select);
2636 }
2637 }
2638 }
2639 #endif
2640
2641 group_announce_route(bgp, afi, safi, rn, new_select);
2642
2643 /* unicast routes must also be annouced to labeled-unicast update-groups
2644 */
2645 if (safi == SAFI_UNICAST)
2646 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, rn,
2647 new_select);
2648
2649 /* FIB update. */
2650 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
2651 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2652 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
2653 && (new_select->sub_type == BGP_ROUTE_NORMAL
2654 || new_select->sub_type == BGP_ROUTE_AGGREGATE
2655 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
2656
2657 /* if this is an evpn imported type-5 prefix,
2658 * we need to withdraw the route first to clear
2659 * the nh neigh and the RMAC entry.
2660 */
2661 if (old_select &&
2662 is_route_parent_evpn(old_select))
2663 bgp_zebra_withdraw(p, old_select, bgp, safi);
2664
2665 bgp_zebra_announce(rn, p, new_select, bgp, afi, safi);
2666 } else {
2667 /* Withdraw the route from the kernel. */
2668 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
2669 && (old_select->sub_type == BGP_ROUTE_NORMAL
2670 || old_select->sub_type == BGP_ROUTE_AGGREGATE
2671 || old_select->sub_type == BGP_ROUTE_IMPORTED))
2672
2673 bgp_zebra_withdraw(p, old_select, bgp, safi);
2674 }
2675 }
2676
2677 /* advertise/withdraw type-5 routes */
2678 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
2679 if (advertise_type5_routes(bgp, afi) &&
2680 new_select &&
2681 is_route_injectable_into_evpn(new_select)) {
2682
2683 /* apply the route-map */
2684 if (bgp->adv_cmd_rmap[afi][safi].map) {
2685 route_map_result_t ret;
2686
2687 ret = route_map_apply(
2688 bgp->adv_cmd_rmap[afi][safi].map,
2689 &rn->p, RMAP_BGP, new_select);
2690 if (ret == RMAP_PERMITMATCH)
2691 bgp_evpn_advertise_type5_route(
2692 bgp, &rn->p, new_select->attr,
2693 afi, safi);
2694 else
2695 bgp_evpn_withdraw_type5_route(
2696 bgp, &rn->p, afi, safi);
2697 } else {
2698 bgp_evpn_advertise_type5_route(bgp,
2699 &rn->p,
2700 new_select->attr,
2701 afi, safi);
2702
2703 }
2704 } else if (advertise_type5_routes(bgp, afi) &&
2705 old_select &&
2706 is_route_injectable_into_evpn(old_select))
2707 bgp_evpn_withdraw_type5_route(bgp, &rn->p, afi, safi);
2708 }
2709
2710 /* Clear any route change flags. */
2711 bgp_zebra_clear_route_change_flags(rn);
2712
2713 /* Reap old select bgp_path_info, if it has been removed */
2714 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
2715 bgp_path_info_reap(rn, old_select);
2716
2717 UNSET_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED);
2718 return;
2719 }
2720
2721 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
2722 int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
2723 {
2724 struct bgp_node *rn;
2725 int cnt = 0;
2726 struct afi_safi_info *thread_info;
2727 struct listnode *node = NULL, *nnode = NULL;
2728
2729 if (bgp->gr_info[afi][safi].t_route_select)
2730 BGP_TIMER_OFF(bgp->gr_info[afi][safi].t_route_select);
2731
2732 if (BGP_DEBUG(update, UPDATE_OUT)) {
2733 zlog_debug("%s: processing route for %s : cnt %d", __func__,
2734 get_afi_safi_str(afi, safi, false),
2735 listcount(bgp->gr_info[afi][safi].route_list));
2736 }
2737
2738 /* Process the route list */
2739 node = listhead(bgp->gr_info[afi][safi].route_list);
2740 while (node) {
2741 rn = listgetdata(node);
2742 nnode = node->next;
2743 list_delete_node(bgp->gr_info[afi][safi].route_list, node);
2744 rn->rt_node = NULL;
2745
2746 if (CHECK_FLAG(rn->flags, BGP_NODE_SELECT_DEFER)) {
2747 UNSET_FLAG(rn->flags, BGP_NODE_SELECT_DEFER);
2748 bgp_process_main_one(bgp, rn, afi, safi);
2749 cnt++;
2750 if (cnt >= BGP_MAX_BEST_ROUTE_SELECT)
2751 break;
2752 }
2753 node = nnode;
2754 }
2755
2756 /* Send EOR message when all routes are processed */
2757 if (list_isempty(bgp->gr_info[afi][safi].route_list)) {
2758 bgp_send_delayed_eor(bgp);
2759 /* Send route processing complete message to RIB */
2760 bgp_zebra_update(afi, safi, bgp->vrf_id,
2761 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
2762 return 0;
2763 }
2764
2765 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
2766
2767 thread_info->afi = afi;
2768 thread_info->safi = safi;
2769 thread_info->bgp = bgp;
2770
2771 /* If there are more routes to be processed, start the
2772 * selection timer
2773 */
2774 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
2775 BGP_ROUTE_SELECT_DELAY,
2776 &bgp->gr_info[afi][safi].t_route_select);
2777 return 0;
2778 }
2779
2780 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
2781 {
2782 struct bgp_process_queue *pqnode = data;
2783 struct bgp *bgp = pqnode->bgp;
2784 struct bgp_table *table;
2785 struct bgp_node *rn;
2786
2787 /* eoiu marker */
2788 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
2789 bgp_process_main_one(bgp, NULL, 0, 0);
2790 /* should always have dedicated wq call */
2791 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
2792 return WQ_SUCCESS;
2793 }
2794
2795 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
2796 rn = STAILQ_FIRST(&pqnode->pqueue);
2797 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
2798 STAILQ_NEXT(rn, pq) = NULL; /* complete unlink */
2799 table = bgp_node_table(rn);
2800 /* note, new RNs may be added as part of processing */
2801 bgp_process_main_one(bgp, rn, table->afi, table->safi);
2802
2803 bgp_unlock_node(rn);
2804 bgp_table_unlock(table);
2805 }
2806
2807 return WQ_SUCCESS;
2808 }
2809
2810 static void bgp_processq_del(struct work_queue *wq, void *data)
2811 {
2812 struct bgp_process_queue *pqnode = data;
2813
2814 bgp_unlock(pqnode->bgp);
2815
2816 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
2817 }
2818
2819 void bgp_process_queue_init(void)
2820 {
2821 if (!bm->process_main_queue)
2822 bm->process_main_queue =
2823 work_queue_new(bm->master, "process_main_queue");
2824
2825 bm->process_main_queue->spec.workfunc = &bgp_process_wq;
2826 bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
2827 bm->process_main_queue->spec.max_retries = 0;
2828 bm->process_main_queue->spec.hold = 50;
2829 /* Use a higher yield value of 50ms for main queue processing */
2830 bm->process_main_queue->spec.yield = 50 * 1000L;
2831 }
2832
2833 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
2834 {
2835 struct bgp_process_queue *pqnode;
2836
2837 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
2838 sizeof(struct bgp_process_queue));
2839
2840 /* unlocked in bgp_processq_del */
2841 pqnode->bgp = bgp_lock(bgp);
2842 STAILQ_INIT(&pqnode->pqueue);
2843
2844 return pqnode;
2845 }
2846
2847 void bgp_process(struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi)
2848 {
2849 #define ARBITRARY_PROCESS_QLEN 10000
2850 struct work_queue *wq = bm->process_main_queue;
2851 struct bgp_process_queue *pqnode;
2852 int pqnode_reuse = 0;
2853
2854 /* already scheduled for processing? */
2855 if (CHECK_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED))
2856 return;
2857
2858 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
2859 * the workqueue
2860 */
2861 if (CHECK_FLAG(rn->flags, BGP_NODE_SELECT_DEFER)) {
2862 if (BGP_DEBUG(update, UPDATE_OUT))
2863 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
2864 rn);
2865 return;
2866 }
2867
2868 if (wq == NULL)
2869 return;
2870
2871 /* Add route nodes to an existing work queue item until reaching the
2872 limit only if is from the same BGP view and it's not an EOIU marker
2873 */
2874 if (work_queue_item_count(wq)) {
2875 struct work_queue_item *item = work_queue_last_item(wq);
2876 pqnode = item->data;
2877
2878 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
2879 || pqnode->bgp != bgp
2880 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
2881 pqnode = bgp_processq_alloc(bgp);
2882 else
2883 pqnode_reuse = 1;
2884 } else
2885 pqnode = bgp_processq_alloc(bgp);
2886 /* all unlocked in bgp_process_wq */
2887 bgp_table_lock(bgp_node_table(rn));
2888
2889 SET_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED);
2890 bgp_lock_node(rn);
2891
2892 /* can't be enqueued twice */
2893 assert(STAILQ_NEXT(rn, pq) == NULL);
2894 STAILQ_INSERT_TAIL(&pqnode->pqueue, rn, pq);
2895 pqnode->queued++;
2896
2897 if (!pqnode_reuse)
2898 work_queue_add(wq, pqnode);
2899
2900 return;
2901 }
2902
2903 void bgp_add_eoiu_mark(struct bgp *bgp)
2904 {
2905 struct bgp_process_queue *pqnode;
2906
2907 if (bm->process_main_queue == NULL)
2908 return;
2909
2910 pqnode = bgp_processq_alloc(bgp);
2911
2912 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
2913 work_queue_add(bm->process_main_queue, pqnode);
2914 }
2915
2916 static int bgp_maximum_prefix_restart_timer(struct thread *thread)
2917 {
2918 struct peer *peer;
2919
2920 peer = THREAD_ARG(thread);
2921 peer->t_pmax_restart = NULL;
2922
2923 if (bgp_debug_neighbor_events(peer))
2924 zlog_debug(
2925 "%s Maximum-prefix restart timer expired, restore peering",
2926 peer->host);
2927
2928 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
2929 zlog_debug("%s: %s peer_clear failed",
2930 __PRETTY_FUNCTION__, peer->host);
2931
2932 return 0;
2933 }
2934
2935 int bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
2936 int always)
2937 {
2938 iana_afi_t pkt_afi;
2939 iana_safi_t pkt_safi;
2940
2941 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
2942 return 0;
2943
2944 if (peer->pcount[afi][safi] > peer->pmax[afi][safi]) {
2945 if (CHECK_FLAG(peer->af_sflags[afi][safi],
2946 PEER_STATUS_PREFIX_LIMIT)
2947 && !always)
2948 return 0;
2949
2950 zlog_info(
2951 "%%MAXPFXEXCEED: No. of %s prefix received from %s %" PRIu32
2952 " exceed, limit %" PRIu32,
2953 get_afi_safi_str(afi, safi, false), peer->host,
2954 peer->pcount[afi][safi], peer->pmax[afi][safi]);
2955 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
2956
2957 if (CHECK_FLAG(peer->af_flags[afi][safi],
2958 PEER_FLAG_MAX_PREFIX_WARNING))
2959 return 0;
2960
2961 /* Convert AFI, SAFI to values for packet. */
2962 pkt_afi = afi_int2iana(afi);
2963 pkt_safi = safi_int2iana(safi);
2964 {
2965 uint8_t ndata[7];
2966
2967 ndata[0] = (pkt_afi >> 8);
2968 ndata[1] = pkt_afi;
2969 ndata[2] = pkt_safi;
2970 ndata[3] = (peer->pmax[afi][safi] >> 24);
2971 ndata[4] = (peer->pmax[afi][safi] >> 16);
2972 ndata[5] = (peer->pmax[afi][safi] >> 8);
2973 ndata[6] = (peer->pmax[afi][safi]);
2974
2975 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
2976 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
2977 BGP_NOTIFY_CEASE_MAX_PREFIX,
2978 ndata, 7);
2979 }
2980
2981 /* Dynamic peers will just close their connection. */
2982 if (peer_dynamic_neighbor(peer))
2983 return 1;
2984
2985 /* restart timer start */
2986 if (peer->pmax_restart[afi][safi]) {
2987 peer->v_pmax_restart =
2988 peer->pmax_restart[afi][safi] * 60;
2989
2990 if (bgp_debug_neighbor_events(peer))
2991 zlog_debug(
2992 "%s Maximum-prefix restart timer started for %d secs",
2993 peer->host, peer->v_pmax_restart);
2994
2995 BGP_TIMER_ON(peer->t_pmax_restart,
2996 bgp_maximum_prefix_restart_timer,
2997 peer->v_pmax_restart);
2998 }
2999
3000 return 1;
3001 } else
3002 UNSET_FLAG(peer->af_sflags[afi][safi],
3003 PEER_STATUS_PREFIX_LIMIT);
3004
3005 if (peer->pcount[afi][safi]
3006 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3007 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3008 PEER_STATUS_PREFIX_THRESHOLD)
3009 && !always)
3010 return 0;
3011
3012 zlog_info(
3013 "%%MAXPFX: No. of %s prefix received from %s reaches %" PRIu32
3014 ", max %" PRIu32,
3015 get_afi_safi_str(afi, safi, false), peer->host,
3016 peer->pcount[afi][safi], peer->pmax[afi][safi]);
3017 SET_FLAG(peer->af_sflags[afi][safi],
3018 PEER_STATUS_PREFIX_THRESHOLD);
3019 } else
3020 UNSET_FLAG(peer->af_sflags[afi][safi],
3021 PEER_STATUS_PREFIX_THRESHOLD);
3022 return 0;
3023 }
3024
3025 /* Unconditionally remove the route from the RIB, without taking
3026 * damping into consideration (eg, because the session went down)
3027 */
3028 void bgp_rib_remove(struct bgp_node *rn, struct bgp_path_info *pi,
3029 struct peer *peer, afi_t afi, safi_t safi)
3030 {
3031
3032 struct bgp *bgp = NULL;
3033 bool delete_route = false;
3034
3035 bgp_aggregate_decrement(peer->bgp, &rn->p, pi, afi, safi);
3036
3037 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3038 bgp_path_info_delete(rn, pi); /* keep historical info */
3039
3040 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3041 * flag
3042 */
3043 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3044 delete_route = true;
3045 else if (bgp_node_set_defer_flag(rn, true) < 0)
3046 delete_route = true;
3047 if (delete_route) {
3048 if (CHECK_FLAG(rn->flags, BGP_NODE_SELECT_DEFER)) {
3049 UNSET_FLAG(rn->flags, BGP_NODE_SELECT_DEFER);
3050 bgp = pi->peer->bgp;
3051 if ((rn->rt_node)
3052 && (bgp->gr_info[afi][safi].route_list)) {
3053 list_delete_node(bgp->gr_info[afi][safi]
3054 .route_list,
3055 rn->rt_node);
3056 rn->rt_node = NULL;
3057 }
3058 }
3059 }
3060 }
3061
3062 hook_call(bgp_process, peer->bgp, afi, safi, rn, peer, true);
3063 bgp_process(peer->bgp, rn, afi, safi);
3064 }
3065
3066 static void bgp_rib_withdraw(struct bgp_node *rn, struct bgp_path_info *pi,
3067 struct peer *peer, afi_t afi, safi_t safi,
3068 struct prefix_rd *prd)
3069 {
3070 /* apply dampening, if result is suppressed, we'll be retaining
3071 * the bgp_path_info in the RIB for historical reference.
3072 */
3073 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3074 && peer->sort == BGP_PEER_EBGP)
3075 if ((bgp_damp_withdraw(pi, rn, afi, safi, 0))
3076 == BGP_DAMP_SUPPRESSED) {
3077 bgp_aggregate_decrement(peer->bgp, &rn->p, pi, afi,
3078 safi);
3079 return;
3080 }
3081
3082 #if ENABLE_BGP_VNC
3083 if (safi == SAFI_MPLS_VPN) {
3084 struct bgp_node *prn = NULL;
3085 struct bgp_table *table = NULL;
3086
3087 prn = bgp_node_get(peer->bgp->rib[afi][safi],
3088 (struct prefix *)prd);
3089 if (bgp_node_has_bgp_path_info_data(prn)) {
3090 table = bgp_node_get_bgp_table_info(prn);
3091
3092 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3093 peer->bgp, prd, table, &rn->p, pi);
3094 }
3095 bgp_unlock_node(prn);
3096 }
3097 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3098 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3099
3100 vnc_import_bgp_del_route(peer->bgp, &rn->p, pi);
3101 vnc_import_bgp_exterior_del_route(peer->bgp, &rn->p,
3102 pi);
3103 }
3104 }
3105 #endif
3106
3107 /* If this is an EVPN route, process for un-import. */
3108 if (safi == SAFI_EVPN)
3109 bgp_evpn_unimport_route(peer->bgp, afi, safi, &rn->p, pi);
3110
3111 bgp_rib_remove(rn, pi, peer, afi, safi);
3112 }
3113
3114 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3115 struct peer *peer, struct attr *attr,
3116 struct bgp_node *rn)
3117 {
3118 struct bgp_path_info *new;
3119
3120 /* Make new BGP info. */
3121 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3122 new->type = type;
3123 new->instance = instance;
3124 new->sub_type = sub_type;
3125 new->peer = peer;
3126 new->attr = attr;
3127 new->uptime = bgp_clock();
3128 new->net = rn;
3129 return new;
3130 }
3131
3132 static void overlay_index_update(struct attr *attr,
3133 struct eth_segment_id *eth_s_id,
3134 union gw_addr *gw_ip)
3135 {
3136 if (!attr)
3137 return;
3138
3139 if (eth_s_id == NULL) {
3140 memset(&(attr->evpn_overlay.eth_s_id), 0,
3141 sizeof(struct eth_segment_id));
3142 } else {
3143 memcpy(&(attr->evpn_overlay.eth_s_id), eth_s_id,
3144 sizeof(struct eth_segment_id));
3145 }
3146 if (gw_ip == NULL) {
3147 memset(&(attr->evpn_overlay.gw_ip), 0, sizeof(union gw_addr));
3148 } else {
3149 memcpy(&(attr->evpn_overlay.gw_ip), gw_ip,
3150 sizeof(union gw_addr));
3151 }
3152 }
3153
3154 static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path,
3155 struct eth_segment_id *eth_s_id,
3156 union gw_addr *gw_ip)
3157 {
3158 struct eth_segment_id *path_eth_s_id, *path_eth_s_id_remote;
3159 union gw_addr *path_gw_ip, *path_gw_ip_remote;
3160 union {
3161 struct eth_segment_id esi;
3162 union gw_addr ip;
3163 } temp;
3164
3165 if (afi != AFI_L2VPN)
3166 return true;
3167
3168 path_eth_s_id = &(path->attr->evpn_overlay.eth_s_id);
3169 path_gw_ip = &(path->attr->evpn_overlay.gw_ip);
3170
3171 if (gw_ip == NULL) {
3172 memset(&temp, 0, sizeof(temp));
3173 path_gw_ip_remote = &temp.ip;
3174 } else
3175 path_gw_ip_remote = gw_ip;
3176
3177 if (eth_s_id == NULL) {
3178 memset(&temp, 0, sizeof(temp));
3179 path_eth_s_id_remote = &temp.esi;
3180 } else
3181 path_eth_s_id_remote = eth_s_id;
3182
3183 if (!memcmp(path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr)))
3184 return false;
3185
3186 return !memcmp(path_eth_s_id, path_eth_s_id_remote,
3187 sizeof(struct eth_segment_id));
3188 }
3189
3190 /* Check if received nexthop is valid or not. */
3191 static int bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3192 uint8_t type, uint8_t stype,
3193 struct attr *attr, struct bgp_node *rn)
3194 {
3195 int ret = 0;
3196
3197 /* Only validated for unicast and multicast currently. */
3198 /* Also valid for EVPN where the nexthop is an IP address. */
3199 if (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN)
3200 return 0;
3201
3202 /* If NEXT_HOP is present, validate it. */
3203 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3204 if (attr->nexthop.s_addr == INADDR_ANY
3205 || IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr))
3206 || bgp_nexthop_self(bgp, afi, type, stype, attr, rn))
3207 return 1;
3208 }
3209
3210 /* If MP_NEXTHOP is present, validate it. */
3211 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3212 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3213 * it is not an IPv6 link-local address.
3214 */
3215 if (attr->mp_nexthop_len) {
3216 switch (attr->mp_nexthop_len) {
3217 case BGP_ATTR_NHLEN_IPV4:
3218 case BGP_ATTR_NHLEN_VPNV4:
3219 ret = (attr->mp_nexthop_global_in.s_addr == INADDR_ANY
3220 || IPV4_CLASS_DE(
3221 ntohl(attr->mp_nexthop_global_in.s_addr))
3222 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3223 rn));
3224 break;
3225
3226 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3227 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3228 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3229 ret = (IN6_IS_ADDR_UNSPECIFIED(&attr->mp_nexthop_global)
3230 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3231 || IN6_IS_ADDR_MULTICAST(
3232 &attr->mp_nexthop_global)
3233 || bgp_nexthop_self(bgp, afi, type, stype,
3234 attr, rn));
3235 break;
3236
3237 default:
3238 ret = 1;
3239 break;
3240 }
3241 }
3242
3243 return ret;
3244 }
3245
3246 int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
3247 struct attr *attr, afi_t afi, safi_t safi, int type,
3248 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3249 uint32_t num_labels, int soft_reconfig,
3250 struct bgp_route_evpn *evpn)
3251 {
3252 int ret;
3253 int aspath_loop_count = 0;
3254 struct bgp_node *rn;
3255 struct bgp *bgp;
3256 struct attr new_attr;
3257 struct attr *attr_new;
3258 struct bgp_path_info *pi;
3259 struct bgp_path_info *new;
3260 struct bgp_path_info_extra *extra;
3261 const char *reason;
3262 char pfx_buf[BGP_PRD_PATH_STRLEN];
3263 int connected = 0;
3264 int do_loop_check = 1;
3265 int has_valid_label = 0;
3266 afi_t nh_afi;
3267 uint8_t pi_type = 0;
3268 uint8_t pi_sub_type = 0;
3269
3270 #if ENABLE_BGP_VNC
3271 int vnc_implicit_withdraw = 0;
3272 #endif
3273 int same_attr = 0;
3274
3275 memset(&new_attr, 0, sizeof(struct attr));
3276 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
3277 new_attr.label = MPLS_INVALID_LABEL;
3278
3279 bgp = peer->bgp;
3280 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3281 /* TODO: Check to see if we can get rid of "is_valid_label" */
3282 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3283 has_valid_label = (num_labels > 0) ? 1 : 0;
3284 else
3285 has_valid_label = bgp_is_valid_label(label);
3286
3287 /* When peer's soft reconfiguration enabled. Record input packet in
3288 Adj-RIBs-In. */
3289 if (!soft_reconfig
3290 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3291 && peer != bgp->peer_self)
3292 bgp_adj_in_set(rn, peer, attr, addpath_id);
3293
3294 /* Check previously received route. */
3295 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
3296 if (pi->peer == peer && pi->type == type
3297 && pi->sub_type == sub_type
3298 && pi->addpath_rx_id == addpath_id)
3299 break;
3300
3301 /* AS path local-as loop check. */
3302 if (peer->change_local_as) {
3303 if (peer->allowas_in[afi][safi])
3304 aspath_loop_count = peer->allowas_in[afi][safi];
3305 else if (!CHECK_FLAG(peer->flags,
3306 PEER_FLAG_LOCAL_AS_NO_PREPEND))
3307 aspath_loop_count = 1;
3308
3309 if (aspath_loop_check(attr->aspath, peer->change_local_as)
3310 > aspath_loop_count) {
3311 peer->stat_pfx_aspath_loop++;
3312 reason = "as-path contains our own AS;";
3313 goto filtered;
3314 }
3315 }
3316
3317 /* If the peer is configured for "allowas-in origin" and the last ASN in
3318 * the
3319 * as-path is our ASN then we do not need to call aspath_loop_check
3320 */
3321 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
3322 if (aspath_get_last_as(attr->aspath) == bgp->as)
3323 do_loop_check = 0;
3324
3325 /* AS path loop check. */
3326 if (do_loop_check) {
3327 if (aspath_loop_check(attr->aspath, bgp->as)
3328 > peer->allowas_in[afi][safi]
3329 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
3330 && aspath_loop_check(attr->aspath, bgp->confed_id)
3331 > peer->allowas_in[afi][safi])) {
3332 peer->stat_pfx_aspath_loop++;
3333 reason = "as-path contains our own AS;";
3334 goto filtered;
3335 }
3336 }
3337
3338 /* Route reflector originator ID check. */
3339 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
3340 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
3341 peer->stat_pfx_originator_loop++;
3342 reason = "originator is us;";
3343 goto filtered;
3344 }
3345
3346 /* Route reflector cluster ID check. */
3347 if (bgp_cluster_filter(peer, attr)) {
3348 peer->stat_pfx_cluster_loop++;
3349 reason = "reflected from the same cluster;";
3350 goto filtered;
3351 }
3352
3353 /* Apply incoming filter. */
3354 if (bgp_input_filter(peer, p, attr, afi, safi) == FILTER_DENY) {
3355 peer->stat_pfx_filter++;
3356 reason = "filter;";
3357 goto filtered;
3358 }
3359
3360 /* RFC 8212 to prevent route leaks.
3361 * This specification intends to improve this situation by requiring the
3362 * explicit configuration of both BGP Import and Export Policies for any
3363 * External BGP (EBGP) session such as customers, peers, or
3364 * confederation boundaries for all enabled address families. Through
3365 * codification of the aforementioned requirement, operators will
3366 * benefit from consistent behavior across different BGP
3367 * implementations.
3368 */
3369 if (peer->bgp->ebgp_requires_policy == DEFAULT_EBGP_POLICY_ENABLED)
3370 if (!bgp_inbound_policy_exists(peer,
3371 &peer->filter[afi][safi])) {
3372 reason = "inbound policy missing";
3373 goto filtered;
3374 }
3375
3376 /* draft-ietf-idr-deprecate-as-set-confed-set
3377 * Filter routes having AS_SET or AS_CONFED_SET in the path.
3378 * Eventually, This document (if approved) updates RFC 4271
3379 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
3380 * and obsoletes RFC 6472.
3381 */
3382 if (peer->bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED)
3383 if (aspath_check_as_sets(attr->aspath)) {
3384 reason =
3385 "as-path contains AS_SET or AS_CONFED_SET type;";
3386 goto filtered;
3387 }
3388
3389 new_attr = *attr;
3390
3391 /* Apply incoming route-map.
3392 * NB: new_attr may now contain newly allocated values from route-map
3393 * "set"
3394 * commands, so we need bgp_attr_flush in the error paths, until we
3395 * intern
3396 * the attr (which takes over the memory references) */
3397 if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL,
3398 label, num_labels, rn) == RMAP_DENY) {
3399 peer->stat_pfx_filter++;
3400 reason = "route-map;";
3401 bgp_attr_flush(&new_attr);
3402 goto filtered;
3403 }
3404
3405 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
3406 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3407 /* remove from RIB previous entry */
3408 bgp_zebra_withdraw(p, pi, bgp, safi);
3409 }
3410
3411 if (peer->sort == BGP_PEER_EBGP) {
3412
3413 /* If we receive the graceful-shutdown community from an eBGP
3414 * peer we must lower local-preference */
3415 if (new_attr.community
3416 && community_include(new_attr.community, COMMUNITY_GSHUT)) {
3417 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
3418 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
3419
3420 /* If graceful-shutdown is configured then add the GSHUT
3421 * community to all paths received from eBGP peers */
3422 } else if (CHECK_FLAG(peer->bgp->flags,
3423 BGP_FLAG_GRACEFUL_SHUTDOWN))
3424 bgp_attr_add_gshut_community(&new_attr);
3425 }
3426
3427 if (pi) {
3428 pi_type = pi->type;
3429 pi_sub_type = pi->sub_type;
3430 }
3431
3432 /* next hop check. */
3433 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
3434 && bgp_update_martian_nexthop(bgp, afi, safi, pi_type,
3435 pi_sub_type, &new_attr, rn)) {
3436 peer->stat_pfx_nh_invalid++;
3437 reason = "martian or self next-hop;";
3438 bgp_attr_flush(&new_attr);
3439 goto filtered;
3440 }
3441
3442 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
3443 peer->stat_pfx_nh_invalid++;
3444 reason = "self mac;";
3445 goto filtered;
3446 }
3447
3448 attr_new = bgp_attr_intern(&new_attr);
3449
3450 /* If the update is implicit withdraw. */
3451 if (pi) {
3452 pi->uptime = bgp_clock();
3453 same_attr = attrhash_cmp(pi->attr, attr_new);
3454
3455 hook_call(bgp_process, bgp, afi, safi, rn, peer, true);
3456
3457 /* Same attribute comes in. */
3458 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
3459 && attrhash_cmp(pi->attr, attr_new)
3460 && (!has_valid_label
3461 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
3462 num_labels * sizeof(mpls_label_t))
3463 == 0)
3464 && (overlay_index_equal(
3465 afi, pi, evpn == NULL ? NULL : &evpn->eth_s_id,
3466 evpn == NULL ? NULL : &evpn->gw_ip))) {
3467 if (CHECK_FLAG(bgp->af_flags[afi][safi],
3468 BGP_CONFIG_DAMPENING)
3469 && peer->sort == BGP_PEER_EBGP
3470 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3471 if (bgp_debug_update(peer, p, NULL, 1)) {
3472 bgp_debug_rdpfxpath2str(
3473 afi, safi, prd, p, label,
3474 num_labels, addpath_id ? 1 : 0,
3475 addpath_id, pfx_buf,
3476 sizeof(pfx_buf));
3477 zlog_debug("%s rcvd %s", peer->host,
3478 pfx_buf);
3479 }
3480
3481 if (bgp_damp_update(pi, rn, afi, safi)
3482 != BGP_DAMP_SUPPRESSED) {
3483 bgp_aggregate_increment(bgp, p, pi, afi,
3484 safi);
3485 bgp_process(bgp, rn, afi, safi);
3486 }
3487 } else /* Duplicate - odd */
3488 {
3489 if (bgp_debug_update(peer, p, NULL, 1)) {
3490 if (!peer->rcvd_attr_printed) {
3491 zlog_debug(
3492 "%s rcvd UPDATE w/ attr: %s",
3493 peer->host,
3494 peer->rcvd_attr_str);
3495 peer->rcvd_attr_printed = 1;
3496 }
3497
3498 bgp_debug_rdpfxpath2str(
3499 afi, safi, prd, p, label,
3500 num_labels, addpath_id ? 1 : 0,
3501 addpath_id, pfx_buf,
3502 sizeof(pfx_buf));
3503 zlog_debug(
3504 "%s rcvd %s...duplicate ignored",
3505 peer->host, pfx_buf);
3506 }
3507
3508 /* graceful restart STALE flag unset. */
3509 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3510 bgp_path_info_unset_flag(
3511 rn, pi, BGP_PATH_STALE);
3512 bgp_node_set_defer_flag(rn, false);
3513 bgp_process(bgp, rn, afi, safi);
3514 }
3515 }
3516
3517 bgp_unlock_node(rn);
3518 bgp_attr_unintern(&attr_new);
3519
3520 return 0;
3521 }
3522
3523 /* Withdraw/Announce before we fully processed the withdraw */
3524 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
3525 if (bgp_debug_update(peer, p, NULL, 1)) {
3526 bgp_debug_rdpfxpath2str(
3527 afi, safi, prd, p, label, num_labels,
3528 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3529 sizeof(pfx_buf));
3530 zlog_debug(
3531 "%s rcvd %s, flapped quicker than processing",
3532 peer->host, pfx_buf);
3533 }
3534
3535 bgp_path_info_restore(rn, pi);
3536 }
3537
3538 /* Received Logging. */
3539 if (bgp_debug_update(peer, p, NULL, 1)) {
3540 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
3541 num_labels, addpath_id ? 1 : 0,
3542 addpath_id, pfx_buf,
3543 sizeof(pfx_buf));
3544 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3545 }
3546
3547 /* graceful restart STALE flag unset. */
3548 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3549 bgp_path_info_unset_flag(rn, pi, BGP_PATH_STALE);
3550 bgp_node_set_defer_flag(rn, false);
3551 }
3552
3553 /* The attribute is changed. */
3554 bgp_path_info_set_flag(rn, pi, BGP_PATH_ATTR_CHANGED);
3555
3556 /* implicit withdraw, decrement aggregate and pcount here.
3557 * only if update is accepted, they'll increment below.
3558 */
3559 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
3560
3561 /* Update bgp route dampening information. */
3562 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3563 && peer->sort == BGP_PEER_EBGP) {
3564 /* This is implicit withdraw so we should update
3565 dampening
3566 information. */
3567 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
3568 bgp_damp_withdraw(pi, rn, afi, safi, 1);
3569 }
3570 #if ENABLE_BGP_VNC
3571 if (safi == SAFI_MPLS_VPN) {
3572 struct bgp_node *prn = NULL;
3573 struct bgp_table *table = NULL;
3574
3575 prn = bgp_node_get(bgp->rib[afi][safi],
3576 (struct prefix *)prd);
3577 if (bgp_node_has_bgp_path_info_data(prn)) {
3578 table = bgp_node_get_bgp_table_info(prn);
3579
3580 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3581 bgp, prd, table, p, pi);
3582 }
3583 bgp_unlock_node(prn);
3584 }
3585 if ((afi == AFI_IP || afi == AFI_IP6)
3586 && (safi == SAFI_UNICAST)) {
3587 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3588 /*
3589 * Implicit withdraw case.
3590 */
3591 ++vnc_implicit_withdraw;
3592 vnc_import_bgp_del_route(bgp, p, pi);
3593 vnc_import_bgp_exterior_del_route(bgp, p, pi);
3594 }
3595 }
3596 #endif
3597
3598 /* Special handling for EVPN update of an existing route. If the
3599 * extended community attribute has changed, we need to
3600 * un-import
3601 * the route using its existing extended community. It will be
3602 * subsequently processed for import with the new extended
3603 * community.
3604 */
3605 if (safi == SAFI_EVPN && !same_attr) {
3606 if ((pi->attr->flag
3607 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
3608 && (attr_new->flag
3609 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
3610 int cmp;
3611
3612 cmp = ecommunity_cmp(pi->attr->ecommunity,
3613 attr_new->ecommunity);
3614 if (!cmp) {
3615 if (bgp_debug_update(peer, p, NULL, 1))
3616 zlog_debug(
3617 "Change in EXT-COMM, existing %s new %s",
3618 ecommunity_str(
3619 pi->attr->ecommunity),
3620 ecommunity_str(
3621 attr_new->ecommunity));
3622 bgp_evpn_unimport_route(bgp, afi, safi,
3623 p, pi);
3624 }
3625 }
3626 }
3627
3628 /* Update to new attribute. */
3629 bgp_attr_unintern(&pi->attr);
3630 pi->attr = attr_new;
3631
3632 /* Update MPLS label */
3633 if (has_valid_label) {
3634 extra = bgp_path_info_extra_get(pi);
3635 if (extra->label != label) {
3636 memcpy(&extra->label, label,
3637 num_labels * sizeof(mpls_label_t));
3638 extra->num_labels = num_labels;
3639 }
3640 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
3641 bgp_set_valid_label(&extra->label[0]);
3642 }
3643
3644 /* Update SRv6 SID */
3645 if (attr->srv6_l3vpn) {
3646 extra = bgp_path_info_extra_get(pi);
3647 if (sid_diff(&extra->sid[0], &attr->srv6_l3vpn->sid)) {
3648 sid_copy(&extra->sid[0],
3649 &attr->srv6_l3vpn->sid);
3650 extra->num_sids = 1;
3651 }
3652 } else if (attr->srv6_vpn) {
3653 extra = bgp_path_info_extra_get(pi);
3654 if (sid_diff(&extra->sid[0], &attr->srv6_vpn->sid)) {
3655 sid_copy(&extra->sid[0], &attr->srv6_vpn->sid);
3656 extra->num_sids = 1;
3657 }
3658 }
3659
3660 #if ENABLE_BGP_VNC
3661 if ((afi == AFI_IP || afi == AFI_IP6)
3662 && (safi == SAFI_UNICAST)) {
3663 if (vnc_implicit_withdraw) {
3664 /*
3665 * Add back the route with its new attributes
3666 * (e.g., nexthop).
3667 * The route is still selected, until the route
3668 * selection
3669 * queued by bgp_process actually runs. We have
3670 * to make this
3671 * update to the VNC side immediately to avoid
3672 * racing against
3673 * configuration changes (e.g., route-map
3674 * changes) which
3675 * trigger re-importation of the entire RIB.
3676 */
3677 vnc_import_bgp_add_route(bgp, p, pi);
3678 vnc_import_bgp_exterior_add_route(bgp, p, pi);
3679 }
3680 }
3681 #endif
3682 /* Update Overlay Index */
3683 if (afi == AFI_L2VPN) {
3684 overlay_index_update(
3685 pi->attr, evpn == NULL ? NULL : &evpn->eth_s_id,
3686 evpn == NULL ? NULL : &evpn->gw_ip);
3687 }
3688
3689 /* Update bgp route dampening information. */
3690 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3691 && peer->sort == BGP_PEER_EBGP) {
3692 /* Now we do normal update dampening. */
3693 ret = bgp_damp_update(pi, rn, afi, safi);
3694 if (ret == BGP_DAMP_SUPPRESSED) {
3695 bgp_unlock_node(rn);
3696 return 0;
3697 }
3698 }
3699
3700 /* Nexthop reachability check - for unicast and
3701 * labeled-unicast.. */
3702 if (((afi == AFI_IP || afi == AFI_IP6)
3703 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
3704 || (safi == SAFI_EVPN &&
3705 bgp_evpn_is_prefix_nht_supported(p))) {
3706 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
3707 && peer->ttl == BGP_DEFAULT_TTL
3708 && !CHECK_FLAG(peer->flags,
3709 PEER_FLAG_DISABLE_CONNECTED_CHECK)
3710 && !CHECK_FLAG(bgp->flags,
3711 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
3712 connected = 1;
3713 else
3714 connected = 0;
3715
3716 struct bgp *bgp_nexthop = bgp;
3717
3718 if (pi->extra && pi->extra->bgp_orig)
3719 bgp_nexthop = pi->extra->bgp_orig;
3720
3721 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
3722
3723 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
3724 pi, NULL, connected)
3725 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
3726 bgp_path_info_set_flag(rn, pi, BGP_PATH_VALID);
3727 else {
3728 if (BGP_DEBUG(nht, NHT)) {
3729 char buf1[INET6_ADDRSTRLEN];
3730 inet_ntop(AF_INET,
3731 (const void *)&attr_new
3732 ->nexthop,
3733 buf1, INET6_ADDRSTRLEN);
3734 zlog_debug("%s(%s): NH unresolved",
3735 __FUNCTION__, buf1);
3736 }
3737 bgp_path_info_unset_flag(rn, pi,
3738 BGP_PATH_VALID);
3739 }
3740 } else
3741 bgp_path_info_set_flag(rn, pi, BGP_PATH_VALID);
3742
3743 #if ENABLE_BGP_VNC
3744 if (safi == SAFI_MPLS_VPN) {
3745 struct bgp_node *prn = NULL;
3746 struct bgp_table *table = NULL;
3747
3748 prn = bgp_node_get(bgp->rib[afi][safi],
3749 (struct prefix *)prd);
3750 if (bgp_node_has_bgp_path_info_data(prn)) {
3751 table = bgp_node_get_bgp_table_info(prn);
3752
3753 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3754 bgp, prd, table, p, pi);
3755 }
3756 bgp_unlock_node(prn);
3757 }
3758 #endif
3759
3760 /* If this is an EVPN route and some attribute has changed,
3761 * process
3762 * route for import. If the extended community has changed, we
3763 * would
3764 * have done the un-import earlier and the import would result
3765 * in the
3766 * route getting injected into appropriate L2 VNIs. If it is
3767 * just
3768 * some other attribute change, the import will result in
3769 * updating
3770 * the attributes for the route in the VNI(s).
3771 */
3772 if (safi == SAFI_EVPN && !same_attr &&
3773 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
3774 bgp_evpn_import_route(bgp, afi, safi, p, pi);
3775
3776 /* Process change. */
3777 bgp_aggregate_increment(bgp, p, pi, afi, safi);
3778
3779 bgp_process(bgp, rn, afi, safi);
3780 bgp_unlock_node(rn);
3781
3782 if (SAFI_UNICAST == safi
3783 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
3784 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3785
3786 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
3787 }
3788 if ((SAFI_MPLS_VPN == safi)
3789 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3790
3791 vpn_leak_to_vrf_update(bgp, pi);
3792 }
3793
3794 #if ENABLE_BGP_VNC
3795 if (SAFI_MPLS_VPN == safi) {
3796 mpls_label_t label_decoded = decode_label(label);
3797
3798 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
3799 type, sub_type, &label_decoded);
3800 }
3801 if (SAFI_ENCAP == safi) {
3802 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
3803 type, sub_type, NULL);
3804 }
3805 #endif
3806
3807 return 0;
3808 } // End of implicit withdraw
3809
3810 /* Received Logging. */
3811 if (bgp_debug_update(peer, p, NULL, 1)) {
3812 if (!peer->rcvd_attr_printed) {
3813 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
3814 peer->rcvd_attr_str);
3815 peer->rcvd_attr_printed = 1;
3816 }
3817
3818 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
3819 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3820 sizeof(pfx_buf));
3821 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3822 }
3823
3824 /* Make new BGP info. */
3825 new = info_make(type, sub_type, 0, peer, attr_new, rn);
3826
3827 /* Update MPLS label */
3828 if (has_valid_label) {
3829 extra = bgp_path_info_extra_get(new);
3830 if (extra->label != label) {
3831 memcpy(&extra->label, label,
3832 num_labels * sizeof(mpls_label_t));
3833 extra->num_labels = num_labels;
3834 }
3835 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
3836 bgp_set_valid_label(&extra->label[0]);
3837 }
3838
3839 /* Update SRv6 SID */
3840 if (safi == SAFI_MPLS_VPN) {
3841 extra = bgp_path_info_extra_get(new);
3842 if (attr->srv6_l3vpn) {
3843 sid_copy(&extra->sid[0], &attr->srv6_l3vpn->sid);
3844 extra->num_sids = 1;
3845 } else if (attr->srv6_vpn) {
3846 sid_copy(&extra->sid[0], &attr->srv6_vpn->sid);
3847 extra->num_sids = 1;
3848 }
3849 }
3850
3851 /* Update Overlay Index */
3852 if (afi == AFI_L2VPN) {
3853 overlay_index_update(new->attr,
3854 evpn == NULL ? NULL : &evpn->eth_s_id,
3855 evpn == NULL ? NULL : &evpn->gw_ip);
3856 }
3857 /* Nexthop reachability check. */
3858 if (((afi == AFI_IP || afi == AFI_IP6)
3859 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
3860 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
3861 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
3862 && peer->ttl == BGP_DEFAULT_TTL
3863 && !CHECK_FLAG(peer->flags,
3864 PEER_FLAG_DISABLE_CONNECTED_CHECK)
3865 && !CHECK_FLAG(bgp->flags,
3866 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
3867 connected = 1;
3868 else
3869 connected = 0;
3870
3871 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
3872
3873 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, new, NULL,
3874 connected)
3875 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
3876 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
3877 else {
3878 if (BGP_DEBUG(nht, NHT)) {
3879 char buf1[INET6_ADDRSTRLEN];
3880 inet_ntop(AF_INET,
3881 (const void *)&attr_new->nexthop,
3882 buf1, INET6_ADDRSTRLEN);
3883 zlog_debug("%s(%s): NH unresolved",
3884 __FUNCTION__, buf1);
3885 }
3886 bgp_path_info_unset_flag(rn, new, BGP_PATH_VALID);
3887 }
3888 } else
3889 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
3890
3891 /* Addpath ID */
3892 new->addpath_rx_id = addpath_id;
3893
3894 /* Increment prefix */
3895 bgp_aggregate_increment(bgp, p, new, afi, safi);
3896
3897 /* Register new BGP information. */
3898 bgp_path_info_add(rn, new);
3899
3900 /* route_node_get lock */
3901 bgp_unlock_node(rn);
3902
3903 #if ENABLE_BGP_VNC
3904 if (safi == SAFI_MPLS_VPN) {
3905 struct bgp_node *prn = NULL;
3906 struct bgp_table *table = NULL;
3907
3908 prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
3909 if (bgp_node_has_bgp_path_info_data(prn)) {
3910 table = bgp_node_get_bgp_table_info(prn);
3911
3912 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3913 bgp, prd, table, p, new);
3914 }
3915 bgp_unlock_node(prn);
3916 }
3917 #endif
3918
3919 /* If maximum prefix count is configured and current prefix
3920 count exeed it. */
3921 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0))
3922 return -1;
3923
3924 /* If this is an EVPN route, process for import. */
3925 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
3926 bgp_evpn_import_route(bgp, afi, safi, p, new);
3927
3928 hook_call(bgp_process, bgp, afi, safi, rn, peer, false);
3929
3930 /* Process change. */
3931 bgp_process(bgp, rn, afi, safi);
3932
3933 if (SAFI_UNICAST == safi
3934 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
3935 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3936 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
3937 }
3938 if ((SAFI_MPLS_VPN == safi)
3939 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3940
3941 vpn_leak_to_vrf_update(bgp, new);
3942 }
3943 #if ENABLE_BGP_VNC
3944 if (SAFI_MPLS_VPN == safi) {
3945 mpls_label_t label_decoded = decode_label(label);
3946
3947 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
3948 sub_type, &label_decoded);
3949 }
3950 if (SAFI_ENCAP == safi) {
3951 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
3952 sub_type, NULL);
3953 }
3954 #endif
3955
3956 return 0;
3957
3958 /* This BGP update is filtered. Log the reason then update BGP
3959 entry. */
3960 filtered:
3961 hook_call(bgp_process, bgp, afi, safi, rn, peer, true);
3962
3963 if (bgp_debug_update(peer, p, NULL, 1)) {
3964 if (!peer->rcvd_attr_printed) {
3965 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
3966 peer->rcvd_attr_str);
3967 peer->rcvd_attr_printed = 1;
3968 }
3969
3970 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
3971 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3972 sizeof(pfx_buf));
3973 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
3974 peer->host, pfx_buf, reason);
3975 }
3976
3977 if (pi) {
3978 /* If this is an EVPN route, un-import it as it is now filtered.
3979 */
3980 if (safi == SAFI_EVPN)
3981 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
3982
3983 if (SAFI_UNICAST == safi
3984 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
3985 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3986
3987 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
3988 }
3989 if ((SAFI_MPLS_VPN == safi)
3990 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
3991
3992 vpn_leak_to_vrf_withdraw(bgp, pi);
3993 }
3994
3995 bgp_rib_remove(rn, pi, peer, afi, safi);
3996 }
3997
3998 bgp_unlock_node(rn);
3999
4000 #if ENABLE_BGP_VNC
4001 /*
4002 * Filtered update is treated as an implicit withdrawal (see
4003 * bgp_rib_remove()
4004 * a few lines above)
4005 */
4006 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4007 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4008 0);
4009 }
4010 #endif
4011
4012 return 0;
4013 }
4014
4015 int bgp_withdraw(struct peer *peer, struct prefix *p, uint32_t addpath_id,
4016 struct attr *attr, afi_t afi, safi_t safi, int type,
4017 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4018 uint32_t num_labels, struct bgp_route_evpn *evpn)
4019 {
4020 struct bgp *bgp;
4021 char pfx_buf[BGP_PRD_PATH_STRLEN];
4022 struct bgp_node *rn;
4023 struct bgp_path_info *pi;
4024
4025 #if ENABLE_BGP_VNC
4026 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4027 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4028 0);
4029 }
4030 #endif
4031
4032 bgp = peer->bgp;
4033
4034 /* Lookup node. */
4035 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4036
4037 /* If peer is soft reconfiguration enabled. Record input packet for
4038 * further calculation.
4039 *
4040 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4041 * routes that are filtered. This tanks out Quagga RS pretty badly due
4042 * to
4043 * the iteration over all RS clients.
4044 * Since we need to remove the entry from adj_in anyway, do that first
4045 * and
4046 * if there was no entry, we don't need to do anything more.
4047 */
4048 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4049 && peer != bgp->peer_self)
4050 if (!bgp_adj_in_unset(rn, peer, addpath_id)) {
4051 peer->stat_pfx_dup_withdraw++;
4052
4053 if (bgp_debug_update(peer, p, NULL, 1)) {
4054 bgp_debug_rdpfxpath2str(
4055 afi, safi, prd, p, label, num_labels,
4056 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4057 sizeof(pfx_buf));
4058 zlog_debug(
4059 "%s withdrawing route %s not in adj-in",
4060 peer->host, pfx_buf);
4061 }
4062 bgp_unlock_node(rn);
4063 return 0;
4064 }
4065
4066 /* Lookup withdrawn route. */
4067 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4068 if (pi->peer == peer && pi->type == type
4069 && pi->sub_type == sub_type
4070 && pi->addpath_rx_id == addpath_id)
4071 break;
4072
4073 /* Logging. */
4074 if (bgp_debug_update(peer, p, NULL, 1)) {
4075 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4076 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4077 sizeof(pfx_buf));
4078 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
4079 pfx_buf);
4080 }
4081
4082 /* Withdraw specified route from routing table. */
4083 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4084 bgp_rib_withdraw(rn, pi, peer, afi, safi, prd);
4085 if (SAFI_UNICAST == safi
4086 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4087 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4088 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4089 }
4090 if ((SAFI_MPLS_VPN == safi)
4091 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4092
4093 vpn_leak_to_vrf_withdraw(bgp, pi);
4094 }
4095 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4096 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4097 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4098 sizeof(pfx_buf));
4099 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4100 }
4101
4102 /* Unlock bgp_node_get() lock. */
4103 bgp_unlock_node(rn);
4104
4105 return 0;
4106 }
4107
4108 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4109 int withdraw)
4110 {
4111 struct update_subgroup *subgrp;
4112 subgrp = peer_subgroup(peer, afi, safi);
4113 subgroup_default_originate(subgrp, withdraw);
4114 }
4115
4116
4117 /*
4118 * bgp_stop_announce_route_timer
4119 */
4120 void bgp_stop_announce_route_timer(struct peer_af *paf)
4121 {
4122 if (!paf->t_announce_route)
4123 return;
4124
4125 THREAD_TIMER_OFF(paf->t_announce_route);
4126 }
4127
4128 /*
4129 * bgp_announce_route_timer_expired
4130 *
4131 * Callback that is invoked when the route announcement timer for a
4132 * peer_af expires.
4133 */
4134 static int bgp_announce_route_timer_expired(struct thread *t)
4135 {
4136 struct peer_af *paf;
4137 struct peer *peer;
4138
4139 paf = THREAD_ARG(t);
4140 peer = paf->peer;
4141
4142 if (peer->status != Established)
4143 return 0;
4144
4145 if (!peer->afc_nego[paf->afi][paf->safi])
4146 return 0;
4147
4148 peer_af_announce_route(paf, 1);
4149 return 0;
4150 }
4151
4152 /*
4153 * bgp_announce_route
4154 *
4155 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
4156 */
4157 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi)
4158 {
4159 struct peer_af *paf;
4160 struct update_subgroup *subgrp;
4161
4162 paf = peer_af_find(peer, afi, safi);
4163 if (!paf)
4164 return;
4165 subgrp = PAF_SUBGRP(paf);
4166
4167 /*
4168 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
4169 * or a refresh has already been triggered.
4170 */
4171 if (!subgrp || paf->t_announce_route)
4172 return;
4173
4174 /*
4175 * Start a timer to stagger/delay the announce. This serves
4176 * two purposes - announcement can potentially be combined for
4177 * multiple peers and the announcement doesn't happen in the
4178 * vty context.
4179 */
4180 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
4181 (subgrp->peer_count == 1)
4182 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
4183 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
4184 &paf->t_announce_route);
4185 }
4186
4187 /*
4188 * Announce routes from all AF tables to a peer.
4189 *
4190 * This should ONLY be called when there is a need to refresh the
4191 * routes to the peer based on a policy change for this peer alone
4192 * or a route refresh request received from the peer.
4193 * The operation will result in splitting the peer from its existing
4194 * subgroups and putting it in new subgroups.
4195 */
4196 void bgp_announce_route_all(struct peer *peer)
4197 {
4198 afi_t afi;
4199 safi_t safi;
4200
4201 FOREACH_AFI_SAFI (afi, safi)
4202 bgp_announce_route(peer, afi, safi);
4203 }
4204
4205 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
4206 struct bgp_table *table,
4207 struct prefix_rd *prd)
4208 {
4209 int ret;
4210 struct bgp_node *rn;
4211 struct bgp_adj_in *ain;
4212
4213 if (!table)
4214 table = peer->bgp->rib[afi][safi];
4215
4216 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
4217 for (ain = rn->adj_in; ain; ain = ain->next) {
4218 if (ain->peer != peer)
4219 continue;
4220
4221 struct bgp_path_info *pi;
4222 uint32_t num_labels = 0;
4223 mpls_label_t *label_pnt = NULL;
4224 struct bgp_route_evpn evpn;
4225
4226 for (pi = bgp_node_get_bgp_path_info(rn); pi;
4227 pi = pi->next)
4228 if (pi->peer == peer)
4229 break;
4230
4231 if (pi && pi->extra)
4232 num_labels = pi->extra->num_labels;
4233 if (num_labels)
4234 label_pnt = &pi->extra->label[0];
4235 if (pi)
4236 memcpy(&evpn, &pi->attr->evpn_overlay,
4237 sizeof(evpn));
4238 else
4239 memset(&evpn, 0, sizeof(evpn));
4240
4241 ret = bgp_update(peer, &rn->p, ain->addpath_rx_id,
4242 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
4243 BGP_ROUTE_NORMAL, prd, label_pnt,
4244 num_labels, 1, &evpn);
4245
4246 if (ret < 0) {
4247 bgp_unlock_node(rn);
4248 return;
4249 }
4250 }
4251 }
4252
4253 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
4254 {
4255 struct bgp_node *rn;
4256 struct bgp_table *table;
4257
4258 if (peer->status != Established)
4259 return;
4260
4261 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
4262 && (safi != SAFI_EVPN))
4263 bgp_soft_reconfig_table(peer, afi, safi, NULL, NULL);
4264 else
4265 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
4266 rn = bgp_route_next(rn)) {
4267 table = bgp_node_get_bgp_table_info(rn);
4268 if (table != NULL) {
4269 struct prefix_rd prd;
4270
4271 prd.family = AF_UNSPEC;
4272 prd.prefixlen = 64;
4273 memcpy(&prd.val, rn->p.u.val, 8);
4274
4275 bgp_soft_reconfig_table(peer, afi, safi, table,
4276 &prd);
4277 }
4278 }
4279 }
4280
4281
4282 struct bgp_clear_node_queue {
4283 struct bgp_node *rn;
4284 };
4285
4286 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
4287 {
4288 struct bgp_clear_node_queue *cnq = data;
4289 struct bgp_node *rn = cnq->rn;
4290 struct peer *peer = wq->spec.data;
4291 struct bgp_path_info *pi;
4292 struct bgp *bgp;
4293 afi_t afi = bgp_node_table(rn)->afi;
4294 safi_t safi = bgp_node_table(rn)->safi;
4295
4296 assert(rn && peer);
4297 bgp = peer->bgp;
4298
4299 /* It is possible that we have multiple paths for a prefix from a peer
4300 * if that peer is using AddPath.
4301 */
4302 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
4303 if (pi->peer != peer)
4304 continue;
4305
4306 /* graceful restart STALE flag set. */
4307 if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
4308 && peer->nsf[afi][safi]
4309 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
4310 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
4311 bgp_path_info_set_flag(rn, pi, BGP_PATH_STALE);
4312 else {
4313 /* If this is an EVPN route, process for
4314 * un-import. */
4315 if (safi == SAFI_EVPN)
4316 bgp_evpn_unimport_route(bgp, afi, safi, &rn->p,
4317 pi);
4318 /* Handle withdraw for VRF route-leaking and L3VPN */
4319 if (SAFI_UNICAST == safi
4320 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
4321 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4322 vpn_leak_from_vrf_withdraw(bgp_get_default(),
4323 bgp, pi);
4324 }
4325 if (SAFI_MPLS_VPN == safi &&
4326 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4327 vpn_leak_to_vrf_withdraw(bgp, pi);
4328 }
4329
4330 bgp_rib_remove(rn, pi, peer, afi, safi);
4331 }
4332 }
4333 return WQ_SUCCESS;
4334 }
4335
4336 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
4337 {
4338 struct bgp_clear_node_queue *cnq = data;
4339 struct bgp_node *rn = cnq->rn;
4340 struct bgp_table *table = bgp_node_table(rn);
4341
4342 bgp_unlock_node(rn);
4343 bgp_table_unlock(table);
4344 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
4345 }
4346
4347 static void bgp_clear_node_complete(struct work_queue *wq)
4348 {
4349 struct peer *peer = wq->spec.data;
4350
4351 /* Tickle FSM to start moving again */
4352 BGP_EVENT_ADD(peer, Clearing_Completed);
4353
4354 peer_unlock(peer); /* bgp_clear_route */
4355 }
4356
4357 static void bgp_clear_node_queue_init(struct peer *peer)
4358 {
4359 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
4360
4361 snprintf(wname, sizeof(wname), "clear %s", peer->host);
4362 #undef CLEAR_QUEUE_NAME_LEN
4363
4364 peer->clear_node_queue = work_queue_new(bm->master, wname);
4365 peer->clear_node_queue->spec.hold = 10;
4366 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
4367 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
4368 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
4369 peer->clear_node_queue->spec.max_retries = 0;
4370
4371 /* we only 'lock' this peer reference when the queue is actually active
4372 */
4373 peer->clear_node_queue->spec.data = peer;
4374 }
4375
4376 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
4377 struct bgp_table *table)
4378 {
4379 struct bgp_node *rn;
4380 int force = bm->process_main_queue ? 0 : 1;
4381
4382 if (!table)
4383 table = peer->bgp->rib[afi][safi];
4384
4385 /* If still no table => afi/safi isn't configured at all or smth. */
4386 if (!table)
4387 return;
4388
4389 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
4390 struct bgp_path_info *pi, *next;
4391 struct bgp_adj_in *ain;
4392 struct bgp_adj_in *ain_next;
4393
4394 /* XXX:TODO: This is suboptimal, every non-empty route_node is
4395 * queued for every clearing peer, regardless of whether it is
4396 * relevant to the peer at hand.
4397 *
4398 * Overview: There are 3 different indices which need to be
4399 * scrubbed, potentially, when a peer is removed:
4400 *
4401 * 1 peer's routes visible via the RIB (ie accepted routes)
4402 * 2 peer's routes visible by the (optional) peer's adj-in index
4403 * 3 other routes visible by the peer's adj-out index
4404 *
4405 * 3 there is no hurry in scrubbing, once the struct peer is
4406 * removed from bgp->peer, we could just GC such deleted peer's
4407 * adj-outs at our leisure.
4408 *
4409 * 1 and 2 must be 'scrubbed' in some way, at least made
4410 * invisible via RIB index before peer session is allowed to be
4411 * brought back up. So one needs to know when such a 'search' is
4412 * complete.
4413 *
4414 * Ideally:
4415 *
4416 * - there'd be a single global queue or a single RIB walker
4417 * - rather than tracking which route_nodes still need to be
4418 * examined on a peer basis, we'd track which peers still
4419 * aren't cleared
4420 *
4421 * Given that our per-peer prefix-counts now should be reliable,
4422 * this may actually be achievable. It doesn't seem to be a huge
4423 * problem at this time,
4424 *
4425 * It is possible that we have multiple paths for a prefix from
4426 * a peer
4427 * if that peer is using AddPath.
4428 */
4429 ain = rn->adj_in;
4430 while (ain) {
4431 ain_next = ain->next;
4432
4433 if (ain->peer == peer) {
4434 bgp_adj_in_remove(rn, ain);
4435 bgp_unlock_node(rn);
4436 }
4437
4438 ain = ain_next;
4439 }
4440
4441 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = next) {
4442 next = pi->next;
4443 if (pi->peer != peer)
4444 continue;
4445
4446 if (force)
4447 bgp_path_info_reap(rn, pi);
4448 else {
4449 struct bgp_clear_node_queue *cnq;
4450
4451 /* both unlocked in bgp_clear_node_queue_del */
4452 bgp_table_lock(bgp_node_table(rn));
4453 bgp_lock_node(rn);
4454 cnq = XCALLOC(
4455 MTYPE_BGP_CLEAR_NODE_QUEUE,
4456 sizeof(struct bgp_clear_node_queue));
4457 cnq->rn = rn;
4458 work_queue_add(peer->clear_node_queue, cnq);
4459 break;
4460 }
4461 }
4462 }
4463 return;
4464 }
4465
4466 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
4467 {
4468 struct bgp_node *rn;
4469 struct bgp_table *table;
4470
4471 if (peer->clear_node_queue == NULL)
4472 bgp_clear_node_queue_init(peer);
4473
4474 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
4475 * Idle until it receives a Clearing_Completed event. This protects
4476 * against peers which flap faster than we can we clear, which could
4477 * lead to:
4478 *
4479 * a) race with routes from the new session being installed before
4480 * clear_route_node visits the node (to delete the route of that
4481 * peer)
4482 * b) resource exhaustion, clear_route_node likely leads to an entry
4483 * on the process_main queue. Fast-flapping could cause that queue
4484 * to grow and grow.
4485 */
4486
4487 /* lock peer in assumption that clear-node-queue will get nodes; if so,
4488 * the unlock will happen upon work-queue completion; other wise, the
4489 * unlock happens at the end of this function.
4490 */
4491 if (!peer->clear_node_queue->thread)
4492 peer_lock(peer);
4493
4494 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
4495 bgp_clear_route_table(peer, afi, safi, NULL);
4496 else
4497 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
4498 rn = bgp_route_next(rn)) {
4499 table = bgp_node_get_bgp_table_info(rn);
4500 if (!table)
4501 continue;
4502
4503 bgp_clear_route_table(peer, afi, safi, table);
4504 }
4505
4506 /* unlock if no nodes got added to the clear-node-queue. */
4507 if (!peer->clear_node_queue->thread)
4508 peer_unlock(peer);
4509 }
4510
4511 void bgp_clear_route_all(struct peer *peer)
4512 {
4513 afi_t afi;
4514 safi_t safi;
4515
4516 FOREACH_AFI_SAFI (afi, safi)
4517 bgp_clear_route(peer, afi, safi);
4518
4519 #if ENABLE_BGP_VNC
4520 rfapiProcessPeerDown(peer);
4521 #endif
4522 }
4523
4524 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
4525 {
4526 struct bgp_table *table;
4527 struct bgp_node *rn;
4528 struct bgp_adj_in *ain;
4529 struct bgp_adj_in *ain_next;
4530
4531 table = peer->bgp->rib[afi][safi];
4532
4533 /* It is possible that we have multiple paths for a prefix from a peer
4534 * if that peer is using AddPath.
4535 */
4536 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
4537 ain = rn->adj_in;
4538
4539 while (ain) {
4540 ain_next = ain->next;
4541
4542 if (ain->peer == peer) {
4543 bgp_adj_in_remove(rn, ain);
4544 bgp_unlock_node(rn);
4545 }
4546
4547 ain = ain_next;
4548 }
4549 }
4550 }
4551
4552 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
4553 {
4554 struct bgp_node *rn;
4555 struct bgp_path_info *pi;
4556 struct bgp_table *table;
4557
4558 if (safi == SAFI_MPLS_VPN) {
4559 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
4560 rn = bgp_route_next(rn)) {
4561 struct bgp_node *rm;
4562
4563 /* look for neighbor in tables */
4564 table = bgp_node_get_bgp_table_info(rn);
4565 if (!table)
4566 continue;
4567
4568 for (rm = bgp_table_top(table); rm;
4569 rm = bgp_route_next(rm))
4570 for (pi = bgp_node_get_bgp_path_info(rm); pi;
4571 pi = pi->next) {
4572 if (pi->peer != peer)
4573 continue;
4574 if (!CHECK_FLAG(pi->flags,
4575 BGP_PATH_STALE))
4576 break;
4577
4578 bgp_rib_remove(rm, pi, peer, afi, safi);
4579 break;
4580 }
4581 }
4582 } else {
4583 for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
4584 rn = bgp_route_next(rn))
4585 for (pi = bgp_node_get_bgp_path_info(rn); pi;
4586 pi = pi->next) {
4587 if (pi->peer != peer)
4588 continue;
4589 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
4590 break;
4591 bgp_rib_remove(rn, pi, peer, afi, safi);
4592 break;
4593 }
4594 }
4595 }
4596
4597 int bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
4598 {
4599 if (peer->sort == BGP_PEER_IBGP)
4600 return 1;
4601
4602 if (peer->sort == BGP_PEER_EBGP
4603 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
4604 || FILTER_LIST_OUT_NAME(filter)
4605 || DISTRIBUTE_OUT_NAME(filter)))
4606 return 1;
4607 return 0;
4608 }
4609
4610 int bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
4611 {
4612 if (peer->sort == BGP_PEER_IBGP)
4613 return 1;
4614
4615 if (peer->sort == BGP_PEER_EBGP
4616 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
4617 || FILTER_LIST_IN_NAME(filter)
4618 || DISTRIBUTE_IN_NAME(filter)))
4619 return 1;
4620 return 0;
4621 }
4622
4623 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
4624 safi_t safi)
4625 {
4626 struct bgp_node *rn;
4627 struct bgp_path_info *pi;
4628 struct bgp_path_info *next;
4629
4630 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
4631 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = next) {
4632 next = pi->next;
4633
4634 /* Unimport EVPN routes from VRFs */
4635 if (safi == SAFI_EVPN)
4636 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
4637 SAFI_EVPN,
4638 &rn->p, pi);
4639
4640 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
4641 && pi->type == ZEBRA_ROUTE_BGP
4642 && (pi->sub_type == BGP_ROUTE_NORMAL
4643 || pi->sub_type == BGP_ROUTE_AGGREGATE
4644 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
4645
4646 if (bgp_fibupd_safi(safi))
4647 bgp_zebra_withdraw(&rn->p, pi, bgp,
4648 safi);
4649 bgp_path_info_reap(rn, pi);
4650 }
4651 }
4652 }
4653
4654 /* Delete all kernel routes. */
4655 void bgp_cleanup_routes(struct bgp *bgp)
4656 {
4657 afi_t afi;
4658 struct bgp_node *rn;
4659 struct bgp_table *table;
4660
4661 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
4662 if (afi == AFI_L2VPN)
4663 continue;
4664 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
4665 SAFI_UNICAST);
4666 /*
4667 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
4668 */
4669 if (afi != AFI_L2VPN) {
4670 safi_t safi;
4671 safi = SAFI_MPLS_VPN;
4672 for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
4673 rn = bgp_route_next(rn)) {
4674 table = bgp_node_get_bgp_table_info(rn);
4675 if (table != NULL) {
4676 bgp_cleanup_table(bgp, table, safi);
4677 bgp_table_finish(&table);
4678 bgp_node_set_bgp_table_info(rn, NULL);
4679 bgp_unlock_node(rn);
4680 }
4681 }
4682 safi = SAFI_ENCAP;
4683 for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
4684 rn = bgp_route_next(rn)) {
4685 table = bgp_node_get_bgp_table_info(rn);
4686 if (table != NULL) {
4687 bgp_cleanup_table(bgp, table, safi);
4688 bgp_table_finish(&table);
4689 bgp_node_set_bgp_table_info(rn, NULL);
4690 bgp_unlock_node(rn);
4691 }
4692 }
4693 }
4694 }
4695 for (rn = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); rn;
4696 rn = bgp_route_next(rn)) {
4697 table = bgp_node_get_bgp_table_info(rn);
4698 if (table != NULL) {
4699 bgp_cleanup_table(bgp, table, SAFI_EVPN);
4700 bgp_table_finish(&table);
4701 bgp_node_set_bgp_table_info(rn, NULL);
4702 bgp_unlock_node(rn);
4703 }
4704 }
4705 }
4706
4707 void bgp_reset(void)
4708 {
4709 vty_reset();
4710 bgp_zclient_reset();
4711 access_list_reset();
4712 prefix_list_reset();
4713 }
4714
4715 static int bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
4716 {
4717 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
4718 && CHECK_FLAG(peer->af_cap[afi][safi],
4719 PEER_CAP_ADDPATH_AF_TX_RCV));
4720 }
4721
4722 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
4723 value. */
4724 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
4725 struct bgp_nlri *packet)
4726 {
4727 uint8_t *pnt;
4728 uint8_t *lim;
4729 struct prefix p;
4730 int psize;
4731 int ret;
4732 afi_t afi;
4733 safi_t safi;
4734 int addpath_encoded;
4735 uint32_t addpath_id;
4736
4737 pnt = packet->nlri;
4738 lim = pnt + packet->length;
4739 afi = packet->afi;
4740 safi = packet->safi;
4741 addpath_id = 0;
4742 addpath_encoded = bgp_addpath_encode_rx(peer, afi, safi);
4743
4744 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
4745 syntactic validity. If the field is syntactically incorrect,
4746 then the Error Subcode is set to Invalid Network Field. */
4747 for (; pnt < lim; pnt += psize) {
4748 /* Clear prefix structure. */
4749 memset(&p, 0, sizeof(struct prefix));
4750
4751 if (addpath_encoded) {
4752
4753 /* When packet overflow occurs return immediately. */
4754 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
4755 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
4756
4757 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
4758 addpath_id = ntohl(addpath_id);
4759 pnt += BGP_ADDPATH_ID_LEN;
4760 }
4761
4762 /* Fetch prefix length. */
4763 p.prefixlen = *pnt++;
4764 /* afi/safi validity already verified by caller,
4765 * bgp_update_receive */
4766 p.family = afi2family(afi);
4767
4768 /* Prefix length check. */
4769 if (p.prefixlen > prefix_blen(&p) * 8) {
4770 flog_err(
4771 EC_BGP_UPDATE_RCV,
4772 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
4773 peer->host, p.prefixlen, packet->afi);
4774 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
4775 }
4776
4777 /* Packet size overflow check. */
4778 psize = PSIZE(p.prefixlen);
4779
4780 /* When packet overflow occur return immediately. */
4781 if (pnt + psize > lim) {
4782 flog_err(
4783 EC_BGP_UPDATE_RCV,
4784 "%s [Error] Update packet error (prefix length %d overflows packet)",
4785 peer->host, p.prefixlen);
4786 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
4787 }
4788
4789 /* Defensive coding, double-check the psize fits in a struct
4790 * prefix */
4791 if (psize > (ssize_t)sizeof(p.u)) {
4792 flog_err(
4793 EC_BGP_UPDATE_RCV,
4794 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
4795 peer->host, p.prefixlen, sizeof(p.u));
4796 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
4797 }
4798
4799 /* Fetch prefix from NLRI packet. */
4800 memcpy(p.u.val, pnt, psize);
4801
4802 /* Check address. */
4803 if (afi == AFI_IP && safi == SAFI_UNICAST) {
4804 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
4805 /* From RFC4271 Section 6.3:
4806 *
4807 * If a prefix in the NLRI field is semantically
4808 * incorrect
4809 * (e.g., an unexpected multicast IP address),
4810 * an error SHOULD
4811 * be logged locally, and the prefix SHOULD be
4812 * ignored.
4813 */
4814 flog_err(
4815 EC_BGP_UPDATE_RCV,
4816 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
4817 peer->host, inet_ntoa(p.u.prefix4));
4818 continue;
4819 }
4820 }
4821
4822 /* Check address. */
4823 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
4824 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
4825 char buf[BUFSIZ];
4826
4827 flog_err(
4828 EC_BGP_UPDATE_RCV,
4829 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
4830 peer->host,
4831 inet_ntop(AF_INET6, &p.u.prefix6, buf,
4832 BUFSIZ));
4833
4834 continue;
4835 }
4836 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
4837 char buf[BUFSIZ];
4838
4839 flog_err(
4840 EC_BGP_UPDATE_RCV,
4841 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
4842 peer->host,
4843 inet_ntop(AF_INET6, &p.u.prefix6, buf,
4844 BUFSIZ));
4845
4846 continue;
4847 }
4848 }
4849
4850 /* Normal process. */
4851 if (attr)
4852 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
4853 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
4854 NULL, NULL, 0, 0, NULL);
4855 else
4856 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
4857 safi, ZEBRA_ROUTE_BGP,
4858 BGP_ROUTE_NORMAL, NULL, NULL, 0,
4859 NULL);
4860
4861 /* Do not send BGP notification twice when maximum-prefix count
4862 * overflow. */
4863 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
4864 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
4865
4866 /* Address family configuration mismatch. */
4867 if (ret < 0)
4868 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
4869 }
4870
4871 /* Packet length consistency check. */
4872 if (pnt != lim) {
4873 flog_err(
4874 EC_BGP_UPDATE_RCV,
4875 "%s [Error] Update packet error (prefix length mismatch with total length)",
4876 peer->host);
4877 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
4878 }
4879
4880 return BGP_NLRI_PARSE_OK;
4881 }
4882
4883 static struct bgp_static *bgp_static_new(void)
4884 {
4885 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
4886 }
4887
4888 static void bgp_static_free(struct bgp_static *bgp_static)
4889 {
4890 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
4891 route_map_counter_decrement(bgp_static->rmap.map);
4892
4893 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
4894 XFREE(MTYPE_BGP_STATIC, bgp_static);
4895 }
4896
4897 void bgp_static_update(struct bgp *bgp, struct prefix *p,
4898 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
4899 {
4900 struct bgp_node *rn;
4901 struct bgp_path_info *pi;
4902 struct bgp_path_info *new;
4903 struct bgp_path_info rmap_path;
4904 struct attr attr;
4905 struct attr *attr_new;
4906 route_map_result_t ret;
4907 #if ENABLE_BGP_VNC
4908 int vnc_implicit_withdraw = 0;
4909 #endif
4910
4911 assert(bgp_static);
4912 if (!bgp_static)
4913 return;
4914
4915 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
4916
4917 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
4918
4919 attr.nexthop = bgp_static->igpnexthop;
4920 attr.med = bgp_static->igpmetric;
4921 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
4922
4923 if (bgp_static->atomic)
4924 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
4925
4926 /* Store label index, if required. */
4927 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
4928 attr.label_index = bgp_static->label_index;
4929 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
4930 }
4931
4932 /* Apply route-map. */
4933 if (bgp_static->rmap.name) {
4934 struct attr attr_tmp = attr;
4935
4936 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
4937 rmap_path.peer = bgp->peer_self;
4938 rmap_path.attr = &attr_tmp;
4939
4940 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
4941
4942 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
4943 &rmap_path);
4944
4945 bgp->peer_self->rmap_type = 0;
4946
4947 if (ret == RMAP_DENYMATCH) {
4948 /* Free uninterned attribute. */
4949 bgp_attr_flush(&attr_tmp);
4950
4951 /* Unintern original. */
4952 aspath_unintern(&attr.aspath);
4953 bgp_static_withdraw(bgp, p, afi, safi);
4954 return;
4955 }
4956
4957 if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN))
4958 bgp_attr_add_gshut_community(&attr_tmp);
4959
4960 attr_new = bgp_attr_intern(&attr_tmp);
4961 } else {
4962
4963 if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN))
4964 bgp_attr_add_gshut_community(&attr);
4965
4966 attr_new = bgp_attr_intern(&attr);
4967 }
4968
4969 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
4970 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
4971 && pi->sub_type == BGP_ROUTE_STATIC)
4972 break;
4973
4974 if (pi) {
4975 if (attrhash_cmp(pi->attr, attr_new)
4976 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4977 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
4978 bgp_unlock_node(rn);
4979 bgp_attr_unintern(&attr_new);
4980 aspath_unintern(&attr.aspath);
4981 return;
4982 } else {
4983 /* The attribute is changed. */
4984 bgp_path_info_set_flag(rn, pi, BGP_PATH_ATTR_CHANGED);
4985
4986 /* Rewrite BGP route information. */
4987 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
4988 bgp_path_info_restore(rn, pi);
4989 else
4990 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4991 #if ENABLE_BGP_VNC
4992 if ((afi == AFI_IP || afi == AFI_IP6)
4993 && (safi == SAFI_UNICAST)) {
4994 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4995 /*
4996 * Implicit withdraw case.
4997 * We have to do this before pi is
4998 * changed
4999 */
5000 ++vnc_implicit_withdraw;
5001 vnc_import_bgp_del_route(bgp, p, pi);
5002 vnc_import_bgp_exterior_del_route(
5003 bgp, p, pi);
5004 }
5005 }
5006 #endif
5007 bgp_attr_unintern(&pi->attr);
5008 pi->attr = attr_new;
5009 pi->uptime = bgp_clock();
5010 #if ENABLE_BGP_VNC
5011 if ((afi == AFI_IP || afi == AFI_IP6)
5012 && (safi == SAFI_UNICAST)) {
5013 if (vnc_implicit_withdraw) {
5014 vnc_import_bgp_add_route(bgp, p, pi);
5015 vnc_import_bgp_exterior_add_route(
5016 bgp, p, pi);
5017 }
5018 }
5019 #endif
5020
5021 /* Nexthop reachability check. */
5022 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5023 && (safi == SAFI_UNICAST
5024 || safi == SAFI_LABELED_UNICAST)) {
5025
5026 struct bgp *bgp_nexthop = bgp;
5027
5028 if (pi->extra && pi->extra->bgp_orig)
5029 bgp_nexthop = pi->extra->bgp_orig;
5030
5031 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
5032 afi, pi, NULL, 0))
5033 bgp_path_info_set_flag(rn, pi,
5034 BGP_PATH_VALID);
5035 else {
5036 if (BGP_DEBUG(nht, NHT)) {
5037 char buf1[INET6_ADDRSTRLEN];
5038 inet_ntop(p->family,
5039 &p->u.prefix, buf1,
5040 INET6_ADDRSTRLEN);
5041 zlog_debug(
5042 "%s(%s): Route not in table, not advertising",
5043 __FUNCTION__, buf1);
5044 }
5045 bgp_path_info_unset_flag(
5046 rn, pi, BGP_PATH_VALID);
5047 }
5048 } else {
5049 /* Delete the NHT structure if any, if we're
5050 * toggling between
5051 * enabling/disabling import check. We
5052 * deregister the route
5053 * from NHT to avoid overloading NHT and the
5054 * process interaction
5055 */
5056 bgp_unlink_nexthop(pi);
5057 bgp_path_info_set_flag(rn, pi, BGP_PATH_VALID);
5058 }
5059 /* Process change. */
5060 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5061 bgp_process(bgp, rn, afi, safi);
5062
5063 if (SAFI_UNICAST == safi
5064 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5065 || bgp->inst_type
5066 == BGP_INSTANCE_TYPE_DEFAULT)) {
5067 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
5068 pi);
5069 }
5070
5071 bgp_unlock_node(rn);
5072 aspath_unintern(&attr.aspath);
5073 return;
5074 }
5075 }
5076
5077 /* Make new BGP info. */
5078 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5079 attr_new, rn);
5080 /* Nexthop reachability check. */
5081 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5082 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
5083 if (bgp_find_or_add_nexthop(bgp, bgp, afi, new, NULL, 0))
5084 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
5085 else {
5086 if (BGP_DEBUG(nht, NHT)) {
5087 char buf1[INET6_ADDRSTRLEN];
5088 inet_ntop(p->family, &p->u.prefix, buf1,
5089 INET6_ADDRSTRLEN);
5090 zlog_debug(
5091 "%s(%s): Route not in table, not advertising",
5092 __FUNCTION__, buf1);
5093 }
5094 bgp_path_info_unset_flag(rn, new, BGP_PATH_VALID);
5095 }
5096 } else {
5097 /* Delete the NHT structure if any, if we're toggling between
5098 * enabling/disabling import check. We deregister the route
5099 * from NHT to avoid overloading NHT and the process interaction
5100 */
5101 bgp_unlink_nexthop(new);
5102
5103 bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
5104 }
5105
5106 /* Aggregate address increment. */
5107 bgp_aggregate_increment(bgp, p, new, afi, safi);
5108
5109 /* Register new BGP information. */
5110 bgp_path_info_add(rn, new);
5111
5112 /* route_node_get lock */
5113 bgp_unlock_node(rn);
5114
5115 /* Process change. */
5116 bgp_process(bgp, rn, afi, safi);
5117
5118 if (SAFI_UNICAST == safi
5119 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5120 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5121 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
5122 }
5123
5124 /* Unintern original. */
5125 aspath_unintern(&attr.aspath);
5126 }
5127
5128 void bgp_static_withdraw(struct bgp *bgp, struct prefix *p, afi_t afi,
5129 safi_t safi)
5130 {
5131 struct bgp_node *rn;
5132 struct bgp_path_info *pi;
5133
5134 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5135
5136 /* Check selected route and self inserted route. */
5137 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
5138 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5139 && pi->sub_type == BGP_ROUTE_STATIC)
5140 break;
5141
5142 /* Withdraw static BGP route from routing table. */
5143 if (pi) {
5144 if (SAFI_UNICAST == safi
5145 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5146 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5147 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5148 }
5149 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5150 bgp_unlink_nexthop(pi);
5151 bgp_path_info_delete(rn, pi);
5152 bgp_process(bgp, rn, afi, safi);
5153 }
5154
5155 /* Unlock bgp_node_lookup. */
5156 bgp_unlock_node(rn);
5157 }
5158
5159 /*
5160 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
5161 */
5162 static void bgp_static_withdraw_safi(struct bgp *bgp, struct prefix *p,
5163 afi_t afi, safi_t safi,
5164 struct prefix_rd *prd)
5165 {
5166 struct bgp_node *rn;
5167 struct bgp_path_info *pi;
5168
5169 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
5170
5171 /* Check selected route and self inserted route. */
5172 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
5173 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5174 && pi->sub_type == BGP_ROUTE_STATIC)
5175 break;
5176
5177 /* Withdraw static BGP route from routing table. */
5178 if (pi) {
5179 #if ENABLE_BGP_VNC
5180 rfapiProcessWithdraw(
5181 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
5182 1); /* Kill, since it is an administrative change */
5183 #endif
5184 if (SAFI_MPLS_VPN == safi
5185 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5186 vpn_leak_to_vrf_withdraw(bgp, pi);
5187 }
5188 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5189 bgp_path_info_delete(rn, pi);
5190 bgp_process(bgp, rn, afi, safi);
5191 }
5192
5193 /* Unlock bgp_node_lookup. */
5194 bgp_unlock_node(rn);
5195 }
5196
5197 static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p,
5198 struct bgp_static *bgp_static, afi_t afi,
5199 safi_t safi)
5200 {
5201 struct bgp_node *rn;
5202 struct bgp_path_info *new;
5203 struct attr *attr_new;
5204 struct attr attr = {0};
5205 struct bgp_path_info *pi;
5206 #if ENABLE_BGP_VNC
5207 mpls_label_t label = 0;
5208 #endif
5209 uint32_t num_labels = 0;
5210 union gw_addr add;
5211
5212 assert(bgp_static);
5213
5214 if (bgp_static->label != MPLS_INVALID_LABEL)
5215 num_labels = 1;
5216 rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
5217 &bgp_static->prd);
5218
5219 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5220
5221 attr.nexthop = bgp_static->igpnexthop;
5222 attr.med = bgp_static->igpmetric;
5223 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5224
5225 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
5226 || (safi == SAFI_ENCAP)) {
5227 if (afi == AFI_IP) {
5228 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
5229 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
5230 }
5231 }
5232 if (afi == AFI_L2VPN) {
5233 if (bgp_static->gatewayIp.family == AF_INET)
5234 add.ipv4.s_addr =
5235 bgp_static->gatewayIp.u.prefix4.s_addr;
5236 else if (bgp_static->gatewayIp.family == AF_INET6)
5237 memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
5238 sizeof(struct in6_addr));
5239 overlay_index_update(&attr, bgp_static->eth_s_id, &add);
5240 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
5241 struct bgp_encap_type_vxlan bet;
5242 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
5243 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
5244 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
5245 }
5246 if (bgp_static->router_mac) {
5247 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
5248 }
5249 }
5250 /* Apply route-map. */
5251 if (bgp_static->rmap.name) {
5252 struct attr attr_tmp = attr;
5253 struct bgp_path_info rmap_path;
5254 route_map_result_t ret;
5255
5256 rmap_path.peer = bgp->peer_self;
5257 rmap_path.attr = &attr_tmp;
5258
5259 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5260
5261 ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
5262 &rmap_path);
5263
5264 bgp->peer_self->rmap_type = 0;
5265
5266 if (ret == RMAP_DENYMATCH) {
5267 /* Free uninterned attribute. */
5268 bgp_attr_flush(&attr_tmp);
5269
5270 /* Unintern original. */
5271 aspath_unintern(&attr.aspath);
5272 bgp_static_withdraw_safi(bgp, p, afi, safi,
5273 &bgp_static->prd);
5274 return;
5275 }
5276
5277 attr_new = bgp_attr_intern(&attr_tmp);
5278 } else {
5279 attr_new = bgp_attr_intern(&attr);
5280 }
5281
5282 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
5283 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5284 && pi->sub_type == BGP_ROUTE_STATIC)
5285 break;
5286
5287 if (pi) {
5288 memset(&add, 0, sizeof(union gw_addr));
5289 if (attrhash_cmp(pi->attr, attr_new)
5290 && overlay_index_equal(afi, pi, bgp_static->eth_s_id, &add)
5291 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
5292 bgp_unlock_node(rn);
5293 bgp_attr_unintern(&attr_new);
5294 aspath_unintern(&attr.aspath);
5295 return;
5296 } else {
5297 /* The attribute is changed. */
5298 bgp_path_info_set_flag(rn, pi, BGP_PATH_ATTR_CHANGED);
5299
5300 /* Rewrite BGP route information. */
5301 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5302 bgp_path_info_restore(rn, pi);
5303 else
5304 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5305 bgp_attr_unintern(&pi->attr);
5306 pi->attr = attr_new;
5307 pi->uptime = bgp_clock();
5308 #if ENABLE_BGP_VNC
5309 if (pi->extra)
5310 label = decode_label(&pi->extra->label[0]);
5311 #endif
5312
5313 /* Process change. */
5314 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5315 bgp_process(bgp, rn, afi, safi);
5316
5317 if (SAFI_MPLS_VPN == safi
5318 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5319 vpn_leak_to_vrf_update(bgp, pi);
5320 }
5321 #if ENABLE_BGP_VNC
5322 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
5323 pi->attr, afi, safi, pi->type,
5324 pi->sub_type, &label);
5325 #endif
5326 bgp_unlock_node(rn);
5327 aspath_unintern(&attr.aspath);
5328 return;
5329 }
5330 }
5331
5332
5333 /* Make new BGP info. */
5334 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5335 attr_new, rn);
5336 SET_FLAG(new->flags, BGP_PATH_VALID);
5337 new->extra = bgp_path_info_extra_new();
5338 if (num_labels) {
5339 new->extra->label[0] = bgp_static->label;
5340 new->extra->num_labels = num_labels;
5341 }
5342 #if ENABLE_BGP_VNC
5343 label = decode_label(&bgp_static->label);
5344 #endif
5345
5346 /* Aggregate address increment. */
5347 bgp_aggregate_increment(bgp, p, new, afi, safi);
5348
5349 /* Register new BGP information. */
5350 bgp_path_info_add(rn, new);
5351 /* route_node_get lock */
5352 bgp_unlock_node(rn);
5353
5354 /* Process change. */
5355 bgp_process(bgp, rn, afi, safi);
5356
5357 if (SAFI_MPLS_VPN == safi
5358 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5359 vpn_leak_to_vrf_update(bgp, new);
5360 }
5361 #if ENABLE_BGP_VNC
5362 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
5363 safi, new->type, new->sub_type, &label);
5364 #endif
5365
5366 /* Unintern original. */
5367 aspath_unintern(&attr.aspath);
5368 }
5369
5370 /* Configure static BGP network. When user don't run zebra, static
5371 route should be installed as valid. */
5372 static int bgp_static_set(struct vty *vty, const char *negate,
5373 const char *ip_str, afi_t afi, safi_t safi,
5374 const char *rmap, int backdoor, uint32_t label_index)
5375 {
5376 VTY_DECLVAR_CONTEXT(bgp, bgp);
5377 int ret;
5378 struct prefix p;
5379 struct bgp_static *bgp_static;
5380 struct bgp_node *rn;
5381 uint8_t need_update = 0;
5382
5383 /* Convert IP prefix string to struct prefix. */
5384 ret = str2prefix(ip_str, &p);
5385 if (!ret) {
5386 vty_out(vty, "%% Malformed prefix\n");
5387 return CMD_WARNING_CONFIG_FAILED;
5388 }
5389 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
5390 vty_out(vty, "%% Malformed prefix (link-local address)\n");
5391 return CMD_WARNING_CONFIG_FAILED;
5392 }
5393
5394 apply_mask(&p);
5395
5396 if (negate) {
5397
5398 /* Set BGP static route configuration. */
5399 rn = bgp_node_lookup(bgp->route[afi][safi], &p);
5400
5401 if (!rn) {
5402 vty_out(vty, "%% Can't find static route specified\n");
5403 return CMD_WARNING_CONFIG_FAILED;
5404 }
5405
5406 bgp_static = bgp_node_get_bgp_static_info(rn);
5407
5408 if ((label_index != BGP_INVALID_LABEL_INDEX)
5409 && (label_index != bgp_static->label_index)) {
5410 vty_out(vty,
5411 "%% label-index doesn't match static route\n");
5412 return CMD_WARNING_CONFIG_FAILED;
5413 }
5414
5415 if ((rmap && bgp_static->rmap.name)
5416 && strcmp(rmap, bgp_static->rmap.name)) {
5417 vty_out(vty,
5418 "%% route-map name doesn't match static route\n");
5419 return CMD_WARNING_CONFIG_FAILED;
5420 }
5421
5422 /* Update BGP RIB. */
5423 if (!bgp_static->backdoor)
5424 bgp_static_withdraw(bgp, &p, afi, safi);
5425
5426 /* Clear configuration. */
5427 bgp_static_free(bgp_static);
5428 bgp_node_set_bgp_static_info(rn, NULL);
5429 bgp_unlock_node(rn);
5430 bgp_unlock_node(rn);
5431 } else {
5432
5433 /* Set BGP static route configuration. */
5434 rn = bgp_node_get(bgp->route[afi][safi], &p);
5435
5436 bgp_static = bgp_node_get_bgp_static_info(rn);
5437 if (bgp_static) {
5438 /* Configuration change. */
5439 /* Label index cannot be changed. */
5440 if (bgp_static->label_index != label_index) {
5441 vty_out(vty, "%% cannot change label-index\n");
5442 return CMD_WARNING_CONFIG_FAILED;
5443 }
5444
5445 /* Check previous routes are installed into BGP. */
5446 if (bgp_static->valid
5447 && bgp_static->backdoor != backdoor)
5448 need_update = 1;
5449
5450 bgp_static->backdoor = backdoor;
5451
5452 if (rmap) {
5453 XFREE(MTYPE_ROUTE_MAP_NAME,
5454 bgp_static->rmap.name);
5455 route_map_counter_decrement(
5456 bgp_static->rmap.map);
5457 bgp_static->rmap.name =
5458 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5459 bgp_static->rmap.map =
5460 route_map_lookup_by_name(rmap);
5461 route_map_counter_increment(
5462 bgp_static->rmap.map);
5463 } else {
5464 XFREE(MTYPE_ROUTE_MAP_NAME,
5465 bgp_static->rmap.name);
5466 route_map_counter_decrement(
5467 bgp_static->rmap.map);
5468 bgp_static->rmap.map = NULL;
5469 bgp_static->valid = 0;
5470 }
5471 bgp_unlock_node(rn);
5472 } else {
5473 /* New configuration. */
5474 bgp_static = bgp_static_new();
5475 bgp_static->backdoor = backdoor;
5476 bgp_static->valid = 0;
5477 bgp_static->igpmetric = 0;
5478 bgp_static->igpnexthop.s_addr = INADDR_ANY;
5479 bgp_static->label_index = label_index;
5480
5481 if (rmap) {
5482 XFREE(MTYPE_ROUTE_MAP_NAME,
5483 bgp_static->rmap.name);
5484 route_map_counter_decrement(
5485 bgp_static->rmap.map);
5486 bgp_static->rmap.name =
5487 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5488 bgp_static->rmap.map =
5489 route_map_lookup_by_name(rmap);
5490 route_map_counter_increment(
5491 bgp_static->rmap.map);
5492 }
5493 bgp_node_set_bgp_static_info(rn, bgp_static);
5494 }
5495
5496 bgp_static->valid = 1;
5497 if (need_update)
5498 bgp_static_withdraw(bgp, &p, afi, safi);
5499
5500 if (!bgp_static->backdoor)
5501 bgp_static_update(bgp, &p, bgp_static, afi, safi);
5502 }
5503
5504 return CMD_SUCCESS;
5505 }
5506
5507 void bgp_static_add(struct bgp *bgp)
5508 {
5509 afi_t afi;
5510 safi_t safi;
5511 struct bgp_node *rn;
5512 struct bgp_node *rm;
5513 struct bgp_table *table;
5514 struct bgp_static *bgp_static;
5515
5516 FOREACH_AFI_SAFI (afi, safi)
5517 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5518 rn = bgp_route_next(rn)) {
5519 if (!bgp_node_has_bgp_path_info_data(rn))
5520 continue;
5521
5522 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5523 || (safi == SAFI_EVPN)) {
5524 table = bgp_node_get_bgp_table_info(rn);
5525
5526 for (rm = bgp_table_top(table); rm;
5527 rm = bgp_route_next(rm)) {
5528 bgp_static =
5529 bgp_node_get_bgp_static_info(
5530 rm);
5531 bgp_static_update_safi(bgp, &rm->p,
5532 bgp_static, afi,
5533 safi);
5534 }
5535 } else {
5536 bgp_static_update(
5537 bgp, &rn->p,
5538 bgp_node_get_bgp_static_info(rn), afi,
5539 safi);
5540 }
5541 }
5542 }
5543
5544 /* Called from bgp_delete(). Delete all static routes from the BGP
5545 instance. */
5546 void bgp_static_delete(struct bgp *bgp)
5547 {
5548 afi_t afi;
5549 safi_t safi;
5550 struct bgp_node *rn;
5551 struct bgp_node *rm;
5552 struct bgp_table *table;
5553 struct bgp_static *bgp_static;
5554
5555 FOREACH_AFI_SAFI (afi, safi)
5556 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5557 rn = bgp_route_next(rn)) {
5558 if (!bgp_node_has_bgp_path_info_data(rn))
5559 continue;
5560
5561 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5562 || (safi == SAFI_EVPN)) {
5563 table = bgp_node_get_bgp_table_info(rn);
5564
5565 for (rm = bgp_table_top(table); rm;
5566 rm = bgp_route_next(rm)) {
5567 bgp_static =
5568 bgp_node_get_bgp_static_info(
5569 rm);
5570 if (!bgp_static)
5571 continue;
5572
5573 bgp_static_withdraw_safi(
5574 bgp, &rm->p, AFI_IP, safi,
5575 (struct prefix_rd *)&rn->p);
5576 bgp_static_free(bgp_static);
5577 bgp_node_set_bgp_static_info(rn, NULL);
5578 bgp_unlock_node(rn);
5579 }
5580 } else {
5581 bgp_static = bgp_node_get_bgp_static_info(rn);
5582 bgp_static_withdraw(bgp, &rn->p, afi, safi);
5583 bgp_static_free(bgp_static);
5584 bgp_node_set_bgp_static_info(rn, NULL);
5585 bgp_unlock_node(rn);
5586 }
5587 }
5588 }
5589
5590 void bgp_static_redo_import_check(struct bgp *bgp)
5591 {
5592 afi_t afi;
5593 safi_t safi;
5594 struct bgp_node *rn;
5595 struct bgp_node *rm;
5596 struct bgp_table *table;
5597 struct bgp_static *bgp_static;
5598
5599 /* Use this flag to force reprocessing of the route */
5600 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
5601 FOREACH_AFI_SAFI (afi, safi) {
5602 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
5603 rn = bgp_route_next(rn)) {
5604 if (!bgp_node_has_bgp_path_info_data(rn))
5605 continue;
5606
5607 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5608 || (safi == SAFI_EVPN)) {
5609 table = bgp_node_get_bgp_table_info(rn);
5610
5611 for (rm = bgp_table_top(table); rm;
5612 rm = bgp_route_next(rm)) {
5613 bgp_static =
5614 bgp_node_get_bgp_static_info(
5615 rm);
5616 bgp_static_update_safi(bgp, &rm->p,
5617 bgp_static, afi,
5618 safi);
5619 }
5620 } else {
5621 bgp_static = bgp_node_get_bgp_static_info(rn);
5622 bgp_static_update(bgp, &rn->p, bgp_static, afi,
5623 safi);
5624 }
5625 }
5626 }
5627 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
5628 }
5629
5630 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
5631 safi_t safi)
5632 {
5633 struct bgp_table *table;
5634 struct bgp_node *rn;
5635 struct bgp_path_info *pi;
5636
5637 /* Do not install the aggregate route if BGP is in the
5638 * process of termination.
5639 */
5640 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
5641 || (bgp->peer_self == NULL))
5642 return;
5643
5644 table = bgp->rib[afi][safi];
5645 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
5646 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
5647 if (pi->peer == bgp->peer_self
5648 && ((pi->type == ZEBRA_ROUTE_BGP
5649 && pi->sub_type == BGP_ROUTE_STATIC)
5650 || (pi->type != ZEBRA_ROUTE_BGP
5651 && pi->sub_type
5652 == BGP_ROUTE_REDISTRIBUTE))) {
5653 bgp_aggregate_decrement(bgp, &rn->p, pi, afi,
5654 safi);
5655 bgp_unlink_nexthop(pi);
5656 bgp_path_info_delete(rn, pi);
5657 bgp_process(bgp, rn, afi, safi);
5658 }
5659 }
5660 }
5661 }
5662
5663 /*
5664 * Purge all networks and redistributed routes from routing table.
5665 * Invoked upon the instance going down.
5666 */
5667 void bgp_purge_static_redist_routes(struct bgp *bgp)
5668 {
5669 afi_t afi;
5670 safi_t safi;
5671
5672 FOREACH_AFI_SAFI (afi, safi)
5673 bgp_purge_af_static_redist_routes(bgp, afi, safi);
5674 }
5675
5676 /*
5677 * gpz 110624
5678 * Currently this is used to set static routes for VPN and ENCAP.
5679 * I think it can probably be factored with bgp_static_set.
5680 */
5681 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
5682 const char *ip_str, const char *rd_str,
5683 const char *label_str, const char *rmap_str,
5684 int evpn_type, const char *esi, const char *gwip,
5685 const char *ethtag, const char *routermac)
5686 {
5687 VTY_DECLVAR_CONTEXT(bgp, bgp);
5688 int ret;
5689 struct prefix p;
5690 struct prefix_rd prd;
5691 struct bgp_node *prn;
5692 struct bgp_node *rn;
5693 struct bgp_table *table;
5694 struct bgp_static *bgp_static;
5695 mpls_label_t label = MPLS_INVALID_LABEL;
5696 struct prefix gw_ip;
5697
5698 /* validate ip prefix */
5699 ret = str2prefix(ip_str, &p);
5700 if (!ret) {
5701 vty_out(vty, "%% Malformed prefix\n");
5702 return CMD_WARNING_CONFIG_FAILED;
5703 }
5704 apply_mask(&p);
5705 if ((afi == AFI_L2VPN)
5706 && (bgp_build_evpn_prefix(evpn_type,
5707 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5708 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5709 return CMD_WARNING_CONFIG_FAILED;
5710 }
5711
5712 ret = str2prefix_rd(rd_str, &prd);
5713 if (!ret) {
5714 vty_out(vty, "%% Malformed rd\n");
5715 return CMD_WARNING_CONFIG_FAILED;
5716 }
5717
5718 if (label_str) {
5719 unsigned long label_val;
5720 label_val = strtoul(label_str, NULL, 10);
5721 encode_label(label_val, &label);
5722 }
5723
5724 if (safi == SAFI_EVPN) {
5725 if (esi && str2esi(esi, NULL) == 0) {
5726 vty_out(vty, "%% Malformed ESI\n");
5727 return CMD_WARNING_CONFIG_FAILED;
5728 }
5729 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
5730 vty_out(vty, "%% Malformed Router MAC\n");
5731 return CMD_WARNING_CONFIG_FAILED;
5732 }
5733 if (gwip) {
5734 memset(&gw_ip, 0, sizeof(struct prefix));
5735 ret = str2prefix(gwip, &gw_ip);
5736 if (!ret) {
5737 vty_out(vty, "%% Malformed GatewayIp\n");
5738 return CMD_WARNING_CONFIG_FAILED;
5739 }
5740 if ((gw_ip.family == AF_INET
5741 && is_evpn_prefix_ipaddr_v6(
5742 (struct prefix_evpn *)&p))
5743 || (gw_ip.family == AF_INET6
5744 && is_evpn_prefix_ipaddr_v4(
5745 (struct prefix_evpn *)&p))) {
5746 vty_out(vty,
5747 "%% GatewayIp family differs with IP prefix\n");
5748 return CMD_WARNING_CONFIG_FAILED;
5749 }
5750 }
5751 }
5752 prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5753 if (!bgp_node_has_bgp_path_info_data(prn))
5754 bgp_node_set_bgp_table_info(prn,
5755 bgp_table_init(bgp, afi, safi));
5756 table = bgp_node_get_bgp_table_info(prn);
5757
5758 rn = bgp_node_get(table, &p);
5759
5760 if (bgp_node_has_bgp_path_info_data(rn)) {
5761 vty_out(vty, "%% Same network configuration exists\n");
5762 bgp_unlock_node(rn);
5763 } else {
5764 /* New configuration. */
5765 bgp_static = bgp_static_new();
5766 bgp_static->backdoor = 0;
5767 bgp_static->valid = 0;
5768 bgp_static->igpmetric = 0;
5769 bgp_static->igpnexthop.s_addr = INADDR_ANY;
5770 bgp_static->label = label;
5771 bgp_static->prd = prd;
5772
5773 if (rmap_str) {
5774 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5775 route_map_counter_decrement(bgp_static->rmap.map);
5776 bgp_static->rmap.name =
5777 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
5778 bgp_static->rmap.map =
5779 route_map_lookup_by_name(rmap_str);
5780 route_map_counter_increment(bgp_static->rmap.map);
5781 }
5782
5783 if (safi == SAFI_EVPN) {
5784 if (esi) {
5785 bgp_static->eth_s_id =
5786 XCALLOC(MTYPE_ATTR,
5787 sizeof(struct eth_segment_id));
5788 str2esi(esi, bgp_static->eth_s_id);
5789 }
5790 if (routermac) {
5791 bgp_static->router_mac =
5792 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
5793 (void)prefix_str2mac(routermac,
5794 bgp_static->router_mac);
5795 }
5796 if (gwip)
5797 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
5798 }
5799 bgp_node_set_bgp_static_info(rn, bgp_static);
5800
5801 bgp_static->valid = 1;
5802 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
5803 }
5804
5805 return CMD_SUCCESS;
5806 }
5807
5808 /* Configure static BGP network. */
5809 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
5810 const char *ip_str, const char *rd_str,
5811 const char *label_str, int evpn_type, const char *esi,
5812 const char *gwip, const char *ethtag)
5813 {
5814 VTY_DECLVAR_CONTEXT(bgp, bgp);
5815 int ret;
5816 struct prefix p;
5817 struct prefix_rd prd;
5818 struct bgp_node *prn;
5819 struct bgp_node *rn;
5820 struct bgp_table *table;
5821 struct bgp_static *bgp_static;
5822 mpls_label_t label = MPLS_INVALID_LABEL;
5823
5824 /* Convert IP prefix string to struct prefix. */
5825 ret = str2prefix(ip_str, &p);
5826 if (!ret) {
5827 vty_out(vty, "%% Malformed prefix\n");
5828 return CMD_WARNING_CONFIG_FAILED;
5829 }
5830 apply_mask(&p);
5831 if ((afi == AFI_L2VPN)
5832 && (bgp_build_evpn_prefix(evpn_type,
5833 ethtag != NULL ? atol(ethtag) : 0, &p))) {
5834 vty_out(vty, "%% L2VPN prefix could not be forged\n");
5835 return CMD_WARNING_CONFIG_FAILED;
5836 }
5837 ret = str2prefix_rd(rd_str, &prd);
5838 if (!ret) {
5839 vty_out(vty, "%% Malformed rd\n");
5840 return CMD_WARNING_CONFIG_FAILED;
5841 }
5842
5843 if (label_str) {
5844 unsigned long label_val;
5845 label_val = strtoul(label_str, NULL, 10);
5846 encode_label(label_val, &label);
5847 }
5848
5849 prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
5850 if (!bgp_node_has_bgp_path_info_data(prn))
5851 bgp_node_set_bgp_table_info(prn,
5852 bgp_table_init(bgp, afi, safi));
5853 else
5854 bgp_unlock_node(prn);
5855 table = bgp_node_get_bgp_table_info(prn);
5856
5857 rn = bgp_node_lookup(table, &p);
5858
5859 if (rn) {
5860 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
5861
5862 bgp_static = bgp_node_get_bgp_static_info(rn);
5863 bgp_static_free(bgp_static);
5864 bgp_node_set_bgp_static_info(rn, NULL);
5865 bgp_unlock_node(rn);
5866 bgp_unlock_node(rn);
5867 } else
5868 vty_out(vty, "%% Can't find the route\n");
5869
5870 return CMD_SUCCESS;
5871 }
5872
5873 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
5874 const char *rmap_name)
5875 {
5876 VTY_DECLVAR_CONTEXT(bgp, bgp);
5877 struct bgp_rmap *rmap;
5878
5879 rmap = &bgp->table_map[afi][safi];
5880 if (rmap_name) {
5881 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5882 route_map_counter_decrement(rmap->map);
5883 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
5884 rmap->map = route_map_lookup_by_name(rmap_name);
5885 route_map_counter_increment(rmap->map);
5886 } else {
5887 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5888 route_map_counter_decrement(rmap->map);
5889 rmap->map = NULL;
5890 }
5891
5892 if (bgp_fibupd_safi(safi))
5893 bgp_zebra_announce_table(bgp, afi, safi);
5894
5895 return CMD_SUCCESS;
5896 }
5897
5898 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
5899 const char *rmap_name)
5900 {
5901 VTY_DECLVAR_CONTEXT(bgp, bgp);
5902 struct bgp_rmap *rmap;
5903
5904 rmap = &bgp->table_map[afi][safi];
5905 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
5906 route_map_counter_decrement(rmap->map);
5907 rmap->map = NULL;
5908
5909 if (bgp_fibupd_safi(safi))
5910 bgp_zebra_announce_table(bgp, afi, safi);
5911
5912 return CMD_SUCCESS;
5913 }
5914
5915 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
5916 safi_t safi)
5917 {
5918 if (bgp->table_map[afi][safi].name) {
5919 vty_out(vty, " table-map %s\n",
5920 bgp->table_map[afi][safi].name);
5921 }
5922 }
5923
5924 DEFUN (bgp_table_map,
5925 bgp_table_map_cmd,
5926 "table-map WORD",
5927 "BGP table to RIB route download filter\n"
5928 "Name of the route map\n")
5929 {
5930 int idx_word = 1;
5931 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
5932 argv[idx_word]->arg);
5933 }
5934 DEFUN (no_bgp_table_map,
5935 no_bgp_table_map_cmd,
5936 "no table-map WORD",
5937 NO_STR
5938 "BGP table to RIB route download filter\n"
5939 "Name of the route map\n")
5940 {
5941 int idx_word = 2;
5942 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
5943 argv[idx_word]->arg);
5944 }
5945
5946 DEFPY(bgp_network,
5947 bgp_network_cmd,
5948 "[no] network \
5949 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
5950 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
5951 backdoor$backdoor}]",
5952 NO_STR
5953 "Specify a network to announce via BGP\n"
5954 "IPv4 prefix\n"
5955 "Network number\n"
5956 "Network mask\n"
5957 "Network mask\n"
5958 "Route-map to modify the attributes\n"
5959 "Name of the route map\n"
5960 "Label index to associate with the prefix\n"
5961 "Label index value\n"
5962 "Specify a BGP backdoor route\n")
5963 {
5964 char addr_prefix_str[BUFSIZ];
5965
5966 if (address_str) {
5967 int ret;
5968
5969 ret = netmask_str2prefix_str(address_str, netmask_str,
5970 addr_prefix_str);
5971 if (!ret) {
5972 vty_out(vty, "%% Inconsistent address and mask\n");
5973 return CMD_WARNING_CONFIG_FAILED;
5974 }
5975 }
5976
5977 return bgp_static_set(
5978 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
5979 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
5980 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
5981 }
5982
5983 DEFPY(ipv6_bgp_network,
5984 ipv6_bgp_network_cmd,
5985 "[no] network X:X::X:X/M$prefix \
5986 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
5987 NO_STR
5988 "Specify a network to announce via BGP\n"
5989 "IPv6 prefix\n"
5990 "Route-map to modify the attributes\n"
5991 "Name of the route map\n"
5992 "Label index to associate with the prefix\n"
5993 "Label index value\n")
5994 {
5995 return bgp_static_set(
5996 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
5997 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
5998 }
5999
6000 static struct bgp_aggregate *bgp_aggregate_new(void)
6001 {
6002 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
6003 }
6004
6005 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
6006 {
6007 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
6008 route_map_counter_decrement(aggregate->rmap.map);
6009 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
6010 }
6011
6012 static int bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
6013 struct aspath *aspath,
6014 struct community *comm,
6015 struct ecommunity *ecomm,
6016 struct lcommunity *lcomm)
6017 {
6018 static struct aspath *ae = NULL;
6019
6020 if (!ae)
6021 ae = aspath_empty();
6022
6023 if (!pi)
6024 return 0;
6025
6026 if (origin != pi->attr->origin)
6027 return 0;
6028
6029 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
6030 return 0;
6031
6032 if (!community_cmp(pi->attr->community, comm))
6033 return 0;
6034
6035 if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
6036 return 0;
6037
6038 if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
6039 return 0;
6040
6041 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
6042 return 0;
6043
6044 return 1;
6045 }
6046
6047 static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
6048 struct prefix *p, uint8_t origin,
6049 struct aspath *aspath,
6050 struct community *community,
6051 struct ecommunity *ecommunity,
6052 struct lcommunity *lcommunity,
6053 uint8_t atomic_aggregate,
6054 struct bgp_aggregate *aggregate)
6055 {
6056 struct bgp_node *rn;
6057 struct bgp_table *table;
6058 struct bgp_path_info *pi, *orig, *new;
6059 struct attr *attr;
6060
6061 table = bgp->rib[afi][safi];
6062
6063 rn = bgp_node_get(table, p);
6064
6065 for (orig = pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
6066 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6067 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6068 break;
6069
6070 if (aggregate->count > 0) {
6071 /*
6072 * If the aggregate information has not changed
6073 * no need to re-install it again.
6074 */
6075 if (bgp_aggregate_info_same(orig, origin, aspath, community,
6076 ecommunity, lcommunity)) {
6077 bgp_unlock_node(rn);
6078
6079 if (aspath)
6080 aspath_free(aspath);
6081 if (community)
6082 community_free(&community);
6083 if (ecommunity)
6084 ecommunity_free(&ecommunity);
6085 if (lcommunity)
6086 lcommunity_free(&lcommunity);
6087
6088 return;
6089 }
6090
6091 /*
6092 * Mark the old as unusable
6093 */
6094 if (pi)
6095 bgp_path_info_delete(rn, pi);
6096
6097 attr = bgp_attr_aggregate_intern(
6098 bgp, origin, aspath, community, ecommunity, lcommunity,
6099 aggregate, atomic_aggregate, p);
6100
6101 if (!attr) {
6102 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
6103 return;
6104 }
6105
6106 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
6107 bgp->peer_self, attr, rn);
6108
6109 SET_FLAG(new->flags, BGP_PATH_VALID);
6110
6111 bgp_path_info_add(rn, new);
6112 bgp_process(bgp, rn, afi, safi);
6113 } else {
6114 for (pi = orig; pi; pi = pi->next)
6115 if (pi->peer == bgp->peer_self
6116 && pi->type == ZEBRA_ROUTE_BGP
6117 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6118 break;
6119
6120 /* Withdraw static BGP route from routing table. */
6121 if (pi) {
6122 bgp_path_info_delete(rn, pi);
6123 bgp_process(bgp, rn, afi, safi);
6124 }
6125 }
6126
6127 bgp_unlock_node(rn);
6128 }
6129
6130 /* Update an aggregate as routes are added/removed from the BGP table */
6131 void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
6132 afi_t afi, safi_t safi,
6133 struct bgp_aggregate *aggregate)
6134 {
6135 struct bgp_table *table;
6136 struct bgp_node *top;
6137 struct bgp_node *rn;
6138 uint8_t origin;
6139 struct aspath *aspath = NULL;
6140 struct community *community = NULL;
6141 struct ecommunity *ecommunity = NULL;
6142 struct lcommunity *lcommunity = NULL;
6143 struct bgp_path_info *pi;
6144 unsigned long match = 0;
6145 uint8_t atomic_aggregate = 0;
6146
6147 /* If the bgp instance is being deleted or self peer is deleted
6148 * then do not create aggregate route
6149 */
6150 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6151 || (bgp->peer_self == NULL))
6152 return;
6153
6154 /* ORIGIN attribute: If at least one route among routes that are
6155 aggregated has ORIGIN with the value INCOMPLETE, then the
6156 aggregated route must have the ORIGIN attribute with the value
6157 INCOMPLETE. Otherwise, if at least one route among routes that
6158 are aggregated has ORIGIN with the value EGP, then the aggregated
6159 route must have the origin attribute with the value EGP. In all
6160 other case the value of the ORIGIN attribute of the aggregated
6161 route is INTERNAL. */
6162 origin = BGP_ORIGIN_IGP;
6163
6164 table = bgp->rib[afi][safi];
6165
6166 top = bgp_node_get(table, p);
6167 for (rn = bgp_node_get(table, p); rn;
6168 rn = bgp_route_next_until(rn, top)) {
6169 if (rn->p.prefixlen <= p->prefixlen)
6170 continue;
6171
6172 match = 0;
6173
6174 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
6175 if (BGP_PATH_HOLDDOWN(pi))
6176 continue;
6177
6178 if (pi->attr->flag
6179 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
6180 atomic_aggregate = 1;
6181
6182 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6183 continue;
6184
6185 /*
6186 * summary-only aggregate route suppress
6187 * aggregated route announcements.
6188 */
6189 if (aggregate->summary_only) {
6190 (bgp_path_info_extra_get(pi))->suppress++;
6191 bgp_path_info_set_flag(rn, pi,
6192 BGP_PATH_ATTR_CHANGED);
6193 match++;
6194 }
6195
6196 aggregate->count++;
6197
6198 /*
6199 * If at least one route among routes that are
6200 * aggregated has ORIGIN with the value INCOMPLETE,
6201 * then the aggregated route MUST have the ORIGIN
6202 * attribute with the value INCOMPLETE. Otherwise, if
6203 * at least one route among routes that are aggregated
6204 * has ORIGIN with the value EGP, then the aggregated
6205 * route MUST have the ORIGIN attribute with the value
6206 * EGP.
6207 */
6208 switch (pi->attr->origin) {
6209 case BGP_ORIGIN_INCOMPLETE:
6210 aggregate->incomplete_origin_count++;
6211 break;
6212 case BGP_ORIGIN_EGP:
6213 aggregate->egp_origin_count++;
6214 break;
6215 default:
6216 /*Do nothing.
6217 */
6218 break;
6219 }
6220
6221 if (!aggregate->as_set)
6222 continue;
6223
6224 /*
6225 * as-set aggregate route generate origin, as path,
6226 * and community aggregation.
6227 */
6228 /* Compute aggregate route's as-path.
6229 */
6230 bgp_compute_aggregate_aspath_hash(aggregate,
6231 pi->attr->aspath);
6232
6233 /* Compute aggregate route's community.
6234 */
6235 if (pi->attr->community)
6236 bgp_compute_aggregate_community_hash(
6237 aggregate,
6238 pi->attr->community);
6239
6240 /* Compute aggregate route's extended community.
6241 */
6242 if (pi->attr->ecommunity)
6243 bgp_compute_aggregate_ecommunity_hash(
6244 aggregate,
6245 pi->attr->ecommunity);
6246
6247 /* Compute aggregate route's large community.
6248 */
6249 if (pi->attr->lcommunity)
6250 bgp_compute_aggregate_lcommunity_hash(
6251 aggregate,
6252 pi->attr->lcommunity);
6253 }
6254 if (match)
6255 bgp_process(bgp, rn, afi, safi);
6256 }
6257 if (aggregate->as_set) {
6258 bgp_compute_aggregate_aspath_val(aggregate);
6259 bgp_compute_aggregate_community_val(aggregate);
6260 bgp_compute_aggregate_ecommunity_val(aggregate);
6261 bgp_compute_aggregate_lcommunity_val(aggregate);
6262 }
6263
6264
6265 bgp_unlock_node(top);
6266
6267
6268 if (aggregate->incomplete_origin_count > 0)
6269 origin = BGP_ORIGIN_INCOMPLETE;
6270 else if (aggregate->egp_origin_count > 0)
6271 origin = BGP_ORIGIN_EGP;
6272
6273 if (aggregate->as_set) {
6274 if (aggregate->aspath)
6275 /* Retrieve aggregate route's as-path.
6276 */
6277 aspath = aspath_dup(aggregate->aspath);
6278
6279 if (aggregate->community)
6280 /* Retrieve aggregate route's community.
6281 */
6282 community = community_dup(aggregate->community);
6283
6284 if (aggregate->ecommunity)
6285 /* Retrieve aggregate route's ecommunity.
6286 */
6287 ecommunity = ecommunity_dup(aggregate->ecommunity);
6288
6289 if (aggregate->lcommunity)
6290 /* Retrieve aggregate route's lcommunity.
6291 */
6292 lcommunity = lcommunity_dup(aggregate->lcommunity);
6293 }
6294
6295 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
6296 ecommunity, lcommunity, atomic_aggregate,
6297 aggregate);
6298 }
6299
6300 void bgp_aggregate_delete(struct bgp *bgp, struct prefix *p, afi_t afi,
6301 safi_t safi, struct bgp_aggregate *aggregate)
6302 {
6303 struct bgp_table *table;
6304 struct bgp_node *top;
6305 struct bgp_node *rn;
6306 struct bgp_path_info *pi;
6307 unsigned long match;
6308
6309 table = bgp->rib[afi][safi];
6310
6311 /* If routes exists below this node, generate aggregate routes. */
6312 top = bgp_node_get(table, p);
6313 for (rn = bgp_node_get(table, p); rn;
6314 rn = bgp_route_next_until(rn, top)) {
6315 if (rn->p.prefixlen <= p->prefixlen)
6316 continue;
6317 match = 0;
6318
6319 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
6320 if (BGP_PATH_HOLDDOWN(pi))
6321 continue;
6322
6323 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6324 continue;
6325
6326 if (aggregate->summary_only && pi->extra) {
6327 pi->extra->suppress--;
6328
6329 if (pi->extra->suppress == 0) {
6330 bgp_path_info_set_flag(
6331 rn, pi, BGP_PATH_ATTR_CHANGED);
6332 match++;
6333 }
6334 }
6335 aggregate->count--;
6336
6337 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
6338 aggregate->incomplete_origin_count--;
6339 else if (pi->attr->origin == BGP_ORIGIN_EGP)
6340 aggregate->egp_origin_count--;
6341
6342 if (aggregate->as_set) {
6343 /* Remove as-path from aggregate.
6344 */
6345 bgp_remove_aspath_from_aggregate_hash(
6346 aggregate,
6347 pi->attr->aspath);
6348
6349 if (pi->attr->community)
6350 /* Remove community from aggregate.
6351 */
6352 bgp_remove_comm_from_aggregate_hash(
6353 aggregate,
6354 pi->attr->community);
6355
6356 if (pi->attr->ecommunity)
6357 /* Remove ecommunity from aggregate.
6358 */
6359 bgp_remove_ecomm_from_aggregate_hash(
6360 aggregate,
6361 pi->attr->ecommunity);
6362
6363 if (pi->attr->lcommunity)
6364 /* Remove lcommunity from aggregate.
6365 */
6366 bgp_remove_lcomm_from_aggregate_hash(
6367 aggregate,
6368 pi->attr->lcommunity);
6369 }
6370
6371 }
6372
6373 /* If this node was suppressed, process the change. */
6374 if (match)
6375 bgp_process(bgp, rn, afi, safi);
6376 }
6377 if (aggregate->as_set) {
6378 aspath_free(aggregate->aspath);
6379 aggregate->aspath = NULL;
6380 if (aggregate->community)
6381 community_free(&aggregate->community);
6382 if (aggregate->ecommunity)
6383 ecommunity_free(&aggregate->ecommunity);
6384 if (aggregate->lcommunity)
6385 lcommunity_free(&aggregate->lcommunity);
6386 }
6387
6388 bgp_unlock_node(top);
6389 }
6390
6391 static void bgp_add_route_to_aggregate(struct bgp *bgp, struct prefix *aggr_p,
6392 struct bgp_path_info *pinew, afi_t afi,
6393 safi_t safi,
6394 struct bgp_aggregate *aggregate)
6395 {
6396 uint8_t origin;
6397 struct aspath *aspath = NULL;
6398 uint8_t atomic_aggregate = 0;
6399 struct community *community = NULL;
6400 struct ecommunity *ecommunity = NULL;
6401 struct lcommunity *lcommunity = NULL;
6402
6403 /* ORIGIN attribute: If at least one route among routes that are
6404 * aggregated has ORIGIN with the value INCOMPLETE, then the
6405 * aggregated route must have the ORIGIN attribute with the value
6406 * INCOMPLETE. Otherwise, if at least one route among routes that
6407 * are aggregated has ORIGIN with the value EGP, then the aggregated
6408 * route must have the origin attribute with the value EGP. In all
6409 * other case the value of the ORIGIN attribute of the aggregated
6410 * route is INTERNAL.
6411 */
6412 origin = BGP_ORIGIN_IGP;
6413
6414 aggregate->count++;
6415
6416 if (aggregate->summary_only)
6417 (bgp_path_info_extra_get(pinew))->suppress++;
6418
6419 switch (pinew->attr->origin) {
6420 case BGP_ORIGIN_INCOMPLETE:
6421 aggregate->incomplete_origin_count++;
6422 break;
6423 case BGP_ORIGIN_EGP:
6424 aggregate->egp_origin_count++;
6425 break;
6426 default:
6427 /* Do nothing.
6428 */
6429 break;
6430 }
6431
6432 if (aggregate->incomplete_origin_count > 0)
6433 origin = BGP_ORIGIN_INCOMPLETE;
6434 else if (aggregate->egp_origin_count > 0)
6435 origin = BGP_ORIGIN_EGP;
6436
6437 if (aggregate->as_set) {
6438 /* Compute aggregate route's as-path.
6439 */
6440 bgp_compute_aggregate_aspath(aggregate,
6441 pinew->attr->aspath);
6442
6443 /* Compute aggregate route's community.
6444 */
6445 if (pinew->attr->community)
6446 bgp_compute_aggregate_community(
6447 aggregate,
6448 pinew->attr->community);
6449
6450 /* Compute aggregate route's extended community.
6451 */
6452 if (pinew->attr->ecommunity)
6453 bgp_compute_aggregate_ecommunity(
6454 aggregate,
6455 pinew->attr->ecommunity);
6456
6457 /* Compute aggregate route's large community.
6458 */
6459 if (pinew->attr->lcommunity)
6460 bgp_compute_aggregate_lcommunity(
6461 aggregate,
6462 pinew->attr->lcommunity);
6463
6464 /* Retrieve aggregate route's as-path.
6465 */
6466 if (aggregate->aspath)
6467 aspath = aspath_dup(aggregate->aspath);
6468
6469 /* Retrieve aggregate route's community.
6470 */
6471 if (aggregate->community)
6472 community = community_dup(aggregate->community);
6473
6474 /* Retrieve aggregate route's ecommunity.
6475 */
6476 if (aggregate->ecommunity)
6477 ecommunity = ecommunity_dup(aggregate->ecommunity);
6478
6479 /* Retrieve aggregate route's lcommunity.
6480 */
6481 if (aggregate->lcommunity)
6482 lcommunity = lcommunity_dup(aggregate->lcommunity);
6483 }
6484
6485 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
6486 aspath, community, ecommunity,
6487 lcommunity, atomic_aggregate, aggregate);
6488 }
6489
6490 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
6491 safi_t safi,
6492 struct bgp_path_info *pi,
6493 struct bgp_aggregate *aggregate,
6494 struct prefix *aggr_p)
6495 {
6496 uint8_t origin;
6497 struct aspath *aspath = NULL;
6498 uint8_t atomic_aggregate = 0;
6499 struct community *community = NULL;
6500 struct ecommunity *ecommunity = NULL;
6501 struct lcommunity *lcommunity = NULL;
6502 unsigned long match = 0;
6503
6504 if (BGP_PATH_HOLDDOWN(pi))
6505 return;
6506
6507 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6508 return;
6509
6510 if (aggregate->summary_only
6511 && pi->extra
6512 && pi->extra->suppress > 0) {
6513 pi->extra->suppress--;
6514
6515 if (pi->extra->suppress == 0) {
6516 bgp_path_info_set_flag(pi->net, pi,
6517 BGP_PATH_ATTR_CHANGED);
6518 match++;
6519 }
6520 }
6521
6522 if (aggregate->count > 0)
6523 aggregate->count--;
6524
6525 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
6526 aggregate->incomplete_origin_count--;
6527 else if (pi->attr->origin == BGP_ORIGIN_EGP)
6528 aggregate->egp_origin_count--;
6529
6530 if (aggregate->as_set) {
6531 /* Remove as-path from aggregate.
6532 */
6533 bgp_remove_aspath_from_aggregate(aggregate,
6534 pi->attr->aspath);
6535
6536 if (pi->attr->community)
6537 /* Remove community from aggregate.
6538 */
6539 bgp_remove_community_from_aggregate(
6540 aggregate,
6541 pi->attr->community);
6542
6543 if (pi->attr->ecommunity)
6544 /* Remove ecommunity from aggregate.
6545 */
6546 bgp_remove_ecommunity_from_aggregate(
6547 aggregate,
6548 pi->attr->ecommunity);
6549
6550 if (pi->attr->lcommunity)
6551 /* Remove lcommunity from aggregate.
6552 */
6553 bgp_remove_lcommunity_from_aggregate(
6554 aggregate,
6555 pi->attr->lcommunity);
6556 }
6557
6558 /* If this node was suppressed, process the change. */
6559 if (match)
6560 bgp_process(bgp, pi->net, afi, safi);
6561
6562 origin = BGP_ORIGIN_IGP;
6563 if (aggregate->incomplete_origin_count > 0)
6564 origin = BGP_ORIGIN_INCOMPLETE;
6565 else if (aggregate->egp_origin_count > 0)
6566 origin = BGP_ORIGIN_EGP;
6567
6568 if (aggregate->as_set) {
6569 /* Retrieve aggregate route's as-path.
6570 */
6571 if (aggregate->aspath)
6572 aspath = aspath_dup(aggregate->aspath);
6573
6574 /* Retrieve aggregate route's community.
6575 */
6576 if (aggregate->community)
6577 community = community_dup(aggregate->community);
6578
6579 /* Retrieve aggregate route's ecommunity.
6580 */
6581 if (aggregate->ecommunity)
6582 ecommunity = ecommunity_dup(aggregate->ecommunity);
6583
6584 /* Retrieve aggregate route's lcommunity.
6585 */
6586 if (aggregate->lcommunity)
6587 lcommunity = lcommunity_dup(aggregate->lcommunity);
6588 }
6589
6590 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
6591 aspath, community, ecommunity,
6592 lcommunity, atomic_aggregate, aggregate);
6593 }
6594
6595 void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p,
6596 struct bgp_path_info *pi, afi_t afi, safi_t safi)
6597 {
6598 struct bgp_node *child;
6599 struct bgp_node *rn;
6600 struct bgp_aggregate *aggregate;
6601 struct bgp_table *table;
6602
6603 table = bgp->aggregate[afi][safi];
6604
6605 /* No aggregates configured. */
6606 if (bgp_table_top_nolock(table) == NULL)
6607 return;
6608
6609 if (p->prefixlen == 0)
6610 return;
6611
6612 if (BGP_PATH_HOLDDOWN(pi))
6613 return;
6614
6615 child = bgp_node_get(table, p);
6616
6617 /* Aggregate address configuration check. */
6618 for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
6619 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6620 if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
6621 bgp_add_route_to_aggregate(bgp, &rn->p, pi, afi,
6622 safi, aggregate);
6623 }
6624 }
6625 bgp_unlock_node(child);
6626 }
6627
6628 void bgp_aggregate_decrement(struct bgp *bgp, struct prefix *p,
6629 struct bgp_path_info *del, afi_t afi, safi_t safi)
6630 {
6631 struct bgp_node *child;
6632 struct bgp_node *rn;
6633 struct bgp_aggregate *aggregate;
6634 struct bgp_table *table;
6635
6636 table = bgp->aggregate[afi][safi];
6637
6638 /* No aggregates configured. */
6639 if (bgp_table_top_nolock(table) == NULL)
6640 return;
6641
6642 if (p->prefixlen == 0)
6643 return;
6644
6645 child = bgp_node_get(table, p);
6646
6647 /* Aggregate address configuration check. */
6648 for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
6649 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6650 if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
6651 bgp_remove_route_from_aggregate(bgp, afi, safi,
6652 del, aggregate, &rn->p);
6653 }
6654 }
6655 bgp_unlock_node(child);
6656 }
6657
6658 /* Aggregate route attribute. */
6659 #define AGGREGATE_SUMMARY_ONLY 1
6660 #define AGGREGATE_AS_SET 1
6661 #define AGGREGATE_AS_UNSET 0
6662
6663 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
6664 afi_t afi, safi_t safi)
6665 {
6666 VTY_DECLVAR_CONTEXT(bgp, bgp);
6667 int ret;
6668 struct prefix p;
6669 struct bgp_node *rn;
6670 struct bgp_aggregate *aggregate;
6671
6672 /* Convert string to prefix structure. */
6673 ret = str2prefix(prefix_str, &p);
6674 if (!ret) {
6675 vty_out(vty, "Malformed prefix\n");
6676 return CMD_WARNING_CONFIG_FAILED;
6677 }
6678 apply_mask(&p);
6679
6680 /* Old configuration check. */
6681 rn = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
6682 if (!rn) {
6683 vty_out(vty,
6684 "%% There is no aggregate-address configuration.\n");
6685 return CMD_WARNING_CONFIG_FAILED;
6686 }
6687
6688 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6689 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
6690 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
6691 NULL, NULL, 0, aggregate);
6692
6693 /* Unlock aggregate address configuration. */
6694 bgp_node_set_bgp_aggregate_info(rn, NULL);
6695
6696 if (aggregate->community)
6697 community_free(&aggregate->community);
6698
6699 if (aggregate->community_hash) {
6700 /* Delete all communities in the hash.
6701 */
6702 hash_clean(aggregate->community_hash,
6703 bgp_aggr_community_remove);
6704 /* Free up the community_hash.
6705 */
6706 hash_free(aggregate->community_hash);
6707 }
6708
6709 if (aggregate->ecommunity)
6710 ecommunity_free(&aggregate->ecommunity);
6711
6712 if (aggregate->ecommunity_hash) {
6713 /* Delete all ecommunities in the hash.
6714 */
6715 hash_clean(aggregate->ecommunity_hash,
6716 bgp_aggr_ecommunity_remove);
6717 /* Free up the ecommunity_hash.
6718 */
6719 hash_free(aggregate->ecommunity_hash);
6720 }
6721
6722 if (aggregate->lcommunity)
6723 lcommunity_free(&aggregate->lcommunity);
6724
6725 if (aggregate->lcommunity_hash) {
6726 /* Delete all lcommunities in the hash.
6727 */
6728 hash_clean(aggregate->lcommunity_hash,
6729 bgp_aggr_lcommunity_remove);
6730 /* Free up the lcommunity_hash.
6731 */
6732 hash_free(aggregate->lcommunity_hash);
6733 }
6734
6735 if (aggregate->aspath)
6736 aspath_free(aggregate->aspath);
6737
6738 if (aggregate->aspath_hash) {
6739 /* Delete all as-paths in the hash.
6740 */
6741 hash_clean(aggregate->aspath_hash,
6742 bgp_aggr_aspath_remove);
6743 /* Free up the aspath_hash.
6744 */
6745 hash_free(aggregate->aspath_hash);
6746 }
6747
6748 bgp_aggregate_free(aggregate);
6749 bgp_unlock_node(rn);
6750 bgp_unlock_node(rn);
6751
6752 return CMD_SUCCESS;
6753 }
6754
6755 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
6756 safi_t safi, const char *rmap, uint8_t summary_only,
6757 uint8_t as_set)
6758 {
6759 VTY_DECLVAR_CONTEXT(bgp, bgp);
6760 int ret;
6761 struct prefix p;
6762 struct bgp_node *rn;
6763 struct bgp_aggregate *aggregate;
6764 uint8_t as_set_new = as_set;
6765
6766 /* Convert string to prefix structure. */
6767 ret = str2prefix(prefix_str, &p);
6768 if (!ret) {
6769 vty_out(vty, "Malformed prefix\n");
6770 return CMD_WARNING_CONFIG_FAILED;
6771 }
6772 apply_mask(&p);
6773
6774 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
6775 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
6776 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
6777 prefix_str);
6778 return CMD_WARNING_CONFIG_FAILED;
6779 }
6780
6781 /* Old configuration check. */
6782 rn = bgp_node_get(bgp->aggregate[afi][safi], &p);
6783 aggregate = bgp_node_get_bgp_aggregate_info(rn);
6784
6785 if (aggregate) {
6786 vty_out(vty, "There is already same aggregate network.\n");
6787 /* try to remove the old entry */
6788 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
6789 if (ret) {
6790 vty_out(vty, "Error deleting aggregate.\n");
6791 bgp_unlock_node(rn);
6792 return CMD_WARNING_CONFIG_FAILED;
6793 }
6794 }
6795
6796 /* Make aggregate address structure. */
6797 aggregate = bgp_aggregate_new();
6798 aggregate->summary_only = summary_only;
6799
6800 /* Network operators MUST NOT locally generate any new
6801 * announcements containing AS_SET or AS_CONFED_SET. If they have
6802 * announced routes with AS_SET or AS_CONFED_SET in them, then they
6803 * SHOULD withdraw those routes and re-announce routes for the
6804 * aggregate or component prefixes (i.e., the more-specific routes
6805 * subsumed by the previously aggregated route) without AS_SET
6806 * or AS_CONFED_SET in the updates.
6807 */
6808 if (bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED) {
6809 if (as_set == AGGREGATE_AS_SET) {
6810 as_set_new = AGGREGATE_AS_UNSET;
6811 zlog_warn(
6812 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.\n",
6813 __func__);
6814 vty_out(vty,
6815 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
6816 }
6817 }
6818
6819 aggregate->as_set = as_set_new;
6820 aggregate->safi = safi;
6821
6822 if (rmap) {
6823 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
6824 route_map_counter_decrement(aggregate->rmap.map);
6825 aggregate->rmap.name =
6826 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6827 aggregate->rmap.map = route_map_lookup_by_name(rmap);
6828 route_map_counter_increment(aggregate->rmap.map);
6829 }
6830 bgp_node_set_bgp_aggregate_info(rn, aggregate);
6831
6832 /* Aggregate address insert into BGP routing table. */
6833 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
6834
6835 return CMD_SUCCESS;
6836 }
6837
6838 DEFUN (aggregate_address,
6839 aggregate_address_cmd,
6840 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6841 "Configure BGP aggregate entries\n"
6842 "Aggregate prefix\n"
6843 "Generate AS set path information\n"
6844 "Filter more specific routes from updates\n"
6845 "Filter more specific routes from updates\n"
6846 "Generate AS set path information\n"
6847 "Apply route map to aggregate network\n"
6848 "Name of route map\n")
6849 {
6850 int idx = 0;
6851 argv_find(argv, argc, "A.B.C.D/M", &idx);
6852 char *prefix = argv[idx]->arg;
6853 char *rmap = NULL;
6854 int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
6855 : AGGREGATE_AS_UNSET;
6856 idx = 0;
6857 int summary_only = argv_find(argv, argc, "summary-only", &idx)
6858 ? AGGREGATE_SUMMARY_ONLY
6859 : 0;
6860
6861 idx = 0;
6862 argv_find(argv, argc, "WORD", &idx);
6863 if (idx)
6864 rmap = argv[idx]->arg;
6865
6866 return bgp_aggregate_set(vty, prefix, AFI_IP, bgp_node_safi(vty),
6867 rmap, summary_only, as_set);
6868 }
6869
6870 DEFUN (aggregate_address_mask,
6871 aggregate_address_mask_cmd,
6872 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6873 "Configure BGP aggregate entries\n"
6874 "Aggregate address\n"
6875 "Aggregate mask\n"
6876 "Generate AS set path information\n"
6877 "Filter more specific routes from updates\n"
6878 "Filter more specific routes from updates\n"
6879 "Generate AS set path information\n"
6880 "Apply route map to aggregate network\n"
6881 "Name of route map\n")
6882 {
6883 int idx = 0;
6884 argv_find(argv, argc, "A.B.C.D", &idx);
6885 char *prefix = argv[idx]->arg;
6886 char *mask = argv[idx + 1]->arg;
6887 bool rmap_found;
6888 char *rmap = NULL;
6889 int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
6890 : AGGREGATE_AS_UNSET;
6891 idx = 0;
6892 int summary_only = argv_find(argv, argc, "summary-only", &idx)
6893 ? AGGREGATE_SUMMARY_ONLY
6894 : 0;
6895
6896 rmap_found = argv_find(argv, argc, "WORD", &idx);
6897 if (rmap_found)
6898 rmap = argv[idx]->arg;
6899
6900 char prefix_str[BUFSIZ];
6901 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
6902
6903 if (!ret) {
6904 vty_out(vty, "%% Inconsistent address and mask\n");
6905 return CMD_WARNING_CONFIG_FAILED;
6906 }
6907
6908 return bgp_aggregate_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty),
6909 rmap, summary_only, as_set);
6910 }
6911
6912 DEFUN (no_aggregate_address,
6913 no_aggregate_address_cmd,
6914 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6915 NO_STR
6916 "Configure BGP aggregate entries\n"
6917 "Aggregate prefix\n"
6918 "Generate AS set path information\n"
6919 "Filter more specific routes from updates\n"
6920 "Filter more specific routes from updates\n"
6921 "Generate AS set path information\n"
6922 "Apply route map to aggregate network\n"
6923 "Name of route map\n")
6924 {
6925 int idx = 0;
6926 argv_find(argv, argc, "A.B.C.D/M", &idx);
6927 char *prefix = argv[idx]->arg;
6928 return bgp_aggregate_unset(vty, prefix, AFI_IP, bgp_node_safi(vty));
6929 }
6930
6931 DEFUN (no_aggregate_address_mask,
6932 no_aggregate_address_mask_cmd,
6933 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6934 NO_STR
6935 "Configure BGP aggregate entries\n"
6936 "Aggregate address\n"
6937 "Aggregate mask\n"
6938 "Generate AS set path information\n"
6939 "Filter more specific routes from updates\n"
6940 "Filter more specific routes from updates\n"
6941 "Generate AS set path information\n"
6942 "Apply route map to aggregate network\n"
6943 "Name of route map\n")
6944 {
6945 int idx = 0;
6946 argv_find(argv, argc, "A.B.C.D", &idx);
6947 char *prefix = argv[idx]->arg;
6948 char *mask = argv[idx + 1]->arg;
6949
6950 char prefix_str[BUFSIZ];
6951 int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
6952
6953 if (!ret) {
6954 vty_out(vty, "%% Inconsistent address and mask\n");
6955 return CMD_WARNING_CONFIG_FAILED;
6956 }
6957
6958 return bgp_aggregate_unset(vty, prefix_str, AFI_IP, bgp_node_safi(vty));
6959 }
6960
6961 DEFUN (ipv6_aggregate_address,
6962 ipv6_aggregate_address_cmd,
6963 "aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6964 "Configure BGP aggregate entries\n"
6965 "Aggregate prefix\n"
6966 "Generate AS set path information\n"
6967 "Filter more specific routes from updates\n"
6968 "Filter more specific routes from updates\n"
6969 "Generate AS set path information\n"
6970 "Apply route map to aggregate network\n"
6971 "Name of route map\n")
6972 {
6973 int idx = 0;
6974 argv_find(argv, argc, "X:X::X:X/M", &idx);
6975 char *prefix = argv[idx]->arg;
6976 char *rmap = NULL;
6977 bool rmap_found;
6978 int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
6979 : AGGREGATE_AS_UNSET;
6980
6981 idx = 0;
6982 int sum_only = argv_find(argv, argc, "summary-only", &idx)
6983 ? AGGREGATE_SUMMARY_ONLY
6984 : 0;
6985
6986 rmap_found = argv_find(argv, argc, "WORD", &idx);
6987 if (rmap_found)
6988 rmap = argv[idx]->arg;
6989
6990 return bgp_aggregate_set(vty, prefix, AFI_IP6, SAFI_UNICAST, rmap,
6991 sum_only, as_set);
6992 }
6993
6994 DEFUN (no_ipv6_aggregate_address,
6995 no_ipv6_aggregate_address_cmd,
6996 "no aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD]",
6997 NO_STR
6998 "Configure BGP aggregate entries\n"
6999 "Aggregate prefix\n"
7000 "Generate AS set path information\n"
7001 "Filter more specific routes from updates\n"
7002 "Filter more specific routes from updates\n"
7003 "Generate AS set path information\n"
7004 "Apply route map to aggregate network\n"
7005 "Name of route map\n")
7006 {
7007 int idx = 0;
7008 argv_find(argv, argc, "X:X::X:X/M", &idx);
7009 char *prefix = argv[idx]->arg;
7010 return bgp_aggregate_unset(vty, prefix, AFI_IP6, SAFI_UNICAST);
7011 }
7012
7013 /* Redistribute route treatment. */
7014 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
7015 const union g_addr *nexthop, ifindex_t ifindex,
7016 enum nexthop_types_t nhtype, uint32_t metric,
7017 uint8_t type, unsigned short instance,
7018 route_tag_t tag)
7019 {
7020 struct bgp_path_info *new;
7021 struct bgp_path_info *bpi;
7022 struct bgp_path_info rmap_path;
7023 struct bgp_node *bn;
7024 struct attr attr;
7025 struct attr *new_attr;
7026 afi_t afi;
7027 route_map_result_t ret;
7028 struct bgp_redist *red;
7029
7030 /* Make default attribute. */
7031 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
7032 /*
7033 * This must not be NULL to satisfy Coverity SA
7034 */
7035 assert(attr.aspath);
7036
7037 switch (nhtype) {
7038 case NEXTHOP_TYPE_IFINDEX:
7039 break;
7040 case NEXTHOP_TYPE_IPV4:
7041 case NEXTHOP_TYPE_IPV4_IFINDEX:
7042 attr.nexthop = nexthop->ipv4;
7043 break;
7044 case NEXTHOP_TYPE_IPV6:
7045 case NEXTHOP_TYPE_IPV6_IFINDEX:
7046 attr.mp_nexthop_global = nexthop->ipv6;
7047 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
7048 break;
7049 case NEXTHOP_TYPE_BLACKHOLE:
7050 switch (p->family) {
7051 case AF_INET:
7052 attr.nexthop.s_addr = INADDR_ANY;
7053 break;
7054 case AF_INET6:
7055 memset(&attr.mp_nexthop_global, 0,
7056 sizeof(attr.mp_nexthop_global));
7057 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
7058 break;
7059 }
7060 break;
7061 }
7062 attr.nh_ifindex = ifindex;
7063
7064 attr.med = metric;
7065 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
7066 attr.tag = tag;
7067
7068 afi = family2afi(p->family);
7069
7070 red = bgp_redist_lookup(bgp, afi, type, instance);
7071 if (red) {
7072 struct attr attr_new;
7073
7074 /* Copy attribute for modification. */
7075 attr_new = attr;
7076
7077 if (red->redist_metric_flag)
7078 attr_new.med = red->redist_metric;
7079
7080 /* Apply route-map. */
7081 if (red->rmap.name) {
7082 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
7083 rmap_path.peer = bgp->peer_self;
7084 rmap_path.attr = &attr_new;
7085
7086 SET_FLAG(bgp->peer_self->rmap_type,
7087 PEER_RMAP_TYPE_REDISTRIBUTE);
7088
7089 ret = route_map_apply(red->rmap.map, p, RMAP_BGP,
7090 &rmap_path);
7091
7092 bgp->peer_self->rmap_type = 0;
7093
7094 if (ret == RMAP_DENYMATCH) {
7095 /* Free uninterned attribute. */
7096 bgp_attr_flush(&attr_new);
7097
7098 /* Unintern original. */
7099 aspath_unintern(&attr.aspath);
7100 bgp_redistribute_delete(bgp, p, type, instance);
7101 return;
7102 }
7103 }
7104
7105 if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN))
7106 bgp_attr_add_gshut_community(&attr_new);
7107
7108 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
7109 SAFI_UNICAST, p, NULL);
7110
7111 new_attr = bgp_attr_intern(&attr_new);
7112
7113 for (bpi = bgp_node_get_bgp_path_info(bn); bpi;
7114 bpi = bpi->next)
7115 if (bpi->peer == bgp->peer_self
7116 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
7117 break;
7118
7119 if (bpi) {
7120 /* Ensure the (source route) type is updated. */
7121 bpi->type = type;
7122 if (attrhash_cmp(bpi->attr, new_attr)
7123 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
7124 bgp_attr_unintern(&new_attr);
7125 aspath_unintern(&attr.aspath);
7126 bgp_unlock_node(bn);
7127 return;
7128 } else {
7129 /* The attribute is changed. */
7130 bgp_path_info_set_flag(bn, bpi,
7131 BGP_PATH_ATTR_CHANGED);
7132
7133 /* Rewrite BGP route information. */
7134 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
7135 bgp_path_info_restore(bn, bpi);
7136 else
7137 bgp_aggregate_decrement(
7138 bgp, p, bpi, afi, SAFI_UNICAST);
7139 bgp_attr_unintern(&bpi->attr);
7140 bpi->attr = new_attr;
7141 bpi->uptime = bgp_clock();
7142
7143 /* Process change. */
7144 bgp_aggregate_increment(bgp, p, bpi, afi,
7145 SAFI_UNICAST);
7146 bgp_process(bgp, bn, afi, SAFI_UNICAST);
7147 bgp_unlock_node(bn);
7148 aspath_unintern(&attr.aspath);
7149
7150 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7151 || (bgp->inst_type
7152 == BGP_INSTANCE_TYPE_DEFAULT)) {
7153
7154 vpn_leak_from_vrf_update(
7155 bgp_get_default(), bgp, bpi);
7156 }
7157 return;
7158 }
7159 }
7160
7161 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
7162 bgp->peer_self, new_attr, bn);
7163 SET_FLAG(new->flags, BGP_PATH_VALID);
7164
7165 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
7166 bgp_path_info_add(bn, new);
7167 bgp_unlock_node(bn);
7168 bgp_process(bgp, bn, afi, SAFI_UNICAST);
7169
7170 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7171 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
7172
7173 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
7174 }
7175 }
7176
7177 /* Unintern original. */
7178 aspath_unintern(&attr.aspath);
7179 }
7180
7181 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
7182 unsigned short instance)
7183 {
7184 afi_t afi;
7185 struct bgp_node *rn;
7186 struct bgp_path_info *pi;
7187 struct bgp_redist *red;
7188
7189 afi = family2afi(p->family);
7190
7191 red = bgp_redist_lookup(bgp, afi, type, instance);
7192 if (red) {
7193 rn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
7194 SAFI_UNICAST, p, NULL);
7195
7196 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
7197 if (pi->peer == bgp->peer_self && pi->type == type)
7198 break;
7199
7200 if (pi) {
7201 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7202 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
7203
7204 vpn_leak_from_vrf_withdraw(bgp_get_default(),
7205 bgp, pi);
7206 }
7207 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
7208 bgp_path_info_delete(rn, pi);
7209 bgp_process(bgp, rn, afi, SAFI_UNICAST);
7210 }
7211 bgp_unlock_node(rn);
7212 }
7213 }
7214
7215 /* Withdraw specified route type's route. */
7216 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
7217 unsigned short instance)
7218 {
7219 struct bgp_node *rn;
7220 struct bgp_path_info *pi;
7221 struct bgp_table *table;
7222
7223 table = bgp->rib[afi][SAFI_UNICAST];
7224
7225 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
7226 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
7227 if (pi->peer == bgp->peer_self && pi->type == type
7228 && pi->instance == instance)
7229 break;
7230
7231 if (pi) {
7232 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
7233 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
7234
7235 vpn_leak_from_vrf_withdraw(bgp_get_default(),
7236 bgp, pi);
7237 }
7238 bgp_aggregate_decrement(bgp, &rn->p, pi, afi,
7239 SAFI_UNICAST);
7240 bgp_path_info_delete(rn, pi);
7241 bgp_process(bgp, rn, afi, SAFI_UNICAST);
7242 }
7243 }
7244 }
7245
7246 /* Static function to display route. */
7247 static void route_vty_out_route(struct prefix *p, struct vty *vty,
7248 json_object *json)
7249 {
7250 int len = 0;
7251 char buf[BUFSIZ];
7252 char buf2[BUFSIZ];
7253
7254 if (p->family == AF_INET) {
7255 if (!json) {
7256 len = vty_out(
7257 vty, "%s/%d",
7258 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
7259 p->prefixlen);
7260 } else {
7261 json_object_string_add(json, "prefix",
7262 inet_ntop(p->family,
7263 &p->u.prefix, buf,
7264 BUFSIZ));
7265 json_object_int_add(json, "prefixLen", p->prefixlen);
7266 prefix2str(p, buf2, PREFIX_STRLEN);
7267 json_object_string_add(json, "network", buf2);
7268 }
7269 } else if (p->family == AF_ETHERNET) {
7270 prefix2str(p, buf, PREFIX_STRLEN);
7271 len = vty_out(vty, "%s", buf);
7272 } else if (p->family == AF_EVPN) {
7273 if (!json)
7274 len = vty_out(
7275 vty, "%s",
7276 bgp_evpn_route2str((struct prefix_evpn *)p, buf,
7277 BUFSIZ));
7278 else
7279 bgp_evpn_route2json((struct prefix_evpn *)p, json);
7280 } else if (p->family == AF_FLOWSPEC) {
7281 route_vty_out_flowspec(vty, p, NULL,
7282 json ?
7283 NLRI_STRING_FORMAT_JSON_SIMPLE :
7284 NLRI_STRING_FORMAT_MIN, json);
7285 } else {
7286 if (!json)
7287 len = vty_out(
7288 vty, "%s/%d",
7289 inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
7290 p->prefixlen);
7291 else {
7292 json_object_string_add(json, "prefix",
7293 inet_ntop(p->family,
7294 &p->u.prefix, buf,
7295 BUFSIZ));
7296 json_object_int_add(json, "prefixLen", p->prefixlen);
7297 prefix2str(p, buf2, PREFIX_STRLEN);
7298 json_object_string_add(json, "network", buf2);
7299 }
7300 }
7301
7302 if (!json) {
7303 len = 17 - len;
7304 if (len < 1)
7305 vty_out(vty, "\n%*s", 20, " ");
7306 else
7307 vty_out(vty, "%*s", len, " ");
7308 }
7309 }
7310
7311 enum bgp_display_type {
7312 normal_list,
7313 };
7314
7315 /* Print the short form route status for a bgp_path_info */
7316 static void route_vty_short_status_out(struct vty *vty,
7317 struct bgp_path_info *path,
7318 json_object *json_path)
7319 {
7320 if (json_path) {
7321
7322 /* Route status display. */
7323 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
7324 json_object_boolean_true_add(json_path, "removed");
7325
7326 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
7327 json_object_boolean_true_add(json_path, "stale");
7328
7329 if (path->extra && path->extra->suppress)
7330 json_object_boolean_true_add(json_path, "suppressed");
7331
7332 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
7333 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7334 json_object_boolean_true_add(json_path, "valid");
7335
7336 /* Selected */
7337 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7338 json_object_boolean_true_add(json_path, "history");
7339
7340 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
7341 json_object_boolean_true_add(json_path, "damped");
7342
7343 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
7344 json_object_boolean_true_add(json_path, "bestpath");
7345
7346 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
7347 json_object_boolean_true_add(json_path, "multipath");
7348
7349 /* Internal route. */
7350 if ((path->peer->as)
7351 && (path->peer->as == path->peer->local_as))
7352 json_object_string_add(json_path, "pathFrom",
7353 "internal");
7354 else
7355 json_object_string_add(json_path, "pathFrom",
7356 "external");
7357
7358 return;
7359 }
7360
7361 /* Route status display. */
7362 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
7363 vty_out(vty, "R");
7364 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
7365 vty_out(vty, "S");
7366 else if (path->extra && path->extra->suppress)
7367 vty_out(vty, "s");
7368 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
7369 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7370 vty_out(vty, "*");
7371 else
7372 vty_out(vty, " ");
7373
7374 /* Selected */
7375 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
7376 vty_out(vty, "h");
7377 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
7378 vty_out(vty, "d");
7379 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
7380 vty_out(vty, ">");
7381 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
7382 vty_out(vty, "=");
7383 else
7384 vty_out(vty, " ");
7385
7386 /* Internal route. */
7387 if (path->peer && (path->peer->as)
7388 && (path->peer->as == path->peer->local_as))
7389 vty_out(vty, "i");
7390 else
7391 vty_out(vty, " ");
7392 }
7393
7394 static char *bgp_nexthop_hostname(struct peer *peer, struct attr *attr)
7395 {
7396 if (peer->hostname
7397 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)
7398 && !(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))
7399 return peer->hostname;
7400 return NULL;
7401 }
7402
7403 /* called from terminal list command */
7404 void route_vty_out(struct vty *vty, struct prefix *p,
7405 struct bgp_path_info *path, int display, safi_t safi,
7406 json_object *json_paths)
7407 {
7408 struct attr *attr = path->attr;
7409 json_object *json_path = NULL;
7410 json_object *json_nexthops = NULL;
7411 json_object *json_nexthop_global = NULL;
7412 json_object *json_nexthop_ll = NULL;
7413 json_object *json_ext_community = NULL;
7414 char vrf_id_str[VRF_NAMSIZ] = {0};
7415 bool nexthop_self =
7416 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
7417 bool nexthop_othervrf = false;
7418 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
7419 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
7420 char *nexthop_hostname = bgp_nexthop_hostname(path->peer, attr);
7421
7422 if (json_paths)
7423 json_path = json_object_new_object();
7424
7425 /* short status lead text */
7426 route_vty_short_status_out(vty, path, json_path);
7427
7428 if (!json_paths) {
7429 /* print prefix and mask */
7430 if (!display)
7431 route_vty_out_route(p, vty, json_path);
7432 else
7433 vty_out(vty, "%*s", 17, " ");
7434 } else {
7435 route_vty_out_route(p, vty, json_path);
7436 }
7437
7438 /*
7439 * If vrf id of nexthop is different from that of prefix,
7440 * set up printable string to append
7441 */
7442 if (path->extra && path->extra->bgp_orig) {
7443 const char *self = "";
7444
7445 if (nexthop_self)
7446 self = "<";
7447
7448 nexthop_othervrf = true;
7449 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
7450
7451 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
7452 snprintf(vrf_id_str, sizeof(vrf_id_str),
7453 "@%s%s", VRFID_NONE_STR, self);
7454 else
7455 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
7456 path->extra->bgp_orig->vrf_id, self);
7457
7458 if (path->extra->bgp_orig->inst_type
7459 != BGP_INSTANCE_TYPE_DEFAULT)
7460
7461 nexthop_vrfname = path->extra->bgp_orig->name;
7462 } else {
7463 const char *self = "";
7464
7465 if (nexthop_self)
7466 self = "<";
7467
7468 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
7469 }
7470
7471 /*
7472 * For ENCAP and EVPN routes, nexthop address family is not
7473 * neccessarily the same as the prefix address family.
7474 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
7475 * EVPN routes are also exchanged with a MP nexthop. Currently,
7476 * this
7477 * is only IPv4, the value will be present in either
7478 * attr->nexthop or
7479 * attr->mp_nexthop_global_in
7480 */
7481 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
7482 char buf[BUFSIZ];
7483 char nexthop[128];
7484 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
7485
7486 switch (af) {
7487 case AF_INET:
7488 sprintf(nexthop, "%s",
7489 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
7490 BUFSIZ));
7491 break;
7492 case AF_INET6:
7493 sprintf(nexthop, "%s",
7494 inet_ntop(af, &attr->mp_nexthop_global, buf,
7495 BUFSIZ));
7496 break;
7497 default:
7498 sprintf(nexthop, "?");
7499 break;
7500 }
7501
7502 if (json_paths) {
7503 json_nexthop_global = json_object_new_object();
7504
7505 json_object_string_add(json_nexthop_global, "ip",
7506 nexthop);
7507
7508 if (nexthop_hostname)
7509 json_object_string_add(json_nexthop_global,
7510 "hostname",
7511 nexthop_hostname);
7512
7513 json_object_string_add(json_nexthop_global, "afi",
7514 (af == AF_INET) ? "ipv4"
7515 : "ipv6");
7516 json_object_boolean_true_add(json_nexthop_global,
7517 "used");
7518 } else
7519 vty_out(vty, "%s%s",
7520 nexthop_hostname ? nexthop_hostname : nexthop,
7521 vrf_id_str);
7522 } else if (safi == SAFI_EVPN) {
7523 if (json_paths) {
7524 json_nexthop_global = json_object_new_object();
7525
7526 json_object_string_add(json_nexthop_global, "ip",
7527 inet_ntoa(attr->nexthop));
7528
7529 if (nexthop_hostname)
7530 json_object_string_add(json_nexthop_global,
7531 "hostname",
7532 nexthop_hostname);
7533
7534 json_object_string_add(json_nexthop_global, "afi",
7535 "ipv4");
7536 json_object_boolean_true_add(json_nexthop_global,
7537 "used");
7538 } else
7539 vty_out(vty, "%-16s%s",
7540 nexthop_hostname ? nexthop_hostname
7541 : inet_ntoa(attr->nexthop),
7542 vrf_id_str);
7543 } else if (safi == SAFI_FLOWSPEC) {
7544 if (attr->nexthop.s_addr != INADDR_ANY) {
7545 if (json_paths) {
7546 json_nexthop_global = json_object_new_object();
7547
7548 json_object_string_add(json_nexthop_global,
7549 "afi", "ipv4");
7550 json_object_string_add(
7551 json_nexthop_global, "ip",
7552 inet_ntoa(attr->nexthop));
7553
7554 if (nexthop_hostname)
7555 json_object_string_add(
7556 json_nexthop_global, "hostname",
7557 nexthop_hostname);
7558
7559 json_object_boolean_true_add(
7560 json_nexthop_global,
7561 "used");
7562 } else {
7563 vty_out(vty, "%-16s",
7564 nexthop_hostname
7565 ? nexthop_hostname
7566 : inet_ntoa(attr->nexthop));
7567 }
7568 }
7569 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7570 if (json_paths) {
7571 json_nexthop_global = json_object_new_object();
7572
7573 json_object_string_add(json_nexthop_global, "ip",
7574 inet_ntoa(attr->nexthop));
7575
7576 if (nexthop_hostname)
7577 json_object_string_add(json_nexthop_global,
7578 "hostname",
7579 nexthop_hostname);
7580
7581 json_object_string_add(json_nexthop_global, "afi",
7582 "ipv4");
7583 json_object_boolean_true_add(json_nexthop_global,
7584 "used");
7585 } else {
7586 char buf[BUFSIZ];
7587
7588 snprintf(buf, sizeof(buf), "%s%s",
7589 nexthop_hostname ? nexthop_hostname
7590 : inet_ntoa(attr->nexthop),
7591 vrf_id_str);
7592 vty_out(vty, "%-16s", buf);
7593 }
7594 }
7595
7596 /* IPv6 Next Hop */
7597 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7598 int len;
7599 char buf[BUFSIZ];
7600
7601 if (json_paths) {
7602 json_nexthop_global = json_object_new_object();
7603 json_object_string_add(
7604 json_nexthop_global, "ip",
7605 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
7606 buf, BUFSIZ));
7607
7608 if (nexthop_hostname)
7609 json_object_string_add(json_nexthop_global,
7610 "hostname",
7611 nexthop_hostname);
7612
7613 json_object_string_add(json_nexthop_global, "afi",
7614 "ipv6");
7615 json_object_string_add(json_nexthop_global, "scope",
7616 "global");
7617
7618 /* We display both LL & GL if both have been
7619 * received */
7620 if ((attr->mp_nexthop_len
7621 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
7622 || (path->peer->conf_if)) {
7623 json_nexthop_ll = json_object_new_object();
7624 json_object_string_add(
7625 json_nexthop_ll, "ip",
7626 inet_ntop(AF_INET6,
7627 &attr->mp_nexthop_local, buf,
7628 BUFSIZ));
7629
7630 if (nexthop_hostname)
7631 json_object_string_add(
7632 json_nexthop_ll, "hostname",
7633 nexthop_hostname);
7634
7635 json_object_string_add(json_nexthop_ll, "afi",
7636 "ipv6");
7637 json_object_string_add(json_nexthop_ll, "scope",
7638 "link-local");
7639
7640 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
7641 &attr->mp_nexthop_local)
7642 != 0)
7643 && !attr->mp_nexthop_prefer_global)
7644 json_object_boolean_true_add(
7645 json_nexthop_ll, "used");
7646 else
7647 json_object_boolean_true_add(
7648 json_nexthop_global, "used");
7649 } else
7650 json_object_boolean_true_add(
7651 json_nexthop_global, "used");
7652 } else {
7653 /* Display LL if LL/Global both in table unless
7654 * prefer-global is set */
7655 if (((attr->mp_nexthop_len
7656 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
7657 && !attr->mp_nexthop_prefer_global)
7658 || (path->peer->conf_if)) {
7659 if (path->peer->conf_if) {
7660 len = vty_out(vty, "%s",
7661 path->peer->conf_if);
7662 len = 16 - len; /* len of IPv6
7663 addr + max
7664 len of def
7665 ifname */
7666
7667 if (len < 1)
7668 vty_out(vty, "\n%*s", 36, " ");
7669 else
7670 vty_out(vty, "%*s", len, " ");
7671 } else {
7672 len = vty_out(
7673 vty, "%s%s",
7674 nexthop_hostname
7675 ? nexthop_hostname
7676 : inet_ntop(
7677 AF_INET6,
7678 &attr->mp_nexthop_local,
7679 buf, BUFSIZ),
7680 vrf_id_str);
7681 len = 16 - len;
7682
7683 if (len < 1)
7684 vty_out(vty, "\n%*s", 36, " ");
7685 else
7686 vty_out(vty, "%*s", len, " ");
7687 }
7688 } else {
7689 len = vty_out(
7690 vty, "%s%s",
7691 nexthop_hostname
7692 ? nexthop_hostname
7693 : inet_ntop(
7694 AF_INET6,
7695 &attr->mp_nexthop_global,
7696 buf, BUFSIZ),
7697 vrf_id_str);
7698 len = 16 - len;
7699
7700 if (len < 1)
7701 vty_out(vty, "\n%*s", 36, " ");
7702 else
7703 vty_out(vty, "%*s", len, " ");
7704 }
7705 }
7706 }
7707
7708 /* MED/Metric */
7709 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7710 if (json_paths) {
7711
7712 /*
7713 * Adding "metric" field to match with corresponding
7714 * CLI. "med" will be deprecated in future.
7715 */
7716 json_object_int_add(json_path, "med", attr->med);
7717 json_object_int_add(json_path, "metric", attr->med);
7718 } else
7719 vty_out(vty, "%10u", attr->med);
7720 else if (!json_paths)
7721 vty_out(vty, " ");
7722
7723 /* Local Pref */
7724 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
7725 if (json_paths) {
7726
7727 /*
7728 * Adding "locPrf" field to match with corresponding
7729 * CLI. "localPref" will be deprecated in future.
7730 */
7731 json_object_int_add(json_path, "localpref",
7732 attr->local_pref);
7733 json_object_int_add(json_path, "locPrf",
7734 attr->local_pref);
7735 } else
7736 vty_out(vty, "%7u", attr->local_pref);
7737 else if (!json_paths)
7738 vty_out(vty, " ");
7739
7740 if (json_paths)
7741 json_object_int_add(json_path, "weight", attr->weight);
7742 else
7743 vty_out(vty, "%7u ", attr->weight);
7744
7745 if (json_paths) {
7746 char buf[BUFSIZ];
7747 json_object_string_add(
7748 json_path, "peerId",
7749 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
7750 }
7751
7752 /* Print aspath */
7753 if (attr->aspath) {
7754 if (json_paths) {
7755
7756 /*
7757 * Adding "path" field to match with corresponding
7758 * CLI. "aspath" will be deprecated in future.
7759 */
7760 json_object_string_add(json_path, "aspath",
7761 attr->aspath->str);
7762 json_object_string_add(json_path, "path",
7763 attr->aspath->str);
7764 } else
7765 aspath_print_vty(vty, "%s", attr->aspath, " ");
7766 }
7767
7768 /* Print origin */
7769 if (json_paths)
7770 json_object_string_add(json_path, "origin",
7771 bgp_origin_long_str[attr->origin]);
7772 else
7773 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7774
7775 if (json_paths) {
7776 if (safi == SAFI_EVPN &&
7777 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
7778 json_ext_community = json_object_new_object();
7779 json_object_string_add(json_ext_community,
7780 "string",
7781 attr->ecommunity->str);
7782 json_object_object_add(json_path,
7783 "extendedCommunity",
7784 json_ext_community);
7785 }
7786
7787 if (nexthop_self)
7788 json_object_boolean_true_add(json_path,
7789 "announceNexthopSelf");
7790 if (nexthop_othervrf) {
7791 json_object_string_add(json_path, "nhVrfName",
7792 nexthop_vrfname);
7793
7794 json_object_int_add(json_path, "nhVrfId",
7795 ((nexthop_vrfid == VRF_UNKNOWN)
7796 ? -1
7797 : (int)nexthop_vrfid));
7798 }
7799 }
7800
7801 if (json_paths) {
7802 if (json_nexthop_global || json_nexthop_ll) {
7803 json_nexthops = json_object_new_array();
7804
7805 if (json_nexthop_global)
7806 json_object_array_add(json_nexthops,
7807 json_nexthop_global);
7808
7809 if (json_nexthop_ll)
7810 json_object_array_add(json_nexthops,
7811 json_nexthop_ll);
7812
7813 json_object_object_add(json_path, "nexthops",
7814 json_nexthops);
7815 }
7816
7817 json_object_array_add(json_paths, json_path);
7818 } else {
7819 vty_out(vty, "\n");
7820
7821 if (safi == SAFI_EVPN &&
7822 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
7823 vty_out(vty, "%*s", 20, " ");
7824 vty_out(vty, "%s\n", attr->ecommunity->str);
7825 }
7826
7827 #if ENABLE_BGP_VNC
7828 /* prints an additional line, indented, with VNC info, if
7829 * present */
7830 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
7831 rfapi_vty_out_vncinfo(vty, p, path, safi);
7832 #endif
7833 }
7834 }
7835
7836 /* called from terminal list command */
7837 void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
7838 safi_t safi, bool use_json, json_object *json_ar)
7839 {
7840 json_object *json_status = NULL;
7841 json_object *json_net = NULL;
7842 char buff[BUFSIZ];
7843
7844 /* Route status display. */
7845 if (use_json) {
7846 json_status = json_object_new_object();
7847 json_net = json_object_new_object();
7848 } else {
7849 vty_out(vty, "*");
7850 vty_out(vty, ">");
7851 vty_out(vty, " ");
7852 }
7853
7854 /* print prefix and mask */
7855 if (use_json) {
7856 if (safi == SAFI_EVPN)
7857 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
7858 else if (p->family == AF_INET || p->family == AF_INET6) {
7859 json_object_string_add(
7860 json_net, "addrPrefix",
7861 inet_ntop(p->family, &p->u.prefix, buff,
7862 BUFSIZ));
7863 json_object_int_add(json_net, "prefixLen",
7864 p->prefixlen);
7865 prefix2str(p, buff, PREFIX_STRLEN);
7866 json_object_string_add(json_net, "network", buff);
7867 }
7868 } else
7869 route_vty_out_route(p, vty, NULL);
7870
7871 /* Print attribute */
7872 if (attr) {
7873 if (use_json) {
7874 if (p->family == AF_INET
7875 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7876 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7877 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
7878 json_object_string_add(
7879 json_net, "nextHop",
7880 inet_ntoa(
7881 attr->mp_nexthop_global_in));
7882 else
7883 json_object_string_add(
7884 json_net, "nextHop",
7885 inet_ntoa(attr->nexthop));
7886 } else if (p->family == AF_INET6
7887 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7888 char buf[BUFSIZ];
7889
7890 json_object_string_add(
7891 json_net, "nextHopGlobal",
7892 inet_ntop(AF_INET6,
7893 &attr->mp_nexthop_global, buf,
7894 BUFSIZ));
7895 } else if (p->family == AF_EVPN &&
7896 !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7897 json_object_string_add(json_net,
7898 "nextHop", inet_ntoa(
7899 attr->mp_nexthop_global_in));
7900
7901 if (attr->flag
7902 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7903 json_object_int_add(json_net, "metric",
7904 attr->med);
7905
7906 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
7907
7908 /*
7909 * Adding "locPrf" field to match with
7910 * corresponding CLI. "localPref" will be
7911 * deprecated in future.
7912 */
7913 json_object_int_add(json_net, "localPref",
7914 attr->local_pref);
7915 json_object_int_add(json_net, "locPrf",
7916 attr->local_pref);
7917 }
7918
7919 json_object_int_add(json_net, "weight", attr->weight);
7920
7921 /* Print aspath */
7922 if (attr->aspath) {
7923
7924 /*
7925 * Adding "path" field to match with
7926 * corresponding CLI. "localPref" will be
7927 * deprecated in future.
7928 */
7929 json_object_string_add(json_net, "asPath",
7930 attr->aspath->str);
7931 json_object_string_add(json_net, "path",
7932 attr->aspath->str);
7933 }
7934
7935 /* Print origin */
7936 json_object_string_add(json_net, "bgpOriginCode",
7937 bgp_origin_str[attr->origin]);
7938 } else {
7939 if (p->family == AF_INET
7940 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7941 || safi == SAFI_EVPN
7942 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
7943 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
7944 || safi == SAFI_EVPN)
7945 vty_out(vty, "%-16s",
7946 inet_ntoa(
7947 attr->mp_nexthop_global_in));
7948 else
7949 vty_out(vty, "%-16s",
7950 inet_ntoa(attr->nexthop));
7951 } else if (p->family == AF_INET6
7952 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
7953 int len;
7954 char buf[BUFSIZ];
7955
7956 len = vty_out(
7957 vty, "%s",
7958 inet_ntop(AF_INET6,
7959 &attr->mp_nexthop_global, buf,
7960 BUFSIZ));
7961 len = 16 - len;
7962 if (len < 1)
7963 vty_out(vty, "\n%*s", 36, " ");
7964 else
7965 vty_out(vty, "%*s", len, " ");
7966 }
7967 if (attr->flag
7968 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7969 vty_out(vty, "%10u", attr->med);
7970 else
7971 vty_out(vty, " ");
7972
7973 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
7974 vty_out(vty, "%7u", attr->local_pref);
7975 else
7976 vty_out(vty, " ");
7977
7978 vty_out(vty, "%7u ", attr->weight);
7979
7980 /* Print aspath */
7981 if (attr->aspath)
7982 aspath_print_vty(vty, "%s", attr->aspath, " ");
7983
7984 /* Print origin */
7985 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
7986 }
7987 }
7988 if (use_json) {
7989 json_object_boolean_true_add(json_status, "*");
7990 json_object_boolean_true_add(json_status, ">");
7991 json_object_object_add(json_net, "appliedStatusSymbols",
7992 json_status);
7993
7994 prefix2str(p, buff, PREFIX_STRLEN);
7995 json_object_object_add(json_ar, buff, json_net);
7996 } else
7997 vty_out(vty, "\n");
7998 }
7999
8000 void route_vty_out_tag(struct vty *vty, struct prefix *p,
8001 struct bgp_path_info *path, int display, safi_t safi,
8002 json_object *json)
8003 {
8004 json_object *json_out = NULL;
8005 struct attr *attr;
8006 mpls_label_t label = MPLS_INVALID_LABEL;
8007
8008 if (!path->extra)
8009 return;
8010
8011 if (json)
8012 json_out = json_object_new_object();
8013
8014 /* short status lead text */
8015 route_vty_short_status_out(vty, path, json_out);
8016
8017 /* print prefix and mask */
8018 if (json == NULL) {
8019 if (!display)
8020 route_vty_out_route(p, vty, NULL);
8021 else
8022 vty_out(vty, "%*s", 17, " ");
8023 }
8024
8025 /* Print attribute */
8026 attr = path->attr;
8027 if (((p->family == AF_INET)
8028 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
8029 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
8030 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8031 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8032 || safi == SAFI_EVPN) {
8033 if (json)
8034 json_object_string_add(
8035 json_out, "mpNexthopGlobalIn",
8036 inet_ntoa(attr->mp_nexthop_global_in));
8037 else
8038 vty_out(vty, "%-16s",
8039 inet_ntoa(attr->mp_nexthop_global_in));
8040 } else {
8041 if (json)
8042 json_object_string_add(
8043 json_out, "nexthop",
8044 inet_ntoa(attr->nexthop));
8045 else
8046 vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
8047 }
8048 } else if (((p->family == AF_INET6)
8049 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
8050 || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
8051 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8052 char buf_a[512];
8053
8054 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
8055 if (json)
8056 json_object_string_add(
8057 json_out, "mpNexthopGlobalIn",
8058 inet_ntop(AF_INET6,
8059 &attr->mp_nexthop_global,
8060 buf_a, sizeof(buf_a)));
8061 else
8062 vty_out(vty, "%s",
8063 inet_ntop(AF_INET6,
8064 &attr->mp_nexthop_global,
8065 buf_a, sizeof(buf_a)));
8066 } else if (attr->mp_nexthop_len
8067 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
8068 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
8069 &attr->mp_nexthop_global,
8070 &attr->mp_nexthop_local);
8071 if (json)
8072 json_object_string_add(json_out,
8073 "mpNexthopGlobalLocal",
8074 buf_a);
8075 else
8076 vty_out(vty, "%s", buf_a);
8077 }
8078 }
8079
8080 label = decode_label(&path->extra->label[0]);
8081
8082 if (bgp_is_valid_label(&label)) {
8083 if (json) {
8084 json_object_int_add(json_out, "notag", label);
8085 json_object_array_add(json, json_out);
8086 } else {
8087 vty_out(vty, "notag/%d", label);
8088 vty_out(vty, "\n");
8089 }
8090 }
8091 }
8092
8093 void route_vty_out_overlay(struct vty *vty, struct prefix *p,
8094 struct bgp_path_info *path, int display,
8095 json_object *json_paths)
8096 {
8097 struct attr *attr;
8098 char buf[BUFSIZ] = {0};
8099 json_object *json_path = NULL;
8100 json_object *json_nexthop = NULL;
8101 json_object *json_overlay = NULL;
8102
8103 if (!path->extra)
8104 return;
8105
8106 if (json_paths) {
8107 json_path = json_object_new_object();
8108 json_overlay = json_object_new_object();
8109 json_nexthop = json_object_new_object();
8110 }
8111
8112 /* short status lead text */
8113 route_vty_short_status_out(vty, path, json_path);
8114
8115 /* print prefix and mask */
8116 if (!display)
8117 route_vty_out_route(p, vty, json_path);
8118 else
8119 vty_out(vty, "%*s", 17, " ");
8120
8121 /* Print attribute */
8122 attr = path->attr;
8123 char buf1[BUFSIZ];
8124 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
8125
8126 switch (af) {
8127 case AF_INET:
8128 inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ);
8129 if (!json_path) {
8130 vty_out(vty, "%-16s", buf);
8131 } else {
8132 json_object_string_add(json_nexthop, "ip", buf);
8133
8134 json_object_string_add(json_nexthop, "afi", "ipv4");
8135
8136 json_object_object_add(json_path, "nexthop",
8137 json_nexthop);
8138 }
8139 break;
8140 case AF_INET6:
8141 inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ);
8142 inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ);
8143 if (!json_path) {
8144 vty_out(vty, "%s(%s)", buf, buf1);
8145 } else {
8146 json_object_string_add(json_nexthop, "ipv6Global", buf);
8147
8148 json_object_string_add(json_nexthop, "ipv6LinkLocal",
8149 buf1);
8150
8151 json_object_string_add(json_nexthop, "afi", "ipv6");
8152
8153 json_object_object_add(json_path, "nexthop",
8154 json_nexthop);
8155 }
8156 break;
8157 default:
8158 if (!json_path) {
8159 vty_out(vty, "?");
8160 } else {
8161 json_object_string_add(json_nexthop, "Error",
8162 "Unsupported address-family");
8163 }
8164 }
8165
8166 char *str = esi2str(&(attr->evpn_overlay.eth_s_id));
8167
8168 if (!json_path)
8169 vty_out(vty, "%s", str);
8170 else
8171 json_object_string_add(json_overlay, "esi", str);
8172
8173 XFREE(MTYPE_TMP, str);
8174
8175 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) {
8176 inet_ntop(AF_INET, &(attr->evpn_overlay.gw_ip.ipv4), buf,
8177 BUFSIZ);
8178 } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) {
8179 inet_ntop(AF_INET6, &(attr->evpn_overlay.gw_ip.ipv6), buf,
8180 BUFSIZ);
8181 }
8182
8183 if (!json_path)
8184 vty_out(vty, "/%s", buf);
8185 else
8186 json_object_string_add(json_overlay, "gw", buf);
8187
8188 if (attr->ecommunity) {
8189 char *mac = NULL;
8190 struct ecommunity_val *routermac = ecommunity_lookup(
8191 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
8192 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
8193
8194 if (routermac)
8195 mac = ecom_mac2str((char *)routermac->val);
8196 if (mac) {
8197 if (!json_path) {
8198 vty_out(vty, "/%s", (char *)mac);
8199 } else {
8200 json_object_string_add(json_overlay, "rmac",
8201 mac);
8202 }
8203 XFREE(MTYPE_TMP, mac);
8204 }
8205 }
8206
8207 if (!json_path) {
8208 vty_out(vty, "\n");
8209 } else {
8210 json_object_object_add(json_path, "overlay", json_overlay);
8211
8212 json_object_array_add(json_paths, json_path);
8213 }
8214 }
8215
8216 /* dampening route */
8217 static void damp_route_vty_out(struct vty *vty, struct prefix *p,
8218 struct bgp_path_info *path, int display, afi_t afi,
8219 safi_t safi, bool use_json, json_object *json)
8220 {
8221 struct attr *attr;
8222 int len;
8223 char timebuf[BGP_UPTIME_LEN];
8224
8225 /* short status lead text */
8226 route_vty_short_status_out(vty, path, json);
8227
8228 /* print prefix and mask */
8229 if (!use_json) {
8230 if (!display)
8231 route_vty_out_route(p, vty, NULL);
8232 else
8233 vty_out(vty, "%*s", 17, " ");
8234 }
8235
8236 len = vty_out(vty, "%s", path->peer->host);
8237 len = 17 - len;
8238 if (len < 1) {
8239 if (!use_json)
8240 vty_out(vty, "\n%*s", 34, " ");
8241 } else {
8242 if (use_json)
8243 json_object_int_add(json, "peerHost", len);
8244 else
8245 vty_out(vty, "%*s", len, " ");
8246 }
8247
8248 if (use_json)
8249 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
8250 safi, use_json, json);
8251 else
8252 vty_out(vty, "%s ",
8253 bgp_damp_reuse_time_vty(vty, path, timebuf,
8254 BGP_UPTIME_LEN, afi, safi,
8255 use_json, json));
8256
8257 /* Print attribute */
8258 attr = path->attr;
8259
8260 /* Print aspath */
8261 if (attr->aspath) {
8262 if (use_json)
8263 json_object_string_add(json, "asPath",
8264 attr->aspath->str);
8265 else
8266 aspath_print_vty(vty, "%s", attr->aspath, " ");
8267 }
8268
8269 /* Print origin */
8270 if (use_json)
8271 json_object_string_add(json, "origin",
8272 bgp_origin_str[attr->origin]);
8273 else
8274 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8275
8276 if (!use_json)
8277 vty_out(vty, "\n");
8278 }
8279
8280 /* flap route */
8281 static void flap_route_vty_out(struct vty *vty, struct prefix *p,
8282 struct bgp_path_info *path, int display, afi_t afi,
8283 safi_t safi, bool use_json, json_object *json)
8284 {
8285 struct attr *attr;
8286 struct bgp_damp_info *bdi;
8287 char timebuf[BGP_UPTIME_LEN];
8288 int len;
8289
8290 if (!path->extra)
8291 return;
8292
8293 bdi = path->extra->damp_info;
8294
8295 /* short status lead text */
8296 route_vty_short_status_out(vty, path, json);
8297
8298 /* print prefix and mask */
8299 if (!use_json) {
8300 if (!display)
8301 route_vty_out_route(p, vty, NULL);
8302 else
8303 vty_out(vty, "%*s", 17, " ");
8304 }
8305
8306 len = vty_out(vty, "%s", path->peer->host);
8307 len = 16 - len;
8308 if (len < 1) {
8309 if (!use_json)
8310 vty_out(vty, "\n%*s", 33, " ");
8311 } else {
8312 if (use_json)
8313 json_object_int_add(json, "peerHost", len);
8314 else
8315 vty_out(vty, "%*s", len, " ");
8316 }
8317
8318 len = vty_out(vty, "%d", bdi->flap);
8319 len = 5 - len;
8320 if (len < 1) {
8321 if (!use_json)
8322 vty_out(vty, " ");
8323 } else {
8324 if (use_json)
8325 json_object_int_add(json, "bdiFlap", len);
8326 else
8327 vty_out(vty, "%*s", len, " ");
8328 }
8329
8330 if (use_json)
8331 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
8332 json);
8333 else
8334 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
8335 BGP_UPTIME_LEN, 0, NULL));
8336
8337 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
8338 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8339 if (use_json)
8340 bgp_damp_reuse_time_vty(vty, path, timebuf,
8341 BGP_UPTIME_LEN, afi, safi,
8342 use_json, json);
8343 else
8344 vty_out(vty, "%s ",
8345 bgp_damp_reuse_time_vty(vty, path, timebuf,
8346 BGP_UPTIME_LEN, afi,
8347 safi, use_json, json));
8348 } else {
8349 if (!use_json)
8350 vty_out(vty, "%*s ", 8, " ");
8351 }
8352
8353 /* Print attribute */
8354 attr = path->attr;
8355
8356 /* Print aspath */
8357 if (attr->aspath) {
8358 if (use_json)
8359 json_object_string_add(json, "asPath",
8360 attr->aspath->str);
8361 else
8362 aspath_print_vty(vty, "%s", attr->aspath, " ");
8363 }
8364
8365 /* Print origin */
8366 if (use_json)
8367 json_object_string_add(json, "origin",
8368 bgp_origin_str[attr->origin]);
8369 else
8370 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8371
8372 if (!use_json)
8373 vty_out(vty, "\n");
8374 }
8375
8376 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
8377 int *first, const char *header,
8378 json_object *json_adv_to)
8379 {
8380 char buf1[INET6_ADDRSTRLEN];
8381 json_object *json_peer = NULL;
8382
8383 if (json_adv_to) {
8384 /* 'advertised-to' is a dictionary of peers we have advertised
8385 * this
8386 * prefix too. The key is the peer's IP or swpX, the value is
8387 * the
8388 * hostname if we know it and "" if not.
8389 */
8390 json_peer = json_object_new_object();
8391
8392 if (peer->hostname)
8393 json_object_string_add(json_peer, "hostname",
8394 peer->hostname);
8395
8396 if (peer->conf_if)
8397 json_object_object_add(json_adv_to, peer->conf_if,
8398 json_peer);
8399 else
8400 json_object_object_add(
8401 json_adv_to,
8402 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
8403 json_peer);
8404 } else {
8405 if (*first) {
8406 vty_out(vty, "%s", header);
8407 *first = 0;
8408 }
8409
8410 if (peer->hostname
8411 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
8412 if (peer->conf_if)
8413 vty_out(vty, " %s(%s)", peer->hostname,
8414 peer->conf_if);
8415 else
8416 vty_out(vty, " %s(%s)", peer->hostname,
8417 sockunion2str(&peer->su, buf1,
8418 SU_ADDRSTRLEN));
8419 } else {
8420 if (peer->conf_if)
8421 vty_out(vty, " %s", peer->conf_if);
8422 else
8423 vty_out(vty, " %s",
8424 sockunion2str(&peer->su, buf1,
8425 SU_ADDRSTRLEN));
8426 }
8427 }
8428 }
8429
8430 static void route_vty_out_tx_ids(struct vty *vty,
8431 struct bgp_addpath_info_data *d)
8432 {
8433 int i;
8434
8435 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
8436 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
8437 d->addpath_tx_id[i],
8438 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
8439 }
8440 }
8441
8442 static const char *bgp_path_selection_reason2str(
8443 enum bgp_path_selection_reason reason)
8444 {
8445 switch (reason) {
8446 case bgp_path_selection_none:
8447 return "Nothing to Select";
8448 case bgp_path_selection_first:
8449 return "First path received";
8450 case bgp_path_selection_evpn_sticky_mac:
8451 return "EVPN Sticky Mac";
8452 case bgp_path_selection_evpn_seq:
8453 return "EVPN sequence number";
8454 case bgp_path_selection_evpn_lower_ip:
8455 return "EVPN lower IP";
8456 case bgp_path_selection_weight:
8457 return "Weight";
8458 case bgp_path_selection_local_pref:
8459 return "Local Pref";
8460 case bgp_path_selection_local_route:
8461 return "Local Route";
8462 case bgp_path_selection_confed_as_path:
8463 return "Confederation based AS Path";
8464 case bgp_path_selection_as_path:
8465 return "AS Path";
8466 case bgp_path_selection_origin:
8467 return "Origin";
8468 case bgp_path_selection_med:
8469 return "MED";
8470 case bgp_path_selection_peer:
8471 return "Peer Type";
8472 case bgp_path_selection_confed:
8473 return "Confed Peer Type";
8474 case bgp_path_selection_igp_metric:
8475 return "IGP Metric";
8476 case bgp_path_selection_older:
8477 return "Older Path";
8478 case bgp_path_selection_router_id:
8479 return "Router ID";
8480 case bgp_path_selection_cluster_length:
8481 return "Cluser length";
8482 case bgp_path_selection_stale:
8483 return "Path Staleness";
8484 case bgp_path_selection_local_configured:
8485 return "Locally configured route";
8486 case bgp_path_selection_neighbor_ip:
8487 return "Neighbor IP";
8488 case bgp_path_selection_default:
8489 return "Nothing left to compare";
8490 }
8491 return "Invalid (internal error)";
8492 }
8493
8494 void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
8495 struct bgp_node *bn, struct bgp_path_info *path,
8496 afi_t afi, safi_t safi, json_object *json_paths)
8497 {
8498 char buf[INET6_ADDRSTRLEN];
8499 char buf1[BUFSIZ];
8500 char buf2[EVPN_ROUTE_STRLEN];
8501 struct attr *attr = path->attr;
8502 int sockunion_vty_out(struct vty *, union sockunion *);
8503 time_t tbuf;
8504 json_object *json_bestpath = NULL;
8505 json_object *json_cluster_list = NULL;
8506 json_object *json_cluster_list_list = NULL;
8507 json_object *json_ext_community = NULL;
8508 json_object *json_last_update = NULL;
8509 json_object *json_pmsi = NULL;
8510 json_object *json_nexthop_global = NULL;
8511 json_object *json_nexthop_ll = NULL;
8512 json_object *json_nexthops = NULL;
8513 json_object *json_path = NULL;
8514 json_object *json_peer = NULL;
8515 json_object *json_string = NULL;
8516 json_object *json_adv_to = NULL;
8517 int first = 0;
8518 struct listnode *node, *nnode;
8519 struct peer *peer;
8520 int addpath_capable;
8521 int has_adj;
8522 unsigned int first_as;
8523 bool nexthop_self =
8524 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8525 int i;
8526 char *nexthop_hostname = bgp_nexthop_hostname(path->peer, attr);
8527
8528 if (json_paths) {
8529 json_path = json_object_new_object();
8530 json_peer = json_object_new_object();
8531 json_nexthop_global = json_object_new_object();
8532 }
8533
8534 if (path->extra) {
8535 char tag_buf[30];
8536
8537 buf2[0] = '\0';
8538 tag_buf[0] = '\0';
8539 if (path->extra && path->extra->num_labels) {
8540 bgp_evpn_label2str(path->extra->label,
8541 path->extra->num_labels, tag_buf,
8542 sizeof(tag_buf));
8543 }
8544 if (safi == SAFI_EVPN) {
8545 if (!json_paths) {
8546 bgp_evpn_route2str((struct prefix_evpn *)&bn->p,
8547 buf2, sizeof(buf2));
8548 vty_out(vty, " Route %s", buf2);
8549 if (tag_buf[0] != '\0')
8550 vty_out(vty, " VNI %s", tag_buf);
8551 vty_out(vty, "\n");
8552 } else {
8553 if (tag_buf[0])
8554 json_object_string_add(json_path, "VNI",
8555 tag_buf);
8556 }
8557 }
8558
8559 if (path->extra && path->extra->parent && !json_paths) {
8560 struct bgp_path_info *parent_ri;
8561 struct bgp_node *rn, *prn;
8562
8563 parent_ri = (struct bgp_path_info *)path->extra->parent;
8564 rn = parent_ri->net;
8565 if (rn && rn->prn) {
8566 prn = rn->prn;
8567 prefix_rd2str((struct prefix_rd *)&prn->p,
8568 buf1, sizeof(buf1));
8569 if (is_pi_family_evpn(parent_ri)) {
8570 bgp_evpn_route2str((struct prefix_evpn *)&rn->p,
8571 buf2, sizeof(buf2));
8572 vty_out(vty, " Imported from %s:%s, VNI %s\n", buf1, buf2, tag_buf);
8573 } else
8574 vty_out(vty, " Imported from %s:%s\n", buf1, buf2);
8575 }
8576 }
8577 }
8578
8579 /* Line1 display AS-path, Aggregator */
8580 if (attr->aspath) {
8581 if (json_paths) {
8582 if (!attr->aspath->json)
8583 aspath_str_update(attr->aspath, true);
8584 json_object_lock(attr->aspath->json);
8585 json_object_object_add(json_path, "aspath",
8586 attr->aspath->json);
8587 } else {
8588 if (attr->aspath->segments)
8589 aspath_print_vty(vty, " %s", attr->aspath, "");
8590 else
8591 vty_out(vty, " Local");
8592 }
8593 }
8594
8595 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
8596 if (json_paths)
8597 json_object_boolean_true_add(json_path, "removed");
8598 else
8599 vty_out(vty, ", (removed)");
8600 }
8601
8602 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
8603 if (json_paths)
8604 json_object_boolean_true_add(json_path, "stale");
8605 else
8606 vty_out(vty, ", (stale)");
8607 }
8608
8609 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
8610 if (json_paths) {
8611 json_object_int_add(json_path, "aggregatorAs",
8612 attr->aggregator_as);
8613 json_object_string_add(
8614 json_path, "aggregatorId",
8615 inet_ntoa(attr->aggregator_addr));
8616 } else {
8617 vty_out(vty, ", (aggregated by %u %s)",
8618 attr->aggregator_as,
8619 inet_ntoa(attr->aggregator_addr));
8620 }
8621 }
8622
8623 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
8624 PEER_FLAG_REFLECTOR_CLIENT)) {
8625 if (json_paths)
8626 json_object_boolean_true_add(json_path,
8627 "rxedFromRrClient");
8628 else
8629 vty_out(vty, ", (Received from a RR-client)");
8630 }
8631
8632 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
8633 PEER_FLAG_RSERVER_CLIENT)) {
8634 if (json_paths)
8635 json_object_boolean_true_add(json_path,
8636 "rxedFromRsClient");
8637 else
8638 vty_out(vty, ", (Received from a RS-client)");
8639 }
8640
8641 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8642 if (json_paths)
8643 json_object_boolean_true_add(json_path,
8644 "dampeningHistoryEntry");
8645 else
8646 vty_out(vty, ", (history entry)");
8647 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
8648 if (json_paths)
8649 json_object_boolean_true_add(json_path,
8650 "dampeningSuppressed");
8651 else
8652 vty_out(vty, ", (suppressed due to dampening)");
8653 }
8654
8655 if (!json_paths)
8656 vty_out(vty, "\n");
8657
8658 /* Line2 display Next-hop, Neighbor, Router-id */
8659 /* Display the nexthop */
8660 if ((bn->p.family == AF_INET || bn->p.family == AF_ETHERNET
8661 || bn->p.family == AF_EVPN)
8662 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
8663 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8664 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8665 || safi == SAFI_EVPN) {
8666 if (json_paths) {
8667 json_object_string_add(
8668 json_nexthop_global, "ip",
8669 inet_ntoa(attr->mp_nexthop_global_in));
8670
8671 if (nexthop_hostname)
8672 json_object_string_add(
8673 json_nexthop_global, "hostname",
8674 nexthop_hostname);
8675 } else
8676 vty_out(vty, " %s",
8677 nexthop_hostname
8678 ? nexthop_hostname
8679 : inet_ntoa(
8680 attr->mp_nexthop_global_in));
8681 } else {
8682 if (json_paths) {
8683 json_object_string_add(
8684 json_nexthop_global, "ip",
8685 inet_ntoa(attr->nexthop));
8686
8687 if (nexthop_hostname)
8688 json_object_string_add(
8689 json_nexthop_global, "hostname",
8690 nexthop_hostname);
8691 } else
8692 vty_out(vty, " %s",
8693 nexthop_hostname
8694 ? nexthop_hostname
8695 : inet_ntoa(attr->nexthop));
8696 }
8697
8698 if (json_paths)
8699 json_object_string_add(json_nexthop_global, "afi",
8700 "ipv4");
8701 } else {
8702 if (json_paths) {
8703 json_object_string_add(
8704 json_nexthop_global, "ip",
8705 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
8706 buf, INET6_ADDRSTRLEN));
8707
8708 if (nexthop_hostname)
8709 json_object_string_add(json_nexthop_global,
8710 "hostname",
8711 nexthop_hostname);
8712
8713 json_object_string_add(json_nexthop_global, "afi",
8714 "ipv6");
8715 json_object_string_add(json_nexthop_global, "scope",
8716 "global");
8717 } else {
8718 vty_out(vty, " %s",
8719 nexthop_hostname
8720 ? nexthop_hostname
8721 : inet_ntop(AF_INET6,
8722 &attr->mp_nexthop_global,
8723 buf, INET6_ADDRSTRLEN));
8724 }
8725 }
8726
8727 /* Display the IGP cost or 'inaccessible' */
8728 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
8729 if (json_paths)
8730 json_object_boolean_false_add(json_nexthop_global,
8731 "accessible");
8732 else
8733 vty_out(vty, " (inaccessible)");
8734 } else {
8735 if (path->extra && path->extra->igpmetric) {
8736 if (json_paths)
8737 json_object_int_add(json_nexthop_global,
8738 "metric",
8739 path->extra->igpmetric);
8740 else
8741 vty_out(vty, " (metric %u)",
8742 path->extra->igpmetric);
8743 }
8744
8745 /* IGP cost is 0, display this only for json */
8746 else {
8747 if (json_paths)
8748 json_object_int_add(json_nexthop_global,
8749 "metric", 0);
8750 }
8751
8752 if (json_paths)
8753 json_object_boolean_true_add(json_nexthop_global,
8754 "accessible");
8755 }
8756
8757 /* Display peer "from" output */
8758 /* This path was originated locally */
8759 if (path->peer == bgp->peer_self) {
8760
8761 if (safi == SAFI_EVPN
8762 || (bn->p.family == AF_INET
8763 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8764 if (json_paths)
8765 json_object_string_add(json_peer, "peerId",
8766 "0.0.0.0");
8767 else
8768 vty_out(vty, " from 0.0.0.0 ");
8769 } else {
8770 if (json_paths)
8771 json_object_string_add(json_peer, "peerId",
8772 "::");
8773 else
8774 vty_out(vty, " from :: ");
8775 }
8776
8777 if (json_paths)
8778 json_object_string_add(json_peer, "routerId",
8779 inet_ntoa(bgp->router_id));
8780 else
8781 vty_out(vty, "(%s)", inet_ntoa(bgp->router_id));
8782 }
8783
8784 /* We RXed this path from one of our peers */
8785 else {
8786
8787 if (json_paths) {
8788 json_object_string_add(json_peer, "peerId",
8789 sockunion2str(&path->peer->su,
8790 buf,
8791 SU_ADDRSTRLEN));
8792 json_object_string_add(json_peer, "routerId",
8793 inet_ntop(AF_INET,
8794 &path->peer->remote_id,
8795 buf1, sizeof(buf1)));
8796
8797 if (path->peer->hostname)
8798 json_object_string_add(json_peer, "hostname",
8799 path->peer->hostname);
8800
8801 if (path->peer->domainname)
8802 json_object_string_add(json_peer, "domainname",
8803 path->peer->domainname);
8804
8805 if (path->peer->conf_if)
8806 json_object_string_add(json_peer, "interface",
8807 path->peer->conf_if);
8808 } else {
8809 if (path->peer->conf_if) {
8810 if (path->peer->hostname
8811 && CHECK_FLAG(path->peer->bgp->flags,
8812 BGP_FLAG_SHOW_HOSTNAME))
8813 vty_out(vty, " from %s(%s)",
8814 path->peer->hostname,
8815 path->peer->conf_if);
8816 else
8817 vty_out(vty, " from %s",
8818 path->peer->conf_if);
8819 } else {
8820 if (path->peer->hostname
8821 && CHECK_FLAG(path->peer->bgp->flags,
8822 BGP_FLAG_SHOW_HOSTNAME))
8823 vty_out(vty, " from %s(%s)",
8824 path->peer->hostname,
8825 path->peer->host);
8826 else
8827 vty_out(vty, " from %s",
8828 sockunion2str(&path->peer->su,
8829 buf,
8830 SU_ADDRSTRLEN));
8831 }
8832
8833 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
8834 vty_out(vty, " (%s)",
8835 inet_ntoa(attr->originator_id));
8836 else
8837 vty_out(vty, " (%s)",
8838 inet_ntop(AF_INET,
8839 &path->peer->remote_id, buf1,
8840 sizeof(buf1)));
8841 }
8842 }
8843
8844 /*
8845 * Note when vrfid of nexthop is different from that of prefix
8846 */
8847 if (path->extra && path->extra->bgp_orig) {
8848 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
8849
8850 if (json_paths) {
8851 const char *vn;
8852
8853 if (path->extra->bgp_orig->inst_type
8854 == BGP_INSTANCE_TYPE_DEFAULT)
8855 vn = VRF_DEFAULT_NAME;
8856 else
8857 vn = path->extra->bgp_orig->name;
8858
8859 json_object_string_add(json_path, "nhVrfName", vn);
8860
8861 if (nexthop_vrfid == VRF_UNKNOWN) {
8862 json_object_int_add(json_path, "nhVrfId", -1);
8863 } else {
8864 json_object_int_add(json_path, "nhVrfId",
8865 (int)nexthop_vrfid);
8866 }
8867 } else {
8868 if (nexthop_vrfid == VRF_UNKNOWN)
8869 vty_out(vty, " vrf ?");
8870 else {
8871 struct vrf *vrf;
8872
8873 vrf = vrf_lookup_by_id(nexthop_vrfid);
8874 vty_out(vty, " vrf %s(%u)",
8875 VRF_LOGNAME(vrf), nexthop_vrfid);
8876 }
8877 }
8878 }
8879
8880 if (nexthop_self) {
8881 if (json_paths) {
8882 json_object_boolean_true_add(json_path,
8883 "announceNexthopSelf");
8884 } else {
8885 vty_out(vty, " announce-nh-self");
8886 }
8887 }
8888
8889 if (!json_paths)
8890 vty_out(vty, "\n");
8891
8892 /* display the link-local nexthop */
8893 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
8894 if (json_paths) {
8895 json_nexthop_ll = json_object_new_object();
8896 json_object_string_add(
8897 json_nexthop_ll, "ip",
8898 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
8899 buf, INET6_ADDRSTRLEN));
8900
8901 if (nexthop_hostname)
8902 json_object_string_add(json_nexthop_ll,
8903 "hostname",
8904 nexthop_hostname);
8905
8906 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
8907 json_object_string_add(json_nexthop_ll, "scope",
8908 "link-local");
8909
8910 json_object_boolean_true_add(json_nexthop_ll,
8911 "accessible");
8912
8913 if (!attr->mp_nexthop_prefer_global)
8914 json_object_boolean_true_add(json_nexthop_ll,
8915 "used");
8916 else
8917 json_object_boolean_true_add(
8918 json_nexthop_global, "used");
8919 } else {
8920 vty_out(vty, " (%s) %s\n",
8921 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
8922 buf, INET6_ADDRSTRLEN),
8923 attr->mp_nexthop_prefer_global
8924 ? "(prefer-global)"
8925 : "(used)");
8926 }
8927 }
8928 /* If we do not have a link-local nexthop then we must flag the
8929 global as "used" */
8930 else {
8931 if (json_paths)
8932 json_object_boolean_true_add(json_nexthop_global,
8933 "used");
8934 }
8935
8936 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
8937 * Int/Ext/Local, Atomic, best */
8938 if (json_paths)
8939 json_object_string_add(json_path, "origin",
8940 bgp_origin_long_str[attr->origin]);
8941 else
8942 vty_out(vty, " Origin %s",
8943 bgp_origin_long_str[attr->origin]);
8944
8945 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
8946 if (json_paths) {
8947 /*
8948 * Adding "metric" field to match with
8949 * corresponding CLI. "med" will be
8950 * deprecated in future.
8951 */
8952 json_object_int_add(json_path, "med", attr->med);
8953 json_object_int_add(json_path, "metric", attr->med);
8954 } else
8955 vty_out(vty, ", metric %u", attr->med);
8956 }
8957
8958 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
8959 if (json_paths)
8960 json_object_int_add(json_path, "localpref",
8961 attr->local_pref);
8962 else
8963 vty_out(vty, ", localpref %u", attr->local_pref);
8964 }
8965
8966 if (attr->weight != 0) {
8967 if (json_paths)
8968 json_object_int_add(json_path, "weight", attr->weight);
8969 else
8970 vty_out(vty, ", weight %u", attr->weight);
8971 }
8972
8973 if (attr->tag != 0) {
8974 if (json_paths)
8975 json_object_int_add(json_path, "tag", attr->tag);
8976 else
8977 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
8978 }
8979
8980 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
8981 if (json_paths)
8982 json_object_boolean_false_add(json_path, "valid");
8983 else
8984 vty_out(vty, ", invalid");
8985 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
8986 if (json_paths)
8987 json_object_boolean_true_add(json_path, "valid");
8988 else
8989 vty_out(vty, ", valid");
8990 }
8991
8992 if (path->peer != bgp->peer_self) {
8993 if (path->peer->as == path->peer->local_as) {
8994 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
8995 if (json_paths)
8996 json_object_string_add(
8997 json_peer, "type",
8998 "confed-internal");
8999 else
9000 vty_out(vty, ", confed-internal");
9001 } else {
9002 if (json_paths)
9003 json_object_string_add(
9004 json_peer, "type", "internal");
9005 else
9006 vty_out(vty, ", internal");
9007 }
9008 } else {
9009 if (bgp_confederation_peers_check(bgp,
9010 path->peer->as)) {
9011 if (json_paths)
9012 json_object_string_add(
9013 json_peer, "type",
9014 "confed-external");
9015 else
9016 vty_out(vty, ", confed-external");
9017 } else {
9018 if (json_paths)
9019 json_object_string_add(
9020 json_peer, "type", "external");
9021 else
9022 vty_out(vty, ", external");
9023 }
9024 }
9025 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
9026 if (json_paths) {
9027 json_object_boolean_true_add(json_path, "aggregated");
9028 json_object_boolean_true_add(json_path, "local");
9029 } else {
9030 vty_out(vty, ", aggregated, local");
9031 }
9032 } else if (path->type != ZEBRA_ROUTE_BGP) {
9033 if (json_paths)
9034 json_object_boolean_true_add(json_path, "sourced");
9035 else
9036 vty_out(vty, ", sourced");
9037 } else {
9038 if (json_paths) {
9039 json_object_boolean_true_add(json_path, "sourced");
9040 json_object_boolean_true_add(json_path, "local");
9041 } else {
9042 vty_out(vty, ", sourced, local");
9043 }
9044 }
9045
9046 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
9047 if (json_paths)
9048 json_object_boolean_true_add(json_path,
9049 "atomicAggregate");
9050 else
9051 vty_out(vty, ", atomic-aggregate");
9052 }
9053
9054 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
9055 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
9056 && bgp_path_info_mpath_count(path))) {
9057 if (json_paths)
9058 json_object_boolean_true_add(json_path, "multipath");
9059 else
9060 vty_out(vty, ", multipath");
9061 }
9062
9063 // Mark the bestpath(s)
9064 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
9065 first_as = aspath_get_first_as(attr->aspath);
9066
9067 if (json_paths) {
9068 if (!json_bestpath)
9069 json_bestpath = json_object_new_object();
9070 json_object_int_add(json_bestpath, "bestpathFromAs",
9071 first_as);
9072 } else {
9073 if (first_as)
9074 vty_out(vty, ", bestpath-from-AS %u", first_as);
9075 else
9076 vty_out(vty, ", bestpath-from-AS Local");
9077 }
9078 }
9079
9080 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9081 if (json_paths) {
9082 if (!json_bestpath)
9083 json_bestpath = json_object_new_object();
9084 json_object_boolean_true_add(json_bestpath, "overall");
9085 json_object_string_add(
9086 json_bestpath, "selectionReason",
9087 bgp_path_selection_reason2str(bn->reason));
9088 } else {
9089 vty_out(vty, ", best");
9090 vty_out(vty, " (%s)",
9091 bgp_path_selection_reason2str(bn->reason));
9092 }
9093 }
9094
9095 if (json_bestpath)
9096 json_object_object_add(json_path, "bestpath", json_bestpath);
9097
9098 if (!json_paths)
9099 vty_out(vty, "\n");
9100
9101 /* Line 4 display Community */
9102 if (attr->community) {
9103 if (json_paths) {
9104 if (!attr->community->json)
9105 community_str(attr->community, true);
9106 json_object_lock(attr->community->json);
9107 json_object_object_add(json_path, "community",
9108 attr->community->json);
9109 } else {
9110 vty_out(vty, " Community: %s\n",
9111 attr->community->str);
9112 }
9113 }
9114
9115 /* Line 5 display Extended-community */
9116 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9117 if (json_paths) {
9118 json_ext_community = json_object_new_object();
9119 json_object_string_add(json_ext_community, "string",
9120 attr->ecommunity->str);
9121 json_object_object_add(json_path, "extendedCommunity",
9122 json_ext_community);
9123 } else {
9124 vty_out(vty, " Extended Community: %s\n",
9125 attr->ecommunity->str);
9126 }
9127 }
9128
9129 /* Line 6 display Large community */
9130 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
9131 if (json_paths) {
9132 if (!attr->lcommunity->json)
9133 lcommunity_str(attr->lcommunity, true);
9134 json_object_lock(attr->lcommunity->json);
9135 json_object_object_add(json_path, "largeCommunity",
9136 attr->lcommunity->json);
9137 } else {
9138 vty_out(vty, " Large Community: %s\n",
9139 attr->lcommunity->str);
9140 }
9141 }
9142
9143 /* Line 7 display Originator, Cluster-id */
9144 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
9145 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
9146 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
9147 if (json_paths)
9148 json_object_string_add(
9149 json_path, "originatorId",
9150 inet_ntoa(attr->originator_id));
9151 else
9152 vty_out(vty, " Originator: %s",
9153 inet_ntoa(attr->originator_id));
9154 }
9155
9156 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
9157 int i;
9158
9159 if (json_paths) {
9160 json_cluster_list = json_object_new_object();
9161 json_cluster_list_list =
9162 json_object_new_array();
9163
9164 for (i = 0; i < attr->cluster->length / 4;
9165 i++) {
9166 json_string = json_object_new_string(
9167 inet_ntoa(attr->cluster
9168 ->list[i]));
9169 json_object_array_add(
9170 json_cluster_list_list,
9171 json_string);
9172 }
9173
9174 /*
9175 * struct cluster_list does not have
9176 * "str" variable like aspath and community
9177 * do. Add this someday if someone asks
9178 * for it.
9179 * json_object_string_add(json_cluster_list,
9180 * "string", attr->cluster->str);
9181 */
9182 json_object_object_add(json_cluster_list,
9183 "list",
9184 json_cluster_list_list);
9185 json_object_object_add(json_path, "clusterList",
9186 json_cluster_list);
9187 } else {
9188 vty_out(vty, ", Cluster list: ");
9189
9190 for (i = 0; i < attr->cluster->length / 4;
9191 i++) {
9192 vty_out(vty, "%s ",
9193 inet_ntoa(attr->cluster
9194 ->list[i]));
9195 }
9196 }
9197 }
9198
9199 if (!json_paths)
9200 vty_out(vty, "\n");
9201 }
9202
9203 if (path->extra && path->extra->damp_info)
9204 bgp_damp_info_vty(vty, path, afi, safi, json_path);
9205
9206 /* Remote Label */
9207 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
9208 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
9209 mpls_label_t label = label_pton(&path->extra->label[0]);
9210
9211 if (json_paths)
9212 json_object_int_add(json_path, "remoteLabel", label);
9213 else
9214 vty_out(vty, " Remote label: %d\n", label);
9215 }
9216
9217 /* Remote SID */
9218 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
9219 inet_ntop(AF_INET6, &path->extra->sid, buf, sizeof(buf));
9220 if (json_paths)
9221 json_object_string_add(json_path, "remoteSid", buf);
9222 else
9223 vty_out(vty, " Remote SID: %s\n", buf);
9224 }
9225
9226 /* Label Index */
9227 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
9228 if (json_paths)
9229 json_object_int_add(json_path, "labelIndex",
9230 attr->label_index);
9231 else
9232 vty_out(vty, " Label Index: %d\n",
9233 attr->label_index);
9234 }
9235
9236 /* Line 8 display Addpath IDs */
9237 if (path->addpath_rx_id
9238 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
9239 if (json_paths) {
9240 json_object_int_add(json_path, "addpathRxId",
9241 path->addpath_rx_id);
9242
9243 /* Keep backwards compatibility with the old API
9244 * by putting TX All's ID in the old field
9245 */
9246 json_object_int_add(
9247 json_path, "addpathTxId",
9248 path->tx_addpath
9249 .addpath_tx_id[BGP_ADDPATH_ALL]);
9250
9251 /* ... but create a specific field for each
9252 * strategy
9253 */
9254 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9255 json_object_int_add(
9256 json_path,
9257 bgp_addpath_names(i)->id_json_name,
9258 path->tx_addpath.addpath_tx_id[i]);
9259 }
9260 } else {
9261 vty_out(vty, " AddPath ID: RX %u, ",
9262 path->addpath_rx_id);
9263
9264 route_vty_out_tx_ids(vty, &path->tx_addpath);
9265 }
9266 }
9267
9268 /* If we used addpath to TX a non-bestpath we need to display
9269 * "Advertised to" on a path-by-path basis
9270 */
9271 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
9272 first = 1;
9273
9274 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
9275 addpath_capable =
9276 bgp_addpath_encode_tx(peer, afi, safi);
9277 has_adj = bgp_adj_out_lookup(
9278 peer, path->net,
9279 bgp_addpath_id_for_peer(peer, afi, safi,
9280 &path->tx_addpath));
9281
9282 if ((addpath_capable && has_adj)
9283 || (!addpath_capable && has_adj
9284 && CHECK_FLAG(path->flags,
9285 BGP_PATH_SELECTED))) {
9286 if (json_path && !json_adv_to)
9287 json_adv_to = json_object_new_object();
9288
9289 route_vty_out_advertised_to(
9290 vty, peer, &first,
9291 " Advertised to:", json_adv_to);
9292 }
9293 }
9294
9295 if (json_path) {
9296 if (json_adv_to) {
9297 json_object_object_add(
9298 json_path, "advertisedTo", json_adv_to);
9299 }
9300 } else {
9301 if (!first) {
9302 vty_out(vty, "\n");
9303 }
9304 }
9305 }
9306
9307 /* Line 9 display Uptime */
9308 tbuf = time(NULL) - (bgp_clock() - path->uptime);
9309 if (json_paths) {
9310 json_last_update = json_object_new_object();
9311 json_object_int_add(json_last_update, "epoch", tbuf);
9312 json_object_string_add(json_last_update, "string",
9313 ctime(&tbuf));
9314 json_object_object_add(json_path, "lastUpdate",
9315 json_last_update);
9316 } else
9317 vty_out(vty, " Last update: %s", ctime(&tbuf));
9318
9319 /* Line 10 display PMSI tunnel attribute, if present */
9320 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
9321 const char *str =
9322 lookup_msg(bgp_pmsi_tnltype_str, attr->pmsi_tnl_type,
9323 PMSI_TNLTYPE_STR_DEFAULT);
9324
9325 if (json_paths) {
9326 json_pmsi = json_object_new_object();
9327 json_object_string_add(json_pmsi, "tunnelType", str);
9328 json_object_int_add(json_pmsi, "label",
9329 label2vni(&attr->label));
9330 json_object_object_add(json_path, "pmsi", json_pmsi);
9331 } else
9332 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
9333 str, label2vni(&attr->label));
9334 }
9335
9336 /* We've constructed the json object for this path, add it to the json
9337 * array of paths
9338 */
9339 if (json_paths) {
9340 if (json_nexthop_global || json_nexthop_ll) {
9341 json_nexthops = json_object_new_array();
9342
9343 if (json_nexthop_global)
9344 json_object_array_add(json_nexthops,
9345 json_nexthop_global);
9346
9347 if (json_nexthop_ll)
9348 json_object_array_add(json_nexthops,
9349 json_nexthop_ll);
9350
9351 json_object_object_add(json_path, "nexthops",
9352 json_nexthops);
9353 }
9354
9355 json_object_object_add(json_path, "peer", json_peer);
9356 json_object_array_add(json_paths, json_path);
9357 }
9358 }
9359
9360 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
9361 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
9362 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
9363
9364 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
9365 const char *prefix_list_str, afi_t afi,
9366 safi_t safi, enum bgp_show_type type);
9367 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
9368 const char *filter, afi_t afi, safi_t safi,
9369 enum bgp_show_type type);
9370 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
9371 const char *rmap_str, afi_t afi, safi_t safi,
9372 enum bgp_show_type type);
9373 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
9374 const char *com, int exact, afi_t afi,
9375 safi_t safi);
9376 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
9377 const char *prefix, afi_t afi, safi_t safi,
9378 enum bgp_show_type type);
9379 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
9380 afi_t afi, safi_t safi, enum bgp_show_type type,
9381 bool use_json);
9382 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
9383 const char *comstr, int exact, afi_t afi,
9384 safi_t safi, bool use_json);
9385
9386
9387 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
9388 struct bgp_table *table, enum bgp_show_type type,
9389 void *output_arg, bool use_json, char *rd,
9390 int is_last, unsigned long *output_cum,
9391 unsigned long *total_cum,
9392 unsigned long *json_header_depth)
9393 {
9394 struct bgp_path_info *pi;
9395 struct bgp_node *rn;
9396 int header = 1;
9397 int display;
9398 unsigned long output_count = 0;
9399 unsigned long total_count = 0;
9400 struct prefix *p;
9401 char buf2[BUFSIZ];
9402 json_object *json_paths = NULL;
9403 int first = 1;
9404
9405 if (output_cum && *output_cum != 0)
9406 header = 0;
9407
9408 if (use_json && !*json_header_depth) {
9409 vty_out(vty,
9410 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
9411 ",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n"
9412 " \"localAS\": %u,\n \"routes\": { ",
9413 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
9414 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
9415 ? VRF_DEFAULT_NAME
9416 : bgp->name,
9417 table->version, inet_ntoa(bgp->router_id),
9418 bgp->default_local_pref, bgp->as);
9419 *json_header_depth = 2;
9420 if (rd) {
9421 vty_out(vty, " \"routeDistinguishers\" : {");
9422 ++*json_header_depth;
9423 }
9424 }
9425
9426 if (use_json && rd) {
9427 vty_out(vty, " \"%s\" : { ", rd);
9428 }
9429
9430 /* Start processing of routes. */
9431 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
9432 pi = bgp_node_get_bgp_path_info(rn);
9433 if (pi == NULL)
9434 continue;
9435
9436 display = 0;
9437 if (use_json)
9438 json_paths = json_object_new_array();
9439 else
9440 json_paths = NULL;
9441
9442 for (; pi; pi = pi->next) {
9443 total_count++;
9444 if (type == bgp_show_type_flap_statistics
9445 || type == bgp_show_type_flap_neighbor
9446 || type == bgp_show_type_dampend_paths
9447 || type == bgp_show_type_damp_neighbor) {
9448 if (!(pi->extra && pi->extra->damp_info))
9449 continue;
9450 }
9451 if (type == bgp_show_type_regexp) {
9452 regex_t *regex = output_arg;
9453
9454 if (bgp_regexec(regex, pi->attr->aspath)
9455 == REG_NOMATCH)
9456 continue;
9457 }
9458 if (type == bgp_show_type_prefix_list) {
9459 struct prefix_list *plist = output_arg;
9460
9461 if (prefix_list_apply(plist, &rn->p)
9462 != PREFIX_PERMIT)
9463 continue;
9464 }
9465 if (type == bgp_show_type_filter_list) {
9466 struct as_list *as_list = output_arg;
9467
9468 if (as_list_apply(as_list, pi->attr->aspath)
9469 != AS_FILTER_PERMIT)
9470 continue;
9471 }
9472 if (type == bgp_show_type_route_map) {
9473 struct route_map *rmap = output_arg;
9474 struct bgp_path_info path;
9475 struct attr dummy_attr;
9476 route_map_result_t ret;
9477
9478 dummy_attr = *pi->attr;
9479
9480 path.peer = pi->peer;
9481 path.attr = &dummy_attr;
9482
9483 ret = route_map_apply(rmap, &rn->p, RMAP_BGP,
9484 &path);
9485 if (ret == RMAP_DENYMATCH)
9486 continue;
9487 }
9488 if (type == bgp_show_type_neighbor
9489 || type == bgp_show_type_flap_neighbor
9490 || type == bgp_show_type_damp_neighbor) {
9491 union sockunion *su = output_arg;
9492
9493 if (pi->peer == NULL
9494 || pi->peer->su_remote == NULL
9495 || !sockunion_same(pi->peer->su_remote, su))
9496 continue;
9497 }
9498 if (type == bgp_show_type_cidr_only) {
9499 uint32_t destination;
9500
9501 destination = ntohl(rn->p.u.prefix4.s_addr);
9502 if (IN_CLASSC(destination)
9503 && rn->p.prefixlen == 24)
9504 continue;
9505 if (IN_CLASSB(destination)
9506 && rn->p.prefixlen == 16)
9507 continue;
9508 if (IN_CLASSA(destination)
9509 && rn->p.prefixlen == 8)
9510 continue;
9511 }
9512 if (type == bgp_show_type_prefix_longer) {
9513 p = output_arg;
9514 if (!prefix_match(p, &rn->p))
9515 continue;
9516 }
9517 if (type == bgp_show_type_community_all) {
9518 if (!pi->attr->community)
9519 continue;
9520 }
9521 if (type == bgp_show_type_community) {
9522 struct community *com = output_arg;
9523
9524 if (!pi->attr->community
9525 || !community_match(pi->attr->community,
9526 com))
9527 continue;
9528 }
9529 if (type == bgp_show_type_community_exact) {
9530 struct community *com = output_arg;
9531
9532 if (!pi->attr->community
9533 || !community_cmp(pi->attr->community, com))
9534 continue;
9535 }
9536 if (type == bgp_show_type_community_list) {
9537 struct community_list *list = output_arg;
9538
9539 if (!community_list_match(pi->attr->community,
9540 list))
9541 continue;
9542 }
9543 if (type == bgp_show_type_community_list_exact) {
9544 struct community_list *list = output_arg;
9545
9546 if (!community_list_exact_match(
9547 pi->attr->community, list))
9548 continue;
9549 }
9550 if (type == bgp_show_type_lcommunity) {
9551 struct lcommunity *lcom = output_arg;
9552
9553 if (!pi->attr->lcommunity
9554 || !lcommunity_match(pi->attr->lcommunity,
9555 lcom))
9556 continue;
9557 }
9558
9559 if (type == bgp_show_type_lcommunity_exact) {
9560 struct lcommunity *lcom = output_arg;
9561
9562 if (!pi->attr->lcommunity
9563 || !lcommunity_cmp(pi->attr->lcommunity,
9564 lcom))
9565 continue;
9566 }
9567 if (type == bgp_show_type_lcommunity_list) {
9568 struct community_list *list = output_arg;
9569
9570 if (!lcommunity_list_match(pi->attr->lcommunity,
9571 list))
9572 continue;
9573 }
9574 if (type
9575 == bgp_show_type_lcommunity_list_exact) {
9576 struct community_list *list = output_arg;
9577
9578 if (!lcommunity_list_exact_match(
9579 pi->attr->lcommunity, list))
9580 continue;
9581 }
9582 if (type == bgp_show_type_lcommunity_all) {
9583 if (!pi->attr->lcommunity)
9584 continue;
9585 }
9586 if (type == bgp_show_type_dampend_paths
9587 || type == bgp_show_type_damp_neighbor) {
9588 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
9589 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
9590 continue;
9591 }
9592
9593 if (!use_json && header) {
9594 vty_out(vty, "BGP table version is %" PRIu64
9595 ", local router ID is %s, vrf id ",
9596 table->version,
9597 inet_ntoa(bgp->router_id));
9598 if (bgp->vrf_id == VRF_UNKNOWN)
9599 vty_out(vty, "%s", VRFID_NONE_STR);
9600 else
9601 vty_out(vty, "%u", bgp->vrf_id);
9602 vty_out(vty, "\n");
9603 vty_out(vty, "Default local pref %u, ",
9604 bgp->default_local_pref);
9605 vty_out(vty, "local AS %u\n", bgp->as);
9606 vty_out(vty, BGP_SHOW_SCODE_HEADER);
9607 vty_out(vty, BGP_SHOW_NCODE_HEADER);
9608 vty_out(vty, BGP_SHOW_OCODE_HEADER);
9609 if (type == bgp_show_type_dampend_paths
9610 || type == bgp_show_type_damp_neighbor)
9611 vty_out(vty, BGP_SHOW_DAMP_HEADER);
9612 else if (type == bgp_show_type_flap_statistics
9613 || type == bgp_show_type_flap_neighbor)
9614 vty_out(vty, BGP_SHOW_FLAP_HEADER);
9615 else
9616 vty_out(vty, BGP_SHOW_HEADER);
9617 header = 0;
9618 }
9619 if (rd != NULL && !display && !output_count) {
9620 if (!use_json)
9621 vty_out(vty,
9622 "Route Distinguisher: %s\n",
9623 rd);
9624 }
9625 if (type == bgp_show_type_dampend_paths
9626 || type == bgp_show_type_damp_neighbor)
9627 damp_route_vty_out(vty, &rn->p, pi, display, AFI_IP,
9628 safi, use_json, json_paths);
9629 else if (type == bgp_show_type_flap_statistics
9630 || type == bgp_show_type_flap_neighbor)
9631 flap_route_vty_out(vty, &rn->p, pi, display, AFI_IP,
9632 safi, use_json, json_paths);
9633 else
9634 route_vty_out(vty, &rn->p, pi, display, safi,
9635 json_paths);
9636 display++;
9637 }
9638
9639 if (display) {
9640 output_count++;
9641 if (!use_json)
9642 continue;
9643
9644 p = &rn->p;
9645 /* encode prefix */
9646 if (p->family == AF_FLOWSPEC) {
9647 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
9648
9649 bgp_fs_nlri_get_string((unsigned char *)
9650 p->u.prefix_flowspec.ptr,
9651 p->u.prefix_flowspec
9652 .prefixlen,
9653 retstr,
9654 NLRI_STRING_FORMAT_MIN,
9655 NULL);
9656 if (first)
9657 vty_out(vty, "\"%s/%d\": ",
9658 retstr,
9659 p->u.prefix_flowspec.prefixlen);
9660 else
9661 vty_out(vty, ",\"%s/%d\": ",
9662 retstr,
9663 p->u.prefix_flowspec.prefixlen);
9664 } else {
9665 prefix2str(p, buf2, sizeof(buf2));
9666 if (first)
9667 vty_out(vty, "\"%s\": ", buf2);
9668 else
9669 vty_out(vty, ",\"%s\": ", buf2);
9670 }
9671 vty_out(vty, "%s",
9672 json_object_to_json_string_ext(
9673 json_paths, JSON_C_TO_STRING_PRETTY));
9674 json_object_free(json_paths);
9675 json_paths = NULL;
9676 first = 0;
9677 } else
9678 json_object_free(json_paths);
9679 }
9680
9681 if (output_cum) {
9682 output_count += *output_cum;
9683 *output_cum = output_count;
9684 }
9685 if (total_cum) {
9686 total_count += *total_cum;
9687 *total_cum = total_count;
9688 }
9689 if (use_json) {
9690 if (rd) {
9691 vty_out(vty, " }%s ", (is_last ? "" : ","));
9692 }
9693 if (is_last) {
9694 unsigned long i;
9695 for (i = 0; i < *json_header_depth; ++i)
9696 vty_out(vty, " } ");
9697 vty_out(vty, "\n");
9698 }
9699 } else {
9700 if (is_last) {
9701 /* No route is displayed */
9702 if (output_count == 0) {
9703 if (type == bgp_show_type_normal)
9704 vty_out(vty,
9705 "No BGP prefixes displayed, %ld exist\n",
9706 total_count);
9707 } else
9708 vty_out(vty,
9709 "\nDisplayed %ld routes and %ld total paths\n",
9710 output_count, total_count);
9711 }
9712 }
9713
9714 return CMD_SUCCESS;
9715 }
9716
9717 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
9718 struct bgp_table *table, struct prefix_rd *prd_match,
9719 enum bgp_show_type type, void *output_arg, bool use_json)
9720 {
9721 struct bgp_node *rn, *next;
9722 unsigned long output_cum = 0;
9723 unsigned long total_cum = 0;
9724 unsigned long json_header_depth = 0;
9725 struct bgp_table *itable;
9726 bool show_msg;
9727
9728 show_msg = (!use_json && type == bgp_show_type_normal);
9729
9730 for (rn = bgp_table_top(table); rn; rn = next) {
9731 next = bgp_route_next(rn);
9732 if (prd_match && memcmp(rn->p.u.val, prd_match->val, 8) != 0)
9733 continue;
9734
9735 itable = bgp_node_get_bgp_table_info(rn);
9736 if (itable != NULL) {
9737 struct prefix_rd prd;
9738 char rd[RD_ADDRSTRLEN];
9739
9740 memcpy(&prd, &(rn->p), sizeof(struct prefix_rd));
9741 prefix_rd2str(&prd, rd, sizeof(rd));
9742 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
9743 use_json, rd, next == NULL, &output_cum,
9744 &total_cum, &json_header_depth);
9745 if (next == NULL)
9746 show_msg = false;
9747 }
9748 }
9749 if (show_msg) {
9750 if (output_cum == 0)
9751 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
9752 total_cum);
9753 else
9754 vty_out(vty,
9755 "\nDisplayed %ld routes and %ld total paths\n",
9756 output_cum, total_cum);
9757 }
9758 return CMD_SUCCESS;
9759 }
9760 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
9761 enum bgp_show_type type, void *output_arg, bool use_json)
9762 {
9763 struct bgp_table *table;
9764 unsigned long json_header_depth = 0;
9765
9766 if (bgp == NULL) {
9767 bgp = bgp_get_default();
9768 }
9769
9770 if (bgp == NULL) {
9771 if (!use_json)
9772 vty_out(vty, "No BGP process is configured\n");
9773 else
9774 vty_out(vty, "{}\n");
9775 return CMD_WARNING;
9776 }
9777
9778 table = bgp->rib[afi][safi];
9779 /* use MPLS and ENCAP specific shows until they are merged */
9780 if (safi == SAFI_MPLS_VPN) {
9781 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
9782 output_arg, use_json);
9783 }
9784
9785 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
9786 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
9787 output_arg, use_json,
9788 1, NULL, NULL);
9789 }
9790 /* labeled-unicast routes live in the unicast table */
9791 else if (safi == SAFI_LABELED_UNICAST)
9792 safi = SAFI_UNICAST;
9793
9794 return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json,
9795 NULL, 1, NULL, NULL, &json_header_depth);
9796 }
9797
9798 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
9799 safi_t safi, bool use_json)
9800 {
9801 struct listnode *node, *nnode;
9802 struct bgp *bgp;
9803 int is_first = 1;
9804 bool route_output = false;
9805
9806 if (use_json)
9807 vty_out(vty, "{\n");
9808
9809 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
9810 route_output = true;
9811 if (use_json) {
9812 if (!is_first)
9813 vty_out(vty, ",\n");
9814 else
9815 is_first = 0;
9816
9817 vty_out(vty, "\"%s\":",
9818 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9819 ? VRF_DEFAULT_NAME
9820 : bgp->name);
9821 } else {
9822 vty_out(vty, "\nInstance %s:\n",
9823 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9824 ? VRF_DEFAULT_NAME
9825 : bgp->name);
9826 }
9827 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
9828 use_json);
9829 }
9830
9831 if (use_json)
9832 vty_out(vty, "}\n");
9833 else if (!route_output)
9834 vty_out(vty, "%% BGP instance not found\n");
9835 }
9836
9837 /* Header of detailed BGP route information */
9838 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
9839 struct bgp_node *rn, struct prefix_rd *prd,
9840 afi_t afi, safi_t safi, json_object *json)
9841 {
9842 struct bgp_path_info *pi;
9843 struct prefix *p;
9844 struct peer *peer;
9845 struct listnode *node, *nnode;
9846 char buf1[RD_ADDRSTRLEN];
9847 char buf2[INET6_ADDRSTRLEN];
9848 char buf3[EVPN_ROUTE_STRLEN];
9849 char prefix_str[BUFSIZ];
9850 int count = 0;
9851 int best = 0;
9852 int suppress = 0;
9853 int accept_own = 0;
9854 int route_filter_translated_v4 = 0;
9855 int route_filter_v4 = 0;
9856 int route_filter_translated_v6 = 0;
9857 int route_filter_v6 = 0;
9858 int llgr_stale = 0;
9859 int no_llgr = 0;
9860 int accept_own_nexthop = 0;
9861 int blackhole = 0;
9862 int no_export = 0;
9863 int no_advertise = 0;
9864 int local_as = 0;
9865 int no_peer = 0;
9866 int first = 1;
9867 int has_valid_label = 0;
9868 mpls_label_t label = 0;
9869 json_object *json_adv_to = NULL;
9870
9871 p = &rn->p;
9872 has_valid_label = bgp_is_valid_label(&rn->local_label);
9873
9874 if (has_valid_label)
9875 label = label_pton(&rn->local_label);
9876
9877 if (safi == SAFI_EVPN) {
9878
9879 if (!json) {
9880 vty_out(vty, "BGP routing table entry for %s%s%s\n",
9881 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
9882 : "", prd ? ":" : "",
9883 bgp_evpn_route2str((struct prefix_evpn *)p,
9884 buf3, sizeof(buf3)));
9885 } else {
9886 json_object_string_add(json, "rd",
9887 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
9888 "");
9889 bgp_evpn_route2json((struct prefix_evpn *)p, json);
9890 }
9891 } else {
9892 if (!json) {
9893 vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
9894 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9895 ? prefix_rd2str(prd, buf1,
9896 sizeof(buf1))
9897 : ""),
9898 safi == SAFI_MPLS_VPN ? ":" : "",
9899 inet_ntop(p->family, &p->u.prefix, buf2,
9900 INET6_ADDRSTRLEN),
9901 p->prefixlen);
9902
9903 } else
9904 json_object_string_add(json, "prefix",
9905 prefix2str(p, prefix_str, sizeof(prefix_str)));
9906 }
9907
9908 if (has_valid_label) {
9909 if (json)
9910 json_object_int_add(json, "localLabel", label);
9911 else
9912 vty_out(vty, "Local label: %d\n", label);
9913 }
9914
9915 if (!json)
9916 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
9917 vty_out(vty, "not allocated\n");
9918
9919 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
9920 count++;
9921 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
9922 best = count;
9923 if (pi->extra && pi->extra->suppress)
9924 suppress = 1;
9925
9926 if (pi->attr->community == NULL)
9927 continue;
9928
9929 no_advertise += community_include(
9930 pi->attr->community, COMMUNITY_NO_ADVERTISE);
9931 no_export += community_include(pi->attr->community,
9932 COMMUNITY_NO_EXPORT);
9933 local_as += community_include(pi->attr->community,
9934 COMMUNITY_LOCAL_AS);
9935 accept_own += community_include(pi->attr->community,
9936 COMMUNITY_ACCEPT_OWN);
9937 route_filter_translated_v4 += community_include(
9938 pi->attr->community,
9939 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
9940 route_filter_translated_v6 += community_include(
9941 pi->attr->community,
9942 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
9943 route_filter_v4 += community_include(
9944 pi->attr->community, COMMUNITY_ROUTE_FILTER_v4);
9945 route_filter_v6 += community_include(
9946 pi->attr->community, COMMUNITY_ROUTE_FILTER_v6);
9947 llgr_stale += community_include(pi->attr->community,
9948 COMMUNITY_LLGR_STALE);
9949 no_llgr += community_include(pi->attr->community,
9950 COMMUNITY_NO_LLGR);
9951 accept_own_nexthop +=
9952 community_include(pi->attr->community,
9953 COMMUNITY_ACCEPT_OWN_NEXTHOP);
9954 blackhole += community_include(pi->attr->community,
9955 COMMUNITY_BLACKHOLE);
9956 no_peer += community_include(pi->attr->community,
9957 COMMUNITY_NO_PEER);
9958 }
9959 }
9960
9961 if (!json) {
9962 vty_out(vty, "Paths: (%d available", count);
9963 if (best) {
9964 vty_out(vty, ", best #%d", best);
9965 if (safi == SAFI_UNICAST) {
9966 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
9967 vty_out(vty, ", table %s",
9968 VRF_DEFAULT_NAME);
9969 else
9970 vty_out(vty, ", vrf %s",
9971 bgp->name);
9972 }
9973 } else
9974 vty_out(vty, ", no best path");
9975
9976 if (accept_own)
9977 vty_out(vty,
9978 ", accept own local route exported and imported in different VRF");
9979 else if (route_filter_translated_v4)
9980 vty_out(vty,
9981 ", mark translated RTs for VPNv4 route filtering");
9982 else if (route_filter_v4)
9983 vty_out(vty,
9984 ", attach RT as-is for VPNv4 route filtering");
9985 else if (route_filter_translated_v6)
9986 vty_out(vty,
9987 ", mark translated RTs for VPNv6 route filtering");
9988 else if (route_filter_v6)
9989 vty_out(vty,
9990 ", attach RT as-is for VPNv6 route filtering");
9991 else if (llgr_stale)
9992 vty_out(vty,
9993 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
9994 else if (no_llgr)
9995 vty_out(vty,
9996 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
9997 else if (accept_own_nexthop)
9998 vty_out(vty,
9999 ", accept local nexthop");
10000 else if (blackhole)
10001 vty_out(vty, ", inform peer to blackhole prefix");
10002 else if (no_export)
10003 vty_out(vty, ", not advertised to EBGP peer");
10004 else if (no_advertise)
10005 vty_out(vty, ", not advertised to any peer");
10006 else if (local_as)
10007 vty_out(vty, ", not advertised outside local AS");
10008 else if (no_peer)
10009 vty_out(vty,
10010 ", inform EBGP peer not to advertise to their EBGP peers");
10011
10012 if (suppress)
10013 vty_out(vty,
10014 ", Advertisements suppressed by an aggregate.");
10015 vty_out(vty, ")\n");
10016 }
10017
10018 /* If we are not using addpath then we can display Advertised to and
10019 * that will
10020 * show what peers we advertised the bestpath to. If we are using
10021 * addpath
10022 * though then we must display Advertised to on a path-by-path basis. */
10023 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
10024 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
10025 if (bgp_adj_out_lookup(peer, rn, 0)) {
10026 if (json && !json_adv_to)
10027 json_adv_to = json_object_new_object();
10028
10029 route_vty_out_advertised_to(
10030 vty, peer, &first,
10031 " Advertised to non peer-group peers:\n ",
10032 json_adv_to);
10033 }
10034 }
10035
10036 if (json) {
10037 if (json_adv_to) {
10038 json_object_object_add(json, "advertisedTo",
10039 json_adv_to);
10040 }
10041 } else {
10042 if (first)
10043 vty_out(vty, " Not advertised to any peer");
10044 vty_out(vty, "\n");
10045 }
10046 }
10047 }
10048
10049 static void bgp_show_path_info(struct prefix_rd *pfx_rd,
10050 struct bgp_node *bgp_node, struct vty *vty,
10051 struct bgp *bgp, afi_t afi,
10052 safi_t safi, json_object *json,
10053 enum bgp_path_type pathtype, int *display)
10054 {
10055 struct bgp_path_info *pi;
10056 int header = 1;
10057 char rdbuf[RD_ADDRSTRLEN];
10058 json_object *json_header = NULL;
10059 json_object *json_paths = NULL;
10060
10061 for (pi = bgp_node_get_bgp_path_info(bgp_node); pi;
10062 pi = pi->next) {
10063
10064 if (json && !json_paths) {
10065 /* Instantiate json_paths only if path is valid */
10066 json_paths = json_object_new_array();
10067 if (pfx_rd) {
10068 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
10069 json_header = json_object_new_object();
10070 } else
10071 json_header = json;
10072 }
10073
10074 if (header) {
10075 route_vty_out_detail_header(
10076 vty, bgp, bgp_node, pfx_rd,
10077 AFI_IP, safi, json_header);
10078 header = 0;
10079 }
10080 (*display)++;
10081
10082 if (pathtype == BGP_PATH_SHOW_ALL
10083 || (pathtype == BGP_PATH_SHOW_BESTPATH
10084 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
10085 || (pathtype == BGP_PATH_SHOW_MULTIPATH
10086 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
10087 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
10088 route_vty_out_detail(vty, bgp, bgp_node,
10089 pi, AFI_IP, safi,
10090 json_paths);
10091 }
10092
10093 if (json && json_paths) {
10094 json_object_object_add(json_header, "paths", json_paths);
10095
10096 if (pfx_rd)
10097 json_object_object_add(json, rdbuf, json_header);
10098 }
10099 }
10100
10101 /* Display specified route of BGP table. */
10102 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
10103 struct bgp_table *rib, const char *ip_str,
10104 afi_t afi, safi_t safi,
10105 struct prefix_rd *prd, int prefix_check,
10106 enum bgp_path_type pathtype, bool use_json)
10107 {
10108 int ret;
10109 int display = 0;
10110 struct prefix match;
10111 struct bgp_node *rn;
10112 struct bgp_node *rm;
10113 struct bgp_table *table;
10114 json_object *json = NULL;
10115 json_object *json_paths = NULL;
10116
10117 /* Check IP address argument. */
10118 ret = str2prefix(ip_str, &match);
10119 if (!ret) {
10120 vty_out(vty, "address is malformed\n");
10121 return CMD_WARNING;
10122 }
10123
10124 match.family = afi2family(afi);
10125
10126 if (use_json)
10127 json = json_object_new_object();
10128
10129 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
10130 for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
10131 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
10132 continue;
10133 table = bgp_node_get_bgp_table_info(rn);
10134 if (!table)
10135 continue;
10136
10137 if ((rm = bgp_node_match(table, &match)) == NULL)
10138 continue;
10139
10140 if (prefix_check
10141 && rm->p.prefixlen != match.prefixlen) {
10142 bgp_unlock_node(rm);
10143 continue;
10144 }
10145
10146 bgp_show_path_info((struct prefix_rd *)&rn->p, rm,
10147 vty, bgp, afi, safi, json,
10148 pathtype, &display);
10149
10150 bgp_unlock_node(rm);
10151 }
10152 } else if (safi == SAFI_EVPN) {
10153 struct bgp_node *longest_pfx;
10154 bool is_exact_pfxlen_match = FALSE;
10155
10156 for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
10157 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
10158 continue;
10159 table = bgp_node_get_bgp_table_info(rn);
10160 if (!table)
10161 continue;
10162
10163 longest_pfx = NULL;
10164 is_exact_pfxlen_match = FALSE;
10165 /*
10166 * Search through all the prefixes for a match. The
10167 * pfx's are enumerated in ascending order of pfxlens.
10168 * So, the last pfx match is the longest match. Set
10169 * is_exact_pfxlen_match when we get exact pfxlen match
10170 */
10171 for (rm = bgp_table_top(table); rm;
10172 rm = bgp_route_next(rm)) {
10173 /*
10174 * Get prefixlen of the ip-prefix within type5
10175 * evpn route
10176 */
10177 if (evpn_type5_prefix_match(&rm->p,
10178 &match) && rm->info) {
10179 longest_pfx = rm;
10180 int type5_pfxlen =
10181 bgp_evpn_get_type5_prefixlen(&rm->p);
10182 if (type5_pfxlen == match.prefixlen) {
10183 is_exact_pfxlen_match = TRUE;
10184 bgp_unlock_node(rm);
10185 break;
10186 }
10187 }
10188 }
10189
10190 if (!longest_pfx)
10191 continue;
10192
10193 if (prefix_check && !is_exact_pfxlen_match)
10194 continue;
10195
10196 rm = longest_pfx;
10197 bgp_lock_node(rm);
10198
10199 bgp_show_path_info((struct prefix_rd *)&rn->p, rm,
10200 vty, bgp, afi, safi, json,
10201 pathtype, &display);
10202
10203 bgp_unlock_node(rm);
10204 }
10205 } else if (safi == SAFI_FLOWSPEC) {
10206 if (use_json)
10207 json_paths = json_object_new_array();
10208
10209 display = bgp_flowspec_display_match_per_ip(afi, rib,
10210 &match, prefix_check,
10211 vty,
10212 use_json,
10213 json_paths);
10214 if (use_json && display)
10215 json_object_object_add(json, "paths", json_paths);
10216 } else {
10217 if ((rn = bgp_node_match(rib, &match)) != NULL) {
10218 if (!prefix_check
10219 || rn->p.prefixlen == match.prefixlen) {
10220 bgp_show_path_info(NULL, rn, vty, bgp, afi,
10221 safi, json,
10222 pathtype, &display);
10223 }
10224
10225 bgp_unlock_node(rn);
10226 }
10227 }
10228
10229 if (use_json) {
10230 vty_out(vty, "%s\n", json_object_to_json_string_ext(
10231 json, JSON_C_TO_STRING_PRETTY |
10232 JSON_C_TO_STRING_NOSLASHESCAPE));
10233 json_object_free(json);
10234 } else {
10235 if (!display) {
10236 vty_out(vty, "%% Network not in table\n");
10237 return CMD_WARNING;
10238 }
10239 }
10240
10241 return CMD_SUCCESS;
10242 }
10243
10244 /* Display specified route of Main RIB */
10245 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
10246 afi_t afi, safi_t safi, struct prefix_rd *prd,
10247 int prefix_check, enum bgp_path_type pathtype,
10248 bool use_json)
10249 {
10250 if (!bgp) {
10251 bgp = bgp_get_default();
10252 if (!bgp) {
10253 if (!use_json)
10254 vty_out(vty, "No BGP process is configured\n");
10255 else
10256 vty_out(vty, "{}\n");
10257 return CMD_WARNING;
10258 }
10259 }
10260
10261 /* labeled-unicast routes live in the unicast table */
10262 if (safi == SAFI_LABELED_UNICAST)
10263 safi = SAFI_UNICAST;
10264
10265 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
10266 afi, safi, prd, prefix_check, pathtype,
10267 use_json);
10268 }
10269
10270 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
10271 struct cmd_token **argv, bool exact, afi_t afi,
10272 safi_t safi, bool uj)
10273 {
10274 struct lcommunity *lcom;
10275 struct buffer *b;
10276 int i;
10277 char *str;
10278 int first = 0;
10279
10280 b = buffer_new(1024);
10281 for (i = 0; i < argc; i++) {
10282 if (first)
10283 buffer_putc(b, ' ');
10284 else {
10285 if (strmatch(argv[i]->text, "AA:BB:CC")) {
10286 first = 1;
10287 buffer_putstr(b, argv[i]->arg);
10288 }
10289 }
10290 }
10291 buffer_putc(b, '\0');
10292
10293 str = buffer_getstr(b);
10294 buffer_free(b);
10295
10296 lcom = lcommunity_str2com(str);
10297 XFREE(MTYPE_TMP, str);
10298 if (!lcom) {
10299 vty_out(vty, "%% Large-community malformed\n");
10300 return CMD_WARNING;
10301 }
10302
10303 return bgp_show(vty, bgp, afi, safi,
10304 (exact ? bgp_show_type_lcommunity_exact
10305 : bgp_show_type_lcommunity),
10306 lcom, uj);
10307 }
10308
10309 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
10310 const char *lcom, bool exact, afi_t afi,
10311 safi_t safi, bool uj)
10312 {
10313 struct community_list *list;
10314
10315 list = community_list_lookup(bgp_clist, lcom, 0,
10316 LARGE_COMMUNITY_LIST_MASTER);
10317 if (list == NULL) {
10318 vty_out(vty, "%% %s is not a valid large-community-list name\n",
10319 lcom);
10320 return CMD_WARNING;
10321 }
10322
10323 return bgp_show(vty, bgp, afi, safi,
10324 (exact ? bgp_show_type_lcommunity_list_exact
10325 : bgp_show_type_lcommunity_list),
10326 list, uj);
10327 }
10328
10329 DEFUN (show_ip_bgp_large_community_list,
10330 show_ip_bgp_large_community_list_cmd,
10331 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community-list <(1-500)|WORD> [exact-match] [json]",
10332 SHOW_STR
10333 IP_STR
10334 BGP_STR
10335 BGP_INSTANCE_HELP_STR
10336 BGP_AFI_HELP_STR
10337 BGP_SAFI_WITH_LABEL_HELP_STR
10338 "Display routes matching the large-community-list\n"
10339 "large-community-list number\n"
10340 "large-community-list name\n"
10341 "Exact match of the large-communities\n"
10342 JSON_STR)
10343 {
10344 char *vrf = NULL;
10345 afi_t afi = AFI_IP6;
10346 safi_t safi = SAFI_UNICAST;
10347 int idx = 0;
10348 bool exact_match = 0;
10349
10350 if (argv_find(argv, argc, "ip", &idx))
10351 afi = AFI_IP;
10352 if (argv_find(argv, argc, "view", &idx)
10353 || argv_find(argv, argc, "vrf", &idx))
10354 vrf = argv[++idx]->arg;
10355 if (argv_find(argv, argc, "ipv4", &idx)
10356 || argv_find(argv, argc, "ipv6", &idx)) {
10357 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
10358 if (argv_find(argv, argc, "unicast", &idx)
10359 || argv_find(argv, argc, "multicast", &idx))
10360 safi = bgp_vty_safi_from_str(argv[idx]->text);
10361 }
10362
10363 bool uj = use_json(argc, argv);
10364
10365 struct bgp *bgp = bgp_lookup_by_name(vrf);
10366 if (bgp == NULL) {
10367 vty_out(vty, "Can't find BGP instance %s\n", vrf);
10368 return CMD_WARNING;
10369 }
10370
10371 argv_find(argv, argc, "large-community-list", &idx);
10372
10373 const char *clist_number_or_name = argv[++idx]->arg;
10374
10375 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
10376 exact_match = 1;
10377
10378 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
10379 exact_match, afi, safi, uj);
10380 }
10381 DEFUN (show_ip_bgp_large_community,
10382 show_ip_bgp_large_community_cmd,
10383 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
10384 SHOW_STR
10385 IP_STR
10386 BGP_STR
10387 BGP_INSTANCE_HELP_STR
10388 BGP_AFI_HELP_STR
10389 BGP_SAFI_WITH_LABEL_HELP_STR
10390 "Display routes matching the large-communities\n"
10391 "List of large-community numbers\n"
10392 "Exact match of the large-communities\n"
10393 JSON_STR)
10394 {
10395 char *vrf = NULL;
10396 afi_t afi = AFI_IP6;
10397 safi_t safi = SAFI_UNICAST;
10398 int idx = 0;
10399 bool exact_match = 0;
10400
10401 if (argv_find(argv, argc, "ip", &idx))
10402 afi = AFI_IP;
10403 if (argv_find(argv, argc, "view", &idx)
10404 || argv_find(argv, argc, "vrf", &idx))
10405 vrf = argv[++idx]->arg;
10406 if (argv_find(argv, argc, "ipv4", &idx)
10407 || argv_find(argv, argc, "ipv6", &idx)) {
10408 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
10409 if (argv_find(argv, argc, "unicast", &idx)
10410 || argv_find(argv, argc, "multicast", &idx))
10411 safi = bgp_vty_safi_from_str(argv[idx]->text);
10412 }
10413
10414 bool uj = use_json(argc, argv);
10415
10416 struct bgp *bgp = bgp_lookup_by_name(vrf);
10417 if (bgp == NULL) {
10418 vty_out(vty, "Can't find BGP instance %s\n", vrf);
10419 return CMD_WARNING;
10420 }
10421
10422 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
10423 if (argv_find(argv, argc, "exact-match", &idx))
10424 exact_match = 1;
10425 return bgp_show_lcommunity(vty, bgp, argc, argv,
10426 exact_match, afi, safi, uj);
10427 } else
10428 return bgp_show(vty, bgp, afi, safi,
10429 bgp_show_type_lcommunity_all, NULL, uj);
10430 }
10431
10432 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
10433 safi_t safi);
10434
10435
10436 /* BGP route print out function without JSON */
10437 DEFUN (show_ip_bgp,
10438 show_ip_bgp_cmd,
10439 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
10440 <dampening <parameters>\
10441 |route-map WORD\
10442 |prefix-list WORD\
10443 |filter-list WORD\
10444 |statistics\
10445 |community-list <(1-500)|WORD> [exact-match]\
10446 |A.B.C.D/M longer-prefixes\
10447 |X:X::X:X/M longer-prefixes\
10448 >",
10449 SHOW_STR
10450 IP_STR
10451 BGP_STR
10452 BGP_INSTANCE_HELP_STR
10453 BGP_AFI_HELP_STR
10454 BGP_SAFI_WITH_LABEL_HELP_STR
10455 "Display detailed information about dampening\n"
10456 "Display detail of configured dampening parameters\n"
10457 "Display routes matching the route-map\n"
10458 "A route-map to match on\n"
10459 "Display routes conforming to the prefix-list\n"
10460 "Prefix-list name\n"
10461 "Display routes conforming to the filter-list\n"
10462 "Regular expression access list name\n"
10463 "BGP RIB advertisement statistics\n"
10464 "Display routes matching the community-list\n"
10465 "community-list number\n"
10466 "community-list name\n"
10467 "Exact match of the communities\n"
10468 "IPv4 prefix\n"
10469 "Display route and more specific routes\n"
10470 "IPv6 prefix\n"
10471 "Display route and more specific routes\n")
10472 {
10473 afi_t afi = AFI_IP6;
10474 safi_t safi = SAFI_UNICAST;
10475 int exact_match = 0;
10476 struct bgp *bgp = NULL;
10477 int idx = 0;
10478
10479 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10480 &bgp, false);
10481 if (!idx)
10482 return CMD_WARNING;
10483
10484 if (argv_find(argv, argc, "dampening", &idx)) {
10485 if (argv_find(argv, argc, "parameters", &idx))
10486 return bgp_show_dampening_parameters(vty, afi, safi);
10487 }
10488
10489 if (argv_find(argv, argc, "prefix-list", &idx))
10490 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
10491 safi, bgp_show_type_prefix_list);
10492
10493 if (argv_find(argv, argc, "filter-list", &idx))
10494 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
10495 safi, bgp_show_type_filter_list);
10496
10497 if (argv_find(argv, argc, "statistics", &idx))
10498 return bgp_table_stats(vty, bgp, afi, safi);
10499
10500 if (argv_find(argv, argc, "route-map", &idx))
10501 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
10502 safi, bgp_show_type_route_map);
10503
10504 if (argv_find(argv, argc, "community-list", &idx)) {
10505 const char *clist_number_or_name = argv[++idx]->arg;
10506 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
10507 exact_match = 1;
10508 return bgp_show_community_list(vty, bgp, clist_number_or_name,
10509 exact_match, afi, safi);
10510 }
10511 /* prefix-longer */
10512 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
10513 || argv_find(argv, argc, "X:X::X:X/M", &idx))
10514 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
10515 safi,
10516 bgp_show_type_prefix_longer);
10517
10518 return CMD_WARNING;
10519 }
10520
10521 /* BGP route print out function with JSON */
10522 DEFUN (show_ip_bgp_json,
10523 show_ip_bgp_json_cmd,
10524 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\
10525 [cidr-only\
10526 |dampening <flap-statistics|dampened-paths>\
10527 |community [AA:NN|local-AS|no-advertise|no-export\
10528 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
10529 |accept-own|accept-own-nexthop|route-filter-v6\
10530 |route-filter-v4|route-filter-translated-v6\
10531 |route-filter-translated-v4] [exact-match]\
10532 ] [json]",
10533 SHOW_STR
10534 IP_STR
10535 BGP_STR
10536 BGP_INSTANCE_HELP_STR
10537 BGP_AFI_HELP_STR
10538 BGP_SAFI_WITH_LABEL_HELP_STR
10539 "Display only routes with non-natural netmasks\n"
10540 "Display detailed information about dampening\n"
10541 "Display flap statistics of routes\n"
10542 "Display paths suppressed due to dampening\n"
10543 "Display routes matching the communities\n"
10544 COMMUNITY_AANN_STR
10545 "Do not send outside local AS (well-known community)\n"
10546 "Do not advertise to any peer (well-known community)\n"
10547 "Do not export to next AS (well-known community)\n"
10548 "Graceful shutdown (well-known community)\n"
10549 "Do not export to any peer (well-known community)\n"
10550 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
10551 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
10552 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
10553 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
10554 "Should accept VPN route with local nexthop (well-known community)\n"
10555 "RT VPNv6 route filtering (well-known community)\n"
10556 "RT VPNv4 route filtering (well-known community)\n"
10557 "RT translated VPNv6 route filtering (well-known community)\n"
10558 "RT translated VPNv4 route filtering (well-known community)\n"
10559 "Exact match of the communities\n"
10560 JSON_STR)
10561 {
10562 afi_t afi = AFI_IP6;
10563 safi_t safi = SAFI_UNICAST;
10564 enum bgp_show_type sh_type = bgp_show_type_normal;
10565 struct bgp *bgp = NULL;
10566 int idx = 0;
10567 int exact_match = 0;
10568 bool uj = use_json(argc, argv);
10569
10570 if (uj)
10571 argc--;
10572
10573 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10574 &bgp, uj);
10575 if (!idx)
10576 return CMD_WARNING;
10577
10578 if (argv_find(argv, argc, "cidr-only", &idx))
10579 return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only,
10580 NULL, uj);
10581
10582 if (argv_find(argv, argc, "dampening", &idx)) {
10583 if (argv_find(argv, argc, "dampened-paths", &idx))
10584 return bgp_show(vty, bgp, afi, safi,
10585 bgp_show_type_dampend_paths, NULL, uj);
10586 else if (argv_find(argv, argc, "flap-statistics", &idx))
10587 return bgp_show(vty, bgp, afi, safi,
10588 bgp_show_type_flap_statistics, NULL,
10589 uj);
10590 }
10591
10592 if (argv_find(argv, argc, "community", &idx)) {
10593 char *maybecomm = NULL;
10594 char *community = NULL;
10595
10596 if (idx + 1 < argc) {
10597 if (argv[idx + 1]->type == VARIABLE_TKN)
10598 maybecomm = argv[idx + 1]->arg;
10599 else
10600 maybecomm = argv[idx + 1]->text;
10601 }
10602
10603 if (maybecomm && !strmatch(maybecomm, "json")
10604 && !strmatch(maybecomm, "exact-match"))
10605 community = maybecomm;
10606
10607 if (argv_find(argv, argc, "exact-match", &idx))
10608 exact_match = 1;
10609
10610 if (community)
10611 return bgp_show_community(vty, bgp, community,
10612 exact_match, afi, safi, uj);
10613 else
10614 return (bgp_show(vty, bgp, afi, safi,
10615 bgp_show_type_community_all, NULL,
10616 uj));
10617 }
10618
10619 return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
10620 }
10621
10622 DEFUN (show_ip_bgp_route,
10623 show_ip_bgp_route_cmd,
10624 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]"
10625 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
10626 SHOW_STR
10627 IP_STR
10628 BGP_STR
10629 BGP_INSTANCE_HELP_STR
10630 BGP_AFI_HELP_STR
10631 BGP_SAFI_WITH_LABEL_HELP_STR
10632 "Network in the BGP routing table to display\n"
10633 "IPv4 prefix\n"
10634 "Network in the BGP routing table to display\n"
10635 "IPv6 prefix\n"
10636 "Display only the bestpath\n"
10637 "Display only multipaths\n"
10638 JSON_STR)
10639 {
10640 int prefix_check = 0;
10641
10642 afi_t afi = AFI_IP6;
10643 safi_t safi = SAFI_UNICAST;
10644 char *prefix = NULL;
10645 struct bgp *bgp = NULL;
10646 enum bgp_path_type path_type;
10647 bool uj = use_json(argc, argv);
10648
10649 int idx = 0;
10650
10651 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10652 &bgp, uj);
10653 if (!idx)
10654 return CMD_WARNING;
10655
10656 if (!bgp) {
10657 vty_out(vty,
10658 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
10659 return CMD_WARNING;
10660 }
10661
10662 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
10663 if (argv_find(argv, argc, "A.B.C.D", &idx)
10664 || argv_find(argv, argc, "X:X::X:X", &idx))
10665 prefix_check = 0;
10666 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
10667 || argv_find(argv, argc, "X:X::X:X/M", &idx))
10668 prefix_check = 1;
10669
10670 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
10671 && afi != AFI_IP6) {
10672 vty_out(vty,
10673 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
10674 return CMD_WARNING;
10675 }
10676 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
10677 && afi != AFI_IP) {
10678 vty_out(vty,
10679 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
10680 return CMD_WARNING;
10681 }
10682
10683 prefix = argv[idx]->arg;
10684
10685 /* [<bestpath|multipath>] */
10686 if (argv_find(argv, argc, "bestpath", &idx))
10687 path_type = BGP_PATH_SHOW_BESTPATH;
10688 else if (argv_find(argv, argc, "multipath", &idx))
10689 path_type = BGP_PATH_SHOW_MULTIPATH;
10690 else
10691 path_type = BGP_PATH_SHOW_ALL;
10692
10693 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
10694 path_type, uj);
10695 }
10696
10697 DEFUN (show_ip_bgp_regexp,
10698 show_ip_bgp_regexp_cmd,
10699 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
10700 SHOW_STR
10701 IP_STR
10702 BGP_STR
10703 BGP_INSTANCE_HELP_STR
10704 BGP_AFI_HELP_STR
10705 BGP_SAFI_WITH_LABEL_HELP_STR
10706 "Display routes matching the AS path regular expression\n"
10707 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
10708 JSON_STR)
10709 {
10710 afi_t afi = AFI_IP6;
10711 safi_t safi = SAFI_UNICAST;
10712 struct bgp *bgp = NULL;
10713 bool uj = use_json(argc, argv);
10714 char *regstr = NULL;
10715
10716 int idx = 0;
10717 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10718 &bgp, false);
10719 if (!idx)
10720 return CMD_WARNING;
10721
10722 // get index of regex
10723 if (argv_find(argv, argc, "REGEX", &idx))
10724 regstr = argv[idx]->arg;
10725
10726 assert(regstr);
10727 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
10728 bgp_show_type_regexp, uj);
10729 }
10730
10731 DEFUN (show_ip_bgp_instance_all,
10732 show_ip_bgp_instance_all_cmd,
10733 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json]",
10734 SHOW_STR
10735 IP_STR
10736 BGP_STR
10737 BGP_INSTANCE_ALL_HELP_STR
10738 BGP_AFI_HELP_STR
10739 BGP_SAFI_WITH_LABEL_HELP_STR
10740 JSON_STR)
10741 {
10742 afi_t afi = AFI_IP;
10743 safi_t safi = SAFI_UNICAST;
10744 struct bgp *bgp = NULL;
10745 int idx = 0;
10746 bool uj = use_json(argc, argv);
10747
10748 if (uj)
10749 argc--;
10750
10751 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
10752 &bgp, uj);
10753 if (!idx)
10754 return CMD_WARNING;
10755
10756 bgp_show_all_instances_routes_vty(vty, afi, safi, uj);
10757 return CMD_SUCCESS;
10758 }
10759
10760 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
10761 afi_t afi, safi_t safi, enum bgp_show_type type,
10762 bool use_json)
10763 {
10764 regex_t *regex;
10765 int rc;
10766
10767 if (!config_bgp_aspath_validate(regstr)) {
10768 vty_out(vty, "Invalid character in REGEX %s\n",
10769 regstr);
10770 return CMD_WARNING_CONFIG_FAILED;
10771 }
10772
10773 regex = bgp_regcomp(regstr);
10774 if (!regex) {
10775 vty_out(vty, "Can't compile regexp %s\n", regstr);
10776 return CMD_WARNING;
10777 }
10778
10779 rc = bgp_show(vty, bgp, afi, safi, type, regex, use_json);
10780 bgp_regex_free(regex);
10781 return rc;
10782 }
10783
10784 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
10785 const char *prefix_list_str, afi_t afi,
10786 safi_t safi, enum bgp_show_type type)
10787 {
10788 struct prefix_list *plist;
10789
10790 plist = prefix_list_lookup(afi, prefix_list_str);
10791 if (plist == NULL) {
10792 vty_out(vty, "%% %s is not a valid prefix-list name\n",
10793 prefix_list_str);
10794 return CMD_WARNING;
10795 }
10796
10797 return bgp_show(vty, bgp, afi, safi, type, plist, 0);
10798 }
10799
10800 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
10801 const char *filter, afi_t afi, safi_t safi,
10802 enum bgp_show_type type)
10803 {
10804 struct as_list *as_list;
10805
10806 as_list = as_list_lookup(filter);
10807 if (as_list == NULL) {
10808 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
10809 filter);
10810 return CMD_WARNING;
10811 }
10812
10813 return bgp_show(vty, bgp, afi, safi, type, as_list, 0);
10814 }
10815
10816 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
10817 const char *rmap_str, afi_t afi, safi_t safi,
10818 enum bgp_show_type type)
10819 {
10820 struct route_map *rmap;
10821
10822 rmap = route_map_lookup_by_name(rmap_str);
10823 if (!rmap) {
10824 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
10825 return CMD_WARNING;
10826 }
10827
10828 return bgp_show(vty, bgp, afi, safi, type, rmap, 0);
10829 }
10830
10831 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
10832 const char *comstr, int exact, afi_t afi,
10833 safi_t safi, bool use_json)
10834 {
10835 struct community *com;
10836 int ret = 0;
10837
10838 com = community_str2com(comstr);
10839 if (!com) {
10840 vty_out(vty, "%% Community malformed: %s\n", comstr);
10841 return CMD_WARNING;
10842 }
10843
10844 ret = bgp_show(vty, bgp, afi, safi,
10845 (exact ? bgp_show_type_community_exact
10846 : bgp_show_type_community),
10847 com, use_json);
10848 community_free(&com);
10849
10850 return ret;
10851 }
10852
10853 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
10854 const char *com, int exact, afi_t afi,
10855 safi_t safi)
10856 {
10857 struct community_list *list;
10858
10859 list = community_list_lookup(bgp_clist, com, 0, COMMUNITY_LIST_MASTER);
10860 if (list == NULL) {
10861 vty_out(vty, "%% %s is not a valid community-list name\n", com);
10862 return CMD_WARNING;
10863 }
10864
10865 return bgp_show(vty, bgp, afi, safi,
10866 (exact ? bgp_show_type_community_list_exact
10867 : bgp_show_type_community_list),
10868 list, 0);
10869 }
10870
10871 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
10872 const char *prefix, afi_t afi, safi_t safi,
10873 enum bgp_show_type type)
10874 {
10875 int ret;
10876 struct prefix *p;
10877
10878 p = prefix_new();
10879
10880 ret = str2prefix(prefix, p);
10881 if (!ret) {
10882 vty_out(vty, "%% Malformed Prefix\n");
10883 return CMD_WARNING;
10884 }
10885
10886 ret = bgp_show(vty, bgp, afi, safi, type, p, 0);
10887 prefix_free(&p);
10888 return ret;
10889 }
10890
10891 enum bgp_stats {
10892 BGP_STATS_MAXBITLEN = 0,
10893 BGP_STATS_RIB,
10894 BGP_STATS_PREFIXES,
10895 BGP_STATS_TOTPLEN,
10896 BGP_STATS_UNAGGREGATEABLE,
10897 BGP_STATS_MAX_AGGREGATEABLE,
10898 BGP_STATS_AGGREGATES,
10899 BGP_STATS_SPACE,
10900 BGP_STATS_ASPATH_COUNT,
10901 BGP_STATS_ASPATH_MAXHOPS,
10902 BGP_STATS_ASPATH_TOTHOPS,
10903 BGP_STATS_ASPATH_MAXSIZE,
10904 BGP_STATS_ASPATH_TOTSIZE,
10905 BGP_STATS_ASN_HIGHEST,
10906 BGP_STATS_MAX,
10907 };
10908
10909 static const char *const table_stats_strs[] = {
10910 [BGP_STATS_PREFIXES] = "Total Prefixes",
10911 [BGP_STATS_TOTPLEN] = "Average prefix length",
10912 [BGP_STATS_RIB] = "Total Advertisements",
10913 [BGP_STATS_UNAGGREGATEABLE] = "Unaggregateable prefixes",
10914 [BGP_STATS_MAX_AGGREGATEABLE] =
10915 "Maximum aggregateable prefixes",
10916 [BGP_STATS_AGGREGATES] = "BGP Aggregate advertisements",
10917 [BGP_STATS_SPACE] = "Address space advertised",
10918 [BGP_STATS_ASPATH_COUNT] = "Advertisements with paths",
10919 [BGP_STATS_ASPATH_MAXHOPS] = "Longest AS-Path (hops)",
10920 [BGP_STATS_ASPATH_MAXSIZE] = "Largest AS-Path (bytes)",
10921 [BGP_STATS_ASPATH_TOTHOPS] = "Average AS-Path length (hops)",
10922 [BGP_STATS_ASPATH_TOTSIZE] = "Average AS-Path size (bytes)",
10923 [BGP_STATS_ASN_HIGHEST] = "Highest public ASN",
10924 [BGP_STATS_MAX] = NULL,
10925 };
10926
10927 struct bgp_table_stats {
10928 struct bgp_table *table;
10929 unsigned long long counts[BGP_STATS_MAX];
10930 double total_space;
10931 };
10932
10933 #if 0
10934 #define TALLY_SIGFIG 100000
10935 static unsigned long
10936 ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
10937 {
10938 unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
10939 unsigned long res = (newtot * TALLY_SIGFIG) / count;
10940 unsigned long ret = newtot / count;
10941
10942 if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
10943 return ret + 1;
10944 else
10945 return ret;
10946 }
10947 #endif
10948
10949 static void bgp_table_stats_rn(struct bgp_node *rn, struct bgp_node *top,
10950 struct bgp_table_stats *ts, unsigned int space)
10951 {
10952 struct bgp_node *prn = bgp_node_parent_nolock(rn);
10953 struct bgp_path_info *pi;
10954
10955 if (rn == top)
10956 return;
10957
10958 if (!bgp_node_has_bgp_path_info_data(rn))
10959 return;
10960
10961 ts->counts[BGP_STATS_PREFIXES]++;
10962 ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
10963
10964 #if 0
10965 ts->counts[BGP_STATS_AVGPLEN]
10966 = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
10967 ts->counts[BGP_STATS_AVGPLEN],
10968 rn->p.prefixlen);
10969 #endif
10970
10971 /* check if the prefix is included by any other announcements */
10972 while (prn && !bgp_node_has_bgp_path_info_data(prn))
10973 prn = bgp_node_parent_nolock(prn);
10974
10975 if (prn == NULL || prn == top) {
10976 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
10977 /* announced address space */
10978 if (space)
10979 ts->total_space += pow(2.0, space - rn->p.prefixlen);
10980 } else if (bgp_node_has_bgp_path_info_data(prn))
10981 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
10982
10983
10984 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
10985 ts->counts[BGP_STATS_RIB]++;
10986
10987 if (CHECK_FLAG(pi->attr->flag,
10988 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
10989 ts->counts[BGP_STATS_AGGREGATES]++;
10990
10991 /* as-path stats */
10992 if (pi->attr->aspath) {
10993 unsigned int hops = aspath_count_hops(pi->attr->aspath);
10994 unsigned int size = aspath_size(pi->attr->aspath);
10995 as_t highest = aspath_highest(pi->attr->aspath);
10996
10997 ts->counts[BGP_STATS_ASPATH_COUNT]++;
10998
10999 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
11000 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
11001
11002 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
11003 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
11004
11005 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
11006 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
11007 #if 0
11008 ts->counts[BGP_STATS_ASPATH_AVGHOPS]
11009 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
11010 ts->counts[BGP_STATS_ASPATH_AVGHOPS],
11011 hops);
11012 ts->counts[BGP_STATS_ASPATH_AVGSIZE]
11013 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
11014 ts->counts[BGP_STATS_ASPATH_AVGSIZE],
11015 size);
11016 #endif
11017 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
11018 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
11019 }
11020 }
11021 }
11022
11023 static int bgp_table_stats_walker(struct thread *t)
11024 {
11025 struct bgp_node *rn, *nrn;
11026 struct bgp_node *top;
11027 struct bgp_table_stats *ts = THREAD_ARG(t);
11028 unsigned int space = 0;
11029
11030 if (!(top = bgp_table_top(ts->table)))
11031 return 0;
11032
11033 switch (ts->table->afi) {
11034 case AFI_IP:
11035 space = IPV4_MAX_BITLEN;
11036 break;
11037 case AFI_IP6:
11038 space = IPV6_MAX_BITLEN;
11039 break;
11040 default:
11041 return 0;
11042 }
11043
11044 ts->counts[BGP_STATS_MAXBITLEN] = space;
11045
11046 for (rn = top; rn; rn = bgp_route_next(rn)) {
11047 if (ts->table->safi == SAFI_MPLS_VPN) {
11048 struct bgp_table *table;
11049
11050 table = bgp_node_get_bgp_table_info(rn);
11051 if (!table)
11052 continue;
11053
11054 top = bgp_table_top(table);
11055 for (nrn = bgp_table_top(table); nrn;
11056 nrn = bgp_route_next(nrn))
11057 bgp_table_stats_rn(nrn, top, ts, space);
11058 } else {
11059 bgp_table_stats_rn(rn, top, ts, space);
11060 }
11061 }
11062
11063 return 0;
11064 }
11065
11066 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
11067 safi_t safi)
11068 {
11069 struct bgp_table_stats ts;
11070 unsigned int i;
11071
11072 if (!bgp->rib[afi][safi]) {
11073 vty_out(vty, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
11074 afi, safi);
11075 return CMD_WARNING;
11076 }
11077
11078 vty_out(vty, "BGP %s RIB statistics\n", get_afi_safi_str(afi, safi, false));
11079
11080 /* labeled-unicast routes live in the unicast table */
11081 if (safi == SAFI_LABELED_UNICAST)
11082 safi = SAFI_UNICAST;
11083
11084 memset(&ts, 0, sizeof(ts));
11085 ts.table = bgp->rib[afi][safi];
11086 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
11087
11088 for (i = 0; i < BGP_STATS_MAX; i++) {
11089 if (!table_stats_strs[i])
11090 continue;
11091
11092 switch (i) {
11093 #if 0
11094 case BGP_STATS_ASPATH_AVGHOPS:
11095 case BGP_STATS_ASPATH_AVGSIZE:
11096 case BGP_STATS_AVGPLEN:
11097 vty_out (vty, "%-30s: ", table_stats_strs[i]);
11098 vty_out (vty, "%12.2f",
11099 (float)ts.counts[i] / (float)TALLY_SIGFIG);
11100 break;
11101 #endif
11102 case BGP_STATS_ASPATH_TOTHOPS:
11103 case BGP_STATS_ASPATH_TOTSIZE:
11104 vty_out(vty, "%-30s: ", table_stats_strs[i]);
11105 vty_out(vty, "%12.2f",
11106 ts.counts[i]
11107 ? (float)ts.counts[i]
11108 / (float)ts.counts
11109 [BGP_STATS_ASPATH_COUNT]
11110 : 0);
11111 break;
11112 case BGP_STATS_TOTPLEN:
11113 vty_out(vty, "%-30s: ", table_stats_strs[i]);
11114 vty_out(vty, "%12.2f",
11115 ts.counts[i]
11116 ? (float)ts.counts[i]
11117 / (float)ts.counts
11118 [BGP_STATS_PREFIXES]
11119 : 0);
11120 break;
11121 case BGP_STATS_SPACE:
11122 vty_out(vty, "%-30s: ", table_stats_strs[i]);
11123 vty_out(vty, "%12g\n", ts.total_space);
11124
11125 if (afi == AFI_IP6) {
11126 vty_out(vty, "%30s: ", "/32 equivalent ");
11127 vty_out(vty, "%12g\n",
11128 ts.total_space * pow(2.0, -128 + 32));
11129 vty_out(vty, "%30s: ", "/48 equivalent ");
11130 vty_out(vty, "%12g\n",
11131 ts.total_space * pow(2.0, -128 + 48));
11132 } else {
11133 vty_out(vty, "%30s: ", "% announced ");
11134 vty_out(vty, "%12.2f\n",
11135 ts.total_space * 100. * pow(2.0, -32));
11136 vty_out(vty, "%30s: ", "/8 equivalent ");
11137 vty_out(vty, "%12.2f\n",
11138 ts.total_space * pow(2.0, -32 + 8));
11139 vty_out(vty, "%30s: ", "/24 equivalent ");
11140 vty_out(vty, "%12.2f\n",
11141 ts.total_space * pow(2.0, -32 + 24));
11142 }
11143 break;
11144 default:
11145 vty_out(vty, "%-30s: ", table_stats_strs[i]);
11146 vty_out(vty, "%12llu", ts.counts[i]);
11147 }
11148
11149 vty_out(vty, "\n");
11150 }
11151 return CMD_SUCCESS;
11152 }
11153
11154 enum bgp_pcounts {
11155 PCOUNT_ADJ_IN = 0,
11156 PCOUNT_DAMPED,
11157 PCOUNT_REMOVED,
11158 PCOUNT_HISTORY,
11159 PCOUNT_STALE,
11160 PCOUNT_VALID,
11161 PCOUNT_ALL,
11162 PCOUNT_COUNTED,
11163 PCOUNT_PFCNT, /* the figure we display to users */
11164 PCOUNT_MAX,
11165 };
11166
11167 static const char *const pcount_strs[] = {
11168 [PCOUNT_ADJ_IN] = "Adj-in",
11169 [PCOUNT_DAMPED] = "Damped",
11170 [PCOUNT_REMOVED] = "Removed",
11171 [PCOUNT_HISTORY] = "History",
11172 [PCOUNT_STALE] = "Stale",
11173 [PCOUNT_VALID] = "Valid",
11174 [PCOUNT_ALL] = "All RIB",
11175 [PCOUNT_COUNTED] = "PfxCt counted",
11176 [PCOUNT_PFCNT] = "Useable",
11177 [PCOUNT_MAX] = NULL,
11178 };
11179
11180 struct peer_pcounts {
11181 unsigned int count[PCOUNT_MAX];
11182 const struct peer *peer;
11183 const struct bgp_table *table;
11184 safi_t safi;
11185 };
11186
11187 static void bgp_peer_count_proc(struct bgp_node *rn,
11188 struct peer_pcounts *pc)
11189 {
11190 const struct bgp_adj_in *ain;
11191 const struct bgp_path_info *pi;
11192 const struct peer *peer = pc->peer;
11193
11194 for (ain = rn->adj_in; ain; ain = ain->next)
11195 if (ain->peer == peer)
11196 pc->count[PCOUNT_ADJ_IN]++;
11197
11198 for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
11199
11200 if (pi->peer != peer)
11201 continue;
11202
11203 pc->count[PCOUNT_ALL]++;
11204
11205 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
11206 pc->count[PCOUNT_DAMPED]++;
11207 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11208 pc->count[PCOUNT_HISTORY]++;
11209 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
11210 pc->count[PCOUNT_REMOVED]++;
11211 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
11212 pc->count[PCOUNT_STALE]++;
11213 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
11214 pc->count[PCOUNT_VALID]++;
11215 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
11216 pc->count[PCOUNT_PFCNT]++;
11217
11218 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
11219 pc->count[PCOUNT_COUNTED]++;
11220 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
11221 flog_err(
11222 EC_LIB_DEVELOPMENT,
11223 "Attempting to count but flags say it is unusable");
11224 } else {
11225 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
11226 flog_err(
11227 EC_LIB_DEVELOPMENT,
11228 "Not counted but flags say we should");
11229 }
11230 }
11231 }
11232
11233 static int bgp_peer_count_walker(struct thread *t)
11234 {
11235 struct bgp_node *rn, *rm;
11236 const struct bgp_table *table;
11237 struct peer_pcounts *pc = THREAD_ARG(t);
11238
11239 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
11240 || pc->safi == SAFI_EVPN) {
11241 /* Special handling for 2-level routing tables. */
11242 for (rn = bgp_table_top(pc->table); rn;
11243 rn = bgp_route_next(rn)) {
11244 table = bgp_node_get_bgp_table_info(rn);
11245 if (table != NULL)
11246 for (rm = bgp_table_top(table); rm;
11247 rm = bgp_route_next(rm))
11248 bgp_peer_count_proc(rm, pc);
11249 }
11250 } else
11251 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
11252 bgp_peer_count_proc(rn, pc);
11253
11254 return 0;
11255 }
11256
11257 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
11258 safi_t safi, bool use_json)
11259 {
11260 struct peer_pcounts pcounts = {.peer = peer};
11261 unsigned int i;
11262 json_object *json = NULL;
11263 json_object *json_loop = NULL;
11264
11265 if (use_json) {
11266 json = json_object_new_object();
11267 json_loop = json_object_new_object();
11268 }
11269
11270 if (!peer || !peer->bgp || !peer->afc[afi][safi]
11271 || !peer->bgp->rib[afi][safi]) {
11272 if (use_json) {
11273 json_object_string_add(
11274 json, "warning",
11275 "No such neighbor or address family");
11276 vty_out(vty, "%s\n", json_object_to_json_string(json));
11277 json_object_free(json);
11278 } else
11279 vty_out(vty, "%% No such neighbor or address family\n");
11280
11281 return CMD_WARNING;
11282 }
11283
11284 memset(&pcounts, 0, sizeof(pcounts));
11285 pcounts.peer = peer;
11286 pcounts.table = peer->bgp->rib[afi][safi];
11287 pcounts.safi = safi;
11288
11289 /* in-place call via thread subsystem so as to record execution time
11290 * stats for the thread-walk (i.e. ensure this can't be blamed on
11291 * on just vty_read()).
11292 */
11293 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
11294
11295 if (use_json) {
11296 json_object_string_add(json, "prefixCountsFor", peer->host);
11297 json_object_string_add(json, "multiProtocol",
11298 get_afi_safi_str(afi, safi, true));
11299 json_object_int_add(json, "pfxCounter",
11300 peer->pcount[afi][safi]);
11301
11302 for (i = 0; i < PCOUNT_MAX; i++)
11303 json_object_int_add(json_loop, pcount_strs[i],
11304 pcounts.count[i]);
11305
11306 json_object_object_add(json, "ribTableWalkCounters", json_loop);
11307
11308 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
11309 json_object_string_add(json, "pfxctDriftFor",
11310 peer->host);
11311 json_object_string_add(
11312 json, "recommended",
11313 "Please report this bug, with the above command output");
11314 }
11315 vty_out(vty, "%s\n", json_object_to_json_string_ext(
11316 json, JSON_C_TO_STRING_PRETTY));
11317 json_object_free(json);
11318 } else {
11319
11320 if (peer->hostname
11321 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
11322 vty_out(vty, "Prefix counts for %s/%s, %s\n",
11323 peer->hostname, peer->host,
11324 get_afi_safi_str(afi, safi, false));
11325 } else {
11326 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
11327 get_afi_safi_str(afi, safi, false));
11328 }
11329
11330 vty_out(vty, "PfxCt: %" PRIu32 "\n", peer->pcount[afi][safi]);
11331 vty_out(vty, "\nCounts from RIB table walk:\n\n");
11332
11333 for (i = 0; i < PCOUNT_MAX; i++)
11334 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
11335 pcounts.count[i]);
11336
11337 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
11338 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
11339 vty_out(vty,
11340 "Please report this bug, with the above command output\n");
11341 }
11342 }
11343
11344 return CMD_SUCCESS;
11345 }
11346
11347 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
11348 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
11349 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] "
11350 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
11351 SHOW_STR
11352 IP_STR
11353 BGP_STR
11354 BGP_INSTANCE_HELP_STR
11355 BGP_AFI_HELP_STR
11356 BGP_SAFI_HELP_STR
11357 "Detailed information on TCP and BGP neighbor connections\n"
11358 "Neighbor to display information about\n"
11359 "Neighbor to display information about\n"
11360 "Neighbor on BGP configured interface\n"
11361 "Display detailed prefix count information\n"
11362 JSON_STR)
11363 {
11364 afi_t afi = AFI_IP6;
11365 safi_t safi = SAFI_UNICAST;
11366 struct peer *peer;
11367 int idx = 0;
11368 struct bgp *bgp = NULL;
11369 bool uj = use_json(argc, argv);
11370
11371 if (uj)
11372 argc--;
11373
11374 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11375 &bgp, uj);
11376 if (!idx)
11377 return CMD_WARNING;
11378
11379 argv_find(argv, argc, "neighbors", &idx);
11380 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
11381 if (!peer)
11382 return CMD_WARNING;
11383
11384 return bgp_peer_counts(vty, peer, afi, safi, uj);
11385 }
11386
11387 #ifdef KEEP_OLD_VPN_COMMANDS
11388 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
11389 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
11390 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
11391 SHOW_STR
11392 IP_STR
11393 BGP_STR
11394 BGP_VPNVX_HELP_STR
11395 "Display information about all VPNv4 NLRIs\n"
11396 "Detailed information on TCP and BGP neighbor connections\n"
11397 "Neighbor to display information about\n"
11398 "Neighbor to display information about\n"
11399 "Neighbor on BGP configured interface\n"
11400 "Display detailed prefix count information\n"
11401 JSON_STR)
11402 {
11403 int idx_peer = 6;
11404 struct peer *peer;
11405 bool uj = use_json(argc, argv);
11406
11407 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
11408 if (!peer)
11409 return CMD_WARNING;
11410
11411 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
11412 }
11413
11414 DEFUN (show_ip_bgp_vpn_all_route_prefix,
11415 show_ip_bgp_vpn_all_route_prefix_cmd,
11416 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
11417 SHOW_STR
11418 IP_STR
11419 BGP_STR
11420 BGP_VPNVX_HELP_STR
11421 "Display information about all VPNv4 NLRIs\n"
11422 "Network in the BGP routing table to display\n"
11423 "Network in the BGP routing table to display\n"
11424 JSON_STR)
11425 {
11426 int idx = 0;
11427 char *network = NULL;
11428 struct bgp *bgp = bgp_get_default();
11429 if (!bgp) {
11430 vty_out(vty, "Can't find default instance\n");
11431 return CMD_WARNING;
11432 }
11433
11434 if (argv_find(argv, argc, "A.B.C.D", &idx))
11435 network = argv[idx]->arg;
11436 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
11437 network = argv[idx]->arg;
11438 else {
11439 vty_out(vty, "Unable to figure out Network\n");
11440 return CMD_WARNING;
11441 }
11442
11443 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
11444 BGP_PATH_SHOW_ALL, use_json(argc, argv));
11445 }
11446 #endif /* KEEP_OLD_VPN_COMMANDS */
11447
11448 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
11449 show_bgp_l2vpn_evpn_route_prefix_cmd,
11450 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
11451 SHOW_STR
11452 BGP_STR
11453 L2VPN_HELP_STR
11454 EVPN_HELP_STR
11455 "Network in the BGP routing table to display\n"
11456 "Network in the BGP routing table to display\n"
11457 "Network in the BGP routing table to display\n"
11458 "Network in the BGP routing table to display\n"
11459 JSON_STR)
11460 {
11461 int idx = 0;
11462 char *network = NULL;
11463 int prefix_check = 0;
11464
11465 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
11466 argv_find(argv, argc, "X:X::X:X", &idx))
11467 network = argv[idx]->arg;
11468 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
11469 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
11470 network = argv[idx]->arg;
11471 prefix_check = 1;
11472 } else {
11473 vty_out(vty, "Unable to figure out Network\n");
11474 return CMD_WARNING;
11475 }
11476 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
11477 prefix_check, BGP_PATH_SHOW_ALL,
11478 use_json(argc, argv));
11479 }
11480
11481 static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
11482 safi_t safi, enum bgp_show_adj_route_type type,
11483 const char *rmap_name, bool use_json,
11484 json_object *json)
11485 {
11486 struct bgp_table *table;
11487 struct bgp_adj_in *ain;
11488 struct bgp_adj_out *adj;
11489 unsigned long output_count;
11490 unsigned long filtered_count;
11491 struct bgp_node *rn;
11492 int header1 = 1;
11493 struct bgp *bgp;
11494 int header2 = 1;
11495 struct attr attr;
11496 int ret;
11497 struct update_subgroup *subgrp;
11498 json_object *json_scode = NULL;
11499 json_object *json_ocode = NULL;
11500 json_object *json_ar = NULL;
11501 struct peer_af *paf;
11502 bool route_filtered;
11503
11504 if (use_json) {
11505 json_scode = json_object_new_object();
11506 json_ocode = json_object_new_object();
11507 json_ar = json_object_new_object();
11508
11509 json_object_string_add(json_scode, "suppressed", "s");
11510 json_object_string_add(json_scode, "damped", "d");
11511 json_object_string_add(json_scode, "history", "h");
11512 json_object_string_add(json_scode, "valid", "*");
11513 json_object_string_add(json_scode, "best", ">");
11514 json_object_string_add(json_scode, "multipath", "=");
11515 json_object_string_add(json_scode, "internal", "i");
11516 json_object_string_add(json_scode, "ribFailure", "r");
11517 json_object_string_add(json_scode, "stale", "S");
11518 json_object_string_add(json_scode, "removed", "R");
11519
11520 json_object_string_add(json_ocode, "igp", "i");
11521 json_object_string_add(json_ocode, "egp", "e");
11522 json_object_string_add(json_ocode, "incomplete", "?");
11523 }
11524
11525 bgp = peer->bgp;
11526
11527 if (!bgp) {
11528 if (use_json) {
11529 json_object_string_add(json, "alert", "no BGP");
11530 vty_out(vty, "%s\n", json_object_to_json_string(json));
11531 json_object_free(json);
11532 } else
11533 vty_out(vty, "%% No bgp\n");
11534 return;
11535 }
11536
11537 /* labeled-unicast routes live in the unicast table */
11538 if (safi == SAFI_LABELED_UNICAST)
11539 table = bgp->rib[afi][SAFI_UNICAST];
11540 else
11541 table = bgp->rib[afi][safi];
11542
11543 output_count = filtered_count = 0;
11544 subgrp = peer_subgroup(peer, afi, safi);
11545
11546 if (type == bgp_show_adj_route_advertised && subgrp
11547 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
11548 if (use_json) {
11549 json_object_int_add(json, "bgpTableVersion",
11550 table->version);
11551 json_object_string_add(json, "bgpLocalRouterId",
11552 inet_ntoa(bgp->router_id));
11553 json_object_int_add(json, "defaultLocPrf",
11554 bgp->default_local_pref);
11555 json_object_int_add(json, "localAS", bgp->as);
11556 json_object_object_add(json, "bgpStatusCodes",
11557 json_scode);
11558 json_object_object_add(json, "bgpOriginCodes",
11559 json_ocode);
11560 json_object_string_add(
11561 json, "bgpOriginatingDefaultNetwork",
11562 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
11563 } else {
11564 vty_out(vty, "BGP table version is %" PRIu64
11565 ", local router ID is %s, vrf id ",
11566 table->version, inet_ntoa(bgp->router_id));
11567 if (bgp->vrf_id == VRF_UNKNOWN)
11568 vty_out(vty, "%s", VRFID_NONE_STR);
11569 else
11570 vty_out(vty, "%u", bgp->vrf_id);
11571 vty_out(vty, "\n");
11572 vty_out(vty, "Default local pref %u, ",
11573 bgp->default_local_pref);
11574 vty_out(vty, "local AS %u\n", bgp->as);
11575 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11576 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11577 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11578
11579 vty_out(vty, "Originating default network %s\n\n",
11580 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
11581 }
11582 header1 = 0;
11583 }
11584
11585 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
11586 if (type == bgp_show_adj_route_received
11587 || type == bgp_show_adj_route_filtered) {
11588 for (ain = rn->adj_in; ain; ain = ain->next) {
11589 if (ain->peer != peer)
11590 continue;
11591
11592 if (header1) {
11593 if (use_json) {
11594 json_object_int_add(
11595 json, "bgpTableVersion",
11596 0);
11597 json_object_string_add(
11598 json,
11599 "bgpLocalRouterId",
11600 inet_ntoa(
11601 bgp->router_id));
11602 json_object_int_add(json,
11603 "defaultLocPrf",
11604 bgp->default_local_pref);
11605 json_object_int_add(json,
11606 "localAS", bgp->as);
11607 json_object_object_add(
11608 json, "bgpStatusCodes",
11609 json_scode);
11610 json_object_object_add(
11611 json, "bgpOriginCodes",
11612 json_ocode);
11613 } else {
11614 vty_out(vty,
11615 "BGP table version is 0, local router ID is %s, vrf id ",
11616 inet_ntoa(
11617 bgp->router_id));
11618 if (bgp->vrf_id == VRF_UNKNOWN)
11619 vty_out(vty, "%s",
11620 VRFID_NONE_STR);
11621 else
11622 vty_out(vty, "%u",
11623 bgp->vrf_id);
11624 vty_out(vty, "\n");
11625 vty_out(vty,
11626 "Default local pref %u, ",
11627 bgp->default_local_pref);
11628 vty_out(vty, "local AS %u\n",
11629 bgp->as);
11630 vty_out(vty,
11631 BGP_SHOW_SCODE_HEADER);
11632 vty_out(vty,
11633 BGP_SHOW_NCODE_HEADER);
11634 vty_out(vty,
11635 BGP_SHOW_OCODE_HEADER);
11636 }
11637 header1 = 0;
11638 }
11639 if (header2) {
11640 if (!use_json)
11641 vty_out(vty, BGP_SHOW_HEADER);
11642 header2 = 0;
11643 }
11644
11645 attr = *ain->attr;
11646 route_filtered = false;
11647
11648 /* Filter prefix using distribute list,
11649 * filter list or prefix list
11650 */
11651 if ((bgp_input_filter(peer, &rn->p, &attr, afi,
11652 safi)) == FILTER_DENY)
11653 route_filtered = true;
11654
11655 /* Filter prefix using route-map */
11656 ret = bgp_input_modifier(peer, &rn->p, &attr,
11657 afi, safi, rmap_name, NULL, 0,
11658 NULL);
11659
11660 if (type == bgp_show_adj_route_filtered &&
11661 !route_filtered && ret != RMAP_DENY) {
11662 bgp_attr_undup(&attr, ain->attr);
11663 continue;
11664 }
11665
11666 if (type == bgp_show_adj_route_received &&
11667 (route_filtered || ret == RMAP_DENY))
11668 filtered_count++;
11669
11670 route_vty_out_tmp(vty, &rn->p, &attr, safi,
11671 use_json, json_ar);
11672 bgp_attr_undup(&attr, ain->attr);
11673 output_count++;
11674 }
11675 } else if (type == bgp_show_adj_route_advertised) {
11676 RB_FOREACH (adj, bgp_adj_out_rb, &rn->adj_out)
11677 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
11678 if (paf->peer != peer || !adj->attr)
11679 continue;
11680
11681 if (header1) {
11682 if (use_json) {
11683 json_object_int_add(
11684 json,
11685 "bgpTableVersion",
11686 table->version);
11687 json_object_string_add(
11688 json,
11689 "bgpLocalRouterId",
11690 inet_ntoa(
11691 bgp->router_id));
11692 json_object_int_add(
11693 json, "defaultLocPrf",
11694 bgp->default_local_pref
11695 );
11696 json_object_int_add(
11697 json, "localAS",
11698 bgp->as);
11699 json_object_object_add(
11700 json,
11701 "bgpStatusCodes",
11702 json_scode);
11703 json_object_object_add(
11704 json,
11705 "bgpOriginCodes",
11706 json_ocode);
11707 } else {
11708 vty_out(vty,
11709 "BGP table version is %" PRIu64
11710 ", local router ID is %s, vrf id ",
11711 table->version,
11712 inet_ntoa(
11713 bgp->router_id));
11714 if (bgp->vrf_id ==
11715 VRF_UNKNOWN)
11716 vty_out(vty,
11717 "%s",
11718 VRFID_NONE_STR);
11719 else
11720 vty_out(vty,
11721 "%u",
11722 bgp->vrf_id);
11723 vty_out(vty, "\n");
11724 vty_out(vty,
11725 "Default local pref %u, ",
11726 bgp->default_local_pref
11727 );
11728 vty_out(vty,
11729 "local AS %u\n",
11730 bgp->as);
11731 vty_out(vty,
11732 BGP_SHOW_SCODE_HEADER);
11733 vty_out(vty,
11734 BGP_SHOW_NCODE_HEADER);
11735 vty_out(vty,
11736 BGP_SHOW_OCODE_HEADER);
11737 }
11738 header1 = 0;
11739 }
11740 if (header2) {
11741 if (!use_json)
11742 vty_out(vty,
11743 BGP_SHOW_HEADER);
11744 header2 = 0;
11745 }
11746
11747 attr = *adj->attr;
11748 ret = bgp_output_modifier(
11749 peer, &rn->p, &attr, afi, safi,
11750 rmap_name);
11751
11752 if (ret != RMAP_DENY) {
11753 route_vty_out_tmp(vty, &rn->p,
11754 &attr, safi,
11755 use_json,
11756 json_ar);
11757 output_count++;
11758 } else {
11759 filtered_count++;
11760 }
11761
11762 bgp_attr_undup(&attr, adj->attr);
11763 }
11764 }
11765 }
11766
11767 if (use_json) {
11768 json_object_object_add(json, "advertisedRoutes", json_ar);
11769 json_object_int_add(json, "totalPrefixCounter", output_count);
11770 json_object_int_add(json, "filteredPrefixCounter",
11771 filtered_count);
11772
11773 vty_out(vty, "%s\n", json_object_to_json_string_ext(
11774 json, JSON_C_TO_STRING_PRETTY));
11775 json_object_free(json);
11776 } else if (output_count > 0) {
11777 if (filtered_count > 0)
11778 vty_out(vty,
11779 "\nTotal number of prefixes %ld (%ld filtered)\n",
11780 output_count, filtered_count);
11781 else
11782 vty_out(vty, "\nTotal number of prefixes %ld\n",
11783 output_count);
11784 }
11785 }
11786
11787 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
11788 safi_t safi, enum bgp_show_adj_route_type type,
11789 const char *rmap_name, bool use_json)
11790 {
11791 json_object *json = NULL;
11792
11793 if (use_json)
11794 json = json_object_new_object();
11795
11796 if (!peer || !peer->afc[afi][safi]) {
11797 if (use_json) {
11798 json_object_string_add(
11799 json, "warning",
11800 "No such neighbor or address family");
11801 vty_out(vty, "%s\n", json_object_to_json_string(json));
11802 json_object_free(json);
11803 } else
11804 vty_out(vty, "%% No such neighbor or address family\n");
11805
11806 return CMD_WARNING;
11807 }
11808
11809 if ((type == bgp_show_adj_route_received
11810 || type == bgp_show_adj_route_filtered)
11811 && !CHECK_FLAG(peer->af_flags[afi][safi],
11812 PEER_FLAG_SOFT_RECONFIG)) {
11813 if (use_json) {
11814 json_object_string_add(
11815 json, "warning",
11816 "Inbound soft reconfiguration not enabled");
11817 vty_out(vty, "%s\n", json_object_to_json_string(json));
11818 json_object_free(json);
11819 } else
11820 vty_out(vty,
11821 "%% Inbound soft reconfiguration not enabled\n");
11822
11823 return CMD_WARNING;
11824 }
11825
11826 show_adj_route(vty, peer, afi, safi, type, rmap_name, use_json, json);
11827
11828 return CMD_SUCCESS;
11829 }
11830
11831 DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
11832 show_ip_bgp_instance_neighbor_advertised_route_cmd,
11833 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
11834 "neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map WORD] [json]",
11835 SHOW_STR
11836 IP_STR
11837 BGP_STR
11838 BGP_INSTANCE_HELP_STR
11839 BGP_AFI_HELP_STR
11840 BGP_SAFI_WITH_LABEL_HELP_STR
11841 "Detailed information on TCP and BGP neighbor connections\n"
11842 "Neighbor to display information about\n"
11843 "Neighbor to display information about\n"
11844 "Neighbor on BGP configured interface\n"
11845 "Display the routes advertised to a BGP neighbor\n"
11846 "Display the received routes from neighbor\n"
11847 "Display the filtered routes received from neighbor\n"
11848 "Route-map to modify the attributes\n"
11849 "Name of the route map\n"
11850 JSON_STR)
11851 {
11852 afi_t afi = AFI_IP6;
11853 safi_t safi = SAFI_UNICAST;
11854 char *rmap_name = NULL;
11855 char *peerstr = NULL;
11856 struct bgp *bgp = NULL;
11857 struct peer *peer;
11858 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
11859 int idx = 0;
11860 bool uj = use_json(argc, argv);
11861
11862 if (uj)
11863 argc--;
11864
11865 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11866 &bgp, uj);
11867 if (!idx)
11868 return CMD_WARNING;
11869
11870 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11871 argv_find(argv, argc, "neighbors", &idx);
11872 peerstr = argv[++idx]->arg;
11873
11874 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
11875 if (!peer)
11876 return CMD_WARNING;
11877
11878 if (argv_find(argv, argc, "advertised-routes", &idx))
11879 type = bgp_show_adj_route_advertised;
11880 else if (argv_find(argv, argc, "received-routes", &idx))
11881 type = bgp_show_adj_route_received;
11882 else if (argv_find(argv, argc, "filtered-routes", &idx))
11883 type = bgp_show_adj_route_filtered;
11884
11885 if (argv_find(argv, argc, "route-map", &idx))
11886 rmap_name = argv[++idx]->arg;
11887
11888 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, uj);
11889 }
11890
11891 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
11892 show_ip_bgp_neighbor_received_prefix_filter_cmd,
11893 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
11894 SHOW_STR
11895 IP_STR
11896 BGP_STR
11897 "Address Family\n"
11898 "Address Family\n"
11899 "Address Family modifier\n"
11900 "Detailed information on TCP and BGP neighbor connections\n"
11901 "Neighbor to display information about\n"
11902 "Neighbor to display information about\n"
11903 "Neighbor on BGP configured interface\n"
11904 "Display information received from a BGP neighbor\n"
11905 "Display the prefixlist filter\n"
11906 JSON_STR)
11907 {
11908 afi_t afi = AFI_IP6;
11909 safi_t safi = SAFI_UNICAST;
11910 char *peerstr = NULL;
11911
11912 char name[BUFSIZ];
11913 union sockunion su;
11914 struct peer *peer;
11915 int count, ret;
11916
11917 int idx = 0;
11918
11919 /* show [ip] bgp */
11920 if (argv_find(argv, argc, "ip", &idx))
11921 afi = AFI_IP;
11922 /* [<ipv4|ipv6> [unicast]] */
11923 if (argv_find(argv, argc, "ipv4", &idx))
11924 afi = AFI_IP;
11925 if (argv_find(argv, argc, "ipv6", &idx))
11926 afi = AFI_IP6;
11927 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11928 argv_find(argv, argc, "neighbors", &idx);
11929 peerstr = argv[++idx]->arg;
11930
11931 bool uj = use_json(argc, argv);
11932
11933 ret = str2sockunion(peerstr, &su);
11934 if (ret < 0) {
11935 peer = peer_lookup_by_conf_if(NULL, peerstr);
11936 if (!peer) {
11937 if (uj)
11938 vty_out(vty, "{}\n");
11939 else
11940 vty_out(vty,
11941 "%% Malformed address or name: %s\n",
11942 peerstr);
11943 return CMD_WARNING;
11944 }
11945 } else {
11946 peer = peer_lookup(NULL, &su);
11947 if (!peer) {
11948 if (uj)
11949 vty_out(vty, "{}\n");
11950 else
11951 vty_out(vty, "No peer\n");
11952 return CMD_WARNING;
11953 }
11954 }
11955
11956 sprintf(name, "%s.%d.%d", peer->host, afi, safi);
11957 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
11958 if (count) {
11959 if (!uj)
11960 vty_out(vty, "Address Family: %s\n",
11961 get_afi_safi_str(afi, safi, false));
11962 prefix_bgp_show_prefix_list(vty, afi, name, uj);
11963 } else {
11964 if (uj)
11965 vty_out(vty, "{}\n");
11966 else
11967 vty_out(vty, "No functional output\n");
11968 }
11969
11970 return CMD_SUCCESS;
11971 }
11972
11973 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
11974 afi_t afi, safi_t safi,
11975 enum bgp_show_type type, bool use_json)
11976 {
11977 /* labeled-unicast routes live in the unicast table */
11978 if (safi == SAFI_LABELED_UNICAST)
11979 safi = SAFI_UNICAST;
11980
11981 if (!peer || !peer->afc[afi][safi]) {
11982 if (use_json) {
11983 json_object *json_no = NULL;
11984 json_no = json_object_new_object();
11985 json_object_string_add(
11986 json_no, "warning",
11987 "No such neighbor or address family");
11988 vty_out(vty, "%s\n",
11989 json_object_to_json_string(json_no));
11990 json_object_free(json_no);
11991 } else
11992 vty_out(vty, "%% No such neighbor or address family\n");
11993 return CMD_WARNING;
11994 }
11995
11996 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, use_json);
11997 }
11998
11999 DEFUN (show_ip_bgp_flowspec_routes_detailed,
12000 show_ip_bgp_flowspec_routes_detailed_cmd,
12001 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
12002 SHOW_STR
12003 IP_STR
12004 BGP_STR
12005 BGP_INSTANCE_HELP_STR
12006 BGP_AFI_HELP_STR
12007 "SAFI Flowspec\n"
12008 "Detailed information on flowspec entries\n"
12009 JSON_STR)
12010 {
12011 afi_t afi = AFI_IP;
12012 safi_t safi = SAFI_UNICAST;
12013 struct bgp *bgp = NULL;
12014 int idx = 0;
12015 bool uj = use_json(argc, argv);
12016
12017 if (uj)
12018 argc--;
12019
12020 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12021 &bgp, uj);
12022 if (!idx)
12023 return CMD_WARNING;
12024
12025 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL, uj);
12026 }
12027
12028 DEFUN (show_ip_bgp_neighbor_routes,
12029 show_ip_bgp_neighbor_routes_cmd,
12030 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] "
12031 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
12032 SHOW_STR
12033 IP_STR
12034 BGP_STR
12035 BGP_INSTANCE_HELP_STR
12036 BGP_AFI_HELP_STR
12037 BGP_SAFI_WITH_LABEL_HELP_STR
12038 "Detailed information on TCP and BGP neighbor connections\n"
12039 "Neighbor to display information about\n"
12040 "Neighbor to display information about\n"
12041 "Neighbor on BGP configured interface\n"
12042 "Display flap statistics of the routes learned from neighbor\n"
12043 "Display the dampened routes received from neighbor\n"
12044 "Display routes learned from neighbor\n"
12045 JSON_STR)
12046 {
12047 char *peerstr = NULL;
12048 struct bgp *bgp = NULL;
12049 afi_t afi = AFI_IP6;
12050 safi_t safi = SAFI_UNICAST;
12051 struct peer *peer;
12052 enum bgp_show_type sh_type = bgp_show_type_neighbor;
12053 int idx = 0;
12054 bool uj = use_json(argc, argv);
12055
12056 if (uj)
12057 argc--;
12058
12059 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12060 &bgp, uj);
12061 if (!idx)
12062 return CMD_WARNING;
12063
12064 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
12065 argv_find(argv, argc, "neighbors", &idx);
12066 peerstr = argv[++idx]->arg;
12067
12068 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
12069 if (!peer)
12070 return CMD_WARNING;
12071
12072 if (argv_find(argv, argc, "flap-statistics", &idx))
12073 sh_type = bgp_show_type_flap_neighbor;
12074 else if (argv_find(argv, argc, "dampened-routes", &idx))
12075 sh_type = bgp_show_type_damp_neighbor;
12076 else if (argv_find(argv, argc, "routes", &idx))
12077 sh_type = bgp_show_type_neighbor;
12078
12079 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
12080 }
12081
12082 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
12083
12084 struct bgp_distance {
12085 /* Distance value for the IP source prefix. */
12086 uint8_t distance;
12087
12088 /* Name of the access-list to be matched. */
12089 char *access_list;
12090 };
12091
12092 DEFUN (show_bgp_afi_vpn_rd_route,
12093 show_bgp_afi_vpn_rd_route_cmd,
12094 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN <A.B.C.D/M|X:X::X:X/M> [json]",
12095 SHOW_STR
12096 BGP_STR
12097 BGP_AFI_HELP_STR
12098 "Address Family modifier\n"
12099 "Display information for a route distinguisher\n"
12100 "Route Distinguisher\n"
12101 "Network in the BGP routing table to display\n"
12102 "Network in the BGP routing table to display\n"
12103 JSON_STR)
12104 {
12105 int ret;
12106 struct prefix_rd prd;
12107 afi_t afi = AFI_MAX;
12108 int idx = 0;
12109
12110 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
12111 vty_out(vty, "%% Malformed Address Family\n");
12112 return CMD_WARNING;
12113 }
12114
12115 ret = str2prefix_rd(argv[5]->arg, &prd);
12116 if (!ret) {
12117 vty_out(vty, "%% Malformed Route Distinguisher\n");
12118 return CMD_WARNING;
12119 }
12120
12121 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
12122 0, BGP_PATH_SHOW_ALL, use_json(argc, argv));
12123 }
12124
12125 static struct bgp_distance *bgp_distance_new(void)
12126 {
12127 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
12128 }
12129
12130 static void bgp_distance_free(struct bgp_distance *bdistance)
12131 {
12132 XFREE(MTYPE_BGP_DISTANCE, bdistance);
12133 }
12134
12135 static int bgp_distance_set(struct vty *vty, const char *distance_str,
12136 const char *ip_str, const char *access_list_str)
12137 {
12138 int ret;
12139 afi_t afi;
12140 safi_t safi;
12141 struct prefix p;
12142 uint8_t distance;
12143 struct bgp_node *rn;
12144 struct bgp_distance *bdistance;
12145
12146 afi = bgp_node_afi(vty);
12147 safi = bgp_node_safi(vty);
12148
12149 ret = str2prefix(ip_str, &p);
12150 if (ret == 0) {
12151 vty_out(vty, "Malformed prefix\n");
12152 return CMD_WARNING_CONFIG_FAILED;
12153 }
12154
12155 distance = atoi(distance_str);
12156
12157 /* Get BGP distance node. */
12158 rn = bgp_node_get(bgp_distance_table[afi][safi], (struct prefix *)&p);
12159 bdistance = bgp_node_get_bgp_distance_info(rn);
12160 if (bdistance)
12161 bgp_unlock_node(rn);
12162 else {
12163 bdistance = bgp_distance_new();
12164 bgp_node_set_bgp_distance_info(rn, bdistance);
12165 }
12166
12167 /* Set distance value. */
12168 bdistance->distance = distance;
12169
12170 /* Reset access-list configuration. */
12171 XFREE(MTYPE_AS_LIST, bdistance->access_list);
12172 if (access_list_str)
12173 bdistance->access_list =
12174 XSTRDUP(MTYPE_AS_LIST, access_list_str);
12175
12176 return CMD_SUCCESS;
12177 }
12178
12179 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
12180 const char *ip_str, const char *access_list_str)
12181 {
12182 int ret;
12183 afi_t afi;
12184 safi_t safi;
12185 struct prefix p;
12186 int distance;
12187 struct bgp_node *rn;
12188 struct bgp_distance *bdistance;
12189
12190 afi = bgp_node_afi(vty);
12191 safi = bgp_node_safi(vty);
12192
12193 ret = str2prefix(ip_str, &p);
12194 if (ret == 0) {
12195 vty_out(vty, "Malformed prefix\n");
12196 return CMD_WARNING_CONFIG_FAILED;
12197 }
12198
12199 rn = bgp_node_lookup(bgp_distance_table[afi][safi],
12200 (struct prefix *)&p);
12201 if (!rn) {
12202 vty_out(vty, "Can't find specified prefix\n");
12203 return CMD_WARNING_CONFIG_FAILED;
12204 }
12205
12206 bdistance = bgp_node_get_bgp_distance_info(rn);
12207 distance = atoi(distance_str);
12208
12209 if (bdistance->distance != distance) {
12210 vty_out(vty, "Distance does not match configured\n");
12211 return CMD_WARNING_CONFIG_FAILED;
12212 }
12213
12214 XFREE(MTYPE_AS_LIST, bdistance->access_list);
12215 bgp_distance_free(bdistance);
12216
12217 bgp_node_set_bgp_path_info(rn, NULL);
12218 bgp_unlock_node(rn);
12219 bgp_unlock_node(rn);
12220
12221 return CMD_SUCCESS;
12222 }
12223
12224 /* Apply BGP information to distance method. */
12225 uint8_t bgp_distance_apply(struct prefix *p, struct bgp_path_info *pinfo,
12226 afi_t afi, safi_t safi, struct bgp *bgp)
12227 {
12228 struct bgp_node *rn;
12229 struct prefix q;
12230 struct peer *peer;
12231 struct bgp_distance *bdistance;
12232 struct access_list *alist;
12233 struct bgp_static *bgp_static;
12234
12235 if (!bgp)
12236 return 0;
12237
12238 peer = pinfo->peer;
12239
12240 if (pinfo->attr->distance)
12241 return pinfo->attr->distance;
12242
12243 /* Check source address. */
12244 sockunion2hostprefix(&peer->su, &q);
12245 rn = bgp_node_match(bgp_distance_table[afi][safi], &q);
12246 if (rn) {
12247 bdistance = bgp_node_get_bgp_distance_info(rn);
12248 bgp_unlock_node(rn);
12249
12250 if (bdistance->access_list) {
12251 alist = access_list_lookup(afi, bdistance->access_list);
12252 if (alist
12253 && access_list_apply(alist, p) == FILTER_PERMIT)
12254 return bdistance->distance;
12255 } else
12256 return bdistance->distance;
12257 }
12258
12259 /* Backdoor check. */
12260 rn = bgp_node_lookup(bgp->route[afi][safi], p);
12261 if (rn) {
12262 bgp_static = bgp_node_get_bgp_static_info(rn);
12263 bgp_unlock_node(rn);
12264
12265 if (bgp_static->backdoor) {
12266 if (bgp->distance_local[afi][safi])
12267 return bgp->distance_local[afi][safi];
12268 else
12269 return ZEBRA_IBGP_DISTANCE_DEFAULT;
12270 }
12271 }
12272
12273 if (peer->sort == BGP_PEER_EBGP) {
12274 if (bgp->distance_ebgp[afi][safi])
12275 return bgp->distance_ebgp[afi][safi];
12276 return ZEBRA_EBGP_DISTANCE_DEFAULT;
12277 } else {
12278 if (bgp->distance_ibgp[afi][safi])
12279 return bgp->distance_ibgp[afi][safi];
12280 return ZEBRA_IBGP_DISTANCE_DEFAULT;
12281 }
12282 }
12283
12284 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
12285 * we should tell ZEBRA update the routes for a specific
12286 * AFI/SAFI to reflect changes in RIB.
12287 */
12288 static void bgp_announce_routes_distance_update(struct bgp *bgp,
12289 afi_t update_afi,
12290 safi_t update_safi)
12291 {
12292 afi_t afi;
12293 safi_t safi;
12294
12295 FOREACH_AFI_SAFI (afi, safi) {
12296 if (!bgp_fibupd_safi(safi))
12297 continue;
12298
12299 if (afi != update_afi && safi != update_safi)
12300 continue;
12301
12302 if (BGP_DEBUG(zebra, ZEBRA))
12303 zlog_debug(
12304 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
12305 __func__, afi, safi);
12306 bgp_zebra_announce_table(bgp, afi, safi);
12307 }
12308 }
12309
12310 DEFUN (bgp_distance,
12311 bgp_distance_cmd,
12312 "distance bgp (1-255) (1-255) (1-255)",
12313 "Define an administrative distance\n"
12314 "BGP distance\n"
12315 "Distance for routes external to the AS\n"
12316 "Distance for routes internal to the AS\n"
12317 "Distance for local routes\n")
12318 {
12319 VTY_DECLVAR_CONTEXT(bgp, bgp);
12320 int idx_number = 2;
12321 int idx_number_2 = 3;
12322 int idx_number_3 = 4;
12323 int distance_ebgp = atoi(argv[idx_number]->arg);
12324 int distance_ibgp = atoi(argv[idx_number_2]->arg);
12325 int distance_local = atoi(argv[idx_number_3]->arg);
12326 afi_t afi;
12327 safi_t safi;
12328
12329 afi = bgp_node_afi(vty);
12330 safi = bgp_node_safi(vty);
12331
12332 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
12333 || bgp->distance_ibgp[afi][safi] != distance_ibgp
12334 || bgp->distance_local[afi][safi] != distance_local) {
12335 bgp->distance_ebgp[afi][safi] = distance_ebgp;
12336 bgp->distance_ibgp[afi][safi] = distance_ibgp;
12337 bgp->distance_local[afi][safi] = distance_local;
12338 bgp_announce_routes_distance_update(bgp, afi, safi);
12339 }
12340 return CMD_SUCCESS;
12341 }
12342
12343 DEFUN (no_bgp_distance,
12344 no_bgp_distance_cmd,
12345 "no distance bgp [(1-255) (1-255) (1-255)]",
12346 NO_STR
12347 "Define an administrative distance\n"
12348 "BGP distance\n"
12349 "Distance for routes external to the AS\n"
12350 "Distance for routes internal to the AS\n"
12351 "Distance for local routes\n")
12352 {
12353 VTY_DECLVAR_CONTEXT(bgp, bgp);
12354 afi_t afi;
12355 safi_t safi;
12356
12357 afi = bgp_node_afi(vty);
12358 safi = bgp_node_safi(vty);
12359
12360 if (bgp->distance_ebgp[afi][safi] != 0
12361 || bgp->distance_ibgp[afi][safi] != 0
12362 || bgp->distance_local[afi][safi] != 0) {
12363 bgp->distance_ebgp[afi][safi] = 0;
12364 bgp->distance_ibgp[afi][safi] = 0;
12365 bgp->distance_local[afi][safi] = 0;
12366 bgp_announce_routes_distance_update(bgp, afi, safi);
12367 }
12368 return CMD_SUCCESS;
12369 }
12370
12371
12372 DEFUN (bgp_distance_source,
12373 bgp_distance_source_cmd,
12374 "distance (1-255) A.B.C.D/M",
12375 "Define an administrative distance\n"
12376 "Administrative distance\n"
12377 "IP source prefix\n")
12378 {
12379 int idx_number = 1;
12380 int idx_ipv4_prefixlen = 2;
12381 bgp_distance_set(vty, argv[idx_number]->arg,
12382 argv[idx_ipv4_prefixlen]->arg, NULL);
12383 return CMD_SUCCESS;
12384 }
12385
12386 DEFUN (no_bgp_distance_source,
12387 no_bgp_distance_source_cmd,
12388 "no distance (1-255) A.B.C.D/M",
12389 NO_STR
12390 "Define an administrative distance\n"
12391 "Administrative distance\n"
12392 "IP source prefix\n")
12393 {
12394 int idx_number = 2;
12395 int idx_ipv4_prefixlen = 3;
12396 bgp_distance_unset(vty, argv[idx_number]->arg,
12397 argv[idx_ipv4_prefixlen]->arg, NULL);
12398 return CMD_SUCCESS;
12399 }
12400
12401 DEFUN (bgp_distance_source_access_list,
12402 bgp_distance_source_access_list_cmd,
12403 "distance (1-255) A.B.C.D/M WORD",
12404 "Define an administrative distance\n"
12405 "Administrative distance\n"
12406 "IP source prefix\n"
12407 "Access list name\n")
12408 {
12409 int idx_number = 1;
12410 int idx_ipv4_prefixlen = 2;
12411 int idx_word = 3;
12412 bgp_distance_set(vty, argv[idx_number]->arg,
12413 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
12414 return CMD_SUCCESS;
12415 }
12416
12417 DEFUN (no_bgp_distance_source_access_list,
12418 no_bgp_distance_source_access_list_cmd,
12419 "no distance (1-255) A.B.C.D/M WORD",
12420 NO_STR
12421 "Define an administrative distance\n"
12422 "Administrative distance\n"
12423 "IP source prefix\n"
12424 "Access list name\n")
12425 {
12426 int idx_number = 2;
12427 int idx_ipv4_prefixlen = 3;
12428 int idx_word = 4;
12429 bgp_distance_unset(vty, argv[idx_number]->arg,
12430 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
12431 return CMD_SUCCESS;
12432 }
12433
12434 DEFUN (ipv6_bgp_distance_source,
12435 ipv6_bgp_distance_source_cmd,
12436 "distance (1-255) X:X::X:X/M",
12437 "Define an administrative distance\n"
12438 "Administrative distance\n"
12439 "IP source prefix\n")
12440 {
12441 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
12442 return CMD_SUCCESS;
12443 }
12444
12445 DEFUN (no_ipv6_bgp_distance_source,
12446 no_ipv6_bgp_distance_source_cmd,
12447 "no distance (1-255) X:X::X:X/M",
12448 NO_STR
12449 "Define an administrative distance\n"
12450 "Administrative distance\n"
12451 "IP source prefix\n")
12452 {
12453 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
12454 return CMD_SUCCESS;
12455 }
12456
12457 DEFUN (ipv6_bgp_distance_source_access_list,
12458 ipv6_bgp_distance_source_access_list_cmd,
12459 "distance (1-255) X:X::X:X/M WORD",
12460 "Define an administrative distance\n"
12461 "Administrative distance\n"
12462 "IP source prefix\n"
12463 "Access list name\n")
12464 {
12465 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
12466 return CMD_SUCCESS;
12467 }
12468
12469 DEFUN (no_ipv6_bgp_distance_source_access_list,
12470 no_ipv6_bgp_distance_source_access_list_cmd,
12471 "no distance (1-255) X:X::X:X/M WORD",
12472 NO_STR
12473 "Define an administrative distance\n"
12474 "Administrative distance\n"
12475 "IP source prefix\n"
12476 "Access list name\n")
12477 {
12478 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
12479 return CMD_SUCCESS;
12480 }
12481
12482 DEFUN (bgp_damp_set,
12483 bgp_damp_set_cmd,
12484 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
12485 "BGP Specific commands\n"
12486 "Enable route-flap dampening\n"
12487 "Half-life time for the penalty\n"
12488 "Value to start reusing a route\n"
12489 "Value to start suppressing a route\n"
12490 "Maximum duration to suppress a stable route\n")
12491 {
12492 VTY_DECLVAR_CONTEXT(bgp, bgp);
12493 int idx_half_life = 2;
12494 int idx_reuse = 3;
12495 int idx_suppress = 4;
12496 int idx_max_suppress = 5;
12497 int half = DEFAULT_HALF_LIFE * 60;
12498 int reuse = DEFAULT_REUSE;
12499 int suppress = DEFAULT_SUPPRESS;
12500 int max = 4 * half;
12501
12502 if (argc == 6) {
12503 half = atoi(argv[idx_half_life]->arg) * 60;
12504 reuse = atoi(argv[idx_reuse]->arg);
12505 suppress = atoi(argv[idx_suppress]->arg);
12506 max = atoi(argv[idx_max_suppress]->arg) * 60;
12507 } else if (argc == 3) {
12508 half = atoi(argv[idx_half_life]->arg) * 60;
12509 max = 4 * half;
12510 }
12511
12512 /*
12513 * These can't be 0 but our SA doesn't understand the
12514 * way our cli is constructed
12515 */
12516 assert(reuse);
12517 assert(half);
12518 if (suppress < reuse) {
12519 vty_out(vty,
12520 "Suppress value cannot be less than reuse value \n");
12521 return 0;
12522 }
12523
12524 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
12525 reuse, suppress, max);
12526 }
12527
12528 DEFUN (bgp_damp_unset,
12529 bgp_damp_unset_cmd,
12530 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
12531 NO_STR
12532 "BGP Specific commands\n"
12533 "Enable route-flap dampening\n"
12534 "Half-life time for the penalty\n"
12535 "Value to start reusing a route\n"
12536 "Value to start suppressing a route\n"
12537 "Maximum duration to suppress a stable route\n")
12538 {
12539 VTY_DECLVAR_CONTEXT(bgp, bgp);
12540 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
12541 }
12542
12543 /* Display specified route of BGP table. */
12544 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
12545 const char *ip_str, afi_t afi, safi_t safi,
12546 struct prefix_rd *prd, int prefix_check)
12547 {
12548 int ret;
12549 struct prefix match;
12550 struct bgp_node *rn;
12551 struct bgp_node *rm;
12552 struct bgp_path_info *pi;
12553 struct bgp_path_info *pi_temp;
12554 struct bgp *bgp;
12555 struct bgp_table *table;
12556
12557 /* BGP structure lookup. */
12558 if (view_name) {
12559 bgp = bgp_lookup_by_name(view_name);
12560 if (bgp == NULL) {
12561 vty_out(vty, "%% Can't find BGP instance %s\n",
12562 view_name);
12563 return CMD_WARNING;
12564 }
12565 } else {
12566 bgp = bgp_get_default();
12567 if (bgp == NULL) {
12568 vty_out(vty, "%% No BGP process is configured\n");
12569 return CMD_WARNING;
12570 }
12571 }
12572
12573 /* Check IP address argument. */
12574 ret = str2prefix(ip_str, &match);
12575 if (!ret) {
12576 vty_out(vty, "%% address is malformed\n");
12577 return CMD_WARNING;
12578 }
12579
12580 match.family = afi2family(afi);
12581
12582 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
12583 || (safi == SAFI_EVPN)) {
12584 for (rn = bgp_table_top(bgp->rib[AFI_IP][safi]); rn;
12585 rn = bgp_route_next(rn)) {
12586 if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
12587 continue;
12588 table = bgp_node_get_bgp_table_info(rn);
12589 if (!table)
12590 continue;
12591 if ((rm = bgp_node_match(table, &match)) == NULL)
12592 continue;
12593
12594 if (!prefix_check
12595 || rm->p.prefixlen == match.prefixlen) {
12596 pi = bgp_node_get_bgp_path_info(rm);
12597 while (pi) {
12598 if (pi->extra && pi->extra->damp_info) {
12599 pi_temp = pi->next;
12600 bgp_damp_info_free(
12601 pi->extra->damp_info,
12602 1, afi, safi);
12603 pi = pi_temp;
12604 } else
12605 pi = pi->next;
12606 }
12607 }
12608
12609 bgp_unlock_node(rm);
12610 }
12611 } else {
12612 if ((rn = bgp_node_match(bgp->rib[afi][safi], &match))
12613 != NULL) {
12614 if (!prefix_check
12615 || rn->p.prefixlen == match.prefixlen) {
12616 pi = bgp_node_get_bgp_path_info(rn);
12617 while (pi) {
12618 if (pi->extra && pi->extra->damp_info) {
12619 pi_temp = pi->next;
12620 bgp_damp_info_free(
12621 pi->extra->damp_info,
12622 1, afi, safi);
12623 pi = pi_temp;
12624 } else
12625 pi = pi->next;
12626 }
12627 }
12628
12629 bgp_unlock_node(rn);
12630 }
12631 }
12632
12633 return CMD_SUCCESS;
12634 }
12635
12636 DEFUN (clear_ip_bgp_dampening,
12637 clear_ip_bgp_dampening_cmd,
12638 "clear ip bgp dampening",
12639 CLEAR_STR
12640 IP_STR
12641 BGP_STR
12642 "Clear route flap dampening information\n")
12643 {
12644 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
12645 return CMD_SUCCESS;
12646 }
12647
12648 DEFUN (clear_ip_bgp_dampening_prefix,
12649 clear_ip_bgp_dampening_prefix_cmd,
12650 "clear ip bgp dampening A.B.C.D/M",
12651 CLEAR_STR
12652 IP_STR
12653 BGP_STR
12654 "Clear route flap dampening information\n"
12655 "IPv4 prefix\n")
12656 {
12657 int idx_ipv4_prefixlen = 4;
12658 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
12659 AFI_IP, SAFI_UNICAST, NULL, 1);
12660 }
12661
12662 DEFUN (clear_ip_bgp_dampening_address,
12663 clear_ip_bgp_dampening_address_cmd,
12664 "clear ip bgp dampening A.B.C.D",
12665 CLEAR_STR
12666 IP_STR
12667 BGP_STR
12668 "Clear route flap dampening information\n"
12669 "Network to clear damping information\n")
12670 {
12671 int idx_ipv4 = 4;
12672 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
12673 SAFI_UNICAST, NULL, 0);
12674 }
12675
12676 DEFUN (clear_ip_bgp_dampening_address_mask,
12677 clear_ip_bgp_dampening_address_mask_cmd,
12678 "clear ip bgp dampening A.B.C.D A.B.C.D",
12679 CLEAR_STR
12680 IP_STR
12681 BGP_STR
12682 "Clear route flap dampening information\n"
12683 "Network to clear damping information\n"
12684 "Network mask\n")
12685 {
12686 int idx_ipv4 = 4;
12687 int idx_ipv4_2 = 5;
12688 int ret;
12689 char prefix_str[BUFSIZ];
12690
12691 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
12692 prefix_str);
12693 if (!ret) {
12694 vty_out(vty, "%% Inconsistent address and mask\n");
12695 return CMD_WARNING;
12696 }
12697
12698 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
12699 NULL, 0);
12700 }
12701
12702 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
12703 {
12704 struct vty *vty = arg;
12705 struct peer *peer = bucket->data;
12706 char buf[SU_ADDRSTRLEN];
12707
12708 vty_out(vty, "\tPeer: %s %s\n", peer->host,
12709 sockunion2str(&peer->su, buf, sizeof(buf)));
12710 }
12711
12712 DEFUN (show_bgp_peerhash,
12713 show_bgp_peerhash_cmd,
12714 "show bgp peerhash",
12715 SHOW_STR
12716 BGP_STR
12717 "Display information about the BGP peerhash\n")
12718 {
12719 struct list *instances = bm->bgp;
12720 struct listnode *node;
12721 struct bgp *bgp;
12722
12723 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
12724 vty_out(vty, "BGP: %s\n", bgp->name);
12725 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
12726 vty);
12727 }
12728
12729 return CMD_SUCCESS;
12730 }
12731
12732 /* also used for encap safi */
12733 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
12734 afi_t afi, safi_t safi)
12735 {
12736 struct bgp_node *prn;
12737 struct bgp_node *rn;
12738 struct bgp_table *table;
12739 struct prefix *p;
12740 struct prefix_rd *prd;
12741 struct bgp_static *bgp_static;
12742 mpls_label_t label;
12743 char buf[SU_ADDRSTRLEN];
12744 char rdbuf[RD_ADDRSTRLEN];
12745
12746 /* Network configuration. */
12747 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
12748 prn = bgp_route_next(prn)) {
12749 table = bgp_node_get_bgp_table_info(prn);
12750 if (!table)
12751 continue;
12752
12753 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
12754 bgp_static = bgp_node_get_bgp_static_info(rn);
12755 if (bgp_static == NULL)
12756 continue;
12757
12758 p = &rn->p;
12759 prd = (struct prefix_rd *)&prn->p;
12760
12761 /* "network" configuration display. */
12762 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
12763 label = decode_label(&bgp_static->label);
12764
12765 vty_out(vty, " network %s/%d rd %s",
12766 inet_ntop(p->family, &p->u.prefix, buf,
12767 SU_ADDRSTRLEN),
12768 p->prefixlen, rdbuf);
12769 if (safi == SAFI_MPLS_VPN)
12770 vty_out(vty, " label %u", label);
12771
12772 if (bgp_static->rmap.name)
12773 vty_out(vty, " route-map %s",
12774 bgp_static->rmap.name);
12775
12776 if (bgp_static->backdoor)
12777 vty_out(vty, " backdoor");
12778
12779 vty_out(vty, "\n");
12780 }
12781 }
12782 }
12783
12784 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
12785 afi_t afi, safi_t safi)
12786 {
12787 struct bgp_node *prn;
12788 struct bgp_node *rn;
12789 struct bgp_table *table;
12790 struct prefix *p;
12791 struct prefix_rd *prd;
12792 struct bgp_static *bgp_static;
12793 char buf[PREFIX_STRLEN * 2];
12794 char buf2[SU_ADDRSTRLEN];
12795 char rdbuf[RD_ADDRSTRLEN];
12796
12797 /* Network configuration. */
12798 for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
12799 prn = bgp_route_next(prn)) {
12800 table = bgp_node_get_bgp_table_info(prn);
12801 if (!table)
12802 continue;
12803
12804 for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
12805 bgp_static = bgp_node_get_bgp_static_info(rn);
12806 if (bgp_static == NULL)
12807 continue;
12808
12809 char *macrouter = NULL;
12810 char *esi = NULL;
12811
12812 if (bgp_static->router_mac)
12813 macrouter = prefix_mac2str(
12814 bgp_static->router_mac, NULL, 0);
12815 if (bgp_static->eth_s_id)
12816 esi = esi2str(bgp_static->eth_s_id);
12817 p = &rn->p;
12818 prd = (struct prefix_rd *)&prn->p;
12819
12820 /* "network" configuration display. */
12821 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
12822 if (p->u.prefix_evpn.route_type == 5) {
12823 char local_buf[PREFIX_STRLEN];
12824 uint8_t family = is_evpn_prefix_ipaddr_v4((
12825 struct prefix_evpn *)p)
12826 ? AF_INET
12827 : AF_INET6;
12828 inet_ntop(family,
12829 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
12830 local_buf, PREFIX_STRLEN);
12831 sprintf(buf, "%s/%u", local_buf,
12832 p->u.prefix_evpn.prefix_addr.ip_prefix_length);
12833 } else {
12834 prefix2str(p, buf, sizeof(buf));
12835 }
12836
12837 if (bgp_static->gatewayIp.family == AF_INET
12838 || bgp_static->gatewayIp.family == AF_INET6)
12839 inet_ntop(bgp_static->gatewayIp.family,
12840 &bgp_static->gatewayIp.u.prefix, buf2,
12841 sizeof(buf2));
12842 vty_out(vty,
12843 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
12844 buf, rdbuf,
12845 p->u.prefix_evpn.prefix_addr.eth_tag,
12846 decode_label(&bgp_static->label), esi, buf2,
12847 macrouter);
12848
12849 XFREE(MTYPE_TMP, macrouter);
12850 XFREE(MTYPE_TMP, esi);
12851 }
12852 }
12853 }
12854
12855 /* Configuration of static route announcement and aggregate
12856 information. */
12857 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
12858 safi_t safi)
12859 {
12860 struct bgp_node *rn;
12861 struct prefix *p;
12862 struct bgp_static *bgp_static;
12863 struct bgp_aggregate *bgp_aggregate;
12864 char buf[SU_ADDRSTRLEN];
12865
12866 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
12867 bgp_config_write_network_vpn(vty, bgp, afi, safi);
12868 return;
12869 }
12870
12871 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
12872 bgp_config_write_network_evpn(vty, bgp, afi, safi);
12873 return;
12874 }
12875
12876 /* Network configuration. */
12877 for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
12878 rn = bgp_route_next(rn)) {
12879 bgp_static = bgp_node_get_bgp_static_info(rn);
12880 if (bgp_static == NULL)
12881 continue;
12882
12883 p = &rn->p;
12884
12885 vty_out(vty, " network %s/%d",
12886 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
12887 p->prefixlen);
12888
12889 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
12890 vty_out(vty, " label-index %u",
12891 bgp_static->label_index);
12892
12893 if (bgp_static->rmap.name)
12894 vty_out(vty, " route-map %s", bgp_static->rmap.name);
12895
12896 if (bgp_static->backdoor)
12897 vty_out(vty, " backdoor");
12898
12899 vty_out(vty, "\n");
12900 }
12901
12902 /* Aggregate-address configuration. */
12903 for (rn = bgp_table_top(bgp->aggregate[afi][safi]); rn;
12904 rn = bgp_route_next(rn)) {
12905 bgp_aggregate = bgp_node_get_bgp_aggregate_info(rn);
12906 if (bgp_aggregate == NULL)
12907 continue;
12908
12909 p = &rn->p;
12910
12911 vty_out(vty, " aggregate-address %s/%d",
12912 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
12913 p->prefixlen);
12914
12915 if (bgp_aggregate->as_set)
12916 vty_out(vty, " as-set");
12917
12918 if (bgp_aggregate->summary_only)
12919 vty_out(vty, " summary-only");
12920
12921 if (bgp_aggregate->rmap.name)
12922 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
12923
12924 vty_out(vty, "\n");
12925 }
12926 }
12927
12928 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
12929 safi_t safi)
12930 {
12931 struct bgp_node *rn;
12932 struct bgp_distance *bdistance;
12933
12934 /* Distance configuration. */
12935 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
12936 && bgp->distance_local[afi][safi]
12937 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
12938 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
12939 || bgp->distance_local[afi][safi]
12940 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
12941 vty_out(vty, " distance bgp %d %d %d\n",
12942 bgp->distance_ebgp[afi][safi],
12943 bgp->distance_ibgp[afi][safi],
12944 bgp->distance_local[afi][safi]);
12945 }
12946
12947 for (rn = bgp_table_top(bgp_distance_table[afi][safi]); rn;
12948 rn = bgp_route_next(rn)) {
12949 bdistance = bgp_node_get_bgp_distance_info(rn);
12950 if (bdistance != NULL) {
12951 char buf[PREFIX_STRLEN];
12952
12953 vty_out(vty, " distance %d %s %s\n",
12954 bdistance->distance,
12955 prefix2str(&rn->p, buf, sizeof(buf)),
12956 bdistance->access_list ? bdistance->access_list
12957 : "");
12958 }
12959 }
12960 }
12961
12962 /* Allocate routing table structure and install commands. */
12963 void bgp_route_init(void)
12964 {
12965 afi_t afi;
12966 safi_t safi;
12967
12968 /* Init BGP distance table. */
12969 FOREACH_AFI_SAFI (afi, safi)
12970 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
12971
12972 /* IPv4 BGP commands. */
12973 install_element(BGP_NODE, &bgp_table_map_cmd);
12974 install_element(BGP_NODE, &bgp_network_cmd);
12975 install_element(BGP_NODE, &no_bgp_table_map_cmd);
12976
12977 install_element(BGP_NODE, &aggregate_address_cmd);
12978 install_element(BGP_NODE, &aggregate_address_mask_cmd);
12979 install_element(BGP_NODE, &no_aggregate_address_cmd);
12980 install_element(BGP_NODE, &no_aggregate_address_mask_cmd);
12981
12982 /* IPv4 unicast configuration. */
12983 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
12984 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
12985 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
12986
12987 install_element(BGP_IPV4_NODE, &aggregate_address_cmd);
12988 install_element(BGP_IPV4_NODE, &aggregate_address_mask_cmd);
12989 install_element(BGP_IPV4_NODE, &no_aggregate_address_cmd);
12990 install_element(BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
12991
12992 /* IPv4 multicast configuration. */
12993 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
12994 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
12995 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
12996 install_element(BGP_IPV4M_NODE, &aggregate_address_cmd);
12997 install_element(BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
12998 install_element(BGP_IPV4M_NODE, &no_aggregate_address_cmd);
12999 install_element(BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
13000
13001 /* IPv4 labeled-unicast configuration. */
13002 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
13003 install_element(VIEW_NODE, &show_ip_bgp_cmd);
13004 install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
13005 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
13006 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
13007
13008 install_element(VIEW_NODE,
13009 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
13010 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
13011 install_element(VIEW_NODE,
13012 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
13013 #ifdef KEEP_OLD_VPN_COMMANDS
13014 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
13015 #endif /* KEEP_OLD_VPN_COMMANDS */
13016 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
13017 install_element(VIEW_NODE,
13018 &show_bgp_l2vpn_evpn_route_prefix_cmd);
13019
13020 /* BGP dampening clear commands */
13021 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
13022 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
13023
13024 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
13025 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
13026
13027 /* prefix count */
13028 install_element(ENABLE_NODE,
13029 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
13030 #ifdef KEEP_OLD_VPN_COMMANDS
13031 install_element(ENABLE_NODE,
13032 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
13033 #endif /* KEEP_OLD_VPN_COMMANDS */
13034
13035 /* New config IPv6 BGP commands. */
13036 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
13037 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
13038 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
13039
13040 install_element(BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
13041 install_element(BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
13042
13043 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
13044
13045 install_element(BGP_NODE, &bgp_distance_cmd);
13046 install_element(BGP_NODE, &no_bgp_distance_cmd);
13047 install_element(BGP_NODE, &bgp_distance_source_cmd);
13048 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
13049 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
13050 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
13051 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
13052 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
13053 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
13054 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
13055 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
13056 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
13057 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
13058 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
13059 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
13060 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
13061 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
13062 install_element(BGP_IPV4M_NODE,
13063 &no_bgp_distance_source_access_list_cmd);
13064 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
13065 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
13066 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
13067 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
13068 install_element(BGP_IPV6_NODE,
13069 &ipv6_bgp_distance_source_access_list_cmd);
13070 install_element(BGP_IPV6_NODE,
13071 &no_ipv6_bgp_distance_source_access_list_cmd);
13072 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
13073 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
13074 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
13075 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
13076 install_element(BGP_IPV6M_NODE,
13077 &ipv6_bgp_distance_source_access_list_cmd);
13078 install_element(BGP_IPV6M_NODE,
13079 &no_ipv6_bgp_distance_source_access_list_cmd);
13080
13081 install_element(BGP_NODE, &bgp_damp_set_cmd);
13082 install_element(BGP_NODE, &bgp_damp_unset_cmd);
13083 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
13084 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
13085
13086 /* IPv4 Multicast Mode */
13087 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
13088 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
13089
13090 /* Large Communities */
13091 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
13092 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
13093
13094 /* show bgp ipv4 flowspec detailed */
13095 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
13096
13097 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
13098 }
13099
13100 void bgp_route_finish(void)
13101 {
13102 afi_t afi;
13103 safi_t safi;
13104
13105 FOREACH_AFI_SAFI (afi, safi) {
13106 bgp_table_unlock(bgp_distance_table[afi][safi]);
13107 bgp_distance_table[afi][safi] = NULL;
13108 }
13109 }