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