1 /* BGP routing information
2 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 * Copyright (C) 2016 Job Snijders <job@instituut.net>
5 * This file is part of GNU Zebra.
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
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.
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
34 #include "sockunion.h"
37 #include "workqueue.h"
41 #include "lib_errors.h"
43 #include "bgpd/bgpd.h"
44 #include "bgpd/bgp_table.h"
45 #include "bgpd/bgp_route.h"
46 #include "bgpd/bgp_attr.h"
47 #include "bgpd/bgp_debug.h"
48 #include "bgpd/bgp_errors.h"
49 #include "bgpd/bgp_aspath.h"
50 #include "bgpd/bgp_regex.h"
51 #include "bgpd/bgp_community.h"
52 #include "bgpd/bgp_ecommunity.h"
53 #include "bgpd/bgp_lcommunity.h"
54 #include "bgpd/bgp_clist.h"
55 #include "bgpd/bgp_packet.h"
56 #include "bgpd/bgp_filter.h"
57 #include "bgpd/bgp_fsm.h"
58 #include "bgpd/bgp_mplsvpn.h"
59 #include "bgpd/bgp_nexthop.h"
60 #include "bgpd/bgp_damp.h"
61 #include "bgpd/bgp_advertise.h"
62 #include "bgpd/bgp_zebra.h"
63 #include "bgpd/bgp_vty.h"
64 #include "bgpd/bgp_mpath.h"
65 #include "bgpd/bgp_nht.h"
66 #include "bgpd/bgp_updgrp.h"
67 #include "bgpd/bgp_label.h"
68 #include "bgpd/bgp_addpath.h"
69 #include "bgpd/bgp_mac.h"
72 #include "bgpd/rfapi/rfapi_backend.h"
73 #include "bgpd/rfapi/vnc_import_bgp.h"
74 #include "bgpd/rfapi/vnc_export_bgp.h"
76 #include "bgpd/bgp_encap_types.h"
77 #include "bgpd/bgp_encap_tlv.h"
78 #include "bgpd/bgp_evpn.h"
79 #include "bgpd/bgp_evpn_vty.h"
80 #include "bgpd/bgp_flowspec.h"
81 #include "bgpd/bgp_flowspec_util.h"
82 #include "bgpd/bgp_pbr.h"
84 #ifndef VTYSH_EXTRACT_PL
85 #include "bgpd/bgp_route_clippy.c"
88 /* Extern from bgp_dump.c */
89 extern const char *bgp_origin_str
[];
90 extern const char *bgp_origin_long_str
[];
93 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
94 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
95 static const struct message bgp_pmsi_tnltype_str
[] = {
96 {PMSI_TNLTYPE_NO_INFO
, PMSI_TNLTYPE_STR_NO_INFO
},
97 {PMSI_TNLTYPE_RSVP_TE_P2MP
, "RSVP-TE P2MP"},
98 {PMSI_TNLTYPE_MLDP_P2MP
, "mLDP P2MP"},
99 {PMSI_TNLTYPE_PIM_SSM
, "PIM-SSM"},
100 {PMSI_TNLTYPE_PIM_SM
, "PIM-SM"},
101 {PMSI_TNLTYPE_PIM_BIDIR
, "PIM-BIDIR"},
102 {PMSI_TNLTYPE_INGR_REPL
, "Ingress Replication"},
103 {PMSI_TNLTYPE_MLDP_MP2MP
, "mLDP MP2MP"},
107 #define VRFID_NONE_STR "-"
109 struct bgp_node
*bgp_afi_node_get(struct bgp_table
*table
, afi_t afi
,
110 safi_t safi
, struct prefix
*p
,
111 struct prefix_rd
*prd
)
114 struct bgp_node
*prn
= NULL
;
120 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
121 || (safi
== SAFI_EVPN
)) {
122 prn
= bgp_node_get(table
, (struct prefix
*)prd
);
124 if (!bgp_node_has_bgp_path_info_data(prn
))
125 bgp_node_set_bgp_table_info(
126 prn
, bgp_table_init(table
->bgp
, afi
, safi
));
128 bgp_unlock_node(prn
);
129 table
= bgp_node_get_bgp_table_info(prn
);
132 rn
= bgp_node_get(table
, p
);
134 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
135 || (safi
== SAFI_EVPN
))
141 struct bgp_node
*bgp_afi_node_lookup(struct bgp_table
*table
, afi_t afi
,
142 safi_t safi
, struct prefix
*p
,
143 struct prefix_rd
*prd
)
146 struct bgp_node
*prn
= NULL
;
151 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
152 || (safi
== SAFI_EVPN
)) {
153 prn
= bgp_node_lookup(table
, (struct prefix
*)prd
);
157 if (!bgp_node_has_bgp_path_info_data(prn
)) {
158 bgp_unlock_node(prn
);
162 table
= bgp_node_get_bgp_table_info(prn
);
165 rn
= bgp_node_lookup(table
, p
);
170 /* Allocate bgp_path_info_extra */
171 static struct bgp_path_info_extra
*bgp_path_info_extra_new(void)
173 struct bgp_path_info_extra
*new;
174 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA
,
175 sizeof(struct bgp_path_info_extra
));
176 new->label
[0] = MPLS_INVALID_LABEL
;
178 new->bgp_fs_pbr
= NULL
;
179 new->bgp_fs_iprule
= NULL
;
183 void bgp_path_info_extra_free(struct bgp_path_info_extra
**extra
)
185 struct bgp_path_info_extra
*e
;
187 if (!extra
|| !*extra
)
192 bgp_damp_info_free(e
->damp_info
, 0);
196 struct bgp_path_info
*bpi
= (struct bgp_path_info
*)e
->parent
;
199 /* FIXME: since multiple e may have the same e->parent
200 * and e->parent->net is holding a refcount for each
201 * of them, we need to do some fudging here.
203 * WARNING: if bpi->net->lock drops to 0, bpi may be
204 * freed as well (because bpi->net was holding the
205 * last reference to bpi) => write after free!
209 bpi
= bgp_path_info_lock(bpi
);
210 refcount
= bpi
->net
->lock
- 1;
211 bgp_unlock_node((struct bgp_node
*)bpi
->net
);
214 bgp_path_info_unlock(bpi
);
216 bgp_path_info_unlock(e
->parent
);
221 bgp_unlock(e
->bgp_orig
);
223 if ((*extra
)->bgp_fs_iprule
)
224 list_delete(&((*extra
)->bgp_fs_iprule
));
225 if ((*extra
)->bgp_fs_pbr
)
226 list_delete(&((*extra
)->bgp_fs_pbr
));
227 XFREE(MTYPE_BGP_ROUTE_EXTRA
, *extra
);
232 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
233 * allocated if required.
235 struct bgp_path_info_extra
*bgp_path_info_extra_get(struct bgp_path_info
*pi
)
238 pi
->extra
= bgp_path_info_extra_new();
242 /* Free bgp route information. */
243 static void bgp_path_info_free(struct bgp_path_info
*path
)
246 bgp_attr_unintern(&path
->attr
);
248 bgp_unlink_nexthop(path
);
249 bgp_path_info_extra_free(&path
->extra
);
250 bgp_path_info_mpath_free(&path
->mpath
);
252 bgp_addpath_free_info_data(&path
->tx_addpath
,
253 &path
->net
->tx_addpath
);
255 peer_unlock(path
->peer
); /* bgp_path_info peer reference */
257 XFREE(MTYPE_BGP_ROUTE
, path
);
260 struct bgp_path_info
*bgp_path_info_lock(struct bgp_path_info
*path
)
266 struct bgp_path_info
*bgp_path_info_unlock(struct bgp_path_info
*path
)
268 assert(path
&& path
->lock
> 0);
271 if (path
->lock
== 0) {
273 zlog_debug ("%s: unlocked and freeing", __func__
);
274 zlog_backtrace (LOG_DEBUG
);
276 bgp_path_info_free(path
);
283 zlog_debug ("%s: unlocked to 1", __func__
);
284 zlog_backtrace (LOG_DEBUG
);
291 void bgp_path_info_add(struct bgp_node
*rn
, struct bgp_path_info
*pi
)
293 struct bgp_path_info
*top
;
295 top
= bgp_node_get_bgp_path_info(rn
);
301 bgp_node_set_bgp_path_info(rn
, pi
);
303 bgp_path_info_lock(pi
);
305 peer_lock(pi
->peer
); /* bgp_path_info peer reference */
308 /* Do the actual removal of info from RIB, for use by bgp_process
309 completion callback *only* */
310 void bgp_path_info_reap(struct bgp_node
*rn
, struct bgp_path_info
*pi
)
313 pi
->next
->prev
= pi
->prev
;
315 pi
->prev
->next
= pi
->next
;
317 bgp_node_set_bgp_path_info(rn
, pi
->next
);
319 bgp_path_info_mpath_dequeue(pi
);
320 bgp_path_info_unlock(pi
);
324 void bgp_path_info_delete(struct bgp_node
*rn
, struct bgp_path_info
*pi
)
326 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_REMOVED
);
327 /* set of previous already took care of pcount */
328 UNSET_FLAG(pi
->flags
, BGP_PATH_VALID
);
331 /* undo the effects of a previous call to bgp_path_info_delete; typically
332 called when a route is deleted and then quickly re-added before the
333 deletion has been processed */
334 void bgp_path_info_restore(struct bgp_node
*rn
, struct bgp_path_info
*pi
)
336 bgp_path_info_unset_flag(rn
, pi
, BGP_PATH_REMOVED
);
337 /* unset of previous already took care of pcount */
338 SET_FLAG(pi
->flags
, BGP_PATH_VALID
);
341 /* Adjust pcount as required */
342 static void bgp_pcount_adjust(struct bgp_node
*rn
, struct bgp_path_info
*pi
)
344 struct bgp_table
*table
;
346 assert(rn
&& bgp_node_table(rn
));
347 assert(pi
&& pi
->peer
&& pi
->peer
->bgp
);
349 table
= bgp_node_table(rn
);
351 if (pi
->peer
== pi
->peer
->bgp
->peer_self
)
354 if (!BGP_PATH_COUNTABLE(pi
)
355 && CHECK_FLAG(pi
->flags
, BGP_PATH_COUNTED
)) {
357 UNSET_FLAG(pi
->flags
, BGP_PATH_COUNTED
);
359 /* slight hack, but more robust against errors. */
360 if (pi
->peer
->pcount
[table
->afi
][table
->safi
])
361 pi
->peer
->pcount
[table
->afi
][table
->safi
]--;
363 flog_err(EC_LIB_DEVELOPMENT
,
364 "Asked to decrement 0 prefix count for peer");
365 } else if (BGP_PATH_COUNTABLE(pi
)
366 && !CHECK_FLAG(pi
->flags
, BGP_PATH_COUNTED
)) {
367 SET_FLAG(pi
->flags
, BGP_PATH_COUNTED
);
368 pi
->peer
->pcount
[table
->afi
][table
->safi
]++;
372 static int bgp_label_index_differs(struct bgp_path_info
*pi1
,
373 struct bgp_path_info
*pi2
)
375 return (!(pi1
->attr
->label_index
== pi2
->attr
->label_index
));
378 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
379 * This is here primarily to keep prefix-count in check.
381 void bgp_path_info_set_flag(struct bgp_node
*rn
, struct bgp_path_info
*pi
,
384 SET_FLAG(pi
->flags
, flag
);
386 /* early bath if we know it's not a flag that changes countability state
388 if (!CHECK_FLAG(flag
,
389 BGP_PATH_VALID
| BGP_PATH_HISTORY
| BGP_PATH_REMOVED
))
392 bgp_pcount_adjust(rn
, pi
);
395 void bgp_path_info_unset_flag(struct bgp_node
*rn
, struct bgp_path_info
*pi
,
398 UNSET_FLAG(pi
->flags
, flag
);
400 /* early bath if we know it's not a flag that changes countability state
402 if (!CHECK_FLAG(flag
,
403 BGP_PATH_VALID
| BGP_PATH_HISTORY
| BGP_PATH_REMOVED
))
406 bgp_pcount_adjust(rn
, pi
);
409 /* Get MED value. If MED value is missing and "bgp bestpath
410 missing-as-worst" is specified, treat it as the worst value. */
411 static uint32_t bgp_med_value(struct attr
*attr
, struct bgp
*bgp
)
413 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
416 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
423 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info
*pi
, char *buf
)
425 if (pi
->addpath_rx_id
)
426 sprintf(buf
, "path %s (addpath rxid %d)", pi
->peer
->host
,
429 sprintf(buf
, "path %s", pi
->peer
->host
);
432 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
434 static int bgp_path_info_cmp(struct bgp
*bgp
, struct bgp_path_info
*new,
435 struct bgp_path_info
*exist
, int *paths_eq
,
436 struct bgp_maxpaths_cfg
*mpath_cfg
, int debug
,
437 char *pfx_buf
, afi_t afi
, safi_t safi
,
438 enum bgp_path_selection_reason
*reason
)
440 struct attr
*newattr
, *existattr
;
441 bgp_peer_sort_t new_sort
;
442 bgp_peer_sort_t exist_sort
;
448 uint32_t exist_weight
;
449 uint32_t newm
, existm
;
450 struct in_addr new_id
;
451 struct in_addr exist_id
;
454 int internal_as_route
;
457 char new_buf
[PATH_ADDPATH_STR_BUFFER
];
458 char exist_buf
[PATH_ADDPATH_STR_BUFFER
];
460 uint32_t exist_mm_seq
;
467 *reason
= bgp_path_selection_none
;
469 zlog_debug("%s: new is NULL", pfx_buf
);
474 bgp_path_info_path_with_addpath_rx_str(new, new_buf
);
477 *reason
= bgp_path_selection_first
;
479 zlog_debug("%s: %s is the initial bestpath", pfx_buf
,
485 bgp_path_info_path_with_addpath_rx_str(exist
, exist_buf
);
486 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
487 pfx_buf
, new_buf
, new->flags
, exist_buf
,
492 existattr
= exist
->attr
;
494 /* For EVPN routes, we cannot just go by local vs remote, we have to
495 * look at the MAC mobility sequence number, if present.
497 if (safi
== SAFI_EVPN
) {
498 /* This is an error condition described in RFC 7432 Section
500 * states that in this scenario "the PE MUST alert the operator"
502 * does not state what other action to take. In order to provide
504 * consistency in this scenario we are going to prefer the path
508 if (newattr
->sticky
!= existattr
->sticky
) {
510 prefix2str(&new->net
->p
, pfx_buf
,
512 * PREFIX2STR_BUFFER
);
513 bgp_path_info_path_with_addpath_rx_str(new,
515 bgp_path_info_path_with_addpath_rx_str(
519 if (newattr
->sticky
&& !existattr
->sticky
) {
520 *reason
= bgp_path_selection_evpn_sticky_mac
;
523 "%s: %s wins over %s due to sticky MAC flag",
524 pfx_buf
, new_buf
, exist_buf
);
528 if (!newattr
->sticky
&& existattr
->sticky
) {
529 *reason
= bgp_path_selection_evpn_sticky_mac
;
532 "%s: %s loses to %s due to sticky MAC flag",
533 pfx_buf
, new_buf
, exist_buf
);
538 new_mm_seq
= mac_mobility_seqnum(newattr
);
539 exist_mm_seq
= mac_mobility_seqnum(existattr
);
541 if (new_mm_seq
> exist_mm_seq
) {
542 *reason
= bgp_path_selection_evpn_seq
;
545 "%s: %s wins over %s due to MM seq %u > %u",
546 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
551 if (new_mm_seq
< exist_mm_seq
) {
552 *reason
= bgp_path_selection_evpn_seq
;
555 "%s: %s loses to %s due to MM seq %u < %u",
556 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
562 * if sequence numbers are the same path with the lowest IP
565 nh_cmp
= bgp_path_info_nexthop_cmp(new, exist
);
567 *reason
= bgp_path_selection_evpn_lower_ip
;
570 "%s: %s wins over %s due to same MM seq %u and lower IP %s",
571 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
572 inet_ntoa(new->attr
->nexthop
));
576 *reason
= bgp_path_selection_evpn_lower_ip
;
579 "%s: %s loses to %s due to same MM seq %u and higher IP %s",
580 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
581 inet_ntoa(new->attr
->nexthop
));
586 /* 1. Weight check. */
587 new_weight
= newattr
->weight
;
588 exist_weight
= existattr
->weight
;
590 if (new_weight
> exist_weight
) {
591 *reason
= bgp_path_selection_weight
;
593 zlog_debug("%s: %s wins over %s due to weight %d > %d",
594 pfx_buf
, new_buf
, exist_buf
, new_weight
,
599 if (new_weight
< exist_weight
) {
600 *reason
= bgp_path_selection_weight
;
602 zlog_debug("%s: %s loses to %s due to weight %d < %d",
603 pfx_buf
, new_buf
, exist_buf
, new_weight
,
608 /* 2. Local preference check. */
609 new_pref
= exist_pref
= bgp
->default_local_pref
;
611 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
612 new_pref
= newattr
->local_pref
;
613 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
614 exist_pref
= existattr
->local_pref
;
616 if (new_pref
> exist_pref
) {
617 *reason
= bgp_path_selection_local_pref
;
620 "%s: %s wins over %s due to localpref %d > %d",
621 pfx_buf
, new_buf
, exist_buf
, new_pref
,
626 if (new_pref
< exist_pref
) {
627 *reason
= bgp_path_selection_local_pref
;
630 "%s: %s loses to %s due to localpref %d < %d",
631 pfx_buf
, new_buf
, exist_buf
, new_pref
,
636 /* 3. Local route check. We prefer:
638 * - BGP_ROUTE_AGGREGATE
639 * - BGP_ROUTE_REDISTRIBUTE
641 if (!(new->sub_type
== BGP_ROUTE_NORMAL
||
642 new->sub_type
== BGP_ROUTE_IMPORTED
)) {
643 *reason
= bgp_path_selection_local_route
;
646 "%s: %s wins over %s due to preferred BGP_ROUTE type",
647 pfx_buf
, new_buf
, exist_buf
);
651 if (!(exist
->sub_type
== BGP_ROUTE_NORMAL
||
652 exist
->sub_type
== BGP_ROUTE_IMPORTED
)) {
653 *reason
= bgp_path_selection_local_route
;
656 "%s: %s loses to %s due to preferred BGP_ROUTE type",
657 pfx_buf
, new_buf
, exist_buf
);
661 /* 4. AS path length check. */
662 if (!bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
)) {
663 int exist_hops
= aspath_count_hops(existattr
->aspath
);
664 int exist_confeds
= aspath_count_confeds(existattr
->aspath
);
666 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
)) {
669 aspath_hops
= aspath_count_hops(newattr
->aspath
);
670 aspath_hops
+= aspath_count_confeds(newattr
->aspath
);
672 if (aspath_hops
< (exist_hops
+ exist_confeds
)) {
673 *reason
= bgp_path_selection_confed_as_path
;
676 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
677 pfx_buf
, new_buf
, exist_buf
,
679 (exist_hops
+ exist_confeds
));
683 if (aspath_hops
> (exist_hops
+ exist_confeds
)) {
684 *reason
= bgp_path_selection_confed_as_path
;
687 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
688 pfx_buf
, new_buf
, exist_buf
,
690 (exist_hops
+ exist_confeds
));
694 int newhops
= aspath_count_hops(newattr
->aspath
);
696 if (newhops
< exist_hops
) {
697 *reason
= bgp_path_selection_as_path
;
700 "%s: %s wins over %s due to aspath hopcount %d < %d",
701 pfx_buf
, new_buf
, exist_buf
,
702 newhops
, exist_hops
);
706 if (newhops
> exist_hops
) {
707 *reason
= bgp_path_selection_as_path
;
710 "%s: %s loses to %s due to aspath hopcount %d > %d",
711 pfx_buf
, new_buf
, exist_buf
,
712 newhops
, exist_hops
);
718 /* 5. Origin check. */
719 if (newattr
->origin
< existattr
->origin
) {
720 *reason
= bgp_path_selection_origin
;
722 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
723 pfx_buf
, new_buf
, exist_buf
,
724 bgp_origin_long_str
[newattr
->origin
],
725 bgp_origin_long_str
[existattr
->origin
]);
729 if (newattr
->origin
> existattr
->origin
) {
730 *reason
= bgp_path_selection_origin
;
732 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
733 pfx_buf
, new_buf
, exist_buf
,
734 bgp_origin_long_str
[newattr
->origin
],
735 bgp_origin_long_str
[existattr
->origin
]);
740 internal_as_route
= (aspath_count_hops(newattr
->aspath
) == 0
741 && aspath_count_hops(existattr
->aspath
) == 0);
742 confed_as_route
= (aspath_count_confeds(newattr
->aspath
) > 0
743 && aspath_count_confeds(existattr
->aspath
) > 0
744 && aspath_count_hops(newattr
->aspath
) == 0
745 && aspath_count_hops(existattr
->aspath
) == 0);
747 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
)
748 || (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
) && confed_as_route
)
749 || aspath_cmp_left(newattr
->aspath
, existattr
->aspath
)
750 || aspath_cmp_left_confed(newattr
->aspath
, existattr
->aspath
)
751 || internal_as_route
) {
752 new_med
= bgp_med_value(new->attr
, bgp
);
753 exist_med
= bgp_med_value(exist
->attr
, bgp
);
755 if (new_med
< exist_med
) {
756 *reason
= bgp_path_selection_med
;
759 "%s: %s wins over %s due to MED %d < %d",
760 pfx_buf
, new_buf
, exist_buf
, new_med
,
765 if (new_med
> exist_med
) {
766 *reason
= bgp_path_selection_med
;
769 "%s: %s loses to %s due to MED %d > %d",
770 pfx_buf
, new_buf
, exist_buf
, new_med
,
776 /* 7. Peer type check. */
777 new_sort
= new->peer
->sort
;
778 exist_sort
= exist
->peer
->sort
;
780 if (new_sort
== BGP_PEER_EBGP
781 && (exist_sort
== BGP_PEER_IBGP
|| exist_sort
== BGP_PEER_CONFED
)) {
782 *reason
= bgp_path_selection_peer
;
785 "%s: %s wins over %s due to eBGP peer > iBGP peer",
786 pfx_buf
, new_buf
, exist_buf
);
790 if (exist_sort
== BGP_PEER_EBGP
791 && (new_sort
== BGP_PEER_IBGP
|| new_sort
== BGP_PEER_CONFED
)) {
792 *reason
= bgp_path_selection_peer
;
795 "%s: %s loses to %s due to iBGP peer < eBGP peer",
796 pfx_buf
, new_buf
, exist_buf
);
800 /* 8. IGP metric check. */
804 newm
= new->extra
->igpmetric
;
806 existm
= exist
->extra
->igpmetric
;
811 "%s: %s wins over %s due to IGP metric %d < %d",
812 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
819 "%s: %s loses to %s due to IGP metric %d > %d",
820 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
824 /* 9. Same IGP metric. Compare the cluster list length as
825 representative of IGP hops metric. Rewrite the metric value
826 pair (newm, existm) with the cluster list length. Prefer the
827 path with smaller cluster list length. */
828 if (newm
== existm
) {
829 if (peer_sort(new->peer
) == BGP_PEER_IBGP
830 && peer_sort(exist
->peer
) == BGP_PEER_IBGP
831 && (mpath_cfg
== NULL
833 mpath_cfg
->ibgp_flags
,
834 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN
))) {
835 newm
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
836 existm
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
841 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
842 pfx_buf
, new_buf
, exist_buf
,
850 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
851 pfx_buf
, new_buf
, exist_buf
,
858 /* 10. confed-external vs. confed-internal */
859 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
860 if (new_sort
== BGP_PEER_CONFED
861 && exist_sort
== BGP_PEER_IBGP
) {
862 *reason
= bgp_path_selection_confed
;
865 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
866 pfx_buf
, new_buf
, exist_buf
);
870 if (exist_sort
== BGP_PEER_CONFED
871 && new_sort
== BGP_PEER_IBGP
) {
872 *reason
= bgp_path_selection_confed
;
875 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
876 pfx_buf
, new_buf
, exist_buf
);
881 /* 11. Maximum path check. */
882 if (newm
== existm
) {
883 /* If one path has a label but the other does not, do not treat
884 * them as equals for multipath
886 if ((new->extra
&&bgp_is_valid_label(&new->extra
->label
[0]))
888 && bgp_is_valid_label(&exist
->extra
->label
[0]))) {
891 "%s: %s and %s cannot be multipath, one has a label while the other does not",
892 pfx_buf
, new_buf
, exist_buf
);
893 } else if (bgp_flag_check(bgp
,
894 BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
897 * For the two paths, all comparison steps till IGP
899 * have succeeded - including AS_PATH hop count. Since
901 * bestpath as-path multipath-relax' knob is on, we
903 * an exact match of AS_PATH. Thus, mark the paths are
905 * That will trigger both these paths to get into the
913 "%s: %s and %s are equal via multipath-relax",
914 pfx_buf
, new_buf
, exist_buf
);
915 } else if (new->peer
->sort
== BGP_PEER_IBGP
) {
916 if (aspath_cmp(new->attr
->aspath
,
917 exist
->attr
->aspath
)) {
922 "%s: %s and %s are equal via matching aspaths",
923 pfx_buf
, new_buf
, exist_buf
);
925 } else if (new->peer
->as
== exist
->peer
->as
) {
930 "%s: %s and %s are equal via same remote-as",
931 pfx_buf
, new_buf
, exist_buf
);
935 * TODO: If unequal cost ibgp multipath is enabled we can
936 * mark the paths as equal here instead of returning
941 "%s: %s wins over %s after IGP metric comparison",
942 pfx_buf
, new_buf
, exist_buf
);
945 "%s: %s loses to %s after IGP metric comparison",
946 pfx_buf
, new_buf
, exist_buf
);
948 *reason
= bgp_path_selection_igp_metric
;
952 /* 12. If both paths are external, prefer the path that was received
953 first (the oldest one). This step minimizes route-flap, since a
954 newer path won't displace an older one, even if it was the
955 preferred route based on the additional decision criteria below. */
956 if (!bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
957 && new_sort
== BGP_PEER_EBGP
&& exist_sort
== BGP_PEER_EBGP
) {
958 if (CHECK_FLAG(new->flags
, BGP_PATH_SELECTED
)) {
959 *reason
= bgp_path_selection_older
;
962 "%s: %s wins over %s due to oldest external",
963 pfx_buf
, new_buf
, exist_buf
);
967 if (CHECK_FLAG(exist
->flags
, BGP_PATH_SELECTED
)) {
968 *reason
= bgp_path_selection_older
;
971 "%s: %s loses to %s due to oldest external",
972 pfx_buf
, new_buf
, exist_buf
);
977 /* 13. Router-ID comparision. */
978 /* If one of the paths is "stale", the corresponding peer router-id will
979 * be 0 and would always win over the other path. If originator id is
980 * used for the comparision, it will decide which path is better.
982 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
983 new_id
.s_addr
= newattr
->originator_id
.s_addr
;
985 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
986 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
987 exist_id
.s_addr
= existattr
->originator_id
.s_addr
;
989 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
991 if (ntohl(new_id
.s_addr
) < ntohl(exist_id
.s_addr
)) {
992 *reason
= bgp_path_selection_router_id
;
995 "%s: %s wins over %s due to Router-ID comparison",
996 pfx_buf
, new_buf
, exist_buf
);
1000 if (ntohl(new_id
.s_addr
) > ntohl(exist_id
.s_addr
)) {
1001 *reason
= bgp_path_selection_router_id
;
1004 "%s: %s loses to %s due to Router-ID comparison",
1005 pfx_buf
, new_buf
, exist_buf
);
1009 /* 14. Cluster length comparision. */
1010 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
1011 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
1013 if (new_cluster
< exist_cluster
) {
1014 *reason
= bgp_path_selection_cluster_length
;
1017 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1018 pfx_buf
, new_buf
, exist_buf
, new_cluster
,
1023 if (new_cluster
> exist_cluster
) {
1024 *reason
= bgp_path_selection_cluster_length
;
1027 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1028 pfx_buf
, new_buf
, exist_buf
, new_cluster
,
1033 /* 15. Neighbor address comparision. */
1034 /* Do this only if neither path is "stale" as stale paths do not have
1035 * valid peer information (as the connection may or may not be up).
1037 if (CHECK_FLAG(exist
->flags
, BGP_PATH_STALE
)) {
1038 *reason
= bgp_path_selection_stale
;
1041 "%s: %s wins over %s due to latter path being STALE",
1042 pfx_buf
, new_buf
, exist_buf
);
1046 if (CHECK_FLAG(new->flags
, BGP_PATH_STALE
)) {
1047 *reason
= bgp_path_selection_stale
;
1050 "%s: %s loses to %s due to former path being STALE",
1051 pfx_buf
, new_buf
, exist_buf
);
1055 /* locally configured routes to advertise do not have su_remote */
1056 if (new->peer
->su_remote
== NULL
) {
1057 *reason
= bgp_path_selection_local_configured
;
1060 if (exist
->peer
->su_remote
== NULL
) {
1061 *reason
= bgp_path_selection_local_configured
;
1065 ret
= sockunion_cmp(new->peer
->su_remote
, exist
->peer
->su_remote
);
1068 *reason
= bgp_path_selection_neighbor_ip
;
1071 "%s: %s loses to %s due to Neighor IP comparison",
1072 pfx_buf
, new_buf
, exist_buf
);
1077 *reason
= bgp_path_selection_neighbor_ip
;
1080 "%s: %s wins over %s due to Neighor IP comparison",
1081 pfx_buf
, new_buf
, exist_buf
);
1085 *reason
= bgp_path_selection_default
;
1087 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1088 pfx_buf
, new_buf
, exist_buf
);
1093 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1094 * is preferred, or 0 if they are the same (usually will only occur if
1095 * multipath is enabled
1096 * This version is compatible with */
1097 int bgp_path_info_cmp_compatible(struct bgp
*bgp
, struct bgp_path_info
*new,
1098 struct bgp_path_info
*exist
, char *pfx_buf
,
1099 afi_t afi
, safi_t safi
,
1100 enum bgp_path_selection_reason
*reason
)
1104 ret
= bgp_path_info_cmp(bgp
, new, exist
, &paths_eq
, NULL
, 0, pfx_buf
,
1118 static enum filter_type
bgp_input_filter(struct peer
*peer
, struct prefix
*p
,
1119 struct attr
*attr
, afi_t afi
,
1122 struct bgp_filter
*filter
;
1124 filter
= &peer
->filter
[afi
][safi
];
1126 #define FILTER_EXIST_WARN(F, f, filter) \
1127 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1128 zlog_debug("%s: Could not find configured input %s-list %s!", \
1129 peer->host, #f, F##_IN_NAME(filter));
1131 if (DISTRIBUTE_IN_NAME(filter
)) {
1132 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
1134 if (access_list_apply(DISTRIBUTE_IN(filter
), p
) == FILTER_DENY
)
1138 if (PREFIX_LIST_IN_NAME(filter
)) {
1139 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
1141 if (prefix_list_apply(PREFIX_LIST_IN(filter
), p
) == PREFIX_DENY
)
1145 if (FILTER_LIST_IN_NAME(filter
)) {
1146 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
1148 if (as_list_apply(FILTER_LIST_IN(filter
), attr
->aspath
)
1153 return FILTER_PERMIT
;
1154 #undef FILTER_EXIST_WARN
1157 static enum filter_type
bgp_output_filter(struct peer
*peer
, struct prefix
*p
,
1158 struct attr
*attr
, afi_t afi
,
1161 struct bgp_filter
*filter
;
1163 filter
= &peer
->filter
[afi
][safi
];
1165 #define FILTER_EXIST_WARN(F, f, filter) \
1166 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1167 zlog_debug("%s: Could not find configured output %s-list %s!", \
1168 peer->host, #f, F##_OUT_NAME(filter));
1170 if (DISTRIBUTE_OUT_NAME(filter
)) {
1171 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
1173 if (access_list_apply(DISTRIBUTE_OUT(filter
), p
) == FILTER_DENY
)
1177 if (PREFIX_LIST_OUT_NAME(filter
)) {
1178 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
1180 if (prefix_list_apply(PREFIX_LIST_OUT(filter
), p
)
1185 if (FILTER_LIST_OUT_NAME(filter
)) {
1186 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
1188 if (as_list_apply(FILTER_LIST_OUT(filter
), attr
->aspath
)
1193 return FILTER_PERMIT
;
1194 #undef FILTER_EXIST_WARN
1197 /* If community attribute includes no_export then return 1. */
1198 static int bgp_community_filter(struct peer
*peer
, struct attr
*attr
)
1200 if (attr
->community
) {
1201 /* NO_ADVERTISE check. */
1202 if (community_include(attr
->community
, COMMUNITY_NO_ADVERTISE
))
1205 /* NO_EXPORT check. */
1206 if (peer
->sort
== BGP_PEER_EBGP
1207 && community_include(attr
->community
, COMMUNITY_NO_EXPORT
))
1210 /* NO_EXPORT_SUBCONFED check. */
1211 if (peer
->sort
== BGP_PEER_EBGP
1212 || peer
->sort
== BGP_PEER_CONFED
)
1213 if (community_include(attr
->community
,
1214 COMMUNITY_NO_EXPORT_SUBCONFED
))
1220 /* Route reflection loop check. */
1221 static int bgp_cluster_filter(struct peer
*peer
, struct attr
*attr
)
1223 struct in_addr cluster_id
;
1225 if (attr
->cluster
) {
1226 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
1227 cluster_id
= peer
->bgp
->cluster_id
;
1229 cluster_id
= peer
->bgp
->router_id
;
1231 if (cluster_loop_check(attr
->cluster
, cluster_id
))
1237 static int bgp_input_modifier(struct peer
*peer
, struct prefix
*p
,
1238 struct attr
*attr
, afi_t afi
, safi_t safi
,
1239 const char *rmap_name
)
1241 struct bgp_filter
*filter
;
1242 struct bgp_path_info rmap_path
;
1243 route_map_result_t ret
;
1244 struct route_map
*rmap
= NULL
;
1246 filter
= &peer
->filter
[afi
][safi
];
1248 /* Apply default weight value. */
1249 if (peer
->weight
[afi
][safi
])
1250 attr
->weight
= peer
->weight
[afi
][safi
];
1253 rmap
= route_map_lookup_by_name(rmap_name
);
1258 if (ROUTE_MAP_IN_NAME(filter
)) {
1259 rmap
= ROUTE_MAP_IN(filter
);
1266 /* Route map apply. */
1268 memset(&rmap_path
, 0, sizeof(struct bgp_path_info
));
1269 /* Duplicate current value to new strucutre for modification. */
1270 rmap_path
.peer
= peer
;
1271 rmap_path
.attr
= attr
;
1273 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1275 /* Apply BGP route map to the attribute. */
1276 ret
= route_map_apply(rmap
, p
, RMAP_BGP
, &rmap_path
);
1278 peer
->rmap_type
= 0;
1280 if (ret
== RMAP_DENYMATCH
)
1286 static int bgp_output_modifier(struct peer
*peer
, struct prefix
*p
,
1287 struct attr
*attr
, afi_t afi
, safi_t safi
,
1288 const char *rmap_name
)
1290 struct bgp_path_info rmap_path
;
1291 route_map_result_t ret
;
1292 struct route_map
*rmap
= NULL
;
1296 * So if we get to this point and have no rmap_name
1297 * we want to just show the output as it currently
1303 /* Apply default weight value. */
1304 if (peer
->weight
[afi
][safi
])
1305 attr
->weight
= peer
->weight
[afi
][safi
];
1307 rmap
= route_map_lookup_by_name(rmap_name
);
1310 * If we have a route map name and we do not find
1311 * the routemap that means we have an implicit
1317 memset(&rmap_path
, 0, sizeof(struct bgp_path_info
));
1318 /* Route map apply. */
1319 /* Duplicate current value to new strucutre for modification. */
1320 rmap_path
.peer
= peer
;
1321 rmap_path
.attr
= attr
;
1323 rmap_type
= peer
->rmap_type
;
1324 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1326 /* Apply BGP route map to the attribute. */
1327 ret
= route_map_apply(rmap
, p
, RMAP_BGP
, &rmap_path
);
1329 peer
->rmap_type
= rmap_type
;
1331 if (ret
== RMAP_DENYMATCH
)
1333 * caller has multiple error paths with bgp_attr_flush()
1340 /* If this is an EBGP peer with remove-private-AS */
1341 static void bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1342 struct peer
*peer
, struct attr
*attr
)
1344 if (peer
->sort
== BGP_PEER_EBGP
1345 && (peer_af_flag_check(peer
, afi
, safi
,
1346 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)
1347 || peer_af_flag_check(peer
, afi
, safi
,
1348 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)
1349 || peer_af_flag_check(peer
, afi
, safi
,
1350 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)
1351 || peer_af_flag_check(peer
, afi
, safi
,
1352 PEER_FLAG_REMOVE_PRIVATE_AS
))) {
1353 // Take action on the entire aspath
1354 if (peer_af_flag_check(peer
, afi
, safi
,
1355 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)
1356 || peer_af_flag_check(peer
, afi
, safi
,
1357 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
1358 if (peer_af_flag_check(
1360 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1361 attr
->aspath
= aspath_replace_private_asns(
1362 attr
->aspath
, bgp
->as
);
1364 // The entire aspath consists of private ASNs so create
1366 else if (aspath_private_as_check(attr
->aspath
))
1367 attr
->aspath
= aspath_empty_get();
1369 // There are some public and some private ASNs, remove
1372 attr
->aspath
= aspath_remove_private_asns(
1376 // 'all' was not specified so the entire aspath must be private
1378 // for us to do anything
1379 else if (aspath_private_as_check(attr
->aspath
)) {
1380 if (peer_af_flag_check(
1382 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1383 attr
->aspath
= aspath_replace_private_asns(
1384 attr
->aspath
, bgp
->as
);
1386 attr
->aspath
= aspath_empty_get();
1391 /* If this is an EBGP peer with as-override */
1392 static void bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1393 struct peer
*peer
, struct attr
*attr
)
1395 if (peer
->sort
== BGP_PEER_EBGP
1396 && peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
1397 if (aspath_single_asn_check(attr
->aspath
, peer
->as
))
1398 attr
->aspath
= aspath_replace_specific_asn(
1399 attr
->aspath
, peer
->as
, bgp
->as
);
1403 void bgp_attr_add_gshut_community(struct attr
*attr
)
1405 struct community
*old
;
1406 struct community
*new;
1407 struct community
*merge
;
1408 struct community
*gshut
;
1410 old
= attr
->community
;
1411 gshut
= community_str2com("graceful-shutdown");
1416 merge
= community_merge(community_dup(old
), gshut
);
1418 if (old
->refcnt
== 0)
1419 community_free(&old
);
1421 new = community_uniq_sort(merge
);
1422 community_free(&merge
);
1424 new = community_dup(gshut
);
1427 community_free(&gshut
);
1428 attr
->community
= new;
1429 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
);
1431 /* When we add the graceful-shutdown community we must also
1432 * lower the local-preference */
1433 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1434 attr
->local_pref
= BGP_GSHUT_LOCAL_PREF
;
1438 static void subgroup_announce_reset_nhop(uint8_t family
, struct attr
*attr
)
1440 if (family
== AF_INET
) {
1441 attr
->nexthop
.s_addr
= 0;
1442 attr
->mp_nexthop_global_in
.s_addr
= 0;
1444 if (family
== AF_INET6
)
1445 memset(&attr
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1446 if (family
== AF_EVPN
)
1447 memset(&attr
->mp_nexthop_global_in
, 0, BGP_ATTR_NHLEN_IPV4
);
1450 int subgroup_announce_check(struct bgp_node
*rn
, struct bgp_path_info
*pi
,
1451 struct update_subgroup
*subgrp
, struct prefix
*p
,
1454 struct bgp_filter
*filter
;
1457 struct peer
*onlypeer
;
1459 struct attr
*piattr
;
1460 char buf
[PREFIX_STRLEN
];
1466 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1468 if (DISABLE_BGP_ANNOUNCE
)
1471 afi
= SUBGRP_AFI(subgrp
);
1472 safi
= SUBGRP_SAFI(subgrp
);
1473 peer
= SUBGRP_PEER(subgrp
);
1475 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
))
1476 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1479 filter
= &peer
->filter
[afi
][safi
];
1480 bgp
= SUBGRP_INST(subgrp
);
1481 piattr
= bgp_path_info_mpath_count(pi
) ? bgp_path_info_mpath_attr(pi
)
1485 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
)
1486 && ((pi
->type
== ZEBRA_ROUTE_BGP_DIRECT
)
1487 || (pi
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1490 * direct and direct_ext type routes originate internally even
1491 * though they can have peer pointers that reference other
1494 prefix2str(p
, buf
, PREFIX_STRLEN
);
1495 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe",
1501 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
))
1502 && ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_UNICAST
))
1503 && (pi
->type
== ZEBRA_ROUTE_BGP
)
1504 && (pi
->sub_type
== BGP_ROUTE_IMPORTED
)) {
1506 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1511 /* With addpath we may be asked to TX all kinds of paths so make sure
1513 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_VALID
)
1514 || CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
)
1515 || CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)) {
1519 /* If this is not the bestpath then check to see if there is an enabled
1521 * feature that requires us to advertise it */
1522 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)) {
1523 if (!bgp_addpath_tx_path(peer
->addpath_type
[afi
][safi
], pi
)) {
1528 /* Aggregate-address suppress check. */
1529 if (pi
->extra
&& pi
->extra
->suppress
)
1530 if (!UNSUPPRESS_MAP_NAME(filter
)) {
1535 * If we are doing VRF 2 VRF leaking via the import
1536 * statement, we want to prevent the route going
1537 * off box as that the RT and RD created are localy
1538 * significant and globaly useless.
1540 if (safi
== SAFI_MPLS_VPN
&& pi
->extra
&& pi
->extra
->num_labels
1541 && pi
->extra
->label
[0] == BGP_PREVENT_VRF_2_VRF_LEAK
)
1544 /* If it's labeled safi, make sure the route has a valid label. */
1545 if (safi
== SAFI_LABELED_UNICAST
) {
1546 mpls_label_t label
= bgp_adv_label(rn
, pi
, peer
, afi
, safi
);
1547 if (!bgp_is_valid_label(&label
)) {
1548 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1549 zlog_debug("u%" PRIu64
":s%" PRIu64
1550 " %s/%d is filtered - no label (%p)",
1551 subgrp
->update_group
->id
, subgrp
->id
,
1552 inet_ntop(p
->family
, &p
->u
.prefix
,
1553 buf
, SU_ADDRSTRLEN
),
1554 p
->prefixlen
, &label
);
1559 /* Do not send back route to sender. */
1560 if (onlypeer
&& from
== onlypeer
) {
1564 /* Do not send the default route in the BGP table if the neighbor is
1565 * configured for default-originate */
1566 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1567 PEER_FLAG_DEFAULT_ORIGINATE
)) {
1568 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1570 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1574 /* Transparency check. */
1575 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1576 && CHECK_FLAG(from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1581 /* If community is not disabled check the no-export and local. */
1582 if (!transparent
&& bgp_community_filter(peer
, piattr
)) {
1583 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1585 "subgrpannouncecheck: community filter check fail");
1589 /* If the attribute has originator-id and it is same as remote
1591 if (onlypeer
&& piattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)
1592 && (IPV4_ADDR_SAME(&onlypeer
->remote_id
, &piattr
->originator_id
))) {
1593 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1595 "%s [Update:SEND] %s originator-id is same as "
1598 prefix2str(p
, buf
, sizeof(buf
)));
1602 /* ORF prefix-list filter check */
1603 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1604 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1605 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
1606 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1607 if (peer
->orf_plist
[afi
][safi
]) {
1608 if (prefix_list_apply(peer
->orf_plist
[afi
][safi
], p
)
1610 if (bgp_debug_update(NULL
, p
,
1611 subgrp
->update_group
, 0))
1613 "%s [Update:SEND] %s is filtered via ORF",
1621 /* Output filter check. */
1622 if (bgp_output_filter(peer
, p
, piattr
, afi
, safi
) == FILTER_DENY
) {
1623 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1624 zlog_debug("%s [Update:SEND] %s is filtered",
1625 peer
->host
, prefix2str(p
, buf
, sizeof(buf
)));
1629 #ifdef BGP_SEND_ASPATH_CHECK
1630 /* AS path loop check. */
1631 if (onlypeer
&& aspath_loop_check(piattr
->aspath
, onlypeer
->as
)) {
1632 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1634 "%s [Update:SEND] suppress announcement to peer AS %u "
1635 "that is part of AS path.",
1636 onlypeer
->host
, onlypeer
->as
);
1639 #endif /* BGP_SEND_ASPATH_CHECK */
1641 /* If we're a CONFED we need to loop check the CONFED ID too */
1642 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
1643 if (aspath_loop_check(piattr
->aspath
, bgp
->confed_id
)) {
1644 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1646 "%s [Update:SEND] suppress announcement to peer AS %u"
1648 peer
->host
, bgp
->confed_id
);
1653 /* Route-Reflect check. */
1654 if (from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1659 /* IBGP reflection check. */
1660 if (reflect
&& !samepeer_safe
) {
1661 /* A route from a Client peer. */
1662 if (CHECK_FLAG(from
->af_flags
[afi
][safi
],
1663 PEER_FLAG_REFLECTOR_CLIENT
)) {
1664 /* Reflect to all the Non-Client peers and also to the
1665 Client peers other than the originator. Originator
1667 is already done. So there is noting to do. */
1668 /* no bgp client-to-client reflection check. */
1669 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
1670 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1671 PEER_FLAG_REFLECTOR_CLIENT
))
1674 /* A route from a Non-client peer. Reflect to all other
1676 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1677 PEER_FLAG_REFLECTOR_CLIENT
))
1682 /* For modify attribute, copy it to temporary structure. */
1683 bgp_attr_dup(attr
, piattr
);
1685 /* If local-preference is not set. */
1686 if ((peer
->sort
== BGP_PEER_IBGP
|| peer
->sort
== BGP_PEER_CONFED
)
1687 && (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)))) {
1688 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1689 attr
->local_pref
= bgp
->default_local_pref
;
1692 /* If originator-id is not set and the route is to be reflected,
1693 set the originator id */
1695 && (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)))) {
1696 IPV4_ADDR_COPY(&(attr
->originator_id
), &(from
->remote_id
));
1697 SET_FLAG(attr
->flag
, BGP_ATTR_ORIGINATOR_ID
);
1700 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
1702 if (peer
->sort
== BGP_PEER_EBGP
1703 && attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)) {
1704 if (from
!= bgp
->peer_self
&& !transparent
1705 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1706 PEER_FLAG_MED_UNCHANGED
))
1708 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
));
1711 /* Since the nexthop attribute can vary per peer, it is not explicitly
1713 * in announce check, only certain flags and length (or number of
1715 * -- for IPv6/MP_REACH) are set here in order to guide the update
1717 * code in setting the nexthop(s) on a per peer basis in
1719 * Typically, the source nexthop in the attribute is preserved but in
1721 * scenarios where we know it will always be overwritten, we reset the
1722 * nexthop to "0" in an attempt to achieve better Update packing. An
1723 * example of this is when a prefix from each of 2 IBGP peers needs to
1725 * announced to an EBGP peer (and they have the same attributes barring
1729 SET_FLAG(attr
->rmap_change_flags
, BATTR_REFLECTED
);
1731 #define NEXTHOP_IS_V6 \
1732 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
1733 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
1734 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
1735 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1737 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
1739 * the peer (group) is configured to receive link-local nexthop
1741 * and it is available in the prefix OR we're not reflecting the route
1743 * the peer (group) to whom we're going to announce is on a shared
1745 * and this is either a self-originated route or the peer is EBGP.
1747 if (NEXTHOP_IS_V6
) {
1748 attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1749 if ((CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1750 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)
1751 && IN6_IS_ADDR_LINKLOCAL(&attr
->mp_nexthop_local
))
1752 || (!reflect
&& peer
->shared_network
1753 && (from
== bgp
->peer_self
1754 || peer
->sort
== BGP_PEER_EBGP
))) {
1755 attr
->mp_nexthop_len
=
1756 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
1759 /* Clear off link-local nexthop in source, whenever it is not
1761 * ensure more prefixes share the same attribute for
1764 if (!(CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1765 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)))
1766 memset(&attr
->mp_nexthop_local
, 0, IPV6_MAX_BYTELEN
);
1769 bgp_peer_remove_private_as(bgp
, afi
, safi
, peer
, attr
);
1770 bgp_peer_as_override(bgp
, afi
, safi
, peer
, attr
);
1772 /* Route map & unsuppress-map apply. */
1773 if (ROUTE_MAP_OUT_NAME(filter
) || (pi
->extra
&& pi
->extra
->suppress
)) {
1774 struct bgp_path_info rmap_path
;
1775 struct bgp_path_info_extra dummy_rmap_path_extra
;
1776 struct attr dummy_attr
;
1778 memset(&rmap_path
, 0, sizeof(struct bgp_path_info
));
1779 rmap_path
.peer
= peer
;
1780 rmap_path
.attr
= attr
;
1783 memcpy(&dummy_rmap_path_extra
, pi
->extra
,
1784 sizeof(struct bgp_path_info_extra
));
1785 rmap_path
.extra
= &dummy_rmap_path_extra
;
1788 /* don't confuse inbound and outbound setting */
1789 RESET_FLAG(attr
->rmap_change_flags
);
1792 * The route reflector is not allowed to modify the attributes
1793 * of the reflected IBGP routes unless explicitly allowed.
1795 if ((from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1796 && !bgp_flag_check(bgp
,
1797 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
1798 bgp_attr_dup(&dummy_attr
, attr
);
1799 rmap_path
.attr
= &dummy_attr
;
1802 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1804 if (pi
->extra
&& pi
->extra
->suppress
)
1805 ret
= route_map_apply(UNSUPPRESS_MAP(filter
), p
,
1806 RMAP_BGP
, &rmap_path
);
1808 ret
= route_map_apply(ROUTE_MAP_OUT(filter
), p
,
1809 RMAP_BGP
, &rmap_path
);
1811 peer
->rmap_type
= 0;
1813 if (ret
== RMAP_DENYMATCH
) {
1814 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1815 zlog_debug("%s [Update:SEND] %s is filtered by route-map",
1816 peer
->host
, prefix2str(p
, buf
, sizeof(buf
)));
1818 bgp_attr_flush(attr
);
1823 /* RFC 8212 to prevent route leaks.
1824 * This specification intends to improve this situation by requiring the
1825 * explicit configuration of both BGP Import and Export Policies for any
1826 * External BGP (EBGP) session such as customers, peers, or
1827 * confederation boundaries for all enabled address families. Through
1828 * codification of the aforementioned requirement, operators will
1829 * benefit from consistent behavior across different BGP
1832 if (peer
->bgp
->ebgp_requires_policy
1833 == DEFAULT_EBGP_POLICY_ENABLED
)
1834 if (!bgp_outbound_policy_exists(peer
, filter
))
1837 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
)) {
1838 if (peer
->sort
== BGP_PEER_IBGP
1839 || peer
->sort
== BGP_PEER_CONFED
) {
1840 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1841 attr
->local_pref
= BGP_GSHUT_LOCAL_PREF
;
1843 bgp_attr_add_gshut_community(attr
);
1847 /* After route-map has been applied, we check to see if the nexthop to
1848 * be carried in the attribute (that is used for the announcement) can
1849 * be cleared off or not. We do this in all cases where we would be
1850 * setting the nexthop to "ourselves". For IPv6, we only need to
1852 * the global nexthop here; the link-local nexthop would have been
1854 * already, and if not, it is required by the update formation code.
1855 * Also see earlier comments in this function.
1858 * If route-map has performed some operation on the nexthop or the peer
1859 * configuration says to pass it unchanged, we cannot reset the nexthop
1860 * here, so only attempt to do it if these aren't true. Note that the
1861 * route-map handler itself might have cleared the nexthop, if for
1863 * it is configured as 'peer-address'.
1865 if (!bgp_rmap_nhop_changed(attr
->rmap_change_flags
,
1866 piattr
->rmap_change_flags
)
1868 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1869 PEER_FLAG_NEXTHOP_UNCHANGED
)) {
1870 /* We can reset the nexthop, if setting (or forcing) it to
1872 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1873 PEER_FLAG_NEXTHOP_SELF
)
1874 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1875 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
1877 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1878 PEER_FLAG_FORCE_NEXTHOP_SELF
))
1879 subgroup_announce_reset_nhop(
1880 (peer_cap_enhe(peer
, afi
, safi
)
1884 } else if (peer
->sort
== BGP_PEER_EBGP
) {
1885 /* Can also reset the nexthop if announcing to EBGP, but
1887 * no peer in the subgroup is on a shared subnet.
1888 * Note: 3rd party nexthop currently implemented for
1891 if ((p
->family
== AF_INET
) &&
1892 (!bgp_subgrp_multiaccess_check_v4(
1895 subgroup_announce_reset_nhop(
1896 (peer_cap_enhe(peer
, afi
, safi
)
1901 if ((p
->family
== AF_INET6
) &&
1902 (!bgp_subgrp_multiaccess_check_v6(
1903 piattr
->mp_nexthop_global
,
1905 subgroup_announce_reset_nhop(
1906 (peer_cap_enhe(peer
, afi
, safi
)
1913 } else if (CHECK_FLAG(pi
->flags
, BGP_PATH_ANNC_NH_SELF
)) {
1915 * This flag is used for leaked vpn-vrf routes
1917 int family
= p
->family
;
1919 if (peer_cap_enhe(peer
, afi
, safi
))
1922 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1924 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
1925 __func__
, family2str(family
));
1926 subgroup_announce_reset_nhop(family
, attr
);
1929 /* If IPv6/MP and nexthop does not have any override and happens
1931 * be a link-local address, reset it so that we don't pass along
1933 * source's link-local IPv6 address to recipients who may not be
1935 * the same interface.
1937 if (p
->family
== AF_INET6
|| peer_cap_enhe(peer
, afi
, safi
)) {
1938 if (IN6_IS_ADDR_LINKLOCAL(&attr
->mp_nexthop_global
))
1939 subgroup_announce_reset_nhop(AF_INET6
, attr
);
1946 void bgp_best_selection(struct bgp
*bgp
, struct bgp_node
*rn
,
1947 struct bgp_maxpaths_cfg
*mpath_cfg
,
1948 struct bgp_path_info_pair
*result
, afi_t afi
,
1951 struct bgp_path_info
*new_select
;
1952 struct bgp_path_info
*old_select
;
1953 struct bgp_path_info
*pi
;
1954 struct bgp_path_info
*pi1
;
1955 struct bgp_path_info
*pi2
;
1956 struct bgp_path_info
*nextpi
= NULL
;
1957 int paths_eq
, do_mpath
, debug
;
1958 struct list mp_list
;
1959 char pfx_buf
[PREFIX2STR_BUFFER
];
1960 char path_buf
[PATH_ADDPATH_STR_BUFFER
];
1962 bgp_mp_list_init(&mp_list
);
1964 (mpath_cfg
->maxpaths_ebgp
> 1 || mpath_cfg
->maxpaths_ibgp
> 1);
1966 debug
= bgp_debug_bestpath(&rn
->p
);
1969 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
1971 /* bgp deterministic-med */
1973 if (bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
1975 /* Clear BGP_PATH_DMED_SELECTED for all paths */
1976 for (pi1
= bgp_node_get_bgp_path_info(rn
); pi1
;
1978 bgp_path_info_unset_flag(rn
, pi1
,
1979 BGP_PATH_DMED_SELECTED
);
1981 for (pi1
= bgp_node_get_bgp_path_info(rn
); pi1
;
1983 if (CHECK_FLAG(pi1
->flags
, BGP_PATH_DMED_CHECK
))
1985 if (BGP_PATH_HOLDDOWN(pi1
))
1987 if (pi1
->peer
!= bgp
->peer_self
)
1988 if (pi1
->peer
->status
!= Established
)
1993 for (pi2
= pi1
->next
; pi2
; pi2
= pi2
->next
) {
1994 if (CHECK_FLAG(pi2
->flags
,
1995 BGP_PATH_DMED_CHECK
))
1997 if (BGP_PATH_HOLDDOWN(pi2
))
1999 if (pi2
->peer
!= bgp
->peer_self
2002 PEER_STATUS_NSF_WAIT
))
2003 if (pi2
->peer
->status
2007 if (!aspath_cmp_left(pi1
->attr
->aspath
,
2009 && !aspath_cmp_left_confed(
2014 if (bgp_path_info_cmp(
2015 bgp
, pi2
, new_select
,
2016 &paths_eq
, mpath_cfg
, debug
,
2019 bgp_path_info_unset_flag(
2021 BGP_PATH_DMED_SELECTED
);
2025 bgp_path_info_set_flag(
2026 rn
, pi2
, BGP_PATH_DMED_CHECK
);
2029 bgp_path_info_set_flag(rn
, new_select
,
2030 BGP_PATH_DMED_CHECK
);
2031 bgp_path_info_set_flag(rn
, new_select
,
2032 BGP_PATH_DMED_SELECTED
);
2035 bgp_path_info_path_with_addpath_rx_str(
2036 new_select
, path_buf
);
2037 zlog_debug("%s: %s is the bestpath from AS %u",
2039 aspath_get_first_as(
2040 new_select
->attr
->aspath
));
2045 /* Check old selected route and new selected route. */
2048 for (pi
= bgp_node_get_bgp_path_info(rn
);
2049 (pi
!= NULL
) && (nextpi
= pi
->next
, 1); pi
= nextpi
) {
2050 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
))
2053 if (BGP_PATH_HOLDDOWN(pi
)) {
2054 /* reap REMOVED routes, if needs be
2055 * selected route must stay for a while longer though
2057 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)
2058 && (pi
!= old_select
))
2059 bgp_path_info_reap(rn
, pi
);
2062 zlog_debug("%s: pi %p in holddown", __func__
,
2068 if (pi
->peer
&& pi
->peer
!= bgp
->peer_self
2069 && !CHECK_FLAG(pi
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
2070 if (pi
->peer
->status
!= Established
) {
2074 "%s: pi %p non self peer %s not estab state",
2075 __func__
, pi
, pi
->peer
->host
);
2080 if (bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
2081 && (!CHECK_FLAG(pi
->flags
, BGP_PATH_DMED_SELECTED
))) {
2082 bgp_path_info_unset_flag(rn
, pi
, BGP_PATH_DMED_CHECK
);
2084 zlog_debug("%s: pi %p dmed", __func__
, pi
);
2088 bgp_path_info_unset_flag(rn
, pi
, BGP_PATH_DMED_CHECK
);
2090 if (bgp_path_info_cmp(bgp
, pi
, new_select
, &paths_eq
, mpath_cfg
,
2091 debug
, pfx_buf
, afi
, safi
, &rn
->reason
)) {
2096 /* Now that we know which path is the bestpath see if any of the other
2098 * qualify as multipaths
2102 bgp_path_info_path_with_addpath_rx_str(new_select
,
2105 sprintf(path_buf
, "NONE");
2107 "%s: After path selection, newbest is %s oldbest was %s",
2109 old_select
? old_select
->peer
->host
: "NONE");
2112 if (do_mpath
&& new_select
) {
2113 for (pi
= bgp_node_get_bgp_path_info(rn
);
2114 (pi
!= NULL
) && (nextpi
= pi
->next
, 1); pi
= nextpi
) {
2117 bgp_path_info_path_with_addpath_rx_str(
2120 if (pi
== new_select
) {
2123 "%s: %s is the bestpath, add to the multipath list",
2125 bgp_mp_list_add(&mp_list
, pi
);
2129 if (BGP_PATH_HOLDDOWN(pi
))
2132 if (pi
->peer
&& pi
->peer
!= bgp
->peer_self
2133 && !CHECK_FLAG(pi
->peer
->sflags
,
2134 PEER_STATUS_NSF_WAIT
))
2135 if (pi
->peer
->status
!= Established
)
2138 if (!bgp_path_info_nexthop_cmp(pi
, new_select
)) {
2141 "%s: %s has the same nexthop as the bestpath, skip it",
2146 bgp_path_info_cmp(bgp
, pi
, new_select
, &paths_eq
,
2147 mpath_cfg
, debug
, pfx_buf
, afi
, safi
,
2153 "%s: %s is equivalent to the bestpath, add to the multipath list",
2155 bgp_mp_list_add(&mp_list
, pi
);
2160 bgp_path_info_mpath_update(rn
, new_select
, old_select
, &mp_list
,
2162 bgp_path_info_mpath_aggregate_update(new_select
, old_select
);
2163 bgp_mp_list_clear(&mp_list
);
2165 bgp_addpath_update_ids(bgp
, rn
, afi
, safi
);
2167 result
->old
= old_select
;
2168 result
->new = new_select
;
2174 * A new route/change in bestpath of an existing route. Evaluate the path
2175 * for advertisement to the subgroup.
2177 int subgroup_process_announce_selected(struct update_subgroup
*subgrp
,
2178 struct bgp_path_info
*selected
,
2179 struct bgp_node
*rn
,
2180 uint32_t addpath_tx_id
)
2183 struct peer
*onlypeer
;
2189 afi
= SUBGRP_AFI(subgrp
);
2190 safi
= SUBGRP_SAFI(subgrp
);
2191 onlypeer
= ((SUBGRP_PCOUNT(subgrp
) == 1) ? (SUBGRP_PFIRST(subgrp
))->peer
2194 if (BGP_DEBUG(update
, UPDATE_OUT
)) {
2195 char buf_prefix
[PREFIX_STRLEN
];
2196 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
2197 zlog_debug("%s: p=%s, selected=%p", __func__
, buf_prefix
,
2201 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2202 if (onlypeer
&& CHECK_FLAG(onlypeer
->af_sflags
[afi
][safi
],
2203 PEER_STATUS_ORF_WAIT_REFRESH
))
2206 memset(&attr
, 0, sizeof(struct attr
));
2207 /* It's initialized in bgp_announce_check() */
2209 /* Announcement to the subgroup. If the route is filtered withdraw it.
2212 if (subgroup_announce_check(rn
, selected
, subgrp
, p
, &attr
))
2213 bgp_adj_out_set_subgroup(rn
, subgrp
, &attr
, selected
);
2215 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1,
2219 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2221 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, addpath_tx_id
);
2228 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2229 * This is called at the end of route processing.
2231 void bgp_zebra_clear_route_change_flags(struct bgp_node
*rn
)
2233 struct bgp_path_info
*pi
;
2235 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
) {
2236 if (BGP_PATH_HOLDDOWN(pi
))
2238 UNSET_FLAG(pi
->flags
, BGP_PATH_IGP_CHANGED
);
2239 UNSET_FLAG(pi
->flags
, BGP_PATH_ATTR_CHANGED
);
2244 * Has the route changed from the RIB's perspective? This is invoked only
2245 * if the route selection returns the same best route as earlier - to
2246 * determine if we need to update zebra or not.
2248 int bgp_zebra_has_route_changed(struct bgp_node
*rn
,
2249 struct bgp_path_info
*selected
)
2251 struct bgp_path_info
*mpinfo
;
2253 /* If this is multipath, check all selected paths for any nexthop
2254 * change or attribute change. Some attribute changes (e.g., community)
2255 * aren't of relevance to the RIB, but we'll update zebra to ensure
2256 * we handle the case of BGP nexthop change. This is the behavior
2257 * when the best path has an attribute change anyway.
2259 if (CHECK_FLAG(selected
->flags
, BGP_PATH_IGP_CHANGED
)
2260 || CHECK_FLAG(selected
->flags
, BGP_PATH_MULTIPATH_CHG
))
2264 * If this is multipath, check all selected paths for any nexthop change
2266 for (mpinfo
= bgp_path_info_mpath_first(selected
); mpinfo
;
2267 mpinfo
= bgp_path_info_mpath_next(mpinfo
)) {
2268 if (CHECK_FLAG(mpinfo
->flags
, BGP_PATH_IGP_CHANGED
)
2269 || CHECK_FLAG(mpinfo
->flags
, BGP_PATH_ATTR_CHANGED
))
2273 /* Nothing has changed from the RIB's perspective. */
2277 struct bgp_process_queue
{
2279 STAILQ_HEAD(, bgp_node
) pqueue
;
2280 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2282 unsigned int queued
;
2286 * old_select = The old best path
2287 * new_select = the new best path
2289 * if (!old_select && new_select)
2290 * We are sending new information on.
2292 * if (old_select && new_select) {
2293 * if (new_select != old_select)
2294 * We have a new best path send a change
2296 * We've received a update with new attributes that needs
2300 * if (old_select && !new_select)
2301 * We have no eligible route that we can announce or the rn
2304 static void bgp_process_main_one(struct bgp
*bgp
, struct bgp_node
*rn
,
2305 afi_t afi
, safi_t safi
)
2307 struct bgp_path_info
*new_select
;
2308 struct bgp_path_info
*old_select
;
2309 struct bgp_path_info_pair old_and_new
;
2310 char pfx_buf
[PREFIX2STR_BUFFER
];
2313 /* Is it end of initial update? (after startup) */
2315 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
2316 sizeof(bgp
->update_delay_zebra_resume_time
));
2318 bgp
->main_zebra_update_hold
= 0;
2319 FOREACH_AFI_SAFI (afi
, safi
) {
2320 if (bgp_fibupd_safi(safi
))
2321 bgp_zebra_announce_table(bgp
, afi
, safi
);
2323 bgp
->main_peers_update_hold
= 0;
2325 bgp_start_routeadv(bgp
);
2329 struct prefix
*p
= &rn
->p
;
2331 debug
= bgp_debug_bestpath(&rn
->p
);
2333 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
2334 zlog_debug("%s: p=%s afi=%s, safi=%s start", __func__
, pfx_buf
,
2335 afi2str(afi
), safi2str(safi
));
2338 /* Best path selection. */
2339 bgp_best_selection(bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
,
2341 old_select
= old_and_new
.old
;
2342 new_select
= old_and_new
.new;
2344 /* Do we need to allocate or free labels?
2345 * Right now, since we only deal with per-prefix labels, it is not
2346 * necessary to do this upon changes to best path. Exceptions:
2347 * - label index has changed -> recalculate resulting label
2348 * - path_info sub_type changed -> switch to/from implicit-null
2349 * - no valid label (due to removed static label binding) -> get new one
2351 if (bgp
->allocate_mpls_labels
[afi
][safi
]) {
2354 || bgp_label_index_differs(new_select
, old_select
)
2355 || new_select
->sub_type
!= old_select
->sub_type
2356 || !bgp_is_valid_label(&rn
->local_label
)) {
2357 /* Enforced penultimate hop popping:
2358 * implicit-null for local routes, aggregate
2359 * and redistributed routes
2361 if (new_select
->sub_type
== BGP_ROUTE_STATIC
2362 || new_select
->sub_type
2363 == BGP_ROUTE_AGGREGATE
2364 || new_select
->sub_type
2365 == BGP_ROUTE_REDISTRIBUTE
) {
2368 BGP_NODE_REGISTERED_FOR_LABEL
))
2369 bgp_unregister_for_label(rn
);
2370 label_ntop(MPLS_LABEL_IMPLICIT_NULL
, 1,
2372 bgp_set_valid_label(&rn
->local_label
);
2374 bgp_register_for_label(rn
, new_select
);
2376 } else if (CHECK_FLAG(rn
->flags
,
2377 BGP_NODE_REGISTERED_FOR_LABEL
)) {
2378 bgp_unregister_for_label(rn
);
2380 } else if (CHECK_FLAG(rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
)) {
2381 bgp_unregister_for_label(rn
);
2385 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
2387 "%s: p=%s afi=%s, safi=%s, old_select=%p, new_select=%p",
2388 __func__
, pfx_buf
, afi2str(afi
), safi2str(safi
),
2389 old_select
, new_select
);
2392 /* If best route remains the same and this is not due to user-initiated
2393 * clear, see exactly what needs to be done.
2395 if (old_select
&& old_select
== new_select
2396 && !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
)
2397 && !CHECK_FLAG(old_select
->flags
, BGP_PATH_ATTR_CHANGED
)
2398 && !bgp_addpath_is_addpath_used(&bgp
->tx_addpath
, afi
, safi
)) {
2399 if (bgp_zebra_has_route_changed(rn
, old_select
)) {
2401 vnc_import_bgp_add_route(bgp
, p
, old_select
);
2402 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
2404 if (bgp_fibupd_safi(safi
)
2405 && !bgp_option_check(BGP_OPT_NO_FIB
)) {
2407 if (new_select
->type
== ZEBRA_ROUTE_BGP
2408 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
2409 || new_select
->sub_type
2410 == BGP_ROUTE_IMPORTED
))
2412 bgp_zebra_announce(rn
, p
, old_select
,
2416 UNSET_FLAG(old_select
->flags
, BGP_PATH_MULTIPATH_CHG
);
2417 bgp_zebra_clear_route_change_flags(rn
);
2419 /* If there is a change of interest to peers, reannounce the
2421 if (CHECK_FLAG(old_select
->flags
, BGP_PATH_ATTR_CHANGED
)
2422 || CHECK_FLAG(rn
->flags
, BGP_NODE_LABEL_CHANGED
)) {
2423 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2425 /* unicast routes must also be annouced to
2426 * labeled-unicast update-groups */
2427 if (safi
== SAFI_UNICAST
)
2428 group_announce_route(bgp
, afi
,
2429 SAFI_LABELED_UNICAST
, rn
,
2432 UNSET_FLAG(old_select
->flags
, BGP_PATH_ATTR_CHANGED
);
2433 UNSET_FLAG(rn
->flags
, BGP_NODE_LABEL_CHANGED
);
2436 UNSET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2440 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2442 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
2444 /* bestpath has changed; bump version */
2445 if (old_select
|| new_select
) {
2446 bgp_bump_version(rn
);
2448 if (!bgp
->t_rmap_def_originate_eval
) {
2452 update_group_refresh_default_originate_route_map
,
2453 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
,
2454 &bgp
->t_rmap_def_originate_eval
);
2459 bgp_path_info_unset_flag(rn
, old_select
, BGP_PATH_SELECTED
);
2462 zlog_debug("%s: setting SELECTED flag", __func__
);
2463 bgp_path_info_set_flag(rn
, new_select
, BGP_PATH_SELECTED
);
2464 bgp_path_info_unset_flag(rn
, new_select
, BGP_PATH_ATTR_CHANGED
);
2465 UNSET_FLAG(new_select
->flags
, BGP_PATH_MULTIPATH_CHG
);
2469 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2470 if (old_select
!= new_select
) {
2472 vnc_import_bgp_exterior_del_route(bgp
, p
,
2474 vnc_import_bgp_del_route(bgp
, p
, old_select
);
2477 vnc_import_bgp_exterior_add_route(bgp
, p
,
2479 vnc_import_bgp_add_route(bgp
, p
, new_select
);
2485 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2487 /* unicast routes must also be annouced to labeled-unicast update-groups
2489 if (safi
== SAFI_UNICAST
)
2490 group_announce_route(bgp
, afi
, SAFI_LABELED_UNICAST
, rn
,
2494 if (bgp_fibupd_safi(safi
) && (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
2495 && !bgp_option_check(BGP_OPT_NO_FIB
)) {
2496 if (new_select
&& new_select
->type
== ZEBRA_ROUTE_BGP
2497 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
2498 || new_select
->sub_type
== BGP_ROUTE_AGGREGATE
2499 || new_select
->sub_type
== BGP_ROUTE_IMPORTED
)) {
2501 /* if this is an evpn imported type-5 prefix,
2502 * we need to withdraw the route first to clear
2503 * the nh neigh and the RMAC entry.
2506 is_route_parent_evpn(old_select
))
2507 bgp_zebra_withdraw(p
, old_select
, bgp
, safi
);
2509 bgp_zebra_announce(rn
, p
, new_select
, bgp
, afi
, safi
);
2511 /* Withdraw the route from the kernel. */
2512 if (old_select
&& old_select
->type
== ZEBRA_ROUTE_BGP
2513 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
2514 || old_select
->sub_type
== BGP_ROUTE_AGGREGATE
2515 || old_select
->sub_type
== BGP_ROUTE_IMPORTED
))
2517 bgp_zebra_withdraw(p
, old_select
, bgp
, safi
);
2521 /* advertise/withdraw type-5 routes */
2522 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2523 if (advertise_type5_routes(bgp
, afi
) &&
2525 is_route_injectable_into_evpn(new_select
)) {
2527 /* apply the route-map */
2528 if (bgp
->adv_cmd_rmap
[afi
][safi
].map
) {
2531 ret
= route_map_apply(
2532 bgp
->adv_cmd_rmap
[afi
][safi
].map
,
2533 &rn
->p
, RMAP_BGP
, new_select
);
2534 if (ret
== RMAP_MATCH
)
2535 bgp_evpn_advertise_type5_route(
2536 bgp
, &rn
->p
, new_select
->attr
,
2539 bgp_evpn_withdraw_type5_route(
2540 bgp
, &rn
->p
, afi
, safi
);
2542 bgp_evpn_advertise_type5_route(bgp
,
2548 } else if (advertise_type5_routes(bgp
, afi
) &&
2550 is_route_injectable_into_evpn(old_select
))
2551 bgp_evpn_withdraw_type5_route(bgp
, &rn
->p
, afi
, safi
);
2554 /* Clear any route change flags. */
2555 bgp_zebra_clear_route_change_flags(rn
);
2557 /* Reap old select bgp_path_info, if it has been removed */
2558 if (old_select
&& CHECK_FLAG(old_select
->flags
, BGP_PATH_REMOVED
))
2559 bgp_path_info_reap(rn
, old_select
);
2561 UNSET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2565 static wq_item_status
bgp_process_wq(struct work_queue
*wq
, void *data
)
2567 struct bgp_process_queue
*pqnode
= data
;
2568 struct bgp
*bgp
= pqnode
->bgp
;
2569 struct bgp_table
*table
;
2570 struct bgp_node
*rn
;
2573 if (CHECK_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
)) {
2574 bgp_process_main_one(bgp
, NULL
, 0, 0);
2575 /* should always have dedicated wq call */
2576 assert(STAILQ_FIRST(&pqnode
->pqueue
) == NULL
);
2580 while (!STAILQ_EMPTY(&pqnode
->pqueue
)) {
2581 rn
= STAILQ_FIRST(&pqnode
->pqueue
);
2582 STAILQ_REMOVE_HEAD(&pqnode
->pqueue
, pq
);
2583 STAILQ_NEXT(rn
, pq
) = NULL
; /* complete unlink */
2584 table
= bgp_node_table(rn
);
2585 /* note, new RNs may be added as part of processing */
2586 bgp_process_main_one(bgp
, rn
, table
->afi
, table
->safi
);
2588 bgp_unlock_node(rn
);
2589 bgp_table_unlock(table
);
2595 static void bgp_processq_del(struct work_queue
*wq
, void *data
)
2597 struct bgp_process_queue
*pqnode
= data
;
2599 bgp_unlock(pqnode
->bgp
);
2601 XFREE(MTYPE_BGP_PROCESS_QUEUE
, pqnode
);
2604 void bgp_process_queue_init(void)
2606 if (!bm
->process_main_queue
)
2607 bm
->process_main_queue
=
2608 work_queue_new(bm
->master
, "process_main_queue");
2610 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_wq
;
2611 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2612 bm
->process_main_queue
->spec
.max_retries
= 0;
2613 bm
->process_main_queue
->spec
.hold
= 50;
2614 /* Use a higher yield value of 50ms for main queue processing */
2615 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2618 static struct bgp_process_queue
*bgp_processq_alloc(struct bgp
*bgp
)
2620 struct bgp_process_queue
*pqnode
;
2622 pqnode
= XCALLOC(MTYPE_BGP_PROCESS_QUEUE
,
2623 sizeof(struct bgp_process_queue
));
2625 /* unlocked in bgp_processq_del */
2626 pqnode
->bgp
= bgp_lock(bgp
);
2627 STAILQ_INIT(&pqnode
->pqueue
);
2632 void bgp_process(struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2634 #define ARBITRARY_PROCESS_QLEN 10000
2635 struct work_queue
*wq
= bm
->process_main_queue
;
2636 struct bgp_process_queue
*pqnode
;
2637 int pqnode_reuse
= 0;
2639 /* already scheduled for processing? */
2640 if (CHECK_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2646 /* Add route nodes to an existing work queue item until reaching the
2647 limit only if is from the same BGP view and it's not an EOIU marker
2649 if (work_queue_item_count(wq
)) {
2650 struct work_queue_item
*item
= work_queue_last_item(wq
);
2651 pqnode
= item
->data
;
2653 if (CHECK_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
)
2654 || pqnode
->bgp
!= bgp
2655 || pqnode
->queued
>= ARBITRARY_PROCESS_QLEN
)
2656 pqnode
= bgp_processq_alloc(bgp
);
2660 pqnode
= bgp_processq_alloc(bgp
);
2661 /* all unlocked in bgp_process_wq */
2662 bgp_table_lock(bgp_node_table(rn
));
2664 SET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2667 /* can't be enqueued twice */
2668 assert(STAILQ_NEXT(rn
, pq
) == NULL
);
2669 STAILQ_INSERT_TAIL(&pqnode
->pqueue
, rn
, pq
);
2673 work_queue_add(wq
, pqnode
);
2678 void bgp_add_eoiu_mark(struct bgp
*bgp
)
2680 struct bgp_process_queue
*pqnode
;
2682 if (bm
->process_main_queue
== NULL
)
2685 pqnode
= bgp_processq_alloc(bgp
);
2687 SET_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
);
2688 work_queue_add(bm
->process_main_queue
, pqnode
);
2691 static int bgp_maximum_prefix_restart_timer(struct thread
*thread
)
2695 peer
= THREAD_ARG(thread
);
2696 peer
->t_pmax_restart
= NULL
;
2698 if (bgp_debug_neighbor_events(peer
))
2700 "%s Maximum-prefix restart timer expired, restore peering",
2703 if ((peer_clear(peer
, NULL
) < 0) && bgp_debug_neighbor_events(peer
))
2704 zlog_debug("%s: %s peer_clear failed",
2705 __PRETTY_FUNCTION__
, peer
->host
);
2710 int bgp_maximum_prefix_overflow(struct peer
*peer
, afi_t afi
, safi_t safi
,
2714 iana_safi_t pkt_safi
;
2716 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2719 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
]) {
2720 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2721 PEER_STATUS_PREFIX_LIMIT
)
2726 "%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2728 afi_safi_print(afi
, safi
), peer
->host
,
2729 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2730 SET_FLAG(peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2732 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
2733 PEER_FLAG_MAX_PREFIX_WARNING
))
2736 /* Convert AFI, SAFI to values for packet. */
2737 pkt_afi
= afi_int2iana(afi
);
2738 pkt_safi
= safi_int2iana(safi
);
2742 ndata
[0] = (pkt_afi
>> 8);
2744 ndata
[2] = pkt_safi
;
2745 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2746 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2747 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2748 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2750 SET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2751 bgp_notify_send_with_data(peer
, BGP_NOTIFY_CEASE
,
2752 BGP_NOTIFY_CEASE_MAX_PREFIX
,
2756 /* Dynamic peers will just close their connection. */
2757 if (peer_dynamic_neighbor(peer
))
2760 /* restart timer start */
2761 if (peer
->pmax_restart
[afi
][safi
]) {
2762 peer
->v_pmax_restart
=
2763 peer
->pmax_restart
[afi
][safi
] * 60;
2765 if (bgp_debug_neighbor_events(peer
))
2767 "%s Maximum-prefix restart timer started for %d secs",
2768 peer
->host
, peer
->v_pmax_restart
);
2770 BGP_TIMER_ON(peer
->t_pmax_restart
,
2771 bgp_maximum_prefix_restart_timer
,
2772 peer
->v_pmax_restart
);
2777 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2778 PEER_STATUS_PREFIX_LIMIT
);
2780 if (peer
->pcount
[afi
][safi
]
2781 > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100)) {
2782 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2783 PEER_STATUS_PREFIX_THRESHOLD
)
2788 "%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2789 afi_safi_print(afi
, safi
), peer
->host
,
2790 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2791 SET_FLAG(peer
->af_sflags
[afi
][safi
],
2792 PEER_STATUS_PREFIX_THRESHOLD
);
2794 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2795 PEER_STATUS_PREFIX_THRESHOLD
);
2799 /* Unconditionally remove the route from the RIB, without taking
2800 * damping into consideration (eg, because the session went down)
2802 void bgp_rib_remove(struct bgp_node
*rn
, struct bgp_path_info
*pi
,
2803 struct peer
*peer
, afi_t afi
, safi_t safi
)
2805 bgp_aggregate_decrement(peer
->bgp
, &rn
->p
, pi
, afi
, safi
);
2807 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
))
2808 bgp_path_info_delete(rn
, pi
); /* keep historical info */
2810 bgp_process(peer
->bgp
, rn
, afi
, safi
);
2813 static void bgp_rib_withdraw(struct bgp_node
*rn
, struct bgp_path_info
*pi
,
2814 struct peer
*peer
, afi_t afi
, safi_t safi
,
2815 struct prefix_rd
*prd
)
2817 /* apply dampening, if result is suppressed, we'll be retaining
2818 * the bgp_path_info in the RIB for historical reference.
2820 if (CHECK_FLAG(peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2821 && peer
->sort
== BGP_PEER_EBGP
)
2822 if ((bgp_damp_withdraw(pi
, rn
, afi
, safi
, 0))
2823 == BGP_DAMP_SUPPRESSED
) {
2824 bgp_aggregate_decrement(peer
->bgp
, &rn
->p
, pi
, afi
,
2830 if (safi
== SAFI_MPLS_VPN
) {
2831 struct bgp_node
*prn
= NULL
;
2832 struct bgp_table
*table
= NULL
;
2834 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
],
2835 (struct prefix
*)prd
);
2836 if (bgp_node_has_bgp_path_info_data(prn
)) {
2837 table
= bgp_node_get_bgp_table_info(prn
);
2839 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2840 peer
->bgp
, prd
, table
, &rn
->p
, pi
);
2842 bgp_unlock_node(prn
);
2844 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2845 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)) {
2847 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, pi
);
2848 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
,
2854 /* If this is an EVPN route, process for un-import. */
2855 if (safi
== SAFI_EVPN
)
2856 bgp_evpn_unimport_route(peer
->bgp
, afi
, safi
, &rn
->p
, pi
);
2858 bgp_rib_remove(rn
, pi
, peer
, afi
, safi
);
2861 struct bgp_path_info
*info_make(int type
, int sub_type
, unsigned short instance
,
2862 struct peer
*peer
, struct attr
*attr
,
2863 struct bgp_node
*rn
)
2865 struct bgp_path_info
*new;
2867 /* Make new BGP info. */
2868 new = XCALLOC(MTYPE_BGP_ROUTE
, sizeof(struct bgp_path_info
));
2870 new->instance
= instance
;
2871 new->sub_type
= sub_type
;
2874 new->uptime
= bgp_clock();
2879 static void overlay_index_update(struct attr
*attr
,
2880 struct eth_segment_id
*eth_s_id
,
2881 union gw_addr
*gw_ip
)
2886 if (eth_s_id
== NULL
) {
2887 memset(&(attr
->evpn_overlay
.eth_s_id
), 0,
2888 sizeof(struct eth_segment_id
));
2890 memcpy(&(attr
->evpn_overlay
.eth_s_id
), eth_s_id
,
2891 sizeof(struct eth_segment_id
));
2893 if (gw_ip
== NULL
) {
2894 memset(&(attr
->evpn_overlay
.gw_ip
), 0, sizeof(union gw_addr
));
2896 memcpy(&(attr
->evpn_overlay
.gw_ip
), gw_ip
,
2897 sizeof(union gw_addr
));
2901 static bool overlay_index_equal(afi_t afi
, struct bgp_path_info
*path
,
2902 struct eth_segment_id
*eth_s_id
,
2903 union gw_addr
*gw_ip
)
2905 struct eth_segment_id
*path_eth_s_id
, *path_eth_s_id_remote
;
2906 union gw_addr
*path_gw_ip
, *path_gw_ip_remote
;
2908 struct eth_segment_id esi
;
2912 if (afi
!= AFI_L2VPN
)
2915 memset(&temp
, 0, sizeof(temp
));
2916 path_eth_s_id
= &temp
.esi
;
2917 path_gw_ip
= &temp
.ip
;
2919 if (eth_s_id
== NULL
&& gw_ip
== NULL
)
2922 path_eth_s_id
= &(path
->attr
->evpn_overlay
.eth_s_id
);
2923 path_gw_ip
= &(path
->attr
->evpn_overlay
.gw_ip
);
2926 if (gw_ip
== NULL
) {
2927 memset(&temp
, 0, sizeof(temp
));
2928 path_gw_ip_remote
= &temp
.ip
;
2930 path_gw_ip_remote
= gw_ip
;
2932 if (eth_s_id
== NULL
) {
2933 memset(&temp
, 0, sizeof(temp
));
2934 path_eth_s_id_remote
= &temp
.esi
;
2936 path_eth_s_id_remote
= eth_s_id
;
2938 if (!memcmp(path_gw_ip
, path_gw_ip_remote
, sizeof(union gw_addr
)))
2941 return !memcmp(path_eth_s_id
, path_eth_s_id_remote
,
2942 sizeof(struct eth_segment_id
));
2945 /* Check if received nexthop is valid or not. */
2946 static int bgp_update_martian_nexthop(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
2951 /* Only validated for unicast and multicast currently. */
2952 /* Also valid for EVPN where the nexthop is an IP address. */
2953 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
&& safi
!= SAFI_EVPN
)
2956 /* If NEXT_HOP is present, validate it. */
2957 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
)) {
2958 if (attr
->nexthop
.s_addr
== 0
2959 || IPV4_CLASS_DE(ntohl(attr
->nexthop
.s_addr
))
2960 || bgp_nexthop_self(bgp
, attr
->nexthop
))
2964 /* If MP_NEXTHOP is present, validate it. */
2965 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2966 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2967 * it is not an IPv6 link-local address.
2969 if (attr
->mp_nexthop_len
) {
2970 switch (attr
->mp_nexthop_len
) {
2971 case BGP_ATTR_NHLEN_IPV4
:
2972 case BGP_ATTR_NHLEN_VPNV4
:
2973 ret
= (attr
->mp_nexthop_global_in
.s_addr
== 0
2974 || IPV4_CLASS_DE(ntohl(
2975 attr
->mp_nexthop_global_in
.s_addr
))
2976 || bgp_nexthop_self(bgp
,
2977 attr
->mp_nexthop_global_in
));
2980 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2981 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2982 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2983 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attr
->mp_nexthop_global
)
2984 || IN6_IS_ADDR_LOOPBACK(&attr
->mp_nexthop_global
)
2985 || IN6_IS_ADDR_MULTICAST(
2986 &attr
->mp_nexthop_global
));
2998 int bgp_update(struct peer
*peer
, struct prefix
*p
, uint32_t addpath_id
,
2999 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
3000 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
3001 uint32_t num_labels
, int soft_reconfig
,
3002 struct bgp_route_evpn
*evpn
)
3005 int aspath_loop_count
= 0;
3006 struct bgp_node
*rn
;
3008 struct attr new_attr
;
3009 struct attr
*attr_new
;
3010 struct bgp_path_info
*pi
;
3011 struct bgp_path_info
*new;
3012 struct bgp_path_info_extra
*extra
;
3014 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
3016 int do_loop_check
= 1;
3017 int has_valid_label
= 0;
3019 int vnc_implicit_withdraw
= 0;
3023 memset(&new_attr
, 0, sizeof(struct attr
));
3024 new_attr
.label_index
= BGP_INVALID_LABEL_INDEX
;
3025 new_attr
.label
= MPLS_INVALID_LABEL
;
3028 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3029 /* TODO: Check to see if we can get rid of "is_valid_label" */
3030 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
3031 has_valid_label
= (num_labels
> 0) ? 1 : 0;
3033 has_valid_label
= bgp_is_valid_label(label
);
3035 /* When peer's soft reconfiguration enabled. Record input packet in
3038 && CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
3039 && peer
!= bgp
->peer_self
)
3040 bgp_adj_in_set(rn
, peer
, attr
, addpath_id
);
3042 /* Check previously received route. */
3043 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
3044 if (pi
->peer
== peer
&& pi
->type
== type
3045 && pi
->sub_type
== sub_type
3046 && pi
->addpath_rx_id
== addpath_id
)
3049 /* AS path local-as loop check. */
3050 if (peer
->change_local_as
) {
3051 if (peer
->allowas_in
[afi
][safi
])
3052 aspath_loop_count
= peer
->allowas_in
[afi
][safi
];
3053 else if (!CHECK_FLAG(peer
->flags
,
3054 PEER_FLAG_LOCAL_AS_NO_PREPEND
))
3055 aspath_loop_count
= 1;
3057 if (aspath_loop_check(attr
->aspath
, peer
->change_local_as
)
3058 > aspath_loop_count
) {
3059 reason
= "as-path contains our own AS;";
3064 /* If the peer is configured for "allowas-in origin" and the last ASN in
3066 * as-path is our ASN then we do not need to call aspath_loop_check
3068 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
3069 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
3072 /* AS path loop check. */
3073 if (do_loop_check
) {
3074 if (aspath_loop_check(attr
->aspath
, bgp
->as
)
3075 > peer
->allowas_in
[afi
][safi
]
3076 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
3077 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
)
3078 > peer
->allowas_in
[afi
][safi
])) {
3079 reason
= "as-path contains our own AS;";
3084 /* Route reflector originator ID check. */
3085 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)
3086 && IPV4_ADDR_SAME(&bgp
->router_id
, &attr
->originator_id
)) {
3087 reason
= "originator is us;";
3091 /* Route reflector cluster ID check. */
3092 if (bgp_cluster_filter(peer
, attr
)) {
3093 reason
= "reflected from the same cluster;";
3097 /* Apply incoming filter. */
3098 if (bgp_input_filter(peer
, p
, attr
, afi
, safi
) == FILTER_DENY
) {
3103 /* RFC 8212 to prevent route leaks.
3104 * This specification intends to improve this situation by requiring the
3105 * explicit configuration of both BGP Import and Export Policies for any
3106 * External BGP (EBGP) session such as customers, peers, or
3107 * confederation boundaries for all enabled address families. Through
3108 * codification of the aforementioned requirement, operators will
3109 * benefit from consistent behavior across different BGP
3112 if (peer
->bgp
->ebgp_requires_policy
== DEFAULT_EBGP_POLICY_ENABLED
)
3113 if (!bgp_inbound_policy_exists(peer
,
3114 &peer
->filter
[afi
][safi
])) {
3115 reason
= "inbound policy missing";
3119 bgp_attr_dup(&new_attr
, attr
);
3121 /* Apply incoming route-map.
3122 * NB: new_attr may now contain newly allocated values from route-map
3124 * commands, so we need bgp_attr_flush in the error paths, until we
3126 * the attr (which takes over the memory references) */
3127 if (bgp_input_modifier(peer
, p
, &new_attr
, afi
, safi
, NULL
)
3129 reason
= "route-map;";
3130 bgp_attr_flush(&new_attr
);
3134 if (peer
->sort
== BGP_PEER_EBGP
) {
3136 /* If we receive the graceful-shutdown community from an eBGP
3137 * peer we must lower local-preference */
3138 if (new_attr
.community
3139 && community_include(new_attr
.community
, COMMUNITY_GSHUT
)) {
3140 new_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
3141 new_attr
.local_pref
= BGP_GSHUT_LOCAL_PREF
;
3143 /* If graceful-shutdown is configured then add the GSHUT
3144 * community to all paths received from eBGP peers */
3145 } else if (bgp_flag_check(peer
->bgp
,
3146 BGP_FLAG_GRACEFUL_SHUTDOWN
)) {
3147 bgp_attr_add_gshut_community(&new_attr
);
3151 /* next hop check. */
3152 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
)
3153 && bgp_update_martian_nexthop(bgp
, afi
, safi
, &new_attr
)) {
3154 reason
= "martian or self next-hop;";
3155 bgp_attr_flush(&new_attr
);
3159 if (bgp_mac_entry_exists(p
) || bgp_mac_exist(&attr
->rmac
)) {
3160 reason
= "self mac;";
3164 attr_new
= bgp_attr_intern(&new_attr
);
3166 /* If the update is implicit withdraw. */
3168 pi
->uptime
= bgp_clock();
3169 same_attr
= attrhash_cmp(pi
->attr
, attr_new
);
3171 /* Same attribute comes in. */
3172 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)
3173 && attrhash_cmp(pi
->attr
, attr_new
)
3174 && (!has_valid_label
3175 || memcmp(&(bgp_path_info_extra_get(pi
))->label
, label
,
3176 num_labels
* sizeof(mpls_label_t
))
3178 && (overlay_index_equal(
3179 afi
, pi
, evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3180 evpn
== NULL
? NULL
: &evpn
->gw_ip
))) {
3181 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
3182 BGP_CONFIG_DAMPENING
)
3183 && peer
->sort
== BGP_PEER_EBGP
3184 && CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
)) {
3185 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3186 bgp_debug_rdpfxpath2str(
3187 afi
, safi
, prd
, p
, label
,
3188 num_labels
, addpath_id
? 1 : 0,
3189 addpath_id
, pfx_buf
,
3191 zlog_debug("%s rcvd %s", peer
->host
,
3195 if (bgp_damp_update(pi
, rn
, afi
, safi
)
3196 != BGP_DAMP_SUPPRESSED
) {
3197 bgp_aggregate_increment(bgp
, p
, pi
, afi
,
3199 bgp_process(bgp
, rn
, afi
, safi
);
3201 } else /* Duplicate - odd */
3203 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3204 if (!peer
->rcvd_attr_printed
) {
3206 "%s rcvd UPDATE w/ attr: %s",
3208 peer
->rcvd_attr_str
);
3209 peer
->rcvd_attr_printed
= 1;
3212 bgp_debug_rdpfxpath2str(
3213 afi
, safi
, prd
, p
, label
,
3214 num_labels
, addpath_id
? 1 : 0,
3215 addpath_id
, pfx_buf
,
3218 "%s rcvd %s...duplicate ignored",
3219 peer
->host
, pfx_buf
);
3222 /* graceful restart STALE flag unset. */
3223 if (CHECK_FLAG(pi
->flags
, BGP_PATH_STALE
)) {
3224 bgp_path_info_unset_flag(
3225 rn
, pi
, BGP_PATH_STALE
);
3226 bgp_process(bgp
, rn
, afi
, safi
);
3230 bgp_unlock_node(rn
);
3231 bgp_attr_unintern(&attr_new
);
3236 /* Withdraw/Announce before we fully processed the withdraw */
3237 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)) {
3238 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3239 bgp_debug_rdpfxpath2str(
3240 afi
, safi
, prd
, p
, label
, num_labels
,
3241 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3244 "%s rcvd %s, flapped quicker than processing",
3245 peer
->host
, pfx_buf
);
3248 bgp_path_info_restore(rn
, pi
);
3251 /* Received Logging. */
3252 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3253 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
,
3254 num_labels
, addpath_id
? 1 : 0,
3255 addpath_id
, pfx_buf
,
3257 zlog_debug("%s rcvd %s", peer
->host
, pfx_buf
);
3260 /* graceful restart STALE flag unset. */
3261 if (CHECK_FLAG(pi
->flags
, BGP_PATH_STALE
))
3262 bgp_path_info_unset_flag(rn
, pi
, BGP_PATH_STALE
);
3264 /* The attribute is changed. */
3265 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_ATTR_CHANGED
);
3267 /* implicit withdraw, decrement aggregate and pcount here.
3268 * only if update is accepted, they'll increment below.
3270 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, safi
);
3272 /* Update bgp route dampening information. */
3273 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
3274 && peer
->sort
== BGP_PEER_EBGP
) {
3275 /* This is implicit withdraw so we should update
3278 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
))
3279 bgp_damp_withdraw(pi
, rn
, afi
, safi
, 1);
3282 if (safi
== SAFI_MPLS_VPN
) {
3283 struct bgp_node
*prn
= NULL
;
3284 struct bgp_table
*table
= NULL
;
3286 prn
= bgp_node_get(bgp
->rib
[afi
][safi
],
3287 (struct prefix
*)prd
);
3288 if (bgp_node_has_bgp_path_info_data(prn
)) {
3289 table
= bgp_node_get_bgp_table_info(prn
);
3291 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3292 bgp
, prd
, table
, p
, pi
);
3294 bgp_unlock_node(prn
);
3296 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3297 && (safi
== SAFI_UNICAST
)) {
3298 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)) {
3300 * Implicit withdraw case.
3302 ++vnc_implicit_withdraw
;
3303 vnc_import_bgp_del_route(bgp
, p
, pi
);
3304 vnc_import_bgp_exterior_del_route(bgp
, p
, pi
);
3309 /* Special handling for EVPN update of an existing route. If the
3310 * extended community attribute has changed, we need to
3312 * the route using its existing extended community. It will be
3313 * subsequently processed for import with the new extended
3316 if (safi
== SAFI_EVPN
&& !same_attr
) {
3318 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
3320 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))) {
3323 cmp
= ecommunity_cmp(pi
->attr
->ecommunity
,
3324 attr_new
->ecommunity
);
3326 if (bgp_debug_update(peer
, p
, NULL
, 1))
3328 "Change in EXT-COMM, existing %s new %s",
3330 pi
->attr
->ecommunity
),
3332 attr_new
->ecommunity
));
3333 bgp_evpn_unimport_route(bgp
, afi
, safi
,
3339 /* Update to new attribute. */
3340 bgp_attr_unintern(&pi
->attr
);
3341 pi
->attr
= attr_new
;
3343 /* Update MPLS label */
3344 if (has_valid_label
) {
3345 extra
= bgp_path_info_extra_get(pi
);
3346 if (extra
->label
!= label
) {
3347 memcpy(&extra
->label
, label
,
3348 num_labels
* sizeof(mpls_label_t
));
3349 extra
->num_labels
= num_labels
;
3351 if (!(afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
))
3352 bgp_set_valid_label(&extra
->label
[0]);
3356 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3357 && (safi
== SAFI_UNICAST
)) {
3358 if (vnc_implicit_withdraw
) {
3360 * Add back the route with its new attributes
3362 * The route is still selected, until the route
3364 * queued by bgp_process actually runs. We have
3366 * update to the VNC side immediately to avoid
3368 * configuration changes (e.g., route-map
3370 * trigger re-importation of the entire RIB.
3372 vnc_import_bgp_add_route(bgp
, p
, pi
);
3373 vnc_import_bgp_exterior_add_route(bgp
, p
, pi
);
3377 /* Update Overlay Index */
3378 if (afi
== AFI_L2VPN
) {
3379 overlay_index_update(
3380 pi
->attr
, evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3381 evpn
== NULL
? NULL
: &evpn
->gw_ip
);
3384 /* Update bgp route dampening information. */
3385 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
3386 && peer
->sort
== BGP_PEER_EBGP
) {
3387 /* Now we do normal update dampening. */
3388 ret
= bgp_damp_update(pi
, rn
, afi
, safi
);
3389 if (ret
== BGP_DAMP_SUPPRESSED
) {
3390 bgp_unlock_node(rn
);
3395 /* Nexthop reachability check - for unicast and
3396 * labeled-unicast.. */
3397 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3398 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
3399 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1
3400 && !CHECK_FLAG(peer
->flags
,
3401 PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3403 bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
3408 struct bgp
*bgp_nexthop
= bgp
;
3410 if (pi
->extra
&& pi
->extra
->bgp_orig
)
3411 bgp_nexthop
= pi
->extra
->bgp_orig
;
3413 if (bgp_find_or_add_nexthop(bgp
, bgp_nexthop
, afi
, pi
,
3415 || CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
))
3416 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_VALID
);
3418 if (BGP_DEBUG(nht
, NHT
)) {
3419 char buf1
[INET6_ADDRSTRLEN
];
3421 (const void *)&attr_new
3423 buf1
, INET6_ADDRSTRLEN
);
3424 zlog_debug("%s(%s): NH unresolved",
3425 __FUNCTION__
, buf1
);
3427 bgp_path_info_unset_flag(rn
, pi
,
3431 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_VALID
);
3434 if (safi
== SAFI_MPLS_VPN
) {
3435 struct bgp_node
*prn
= NULL
;
3436 struct bgp_table
*table
= NULL
;
3438 prn
= bgp_node_get(bgp
->rib
[afi
][safi
],
3439 (struct prefix
*)prd
);
3440 if (bgp_node_has_bgp_path_info_data(prn
)) {
3441 table
= bgp_node_get_bgp_table_info(prn
);
3443 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3444 bgp
, prd
, table
, p
, pi
);
3446 bgp_unlock_node(prn
);
3450 /* If this is an EVPN route and some attribute has changed,
3452 * route for import. If the extended community has changed, we
3454 * have done the un-import earlier and the import would result
3456 * route getting injected into appropriate L2 VNIs. If it is
3458 * some other attribute change, the import will result in
3460 * the attributes for the route in the VNI(s).
3462 if (safi
== SAFI_EVPN
&& !same_attr
)
3463 bgp_evpn_import_route(bgp
, afi
, safi
, p
, pi
);
3465 /* Process change. */
3466 bgp_aggregate_increment(bgp
, p
, pi
, afi
, safi
);
3468 bgp_process(bgp
, rn
, afi
, safi
);
3469 bgp_unlock_node(rn
);
3471 if (SAFI_UNICAST
== safi
3472 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3473 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3475 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, pi
);
3477 if ((SAFI_MPLS_VPN
== safi
)
3478 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3480 vpn_leak_to_vrf_update(bgp
, pi
);
3484 if (SAFI_MPLS_VPN
== safi
) {
3485 mpls_label_t label_decoded
= decode_label(label
);
3487 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
,
3488 type
, sub_type
, &label_decoded
);
3490 if (SAFI_ENCAP
== safi
) {
3491 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
,
3492 type
, sub_type
, NULL
);
3497 } // End of implicit withdraw
3499 /* Received Logging. */
3500 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3501 if (!peer
->rcvd_attr_printed
) {
3502 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
3503 peer
->rcvd_attr_str
);
3504 peer
->rcvd_attr_printed
= 1;
3507 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3508 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3510 zlog_debug("%s rcvd %s", peer
->host
, pfx_buf
);
3513 /* Make new BGP info. */
3514 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
3516 /* Update MPLS label */
3517 if (has_valid_label
) {
3518 extra
= bgp_path_info_extra_get(new);
3519 if (extra
->label
!= label
) {
3520 memcpy(&extra
->label
, label
,
3521 num_labels
* sizeof(mpls_label_t
));
3522 extra
->num_labels
= num_labels
;
3524 if (!(afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
))
3525 bgp_set_valid_label(&extra
->label
[0]);
3528 /* Update Overlay Index */
3529 if (afi
== AFI_L2VPN
) {
3530 overlay_index_update(new->attr
,
3531 evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3532 evpn
== NULL
? NULL
: &evpn
->gw_ip
);
3534 /* Nexthop reachability check. */
3535 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3536 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
3537 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1
3538 && !CHECK_FLAG(peer
->flags
,
3539 PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3540 && !bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
3545 if (bgp_find_or_add_nexthop(bgp
, bgp
, afi
, new, NULL
, connected
)
3546 || CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
))
3547 bgp_path_info_set_flag(rn
, new, BGP_PATH_VALID
);
3549 if (BGP_DEBUG(nht
, NHT
)) {
3550 char buf1
[INET6_ADDRSTRLEN
];
3552 (const void *)&attr_new
->nexthop
,
3553 buf1
, INET6_ADDRSTRLEN
);
3554 zlog_debug("%s(%s): NH unresolved",
3555 __FUNCTION__
, buf1
);
3557 bgp_path_info_unset_flag(rn
, new, BGP_PATH_VALID
);
3560 bgp_path_info_set_flag(rn
, new, BGP_PATH_VALID
);
3563 new->addpath_rx_id
= addpath_id
;
3565 /* Increment prefix */
3566 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
3568 /* Register new BGP information. */
3569 bgp_path_info_add(rn
, new);
3571 /* route_node_get lock */
3572 bgp_unlock_node(rn
);
3575 if (safi
== SAFI_MPLS_VPN
) {
3576 struct bgp_node
*prn
= NULL
;
3577 struct bgp_table
*table
= NULL
;
3579 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*)prd
);
3580 if (bgp_node_has_bgp_path_info_data(prn
)) {
3581 table
= bgp_node_get_bgp_table_info(prn
);
3583 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3584 bgp
, prd
, table
, p
, new);
3586 bgp_unlock_node(prn
);
3590 /* If maximum prefix count is configured and current prefix
3592 if (bgp_maximum_prefix_overflow(peer
, afi
, safi
, 0))
3595 /* If this is an EVPN route, process for import. */
3596 if (safi
== SAFI_EVPN
)
3597 bgp_evpn_import_route(bgp
, afi
, safi
, p
, new);
3599 /* Process change. */
3600 bgp_process(bgp
, rn
, afi
, safi
);
3602 if (SAFI_UNICAST
== safi
3603 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3604 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3605 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
3607 if ((SAFI_MPLS_VPN
== safi
)
3608 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3610 vpn_leak_to_vrf_update(bgp
, new);
3613 if (SAFI_MPLS_VPN
== safi
) {
3614 mpls_label_t label_decoded
= decode_label(label
);
3616 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
,
3617 sub_type
, &label_decoded
);
3619 if (SAFI_ENCAP
== safi
) {
3620 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
,
3627 /* This BGP update is filtered. Log the reason then update BGP
3630 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3631 if (!peer
->rcvd_attr_printed
) {
3632 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
3633 peer
->rcvd_attr_str
);
3634 peer
->rcvd_attr_printed
= 1;
3637 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3638 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3640 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
3641 peer
->host
, pfx_buf
, reason
);
3645 /* If this is an EVPN route, un-import it as it is now filtered.
3647 if (safi
== SAFI_EVPN
)
3648 bgp_evpn_unimport_route(bgp
, afi
, safi
, p
, pi
);
3650 if (SAFI_UNICAST
== safi
3651 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3652 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3654 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, pi
);
3656 if ((SAFI_MPLS_VPN
== safi
)
3657 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3659 vpn_leak_to_vrf_withdraw(bgp
, pi
);
3662 bgp_rib_remove(rn
, pi
, peer
, afi
, safi
);
3665 bgp_unlock_node(rn
);
3669 * Filtered update is treated as an implicit withdrawal (see
3671 * a few lines above)
3673 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
)) {
3674 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
,
3682 int bgp_withdraw(struct peer
*peer
, struct prefix
*p
, uint32_t addpath_id
,
3683 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
3684 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
3685 uint32_t num_labels
, struct bgp_route_evpn
*evpn
)
3688 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
3689 struct bgp_node
*rn
;
3690 struct bgp_path_info
*pi
;
3693 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
)) {
3694 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
,
3702 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3704 /* If peer is soft reconfiguration enabled. Record input packet for
3705 * further calculation.
3707 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
3708 * routes that are filtered. This tanks out Quagga RS pretty badly due
3710 * the iteration over all RS clients.
3711 * Since we need to remove the entry from adj_in anyway, do that first
3713 * if there was no entry, we don't need to do anything more.
3715 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
3716 && peer
!= bgp
->peer_self
)
3717 if (!bgp_adj_in_unset(rn
, peer
, addpath_id
)) {
3718 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3719 bgp_debug_rdpfxpath2str(
3720 afi
, safi
, prd
, p
, label
, num_labels
,
3721 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3724 "%s withdrawing route %s not in adj-in",
3725 peer
->host
, pfx_buf
);
3727 bgp_unlock_node(rn
);
3731 /* Lookup withdrawn route. */
3732 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
3733 if (pi
->peer
== peer
&& pi
->type
== type
3734 && pi
->sub_type
== sub_type
3735 && pi
->addpath_rx_id
== addpath_id
)
3739 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3740 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3741 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3743 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer
->host
,
3747 /* Withdraw specified route from routing table. */
3748 if (pi
&& !CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
)) {
3749 bgp_rib_withdraw(rn
, pi
, peer
, afi
, safi
, prd
);
3750 if (SAFI_UNICAST
== safi
3751 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3752 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3753 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, pi
);
3755 if ((SAFI_MPLS_VPN
== safi
)
3756 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3758 vpn_leak_to_vrf_withdraw(bgp
, pi
);
3760 } else if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3761 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3762 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3764 zlog_debug("%s Can't find the route %s", peer
->host
, pfx_buf
);
3767 /* Unlock bgp_node_get() lock. */
3768 bgp_unlock_node(rn
);
3773 void bgp_default_originate(struct peer
*peer
, afi_t afi
, safi_t safi
,
3776 struct update_subgroup
*subgrp
;
3777 subgrp
= peer_subgroup(peer
, afi
, safi
);
3778 subgroup_default_originate(subgrp
, withdraw
);
3783 * bgp_stop_announce_route_timer
3785 void bgp_stop_announce_route_timer(struct peer_af
*paf
)
3787 if (!paf
->t_announce_route
)
3790 THREAD_TIMER_OFF(paf
->t_announce_route
);
3794 * bgp_announce_route_timer_expired
3796 * Callback that is invoked when the route announcement timer for a
3799 static int bgp_announce_route_timer_expired(struct thread
*t
)
3801 struct peer_af
*paf
;
3804 paf
= THREAD_ARG(t
);
3807 if (peer
->status
!= Established
)
3810 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
3813 peer_af_announce_route(paf
, 1);
3818 * bgp_announce_route
3820 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3822 void bgp_announce_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3824 struct peer_af
*paf
;
3825 struct update_subgroup
*subgrp
;
3827 paf
= peer_af_find(peer
, afi
, safi
);
3830 subgrp
= PAF_SUBGRP(paf
);
3833 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3834 * or a refresh has already been triggered.
3836 if (!subgrp
|| paf
->t_announce_route
)
3840 * Start a timer to stagger/delay the announce. This serves
3841 * two purposes - announcement can potentially be combined for
3842 * multiple peers and the announcement doesn't happen in the
3845 thread_add_timer_msec(bm
->master
, bgp_announce_route_timer_expired
, paf
,
3846 (subgrp
->peer_count
== 1)
3847 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
3848 : BGP_ANNOUNCE_ROUTE_DELAY_MS
,
3849 &paf
->t_announce_route
);
3853 * Announce routes from all AF tables to a peer.
3855 * This should ONLY be called when there is a need to refresh the
3856 * routes to the peer based on a policy change for this peer alone
3857 * or a route refresh request received from the peer.
3858 * The operation will result in splitting the peer from its existing
3859 * subgroups and putting it in new subgroups.
3861 void bgp_announce_route_all(struct peer
*peer
)
3866 FOREACH_AFI_SAFI (afi
, safi
)
3867 bgp_announce_route(peer
, afi
, safi
);
3870 static void bgp_soft_reconfig_table(struct peer
*peer
, afi_t afi
, safi_t safi
,
3871 struct bgp_table
*table
,
3872 struct prefix_rd
*prd
)
3875 struct bgp_node
*rn
;
3876 struct bgp_adj_in
*ain
;
3879 table
= peer
->bgp
->rib
[afi
][safi
];
3881 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
3882 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
) {
3883 if (ain
->peer
!= peer
)
3886 struct bgp_path_info
*pi
=
3887 bgp_node_get_bgp_path_info(rn
);
3888 uint32_t num_labels
= 0;
3889 mpls_label_t
*label_pnt
= NULL
;
3890 struct bgp_route_evpn evpn
;
3892 if (pi
&& pi
->extra
)
3893 num_labels
= pi
->extra
->num_labels
;
3895 label_pnt
= &pi
->extra
->label
[0];
3897 memcpy(&evpn
, &pi
->attr
->evpn_overlay
,
3900 memset(&evpn
, 0, sizeof(evpn
));
3902 ret
= bgp_update(peer
, &rn
->p
, ain
->addpath_rx_id
,
3903 ain
->attr
, afi
, safi
, ZEBRA_ROUTE_BGP
,
3904 BGP_ROUTE_NORMAL
, prd
, label_pnt
,
3905 num_labels
, 1, &evpn
);
3908 bgp_unlock_node(rn
);
3914 void bgp_soft_reconfig_in(struct peer
*peer
, afi_t afi
, safi_t safi
)
3916 struct bgp_node
*rn
;
3917 struct bgp_table
*table
;
3919 if (peer
->status
!= Established
)
3922 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
)
3923 && (safi
!= SAFI_EVPN
))
3924 bgp_soft_reconfig_table(peer
, afi
, safi
, NULL
, NULL
);
3926 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3927 rn
= bgp_route_next(rn
)) {
3928 table
= bgp_node_get_bgp_table_info(rn
);
3929 if (table
!= NULL
) {
3930 struct prefix_rd prd
;
3932 prd
.family
= AF_UNSPEC
;
3934 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3936 bgp_soft_reconfig_table(peer
, afi
, safi
, table
,
3943 struct bgp_clear_node_queue
{
3944 struct bgp_node
*rn
;
3947 static wq_item_status
bgp_clear_route_node(struct work_queue
*wq
, void *data
)
3949 struct bgp_clear_node_queue
*cnq
= data
;
3950 struct bgp_node
*rn
= cnq
->rn
;
3951 struct peer
*peer
= wq
->spec
.data
;
3952 struct bgp_path_info
*pi
;
3954 afi_t afi
= bgp_node_table(rn
)->afi
;
3955 safi_t safi
= bgp_node_table(rn
)->safi
;
3960 /* It is possible that we have multiple paths for a prefix from a peer
3961 * if that peer is using AddPath.
3963 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
) {
3964 if (pi
->peer
!= peer
)
3967 /* graceful restart STALE flag set. */
3968 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3969 && peer
->nsf
[afi
][safi
]
3970 && !CHECK_FLAG(pi
->flags
, BGP_PATH_STALE
)
3971 && !CHECK_FLAG(pi
->flags
, BGP_PATH_UNUSEABLE
))
3972 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_STALE
);
3974 /* If this is an EVPN route, process for
3976 if (safi
== SAFI_EVPN
)
3977 bgp_evpn_unimport_route(bgp
, afi
, safi
, &rn
->p
,
3979 /* Handle withdraw for VRF route-leaking and L3VPN */
3980 if (SAFI_UNICAST
== safi
3981 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
||
3982 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3983 vpn_leak_from_vrf_withdraw(bgp_get_default(),
3986 if (SAFI_MPLS_VPN
== safi
&&
3987 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
3988 vpn_leak_to_vrf_withdraw(bgp
, pi
);
3991 bgp_rib_remove(rn
, pi
, peer
, afi
, safi
);
3997 static void bgp_clear_node_queue_del(struct work_queue
*wq
, void *data
)
3999 struct bgp_clear_node_queue
*cnq
= data
;
4000 struct bgp_node
*rn
= cnq
->rn
;
4001 struct bgp_table
*table
= bgp_node_table(rn
);
4003 bgp_unlock_node(rn
);
4004 bgp_table_unlock(table
);
4005 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
4008 static void bgp_clear_node_complete(struct work_queue
*wq
)
4010 struct peer
*peer
= wq
->spec
.data
;
4012 /* Tickle FSM to start moving again */
4013 BGP_EVENT_ADD(peer
, Clearing_Completed
);
4015 peer_unlock(peer
); /* bgp_clear_route */
4018 static void bgp_clear_node_queue_init(struct peer
*peer
)
4020 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
4022 snprintf(wname
, sizeof(wname
), "clear %s", peer
->host
);
4023 #undef CLEAR_QUEUE_NAME_LEN
4025 peer
->clear_node_queue
= work_queue_new(bm
->master
, wname
);
4026 peer
->clear_node_queue
->spec
.hold
= 10;
4027 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
4028 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
4029 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
4030 peer
->clear_node_queue
->spec
.max_retries
= 0;
4032 /* we only 'lock' this peer reference when the queue is actually active
4034 peer
->clear_node_queue
->spec
.data
= peer
;
4037 static void bgp_clear_route_table(struct peer
*peer
, afi_t afi
, safi_t safi
,
4038 struct bgp_table
*table
)
4040 struct bgp_node
*rn
;
4041 int force
= bm
->process_main_queue
? 0 : 1;
4044 table
= peer
->bgp
->rib
[afi
][safi
];
4046 /* If still no table => afi/safi isn't configured at all or smth. */
4050 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
4051 struct bgp_path_info
*pi
, *next
;
4052 struct bgp_adj_in
*ain
;
4053 struct bgp_adj_in
*ain_next
;
4055 /* XXX:TODO: This is suboptimal, every non-empty route_node is
4056 * queued for every clearing peer, regardless of whether it is
4057 * relevant to the peer at hand.
4059 * Overview: There are 3 different indices which need to be
4060 * scrubbed, potentially, when a peer is removed:
4062 * 1 peer's routes visible via the RIB (ie accepted routes)
4063 * 2 peer's routes visible by the (optional) peer's adj-in index
4064 * 3 other routes visible by the peer's adj-out index
4066 * 3 there is no hurry in scrubbing, once the struct peer is
4067 * removed from bgp->peer, we could just GC such deleted peer's
4068 * adj-outs at our leisure.
4070 * 1 and 2 must be 'scrubbed' in some way, at least made
4071 * invisible via RIB index before peer session is allowed to be
4072 * brought back up. So one needs to know when such a 'search' is
4077 * - there'd be a single global queue or a single RIB walker
4078 * - rather than tracking which route_nodes still need to be
4079 * examined on a peer basis, we'd track which peers still
4082 * Given that our per-peer prefix-counts now should be reliable,
4083 * this may actually be achievable. It doesn't seem to be a huge
4084 * problem at this time,
4086 * It is possible that we have multiple paths for a prefix from
4088 * if that peer is using AddPath.
4092 ain_next
= ain
->next
;
4094 if (ain
->peer
== peer
) {
4095 bgp_adj_in_remove(rn
, ain
);
4096 bgp_unlock_node(rn
);
4102 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= next
) {
4104 if (pi
->peer
!= peer
)
4108 bgp_path_info_reap(rn
, pi
);
4110 struct bgp_clear_node_queue
*cnq
;
4112 /* both unlocked in bgp_clear_node_queue_del */
4113 bgp_table_lock(bgp_node_table(rn
));
4116 MTYPE_BGP_CLEAR_NODE_QUEUE
,
4117 sizeof(struct bgp_clear_node_queue
));
4119 work_queue_add(peer
->clear_node_queue
, cnq
);
4127 void bgp_clear_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
4129 struct bgp_node
*rn
;
4130 struct bgp_table
*table
;
4132 if (peer
->clear_node_queue
== NULL
)
4133 bgp_clear_node_queue_init(peer
);
4135 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
4136 * Idle until it receives a Clearing_Completed event. This protects
4137 * against peers which flap faster than we can we clear, which could
4140 * a) race with routes from the new session being installed before
4141 * clear_route_node visits the node (to delete the route of that
4143 * b) resource exhaustion, clear_route_node likely leads to an entry
4144 * on the process_main queue. Fast-flapping could cause that queue
4148 /* lock peer in assumption that clear-node-queue will get nodes; if so,
4149 * the unlock will happen upon work-queue completion; other wise, the
4150 * unlock happens at the end of this function.
4152 if (!peer
->clear_node_queue
->thread
)
4155 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
&& safi
!= SAFI_EVPN
)
4156 bgp_clear_route_table(peer
, afi
, safi
, NULL
);
4158 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
4159 rn
= bgp_route_next(rn
)) {
4160 table
= bgp_node_get_bgp_table_info(rn
);
4164 bgp_clear_route_table(peer
, afi
, safi
, table
);
4167 /* unlock if no nodes got added to the clear-node-queue. */
4168 if (!peer
->clear_node_queue
->thread
)
4172 void bgp_clear_route_all(struct peer
*peer
)
4177 FOREACH_AFI_SAFI (afi
, safi
)
4178 bgp_clear_route(peer
, afi
, safi
);
4181 rfapiProcessPeerDown(peer
);
4185 void bgp_clear_adj_in(struct peer
*peer
, afi_t afi
, safi_t safi
)
4187 struct bgp_table
*table
;
4188 struct bgp_node
*rn
;
4189 struct bgp_adj_in
*ain
;
4190 struct bgp_adj_in
*ain_next
;
4192 table
= peer
->bgp
->rib
[afi
][safi
];
4194 /* It is possible that we have multiple paths for a prefix from a peer
4195 * if that peer is using AddPath.
4197 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
4201 ain_next
= ain
->next
;
4203 if (ain
->peer
== peer
) {
4204 bgp_adj_in_remove(rn
, ain
);
4205 bgp_unlock_node(rn
);
4213 void bgp_clear_stale_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
4215 struct bgp_node
*rn
;
4216 struct bgp_path_info
*pi
;
4217 struct bgp_table
*table
;
4219 if (safi
== SAFI_MPLS_VPN
) {
4220 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
4221 rn
= bgp_route_next(rn
)) {
4222 struct bgp_node
*rm
;
4224 /* look for neighbor in tables */
4225 table
= bgp_node_get_bgp_table_info(rn
);
4229 for (rm
= bgp_table_top(table
); rm
;
4230 rm
= bgp_route_next(rm
))
4231 for (pi
= bgp_node_get_bgp_path_info(rm
); pi
;
4233 if (pi
->peer
!= peer
)
4235 if (!CHECK_FLAG(pi
->flags
,
4239 bgp_rib_remove(rm
, pi
, peer
, afi
, safi
);
4244 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
4245 rn
= bgp_route_next(rn
))
4246 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
;
4248 if (pi
->peer
!= peer
)
4250 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_STALE
))
4252 bgp_rib_remove(rn
, pi
, peer
, afi
, safi
);
4258 int bgp_outbound_policy_exists(struct peer
*peer
, struct bgp_filter
*filter
)
4260 if (peer
->sort
== BGP_PEER_EBGP
4261 && (ROUTE_MAP_OUT_NAME(filter
) || PREFIX_LIST_OUT_NAME(filter
)
4262 || FILTER_LIST_OUT_NAME(filter
)
4263 || DISTRIBUTE_OUT_NAME(filter
)))
4268 int bgp_inbound_policy_exists(struct peer
*peer
, struct bgp_filter
*filter
)
4270 if (peer
->sort
== BGP_PEER_EBGP
4271 && (ROUTE_MAP_IN_NAME(filter
) || PREFIX_LIST_IN_NAME(filter
)
4272 || FILTER_LIST_IN_NAME(filter
)
4273 || DISTRIBUTE_IN_NAME(filter
)))
4278 static void bgp_cleanup_table(struct bgp
*bgp
, struct bgp_table
*table
,
4281 struct bgp_node
*rn
;
4282 struct bgp_path_info
*pi
;
4283 struct bgp_path_info
*next
;
4285 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
4286 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= next
) {
4289 /* Unimport EVPN routes from VRFs */
4290 if (safi
== SAFI_EVPN
)
4291 bgp_evpn_unimport_route(bgp
, AFI_L2VPN
,
4295 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)
4296 && pi
->type
== ZEBRA_ROUTE_BGP
4297 && (pi
->sub_type
== BGP_ROUTE_NORMAL
4298 || pi
->sub_type
== BGP_ROUTE_AGGREGATE
4299 || pi
->sub_type
== BGP_ROUTE_IMPORTED
)) {
4301 if (bgp_fibupd_safi(safi
))
4302 bgp_zebra_withdraw(&rn
->p
, pi
, bgp
,
4304 bgp_path_info_reap(rn
, pi
);
4309 /* Delete all kernel routes. */
4310 void bgp_cleanup_routes(struct bgp
*bgp
)
4313 struct bgp_node
*rn
;
4314 struct bgp_table
*table
;
4316 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
4317 if (afi
== AFI_L2VPN
)
4319 bgp_cleanup_table(bgp
, bgp
->rib
[afi
][SAFI_UNICAST
],
4322 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
4324 if (afi
!= AFI_L2VPN
) {
4326 safi
= SAFI_MPLS_VPN
;
4327 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
4328 rn
= bgp_route_next(rn
)) {
4329 table
= bgp_node_get_bgp_table_info(rn
);
4330 if (table
!= NULL
) {
4331 bgp_cleanup_table(bgp
, table
, safi
);
4332 bgp_table_finish(&table
);
4333 bgp_node_set_bgp_table_info(rn
, NULL
);
4334 bgp_unlock_node(rn
);
4338 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
4339 rn
= bgp_route_next(rn
)) {
4340 table
= bgp_node_get_bgp_table_info(rn
);
4341 if (table
!= NULL
) {
4342 bgp_cleanup_table(bgp
, table
, safi
);
4343 bgp_table_finish(&table
);
4344 bgp_node_set_bgp_table_info(rn
, NULL
);
4345 bgp_unlock_node(rn
);
4350 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
4351 rn
= bgp_route_next(rn
)) {
4352 table
= bgp_node_get_bgp_table_info(rn
);
4353 if (table
!= NULL
) {
4354 bgp_cleanup_table(bgp
, table
, SAFI_EVPN
);
4355 bgp_table_finish(&table
);
4356 bgp_node_set_bgp_table_info(rn
, NULL
);
4357 bgp_unlock_node(rn
);
4362 void bgp_reset(void)
4365 bgp_zclient_reset();
4366 access_list_reset();
4367 prefix_list_reset();
4370 static int bgp_addpath_encode_rx(struct peer
*peer
, afi_t afi
, safi_t safi
)
4372 return (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
4373 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
4374 PEER_CAP_ADDPATH_AF_TX_RCV
));
4377 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
4379 int bgp_nlri_parse_ip(struct peer
*peer
, struct attr
*attr
,
4380 struct bgp_nlri
*packet
)
4389 int addpath_encoded
;
4390 uint32_t addpath_id
;
4393 lim
= pnt
+ packet
->length
;
4395 safi
= packet
->safi
;
4397 addpath_encoded
= bgp_addpath_encode_rx(peer
, afi
, safi
);
4399 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
4400 syntactic validity. If the field is syntactically incorrect,
4401 then the Error Subcode is set to Invalid Network Field. */
4402 for (; pnt
< lim
; pnt
+= psize
) {
4403 /* Clear prefix structure. */
4404 memset(&p
, 0, sizeof(struct prefix
));
4406 if (addpath_encoded
) {
4408 /* When packet overflow occurs return immediately. */
4409 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
4410 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW
;
4412 addpath_id
= ntohl(*((uint32_t *)pnt
));
4413 pnt
+= BGP_ADDPATH_ID_LEN
;
4416 /* Fetch prefix length. */
4417 p
.prefixlen
= *pnt
++;
4418 /* afi/safi validity already verified by caller,
4419 * bgp_update_receive */
4420 p
.family
= afi2family(afi
);
4422 /* Prefix length check. */
4423 if (p
.prefixlen
> prefix_blen(&p
) * 8) {
4426 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
4427 peer
->host
, p
.prefixlen
, packet
->afi
);
4428 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH
;
4431 /* Packet size overflow check. */
4432 psize
= PSIZE(p
.prefixlen
);
4434 /* When packet overflow occur return immediately. */
4435 if (pnt
+ psize
> lim
) {
4438 "%s [Error] Update packet error (prefix length %d overflows packet)",
4439 peer
->host
, p
.prefixlen
);
4440 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW
;
4443 /* Defensive coding, double-check the psize fits in a struct
4445 if (psize
> (ssize_t
)sizeof(p
.u
)) {
4448 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
4449 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
4450 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
4453 /* Fetch prefix from NLRI packet. */
4454 memcpy(p
.u
.val
, pnt
, psize
);
4456 /* Check address. */
4457 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
) {
4458 if (IN_CLASSD(ntohl(p
.u
.prefix4
.s_addr
))) {
4459 /* From RFC4271 Section 6.3:
4461 * If a prefix in the NLRI field is semantically
4463 * (e.g., an unexpected multicast IP address),
4465 * be logged locally, and the prefix SHOULD be
4470 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
4471 peer
->host
, inet_ntoa(p
.u
.prefix4
));
4476 /* Check address. */
4477 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
) {
4478 if (IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
4483 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
4485 inet_ntop(AF_INET6
, &p
.u
.prefix6
, buf
,
4490 if (IN6_IS_ADDR_MULTICAST(&p
.u
.prefix6
)) {
4495 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
4497 inet_ntop(AF_INET6
, &p
.u
.prefix6
, buf
,
4504 /* Normal process. */
4506 ret
= bgp_update(peer
, &p
, addpath_id
, attr
, afi
, safi
,
4507 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
4508 NULL
, NULL
, 0, 0, NULL
);
4510 ret
= bgp_withdraw(peer
, &p
, addpath_id
, attr
, afi
,
4511 safi
, ZEBRA_ROUTE_BGP
,
4512 BGP_ROUTE_NORMAL
, NULL
, NULL
, 0,
4515 /* Do not send BGP notification twice when maximum-prefix count
4517 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
))
4518 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW
;
4520 /* Address family configuration mismatch. */
4522 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY
;
4525 /* Packet length consistency check. */
4529 "%s [Error] Update packet error (prefix length mismatch with total length)",
4531 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH
;
4534 return BGP_NLRI_PARSE_OK
;
4537 static struct bgp_static
*bgp_static_new(void)
4539 return XCALLOC(MTYPE_BGP_STATIC
, sizeof(struct bgp_static
));
4542 static void bgp_static_free(struct bgp_static
*bgp_static
)
4544 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4545 route_map_counter_decrement(bgp_static
->rmap
.map
);
4547 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
4548 XFREE(MTYPE_BGP_STATIC
, bgp_static
);
4551 void bgp_static_update(struct bgp
*bgp
, struct prefix
*p
,
4552 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
4554 struct bgp_node
*rn
;
4555 struct bgp_path_info
*pi
;
4556 struct bgp_path_info
*new;
4557 struct bgp_path_info rmap_path
;
4559 struct attr
*attr_new
;
4562 int vnc_implicit_withdraw
= 0;
4569 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4571 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
4573 attr
.nexthop
= bgp_static
->igpnexthop
;
4574 attr
.med
= bgp_static
->igpmetric
;
4575 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
4577 if (bgp_static
->atomic
)
4578 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
);
4580 /* Store label index, if required. */
4581 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
) {
4582 attr
.label_index
= bgp_static
->label_index
;
4583 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID
);
4586 /* Apply route-map. */
4587 if (bgp_static
->rmap
.name
) {
4588 struct attr attr_tmp
= attr
;
4590 memset(&rmap_path
, 0, sizeof(struct bgp_path_info
));
4591 rmap_path
.peer
= bgp
->peer_self
;
4592 rmap_path
.attr
= &attr_tmp
;
4594 SET_FLAG(bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4596 ret
= route_map_apply(bgp_static
->rmap
.map
, p
, RMAP_BGP
,
4599 bgp
->peer_self
->rmap_type
= 0;
4601 if (ret
== RMAP_DENYMATCH
) {
4602 /* Free uninterned attribute. */
4603 bgp_attr_flush(&attr_tmp
);
4605 /* Unintern original. */
4606 aspath_unintern(&attr
.aspath
);
4607 bgp_static_withdraw(bgp
, p
, afi
, safi
);
4611 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
4612 bgp_attr_add_gshut_community(&attr_tmp
);
4614 attr_new
= bgp_attr_intern(&attr_tmp
);
4617 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
4618 bgp_attr_add_gshut_community(&attr
);
4620 attr_new
= bgp_attr_intern(&attr
);
4623 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
4624 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== ZEBRA_ROUTE_BGP
4625 && pi
->sub_type
== BGP_ROUTE_STATIC
)
4629 if (attrhash_cmp(pi
->attr
, attr_new
)
4630 && !CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)
4631 && !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
)) {
4632 bgp_unlock_node(rn
);
4633 bgp_attr_unintern(&attr_new
);
4634 aspath_unintern(&attr
.aspath
);
4637 /* The attribute is changed. */
4638 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_ATTR_CHANGED
);
4640 /* Rewrite BGP route information. */
4641 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
))
4642 bgp_path_info_restore(rn
, pi
);
4644 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, safi
);
4646 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
4647 && (safi
== SAFI_UNICAST
)) {
4648 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)) {
4650 * Implicit withdraw case.
4651 * We have to do this before pi is
4654 ++vnc_implicit_withdraw
;
4655 vnc_import_bgp_del_route(bgp
, p
, pi
);
4656 vnc_import_bgp_exterior_del_route(
4661 bgp_attr_unintern(&pi
->attr
);
4662 pi
->attr
= attr_new
;
4663 pi
->uptime
= bgp_clock();
4665 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
4666 && (safi
== SAFI_UNICAST
)) {
4667 if (vnc_implicit_withdraw
) {
4668 vnc_import_bgp_add_route(bgp
, p
, pi
);
4669 vnc_import_bgp_exterior_add_route(
4675 /* Nexthop reachability check. */
4676 if (bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
4677 && (safi
== SAFI_UNICAST
4678 || safi
== SAFI_LABELED_UNICAST
)) {
4680 struct bgp
*bgp_nexthop
= bgp
;
4682 if (pi
->extra
&& pi
->extra
->bgp_orig
)
4683 bgp_nexthop
= pi
->extra
->bgp_orig
;
4685 if (bgp_find_or_add_nexthop(bgp
, bgp_nexthop
,
4687 bgp_path_info_set_flag(rn
, pi
,
4690 if (BGP_DEBUG(nht
, NHT
)) {
4691 char buf1
[INET6_ADDRSTRLEN
];
4692 inet_ntop(p
->family
,
4696 "%s(%s): Route not in table, not advertising",
4697 __FUNCTION__
, buf1
);
4699 bgp_path_info_unset_flag(
4700 rn
, pi
, BGP_PATH_VALID
);
4703 /* Delete the NHT structure if any, if we're
4705 * enabling/disabling import check. We
4706 * deregister the route
4707 * from NHT to avoid overloading NHT and the
4708 * process interaction
4710 bgp_unlink_nexthop(pi
);
4711 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_VALID
);
4713 /* Process change. */
4714 bgp_aggregate_increment(bgp
, p
, pi
, afi
, safi
);
4715 bgp_process(bgp
, rn
, afi
, safi
);
4717 if (SAFI_UNICAST
== safi
4718 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4720 == BGP_INSTANCE_TYPE_DEFAULT
)) {
4721 vpn_leak_from_vrf_update(bgp_get_default(), bgp
,
4725 bgp_unlock_node(rn
);
4726 aspath_unintern(&attr
.aspath
);
4731 /* Make new BGP info. */
4732 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
,
4734 /* Nexthop reachability check. */
4735 if (bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
4736 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
4737 if (bgp_find_or_add_nexthop(bgp
, bgp
, afi
, new, NULL
, 0))
4738 bgp_path_info_set_flag(rn
, new, BGP_PATH_VALID
);
4740 if (BGP_DEBUG(nht
, NHT
)) {
4741 char buf1
[INET6_ADDRSTRLEN
];
4742 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
4745 "%s(%s): Route not in table, not advertising",
4746 __FUNCTION__
, buf1
);
4748 bgp_path_info_unset_flag(rn
, new, BGP_PATH_VALID
);
4751 /* Delete the NHT structure if any, if we're toggling between
4752 * enabling/disabling import check. We deregister the route
4753 * from NHT to avoid overloading NHT and the process interaction
4755 bgp_unlink_nexthop(new);
4757 bgp_path_info_set_flag(rn
, new, BGP_PATH_VALID
);
4760 /* Aggregate address increment. */
4761 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
4763 /* Register new BGP information. */
4764 bgp_path_info_add(rn
, new);
4766 /* route_node_get lock */
4767 bgp_unlock_node(rn
);
4769 /* Process change. */
4770 bgp_process(bgp
, rn
, afi
, safi
);
4772 if (SAFI_UNICAST
== safi
4773 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4774 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
4775 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
4778 /* Unintern original. */
4779 aspath_unintern(&attr
.aspath
);
4782 void bgp_static_withdraw(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
4785 struct bgp_node
*rn
;
4786 struct bgp_path_info
*pi
;
4788 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4790 /* Check selected route and self inserted route. */
4791 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
4792 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== ZEBRA_ROUTE_BGP
4793 && pi
->sub_type
== BGP_ROUTE_STATIC
)
4796 /* Withdraw static BGP route from routing table. */
4798 if (SAFI_UNICAST
== safi
4799 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4800 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
4801 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, pi
);
4803 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, safi
);
4804 bgp_unlink_nexthop(pi
);
4805 bgp_path_info_delete(rn
, pi
);
4806 bgp_process(bgp
, rn
, afi
, safi
);
4809 /* Unlock bgp_node_lookup. */
4810 bgp_unlock_node(rn
);
4814 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4816 static void bgp_static_withdraw_safi(struct bgp
*bgp
, struct prefix
*p
,
4817 afi_t afi
, safi_t safi
,
4818 struct prefix_rd
*prd
)
4820 struct bgp_node
*rn
;
4821 struct bgp_path_info
*pi
;
4823 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
4825 /* Check selected route and self inserted route. */
4826 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
4827 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== ZEBRA_ROUTE_BGP
4828 && pi
->sub_type
== BGP_ROUTE_STATIC
)
4831 /* Withdraw static BGP route from routing table. */
4834 rfapiProcessWithdraw(
4835 pi
->peer
, NULL
, p
, prd
, pi
->attr
, afi
, safi
, pi
->type
,
4836 1); /* Kill, since it is an administrative change */
4838 if (SAFI_MPLS_VPN
== safi
4839 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4840 vpn_leak_to_vrf_withdraw(bgp
, pi
);
4842 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, safi
);
4843 bgp_path_info_delete(rn
, pi
);
4844 bgp_process(bgp
, rn
, afi
, safi
);
4847 /* Unlock bgp_node_lookup. */
4848 bgp_unlock_node(rn
);
4851 static void bgp_static_update_safi(struct bgp
*bgp
, struct prefix
*p
,
4852 struct bgp_static
*bgp_static
, afi_t afi
,
4855 struct bgp_node
*rn
;
4856 struct bgp_path_info
*new;
4857 struct attr
*attr_new
;
4858 struct attr attr
= {0};
4859 struct bgp_path_info
*pi
;
4861 mpls_label_t label
= 0;
4863 uint32_t num_labels
= 0;
4868 if (bgp_static
->label
!= MPLS_INVALID_LABEL
)
4870 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
,
4873 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
4875 attr
.nexthop
= bgp_static
->igpnexthop
;
4876 attr
.med
= bgp_static
->igpmetric
;
4877 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
4879 if ((safi
== SAFI_EVPN
) || (safi
== SAFI_MPLS_VPN
)
4880 || (safi
== SAFI_ENCAP
)) {
4881 if (afi
== AFI_IP
) {
4882 attr
.mp_nexthop_global_in
= bgp_static
->igpnexthop
;
4883 attr
.mp_nexthop_len
= IPV4_MAX_BYTELEN
;
4886 if (afi
== AFI_L2VPN
) {
4887 if (bgp_static
->gatewayIp
.family
== AF_INET
)
4889 bgp_static
->gatewayIp
.u
.prefix4
.s_addr
;
4890 else if (bgp_static
->gatewayIp
.family
== AF_INET6
)
4891 memcpy(&(add
.ipv6
), &(bgp_static
->gatewayIp
.u
.prefix6
),
4892 sizeof(struct in6_addr
));
4893 overlay_index_update(&attr
, bgp_static
->eth_s_id
, &add
);
4894 if (bgp_static
->encap_tunneltype
== BGP_ENCAP_TYPE_VXLAN
) {
4895 struct bgp_encap_type_vxlan bet
;
4896 memset(&bet
, 0, sizeof(struct bgp_encap_type_vxlan
));
4897 bet
.vnid
= p
->u
.prefix_evpn
.prefix_addr
.eth_tag
;
4898 bgp_encap_type_vxlan_to_tlv(&bet
, &attr
);
4900 if (bgp_static
->router_mac
) {
4901 bgp_add_routermac_ecom(&attr
, bgp_static
->router_mac
);
4904 /* Apply route-map. */
4905 if (bgp_static
->rmap
.name
) {
4906 struct attr attr_tmp
= attr
;
4907 struct bgp_path_info rmap_path
;
4910 rmap_path
.peer
= bgp
->peer_self
;
4911 rmap_path
.attr
= &attr_tmp
;
4913 SET_FLAG(bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4915 ret
= route_map_apply(bgp_static
->rmap
.map
, p
, RMAP_BGP
,
4918 bgp
->peer_self
->rmap_type
= 0;
4920 if (ret
== RMAP_DENYMATCH
) {
4921 /* Free uninterned attribute. */
4922 bgp_attr_flush(&attr_tmp
);
4924 /* Unintern original. */
4925 aspath_unintern(&attr
.aspath
);
4926 bgp_static_withdraw_safi(bgp
, p
, afi
, safi
,
4931 attr_new
= bgp_attr_intern(&attr_tmp
);
4933 attr_new
= bgp_attr_intern(&attr
);
4936 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
4937 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== ZEBRA_ROUTE_BGP
4938 && pi
->sub_type
== BGP_ROUTE_STATIC
)
4942 memset(&add
, 0, sizeof(union gw_addr
));
4943 if (attrhash_cmp(pi
->attr
, attr_new
)
4944 && overlay_index_equal(afi
, pi
, bgp_static
->eth_s_id
, &add
)
4945 && !CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)) {
4946 bgp_unlock_node(rn
);
4947 bgp_attr_unintern(&attr_new
);
4948 aspath_unintern(&attr
.aspath
);
4951 /* The attribute is changed. */
4952 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_ATTR_CHANGED
);
4954 /* Rewrite BGP route information. */
4955 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
))
4956 bgp_path_info_restore(rn
, pi
);
4958 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, safi
);
4959 bgp_attr_unintern(&pi
->attr
);
4960 pi
->attr
= attr_new
;
4961 pi
->uptime
= bgp_clock();
4964 label
= decode_label(&pi
->extra
->label
[0]);
4967 /* Process change. */
4968 bgp_aggregate_increment(bgp
, p
, pi
, afi
, safi
);
4969 bgp_process(bgp
, rn
, afi
, safi
);
4971 if (SAFI_MPLS_VPN
== safi
4972 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4973 vpn_leak_to_vrf_update(bgp
, pi
);
4976 rfapiProcessUpdate(pi
->peer
, NULL
, p
, &bgp_static
->prd
,
4977 pi
->attr
, afi
, safi
, pi
->type
,
4978 pi
->sub_type
, &label
);
4980 bgp_unlock_node(rn
);
4981 aspath_unintern(&attr
.aspath
);
4987 /* Make new BGP info. */
4988 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
,
4990 SET_FLAG(new->flags
, BGP_PATH_VALID
);
4991 new->extra
= bgp_path_info_extra_new();
4993 new->extra
->label
[0] = bgp_static
->label
;
4994 new->extra
->num_labels
= num_labels
;
4997 label
= decode_label(&bgp_static
->label
);
5000 /* Aggregate address increment. */
5001 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
5003 /* Register new BGP information. */
5004 bgp_path_info_add(rn
, new);
5005 /* route_node_get lock */
5006 bgp_unlock_node(rn
);
5008 /* Process change. */
5009 bgp_process(bgp
, rn
, afi
, safi
);
5011 if (SAFI_MPLS_VPN
== safi
5012 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
5013 vpn_leak_to_vrf_update(bgp
, new);
5016 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
, new->attr
, afi
,
5017 safi
, new->type
, new->sub_type
, &label
);
5020 /* Unintern original. */
5021 aspath_unintern(&attr
.aspath
);
5024 /* Configure static BGP network. When user don't run zebra, static
5025 route should be installed as valid. */
5026 static int bgp_static_set(struct vty
*vty
, const char *negate
,
5027 const char *ip_str
, afi_t afi
, safi_t safi
,
5028 const char *rmap
, int backdoor
, uint32_t label_index
)
5030 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5033 struct bgp_static
*bgp_static
;
5034 struct bgp_node
*rn
;
5035 uint8_t need_update
= 0;
5037 /* Convert IP prefix string to struct prefix. */
5038 ret
= str2prefix(ip_str
, &p
);
5040 vty_out(vty
, "%% Malformed prefix\n");
5041 return CMD_WARNING_CONFIG_FAILED
;
5043 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
5044 vty_out(vty
, "%% Malformed prefix (link-local address)\n");
5045 return CMD_WARNING_CONFIG_FAILED
;
5052 /* Set BGP static route configuration. */
5053 rn
= bgp_node_lookup(bgp
->route
[afi
][safi
], &p
);
5056 vty_out(vty
, "%% Can't find static route specified\n");
5057 return CMD_WARNING_CONFIG_FAILED
;
5060 bgp_static
= bgp_node_get_bgp_static_info(rn
);
5062 if ((label_index
!= BGP_INVALID_LABEL_INDEX
)
5063 && (label_index
!= bgp_static
->label_index
)) {
5065 "%% label-index doesn't match static route\n");
5066 return CMD_WARNING_CONFIG_FAILED
;
5069 if ((rmap
&& bgp_static
->rmap
.name
)
5070 && strcmp(rmap
, bgp_static
->rmap
.name
)) {
5072 "%% route-map name doesn't match static route\n");
5073 return CMD_WARNING_CONFIG_FAILED
;
5076 /* Update BGP RIB. */
5077 if (!bgp_static
->backdoor
)
5078 bgp_static_withdraw(bgp
, &p
, afi
, safi
);
5080 /* Clear configuration. */
5081 bgp_static_free(bgp_static
);
5082 bgp_node_set_bgp_static_info(rn
, NULL
);
5083 bgp_unlock_node(rn
);
5084 bgp_unlock_node(rn
);
5087 /* Set BGP static route configuration. */
5088 rn
= bgp_node_get(bgp
->route
[afi
][safi
], &p
);
5090 bgp_static
= bgp_node_get_bgp_static_info(rn
);
5092 /* Configuration change. */
5093 /* Label index cannot be changed. */
5094 if (bgp_static
->label_index
!= label_index
) {
5095 vty_out(vty
, "%% cannot change label-index\n");
5096 return CMD_WARNING_CONFIG_FAILED
;
5099 /* Check previous routes are installed into BGP. */
5100 if (bgp_static
->valid
5101 && bgp_static
->backdoor
!= backdoor
)
5104 bgp_static
->backdoor
= backdoor
;
5107 XFREE(MTYPE_ROUTE_MAP_NAME
,
5108 bgp_static
->rmap
.name
);
5109 route_map_counter_decrement(
5110 bgp_static
->rmap
.map
);
5111 bgp_static
->rmap
.name
=
5112 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
5113 bgp_static
->rmap
.map
=
5114 route_map_lookup_by_name(rmap
);
5115 route_map_counter_increment(
5116 bgp_static
->rmap
.map
);
5118 XFREE(MTYPE_ROUTE_MAP_NAME
,
5119 bgp_static
->rmap
.name
);
5120 route_map_counter_decrement(
5121 bgp_static
->rmap
.map
);
5122 bgp_static
->rmap
.name
= NULL
;
5123 bgp_static
->rmap
.map
= NULL
;
5124 bgp_static
->valid
= 0;
5126 bgp_unlock_node(rn
);
5128 /* New configuration. */
5129 bgp_static
= bgp_static_new();
5130 bgp_static
->backdoor
= backdoor
;
5131 bgp_static
->valid
= 0;
5132 bgp_static
->igpmetric
= 0;
5133 bgp_static
->igpnexthop
.s_addr
= 0;
5134 bgp_static
->label_index
= label_index
;
5137 XFREE(MTYPE_ROUTE_MAP_NAME
,
5138 bgp_static
->rmap
.name
);
5139 route_map_counter_decrement(
5140 bgp_static
->rmap
.map
);
5141 bgp_static
->rmap
.name
=
5142 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
5143 bgp_static
->rmap
.map
=
5144 route_map_lookup_by_name(rmap
);
5145 route_map_counter_increment(
5146 bgp_static
->rmap
.map
);
5148 bgp_node_set_bgp_static_info(rn
, bgp_static
);
5151 bgp_static
->valid
= 1;
5153 bgp_static_withdraw(bgp
, &p
, afi
, safi
);
5155 if (!bgp_static
->backdoor
)
5156 bgp_static_update(bgp
, &p
, bgp_static
, afi
, safi
);
5162 void bgp_static_add(struct bgp
*bgp
)
5166 struct bgp_node
*rn
;
5167 struct bgp_node
*rm
;
5168 struct bgp_table
*table
;
5169 struct bgp_static
*bgp_static
;
5171 FOREACH_AFI_SAFI (afi
, safi
)
5172 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
5173 rn
= bgp_route_next(rn
)) {
5174 if (!bgp_node_has_bgp_path_info_data(rn
))
5177 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5178 || (safi
== SAFI_EVPN
)) {
5179 table
= bgp_node_get_bgp_table_info(rn
);
5181 for (rm
= bgp_table_top(table
); rm
;
5182 rm
= bgp_route_next(rm
)) {
5184 bgp_node_get_bgp_static_info(
5186 bgp_static_update_safi(bgp
, &rm
->p
,
5193 bgp_node_get_bgp_static_info(rn
), afi
,
5199 /* Called from bgp_delete(). Delete all static routes from the BGP
5201 void bgp_static_delete(struct bgp
*bgp
)
5205 struct bgp_node
*rn
;
5206 struct bgp_node
*rm
;
5207 struct bgp_table
*table
;
5208 struct bgp_static
*bgp_static
;
5210 FOREACH_AFI_SAFI (afi
, safi
)
5211 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
5212 rn
= bgp_route_next(rn
)) {
5213 if (!bgp_node_has_bgp_path_info_data(rn
))
5216 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5217 || (safi
== SAFI_EVPN
)) {
5218 table
= bgp_node_get_bgp_table_info(rn
);
5220 for (rm
= bgp_table_top(table
); rm
;
5221 rm
= bgp_route_next(rm
)) {
5223 bgp_node_get_bgp_static_info(
5228 bgp_static_withdraw_safi(
5229 bgp
, &rm
->p
, AFI_IP
, safi
,
5230 (struct prefix_rd
*)&rn
->p
);
5231 bgp_static_free(bgp_static
);
5232 bgp_node_set_bgp_static_info(rn
, NULL
);
5233 bgp_unlock_node(rn
);
5236 bgp_static
= bgp_node_get_bgp_static_info(rn
);
5237 bgp_static_withdraw(bgp
, &rn
->p
, afi
, safi
);
5238 bgp_static_free(bgp_static
);
5239 bgp_node_set_bgp_static_info(rn
, NULL
);
5240 bgp_unlock_node(rn
);
5245 void bgp_static_redo_import_check(struct bgp
*bgp
)
5249 struct bgp_node
*rn
;
5250 struct bgp_node
*rm
;
5251 struct bgp_table
*table
;
5252 struct bgp_static
*bgp_static
;
5254 /* Use this flag to force reprocessing of the route */
5255 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
5256 FOREACH_AFI_SAFI (afi
, safi
) {
5257 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
5258 rn
= bgp_route_next(rn
)) {
5259 if (!bgp_node_has_bgp_path_info_data(rn
))
5262 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5263 || (safi
== SAFI_EVPN
)) {
5264 table
= bgp_node_get_bgp_table_info(rn
);
5266 for (rm
= bgp_table_top(table
); rm
;
5267 rm
= bgp_route_next(rm
)) {
5269 bgp_node_get_bgp_static_info(
5271 bgp_static_update_safi(bgp
, &rm
->p
,
5276 bgp_static
= bgp_node_get_bgp_static_info(rn
);
5277 bgp_static_update(bgp
, &rn
->p
, bgp_static
, afi
,
5282 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
5285 static void bgp_purge_af_static_redist_routes(struct bgp
*bgp
, afi_t afi
,
5288 struct bgp_table
*table
;
5289 struct bgp_node
*rn
;
5290 struct bgp_path_info
*pi
;
5292 table
= bgp
->rib
[afi
][safi
];
5293 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
5294 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
) {
5295 if (pi
->peer
== bgp
->peer_self
5296 && ((pi
->type
== ZEBRA_ROUTE_BGP
5297 && pi
->sub_type
== BGP_ROUTE_STATIC
)
5298 || (pi
->type
!= ZEBRA_ROUTE_BGP
5300 == BGP_ROUTE_REDISTRIBUTE
))) {
5301 bgp_aggregate_decrement(bgp
, &rn
->p
, pi
, afi
,
5303 bgp_unlink_nexthop(pi
);
5304 bgp_path_info_delete(rn
, pi
);
5305 bgp_process(bgp
, rn
, afi
, safi
);
5312 * Purge all networks and redistributed routes from routing table.
5313 * Invoked upon the instance going down.
5315 void bgp_purge_static_redist_routes(struct bgp
*bgp
)
5320 FOREACH_AFI_SAFI (afi
, safi
)
5321 bgp_purge_af_static_redist_routes(bgp
, afi
, safi
);
5326 * Currently this is used to set static routes for VPN and ENCAP.
5327 * I think it can probably be factored with bgp_static_set.
5329 int bgp_static_set_safi(afi_t afi
, safi_t safi
, struct vty
*vty
,
5330 const char *ip_str
, const char *rd_str
,
5331 const char *label_str
, const char *rmap_str
,
5332 int evpn_type
, const char *esi
, const char *gwip
,
5333 const char *ethtag
, const char *routermac
)
5335 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5338 struct prefix_rd prd
;
5339 struct bgp_node
*prn
;
5340 struct bgp_node
*rn
;
5341 struct bgp_table
*table
;
5342 struct bgp_static
*bgp_static
;
5343 mpls_label_t label
= MPLS_INVALID_LABEL
;
5344 struct prefix gw_ip
;
5346 /* validate ip prefix */
5347 ret
= str2prefix(ip_str
, &p
);
5349 vty_out(vty
, "%% Malformed prefix\n");
5350 return CMD_WARNING_CONFIG_FAILED
;
5353 if ((afi
== AFI_L2VPN
)
5354 && (bgp_build_evpn_prefix(evpn_type
,
5355 ethtag
!= NULL
? atol(ethtag
) : 0, &p
))) {
5356 vty_out(vty
, "%% L2VPN prefix could not be forged\n");
5357 return CMD_WARNING_CONFIG_FAILED
;
5360 ret
= str2prefix_rd(rd_str
, &prd
);
5362 vty_out(vty
, "%% Malformed rd\n");
5363 return CMD_WARNING_CONFIG_FAILED
;
5367 unsigned long label_val
;
5368 label_val
= strtoul(label_str
, NULL
, 10);
5369 encode_label(label_val
, &label
);
5372 if (safi
== SAFI_EVPN
) {
5373 if (esi
&& str2esi(esi
, NULL
) == 0) {
5374 vty_out(vty
, "%% Malformed ESI\n");
5375 return CMD_WARNING_CONFIG_FAILED
;
5377 if (routermac
&& prefix_str2mac(routermac
, NULL
) == 0) {
5378 vty_out(vty
, "%% Malformed Router MAC\n");
5379 return CMD_WARNING_CONFIG_FAILED
;
5382 memset(&gw_ip
, 0, sizeof(struct prefix
));
5383 ret
= str2prefix(gwip
, &gw_ip
);
5385 vty_out(vty
, "%% Malformed GatewayIp\n");
5386 return CMD_WARNING_CONFIG_FAILED
;
5388 if ((gw_ip
.family
== AF_INET
5389 && is_evpn_prefix_ipaddr_v6(
5390 (struct prefix_evpn
*)&p
))
5391 || (gw_ip
.family
== AF_INET6
5392 && is_evpn_prefix_ipaddr_v4(
5393 (struct prefix_evpn
*)&p
))) {
5395 "%% GatewayIp family differs with IP prefix\n");
5396 return CMD_WARNING_CONFIG_FAILED
;
5400 prn
= bgp_node_get(bgp
->route
[afi
][safi
], (struct prefix
*)&prd
);
5401 if (!bgp_node_has_bgp_path_info_data(prn
))
5402 bgp_node_set_bgp_table_info(prn
,
5403 bgp_table_init(bgp
, afi
, safi
));
5404 table
= bgp_node_get_bgp_table_info(prn
);
5406 rn
= bgp_node_get(table
, &p
);
5408 if (bgp_node_has_bgp_path_info_data(rn
)) {
5409 vty_out(vty
, "%% Same network configuration exists\n");
5410 bgp_unlock_node(rn
);
5412 /* New configuration. */
5413 bgp_static
= bgp_static_new();
5414 bgp_static
->backdoor
= 0;
5415 bgp_static
->valid
= 0;
5416 bgp_static
->igpmetric
= 0;
5417 bgp_static
->igpnexthop
.s_addr
= 0;
5418 bgp_static
->label
= label
;
5419 bgp_static
->prd
= prd
;
5422 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
5423 route_map_counter_decrement(bgp_static
->rmap
.map
);
5424 bgp_static
->rmap
.name
=
5425 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_str
);
5426 bgp_static
->rmap
.map
=
5427 route_map_lookup_by_name(rmap_str
);
5428 route_map_counter_increment(bgp_static
->rmap
.map
);
5431 if (safi
== SAFI_EVPN
) {
5433 bgp_static
->eth_s_id
=
5435 sizeof(struct eth_segment_id
));
5436 str2esi(esi
, bgp_static
->eth_s_id
);
5439 bgp_static
->router_mac
=
5440 XCALLOC(MTYPE_ATTR
, ETH_ALEN
+ 1);
5441 (void)prefix_str2mac(routermac
,
5442 bgp_static
->router_mac
);
5445 prefix_copy(&bgp_static
->gatewayIp
, &gw_ip
);
5447 bgp_node_set_bgp_static_info(rn
, bgp_static
);
5449 bgp_static
->valid
= 1;
5450 bgp_static_update_safi(bgp
, &p
, bgp_static
, afi
, safi
);
5456 /* Configure static BGP network. */
5457 int bgp_static_unset_safi(afi_t afi
, safi_t safi
, struct vty
*vty
,
5458 const char *ip_str
, const char *rd_str
,
5459 const char *label_str
, int evpn_type
, const char *esi
,
5460 const char *gwip
, const char *ethtag
)
5462 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5465 struct prefix_rd prd
;
5466 struct bgp_node
*prn
;
5467 struct bgp_node
*rn
;
5468 struct bgp_table
*table
;
5469 struct bgp_static
*bgp_static
;
5470 mpls_label_t label
= MPLS_INVALID_LABEL
;
5472 /* Convert IP prefix string to struct prefix. */
5473 ret
= str2prefix(ip_str
, &p
);
5475 vty_out(vty
, "%% Malformed prefix\n");
5476 return CMD_WARNING_CONFIG_FAILED
;
5479 if ((afi
== AFI_L2VPN
)
5480 && (bgp_build_evpn_prefix(evpn_type
,
5481 ethtag
!= NULL
? atol(ethtag
) : 0, &p
))) {
5482 vty_out(vty
, "%% L2VPN prefix could not be forged\n");
5483 return CMD_WARNING_CONFIG_FAILED
;
5485 ret
= str2prefix_rd(rd_str
, &prd
);
5487 vty_out(vty
, "%% Malformed rd\n");
5488 return CMD_WARNING_CONFIG_FAILED
;
5492 unsigned long label_val
;
5493 label_val
= strtoul(label_str
, NULL
, 10);
5494 encode_label(label_val
, &label
);
5497 prn
= bgp_node_get(bgp
->route
[afi
][safi
], (struct prefix
*)&prd
);
5498 if (!bgp_node_has_bgp_path_info_data(prn
))
5499 bgp_node_set_bgp_table_info(prn
,
5500 bgp_table_init(bgp
, afi
, safi
));
5502 bgp_unlock_node(prn
);
5503 table
= bgp_node_get_bgp_table_info(prn
);
5505 rn
= bgp_node_lookup(table
, &p
);
5508 bgp_static_withdraw_safi(bgp
, &p
, afi
, safi
, &prd
);
5510 bgp_static
= bgp_node_get_bgp_static_info(rn
);
5511 bgp_static_free(bgp_static
);
5512 bgp_node_set_bgp_static_info(rn
, NULL
);
5513 bgp_unlock_node(rn
);
5514 bgp_unlock_node(rn
);
5516 vty_out(vty
, "%% Can't find the route\n");
5521 static int bgp_table_map_set(struct vty
*vty
, afi_t afi
, safi_t safi
,
5522 const char *rmap_name
)
5524 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5525 struct bgp_rmap
*rmap
;
5527 rmap
= &bgp
->table_map
[afi
][safi
];
5529 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5530 route_map_counter_decrement(rmap
->map
);
5531 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
5532 rmap
->map
= route_map_lookup_by_name(rmap_name
);
5533 route_map_counter_increment(rmap
->map
);
5535 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5536 route_map_counter_decrement(rmap
->map
);
5541 if (bgp_fibupd_safi(safi
))
5542 bgp_zebra_announce_table(bgp
, afi
, safi
);
5547 static int bgp_table_map_unset(struct vty
*vty
, afi_t afi
, safi_t safi
,
5548 const char *rmap_name
)
5550 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5551 struct bgp_rmap
*rmap
;
5553 rmap
= &bgp
->table_map
[afi
][safi
];
5554 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5555 route_map_counter_decrement(rmap
->map
);
5559 if (bgp_fibupd_safi(safi
))
5560 bgp_zebra_announce_table(bgp
, afi
, safi
);
5565 void bgp_config_write_table_map(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
5568 if (bgp
->table_map
[afi
][safi
].name
) {
5569 vty_out(vty
, " table-map %s\n",
5570 bgp
->table_map
[afi
][safi
].name
);
5574 DEFUN (bgp_table_map
,
5577 "BGP table to RIB route download filter\n"
5578 "Name of the route map\n")
5581 return bgp_table_map_set(vty
, bgp_node_afi(vty
), bgp_node_safi(vty
),
5582 argv
[idx_word
]->arg
);
5584 DEFUN (no_bgp_table_map
,
5585 no_bgp_table_map_cmd
,
5586 "no table-map WORD",
5588 "BGP table to RIB route download filter\n"
5589 "Name of the route map\n")
5592 return bgp_table_map_unset(vty
, bgp_node_afi(vty
), bgp_node_safi(vty
),
5593 argv
[idx_word
]->arg
);
5599 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
5600 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
5601 backdoor$backdoor}]",
5603 "Specify a network to announce via BGP\n"
5608 "Route-map to modify the attributes\n"
5609 "Name of the route map\n"
5610 "Label index to associate with the prefix\n"
5611 "Label index value\n"
5612 "Specify a BGP backdoor route\n")
5614 char addr_prefix_str
[BUFSIZ
];
5619 ret
= netmask_str2prefix_str(address_str
, netmask_str
,
5622 vty_out(vty
, "%% Inconsistent address and mask\n");
5623 return CMD_WARNING_CONFIG_FAILED
;
5627 return bgp_static_set(
5628 vty
, no
, address_str
? addr_prefix_str
: prefix_str
, AFI_IP
,
5629 bgp_node_safi(vty
), map_name
, backdoor
? 1 : 0,
5630 label_index
? (uint32_t)label_index
: BGP_INVALID_LABEL_INDEX
);
5633 DEFPY(ipv6_bgp_network
,
5634 ipv6_bgp_network_cmd
,
5635 "[no] network X:X::X:X/M$prefix \
5636 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
5638 "Specify a network to announce via BGP\n"
5640 "Route-map to modify the attributes\n"
5641 "Name of the route map\n"
5642 "Label index to associate with the prefix\n"
5643 "Label index value\n")
5645 return bgp_static_set(
5646 vty
, no
, prefix_str
, AFI_IP6
, bgp_node_safi(vty
), map_name
, 0,
5647 label_index
? (uint32_t)label_index
: BGP_INVALID_LABEL_INDEX
);
5650 static struct bgp_aggregate
*bgp_aggregate_new(void)
5652 return XCALLOC(MTYPE_BGP_AGGREGATE
, sizeof(struct bgp_aggregate
));
5655 static void bgp_aggregate_free(struct bgp_aggregate
*aggregate
)
5657 XFREE(MTYPE_BGP_AGGREGATE
, aggregate
);
5660 static int bgp_aggregate_info_same(struct bgp_path_info
*pi
, uint8_t origin
,
5661 struct aspath
*aspath
,
5662 struct community
*comm
,
5663 struct ecommunity
*ecomm
,
5664 struct lcommunity
*lcomm
)
5666 static struct aspath
*ae
= NULL
;
5669 ae
= aspath_empty();
5674 if (origin
!= pi
->attr
->origin
)
5677 if (!aspath_cmp(pi
->attr
->aspath
, (aspath
) ? aspath
: ae
))
5680 if (!community_cmp(pi
->attr
->community
, comm
))
5683 if (!ecommunity_cmp(pi
->attr
->ecommunity
, ecomm
))
5686 if (!lcommunity_cmp(pi
->attr
->lcommunity
, lcomm
))
5689 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_VALID
))
5695 static void bgp_aggregate_install(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
5696 struct prefix
*p
, uint8_t origin
,
5697 struct aspath
*aspath
,
5698 struct community
*community
,
5699 struct ecommunity
*ecommunity
,
5700 struct lcommunity
*lcommunity
,
5701 uint8_t atomic_aggregate
,
5702 struct bgp_aggregate
*aggregate
)
5704 struct bgp_node
*rn
;
5705 struct bgp_table
*table
;
5706 struct bgp_path_info
*pi
, *orig
, *new;
5708 table
= bgp
->rib
[afi
][safi
];
5710 rn
= bgp_node_get(table
, p
);
5712 for (orig
= pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
5713 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== ZEBRA_ROUTE_BGP
5714 && pi
->sub_type
== BGP_ROUTE_AGGREGATE
)
5717 if (aggregate
->count
> 0) {
5719 * If the aggregate information has not changed
5720 * no need to re-install it again.
5722 if (bgp_aggregate_info_same(orig
, origin
, aspath
, community
,
5723 ecommunity
, lcommunity
)) {
5724 bgp_unlock_node(rn
);
5727 aspath_free(aspath
);
5729 community_free(&community
);
5731 ecommunity_free(&ecommunity
);
5733 lcommunity_free(&lcommunity
);
5739 * Mark the old as unusable
5742 bgp_path_info_delete(rn
, pi
);
5744 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0,
5746 bgp_attr_aggregate_intern(bgp
, origin
, aspath
,
5747 community
, ecommunity
,
5752 SET_FLAG(new->flags
, BGP_PATH_VALID
);
5754 bgp_path_info_add(rn
, new);
5755 bgp_process(bgp
, rn
, afi
, safi
);
5757 for (pi
= orig
; pi
; pi
= pi
->next
)
5758 if (pi
->peer
== bgp
->peer_self
5759 && pi
->type
== ZEBRA_ROUTE_BGP
5760 && pi
->sub_type
== BGP_ROUTE_AGGREGATE
)
5763 /* Withdraw static BGP route from routing table. */
5765 bgp_path_info_delete(rn
, pi
);
5766 bgp_process(bgp
, rn
, afi
, safi
);
5770 bgp_unlock_node(rn
);
5773 /* Update an aggregate as routes are added/removed from the BGP table */
5774 static void bgp_aggregate_route(struct bgp
*bgp
, struct prefix
*p
,
5775 afi_t afi
, safi_t safi
,
5776 struct bgp_aggregate
*aggregate
)
5778 struct bgp_table
*table
;
5779 struct bgp_node
*top
;
5780 struct bgp_node
*rn
;
5782 struct aspath
*aspath
= NULL
;
5783 struct community
*community
= NULL
;
5784 struct ecommunity
*ecommunity
= NULL
;
5785 struct lcommunity
*lcommunity
= NULL
;
5786 struct bgp_path_info
*pi
;
5787 unsigned long match
= 0;
5788 uint8_t atomic_aggregate
= 0;
5790 /* ORIGIN attribute: If at least one route among routes that are
5791 aggregated has ORIGIN with the value INCOMPLETE, then the
5792 aggregated route must have the ORIGIN attribute with the value
5793 INCOMPLETE. Otherwise, if at least one route among routes that
5794 are aggregated has ORIGIN with the value EGP, then the aggregated
5795 route must have the origin attribute with the value EGP. In all
5796 other case the value of the ORIGIN attribute of the aggregated
5797 route is INTERNAL. */
5798 origin
= BGP_ORIGIN_IGP
;
5800 table
= bgp
->rib
[afi
][safi
];
5802 top
= bgp_node_get(table
, p
);
5803 for (rn
= bgp_node_get(table
, p
); rn
;
5804 rn
= bgp_route_next_until(rn
, top
)) {
5805 if (rn
->p
.prefixlen
<= p
->prefixlen
)
5810 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
) {
5811 if (BGP_PATH_HOLDDOWN(pi
))
5815 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5816 atomic_aggregate
= 1;
5818 if (pi
->sub_type
== BGP_ROUTE_AGGREGATE
)
5822 * summary-only aggregate route suppress
5823 * aggregated route announcements.
5825 if (aggregate
->summary_only
) {
5826 (bgp_path_info_extra_get(pi
))->suppress
++;
5827 bgp_path_info_set_flag(rn
, pi
,
5828 BGP_PATH_ATTR_CHANGED
);
5835 * If at least one route among routes that are
5836 * aggregated has ORIGIN with the value INCOMPLETE,
5837 * then the aggregated route MUST have the ORIGIN
5838 * attribute with the value INCOMPLETE. Otherwise, if
5839 * at least one route among routes that are aggregated
5840 * has ORIGIN with the value EGP, then the aggregated
5841 * route MUST have the ORIGIN attribute with the value
5844 switch (pi
->attr
->origin
) {
5845 case BGP_ORIGIN_INCOMPLETE
:
5846 aggregate
->incomplete_origin_count
++;
5848 case BGP_ORIGIN_EGP
:
5849 aggregate
->egp_origin_count
++;
5857 if (!aggregate
->as_set
)
5861 * as-set aggregate route generate origin, as path,
5862 * and community aggregation.
5864 /* Compute aggregate route's as-path.
5866 bgp_compute_aggregate_aspath(aggregate
,
5869 /* Compute aggregate route's community.
5871 if (pi
->attr
->community
)
5872 bgp_compute_aggregate_community(
5874 pi
->attr
->community
);
5876 /* Compute aggregate route's extended community.
5878 if (pi
->attr
->ecommunity
)
5879 bgp_compute_aggregate_ecommunity(
5881 pi
->attr
->ecommunity
);
5883 /* Compute aggregate route's large community.
5885 if (pi
->attr
->lcommunity
)
5886 bgp_compute_aggregate_lcommunity(
5888 pi
->attr
->lcommunity
);
5891 bgp_process(bgp
, rn
, afi
, safi
);
5893 bgp_unlock_node(top
);
5896 if (aggregate
->incomplete_origin_count
> 0)
5897 origin
= BGP_ORIGIN_INCOMPLETE
;
5898 else if (aggregate
->egp_origin_count
> 0)
5899 origin
= BGP_ORIGIN_EGP
;
5901 if (aggregate
->as_set
) {
5902 if (aggregate
->aspath
)
5903 /* Retrieve aggregate route's as-path.
5905 aspath
= aspath_dup(aggregate
->aspath
);
5907 if (aggregate
->community
)
5908 /* Retrieve aggregate route's community.
5910 community
= community_dup(aggregate
->community
);
5912 if (aggregate
->ecommunity
)
5913 /* Retrieve aggregate route's ecommunity.
5915 ecommunity
= ecommunity_dup(aggregate
->ecommunity
);
5917 if (aggregate
->lcommunity
)
5918 /* Retrieve aggregate route's lcommunity.
5920 lcommunity
= lcommunity_dup(aggregate
->lcommunity
);
5923 bgp_aggregate_install(bgp
, afi
, safi
, p
, origin
, aspath
, community
,
5924 ecommunity
, lcommunity
, atomic_aggregate
,
5928 static void bgp_aggregate_delete(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5929 safi_t safi
, struct bgp_aggregate
*aggregate
)
5931 struct bgp_table
*table
;
5932 struct bgp_node
*top
;
5933 struct bgp_node
*rn
;
5934 struct bgp_path_info
*pi
;
5935 unsigned long match
;
5937 table
= bgp
->rib
[afi
][safi
];
5939 /* If routes exists below this node, generate aggregate routes. */
5940 top
= bgp_node_get(table
, p
);
5941 for (rn
= bgp_node_get(table
, p
); rn
;
5942 rn
= bgp_route_next_until(rn
, top
)) {
5943 if (rn
->p
.prefixlen
<= p
->prefixlen
)
5947 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
) {
5948 if (BGP_PATH_HOLDDOWN(pi
))
5951 if (pi
->sub_type
== BGP_ROUTE_AGGREGATE
)
5954 if (aggregate
->summary_only
&& pi
->extra
) {
5955 pi
->extra
->suppress
--;
5957 if (pi
->extra
->suppress
== 0) {
5958 bgp_path_info_set_flag(
5959 rn
, pi
, BGP_PATH_ATTR_CHANGED
);
5965 if (pi
->attr
->origin
== BGP_ORIGIN_INCOMPLETE
)
5966 aggregate
->incomplete_origin_count
--;
5967 else if (pi
->attr
->origin
== BGP_ORIGIN_EGP
)
5968 aggregate
->egp_origin_count
--;
5970 if (aggregate
->as_set
) {
5971 /* Remove as-path from aggregate.
5973 bgp_remove_aspath_from_aggregate(
5977 if (pi
->attr
->community
)
5978 /* Remove community from aggregate.
5980 bgp_remove_community_from_aggregate(
5982 pi
->attr
->community
);
5984 if (pi
->attr
->ecommunity
)
5985 /* Remove ecommunity from aggregate.
5987 bgp_remove_ecommunity_from_aggregate(
5989 pi
->attr
->ecommunity
);
5991 if (pi
->attr
->lcommunity
)
5992 /* Remove lcommunity from aggregate.
5994 bgp_remove_lcommunity_from_aggregate(
5996 pi
->attr
->lcommunity
);
6001 /* If this node was suppressed, process the change. */
6003 bgp_process(bgp
, rn
, afi
, safi
);
6005 bgp_unlock_node(top
);
6008 static void bgp_add_route_to_aggregate(struct bgp
*bgp
, struct prefix
*aggr_p
,
6009 struct bgp_path_info
*pinew
, afi_t afi
,
6011 struct bgp_aggregate
*aggregate
)
6014 struct aspath
*aspath
= NULL
;
6015 uint8_t atomic_aggregate
= 0;
6016 struct community
*community
= NULL
;
6017 struct ecommunity
*ecommunity
= NULL
;
6018 struct lcommunity
*lcommunity
= NULL
;
6020 /* ORIGIN attribute: If at least one route among routes that are
6021 * aggregated has ORIGIN with the value INCOMPLETE, then the
6022 * aggregated route must have the ORIGIN attribute with the value
6023 * INCOMPLETE. Otherwise, if at least one route among routes that
6024 * are aggregated has ORIGIN with the value EGP, then the aggregated
6025 * route must have the origin attribute with the value EGP. In all
6026 * other case the value of the ORIGIN attribute of the aggregated
6027 * route is INTERNAL.
6029 origin
= BGP_ORIGIN_IGP
;
6033 if (aggregate
->summary_only
)
6034 (bgp_path_info_extra_get(pinew
))->suppress
++;
6036 switch (pinew
->attr
->origin
) {
6037 case BGP_ORIGIN_INCOMPLETE
:
6038 aggregate
->incomplete_origin_count
++;
6040 case BGP_ORIGIN_EGP
:
6041 aggregate
->egp_origin_count
++;
6049 if (aggregate
->incomplete_origin_count
> 0)
6050 origin
= BGP_ORIGIN_INCOMPLETE
;
6051 else if (aggregate
->egp_origin_count
> 0)
6052 origin
= BGP_ORIGIN_EGP
;
6054 if (aggregate
->as_set
) {
6055 /* Compute aggregate route's as-path.
6057 bgp_compute_aggregate_aspath(aggregate
,
6058 pinew
->attr
->aspath
);
6060 /* Compute aggregate route's community.
6062 if (pinew
->attr
->community
)
6063 bgp_compute_aggregate_community(
6065 pinew
->attr
->community
);
6067 /* Compute aggregate route's extended community.
6069 if (pinew
->attr
->ecommunity
)
6070 bgp_compute_aggregate_ecommunity(
6072 pinew
->attr
->ecommunity
);
6074 /* Compute aggregate route's large community.
6076 if (pinew
->attr
->lcommunity
)
6077 bgp_compute_aggregate_lcommunity(
6079 pinew
->attr
->lcommunity
);
6081 /* Retrieve aggregate route's as-path.
6083 if (aggregate
->aspath
)
6084 aspath
= aspath_dup(aggregate
->aspath
);
6086 /* Retrieve aggregate route's community.
6088 if (aggregate
->community
)
6089 community
= community_dup(aggregate
->community
);
6091 /* Retrieve aggregate route's ecommunity.
6093 if (aggregate
->ecommunity
)
6094 ecommunity
= ecommunity_dup(aggregate
->ecommunity
);
6096 /* Retrieve aggregate route's lcommunity.
6098 if (aggregate
->lcommunity
)
6099 lcommunity
= lcommunity_dup(aggregate
->lcommunity
);
6102 bgp_aggregate_install(bgp
, afi
, safi
, aggr_p
, origin
,
6103 aspath
, community
, ecommunity
,
6104 lcommunity
, atomic_aggregate
, aggregate
);
6107 static void bgp_remove_route_from_aggregate(struct bgp
*bgp
, afi_t afi
,
6109 struct bgp_path_info
*pi
,
6110 struct bgp_aggregate
*aggregate
,
6111 struct prefix
*aggr_p
)
6114 struct aspath
*aspath
= NULL
;
6115 uint8_t atomic_aggregate
= 0;
6116 struct community
*community
= NULL
;
6117 struct ecommunity
*ecommunity
= NULL
;
6118 struct lcommunity
*lcommunity
= NULL
;
6119 unsigned long match
= 0;
6121 if (BGP_PATH_HOLDDOWN(pi
))
6124 if (pi
->sub_type
== BGP_ROUTE_AGGREGATE
)
6127 if (aggregate
->summary_only
6129 && pi
->extra
->suppress
> 0) {
6130 pi
->extra
->suppress
--;
6132 if (pi
->extra
->suppress
== 0) {
6133 bgp_path_info_set_flag(pi
->net
, pi
,
6134 BGP_PATH_ATTR_CHANGED
);
6139 if (aggregate
->count
> 0)
6142 if (pi
->attr
->origin
== BGP_ORIGIN_INCOMPLETE
)
6143 aggregate
->incomplete_origin_count
--;
6144 else if (pi
->attr
->origin
== BGP_ORIGIN_EGP
)
6145 aggregate
->egp_origin_count
--;
6147 if (aggregate
->as_set
) {
6148 /* Remove as-path from aggregate.
6150 bgp_remove_aspath_from_aggregate(aggregate
,
6153 if (pi
->attr
->community
)
6154 /* Remove community from aggregate.
6156 bgp_remove_community_from_aggregate(
6158 pi
->attr
->community
);
6160 if (pi
->attr
->ecommunity
)
6161 /* Remove ecommunity from aggregate.
6163 bgp_remove_ecommunity_from_aggregate(
6165 pi
->attr
->ecommunity
);
6167 if (pi
->attr
->lcommunity
)
6168 /* Remove lcommunity from aggregate.
6170 bgp_remove_lcommunity_from_aggregate(
6172 pi
->attr
->lcommunity
);
6175 /* If this node was suppressed, process the change. */
6177 bgp_process(bgp
, pi
->net
, afi
, safi
);
6179 origin
= BGP_ORIGIN_IGP
;
6180 if (aggregate
->incomplete_origin_count
> 0)
6181 origin
= BGP_ORIGIN_INCOMPLETE
;
6182 else if (aggregate
->egp_origin_count
> 0)
6183 origin
= BGP_ORIGIN_EGP
;
6185 if (aggregate
->as_set
) {
6186 /* Retrieve aggregate route's as-path.
6188 if (aggregate
->aspath
)
6189 aspath
= aspath_dup(aggregate
->aspath
);
6191 /* Retrieve aggregate route's community.
6193 if (aggregate
->community
)
6194 community
= community_dup(aggregate
->community
);
6196 /* Retrieve aggregate route's ecommunity.
6198 if (aggregate
->ecommunity
)
6199 ecommunity
= ecommunity_dup(aggregate
->ecommunity
);
6201 /* Retrieve aggregate route's lcommunity.
6203 if (aggregate
->lcommunity
)
6204 lcommunity
= lcommunity_dup(aggregate
->lcommunity
);
6207 bgp_aggregate_install(bgp
, afi
, safi
, aggr_p
, origin
,
6208 aspath
, community
, ecommunity
,
6209 lcommunity
, atomic_aggregate
, aggregate
);
6212 void bgp_aggregate_increment(struct bgp
*bgp
, struct prefix
*p
,
6213 struct bgp_path_info
*pi
, afi_t afi
, safi_t safi
)
6215 struct bgp_node
*child
;
6216 struct bgp_node
*rn
;
6217 struct bgp_aggregate
*aggregate
;
6218 struct bgp_table
*table
;
6220 table
= bgp
->aggregate
[afi
][safi
];
6222 /* No aggregates configured. */
6223 if (bgp_table_top_nolock(table
) == NULL
)
6226 if (p
->prefixlen
== 0)
6229 if (BGP_PATH_HOLDDOWN(pi
))
6232 child
= bgp_node_get(table
, p
);
6234 /* Aggregate address configuration check. */
6235 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock(rn
)) {
6236 aggregate
= bgp_node_get_bgp_aggregate_info(rn
);
6237 if (aggregate
!= NULL
&& rn
->p
.prefixlen
< p
->prefixlen
) {
6238 bgp_add_route_to_aggregate(bgp
, &rn
->p
, pi
, afi
,
6242 bgp_unlock_node(child
);
6245 void bgp_aggregate_decrement(struct bgp
*bgp
, struct prefix
*p
,
6246 struct bgp_path_info
*del
, afi_t afi
, safi_t safi
)
6248 struct bgp_node
*child
;
6249 struct bgp_node
*rn
;
6250 struct bgp_aggregate
*aggregate
;
6251 struct bgp_table
*table
;
6253 table
= bgp
->aggregate
[afi
][safi
];
6255 /* No aggregates configured. */
6256 if (bgp_table_top_nolock(table
) == NULL
)
6259 if (p
->prefixlen
== 0)
6262 child
= bgp_node_get(table
, p
);
6264 /* Aggregate address configuration check. */
6265 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock(rn
)) {
6266 aggregate
= bgp_node_get_bgp_aggregate_info(rn
);
6267 if (aggregate
!= NULL
&& rn
->p
.prefixlen
< p
->prefixlen
) {
6268 bgp_remove_route_from_aggregate(bgp
, afi
, safi
,
6269 del
, aggregate
, &rn
->p
);
6272 bgp_unlock_node(child
);
6275 /* Aggregate route attribute. */
6276 #define AGGREGATE_SUMMARY_ONLY 1
6277 #define AGGREGATE_AS_SET 1
6279 static int bgp_aggregate_unset(struct vty
*vty
, const char *prefix_str
,
6280 afi_t afi
, safi_t safi
)
6282 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
6285 struct bgp_node
*rn
;
6286 struct bgp_aggregate
*aggregate
;
6288 /* Convert string to prefix structure. */
6289 ret
= str2prefix(prefix_str
, &p
);
6291 vty_out(vty
, "Malformed prefix\n");
6292 return CMD_WARNING_CONFIG_FAILED
;
6296 /* Old configuration check. */
6297 rn
= bgp_node_lookup(bgp
->aggregate
[afi
][safi
], &p
);
6300 "%% There is no aggregate-address configuration.\n");
6301 return CMD_WARNING_CONFIG_FAILED
;
6304 aggregate
= bgp_node_get_bgp_aggregate_info(rn
);
6305 bgp_aggregate_delete(bgp
, &p
, afi
, safi
, aggregate
);
6306 bgp_aggregate_install(bgp
, afi
, safi
, &p
, 0, NULL
, NULL
,
6307 NULL
, NULL
, 0, aggregate
);
6309 /* Unlock aggregate address configuration. */
6310 bgp_node_set_bgp_aggregate_info(rn
, NULL
);
6312 if (aggregate
->community
)
6313 community_free(&aggregate
->community
);
6315 if (aggregate
->community_hash
) {
6316 /* Delete all communities in the hash.
6318 hash_clean(aggregate
->community_hash
,
6319 bgp_aggr_community_remove
);
6320 /* Free up the community_hash.
6322 hash_free(aggregate
->community_hash
);
6325 if (aggregate
->ecommunity
)
6326 ecommunity_free(&aggregate
->ecommunity
);
6328 if (aggregate
->ecommunity_hash
) {
6329 /* Delete all ecommunities in the hash.
6331 hash_clean(aggregate
->ecommunity_hash
,
6332 bgp_aggr_ecommunity_remove
);
6333 /* Free up the ecommunity_hash.
6335 hash_free(aggregate
->ecommunity_hash
);
6338 if (aggregate
->lcommunity
)
6339 lcommunity_free(&aggregate
->lcommunity
);
6341 if (aggregate
->lcommunity_hash
) {
6342 /* Delete all lcommunities in the hash.
6344 hash_clean(aggregate
->lcommunity_hash
,
6345 bgp_aggr_lcommunity_remove
);
6346 /* Free up the lcommunity_hash.
6348 hash_free(aggregate
->lcommunity_hash
);
6351 if (aggregate
->aspath
)
6352 aspath_free(aggregate
->aspath
);
6354 if (aggregate
->aspath_hash
) {
6355 /* Delete all as-paths in the hash.
6357 hash_clean(aggregate
->aspath_hash
,
6358 bgp_aggr_aspath_remove
);
6359 /* Free up the aspath_hash.
6361 hash_free(aggregate
->aspath_hash
);
6364 bgp_aggregate_free(aggregate
);
6365 bgp_unlock_node(rn
);
6366 bgp_unlock_node(rn
);
6371 static int bgp_aggregate_set(struct vty
*vty
, const char *prefix_str
, afi_t afi
,
6372 safi_t safi
, uint8_t summary_only
, uint8_t as_set
)
6374 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
6377 struct bgp_node
*rn
;
6378 struct bgp_aggregate
*aggregate
;
6380 /* Convert string to prefix structure. */
6381 ret
= str2prefix(prefix_str
, &p
);
6383 vty_out(vty
, "Malformed prefix\n");
6384 return CMD_WARNING_CONFIG_FAILED
;
6388 if ((afi
== AFI_IP
&& p
.prefixlen
== IPV4_MAX_BITLEN
) ||
6389 (afi
== AFI_IP6
&& p
.prefixlen
== IPV6_MAX_BITLEN
)) {
6390 vty_out(vty
, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
6392 return CMD_WARNING_CONFIG_FAILED
;
6395 /* Old configuration check. */
6396 rn
= bgp_node_get(bgp
->aggregate
[afi
][safi
], &p
);
6398 if (bgp_node_has_bgp_path_info_data(rn
)) {
6399 vty_out(vty
, "There is already same aggregate network.\n");
6400 /* try to remove the old entry */
6401 ret
= bgp_aggregate_unset(vty
, prefix_str
, afi
, safi
);
6403 vty_out(vty
, "Error deleting aggregate.\n");
6404 bgp_unlock_node(rn
);
6405 return CMD_WARNING_CONFIG_FAILED
;
6409 /* Make aggregate address structure. */
6410 aggregate
= bgp_aggregate_new();
6411 aggregate
->summary_only
= summary_only
;
6412 aggregate
->as_set
= as_set
;
6413 aggregate
->safi
= safi
;
6414 bgp_node_set_bgp_aggregate_info(rn
, aggregate
);
6416 /* Aggregate address insert into BGP routing table. */
6417 bgp_aggregate_route(bgp
, &p
, afi
, safi
, aggregate
);
6422 DEFUN (aggregate_address
,
6423 aggregate_address_cmd
,
6424 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
6425 "Configure BGP aggregate entries\n"
6426 "Aggregate prefix\n"
6427 "Generate AS set path information\n"
6428 "Filter more specific routes from updates\n"
6429 "Filter more specific routes from updates\n"
6430 "Generate AS set path information\n")
6433 argv_find(argv
, argc
, "A.B.C.D/M", &idx
);
6434 char *prefix
= argv
[idx
]->arg
;
6436 argv_find(argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
6438 int summary_only
= argv_find(argv
, argc
, "summary-only", &idx
)
6439 ? AGGREGATE_SUMMARY_ONLY
6442 return bgp_aggregate_set(vty
, prefix
, AFI_IP
, bgp_node_safi(vty
),
6443 summary_only
, as_set
);
6446 DEFUN (aggregate_address_mask
,
6447 aggregate_address_mask_cmd
,
6448 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
6449 "Configure BGP aggregate entries\n"
6450 "Aggregate address\n"
6452 "Generate AS set path information\n"
6453 "Filter more specific routes from updates\n"
6454 "Filter more specific routes from updates\n"
6455 "Generate AS set path information\n")
6458 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6459 char *prefix
= argv
[idx
]->arg
;
6460 char *mask
= argv
[idx
+ 1]->arg
;
6462 argv_find(argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
6464 int summary_only
= argv_find(argv
, argc
, "summary-only", &idx
)
6465 ? AGGREGATE_SUMMARY_ONLY
6468 char prefix_str
[BUFSIZ
];
6469 int ret
= netmask_str2prefix_str(prefix
, mask
, prefix_str
);
6472 vty_out(vty
, "%% Inconsistent address and mask\n");
6473 return CMD_WARNING_CONFIG_FAILED
;
6476 return bgp_aggregate_set(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
),
6477 summary_only
, as_set
);
6480 DEFUN (no_aggregate_address
,
6481 no_aggregate_address_cmd
,
6482 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
6484 "Configure BGP aggregate entries\n"
6485 "Aggregate prefix\n"
6486 "Generate AS set path information\n"
6487 "Filter more specific routes from updates\n"
6488 "Filter more specific routes from updates\n"
6489 "Generate AS set path information\n")
6492 argv_find(argv
, argc
, "A.B.C.D/M", &idx
);
6493 char *prefix
= argv
[idx
]->arg
;
6494 return bgp_aggregate_unset(vty
, prefix
, AFI_IP
, bgp_node_safi(vty
));
6497 DEFUN (no_aggregate_address_mask
,
6498 no_aggregate_address_mask_cmd
,
6499 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
6501 "Configure BGP aggregate entries\n"
6502 "Aggregate address\n"
6504 "Generate AS set path information\n"
6505 "Filter more specific routes from updates\n"
6506 "Filter more specific routes from updates\n"
6507 "Generate AS set path information\n")
6510 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6511 char *prefix
= argv
[idx
]->arg
;
6512 char *mask
= argv
[idx
+ 1]->arg
;
6514 char prefix_str
[BUFSIZ
];
6515 int ret
= netmask_str2prefix_str(prefix
, mask
, prefix_str
);
6518 vty_out(vty
, "%% Inconsistent address and mask\n");
6519 return CMD_WARNING_CONFIG_FAILED
;
6522 return bgp_aggregate_unset(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
));
6525 DEFUN (ipv6_aggregate_address
,
6526 ipv6_aggregate_address_cmd
,
6527 "aggregate-address X:X::X:X/M [summary-only]",
6528 "Configure BGP aggregate entries\n"
6529 "Aggregate prefix\n"
6530 "Filter more specific routes from updates\n")
6533 argv_find(argv
, argc
, "X:X::X:X/M", &idx
);
6534 char *prefix
= argv
[idx
]->arg
;
6535 int sum_only
= argv_find(argv
, argc
, "summary-only", &idx
)
6536 ? AGGREGATE_SUMMARY_ONLY
6538 return bgp_aggregate_set(vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
,
6542 DEFUN (no_ipv6_aggregate_address
,
6543 no_ipv6_aggregate_address_cmd
,
6544 "no aggregate-address X:X::X:X/M [summary-only]",
6546 "Configure BGP aggregate entries\n"
6547 "Aggregate prefix\n"
6548 "Filter more specific routes from updates\n")
6551 argv_find(argv
, argc
, "X:X::X:X/M", &idx
);
6552 char *prefix
= argv
[idx
]->arg
;
6553 return bgp_aggregate_unset(vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
6556 /* Redistribute route treatment. */
6557 void bgp_redistribute_add(struct bgp
*bgp
, struct prefix
*p
,
6558 const union g_addr
*nexthop
, ifindex_t ifindex
,
6559 enum nexthop_types_t nhtype
, uint32_t metric
,
6560 uint8_t type
, unsigned short instance
,
6563 struct bgp_path_info
*new;
6564 struct bgp_path_info
*bpi
;
6565 struct bgp_path_info rmap_path
;
6566 struct bgp_node
*bn
;
6568 struct attr
*new_attr
;
6571 struct bgp_redist
*red
;
6573 /* Make default attribute. */
6574 bgp_attr_default_set(&attr
, BGP_ORIGIN_INCOMPLETE
);
6577 case NEXTHOP_TYPE_IFINDEX
:
6579 case NEXTHOP_TYPE_IPV4
:
6580 case NEXTHOP_TYPE_IPV4_IFINDEX
:
6581 attr
.nexthop
= nexthop
->ipv4
;
6583 case NEXTHOP_TYPE_IPV6
:
6584 case NEXTHOP_TYPE_IPV6_IFINDEX
:
6585 attr
.mp_nexthop_global
= nexthop
->ipv6
;
6586 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
6588 case NEXTHOP_TYPE_BLACKHOLE
:
6589 switch (p
->family
) {
6591 attr
.nexthop
.s_addr
= INADDR_ANY
;
6594 memset(&attr
.mp_nexthop_global
, 0,
6595 sizeof(attr
.mp_nexthop_global
));
6596 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
6601 attr
.nh_ifindex
= ifindex
;
6604 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
6607 afi
= family2afi(p
->family
);
6609 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6611 struct attr attr_new
;
6613 /* Copy attribute for modification. */
6614 bgp_attr_dup(&attr_new
, &attr
);
6616 if (red
->redist_metric_flag
)
6617 attr_new
.med
= red
->redist_metric
;
6619 /* Apply route-map. */
6620 if (red
->rmap
.name
) {
6621 memset(&rmap_path
, 0, sizeof(struct bgp_path_info
));
6622 rmap_path
.peer
= bgp
->peer_self
;
6623 rmap_path
.attr
= &attr_new
;
6625 SET_FLAG(bgp
->peer_self
->rmap_type
,
6626 PEER_RMAP_TYPE_REDISTRIBUTE
);
6628 ret
= route_map_apply(red
->rmap
.map
, p
, RMAP_BGP
,
6631 bgp
->peer_self
->rmap_type
= 0;
6633 if (ret
== RMAP_DENYMATCH
) {
6634 /* Free uninterned attribute. */
6635 bgp_attr_flush(&attr_new
);
6637 /* Unintern original. */
6638 aspath_unintern(&attr
.aspath
);
6639 bgp_redistribute_delete(bgp
, p
, type
, instance
);
6644 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
6645 bgp_attr_add_gshut_community(&attr_new
);
6647 bn
= bgp_afi_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], afi
,
6648 SAFI_UNICAST
, p
, NULL
);
6650 new_attr
= bgp_attr_intern(&attr_new
);
6652 for (bpi
= bgp_node_get_bgp_path_info(bn
); bpi
;
6654 if (bpi
->peer
== bgp
->peer_self
6655 && bpi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
6659 /* Ensure the (source route) type is updated. */
6661 if (attrhash_cmp(bpi
->attr
, new_attr
)
6662 && !CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
6663 bgp_attr_unintern(&new_attr
);
6664 aspath_unintern(&attr
.aspath
);
6665 bgp_unlock_node(bn
);
6668 /* The attribute is changed. */
6669 bgp_path_info_set_flag(bn
, bpi
,
6670 BGP_PATH_ATTR_CHANGED
);
6672 /* Rewrite BGP route information. */
6673 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
6674 bgp_path_info_restore(bn
, bpi
);
6676 bgp_aggregate_decrement(
6677 bgp
, p
, bpi
, afi
, SAFI_UNICAST
);
6678 bgp_attr_unintern(&bpi
->attr
);
6679 bpi
->attr
= new_attr
;
6680 bpi
->uptime
= bgp_clock();
6682 /* Process change. */
6683 bgp_aggregate_increment(bgp
, p
, bpi
, afi
,
6685 bgp_process(bgp
, bn
, afi
, SAFI_UNICAST
);
6686 bgp_unlock_node(bn
);
6687 aspath_unintern(&attr
.aspath
);
6689 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6691 == BGP_INSTANCE_TYPE_DEFAULT
)) {
6693 vpn_leak_from_vrf_update(
6694 bgp_get_default(), bgp
, bpi
);
6700 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
,
6701 bgp
->peer_self
, new_attr
, bn
);
6702 SET_FLAG(new->flags
, BGP_PATH_VALID
);
6704 bgp_aggregate_increment(bgp
, p
, new, afi
, SAFI_UNICAST
);
6705 bgp_path_info_add(bn
, new);
6706 bgp_unlock_node(bn
);
6707 bgp_process(bgp
, bn
, afi
, SAFI_UNICAST
);
6709 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6710 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6712 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
6716 /* Unintern original. */
6717 aspath_unintern(&attr
.aspath
);
6720 void bgp_redistribute_delete(struct bgp
*bgp
, struct prefix
*p
, uint8_t type
,
6721 unsigned short instance
)
6724 struct bgp_node
*rn
;
6725 struct bgp_path_info
*pi
;
6726 struct bgp_redist
*red
;
6728 afi
= family2afi(p
->family
);
6730 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6732 rn
= bgp_afi_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], afi
,
6733 SAFI_UNICAST
, p
, NULL
);
6735 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
6736 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== type
)
6740 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6741 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6743 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6746 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, SAFI_UNICAST
);
6747 bgp_path_info_delete(rn
, pi
);
6748 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
6750 bgp_unlock_node(rn
);
6754 /* Withdraw specified route type's route. */
6755 void bgp_redistribute_withdraw(struct bgp
*bgp
, afi_t afi
, int type
,
6756 unsigned short instance
)
6758 struct bgp_node
*rn
;
6759 struct bgp_path_info
*pi
;
6760 struct bgp_table
*table
;
6762 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
6764 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
6765 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
)
6766 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== type
6767 && pi
->instance
== instance
)
6771 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6772 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6774 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6777 bgp_aggregate_decrement(bgp
, &rn
->p
, pi
, afi
,
6779 bgp_path_info_delete(rn
, pi
);
6780 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
6785 /* Static function to display route. */
6786 static void route_vty_out_route(struct prefix
*p
, struct vty
*vty
,
6793 if (p
->family
== AF_INET
) {
6797 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6800 json_object_string_add(json
, "prefix",
6801 inet_ntop(p
->family
,
6804 json_object_int_add(json
, "prefixLen", p
->prefixlen
);
6805 prefix2str(p
, buf2
, PREFIX_STRLEN
);
6806 json_object_string_add(json
, "network", buf2
);
6808 } else if (p
->family
== AF_ETHERNET
) {
6809 prefix2str(p
, buf
, PREFIX_STRLEN
);
6810 len
= vty_out(vty
, "%s", buf
);
6811 } else if (p
->family
== AF_EVPN
) {
6815 bgp_evpn_route2str((struct prefix_evpn
*)p
, buf
,
6818 bgp_evpn_route2json((struct prefix_evpn
*)p
, json
);
6819 } else if (p
->family
== AF_FLOWSPEC
) {
6820 route_vty_out_flowspec(vty
, p
, NULL
,
6822 NLRI_STRING_FORMAT_JSON_SIMPLE
:
6823 NLRI_STRING_FORMAT_MIN
, json
);
6828 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6831 json_object_string_add(json
, "prefix",
6832 inet_ntop(p
->family
,
6835 json_object_int_add(json
, "prefixLen", p
->prefixlen
);
6836 prefix2str(p
, buf2
, PREFIX_STRLEN
);
6837 json_object_string_add(json
, "network", buf2
);
6844 vty_out(vty
, "\n%*s", 20, " ");
6846 vty_out(vty
, "%*s", len
, " ");
6850 enum bgp_display_type
{
6854 /* Print the short form route status for a bgp_path_info */
6855 static void route_vty_short_status_out(struct vty
*vty
,
6856 struct bgp_path_info
*path
,
6857 json_object
*json_path
)
6861 /* Route status display. */
6862 if (CHECK_FLAG(path
->flags
, BGP_PATH_REMOVED
))
6863 json_object_boolean_true_add(json_path
, "removed");
6865 if (CHECK_FLAG(path
->flags
, BGP_PATH_STALE
))
6866 json_object_boolean_true_add(json_path
, "stale");
6868 if (path
->extra
&& path
->extra
->suppress
)
6869 json_object_boolean_true_add(json_path
, "suppressed");
6871 if (CHECK_FLAG(path
->flags
, BGP_PATH_VALID
)
6872 && !CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
))
6873 json_object_boolean_true_add(json_path
, "valid");
6876 if (CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
))
6877 json_object_boolean_true_add(json_path
, "history");
6879 if (CHECK_FLAG(path
->flags
, BGP_PATH_DAMPED
))
6880 json_object_boolean_true_add(json_path
, "damped");
6882 if (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
))
6883 json_object_boolean_true_add(json_path
, "bestpath");
6885 if (CHECK_FLAG(path
->flags
, BGP_PATH_MULTIPATH
))
6886 json_object_boolean_true_add(json_path
, "multipath");
6888 /* Internal route. */
6889 if ((path
->peer
->as
)
6890 && (path
->peer
->as
== path
->peer
->local_as
))
6891 json_object_string_add(json_path
, "pathFrom",
6894 json_object_string_add(json_path
, "pathFrom",
6900 /* Route status display. */
6901 if (CHECK_FLAG(path
->flags
, BGP_PATH_REMOVED
))
6903 else if (CHECK_FLAG(path
->flags
, BGP_PATH_STALE
))
6905 else if (path
->extra
&& path
->extra
->suppress
)
6907 else if (CHECK_FLAG(path
->flags
, BGP_PATH_VALID
)
6908 && !CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
))
6914 if (CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
))
6916 else if (CHECK_FLAG(path
->flags
, BGP_PATH_DAMPED
))
6918 else if (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
))
6920 else if (CHECK_FLAG(path
->flags
, BGP_PATH_MULTIPATH
))
6925 /* Internal route. */
6926 if (path
->peer
&& (path
->peer
->as
)
6927 && (path
->peer
->as
== path
->peer
->local_as
))
6933 static char *bgp_nexthop_fqdn(struct peer
*peer
)
6935 if (peer
->hostname
&& bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
))
6936 return peer
->hostname
;
6940 /* called from terminal list command */
6941 void route_vty_out(struct vty
*vty
, struct prefix
*p
,
6942 struct bgp_path_info
*path
, int display
, safi_t safi
,
6943 json_object
*json_paths
)
6946 json_object
*json_path
= NULL
;
6947 json_object
*json_nexthops
= NULL
;
6948 json_object
*json_nexthop_global
= NULL
;
6949 json_object
*json_nexthop_ll
= NULL
;
6950 char vrf_id_str
[VRF_NAMSIZ
] = {0};
6952 CHECK_FLAG(path
->flags
, BGP_PATH_ANNC_NH_SELF
) ? true : false;
6953 bool nexthop_othervrf
= false;
6954 vrf_id_t nexthop_vrfid
= VRF_DEFAULT
;
6955 const char *nexthop_vrfname
= VRF_DEFAULT_NAME
;
6956 char *nexthop_fqdn
= bgp_nexthop_fqdn(path
->peer
);
6959 json_path
= json_object_new_object();
6961 /* short status lead text */
6962 route_vty_short_status_out(vty
, path
, json_path
);
6965 /* print prefix and mask */
6967 route_vty_out_route(p
, vty
, json_path
);
6969 vty_out(vty
, "%*s", 17, " ");
6971 route_vty_out_route(p
, vty
, json_path
);
6974 /* Print attribute */
6978 json_object_array_add(json_paths
, json_path
);
6986 * If vrf id of nexthop is different from that of prefix,
6987 * set up printable string to append
6989 if (path
->extra
&& path
->extra
->bgp_orig
) {
6990 const char *self
= "";
6995 nexthop_othervrf
= true;
6996 nexthop_vrfid
= path
->extra
->bgp_orig
->vrf_id
;
6998 if (path
->extra
->bgp_orig
->vrf_id
== VRF_UNKNOWN
)
6999 snprintf(vrf_id_str
, sizeof(vrf_id_str
),
7000 "@%s%s", VRFID_NONE_STR
, self
);
7002 snprintf(vrf_id_str
, sizeof(vrf_id_str
), "@%u%s",
7003 path
->extra
->bgp_orig
->vrf_id
, self
);
7005 if (path
->extra
->bgp_orig
->inst_type
7006 != BGP_INSTANCE_TYPE_DEFAULT
)
7008 nexthop_vrfname
= path
->extra
->bgp_orig
->name
;
7010 const char *self
= "";
7015 snprintf(vrf_id_str
, sizeof(vrf_id_str
), "%s", self
);
7019 * For ENCAP and EVPN routes, nexthop address family is not
7020 * neccessarily the same as the prefix address family.
7021 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
7022 * EVPN routes are also exchanged with a MP nexthop. Currently,
7024 * is only IPv4, the value will be present in either
7026 * attr->mp_nexthop_global_in
7028 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
)) {
7031 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
7035 sprintf(nexthop
, "%s",
7036 inet_ntop(af
, &attr
->mp_nexthop_global_in
, buf
,
7040 sprintf(nexthop
, "%s",
7041 inet_ntop(af
, &attr
->mp_nexthop_global
, buf
,
7045 sprintf(nexthop
, "?");
7050 json_nexthop_global
= json_object_new_object();
7052 json_object_string_add(
7053 json_nexthop_global
, "afi",
7054 nexthop_fqdn
? "fqdn"
7055 : (af
== AF_INET
) ? "ip" : "ipv6");
7056 json_object_string_add(
7057 json_nexthop_global
,
7058 nexthop_fqdn
? "fqdn"
7059 : (af
== AF_INET
) ? "ip" : "ipv6",
7060 nexthop_fqdn
? nexthop_fqdn
: nexthop
);
7061 json_object_boolean_true_add(json_nexthop_global
,
7064 vty_out(vty
, "%s%s",
7065 nexthop_fqdn
? nexthop_fqdn
: nexthop
,
7067 } else if (safi
== SAFI_EVPN
) {
7069 json_nexthop_global
= json_object_new_object();
7071 json_object_string_add(
7072 json_nexthop_global
,
7073 nexthop_fqdn
? "fqdn" : "ip",
7074 nexthop_fqdn
? nexthop_fqdn
7075 : inet_ntoa(attr
->nexthop
));
7076 json_object_string_add(json_nexthop_global
, "afi",
7078 json_object_boolean_true_add(json_nexthop_global
,
7081 vty_out(vty
, "%-16s%s",
7082 nexthop_fqdn
?: inet_ntoa(attr
->nexthop
),
7084 } else if (safi
== SAFI_FLOWSPEC
) {
7085 if (attr
->nexthop
.s_addr
!= 0) {
7087 json_nexthop_global
= json_object_new_object();
7088 json_object_string_add(
7089 json_nexthop_global
,
7090 nexthop_fqdn
? "fqdn" : "ip",
7093 : inet_ntoa(attr
->nexthop
));
7094 json_object_string_add(json_nexthop_global
,
7096 json_object_boolean_true_add(
7097 json_nexthop_global
,
7100 vty_out(vty
, "%-16s",
7103 : inet_ntoa(attr
->nexthop
));
7106 } else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
7108 json_nexthop_global
= json_object_new_object();
7110 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
7111 json_object_string_add(
7112 json_nexthop_global
,
7113 nexthop_fqdn
? "fqdn" : "ip",
7117 attr
->mp_nexthop_global_in
));
7119 json_object_string_add(
7120 json_nexthop_global
,
7121 nexthop_fqdn
? "fqdn" : "ip",
7124 : inet_ntoa(attr
->nexthop
));
7126 json_object_string_add(json_nexthop_global
, "afi",
7128 json_object_boolean_true_add(json_nexthop_global
,
7133 snprintf(buf
, sizeof(buf
), "%s%s",
7134 nexthop_fqdn
? nexthop_fqdn
7135 : inet_ntoa(attr
->nexthop
),
7137 vty_out(vty
, "%-16s", buf
);
7142 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
7147 json_nexthop_global
= json_object_new_object();
7148 json_object_string_add(
7149 json_nexthop_global
,
7150 nexthop_fqdn
? "fqdn" : "ip",
7153 : inet_ntop(AF_INET6
,
7154 &attr
->mp_nexthop_global
,
7156 json_object_string_add(json_nexthop_global
, "afi",
7158 json_object_string_add(json_nexthop_global
, "scope",
7161 /* We display both LL & GL if both have been
7163 if ((attr
->mp_nexthop_len
== 32)
7164 || (path
->peer
->conf_if
)) {
7165 json_nexthop_ll
= json_object_new_object();
7166 json_object_string_add(
7168 nexthop_fqdn
? "fqdn" : "ip",
7173 &attr
->mp_nexthop_local
,
7175 json_object_string_add(json_nexthop_ll
, "afi",
7177 json_object_string_add(json_nexthop_ll
, "scope",
7180 if ((IPV6_ADDR_CMP(&attr
->mp_nexthop_global
,
7181 &attr
->mp_nexthop_local
)
7183 && !attr
->mp_nexthop_prefer_global
)
7184 json_object_boolean_true_add(
7185 json_nexthop_ll
, "used");
7187 json_object_boolean_true_add(
7188 json_nexthop_global
, "used");
7190 json_object_boolean_true_add(
7191 json_nexthop_global
, "used");
7193 /* Display LL if LL/Global both in table unless
7194 * prefer-global is set */
7195 if (((attr
->mp_nexthop_len
== 32)
7196 && !attr
->mp_nexthop_prefer_global
)
7197 || (path
->peer
->conf_if
)) {
7198 if (path
->peer
->conf_if
) {
7199 len
= vty_out(vty
, "%s",
7200 path
->peer
->conf_if
);
7201 len
= 16 - len
; /* len of IPv6
7207 vty_out(vty
, "\n%*s", 36, " ");
7209 vty_out(vty
, "%*s", len
, " ");
7217 &attr
->mp_nexthop_local
,
7223 vty_out(vty
, "\n%*s", 36, " ");
7225 vty_out(vty
, "%*s", len
, " ");
7234 &attr
->mp_nexthop_global
,
7240 vty_out(vty
, "\n%*s", 36, " ");
7242 vty_out(vty
, "%*s", len
, " ");
7248 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
7252 * Adding "metric" field to match with corresponding
7253 * CLI. "med" will be deprecated in future.
7255 json_object_int_add(json_path
, "med", attr
->med
);
7256 json_object_int_add(json_path
, "metric", attr
->med
);
7258 vty_out(vty
, "%10u", attr
->med
);
7259 else if (!json_paths
)
7263 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
7267 * Adding "locPrf" field to match with corresponding
7268 * CLI. "localPref" will be deprecated in future.
7270 json_object_int_add(json_path
, "localpref",
7272 json_object_int_add(json_path
, "locPrf",
7275 vty_out(vty
, "%7u", attr
->local_pref
);
7276 else if (!json_paths
)
7280 json_object_int_add(json_path
, "weight", attr
->weight
);
7282 vty_out(vty
, "%7u ", attr
->weight
);
7286 json_object_string_add(
7287 json_path
, "peerId",
7288 sockunion2str(&path
->peer
->su
, buf
, SU_ADDRSTRLEN
));
7296 * Adding "path" field to match with corresponding
7297 * CLI. "aspath" will be deprecated in future.
7299 json_object_string_add(json_path
, "aspath",
7301 json_object_string_add(json_path
, "path",
7304 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7309 json_object_string_add(json_path
, "origin",
7310 bgp_origin_long_str
[attr
->origin
]);
7312 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7316 json_object_boolean_true_add(json_path
,
7317 "announceNexthopSelf");
7318 if (nexthop_othervrf
) {
7319 json_object_string_add(json_path
, "nhVrfName",
7322 json_object_int_add(json_path
, "nhVrfId",
7323 ((nexthop_vrfid
== VRF_UNKNOWN
)
7325 : (int)nexthop_vrfid
));
7330 if (json_nexthop_global
|| json_nexthop_ll
) {
7331 json_nexthops
= json_object_new_array();
7333 if (json_nexthop_global
)
7334 json_object_array_add(json_nexthops
,
7335 json_nexthop_global
);
7337 if (json_nexthop_ll
)
7338 json_object_array_add(json_nexthops
,
7341 json_object_object_add(json_path
, "nexthops",
7345 json_object_array_add(json_paths
, json_path
);
7349 /* prints an additional line, indented, with VNC info, if
7351 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
7352 rfapi_vty_out_vncinfo(vty
, p
, path
, safi
);
7357 /* called from terminal list command */
7358 void route_vty_out_tmp(struct vty
*vty
, struct prefix
*p
, struct attr
*attr
,
7359 safi_t safi
, bool use_json
, json_object
*json_ar
)
7361 json_object
*json_status
= NULL
;
7362 json_object
*json_net
= NULL
;
7365 /* Route status display. */
7367 json_status
= json_object_new_object();
7368 json_net
= json_object_new_object();
7375 /* print prefix and mask */
7377 json_object_string_add(
7378 json_net
, "addrPrefix",
7379 inet_ntop(p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
7380 json_object_int_add(json_net
, "prefixLen", p
->prefixlen
);
7381 prefix2str(p
, buf2
, PREFIX_STRLEN
);
7382 json_object_string_add(json_net
, "network", buf2
);
7384 route_vty_out_route(p
, vty
, NULL
);
7386 /* Print attribute */
7389 if (p
->family
== AF_INET
7390 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7391 || safi
== SAFI_EVPN
7392 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7393 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7394 || safi
== SAFI_EVPN
)
7395 json_object_string_add(
7396 json_net
, "nextHop",
7398 attr
->mp_nexthop_global_in
));
7400 json_object_string_add(
7401 json_net
, "nextHop",
7402 inet_ntoa(attr
->nexthop
));
7403 } else if (p
->family
== AF_INET6
7404 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
7407 json_object_string_add(
7408 json_net
, "nextHopGlobal",
7410 &attr
->mp_nexthop_global
, buf
,
7415 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
7416 json_object_int_add(json_net
, "metric",
7419 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
7422 * Adding "locPrf" field to match with
7423 * corresponding CLI. "localPref" will be
7424 * deprecated in future.
7426 json_object_int_add(json_net
, "localPref",
7428 json_object_int_add(json_net
, "locPrf",
7432 json_object_int_add(json_net
, "weight", attr
->weight
);
7438 * Adding "path" field to match with
7439 * corresponding CLI. "localPref" will be
7440 * deprecated in future.
7442 json_object_string_add(json_net
, "asPath",
7444 json_object_string_add(json_net
, "path",
7449 json_object_string_add(json_net
, "bgpOriginCode",
7450 bgp_origin_str
[attr
->origin
]);
7452 if (p
->family
== AF_INET
7453 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7454 || safi
== SAFI_EVPN
7455 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7456 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7457 || safi
== SAFI_EVPN
)
7458 vty_out(vty
, "%-16s",
7460 attr
->mp_nexthop_global_in
));
7462 vty_out(vty
, "%-16s",
7463 inet_ntoa(attr
->nexthop
));
7464 } else if (p
->family
== AF_INET6
7465 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
7472 &attr
->mp_nexthop_global
, buf
,
7476 vty_out(vty
, "\n%*s", 36, " ");
7478 vty_out(vty
, "%*s", len
, " ");
7481 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
7482 vty_out(vty
, "%10u", attr
->med
);
7486 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
7487 vty_out(vty
, "%7u", attr
->local_pref
);
7491 vty_out(vty
, "%7u ", attr
->weight
);
7495 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7498 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7502 json_object_boolean_true_add(json_status
, "*");
7503 json_object_boolean_true_add(json_status
, ">");
7504 json_object_object_add(json_net
, "appliedStatusSymbols",
7506 char buf_cut
[BUFSIZ
];
7507 json_object_object_add(
7509 inet_ntop(p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
),
7515 void route_vty_out_tag(struct vty
*vty
, struct prefix
*p
,
7516 struct bgp_path_info
*path
, int display
, safi_t safi
,
7519 json_object
*json_out
= NULL
;
7521 mpls_label_t label
= MPLS_INVALID_LABEL
;
7527 json_out
= json_object_new_object();
7529 /* short status lead text */
7530 route_vty_short_status_out(vty
, path
, json_out
);
7532 /* print prefix and mask */
7535 route_vty_out_route(p
, vty
, NULL
);
7537 vty_out(vty
, "%*s", 17, " ");
7540 /* Print attribute */
7543 if (((p
->family
== AF_INET
)
7544 && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
7545 || (safi
== SAFI_EVPN
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
7546 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7547 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7548 || safi
== SAFI_EVPN
) {
7550 json_object_string_add(
7551 json_out
, "mpNexthopGlobalIn",
7553 attr
->mp_nexthop_global_in
));
7555 vty_out(vty
, "%-16s",
7557 attr
->mp_nexthop_global_in
));
7560 json_object_string_add(
7561 json_out
, "nexthop",
7562 inet_ntoa(attr
->nexthop
));
7564 vty_out(vty
, "%-16s",
7565 inet_ntoa(attr
->nexthop
));
7567 } else if (((p
->family
== AF_INET6
)
7568 && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
7569 || (safi
== SAFI_EVPN
7570 && BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
7571 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7575 if (attr
->mp_nexthop_len
7576 == BGP_ATTR_NHLEN_IPV6_GLOBAL
) {
7578 json_object_string_add(
7579 json_out
, "mpNexthopGlobalIn",
7582 &attr
->mp_nexthop_global
,
7583 buf_a
, sizeof(buf_a
)));
7588 &attr
->mp_nexthop_global
,
7589 buf_a
, sizeof(buf_a
)));
7590 } else if (attr
->mp_nexthop_len
7591 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) {
7594 &attr
->mp_nexthop_global
,
7595 buf_a
, sizeof(buf_a
));
7597 &attr
->mp_nexthop_local
,
7598 buf_b
, sizeof(buf_b
));
7599 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
7600 json_object_string_add(
7602 "mpNexthopGlobalLocal", buf_c
);
7604 vty_out(vty
, "%s(%s)",
7607 &attr
->mp_nexthop_global
,
7608 buf_a
, sizeof(buf_a
)),
7611 &attr
->mp_nexthop_local
,
7612 buf_b
, sizeof(buf_b
)));
7617 label
= decode_label(&path
->extra
->label
[0]);
7619 if (bgp_is_valid_label(&label
)) {
7621 json_object_int_add(json_out
, "notag", label
);
7622 json_object_array_add(json
, json_out
);
7624 vty_out(vty
, "notag/%d", label
);
7630 void route_vty_out_overlay(struct vty
*vty
, struct prefix
*p
,
7631 struct bgp_path_info
*path
, int display
,
7632 json_object
*json_paths
)
7635 char buf
[BUFSIZ
] = {0};
7636 json_object
*json_path
= NULL
;
7637 json_object
*json_nexthop
= NULL
;
7638 json_object
*json_overlay
= NULL
;
7644 json_path
= json_object_new_object();
7645 json_overlay
= json_object_new_object();
7646 json_nexthop
= json_object_new_object();
7649 /* short status lead text */
7650 route_vty_short_status_out(vty
, path
, json_path
);
7652 /* print prefix and mask */
7654 route_vty_out_route(p
, vty
, json_path
);
7656 vty_out(vty
, "%*s", 17, " ");
7658 /* Print attribute */
7662 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
7666 inet_ntop(af
, &attr
->mp_nexthop_global_in
, buf
, BUFSIZ
);
7668 vty_out(vty
, "%-16s", buf
);
7670 json_object_string_add(json_nexthop
, "ip", buf
);
7672 json_object_string_add(json_nexthop
, "afi",
7675 json_object_object_add(json_path
, "nexthop",
7680 inet_ntop(af
, &attr
->mp_nexthop_global
, buf
, BUFSIZ
);
7681 inet_ntop(af
, &attr
->mp_nexthop_local
, buf1
, BUFSIZ
);
7683 vty_out(vty
, "%s(%s)", buf
, buf1
);
7685 json_object_string_add(json_nexthop
,
7688 json_object_string_add(json_nexthop
,
7689 "ipv6LinkLocal", buf1
);
7691 json_object_string_add(json_nexthop
, "afi",
7694 json_object_object_add(json_path
, "nexthop",
7702 json_object_string_add(json_nexthop
, "Error",
7703 "Unsupported address-family");
7707 char *str
= esi2str(&(attr
->evpn_overlay
.eth_s_id
));
7710 vty_out(vty
, "%s", str
);
7712 json_object_string_add(json_overlay
, "esi", str
);
7714 XFREE(MTYPE_TMP
, str
);
7716 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn
*)p
)) {
7717 inet_ntop(AF_INET
, &(attr
->evpn_overlay
.gw_ip
.ipv4
),
7719 } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn
*)p
)) {
7720 inet_ntop(AF_INET6
, &(attr
->evpn_overlay
.gw_ip
.ipv6
),
7725 vty_out(vty
, "/%s", buf
);
7727 json_object_string_add(json_overlay
, "gw", buf
);
7729 if (attr
->ecommunity
) {
7731 struct ecommunity_val
*routermac
= ecommunity_lookup(
7732 attr
->ecommunity
, ECOMMUNITY_ENCODE_EVPN
,
7733 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC
);
7735 mac
= ecom_mac2str((char *)routermac
->val
);
7738 vty_out(vty
, "/%s", (char *)mac
);
7740 json_object_string_add(json_overlay
,
7743 XFREE(MTYPE_TMP
, mac
);
7750 json_object_object_add(json_path
, "overlay",
7753 json_object_array_add(json_paths
, json_path
);
7758 /* dampening route */
7759 static void damp_route_vty_out(struct vty
*vty
, struct prefix
*p
,
7760 struct bgp_path_info
*path
, int display
,
7761 safi_t safi
, bool use_json
, json_object
*json
)
7765 char timebuf
[BGP_UPTIME_LEN
];
7767 /* short status lead text */
7768 route_vty_short_status_out(vty
, path
, json
);
7770 /* print prefix and mask */
7773 route_vty_out_route(p
, vty
, NULL
);
7775 vty_out(vty
, "%*s", 17, " ");
7778 len
= vty_out(vty
, "%s", path
->peer
->host
);
7782 vty_out(vty
, "\n%*s", 34, " ");
7785 json_object_int_add(json
, "peerHost", len
);
7787 vty_out(vty
, "%*s", len
, " ");
7791 bgp_damp_reuse_time_vty(vty
, path
, timebuf
, BGP_UPTIME_LEN
,
7795 bgp_damp_reuse_time_vty(vty
, path
, timebuf
,
7796 BGP_UPTIME_LEN
, use_json
,
7799 /* Print attribute */
7805 json_object_string_add(json
, "asPath",
7808 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7813 json_object_string_add(json
, "origin",
7814 bgp_origin_str
[attr
->origin
]);
7816 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7823 static void flap_route_vty_out(struct vty
*vty
, struct prefix
*p
,
7824 struct bgp_path_info
*path
, int display
,
7825 safi_t safi
, bool use_json
, json_object
*json
)
7828 struct bgp_damp_info
*bdi
;
7829 char timebuf
[BGP_UPTIME_LEN
];
7835 bdi
= path
->extra
->damp_info
;
7837 /* short status lead text */
7838 route_vty_short_status_out(vty
, path
, json
);
7840 /* print prefix and mask */
7843 route_vty_out_route(p
, vty
, NULL
);
7845 vty_out(vty
, "%*s", 17, " ");
7848 len
= vty_out(vty
, "%s", path
->peer
->host
);
7852 vty_out(vty
, "\n%*s", 33, " ");
7855 json_object_int_add(json
, "peerHost", len
);
7857 vty_out(vty
, "%*s", len
, " ");
7860 len
= vty_out(vty
, "%d", bdi
->flap
);
7867 json_object_int_add(json
, "bdiFlap", len
);
7869 vty_out(vty
, "%*s", len
, " ");
7873 peer_uptime(bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
,
7876 vty_out(vty
, "%s ", peer_uptime(bdi
->start_time
, timebuf
,
7877 BGP_UPTIME_LEN
, 0, NULL
));
7879 if (CHECK_FLAG(path
->flags
, BGP_PATH_DAMPED
)
7880 && !CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
)) {
7882 bgp_damp_reuse_time_vty(vty
, path
, timebuf
,
7883 BGP_UPTIME_LEN
, use_json
, json
);
7886 bgp_damp_reuse_time_vty(vty
, path
, timebuf
,
7891 vty_out(vty
, "%*s ", 8, " ");
7894 /* Print attribute */
7900 json_object_string_add(json
, "asPath",
7903 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7908 json_object_string_add(json
, "origin",
7909 bgp_origin_str
[attr
->origin
]);
7911 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7917 static void route_vty_out_advertised_to(struct vty
*vty
, struct peer
*peer
,
7918 int *first
, const char *header
,
7919 json_object
*json_adv_to
)
7921 char buf1
[INET6_ADDRSTRLEN
];
7922 json_object
*json_peer
= NULL
;
7925 /* 'advertised-to' is a dictionary of peers we have advertised
7927 * prefix too. The key is the peer's IP or swpX, the value is
7929 * hostname if we know it and "" if not.
7931 json_peer
= json_object_new_object();
7934 json_object_string_add(json_peer
, "hostname",
7938 json_object_object_add(json_adv_to
, peer
->conf_if
,
7941 json_object_object_add(
7943 sockunion2str(&peer
->su
, buf1
, SU_ADDRSTRLEN
),
7947 vty_out(vty
, "%s", header
);
7952 && bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
)) {
7954 vty_out(vty
, " %s(%s)", peer
->hostname
,
7957 vty_out(vty
, " %s(%s)", peer
->hostname
,
7958 sockunion2str(&peer
->su
, buf1
,
7962 vty_out(vty
, " %s", peer
->conf_if
);
7965 sockunion2str(&peer
->su
, buf1
,
7971 static void route_vty_out_tx_ids(struct vty
*vty
,
7972 struct bgp_addpath_info_data
*d
)
7976 for (i
= 0; i
< BGP_ADDPATH_MAX
; i
++) {
7977 vty_out(vty
, "TX-%s %u%s", bgp_addpath_names(i
)->human_name
,
7978 d
->addpath_tx_id
[i
],
7979 i
< BGP_ADDPATH_MAX
- 1 ? " " : "\n");
7983 static const char *bgp_path_selection_reason2str(
7984 enum bgp_path_selection_reason reason
)
7987 case bgp_path_selection_none
:
7988 return "Nothing to Select";
7990 case bgp_path_selection_first
:
7991 return "First path received";
7993 case bgp_path_selection_evpn_sticky_mac
:
7994 return "EVPN Sticky Mac";
7996 case bgp_path_selection_evpn_seq
:
7997 return "EVPN sequence number";
7999 case bgp_path_selection_evpn_lower_ip
:
8000 return "EVPN lower IP";
8002 case bgp_path_selection_weight
:
8005 case bgp_path_selection_local_pref
:
8006 return "Local Pref";
8008 case bgp_path_selection_local_route
:
8009 return "Local Route";
8011 case bgp_path_selection_confed_as_path
:
8012 return "Confederation based AS Path";
8014 case bgp_path_selection_as_path
:
8017 case bgp_path_selection_origin
:
8020 case bgp_path_selection_med
:
8023 case bgp_path_selection_peer
:
8026 case bgp_path_selection_confed
:
8027 return "Confed Peer Type";
8029 case bgp_path_selection_igp_metric
:
8030 return "IGP Metric";
8032 case bgp_path_selection_older
:
8033 return "Older Path";
8035 case bgp_path_selection_router_id
:
8038 case bgp_path_selection_cluster_length
:
8039 return "Cluser length";
8041 case bgp_path_selection_stale
:
8042 return "Path Staleness";
8044 case bgp_path_selection_local_configured
:
8045 return "Locally configured route";
8047 case bgp_path_selection_neighbor_ip
:
8048 return "Neighbor IP";
8050 case bgp_path_selection_default
:
8051 return "Nothing left to compare";
8054 return "Invalid (internal error)";
8057 void route_vty_out_detail(struct vty
*vty
, struct bgp
*bgp
,
8058 struct bgp_node
*bn
, struct bgp_path_info
*path
,
8059 afi_t afi
, safi_t safi
, json_object
*json_paths
)
8061 char buf
[INET6_ADDRSTRLEN
];
8063 char buf2
[EVPN_ROUTE_STRLEN
];
8065 int sockunion_vty_out(struct vty
*, union sockunion
*);
8067 json_object
*json_bestpath
= NULL
;
8068 json_object
*json_cluster_list
= NULL
;
8069 json_object
*json_cluster_list_list
= NULL
;
8070 json_object
*json_ext_community
= NULL
;
8071 json_object
*json_last_update
= NULL
;
8072 json_object
*json_pmsi
= NULL
;
8073 json_object
*json_nexthop_global
= NULL
;
8074 json_object
*json_nexthop_ll
= NULL
;
8075 json_object
*json_nexthops
= NULL
;
8076 json_object
*json_path
= NULL
;
8077 json_object
*json_peer
= NULL
;
8078 json_object
*json_string
= NULL
;
8079 json_object
*json_adv_to
= NULL
;
8081 struct listnode
*node
, *nnode
;
8083 int addpath_capable
;
8085 unsigned int first_as
;
8087 CHECK_FLAG(path
->flags
, BGP_PATH_ANNC_NH_SELF
) ? true : false;
8089 char *nexthop_fqdn
= bgp_nexthop_fqdn(path
->peer
);
8092 json_path
= json_object_new_object();
8093 json_peer
= json_object_new_object();
8094 json_nexthop_global
= json_object_new_object();
8097 if (!json_paths
&& safi
== SAFI_EVPN
) {
8100 bgp_evpn_route2str((struct prefix_evpn
*)&bn
->p
,
8101 buf2
, sizeof(buf2
));
8102 vty_out(vty
, " Route %s", buf2
);
8104 if (path
->extra
&& path
->extra
->num_labels
) {
8105 bgp_evpn_label2str(path
->extra
->label
,
8106 path
->extra
->num_labels
, tag_buf
,
8108 vty_out(vty
, " VNI %s", tag_buf
);
8111 if (path
->extra
&& path
->extra
->parent
) {
8112 struct bgp_path_info
*parent_ri
;
8113 struct bgp_node
*rn
, *prn
;
8115 parent_ri
= (struct bgp_path_info
*)path
->extra
->parent
;
8116 rn
= parent_ri
->net
;
8117 if (rn
&& rn
->prn
) {
8119 vty_out(vty
, " Imported from %s:%s\n",
8121 (struct prefix_rd
*)&prn
->p
,
8122 buf1
, sizeof(buf1
)),
8131 /* Line1 display AS-path, Aggregator */
8134 if (!attr
->aspath
->json
)
8135 aspath_str_update(attr
->aspath
, true);
8136 json_object_lock(attr
->aspath
->json
);
8137 json_object_object_add(json_path
, "aspath",
8138 attr
->aspath
->json
);
8140 if (attr
->aspath
->segments
)
8141 aspath_print_vty(vty
, " %s",
8144 vty_out(vty
, " Local");
8148 if (CHECK_FLAG(path
->flags
, BGP_PATH_REMOVED
)) {
8150 json_object_boolean_true_add(json_path
,
8153 vty_out(vty
, ", (removed)");
8156 if (CHECK_FLAG(path
->flags
, BGP_PATH_STALE
)) {
8158 json_object_boolean_true_add(json_path
,
8161 vty_out(vty
, ", (stale)");
8164 if (CHECK_FLAG(attr
->flag
,
8165 ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR
))) {
8167 json_object_int_add(json_path
, "aggregatorAs",
8168 attr
->aggregator_as
);
8169 json_object_string_add(
8170 json_path
, "aggregatorId",
8171 inet_ntoa(attr
->aggregator_addr
));
8173 vty_out(vty
, ", (aggregated by %u %s)",
8174 attr
->aggregator_as
,
8175 inet_ntoa(attr
->aggregator_addr
));
8179 if (CHECK_FLAG(path
->peer
->af_flags
[afi
][safi
],
8180 PEER_FLAG_REFLECTOR_CLIENT
)) {
8182 json_object_boolean_true_add(
8183 json_path
, "rxedFromRrClient");
8185 vty_out(vty
, ", (Received from a RR-client)");
8188 if (CHECK_FLAG(path
->peer
->af_flags
[afi
][safi
],
8189 PEER_FLAG_RSERVER_CLIENT
)) {
8191 json_object_boolean_true_add(
8192 json_path
, "rxedFromRsClient");
8194 vty_out(vty
, ", (Received from a RS-client)");
8197 if (CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
)) {
8199 json_object_boolean_true_add(
8200 json_path
, "dampeningHistoryEntry");
8202 vty_out(vty
, ", (history entry)");
8203 } else if (CHECK_FLAG(path
->flags
, BGP_PATH_DAMPED
)) {
8205 json_object_boolean_true_add(
8206 json_path
, "dampeningSuppressed");
8208 vty_out(vty
, ", (suppressed due to dampening)");
8214 /* Line2 display Next-hop, Neighbor, Router-id */
8215 /* Display the nexthop */
8216 if ((bn
->p
.family
== AF_INET
|| bn
->p
.family
== AF_ETHERNET
8217 || bn
->p
.family
== AF_EVPN
)
8218 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
8219 || safi
== SAFI_EVPN
8220 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
8221 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
8222 || safi
== SAFI_EVPN
) {
8224 json_object_string_add(
8225 json_nexthop_global
,
8226 nexthop_fqdn
? "fqdn" : "ip",
8230 attr
->mp_nexthop_global_in
));
8236 attr
->mp_nexthop_global_in
));
8239 json_object_string_add(
8240 json_nexthop_global
,
8241 nexthop_fqdn
? "fqdn" : "ip",
8255 json_object_string_add(json_nexthop_global
,
8259 json_object_string_add(
8260 json_nexthop_global
,
8261 nexthop_fqdn
? "fqdn" : "ip",
8266 &attr
->mp_nexthop_global
,
8269 json_object_string_add(json_nexthop_global
,
8271 json_object_string_add(json_nexthop_global
,
8279 &attr
->mp_nexthop_global
,
8285 /* Display the IGP cost or 'inaccessible' */
8286 if (!CHECK_FLAG(path
->flags
, BGP_PATH_VALID
)) {
8288 json_object_boolean_false_add(
8289 json_nexthop_global
, "accessible");
8291 vty_out(vty
, " (inaccessible)");
8293 if (path
->extra
&& path
->extra
->igpmetric
) {
8295 json_object_int_add(
8296 json_nexthop_global
, "metric",
8297 path
->extra
->igpmetric
);
8299 vty_out(vty
, " (metric %u)",
8300 path
->extra
->igpmetric
);
8303 /* IGP cost is 0, display this only for json */
8306 json_object_int_add(json_nexthop_global
,
8311 json_object_boolean_true_add(
8312 json_nexthop_global
, "accessible");
8315 /* Display peer "from" output */
8316 /* This path was originated locally */
8317 if (path
->peer
== bgp
->peer_self
) {
8319 if (safi
== SAFI_EVPN
8320 || (bn
->p
.family
== AF_INET
8321 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
8323 json_object_string_add(
8324 json_peer
, "peerId", "0.0.0.0");
8326 vty_out(vty
, " from 0.0.0.0 ");
8329 json_object_string_add(json_peer
,
8332 vty_out(vty
, " from :: ");
8336 json_object_string_add(
8337 json_peer
, "routerId",
8338 inet_ntoa(bgp
->router_id
));
8340 vty_out(vty
, "(%s)", inet_ntoa(bgp
->router_id
));
8343 /* We RXed this path from one of our peers */
8347 json_object_string_add(
8348 json_peer
, "peerId",
8349 sockunion2str(&path
->peer
->su
, buf
,
8351 json_object_string_add(
8352 json_peer
, "routerId",
8354 &path
->peer
->remote_id
, buf1
,
8357 if (path
->peer
->hostname
)
8358 json_object_string_add(
8359 json_peer
, "hostname",
8360 path
->peer
->hostname
);
8362 if (path
->peer
->domainname
)
8363 json_object_string_add(
8364 json_peer
, "domainname",
8365 path
->peer
->domainname
);
8367 if (path
->peer
->conf_if
)
8368 json_object_string_add(
8369 json_peer
, "interface",
8370 path
->peer
->conf_if
);
8372 if (path
->peer
->conf_if
) {
8373 if (path
->peer
->hostname
8376 BGP_FLAG_SHOW_HOSTNAME
))
8377 vty_out(vty
, " from %s(%s)",
8378 path
->peer
->hostname
,
8379 path
->peer
->conf_if
);
8381 vty_out(vty
, " from %s",
8382 path
->peer
->conf_if
);
8384 if (path
->peer
->hostname
8387 BGP_FLAG_SHOW_HOSTNAME
))
8388 vty_out(vty
, " from %s(%s)",
8389 path
->peer
->hostname
,
8392 vty_out(vty
, " from %s",
8400 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
8401 vty_out(vty
, " (%s)",
8402 inet_ntoa(attr
->originator_id
));
8404 vty_out(vty
, " (%s)",
8407 &path
->peer
->remote_id
,
8408 buf1
, sizeof(buf1
)));
8413 * Note when vrfid of nexthop is different from that of prefix
8415 if (path
->extra
&& path
->extra
->bgp_orig
) {
8416 vrf_id_t nexthop_vrfid
= path
->extra
->bgp_orig
->vrf_id
;
8421 if (path
->extra
->bgp_orig
->inst_type
8422 == BGP_INSTANCE_TYPE_DEFAULT
)
8424 vn
= VRF_DEFAULT_NAME
;
8426 vn
= path
->extra
->bgp_orig
->name
;
8428 json_object_string_add(json_path
, "nhVrfName",
8431 if (nexthop_vrfid
== VRF_UNKNOWN
) {
8432 json_object_int_add(json_path
,
8435 json_object_int_add(json_path
,
8436 "nhVrfId", (int)nexthop_vrfid
);
8439 if (nexthop_vrfid
== VRF_UNKNOWN
)
8440 vty_out(vty
, " vrf ?");
8442 vty_out(vty
, " vrf %u", nexthop_vrfid
);
8448 json_object_boolean_true_add(json_path
,
8449 "announceNexthopSelf");
8451 vty_out(vty
, " announce-nh-self");
8458 /* display the link-local nexthop */
8459 if (attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) {
8461 json_nexthop_ll
= json_object_new_object();
8462 json_object_string_add(
8464 nexthop_fqdn
? "fqdn" : "ip",
8469 &attr
->mp_nexthop_local
,
8472 json_object_string_add(json_nexthop_ll
, "afi",
8474 json_object_string_add(json_nexthop_ll
, "scope",
8477 json_object_boolean_true_add(json_nexthop_ll
,
8480 if (!attr
->mp_nexthop_prefer_global
)
8481 json_object_boolean_true_add(
8482 json_nexthop_ll
, "used");
8484 json_object_boolean_true_add(
8485 json_nexthop_global
, "used");
8487 vty_out(vty
, " (%s) %s\n",
8489 &attr
->mp_nexthop_local
, buf
,
8491 attr
->mp_nexthop_prefer_global
8496 /* If we do not have a link-local nexthop then we must flag the
8500 json_object_boolean_true_add(
8501 json_nexthop_global
, "used");
8504 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
8505 * Int/Ext/Local, Atomic, best */
8507 json_object_string_add(
8508 json_path
, "origin",
8509 bgp_origin_long_str
[attr
->origin
]);
8511 vty_out(vty
, " Origin %s",
8512 bgp_origin_long_str
[attr
->origin
]);
8514 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)) {
8518 * Adding "metric" field to match with
8519 * corresponding CLI. "med" will be
8520 * deprecated in future.
8522 json_object_int_add(json_path
, "med",
8524 json_object_int_add(json_path
, "metric",
8527 vty_out(vty
, ", metric %u", attr
->med
);
8530 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
8532 json_object_int_add(json_path
, "localpref",
8535 vty_out(vty
, ", localpref %u",
8539 if (attr
->weight
!= 0) {
8541 json_object_int_add(json_path
, "weight",
8544 vty_out(vty
, ", weight %u", attr
->weight
);
8547 if (attr
->tag
!= 0) {
8549 json_object_int_add(json_path
, "tag",
8552 vty_out(vty
, ", tag %" ROUTE_TAG_PRI
,
8556 if (!CHECK_FLAG(path
->flags
, BGP_PATH_VALID
)) {
8558 json_object_boolean_false_add(json_path
,
8561 vty_out(vty
, ", invalid");
8562 } else if (!CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
)) {
8564 json_object_boolean_true_add(json_path
,
8567 vty_out(vty
, ", valid");
8570 if (path
->peer
!= bgp
->peer_self
) {
8571 if (path
->peer
->as
== path
->peer
->local_as
) {
8572 if (CHECK_FLAG(bgp
->config
,
8573 BGP_CONFIG_CONFEDERATION
)) {
8575 json_object_string_add(
8580 ", confed-internal");
8583 json_object_string_add(
8587 vty_out(vty
, ", internal");
8590 if (bgp_confederation_peers_check(
8591 bgp
, path
->peer
->as
)) {
8593 json_object_string_add(
8598 ", confed-external");
8601 json_object_string_add(
8605 vty_out(vty
, ", external");
8608 } else if (path
->sub_type
== BGP_ROUTE_AGGREGATE
) {
8610 json_object_boolean_true_add(json_path
,
8612 json_object_boolean_true_add(json_path
,
8615 vty_out(vty
, ", aggregated, local");
8617 } else if (path
->type
!= ZEBRA_ROUTE_BGP
) {
8619 json_object_boolean_true_add(json_path
,
8622 vty_out(vty
, ", sourced");
8625 json_object_boolean_true_add(json_path
,
8627 json_object_boolean_true_add(json_path
,
8630 vty_out(vty
, ", sourced, local");
8634 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
)) {
8636 json_object_boolean_true_add(json_path
,
8639 vty_out(vty
, ", atomic-aggregate");
8642 if (CHECK_FLAG(path
->flags
, BGP_PATH_MULTIPATH
)
8643 || (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
)
8644 && bgp_path_info_mpath_count(path
))) {
8646 json_object_boolean_true_add(json_path
,
8649 vty_out(vty
, ", multipath");
8652 // Mark the bestpath(s)
8653 if (CHECK_FLAG(path
->flags
, BGP_PATH_DMED_SELECTED
)) {
8654 first_as
= aspath_get_first_as(attr
->aspath
);
8659 json_object_new_object();
8660 json_object_int_add(json_bestpath
,
8661 "bestpathFromAs", first_as
);
8664 vty_out(vty
, ", bestpath-from-AS %u",
8668 ", bestpath-from-AS Local");
8672 if (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
)) {
8676 json_object_new_object();
8677 json_object_boolean_true_add(json_bestpath
,
8679 json_object_string_add(json_bestpath
,
8681 bgp_path_selection_reason2str(bn
->reason
));
8683 vty_out(vty
, ", best");
8684 vty_out(vty
, " (%s)",
8685 bgp_path_selection_reason2str(bn
->reason
));
8690 json_object_object_add(json_path
, "bestpath",
8696 /* Line 4 display Community */
8697 if (attr
->community
) {
8699 if (!attr
->community
->json
)
8700 community_str(attr
->community
, true);
8701 json_object_lock(attr
->community
->json
);
8702 json_object_object_add(json_path
, "community",
8703 attr
->community
->json
);
8705 vty_out(vty
, " Community: %s\n",
8706 attr
->community
->str
);
8710 /* Line 5 display Extended-community */
8711 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)) {
8713 json_ext_community
= json_object_new_object();
8714 json_object_string_add(json_ext_community
,
8716 attr
->ecommunity
->str
);
8717 json_object_object_add(json_path
,
8718 "extendedCommunity",
8719 json_ext_community
);
8721 vty_out(vty
, " Extended Community: %s\n",
8722 attr
->ecommunity
->str
);
8726 /* Line 6 display Large community */
8727 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
)) {
8729 if (!attr
->lcommunity
->json
)
8730 lcommunity_str(attr
->lcommunity
, true);
8731 json_object_lock(attr
->lcommunity
->json
);
8732 json_object_object_add(json_path
,
8734 attr
->lcommunity
->json
);
8736 vty_out(vty
, " Large Community: %s\n",
8737 attr
->lcommunity
->str
);
8741 /* Line 7 display Originator, Cluster-id */
8742 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
8743 || (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))) {
8745 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) {
8747 json_object_string_add(
8748 json_path
, "originatorId",
8749 inet_ntoa(attr
->originator_id
));
8751 vty_out(vty
, " Originator: %s",
8752 inet_ntoa(attr
->originator_id
));
8755 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)) {
8760 json_object_new_object();
8761 json_cluster_list_list
=
8762 json_object_new_array();
8765 i
< attr
->cluster
->length
/ 4;
8767 json_string
= json_object_new_string(
8771 json_object_array_add(
8772 json_cluster_list_list
,
8776 /* struct cluster_list does not have
8778 * aspath and community do. Add this
8781 json_object_string_add(json_cluster_list,
8782 "string", attr->cluster->str);
8784 json_object_object_add(
8785 json_cluster_list
, "list",
8786 json_cluster_list_list
);
8787 json_object_object_add(
8788 json_path
, "clusterList",
8791 vty_out(vty
, ", Cluster list: ");
8794 i
< attr
->cluster
->length
/ 4;
8808 if (path
->extra
&& path
->extra
->damp_info
)
8809 bgp_damp_info_vty(vty
, path
, json_path
);
8812 if (path
->extra
&& bgp_is_valid_label(&path
->extra
->label
[0])
8813 && safi
!= SAFI_EVPN
) {
8814 mpls_label_t label
= label_pton(&path
->extra
->label
[0]);
8817 json_object_int_add(json_path
, "remoteLabel",
8820 vty_out(vty
, " Remote label: %d\n", label
);
8824 if (attr
->label_index
!= BGP_INVALID_LABEL_INDEX
) {
8826 json_object_int_add(json_path
, "labelIndex",
8829 vty_out(vty
, " Label Index: %d\n",
8833 /* Line 8 display Addpath IDs */
8834 if (path
->addpath_rx_id
8835 || bgp_addpath_info_has_ids(&path
->tx_addpath
)) {
8837 json_object_int_add(json_path
, "addpathRxId",
8838 path
->addpath_rx_id
);
8840 /* Keep backwards compatibility with the old API
8841 * by putting TX All's ID in the old field
8843 json_object_int_add(
8844 json_path
, "addpathTxId",
8845 path
->tx_addpath
.addpath_tx_id
8848 /* ... but create a specific field for each
8851 for (i
= 0; i
< BGP_ADDPATH_MAX
; i
++) {
8852 json_object_int_add(
8854 bgp_addpath_names(i
)
8860 vty_out(vty
, " AddPath ID: RX %u, ",
8861 path
->addpath_rx_id
);
8863 route_vty_out_tx_ids(vty
, &path
->tx_addpath
);
8867 /* If we used addpath to TX a non-bestpath we need to display
8868 * "Advertised to" on a path-by-path basis
8870 if (bgp_addpath_is_addpath_used(&bgp
->tx_addpath
, afi
, safi
)) {
8873 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
8875 bgp_addpath_encode_tx(peer
, afi
, safi
);
8876 has_adj
= bgp_adj_out_lookup(
8878 bgp_addpath_id_for_peer(
8880 &path
->tx_addpath
));
8882 if ((addpath_capable
&& has_adj
)
8883 || (!addpath_capable
&& has_adj
8884 && CHECK_FLAG(path
->flags
,
8885 BGP_PATH_SELECTED
))) {
8886 if (json_path
&& !json_adv_to
)
8888 json_object_new_object();
8890 route_vty_out_advertised_to(
8899 json_object_object_add(json_path
,
8910 /* Line 9 display Uptime */
8911 tbuf
= time(NULL
) - (bgp_clock() - path
->uptime
);
8913 json_last_update
= json_object_new_object();
8914 json_object_int_add(json_last_update
, "epoch", tbuf
);
8915 json_object_string_add(json_last_update
, "string",
8917 json_object_object_add(json_path
, "lastUpdate",
8920 vty_out(vty
, " Last update: %s", ctime(&tbuf
));
8922 /* Line 10 display PMSI tunnel attribute, if present */
8923 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL
)) {
8924 const char *str
= lookup_msg(bgp_pmsi_tnltype_str
,
8925 attr
->pmsi_tnl_type
,
8926 PMSI_TNLTYPE_STR_DEFAULT
);
8929 json_pmsi
= json_object_new_object();
8930 json_object_string_add(json_pmsi
,
8932 json_object_int_add(json_pmsi
,
8934 label2vni(&attr
->label
));
8935 json_object_object_add(json_path
, "pmsi",
8939 " PMSI Tunnel Type: %s, label: %d\n",
8940 str
, label2vni(&attr
->label
));
8945 /* We've constructed the json object for this path, add it to the json
8949 if (json_nexthop_global
|| json_nexthop_ll
) {
8950 json_nexthops
= json_object_new_array();
8952 if (json_nexthop_global
)
8953 json_object_array_add(json_nexthops
,
8954 json_nexthop_global
);
8956 if (json_nexthop_ll
)
8957 json_object_array_add(json_nexthops
,
8960 json_object_object_add(json_path
, "nexthops",
8964 json_object_object_add(json_path
, "peer", json_peer
);
8965 json_object_array_add(json_paths
, json_path
);
8970 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
8971 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
8972 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
8974 static int bgp_show_prefix_list(struct vty
*vty
, struct bgp
*bgp
,
8975 const char *prefix_list_str
, afi_t afi
,
8976 safi_t safi
, enum bgp_show_type type
);
8977 static int bgp_show_filter_list(struct vty
*vty
, struct bgp
*bgp
,
8978 const char *filter
, afi_t afi
, safi_t safi
,
8979 enum bgp_show_type type
);
8980 static int bgp_show_route_map(struct vty
*vty
, struct bgp
*bgp
,
8981 const char *rmap_str
, afi_t afi
, safi_t safi
,
8982 enum bgp_show_type type
);
8983 static int bgp_show_community_list(struct vty
*vty
, struct bgp
*bgp
,
8984 const char *com
, int exact
, afi_t afi
,
8986 static int bgp_show_prefix_longer(struct vty
*vty
, struct bgp
*bgp
,
8987 const char *prefix
, afi_t afi
, safi_t safi
,
8988 enum bgp_show_type type
);
8989 static int bgp_show_regexp(struct vty
*vty
, struct bgp
*bgp
, const char *regstr
,
8990 afi_t afi
, safi_t safi
, enum bgp_show_type type
);
8991 static int bgp_show_community(struct vty
*vty
, struct bgp
*bgp
,
8992 const char *comstr
, int exact
, afi_t afi
,
8993 safi_t safi
, bool use_json
);
8996 static int bgp_show_table(struct vty
*vty
, struct bgp
*bgp
, safi_t safi
,
8997 struct bgp_table
*table
, enum bgp_show_type type
,
8998 void *output_arg
, bool use_json
, char *rd
,
8999 int is_last
, unsigned long *output_cum
,
9000 unsigned long *total_cum
,
9001 unsigned long *json_header_depth
)
9003 struct bgp_path_info
*pi
;
9004 struct bgp_node
*rn
;
9007 unsigned long output_count
= 0;
9008 unsigned long total_count
= 0;
9011 json_object
*json_paths
= NULL
;
9014 if (output_cum
&& *output_cum
!= 0)
9017 if (use_json
&& !*json_header_depth
) {
9019 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
9020 ",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n"
9021 " \"localAS\": %u,\n \"routes\": { ",
9022 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : (int)bgp
->vrf_id
,
9023 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
9026 table
->version
, inet_ntoa(bgp
->router_id
),
9027 bgp
->default_local_pref
, bgp
->as
);
9028 *json_header_depth
= 2;
9030 vty_out(vty
, " \"routeDistinguishers\" : {");
9031 ++*json_header_depth
;
9035 if (use_json
&& rd
) {
9036 vty_out(vty
, " \"%s\" : { ", rd
);
9039 /* Start processing of routes. */
9040 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
9041 pi
= bgp_node_get_bgp_path_info(rn
);
9047 json_paths
= json_object_new_array();
9051 for (; pi
; pi
= pi
->next
) {
9053 if (type
== bgp_show_type_flap_statistics
9054 || type
== bgp_show_type_flap_neighbor
9055 || type
== bgp_show_type_dampend_paths
9056 || type
== bgp_show_type_damp_neighbor
) {
9057 if (!(pi
->extra
&& pi
->extra
->damp_info
))
9060 if (type
== bgp_show_type_regexp
) {
9061 regex_t
*regex
= output_arg
;
9063 if (bgp_regexec(regex
, pi
->attr
->aspath
)
9067 if (type
== bgp_show_type_prefix_list
) {
9068 struct prefix_list
*plist
= output_arg
;
9070 if (prefix_list_apply(plist
, &rn
->p
)
9074 if (type
== bgp_show_type_filter_list
) {
9075 struct as_list
*as_list
= output_arg
;
9077 if (as_list_apply(as_list
, pi
->attr
->aspath
)
9078 != AS_FILTER_PERMIT
)
9081 if (type
== bgp_show_type_route_map
) {
9082 struct route_map
*rmap
= output_arg
;
9083 struct bgp_path_info path
;
9084 struct attr dummy_attr
;
9087 bgp_attr_dup(&dummy_attr
, pi
->attr
);
9089 path
.peer
= pi
->peer
;
9090 path
.attr
= &dummy_attr
;
9092 ret
= route_map_apply(rmap
, &rn
->p
, RMAP_BGP
,
9094 if (ret
== RMAP_DENYMATCH
)
9097 if (type
== bgp_show_type_neighbor
9098 || type
== bgp_show_type_flap_neighbor
9099 || type
== bgp_show_type_damp_neighbor
) {
9100 union sockunion
*su
= output_arg
;
9102 if (pi
->peer
== NULL
9103 || pi
->peer
->su_remote
== NULL
9104 || !sockunion_same(pi
->peer
->su_remote
, su
))
9107 if (type
== bgp_show_type_cidr_only
) {
9108 uint32_t destination
;
9110 destination
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
9111 if (IN_CLASSC(destination
)
9112 && rn
->p
.prefixlen
== 24)
9114 if (IN_CLASSB(destination
)
9115 && rn
->p
.prefixlen
== 16)
9117 if (IN_CLASSA(destination
)
9118 && rn
->p
.prefixlen
== 8)
9121 if (type
== bgp_show_type_prefix_longer
) {
9123 if (!prefix_match(p
, &rn
->p
))
9126 if (type
== bgp_show_type_community_all
) {
9127 if (!pi
->attr
->community
)
9130 if (type
== bgp_show_type_community
) {
9131 struct community
*com
= output_arg
;
9133 if (!pi
->attr
->community
9134 || !community_match(pi
->attr
->community
,
9138 if (type
== bgp_show_type_community_exact
) {
9139 struct community
*com
= output_arg
;
9141 if (!pi
->attr
->community
9142 || !community_cmp(pi
->attr
->community
, com
))
9145 if (type
== bgp_show_type_community_list
) {
9146 struct community_list
*list
= output_arg
;
9148 if (!community_list_match(pi
->attr
->community
,
9152 if (type
== bgp_show_type_community_list_exact
) {
9153 struct community_list
*list
= output_arg
;
9155 if (!community_list_exact_match(
9156 pi
->attr
->community
, list
))
9159 if (type
== bgp_show_type_lcommunity
) {
9160 struct lcommunity
*lcom
= output_arg
;
9162 if (!pi
->attr
->lcommunity
9163 || !lcommunity_match(pi
->attr
->lcommunity
,
9167 if (type
== bgp_show_type_lcommunity_list
) {
9168 struct community_list
*list
= output_arg
;
9170 if (!lcommunity_list_match(pi
->attr
->lcommunity
,
9174 if (type
== bgp_show_type_lcommunity_all
) {
9175 if (!pi
->attr
->lcommunity
)
9178 if (type
== bgp_show_type_dampend_paths
9179 || type
== bgp_show_type_damp_neighbor
) {
9180 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_DAMPED
)
9181 || CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
))
9185 if (!use_json
&& header
) {
9186 vty_out(vty
, "BGP table version is %" PRIu64
9187 ", local router ID is %s, vrf id ",
9189 inet_ntoa(bgp
->router_id
));
9190 if (bgp
->vrf_id
== VRF_UNKNOWN
)
9191 vty_out(vty
, "%s", VRFID_NONE_STR
);
9193 vty_out(vty
, "%u", bgp
->vrf_id
);
9195 vty_out(vty
, "Default local pref %u, ",
9196 bgp
->default_local_pref
);
9197 vty_out(vty
, "local AS %u\n", bgp
->as
);
9198 vty_out(vty
, BGP_SHOW_SCODE_HEADER
);
9199 vty_out(vty
, BGP_SHOW_NCODE_HEADER
);
9200 vty_out(vty
, BGP_SHOW_OCODE_HEADER
);
9201 if (type
== bgp_show_type_dampend_paths
9202 || type
== bgp_show_type_damp_neighbor
)
9203 vty_out(vty
, BGP_SHOW_DAMP_HEADER
);
9204 else if (type
== bgp_show_type_flap_statistics
9205 || type
== bgp_show_type_flap_neighbor
)
9206 vty_out(vty
, BGP_SHOW_FLAP_HEADER
);
9208 vty_out(vty
, BGP_SHOW_HEADER
);
9211 if (rd
!= NULL
&& !display
&& !output_count
) {
9214 "Route Distinguisher: %s\n",
9217 if (type
== bgp_show_type_dampend_paths
9218 || type
== bgp_show_type_damp_neighbor
)
9219 damp_route_vty_out(vty
, &rn
->p
, pi
, display
,
9220 safi
, use_json
, json_paths
);
9221 else if (type
== bgp_show_type_flap_statistics
9222 || type
== bgp_show_type_flap_neighbor
)
9223 flap_route_vty_out(vty
, &rn
->p
, pi
, display
,
9224 safi
, use_json
, json_paths
);
9226 route_vty_out(vty
, &rn
->p
, pi
, display
, safi
,
9238 if (p
->family
== AF_FLOWSPEC
) {
9239 char retstr
[BGP_FLOWSPEC_STRING_DISPLAY_MAX
];
9241 bgp_fs_nlri_get_string((unsigned char *)
9242 p
->u
.prefix_flowspec
.ptr
,
9243 p
->u
.prefix_flowspec
9246 NLRI_STRING_FORMAT_MIN
,
9249 vty_out(vty
, "\"%s/%d\": ",
9251 p
->u
.prefix_flowspec
.prefixlen
);
9253 vty_out(vty
, ",\"%s/%d\": ",
9255 p
->u
.prefix_flowspec
.prefixlen
);
9257 prefix2str(p
, buf2
, sizeof(buf2
));
9259 vty_out(vty
, "\"%s\": ", buf2
);
9261 vty_out(vty
, ",\"%s\": ", buf2
);
9264 json_object_to_json_string(json_paths
));
9265 json_object_free(json_paths
);
9272 output_count
+= *output_cum
;
9273 *output_cum
= output_count
;
9276 total_count
+= *total_cum
;
9277 *total_cum
= total_count
;
9281 vty_out(vty
, " }%s ", (is_last
? "" : ","));
9285 for (i
= 0; i
< *json_header_depth
; ++i
)
9286 vty_out(vty
, " } ");
9291 /* No route is displayed */
9292 if (output_count
== 0) {
9293 if (type
== bgp_show_type_normal
)
9295 "No BGP prefixes displayed, %ld exist\n",
9299 "\nDisplayed %ld routes and %ld total paths\n",
9300 output_count
, total_count
);
9307 int bgp_show_table_rd(struct vty
*vty
, struct bgp
*bgp
, safi_t safi
,
9308 struct bgp_table
*table
, struct prefix_rd
*prd_match
,
9309 enum bgp_show_type type
, void *output_arg
, bool use_json
)
9311 struct bgp_node
*rn
, *next
;
9312 unsigned long output_cum
= 0;
9313 unsigned long total_cum
= 0;
9314 unsigned long json_header_depth
= 0;
9315 struct bgp_table
*itable
;
9318 show_msg
= (!use_json
&& type
== bgp_show_type_normal
);
9320 for (rn
= bgp_table_top(table
); rn
; rn
= next
) {
9321 next
= bgp_route_next(rn
);
9322 if (prd_match
&& memcmp(rn
->p
.u
.val
, prd_match
->val
, 8) != 0)
9325 itable
= bgp_node_get_bgp_table_info(rn
);
9326 if (itable
!= NULL
) {
9327 struct prefix_rd prd
;
9328 char rd
[RD_ADDRSTRLEN
];
9330 memcpy(&prd
, &(rn
->p
), sizeof(struct prefix_rd
));
9331 prefix_rd2str(&prd
, rd
, sizeof(rd
));
9332 bgp_show_table(vty
, bgp
, safi
, itable
, type
, output_arg
,
9333 use_json
, rd
, next
== NULL
, &output_cum
,
9334 &total_cum
, &json_header_depth
);
9340 if (output_cum
== 0)
9341 vty_out(vty
, "No BGP prefixes displayed, %ld exist\n",
9345 "\nDisplayed %ld routes and %ld total paths\n",
9346 output_cum
, total_cum
);
9350 static int bgp_show(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
9351 enum bgp_show_type type
, void *output_arg
, bool use_json
)
9353 struct bgp_table
*table
;
9354 unsigned long json_header_depth
= 0;
9357 bgp
= bgp_get_default();
9362 vty_out(vty
, "No BGP process is configured\n");
9364 vty_out(vty
, "{}\n");
9368 table
= bgp
->rib
[afi
][safi
];
9369 /* use MPLS and ENCAP specific shows until they are merged */
9370 if (safi
== SAFI_MPLS_VPN
) {
9371 return bgp_show_table_rd(vty
, bgp
, safi
, table
, NULL
, type
,
9372 output_arg
, use_json
);
9375 if (safi
== SAFI_FLOWSPEC
&& type
== bgp_show_type_detail
) {
9376 return bgp_show_table_flowspec(vty
, bgp
, afi
, table
, type
,
9377 output_arg
, use_json
,
9380 /* labeled-unicast routes live in the unicast table */
9381 else if (safi
== SAFI_LABELED_UNICAST
)
9382 safi
= SAFI_UNICAST
;
9384 return bgp_show_table(vty
, bgp
, safi
, table
, type
, output_arg
, use_json
,
9385 NULL
, 1, NULL
, NULL
, &json_header_depth
);
9388 static void bgp_show_all_instances_routes_vty(struct vty
*vty
, afi_t afi
,
9389 safi_t safi
, bool use_json
)
9391 struct listnode
*node
, *nnode
;
9394 bool route_output
= false;
9397 vty_out(vty
, "{\n");
9399 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
9400 route_output
= true;
9403 vty_out(vty
, ",\n");
9407 vty_out(vty
, "\"%s\":",
9408 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
9412 vty_out(vty
, "\nInstance %s:\n",
9413 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
9417 bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_normal
, NULL
,
9422 vty_out(vty
, "}\n");
9423 else if (!route_output
)
9424 vty_out(vty
, "%% BGP instance not found\n");
9427 /* Header of detailed BGP route information */
9428 void route_vty_out_detail_header(struct vty
*vty
, struct bgp
*bgp
,
9429 struct bgp_node
*rn
, struct prefix_rd
*prd
,
9430 afi_t afi
, safi_t safi
, json_object
*json
)
9432 struct bgp_path_info
*pi
;
9435 struct listnode
*node
, *nnode
;
9436 char buf1
[RD_ADDRSTRLEN
];
9437 char buf2
[INET6_ADDRSTRLEN
];
9438 char buf3
[EVPN_ROUTE_STRLEN
];
9439 char prefix_str
[BUFSIZ
];
9444 int route_filter_translated_v4
= 0;
9445 int route_filter_v4
= 0;
9446 int route_filter_translated_v6
= 0;
9447 int route_filter_v6
= 0;
9450 int accept_own_nexthop
= 0;
9453 int no_advertise
= 0;
9457 int has_valid_label
= 0;
9458 mpls_label_t label
= 0;
9459 json_object
*json_adv_to
= NULL
;
9462 has_valid_label
= bgp_is_valid_label(&rn
->local_label
);
9464 if (has_valid_label
)
9465 label
= label_pton(&rn
->local_label
);
9468 if (has_valid_label
)
9469 json_object_int_add(json
, "localLabel", label
);
9471 json_object_string_add(
9473 prefix2str(p
, prefix_str
, sizeof(prefix_str
)));
9475 if (safi
== SAFI_EVPN
)
9476 vty_out(vty
, "BGP routing table entry for %s%s%s\n",
9477 prd
? prefix_rd2str(prd
, buf1
, sizeof(buf1
))
9480 bgp_evpn_route2str((struct prefix_evpn
*)p
,
9481 buf3
, sizeof(buf3
)));
9483 vty_out(vty
, "BGP routing table entry for %s%s%s/%d\n",
9484 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
9485 ? prefix_rd2str(prd
, buf1
,
9488 safi
== SAFI_MPLS_VPN
? ":" : "",
9489 inet_ntop(p
->family
, &p
->u
.prefix
, buf2
,
9493 if (has_valid_label
)
9494 vty_out(vty
, "Local label: %d\n", label
);
9495 if (bgp_labeled_safi(safi
) && safi
!= SAFI_EVPN
)
9496 vty_out(vty
, "not allocated\n");
9499 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
) {
9501 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)) {
9503 if (pi
->extra
&& pi
->extra
->suppress
)
9506 if (pi
->attr
->community
== NULL
)
9509 no_advertise
+= community_include(
9510 pi
->attr
->community
, COMMUNITY_NO_ADVERTISE
);
9511 no_export
+= community_include(pi
->attr
->community
,
9512 COMMUNITY_NO_EXPORT
);
9513 local_as
+= community_include(pi
->attr
->community
,
9514 COMMUNITY_LOCAL_AS
);
9515 accept_own
+= community_include(pi
->attr
->community
,
9516 COMMUNITY_ACCEPT_OWN
);
9517 route_filter_translated_v4
+= community_include(
9518 pi
->attr
->community
,
9519 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4
);
9520 route_filter_translated_v6
+= community_include(
9521 pi
->attr
->community
,
9522 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6
);
9523 route_filter_v4
+= community_include(
9524 pi
->attr
->community
, COMMUNITY_ROUTE_FILTER_v4
);
9525 route_filter_v6
+= community_include(
9526 pi
->attr
->community
, COMMUNITY_ROUTE_FILTER_v6
);
9527 llgr_stale
+= community_include(pi
->attr
->community
,
9528 COMMUNITY_LLGR_STALE
);
9529 no_llgr
+= community_include(pi
->attr
->community
,
9531 accept_own_nexthop
+=
9532 community_include(pi
->attr
->community
,
9533 COMMUNITY_ACCEPT_OWN_NEXTHOP
);
9534 blackhole
+= community_include(pi
->attr
->community
,
9535 COMMUNITY_BLACKHOLE
);
9536 no_peer
+= community_include(pi
->attr
->community
,
9542 vty_out(vty
, "Paths: (%d available", count
);
9544 vty_out(vty
, ", best #%d", best
);
9545 if (safi
== SAFI_UNICAST
) {
9546 if (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
9547 vty_out(vty
, ", table %s",
9550 vty_out(vty
, ", vrf %s",
9554 vty_out(vty
, ", no best path");
9558 ", accept own local route exported and imported in different VRF");
9559 else if (route_filter_translated_v4
)
9561 ", mark translated RTs for VPNv4 route filtering");
9562 else if (route_filter_v4
)
9564 ", attach RT as-is for VPNv4 route filtering");
9565 else if (route_filter_translated_v6
)
9567 ", mark translated RTs for VPNv6 route filtering");
9568 else if (route_filter_v6
)
9570 ", attach RT as-is for VPNv6 route filtering");
9571 else if (llgr_stale
)
9573 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
9576 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
9577 else if (accept_own_nexthop
)
9579 ", accept local nexthop");
9581 vty_out(vty
, ", inform peer to blackhole prefix");
9583 vty_out(vty
, ", not advertised to EBGP peer");
9584 else if (no_advertise
)
9585 vty_out(vty
, ", not advertised to any peer");
9587 vty_out(vty
, ", not advertised outside local AS");
9590 ", inform EBGP peer not to advertise to their EBGP peers");
9594 ", Advertisements suppressed by an aggregate.");
9595 vty_out(vty
, ")\n");
9598 /* If we are not using addpath then we can display Advertised to and
9600 * show what peers we advertised the bestpath to. If we are using
9602 * though then we must display Advertised to on a path-by-path basis. */
9603 if (!bgp_addpath_is_addpath_used(&bgp
->tx_addpath
, afi
, safi
)) {
9604 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
9605 if (bgp_adj_out_lookup(peer
, rn
, 0)) {
9606 if (json
&& !json_adv_to
)
9607 json_adv_to
= json_object_new_object();
9609 route_vty_out_advertised_to(
9611 " Advertised to non peer-group peers:\n ",
9618 json_object_object_add(json
, "advertisedTo",
9623 vty_out(vty
, " Not advertised to any peer");
9629 /* Display specified route of BGP table. */
9630 static int bgp_show_route_in_table(struct vty
*vty
, struct bgp
*bgp
,
9631 struct bgp_table
*rib
, const char *ip_str
,
9632 afi_t afi
, safi_t safi
,
9633 struct prefix_rd
*prd
, int prefix_check
,
9634 enum bgp_path_type pathtype
, bool use_json
)
9639 struct prefix match
;
9640 struct bgp_node
*rn
;
9641 struct bgp_node
*rm
;
9642 struct bgp_path_info
*pi
;
9643 struct bgp_table
*table
;
9644 json_object
*json
= NULL
;
9645 json_object
*json_paths
= NULL
;
9647 /* Check IP address argument. */
9648 ret
= str2prefix(ip_str
, &match
);
9650 vty_out(vty
, "address is malformed\n");
9654 match
.family
= afi2family(afi
);
9657 json
= json_object_new_object();
9658 json_paths
= json_object_new_array();
9661 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) {
9662 for (rn
= bgp_table_top(rib
); rn
; rn
= bgp_route_next(rn
)) {
9663 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
9665 table
= bgp_node_get_bgp_table_info(rn
);
9671 if ((rm
= bgp_node_match(table
, &match
)) == NULL
)
9675 && rm
->p
.prefixlen
!= match
.prefixlen
) {
9676 bgp_unlock_node(rm
);
9680 for (pi
= bgp_node_get_bgp_path_info(rm
); pi
;
9683 route_vty_out_detail_header(
9685 (struct prefix_rd
*)&rn
->p
,
9686 AFI_IP
, safi
, json
);
9691 if (pathtype
== BGP_PATH_SHOW_ALL
9692 || (pathtype
== BGP_PATH_SHOW_BESTPATH
9693 && CHECK_FLAG(pi
->flags
,
9695 || (pathtype
== BGP_PATH_SHOW_MULTIPATH
9696 && (CHECK_FLAG(pi
->flags
,
9698 || CHECK_FLAG(pi
->flags
,
9699 BGP_PATH_SELECTED
))))
9700 route_vty_out_detail(vty
, bgp
, rm
,
9705 bgp_unlock_node(rm
);
9707 } else if (safi
== SAFI_FLOWSPEC
) {
9708 display
= bgp_flowspec_display_match_per_ip(afi
, rib
,
9709 &match
, prefix_check
,
9716 if ((rn
= bgp_node_match(rib
, &match
)) != NULL
) {
9718 || rn
->p
.prefixlen
== match
.prefixlen
) {
9719 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
;
9722 route_vty_out_detail_header(
9723 vty
, bgp
, rn
, NULL
, afi
,
9729 if (pathtype
== BGP_PATH_SHOW_ALL
9731 == BGP_PATH_SHOW_BESTPATH
9736 == BGP_PATH_SHOW_MULTIPATH
9742 BGP_PATH_SELECTED
))))
9743 route_vty_out_detail(
9745 afi
, safi
, json_paths
);
9749 bgp_unlock_node(rn
);
9755 json_object_object_add(json
, "paths", json_paths
);
9757 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9758 json
, JSON_C_TO_STRING_PRETTY
));
9759 json_object_free(json
);
9762 vty_out(vty
, "%% Network not in table\n");
9770 /* Display specified route of Main RIB */
9771 static int bgp_show_route(struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
9772 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
9773 int prefix_check
, enum bgp_path_type pathtype
,
9777 bgp
= bgp_get_default();
9780 vty_out(vty
, "No BGP process is configured\n");
9782 vty_out(vty
, "{}\n");
9787 /* labeled-unicast routes live in the unicast table */
9788 if (safi
== SAFI_LABELED_UNICAST
)
9789 safi
= SAFI_UNICAST
;
9791 return bgp_show_route_in_table(vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
9792 afi
, safi
, prd
, prefix_check
, pathtype
,
9796 static int bgp_show_lcommunity(struct vty
*vty
, struct bgp
*bgp
, int argc
,
9797 struct cmd_token
**argv
, afi_t afi
, safi_t safi
,
9800 struct lcommunity
*lcom
;
9806 b
= buffer_new(1024);
9807 for (i
= 0; i
< argc
; i
++) {
9809 buffer_putc(b
, ' ');
9811 if (strmatch(argv
[i
]->text
, "AA:BB:CC")) {
9813 buffer_putstr(b
, argv
[i
]->arg
);
9817 buffer_putc(b
, '\0');
9819 str
= buffer_getstr(b
);
9822 lcom
= lcommunity_str2com(str
);
9823 XFREE(MTYPE_TMP
, str
);
9825 vty_out(vty
, "%% Large-community malformed\n");
9829 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
,
9833 static int bgp_show_lcommunity_list(struct vty
*vty
, struct bgp
*bgp
,
9834 const char *lcom
, afi_t afi
, safi_t safi
,
9837 struct community_list
*list
;
9839 list
= community_list_lookup(bgp_clist
, lcom
, 0,
9840 LARGE_COMMUNITY_LIST_MASTER
);
9842 vty_out(vty
, "%% %s is not a valid large-community-list name\n",
9847 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
,
9851 DEFUN (show_ip_bgp_large_community_list
,
9852 show_ip_bgp_large_community_list_cmd
,
9853 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community-list <(1-500)|WORD> [json]",
9857 BGP_INSTANCE_HELP_STR
9859 BGP_SAFI_WITH_LABEL_HELP_STR
9860 "Display routes matching the large-community-list\n"
9861 "large-community-list number\n"
9862 "large-community-list name\n"
9866 afi_t afi
= AFI_IP6
;
9867 safi_t safi
= SAFI_UNICAST
;
9870 if (argv_find(argv
, argc
, "ip", &idx
))
9872 if (argv_find(argv
, argc
, "view", &idx
)
9873 || argv_find(argv
, argc
, "vrf", &idx
))
9874 vrf
= argv
[++idx
]->arg
;
9875 if (argv_find(argv
, argc
, "ipv4", &idx
)
9876 || argv_find(argv
, argc
, "ipv6", &idx
)) {
9877 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
9878 if (argv_find(argv
, argc
, "unicast", &idx
)
9879 || argv_find(argv
, argc
, "multicast", &idx
))
9880 safi
= bgp_vty_safi_from_str(argv
[idx
]->text
);
9883 bool uj
= use_json(argc
, argv
);
9885 struct bgp
*bgp
= bgp_lookup_by_name(vrf
);
9887 vty_out(vty
, "Can't find BGP instance %s\n", vrf
);
9891 argv_find(argv
, argc
, "large-community-list", &idx
);
9892 return bgp_show_lcommunity_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
,
9895 DEFUN (show_ip_bgp_large_community
,
9896 show_ip_bgp_large_community_cmd
,
9897 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community [AA:BB:CC] [json]",
9901 BGP_INSTANCE_HELP_STR
9903 BGP_SAFI_WITH_LABEL_HELP_STR
9904 "Display routes matching the large-communities\n"
9905 "List of large-community numbers\n"
9909 afi_t afi
= AFI_IP6
;
9910 safi_t safi
= SAFI_UNICAST
;
9913 if (argv_find(argv
, argc
, "ip", &idx
))
9915 if (argv_find(argv
, argc
, "view", &idx
)
9916 || argv_find(argv
, argc
, "vrf", &idx
))
9917 vrf
= argv
[++idx
]->arg
;
9918 if (argv_find(argv
, argc
, "ipv4", &idx
)
9919 || argv_find(argv
, argc
, "ipv6", &idx
)) {
9920 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
9921 if (argv_find(argv
, argc
, "unicast", &idx
)
9922 || argv_find(argv
, argc
, "multicast", &idx
))
9923 safi
= bgp_vty_safi_from_str(argv
[idx
]->text
);
9926 bool uj
= use_json(argc
, argv
);
9928 struct bgp
*bgp
= bgp_lookup_by_name(vrf
);
9930 vty_out(vty
, "Can't find BGP instance %s\n", vrf
);
9934 if (argv_find(argv
, argc
, "AA:BB:CC", &idx
))
9935 return bgp_show_lcommunity(vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
9937 return bgp_show(vty
, bgp
, afi
, safi
,
9938 bgp_show_type_lcommunity_all
, NULL
, uj
);
9941 static int bgp_table_stats(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
9945 /* BGP route print out function without JSON */
9948 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
9949 <dampening <parameters>\
9954 |community-list <(1-500)|WORD> [exact-match]\
9955 |A.B.C.D/M longer-prefixes\
9956 |X:X::X:X/M longer-prefixes\
9961 BGP_INSTANCE_HELP_STR
9963 BGP_SAFI_WITH_LABEL_HELP_STR
9964 "Display detailed information about dampening\n"
9965 "Display detail of configured dampening parameters\n"
9966 "Display routes matching the route-map\n"
9967 "A route-map to match on\n"
9968 "Display routes conforming to the prefix-list\n"
9969 "Prefix-list name\n"
9970 "Display routes conforming to the filter-list\n"
9971 "Regular expression access list name\n"
9972 "BGP RIB advertisement statistics\n"
9973 "Display routes matching the community-list\n"
9974 "community-list number\n"
9975 "community-list name\n"
9976 "Exact match of the communities\n"
9978 "Display route and more specific routes\n"
9980 "Display route and more specific routes\n")
9982 afi_t afi
= AFI_IP6
;
9983 safi_t safi
= SAFI_UNICAST
;
9984 int exact_match
= 0;
9985 struct bgp
*bgp
= NULL
;
9988 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9993 if (argv_find(argv
, argc
, "dampening", &idx
)) {
9994 if (argv_find(argv
, argc
, "parameters", &idx
))
9995 return bgp_show_dampening_parameters(vty
, afi
, safi
);
9998 if (argv_find(argv
, argc
, "prefix-list", &idx
))
9999 return bgp_show_prefix_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
10000 safi
, bgp_show_type_prefix_list
);
10002 if (argv_find(argv
, argc
, "filter-list", &idx
))
10003 return bgp_show_filter_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
10004 safi
, bgp_show_type_filter_list
);
10006 if (argv_find(argv
, argc
, "statistics", &idx
))
10007 return bgp_table_stats(vty
, bgp
, afi
, safi
);
10009 if (argv_find(argv
, argc
, "route-map", &idx
))
10010 return bgp_show_route_map(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
10011 safi
, bgp_show_type_route_map
);
10013 if (argv_find(argv
, argc
, "community-list", &idx
)) {
10014 const char *clist_number_or_name
= argv
[++idx
]->arg
;
10015 if (++idx
< argc
&& strmatch(argv
[idx
]->text
, "exact-match"))
10017 return bgp_show_community_list(vty
, bgp
, clist_number_or_name
,
10018 exact_match
, afi
, safi
);
10020 /* prefix-longer */
10021 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)
10022 || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
10023 return bgp_show_prefix_longer(vty
, bgp
, argv
[idx
]->arg
, afi
,
10025 bgp_show_type_prefix_longer
);
10027 return CMD_WARNING
;
10030 /* BGP route print out function with JSON */
10031 DEFUN (show_ip_bgp_json
,
10032 show_ip_bgp_json_cmd
,
10033 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
10035 |dampening <flap-statistics|dampened-paths>\
10036 |community [AA:NN|local-AS|no-advertise|no-export\
10037 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
10038 |accept-own|accept-own-nexthop|route-filter-v6\
10039 |route-filter-v4|route-filter-translated-v6\
10040 |route-filter-translated-v4] [exact-match]\
10045 BGP_INSTANCE_HELP_STR
10047 BGP_SAFI_WITH_LABEL_HELP_STR
10048 "Display only routes with non-natural netmasks\n"
10049 "Display detailed information about dampening\n"
10050 "Display flap statistics of routes\n"
10051 "Display paths suppressed due to dampening\n"
10052 "Display routes matching the communities\n"
10054 "Do not send outside local AS (well-known community)\n"
10055 "Do not advertise to any peer (well-known community)\n"
10056 "Do not export to next AS (well-known community)\n"
10057 "Graceful shutdown (well-known community)\n"
10058 "Do not export to any peer (well-known community)\n"
10059 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
10060 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
10061 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
10062 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
10063 "Should accept VPN route with local nexthop (well-known community)\n"
10064 "RT VPNv6 route filtering (well-known community)\n"
10065 "RT VPNv4 route filtering (well-known community)\n"
10066 "RT translated VPNv6 route filtering (well-known community)\n"
10067 "RT translated VPNv4 route filtering (well-known community)\n"
10068 "Exact match of the communities\n"
10071 afi_t afi
= AFI_IP6
;
10072 safi_t safi
= SAFI_UNICAST
;
10073 enum bgp_show_type sh_type
= bgp_show_type_normal
;
10074 struct bgp
*bgp
= NULL
;
10076 int exact_match
= 0;
10077 bool uj
= use_json(argc
, argv
);
10082 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10085 return CMD_WARNING
;
10087 if (argv_find(argv
, argc
, "cidr-only", &idx
))
10088 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
,
10091 if (argv_find(argv
, argc
, "dampening", &idx
)) {
10092 if (argv_find(argv
, argc
, "dampened-paths", &idx
))
10093 return bgp_show(vty
, bgp
, afi
, safi
,
10094 bgp_show_type_dampend_paths
, NULL
, uj
);
10095 else if (argv_find(argv
, argc
, "flap-statistics", &idx
))
10096 return bgp_show(vty
, bgp
, afi
, safi
,
10097 bgp_show_type_flap_statistics
, NULL
,
10101 if (argv_find(argv
, argc
, "community", &idx
)) {
10102 char *maybecomm
= NULL
;
10103 char *community
= NULL
;
10105 if (idx
+ 1 < argc
) {
10106 if (argv
[idx
+ 1]->type
== VARIABLE_TKN
)
10107 maybecomm
= argv
[idx
+ 1]->arg
;
10109 maybecomm
= argv
[idx
+ 1]->text
;
10112 if (maybecomm
&& !strmatch(maybecomm
, "json")
10113 && !strmatch(maybecomm
, "exact-match"))
10114 community
= maybecomm
;
10116 if (argv_find(argv
, argc
, "exact-match", &idx
))
10120 return bgp_show_community(vty
, bgp
, community
,
10121 exact_match
, afi
, safi
, uj
);
10123 return (bgp_show(vty
, bgp
, afi
, safi
,
10124 bgp_show_type_community_all
, NULL
,
10128 return bgp_show(vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
10131 DEFUN (show_ip_bgp_route
,
10132 show_ip_bgp_route_cmd
,
10133 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]"
10134 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
10138 BGP_INSTANCE_HELP_STR
10140 BGP_SAFI_WITH_LABEL_HELP_STR
10141 "Network in the BGP routing table to display\n"
10143 "Network in the BGP routing table to display\n"
10145 "Display only the bestpath\n"
10146 "Display only multipaths\n"
10149 int prefix_check
= 0;
10151 afi_t afi
= AFI_IP6
;
10152 safi_t safi
= SAFI_UNICAST
;
10153 char *prefix
= NULL
;
10154 struct bgp
*bgp
= NULL
;
10155 enum bgp_path_type path_type
;
10156 bool uj
= use_json(argc
, argv
);
10160 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10163 return CMD_WARNING
;
10167 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
10168 return CMD_WARNING
;
10171 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
10172 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)
10173 || argv_find(argv
, argc
, "X:X::X:X", &idx
))
10175 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)
10176 || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
10179 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
)
10180 && afi
!= AFI_IP6
) {
10182 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
10183 return CMD_WARNING
;
10185 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
)
10186 && afi
!= AFI_IP
) {
10188 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
10189 return CMD_WARNING
;
10192 prefix
= argv
[idx
]->arg
;
10194 /* [<bestpath|multipath>] */
10195 if (argv_find(argv
, argc
, "bestpath", &idx
))
10196 path_type
= BGP_PATH_SHOW_BESTPATH
;
10197 else if (argv_find(argv
, argc
, "multipath", &idx
))
10198 path_type
= BGP_PATH_SHOW_MULTIPATH
;
10200 path_type
= BGP_PATH_SHOW_ALL
;
10202 return bgp_show_route(vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
,
10206 DEFUN (show_ip_bgp_regexp
,
10207 show_ip_bgp_regexp_cmd
,
10208 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] regexp REGEX...",
10212 BGP_INSTANCE_HELP_STR
10214 BGP_SAFI_WITH_LABEL_HELP_STR
10215 "Display routes matching the AS path regular expression\n"
10216 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n")
10218 afi_t afi
= AFI_IP6
;
10219 safi_t safi
= SAFI_UNICAST
;
10220 struct bgp
*bgp
= NULL
;
10223 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10226 return CMD_WARNING
;
10228 // get index of regex
10229 argv_find(argv
, argc
, "regexp", &idx
);
10232 char *regstr
= argv_concat(argv
, argc
, idx
);
10233 int rc
= bgp_show_regexp(vty
, bgp
, (const char *)regstr
, afi
, safi
,
10234 bgp_show_type_regexp
);
10235 XFREE(MTYPE_TMP
, regstr
);
10239 DEFUN (show_ip_bgp_instance_all
,
10240 show_ip_bgp_instance_all_cmd
,
10241 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] [json]",
10245 BGP_INSTANCE_ALL_HELP_STR
10247 BGP_SAFI_WITH_LABEL_HELP_STR
10250 afi_t afi
= AFI_IP
;
10251 safi_t safi
= SAFI_UNICAST
;
10252 struct bgp
*bgp
= NULL
;
10254 bool uj
= use_json(argc
, argv
);
10259 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10262 return CMD_WARNING
;
10264 bgp_show_all_instances_routes_vty(vty
, afi
, safi
, uj
);
10265 return CMD_SUCCESS
;
10268 static int bgp_show_regexp(struct vty
*vty
, struct bgp
*bgp
, const char *regstr
,
10269 afi_t afi
, safi_t safi
, enum bgp_show_type type
)
10274 if (!config_bgp_aspath_validate(regstr
)) {
10275 vty_out(vty
, "Invalid character in as-path access-list %s\n",
10277 return CMD_WARNING_CONFIG_FAILED
;
10280 regex
= bgp_regcomp(regstr
);
10282 vty_out(vty
, "Can't compile regexp %s\n", regstr
);
10283 return CMD_WARNING
;
10286 rc
= bgp_show(vty
, bgp
, afi
, safi
, type
, regex
, 0);
10287 bgp_regex_free(regex
);
10291 static int bgp_show_prefix_list(struct vty
*vty
, struct bgp
*bgp
,
10292 const char *prefix_list_str
, afi_t afi
,
10293 safi_t safi
, enum bgp_show_type type
)
10295 struct prefix_list
*plist
;
10297 plist
= prefix_list_lookup(afi
, prefix_list_str
);
10298 if (plist
== NULL
) {
10299 vty_out(vty
, "%% %s is not a valid prefix-list name\n",
10301 return CMD_WARNING
;
10304 return bgp_show(vty
, bgp
, afi
, safi
, type
, plist
, 0);
10307 static int bgp_show_filter_list(struct vty
*vty
, struct bgp
*bgp
,
10308 const char *filter
, afi_t afi
, safi_t safi
,
10309 enum bgp_show_type type
)
10311 struct as_list
*as_list
;
10313 as_list
= as_list_lookup(filter
);
10314 if (as_list
== NULL
) {
10315 vty_out(vty
, "%% %s is not a valid AS-path access-list name\n",
10317 return CMD_WARNING
;
10320 return bgp_show(vty
, bgp
, afi
, safi
, type
, as_list
, 0);
10323 static int bgp_show_route_map(struct vty
*vty
, struct bgp
*bgp
,
10324 const char *rmap_str
, afi_t afi
, safi_t safi
,
10325 enum bgp_show_type type
)
10327 struct route_map
*rmap
;
10329 rmap
= route_map_lookup_by_name(rmap_str
);
10331 vty_out(vty
, "%% %s is not a valid route-map name\n", rmap_str
);
10332 return CMD_WARNING
;
10335 return bgp_show(vty
, bgp
, afi
, safi
, type
, rmap
, 0);
10338 static int bgp_show_community(struct vty
*vty
, struct bgp
*bgp
,
10339 const char *comstr
, int exact
, afi_t afi
,
10340 safi_t safi
, bool use_json
)
10342 struct community
*com
;
10345 com
= community_str2com(comstr
);
10347 vty_out(vty
, "%% Community malformed: %s\n", comstr
);
10348 return CMD_WARNING
;
10351 ret
= bgp_show(vty
, bgp
, afi
, safi
,
10352 (exact
? bgp_show_type_community_exact
10353 : bgp_show_type_community
),
10355 community_free(&com
);
10360 static int bgp_show_community_list(struct vty
*vty
, struct bgp
*bgp
,
10361 const char *com
, int exact
, afi_t afi
,
10364 struct community_list
*list
;
10366 list
= community_list_lookup(bgp_clist
, com
, 0, COMMUNITY_LIST_MASTER
);
10367 if (list
== NULL
) {
10368 vty_out(vty
, "%% %s is not a valid community-list name\n", com
);
10369 return CMD_WARNING
;
10372 return bgp_show(vty
, bgp
, afi
, safi
,
10373 (exact
? bgp_show_type_community_list_exact
10374 : bgp_show_type_community_list
),
10378 static int bgp_show_prefix_longer(struct vty
*vty
, struct bgp
*bgp
,
10379 const char *prefix
, afi_t afi
, safi_t safi
,
10380 enum bgp_show_type type
)
10387 ret
= str2prefix(prefix
, p
);
10389 vty_out(vty
, "%% Malformed Prefix\n");
10390 return CMD_WARNING
;
10393 ret
= bgp_show(vty
, bgp
, afi
, safi
, type
, p
, 0);
10398 static struct peer
*peer_lookup_in_view(struct vty
*vty
, struct bgp
*bgp
,
10399 const char *ip_str
, bool use_json
)
10403 union sockunion su
;
10405 /* Get peer sockunion. */
10406 ret
= str2sockunion(ip_str
, &su
);
10408 peer
= peer_lookup_by_conf_if(bgp
, ip_str
);
10410 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
10414 json_object
*json_no
= NULL
;
10415 json_no
= json_object_new_object();
10416 json_object_string_add(
10418 "malformedAddressOrName",
10420 vty_out(vty
, "%s\n",
10421 json_object_to_json_string_ext(
10423 JSON_C_TO_STRING_PRETTY
));
10424 json_object_free(json_no
);
10427 "%% Malformed address or name: %s\n",
10435 /* Peer structure lookup. */
10436 peer
= peer_lookup(bgp
, &su
);
10439 json_object
*json_no
= NULL
;
10440 json_no
= json_object_new_object();
10441 json_object_string_add(json_no
, "warning",
10442 "No such neighbor in this view/vrf");
10443 vty_out(vty
, "%s\n",
10444 json_object_to_json_string_ext(
10445 json_no
, JSON_C_TO_STRING_PRETTY
));
10446 json_object_free(json_no
);
10448 vty_out(vty
, "No such neighbor in this view/vrf\n");
10456 BGP_STATS_MAXBITLEN
= 0,
10458 BGP_STATS_PREFIXES
,
10460 BGP_STATS_UNAGGREGATEABLE
,
10461 BGP_STATS_MAX_AGGREGATEABLE
,
10462 BGP_STATS_AGGREGATES
,
10464 BGP_STATS_ASPATH_COUNT
,
10465 BGP_STATS_ASPATH_MAXHOPS
,
10466 BGP_STATS_ASPATH_TOTHOPS
,
10467 BGP_STATS_ASPATH_MAXSIZE
,
10468 BGP_STATS_ASPATH_TOTSIZE
,
10469 BGP_STATS_ASN_HIGHEST
,
10473 static const char *table_stats_strs
[] = {
10474 [BGP_STATS_PREFIXES
] = "Total Prefixes",
10475 [BGP_STATS_TOTPLEN
] = "Average prefix length",
10476 [BGP_STATS_RIB
] = "Total Advertisements",
10477 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
10478 [BGP_STATS_MAX_AGGREGATEABLE
] =
10479 "Maximum aggregateable prefixes",
10480 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
10481 [BGP_STATS_SPACE
] = "Address space advertised",
10482 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
10483 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
10484 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
10485 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
10486 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
10487 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
10488 [BGP_STATS_MAX
] = NULL
,
10491 struct bgp_table_stats
{
10492 struct bgp_table
*table
;
10493 unsigned long long counts
[BGP_STATS_MAX
];
10494 double total_space
;
10498 #define TALLY_SIGFIG 100000
10499 static unsigned long
10500 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
10502 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
10503 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
10504 unsigned long ret
= newtot
/ count
;
10506 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
10513 static void bgp_table_stats_rn(struct bgp_node
*rn
, struct bgp_node
*top
,
10514 struct bgp_table_stats
*ts
, unsigned int space
)
10516 struct bgp_node
*prn
= bgp_node_parent_nolock(rn
);
10517 struct bgp_path_info
*pi
;
10522 if (!bgp_node_has_bgp_path_info_data(rn
))
10525 ts
->counts
[BGP_STATS_PREFIXES
]++;
10526 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
10529 ts
->counts
[BGP_STATS_AVGPLEN
]
10530 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
10531 ts
->counts
[BGP_STATS_AVGPLEN
],
10535 /* check if the prefix is included by any other announcements */
10536 while (prn
&& !bgp_node_has_bgp_path_info_data(prn
))
10537 prn
= bgp_node_parent_nolock(prn
);
10539 if (prn
== NULL
|| prn
== top
) {
10540 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
10541 /* announced address space */
10543 ts
->total_space
+= pow(2.0, space
- rn
->p
.prefixlen
);
10544 } else if (bgp_node_has_bgp_path_info_data(prn
))
10545 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
10548 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
) {
10549 ts
->counts
[BGP_STATS_RIB
]++;
10552 && (CHECK_FLAG(pi
->attr
->flag
,
10553 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))))
10554 ts
->counts
[BGP_STATS_AGGREGATES
]++;
10556 /* as-path stats */
10557 if (pi
->attr
&& pi
->attr
->aspath
) {
10558 unsigned int hops
= aspath_count_hops(pi
->attr
->aspath
);
10559 unsigned int size
= aspath_size(pi
->attr
->aspath
);
10560 as_t highest
= aspath_highest(pi
->attr
->aspath
);
10562 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
10564 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
10565 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] = hops
;
10567 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
10568 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] = size
;
10570 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
10571 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
10573 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
10574 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
10575 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
10577 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
10578 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
10579 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
10582 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
10583 ts
->counts
[BGP_STATS_ASN_HIGHEST
] = highest
;
10588 static int bgp_table_stats_walker(struct thread
*t
)
10590 struct bgp_node
*rn
, *nrn
;
10591 struct bgp_node
*top
;
10592 struct bgp_table_stats
*ts
= THREAD_ARG(t
);
10593 unsigned int space
= 0;
10595 if (!(top
= bgp_table_top(ts
->table
)))
10598 switch (ts
->table
->afi
) {
10600 space
= IPV4_MAX_BITLEN
;
10603 space
= IPV6_MAX_BITLEN
;
10609 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
10611 for (rn
= top
; rn
; rn
= bgp_route_next(rn
)) {
10612 if (ts
->table
->safi
== SAFI_MPLS_VPN
) {
10613 struct bgp_table
*table
;
10615 table
= bgp_node_get_bgp_table_info(rn
);
10619 top
= bgp_table_top(table
);
10620 for (nrn
= bgp_table_top(table
); nrn
;
10621 nrn
= bgp_route_next(nrn
))
10622 bgp_table_stats_rn(nrn
, top
, ts
, space
);
10624 bgp_table_stats_rn(rn
, top
, ts
, space
);
10631 static int bgp_table_stats(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
10634 struct bgp_table_stats ts
;
10637 if (!bgp
->rib
[afi
][safi
]) {
10638 vty_out(vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
10640 return CMD_WARNING
;
10643 vty_out(vty
, "BGP %s RIB statistics\n", afi_safi_print(afi
, safi
));
10645 /* labeled-unicast routes live in the unicast table */
10646 if (safi
== SAFI_LABELED_UNICAST
)
10647 safi
= SAFI_UNICAST
;
10649 memset(&ts
, 0, sizeof(ts
));
10650 ts
.table
= bgp
->rib
[afi
][safi
];
10651 thread_execute(bm
->master
, bgp_table_stats_walker
, &ts
, 0);
10653 for (i
= 0; i
< BGP_STATS_MAX
; i
++) {
10654 if (!table_stats_strs
[i
])
10659 case BGP_STATS_ASPATH_AVGHOPS
:
10660 case BGP_STATS_ASPATH_AVGSIZE
:
10661 case BGP_STATS_AVGPLEN
:
10662 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
10663 vty_out (vty
, "%12.2f",
10664 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
10667 case BGP_STATS_ASPATH_TOTHOPS
:
10668 case BGP_STATS_ASPATH_TOTSIZE
:
10669 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
10670 vty_out(vty
, "%12.2f",
10672 ? (float)ts
.counts
[i
]
10674 [BGP_STATS_ASPATH_COUNT
]
10677 case BGP_STATS_TOTPLEN
:
10678 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
10679 vty_out(vty
, "%12.2f",
10681 ? (float)ts
.counts
[i
]
10683 [BGP_STATS_PREFIXES
]
10686 case BGP_STATS_SPACE
:
10687 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
10688 vty_out(vty
, "%12g\n", ts
.total_space
);
10690 if (afi
== AFI_IP6
) {
10691 vty_out(vty
, "%30s: ", "/32 equivalent ");
10692 vty_out(vty
, "%12g\n",
10693 ts
.total_space
* pow(2.0, -128 + 32));
10694 vty_out(vty
, "%30s: ", "/48 equivalent ");
10695 vty_out(vty
, "%12g\n",
10696 ts
.total_space
* pow(2.0, -128 + 48));
10698 vty_out(vty
, "%30s: ", "% announced ");
10699 vty_out(vty
, "%12.2f\n",
10700 ts
.total_space
* 100. * pow(2.0, -32));
10701 vty_out(vty
, "%30s: ", "/8 equivalent ");
10702 vty_out(vty
, "%12.2f\n",
10703 ts
.total_space
* pow(2.0, -32 + 8));
10704 vty_out(vty
, "%30s: ", "/24 equivalent ");
10705 vty_out(vty
, "%12.2f\n",
10706 ts
.total_space
* pow(2.0, -32 + 24));
10710 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
10711 vty_out(vty
, "%12llu", ts
.counts
[i
]);
10714 vty_out(vty
, "\n");
10716 return CMD_SUCCESS
;
10728 PCOUNT_PFCNT
, /* the figure we display to users */
10732 static const char *pcount_strs
[] = {
10733 [PCOUNT_ADJ_IN
] = "Adj-in",
10734 [PCOUNT_DAMPED
] = "Damped",
10735 [PCOUNT_REMOVED
] = "Removed",
10736 [PCOUNT_HISTORY
] = "History",
10737 [PCOUNT_STALE
] = "Stale",
10738 [PCOUNT_VALID
] = "Valid",
10739 [PCOUNT_ALL
] = "All RIB",
10740 [PCOUNT_COUNTED
] = "PfxCt counted",
10741 [PCOUNT_PFCNT
] = "Useable",
10742 [PCOUNT_MAX
] = NULL
,
10745 struct peer_pcounts
{
10746 unsigned int count
[PCOUNT_MAX
];
10747 const struct peer
*peer
;
10748 const struct bgp_table
*table
;
10751 static int bgp_peer_count_walker(struct thread
*t
)
10753 struct bgp_node
*rn
;
10754 struct peer_pcounts
*pc
= THREAD_ARG(t
);
10755 const struct peer
*peer
= pc
->peer
;
10757 for (rn
= bgp_table_top(pc
->table
); rn
; rn
= bgp_route_next(rn
)) {
10758 struct bgp_adj_in
*ain
;
10759 struct bgp_path_info
*pi
;
10761 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
10762 if (ain
->peer
== peer
)
10763 pc
->count
[PCOUNT_ADJ_IN
]++;
10765 for (pi
= bgp_node_get_bgp_path_info(rn
); pi
; pi
= pi
->next
) {
10767 if (pi
->peer
!= peer
)
10770 pc
->count
[PCOUNT_ALL
]++;
10772 if (CHECK_FLAG(pi
->flags
, BGP_PATH_DAMPED
))
10773 pc
->count
[PCOUNT_DAMPED
]++;
10774 if (CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
))
10775 pc
->count
[PCOUNT_HISTORY
]++;
10776 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
))
10777 pc
->count
[PCOUNT_REMOVED
]++;
10778 if (CHECK_FLAG(pi
->flags
, BGP_PATH_STALE
))
10779 pc
->count
[PCOUNT_STALE
]++;
10780 if (CHECK_FLAG(pi
->flags
, BGP_PATH_VALID
))
10781 pc
->count
[PCOUNT_VALID
]++;
10782 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_UNUSEABLE
))
10783 pc
->count
[PCOUNT_PFCNT
]++;
10785 if (CHECK_FLAG(pi
->flags
, BGP_PATH_COUNTED
)) {
10786 pc
->count
[PCOUNT_COUNTED
]++;
10787 if (CHECK_FLAG(pi
->flags
, BGP_PATH_UNUSEABLE
))
10789 EC_LIB_DEVELOPMENT
,
10790 "Attempting to count but flags say it is unusable");
10792 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_UNUSEABLE
))
10794 EC_LIB_DEVELOPMENT
,
10795 "Not counted but flags say we should");
10802 static int bgp_peer_counts(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
10803 safi_t safi
, bool use_json
)
10805 struct peer_pcounts pcounts
= {.peer
= peer
};
10807 json_object
*json
= NULL
;
10808 json_object
*json_loop
= NULL
;
10811 json
= json_object_new_object();
10812 json_loop
= json_object_new_object();
10815 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
10816 || !peer
->bgp
->rib
[afi
][safi
]) {
10818 json_object_string_add(
10820 "No such neighbor or address family");
10821 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10822 json_object_free(json
);
10824 vty_out(vty
, "%% No such neighbor or address family\n");
10826 return CMD_WARNING
;
10829 memset(&pcounts
, 0, sizeof(pcounts
));
10830 pcounts
.peer
= peer
;
10831 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
10833 /* in-place call via thread subsystem so as to record execution time
10834 * stats for the thread-walk (i.e. ensure this can't be blamed on
10835 * on just vty_read()).
10837 thread_execute(bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
10840 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
10841 json_object_string_add(json
, "multiProtocol",
10842 afi_safi_print(afi
, safi
));
10843 json_object_int_add(json
, "pfxCounter",
10844 peer
->pcount
[afi
][safi
]);
10846 for (i
= 0; i
< PCOUNT_MAX
; i
++)
10847 json_object_int_add(json_loop
, pcount_strs
[i
],
10850 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
10852 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
]) {
10853 json_object_string_add(json
, "pfxctDriftFor",
10855 json_object_string_add(
10856 json
, "recommended",
10857 "Please report this bug, with the above command output");
10859 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10860 json
, JSON_C_TO_STRING_PRETTY
));
10861 json_object_free(json
);
10865 && bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
)) {
10866 vty_out(vty
, "Prefix counts for %s/%s, %s\n",
10867 peer
->hostname
, peer
->host
,
10868 afi_safi_print(afi
, safi
));
10870 vty_out(vty
, "Prefix counts for %s, %s\n", peer
->host
,
10871 afi_safi_print(afi
, safi
));
10874 vty_out(vty
, "PfxCt: %ld\n", peer
->pcount
[afi
][safi
]);
10875 vty_out(vty
, "\nCounts from RIB table walk:\n\n");
10877 for (i
= 0; i
< PCOUNT_MAX
; i
++)
10878 vty_out(vty
, "%20s: %-10d\n", pcount_strs
[i
],
10881 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
]) {
10882 vty_out(vty
, "%s [pcount] PfxCt drift!\n", peer
->host
);
10884 "Please report this bug, with the above command output\n");
10888 return CMD_SUCCESS
;
10891 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
10892 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
10893 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
10894 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
10898 BGP_INSTANCE_HELP_STR
10901 "Detailed information on TCP and BGP neighbor connections\n"
10902 "Neighbor to display information about\n"
10903 "Neighbor to display information about\n"
10904 "Neighbor on BGP configured interface\n"
10905 "Display detailed prefix count information\n"
10908 afi_t afi
= AFI_IP6
;
10909 safi_t safi
= SAFI_UNICAST
;
10912 struct bgp
*bgp
= NULL
;
10913 bool uj
= use_json(argc
, argv
);
10918 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10921 return CMD_WARNING
;
10923 argv_find(argv
, argc
, "neighbors", &idx
);
10924 peer
= peer_lookup_in_view(vty
, bgp
, argv
[idx
+ 1]->arg
, uj
);
10926 return CMD_WARNING
;
10928 return bgp_peer_counts(vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
10931 #ifdef KEEP_OLD_VPN_COMMANDS
10932 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
10933 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
10934 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
10939 "Display information about all VPNv4 NLRIs\n"
10940 "Detailed information on TCP and BGP neighbor connections\n"
10941 "Neighbor to display information about\n"
10942 "Neighbor to display information about\n"
10943 "Neighbor on BGP configured interface\n"
10944 "Display detailed prefix count information\n"
10949 bool uj
= use_json(argc
, argv
);
10951 peer
= peer_lookup_in_view(vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
10953 return CMD_WARNING
;
10955 return bgp_peer_counts(vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
10958 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
10959 show_ip_bgp_vpn_all_route_prefix_cmd
,
10960 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
10965 "Display information about all VPNv4 NLRIs\n"
10966 "Network in the BGP routing table to display\n"
10967 "Network in the BGP routing table to display\n"
10971 char *network
= NULL
;
10972 struct bgp
*bgp
= bgp_get_default();
10974 vty_out(vty
, "Can't find default instance\n");
10975 return CMD_WARNING
;
10978 if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
10979 network
= argv
[idx
]->arg
;
10980 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
))
10981 network
= argv
[idx
]->arg
;
10983 vty_out(vty
, "Unable to figure out Network\n");
10984 return CMD_WARNING
;
10987 return bgp_show_route(vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0,
10988 BGP_PATH_SHOW_ALL
, use_json(argc
, argv
));
10990 #endif /* KEEP_OLD_VPN_COMMANDS */
10992 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix
,
10993 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
,
10994 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
11000 "Display information about all EVPN NLRIs\n"
11001 "Network in the BGP routing table to display\n"
11002 "Network in the BGP routing table to display\n"
11006 char *network
= NULL
;
11008 if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
11009 network
= argv
[idx
]->arg
;
11010 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
))
11011 network
= argv
[idx
]->arg
;
11013 vty_out(vty
, "Unable to figure out Network\n");
11014 return CMD_WARNING
;
11016 return bgp_show_route(vty
, NULL
, network
, AFI_L2VPN
, SAFI_EVPN
, NULL
, 0,
11017 BGP_PATH_SHOW_ALL
, use_json(argc
, argv
));
11020 static void show_adj_route(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
11021 safi_t safi
, enum bgp_show_adj_route_type type
,
11022 const char *rmap_name
, bool use_json
,
11025 struct bgp_table
*table
;
11026 struct bgp_adj_in
*ain
;
11027 struct bgp_adj_out
*adj
;
11028 unsigned long output_count
;
11029 unsigned long filtered_count
;
11030 struct bgp_node
*rn
;
11036 struct update_subgroup
*subgrp
;
11037 json_object
*json_scode
= NULL
;
11038 json_object
*json_ocode
= NULL
;
11039 json_object
*json_ar
= NULL
;
11040 struct peer_af
*paf
;
11041 bool route_filtered
;
11044 json_scode
= json_object_new_object();
11045 json_ocode
= json_object_new_object();
11046 json_ar
= json_object_new_object();
11048 json_object_string_add(json_scode
, "suppressed", "s");
11049 json_object_string_add(json_scode
, "damped", "d");
11050 json_object_string_add(json_scode
, "history", "h");
11051 json_object_string_add(json_scode
, "valid", "*");
11052 json_object_string_add(json_scode
, "best", ">");
11053 json_object_string_add(json_scode
, "multipath", "=");
11054 json_object_string_add(json_scode
, "internal", "i");
11055 json_object_string_add(json_scode
, "ribFailure", "r");
11056 json_object_string_add(json_scode
, "stale", "S");
11057 json_object_string_add(json_scode
, "removed", "R");
11059 json_object_string_add(json_ocode
, "igp", "i");
11060 json_object_string_add(json_ocode
, "egp", "e");
11061 json_object_string_add(json_ocode
, "incomplete", "?");
11068 json_object_string_add(json
, "alert", "no BGP");
11069 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
11070 json_object_free(json
);
11072 vty_out(vty
, "%% No bgp\n");
11076 /* labeled-unicast routes live in the unicast table */
11077 if (safi
== SAFI_LABELED_UNICAST
)
11078 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
11080 table
= bgp
->rib
[afi
][safi
];
11082 output_count
= filtered_count
= 0;
11083 subgrp
= peer_subgroup(peer
, afi
, safi
);
11085 if (type
== bgp_show_adj_route_advertised
&& subgrp
11086 && CHECK_FLAG(subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
)) {
11088 json_object_int_add(json
, "bgpTableVersion",
11090 json_object_string_add(json
, "bgpLocalRouterId",
11091 inet_ntoa(bgp
->router_id
));
11092 json_object_int_add(json
, "defaultLocPrf",
11093 bgp
->default_local_pref
);
11094 json_object_int_add(json
, "localAS", bgp
->as
);
11095 json_object_object_add(json
, "bgpStatusCodes",
11097 json_object_object_add(json
, "bgpOriginCodes",
11099 json_object_string_add(
11100 json
, "bgpOriginatingDefaultNetwork",
11101 (afi
== AFI_IP
) ? "0.0.0.0/0" : "::/0");
11103 vty_out(vty
, "BGP table version is %" PRIu64
11104 ", local router ID is %s, vrf id ",
11105 table
->version
, inet_ntoa(bgp
->router_id
));
11106 if (bgp
->vrf_id
== VRF_UNKNOWN
)
11107 vty_out(vty
, "%s", VRFID_NONE_STR
);
11109 vty_out(vty
, "%u", bgp
->vrf_id
);
11110 vty_out(vty
, "\n");
11111 vty_out(vty
, "Default local pref %u, ",
11112 bgp
->default_local_pref
);
11113 vty_out(vty
, "local AS %u\n", bgp
->as
);
11114 vty_out(vty
, BGP_SHOW_SCODE_HEADER
);
11115 vty_out(vty
, BGP_SHOW_NCODE_HEADER
);
11116 vty_out(vty
, BGP_SHOW_OCODE_HEADER
);
11118 vty_out(vty
, "Originating default network %s\n\n",
11119 (afi
== AFI_IP
) ? "0.0.0.0/0" : "::/0");
11124 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
11125 if (type
== bgp_show_adj_route_received
11126 || type
== bgp_show_adj_route_filtered
) {
11127 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
) {
11128 if (ain
->peer
!= peer
|| !ain
->attr
)
11133 json_object_int_add(
11134 json
, "bgpTableVersion",
11136 json_object_string_add(
11138 "bgpLocalRouterId",
11141 json_object_int_add(json
,
11143 bgp
->default_local_pref
);
11144 json_object_int_add(json
,
11145 "localAS", bgp
->as
);
11146 json_object_object_add(
11147 json
, "bgpStatusCodes",
11149 json_object_object_add(
11150 json
, "bgpOriginCodes",
11154 "BGP table version is 0, local router ID is %s, vrf id ",
11157 if (bgp
->vrf_id
== VRF_UNKNOWN
)
11163 vty_out(vty
, "\n");
11165 "Default local pref %u, ",
11166 bgp
->default_local_pref
);
11167 vty_out(vty
, "local AS %u\n",
11170 BGP_SHOW_SCODE_HEADER
);
11172 BGP_SHOW_NCODE_HEADER
);
11174 BGP_SHOW_OCODE_HEADER
);
11180 vty_out(vty
, BGP_SHOW_HEADER
);
11184 bgp_attr_dup(&attr
, ain
->attr
);
11185 route_filtered
= false;
11187 /* Filter prefix using distribute list,
11188 * filter list or prefix list
11190 if ((bgp_input_filter(peer
, &rn
->p
, &attr
, afi
,
11191 safi
)) == FILTER_DENY
)
11192 route_filtered
= true;
11194 /* Filter prefix using route-map */
11195 ret
= bgp_input_modifier(peer
, &rn
->p
, &attr
,
11196 afi
, safi
, rmap_name
);
11198 if (type
== bgp_show_adj_route_filtered
&&
11199 !route_filtered
&& ret
!= RMAP_DENY
) {
11200 bgp_attr_undup(&attr
, ain
->attr
);
11204 if (type
== bgp_show_adj_route_received
&&
11205 (route_filtered
|| ret
== RMAP_DENY
))
11208 route_vty_out_tmp(vty
, &rn
->p
, &attr
, safi
,
11209 use_json
, json_ar
);
11210 bgp_attr_undup(&attr
, ain
->attr
);
11213 } else if (type
== bgp_show_adj_route_advertised
) {
11214 RB_FOREACH (adj
, bgp_adj_out_rb
, &rn
->adj_out
)
11215 SUBGRP_FOREACH_PEER (adj
->subgroup
, paf
) {
11216 if (paf
->peer
!= peer
|| !adj
->attr
)
11221 json_object_int_add(
11225 json_object_string_add(
11227 "bgpLocalRouterId",
11230 json_object_int_add(
11231 json
, "defaultLocPrf",
11232 bgp
->default_local_pref
11234 json_object_int_add(
11237 json_object_object_add(
11241 json_object_object_add(
11247 "BGP table version is %" PRIu64
11248 ", local router ID is %s, vrf id ",
11261 vty_out(vty
, "\n");
11263 "Default local pref %u, ",
11264 bgp
->default_local_pref
11270 BGP_SHOW_SCODE_HEADER
);
11272 BGP_SHOW_NCODE_HEADER
);
11274 BGP_SHOW_OCODE_HEADER
);
11285 bgp_attr_dup(&attr
, adj
->attr
);
11286 ret
= bgp_output_modifier(
11287 peer
, &rn
->p
, &attr
, afi
, safi
,
11290 if (ret
!= RMAP_DENY
) {
11291 route_vty_out_tmp(vty
, &rn
->p
,
11300 bgp_attr_undup(&attr
, adj
->attr
);
11306 json_object_object_add(json
, "advertisedRoutes", json_ar
);
11307 json_object_int_add(json
, "totalPrefixCounter", output_count
);
11308 json_object_int_add(json
, "filteredPrefixCounter",
11311 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
11312 json
, JSON_C_TO_STRING_PRETTY
));
11313 json_object_free(json
);
11314 } else if (output_count
> 0) {
11315 if (filtered_count
> 0)
11317 "\nTotal number of prefixes %ld (%ld filtered)\n",
11318 output_count
, filtered_count
);
11320 vty_out(vty
, "\nTotal number of prefixes %ld\n",
11325 static int peer_adj_routes(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
11326 safi_t safi
, enum bgp_show_adj_route_type type
,
11327 const char *rmap_name
, bool use_json
)
11329 json_object
*json
= NULL
;
11332 json
= json_object_new_object();
11334 if (!peer
|| !peer
->afc
[afi
][safi
]) {
11336 json_object_string_add(
11338 "No such neighbor or address family");
11339 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
11340 json_object_free(json
);
11342 vty_out(vty
, "%% No such neighbor or address family\n");
11344 return CMD_WARNING
;
11347 if ((type
== bgp_show_adj_route_received
11348 || type
== bgp_show_adj_route_filtered
)
11349 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
11350 PEER_FLAG_SOFT_RECONFIG
)) {
11352 json_object_string_add(
11354 "Inbound soft reconfiguration not enabled");
11355 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
11356 json_object_free(json
);
11359 "%% Inbound soft reconfiguration not enabled\n");
11361 return CMD_WARNING
;
11364 show_adj_route(vty
, peer
, afi
, safi
, type
, rmap_name
, use_json
, json
);
11366 return CMD_SUCCESS
;
11369 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
11370 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
11371 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
11372 "neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map WORD] [json]",
11376 BGP_INSTANCE_HELP_STR
11378 BGP_SAFI_WITH_LABEL_HELP_STR
11379 "Detailed information on TCP and BGP neighbor connections\n"
11380 "Neighbor to display information about\n"
11381 "Neighbor to display information about\n"
11382 "Neighbor on BGP configured interface\n"
11383 "Display the routes advertised to a BGP neighbor\n"
11384 "Display the received routes from neighbor\n"
11385 "Display the filtered routes received from neighbor\n"
11386 "Route-map to modify the attributes\n"
11387 "Name of the route map\n"
11390 afi_t afi
= AFI_IP6
;
11391 safi_t safi
= SAFI_UNICAST
;
11392 char *rmap_name
= NULL
;
11393 char *peerstr
= NULL
;
11394 struct bgp
*bgp
= NULL
;
11396 enum bgp_show_adj_route_type type
= bgp_show_adj_route_advertised
;
11398 bool uj
= use_json(argc
, argv
);
11403 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
11406 return CMD_WARNING
;
11408 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11409 argv_find(argv
, argc
, "neighbors", &idx
);
11410 peerstr
= argv
[++idx
]->arg
;
11412 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
11414 return CMD_WARNING
;
11416 if (argv_find(argv
, argc
, "advertised-routes", &idx
))
11417 type
= bgp_show_adj_route_advertised
;
11418 else if (argv_find(argv
, argc
, "received-routes", &idx
))
11419 type
= bgp_show_adj_route_received
;
11420 else if (argv_find(argv
, argc
, "filtered-routes", &idx
))
11421 type
= bgp_show_adj_route_filtered
;
11423 if (argv_find(argv
, argc
, "route-map", &idx
))
11424 rmap_name
= argv
[++idx
]->arg
;
11426 return peer_adj_routes(vty
, peer
, afi
, safi
, type
, rmap_name
, uj
);
11429 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
11430 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
11431 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
11437 "Address Family modifier\n"
11438 "Detailed information on TCP and BGP neighbor connections\n"
11439 "Neighbor to display information about\n"
11440 "Neighbor to display information about\n"
11441 "Neighbor on BGP configured interface\n"
11442 "Display information received from a BGP neighbor\n"
11443 "Display the prefixlist filter\n"
11446 afi_t afi
= AFI_IP6
;
11447 safi_t safi
= SAFI_UNICAST
;
11448 char *peerstr
= NULL
;
11451 union sockunion su
;
11457 /* show [ip] bgp */
11458 if (argv_find(argv
, argc
, "ip", &idx
))
11460 /* [<ipv4|ipv6> [unicast]] */
11461 if (argv_find(argv
, argc
, "ipv4", &idx
))
11463 if (argv_find(argv
, argc
, "ipv6", &idx
))
11465 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11466 argv_find(argv
, argc
, "neighbors", &idx
);
11467 peerstr
= argv
[++idx
]->arg
;
11469 bool uj
= use_json(argc
, argv
);
11471 ret
= str2sockunion(peerstr
, &su
);
11473 peer
= peer_lookup_by_conf_if(NULL
, peerstr
);
11476 vty_out(vty
, "{}\n");
11479 "%% Malformed address or name: %s\n",
11481 return CMD_WARNING
;
11484 peer
= peer_lookup(NULL
, &su
);
11487 vty_out(vty
, "{}\n");
11489 vty_out(vty
, "No peer\n");
11490 return CMD_WARNING
;
11494 sprintf(name
, "%s.%d.%d", peer
->host
, afi
, safi
);
11495 count
= prefix_bgp_show_prefix_list(NULL
, afi
, name
, uj
);
11498 vty_out(vty
, "Address Family: %s\n",
11499 afi_safi_print(afi
, safi
));
11500 prefix_bgp_show_prefix_list(vty
, afi
, name
, uj
);
11503 vty_out(vty
, "{}\n");
11505 vty_out(vty
, "No functional output\n");
11508 return CMD_SUCCESS
;
11511 static int bgp_show_neighbor_route(struct vty
*vty
, struct peer
*peer
,
11512 afi_t afi
, safi_t safi
,
11513 enum bgp_show_type type
, bool use_json
)
11515 /* labeled-unicast routes live in the unicast table */
11516 if (safi
== SAFI_LABELED_UNICAST
)
11517 safi
= SAFI_UNICAST
;
11519 if (!peer
|| !peer
->afc
[afi
][safi
]) {
11521 json_object
*json_no
= NULL
;
11522 json_no
= json_object_new_object();
11523 json_object_string_add(
11524 json_no
, "warning",
11525 "No such neighbor or address family");
11526 vty_out(vty
, "%s\n",
11527 json_object_to_json_string(json_no
));
11528 json_object_free(json_no
);
11530 vty_out(vty
, "%% No such neighbor or address family\n");
11531 return CMD_WARNING
;
11534 return bgp_show(vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
11537 DEFUN (show_ip_bgp_flowspec_routes_detailed
,
11538 show_ip_bgp_flowspec_routes_detailed_cmd
,
11539 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" flowspec] detail [json]",
11543 BGP_INSTANCE_HELP_STR
11546 "Detailed information on flowspec entries\n"
11549 afi_t afi
= AFI_IP
;
11550 safi_t safi
= SAFI_UNICAST
;
11551 struct bgp
*bgp
= NULL
;
11553 bool uj
= use_json(argc
, argv
);
11558 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
11561 return CMD_WARNING
;
11563 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_detail
, NULL
, uj
);
11566 DEFUN (show_ip_bgp_neighbor_routes
,
11567 show_ip_bgp_neighbor_routes_cmd
,
11568 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
11569 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
11573 BGP_INSTANCE_HELP_STR
11575 BGP_SAFI_WITH_LABEL_HELP_STR
11576 "Detailed information on TCP and BGP neighbor connections\n"
11577 "Neighbor to display information about\n"
11578 "Neighbor to display information about\n"
11579 "Neighbor on BGP configured interface\n"
11580 "Display flap statistics of the routes learned from neighbor\n"
11581 "Display the dampened routes received from neighbor\n"
11582 "Display routes learned from neighbor\n"
11585 char *peerstr
= NULL
;
11586 struct bgp
*bgp
= NULL
;
11587 afi_t afi
= AFI_IP6
;
11588 safi_t safi
= SAFI_UNICAST
;
11590 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
11592 bool uj
= use_json(argc
, argv
);
11597 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
11600 return CMD_WARNING
;
11602 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
11603 argv_find(argv
, argc
, "neighbors", &idx
);
11604 peerstr
= argv
[++idx
]->arg
;
11606 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
11608 return CMD_WARNING
;
11610 if (argv_find(argv
, argc
, "flap-statistics", &idx
))
11611 sh_type
= bgp_show_type_flap_neighbor
;
11612 else if (argv_find(argv
, argc
, "dampened-routes", &idx
))
11613 sh_type
= bgp_show_type_damp_neighbor
;
11614 else if (argv_find(argv
, argc
, "routes", &idx
))
11615 sh_type
= bgp_show_type_neighbor
;
11617 return bgp_show_neighbor_route(vty
, peer
, afi
, safi
, sh_type
, uj
);
11620 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
11622 struct bgp_distance
{
11623 /* Distance value for the IP source prefix. */
11626 /* Name of the access-list to be matched. */
11630 DEFUN (show_bgp_afi_vpn_rd_route
,
11631 show_bgp_afi_vpn_rd_route_cmd
,
11632 "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]",
11636 "Address Family modifier\n"
11637 "Display information for a route distinguisher\n"
11638 "Route Distinguisher\n"
11639 "Network in the BGP routing table to display\n"
11640 "Network in the BGP routing table to display\n"
11644 struct prefix_rd prd
;
11645 afi_t afi
= AFI_MAX
;
11648 if (!argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
11649 vty_out(vty
, "%% Malformed Address Family\n");
11650 return CMD_WARNING
;
11653 ret
= str2prefix_rd(argv
[5]->arg
, &prd
);
11655 vty_out(vty
, "%% Malformed Route Distinguisher\n");
11656 return CMD_WARNING
;
11659 return bgp_show_route(vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
,
11660 0, BGP_PATH_SHOW_ALL
, use_json(argc
, argv
));
11663 static struct bgp_distance
*bgp_distance_new(void)
11665 return XCALLOC(MTYPE_BGP_DISTANCE
, sizeof(struct bgp_distance
));
11668 static void bgp_distance_free(struct bgp_distance
*bdistance
)
11670 XFREE(MTYPE_BGP_DISTANCE
, bdistance
);
11673 static int bgp_distance_set(struct vty
*vty
, const char *distance_str
,
11674 const char *ip_str
, const char *access_list_str
)
11681 struct bgp_node
*rn
;
11682 struct bgp_distance
*bdistance
;
11684 afi
= bgp_node_afi(vty
);
11685 safi
= bgp_node_safi(vty
);
11687 ret
= str2prefix(ip_str
, &p
);
11689 vty_out(vty
, "Malformed prefix\n");
11690 return CMD_WARNING_CONFIG_FAILED
;
11693 distance
= atoi(distance_str
);
11695 /* Get BGP distance node. */
11696 rn
= bgp_node_get(bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
11697 bdistance
= bgp_node_get_bgp_distance_info(rn
);
11699 bgp_unlock_node(rn
);
11701 bdistance
= bgp_distance_new();
11702 bgp_node_set_bgp_distance_info(rn
, bdistance
);
11705 /* Set distance value. */
11706 bdistance
->distance
= distance
;
11708 /* Reset access-list configuration. */
11709 if (bdistance
->access_list
) {
11710 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
11711 bdistance
->access_list
= NULL
;
11713 if (access_list_str
)
11714 bdistance
->access_list
=
11715 XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
11717 return CMD_SUCCESS
;
11720 static int bgp_distance_unset(struct vty
*vty
, const char *distance_str
,
11721 const char *ip_str
, const char *access_list_str
)
11728 struct bgp_node
*rn
;
11729 struct bgp_distance
*bdistance
;
11731 afi
= bgp_node_afi(vty
);
11732 safi
= bgp_node_safi(vty
);
11734 ret
= str2prefix(ip_str
, &p
);
11736 vty_out(vty
, "Malformed prefix\n");
11737 return CMD_WARNING_CONFIG_FAILED
;
11740 rn
= bgp_node_lookup(bgp_distance_table
[afi
][safi
],
11741 (struct prefix
*)&p
);
11743 vty_out(vty
, "Can't find specified prefix\n");
11744 return CMD_WARNING_CONFIG_FAILED
;
11747 bdistance
= bgp_node_get_bgp_distance_info(rn
);
11748 distance
= atoi(distance_str
);
11750 if (bdistance
->distance
!= distance
) {
11751 vty_out(vty
, "Distance does not match configured\n");
11752 return CMD_WARNING_CONFIG_FAILED
;
11755 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
11756 bgp_distance_free(bdistance
);
11758 bgp_node_set_bgp_path_info(rn
, NULL
);
11759 bgp_unlock_node(rn
);
11760 bgp_unlock_node(rn
);
11762 return CMD_SUCCESS
;
11765 /* Apply BGP information to distance method. */
11766 uint8_t bgp_distance_apply(struct prefix
*p
, struct bgp_path_info
*pinfo
,
11767 afi_t afi
, safi_t safi
, struct bgp
*bgp
)
11769 struct bgp_node
*rn
;
11772 struct bgp_distance
*bdistance
;
11773 struct access_list
*alist
;
11774 struct bgp_static
*bgp_static
;
11779 peer
= pinfo
->peer
;
11781 /* Check source address. */
11782 sockunion2hostprefix(&peer
->su
, &q
);
11783 rn
= bgp_node_match(bgp_distance_table
[afi
][safi
], &q
);
11785 bdistance
= bgp_node_get_bgp_distance_info(rn
);
11786 bgp_unlock_node(rn
);
11788 if (bdistance
->access_list
) {
11789 alist
= access_list_lookup(afi
, bdistance
->access_list
);
11791 && access_list_apply(alist
, p
) == FILTER_PERMIT
)
11792 return bdistance
->distance
;
11794 return bdistance
->distance
;
11797 /* Backdoor check. */
11798 rn
= bgp_node_lookup(bgp
->route
[afi
][safi
], p
);
11800 bgp_static
= bgp_node_get_bgp_static_info(rn
);
11801 bgp_unlock_node(rn
);
11803 if (bgp_static
->backdoor
) {
11804 if (bgp
->distance_local
[afi
][safi
])
11805 return bgp
->distance_local
[afi
][safi
];
11807 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
11811 if (peer
->sort
== BGP_PEER_EBGP
) {
11812 if (bgp
->distance_ebgp
[afi
][safi
])
11813 return bgp
->distance_ebgp
[afi
][safi
];
11814 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
11816 if (bgp
->distance_ibgp
[afi
][safi
])
11817 return bgp
->distance_ibgp
[afi
][safi
];
11818 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
11822 DEFUN (bgp_distance
,
11824 "distance bgp (1-255) (1-255) (1-255)",
11825 "Define an administrative distance\n"
11827 "Distance for routes external to the AS\n"
11828 "Distance for routes internal to the AS\n"
11829 "Distance for local routes\n")
11831 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
11832 int idx_number
= 2;
11833 int idx_number_2
= 3;
11834 int idx_number_3
= 4;
11838 afi
= bgp_node_afi(vty
);
11839 safi
= bgp_node_safi(vty
);
11841 bgp
->distance_ebgp
[afi
][safi
] = atoi(argv
[idx_number
]->arg
);
11842 bgp
->distance_ibgp
[afi
][safi
] = atoi(argv
[idx_number_2
]->arg
);
11843 bgp
->distance_local
[afi
][safi
] = atoi(argv
[idx_number_3
]->arg
);
11844 return CMD_SUCCESS
;
11847 DEFUN (no_bgp_distance
,
11848 no_bgp_distance_cmd
,
11849 "no distance bgp [(1-255) (1-255) (1-255)]",
11851 "Define an administrative distance\n"
11853 "Distance for routes external to the AS\n"
11854 "Distance for routes internal to the AS\n"
11855 "Distance for local routes\n")
11857 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
11861 afi
= bgp_node_afi(vty
);
11862 safi
= bgp_node_safi(vty
);
11864 bgp
->distance_ebgp
[afi
][safi
] = 0;
11865 bgp
->distance_ibgp
[afi
][safi
] = 0;
11866 bgp
->distance_local
[afi
][safi
] = 0;
11867 return CMD_SUCCESS
;
11871 DEFUN (bgp_distance_source
,
11872 bgp_distance_source_cmd
,
11873 "distance (1-255) A.B.C.D/M",
11874 "Define an administrative distance\n"
11875 "Administrative distance\n"
11876 "IP source prefix\n")
11878 int idx_number
= 1;
11879 int idx_ipv4_prefixlen
= 2;
11880 bgp_distance_set(vty
, argv
[idx_number
]->arg
,
11881 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
11882 return CMD_SUCCESS
;
11885 DEFUN (no_bgp_distance_source
,
11886 no_bgp_distance_source_cmd
,
11887 "no distance (1-255) A.B.C.D/M",
11889 "Define an administrative distance\n"
11890 "Administrative distance\n"
11891 "IP source prefix\n")
11893 int idx_number
= 2;
11894 int idx_ipv4_prefixlen
= 3;
11895 bgp_distance_unset(vty
, argv
[idx_number
]->arg
,
11896 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
11897 return CMD_SUCCESS
;
11900 DEFUN (bgp_distance_source_access_list
,
11901 bgp_distance_source_access_list_cmd
,
11902 "distance (1-255) A.B.C.D/M WORD",
11903 "Define an administrative distance\n"
11904 "Administrative distance\n"
11905 "IP source prefix\n"
11906 "Access list name\n")
11908 int idx_number
= 1;
11909 int idx_ipv4_prefixlen
= 2;
11911 bgp_distance_set(vty
, argv
[idx_number
]->arg
,
11912 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
11913 return CMD_SUCCESS
;
11916 DEFUN (no_bgp_distance_source_access_list
,
11917 no_bgp_distance_source_access_list_cmd
,
11918 "no distance (1-255) A.B.C.D/M WORD",
11920 "Define an administrative distance\n"
11921 "Administrative distance\n"
11922 "IP source prefix\n"
11923 "Access list name\n")
11925 int idx_number
= 2;
11926 int idx_ipv4_prefixlen
= 3;
11928 bgp_distance_unset(vty
, argv
[idx_number
]->arg
,
11929 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
11930 return CMD_SUCCESS
;
11933 DEFUN (ipv6_bgp_distance_source
,
11934 ipv6_bgp_distance_source_cmd
,
11935 "distance (1-255) X:X::X:X/M",
11936 "Define an administrative distance\n"
11937 "Administrative distance\n"
11938 "IP source prefix\n")
11940 bgp_distance_set(vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
11941 return CMD_SUCCESS
;
11944 DEFUN (no_ipv6_bgp_distance_source
,
11945 no_ipv6_bgp_distance_source_cmd
,
11946 "no distance (1-255) X:X::X:X/M",
11948 "Define an administrative distance\n"
11949 "Administrative distance\n"
11950 "IP source prefix\n")
11952 bgp_distance_unset(vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
11953 return CMD_SUCCESS
;
11956 DEFUN (ipv6_bgp_distance_source_access_list
,
11957 ipv6_bgp_distance_source_access_list_cmd
,
11958 "distance (1-255) X:X::X:X/M WORD",
11959 "Define an administrative distance\n"
11960 "Administrative distance\n"
11961 "IP source prefix\n"
11962 "Access list name\n")
11964 bgp_distance_set(vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
11965 return CMD_SUCCESS
;
11968 DEFUN (no_ipv6_bgp_distance_source_access_list
,
11969 no_ipv6_bgp_distance_source_access_list_cmd
,
11970 "no distance (1-255) X:X::X:X/M WORD",
11972 "Define an administrative distance\n"
11973 "Administrative distance\n"
11974 "IP source prefix\n"
11975 "Access list name\n")
11977 bgp_distance_unset(vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
11978 return CMD_SUCCESS
;
11981 DEFUN (bgp_damp_set
,
11983 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
11984 "BGP Specific commands\n"
11985 "Enable route-flap dampening\n"
11986 "Half-life time for the penalty\n"
11987 "Value to start reusing a route\n"
11988 "Value to start suppressing a route\n"
11989 "Maximum duration to suppress a stable route\n")
11991 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
11992 int idx_half_life
= 2;
11994 int idx_suppress
= 4;
11995 int idx_max_suppress
= 5;
11996 int half
= DEFAULT_HALF_LIFE
* 60;
11997 int reuse
= DEFAULT_REUSE
;
11998 int suppress
= DEFAULT_SUPPRESS
;
11999 int max
= 4 * half
;
12002 half
= atoi(argv
[idx_half_life
]->arg
) * 60;
12003 reuse
= atoi(argv
[idx_reuse
]->arg
);
12004 suppress
= atoi(argv
[idx_suppress
]->arg
);
12005 max
= atoi(argv
[idx_max_suppress
]->arg
) * 60;
12006 } else if (argc
== 3) {
12007 half
= atoi(argv
[idx_half_life
]->arg
) * 60;
12011 if (suppress
< reuse
) {
12013 "Suppress value cannot be less than reuse value \n");
12017 return bgp_damp_enable(bgp
, bgp_node_afi(vty
), bgp_node_safi(vty
), half
,
12018 reuse
, suppress
, max
);
12021 DEFUN (bgp_damp_unset
,
12022 bgp_damp_unset_cmd
,
12023 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
12025 "BGP Specific commands\n"
12026 "Enable route-flap dampening\n"
12027 "Half-life time for the penalty\n"
12028 "Value to start reusing a route\n"
12029 "Value to start suppressing a route\n"
12030 "Maximum duration to suppress a stable route\n")
12032 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
12033 return bgp_damp_disable(bgp
, bgp_node_afi(vty
), bgp_node_safi(vty
));
12036 /* Display specified route of BGP table. */
12037 static int bgp_clear_damp_route(struct vty
*vty
, const char *view_name
,
12038 const char *ip_str
, afi_t afi
, safi_t safi
,
12039 struct prefix_rd
*prd
, int prefix_check
)
12042 struct prefix match
;
12043 struct bgp_node
*rn
;
12044 struct bgp_node
*rm
;
12045 struct bgp_path_info
*pi
;
12046 struct bgp_path_info
*pi_temp
;
12048 struct bgp_table
*table
;
12050 /* BGP structure lookup. */
12052 bgp
= bgp_lookup_by_name(view_name
);
12054 vty_out(vty
, "%% Can't find BGP instance %s\n",
12056 return CMD_WARNING
;
12059 bgp
= bgp_get_default();
12061 vty_out(vty
, "%% No BGP process is configured\n");
12062 return CMD_WARNING
;
12066 /* Check IP address argument. */
12067 ret
= str2prefix(ip_str
, &match
);
12069 vty_out(vty
, "%% address is malformed\n");
12070 return CMD_WARNING
;
12073 match
.family
= afi2family(afi
);
12075 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
12076 || (safi
== SAFI_EVPN
)) {
12077 for (rn
= bgp_table_top(bgp
->rib
[AFI_IP
][safi
]); rn
;
12078 rn
= bgp_route_next(rn
)) {
12079 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
12081 table
= bgp_node_get_bgp_table_info(rn
);
12084 if ((rm
= bgp_node_match(table
, &match
)) == NULL
)
12088 || rm
->p
.prefixlen
== match
.prefixlen
) {
12089 pi
= bgp_node_get_bgp_path_info(rm
);
12091 if (pi
->extra
&& pi
->extra
->damp_info
) {
12092 pi_temp
= pi
->next
;
12093 bgp_damp_info_free(
12094 pi
->extra
->damp_info
,
12102 bgp_unlock_node(rm
);
12105 if ((rn
= bgp_node_match(bgp
->rib
[afi
][safi
], &match
))
12108 || rn
->p
.prefixlen
== match
.prefixlen
) {
12109 pi
= bgp_node_get_bgp_path_info(rn
);
12111 if (pi
->extra
&& pi
->extra
->damp_info
) {
12112 pi_temp
= pi
->next
;
12113 bgp_damp_info_free(
12114 pi
->extra
->damp_info
,
12122 bgp_unlock_node(rn
);
12126 return CMD_SUCCESS
;
12129 DEFUN (clear_ip_bgp_dampening
,
12130 clear_ip_bgp_dampening_cmd
,
12131 "clear ip bgp dampening",
12135 "Clear route flap dampening information\n")
12137 bgp_damp_info_clean();
12138 return CMD_SUCCESS
;
12141 DEFUN (clear_ip_bgp_dampening_prefix
,
12142 clear_ip_bgp_dampening_prefix_cmd
,
12143 "clear ip bgp dampening A.B.C.D/M",
12147 "Clear route flap dampening information\n"
12150 int idx_ipv4_prefixlen
= 4;
12151 return bgp_clear_damp_route(vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
,
12152 AFI_IP
, SAFI_UNICAST
, NULL
, 1);
12155 DEFUN (clear_ip_bgp_dampening_address
,
12156 clear_ip_bgp_dampening_address_cmd
,
12157 "clear ip bgp dampening A.B.C.D",
12161 "Clear route flap dampening information\n"
12162 "Network to clear damping information\n")
12165 return bgp_clear_damp_route(vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
12166 SAFI_UNICAST
, NULL
, 0);
12169 DEFUN (clear_ip_bgp_dampening_address_mask
,
12170 clear_ip_bgp_dampening_address_mask_cmd
,
12171 "clear ip bgp dampening A.B.C.D A.B.C.D",
12175 "Clear route flap dampening information\n"
12176 "Network to clear damping information\n"
12180 int idx_ipv4_2
= 5;
12182 char prefix_str
[BUFSIZ
];
12184 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
,
12187 vty_out(vty
, "%% Inconsistent address and mask\n");
12188 return CMD_WARNING
;
12191 return bgp_clear_damp_route(vty
, NULL
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
12195 static void show_bgp_peerhash_entry(struct hash_bucket
*bucket
, void *arg
)
12197 struct vty
*vty
= arg
;
12198 struct peer
*peer
= bucket
->data
;
12199 char buf
[SU_ADDRSTRLEN
];
12201 vty_out(vty
, "\tPeer: %s %s\n", peer
->host
,
12202 sockunion2str(&peer
->su
, buf
, sizeof(buf
)));
12205 DEFUN (show_bgp_peerhash
,
12206 show_bgp_peerhash_cmd
,
12207 "show bgp peerhash",
12210 "Display information about the BGP peerhash\n")
12212 struct list
*instances
= bm
->bgp
;
12213 struct listnode
*node
;
12216 for (ALL_LIST_ELEMENTS_RO(instances
, node
, bgp
)) {
12217 vty_out(vty
, "BGP: %s\n", bgp
->name
);
12218 hash_iterate(bgp
->peerhash
, show_bgp_peerhash_entry
,
12222 return CMD_SUCCESS
;
12225 /* also used for encap safi */
12226 static void bgp_config_write_network_vpn(struct vty
*vty
, struct bgp
*bgp
,
12227 afi_t afi
, safi_t safi
)
12229 struct bgp_node
*prn
;
12230 struct bgp_node
*rn
;
12231 struct bgp_table
*table
;
12233 struct prefix_rd
*prd
;
12234 struct bgp_static
*bgp_static
;
12235 mpls_label_t label
;
12236 char buf
[SU_ADDRSTRLEN
];
12237 char rdbuf
[RD_ADDRSTRLEN
];
12239 /* Network configuration. */
12240 for (prn
= bgp_table_top(bgp
->route
[afi
][safi
]); prn
;
12241 prn
= bgp_route_next(prn
)) {
12242 table
= bgp_node_get_bgp_table_info(prn
);
12246 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
12247 bgp_static
= bgp_node_get_bgp_static_info(rn
);
12248 if (bgp_static
== NULL
)
12252 prd
= (struct prefix_rd
*)&prn
->p
;
12254 /* "network" configuration display. */
12255 prefix_rd2str(prd
, rdbuf
, sizeof(rdbuf
));
12256 label
= decode_label(&bgp_static
->label
);
12258 vty_out(vty
, " network %s/%d rd %s",
12259 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
12261 p
->prefixlen
, rdbuf
);
12262 if (safi
== SAFI_MPLS_VPN
)
12263 vty_out(vty
, " label %u", label
);
12265 if (bgp_static
->rmap
.name
)
12266 vty_out(vty
, " route-map %s",
12267 bgp_static
->rmap
.name
);
12269 if (bgp_static
->backdoor
)
12270 vty_out(vty
, " backdoor");
12272 vty_out(vty
, "\n");
12277 static void bgp_config_write_network_evpn(struct vty
*vty
, struct bgp
*bgp
,
12278 afi_t afi
, safi_t safi
)
12280 struct bgp_node
*prn
;
12281 struct bgp_node
*rn
;
12282 struct bgp_table
*table
;
12284 struct prefix_rd
*prd
;
12285 struct bgp_static
*bgp_static
;
12286 char buf
[PREFIX_STRLEN
* 2];
12287 char buf2
[SU_ADDRSTRLEN
];
12288 char rdbuf
[RD_ADDRSTRLEN
];
12290 /* Network configuration. */
12291 for (prn
= bgp_table_top(bgp
->route
[afi
][safi
]); prn
;
12292 prn
= bgp_route_next(prn
)) {
12293 table
= bgp_node_get_bgp_table_info(prn
);
12297 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
12298 bgp_static
= bgp_node_get_bgp_static_info(rn
);
12299 if (bgp_static
== NULL
)
12302 char *macrouter
= NULL
;
12305 if (bgp_static
->router_mac
)
12306 macrouter
= prefix_mac2str(
12307 bgp_static
->router_mac
, NULL
, 0);
12308 if (bgp_static
->eth_s_id
)
12309 esi
= esi2str(bgp_static
->eth_s_id
);
12311 prd
= (struct prefix_rd
*)&prn
->p
;
12313 /* "network" configuration display. */
12314 prefix_rd2str(prd
, rdbuf
, sizeof(rdbuf
));
12315 if (p
->u
.prefix_evpn
.route_type
== 5) {
12316 char local_buf
[PREFIX_STRLEN
];
12317 uint8_t family
= is_evpn_prefix_ipaddr_v4((
12318 struct prefix_evpn
*)p
)
12322 &p
->u
.prefix_evpn
.prefix_addr
.ip
.ip
.addr
,
12323 local_buf
, PREFIX_STRLEN
);
12324 sprintf(buf
, "%s/%u", local_buf
,
12325 p
->u
.prefix_evpn
.prefix_addr
.ip_prefix_length
);
12327 prefix2str(p
, buf
, sizeof(buf
));
12330 if (bgp_static
->gatewayIp
.family
== AF_INET
12331 || bgp_static
->gatewayIp
.family
== AF_INET6
)
12332 inet_ntop(bgp_static
->gatewayIp
.family
,
12333 &bgp_static
->gatewayIp
.u
.prefix
, buf2
,
12336 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
12338 p
->u
.prefix_evpn
.prefix_addr
.eth_tag
,
12339 decode_label(&bgp_static
->label
), esi
, buf2
,
12342 XFREE(MTYPE_TMP
, macrouter
);
12343 XFREE(MTYPE_TMP
, esi
);
12348 /* Configuration of static route announcement and aggregate
12350 void bgp_config_write_network(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
12353 struct bgp_node
*rn
;
12355 struct bgp_static
*bgp_static
;
12356 struct bgp_aggregate
*bgp_aggregate
;
12357 char buf
[SU_ADDRSTRLEN
];
12359 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)) {
12360 bgp_config_write_network_vpn(vty
, bgp
, afi
, safi
);
12364 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
12365 bgp_config_write_network_evpn(vty
, bgp
, afi
, safi
);
12369 /* Network configuration. */
12370 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
12371 rn
= bgp_route_next(rn
)) {
12372 bgp_static
= bgp_node_get_bgp_static_info(rn
);
12373 if (bgp_static
== NULL
)
12378 vty_out(vty
, " network %s/%d",
12379 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
12382 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
12383 vty_out(vty
, " label-index %u",
12384 bgp_static
->label_index
);
12386 if (bgp_static
->rmap
.name
)
12387 vty_out(vty
, " route-map %s", bgp_static
->rmap
.name
);
12389 if (bgp_static
->backdoor
)
12390 vty_out(vty
, " backdoor");
12392 vty_out(vty
, "\n");
12395 /* Aggregate-address configuration. */
12396 for (rn
= bgp_table_top(bgp
->aggregate
[afi
][safi
]); rn
;
12397 rn
= bgp_route_next(rn
)) {
12398 bgp_aggregate
= bgp_node_get_bgp_aggregate_info(rn
);
12399 if (bgp_aggregate
== NULL
)
12404 vty_out(vty
, " aggregate-address %s/%d",
12405 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, SU_ADDRSTRLEN
),
12408 if (bgp_aggregate
->as_set
)
12409 vty_out(vty
, " as-set");
12411 if (bgp_aggregate
->summary_only
)
12412 vty_out(vty
, " summary-only");
12414 vty_out(vty
, "\n");
12418 void bgp_config_write_distance(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
12421 struct bgp_node
*rn
;
12422 struct bgp_distance
*bdistance
;
12424 /* Distance configuration. */
12425 if (bgp
->distance_ebgp
[afi
][safi
] && bgp
->distance_ibgp
[afi
][safi
]
12426 && bgp
->distance_local
[afi
][safi
]
12427 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
12428 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
12429 || bgp
->distance_local
[afi
][safi
]
12430 != ZEBRA_IBGP_DISTANCE_DEFAULT
)) {
12431 vty_out(vty
, " distance bgp %d %d %d\n",
12432 bgp
->distance_ebgp
[afi
][safi
],
12433 bgp
->distance_ibgp
[afi
][safi
],
12434 bgp
->distance_local
[afi
][safi
]);
12437 for (rn
= bgp_table_top(bgp_distance_table
[afi
][safi
]); rn
;
12438 rn
= bgp_route_next(rn
)) {
12439 bdistance
= bgp_node_get_bgp_distance_info(rn
);
12440 if (bdistance
!= NULL
) {
12441 char buf
[PREFIX_STRLEN
];
12443 vty_out(vty
, " distance %d %s %s\n",
12444 bdistance
->distance
,
12445 prefix2str(&rn
->p
, buf
, sizeof(buf
)),
12446 bdistance
->access_list
? bdistance
->access_list
12452 /* Allocate routing table structure and install commands. */
12453 void bgp_route_init(void)
12458 /* Init BGP distance table. */
12459 FOREACH_AFI_SAFI (afi
, safi
)
12460 bgp_distance_table
[afi
][safi
] = bgp_table_init(NULL
, afi
, safi
);
12462 /* IPv4 BGP commands. */
12463 install_element(BGP_NODE
, &bgp_table_map_cmd
);
12464 install_element(BGP_NODE
, &bgp_network_cmd
);
12465 install_element(BGP_NODE
, &no_bgp_table_map_cmd
);
12467 install_element(BGP_NODE
, &aggregate_address_cmd
);
12468 install_element(BGP_NODE
, &aggregate_address_mask_cmd
);
12469 install_element(BGP_NODE
, &no_aggregate_address_cmd
);
12470 install_element(BGP_NODE
, &no_aggregate_address_mask_cmd
);
12472 /* IPv4 unicast configuration. */
12473 install_element(BGP_IPV4_NODE
, &bgp_table_map_cmd
);
12474 install_element(BGP_IPV4_NODE
, &bgp_network_cmd
);
12475 install_element(BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
12477 install_element(BGP_IPV4_NODE
, &aggregate_address_cmd
);
12478 install_element(BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
12479 install_element(BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
12480 install_element(BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
12482 /* IPv4 multicast configuration. */
12483 install_element(BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
12484 install_element(BGP_IPV4M_NODE
, &bgp_network_cmd
);
12485 install_element(BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
12486 install_element(BGP_IPV4M_NODE
, &aggregate_address_cmd
);
12487 install_element(BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
12488 install_element(BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
12489 install_element(BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
12491 /* IPv4 labeled-unicast configuration. */
12492 install_element(VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
12493 install_element(VIEW_NODE
, &show_ip_bgp_cmd
);
12494 install_element(VIEW_NODE
, &show_ip_bgp_json_cmd
);
12495 install_element(VIEW_NODE
, &show_ip_bgp_route_cmd
);
12496 install_element(VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
12498 install_element(VIEW_NODE
,
12499 &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
12500 install_element(VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
12501 install_element(VIEW_NODE
,
12502 &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
12503 #ifdef KEEP_OLD_VPN_COMMANDS
12504 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
12505 #endif /* KEEP_OLD_VPN_COMMANDS */
12506 install_element(VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
12507 install_element(VIEW_NODE
,
12508 &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
);
12510 /* BGP dampening clear commands */
12511 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
12512 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
12514 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
12515 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
12518 install_element(ENABLE_NODE
,
12519 &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
12520 #ifdef KEEP_OLD_VPN_COMMANDS
12521 install_element(ENABLE_NODE
,
12522 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
12523 #endif /* KEEP_OLD_VPN_COMMANDS */
12525 /* New config IPv6 BGP commands. */
12526 install_element(BGP_IPV6_NODE
, &bgp_table_map_cmd
);
12527 install_element(BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
12528 install_element(BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
12530 install_element(BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
12531 install_element(BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
12533 install_element(BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
12535 install_element(BGP_NODE
, &bgp_distance_cmd
);
12536 install_element(BGP_NODE
, &no_bgp_distance_cmd
);
12537 install_element(BGP_NODE
, &bgp_distance_source_cmd
);
12538 install_element(BGP_NODE
, &no_bgp_distance_source_cmd
);
12539 install_element(BGP_NODE
, &bgp_distance_source_access_list_cmd
);
12540 install_element(BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
12541 install_element(BGP_IPV4_NODE
, &bgp_distance_cmd
);
12542 install_element(BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
12543 install_element(BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
12544 install_element(BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
12545 install_element(BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
12546 install_element(BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
12547 install_element(BGP_IPV4M_NODE
, &bgp_distance_cmd
);
12548 install_element(BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
12549 install_element(BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
12550 install_element(BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
12551 install_element(BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
12552 install_element(BGP_IPV4M_NODE
,
12553 &no_bgp_distance_source_access_list_cmd
);
12554 install_element(BGP_IPV6_NODE
, &bgp_distance_cmd
);
12555 install_element(BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
12556 install_element(BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
12557 install_element(BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
12558 install_element(BGP_IPV6_NODE
,
12559 &ipv6_bgp_distance_source_access_list_cmd
);
12560 install_element(BGP_IPV6_NODE
,
12561 &no_ipv6_bgp_distance_source_access_list_cmd
);
12562 install_element(BGP_IPV6M_NODE
, &bgp_distance_cmd
);
12563 install_element(BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
12564 install_element(BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
12565 install_element(BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
12566 install_element(BGP_IPV6M_NODE
,
12567 &ipv6_bgp_distance_source_access_list_cmd
);
12568 install_element(BGP_IPV6M_NODE
,
12569 &no_ipv6_bgp_distance_source_access_list_cmd
);
12571 install_element(BGP_NODE
, &bgp_damp_set_cmd
);
12572 install_element(BGP_NODE
, &bgp_damp_unset_cmd
);
12573 install_element(BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
12574 install_element(BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
12576 /* IPv4 Multicast Mode */
12577 install_element(BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
12578 install_element(BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
12580 /* Large Communities */
12581 install_element(VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
12582 install_element(VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
12584 /* show bgp ipv4 flowspec detailed */
12585 install_element(VIEW_NODE
, &show_ip_bgp_flowspec_routes_detailed_cmd
);
12587 install_element(VIEW_NODE
, &show_bgp_peerhash_cmd
);
12590 void bgp_route_finish(void)
12595 FOREACH_AFI_SAFI (afi
, safi
) {
12596 bgp_table_unlock(bgp_distance_table
[afi
][safi
]);
12597 bgp_distance_table
[afi
][safi
] = NULL
;