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"
42 #include "bgpd/bgpd.h"
43 #include "bgpd/bgp_table.h"
44 #include "bgpd/bgp_route.h"
45 #include "bgpd/bgp_attr.h"
46 #include "bgpd/bgp_debug.h"
47 #include "bgpd/bgp_aspath.h"
48 #include "bgpd/bgp_regex.h"
49 #include "bgpd/bgp_community.h"
50 #include "bgpd/bgp_ecommunity.h"
51 #include "bgpd/bgp_lcommunity.h"
52 #include "bgpd/bgp_clist.h"
53 #include "bgpd/bgp_packet.h"
54 #include "bgpd/bgp_filter.h"
55 #include "bgpd/bgp_fsm.h"
56 #include "bgpd/bgp_mplsvpn.h"
57 #include "bgpd/bgp_nexthop.h"
58 #include "bgpd/bgp_damp.h"
59 #include "bgpd/bgp_advertise.h"
60 #include "bgpd/bgp_zebra.h"
61 #include "bgpd/bgp_vty.h"
62 #include "bgpd/bgp_mpath.h"
63 #include "bgpd/bgp_nht.h"
64 #include "bgpd/bgp_updgrp.h"
65 #include "bgpd/bgp_label.h"
68 #include "bgpd/rfapi/rfapi_backend.h"
69 #include "bgpd/rfapi/vnc_import_bgp.h"
70 #include "bgpd/rfapi/vnc_export_bgp.h"
72 #include "bgpd/bgp_encap_types.h"
73 #include "bgpd/bgp_encap_tlv.h"
74 #include "bgpd/bgp_evpn.h"
75 #include "bgpd/bgp_evpn_vty.h"
78 /* Extern from bgp_dump.c */
79 extern const char *bgp_origin_str
[];
80 extern const char *bgp_origin_long_str
[];
82 struct bgp_node
*bgp_afi_node_get(struct bgp_table
*table
, afi_t afi
,
83 safi_t safi
, struct prefix
*p
,
84 struct prefix_rd
*prd
)
87 struct bgp_node
*prn
= NULL
;
93 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
94 || (safi
== SAFI_EVPN
)) {
95 prn
= bgp_node_get(table
, (struct prefix
*)prd
);
97 if (prn
->info
== NULL
)
98 prn
->info
= bgp_table_init(afi
, safi
);
100 bgp_unlock_node(prn
);
104 rn
= bgp_node_get(table
, p
);
106 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
107 || (safi
== SAFI_EVPN
))
113 struct bgp_node
*bgp_afi_node_lookup(struct bgp_table
*table
, afi_t afi
,
114 safi_t safi
, struct prefix
*p
,
115 struct prefix_rd
*prd
)
118 struct bgp_node
*prn
= NULL
;
123 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
124 || (safi
== SAFI_EVPN
)) {
125 prn
= bgp_node_lookup(table
, (struct prefix
*)prd
);
129 if (prn
->info
== NULL
) {
130 bgp_unlock_node(prn
);
137 rn
= bgp_node_lookup(table
, p
);
142 /* Allocate bgp_info_extra */
143 static struct bgp_info_extra
*bgp_info_extra_new(void)
145 struct bgp_info_extra
*new;
146 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA
, sizeof(struct bgp_info_extra
));
147 new->label
= MPLS_INVALID_LABEL
;
151 static void bgp_info_extra_free(struct bgp_info_extra
**extra
)
153 if (extra
&& *extra
) {
154 if ((*extra
)->damp_info
)
155 bgp_damp_info_free((*extra
)->damp_info
, 0);
157 (*extra
)->damp_info
= NULL
;
159 XFREE(MTYPE_BGP_ROUTE_EXTRA
, *extra
);
165 /* Get bgp_info extra information for the given bgp_info, lazy allocated
168 struct bgp_info_extra
*bgp_info_extra_get(struct bgp_info
*ri
)
171 ri
->extra
= bgp_info_extra_new();
175 /* Allocate new bgp info structure. */
176 struct bgp_info
*bgp_info_new(void)
178 return XCALLOC(MTYPE_BGP_ROUTE
, sizeof(struct bgp_info
));
181 /* Free bgp route information. */
182 static void bgp_info_free(struct bgp_info
*binfo
)
185 bgp_attr_unintern(&binfo
->attr
);
187 bgp_unlink_nexthop(binfo
);
188 bgp_info_extra_free(&binfo
->extra
);
189 bgp_info_mpath_free(&binfo
->mpath
);
191 peer_unlock(binfo
->peer
); /* bgp_info peer reference */
193 XFREE(MTYPE_BGP_ROUTE
, binfo
);
196 struct bgp_info
*bgp_info_lock(struct bgp_info
*binfo
)
202 struct bgp_info
*bgp_info_unlock(struct bgp_info
*binfo
)
204 assert(binfo
&& binfo
->lock
> 0);
207 if (binfo
->lock
== 0) {
209 zlog_debug ("%s: unlocked and freeing", __func__
);
210 zlog_backtrace (LOG_DEBUG
);
212 bgp_info_free(binfo
);
217 if (binfo
->lock
== 1)
219 zlog_debug ("%s: unlocked to 1", __func__
);
220 zlog_backtrace (LOG_DEBUG
);
227 void bgp_info_add(struct bgp_node
*rn
, struct bgp_info
*ri
)
229 struct bgp_info
*top
;
241 peer_lock(ri
->peer
); /* bgp_info peer reference */
244 /* Do the actual removal of info from RIB, for use by bgp_process
245 completion callback *only* */
246 void bgp_info_reap(struct bgp_node
*rn
, struct bgp_info
*ri
)
249 ri
->next
->prev
= ri
->prev
;
251 ri
->prev
->next
= ri
->next
;
255 bgp_info_mpath_dequeue(ri
);
260 void bgp_info_delete(struct bgp_node
*rn
, struct bgp_info
*ri
)
262 bgp_info_set_flag(rn
, ri
, BGP_INFO_REMOVED
);
263 /* set of previous already took care of pcount */
264 UNSET_FLAG(ri
->flags
, BGP_INFO_VALID
);
267 /* undo the effects of a previous call to bgp_info_delete; typically
268 called when a route is deleted and then quickly re-added before the
269 deletion has been processed */
270 void bgp_info_restore(struct bgp_node
*rn
, struct bgp_info
*ri
)
272 bgp_info_unset_flag(rn
, ri
, BGP_INFO_REMOVED
);
273 /* unset of previous already took care of pcount */
274 SET_FLAG(ri
->flags
, BGP_INFO_VALID
);
277 /* Adjust pcount as required */
278 static void bgp_pcount_adjust(struct bgp_node
*rn
, struct bgp_info
*ri
)
280 struct bgp_table
*table
;
282 assert(rn
&& bgp_node_table(rn
));
283 assert(ri
&& ri
->peer
&& ri
->peer
->bgp
);
285 table
= bgp_node_table(rn
);
287 if (ri
->peer
== ri
->peer
->bgp
->peer_self
)
290 if (!BGP_INFO_COUNTABLE(ri
)
291 && CHECK_FLAG(ri
->flags
, BGP_INFO_COUNTED
)) {
293 UNSET_FLAG(ri
->flags
, BGP_INFO_COUNTED
);
295 /* slight hack, but more robust against errors. */
296 if (ri
->peer
->pcount
[table
->afi
][table
->safi
])
297 ri
->peer
->pcount
[table
->afi
][table
->safi
]--;
300 "%s: Asked to decrement 0 prefix count for peer %s",
301 __func__
, ri
->peer
->host
);
302 zlog_backtrace(LOG_WARNING
);
303 zlog_warn("%s: Please report to Quagga bugzilla",
306 } else if (BGP_INFO_COUNTABLE(ri
)
307 && !CHECK_FLAG(ri
->flags
, BGP_INFO_COUNTED
)) {
308 SET_FLAG(ri
->flags
, BGP_INFO_COUNTED
);
309 ri
->peer
->pcount
[table
->afi
][table
->safi
]++;
313 static int bgp_label_index_differs(struct bgp_info
*ri1
, struct bgp_info
*ri2
)
315 return (!(ri1
->attr
->label_index
== ri2
->attr
->label_index
));
318 /* Set/unset bgp_info flags, adjusting any other state as needed.
319 * This is here primarily to keep prefix-count in check.
321 void bgp_info_set_flag(struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
323 SET_FLAG(ri
->flags
, flag
);
325 /* early bath if we know it's not a flag that changes countability state
327 if (!CHECK_FLAG(flag
,
328 BGP_INFO_VALID
| BGP_INFO_HISTORY
| BGP_INFO_REMOVED
))
331 bgp_pcount_adjust(rn
, ri
);
334 void bgp_info_unset_flag(struct bgp_node
*rn
, struct bgp_info
*ri
,
337 UNSET_FLAG(ri
->flags
, flag
);
339 /* early bath if we know it's not a flag that changes countability state
341 if (!CHECK_FLAG(flag
,
342 BGP_INFO_VALID
| BGP_INFO_HISTORY
| BGP_INFO_REMOVED
))
345 bgp_pcount_adjust(rn
, ri
);
348 /* Get MED value. If MED value is missing and "bgp bestpath
349 missing-as-worst" is specified, treat it as the worst value. */
350 static u_int32_t
bgp_med_value(struct attr
*attr
, struct bgp
*bgp
)
352 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
355 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
362 void bgp_info_path_with_addpath_rx_str(struct bgp_info
*ri
, char *buf
)
364 if (ri
->addpath_rx_id
)
365 sprintf(buf
, "path %s (addpath rxid %d)", ri
->peer
->host
,
368 sprintf(buf
, "path %s", ri
->peer
->host
);
371 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
373 static int bgp_info_cmp(struct bgp
*bgp
, struct bgp_info
*new,
374 struct bgp_info
*exist
, int *paths_eq
,
375 struct bgp_maxpaths_cfg
*mpath_cfg
, int debug
,
376 char *pfx_buf
, afi_t afi
, safi_t safi
)
378 struct attr
*newattr
, *existattr
;
379 bgp_peer_sort_t new_sort
;
380 bgp_peer_sort_t exist_sort
;
382 u_int32_t exist_pref
;
385 u_int32_t new_weight
;
386 u_int32_t exist_weight
;
387 uint32_t newm
, existm
;
388 struct in_addr new_id
;
389 struct in_addr exist_id
;
392 int internal_as_route
;
395 char new_buf
[PATH_ADDPATH_STR_BUFFER
];
396 char exist_buf
[PATH_ADDPATH_STR_BUFFER
];
397 u_int32_t new_mm_seq
;
398 u_int32_t exist_mm_seq
;
405 zlog_debug("%s: new is NULL", pfx_buf
);
410 bgp_info_path_with_addpath_rx_str(new, new_buf
);
414 zlog_debug("%s: %s is the initial bestpath", pfx_buf
,
420 bgp_info_path_with_addpath_rx_str(exist
, exist_buf
);
421 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
422 pfx_buf
, new_buf
, new->flags
, exist_buf
,
427 existattr
= exist
->attr
;
429 /* For EVPN routes, we cannot just go by local vs remote, we have to
430 * look at the MAC mobility sequence number, if present.
432 if (safi
== SAFI_EVPN
) {
433 /* This is an error condition described in RFC 7432 Section
435 * states that in this scenario "the PE MUST alert the operator"
437 * does not state what other action to take. In order to provide
439 * consistency in this scenario we are going to prefer the path
443 if (newattr
->sticky
!= existattr
->sticky
) {
445 prefix2str(&new->net
->p
, pfx_buf
,
447 * PREFIX2STR_BUFFER
);
448 bgp_info_path_with_addpath_rx_str(new, new_buf
);
449 bgp_info_path_with_addpath_rx_str(exist
,
453 if (newattr
->sticky
&& !existattr
->sticky
) {
455 "%s: %s wins over %s due to sticky MAC flag",
456 pfx_buf
, new_buf
, exist_buf
);
460 if (!newattr
->sticky
&& existattr
->sticky
) {
462 "%s: %s loses to %s due to sticky MAC flag",
463 pfx_buf
, new_buf
, exist_buf
);
468 new_mm_seq
= mac_mobility_seqnum(newattr
);
469 exist_mm_seq
= mac_mobility_seqnum(existattr
);
471 if (new_mm_seq
> exist_mm_seq
) {
474 "%s: %s wins over %s due to MM seq %u > %u",
475 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
480 if (new_mm_seq
< exist_mm_seq
) {
483 "%s: %s loses to %s due to MM seq %u < %u",
484 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
490 /* 1. Weight check. */
491 new_weight
= exist_weight
= 0;
493 new_weight
= newattr
->weight
;
494 exist_weight
= existattr
->weight
;
496 if (new_weight
> exist_weight
) {
498 zlog_debug("%s: %s wins over %s due to weight %d > %d",
499 pfx_buf
, new_buf
, exist_buf
, new_weight
,
504 if (new_weight
< exist_weight
) {
506 zlog_debug("%s: %s loses to %s due to weight %d < %d",
507 pfx_buf
, new_buf
, exist_buf
, new_weight
,
512 /* 2. Local preference check. */
513 new_pref
= exist_pref
= bgp
->default_local_pref
;
515 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
516 new_pref
= newattr
->local_pref
;
517 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
518 exist_pref
= existattr
->local_pref
;
520 if (new_pref
> exist_pref
) {
523 "%s: %s wins over %s due to localpref %d > %d",
524 pfx_buf
, new_buf
, exist_buf
, new_pref
,
529 if (new_pref
< exist_pref
) {
532 "%s: %s loses to %s due to localpref %d < %d",
533 pfx_buf
, new_buf
, exist_buf
, new_pref
,
538 /* 3. Local route check. We prefer:
540 * - BGP_ROUTE_AGGREGATE
541 * - BGP_ROUTE_REDISTRIBUTE
543 if (!(new->sub_type
== BGP_ROUTE_NORMAL
)) {
546 "%s: %s wins over %s due to preferred BGP_ROUTE type",
547 pfx_buf
, new_buf
, exist_buf
);
551 if (!(exist
->sub_type
== BGP_ROUTE_NORMAL
)) {
554 "%s: %s loses to %s due to preferred BGP_ROUTE type",
555 pfx_buf
, new_buf
, exist_buf
);
559 /* 4. AS path length check. */
560 if (!bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
)) {
561 int exist_hops
= aspath_count_hops(existattr
->aspath
);
562 int exist_confeds
= aspath_count_confeds(existattr
->aspath
);
564 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
)) {
567 aspath_hops
= aspath_count_hops(newattr
->aspath
);
568 aspath_hops
+= aspath_count_confeds(newattr
->aspath
);
570 if (aspath_hops
< (exist_hops
+ exist_confeds
)) {
573 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
574 pfx_buf
, new_buf
, exist_buf
,
576 (exist_hops
+ exist_confeds
));
580 if (aspath_hops
> (exist_hops
+ exist_confeds
)) {
583 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
584 pfx_buf
, new_buf
, exist_buf
,
586 (exist_hops
+ exist_confeds
));
590 int newhops
= aspath_count_hops(newattr
->aspath
);
592 if (newhops
< exist_hops
) {
595 "%s: %s wins over %s due to aspath hopcount %d < %d",
596 pfx_buf
, new_buf
, exist_buf
,
597 newhops
, exist_hops
);
601 if (newhops
> exist_hops
) {
604 "%s: %s loses to %s due to aspath hopcount %d > %d",
605 pfx_buf
, new_buf
, exist_buf
,
606 newhops
, exist_hops
);
612 /* 5. Origin check. */
613 if (newattr
->origin
< existattr
->origin
) {
615 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
616 pfx_buf
, new_buf
, exist_buf
,
617 bgp_origin_long_str
[newattr
->origin
],
618 bgp_origin_long_str
[existattr
->origin
]);
622 if (newattr
->origin
> existattr
->origin
) {
624 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
625 pfx_buf
, new_buf
, exist_buf
,
626 bgp_origin_long_str
[newattr
->origin
],
627 bgp_origin_long_str
[existattr
->origin
]);
632 internal_as_route
= (aspath_count_hops(newattr
->aspath
) == 0
633 && aspath_count_hops(existattr
->aspath
) == 0);
634 confed_as_route
= (aspath_count_confeds(newattr
->aspath
) > 0
635 && aspath_count_confeds(existattr
->aspath
) > 0
636 && aspath_count_hops(newattr
->aspath
) == 0
637 && aspath_count_hops(existattr
->aspath
) == 0);
639 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
)
640 || (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
) && confed_as_route
)
641 || aspath_cmp_left(newattr
->aspath
, existattr
->aspath
)
642 || aspath_cmp_left_confed(newattr
->aspath
, existattr
->aspath
)
643 || internal_as_route
) {
644 new_med
= bgp_med_value(new->attr
, bgp
);
645 exist_med
= bgp_med_value(exist
->attr
, bgp
);
647 if (new_med
< exist_med
) {
650 "%s: %s wins over %s due to MED %d < %d",
651 pfx_buf
, new_buf
, exist_buf
, new_med
,
656 if (new_med
> exist_med
) {
659 "%s: %s loses to %s due to MED %d > %d",
660 pfx_buf
, new_buf
, exist_buf
, new_med
,
666 /* 7. Peer type check. */
667 new_sort
= new->peer
->sort
;
668 exist_sort
= exist
->peer
->sort
;
670 if (new_sort
== BGP_PEER_EBGP
671 && (exist_sort
== BGP_PEER_IBGP
|| exist_sort
== BGP_PEER_CONFED
)) {
674 "%s: %s wins over %s due to eBGP peer > iBGP peer",
675 pfx_buf
, new_buf
, exist_buf
);
679 if (exist_sort
== BGP_PEER_EBGP
680 && (new_sort
== BGP_PEER_IBGP
|| new_sort
== BGP_PEER_CONFED
)) {
683 "%s: %s loses to %s due to iBGP peer < eBGP peer",
684 pfx_buf
, new_buf
, exist_buf
);
688 /* 8. IGP metric check. */
692 newm
= new->extra
->igpmetric
;
694 existm
= exist
->extra
->igpmetric
;
699 "%s: %s wins over %s due to IGP metric %d < %d",
700 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
707 "%s: %s loses to %s due to IGP metric %d > %d",
708 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
712 /* 9. Same IGP metric. Compare the cluster list length as
713 representative of IGP hops metric. Rewrite the metric value
714 pair (newm, existm) with the cluster list length. Prefer the
715 path with smaller cluster list length. */
716 if (newm
== existm
) {
717 if (peer_sort(new->peer
) == BGP_PEER_IBGP
718 && peer_sort(exist
->peer
) == BGP_PEER_IBGP
719 && (mpath_cfg
== NULL
721 mpath_cfg
->ibgp_flags
,
722 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN
))) {
723 newm
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
724 existm
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
729 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
730 pfx_buf
, new_buf
, exist_buf
,
738 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
739 pfx_buf
, new_buf
, exist_buf
,
746 /* 10. confed-external vs. confed-internal */
747 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
748 if (new_sort
== BGP_PEER_CONFED
749 && exist_sort
== BGP_PEER_IBGP
) {
752 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
753 pfx_buf
, new_buf
, exist_buf
);
757 if (exist_sort
== BGP_PEER_CONFED
758 && new_sort
== BGP_PEER_IBGP
) {
761 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
762 pfx_buf
, new_buf
, exist_buf
);
767 /* 11. Maximum path check. */
768 if (newm
== existm
) {
769 /* If one path has a label but the other does not, do not treat
770 * them as equals for multipath
772 if ((new->extra
&&bgp_is_valid_label(&new->extra
->label
))
774 && bgp_is_valid_label(&exist
->extra
->label
))) {
777 "%s: %s and %s cannot be multipath, one has a label while the other does not",
778 pfx_buf
, new_buf
, exist_buf
);
779 } else if (bgp_flag_check(bgp
,
780 BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
783 * For the two paths, all comparison steps till IGP
785 * have succeeded - including AS_PATH hop count. Since
787 * bestpath as-path multipath-relax' knob is on, we
789 * an exact match of AS_PATH. Thus, mark the paths are
791 * That will trigger both these paths to get into the
799 "%s: %s and %s are equal via multipath-relax",
800 pfx_buf
, new_buf
, exist_buf
);
801 } else if (new->peer
->sort
== BGP_PEER_IBGP
) {
802 if (aspath_cmp(new->attr
->aspath
,
803 exist
->attr
->aspath
)) {
808 "%s: %s and %s are equal via matching aspaths",
809 pfx_buf
, new_buf
, exist_buf
);
811 } else if (new->peer
->as
== exist
->peer
->as
) {
816 "%s: %s and %s are equal via same remote-as",
817 pfx_buf
, new_buf
, exist_buf
);
821 * TODO: If unequal cost ibgp multipath is enabled we can
822 * mark the paths as equal here instead of returning
827 "%s: %s wins over %s after IGP metric comparison",
828 pfx_buf
, new_buf
, exist_buf
);
831 "%s: %s loses to %s after IGP metric comparison",
832 pfx_buf
, new_buf
, exist_buf
);
837 /* 12. If both paths are external, prefer the path that was received
838 first (the oldest one). This step minimizes route-flap, since a
839 newer path won't displace an older one, even if it was the
840 preferred route based on the additional decision criteria below. */
841 if (!bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
842 && new_sort
== BGP_PEER_EBGP
&& exist_sort
== BGP_PEER_EBGP
) {
843 if (CHECK_FLAG(new->flags
, BGP_INFO_SELECTED
)) {
846 "%s: %s wins over %s due to oldest external",
847 pfx_buf
, new_buf
, exist_buf
);
851 if (CHECK_FLAG(exist
->flags
, BGP_INFO_SELECTED
)) {
854 "%s: %s loses to %s due to oldest external",
855 pfx_buf
, new_buf
, exist_buf
);
860 /* 13. Router-ID comparision. */
861 /* If one of the paths is "stale", the corresponding peer router-id will
862 * be 0 and would always win over the other path. If originator id is
863 * used for the comparision, it will decide which path is better.
865 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
866 new_id
.s_addr
= newattr
->originator_id
.s_addr
;
868 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
869 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
870 exist_id
.s_addr
= existattr
->originator_id
.s_addr
;
872 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
874 if (ntohl(new_id
.s_addr
) < ntohl(exist_id
.s_addr
)) {
877 "%s: %s wins over %s due to Router-ID comparison",
878 pfx_buf
, new_buf
, exist_buf
);
882 if (ntohl(new_id
.s_addr
) > ntohl(exist_id
.s_addr
)) {
885 "%s: %s loses to %s due to Router-ID comparison",
886 pfx_buf
, new_buf
, exist_buf
);
890 /* 14. Cluster length comparision. */
891 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
892 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
894 if (new_cluster
< exist_cluster
) {
897 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
898 pfx_buf
, new_buf
, exist_buf
, new_cluster
,
903 if (new_cluster
> exist_cluster
) {
906 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
907 pfx_buf
, new_buf
, exist_buf
, new_cluster
,
912 /* 15. Neighbor address comparision. */
913 /* Do this only if neither path is "stale" as stale paths do not have
914 * valid peer information (as the connection may or may not be up).
916 if (CHECK_FLAG(exist
->flags
, BGP_INFO_STALE
)) {
919 "%s: %s wins over %s due to latter path being STALE",
920 pfx_buf
, new_buf
, exist_buf
);
924 if (CHECK_FLAG(new->flags
, BGP_INFO_STALE
)) {
927 "%s: %s loses to %s due to former path being STALE",
928 pfx_buf
, new_buf
, exist_buf
);
932 /* locally configured routes to advertise do not have su_remote */
933 if (new->peer
->su_remote
== NULL
)
935 if (exist
->peer
->su_remote
== NULL
)
938 ret
= sockunion_cmp(new->peer
->su_remote
, exist
->peer
->su_remote
);
943 "%s: %s loses to %s due to Neighor IP comparison",
944 pfx_buf
, new_buf
, exist_buf
);
951 "%s: %s wins over %s due to Neighor IP comparison",
952 pfx_buf
, new_buf
, exist_buf
);
957 zlog_debug("%s: %s wins over %s due to nothing left to compare",
958 pfx_buf
, new_buf
, exist_buf
);
963 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
964 * is preferred, or 0 if they are the same (usually will only occur if
965 * multipath is enabled
966 * This version is compatible with */
967 int bgp_info_cmp_compatible(struct bgp
*bgp
, struct bgp_info
*new,
968 struct bgp_info
*exist
, char *pfx_buf
, afi_t afi
,
973 ret
= bgp_info_cmp(bgp
, new, exist
, &paths_eq
, NULL
, 0, pfx_buf
, afi
,
987 static enum filter_type
bgp_input_filter(struct peer
*peer
, struct prefix
*p
,
988 struct attr
*attr
, afi_t afi
,
991 struct bgp_filter
*filter
;
993 filter
= &peer
->filter
[afi
][safi
];
995 #define FILTER_EXIST_WARN(F, f, filter) \
996 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
997 zlog_warn("%s: Could not find configured input %s-list %s!", \
998 peer->host, #f, F##_IN_NAME(filter));
1000 if (DISTRIBUTE_IN_NAME(filter
)) {
1001 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
1003 if (access_list_apply(DISTRIBUTE_IN(filter
), p
) == FILTER_DENY
)
1007 if (PREFIX_LIST_IN_NAME(filter
)) {
1008 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
1010 if (prefix_list_apply(PREFIX_LIST_IN(filter
), p
) == PREFIX_DENY
)
1014 if (FILTER_LIST_IN_NAME(filter
)) {
1015 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
1017 if (as_list_apply(FILTER_LIST_IN(filter
), attr
->aspath
)
1022 return FILTER_PERMIT
;
1023 #undef FILTER_EXIST_WARN
1026 static enum filter_type
bgp_output_filter(struct peer
*peer
, struct prefix
*p
,
1027 struct attr
*attr
, afi_t afi
,
1030 struct bgp_filter
*filter
;
1032 filter
= &peer
->filter
[afi
][safi
];
1034 #define FILTER_EXIST_WARN(F, f, filter) \
1035 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1036 zlog_warn("%s: Could not find configured output %s-list %s!", \
1037 peer->host, #f, F##_OUT_NAME(filter));
1039 if (DISTRIBUTE_OUT_NAME(filter
)) {
1040 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
1042 if (access_list_apply(DISTRIBUTE_OUT(filter
), p
) == FILTER_DENY
)
1046 if (PREFIX_LIST_OUT_NAME(filter
)) {
1047 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
1049 if (prefix_list_apply(PREFIX_LIST_OUT(filter
), p
)
1054 if (FILTER_LIST_OUT_NAME(filter
)) {
1055 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
1057 if (as_list_apply(FILTER_LIST_OUT(filter
), attr
->aspath
)
1062 return FILTER_PERMIT
;
1063 #undef FILTER_EXIST_WARN
1066 /* If community attribute includes no_export then return 1. */
1067 static int bgp_community_filter(struct peer
*peer
, struct attr
*attr
)
1069 if (attr
->community
) {
1070 /* NO_ADVERTISE check. */
1071 if (community_include(attr
->community
, COMMUNITY_NO_ADVERTISE
))
1074 /* NO_EXPORT check. */
1075 if (peer
->sort
== BGP_PEER_EBGP
1076 && community_include(attr
->community
, COMMUNITY_NO_EXPORT
))
1079 /* NO_EXPORT_SUBCONFED check. */
1080 if (peer
->sort
== BGP_PEER_EBGP
1081 || peer
->sort
== BGP_PEER_CONFED
)
1082 if (community_include(attr
->community
,
1083 COMMUNITY_NO_EXPORT_SUBCONFED
))
1089 /* Route reflection loop check. */
1090 static int bgp_cluster_filter(struct peer
*peer
, struct attr
*attr
)
1092 struct in_addr cluster_id
;
1094 if (attr
->cluster
) {
1095 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
1096 cluster_id
= peer
->bgp
->cluster_id
;
1098 cluster_id
= peer
->bgp
->router_id
;
1100 if (cluster_loop_check(attr
->cluster
, cluster_id
))
1106 static int bgp_input_modifier(struct peer
*peer
, struct prefix
*p
,
1107 struct attr
*attr
, afi_t afi
, safi_t safi
,
1108 const char *rmap_name
)
1110 struct bgp_filter
*filter
;
1111 struct bgp_info info
;
1112 route_map_result_t ret
;
1113 struct route_map
*rmap
= NULL
;
1115 filter
= &peer
->filter
[afi
][safi
];
1117 /* Apply default weight value. */
1118 if (peer
->weight
[afi
][safi
])
1119 attr
->weight
= peer
->weight
[afi
][safi
];
1122 rmap
= route_map_lookup_by_name(rmap_name
);
1127 if (ROUTE_MAP_IN_NAME(filter
)) {
1128 rmap
= ROUTE_MAP_IN(filter
);
1135 /* Route map apply. */
1137 /* Duplicate current value to new strucutre for modification. */
1141 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1143 /* Apply BGP route map to the attribute. */
1144 ret
= route_map_apply(rmap
, p
, RMAP_BGP
, &info
);
1146 peer
->rmap_type
= 0;
1148 if (ret
== RMAP_DENYMATCH
) {
1149 /* Free newly generated AS path and community by
1151 bgp_attr_flush(attr
);
1158 static int bgp_output_modifier(struct peer
*peer
, struct prefix
*p
,
1159 struct attr
*attr
, afi_t afi
, safi_t safi
,
1160 const char *rmap_name
)
1162 struct bgp_filter
*filter
;
1163 struct bgp_info info
;
1164 route_map_result_t ret
;
1165 struct route_map
*rmap
= NULL
;
1167 filter
= &peer
->filter
[afi
][safi
];
1169 /* Apply default weight value. */
1170 if (peer
->weight
[afi
][safi
])
1171 attr
->weight
= peer
->weight
[afi
][safi
];
1174 rmap
= route_map_lookup_by_name(rmap_name
);
1179 if (ROUTE_MAP_OUT_NAME(filter
)) {
1180 rmap
= ROUTE_MAP_OUT(filter
);
1187 /* Route map apply. */
1189 /* Duplicate current value to new strucutre for modification. */
1193 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1195 /* Apply BGP route map to the attribute. */
1196 ret
= route_map_apply(rmap
, p
, RMAP_BGP
, &info
);
1198 peer
->rmap_type
= 0;
1200 if (ret
== RMAP_DENYMATCH
)
1201 /* caller has multiple error paths with bgp_attr_flush()
1208 /* If this is an EBGP peer with remove-private-AS */
1209 static void bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1210 struct peer
*peer
, struct attr
*attr
)
1212 if (peer
->sort
== BGP_PEER_EBGP
1213 && (peer_af_flag_check(peer
, afi
, safi
,
1214 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)
1215 || peer_af_flag_check(peer
, afi
, safi
,
1216 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)
1217 || peer_af_flag_check(peer
, afi
, safi
,
1218 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)
1219 || peer_af_flag_check(peer
, afi
, safi
,
1220 PEER_FLAG_REMOVE_PRIVATE_AS
))) {
1221 // Take action on the entire aspath
1222 if (peer_af_flag_check(peer
, afi
, safi
,
1223 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)
1224 || peer_af_flag_check(peer
, afi
, safi
,
1225 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
1226 if (peer_af_flag_check(
1228 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1229 attr
->aspath
= aspath_replace_private_asns(
1230 attr
->aspath
, bgp
->as
);
1232 // The entire aspath consists of private ASNs so create
1234 else if (aspath_private_as_check(attr
->aspath
))
1235 attr
->aspath
= aspath_empty_get();
1237 // There are some public and some private ASNs, remove
1240 attr
->aspath
= aspath_remove_private_asns(
1244 // 'all' was not specified so the entire aspath must be private
1246 // for us to do anything
1247 else if (aspath_private_as_check(attr
->aspath
)) {
1248 if (peer_af_flag_check(
1250 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1251 attr
->aspath
= aspath_replace_private_asns(
1252 attr
->aspath
, bgp
->as
);
1254 attr
->aspath
= aspath_empty_get();
1259 /* If this is an EBGP peer with as-override */
1260 static void bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1261 struct peer
*peer
, struct attr
*attr
)
1263 if (peer
->sort
== BGP_PEER_EBGP
1264 && peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
1265 if (aspath_single_asn_check(attr
->aspath
, peer
->as
))
1266 attr
->aspath
= aspath_replace_specific_asn(
1267 attr
->aspath
, peer
->as
, bgp
->as
);
1271 void bgp_attr_add_gshut_community(struct attr
*attr
)
1273 struct community
*old
;
1274 struct community
*new;
1275 struct community
*merge
;
1276 struct community
*gshut
;
1278 old
= attr
->community
;
1279 gshut
= community_str2com("graceful-shutdown");
1282 merge
= community_merge(community_dup(old
), gshut
);
1284 if (old
->refcnt
== 0)
1285 community_free(old
);
1287 new = community_uniq_sort(merge
);
1288 community_free(merge
);
1290 new = community_dup(gshut
);
1293 community_free(gshut
);
1294 attr
->community
= new;
1295 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
);
1297 /* When we add the graceful-shutdown community we must also
1298 * lower the local-preference */
1299 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1300 attr
->local_pref
= BGP_GSHUT_LOCAL_PREF
;
1304 static void subgroup_announce_reset_nhop(u_char family
, struct attr
*attr
)
1306 if (family
== AF_INET
)
1307 attr
->nexthop
.s_addr
= 0;
1308 if (family
== AF_INET6
)
1309 memset(&attr
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1312 int subgroup_announce_check(struct bgp_node
*rn
, struct bgp_info
*ri
,
1313 struct update_subgroup
*subgrp
, struct prefix
*p
,
1316 struct bgp_filter
*filter
;
1319 struct peer
*onlypeer
;
1321 struct attr
*riattr
;
1322 struct peer_af
*paf
;
1323 char buf
[PREFIX_STRLEN
];
1329 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1331 if (DISABLE_BGP_ANNOUNCE
)
1334 afi
= SUBGRP_AFI(subgrp
);
1335 safi
= SUBGRP_SAFI(subgrp
);
1336 peer
= SUBGRP_PEER(subgrp
);
1338 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
))
1339 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1342 filter
= &peer
->filter
[afi
][safi
];
1343 bgp
= SUBGRP_INST(subgrp
);
1344 riattr
= bgp_info_mpath_count(ri
) ? bgp_info_mpath_attr(ri
) : ri
->attr
;
1347 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
)
1348 && ((ri
->type
== ZEBRA_ROUTE_BGP_DIRECT
)
1349 || (ri
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1352 * direct and direct_ext type routes originate internally even
1353 * though they can have peer pointers that reference other
1356 prefix2str(p
, buf
, PREFIX_STRLEN
);
1357 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe",
1363 /* With addpath we may be asked to TX all kinds of paths so make sure
1365 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_VALID
)
1366 || CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
)
1367 || CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
1371 /* If this is not the bestpath then check to see if there is an enabled
1373 * feature that requires us to advertise it */
1374 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
1375 if (!bgp_addpath_tx_path(peer
, afi
, safi
, ri
)) {
1380 /* Aggregate-address suppress check. */
1381 if (ri
->extra
&& ri
->extra
->suppress
)
1382 if (!UNSUPPRESS_MAP_NAME(filter
)) {
1386 /* If it's labeled safi, make sure the route has a valid label. */
1387 if (safi
== SAFI_LABELED_UNICAST
) {
1388 mpls_label_t label
= bgp_adv_label(rn
, ri
, peer
, afi
, safi
);
1389 if (!bgp_is_valid_label(&label
)) {
1390 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1391 zlog_debug("u%" PRIu64
":s%" PRIu64
1392 " %s/%d is filtered - no label (%p)",
1393 subgrp
->update_group
->id
, subgrp
->id
,
1394 inet_ntop(p
->family
, &p
->u
.prefix
,
1395 buf
, SU_ADDRSTRLEN
),
1396 p
->prefixlen
, &label
);
1401 /* Do not send back route to sender. */
1402 if (onlypeer
&& from
== onlypeer
) {
1406 /* Do not send the default route in the BGP table if the neighbor is
1407 * configured for default-originate */
1408 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1409 PEER_FLAG_DEFAULT_ORIGINATE
)) {
1410 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1412 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1416 /* Transparency check. */
1417 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1418 && CHECK_FLAG(from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1423 /* If community is not disabled check the no-export and local. */
1424 if (!transparent
&& bgp_community_filter(peer
, riattr
)) {
1425 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1427 "subgrpannouncecheck: community filter check fail");
1431 /* If the attribute has originator-id and it is same as remote
1433 if (onlypeer
&& riattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)
1434 && (IPV4_ADDR_SAME(&onlypeer
->remote_id
, &riattr
->originator_id
))) {
1435 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1437 "%s [Update:SEND] %s originator-id is same as "
1440 prefix2str(p
, buf
, sizeof(buf
)));
1444 /* ORF prefix-list filter check */
1445 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1446 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1447 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
1448 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1449 if (peer
->orf_plist
[afi
][safi
]) {
1450 if (prefix_list_apply(peer
->orf_plist
[afi
][safi
], p
)
1452 if (bgp_debug_update(NULL
, p
,
1453 subgrp
->update_group
, 0))
1455 "%s [Update:SEND] %s is filtered via ORF",
1463 /* Output filter check. */
1464 if (bgp_output_filter(peer
, p
, riattr
, afi
, safi
) == FILTER_DENY
) {
1465 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1466 zlog_debug("%s [Update:SEND] %s is filtered",
1467 peer
->host
, prefix2str(p
, buf
, sizeof(buf
)));
1471 #ifdef BGP_SEND_ASPATH_CHECK
1472 /* AS path loop check. */
1473 if (onlypeer
&& aspath_loop_check(riattr
->aspath
, onlypeer
->as
)) {
1474 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1476 "%s [Update:SEND] suppress announcement to peer AS %u "
1477 "that is part of AS path.",
1478 onlypeer
->host
, onlypeer
->as
);
1481 #endif /* BGP_SEND_ASPATH_CHECK */
1483 /* If we're a CONFED we need to loop check the CONFED ID too */
1484 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
1485 if (aspath_loop_check(riattr
->aspath
, bgp
->confed_id
)) {
1486 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1488 "%s [Update:SEND] suppress announcement to peer AS %u"
1490 peer
->host
, bgp
->confed_id
);
1495 /* Route-Reflect check. */
1496 if (from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1501 /* IBGP reflection check. */
1502 if (reflect
&& !samepeer_safe
) {
1503 /* A route from a Client peer. */
1504 if (CHECK_FLAG(from
->af_flags
[afi
][safi
],
1505 PEER_FLAG_REFLECTOR_CLIENT
)) {
1506 /* Reflect to all the Non-Client peers and also to the
1507 Client peers other than the originator. Originator
1509 is already done. So there is noting to do. */
1510 /* no bgp client-to-client reflection check. */
1511 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
1512 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1513 PEER_FLAG_REFLECTOR_CLIENT
))
1516 /* A route from a Non-client peer. Reflect to all other
1518 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1519 PEER_FLAG_REFLECTOR_CLIENT
))
1524 /* For modify attribute, copy it to temporary structure. */
1525 bgp_attr_dup(attr
, riattr
);
1527 /* If local-preference is not set. */
1528 if ((peer
->sort
== BGP_PEER_IBGP
|| peer
->sort
== BGP_PEER_CONFED
)
1529 && (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)))) {
1530 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1531 attr
->local_pref
= bgp
->default_local_pref
;
1534 /* If originator-id is not set and the route is to be reflected,
1535 set the originator id */
1537 && (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)))) {
1538 IPV4_ADDR_COPY(&(attr
->originator_id
), &(from
->remote_id
));
1539 SET_FLAG(attr
->flag
, BGP_ATTR_ORIGINATOR_ID
);
1542 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
1544 if (peer
->sort
== BGP_PEER_EBGP
1545 && attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)) {
1546 if (from
!= bgp
->peer_self
&& !transparent
1547 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1548 PEER_FLAG_MED_UNCHANGED
))
1550 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
));
1553 /* Since the nexthop attribute can vary per peer, it is not explicitly
1555 * in announce check, only certain flags and length (or number of
1557 * -- for IPv6/MP_REACH) are set here in order to guide the update
1559 * code in setting the nexthop(s) on a per peer basis in
1561 * Typically, the source nexthop in the attribute is preserved but in
1563 * scenarios where we know it will always be overwritten, we reset the
1564 * nexthop to "0" in an attempt to achieve better Update packing. An
1565 * example of this is when a prefix from each of 2 IBGP peers needs to
1567 * announced to an EBGP peer (and they have the same attributes barring
1571 SET_FLAG(attr
->rmap_change_flags
, BATTR_REFLECTED
);
1573 #define NEXTHOP_IS_V6 \
1574 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
1575 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
1576 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
1577 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1579 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
1581 * the peer (group) is configured to receive link-local nexthop
1583 * and it is available in the prefix OR we're not reflecting the route
1585 * the peer (group) to whom we're going to announce is on a shared
1587 * and this is either a self-originated route or the peer is EBGP.
1589 if (NEXTHOP_IS_V6
) {
1590 attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1591 if ((CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1592 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)
1593 && IN6_IS_ADDR_LINKLOCAL(&attr
->mp_nexthop_local
))
1594 || (!reflect
&& peer
->shared_network
1595 && (from
== bgp
->peer_self
1596 || peer
->sort
== BGP_PEER_EBGP
))) {
1597 attr
->mp_nexthop_len
=
1598 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
1601 /* Clear off link-local nexthop in source, whenever it is not
1603 * ensure more prefixes share the same attribute for
1606 if (!(CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1607 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)))
1608 memset(&attr
->mp_nexthop_local
, 0, IPV6_MAX_BYTELEN
);
1611 bgp_peer_remove_private_as(bgp
, afi
, safi
, peer
, attr
);
1612 bgp_peer_as_override(bgp
, afi
, safi
, peer
, attr
);
1614 /* Route map & unsuppress-map apply. */
1615 if (ROUTE_MAP_OUT_NAME(filter
) || (ri
->extra
&& ri
->extra
->suppress
)) {
1616 struct bgp_info info
;
1617 struct bgp_info_extra dummy_info_extra
;
1618 struct attr dummy_attr
;
1624 memcpy(&dummy_info_extra
, ri
->extra
,
1625 sizeof(struct bgp_info_extra
));
1626 info
.extra
= &dummy_info_extra
;
1629 /* don't confuse inbound and outbound setting */
1630 RESET_FLAG(attr
->rmap_change_flags
);
1633 * The route reflector is not allowed to modify the attributes
1634 * of the reflected IBGP routes unless explicitly allowed.
1636 if ((from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1637 && !bgp_flag_check(bgp
,
1638 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
1639 bgp_attr_dup(&dummy_attr
, attr
);
1640 info
.attr
= &dummy_attr
;
1643 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1645 if (ri
->extra
&& ri
->extra
->suppress
)
1646 ret
= route_map_apply(UNSUPPRESS_MAP(filter
), p
,
1649 ret
= route_map_apply(ROUTE_MAP_OUT(filter
), p
,
1652 peer
->rmap_type
= 0;
1654 if (ret
== RMAP_DENYMATCH
) {
1655 bgp_attr_flush(attr
);
1660 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
)) {
1661 if (peer
->sort
== BGP_PEER_IBGP
|| peer
->sort
== BGP_PEER_CONFED
) {
1662 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1663 attr
->local_pref
= BGP_GSHUT_LOCAL_PREF
;
1665 bgp_attr_add_gshut_community(attr
);
1669 /* After route-map has been applied, we check to see if the nexthop to
1670 * be carried in the attribute (that is used for the announcement) can
1671 * be cleared off or not. We do this in all cases where we would be
1672 * setting the nexthop to "ourselves". For IPv6, we only need to
1674 * the global nexthop here; the link-local nexthop would have been
1676 * already, and if not, it is required by the update formation code.
1677 * Also see earlier comments in this function.
1680 * If route-map has performed some operation on the nexthop or the peer
1681 * configuration says to pass it unchanged, we cannot reset the nexthop
1682 * here, so only attempt to do it if these aren't true. Note that the
1683 * route-map handler itself might have cleared the nexthop, if for
1685 * it is configured as 'peer-address'.
1687 if (!bgp_rmap_nhop_changed(attr
->rmap_change_flags
,
1688 riattr
->rmap_change_flags
)
1690 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1691 PEER_FLAG_NEXTHOP_UNCHANGED
)) {
1692 /* We can reset the nexthop, if setting (or forcing) it to
1694 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1695 PEER_FLAG_NEXTHOP_SELF
)
1696 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1697 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
1699 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1700 PEER_FLAG_FORCE_NEXTHOP_SELF
))
1701 subgroup_announce_reset_nhop(
1702 (peer_cap_enhe(peer
, afi
, safi
)
1706 } else if (peer
->sort
== BGP_PEER_EBGP
) {
1707 /* Can also reset the nexthop if announcing to EBGP, but
1709 * no peer in the subgroup is on a shared subnet.
1710 * Note: 3rd party nexthop currently implemented for
1713 SUBGRP_FOREACH_PEER(subgrp
, paf
)
1715 if (bgp_multiaccess_check_v4(riattr
->nexthop
,
1720 subgroup_announce_reset_nhop(
1721 (peer_cap_enhe(peer
, afi
, safi
)
1726 /* If IPv6/MP and nexthop does not have any override and happens
1728 * be a link-local address, reset it so that we don't pass along
1730 * source's link-local IPv6 address to recipients who may not be
1732 * the same interface.
1734 if (p
->family
== AF_INET6
|| peer_cap_enhe(peer
, afi
, safi
)) {
1735 if (IN6_IS_ADDR_LINKLOCAL(&attr
->mp_nexthop_global
))
1736 subgroup_announce_reset_nhop(AF_INET6
, attr
);
1743 void bgp_best_selection(struct bgp
*bgp
, struct bgp_node
*rn
,
1744 struct bgp_maxpaths_cfg
*mpath_cfg
,
1745 struct bgp_info_pair
*result
, afi_t afi
, safi_t safi
)
1747 struct bgp_info
*new_select
;
1748 struct bgp_info
*old_select
;
1749 struct bgp_info
*ri
;
1750 struct bgp_info
*ri1
;
1751 struct bgp_info
*ri2
;
1752 struct bgp_info
*nextri
= NULL
;
1753 int paths_eq
, do_mpath
, debug
;
1754 struct list mp_list
;
1755 char pfx_buf
[PREFIX2STR_BUFFER
];
1756 char path_buf
[PATH_ADDPATH_STR_BUFFER
];
1758 bgp_mp_list_init(&mp_list
);
1760 (mpath_cfg
->maxpaths_ebgp
> 1 || mpath_cfg
->maxpaths_ibgp
> 1);
1762 debug
= bgp_debug_bestpath(&rn
->p
);
1765 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
1767 /* bgp deterministic-med */
1769 if (bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
1771 /* Clear BGP_INFO_DMED_SELECTED for all paths */
1772 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1773 bgp_info_unset_flag(rn
, ri1
, BGP_INFO_DMED_SELECTED
);
1775 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
) {
1776 if (CHECK_FLAG(ri1
->flags
, BGP_INFO_DMED_CHECK
))
1778 if (BGP_INFO_HOLDDOWN(ri1
))
1780 if (ri1
->peer
&& ri1
->peer
!= bgp
->peer_self
)
1781 if (ri1
->peer
->status
!= Established
)
1786 for (ri2
= ri1
->next
; ri2
; ri2
= ri2
->next
) {
1787 if (CHECK_FLAG(ri2
->flags
,
1788 BGP_INFO_DMED_CHECK
))
1790 if (BGP_INFO_HOLDDOWN(ri2
))
1793 && ri2
->peer
!= bgp
->peer_self
1796 PEER_STATUS_NSF_WAIT
))
1797 if (ri2
->peer
->status
1801 if (aspath_cmp_left(ri1
->attr
->aspath
,
1803 || aspath_cmp_left_confed(
1805 ri2
->attr
->aspath
)) {
1806 if (bgp_info_cmp(bgp
, ri2
,
1812 bgp_info_unset_flag(
1814 BGP_INFO_DMED_SELECTED
);
1820 BGP_INFO_DMED_CHECK
);
1824 bgp_info_set_flag(rn
, new_select
, BGP_INFO_DMED_CHECK
);
1825 bgp_info_set_flag(rn
, new_select
,
1826 BGP_INFO_DMED_SELECTED
);
1829 bgp_info_path_with_addpath_rx_str(new_select
,
1831 zlog_debug("%s: %s is the bestpath from AS %d",
1833 aspath_get_first_as(
1834 new_select
->attr
->aspath
));
1839 /* Check old selected route and new selected route. */
1842 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1);
1844 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
))
1847 if (BGP_INFO_HOLDDOWN(ri
)) {
1848 /* reap REMOVED routes, if needs be
1849 * selected route must stay for a while longer though
1851 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)
1852 && (ri
!= old_select
))
1853 bgp_info_reap(rn
, ri
);
1858 if (ri
->peer
&& ri
->peer
!= bgp
->peer_self
1859 && !CHECK_FLAG(ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1860 if (ri
->peer
->status
!= Established
)
1863 if (bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
1864 && (!CHECK_FLAG(ri
->flags
, BGP_INFO_DMED_SELECTED
))) {
1865 bgp_info_unset_flag(rn
, ri
, BGP_INFO_DMED_CHECK
);
1869 bgp_info_unset_flag(rn
, ri
, BGP_INFO_DMED_CHECK
);
1871 if (bgp_info_cmp(bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
,
1872 debug
, pfx_buf
, afi
, safi
)) {
1877 /* Now that we know which path is the bestpath see if any of the other
1879 * qualify as multipaths
1883 bgp_info_path_with_addpath_rx_str(new_select
, path_buf
);
1885 sprintf(path_buf
, "NONE");
1887 "%s: After path selection, newbest is %s oldbest was %s",
1889 old_select
? old_select
->peer
->host
: "NONE");
1892 if (do_mpath
&& new_select
) {
1893 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1);
1897 bgp_info_path_with_addpath_rx_str(ri
, path_buf
);
1899 if (ri
== new_select
) {
1902 "%s: %s is the bestpath, add to the multipath list",
1904 bgp_mp_list_add(&mp_list
, ri
);
1908 if (BGP_INFO_HOLDDOWN(ri
))
1911 if (ri
->peer
&& ri
->peer
!= bgp
->peer_self
1912 && !CHECK_FLAG(ri
->peer
->sflags
,
1913 PEER_STATUS_NSF_WAIT
))
1914 if (ri
->peer
->status
!= Established
)
1917 if (!bgp_info_nexthop_cmp(ri
, new_select
)) {
1920 "%s: %s has the same nexthop as the bestpath, skip it",
1925 bgp_info_cmp(bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
,
1926 debug
, pfx_buf
, afi
, safi
);
1931 "%s: %s is equivalent to the bestpath, add to the multipath list",
1933 bgp_mp_list_add(&mp_list
, ri
);
1938 bgp_info_mpath_update(rn
, new_select
, old_select
, &mp_list
, mpath_cfg
);
1939 bgp_info_mpath_aggregate_update(new_select
, old_select
);
1940 bgp_mp_list_clear(&mp_list
);
1942 result
->old
= old_select
;
1943 result
->new = new_select
;
1949 * A new route/change in bestpath of an existing route. Evaluate the path
1950 * for advertisement to the subgroup.
1952 int subgroup_process_announce_selected(struct update_subgroup
*subgrp
,
1953 struct bgp_info
*selected
,
1954 struct bgp_node
*rn
,
1955 u_int32_t addpath_tx_id
)
1958 struct peer
*onlypeer
;
1964 afi
= SUBGRP_AFI(subgrp
);
1965 safi
= SUBGRP_SAFI(subgrp
);
1966 onlypeer
= ((SUBGRP_PCOUNT(subgrp
) == 1) ? (SUBGRP_PFIRST(subgrp
))->peer
1969 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1970 if (onlypeer
&& CHECK_FLAG(onlypeer
->af_sflags
[afi
][safi
],
1971 PEER_STATUS_ORF_WAIT_REFRESH
))
1974 memset(&attr
, 0, sizeof(struct attr
));
1975 /* It's initialized in bgp_announce_check() */
1977 /* Announcement to the subgroup. If the route is filtered withdraw it.
1980 if (subgroup_announce_check(rn
, selected
, subgrp
, p
, &attr
))
1981 bgp_adj_out_set_subgroup(rn
, subgrp
, &attr
, selected
);
1983 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1,
1984 selected
->addpath_tx_id
);
1987 /* If selected is NULL we must withdraw the path using addpath_tx_id */
1989 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, addpath_tx_id
);
1996 * Clear IGP changed flag and attribute changed flag for a route (all paths).
1997 * This is called at the end of route processing.
1999 void bgp_zebra_clear_route_change_flags(struct bgp_node
*rn
)
2001 struct bgp_info
*ri
;
2003 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
2004 if (BGP_INFO_HOLDDOWN(ri
))
2006 UNSET_FLAG(ri
->flags
, BGP_INFO_IGP_CHANGED
);
2007 UNSET_FLAG(ri
->flags
, BGP_INFO_ATTR_CHANGED
);
2012 * Has the route changed from the RIB's perspective? This is invoked only
2013 * if the route selection returns the same best route as earlier - to
2014 * determine if we need to update zebra or not.
2016 int bgp_zebra_has_route_changed(struct bgp_node
*rn
, struct bgp_info
*selected
)
2018 struct bgp_info
*mpinfo
;
2020 /* If this is multipath, check all selected paths for any nexthop change
2022 * attribute change. Some attribute changes (e.g., community) aren't of
2023 * relevance to the RIB, but we'll update zebra to ensure we handle the
2024 * case of BGP nexthop change. This is the behavior when the best path
2026 * an attribute change anyway.
2028 if (CHECK_FLAG(selected
->flags
, BGP_INFO_IGP_CHANGED
)
2029 || CHECK_FLAG(selected
->flags
, BGP_INFO_MULTIPATH_CHG
))
2032 /* If this is multipath, check all selected paths for any nexthop change
2034 for (mpinfo
= bgp_info_mpath_first(selected
); mpinfo
;
2035 mpinfo
= bgp_info_mpath_next(mpinfo
)) {
2036 if (CHECK_FLAG(mpinfo
->flags
, BGP_INFO_IGP_CHANGED
)
2037 || CHECK_FLAG(mpinfo
->flags
, BGP_INFO_ATTR_CHANGED
))
2041 /* Nothing has changed from the RIB's perspective. */
2045 struct bgp_process_queue
{
2047 STAILQ_HEAD(, bgp_node
)pqueue
;
2048 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2050 unsigned int queued
;
2053 static void bgp_process_main_one(struct bgp
*bgp
, struct bgp_node
*rn
,
2054 afi_t afi
, safi_t safi
)
2056 struct prefix
*p
= &rn
->p
;
2057 struct bgp_info
*new_select
;
2058 struct bgp_info
*old_select
;
2059 struct bgp_info_pair old_and_new
;
2061 /* Is it end of initial update? (after startup) */
2063 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
2064 sizeof(bgp
->update_delay_zebra_resume_time
));
2066 bgp
->main_zebra_update_hold
= 0;
2067 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
2068 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
2069 if (bgp_fibupd_safi(safi
))
2070 bgp_zebra_announce_table(bgp
, afi
,
2073 bgp
->main_peers_update_hold
= 0;
2075 bgp_start_routeadv(bgp
);
2079 /* Best path selection. */
2080 bgp_best_selection(bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
,
2082 old_select
= old_and_new
.old
;
2083 new_select
= old_and_new
.new;
2085 /* Do we need to allocate or free labels?
2086 * Right now, since we only deal with per-prefix labels, it is not
2088 * to do this upon changes to best path except of the label index
2091 if (bgp
->allocate_mpls_labels
[afi
][safi
]) {
2094 || bgp_label_index_differs(new_select
, old_select
)
2095 || new_select
->sub_type
!= old_select
->sub_type
) {
2096 if (new_select
->sub_type
== BGP_ROUTE_STATIC
2097 && new_select
->attr
->flag
2099 BGP_ATTR_PREFIX_SID
)
2100 && new_select
->attr
->label_index
2101 != BGP_INVALID_LABEL_INDEX
) {
2104 BGP_NODE_REGISTERED_FOR_LABEL
))
2105 bgp_unregister_for_label(rn
);
2106 label_ntop(MPLS_IMP_NULL_LABEL
, 1,
2108 bgp_set_valid_label(&rn
->local_label
);
2110 bgp_register_for_label(rn
, new_select
);
2112 } else if (CHECK_FLAG(rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
)) {
2113 bgp_unregister_for_label(rn
);
2115 } else if (CHECK_FLAG(rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
)) {
2116 bgp_unregister_for_label(rn
);
2119 /* If best route remains the same and this is not due to user-initiated
2120 * clear, see exactly what needs to be done.
2123 if (old_select
&& old_select
== new_select
2124 && !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
)
2125 && !CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
)
2126 && !bgp
->addpath_tx_used
[afi
][safi
]) {
2127 if (bgp_zebra_has_route_changed(rn
, old_select
)) {
2129 vnc_import_bgp_add_route(bgp
, p
, old_select
);
2130 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
2132 if (bgp_fibupd_safi(safi
)
2133 && !bgp_option_check(BGP_OPT_NO_FIB
)
2134 && new_select
->type
== ZEBRA_ROUTE_BGP
2135 && new_select
->sub_type
== BGP_ROUTE_NORMAL
)
2136 bgp_zebra_announce(rn
, p
, old_select
, bgp
, afi
,
2139 UNSET_FLAG(old_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
2140 bgp_zebra_clear_route_change_flags(rn
);
2142 /* If there is a change of interest to peers, reannounce the
2144 if (CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
)
2145 || CHECK_FLAG(rn
->flags
, BGP_NODE_LABEL_CHANGED
)) {
2146 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2148 /* unicast routes must also be annouced to
2149 * labeled-unicast update-groups */
2150 if (safi
== SAFI_UNICAST
)
2151 group_announce_route(bgp
, afi
,
2152 SAFI_LABELED_UNICAST
, rn
,
2155 UNSET_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
);
2156 UNSET_FLAG(rn
->flags
, BGP_NODE_LABEL_CHANGED
);
2159 UNSET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2163 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2165 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
2167 /* bestpath has changed; bump version */
2168 if (old_select
|| new_select
) {
2169 bgp_bump_version(rn
);
2171 if (!bgp
->t_rmap_def_originate_eval
) {
2175 update_group_refresh_default_originate_route_map
,
2176 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
,
2177 &bgp
->t_rmap_def_originate_eval
);
2182 bgp_info_unset_flag(rn
, old_select
, BGP_INFO_SELECTED
);
2184 bgp_info_set_flag(rn
, new_select
, BGP_INFO_SELECTED
);
2185 bgp_info_unset_flag(rn
, new_select
, BGP_INFO_ATTR_CHANGED
);
2186 UNSET_FLAG(new_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
2190 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2191 if (old_select
!= new_select
) {
2193 vnc_import_bgp_exterior_del_route(bgp
, p
,
2195 vnc_import_bgp_del_route(bgp
, p
, old_select
);
2198 vnc_import_bgp_exterior_add_route(bgp
, p
,
2200 vnc_import_bgp_add_route(bgp
, p
, new_select
);
2206 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2208 /* unicast routes must also be annouced to labeled-unicast update-groups
2210 if (safi
== SAFI_UNICAST
)
2211 group_announce_route(bgp
, afi
, SAFI_LABELED_UNICAST
, rn
,
2215 if (bgp_fibupd_safi(safi
) && (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
2216 && !bgp_option_check(BGP_OPT_NO_FIB
)) {
2217 if (new_select
&& new_select
->type
== ZEBRA_ROUTE_BGP
2218 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
2219 || new_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
2220 bgp_zebra_announce(rn
, p
, new_select
, bgp
, afi
, safi
);
2222 /* Withdraw the route from the kernel. */
2223 if (old_select
&& old_select
->type
== ZEBRA_ROUTE_BGP
2224 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
2225 || old_select
->sub_type
== BGP_ROUTE_AGGREGATE
))
2226 bgp_zebra_withdraw(p
, old_select
, safi
);
2230 /* Clear any route change flags. */
2231 bgp_zebra_clear_route_change_flags(rn
);
2233 /* Reap old select bgp_info, if it has been removed */
2234 if (old_select
&& CHECK_FLAG(old_select
->flags
, BGP_INFO_REMOVED
))
2235 bgp_info_reap(rn
, old_select
);
2237 UNSET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2241 static wq_item_status
bgp_process_wq(struct work_queue
*wq
, void *data
)
2243 struct bgp_process_queue
*pqnode
= data
;
2244 struct bgp
*bgp
= pqnode
->bgp
;
2245 struct bgp_table
*table
;
2246 struct bgp_node
*rn
, *nrn
;
2249 if (CHECK_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
)) {
2250 bgp_process_main_one(bgp
, NULL
, 0, 0);
2255 STAILQ_FOREACH_SAFE(rn
, &pqnode
->pqueue
, pq
, nrn
) {
2256 table
= bgp_node_table(rn
);
2258 bgp_process_main_one(bgp
, rn
, table
->afi
, table
->safi
);
2260 bgp_unlock_node(rn
);
2261 bgp_table_unlock(table
);
2267 static void bgp_processq_del(struct work_queue
*wq
, void *data
)
2269 struct bgp_process_queue
*pqnode
= data
;
2271 bgp_unlock(pqnode
->bgp
);
2273 XFREE(MTYPE_BGP_PROCESS_QUEUE
, pqnode
);
2276 void bgp_process_queue_init(void)
2278 if (!bm
->process_main_queue
) {
2279 bm
->process_main_queue
=
2280 work_queue_new(bm
->master
, "process_main_queue");
2282 if (!bm
->process_main_queue
) {
2283 zlog_err("%s: Failed to allocate work queue", __func__
);
2288 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_wq
;
2289 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2290 bm
->process_main_queue
->spec
.max_retries
= 0;
2291 bm
->process_main_queue
->spec
.hold
= 50;
2292 /* Use a higher yield value of 50ms for main queue processing */
2293 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2296 static struct bgp_process_queue
*bgp_process_queue_work(struct work_queue
*wq
,
2299 struct bgp_process_queue
*pqnode
;
2301 pqnode
= XCALLOC(MTYPE_BGP_PROCESS_QUEUE
, sizeof(struct bgp_process_queue
));
2303 /* unlocked in bgp_processq_del */
2304 pqnode
->bgp
= bgp_lock(bgp
);
2305 STAILQ_INIT(&pqnode
->pqueue
);
2307 work_queue_add(wq
, pqnode
);
2312 void bgp_process(struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2314 #define ARBITRARY_PROCESS_QLEN 10000
2315 struct work_queue
*wq
= bm
->process_main_queue
;
2316 struct bgp_process_queue
*pqnode
;
2318 /* already scheduled for processing? */
2319 if (CHECK_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2325 /* Add route nodes to an existing work queue item until reaching the
2326 limit only if is from the same BGP view and it's not an EOIU marker */
2327 if (work_queue_item_count(wq
)) {
2328 struct work_queue_item
*item
= work_queue_last_item(wq
);
2329 pqnode
= item
->data
;
2331 if (CHECK_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
) ||
2332 pqnode
->bgp
!= bgp
|| pqnode
->queued
>= ARBITRARY_PROCESS_QLEN
)
2333 pqnode
= bgp_process_queue_work(wq
, bgp
);
2335 pqnode
= bgp_process_queue_work(wq
, bgp
);
2337 /* all unlocked in bgp_process_wq */
2338 bgp_table_lock(bgp_node_table(rn
));
2340 SET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2343 STAILQ_INSERT_TAIL(&pqnode
->pqueue
, rn
, pq
);
2349 void bgp_add_eoiu_mark(struct bgp
*bgp
)
2351 struct bgp_process_queue
*pqnode
;
2353 if (bm
->process_main_queue
== NULL
)
2356 pqnode
= bgp_process_queue_work(bm
->process_main_queue
, bgp
);
2358 SET_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
);
2361 static int bgp_maximum_prefix_restart_timer(struct thread
*thread
)
2365 peer
= THREAD_ARG(thread
);
2366 peer
->t_pmax_restart
= NULL
;
2368 if (bgp_debug_neighbor_events(peer
))
2370 "%s Maximum-prefix restart timer expired, restore peering",
2373 peer_clear(peer
, NULL
);
2378 int bgp_maximum_prefix_overflow(struct peer
*peer
, afi_t afi
, safi_t safi
,
2382 iana_safi_t pkt_safi
;
2384 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2387 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
]) {
2388 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2389 PEER_STATUS_PREFIX_LIMIT
)
2394 "%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2396 afi_safi_print(afi
, safi
), peer
->host
,
2397 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2398 SET_FLAG(peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2400 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
2401 PEER_FLAG_MAX_PREFIX_WARNING
))
2404 /* Convert AFI, SAFI to values for packet. */
2405 pkt_afi
= afi_int2iana(afi
);
2406 pkt_safi
= safi_int2iana(safi
);
2410 ndata
[0] = (pkt_afi
>> 8);
2412 ndata
[2] = pkt_safi
;
2413 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2414 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2415 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2416 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2418 SET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2419 bgp_notify_send_with_data(peer
, BGP_NOTIFY_CEASE
,
2420 BGP_NOTIFY_CEASE_MAX_PREFIX
,
2424 /* Dynamic peers will just close their connection. */
2425 if (peer_dynamic_neighbor(peer
))
2428 /* restart timer start */
2429 if (peer
->pmax_restart
[afi
][safi
]) {
2430 peer
->v_pmax_restart
=
2431 peer
->pmax_restart
[afi
][safi
] * 60;
2433 if (bgp_debug_neighbor_events(peer
))
2435 "%s Maximum-prefix restart timer started for %d secs",
2436 peer
->host
, peer
->v_pmax_restart
);
2438 BGP_TIMER_ON(peer
->t_pmax_restart
,
2439 bgp_maximum_prefix_restart_timer
,
2440 peer
->v_pmax_restart
);
2445 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2446 PEER_STATUS_PREFIX_LIMIT
);
2448 if (peer
->pcount
[afi
][safi
]
2449 > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100)) {
2450 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2451 PEER_STATUS_PREFIX_THRESHOLD
)
2456 "%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2457 afi_safi_print(afi
, safi
), peer
->host
,
2458 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2459 SET_FLAG(peer
->af_sflags
[afi
][safi
],
2460 PEER_STATUS_PREFIX_THRESHOLD
);
2462 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2463 PEER_STATUS_PREFIX_THRESHOLD
);
2467 /* Unconditionally remove the route from the RIB, without taking
2468 * damping into consideration (eg, because the session went down)
2470 static void bgp_rib_remove(struct bgp_node
*rn
, struct bgp_info
*ri
,
2471 struct peer
*peer
, afi_t afi
, safi_t safi
)
2473 bgp_aggregate_decrement(peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2475 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
2476 bgp_info_delete(rn
, ri
); /* keep historical info */
2478 bgp_process(peer
->bgp
, rn
, afi
, safi
);
2481 static void bgp_rib_withdraw(struct bgp_node
*rn
, struct bgp_info
*ri
,
2482 struct peer
*peer
, afi_t afi
, safi_t safi
,
2483 struct prefix_rd
*prd
)
2485 int status
= BGP_DAMP_NONE
;
2487 /* apply dampening, if result is suppressed, we'll be retaining
2488 * the bgp_info in the RIB for historical reference.
2490 if (CHECK_FLAG(peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2491 && peer
->sort
== BGP_PEER_EBGP
)
2492 if ((status
= bgp_damp_withdraw(ri
, rn
, afi
, safi
, 0))
2493 == BGP_DAMP_SUPPRESSED
) {
2494 bgp_aggregate_decrement(peer
->bgp
, &rn
->p
, ri
, afi
,
2500 if (safi
== SAFI_MPLS_VPN
) {
2501 struct bgp_node
*prn
= NULL
;
2502 struct bgp_table
*table
= NULL
;
2504 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
],
2505 (struct prefix
*)prd
);
2507 table
= (struct bgp_table
*)(prn
->info
);
2509 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2510 peer
->bgp
, prd
, table
, &rn
->p
, ri
);
2512 bgp_unlock_node(prn
);
2514 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2515 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
2517 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, ri
);
2518 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
,
2524 /* If this is an EVPN route, process for un-import. */
2525 if (safi
== SAFI_EVPN
)
2526 bgp_evpn_unimport_route(peer
->bgp
, afi
, safi
, &rn
->p
, ri
);
2528 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
2531 struct bgp_info
*info_make(int type
, int sub_type
, u_short instance
,
2532 struct peer
*peer
, struct attr
*attr
,
2533 struct bgp_node
*rn
)
2535 struct bgp_info
*new;
2537 /* Make new BGP info. */
2538 new = XCALLOC(MTYPE_BGP_ROUTE
, sizeof(struct bgp_info
));
2540 new->instance
= instance
;
2541 new->sub_type
= sub_type
;
2544 new->uptime
= bgp_clock();
2546 new->addpath_tx_id
= ++peer
->bgp
->addpath_tx_id
;
2550 static void overlay_index_update(struct attr
*attr
,
2551 struct eth_segment_id
*eth_s_id
,
2552 union gw_addr
*gw_ip
)
2557 if (eth_s_id
== NULL
) {
2558 memset(&(attr
->evpn_overlay
.eth_s_id
), 0,
2559 sizeof(struct eth_segment_id
));
2561 memcpy(&(attr
->evpn_overlay
.eth_s_id
), eth_s_id
,
2562 sizeof(struct eth_segment_id
));
2564 if (gw_ip
== NULL
) {
2565 memset(&(attr
->evpn_overlay
.gw_ip
), 0, sizeof(union gw_addr
));
2567 memcpy(&(attr
->evpn_overlay
.gw_ip
), gw_ip
,
2568 sizeof(union gw_addr
));
2572 static bool overlay_index_equal(afi_t afi
, struct bgp_info
*info
,
2573 struct eth_segment_id
*eth_s_id
,
2574 union gw_addr
*gw_ip
)
2576 struct eth_segment_id
*info_eth_s_id
, *info_eth_s_id_remote
;
2577 union gw_addr
*info_gw_ip
, *info_gw_ip_remote
;
2580 if (afi
!= AFI_L2VPN
)
2583 memset(&temp
, 0, 16);
2584 info_eth_s_id
= (struct eth_segment_id
*)&temp
;
2585 info_gw_ip
= (union gw_addr
*)&temp
;
2586 if (eth_s_id
== NULL
&& gw_ip
== NULL
)
2589 info_eth_s_id
= &(info
->attr
->evpn_overlay
.eth_s_id
);
2590 info_gw_ip
= &(info
->attr
->evpn_overlay
.gw_ip
);
2593 info_gw_ip_remote
= (union gw_addr
*)&temp
;
2595 info_gw_ip_remote
= gw_ip
;
2596 if (eth_s_id
== NULL
)
2597 info_eth_s_id_remote
= (struct eth_segment_id
*)&temp
;
2599 info_eth_s_id_remote
= eth_s_id
;
2600 if (!memcmp(info_gw_ip
, info_gw_ip_remote
, sizeof(union gw_addr
)))
2602 return !memcmp(info_eth_s_id
, info_eth_s_id_remote
,
2603 sizeof(struct eth_segment_id
));
2606 /* Check if received nexthop is valid or not. */
2607 static int bgp_update_martian_nexthop(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
2612 /* Only validated for unicast and multicast currently. */
2613 /* Also valid for EVPN where the nexthop is an IP address. */
2614 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
&& safi
!= SAFI_EVPN
)
2617 /* If NEXT_HOP is present, validate it. */
2618 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
)) {
2619 if (attr
->nexthop
.s_addr
== 0
2620 || IPV4_CLASS_DE(ntohl(attr
->nexthop
.s_addr
))
2621 || bgp_nexthop_self(bgp
, attr
->nexthop
))
2625 /* If MP_NEXTHOP is present, validate it. */
2626 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2627 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2628 * it is not an IPv6 link-local address.
2630 if (attr
->mp_nexthop_len
) {
2631 switch (attr
->mp_nexthop_len
) {
2632 case BGP_ATTR_NHLEN_IPV4
:
2633 case BGP_ATTR_NHLEN_VPNV4
:
2634 ret
= (attr
->mp_nexthop_global_in
.s_addr
== 0
2635 || IPV4_CLASS_DE(ntohl(
2636 attr
->mp_nexthop_global_in
.s_addr
))
2637 || bgp_nexthop_self(bgp
,
2638 attr
->mp_nexthop_global_in
));
2641 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2642 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2643 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2644 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attr
->mp_nexthop_global
)
2645 || IN6_IS_ADDR_LOOPBACK(&attr
->mp_nexthop_global
)
2646 || IN6_IS_ADDR_MULTICAST(
2647 &attr
->mp_nexthop_global
));
2659 int bgp_update(struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2660 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2661 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
2662 int soft_reconfig
, struct bgp_route_evpn
*evpn
)
2665 int aspath_loop_count
= 0;
2666 struct bgp_node
*rn
;
2668 struct attr new_attr
;
2669 struct attr
*attr_new
;
2670 struct bgp_info
*ri
;
2671 struct bgp_info
*new;
2673 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2676 int do_loop_check
= 1;
2677 int has_valid_label
= 0;
2679 int vnc_implicit_withdraw
= 0;
2683 memset(&new_attr
, 0, sizeof(struct attr
));
2684 new_attr
.label_index
= BGP_INVALID_LABEL_INDEX
;
2685 new_attr
.label
= MPLS_INVALID_LABEL
;
2688 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2689 has_valid_label
= bgp_is_valid_label(label
);
2691 if (has_valid_label
)
2692 sprintf(label_buf
, "label %u", label_pton(label
));
2694 /* When peer's soft reconfiguration enabled. Record input packet in
2697 && CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2698 && peer
!= bgp
->peer_self
)
2699 bgp_adj_in_set(rn
, peer
, attr
, addpath_id
);
2701 /* Check previously received route. */
2702 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2703 if (ri
->peer
== peer
&& ri
->type
== type
2704 && ri
->sub_type
== sub_type
2705 && ri
->addpath_rx_id
== addpath_id
)
2708 /* AS path local-as loop check. */
2709 if (peer
->change_local_as
) {
2710 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2711 aspath_loop_count
= 1;
2713 if (aspath_loop_check(attr
->aspath
, peer
->change_local_as
)
2714 > aspath_loop_count
) {
2715 reason
= "as-path contains our own AS;";
2720 /* If the peer is configured for "allowas-in origin" and the last ASN in
2722 * as-path is our ASN then we do not need to call aspath_loop_check
2724 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2725 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2728 /* AS path loop check. */
2729 if (do_loop_check
) {
2730 if (aspath_loop_check(attr
->aspath
, bgp
->as
)
2731 > peer
->allowas_in
[afi
][safi
]
2732 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2733 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
)
2734 > peer
->allowas_in
[afi
][safi
])) {
2735 reason
= "as-path contains our own AS;";
2740 /* Route reflector originator ID check. */
2741 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)
2742 && IPV4_ADDR_SAME(&bgp
->router_id
, &attr
->originator_id
)) {
2743 reason
= "originator is us;";
2747 /* Route reflector cluster ID check. */
2748 if (bgp_cluster_filter(peer
, attr
)) {
2749 reason
= "reflected from the same cluster;";
2753 /* Apply incoming filter. */
2754 if (bgp_input_filter(peer
, p
, attr
, afi
, safi
) == FILTER_DENY
) {
2759 bgp_attr_dup(&new_attr
, attr
);
2761 /* Apply incoming route-map.
2762 * NB: new_attr may now contain newly allocated values from route-map
2764 * commands, so we need bgp_attr_flush in the error paths, until we
2766 * the attr (which takes over the memory references) */
2767 if (bgp_input_modifier(peer
, p
, &new_attr
, afi
, safi
, NULL
)
2769 reason
= "route-map;";
2770 bgp_attr_flush(&new_attr
);
2774 if (peer
->sort
== BGP_PEER_EBGP
) {
2776 /* If we receive the graceful-shutdown community from an eBGP peer we
2777 * must lower local-preference */
2778 if (new_attr
.community
&&
2779 community_include(new_attr
.community
, COMMUNITY_GSHUT
)) {
2780 new_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
2781 new_attr
.local_pref
= BGP_GSHUT_LOCAL_PREF
;
2783 /* If graceful-shutdown is configured then add the GSHUT community to
2784 * all paths received from eBGP peers */
2785 } else if (bgp_flag_check(peer
->bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
)) {
2786 bgp_attr_add_gshut_community(&new_attr
);
2790 /* next hop check. */
2791 if (bgp_update_martian_nexthop(bgp
, afi
, safi
, &new_attr
)) {
2792 reason
= "martian or self next-hop;";
2793 bgp_attr_flush(&new_attr
);
2797 attr_new
= bgp_attr_intern(&new_attr
);
2799 /* If the update is implicit withdraw. */
2801 ri
->uptime
= bgp_clock();
2802 same_attr
= attrhash_cmp(ri
->attr
, attr_new
);
2804 /* Same attribute comes in. */
2805 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)
2806 && attrhash_cmp(ri
->attr
, attr_new
)
2807 && (!has_valid_label
2808 || memcmp(&(bgp_info_extra_get(ri
))->label
, label
,
2811 && (overlay_index_equal(
2812 afi
, ri
, evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
2813 evpn
== NULL
? NULL
: &evpn
->gw_ip
))) {
2814 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
2815 BGP_CONFIG_DAMPENING
)
2816 && peer
->sort
== BGP_PEER_EBGP
2817 && CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
)) {
2818 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2819 bgp_debug_rdpfxpath2str(
2820 afi
, safi
, prd
, p
, label
,
2821 addpath_id
? 1 : 0, addpath_id
,
2822 pfx_buf
, sizeof(pfx_buf
));
2823 zlog_debug("%s rcvd %s", peer
->host
,
2827 if (bgp_damp_update(ri
, rn
, afi
, safi
)
2828 != BGP_DAMP_SUPPRESSED
) {
2829 bgp_aggregate_increment(bgp
, p
, ri
, afi
,
2831 bgp_process(bgp
, rn
, afi
, safi
);
2833 } else /* Duplicate - odd */
2835 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2836 if (!peer
->rcvd_attr_printed
) {
2838 "%s rcvd UPDATE w/ attr: %s",
2840 peer
->rcvd_attr_str
);
2841 peer
->rcvd_attr_printed
= 1;
2844 bgp_debug_rdpfxpath2str(
2845 afi
, safi
, prd
, p
, label
,
2846 addpath_id
? 1 : 0, addpath_id
,
2847 pfx_buf
, sizeof(pfx_buf
));
2849 "%s rcvd %s...duplicate ignored",
2850 peer
->host
, pfx_buf
);
2853 /* graceful restart STALE flag unset. */
2854 if (CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
)) {
2855 bgp_info_unset_flag(rn
, ri
,
2857 bgp_process(bgp
, rn
, afi
, safi
);
2861 bgp_unlock_node(rn
);
2862 bgp_attr_unintern(&attr_new
);
2867 /* Withdraw/Announce before we fully processed the withdraw */
2868 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
2869 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2870 bgp_debug_rdpfxpath2str(
2871 afi
, safi
, prd
, p
, label
,
2872 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
2875 "%s rcvd %s, flapped quicker than processing",
2876 peer
->host
, pfx_buf
);
2879 bgp_info_restore(rn
, ri
);
2882 /* Received Logging. */
2883 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2884 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
,
2885 addpath_id
? 1 : 0, addpath_id
,
2886 pfx_buf
, sizeof(pfx_buf
));
2887 zlog_debug("%s rcvd %s", peer
->host
, pfx_buf
);
2890 /* graceful restart STALE flag unset. */
2891 if (CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
))
2892 bgp_info_unset_flag(rn
, ri
, BGP_INFO_STALE
);
2894 /* The attribute is changed. */
2895 bgp_info_set_flag(rn
, ri
, BGP_INFO_ATTR_CHANGED
);
2897 /* implicit withdraw, decrement aggregate and pcount here.
2898 * only if update is accepted, they'll increment below.
2900 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
2902 /* Update bgp route dampening information. */
2903 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2904 && peer
->sort
== BGP_PEER_EBGP
) {
2905 /* This is implicit withdraw so we should update
2908 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
2909 bgp_damp_withdraw(ri
, rn
, afi
, safi
, 1);
2912 if (safi
== SAFI_MPLS_VPN
) {
2913 struct bgp_node
*prn
= NULL
;
2914 struct bgp_table
*table
= NULL
;
2916 prn
= bgp_node_get(bgp
->rib
[afi
][safi
],
2917 (struct prefix
*)prd
);
2919 table
= (struct bgp_table
*)(prn
->info
);
2921 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2922 bgp
, prd
, table
, p
, ri
);
2924 bgp_unlock_node(prn
);
2926 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
2927 && (safi
== SAFI_UNICAST
)) {
2928 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
2930 * Implicit withdraw case.
2932 ++vnc_implicit_withdraw
;
2933 vnc_import_bgp_del_route(bgp
, p
, ri
);
2934 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
2939 /* Special handling for EVPN update of an existing route. If the
2940 * extended community attribute has changed, we need to
2942 * the route using its existing extended community. It will be
2943 * subsequently processed for import with the new extended
2946 if (safi
== SAFI_EVPN
&& !same_attr
) {
2948 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
2950 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))) {
2953 cmp
= ecommunity_cmp(ri
->attr
->ecommunity
,
2954 attr_new
->ecommunity
);
2956 if (bgp_debug_update(peer
, p
, NULL
, 1))
2958 "Change in EXT-COMM, existing %s new %s",
2960 ri
->attr
->ecommunity
),
2962 attr_new
->ecommunity
));
2963 bgp_evpn_unimport_route(bgp
, afi
, safi
,
2969 /* Update to new attribute. */
2970 bgp_attr_unintern(&ri
->attr
);
2971 ri
->attr
= attr_new
;
2973 /* Update MPLS label */
2974 if (has_valid_label
) {
2975 memcpy(&(bgp_info_extra_get(ri
))->label
, label
,
2977 bgp_set_valid_label(&(bgp_info_extra_get(ri
))->label
);
2981 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
2982 && (safi
== SAFI_UNICAST
)) {
2983 if (vnc_implicit_withdraw
) {
2985 * Add back the route with its new attributes
2987 * The route is still selected, until the route
2989 * queued by bgp_process actually runs. We have
2991 * update to the VNC side immediately to avoid
2993 * configuration changes (e.g., route-map
2995 * trigger re-importation of the entire RIB.
2997 vnc_import_bgp_add_route(bgp
, p
, ri
);
2998 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
3002 /* Update Overlay Index */
3003 if (afi
== AFI_L2VPN
) {
3004 overlay_index_update(
3005 ri
->attr
, evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3006 evpn
== NULL
? NULL
: &evpn
->gw_ip
);
3009 /* Update bgp route dampening information. */
3010 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
3011 && peer
->sort
== BGP_PEER_EBGP
) {
3012 /* Now we do normal update dampening. */
3013 ret
= bgp_damp_update(ri
, rn
, afi
, safi
);
3014 if (ret
== BGP_DAMP_SUPPRESSED
) {
3015 bgp_unlock_node(rn
);
3020 /* Nexthop reachability check - for unicast and
3021 * labeled-unicast.. */
3022 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3023 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
3024 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1
3025 && !CHECK_FLAG(peer
->flags
,
3026 PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3028 bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
3033 if (bgp_find_or_add_nexthop(bgp
, afi
, ri
, NULL
,
3035 bgp_info_set_flag(rn
, ri
, BGP_INFO_VALID
);
3037 if (BGP_DEBUG(nht
, NHT
)) {
3038 char buf1
[INET6_ADDRSTRLEN
];
3040 (const void *)&attr_new
3042 buf1
, INET6_ADDRSTRLEN
);
3043 zlog_debug("%s(%s): NH unresolved",
3044 __FUNCTION__
, buf1
);
3046 bgp_info_unset_flag(rn
, ri
, BGP_INFO_VALID
);
3049 bgp_info_set_flag(rn
, ri
, BGP_INFO_VALID
);
3052 if (safi
== SAFI_MPLS_VPN
) {
3053 struct bgp_node
*prn
= NULL
;
3054 struct bgp_table
*table
= NULL
;
3056 prn
= bgp_node_get(bgp
->rib
[afi
][safi
],
3057 (struct prefix
*)prd
);
3059 table
= (struct bgp_table
*)(prn
->info
);
3061 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3062 bgp
, prd
, table
, p
, ri
);
3064 bgp_unlock_node(prn
);
3068 /* If this is an EVPN route and some attribute has changed,
3070 * route for import. If the extended community has changed, we
3072 * have done the un-import earlier and the import would result
3074 * route getting injected into appropriate L2 VNIs. If it is
3076 * some other attribute change, the import will result in
3078 * the attributes for the route in the VNI(s).
3080 if (safi
== SAFI_EVPN
&& !same_attr
)
3081 bgp_evpn_import_route(bgp
, afi
, safi
, p
, ri
);
3083 /* Process change. */
3084 bgp_aggregate_increment(bgp
, p
, ri
, afi
, safi
);
3086 bgp_process(bgp
, rn
, afi
, safi
);
3087 bgp_unlock_node(rn
);
3090 if (SAFI_MPLS_VPN
== safi
) {
3091 mpls_label_t label_decoded
= decode_label(label
);
3093 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
,
3094 type
, sub_type
, &label_decoded
);
3096 if (SAFI_ENCAP
== safi
) {
3097 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
,
3098 type
, sub_type
, NULL
);
3103 } // End of implicit withdraw
3105 /* Received Logging. */
3106 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3107 if (!peer
->rcvd_attr_printed
) {
3108 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
3109 peer
->rcvd_attr_str
);
3110 peer
->rcvd_attr_printed
= 1;
3113 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
,
3114 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3116 zlog_debug("%s rcvd %s", peer
->host
, pfx_buf
);
3119 /* Make new BGP info. */
3120 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
3122 /* Update MPLS label */
3123 if (has_valid_label
) {
3124 memcpy(&(bgp_info_extra_get(new))->label
, label
,
3126 bgp_set_valid_label(&(bgp_info_extra_get(new))->label
);
3129 /* Update Overlay Index */
3130 if (afi
== AFI_L2VPN
) {
3131 overlay_index_update(new->attr
,
3132 evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3133 evpn
== NULL
? NULL
: &evpn
->gw_ip
);
3135 /* Nexthop reachability check. */
3136 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3137 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
3138 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1
3139 && !CHECK_FLAG(peer
->flags
,
3140 PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3141 && !bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
3146 if (bgp_find_or_add_nexthop(bgp
, afi
, new, NULL
, connected
))
3147 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
3149 if (BGP_DEBUG(nht
, NHT
)) {
3150 char buf1
[INET6_ADDRSTRLEN
];
3152 (const void *)&attr_new
->nexthop
,
3153 buf1
, INET6_ADDRSTRLEN
);
3154 zlog_debug("%s(%s): NH unresolved",
3155 __FUNCTION__
, buf1
);
3157 bgp_info_unset_flag(rn
, new, BGP_INFO_VALID
);
3160 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
3163 new->addpath_rx_id
= addpath_id
;
3165 /* Increment prefix */
3166 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
3168 /* Register new BGP information. */
3169 bgp_info_add(rn
, new);
3171 /* route_node_get lock */
3172 bgp_unlock_node(rn
);
3175 if (safi
== SAFI_MPLS_VPN
) {
3176 struct bgp_node
*prn
= NULL
;
3177 struct bgp_table
*table
= NULL
;
3179 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*)prd
);
3181 table
= (struct bgp_table
*)(prn
->info
);
3183 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3184 bgp
, prd
, table
, p
, new);
3186 bgp_unlock_node(prn
);
3190 /* If maximum prefix count is configured and current prefix
3192 if (bgp_maximum_prefix_overflow(peer
, afi
, safi
, 0))
3195 /* If this is an EVPN route, process for import. */
3196 if (safi
== SAFI_EVPN
)
3197 bgp_evpn_import_route(bgp
, afi
, safi
, p
, new);
3199 /* Process change. */
3200 bgp_process(bgp
, rn
, afi
, safi
);
3203 if (SAFI_MPLS_VPN
== safi
) {
3204 mpls_label_t label_decoded
= decode_label(label
);
3206 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
,
3207 sub_type
, &label_decoded
);
3209 if (SAFI_ENCAP
== safi
) {
3210 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
,
3217 /* This BGP update is filtered. Log the reason then update BGP
3220 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3221 if (!peer
->rcvd_attr_printed
) {
3222 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
3223 peer
->rcvd_attr_str
);
3224 peer
->rcvd_attr_printed
= 1;
3227 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
,
3228 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3230 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
3231 peer
->host
, pfx_buf
, reason
);
3235 /* If this is an EVPN route, un-import it as it is now filtered.
3237 if (safi
== SAFI_EVPN
)
3238 bgp_evpn_unimport_route(bgp
, afi
, safi
, p
, ri
);
3240 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
3243 bgp_unlock_node(rn
);
3247 * Filtered update is treated as an implicit withdrawal (see
3249 * a few lines above)
3251 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
)) {
3252 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
,
3260 int bgp_withdraw(struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
3261 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
3262 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
3263 struct bgp_route_evpn
*evpn
)
3266 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
3267 struct bgp_node
*rn
;
3268 struct bgp_info
*ri
;
3271 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
)) {
3272 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
,
3280 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3282 /* If peer is soft reconfiguration enabled. Record input packet for
3283 * further calculation.
3285 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
3286 * routes that are filtered. This tanks out Quagga RS pretty badly due
3288 * the iteration over all RS clients.
3289 * Since we need to remove the entry from adj_in anyway, do that first
3291 * if there was no entry, we don't need to do anything more.
3293 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
3294 && peer
!= bgp
->peer_self
)
3295 if (!bgp_adj_in_unset(rn
, peer
, addpath_id
)) {
3296 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3297 bgp_debug_rdpfxpath2str(
3298 afi
, safi
, prd
, p
, label
,
3299 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3302 "%s withdrawing route %s not in adj-in",
3303 peer
->host
, pfx_buf
);
3305 bgp_unlock_node(rn
);
3309 /* Lookup withdrawn route. */
3310 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3311 if (ri
->peer
== peer
&& ri
->type
== type
3312 && ri
->sub_type
== sub_type
3313 && ri
->addpath_rx_id
== addpath_id
)
3317 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3318 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
,
3319 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3321 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer
->host
,
3325 /* Withdraw specified route from routing table. */
3326 if (ri
&& !CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
3327 bgp_rib_withdraw(rn
, ri
, peer
, afi
, safi
, prd
);
3328 else if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3329 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
,
3330 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3332 zlog_debug("%s Can't find the route %s", peer
->host
, pfx_buf
);
3335 /* Unlock bgp_node_get() lock. */
3336 bgp_unlock_node(rn
);
3341 void bgp_default_originate(struct peer
*peer
, afi_t afi
, safi_t safi
,
3344 struct update_subgroup
*subgrp
;
3345 subgrp
= peer_subgroup(peer
, afi
, safi
);
3346 subgroup_default_originate(subgrp
, withdraw
);
3351 * bgp_stop_announce_route_timer
3353 void bgp_stop_announce_route_timer(struct peer_af
*paf
)
3355 if (!paf
->t_announce_route
)
3358 THREAD_TIMER_OFF(paf
->t_announce_route
);
3362 * bgp_announce_route_timer_expired
3364 * Callback that is invoked when the route announcement timer for a
3367 static int bgp_announce_route_timer_expired(struct thread
*t
)
3369 struct peer_af
*paf
;
3372 paf
= THREAD_ARG(t
);
3375 if (peer
->status
!= Established
)
3378 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
3381 peer_af_announce_route(paf
, 1);
3386 * bgp_announce_route
3388 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3390 void bgp_announce_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3392 struct peer_af
*paf
;
3393 struct update_subgroup
*subgrp
;
3395 paf
= peer_af_find(peer
, afi
, safi
);
3398 subgrp
= PAF_SUBGRP(paf
);
3401 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3402 * or a refresh has already been triggered.
3404 if (!subgrp
|| paf
->t_announce_route
)
3408 * Start a timer to stagger/delay the announce. This serves
3409 * two purposes - announcement can potentially be combined for
3410 * multiple peers and the announcement doesn't happen in the
3413 thread_add_timer_msec(bm
->master
, bgp_announce_route_timer_expired
, paf
,
3414 (subgrp
->peer_count
== 1)
3415 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
3416 : BGP_ANNOUNCE_ROUTE_DELAY_MS
,
3417 &paf
->t_announce_route
);
3421 * Announce routes from all AF tables to a peer.
3423 * This should ONLY be called when there is a need to refresh the
3424 * routes to the peer based on a policy change for this peer alone
3425 * or a route refresh request received from the peer.
3426 * The operation will result in splitting the peer from its existing
3427 * subgroups and putting it in new subgroups.
3429 void bgp_announce_route_all(struct peer
*peer
)
3434 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3435 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3436 bgp_announce_route(peer
, afi
, safi
);
3439 static void bgp_soft_reconfig_table(struct peer
*peer
, afi_t afi
, safi_t safi
,
3440 struct bgp_table
*table
,
3441 struct prefix_rd
*prd
)
3444 struct bgp_node
*rn
;
3445 struct bgp_adj_in
*ain
;
3448 table
= peer
->bgp
->rib
[afi
][safi
];
3450 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
3451 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
) {
3452 if (ain
->peer
== peer
) {
3453 struct bgp_info
*ri
= rn
->info
;
3454 mpls_label_t label
=
3455 (ri
&& ri
->extra
) ? ri
->extra
->label
3456 : MPLS_INVALID_LABEL
;
3459 peer
, &rn
->p
, ain
->addpath_rx_id
,
3460 ain
->attr
, afi
, safi
, ZEBRA_ROUTE_BGP
,
3461 BGP_ROUTE_NORMAL
, prd
, &label
, 1, NULL
);
3464 bgp_unlock_node(rn
);
3471 void bgp_soft_reconfig_in(struct peer
*peer
, afi_t afi
, safi_t safi
)
3473 struct bgp_node
*rn
;
3474 struct bgp_table
*table
;
3476 if (peer
->status
!= Established
)
3479 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
)
3480 && (safi
!= SAFI_EVPN
))
3481 bgp_soft_reconfig_table(peer
, afi
, safi
, NULL
, NULL
);
3483 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3484 rn
= bgp_route_next(rn
))
3485 if ((table
= rn
->info
) != NULL
) {
3486 struct prefix_rd prd
;
3487 prd
.family
= AF_UNSPEC
;
3489 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3491 bgp_soft_reconfig_table(peer
, afi
, safi
, table
,
3497 struct bgp_clear_node_queue
{
3498 struct bgp_node
*rn
;
3501 static wq_item_status
bgp_clear_route_node(struct work_queue
*wq
, void *data
)
3503 struct bgp_clear_node_queue
*cnq
= data
;
3504 struct bgp_node
*rn
= cnq
->rn
;
3505 struct peer
*peer
= wq
->spec
.data
;
3506 struct bgp_info
*ri
;
3507 afi_t afi
= bgp_node_table(rn
)->afi
;
3508 safi_t safi
= bgp_node_table(rn
)->safi
;
3512 /* It is possible that we have multiple paths for a prefix from a peer
3513 * if that peer is using AddPath.
3515 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3516 if (ri
->peer
== peer
) {
3517 /* graceful restart STALE flag set. */
3518 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3519 && peer
->nsf
[afi
][safi
]
3520 && !CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
)
3521 && !CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
3522 bgp_info_set_flag(rn
, ri
, BGP_INFO_STALE
);
3524 /* If this is an EVPN route, process for
3526 if (safi
== SAFI_EVPN
)
3527 bgp_evpn_unimport_route(peer
->bgp
, afi
,
3530 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
3536 static void bgp_clear_node_queue_del(struct work_queue
*wq
, void *data
)
3538 struct bgp_clear_node_queue
*cnq
= data
;
3539 struct bgp_node
*rn
= cnq
->rn
;
3540 struct bgp_table
*table
= bgp_node_table(rn
);
3542 bgp_unlock_node(rn
);
3543 bgp_table_unlock(table
);
3544 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3547 static void bgp_clear_node_complete(struct work_queue
*wq
)
3549 struct peer
*peer
= wq
->spec
.data
;
3551 /* Tickle FSM to start moving again */
3552 BGP_EVENT_ADD(peer
, Clearing_Completed
);
3554 peer_unlock(peer
); /* bgp_clear_route */
3557 static void bgp_clear_node_queue_init(struct peer
*peer
)
3559 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3561 snprintf(wname
, sizeof(wname
), "clear %s", peer
->host
);
3562 #undef CLEAR_QUEUE_NAME_LEN
3564 if ((peer
->clear_node_queue
= work_queue_new(bm
->master
, wname
))
3566 zlog_err("%s: Failed to allocate work queue", __func__
);
3569 peer
->clear_node_queue
->spec
.hold
= 10;
3570 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3571 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3572 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3573 peer
->clear_node_queue
->spec
.max_retries
= 0;
3575 /* we only 'lock' this peer reference when the queue is actually active
3577 peer
->clear_node_queue
->spec
.data
= peer
;
3580 static void bgp_clear_route_table(struct peer
*peer
, afi_t afi
, safi_t safi
,
3581 struct bgp_table
*table
)
3583 struct bgp_node
*rn
;
3584 int force
= bm
->process_main_queue
? 0 : 1;
3587 table
= peer
->bgp
->rib
[afi
][safi
];
3589 /* If still no table => afi/safi isn't configured at all or smth. */
3593 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
3594 struct bgp_info
*ri
, *next
;
3595 struct bgp_adj_in
*ain
;
3596 struct bgp_adj_in
*ain_next
;
3598 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3599 * queued for every clearing peer, regardless of whether it is
3600 * relevant to the peer at hand.
3602 * Overview: There are 3 different indices which need to be
3603 * scrubbed, potentially, when a peer is removed:
3605 * 1 peer's routes visible via the RIB (ie accepted routes)
3606 * 2 peer's routes visible by the (optional) peer's adj-in index
3607 * 3 other routes visible by the peer's adj-out index
3609 * 3 there is no hurry in scrubbing, once the struct peer is
3610 * removed from bgp->peer, we could just GC such deleted peer's
3611 * adj-outs at our leisure.
3613 * 1 and 2 must be 'scrubbed' in some way, at least made
3614 * invisible via RIB index before peer session is allowed to be
3615 * brought back up. So one needs to know when such a 'search' is
3620 * - there'd be a single global queue or a single RIB walker
3621 * - rather than tracking which route_nodes still need to be
3622 * examined on a peer basis, we'd track which peers still
3625 * Given that our per-peer prefix-counts now should be reliable,
3626 * this may actually be achievable. It doesn't seem to be a huge
3627 * problem at this time,
3629 * It is possible that we have multiple paths for a prefix from
3631 * if that peer is using AddPath.
3635 ain_next
= ain
->next
;
3637 if (ain
->peer
== peer
) {
3638 bgp_adj_in_remove(rn
, ain
);
3639 bgp_unlock_node(rn
);
3645 for (ri
= rn
->info
; ri
; ri
= next
) {
3647 if (ri
->peer
!= peer
)
3651 bgp_info_reap(rn
, ri
);
3653 struct bgp_clear_node_queue
*cnq
;
3655 /* both unlocked in bgp_clear_node_queue_del */
3656 bgp_table_lock(bgp_node_table(rn
));
3659 MTYPE_BGP_CLEAR_NODE_QUEUE
,
3660 sizeof(struct bgp_clear_node_queue
));
3662 work_queue_add(peer
->clear_node_queue
, cnq
);
3670 void bgp_clear_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3672 struct bgp_node
*rn
;
3673 struct bgp_table
*table
;
3675 if (peer
->clear_node_queue
== NULL
)
3676 bgp_clear_node_queue_init(peer
);
3678 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3679 * Idle until it receives a Clearing_Completed event. This protects
3680 * against peers which flap faster than we can we clear, which could
3683 * a) race with routes from the new session being installed before
3684 * clear_route_node visits the node (to delete the route of that
3686 * b) resource exhaustion, clear_route_node likely leads to an entry
3687 * on the process_main queue. Fast-flapping could cause that queue
3691 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3692 * the unlock will happen upon work-queue completion; other wise, the
3693 * unlock happens at the end of this function.
3695 if (!peer
->clear_node_queue
->thread
)
3698 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
&& safi
!= SAFI_EVPN
)
3699 bgp_clear_route_table(peer
, afi
, safi
, NULL
);
3701 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3702 rn
= bgp_route_next(rn
))
3703 if ((table
= rn
->info
) != NULL
)
3704 bgp_clear_route_table(peer
, afi
, safi
, table
);
3706 /* unlock if no nodes got added to the clear-node-queue. */
3707 if (!peer
->clear_node_queue
->thread
)
3711 void bgp_clear_route_all(struct peer
*peer
)
3716 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
3717 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
3718 bgp_clear_route(peer
, afi
, safi
);
3721 rfapiProcessPeerDown(peer
);
3725 void bgp_clear_adj_in(struct peer
*peer
, afi_t afi
, safi_t safi
)
3727 struct bgp_table
*table
;
3728 struct bgp_node
*rn
;
3729 struct bgp_adj_in
*ain
;
3730 struct bgp_adj_in
*ain_next
;
3732 table
= peer
->bgp
->rib
[afi
][safi
];
3734 /* It is possible that we have multiple paths for a prefix from a peer
3735 * if that peer is using AddPath.
3737 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
3741 ain_next
= ain
->next
;
3743 if (ain
->peer
== peer
) {
3744 bgp_adj_in_remove(rn
, ain
);
3745 bgp_unlock_node(rn
);
3753 void bgp_clear_stale_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3755 struct bgp_node
*rn
;
3756 struct bgp_info
*ri
;
3757 struct bgp_table
*table
;
3759 if (safi
== SAFI_MPLS_VPN
) {
3760 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3761 rn
= bgp_route_next(rn
)) {
3762 struct bgp_node
*rm
;
3763 struct bgp_info
*ri
;
3765 /* look for neighbor in tables */
3766 if ((table
= rn
->info
) != NULL
) {
3767 for (rm
= bgp_table_top(table
); rm
;
3768 rm
= bgp_route_next(rm
))
3769 for (ri
= rm
->info
; ri
; ri
= ri
->next
)
3770 if (ri
->peer
== peer
) {
3784 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3785 rn
= bgp_route_next(rn
))
3786 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3787 if (ri
->peer
== peer
) {
3788 if (CHECK_FLAG(ri
->flags
,
3790 bgp_rib_remove(rn
, ri
, peer
,
3797 static void bgp_cleanup_table(struct bgp_table
*table
, safi_t safi
)
3799 struct bgp_node
*rn
;
3800 struct bgp_info
*ri
;
3801 struct bgp_info
*next
;
3803 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
3804 for (ri
= rn
->info
; ri
; ri
= next
) {
3806 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)
3807 && ri
->type
== ZEBRA_ROUTE_BGP
3808 && (ri
->sub_type
== BGP_ROUTE_NORMAL
3809 || ri
->sub_type
== BGP_ROUTE_AGGREGATE
)) {
3810 if (bgp_fibupd_safi(safi
))
3811 bgp_zebra_withdraw(&rn
->p
, ri
, safi
);
3812 bgp_info_reap(rn
, ri
);
3817 /* Delete all kernel routes. */
3818 void bgp_cleanup_routes(struct bgp
*bgp
)
3821 struct bgp_node
*rn
;
3823 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
3824 if (afi
== AFI_L2VPN
)
3826 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3828 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
3830 if (afi
!= AFI_L2VPN
) {
3832 safi
= SAFI_MPLS_VPN
;
3833 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3834 rn
= bgp_route_next(rn
)) {
3837 (struct bgp_table
*)(rn
->info
),
3839 bgp_table_finish((struct bgp_table
**)&(
3842 bgp_unlock_node(rn
);
3846 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3847 rn
= bgp_route_next(rn
)) {
3850 (struct bgp_table
*)(rn
->info
),
3852 bgp_table_finish((struct bgp_table
**)&(
3855 bgp_unlock_node(rn
);
3860 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
3861 rn
= bgp_route_next(rn
)) {
3863 bgp_cleanup_table((struct bgp_table
*)(rn
->info
),
3865 bgp_table_finish((struct bgp_table
**)&(rn
->info
));
3867 bgp_unlock_node(rn
);
3872 void bgp_reset(void)
3875 bgp_zclient_reset();
3876 access_list_reset();
3877 prefix_list_reset();
3880 static int bgp_addpath_encode_rx(struct peer
*peer
, afi_t afi
, safi_t safi
)
3882 return (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
3883 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
3884 PEER_CAP_ADDPATH_AF_TX_RCV
));
3887 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3889 int bgp_nlri_parse_ip(struct peer
*peer
, struct attr
*attr
,
3890 struct bgp_nlri
*packet
)
3899 int addpath_encoded
;
3900 u_int32_t addpath_id
;
3902 /* Check peer status. */
3903 if (peer
->status
!= Established
)
3907 lim
= pnt
+ packet
->length
;
3909 safi
= packet
->safi
;
3911 addpath_encoded
= bgp_addpath_encode_rx(peer
, afi
, safi
);
3913 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3914 syntactic validity. If the field is syntactically incorrect,
3915 then the Error Subcode is set to Invalid Network Field. */
3916 for (; pnt
< lim
; pnt
+= psize
) {
3917 /* Clear prefix structure. */
3918 memset(&p
, 0, sizeof(struct prefix
));
3920 if (addpath_encoded
) {
3922 /* When packet overflow occurs return immediately. */
3923 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
3926 addpath_id
= ntohl(*((uint32_t *)pnt
));
3927 pnt
+= BGP_ADDPATH_ID_LEN
;
3930 /* Fetch prefix length. */
3931 p
.prefixlen
= *pnt
++;
3932 /* afi/safi validity already verified by caller,
3933 * bgp_update_receive */
3934 p
.family
= afi2family(afi
);
3936 /* Prefix length check. */
3937 if (p
.prefixlen
> prefix_blen(&p
) * 8) {
3939 "%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3940 peer
->host
, p
.prefixlen
, packet
->afi
);
3944 /* Packet size overflow check. */
3945 psize
= PSIZE(p
.prefixlen
);
3947 /* When packet overflow occur return immediately. */
3948 if (pnt
+ psize
> lim
) {
3950 "%s [Error] Update packet error (prefix length %d overflows packet)",
3951 peer
->host
, p
.prefixlen
);
3955 /* Defensive coding, double-check the psize fits in a struct
3957 if (psize
> (ssize_t
)sizeof(p
.u
)) {
3959 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3960 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
3964 /* Fetch prefix from NLRI packet. */
3965 memcpy(&p
.u
.prefix
, pnt
, psize
);
3967 /* Check address. */
3968 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
) {
3969 if (IN_CLASSD(ntohl(p
.u
.prefix4
.s_addr
))) {
3970 /* From RFC4271 Section 6.3:
3972 * If a prefix in the NLRI field is semantically
3974 * (e.g., an unexpected multicast IP address),
3976 * be logged locally, and the prefix SHOULD be
3980 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3981 peer
->host
, inet_ntoa(p
.u
.prefix4
));
3986 /* Check address. */
3987 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
) {
3988 if (IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
3992 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3994 inet_ntop(AF_INET6
, &p
.u
.prefix6
, buf
,
3999 if (IN6_IS_ADDR_MULTICAST(&p
.u
.prefix6
)) {
4003 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
4005 inet_ntop(AF_INET6
, &p
.u
.prefix6
, buf
,
4012 /* Normal process. */
4014 ret
= bgp_update(peer
, &p
, addpath_id
, attr
, afi
, safi
,
4015 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
4016 NULL
, NULL
, 0, NULL
);
4018 ret
= bgp_withdraw(peer
, &p
, addpath_id
, attr
, afi
,
4019 safi
, ZEBRA_ROUTE_BGP
,
4020 BGP_ROUTE_NORMAL
, NULL
, NULL
, NULL
);
4022 /* Address family configuration mismatch or maximum-prefix count
4028 /* Packet length consistency check. */
4031 "%s [Error] Update packet error (prefix length mismatch with total length)",
4039 static struct bgp_static
*bgp_static_new(void)
4041 return XCALLOC(MTYPE_BGP_STATIC
, sizeof(struct bgp_static
));
4044 static void bgp_static_free(struct bgp_static
*bgp_static
)
4046 if (bgp_static
->rmap
.name
)
4047 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4048 if (bgp_static
->eth_s_id
)
4049 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
4050 XFREE(MTYPE_BGP_STATIC
, bgp_static
);
4053 void bgp_static_update(struct bgp
*bgp
, struct prefix
*p
,
4054 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
4056 struct bgp_node
*rn
;
4057 struct bgp_info
*ri
;
4058 struct bgp_info
*new;
4059 struct bgp_info info
;
4061 struct attr
*attr_new
;
4064 int vnc_implicit_withdraw
= 0;
4071 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4073 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
4075 attr
.nexthop
= bgp_static
->igpnexthop
;
4076 attr
.med
= bgp_static
->igpmetric
;
4077 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
4079 if (bgp_static
->atomic
)
4080 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
);
4082 /* Store label index, if required. */
4083 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
) {
4084 attr
.label_index
= bgp_static
->label_index
;
4085 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID
);
4088 /* Apply route-map. */
4089 if (bgp_static
->rmap
.name
) {
4090 struct attr attr_tmp
= attr
;
4091 info
.peer
= bgp
->peer_self
;
4092 info
.attr
= &attr_tmp
;
4094 SET_FLAG(bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4096 ret
= route_map_apply(bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4098 bgp
->peer_self
->rmap_type
= 0;
4100 if (ret
== RMAP_DENYMATCH
) {
4101 /* Free uninterned attribute. */
4102 bgp_attr_flush(&attr_tmp
);
4104 /* Unintern original. */
4105 aspath_unintern(&attr
.aspath
);
4106 bgp_static_withdraw(bgp
, p
, afi
, safi
);
4110 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
4111 bgp_attr_add_gshut_community(&attr_tmp
);
4113 attr_new
= bgp_attr_intern(&attr_tmp
);
4116 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
4117 bgp_attr_add_gshut_community(&attr
);
4119 attr_new
= bgp_attr_intern(&attr
);
4122 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4123 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4124 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4128 if (attrhash_cmp(ri
->attr
, attr_new
)
4129 && !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)
4130 && !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
)) {
4131 bgp_unlock_node(rn
);
4132 bgp_attr_unintern(&attr_new
);
4133 aspath_unintern(&attr
.aspath
);
4136 /* The attribute is changed. */
4137 bgp_info_set_flag(rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4139 /* Rewrite BGP route information. */
4140 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4141 bgp_info_restore(rn
, ri
);
4143 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4145 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
4146 && (safi
== SAFI_UNICAST
)) {
4147 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
4149 * Implicit withdraw case.
4150 * We have to do this before ri is
4153 ++vnc_implicit_withdraw
;
4154 vnc_import_bgp_del_route(bgp
, p
, ri
);
4155 vnc_import_bgp_exterior_del_route(
4160 bgp_attr_unintern(&ri
->attr
);
4161 ri
->attr
= attr_new
;
4162 ri
->uptime
= bgp_clock();
4164 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
4165 && (safi
== SAFI_UNICAST
)) {
4166 if (vnc_implicit_withdraw
) {
4167 vnc_import_bgp_add_route(bgp
, p
, ri
);
4168 vnc_import_bgp_exterior_add_route(
4174 /* Nexthop reachability check. */
4175 if (bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
4176 && (safi
== SAFI_UNICAST
4177 || safi
== SAFI_LABELED_UNICAST
)) {
4178 if (bgp_find_or_add_nexthop(bgp
, afi
, ri
, NULL
,
4180 bgp_info_set_flag(rn
, ri
,
4183 if (BGP_DEBUG(nht
, NHT
)) {
4184 char buf1
[INET6_ADDRSTRLEN
];
4185 inet_ntop(p
->family
,
4189 "%s(%s): Route not in table, not advertising",
4190 __FUNCTION__
, buf1
);
4192 bgp_info_unset_flag(rn
, ri
,
4196 /* Delete the NHT structure if any, if we're
4198 * enabling/disabling import check. We
4199 * deregister the route
4200 * from NHT to avoid overloading NHT and the
4201 * process interaction
4203 bgp_unlink_nexthop(ri
);
4204 bgp_info_set_flag(rn
, ri
, BGP_INFO_VALID
);
4206 /* Process change. */
4207 bgp_aggregate_increment(bgp
, p
, ri
, afi
, safi
);
4208 bgp_process(bgp
, rn
, afi
, safi
);
4209 bgp_unlock_node(rn
);
4210 aspath_unintern(&attr
.aspath
);
4215 /* Make new BGP info. */
4216 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
,
4218 /* Nexthop reachability check. */
4219 if (bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
4220 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
4221 if (bgp_find_or_add_nexthop(bgp
, afi
, new, NULL
, 0))
4222 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
4224 if (BGP_DEBUG(nht
, NHT
)) {
4225 char buf1
[INET6_ADDRSTRLEN
];
4226 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
4229 "%s(%s): Route not in table, not advertising",
4230 __FUNCTION__
, buf1
);
4232 bgp_info_unset_flag(rn
, new, BGP_INFO_VALID
);
4235 /* Delete the NHT structure if any, if we're toggling between
4236 * enabling/disabling import check. We deregister the route
4237 * from NHT to avoid overloading NHT and the process interaction
4239 bgp_unlink_nexthop(new);
4241 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
4244 /* Aggregate address increment. */
4245 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
4247 /* Register new BGP information. */
4248 bgp_info_add(rn
, new);
4250 /* route_node_get lock */
4251 bgp_unlock_node(rn
);
4253 /* Process change. */
4254 bgp_process(bgp
, rn
, afi
, safi
);
4256 /* Unintern original. */
4257 aspath_unintern(&attr
.aspath
);
4260 void bgp_static_withdraw(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
4263 struct bgp_node
*rn
;
4264 struct bgp_info
*ri
;
4266 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4268 /* Check selected route and self inserted route. */
4269 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4270 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4271 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4274 /* Withdraw static BGP route from routing table. */
4276 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4277 bgp_unlink_nexthop(ri
);
4278 bgp_info_delete(rn
, ri
);
4279 bgp_process(bgp
, rn
, afi
, safi
);
4282 /* Unlock bgp_node_lookup. */
4283 bgp_unlock_node(rn
);
4287 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4289 static void bgp_static_withdraw_safi(struct bgp
*bgp
, struct prefix
*p
,
4290 afi_t afi
, safi_t safi
,
4291 struct prefix_rd
*prd
)
4293 struct bgp_node
*rn
;
4294 struct bgp_info
*ri
;
4296 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
4298 /* Check selected route and self inserted route. */
4299 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4300 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4301 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4304 /* Withdraw static BGP route from routing table. */
4307 rfapiProcessWithdraw(
4308 ri
->peer
, NULL
, p
, prd
, ri
->attr
, afi
, safi
, ri
->type
,
4309 1); /* Kill, since it is an administrative change */
4311 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4312 bgp_info_delete(rn
, ri
);
4313 bgp_process(bgp
, rn
, afi
, safi
);
4316 /* Unlock bgp_node_lookup. */
4317 bgp_unlock_node(rn
);
4320 static void bgp_static_update_safi(struct bgp
*bgp
, struct prefix
*p
,
4321 struct bgp_static
*bgp_static
, afi_t afi
,
4324 struct bgp_node
*rn
;
4325 struct bgp_info
*new;
4326 struct attr
*attr_new
;
4327 struct attr attr
= {0};
4328 struct bgp_info
*ri
;
4330 mpls_label_t label
= 0;
4336 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
,
4339 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
4341 attr
.nexthop
= bgp_static
->igpnexthop
;
4342 attr
.med
= bgp_static
->igpmetric
;
4343 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
4345 if ((safi
== SAFI_EVPN
) || (safi
== SAFI_MPLS_VPN
)
4346 || (safi
== SAFI_ENCAP
)) {
4347 if (afi
== AFI_IP
) {
4348 attr
.mp_nexthop_global_in
= bgp_static
->igpnexthop
;
4349 attr
.mp_nexthop_len
= IPV4_MAX_BYTELEN
;
4352 if (afi
== AFI_L2VPN
) {
4353 if (bgp_static
->gatewayIp
.family
== AF_INET
)
4355 bgp_static
->gatewayIp
.u
.prefix4
.s_addr
;
4356 else if (bgp_static
->gatewayIp
.family
== AF_INET6
)
4357 memcpy(&(add
.ipv6
), &(bgp_static
->gatewayIp
.u
.prefix6
),
4358 sizeof(struct in6_addr
));
4359 overlay_index_update(&attr
, bgp_static
->eth_s_id
, &add
);
4360 if (bgp_static
->encap_tunneltype
== BGP_ENCAP_TYPE_VXLAN
) {
4361 struct bgp_encap_type_vxlan bet
;
4362 memset(&bet
, 0, sizeof(struct bgp_encap_type_vxlan
));
4363 bet
.vnid
= p
->u
.prefix_evpn
.eth_tag
;
4364 bgp_encap_type_vxlan_to_tlv(&bet
, &attr
);
4366 if (bgp_static
->router_mac
) {
4367 bgp_add_routermac_ecom(&attr
, bgp_static
->router_mac
);
4370 /* Apply route-map. */
4371 if (bgp_static
->rmap
.name
) {
4372 struct attr attr_tmp
= attr
;
4373 struct bgp_info info
;
4376 info
.peer
= bgp
->peer_self
;
4377 info
.attr
= &attr_tmp
;
4379 SET_FLAG(bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4381 ret
= route_map_apply(bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4383 bgp
->peer_self
->rmap_type
= 0;
4385 if (ret
== RMAP_DENYMATCH
) {
4386 /* Free uninterned attribute. */
4387 bgp_attr_flush(&attr_tmp
);
4389 /* Unintern original. */
4390 aspath_unintern(&attr
.aspath
);
4391 bgp_static_withdraw_safi(bgp
, p
, afi
, safi
,
4396 attr_new
= bgp_attr_intern(&attr_tmp
);
4398 attr_new
= bgp_attr_intern(&attr
);
4401 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4402 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4403 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4408 memset(&add
, 0, sizeof(union gw_addr
));
4409 if (attrhash_cmp(ri
->attr
, attr_new
)
4410 && overlay_index_equal(afi
, ri
, bgp_static
->eth_s_id
, &add
)
4411 && !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
4412 bgp_unlock_node(rn
);
4413 bgp_attr_unintern(&attr_new
);
4414 aspath_unintern(&attr
.aspath
);
4417 /* The attribute is changed. */
4418 bgp_info_set_flag(rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4420 /* Rewrite BGP route information. */
4421 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4422 bgp_info_restore(rn
, ri
);
4424 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4425 bgp_attr_unintern(&ri
->attr
);
4426 ri
->attr
= attr_new
;
4427 ri
->uptime
= bgp_clock();
4430 label
= decode_label(&ri
->extra
->label
);
4433 /* Process change. */
4434 bgp_aggregate_increment(bgp
, p
, ri
, afi
, safi
);
4435 bgp_process(bgp
, rn
, afi
, safi
);
4437 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
4438 ri
->attr
, afi
, safi
, ri
->type
,
4439 ri
->sub_type
, &label
);
4441 bgp_unlock_node(rn
);
4442 aspath_unintern(&attr
.aspath
);
4448 /* Make new BGP info. */
4449 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
,
4451 SET_FLAG(new->flags
, BGP_INFO_VALID
);
4452 new->extra
= bgp_info_extra_new();
4453 new->extra
->label
= bgp_static
->label
;
4455 label
= decode_label(&bgp_static
->label
);
4458 /* Aggregate address increment. */
4459 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
4461 /* Register new BGP information. */
4462 bgp_info_add(rn
, new);
4463 /* route_node_get lock */
4464 bgp_unlock_node(rn
);
4466 /* Process change. */
4467 bgp_process(bgp
, rn
, afi
, safi
);
4470 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
, new->attr
, afi
,
4471 safi
, new->type
, new->sub_type
, &label
);
4474 /* Unintern original. */
4475 aspath_unintern(&attr
.aspath
);
4478 /* Configure static BGP network. When user don't run zebra, static
4479 route should be installed as valid. */
4480 static int bgp_static_set(struct vty
*vty
, const char *ip_str
, afi_t afi
,
4481 safi_t safi
, const char *rmap
, int backdoor
,
4482 u_int32_t label_index
)
4484 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4487 struct bgp_static
*bgp_static
;
4488 struct bgp_node
*rn
;
4489 u_char need_update
= 0;
4491 /* Convert IP prefix string to struct prefix. */
4492 ret
= str2prefix(ip_str
, &p
);
4494 vty_out(vty
, "%% Malformed prefix\n");
4495 return CMD_WARNING_CONFIG_FAILED
;
4497 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
4498 vty_out(vty
, "%% Malformed prefix (link-local address)\n");
4499 return CMD_WARNING_CONFIG_FAILED
;
4504 /* Set BGP static route configuration. */
4505 rn
= bgp_node_get(bgp
->route
[afi
][safi
], &p
);
4508 /* Configuration change. */
4509 bgp_static
= rn
->info
;
4511 /* Label index cannot be changed. */
4512 if (bgp_static
->label_index
!= label_index
) {
4513 vty_out(vty
, "%% Label index cannot be changed\n");
4514 return CMD_WARNING_CONFIG_FAILED
;
4517 /* Check previous routes are installed into BGP. */
4518 if (bgp_static
->valid
&& bgp_static
->backdoor
!= backdoor
)
4521 bgp_static
->backdoor
= backdoor
;
4524 if (bgp_static
->rmap
.name
)
4525 XFREE(MTYPE_ROUTE_MAP_NAME
,
4526 bgp_static
->rmap
.name
);
4527 bgp_static
->rmap
.name
=
4528 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4529 bgp_static
->rmap
.map
= route_map_lookup_by_name(rmap
);
4531 if (bgp_static
->rmap
.name
)
4532 XFREE(MTYPE_ROUTE_MAP_NAME
,
4533 bgp_static
->rmap
.name
);
4534 bgp_static
->rmap
.name
= NULL
;
4535 bgp_static
->rmap
.map
= NULL
;
4536 bgp_static
->valid
= 0;
4538 bgp_unlock_node(rn
);
4540 /* New configuration. */
4541 bgp_static
= bgp_static_new();
4542 bgp_static
->backdoor
= backdoor
;
4543 bgp_static
->valid
= 0;
4544 bgp_static
->igpmetric
= 0;
4545 bgp_static
->igpnexthop
.s_addr
= 0;
4546 bgp_static
->label_index
= label_index
;
4549 if (bgp_static
->rmap
.name
)
4550 XFREE(MTYPE_ROUTE_MAP_NAME
,
4551 bgp_static
->rmap
.name
);
4552 bgp_static
->rmap
.name
=
4553 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4554 bgp_static
->rmap
.map
= route_map_lookup_by_name(rmap
);
4556 rn
->info
= bgp_static
;
4559 bgp_static
->valid
= 1;
4561 bgp_static_withdraw(bgp
, &p
, afi
, safi
);
4563 if (!bgp_static
->backdoor
)
4564 bgp_static_update(bgp
, &p
, bgp_static
, afi
, safi
);
4569 /* Configure static BGP network. */
4570 static int bgp_static_unset(struct vty
*vty
, const char *ip_str
, afi_t afi
,
4573 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4576 struct bgp_static
*bgp_static
;
4577 struct bgp_node
*rn
;
4579 /* Convert IP prefix string to struct prefix. */
4580 ret
= str2prefix(ip_str
, &p
);
4582 vty_out(vty
, "%% Malformed prefix\n");
4583 return CMD_WARNING_CONFIG_FAILED
;
4585 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
4586 vty_out(vty
, "%% Malformed prefix (link-local address)\n");
4587 return CMD_WARNING_CONFIG_FAILED
;
4592 rn
= bgp_node_lookup(bgp
->route
[afi
][safi
], &p
);
4595 "%% Can't find specified static route configuration.\n");
4596 return CMD_WARNING_CONFIG_FAILED
;
4599 bgp_static
= rn
->info
;
4601 /* Update BGP RIB. */
4602 if (!bgp_static
->backdoor
)
4603 bgp_static_withdraw(bgp
, &p
, afi
, safi
);
4605 /* Clear configuration. */
4606 bgp_static_free(bgp_static
);
4608 bgp_unlock_node(rn
);
4609 bgp_unlock_node(rn
);
4614 void bgp_static_add(struct bgp
*bgp
)
4618 struct bgp_node
*rn
;
4619 struct bgp_node
*rm
;
4620 struct bgp_table
*table
;
4621 struct bgp_static
*bgp_static
;
4623 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4624 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4625 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
4626 rn
= bgp_route_next(rn
))
4627 if (rn
->info
!= NULL
) {
4628 if ((safi
== SAFI_MPLS_VPN
)
4629 || (safi
== SAFI_ENCAP
)
4630 || (safi
== SAFI_EVPN
)) {
4633 for (rm
= bgp_table_top(table
);
4635 rm
= bgp_route_next(rm
)) {
4636 bgp_static
= rm
->info
;
4637 bgp_static_update_safi(
4643 bgp_static_update(bgp
, &rn
->p
,
4650 /* Called from bgp_delete(). Delete all static routes from the BGP
4652 void bgp_static_delete(struct bgp
*bgp
)
4656 struct bgp_node
*rn
;
4657 struct bgp_node
*rm
;
4658 struct bgp_table
*table
;
4659 struct bgp_static
*bgp_static
;
4661 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4662 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4663 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
4664 rn
= bgp_route_next(rn
))
4665 if (rn
->info
!= NULL
) {
4666 if ((safi
== SAFI_MPLS_VPN
)
4667 || (safi
== SAFI_ENCAP
)
4668 || (safi
== SAFI_EVPN
)) {
4671 for (rm
= bgp_table_top(table
);
4673 rm
= bgp_route_next(rm
)) {
4674 bgp_static
= rm
->info
;
4675 bgp_static_withdraw_safi(
4684 bgp_unlock_node(rn
);
4687 bgp_static
= rn
->info
;
4688 bgp_static_withdraw(bgp
, &rn
->p
,
4690 bgp_static_free(bgp_static
);
4692 bgp_unlock_node(rn
);
4697 void bgp_static_redo_import_check(struct bgp
*bgp
)
4701 struct bgp_node
*rn
;
4702 struct bgp_node
*rm
;
4703 struct bgp_table
*table
;
4704 struct bgp_static
*bgp_static
;
4706 /* Use this flag to force reprocessing of the route */
4707 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4708 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4709 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4710 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
4711 rn
= bgp_route_next(rn
))
4712 if (rn
->info
!= NULL
) {
4713 if ((safi
== SAFI_MPLS_VPN
)
4714 || (safi
== SAFI_ENCAP
)
4715 || (safi
== SAFI_EVPN
)) {
4718 for (rm
= bgp_table_top(table
);
4720 rm
= bgp_route_next(rm
)) {
4721 bgp_static
= rm
->info
;
4722 bgp_static_update_safi(
4728 bgp_static
= rn
->info
;
4729 bgp_static_update(bgp
, &rn
->p
,
4734 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4737 static void bgp_purge_af_static_redist_routes(struct bgp
*bgp
, afi_t afi
,
4740 struct bgp_table
*table
;
4741 struct bgp_node
*rn
;
4742 struct bgp_info
*ri
;
4744 table
= bgp
->rib
[afi
][safi
];
4745 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
4746 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
4747 if (ri
->peer
== bgp
->peer_self
4748 && ((ri
->type
== ZEBRA_ROUTE_BGP
4749 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4750 || (ri
->type
!= ZEBRA_ROUTE_BGP
4752 == BGP_ROUTE_REDISTRIBUTE
))) {
4753 bgp_aggregate_decrement(bgp
, &rn
->p
, ri
, afi
,
4755 bgp_unlink_nexthop(ri
);
4756 bgp_info_delete(rn
, ri
);
4757 bgp_process(bgp
, rn
, afi
, safi
);
4764 * Purge all networks and redistributed routes from routing table.
4765 * Invoked upon the instance going down.
4767 void bgp_purge_static_redist_routes(struct bgp
*bgp
)
4772 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
4773 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
4774 bgp_purge_af_static_redist_routes(bgp
, afi
, safi
);
4779 * Currently this is used to set static routes for VPN and ENCAP.
4780 * I think it can probably be factored with bgp_static_set.
4782 int bgp_static_set_safi(afi_t afi
, safi_t safi
, struct vty
*vty
,
4783 const char *ip_str
, const char *rd_str
,
4784 const char *label_str
, const char *rmap_str
,
4785 int evpn_type
, const char *esi
, const char *gwip
,
4786 const char *ethtag
, const char *routermac
)
4788 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4791 struct prefix_rd prd
;
4792 struct bgp_node
*prn
;
4793 struct bgp_node
*rn
;
4794 struct bgp_table
*table
;
4795 struct bgp_static
*bgp_static
;
4796 mpls_label_t label
= MPLS_INVALID_LABEL
;
4797 struct prefix gw_ip
;
4799 /* validate ip prefix */
4800 ret
= str2prefix(ip_str
, &p
);
4802 vty_out(vty
, "%% Malformed prefix\n");
4803 return CMD_WARNING_CONFIG_FAILED
;
4806 if ((afi
== AFI_L2VPN
)
4807 && (bgp_build_evpn_prefix(evpn_type
,
4808 ethtag
!= NULL
? atol(ethtag
) : 0, &p
))) {
4809 vty_out(vty
, "%% L2VPN prefix could not be forged\n");
4810 return CMD_WARNING_CONFIG_FAILED
;
4813 ret
= str2prefix_rd(rd_str
, &prd
);
4815 vty_out(vty
, "%% Malformed rd\n");
4816 return CMD_WARNING_CONFIG_FAILED
;
4820 unsigned long label_val
;
4821 label_val
= strtoul(label_str
, NULL
, 10);
4822 encode_label(label_val
, &label
);
4825 if (safi
== SAFI_EVPN
) {
4826 if (esi
&& str2esi(esi
, NULL
) == 0) {
4827 vty_out(vty
, "%% Malformed ESI\n");
4828 return CMD_WARNING_CONFIG_FAILED
;
4830 if (routermac
&& prefix_str2mac(routermac
, NULL
) == 0) {
4831 vty_out(vty
, "%% Malformed Router MAC\n");
4832 return CMD_WARNING_CONFIG_FAILED
;
4835 memset(&gw_ip
, 0, sizeof(struct prefix
));
4836 ret
= str2prefix(gwip
, &gw_ip
);
4838 vty_out(vty
, "%% Malformed GatewayIp\n");
4839 return CMD_WARNING_CONFIG_FAILED
;
4841 if ((gw_ip
.family
== AF_INET
4842 && IS_EVPN_PREFIX_IPADDR_V6(
4843 (struct prefix_evpn
*)&p
))
4844 || (gw_ip
.family
== AF_INET6
4845 && IS_EVPN_PREFIX_IPADDR_V4(
4846 (struct prefix_evpn
*)&p
))) {
4848 "%% GatewayIp family differs with IP prefix\n");
4849 return CMD_WARNING_CONFIG_FAILED
;
4853 prn
= bgp_node_get(bgp
->route
[afi
][safi
], (struct prefix
*)&prd
);
4854 if (prn
->info
== NULL
)
4855 prn
->info
= bgp_table_init(afi
, safi
);
4857 bgp_unlock_node(prn
);
4860 rn
= bgp_node_get(table
, &p
);
4863 vty_out(vty
, "%% Same network configuration exists\n");
4864 bgp_unlock_node(rn
);
4866 /* New configuration. */
4867 bgp_static
= bgp_static_new();
4868 bgp_static
->backdoor
= 0;
4869 bgp_static
->valid
= 0;
4870 bgp_static
->igpmetric
= 0;
4871 bgp_static
->igpnexthop
.s_addr
= 0;
4872 bgp_static
->label
= label
;
4873 bgp_static
->prd
= prd
;
4876 if (bgp_static
->rmap
.name
)
4877 XFREE(MTYPE_ROUTE_MAP_NAME
,
4878 bgp_static
->rmap
.name
);
4879 bgp_static
->rmap
.name
=
4880 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_str
);
4881 bgp_static
->rmap
.map
=
4882 route_map_lookup_by_name(rmap_str
);
4885 if (safi
== SAFI_EVPN
) {
4887 bgp_static
->eth_s_id
=
4889 sizeof(struct eth_segment_id
));
4890 str2esi(esi
, bgp_static
->eth_s_id
);
4893 bgp_static
->router_mac
=
4894 XCALLOC(MTYPE_ATTR
, ETH_ALEN
+ 1);
4895 prefix_str2mac(routermac
,
4896 bgp_static
->router_mac
);
4899 prefix_copy(&bgp_static
->gatewayIp
, &gw_ip
);
4901 rn
->info
= bgp_static
;
4903 bgp_static
->valid
= 1;
4904 bgp_static_update_safi(bgp
, &p
, bgp_static
, afi
, safi
);
4910 /* Configure static BGP network. */
4911 int bgp_static_unset_safi(afi_t afi
, safi_t safi
, struct vty
*vty
,
4912 const char *ip_str
, const char *rd_str
,
4913 const char *label_str
, int evpn_type
, const char *esi
,
4914 const char *gwip
, const char *ethtag
)
4916 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4919 struct prefix_rd prd
;
4920 struct bgp_node
*prn
;
4921 struct bgp_node
*rn
;
4922 struct bgp_table
*table
;
4923 struct bgp_static
*bgp_static
;
4924 mpls_label_t label
= MPLS_INVALID_LABEL
;
4926 /* Convert IP prefix string to struct prefix. */
4927 ret
= str2prefix(ip_str
, &p
);
4929 vty_out(vty
, "%% Malformed prefix\n");
4930 return CMD_WARNING_CONFIG_FAILED
;
4933 if ((afi
== AFI_L2VPN
)
4934 && (bgp_build_evpn_prefix(evpn_type
,
4935 ethtag
!= NULL
? atol(ethtag
) : 0, &p
))) {
4936 vty_out(vty
, "%% L2VPN prefix could not be forged\n");
4937 return CMD_WARNING_CONFIG_FAILED
;
4939 ret
= str2prefix_rd(rd_str
, &prd
);
4941 vty_out(vty
, "%% Malformed rd\n");
4942 return CMD_WARNING_CONFIG_FAILED
;
4946 unsigned long label_val
;
4947 label_val
= strtoul(label_str
, NULL
, 10);
4948 encode_label(label_val
, &label
);
4951 prn
= bgp_node_get(bgp
->route
[afi
][safi
], (struct prefix
*)&prd
);
4952 if (prn
->info
== NULL
)
4953 prn
->info
= bgp_table_init(afi
, safi
);
4955 bgp_unlock_node(prn
);
4958 rn
= bgp_node_lookup(table
, &p
);
4961 bgp_static_withdraw_safi(bgp
, &p
, afi
, safi
, &prd
);
4963 bgp_static
= rn
->info
;
4964 bgp_static_free(bgp_static
);
4966 bgp_unlock_node(rn
);
4967 bgp_unlock_node(rn
);
4969 vty_out(vty
, "%% Can't find the route\n");
4974 static int bgp_table_map_set(struct vty
*vty
, afi_t afi
, safi_t safi
,
4975 const char *rmap_name
)
4977 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4978 struct bgp_rmap
*rmap
;
4980 rmap
= &bgp
->table_map
[afi
][safi
];
4983 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4984 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
4985 rmap
->map
= route_map_lookup_by_name(rmap_name
);
4988 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
4993 if (bgp_fibupd_safi(safi
))
4994 bgp_zebra_announce_table(bgp
, afi
, safi
);
4999 static int bgp_table_map_unset(struct vty
*vty
, afi_t afi
, safi_t safi
,
5000 const char *rmap_name
)
5002 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5003 struct bgp_rmap
*rmap
;
5005 rmap
= &bgp
->table_map
[afi
][safi
];
5007 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5011 if (bgp_fibupd_safi(safi
))
5012 bgp_zebra_announce_table(bgp
, afi
, safi
);
5017 int bgp_config_write_table_map(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
5018 safi_t safi
, int *write
)
5020 if (bgp
->table_map
[afi
][safi
].name
) {
5021 bgp_config_write_family_header(vty
, afi
, safi
, write
);
5022 vty_out(vty
, " table-map %s\n",
5023 bgp
->table_map
[afi
][safi
].name
);
5029 DEFUN (bgp_table_map
,
5032 "BGP table to RIB route download filter\n"
5033 "Name of the route map\n")
5036 return bgp_table_map_set(vty
, bgp_node_afi(vty
), bgp_node_safi(vty
),
5037 argv
[idx_word
]->arg
);
5039 DEFUN (no_bgp_table_map
,
5040 no_bgp_table_map_cmd
,
5041 "no table-map WORD",
5043 "BGP table to RIB route download filter\n"
5044 "Name of the route map\n")
5047 return bgp_table_map_unset(vty
, bgp_node_afi(vty
), bgp_node_safi(vty
),
5048 argv
[idx_word
]->arg
);
5053 "network A.B.C.D/M",
5054 "Specify a network to announce via BGP\n"
5057 int idx_ipv4_prefixlen
= 1;
5058 return bgp_static_set(vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
5059 bgp_node_safi(vty
), NULL
, 0,
5060 BGP_INVALID_LABEL_INDEX
);
5063 DEFUN (bgp_network_route_map
,
5064 bgp_network_route_map_cmd
,
5065 "network A.B.C.D/M route-map WORD",
5066 "Specify a network to announce via BGP\n"
5068 "Route-map to modify the attributes\n"
5069 "Name of the route map\n")
5071 int idx_ipv4_prefixlen
= 1;
5073 return bgp_static_set(vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
5074 bgp_node_safi(vty
), argv
[idx_word
]->arg
, 0,
5075 BGP_INVALID_LABEL_INDEX
);
5078 DEFUN (bgp_network_backdoor
,
5079 bgp_network_backdoor_cmd
,
5080 "network A.B.C.D/M backdoor",
5081 "Specify a network to announce via BGP\n"
5083 "Specify a BGP backdoor route\n")
5085 int idx_ipv4_prefixlen
= 1;
5086 return bgp_static_set(vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
5087 SAFI_UNICAST
, NULL
, 1, BGP_INVALID_LABEL_INDEX
);
5090 DEFUN (bgp_network_mask
,
5091 bgp_network_mask_cmd
,
5092 "network A.B.C.D mask A.B.C.D",
5093 "Specify a network to announce via BGP\n"
5101 char prefix_str
[BUFSIZ
];
5103 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
,
5106 vty_out(vty
, "%% Inconsistent address and mask\n");
5107 return CMD_WARNING_CONFIG_FAILED
;
5110 return bgp_static_set(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
), NULL
,
5111 0, BGP_INVALID_LABEL_INDEX
);
5114 DEFUN (bgp_network_mask_route_map
,
5115 bgp_network_mask_route_map_cmd
,
5116 "network A.B.C.D mask A.B.C.D route-map WORD",
5117 "Specify a network to announce via BGP\n"
5121 "Route-map to modify the attributes\n"
5122 "Name of the route map\n")
5128 char prefix_str
[BUFSIZ
];
5130 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
,
5133 vty_out(vty
, "%% Inconsistent address and mask\n");
5134 return CMD_WARNING_CONFIG_FAILED
;
5137 return bgp_static_set(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
),
5138 argv
[idx_word
]->arg
, 0, BGP_INVALID_LABEL_INDEX
);
5141 DEFUN (bgp_network_mask_backdoor
,
5142 bgp_network_mask_backdoor_cmd
,
5143 "network A.B.C.D mask A.B.C.D backdoor",
5144 "Specify a network to announce via BGP\n"
5148 "Specify a BGP backdoor route\n")
5153 char prefix_str
[BUFSIZ
];
5155 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
,
5158 vty_out(vty
, "%% Inconsistent address and mask\n");
5159 return CMD_WARNING_CONFIG_FAILED
;
5162 return bgp_static_set(vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
, NULL
, 1,
5163 BGP_INVALID_LABEL_INDEX
);
5166 DEFUN (bgp_network_mask_natural
,
5167 bgp_network_mask_natural_cmd
,
5169 "Specify a network to announce via BGP\n"
5174 char prefix_str
[BUFSIZ
];
5176 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5178 vty_out(vty
, "%% Inconsistent address and mask\n");
5179 return CMD_WARNING_CONFIG_FAILED
;
5182 return bgp_static_set(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
), NULL
,
5183 0, BGP_INVALID_LABEL_INDEX
);
5186 DEFUN (bgp_network_mask_natural_route_map
,
5187 bgp_network_mask_natural_route_map_cmd
,
5188 "network A.B.C.D route-map WORD",
5189 "Specify a network to announce via BGP\n"
5191 "Route-map to modify the attributes\n"
5192 "Name of the route map\n")
5197 char prefix_str
[BUFSIZ
];
5199 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5201 vty_out(vty
, "%% Inconsistent address and mask\n");
5202 return CMD_WARNING_CONFIG_FAILED
;
5205 return bgp_static_set(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
),
5206 argv
[idx_word
]->arg
, 0, BGP_INVALID_LABEL_INDEX
);
5209 DEFUN (bgp_network_mask_natural_backdoor
,
5210 bgp_network_mask_natural_backdoor_cmd
,
5211 "network A.B.C.D backdoor",
5212 "Specify a network to announce via BGP\n"
5214 "Specify a BGP backdoor route\n")
5218 char prefix_str
[BUFSIZ
];
5220 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5222 vty_out(vty
, "%% Inconsistent address and mask\n");
5223 return CMD_WARNING_CONFIG_FAILED
;
5226 return bgp_static_set(vty
, prefix_str
, AFI_IP
, SAFI_UNICAST
, NULL
, 1,
5227 BGP_INVALID_LABEL_INDEX
);
5230 DEFUN (bgp_network_label_index
,
5231 bgp_network_label_index_cmd
,
5232 "network A.B.C.D/M label-index (0-1048560)",
5233 "Specify a network to announce via BGP\n"
5234 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5235 "Label index to associate with the prefix\n"
5236 "Label index value\n")
5238 u_int32_t label_index
;
5240 label_index
= strtoul(argv
[3]->arg
, NULL
, 10);
5241 return bgp_static_set(vty
, argv
[1]->arg
, AFI_IP
, bgp_node_safi(vty
),
5242 NULL
, 0, label_index
);
5245 DEFUN (bgp_network_label_index_route_map
,
5246 bgp_network_label_index_route_map_cmd
,
5247 "network A.B.C.D/M label-index (0-1048560) route-map WORD",
5248 "Specify a network to announce via BGP\n"
5250 "Label index to associate with the prefix\n"
5251 "Label index value\n"
5252 "Route-map to modify the attributes\n"
5253 "Name of the route map\n")
5255 u_int32_t label_index
;
5257 label_index
= strtoul(argv
[3]->arg
, NULL
, 10);
5258 return bgp_static_set(vty
, argv
[1]->arg
, AFI_IP
, bgp_node_safi(vty
),
5259 argv
[5]->arg
, 0, label_index
);
5262 DEFUN (no_bgp_network
,
5264 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
5266 "Specify a network to announce via BGP\n"
5268 "Specify a BGP backdoor route\n"
5269 "Route-map to modify the attributes\n"
5270 "Name of the route map\n")
5272 int idx_ipv4_prefixlen
= 2;
5273 return bgp_static_unset(vty
, argv
[idx_ipv4_prefixlen
]->arg
, AFI_IP
,
5274 bgp_node_safi(vty
));
5277 DEFUN (no_bgp_network_mask
,
5278 no_bgp_network_mask_cmd
,
5279 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
5281 "Specify a network to announce via BGP\n"
5285 "Specify a BGP backdoor route\n"
5286 "Route-map to modify the attributes\n"
5287 "Name of the route map\n")
5292 char prefix_str
[BUFSIZ
];
5294 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
,
5297 vty_out(vty
, "%% Inconsistent address and mask\n");
5298 return CMD_WARNING_CONFIG_FAILED
;
5301 return bgp_static_unset(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
));
5304 DEFUN (no_bgp_network_mask_natural
,
5305 no_bgp_network_mask_natural_cmd
,
5306 "no network A.B.C.D [<backdoor|route-map WORD>]",
5308 "Specify a network to announce via BGP\n"
5310 "Specify a BGP backdoor route\n"
5311 "Route-map to modify the attributes\n"
5312 "Name of the route map\n")
5316 char prefix_str
[BUFSIZ
];
5318 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, NULL
, prefix_str
);
5320 vty_out(vty
, "%% Inconsistent address and mask\n");
5321 return CMD_WARNING_CONFIG_FAILED
;
5324 return bgp_static_unset(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
));
5327 ALIAS(no_bgp_network
, no_bgp_network_label_index_cmd
,
5328 "no network A.B.C.D/M label-index (0-1048560)", NO_STR
5329 "Specify a network to announce via BGP\n"
5330 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5331 "Label index to associate with the prefix\n"
5332 "Label index value\n")
5334 ALIAS(no_bgp_network
, no_bgp_network_label_index_route_map_cmd
,
5335 "no network A.B.C.D/M label-index (0-1048560) route-map WORD", NO_STR
5336 "Specify a network to announce via BGP\n"
5338 "Label index to associate with the prefix\n"
5339 "Label index value\n"
5340 "Route-map to modify the attributes\n"
5341 "Name of the route map\n")
5343 DEFUN (ipv6_bgp_network
,
5344 ipv6_bgp_network_cmd
,
5345 "network X:X::X:X/M",
5346 "Specify a network to announce via BGP\n"
5349 int idx_ipv6_prefixlen
= 1;
5350 return bgp_static_set(vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
5351 bgp_node_safi(vty
), NULL
, 0,
5352 BGP_INVALID_LABEL_INDEX
);
5355 DEFUN (ipv6_bgp_network_route_map
,
5356 ipv6_bgp_network_route_map_cmd
,
5357 "network X:X::X:X/M route-map WORD",
5358 "Specify a network to announce via BGP\n"
5360 "Route-map to modify the attributes\n"
5361 "Name of the route map\n")
5363 int idx_ipv6_prefixlen
= 1;
5365 return bgp_static_set(vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
5366 bgp_node_safi(vty
), argv
[idx_word
]->arg
, 0,
5367 BGP_INVALID_LABEL_INDEX
);
5370 DEFUN (ipv6_bgp_network_label_index
,
5371 ipv6_bgp_network_label_index_cmd
,
5372 "network X:X::X:X/M label-index (0-1048560)",
5373 "Specify a network to announce via BGP\n"
5374 "IPv6 prefix <network>/<length>\n"
5375 "Label index to associate with the prefix\n"
5376 "Label index value\n")
5378 u_int32_t label_index
;
5380 label_index
= strtoul(argv
[3]->arg
, NULL
, 10);
5381 return bgp_static_set(vty
, argv
[1]->arg
, AFI_IP6
, bgp_node_safi(vty
),
5382 NULL
, 0, label_index
);
5385 DEFUN (ipv6_bgp_network_label_index_route_map
,
5386 ipv6_bgp_network_label_index_route_map_cmd
,
5387 "network X:X::X:X/M label-index (0-1048560) route-map WORD",
5388 "Specify a network to announce via BGP\n"
5390 "Label index to associate with the prefix\n"
5391 "Label index value\n"
5392 "Route-map to modify the attributes\n"
5393 "Name of the route map\n")
5395 u_int32_t label_index
;
5397 label_index
= strtoul(argv
[3]->arg
, NULL
, 10);
5398 return bgp_static_set(vty
, argv
[1]->arg
, AFI_IP6
, bgp_node_safi(vty
),
5399 argv
[5]->arg
, 0, label_index
);
5402 DEFUN (no_ipv6_bgp_network
,
5403 no_ipv6_bgp_network_cmd
,
5404 "no network X:X::X:X/M [route-map WORD]",
5406 "Specify a network to announce via BGP\n"
5408 "Route-map to modify the attributes\n"
5409 "Name of the route map\n")
5411 int idx_ipv6_prefixlen
= 2;
5412 return bgp_static_unset(vty
, argv
[idx_ipv6_prefixlen
]->arg
, AFI_IP6
,
5413 bgp_node_safi(vty
));
5416 ALIAS(no_ipv6_bgp_network
, no_ipv6_bgp_network_label_index_cmd
,
5417 "no network X:X::X:X/M label-index (0-1048560)", NO_STR
5418 "Specify a network to announce via BGP\n"
5419 "IPv6 prefix <network>/<length>\n"
5420 "Label index to associate with the prefix\n"
5421 "Label index value\n")
5423 ALIAS(no_ipv6_bgp_network
, no_ipv6_bgp_network_label_index_route_map_cmd
,
5424 "no network X:X::X:X/M label-index (0-1048560) route-map WORD", NO_STR
5425 "Specify a network to announce via BGP\n"
5427 "Label index to associate with the prefix\n"
5428 "Label index value\n"
5429 "Route-map to modify the attributes\n"
5430 "Name of the route map\n")
5432 /* Aggreagete address:
5434 advertise-map Set condition to advertise attribute
5435 as-set Generate AS set path information
5436 attribute-map Set attributes of aggregate
5437 route-map Set parameters of aggregate
5438 summary-only Filter more specific routes from updates
5439 suppress-map Conditionally filter more specific routes from updates
5442 struct bgp_aggregate
{
5443 /* Summary-only flag. */
5444 u_char summary_only
;
5446 /* AS set generation. */
5449 /* Route-map for aggregated route. */
5450 struct route_map
*map
;
5452 /* Suppress-count. */
5453 unsigned long count
;
5455 /* SAFI configuration. */
5459 static struct bgp_aggregate
*bgp_aggregate_new(void)
5461 return XCALLOC(MTYPE_BGP_AGGREGATE
, sizeof(struct bgp_aggregate
));
5464 static void bgp_aggregate_free(struct bgp_aggregate
*aggregate
)
5466 XFREE(MTYPE_BGP_AGGREGATE
, aggregate
);
5469 /* Update an aggregate as routes are added/removed from the BGP table */
5470 static void bgp_aggregate_route(struct bgp
*bgp
, struct prefix
*p
,
5471 struct bgp_info
*rinew
, afi_t afi
, safi_t safi
,
5472 struct bgp_info
*del
,
5473 struct bgp_aggregate
*aggregate
)
5475 struct bgp_table
*table
;
5476 struct bgp_node
*top
;
5477 struct bgp_node
*rn
;
5479 struct aspath
*aspath
= NULL
;
5480 struct aspath
*asmerge
= NULL
;
5481 struct community
*community
= NULL
;
5482 struct community
*commerge
= NULL
;
5483 #if defined(AGGREGATE_NEXTHOP_CHECK)
5484 struct in_addr nexthop
;
5487 struct bgp_info
*ri
;
5488 struct bgp_info
*new;
5490 unsigned long match
= 0;
5491 u_char atomic_aggregate
= 0;
5493 /* Record adding route's nexthop and med. */
5495 #if defined(AGGREGATE_NEXTHOP_CHECK)
5496 nexthop
= rinew
->attr
->nexthop
;
5497 med
= rinew
->attr
->med
;
5501 /* ORIGIN attribute: If at least one route among routes that are
5502 aggregated has ORIGIN with the value INCOMPLETE, then the
5503 aggregated route must have the ORIGIN attribute with the value
5504 INCOMPLETE. Otherwise, if at least one route among routes that
5505 are aggregated has ORIGIN with the value EGP, then the aggregated
5506 route must have the origin attribute with the value EGP. In all
5507 other case the value of the ORIGIN attribute of the aggregated
5508 route is INTERNAL. */
5509 origin
= BGP_ORIGIN_IGP
;
5511 table
= bgp
->rib
[afi
][safi
];
5513 top
= bgp_node_get(table
, p
);
5514 for (rn
= bgp_node_get(table
, p
); rn
;
5515 rn
= bgp_route_next_until(rn
, top
))
5516 if (rn
->p
.prefixlen
> p
->prefixlen
) {
5519 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
5520 if (BGP_INFO_HOLDDOWN(ri
))
5523 if (del
&& ri
== del
)
5526 if (!rinew
&& first
) {
5527 #if defined(AGGREGATE_NEXTHOP_CHECK)
5528 nexthop
= ri
->attr
->nexthop
;
5529 med
= ri
->attr
->med
;
5534 #ifdef AGGREGATE_NEXTHOP_CHECK
5535 if (!IPV4_ADDR_SAME(&ri
->attr
->nexthop
,
5537 || ri
->attr
->med
!= med
) {
5539 aspath_free(aspath
);
5541 community_free(community
);
5542 bgp_unlock_node(rn
);
5543 bgp_unlock_node(top
);
5546 #endif /* AGGREGATE_NEXTHOP_CHECK */
5549 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5550 atomic_aggregate
= 1;
5552 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
) {
5553 if (aggregate
->summary_only
) {
5554 (bgp_info_extra_get(ri
))
5558 BGP_INFO_ATTR_CHANGED
);
5564 if (origin
< ri
->attr
->origin
)
5565 origin
= ri
->attr
->origin
;
5567 if (aggregate
->as_set
) {
5569 asmerge
= aspath_aggregate(
5572 aspath_free(aspath
);
5575 aspath
= aspath_dup(
5578 if (ri
->attr
->community
) {
5580 commerge
= community_merge(
5582 ri
->attr
->community
);
5583 community
= community_uniq_sort(
5588 community
= community_dup(
5589 ri
->attr
->community
);
5595 bgp_process(bgp
, rn
, afi
, safi
);
5597 bgp_unlock_node(top
);
5602 if (aggregate
->summary_only
)
5603 (bgp_info_extra_get(rinew
))->suppress
++;
5605 if (origin
< rinew
->attr
->origin
)
5606 origin
= rinew
->attr
->origin
;
5608 if (aggregate
->as_set
) {
5610 asmerge
= aspath_aggregate(aspath
,
5611 rinew
->attr
->aspath
);
5612 aspath_free(aspath
);
5615 aspath
= aspath_dup(rinew
->attr
->aspath
);
5617 if (rinew
->attr
->community
) {
5619 commerge
= community_merge(
5621 rinew
->attr
->community
);
5623 community_uniq_sort(commerge
);
5624 community_free(commerge
);
5626 community
= community_dup(
5627 rinew
->attr
->community
);
5632 if (aggregate
->count
> 0) {
5633 rn
= bgp_node_get(table
, p
);
5635 ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5636 bgp_attr_aggregate_intern(bgp
, origin
, aspath
,
5637 community
, aggregate
->as_set
,
5640 SET_FLAG(new->flags
, BGP_INFO_VALID
);
5642 bgp_info_add(rn
, new);
5643 bgp_unlock_node(rn
);
5644 bgp_process(bgp
, rn
, afi
, safi
);
5647 aspath_free(aspath
);
5649 community_free(community
);
5653 void bgp_aggregate_delete(struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5654 struct bgp_aggregate
*);
5656 void bgp_aggregate_increment(struct bgp
*bgp
, struct prefix
*p
,
5657 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5659 struct bgp_node
*child
;
5660 struct bgp_node
*rn
;
5661 struct bgp_aggregate
*aggregate
;
5662 struct bgp_table
*table
;
5664 /* MPLS-VPN aggregation is not yet supported. */
5665 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5666 || (safi
== SAFI_EVPN
))
5669 table
= bgp
->aggregate
[afi
][safi
];
5671 /* No aggregates configured. */
5672 if (bgp_table_top_nolock(table
) == NULL
)
5675 if (p
->prefixlen
== 0)
5678 if (BGP_INFO_HOLDDOWN(ri
))
5681 child
= bgp_node_get(table
, p
);
5683 /* Aggregate address configuration check. */
5684 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock(rn
))
5685 if ((aggregate
= rn
->info
) != NULL
5686 && rn
->p
.prefixlen
< p
->prefixlen
) {
5687 bgp_aggregate_delete(bgp
, &rn
->p
, afi
, safi
, aggregate
);
5688 bgp_aggregate_route(bgp
, &rn
->p
, ri
, afi
, safi
, NULL
,
5691 bgp_unlock_node(child
);
5694 void bgp_aggregate_decrement(struct bgp
*bgp
, struct prefix
*p
,
5695 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5697 struct bgp_node
*child
;
5698 struct bgp_node
*rn
;
5699 struct bgp_aggregate
*aggregate
;
5700 struct bgp_table
*table
;
5702 /* MPLS-VPN aggregation is not yet supported. */
5703 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5704 || (safi
== SAFI_EVPN
))
5707 table
= bgp
->aggregate
[afi
][safi
];
5709 /* No aggregates configured. */
5710 if (bgp_table_top_nolock(table
) == NULL
)
5713 if (p
->prefixlen
== 0)
5716 child
= bgp_node_get(table
, p
);
5718 /* Aggregate address configuration check. */
5719 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock(rn
))
5720 if ((aggregate
= rn
->info
) != NULL
5721 && rn
->p
.prefixlen
< p
->prefixlen
) {
5722 bgp_aggregate_delete(bgp
, &rn
->p
, afi
, safi
, aggregate
);
5723 bgp_aggregate_route(bgp
, &rn
->p
, NULL
, afi
, safi
, del
,
5726 bgp_unlock_node(child
);
5729 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5730 static void bgp_aggregate_add(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5731 safi_t safi
, struct bgp_aggregate
*aggregate
)
5733 struct bgp_table
*table
;
5734 struct bgp_node
*top
;
5735 struct bgp_node
*rn
;
5736 struct bgp_info
*new;
5737 struct bgp_info
*ri
;
5738 unsigned long match
;
5739 u_char origin
= BGP_ORIGIN_IGP
;
5740 struct aspath
*aspath
= NULL
;
5741 struct aspath
*asmerge
= NULL
;
5742 struct community
*community
= NULL
;
5743 struct community
*commerge
= NULL
;
5744 u_char atomic_aggregate
= 0;
5746 table
= bgp
->rib
[afi
][safi
];
5749 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5751 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5754 /* If routes exists below this node, generate aggregate routes. */
5755 top
= bgp_node_get(table
, p
);
5756 for (rn
= bgp_node_get(table
, p
); rn
;
5757 rn
= bgp_route_next_until(rn
, top
))
5758 if (rn
->p
.prefixlen
> p
->prefixlen
) {
5761 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
5762 if (BGP_INFO_HOLDDOWN(ri
))
5766 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5767 atomic_aggregate
= 1;
5769 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
) {
5770 /* summary-only aggregate route suppress
5772 route announcement. */
5773 if (aggregate
->summary_only
) {
5774 (bgp_info_extra_get(ri
))
5778 BGP_INFO_ATTR_CHANGED
);
5782 /* If at least one route among routes
5783 * that are aggregated has
5784 * ORIGIN with the value INCOMPLETE,
5785 * then the aggregated route
5786 * MUST have the ORIGIN attribute with
5787 * the value INCOMPLETE.
5788 * Otherwise, if at least one route
5789 * among routes that are
5790 * aggregated has ORIGIN with the value
5791 * EGP, then the aggregated
5792 * route MUST have the ORIGIN attribute
5793 * with the value EGP.
5795 if (origin
< ri
->attr
->origin
)
5796 origin
= ri
->attr
->origin
;
5798 /* as-set aggregate route generate
5800 community aggregation. */
5801 if (aggregate
->as_set
) {
5803 asmerge
= aspath_aggregate(
5806 aspath_free(aspath
);
5809 aspath
= aspath_dup(
5812 if (ri
->attr
->community
) {
5814 commerge
= community_merge(
5816 ri
->attr
->community
);
5817 community
= community_uniq_sort(
5822 community
= community_dup(
5823 ri
->attr
->community
);
5830 /* If this node is suppressed, process the change. */
5832 bgp_process(bgp
, rn
, afi
, safi
);
5834 bgp_unlock_node(top
);
5836 /* Add aggregate route to BGP table. */
5837 if (aggregate
->count
) {
5838 rn
= bgp_node_get(table
, p
);
5840 ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5841 bgp_attr_aggregate_intern(bgp
, origin
, aspath
,
5842 community
, aggregate
->as_set
,
5845 SET_FLAG(new->flags
, BGP_INFO_VALID
);
5847 bgp_info_add(rn
, new);
5848 bgp_unlock_node(rn
);
5850 /* Process change. */
5851 bgp_process(bgp
, rn
, afi
, safi
);
5854 aspath_free(aspath
);
5856 community_free(community
);
5860 void bgp_aggregate_delete(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5861 safi_t safi
, struct bgp_aggregate
*aggregate
)
5863 struct bgp_table
*table
;
5864 struct bgp_node
*top
;
5865 struct bgp_node
*rn
;
5866 struct bgp_info
*ri
;
5867 unsigned long match
;
5869 table
= bgp
->rib
[afi
][safi
];
5871 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5873 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5876 /* If routes exists below this node, generate aggregate routes. */
5877 top
= bgp_node_get(table
, p
);
5878 for (rn
= bgp_node_get(table
, p
); rn
;
5879 rn
= bgp_route_next_until(rn
, top
))
5880 if (rn
->p
.prefixlen
> p
->prefixlen
) {
5883 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
5884 if (BGP_INFO_HOLDDOWN(ri
))
5887 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
) {
5888 if (aggregate
->summary_only
5890 ri
->extra
->suppress
--;
5892 if (ri
->extra
->suppress
== 0) {
5895 BGP_INFO_ATTR_CHANGED
);
5903 /* If this node was suppressed, process the change. */
5905 bgp_process(bgp
, rn
, afi
, safi
);
5907 bgp_unlock_node(top
);
5909 /* Delete aggregate route from BGP table. */
5910 rn
= bgp_node_get(table
, p
);
5912 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5913 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
5914 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5917 /* Withdraw static BGP route from routing table. */
5919 bgp_info_delete(rn
, ri
);
5920 bgp_process(bgp
, rn
, afi
, safi
);
5923 /* Unlock bgp_node_lookup. */
5924 bgp_unlock_node(rn
);
5927 /* Aggregate route attribute. */
5928 #define AGGREGATE_SUMMARY_ONLY 1
5929 #define AGGREGATE_AS_SET 1
5931 static int bgp_aggregate_unset(struct vty
*vty
, const char *prefix_str
,
5932 afi_t afi
, safi_t safi
)
5934 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5937 struct bgp_node
*rn
;
5938 struct bgp_aggregate
*aggregate
;
5940 /* Convert string to prefix structure. */
5941 ret
= str2prefix(prefix_str
, &p
);
5943 vty_out(vty
, "Malformed prefix\n");
5944 return CMD_WARNING_CONFIG_FAILED
;
5948 /* Old configuration check. */
5949 rn
= bgp_node_lookup(bgp
->aggregate
[afi
][safi
], &p
);
5952 "%% There is no aggregate-address configuration.\n");
5953 return CMD_WARNING_CONFIG_FAILED
;
5956 aggregate
= rn
->info
;
5957 if (aggregate
->safi
== SAFI_UNICAST
)
5958 bgp_aggregate_delete(bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5959 if (aggregate
->safi
== SAFI_LABELED_UNICAST
)
5960 bgp_aggregate_delete(bgp
, &p
, afi
, SAFI_LABELED_UNICAST
,
5962 if (aggregate
->safi
== SAFI_MULTICAST
)
5963 bgp_aggregate_delete(bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5965 /* Unlock aggregate address configuration. */
5967 bgp_aggregate_free(aggregate
);
5968 bgp_unlock_node(rn
);
5969 bgp_unlock_node(rn
);
5974 static int bgp_aggregate_set(struct vty
*vty
, const char *prefix_str
, afi_t afi
,
5975 safi_t safi
, u_char summary_only
, u_char as_set
)
5977 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5980 struct bgp_node
*rn
;
5981 struct bgp_aggregate
*aggregate
;
5983 /* Convert string to prefix structure. */
5984 ret
= str2prefix(prefix_str
, &p
);
5986 vty_out(vty
, "Malformed prefix\n");
5987 return CMD_WARNING_CONFIG_FAILED
;
5991 /* Old configuration check. */
5992 rn
= bgp_node_get(bgp
->aggregate
[afi
][safi
], &p
);
5995 vty_out(vty
, "There is already same aggregate network.\n");
5996 /* try to remove the old entry */
5997 ret
= bgp_aggregate_unset(vty
, prefix_str
, afi
, safi
);
5999 vty_out(vty
, "Error deleting aggregate.\n");
6000 bgp_unlock_node(rn
);
6001 return CMD_WARNING_CONFIG_FAILED
;
6005 /* Make aggregate address structure. */
6006 aggregate
= bgp_aggregate_new();
6007 aggregate
->summary_only
= summary_only
;
6008 aggregate
->as_set
= as_set
;
6009 aggregate
->safi
= safi
;
6010 rn
->info
= aggregate
;
6012 /* Aggregate address insert into BGP routing table. */
6013 if (safi
== SAFI_UNICAST
)
6014 bgp_aggregate_add(bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
6015 if (safi
== SAFI_LABELED_UNICAST
)
6016 bgp_aggregate_add(bgp
, &p
, afi
, SAFI_LABELED_UNICAST
,
6018 if (safi
== SAFI_MULTICAST
)
6019 bgp_aggregate_add(bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
6024 DEFUN (aggregate_address
,
6025 aggregate_address_cmd
,
6026 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
6027 "Configure BGP aggregate entries\n"
6028 "Aggregate prefix\n"
6029 "Generate AS set path information\n"
6030 "Filter more specific routes from updates\n"
6031 "Filter more specific routes from updates\n"
6032 "Generate AS set path information\n")
6035 argv_find(argv
, argc
, "A.B.C.D/M", &idx
);
6036 char *prefix
= argv
[idx
]->arg
;
6038 argv_find(argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
6040 int summary_only
= argv_find(argv
, argc
, "summary-only", &idx
)
6041 ? AGGREGATE_SUMMARY_ONLY
6044 return bgp_aggregate_set(vty
, prefix
, AFI_IP
, bgp_node_safi(vty
),
6045 summary_only
, as_set
);
6048 DEFUN (aggregate_address_mask
,
6049 aggregate_address_mask_cmd
,
6050 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
6051 "Configure BGP aggregate entries\n"
6052 "Aggregate address\n"
6054 "Generate AS set path information\n"
6055 "Filter more specific routes from updates\n"
6056 "Filter more specific routes from updates\n"
6057 "Generate AS set path information\n")
6060 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6061 char *prefix
= argv
[idx
]->arg
;
6062 char *mask
= argv
[idx
+ 1]->arg
;
6064 argv_find(argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
6066 int summary_only
= argv_find(argv
, argc
, "summary-only", &idx
)
6067 ? AGGREGATE_SUMMARY_ONLY
6070 char prefix_str
[BUFSIZ
];
6071 int ret
= netmask_str2prefix_str(prefix
, mask
, prefix_str
);
6074 vty_out(vty
, "%% Inconsistent address and mask\n");
6075 return CMD_WARNING_CONFIG_FAILED
;
6078 return bgp_aggregate_set(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
),
6079 summary_only
, as_set
);
6082 DEFUN (no_aggregate_address
,
6083 no_aggregate_address_cmd
,
6084 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
6086 "Configure BGP aggregate entries\n"
6087 "Aggregate prefix\n"
6088 "Generate AS set path information\n"
6089 "Filter more specific routes from updates\n"
6090 "Filter more specific routes from updates\n"
6091 "Generate AS set path information\n")
6094 argv_find(argv
, argc
, "A.B.C.D/M", &idx
);
6095 char *prefix
= argv
[idx
]->arg
;
6096 return bgp_aggregate_unset(vty
, prefix
, AFI_IP
, bgp_node_safi(vty
));
6099 DEFUN (no_aggregate_address_mask
,
6100 no_aggregate_address_mask_cmd
,
6101 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
6103 "Configure BGP aggregate entries\n"
6104 "Aggregate address\n"
6106 "Generate AS set path information\n"
6107 "Filter more specific routes from updates\n"
6108 "Filter more specific routes from updates\n"
6109 "Generate AS set path information\n")
6112 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6113 char *prefix
= argv
[idx
]->arg
;
6114 char *mask
= argv
[idx
+ 1]->arg
;
6116 char prefix_str
[BUFSIZ
];
6117 int ret
= netmask_str2prefix_str(prefix
, mask
, prefix_str
);
6120 vty_out(vty
, "%% Inconsistent address and mask\n");
6121 return CMD_WARNING_CONFIG_FAILED
;
6124 return bgp_aggregate_unset(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
));
6127 DEFUN (ipv6_aggregate_address
,
6128 ipv6_aggregate_address_cmd
,
6129 "aggregate-address X:X::X:X/M [summary-only]",
6130 "Configure BGP aggregate entries\n"
6131 "Aggregate prefix\n"
6132 "Filter more specific routes from updates\n")
6135 argv_find(argv
, argc
, "X:X::X:X/M", &idx
);
6136 char *prefix
= argv
[idx
]->arg
;
6137 int sum_only
= argv_find(argv
, argc
, "summary-only", &idx
)
6138 ? AGGREGATE_SUMMARY_ONLY
6140 return bgp_aggregate_set(vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
,
6144 DEFUN (no_ipv6_aggregate_address
,
6145 no_ipv6_aggregate_address_cmd
,
6146 "no aggregate-address X:X::X:X/M [summary-only]",
6148 "Configure BGP aggregate entries\n"
6149 "Aggregate prefix\n"
6150 "Filter more specific routes from updates\n")
6153 argv_find(argv
, argc
, "X:X::X:X/M", &idx
);
6154 char *prefix
= argv
[idx
]->arg
;
6155 return bgp_aggregate_unset(vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
6158 /* Redistribute route treatment. */
6159 void bgp_redistribute_add(struct bgp
*bgp
, struct prefix
*p
,
6160 const union g_addr
*nexthop
, unsigned int ifindex
,
6161 u_int32_t metric
, u_char type
, u_short instance
,
6164 struct bgp_info
*new;
6165 struct bgp_info
*bi
;
6166 struct bgp_info info
;
6167 struct bgp_node
*bn
;
6169 struct attr
*new_attr
;
6172 struct bgp_redist
*red
;
6174 /* Make default attribute. */
6175 bgp_attr_default_set(&attr
, BGP_ORIGIN_INCOMPLETE
);
6177 switch (p
->family
) {
6179 attr
.nexthop
= nexthop
->ipv4
;
6182 attr
.mp_nexthop_global
= nexthop
->ipv6
;
6183 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
6186 attr
.nh_ifindex
= ifindex
;
6189 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
6192 afi
= family2afi(p
->family
);
6194 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6196 struct attr attr_new
;
6198 /* Copy attribute for modification. */
6199 bgp_attr_dup(&attr_new
, &attr
);
6201 if (red
->redist_metric_flag
)
6202 attr_new
.med
= red
->redist_metric
;
6204 /* Apply route-map. */
6205 if (red
->rmap
.name
) {
6206 info
.peer
= bgp
->peer_self
;
6207 info
.attr
= &attr_new
;
6209 SET_FLAG(bgp
->peer_self
->rmap_type
,
6210 PEER_RMAP_TYPE_REDISTRIBUTE
);
6212 ret
= route_map_apply(red
->rmap
.map
, p
, RMAP_BGP
,
6215 bgp
->peer_self
->rmap_type
= 0;
6217 if (ret
== RMAP_DENYMATCH
) {
6218 /* Free uninterned attribute. */
6219 bgp_attr_flush(&attr_new
);
6221 /* Unintern original. */
6222 aspath_unintern(&attr
.aspath
);
6223 bgp_redistribute_delete(bgp
, p
, type
, instance
);
6228 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
6229 bgp_attr_add_gshut_community(&attr_new
);
6231 bn
= bgp_afi_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], afi
,
6232 SAFI_UNICAST
, p
, NULL
);
6234 new_attr
= bgp_attr_intern(&attr_new
);
6236 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
6237 if (bi
->peer
== bgp
->peer_self
6238 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
6242 /* Ensure the (source route) type is updated. */
6244 if (attrhash_cmp(bi
->attr
, new_attr
)
6245 && !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
)) {
6246 bgp_attr_unintern(&new_attr
);
6247 aspath_unintern(&attr
.aspath
);
6248 bgp_unlock_node(bn
);
6251 /* The attribute is changed. */
6252 bgp_info_set_flag(bn
, bi
,
6253 BGP_INFO_ATTR_CHANGED
);
6255 /* Rewrite BGP route information. */
6256 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6257 bgp_info_restore(bn
, bi
);
6259 bgp_aggregate_decrement(bgp
, p
, bi
, afi
,
6261 bgp_attr_unintern(&bi
->attr
);
6262 bi
->attr
= new_attr
;
6263 bi
->uptime
= bgp_clock();
6265 /* Process change. */
6266 bgp_aggregate_increment(bgp
, p
, bi
, afi
,
6268 bgp_process(bgp
, bn
, afi
, SAFI_UNICAST
);
6269 bgp_unlock_node(bn
);
6270 aspath_unintern(&attr
.aspath
);
6275 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
,
6276 bgp
->peer_self
, new_attr
, bn
);
6277 SET_FLAG(new->flags
, BGP_INFO_VALID
);
6279 bgp_aggregate_increment(bgp
, p
, new, afi
, SAFI_UNICAST
);
6280 bgp_info_add(bn
, new);
6281 bgp_unlock_node(bn
);
6282 bgp_process(bgp
, bn
, afi
, SAFI_UNICAST
);
6285 /* Unintern original. */
6286 aspath_unintern(&attr
.aspath
);
6289 void bgp_redistribute_delete(struct bgp
*bgp
, struct prefix
*p
, u_char type
,
6293 struct bgp_node
*rn
;
6294 struct bgp_info
*ri
;
6295 struct bgp_redist
*red
;
6297 afi
= family2afi(p
->family
);
6299 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6301 rn
= bgp_afi_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], afi
,
6302 SAFI_UNICAST
, p
, NULL
);
6304 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6305 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== type
)
6309 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, SAFI_UNICAST
);
6310 bgp_info_delete(rn
, ri
);
6311 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
6313 bgp_unlock_node(rn
);
6317 /* Withdraw specified route type's route. */
6318 void bgp_redistribute_withdraw(struct bgp
*bgp
, afi_t afi
, int type
,
6321 struct bgp_node
*rn
;
6322 struct bgp_info
*ri
;
6323 struct bgp_table
*table
;
6325 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
6327 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
6328 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6329 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== type
6330 && ri
->instance
== instance
)
6334 bgp_aggregate_decrement(bgp
, &rn
->p
, ri
, afi
,
6336 bgp_info_delete(rn
, ri
);
6337 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
6342 /* Static function to display route. */
6343 static void route_vty_out_route(struct prefix
*p
, struct vty
*vty
)
6346 u_int32_t destination
;
6349 if (p
->family
== AF_INET
) {
6350 len
= vty_out(vty
, "%s",
6351 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
));
6352 destination
= ntohl(p
->u
.prefix4
.s_addr
);
6354 if ((IN_CLASSC(destination
) && p
->prefixlen
== 24)
6355 || (IN_CLASSB(destination
) && p
->prefixlen
== 16)
6356 || (IN_CLASSA(destination
) && p
->prefixlen
== 8)
6357 || p
->u
.prefix4
.s_addr
== 0) {
6358 /* When mask is natural, mask is not displayed. */
6360 len
+= vty_out(vty
, "/%d", p
->prefixlen
);
6361 } else if (p
->family
== AF_ETHERNET
) {
6362 prefix2str(p
, buf
, PREFIX_STRLEN
);
6363 len
= vty_out(vty
, "%s", buf
);
6364 } else if (p
->family
== AF_EVPN
) {
6365 #if defined(HAVE_CUMULUS)
6366 len
= vty_out(vty
, "%s",
6367 bgp_evpn_route2str((struct prefix_evpn
*)p
, buf
,
6370 prefix2str(p
, buf
, PREFIX_STRLEN
);
6371 len
= vty_out(vty
, "%s", buf
);
6374 len
= vty_out(vty
, "%s/%d",
6375 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6380 vty_out(vty
, "\n%*s", 20, " ");
6382 vty_out(vty
, "%*s", len
, " ");
6385 enum bgp_display_type
{
6389 /* Print the short form route status for a bgp_info */
6390 static void route_vty_short_status_out(struct vty
*vty
, struct bgp_info
*binfo
,
6391 json_object
*json_path
)
6395 /* Route status display. */
6396 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_REMOVED
))
6397 json_object_boolean_true_add(json_path
, "removed");
6399 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_STALE
))
6400 json_object_boolean_true_add(json_path
, "stale");
6402 if (binfo
->extra
&& binfo
->extra
->suppress
)
6403 json_object_boolean_true_add(json_path
, "suppressed");
6405 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)
6406 && !CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6407 json_object_boolean_true_add(json_path
, "valid");
6410 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6411 json_object_boolean_true_add(json_path
, "history");
6413 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
))
6414 json_object_boolean_true_add(json_path
, "damped");
6416 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
))
6417 json_object_boolean_true_add(json_path
, "bestpath");
6419 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_MULTIPATH
))
6420 json_object_boolean_true_add(json_path
, "multipath");
6422 /* Internal route. */
6423 if ((binfo
->peer
->as
)
6424 && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6425 json_object_string_add(json_path
, "pathFrom",
6428 json_object_string_add(json_path
, "pathFrom",
6434 /* Route status display. */
6435 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_REMOVED
))
6437 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_STALE
))
6439 else if (binfo
->extra
&& binfo
->extra
->suppress
)
6441 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)
6442 && !CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6448 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6450 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
))
6452 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
))
6454 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_MULTIPATH
))
6459 /* Internal route. */
6460 if (binfo
->peer
&& (binfo
->peer
->as
)
6461 && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6467 /* called from terminal list command */
6468 void route_vty_out(struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6469 int display
, safi_t safi
, json_object
*json_paths
)
6472 json_object
*json_path
= NULL
;
6473 json_object
*json_nexthops
= NULL
;
6474 json_object
*json_nexthop_global
= NULL
;
6475 json_object
*json_nexthop_ll
= NULL
;
6478 json_path
= json_object_new_object();
6480 /* short status lead text */
6481 route_vty_short_status_out(vty
, binfo
, json_path
);
6484 /* print prefix and mask */
6486 route_vty_out_route(p
, vty
);
6488 vty_out(vty
, "%*s", 17, " ");
6491 /* Print attribute */
6495 * For ENCAP and EVPN routes, nexthop address family is not
6496 * neccessarily the same as the prefix address family.
6497 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6498 * EVPN routes are also exchanged with a MP nexthop. Currently,
6500 * is only IPv4, the value will be present in either
6502 * attr->mp_nexthop_global_in
6504 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
)) {
6506 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
6512 &attr
->mp_nexthop_global_in
,
6517 inet_ntop(af
, &attr
->mp_nexthop_global
,
6524 } else if (safi
== SAFI_EVPN
) {
6526 json_nexthop_global
= json_object_new_object();
6528 json_object_string_add(
6529 json_nexthop_global
, "ip",
6530 inet_ntoa(attr
->nexthop
));
6531 json_object_string_add(json_nexthop_global
,
6533 json_object_boolean_true_add(
6534 json_nexthop_global
, "used");
6536 vty_out(vty
, "%-16s", inet_ntoa(attr
->nexthop
));
6539 else if (p
->family
== AF_INET
6540 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6542 json_nexthop_global
= json_object_new_object();
6544 if ((safi
== SAFI_MPLS_VPN
)
6545 || (safi
== SAFI_EVPN
))
6546 json_object_string_add(
6547 json_nexthop_global
, "ip",
6549 attr
->mp_nexthop_global_in
));
6551 json_object_string_add(
6552 json_nexthop_global
, "ip",
6553 inet_ntoa(attr
->nexthop
));
6555 json_object_string_add(json_nexthop_global
,
6557 json_object_boolean_true_add(
6558 json_nexthop_global
, "used");
6560 if ((safi
== SAFI_MPLS_VPN
)
6561 || (safi
== SAFI_EVPN
))
6562 vty_out(vty
, "%-16s",
6564 attr
->mp_nexthop_global_in
));
6566 vty_out(vty
, "%-16s",
6567 inet_ntoa(attr
->nexthop
));
6572 else if (p
->family
== AF_INET6
6573 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6578 json_nexthop_global
= json_object_new_object();
6579 json_object_string_add(
6580 json_nexthop_global
, "ip",
6582 &attr
->mp_nexthop_global
, buf
,
6584 json_object_string_add(json_nexthop_global
,
6586 json_object_string_add(json_nexthop_global
,
6589 /* We display both LL & GL if both have been
6591 if ((attr
->mp_nexthop_len
== 32)
6592 || (binfo
->peer
->conf_if
)) {
6594 json_object_new_object();
6595 json_object_string_add(
6596 json_nexthop_ll
, "ip",
6599 &attr
->mp_nexthop_local
,
6601 json_object_string_add(json_nexthop_ll
,
6603 json_object_string_add(json_nexthop_ll
,
6608 &attr
->mp_nexthop_global
,
6609 &attr
->mp_nexthop_local
)
6611 && !attr
->mp_nexthop_prefer_global
)
6612 json_object_boolean_true_add(
6616 json_object_boolean_true_add(
6617 json_nexthop_global
,
6620 json_object_boolean_true_add(
6621 json_nexthop_global
, "used");
6623 /* Display LL if LL/Global both in table unless
6624 * prefer-global is set */
6625 if (((attr
->mp_nexthop_len
== 32)
6626 && !attr
->mp_nexthop_prefer_global
)
6627 || (binfo
->peer
->conf_if
)) {
6628 if (binfo
->peer
->conf_if
) {
6631 binfo
->peer
->conf_if
);
6632 len
= 16 - len
; /* len of IPv6
6638 vty_out(vty
, "\n%*s",
6641 vty_out(vty
, "%*s", len
,
6648 &attr
->mp_nexthop_local
,
6653 vty_out(vty
, "\n%*s",
6656 vty_out(vty
, "%*s", len
,
6664 &attr
->mp_nexthop_global
,
6669 vty_out(vty
, "\n%*s", 36, " ");
6671 vty_out(vty
, "%*s", len
, " ");
6677 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6679 json_object_int_add(json_path
, "med",
6682 vty_out(vty
, "%10u", attr
->med
);
6683 else if (!json_paths
)
6687 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6689 json_object_int_add(json_path
, "localpref",
6692 vty_out(vty
, "%7u", attr
->local_pref
);
6693 else if (!json_paths
)
6697 json_object_int_add(json_path
, "weight", attr
->weight
);
6699 vty_out(vty
, "%7u ", attr
->weight
);
6703 json_object_string_add(json_path
, "peerId",
6704 sockunion2str(&binfo
->peer
->su
,
6712 json_object_string_add(json_path
, "aspath",
6715 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
6720 json_object_string_add(
6721 json_path
, "origin",
6722 bgp_origin_long_str
[attr
->origin
]);
6724 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
6727 json_object_string_add(json_path
, "alert",
6730 vty_out(vty
, "No attributes to print\n");
6734 if (json_nexthop_global
|| json_nexthop_ll
) {
6735 json_nexthops
= json_object_new_array();
6737 if (json_nexthop_global
)
6738 json_object_array_add(json_nexthops
,
6739 json_nexthop_global
);
6741 if (json_nexthop_ll
)
6742 json_object_array_add(json_nexthops
,
6745 json_object_object_add(json_path
, "nexthops",
6749 json_object_array_add(json_paths
, json_path
);
6753 /* prints an additional line, indented, with VNC info, if
6755 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6756 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6761 /* called from terminal list command */
6762 void route_vty_out_tmp(struct vty
*vty
, struct prefix
*p
, struct attr
*attr
,
6763 safi_t safi
, u_char use_json
, json_object
*json_ar
)
6765 json_object
*json_status
= NULL
;
6766 json_object
*json_net
= NULL
;
6768 /* Route status display. */
6770 json_status
= json_object_new_object();
6771 json_net
= json_object_new_object();
6778 /* print prefix and mask */
6780 json_object_string_add(
6781 json_net
, "addrPrefix",
6782 inet_ntop(p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6784 route_vty_out_route(p
, vty
);
6786 /* Print attribute */
6789 if (p
->family
== AF_INET
6790 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6791 || safi
== SAFI_EVPN
6792 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6793 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6794 || safi
== SAFI_EVPN
)
6795 json_object_string_add(
6796 json_net
, "nextHop",
6798 attr
->mp_nexthop_global_in
));
6800 json_object_string_add(
6801 json_net
, "nextHop",
6802 inet_ntoa(attr
->nexthop
));
6803 } else if (p
->family
== AF_INET6
6804 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6807 json_object_string_add(
6808 json_net
, "netHopGloabal",
6810 &attr
->mp_nexthop_global
, buf
,
6815 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6816 json_object_int_add(json_net
, "metric",
6819 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6820 json_object_int_add(json_net
, "localPref",
6823 json_object_int_add(json_net
, "weight", attr
->weight
);
6827 json_object_string_add(json_net
, "asPath",
6831 json_object_string_add(json_net
, "bgpOriginCode",
6832 bgp_origin_str
[attr
->origin
]);
6834 if (p
->family
== AF_INET
6835 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6836 || safi
== SAFI_EVPN
6837 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6838 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6839 || safi
== SAFI_EVPN
)
6840 vty_out(vty
, "%-16s",
6842 attr
->mp_nexthop_global_in
));
6844 vty_out(vty
, "%-16s",
6845 inet_ntoa(attr
->nexthop
));
6846 } else if (p
->family
== AF_INET6
6847 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6854 &attr
->mp_nexthop_global
, buf
,
6858 vty_out(vty
, "\n%*s", 36, " ");
6860 vty_out(vty
, "%*s", len
, " ");
6863 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6864 vty_out(vty
, "%10u", attr
->med
);
6868 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6869 vty_out(vty
, "%7u", attr
->local_pref
);
6873 vty_out(vty
, "%7u ", attr
->weight
);
6877 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
6880 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
6884 json_object_boolean_true_add(json_status
, "*");
6885 json_object_boolean_true_add(json_status
, ">");
6886 json_object_object_add(json_net
, "appliedStatusSymbols",
6888 char buf_cut
[BUFSIZ
];
6889 json_object_object_add(
6891 inet_ntop(p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
),
6897 void route_vty_out_tag(struct vty
*vty
, struct prefix
*p
,
6898 struct bgp_info
*binfo
, int display
, safi_t safi
,
6901 json_object
*json_out
= NULL
;
6903 mpls_label_t label
= MPLS_INVALID_LABEL
;
6909 json_out
= json_object_new_object();
6911 /* short status lead text */
6912 route_vty_short_status_out(vty
, binfo
, json_out
);
6914 /* print prefix and mask */
6917 route_vty_out_route(p
, vty
);
6919 vty_out(vty
, "%*s", 17, " ");
6922 /* Print attribute */
6925 if (((p
->family
== AF_INET
)
6926 && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6927 || (safi
== SAFI_EVPN
6928 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6929 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6930 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6931 || safi
== SAFI_EVPN
) {
6933 json_object_string_add(
6934 json_out
, "mpNexthopGlobalIn",
6936 attr
->mp_nexthop_global_in
));
6938 vty_out(vty
, "%-16s",
6940 attr
->mp_nexthop_global_in
));
6943 json_object_string_add(
6944 json_out
, "nexthop",
6945 inet_ntoa(attr
->nexthop
));
6947 vty_out(vty
, "%-16s",
6948 inet_ntoa(attr
->nexthop
));
6950 } else if (((p
->family
== AF_INET6
)
6951 && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6952 || (safi
== SAFI_EVPN
6953 && BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6954 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6958 if (attr
->mp_nexthop_len
6959 == BGP_ATTR_NHLEN_IPV6_GLOBAL
) {
6961 json_object_string_add(
6962 json_out
, "mpNexthopGlobalIn",
6965 &attr
->mp_nexthop_global
,
6971 &attr
->mp_nexthop_global
,
6973 } else if (attr
->mp_nexthop_len
6974 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) {
6977 &attr
->mp_nexthop_global
,
6980 &attr
->mp_nexthop_local
,
6982 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6983 json_object_string_add(
6985 "mpNexthopGlobalLocal", buf_c
);
6987 vty_out(vty
, "%s(%s)",
6990 &attr
->mp_nexthop_global
,
6994 &attr
->mp_nexthop_local
,
7000 label
= decode_label(&binfo
->extra
->label
);
7002 if (bgp_is_valid_label(&label
)) {
7004 json_object_int_add(json_out
, "notag", label
);
7005 json_object_array_add(json
, json_out
);
7007 vty_out(vty
, "notag/%d", label
);
7013 void route_vty_out_overlay(struct vty
*vty
, struct prefix
*p
,
7014 struct bgp_info
*binfo
, int display
,
7015 json_object
*json_paths
)
7019 json_object
*json_path
= NULL
;
7022 json_path
= json_object_new_object();
7027 /* short status lead text */
7028 route_vty_short_status_out(vty
, binfo
, json_path
);
7030 /* print prefix and mask */
7032 route_vty_out_route(p
, vty
);
7034 vty_out(vty
, "%*s", 17, " ");
7036 /* Print attribute */
7040 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
7044 vty_out(vty
, "%-16s",
7045 inet_ntop(af
, &attr
->mp_nexthop_global_in
, buf
,
7049 vty_out(vty
, "%s(%s)",
7050 inet_ntop(af
, &attr
->mp_nexthop_global
, buf
,
7052 inet_ntop(af
, &attr
->mp_nexthop_local
, buf1
,
7060 struct eth_segment_id
*id
= &(attr
->evpn_overlay
.eth_s_id
);
7061 char *str
= esi2str(id
);
7062 vty_out(vty
, "%s", str
);
7063 XFREE(MTYPE_TMP
, str
);
7064 if (IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn
*)p
)) {
7065 vty_out(vty
, "/%s", inet_ntoa(attr
->evpn_overlay
.gw_ip
.ipv4
));
7066 } else if (IS_EVPN_PREFIX_IPADDR_V6((struct prefix_evpn
*)p
)) {
7068 inet_ntop(AF_INET6
, &(attr
->evpn_overlay
.gw_ip
.ipv6
),
7071 if (attr
->ecommunity
) {
7073 struct ecommunity_val
*routermac
= ecommunity_lookup(
7074 attr
->ecommunity
, ECOMMUNITY_ENCODE_EVPN
,
7075 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC
);
7077 mac
= ecom_mac2str((char *)routermac
->val
);
7079 vty_out(vty
, "/%s", (char *)mac
);
7080 XFREE(MTYPE_TMP
, mac
);
7086 /* dampening route */
7087 static void damp_route_vty_out(struct vty
*vty
, struct prefix
*p
,
7088 struct bgp_info
*binfo
, int display
, safi_t safi
,
7089 u_char use_json
, json_object
*json
)
7093 char timebuf
[BGP_UPTIME_LEN
];
7095 /* short status lead text */
7096 route_vty_short_status_out(vty
, binfo
, json
);
7098 /* print prefix and mask */
7101 route_vty_out_route(p
, vty
);
7103 vty_out(vty
, "%*s", 17, " ");
7106 len
= vty_out(vty
, "%s", binfo
->peer
->host
);
7110 vty_out(vty
, "\n%*s", 34, " ");
7113 json_object_int_add(json
, "peerHost", len
);
7115 vty_out(vty
, "%*s", len
, " ");
7119 bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
, BGP_UPTIME_LEN
,
7122 vty_out(vty
, "%s ", bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
,
7126 /* Print attribute */
7132 json_object_string_add(json
, "asPath",
7135 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7140 json_object_string_add(json
, "origin",
7141 bgp_origin_str
[attr
->origin
]);
7143 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7150 static void flap_route_vty_out(struct vty
*vty
, struct prefix
*p
,
7151 struct bgp_info
*binfo
, int display
, safi_t safi
,
7152 u_char use_json
, json_object
*json
)
7155 struct bgp_damp_info
*bdi
;
7156 char timebuf
[BGP_UPTIME_LEN
];
7162 bdi
= binfo
->extra
->damp_info
;
7164 /* short status lead text */
7165 route_vty_short_status_out(vty
, binfo
, json
);
7167 /* print prefix and mask */
7170 route_vty_out_route(p
, vty
);
7172 vty_out(vty
, "%*s", 17, " ");
7175 len
= vty_out(vty
, "%s", binfo
->peer
->host
);
7179 vty_out(vty
, "\n%*s", 33, " ");
7182 json_object_int_add(json
, "peerHost", len
);
7184 vty_out(vty
, "%*s", len
, " ");
7187 len
= vty_out(vty
, "%d", bdi
->flap
);
7194 json_object_int_add(json
, "bdiFlap", len
);
7196 vty_out(vty
, "%*s", len
, " ");
7200 peer_uptime(bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
,
7203 vty_out(vty
, "%s ", peer_uptime(bdi
->start_time
, timebuf
,
7204 BGP_UPTIME_LEN
, 0, NULL
));
7206 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
)
7207 && !CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
)) {
7209 bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
,
7210 BGP_UPTIME_LEN
, use_json
, json
);
7213 bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
,
7218 vty_out(vty
, "%*s ", 8, " ");
7221 /* Print attribute */
7227 json_object_string_add(json
, "asPath",
7230 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7235 json_object_string_add(json
, "origin",
7236 bgp_origin_str
[attr
->origin
]);
7238 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7244 static void route_vty_out_advertised_to(struct vty
*vty
, struct peer
*peer
,
7245 int *first
, const char *header
,
7246 json_object
*json_adv_to
)
7248 char buf1
[INET6_ADDRSTRLEN
];
7249 json_object
*json_peer
= NULL
;
7252 /* 'advertised-to' is a dictionary of peers we have advertised
7254 * prefix too. The key is the peer's IP or swpX, the value is
7256 * hostname if we know it and "" if not.
7258 json_peer
= json_object_new_object();
7261 json_object_string_add(json_peer
, "hostname",
7265 json_object_object_add(json_adv_to
, peer
->conf_if
,
7268 json_object_object_add(
7270 sockunion2str(&peer
->su
, buf1
, SU_ADDRSTRLEN
),
7274 vty_out(vty
, "%s", header
);
7279 && bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
)) {
7281 vty_out(vty
, " %s(%s)", peer
->hostname
,
7284 vty_out(vty
, " %s(%s)", peer
->hostname
,
7285 sockunion2str(&peer
->su
, buf1
,
7289 vty_out(vty
, " %s", peer
->conf_if
);
7292 sockunion2str(&peer
->su
, buf1
,
7298 void route_vty_out_detail(struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
7299 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
7300 json_object
*json_paths
)
7302 char buf
[INET6_ADDRSTRLEN
];
7304 #if defined(HAVE_CUMULUS)
7305 char buf2
[EVPN_ROUTE_STRLEN
];
7308 int sockunion_vty_out(struct vty
*, union sockunion
*);
7310 json_object
*json_bestpath
= NULL
;
7311 json_object
*json_cluster_list
= NULL
;
7312 json_object
*json_cluster_list_list
= NULL
;
7313 json_object
*json_ext_community
= NULL
;
7314 json_object
*json_last_update
= NULL
;
7315 json_object
*json_nexthop_global
= NULL
;
7316 json_object
*json_nexthop_ll
= NULL
;
7317 json_object
*json_nexthops
= NULL
;
7318 json_object
*json_path
= NULL
;
7319 json_object
*json_peer
= NULL
;
7320 json_object
*json_string
= NULL
;
7321 json_object
*json_adv_to
= NULL
;
7323 struct listnode
*node
, *nnode
;
7325 int addpath_capable
;
7327 unsigned int first_as
;
7330 json_path
= json_object_new_object();
7331 json_peer
= json_object_new_object();
7332 json_nexthop_global
= json_object_new_object();
7335 #if defined(HAVE_CUMULUS)
7336 if (!json_paths
&& safi
== SAFI_EVPN
) {
7339 bgp_evpn_route2str((struct prefix_evpn
*)p
, buf2
, sizeof(buf2
));
7340 vty_out(vty
, " Route %s", buf2
);
7343 bgp_evpn_label2str(&binfo
->extra
->label
, tag_buf
,
7345 vty_out(vty
, " VNI %s", tag_buf
);
7348 if (binfo
->extra
&& binfo
->extra
->parent
) {
7349 struct bgp_info
*parent_ri
;
7350 struct bgp_node
*rn
, *prn
;
7352 parent_ri
= (struct bgp_info
*)binfo
->extra
->parent
;
7353 rn
= parent_ri
->net
;
7354 if (rn
&& rn
->prn
) {
7356 vty_out(vty
, " Imported from %s:%s\n",
7358 (struct prefix_rd
*)&prn
->p
,
7359 buf1
, RD_ADDRSTRLEN
),
7369 /* Line1 display AS-path, Aggregator */
7372 json_object_lock(attr
->aspath
->json
);
7373 json_object_object_add(json_path
, "aspath",
7374 attr
->aspath
->json
);
7376 if (attr
->aspath
->segments
)
7377 aspath_print_vty(vty
, " %s",
7380 vty_out(vty
, " Local");
7384 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_REMOVED
)) {
7386 json_object_boolean_true_add(json_path
,
7389 vty_out(vty
, ", (removed)");
7392 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_STALE
)) {
7394 json_object_boolean_true_add(json_path
,
7397 vty_out(vty
, ", (stale)");
7400 if (CHECK_FLAG(attr
->flag
,
7401 ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR
))) {
7403 json_object_int_add(json_path
, "aggregatorAs",
7404 attr
->aggregator_as
);
7405 json_object_string_add(
7406 json_path
, "aggregatorId",
7407 inet_ntoa(attr
->aggregator_addr
));
7409 vty_out(vty
, ", (aggregated by %u %s)",
7410 attr
->aggregator_as
,
7411 inet_ntoa(attr
->aggregator_addr
));
7415 if (CHECK_FLAG(binfo
->peer
->af_flags
[afi
][safi
],
7416 PEER_FLAG_REFLECTOR_CLIENT
)) {
7418 json_object_boolean_true_add(
7419 json_path
, "rxedFromRrClient");
7421 vty_out(vty
, ", (Received from a RR-client)");
7424 if (CHECK_FLAG(binfo
->peer
->af_flags
[afi
][safi
],
7425 PEER_FLAG_RSERVER_CLIENT
)) {
7427 json_object_boolean_true_add(
7428 json_path
, "rxedFromRsClient");
7430 vty_out(vty
, ", (Received from a RS-client)");
7433 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
)) {
7435 json_object_boolean_true_add(
7436 json_path
, "dampeningHistoryEntry");
7438 vty_out(vty
, ", (history entry)");
7439 } else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
)) {
7441 json_object_boolean_true_add(
7442 json_path
, "dampeningSuppressed");
7444 vty_out(vty
, ", (suppressed due to dampening)");
7450 /* Line2 display Next-hop, Neighbor, Router-id */
7451 /* Display the nexthop */
7452 if ((p
->family
== AF_INET
|| p
->family
== AF_ETHERNET
||
7453 p
->family
== AF_EVPN
)
7454 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7455 || safi
== SAFI_EVPN
7456 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7457 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7458 || safi
== SAFI_EVPN
) {
7460 json_object_string_add(
7461 json_nexthop_global
, "ip",
7463 attr
->mp_nexthop_global_in
));
7467 attr
->mp_nexthop_global_in
));
7470 json_object_string_add(
7471 json_nexthop_global
, "ip",
7472 inet_ntoa(attr
->nexthop
));
7475 inet_ntoa(attr
->nexthop
));
7479 json_object_string_add(json_nexthop_global
,
7483 json_object_string_add(
7484 json_nexthop_global
, "ip",
7486 &attr
->mp_nexthop_global
, buf
,
7488 json_object_string_add(json_nexthop_global
,
7490 json_object_string_add(json_nexthop_global
,
7495 &attr
->mp_nexthop_global
, buf
,
7500 /* Display the IGP cost or 'inaccessible' */
7501 if (!CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)) {
7503 json_object_boolean_false_add(
7504 json_nexthop_global
, "accessible");
7506 vty_out(vty
, " (inaccessible)");
7508 if (binfo
->extra
&& binfo
->extra
->igpmetric
) {
7510 json_object_int_add(
7511 json_nexthop_global
, "metric",
7512 binfo
->extra
->igpmetric
);
7514 vty_out(vty
, " (metric %u)",
7515 binfo
->extra
->igpmetric
);
7518 /* IGP cost is 0, display this only for json */
7521 json_object_int_add(json_nexthop_global
,
7526 json_object_boolean_true_add(
7527 json_nexthop_global
, "accessible");
7530 /* Display peer "from" output */
7531 /* This path was originated locally */
7532 if (binfo
->peer
== bgp
->peer_self
) {
7534 if (safi
== SAFI_EVPN
7535 || (p
->family
== AF_INET
7536 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7538 json_object_string_add(
7539 json_peer
, "peerId", "0.0.0.0");
7541 vty_out(vty
, " from 0.0.0.0 ");
7544 json_object_string_add(json_peer
,
7547 vty_out(vty
, " from :: ");
7551 json_object_string_add(
7552 json_peer
, "routerId",
7553 inet_ntoa(bgp
->router_id
));
7555 vty_out(vty
, "(%s)", inet_ntoa(bgp
->router_id
));
7558 /* We RXed this path from one of our peers */
7562 json_object_string_add(
7563 json_peer
, "peerId",
7564 sockunion2str(&binfo
->peer
->su
, buf
,
7566 json_object_string_add(
7567 json_peer
, "routerId",
7569 &binfo
->peer
->remote_id
, buf1
,
7572 if (binfo
->peer
->hostname
)
7573 json_object_string_add(
7574 json_peer
, "hostname",
7575 binfo
->peer
->hostname
);
7577 if (binfo
->peer
->domainname
)
7578 json_object_string_add(
7579 json_peer
, "domainname",
7580 binfo
->peer
->domainname
);
7582 if (binfo
->peer
->conf_if
)
7583 json_object_string_add(
7584 json_peer
, "interface",
7585 binfo
->peer
->conf_if
);
7587 if (binfo
->peer
->conf_if
) {
7588 if (binfo
->peer
->hostname
7591 BGP_FLAG_SHOW_HOSTNAME
))
7592 vty_out(vty
, " from %s(%s)",
7593 binfo
->peer
->hostname
,
7594 binfo
->peer
->conf_if
);
7596 vty_out(vty
, " from %s",
7597 binfo
->peer
->conf_if
);
7599 if (binfo
->peer
->hostname
7602 BGP_FLAG_SHOW_HOSTNAME
))
7603 vty_out(vty
, " from %s(%s)",
7604 binfo
->peer
->hostname
,
7607 vty_out(vty
, " from %s",
7616 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7617 vty_out(vty
, " (%s)",
7618 inet_ntoa(attr
->originator_id
));
7620 vty_out(vty
, " (%s)",
7623 &binfo
->peer
->remote_id
,
7631 /* display the link-local nexthop */
7632 if (attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) {
7634 json_nexthop_ll
= json_object_new_object();
7635 json_object_string_add(
7636 json_nexthop_ll
, "ip",
7638 &attr
->mp_nexthop_local
, buf
,
7640 json_object_string_add(json_nexthop_ll
, "afi",
7642 json_object_string_add(json_nexthop_ll
, "scope",
7645 json_object_boolean_true_add(json_nexthop_ll
,
7648 if (!attr
->mp_nexthop_prefer_global
)
7649 json_object_boolean_true_add(
7650 json_nexthop_ll
, "used");
7652 json_object_boolean_true_add(
7653 json_nexthop_global
, "used");
7655 vty_out(vty
, " (%s) %s\n",
7657 &attr
->mp_nexthop_local
, buf
,
7659 attr
->mp_nexthop_prefer_global
7664 /* If we do not have a link-local nexthop then we must flag the
7668 json_object_boolean_true_add(
7669 json_nexthop_global
, "used");
7672 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
7673 * Int/Ext/Local, Atomic, best */
7675 json_object_string_add(
7676 json_path
, "origin",
7677 bgp_origin_long_str
[attr
->origin
]);
7679 vty_out(vty
, " Origin %s",
7680 bgp_origin_long_str
[attr
->origin
]);
7682 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)) {
7684 json_object_int_add(json_path
, "med",
7687 vty_out(vty
, ", metric %u", attr
->med
);
7690 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
7692 json_object_int_add(json_path
, "localpref",
7695 vty_out(vty
, ", localpref %u",
7699 json_object_int_add(json_path
, "localpref",
7700 bgp
->default_local_pref
);
7702 vty_out(vty
, ", localpref %u",
7703 bgp
->default_local_pref
);
7706 if (attr
->weight
!= 0) {
7708 json_object_int_add(json_path
, "weight",
7711 vty_out(vty
, ", weight %u", attr
->weight
);
7714 if (attr
->tag
!= 0) {
7716 json_object_int_add(json_path
, "tag",
7719 vty_out(vty
, ", tag %" ROUTE_TAG_PRI
,
7723 if (!CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)) {
7725 json_object_boolean_false_add(json_path
,
7728 vty_out(vty
, ", invalid");
7729 } else if (!CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
)) {
7731 json_object_boolean_true_add(json_path
,
7734 vty_out(vty
, ", valid");
7737 if (binfo
->peer
!= bgp
->peer_self
) {
7738 if (binfo
->peer
->as
== binfo
->peer
->local_as
) {
7739 if (CHECK_FLAG(bgp
->config
,
7740 BGP_CONFIG_CONFEDERATION
)) {
7742 json_object_string_add(
7747 ", confed-internal");
7750 json_object_string_add(
7754 vty_out(vty
, ", internal");
7757 if (bgp_confederation_peers_check(
7758 bgp
, binfo
->peer
->as
)) {
7760 json_object_string_add(
7765 ", confed-external");
7768 json_object_string_add(
7772 vty_out(vty
, ", external");
7775 } else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
) {
7777 json_object_boolean_true_add(json_path
,
7779 json_object_boolean_true_add(json_path
,
7782 vty_out(vty
, ", aggregated, local");
7784 } else if (binfo
->type
!= ZEBRA_ROUTE_BGP
) {
7786 json_object_boolean_true_add(json_path
,
7789 vty_out(vty
, ", sourced");
7792 json_object_boolean_true_add(json_path
,
7794 json_object_boolean_true_add(json_path
,
7797 vty_out(vty
, ", sourced, local");
7801 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
)) {
7803 json_object_boolean_true_add(json_path
,
7806 vty_out(vty
, ", atomic-aggregate");
7809 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_MULTIPATH
)
7810 || (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
)
7811 && bgp_info_mpath_count(binfo
))) {
7813 json_object_boolean_true_add(json_path
,
7816 vty_out(vty
, ", multipath");
7819 // Mark the bestpath(s)
7820 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DMED_SELECTED
)) {
7821 first_as
= aspath_get_first_as(attr
->aspath
);
7826 json_object_new_object();
7827 json_object_int_add(json_bestpath
,
7828 "bestpathFromAs", first_as
);
7831 vty_out(vty
, ", bestpath-from-AS %d",
7835 ", bestpath-from-AS Local");
7839 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
)) {
7843 json_object_new_object();
7844 json_object_boolean_true_add(json_bestpath
,
7847 vty_out(vty
, ", best");
7851 json_object_object_add(json_path
, "bestpath",
7857 /* Line 4 display Community */
7858 if (attr
->community
) {
7860 json_object_lock(attr
->community
->json
);
7861 json_object_object_add(json_path
, "community",
7862 attr
->community
->json
);
7864 vty_out(vty
, " Community: %s\n",
7865 attr
->community
->str
);
7869 /* Line 5 display Extended-community */
7870 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)) {
7872 json_ext_community
= json_object_new_object();
7873 json_object_string_add(json_ext_community
,
7875 attr
->ecommunity
->str
);
7876 json_object_object_add(json_path
,
7877 "extendedCommunity",
7878 json_ext_community
);
7880 vty_out(vty
, " Extended Community: %s\n",
7881 attr
->ecommunity
->str
);
7885 /* Line 6 display Large community */
7886 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
))
7887 vty_out(vty
, " Large Community: %s\n",
7888 attr
->lcommunity
->str
);
7890 /* Line 7 display Originator, Cluster-id */
7891 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7892 || (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))) {
7894 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) {
7896 json_object_string_add(
7897 json_path
, "originatorId",
7898 inet_ntoa(attr
->originator_id
));
7900 vty_out(vty
, " Originator: %s",
7901 inet_ntoa(attr
->originator_id
));
7904 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)) {
7909 json_object_new_object();
7910 json_cluster_list_list
=
7911 json_object_new_array();
7914 i
< attr
->cluster
->length
/ 4;
7916 json_string
= json_object_new_string(
7920 json_object_array_add(
7921 json_cluster_list_list
,
7925 /* struct cluster_list does not have
7927 * aspath and community do. Add this
7930 json_object_string_add(json_cluster_list,
7931 "string", attr->cluster->str);
7933 json_object_object_add(
7934 json_cluster_list
, "list",
7935 json_cluster_list_list
);
7936 json_object_object_add(
7937 json_path
, "clusterList",
7940 vty_out(vty
, ", Cluster list: ");
7943 i
< attr
->cluster
->length
/ 4;
7957 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7958 bgp_damp_info_vty(vty
, binfo
, json_path
);
7961 #if defined(HAVE_CUMULUS)
7962 if (binfo
->extra
&& bgp_is_valid_label(&binfo
->extra
->label
)
7963 && safi
!= SAFI_EVPN
)
7965 if (binfo
->extra
&& bgp_is_valid_label(&binfo
->extra
->label
))
7968 mpls_label_t label
= label_pton(&binfo
->extra
->label
);
7970 json_object_int_add(json_path
, "remoteLabel",
7973 vty_out(vty
, " Remote label: %d\n", label
);
7977 if (attr
->label_index
!= BGP_INVALID_LABEL_INDEX
) {
7979 json_object_int_add(json_path
, "labelIndex",
7982 vty_out(vty
, " Label Index: %d\n",
7986 /* Line 8 display Addpath IDs */
7987 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
) {
7989 json_object_int_add(json_path
, "addpathRxId",
7990 binfo
->addpath_rx_id
);
7991 json_object_int_add(json_path
, "addpathTxId",
7992 binfo
->addpath_tx_id
);
7994 vty_out(vty
, " AddPath ID: RX %u, TX %u\n",
7995 binfo
->addpath_rx_id
,
7996 binfo
->addpath_tx_id
);
8000 /* If we used addpath to TX a non-bestpath we need to display
8001 * "Advertised to" on a path-by-path basis */
8002 if (bgp
->addpath_tx_used
[afi
][safi
]) {
8005 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
8007 bgp_addpath_encode_tx(peer
, afi
, safi
);
8008 has_adj
= bgp_adj_out_lookup(
8009 peer
, binfo
->net
, binfo
->addpath_tx_id
);
8011 if ((addpath_capable
&& has_adj
)
8012 || (!addpath_capable
&& has_adj
8013 && CHECK_FLAG(binfo
->flags
,
8014 BGP_INFO_SELECTED
))) {
8015 if (json_path
&& !json_adv_to
)
8017 json_object_new_object();
8019 route_vty_out_advertised_to(
8028 json_object_object_add(json_path
,
8039 /* Line 9 display Uptime */
8040 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
8042 json_last_update
= json_object_new_object();
8043 json_object_int_add(json_last_update
, "epoch", tbuf
);
8044 json_object_string_add(json_last_update
, "string",
8046 json_object_object_add(json_path
, "lastUpdate",
8049 vty_out(vty
, " Last update: %s", ctime(&tbuf
));
8052 /* We've constructed the json object for this path, add it to the json
8056 if (json_nexthop_global
|| json_nexthop_ll
) {
8057 json_nexthops
= json_object_new_array();
8059 if (json_nexthop_global
)
8060 json_object_array_add(json_nexthops
,
8061 json_nexthop_global
);
8063 if (json_nexthop_ll
)
8064 json_object_array_add(json_nexthops
,
8067 json_object_object_add(json_path
, "nexthops",
8071 json_object_object_add(json_path
, "peer", json_peer
);
8072 json_object_array_add(json_paths
, json_path
);
8077 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
8078 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
8079 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
8081 static int bgp_show_prefix_list(struct vty
*vty
, struct bgp
*bgp
,
8082 const char *prefix_list_str
, afi_t afi
,
8083 safi_t safi
, enum bgp_show_type type
);
8084 static int bgp_show_filter_list(struct vty
*vty
, struct bgp
*bgp
,
8085 const char *filter
, afi_t afi
, safi_t safi
,
8086 enum bgp_show_type type
);
8087 static int bgp_show_route_map(struct vty
*vty
, struct bgp
*bgp
,
8088 const char *rmap_str
, afi_t afi
, safi_t safi
,
8089 enum bgp_show_type type
);
8090 static int bgp_show_community_list(struct vty
*vty
, struct bgp
*bgp
,
8091 const char *com
, int exact
, afi_t afi
,
8093 static int bgp_show_prefix_longer(struct vty
*vty
, struct bgp
*bgp
,
8094 const char *prefix
, afi_t afi
, safi_t safi
,
8095 enum bgp_show_type type
);
8096 static int bgp_show_regexp(struct vty
*vty
, struct bgp
*bgp
,
8097 const char *regstr
, afi_t afi
,
8098 safi_t safi
, enum bgp_show_type type
);
8099 static int bgp_show_community(struct vty
*vty
, struct bgp
*bgp
,
8100 const char *comstr
, int exact
, afi_t afi
,
8103 static int bgp_show_table(struct vty
*vty
, struct bgp
*bgp
,
8104 struct bgp_table
*table
, enum bgp_show_type type
,
8105 void *output_arg
, u_char use_json
)
8107 struct bgp_info
*ri
;
8108 struct bgp_node
*rn
;
8111 unsigned long output_count
;
8112 unsigned long total_count
;
8116 json_object
*json_paths
= NULL
;
8121 "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
8122 ", \"routerId\": \"%s\", \"routes\": { ",
8123 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : bgp
->vrf_id
,
8124 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default"
8126 table
->version
, inet_ntoa(bgp
->router_id
));
8127 json_paths
= json_object_new_object();
8130 /* This is first entry point, so reset total line. */
8134 /* Start processing of routes. */
8135 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
8136 if (rn
->info
!= NULL
) {
8138 if (!first
&& use_json
) {
8142 json_paths
= json_object_new_array();
8146 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
8148 if (type
== bgp_show_type_flap_statistics
8149 || type
== bgp_show_type_flap_neighbor
8150 || type
== bgp_show_type_dampend_paths
8151 || type
== bgp_show_type_damp_neighbor
) {
8153 && ri
->extra
->damp_info
))
8156 if (type
== bgp_show_type_regexp
) {
8157 regex_t
*regex
= output_arg
;
8159 if (bgp_regexec(regex
, ri
->attr
->aspath
)
8163 if (type
== bgp_show_type_prefix_list
) {
8164 struct prefix_list
*plist
= output_arg
;
8166 if (prefix_list_apply(plist
, &rn
->p
)
8170 if (type
== bgp_show_type_filter_list
) {
8171 struct as_list
*as_list
= output_arg
;
8173 if (as_list_apply(as_list
,
8175 != AS_FILTER_PERMIT
)
8178 if (type
== bgp_show_type_route_map
) {
8179 struct route_map
*rmap
= output_arg
;
8180 struct bgp_info binfo
;
8181 struct attr dummy_attr
;
8184 bgp_attr_dup(&dummy_attr
, ri
->attr
);
8186 binfo
.peer
= ri
->peer
;
8187 binfo
.attr
= &dummy_attr
;
8189 ret
= route_map_apply(rmap
, &rn
->p
,
8191 if (ret
== RMAP_DENYMATCH
)
8194 if (type
== bgp_show_type_neighbor
8195 || type
== bgp_show_type_flap_neighbor
8196 || type
== bgp_show_type_damp_neighbor
) {
8197 union sockunion
*su
= output_arg
;
8199 if (ri
->peer
== NULL
8200 || ri
->peer
->su_remote
== NULL
8202 ri
->peer
->su_remote
, su
))
8205 if (type
== bgp_show_type_cidr_only
) {
8206 u_int32_t destination
;
8209 ntohl(rn
->p
.u
.prefix4
.s_addr
);
8210 if (IN_CLASSC(destination
)
8211 && rn
->p
.prefixlen
== 24)
8213 if (IN_CLASSB(destination
)
8214 && rn
->p
.prefixlen
== 16)
8216 if (IN_CLASSA(destination
)
8217 && rn
->p
.prefixlen
== 8)
8220 if (type
== bgp_show_type_prefix_longer
) {
8221 struct prefix
*p
= output_arg
;
8223 if (!prefix_match(p
, &rn
->p
))
8226 if (type
== bgp_show_type_community_all
) {
8227 if (!ri
->attr
->community
)
8230 if (type
== bgp_show_type_community
) {
8231 struct community
*com
= output_arg
;
8233 if (!ri
->attr
->community
8234 || !community_match(
8235 ri
->attr
->community
,
8239 if (type
== bgp_show_type_community_exact
) {
8240 struct community
*com
= output_arg
;
8242 if (!ri
->attr
->community
8244 ri
->attr
->community
,
8248 if (type
== bgp_show_type_community_list
) {
8249 struct community_list
*list
=
8252 if (!community_list_match(
8253 ri
->attr
->community
, list
))
8257 == bgp_show_type_community_list_exact
) {
8258 struct community_list
*list
=
8261 if (!community_list_exact_match(
8262 ri
->attr
->community
, list
))
8265 if (type
== bgp_show_type_lcommunity
) {
8266 struct lcommunity
*lcom
= output_arg
;
8268 if (!ri
->attr
->lcommunity
8269 || !lcommunity_match(
8270 ri
->attr
->lcommunity
,
8274 if (type
== bgp_show_type_lcommunity_list
) {
8275 struct community_list
*list
=
8278 if (!lcommunity_list_match(
8279 ri
->attr
->lcommunity
, list
))
8282 if (type
== bgp_show_type_lcommunity_all
) {
8283 if (!ri
->attr
->lcommunity
)
8286 if (type
== bgp_show_type_dampend_paths
8287 || type
== bgp_show_type_damp_neighbor
) {
8288 if (!CHECK_FLAG(ri
->flags
,
8290 || CHECK_FLAG(ri
->flags
,
8295 if (!use_json
&& header
) {
8297 "BGP table version is %" PRIu64
8298 ", local router ID is %s\n",
8300 inet_ntoa(bgp
->router_id
));
8301 vty_out(vty
, BGP_SHOW_SCODE_HEADER
);
8302 vty_out(vty
, BGP_SHOW_OCODE_HEADER
);
8303 if (type
== bgp_show_type_dampend_paths
8304 || type
== bgp_show_type_damp_neighbor
)
8306 BGP_SHOW_DAMP_HEADER
);
8308 type
== bgp_show_type_flap_statistics
8309 || type
== bgp_show_type_flap_neighbor
)
8311 BGP_SHOW_FLAP_HEADER
);
8313 vty_out(vty
, BGP_SHOW_HEADER
);
8317 if (type
== bgp_show_type_dampend_paths
8318 || type
== bgp_show_type_damp_neighbor
)
8320 vty
, &rn
->p
, ri
, display
,
8321 SAFI_UNICAST
, use_json
,
8323 else if (type
== bgp_show_type_flap_statistics
8324 || type
== bgp_show_type_flap_neighbor
)
8326 vty
, &rn
->p
, ri
, display
,
8327 SAFI_UNICAST
, use_json
,
8330 route_vty_out(vty
, &rn
->p
, ri
, display
,
8331 SAFI_UNICAST
, json_paths
);
8339 sprintf(buf2
, "%s/%d",
8340 inet_ntop(p
->family
,
8344 vty_out(vty
, "\"%s\": ", buf2
);
8346 json_object_to_json_string(
8348 json_object_free(json_paths
);
8355 json_object_free(json_paths
);
8356 vty_out(vty
, " } }\n");
8358 /* No route is displayed */
8359 if (output_count
== 0) {
8360 if (type
== bgp_show_type_normal
)
8362 "No BGP prefixes displayed, %ld exist\n",
8366 "\nDisplayed %ld routes and %ld total paths\n",
8367 output_count
, total_count
);
8373 static int bgp_show(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
8374 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
8376 struct bgp_table
*table
;
8379 bgp
= bgp_get_default();
8384 vty_out(vty
, "No BGP process is configured\n");
8386 vty_out(vty
, "{}\n");
8390 /* use MPLS and ENCAP specific shows until they are merged */
8391 if (safi
== SAFI_MPLS_VPN
) {
8392 return bgp_show_mpls_vpn(vty
, afi
, NULL
, type
, output_arg
, 0,
8395 /* labeled-unicast routes live in the unicast table */
8396 else if (safi
== SAFI_LABELED_UNICAST
)
8397 safi
= SAFI_UNICAST
;
8399 table
= bgp
->rib
[afi
][safi
];
8401 return bgp_show_table(vty
, bgp
, table
, type
, output_arg
, use_json
);
8404 static void bgp_show_all_instances_routes_vty(struct vty
*vty
, afi_t afi
,
8405 safi_t safi
, u_char use_json
)
8407 struct listnode
*node
, *nnode
;
8412 vty_out(vty
, "{\n");
8414 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
8417 vty_out(vty
, ",\n");
8421 vty_out(vty
, "\"%s\":",
8422 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8426 vty_out(vty
, "\nInstance %s:\n",
8427 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8431 bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_normal
, NULL
,
8436 vty_out(vty
, "}\n");
8439 /* Header of detailed BGP route information */
8440 void route_vty_out_detail_header(struct vty
*vty
, struct bgp
*bgp
,
8441 struct bgp_node
*rn
, struct prefix_rd
*prd
,
8442 afi_t afi
, safi_t safi
, json_object
*json
)
8444 struct bgp_info
*ri
;
8447 struct listnode
*node
, *nnode
;
8448 char buf1
[INET6_ADDRSTRLEN
];
8449 char buf2
[INET6_ADDRSTRLEN
];
8450 #if defined(HAVE_CUMULUS)
8451 char buf3
[EVPN_ROUTE_STRLEN
];
8457 int no_advertise
= 0;
8460 int has_valid_label
= 0;
8461 mpls_label_t label
= 0;
8462 json_object
*json_adv_to
= NULL
;
8465 has_valid_label
= bgp_is_valid_label(&rn
->local_label
);
8467 if (has_valid_label
)
8468 label
= label_pton(&rn
->local_label
);
8471 if (has_valid_label
)
8472 json_object_int_add(json
, "localLabel", label
);
8474 json_object_string_add(json
, "prefix",
8475 inet_ntop(p
->family
, &p
->u
.prefix
, buf2
,
8477 json_object_int_add(json
, "prefixlen", p
->prefixlen
);
8479 #if defined(HAVE_CUMULUS)
8480 if (safi
== SAFI_EVPN
)
8481 vty_out(vty
, "BGP routing table entry for %s%s%s\n",
8482 prd
? prefix_rd2str(prd
, buf1
, RD_ADDRSTRLEN
)
8485 bgp_evpn_route2str((struct prefix_evpn
*)p
,
8486 buf3
, sizeof(buf3
)));
8488 vty_out(vty
, "BGP routing table entry for %s%s%s/%d\n",
8489 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
8490 ? prefix_rd2str(prd
, buf1
,
8493 safi
== SAFI_MPLS_VPN
? ":" : "",
8494 inet_ntop(p
->family
, &p
->u
.prefix
, buf2
,
8498 if (p
->family
== AF_ETHERNET
)
8499 prefix2str(p
, buf2
, INET6_ADDRSTRLEN
);
8501 inet_ntop(p
->family
, &p
->u
.prefix
, buf2
,
8503 vty_out(vty
, "BGP routing table entry for %s%s%s/%d\n",
8504 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
8505 || safi
== SAFI_EVPN
)
8506 ? prefix_rd2str(prd
, buf1
, RD_ADDRSTRLEN
)
8508 ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
)) ? ":"
8510 buf2
, p
->prefixlen
);
8513 if (has_valid_label
)
8514 vty_out(vty
, "Local label: %d\n", label
);
8515 #if defined(HAVE_CUMULUS)
8516 if (bgp_labeled_safi(safi
) && safi
!= SAFI_EVPN
)
8518 if (bgp_labeled_safi(safi
))
8520 vty_out(vty
, "not allocated\n");
8523 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
8525 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
8527 if (ri
->extra
&& ri
->extra
->suppress
)
8529 if (ri
->attr
->community
!= NULL
) {
8530 if (community_include(ri
->attr
->community
,
8531 COMMUNITY_NO_ADVERTISE
))
8533 if (community_include(ri
->attr
->community
,
8534 COMMUNITY_NO_EXPORT
))
8536 if (community_include(ri
->attr
->community
,
8537 COMMUNITY_LOCAL_AS
))
8544 vty_out(vty
, "Paths: (%d available", count
);
8546 vty_out(vty
, ", best #%d", best
);
8547 if (safi
== SAFI_UNICAST
)
8548 vty_out(vty
, ", table %s",
8550 == BGP_INSTANCE_TYPE_DEFAULT
)
8551 ? "Default-IP-Routing-Table"
8554 vty_out(vty
, ", no best path");
8557 vty_out(vty
, ", not advertised to any peer");
8559 vty_out(vty
, ", not advertised to EBGP peer");
8561 vty_out(vty
, ", not advertised outside local AS");
8565 ", Advertisements suppressed by an aggregate.");
8566 vty_out(vty
, ")\n");
8569 /* If we are not using addpath then we can display Advertised to and
8571 * show what peers we advertised the bestpath to. If we are using
8573 * though then we must display Advertised to on a path-by-path basis. */
8574 if (!bgp
->addpath_tx_used
[afi
][safi
]) {
8575 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
8576 if (bgp_adj_out_lookup(peer
, rn
, 0)) {
8577 if (json
&& !json_adv_to
)
8578 json_adv_to
= json_object_new_object();
8580 route_vty_out_advertised_to(
8582 " Advertised to non peer-group peers:\n ",
8589 json_object_object_add(json
, "advertisedTo",
8594 vty_out(vty
, " Not advertised to any peer");
8600 /* Display specified route of BGP table. */
8601 static int bgp_show_route_in_table(struct vty
*vty
, struct bgp
*bgp
,
8602 struct bgp_table
*rib
, const char *ip_str
,
8603 afi_t afi
, safi_t safi
,
8604 struct prefix_rd
*prd
, int prefix_check
,
8605 enum bgp_path_type pathtype
, u_char use_json
)
8610 struct prefix match
;
8611 struct bgp_node
*rn
;
8612 struct bgp_node
*rm
;
8613 struct bgp_info
*ri
;
8614 struct bgp_table
*table
;
8615 json_object
*json
= NULL
;
8616 json_object
*json_paths
= NULL
;
8618 /* Check IP address argument. */
8619 ret
= str2prefix(ip_str
, &match
);
8621 vty_out(vty
, "address is malformed\n");
8625 match
.family
= afi2family(afi
);
8628 json
= json_object_new_object();
8629 json_paths
= json_object_new_array();
8632 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) {
8633 for (rn
= bgp_table_top(rib
); rn
; rn
= bgp_route_next(rn
)) {
8634 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
8637 if ((table
= rn
->info
) != NULL
) {
8640 if ((rm
= bgp_node_match(table
, &match
))
8644 != match
.prefixlen
) {
8645 bgp_unlock_node(rm
);
8649 for (ri
= rm
->info
; ri
; ri
= ri
->next
) {
8651 route_vty_out_detail_header(
8662 if (pathtype
== BGP_PATH_ALL
8664 == BGP_PATH_BESTPATH
8669 == BGP_PATH_MULTIPATH
8675 BGP_INFO_SELECTED
))))
8676 route_vty_out_detail(
8683 bgp_unlock_node(rm
);
8690 if ((rn
= bgp_node_match(rib
, &match
)) != NULL
) {
8692 || rn
->p
.prefixlen
== match
.prefixlen
) {
8693 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
8695 route_vty_out_detail_header(
8696 vty
, bgp
, rn
, NULL
, afi
,
8702 if (pathtype
== BGP_PATH_ALL
8703 || (pathtype
== BGP_PATH_BESTPATH
8707 || (pathtype
== BGP_PATH_MULTIPATH
8713 BGP_INFO_SELECTED
))))
8714 route_vty_out_detail(
8715 vty
, bgp
, &rn
->p
, ri
,
8716 afi
, safi
, json_paths
);
8720 bgp_unlock_node(rn
);
8726 json_object_object_add(json
, "paths", json_paths
);
8728 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8729 json
, JSON_C_TO_STRING_PRETTY
));
8730 json_object_free(json
);
8733 vty_out(vty
, "%% Network not in table\n");
8741 /* Display specified route of Main RIB */
8742 static int bgp_show_route(struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
8743 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8744 int prefix_check
, enum bgp_path_type pathtype
,
8748 bgp
= bgp_get_default();
8751 vty_out(vty
, "No BGP process is configured\n");
8753 vty_out(vty
, "{}\n");
8758 /* labeled-unicast routes live in the unicast table */
8759 if (safi
== SAFI_LABELED_UNICAST
)
8760 safi
= SAFI_UNICAST
;
8762 return bgp_show_route_in_table(vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
8763 afi
, safi
, prd
, prefix_check
, pathtype
,
8767 static int bgp_show_lcommunity(struct vty
*vty
, struct bgp
*bgp
, int argc
,
8768 struct cmd_token
**argv
, afi_t afi
, safi_t safi
,
8771 struct lcommunity
*lcom
;
8777 b
= buffer_new(1024);
8778 for (i
= 0; i
< argc
; i
++) {
8780 buffer_putc(b
, ' ');
8782 if (strmatch(argv
[i
]->text
, "AA:BB:CC")) {
8784 buffer_putstr(b
, argv
[i
]->arg
);
8788 buffer_putc(b
, '\0');
8790 str
= buffer_getstr(b
);
8793 lcom
= lcommunity_str2com(str
);
8794 XFREE(MTYPE_TMP
, str
);
8796 vty_out(vty
, "%% Large-community malformed\n");
8800 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
,
8804 static int bgp_show_lcommunity_list(struct vty
*vty
, struct bgp
*bgp
,
8805 const char *lcom
, afi_t afi
, safi_t safi
,
8808 struct community_list
*list
;
8810 list
= community_list_lookup(bgp_clist
, lcom
,
8811 LARGE_COMMUNITY_LIST_MASTER
);
8813 vty_out(vty
, "%% %s is not a valid large-community-list name\n",
8818 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
,
8822 DEFUN (show_ip_bgp_large_community_list
,
8823 show_ip_bgp_large_community_list_cmd
,
8824 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community-list <(1-500)|WORD> [json]",
8828 BGP_INSTANCE_HELP_STR
8830 BGP_SAFI_WITH_LABEL_HELP_STR
8831 "Display routes matching the large-community-list\n"
8832 "large-community-list number\n"
8833 "large-community-list name\n"
8837 afi_t afi
= AFI_IP6
;
8838 safi_t safi
= SAFI_UNICAST
;
8841 if (argv_find(argv
, argc
, "ip", &idx
))
8843 if (argv_find(argv
, argc
, "view", &idx
)
8844 || argv_find(argv
, argc
, "vrf", &idx
))
8845 vrf
= argv
[++idx
]->arg
;
8846 if (argv_find(argv
, argc
, "ipv4", &idx
)
8847 || argv_find(argv
, argc
, "ipv6", &idx
)) {
8848 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8849 if (argv_find(argv
, argc
, "unicast", &idx
)
8850 || argv_find(argv
, argc
, "multicast", &idx
))
8851 safi
= bgp_vty_safi_from_str(argv
[idx
]->text
);
8854 int uj
= use_json(argc
, argv
);
8856 struct bgp
*bgp
= bgp_lookup_by_name(vrf
);
8858 vty_out(vty
, "Can't find BGP instance %s\n", vrf
);
8862 argv_find(argv
, argc
, "large-community-list", &idx
);
8863 return bgp_show_lcommunity_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
,
8866 DEFUN (show_ip_bgp_large_community
,
8867 show_ip_bgp_large_community_cmd
,
8868 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community [AA:BB:CC] [json]",
8872 BGP_INSTANCE_HELP_STR
8874 BGP_SAFI_WITH_LABEL_HELP_STR
8875 "Display routes matching the large-communities\n"
8876 "List of large-community numbers\n"
8880 afi_t afi
= AFI_IP6
;
8881 safi_t safi
= SAFI_UNICAST
;
8884 if (argv_find(argv
, argc
, "ip", &idx
))
8886 if (argv_find(argv
, argc
, "view", &idx
)
8887 || argv_find(argv
, argc
, "vrf", &idx
))
8888 vrf
= argv
[++idx
]->arg
;
8889 if (argv_find(argv
, argc
, "ipv4", &idx
)
8890 || argv_find(argv
, argc
, "ipv6", &idx
)) {
8891 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8892 if (argv_find(argv
, argc
, "unicast", &idx
)
8893 || argv_find(argv
, argc
, "multicast", &idx
))
8894 safi
= bgp_vty_safi_from_str(argv
[idx
]->text
);
8897 int uj
= use_json(argc
, argv
);
8899 struct bgp
*bgp
= bgp_lookup_by_name(vrf
);
8901 vty_out(vty
, "Can't find BGP instance %s\n", vrf
);
8905 if (argv_find(argv
, argc
, "AA:BB:CC", &idx
))
8906 return bgp_show_lcommunity(vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
8908 return bgp_show(vty
, bgp
, afi
, safi
,
8909 bgp_show_type_lcommunity_all
, NULL
, uj
);
8912 static int bgp_table_stats(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
8916 /* BGP route print out function without JSON */
8919 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
8920 <dampening <parameters>\
8925 |community <AA:NN|local-AS|no-advertise|no-export|graceful-shutdown> [exact-match]\
8926 |community-list <(1-500)|WORD> [exact-match]\
8927 |A.B.C.D/M longer-prefixes\
8928 |X:X::X:X/M longer-prefixes\
8933 BGP_INSTANCE_HELP_STR
8935 BGP_SAFI_WITH_LABEL_HELP_STR
8936 "Display detailed information about dampening\n"
8937 "Display detail of configured dampening parameters\n"
8938 "Display routes matching the route-map\n"
8939 "A route-map to match on\n"
8940 "Display routes conforming to the prefix-list\n"
8941 "Prefix-list name\n"
8942 "Display routes conforming to the filter-list\n"
8943 "Regular expression access list name\n"
8944 "BGP RIB advertisement statistics\n"
8945 "Display routes matching the communities\n"
8947 "Do not send outside local AS (well-known community)\n"
8948 "Do not advertise to any peer (well-known community)\n"
8949 "Do not export to next AS (well-known community)\n"
8950 "Graceful shutdown (well-known community)\n"
8951 "Exact match of the communities\n"
8952 "Display routes matching the community-list\n"
8953 "community-list number\n"
8954 "community-list name\n"
8955 "Exact match of the communities\n"
8957 "Display route and more specific routes\n"
8959 "Display route and more specific routes\n")
8961 afi_t afi
= AFI_IP6
;
8962 safi_t safi
= SAFI_UNICAST
;
8963 int exact_match
= 0;
8964 struct bgp
*bgp
= NULL
;
8966 int idx_community_type
= 0;
8968 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
8973 if (argv_find(argv
, argc
, "dampening", &idx
)) {
8974 if (argv_find(argv
, argc
, "parameters", &idx
))
8975 return bgp_show_dampening_parameters(vty
, afi
, safi
);
8978 if (argv_find(argv
, argc
, "prefix-list", &idx
))
8979 return bgp_show_prefix_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
8980 safi
, bgp_show_type_prefix_list
);
8982 if (argv_find(argv
, argc
, "filter-list", &idx
))
8983 return bgp_show_filter_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
8984 safi
, bgp_show_type_filter_list
);
8986 if (argv_find(argv
, argc
, "statistics", &idx
))
8987 return bgp_table_stats(vty
, bgp
, afi
, safi
);
8989 if (argv_find(argv
, argc
, "route-map", &idx
))
8990 return bgp_show_route_map(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
8991 safi
, bgp_show_type_route_map
);
8993 if (argv_find(argv
, argc
, "community", &idx
)) {
8994 /* show a specific community */
8995 if (argv_find(argv
, argc
, "local-AS", &idx_community_type
)
8996 || argv_find(argv
, argc
, "no-advertise", &idx_community_type
)
8997 || argv_find(argv
, argc
, "no-export", &idx_community_type
)
8998 || argv_find(argv
, argc
, "graceful-shutdown", &idx_community_type
)
8999 || argv_find(argv
, argc
, "AA:NN", &idx_community_type
)) {
9001 if (argv_find(argv
, argc
, "exact-match", &idx
))
9003 return bgp_show_community(vty
, bgp
, argv
[idx_community_type
]->arg
,
9004 exact_match
, afi
, safi
);
9008 if (argv_find(argv
, argc
, "community-list", &idx
)) {
9009 const char *clist_number_or_name
= argv
[++idx
]->arg
;
9010 if (++idx
< argc
&& strmatch(argv
[idx
]->text
, "exact-match"))
9012 return bgp_show_community_list(vty
, bgp
, clist_number_or_name
,
9013 exact_match
, afi
, safi
);
9016 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)
9017 || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
9018 return bgp_show_prefix_longer(vty
, bgp
, argv
[idx
]->arg
, afi
,
9020 bgp_show_type_prefix_longer
);
9025 /* BGP route print out function with JSON */
9026 DEFUN (show_ip_bgp_json
,
9027 show_ip_bgp_json_cmd
,
9028 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
9031 |dampening <flap-statistics|dampened-paths>\
9037 BGP_INSTANCE_HELP_STR
9039 BGP_SAFI_WITH_LABEL_HELP_STR
9040 "Display only routes with non-natural netmasks\n"
9041 "Display detailed information about dampening\n"
9042 "Display flap statistics of routes\n"
9043 "Display paths suppressed due to dampening\n"
9044 "Display routes matching the communities\n"
9047 afi_t afi
= AFI_IP6
;
9048 safi_t safi
= SAFI_UNICAST
;
9049 enum bgp_show_type sh_type
= bgp_show_type_normal
;
9050 struct bgp
*bgp
= NULL
;
9053 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9058 int uj
= use_json(argc
, argv
);
9062 if (argv_find(argv
, argc
, "cidr-only", &idx
))
9063 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
,
9066 if (argv_find(argv
, argc
, "dampening", &idx
)) {
9067 if (argv_find(argv
, argc
, "dampened-paths", &idx
))
9068 return bgp_show(vty
, bgp
, afi
, safi
,
9069 bgp_show_type_dampend_paths
, NULL
, uj
);
9070 else if (argv_find(argv
, argc
, "flap-statistics", &idx
))
9071 return bgp_show(vty
, bgp
, afi
, safi
,
9072 bgp_show_type_flap_statistics
, NULL
,
9076 if (argv_find(argv
, argc
, "community", &idx
)) {
9077 /* show all communities */
9078 return bgp_show(vty
, bgp
, afi
, safi
,
9079 bgp_show_type_community_all
, NULL
, uj
);
9082 if (safi
== SAFI_MPLS_VPN
)
9083 return bgp_show_mpls_vpn(vty
, afi
, NULL
, bgp_show_type_normal
,
9086 return bgp_show(vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
9089 DEFUN (show_ip_bgp_route
,
9090 show_ip_bgp_route_cmd
,
9091 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]"
9092 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
9096 BGP_INSTANCE_HELP_STR
9098 BGP_SAFI_WITH_LABEL_HELP_STR
9099 "Network in the BGP routing table to display\n"
9101 "Network in the BGP routing table to display\n"
9103 "Display only the bestpath\n"
9104 "Display only multipaths\n"
9107 int prefix_check
= 0;
9109 afi_t afi
= AFI_IP6
;
9110 safi_t safi
= SAFI_UNICAST
;
9111 char *prefix
= NULL
;
9112 struct bgp
*bgp
= NULL
;
9113 enum bgp_path_type path_type
;
9114 u_char uj
= use_json(argc
, argv
);
9118 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9125 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
9129 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
9130 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)
9131 || argv_find(argv
, argc
, "X:X::X:X", &idx
))
9133 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)
9134 || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
9137 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
)
9138 && afi
!= AFI_IP6
) {
9140 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
9143 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
)
9146 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
9150 prefix
= argv
[idx
]->arg
;
9152 /* [<bestpath|multipath>] */
9153 if (argv_find(argv
, argc
, "bestpath", &idx
))
9154 path_type
= BGP_PATH_BESTPATH
;
9155 else if (argv_find(argv
, argc
, "multipath", &idx
))
9156 path_type
= BGP_PATH_MULTIPATH
;
9158 path_type
= BGP_PATH_ALL
;
9160 return bgp_show_route(vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
,
9164 DEFUN (show_ip_bgp_regexp
,
9165 show_ip_bgp_regexp_cmd
,
9166 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] regexp REGEX...",
9170 BGP_INSTANCE_HELP_STR
9172 BGP_SAFI_WITH_LABEL_HELP_STR
9173 "Display routes matching the AS path regular expression\n"
9174 "A regular-expression to match the BGP AS paths\n")
9176 afi_t afi
= AFI_IP6
;
9177 safi_t safi
= SAFI_UNICAST
;
9178 struct bgp
*bgp
= NULL
;
9181 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9186 // get index of regex
9187 argv_find(argv
, argc
, "regexp", &idx
);
9190 char *regstr
= argv_concat(argv
, argc
, idx
);
9191 int rc
= bgp_show_regexp(vty
, bgp
, (const char *)regstr
, afi
, safi
,
9192 bgp_show_type_regexp
);
9193 XFREE(MTYPE_TMP
, regstr
);
9197 DEFUN (show_ip_bgp_instance_all
,
9198 show_ip_bgp_instance_all_cmd
,
9199 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] [json]",
9203 BGP_INSTANCE_ALL_HELP_STR
9205 BGP_SAFI_WITH_LABEL_HELP_STR
9209 safi_t safi
= SAFI_UNICAST
;
9210 struct bgp
*bgp
= NULL
;
9213 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9218 int uj
= use_json(argc
, argv
);
9222 bgp_show_all_instances_routes_vty(vty
, afi
, safi
, uj
);
9226 static int bgp_show_regexp(struct vty
*vty
, struct bgp
*bgp
,
9227 const char *regstr
, afi_t afi
,
9228 safi_t safi
, enum bgp_show_type type
)
9233 regex
= bgp_regcomp(regstr
);
9235 vty_out(vty
, "Can't compile regexp %s\n", regstr
);
9239 rc
= bgp_show(vty
, bgp
, afi
, safi
, type
, regex
, 0);
9240 bgp_regex_free(regex
);
9244 static int bgp_show_prefix_list(struct vty
*vty
, struct bgp
*bgp
,
9245 const char *prefix_list_str
, afi_t afi
,
9246 safi_t safi
, enum bgp_show_type type
)
9248 struct prefix_list
*plist
;
9250 plist
= prefix_list_lookup(afi
, prefix_list_str
);
9251 if (plist
== NULL
) {
9252 vty_out(vty
, "%% %s is not a valid prefix-list name\n",
9257 return bgp_show(vty
, bgp
, afi
, safi
, type
, plist
, 0);
9260 static int bgp_show_filter_list(struct vty
*vty
, struct bgp
*bgp
,
9261 const char *filter
, afi_t afi
, safi_t safi
,
9262 enum bgp_show_type type
)
9264 struct as_list
*as_list
;
9266 as_list
= as_list_lookup(filter
);
9267 if (as_list
== NULL
) {
9268 vty_out(vty
, "%% %s is not a valid AS-path access-list name\n",
9273 return bgp_show(vty
, bgp
, afi
, safi
, type
, as_list
, 0);
9276 static int bgp_show_route_map(struct vty
*vty
, struct bgp
*bgp
,
9277 const char *rmap_str
, afi_t afi
, safi_t safi
,
9278 enum bgp_show_type type
)
9280 struct route_map
*rmap
;
9282 rmap
= route_map_lookup_by_name(rmap_str
);
9284 vty_out(vty
, "%% %s is not a valid route-map name\n", rmap_str
);
9288 return bgp_show(vty
, bgp
, afi
, safi
, type
, rmap
, 0);
9291 static int bgp_show_community(struct vty
*vty
, struct bgp
*bgp
,
9292 const char *comstr
, int exact
, afi_t afi
,
9295 struct community
*com
;
9298 com
= community_str2com(comstr
);
9300 vty_out(vty
, "%% Community malformed: %s\n", comstr
);
9304 ret
= bgp_show(vty
, bgp
, afi
, safi
,
9305 (exact
? bgp_show_type_community_exact
9306 : bgp_show_type_community
),
9308 community_free(com
);
9313 static int bgp_show_community_list(struct vty
*vty
, struct bgp
*bgp
,
9314 const char *com
, int exact
, afi_t afi
,
9317 struct community_list
*list
;
9319 list
= community_list_lookup(bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
9321 vty_out(vty
, "%% %s is not a valid community-list name\n", com
);
9325 return bgp_show(vty
, bgp
, afi
, safi
,
9326 (exact
? bgp_show_type_community_list_exact
9327 : bgp_show_type_community_list
),
9331 static int bgp_show_prefix_longer(struct vty
*vty
, struct bgp
*bgp
,
9332 const char *prefix
, afi_t afi
, safi_t safi
,
9333 enum bgp_show_type type
)
9340 ret
= str2prefix(prefix
, p
);
9342 vty_out(vty
, "%% Malformed Prefix\n");
9346 ret
= bgp_show(vty
, bgp
, afi
, safi
, type
, p
, 0);
9351 static struct peer
*peer_lookup_in_view(struct vty
*vty
, struct bgp
*bgp
,
9352 const char *ip_str
, u_char use_json
)
9358 /* Get peer sockunion. */
9359 ret
= str2sockunion(ip_str
, &su
);
9361 peer
= peer_lookup_by_conf_if(bgp
, ip_str
);
9363 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
9367 json_object
*json_no
= NULL
;
9368 json_no
= json_object_new_object();
9369 json_object_string_add(
9371 "malformedAddressOrName",
9373 vty_out(vty
, "%s\n",
9374 json_object_to_json_string(
9376 json_object_free(json_no
);
9379 "%% Malformed address or name: %s\n",
9387 /* Peer structure lookup. */
9388 peer
= peer_lookup(bgp
, &su
);
9391 json_object
*json_no
= NULL
;
9392 json_no
= json_object_new_object();
9393 json_object_string_add(json_no
, "warning",
9394 "No such neighbor");
9395 vty_out(vty
, "%s\n",
9396 json_object_to_json_string(json_no
));
9397 json_object_free(json_no
);
9399 vty_out(vty
, "No such neighbor\n");
9407 BGP_STATS_MAXBITLEN
= 0,
9411 BGP_STATS_UNAGGREGATEABLE
,
9412 BGP_STATS_MAX_AGGREGATEABLE
,
9413 BGP_STATS_AGGREGATES
,
9415 BGP_STATS_ASPATH_COUNT
,
9416 BGP_STATS_ASPATH_MAXHOPS
,
9417 BGP_STATS_ASPATH_TOTHOPS
,
9418 BGP_STATS_ASPATH_MAXSIZE
,
9419 BGP_STATS_ASPATH_TOTSIZE
,
9420 BGP_STATS_ASN_HIGHEST
,
9424 static const char *table_stats_strs
[] = {
9425 [BGP_STATS_PREFIXES
] = "Total Prefixes",
9426 [BGP_STATS_TOTPLEN
] = "Average prefix length",
9427 [BGP_STATS_RIB
] = "Total Advertisements",
9428 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
9429 [BGP_STATS_MAX_AGGREGATEABLE
] =
9430 "Maximum aggregateable prefixes",
9431 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
9432 [BGP_STATS_SPACE
] = "Address space advertised",
9433 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
9434 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
9435 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
9436 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
9437 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
9438 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
9439 [BGP_STATS_MAX
] = NULL
,
9442 struct bgp_table_stats
{
9443 struct bgp_table
*table
;
9444 unsigned long long counts
[BGP_STATS_MAX
];
9449 #define TALLY_SIGFIG 100000
9450 static unsigned long
9451 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
9453 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
9454 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
9455 unsigned long ret
= newtot
/ count
;
9457 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
9464 static int bgp_table_stats_walker(struct thread
*t
)
9466 struct bgp_node
*rn
;
9467 struct bgp_node
*top
;
9468 struct bgp_table_stats
*ts
= THREAD_ARG(t
);
9469 unsigned int space
= 0;
9471 if (!(top
= bgp_table_top(ts
->table
)))
9474 switch (top
->p
.family
) {
9476 space
= IPV4_MAX_BITLEN
;
9479 space
= IPV6_MAX_BITLEN
;
9483 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
9485 for (rn
= top
; rn
; rn
= bgp_route_next(rn
)) {
9486 struct bgp_info
*ri
;
9487 struct bgp_node
*prn
= bgp_node_parent_nolock(rn
);
9488 unsigned int rinum
= 0;
9496 ts
->counts
[BGP_STATS_PREFIXES
]++;
9497 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
9500 ts
->counts
[BGP_STATS_AVGPLEN
]
9501 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
9502 ts
->counts
[BGP_STATS_AVGPLEN
],
9506 /* check if the prefix is included by any other announcements */
9507 while (prn
&& !prn
->info
)
9508 prn
= bgp_node_parent_nolock(prn
);
9510 if (prn
== NULL
|| prn
== top
) {
9511 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
9512 /* announced address space */
9514 ts
->total_space
+= pow(2.0,
9515 space
- rn
->p
.prefixlen
);
9516 } else if (prn
->info
)
9517 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
9519 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
9521 ts
->counts
[BGP_STATS_RIB
]++;
9524 && (CHECK_FLAG(ri
->attr
->flag
,
9526 BGP_ATTR_ATOMIC_AGGREGATE
))))
9527 ts
->counts
[BGP_STATS_AGGREGATES
]++;
9530 if (ri
->attr
&& ri
->attr
->aspath
) {
9532 aspath_count_hops(ri
->attr
->aspath
);
9534 aspath_size(ri
->attr
->aspath
);
9535 as_t highest
= aspath_highest(ri
->attr
->aspath
);
9537 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
9539 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
9540 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] =
9543 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
9544 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] =
9547 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
9548 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
9550 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
9551 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9552 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
9554 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
9555 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9556 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
9559 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
9560 ts
->counts
[BGP_STATS_ASN_HIGHEST
] =
9568 static int bgp_table_stats(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
9571 struct bgp_table_stats ts
;
9574 if (!bgp
->rib
[afi
][safi
]) {
9575 vty_out(vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
9580 vty_out(vty
, "BGP %s RIB statistics\n", afi_safi_print(afi
, safi
));
9582 /* labeled-unicast routes live in the unicast table */
9583 if (safi
== SAFI_LABELED_UNICAST
)
9584 safi
= SAFI_UNICAST
;
9586 memset(&ts
, 0, sizeof(ts
));
9587 ts
.table
= bgp
->rib
[afi
][safi
];
9588 thread_execute(bm
->master
, bgp_table_stats_walker
, &ts
, 0);
9590 for (i
= 0; i
< BGP_STATS_MAX
; i
++) {
9591 if (!table_stats_strs
[i
])
9596 case BGP_STATS_ASPATH_AVGHOPS
:
9597 case BGP_STATS_ASPATH_AVGSIZE
:
9598 case BGP_STATS_AVGPLEN
:
9599 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9600 vty_out (vty
, "%12.2f",
9601 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
9604 case BGP_STATS_ASPATH_TOTHOPS
:
9605 case BGP_STATS_ASPATH_TOTSIZE
:
9606 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9607 vty_out(vty
, "%12.2f",
9609 ? (float)ts
.counts
[i
]
9611 [BGP_STATS_ASPATH_COUNT
]
9614 case BGP_STATS_TOTPLEN
:
9615 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9616 vty_out(vty
, "%12.2f",
9618 ? (float)ts
.counts
[i
]
9620 [BGP_STATS_PREFIXES
]
9623 case BGP_STATS_SPACE
:
9624 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9625 vty_out(vty
, "%12g\n", ts
.total_space
);
9627 if (afi
== AFI_IP6
) {
9628 vty_out(vty
, "%30s: ", "/32 equivalent ");
9629 vty_out(vty
, "%12g\n",
9630 ts
.total_space
* pow(2.0, -128+32));
9631 vty_out(vty
, "%30s: ", "/48 equivalent ");
9632 vty_out(vty
, "%12g\n",
9633 ts
.total_space
* pow(2.0, -128+48));
9635 vty_out(vty
, "%30s: ", "% announced ");
9636 vty_out(vty
, "%12.2f\n",
9637 ts
.total_space
* 100. * pow(2.0, -32));
9638 vty_out(vty
, "%30s: ", "/8 equivalent ");
9639 vty_out(vty
, "%12.2f\n",
9640 ts
.total_space
* pow(2.0, -32+8));
9641 vty_out(vty
, "%30s: ", "/24 equivalent ");
9642 vty_out(vty
, "%12.2f\n",
9643 ts
.total_space
* pow(2.0, -32+24));
9647 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9648 vty_out(vty
, "%12llu", ts
.counts
[i
]);
9665 PCOUNT_PFCNT
, /* the figure we display to users */
9669 static const char *pcount_strs
[] = {
9670 [PCOUNT_ADJ_IN
] = "Adj-in",
9671 [PCOUNT_DAMPED
] = "Damped",
9672 [PCOUNT_REMOVED
] = "Removed",
9673 [PCOUNT_HISTORY
] = "History",
9674 [PCOUNT_STALE
] = "Stale",
9675 [PCOUNT_VALID
] = "Valid",
9676 [PCOUNT_ALL
] = "All RIB",
9677 [PCOUNT_COUNTED
] = "PfxCt counted",
9678 [PCOUNT_PFCNT
] = "Useable",
9679 [PCOUNT_MAX
] = NULL
,
9682 struct peer_pcounts
{
9683 unsigned int count
[PCOUNT_MAX
];
9684 const struct peer
*peer
;
9685 const struct bgp_table
*table
;
9688 static int bgp_peer_count_walker(struct thread
*t
)
9690 struct bgp_node
*rn
;
9691 struct peer_pcounts
*pc
= THREAD_ARG(t
);
9692 const struct peer
*peer
= pc
->peer
;
9694 for (rn
= bgp_table_top(pc
->table
); rn
; rn
= bgp_route_next(rn
)) {
9695 struct bgp_adj_in
*ain
;
9696 struct bgp_info
*ri
;
9698 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9699 if (ain
->peer
== peer
)
9700 pc
->count
[PCOUNT_ADJ_IN
]++;
9702 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
9703 char buf
[SU_ADDRSTRLEN
];
9705 if (ri
->peer
!= peer
)
9708 pc
->count
[PCOUNT_ALL
]++;
9710 if (CHECK_FLAG(ri
->flags
, BGP_INFO_DAMPED
))
9711 pc
->count
[PCOUNT_DAMPED
]++;
9712 if (CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
9713 pc
->count
[PCOUNT_HISTORY
]++;
9714 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
9715 pc
->count
[PCOUNT_REMOVED
]++;
9716 if (CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
))
9717 pc
->count
[PCOUNT_STALE
]++;
9718 if (CHECK_FLAG(ri
->flags
, BGP_INFO_VALID
))
9719 pc
->count
[PCOUNT_VALID
]++;
9720 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
9721 pc
->count
[PCOUNT_PFCNT
]++;
9723 if (CHECK_FLAG(ri
->flags
, BGP_INFO_COUNTED
)) {
9724 pc
->count
[PCOUNT_COUNTED
]++;
9725 if (CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
9727 "%s [pcount] %s/%d is counted but flags 0x%x",
9729 inet_ntop(rn
->p
.family
,
9730 &rn
->p
.u
.prefix
, buf
,
9732 rn
->p
.prefixlen
, ri
->flags
);
9734 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
9736 "%s [pcount] %s/%d not counted but flags 0x%x",
9738 inet_ntop(rn
->p
.family
,
9739 &rn
->p
.u
.prefix
, buf
,
9741 rn
->p
.prefixlen
, ri
->flags
);
9748 static int bgp_peer_counts(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9749 safi_t safi
, u_char use_json
)
9751 struct peer_pcounts pcounts
= {.peer
= peer
};
9753 json_object
*json
= NULL
;
9754 json_object
*json_loop
= NULL
;
9757 json
= json_object_new_object();
9758 json_loop
= json_object_new_object();
9761 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
9762 || !peer
->bgp
->rib
[afi
][safi
]) {
9764 json_object_string_add(
9766 "No such neighbor or address family");
9767 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
9768 json_object_free(json
);
9770 vty_out(vty
, "%% No such neighbor or address family\n");
9775 memset(&pcounts
, 0, sizeof(pcounts
));
9776 pcounts
.peer
= peer
;
9777 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
9779 /* in-place call via thread subsystem so as to record execution time
9780 * * stats for the thread-walk (i.e. ensure this can't be blamed on
9781 * * on just vty_read()).
9783 thread_execute(bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
9786 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
9787 json_object_string_add(json
, "multiProtocol",
9788 afi_safi_print(afi
, safi
));
9789 json_object_int_add(json
, "pfxCounter",
9790 peer
->pcount
[afi
][safi
]);
9792 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9793 json_object_int_add(json_loop
, pcount_strs
[i
],
9796 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
9798 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
]) {
9799 json_object_string_add(json
, "pfxctDriftFor",
9801 json_object_string_add(
9802 json
, "recommended",
9803 "Please report this bug, with the above command output");
9805 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
9806 json_object_free(json
);
9810 && bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
)) {
9811 vty_out(vty
, "Prefix counts for %s/%s, %s\n",
9812 peer
->hostname
, peer
->host
,
9813 afi_safi_print(afi
, safi
));
9815 vty_out(vty
, "Prefix counts for %s, %s\n", peer
->host
,
9816 afi_safi_print(afi
, safi
));
9819 vty_out(vty
, "PfxCt: %ld\n", peer
->pcount
[afi
][safi
]);
9820 vty_out(vty
, "\nCounts from RIB table walk:\n\n");
9822 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9823 vty_out(vty
, "%20s: %-10d\n", pcount_strs
[i
],
9826 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
]) {
9827 vty_out(vty
, "%s [pcount] PfxCt drift!\n", peer
->host
);
9829 "Please report this bug, with the above command output\n");
9836 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9837 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9838 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9839 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9843 BGP_INSTANCE_HELP_STR
9846 "Detailed information on TCP and BGP neighbor connections\n"
9847 "Neighbor to display information about\n"
9848 "Neighbor to display information about\n"
9849 "Neighbor on BGP configured interface\n"
9850 "Display detailed prefix count information\n"
9853 afi_t afi
= AFI_IP6
;
9854 safi_t safi
= SAFI_UNICAST
;
9857 struct bgp
*bgp
= NULL
;
9859 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9864 int uj
= use_json(argc
, argv
);
9868 argv_find(argv
, argc
, "neighbors", &idx
);
9869 peer
= peer_lookup_in_view(vty
, bgp
, argv
[idx
+ 1]->arg
, uj
);
9873 return bgp_peer_counts(vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9876 #ifdef KEEP_OLD_VPN_COMMANDS
9877 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
9878 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
9879 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9884 "Display information about all VPNv4 NLRIs\n"
9885 "Detailed information on TCP and BGP neighbor connections\n"
9886 "Neighbor to display information about\n"
9887 "Neighbor to display information about\n"
9888 "Neighbor on BGP configured interface\n"
9889 "Display detailed prefix count information\n"
9894 u_char uj
= use_json(argc
, argv
);
9896 peer
= peer_lookup_in_view(vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9900 return bgp_peer_counts(vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9903 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
9904 show_ip_bgp_vpn_all_route_prefix_cmd
,
9905 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9910 "Display information about all VPNv4 NLRIs\n"
9911 "Network in the BGP routing table to display\n"
9912 "Network in the BGP routing table to display\n"
9916 char *network
= NULL
;
9917 struct bgp
*bgp
= bgp_get_default();
9919 vty_out(vty
, "Can't find default instance\n");
9923 if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9924 network
= argv
[idx
]->arg
;
9925 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
))
9926 network
= argv
[idx
]->arg
;
9928 vty_out(vty
, "Unable to figure out Network\n");
9932 return bgp_show_route(vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0,
9933 BGP_PATH_ALL
, use_json(argc
, argv
));
9935 #endif /* KEEP_OLD_VPN_COMMANDS */
9937 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix
,
9938 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
,
9939 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
9945 "Display information about all EVPN NLRIs\n"
9946 "Network in the BGP routing table to display\n"
9947 "Network in the BGP routing table to display\n"
9951 char *network
= NULL
;
9953 if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9954 network
= argv
[idx
]->arg
;
9955 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
))
9956 network
= argv
[idx
]->arg
;
9958 vty_out(vty
, "Unable to figure out Network\n");
9961 return bgp_show_route(vty
, NULL
, network
, AFI_L2VPN
, SAFI_EVPN
, NULL
, 0,
9962 BGP_PATH_ALL
, use_json(argc
, argv
));
9965 static void show_adj_route(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9966 safi_t safi
, int in
, const char *rmap_name
,
9967 u_char use_json
, json_object
*json
)
9969 struct bgp_table
*table
;
9970 struct bgp_adj_in
*ain
;
9971 struct bgp_adj_out
*adj
;
9972 unsigned long output_count
;
9973 unsigned long filtered_count
;
9974 struct bgp_node
*rn
;
9980 struct update_subgroup
*subgrp
;
9981 json_object
*json_scode
= NULL
;
9982 json_object
*json_ocode
= NULL
;
9983 json_object
*json_ar
= NULL
;
9984 struct peer_af
*paf
;
9987 json_scode
= json_object_new_object();
9988 json_ocode
= json_object_new_object();
9989 json_ar
= json_object_new_object();
9991 json_object_string_add(json_scode
, "suppressed", "s");
9992 json_object_string_add(json_scode
, "damped", "d");
9993 json_object_string_add(json_scode
, "history", "h");
9994 json_object_string_add(json_scode
, "valid", "*");
9995 json_object_string_add(json_scode
, "best", ">");
9996 json_object_string_add(json_scode
, "multipath", "=");
9997 json_object_string_add(json_scode
, "internal", "i");
9998 json_object_string_add(json_scode
, "ribFailure", "r");
9999 json_object_string_add(json_scode
, "stale", "S");
10000 json_object_string_add(json_scode
, "removed", "R");
10002 json_object_string_add(json_ocode
, "igp", "i");
10003 json_object_string_add(json_ocode
, "egp", "e");
10004 json_object_string_add(json_ocode
, "incomplete", "?");
10011 json_object_string_add(json
, "alert", "no BGP");
10012 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10013 json_object_free(json
);
10015 vty_out(vty
, "%% No bgp\n");
10019 table
= bgp
->rib
[afi
][safi
];
10021 output_count
= filtered_count
= 0;
10022 subgrp
= peer_subgroup(peer
, afi
, safi
);
10025 && CHECK_FLAG(subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
)) {
10027 json_object_int_add(json
, "bgpTableVersion",
10029 json_object_string_add(json
, "bgpLocalRouterId",
10030 inet_ntoa(bgp
->router_id
));
10031 json_object_object_add(json
, "bgpStatusCodes",
10033 json_object_object_add(json
, "bgpOriginCodes",
10035 json_object_string_add(json
,
10036 "bgpOriginatingDefaultNetwork",
10039 vty_out(vty
, "BGP table version is %" PRIu64
10040 ", local router ID is %s\n",
10041 table
->version
, inet_ntoa(bgp
->router_id
));
10042 vty_out(vty
, BGP_SHOW_SCODE_HEADER
);
10043 vty_out(vty
, BGP_SHOW_OCODE_HEADER
);
10045 vty_out(vty
, "Originating default network 0.0.0.0\n\n");
10050 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
10052 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
) {
10053 if (ain
->peer
== peer
) {
10056 json_object_int_add(
10060 json_object_string_add(
10062 "bgpLocalRouterId",
10065 json_object_object_add(
10069 json_object_object_add(
10075 "BGP table version is 0, local router ID is %s\n",
10079 BGP_SHOW_SCODE_HEADER
);
10081 BGP_SHOW_OCODE_HEADER
);
10092 bgp_attr_dup(&attr
, ain
->attr
);
10093 if (bgp_input_modifier(
10094 peer
, &rn
->p
, &attr
,
10110 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
10111 SUBGRP_FOREACH_PEER(adj
->subgroup
, paf
)
10112 if (paf
->peer
== peer
) {
10115 json_object_int_add(
10116 json
, "bgpTableVersion",
10118 json_object_string_add(
10120 "bgpLocalRouterId",
10123 json_object_object_add(
10124 json
, "bgpStatusCodes",
10126 json_object_object_add(
10127 json
, "bgpOriginCodes",
10131 "BGP table version is %" PRIu64
10132 ", local router ID is %s\n",
10137 BGP_SHOW_SCODE_HEADER
);
10139 BGP_SHOW_OCODE_HEADER
);
10146 vty_out(vty
, BGP_SHOW_HEADER
);
10151 bgp_attr_dup(&attr
, adj
->attr
);
10152 ret
= bgp_output_modifier(
10153 peer
, &rn
->p
, &attr
, afi
, safi
,
10155 if (ret
!= RMAP_DENY
) {
10156 route_vty_out_tmp(vty
, &rn
->p
,
10168 json_object_object_add(json
, "advertisedRoutes", json_ar
);
10170 if (output_count
!= 0) {
10172 json_object_int_add(json
, "totalPrefixCounter",
10175 vty_out(vty
, "\nTotal number of prefixes %ld\n",
10179 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10180 json_object_free(json
);
10184 static int peer_adj_routes(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
10185 safi_t safi
, int in
, const char *rmap_name
,
10188 json_object
*json
= NULL
;
10191 json
= json_object_new_object();
10193 /* labeled-unicast routes live in the unicast table */
10194 if (safi
== SAFI_LABELED_UNICAST
)
10195 safi
= SAFI_UNICAST
;
10197 if (!peer
|| !peer
->afc
[afi
][safi
]) {
10199 json_object_string_add(
10201 "No such neighbor or address family");
10202 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10203 json_object_free(json
);
10205 vty_out(vty
, "%% No such neighbor or address family\n");
10207 return CMD_WARNING
;
10211 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
10212 PEER_FLAG_SOFT_RECONFIG
)) {
10214 json_object_string_add(
10216 "Inbound soft reconfiguration not enabled");
10217 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10218 json_object_free(json
);
10221 "%% Inbound soft reconfiguration not enabled\n");
10223 return CMD_WARNING
;
10226 show_adj_route(vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
10228 return CMD_SUCCESS
;
10231 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
10232 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
10233 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
10234 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
10238 BGP_INSTANCE_HELP_STR
10240 BGP_SAFI_WITH_LABEL_HELP_STR
10241 "Detailed information on TCP and BGP neighbor connections\n"
10242 "Neighbor to display information about\n"
10243 "Neighbor to display information about\n"
10244 "Neighbor on BGP configured interface\n"
10245 "Display the received routes from neighbor\n"
10246 "Display the routes advertised to a BGP neighbor\n"
10247 "Route-map to modify the attributes\n"
10248 "Name of the route map\n"
10251 afi_t afi
= AFI_IP6
;
10252 safi_t safi
= SAFI_UNICAST
;
10253 char *rmap_name
= NULL
;
10254 char *peerstr
= NULL
;
10256 struct bgp
*bgp
= NULL
;
10261 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10264 return CMD_WARNING
;
10266 int uj
= use_json(argc
, argv
);
10270 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10271 argv_find(argv
, argc
, "neighbors", &idx
);
10272 peerstr
= argv
[++idx
]->arg
;
10274 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
10276 return CMD_WARNING
;
10278 if (argv_find(argv
, argc
, "received-routes", &idx
))
10280 if (argv_find(argv
, argc
, "advertised-routes", &idx
))
10282 if (argv_find(argv
, argc
, "route-map", &idx
))
10283 rmap_name
= argv
[++idx
]->arg
;
10285 return peer_adj_routes(vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
10288 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
10289 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
10290 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
10296 "Address Family modifier\n"
10297 "Detailed information on TCP and BGP neighbor connections\n"
10298 "Neighbor to display information about\n"
10299 "Neighbor to display information about\n"
10300 "Neighbor on BGP configured interface\n"
10301 "Display information received from a BGP neighbor\n"
10302 "Display the prefixlist filter\n"
10305 afi_t afi
= AFI_IP6
;
10306 safi_t safi
= SAFI_UNICAST
;
10307 char *peerstr
= NULL
;
10310 union sockunion su
;
10316 /* show [ip] bgp */
10317 if (argv_find(argv
, argc
, "ip", &idx
))
10319 /* [<ipv4|ipv6> [unicast]] */
10320 if (argv_find(argv
, argc
, "ipv4", &idx
))
10322 if (argv_find(argv
, argc
, "ipv6", &idx
))
10324 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10325 argv_find(argv
, argc
, "neighbors", &idx
);
10326 peerstr
= argv
[++idx
]->arg
;
10328 u_char uj
= use_json(argc
, argv
);
10330 ret
= str2sockunion(peerstr
, &su
);
10332 peer
= peer_lookup_by_conf_if(NULL
, peerstr
);
10335 vty_out(vty
, "{}\n");
10338 "%% Malformed address or name: %s\n",
10340 return CMD_WARNING
;
10343 peer
= peer_lookup(NULL
, &su
);
10346 vty_out(vty
, "{}\n");
10348 vty_out(vty
, "No peer\n");
10349 return CMD_WARNING
;
10353 sprintf(name
, "%s.%d.%d", peer
->host
, afi
, safi
);
10354 count
= prefix_bgp_show_prefix_list(NULL
, afi
, name
, uj
);
10357 vty_out(vty
, "Address Family: %s\n",
10358 afi_safi_print(afi
, safi
));
10359 prefix_bgp_show_prefix_list(vty
, afi
, name
, uj
);
10362 vty_out(vty
, "{}\n");
10364 vty_out(vty
, "No functional output\n");
10367 return CMD_SUCCESS
;
10370 static int bgp_show_neighbor_route(struct vty
*vty
, struct peer
*peer
,
10371 afi_t afi
, safi_t safi
,
10372 enum bgp_show_type type
, u_char use_json
)
10374 /* labeled-unicast routes live in the unicast table */
10375 if (safi
== SAFI_LABELED_UNICAST
)
10376 safi
= SAFI_UNICAST
;
10378 if (!peer
|| !peer
->afc
[afi
][safi
]) {
10380 json_object
*json_no
= NULL
;
10381 json_no
= json_object_new_object();
10382 json_object_string_add(
10383 json_no
, "warning",
10384 "No such neighbor or address family");
10385 vty_out(vty
, "%s\n",
10386 json_object_to_json_string(json_no
));
10387 json_object_free(json_no
);
10389 vty_out(vty
, "%% No such neighbor or address family\n");
10390 return CMD_WARNING
;
10393 /* labeled-unicast routes live in the unicast table */
10394 if (safi
== SAFI_LABELED_UNICAST
)
10395 safi
= SAFI_UNICAST
;
10397 return bgp_show(vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
10400 DEFUN (show_ip_bgp_neighbor_routes
,
10401 show_ip_bgp_neighbor_routes_cmd
,
10402 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
10403 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
10407 BGP_INSTANCE_HELP_STR
10409 BGP_SAFI_WITH_LABEL_HELP_STR
10410 "Detailed information on TCP and BGP neighbor connections\n"
10411 "Neighbor to display information about\n"
10412 "Neighbor to display information about\n"
10413 "Neighbor on BGP configured interface\n"
10414 "Display flap statistics of the routes learned from neighbor\n"
10415 "Display the dampened routes received from neighbor\n"
10416 "Display routes learned from neighbor\n"
10419 char *peerstr
= NULL
;
10420 struct bgp
*bgp
= NULL
;
10421 afi_t afi
= AFI_IP6
;
10422 safi_t safi
= SAFI_UNICAST
;
10424 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
10428 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10431 return CMD_WARNING
;
10433 int uj
= use_json(argc
, argv
);
10437 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10438 argv_find(argv
, argc
, "neighbors", &idx
);
10439 peerstr
= argv
[++idx
]->arg
;
10441 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
10443 vty_out(vty
, "No such neighbor\n");
10444 return CMD_WARNING
;
10447 if (argv_find(argv
, argc
, "flap-statistics", &idx
))
10448 sh_type
= bgp_show_type_flap_neighbor
;
10449 else if (argv_find(argv
, argc
, "dampened-routes", &idx
))
10450 sh_type
= bgp_show_type_damp_neighbor
;
10451 else if (argv_find(argv
, argc
, "routes", &idx
))
10452 sh_type
= bgp_show_type_neighbor
;
10454 return bgp_show_neighbor_route(vty
, peer
, afi
, safi
, sh_type
, uj
);
10457 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
10459 struct bgp_distance
{
10460 /* Distance value for the IP source prefix. */
10463 /* Name of the access-list to be matched. */
10467 DEFUN (show_bgp_afi_vpn_rd_route
,
10468 show_bgp_afi_vpn_rd_route_cmd
,
10469 "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]",
10473 "Address Family modifier\n"
10474 "Display information for a route distinguisher\n"
10475 "Route Distinguisher\n"
10476 "Network in the BGP routing table to display\n"
10477 "Network in the BGP routing table to display\n"
10481 struct prefix_rd prd
;
10482 afi_t afi
= AFI_MAX
;
10485 argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
);
10486 ret
= str2prefix_rd(argv
[5]->arg
, &prd
);
10488 vty_out(vty
, "%% Malformed Route Distinguisher\n");
10489 return CMD_WARNING
;
10491 return bgp_show_route(vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
,
10492 0, BGP_PATH_ALL
, use_json(argc
, argv
));
10495 static struct bgp_distance
*bgp_distance_new(void)
10497 return XCALLOC(MTYPE_BGP_DISTANCE
, sizeof(struct bgp_distance
));
10500 static void bgp_distance_free(struct bgp_distance
*bdistance
)
10502 XFREE(MTYPE_BGP_DISTANCE
, bdistance
);
10505 static int bgp_distance_set(struct vty
*vty
, const char *distance_str
,
10506 const char *ip_str
, const char *access_list_str
)
10513 struct bgp_node
*rn
;
10514 struct bgp_distance
*bdistance
;
10516 afi
= bgp_node_afi(vty
);
10517 safi
= bgp_node_safi(vty
);
10519 ret
= str2prefix(ip_str
, &p
);
10521 vty_out(vty
, "Malformed prefix\n");
10522 return CMD_WARNING_CONFIG_FAILED
;
10525 distance
= atoi(distance_str
);
10527 /* Get BGP distance node. */
10528 rn
= bgp_node_get(bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
10530 bdistance
= rn
->info
;
10531 bgp_unlock_node(rn
);
10533 bdistance
= bgp_distance_new();
10534 rn
->info
= bdistance
;
10537 /* Set distance value. */
10538 bdistance
->distance
= distance
;
10540 /* Reset access-list configuration. */
10541 if (bdistance
->access_list
) {
10542 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10543 bdistance
->access_list
= NULL
;
10545 if (access_list_str
)
10546 bdistance
->access_list
=
10547 XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
10549 return CMD_SUCCESS
;
10552 static int bgp_distance_unset(struct vty
*vty
, const char *distance_str
,
10553 const char *ip_str
, const char *access_list_str
)
10560 struct bgp_node
*rn
;
10561 struct bgp_distance
*bdistance
;
10563 afi
= bgp_node_afi(vty
);
10564 safi
= bgp_node_safi(vty
);
10566 ret
= str2prefix(ip_str
, &p
);
10568 vty_out(vty
, "Malformed prefix\n");
10569 return CMD_WARNING_CONFIG_FAILED
;
10572 rn
= bgp_node_lookup(bgp_distance_table
[afi
][safi
],
10573 (struct prefix
*)&p
);
10575 vty_out(vty
, "Can't find specified prefix\n");
10576 return CMD_WARNING_CONFIG_FAILED
;
10579 bdistance
= rn
->info
;
10580 distance
= atoi(distance_str
);
10582 if (bdistance
->distance
!= distance
) {
10583 vty_out(vty
, "Distance does not match configured\n");
10584 return CMD_WARNING_CONFIG_FAILED
;
10587 if (bdistance
->access_list
)
10588 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10589 bgp_distance_free(bdistance
);
10592 bgp_unlock_node(rn
);
10593 bgp_unlock_node(rn
);
10595 return CMD_SUCCESS
;
10598 /* Apply BGP information to distance method. */
10599 u_char
bgp_distance_apply(struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
10600 safi_t safi
, struct bgp
*bgp
)
10602 struct bgp_node
*rn
;
10605 struct bgp_distance
*bdistance
;
10606 struct access_list
*alist
;
10607 struct bgp_static
*bgp_static
;
10612 peer
= rinfo
->peer
;
10614 /* Check source address. */
10615 sockunion2hostprefix(&peer
->su
, &q
);
10616 rn
= bgp_node_match(bgp_distance_table
[afi
][safi
], &q
);
10618 bdistance
= rn
->info
;
10619 bgp_unlock_node(rn
);
10621 if (bdistance
->access_list
) {
10622 alist
= access_list_lookup(afi
, bdistance
->access_list
);
10624 && access_list_apply(alist
, p
) == FILTER_PERMIT
)
10625 return bdistance
->distance
;
10627 return bdistance
->distance
;
10630 /* Backdoor check. */
10631 rn
= bgp_node_lookup(bgp
->route
[afi
][safi
], p
);
10633 bgp_static
= rn
->info
;
10634 bgp_unlock_node(rn
);
10636 if (bgp_static
->backdoor
) {
10637 if (bgp
->distance_local
[afi
][safi
])
10638 return bgp
->distance_local
[afi
][safi
];
10640 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10644 if (peer
->sort
== BGP_PEER_EBGP
) {
10645 if (bgp
->distance_ebgp
[afi
][safi
])
10646 return bgp
->distance_ebgp
[afi
][safi
];
10647 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
10649 if (bgp
->distance_ibgp
[afi
][safi
])
10650 return bgp
->distance_ibgp
[afi
][safi
];
10651 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10655 DEFUN (bgp_distance
,
10657 "distance bgp (1-255) (1-255) (1-255)",
10658 "Define an administrative distance\n"
10660 "Distance for routes external to the AS\n"
10661 "Distance for routes internal to the AS\n"
10662 "Distance for local routes\n")
10664 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10665 int idx_number
= 2;
10666 int idx_number_2
= 3;
10667 int idx_number_3
= 4;
10671 afi
= bgp_node_afi(vty
);
10672 safi
= bgp_node_safi(vty
);
10674 bgp
->distance_ebgp
[afi
][safi
] = atoi(argv
[idx_number
]->arg
);
10675 bgp
->distance_ibgp
[afi
][safi
] = atoi(argv
[idx_number_2
]->arg
);
10676 bgp
->distance_local
[afi
][safi
] = atoi(argv
[idx_number_3
]->arg
);
10677 return CMD_SUCCESS
;
10680 DEFUN (no_bgp_distance
,
10681 no_bgp_distance_cmd
,
10682 "no distance bgp [(1-255) (1-255) (1-255)]",
10684 "Define an administrative distance\n"
10686 "Distance for routes external to the AS\n"
10687 "Distance for routes internal to the AS\n"
10688 "Distance for local routes\n")
10690 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10694 afi
= bgp_node_afi(vty
);
10695 safi
= bgp_node_safi(vty
);
10697 bgp
->distance_ebgp
[afi
][safi
] = 0;
10698 bgp
->distance_ibgp
[afi
][safi
] = 0;
10699 bgp
->distance_local
[afi
][safi
] = 0;
10700 return CMD_SUCCESS
;
10704 DEFUN (bgp_distance_source
,
10705 bgp_distance_source_cmd
,
10706 "distance (1-255) A.B.C.D/M",
10707 "Define an administrative distance\n"
10708 "Administrative distance\n"
10709 "IP source prefix\n")
10711 int idx_number
= 1;
10712 int idx_ipv4_prefixlen
= 2;
10713 bgp_distance_set(vty
, argv
[idx_number
]->arg
,
10714 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10715 return CMD_SUCCESS
;
10718 DEFUN (no_bgp_distance_source
,
10719 no_bgp_distance_source_cmd
,
10720 "no distance (1-255) A.B.C.D/M",
10722 "Define an administrative distance\n"
10723 "Administrative distance\n"
10724 "IP source prefix\n")
10726 int idx_number
= 2;
10727 int idx_ipv4_prefixlen
= 3;
10728 bgp_distance_unset(vty
, argv
[idx_number
]->arg
,
10729 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10730 return CMD_SUCCESS
;
10733 DEFUN (bgp_distance_source_access_list
,
10734 bgp_distance_source_access_list_cmd
,
10735 "distance (1-255) A.B.C.D/M WORD",
10736 "Define an administrative distance\n"
10737 "Administrative distance\n"
10738 "IP source prefix\n"
10739 "Access list name\n")
10741 int idx_number
= 1;
10742 int idx_ipv4_prefixlen
= 2;
10744 bgp_distance_set(vty
, argv
[idx_number
]->arg
,
10745 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10746 return CMD_SUCCESS
;
10749 DEFUN (no_bgp_distance_source_access_list
,
10750 no_bgp_distance_source_access_list_cmd
,
10751 "no distance (1-255) A.B.C.D/M WORD",
10753 "Define an administrative distance\n"
10754 "Administrative distance\n"
10755 "IP source prefix\n"
10756 "Access list name\n")
10758 int idx_number
= 2;
10759 int idx_ipv4_prefixlen
= 3;
10761 bgp_distance_unset(vty
, argv
[idx_number
]->arg
,
10762 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10763 return CMD_SUCCESS
;
10766 DEFUN (ipv6_bgp_distance_source
,
10767 ipv6_bgp_distance_source_cmd
,
10768 "distance (1-255) X:X::X:X/M",
10769 "Define an administrative distance\n"
10770 "Administrative distance\n"
10771 "IP source prefix\n")
10773 bgp_distance_set(vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
10774 return CMD_SUCCESS
;
10777 DEFUN (no_ipv6_bgp_distance_source
,
10778 no_ipv6_bgp_distance_source_cmd
,
10779 "no distance (1-255) X:X::X:X/M",
10781 "Define an administrative distance\n"
10782 "Administrative distance\n"
10783 "IP source prefix\n")
10785 bgp_distance_unset(vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10786 return CMD_SUCCESS
;
10789 DEFUN (ipv6_bgp_distance_source_access_list
,
10790 ipv6_bgp_distance_source_access_list_cmd
,
10791 "distance (1-255) X:X::X:X/M WORD",
10792 "Define an administrative distance\n"
10793 "Administrative distance\n"
10794 "IP source prefix\n"
10795 "Access list name\n")
10797 bgp_distance_set(vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10798 return CMD_SUCCESS
;
10801 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10802 no_ipv6_bgp_distance_source_access_list_cmd
,
10803 "no distance (1-255) X:X::X:X/M WORD",
10805 "Define an administrative distance\n"
10806 "Administrative distance\n"
10807 "IP source prefix\n"
10808 "Access list name\n")
10810 bgp_distance_unset(vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10811 return CMD_SUCCESS
;
10814 DEFUN (bgp_damp_set
,
10816 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10817 "BGP Specific commands\n"
10818 "Enable route-flap dampening\n"
10819 "Half-life time for the penalty\n"
10820 "Value to start reusing a route\n"
10821 "Value to start suppressing a route\n"
10822 "Maximum duration to suppress a stable route\n")
10824 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10825 int idx_half_life
= 2;
10827 int idx_suppress
= 4;
10828 int idx_max_suppress
= 5;
10829 int half
= DEFAULT_HALF_LIFE
* 60;
10830 int reuse
= DEFAULT_REUSE
;
10831 int suppress
= DEFAULT_SUPPRESS
;
10832 int max
= 4 * half
;
10835 half
= atoi(argv
[idx_half_life
]->arg
) * 60;
10836 reuse
= atoi(argv
[idx_reuse
]->arg
);
10837 suppress
= atoi(argv
[idx_suppress
]->arg
);
10838 max
= atoi(argv
[idx_max_suppress
]->arg
) * 60;
10839 } else if (argc
== 3) {
10840 half
= atoi(argv
[idx_half_life
]->arg
) * 60;
10844 if (suppress
< reuse
) {
10846 "Suppress value cannot be less than reuse value \n");
10850 return bgp_damp_enable(bgp
, bgp_node_afi(vty
), bgp_node_safi(vty
), half
,
10851 reuse
, suppress
, max
);
10854 DEFUN (bgp_damp_unset
,
10855 bgp_damp_unset_cmd
,
10856 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10858 "BGP Specific commands\n"
10859 "Enable route-flap dampening\n"
10860 "Half-life time for the penalty\n"
10861 "Value to start reusing a route\n"
10862 "Value to start suppressing a route\n"
10863 "Maximum duration to suppress a stable route\n")
10865 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10866 return bgp_damp_disable(bgp
, bgp_node_afi(vty
), bgp_node_safi(vty
));
10869 /* Display specified route of BGP table. */
10870 static int bgp_clear_damp_route(struct vty
*vty
, const char *view_name
,
10871 const char *ip_str
, afi_t afi
, safi_t safi
,
10872 struct prefix_rd
*prd
, int prefix_check
)
10875 struct prefix match
;
10876 struct bgp_node
*rn
;
10877 struct bgp_node
*rm
;
10878 struct bgp_info
*ri
;
10879 struct bgp_info
*ri_temp
;
10881 struct bgp_table
*table
;
10883 /* BGP structure lookup. */
10885 bgp
= bgp_lookup_by_name(view_name
);
10887 vty_out(vty
, "%% Can't find BGP instance %s\n",
10889 return CMD_WARNING
;
10892 bgp
= bgp_get_default();
10894 vty_out(vty
, "%% No BGP process is configured\n");
10895 return CMD_WARNING
;
10899 /* Check IP address argument. */
10900 ret
= str2prefix(ip_str
, &match
);
10902 vty_out(vty
, "%% address is malformed\n");
10903 return CMD_WARNING
;
10906 match
.family
= afi2family(afi
);
10908 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
10909 || (safi
== SAFI_EVPN
)) {
10910 for (rn
= bgp_table_top(bgp
->rib
[AFI_IP
][safi
]); rn
;
10911 rn
= bgp_route_next(rn
)) {
10912 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
10915 if ((table
= rn
->info
) != NULL
)
10916 if ((rm
= bgp_node_match(table
, &match
))
10920 == match
.prefixlen
) {
10928 bgp_damp_info_free(
10938 bgp_unlock_node(rm
);
10942 if ((rn
= bgp_node_match(bgp
->rib
[afi
][safi
], &match
))
10945 || rn
->p
.prefixlen
== match
.prefixlen
) {
10948 if (ri
->extra
&& ri
->extra
->damp_info
) {
10949 ri_temp
= ri
->next
;
10950 bgp_damp_info_free(
10951 ri
->extra
->damp_info
,
10959 bgp_unlock_node(rn
);
10963 return CMD_SUCCESS
;
10966 DEFUN (clear_ip_bgp_dampening
,
10967 clear_ip_bgp_dampening_cmd
,
10968 "clear ip bgp dampening",
10972 "Clear route flap dampening information\n")
10974 bgp_damp_info_clean();
10975 return CMD_SUCCESS
;
10978 DEFUN (clear_ip_bgp_dampening_prefix
,
10979 clear_ip_bgp_dampening_prefix_cmd
,
10980 "clear ip bgp dampening A.B.C.D/M",
10984 "Clear route flap dampening information\n"
10987 int idx_ipv4_prefixlen
= 4;
10988 return bgp_clear_damp_route(vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
,
10989 AFI_IP
, SAFI_UNICAST
, NULL
, 1);
10992 DEFUN (clear_ip_bgp_dampening_address
,
10993 clear_ip_bgp_dampening_address_cmd
,
10994 "clear ip bgp dampening A.B.C.D",
10998 "Clear route flap dampening information\n"
10999 "Network to clear damping information\n")
11002 return bgp_clear_damp_route(vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
11003 SAFI_UNICAST
, NULL
, 0);
11006 DEFUN (clear_ip_bgp_dampening_address_mask
,
11007 clear_ip_bgp_dampening_address_mask_cmd
,
11008 "clear ip bgp dampening A.B.C.D A.B.C.D",
11012 "Clear route flap dampening information\n"
11013 "Network to clear damping information\n"
11017 int idx_ipv4_2
= 5;
11019 char prefix_str
[BUFSIZ
];
11021 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
,
11024 vty_out(vty
, "%% Inconsistent address and mask\n");
11025 return CMD_WARNING
;
11028 return bgp_clear_damp_route(vty
, NULL
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
11032 /* also used for encap safi */
11033 static int bgp_config_write_network_vpn(struct vty
*vty
, struct bgp
*bgp
,
11034 afi_t afi
, safi_t safi
, int *write
)
11036 struct bgp_node
*prn
;
11037 struct bgp_node
*rn
;
11038 struct bgp_table
*table
;
11040 struct prefix_rd
*prd
;
11041 struct bgp_static
*bgp_static
;
11042 mpls_label_t label
;
11043 char buf
[SU_ADDRSTRLEN
];
11044 char rdbuf
[RD_ADDRSTRLEN
];
11046 /* Network configuration. */
11047 for (prn
= bgp_table_top(bgp
->route
[afi
][safi
]); prn
;
11048 prn
= bgp_route_next(prn
))
11049 if ((table
= prn
->info
) != NULL
)
11050 for (rn
= bgp_table_top(table
); rn
;
11051 rn
= bgp_route_next(rn
))
11052 if ((bgp_static
= rn
->info
) != NULL
) {
11054 prd
= (struct prefix_rd
*)&prn
->p
;
11056 /* "address-family" display. */
11057 bgp_config_write_family_header(
11058 vty
, afi
, safi
, write
);
11060 /* "network" configuration display. */
11061 prefix_rd2str(prd
, rdbuf
,
11063 label
= decode_label(
11064 &bgp_static
->label
);
11066 vty_out(vty
, " network %s/%d rd %s",
11067 inet_ntop(p
->family
,
11070 p
->prefixlen
, rdbuf
);
11071 if (safi
== SAFI_MPLS_VPN
)
11072 vty_out(vty
, " label %u",
11075 if (bgp_static
->rmap
.name
)
11076 vty_out(vty
, " route-map %s",
11077 bgp_static
->rmap
.name
);
11079 if (bgp_static
->backdoor
)
11083 vty_out(vty
, "\n");
11088 static int bgp_config_write_network_evpn(struct vty
*vty
, struct bgp
*bgp
,
11089 afi_t afi
, safi_t safi
, int *write
)
11091 struct bgp_node
*prn
;
11092 struct bgp_node
*rn
;
11093 struct bgp_table
*table
;
11095 struct prefix_rd
*prd
;
11096 struct bgp_static
*bgp_static
;
11097 char buf
[PREFIX_STRLEN
];
11098 char buf2
[SU_ADDRSTRLEN
];
11099 char rdbuf
[RD_ADDRSTRLEN
];
11101 /* Network configuration. */
11102 for (prn
= bgp_table_top(bgp
->route
[afi
][safi
]); prn
;
11103 prn
= bgp_route_next(prn
))
11104 if ((table
= prn
->info
) != NULL
)
11105 for (rn
= bgp_table_top(table
); rn
;
11106 rn
= bgp_route_next(rn
))
11107 if ((bgp_static
= rn
->info
) != NULL
) {
11108 char *macrouter
= NULL
;
11111 if (bgp_static
->router_mac
)
11112 macrouter
= prefix_mac2str(
11113 bgp_static
->router_mac
,
11115 if (bgp_static
->eth_s_id
)
11117 bgp_static
->eth_s_id
);
11119 prd
= (struct prefix_rd
*)&prn
->p
;
11121 /* "address-family" display. */
11122 bgp_config_write_family_header(
11123 vty
, afi
, safi
, write
);
11125 /* "network" configuration display. */
11126 prefix_rd2str(prd
, rdbuf
,
11130 &bgp_static
->igpnexthop
, buf2
,
11133 prefix2str(p
, buf
, sizeof(buf
)),
11135 " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s",
11142 esi
, buf2
, macrouter
);
11143 vty_out(vty
, "\n");
11145 XFREE(MTYPE_TMP
, macrouter
);
11147 XFREE(MTYPE_TMP
, esi
);
11152 /* Configuration of static route announcement and aggregate
11154 int bgp_config_write_network(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
11155 safi_t safi
, int *write
)
11157 struct bgp_node
*rn
;
11159 struct bgp_static
*bgp_static
;
11160 struct bgp_aggregate
*bgp_aggregate
;
11161 char buf
[SU_ADDRSTRLEN
];
11163 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
11164 return bgp_config_write_network_vpn(vty
, bgp
, afi
, safi
, write
);
11166 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
11167 return bgp_config_write_network_evpn(vty
, bgp
, afi
, safi
,
11170 /* Network configuration. */
11171 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
11172 rn
= bgp_route_next(rn
))
11173 if ((bgp_static
= rn
->info
) != NULL
) {
11176 /* "address-family" display. */
11177 bgp_config_write_family_header(vty
, afi
, safi
, write
);
11179 /* "network" configuration display. */
11180 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)
11181 && afi
== AFI_IP
) {
11182 u_int32_t destination
;
11183 struct in_addr netmask
;
11185 destination
= ntohl(p
->u
.prefix4
.s_addr
);
11186 masklen2ip(p
->prefixlen
, &netmask
);
11187 vty_out(vty
, " network %s",
11188 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11191 if ((IN_CLASSC(destination
)
11192 && p
->prefixlen
== 24)
11193 || (IN_CLASSB(destination
)
11194 && p
->prefixlen
== 16)
11195 || (IN_CLASSA(destination
)
11196 && p
->prefixlen
== 8)
11197 || p
->u
.prefix4
.s_addr
== 0) {
11198 /* Natural mask is not display. */
11200 vty_out(vty
, " mask %s",
11201 inet_ntoa(netmask
));
11203 vty_out(vty
, " network %s/%d",
11204 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11209 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
11210 vty_out(vty
, " label-index %u",
11211 bgp_static
->label_index
);
11213 if (bgp_static
->rmap
.name
)
11214 vty_out(vty
, " route-map %s",
11215 bgp_static
->rmap
.name
);
11217 if (bgp_static
->backdoor
)
11218 vty_out(vty
, " backdoor");
11221 vty_out(vty
, "\n");
11224 /* Aggregate-address configuration. */
11225 for (rn
= bgp_table_top(bgp
->aggregate
[afi
][safi
]); rn
;
11226 rn
= bgp_route_next(rn
))
11227 if ((bgp_aggregate
= rn
->info
) != NULL
) {
11230 /* "address-family" display. */
11231 bgp_config_write_family_header(vty
, afi
, safi
, write
);
11233 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
)
11234 && afi
== AFI_IP
) {
11235 struct in_addr netmask
;
11237 masklen2ip(p
->prefixlen
, &netmask
);
11238 vty_out(vty
, " aggregate-address %s %s",
11239 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11241 inet_ntoa(netmask
));
11243 vty_out(vty
, " aggregate-address %s/%d",
11244 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11249 if (bgp_aggregate
->as_set
)
11250 vty_out(vty
, " as-set");
11252 if (bgp_aggregate
->summary_only
)
11253 vty_out(vty
, " summary-only");
11255 vty_out(vty
, "\n");
11261 int bgp_config_write_distance(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
11262 safi_t safi
, int *write
)
11264 struct bgp_node
*rn
;
11265 struct bgp_distance
*bdistance
;
11267 /* Distance configuration. */
11268 if (bgp
->distance_ebgp
[afi
][safi
] && bgp
->distance_ibgp
[afi
][safi
]
11269 && bgp
->distance_local
[afi
][safi
]
11270 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
11271 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
11272 || bgp
->distance_local
[afi
][safi
]
11273 != ZEBRA_IBGP_DISTANCE_DEFAULT
)) {
11274 bgp_config_write_family_header(vty
, afi
, safi
, write
);
11275 vty_out(vty
, " distance bgp %d %d %d\n",
11276 bgp
->distance_ebgp
[afi
][safi
],
11277 bgp
->distance_ibgp
[afi
][safi
],
11278 bgp
->distance_local
[afi
][safi
]);
11281 for (rn
= bgp_table_top(bgp_distance_table
[afi
][safi
]); rn
;
11282 rn
= bgp_route_next(rn
))
11283 if ((bdistance
= rn
->info
) != NULL
) {
11284 char buf
[PREFIX_STRLEN
];
11286 bgp_config_write_family_header(vty
, afi
, safi
, write
);
11287 vty_out(vty
, " distance %d %s %s\n",
11288 bdistance
->distance
,
11289 prefix2str(&rn
->p
, buf
, sizeof(buf
)),
11290 bdistance
->access_list
? bdistance
->access_list
11297 /* Allocate routing table structure and install commands. */
11298 void bgp_route_init(void)
11303 /* Init BGP distance table. */
11304 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
11305 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++)
11306 bgp_distance_table
[afi
][safi
] =
11307 bgp_table_init(afi
, safi
);
11309 /* IPv4 BGP commands. */
11310 install_element(BGP_NODE
, &bgp_table_map_cmd
);
11311 install_element(BGP_NODE
, &bgp_network_cmd
);
11312 install_element(BGP_NODE
, &bgp_network_mask_cmd
);
11313 install_element(BGP_NODE
, &bgp_network_mask_natural_cmd
);
11314 install_element(BGP_NODE
, &bgp_network_route_map_cmd
);
11315 install_element(BGP_NODE
, &bgp_network_mask_route_map_cmd
);
11316 install_element(BGP_NODE
, &bgp_network_mask_natural_route_map_cmd
);
11317 install_element(BGP_NODE
, &bgp_network_backdoor_cmd
);
11318 install_element(BGP_NODE
, &bgp_network_mask_backdoor_cmd
);
11319 install_element(BGP_NODE
, &bgp_network_mask_natural_backdoor_cmd
);
11320 install_element(BGP_NODE
, &no_bgp_table_map_cmd
);
11321 install_element(BGP_NODE
, &no_bgp_network_cmd
);
11322 install_element(BGP_NODE
, &no_bgp_network_mask_cmd
);
11323 install_element(BGP_NODE
, &no_bgp_network_mask_natural_cmd
);
11325 install_element(BGP_NODE
, &aggregate_address_cmd
);
11326 install_element(BGP_NODE
, &aggregate_address_mask_cmd
);
11327 install_element(BGP_NODE
, &no_aggregate_address_cmd
);
11328 install_element(BGP_NODE
, &no_aggregate_address_mask_cmd
);
11330 /* IPv4 unicast configuration. */
11331 install_element(BGP_IPV4_NODE
, &bgp_table_map_cmd
);
11332 install_element(BGP_IPV4_NODE
, &bgp_network_cmd
);
11333 install_element(BGP_IPV4_NODE
, &bgp_network_mask_cmd
);
11334 install_element(BGP_IPV4_NODE
, &bgp_network_mask_natural_cmd
);
11335 install_element(BGP_IPV4_NODE
, &bgp_network_route_map_cmd
);
11336 install_element(BGP_IPV4_NODE
, &bgp_network_mask_route_map_cmd
);
11337 install_element(BGP_IPV4_NODE
, &bgp_network_mask_natural_route_map_cmd
);
11338 install_element(BGP_IPV4_NODE
, &bgp_network_label_index_cmd
);
11339 install_element(BGP_IPV4_NODE
, &bgp_network_label_index_route_map_cmd
);
11340 install_element(BGP_IPV4_NODE
, &no_bgp_network_label_index_cmd
);
11341 install_element(BGP_IPV4_NODE
,
11342 &no_bgp_network_label_index_route_map_cmd
);
11343 install_element(BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
11344 install_element(BGP_IPV4_NODE
, &no_bgp_network_cmd
);
11345 install_element(BGP_IPV4_NODE
, &no_bgp_network_mask_cmd
);
11346 install_element(BGP_IPV4_NODE
, &no_bgp_network_mask_natural_cmd
);
11348 install_element(BGP_IPV4_NODE
, &aggregate_address_cmd
);
11349 install_element(BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
11350 install_element(BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
11351 install_element(BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
11353 /* IPv4 multicast configuration. */
11354 install_element(BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
11355 install_element(BGP_IPV4M_NODE
, &bgp_network_cmd
);
11356 install_element(BGP_IPV4M_NODE
, &bgp_network_mask_cmd
);
11357 install_element(BGP_IPV4M_NODE
, &bgp_network_mask_natural_cmd
);
11358 install_element(BGP_IPV4M_NODE
, &bgp_network_route_map_cmd
);
11359 install_element(BGP_IPV4M_NODE
, &bgp_network_mask_route_map_cmd
);
11360 install_element(BGP_IPV4M_NODE
,
11361 &bgp_network_mask_natural_route_map_cmd
);
11362 install_element(BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
11363 install_element(BGP_IPV4M_NODE
, &no_bgp_network_cmd
);
11364 install_element(BGP_IPV4M_NODE
, &no_bgp_network_mask_cmd
);
11365 install_element(BGP_IPV4M_NODE
, &no_bgp_network_mask_natural_cmd
);
11366 install_element(BGP_IPV4M_NODE
, &aggregate_address_cmd
);
11367 install_element(BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
11368 install_element(BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
11369 install_element(BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
11371 /* IPv4 labeled-unicast configuration. */
11372 install_element(VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
11373 install_element(VIEW_NODE
, &show_ip_bgp_cmd
);
11374 install_element(VIEW_NODE
, &show_ip_bgp_json_cmd
);
11375 install_element(VIEW_NODE
, &show_ip_bgp_route_cmd
);
11376 install_element(VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
11378 install_element(VIEW_NODE
,
11379 &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
11380 install_element(VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
11381 install_element(VIEW_NODE
,
11382 &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
11383 #ifdef KEEP_OLD_VPN_COMMANDS
11384 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
11385 #endif /* KEEP_OLD_VPN_COMMANDS */
11386 install_element(VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
11387 install_element(VIEW_NODE
,
11388 &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
);
11390 /* BGP dampening clear commands */
11391 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
11392 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
11394 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
11395 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
11398 install_element(ENABLE_NODE
,
11399 &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
11400 #ifdef KEEP_OLD_VPN_COMMANDS
11401 install_element(ENABLE_NODE
,
11402 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
11403 #endif /* KEEP_OLD_VPN_COMMANDS */
11405 /* New config IPv6 BGP commands. */
11406 install_element(BGP_IPV6_NODE
, &bgp_table_map_cmd
);
11407 install_element(BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
11408 install_element(BGP_IPV6_NODE
, &ipv6_bgp_network_route_map_cmd
);
11409 install_element(BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
11410 install_element(BGP_IPV6_NODE
, &no_ipv6_bgp_network_cmd
);
11411 install_element(BGP_IPV6_NODE
, &ipv6_bgp_network_label_index_cmd
);
11412 install_element(BGP_IPV6_NODE
, &no_ipv6_bgp_network_label_index_cmd
);
11413 install_element(BGP_IPV6_NODE
,
11414 &ipv6_bgp_network_label_index_route_map_cmd
);
11415 install_element(BGP_IPV6_NODE
,
11416 &no_ipv6_bgp_network_label_index_route_map_cmd
);
11418 install_element(BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
11419 install_element(BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
11421 install_element(BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
11422 install_element(BGP_IPV6M_NODE
, &no_ipv6_bgp_network_cmd
);
11424 install_element(BGP_IPV6L_NODE
, &bgp_table_map_cmd
);
11425 install_element(BGP_IPV6L_NODE
, &ipv6_bgp_network_cmd
);
11426 install_element(BGP_IPV6L_NODE
, &ipv6_bgp_network_route_map_cmd
);
11427 install_element(BGP_IPV6L_NODE
, &no_bgp_table_map_cmd
);
11428 install_element(BGP_IPV6L_NODE
, &no_ipv6_bgp_network_cmd
);
11430 install_element(BGP_NODE
, &bgp_distance_cmd
);
11431 install_element(BGP_NODE
, &no_bgp_distance_cmd
);
11432 install_element(BGP_NODE
, &bgp_distance_source_cmd
);
11433 install_element(BGP_NODE
, &no_bgp_distance_source_cmd
);
11434 install_element(BGP_NODE
, &bgp_distance_source_access_list_cmd
);
11435 install_element(BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
11436 install_element(BGP_IPV4_NODE
, &bgp_distance_cmd
);
11437 install_element(BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
11438 install_element(BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
11439 install_element(BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
11440 install_element(BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
11441 install_element(BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
11442 install_element(BGP_IPV4M_NODE
, &bgp_distance_cmd
);
11443 install_element(BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
11444 install_element(BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
11445 install_element(BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
11446 install_element(BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
11447 install_element(BGP_IPV4M_NODE
,
11448 &no_bgp_distance_source_access_list_cmd
);
11449 install_element(BGP_IPV6_NODE
, &bgp_distance_cmd
);
11450 install_element(BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
11451 install_element(BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
11452 install_element(BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11453 install_element(BGP_IPV6_NODE
,
11454 &ipv6_bgp_distance_source_access_list_cmd
);
11455 install_element(BGP_IPV6_NODE
,
11456 &no_ipv6_bgp_distance_source_access_list_cmd
);
11457 install_element(BGP_IPV6M_NODE
, &bgp_distance_cmd
);
11458 install_element(BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
11459 install_element(BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
11460 install_element(BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11461 install_element(BGP_IPV6M_NODE
,
11462 &ipv6_bgp_distance_source_access_list_cmd
);
11463 install_element(BGP_IPV6M_NODE
,
11464 &no_ipv6_bgp_distance_source_access_list_cmd
);
11466 install_element(BGP_NODE
, &bgp_damp_set_cmd
);
11467 install_element(BGP_NODE
, &bgp_damp_unset_cmd
);
11468 install_element(BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
11469 install_element(BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
11471 /* IPv4 Multicast Mode */
11472 install_element(BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
11473 install_element(BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
11475 /* Large Communities */
11476 install_element(VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
11477 install_element(VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
11480 void bgp_route_finish(void)
11485 for (afi
= AFI_IP
; afi
< AFI_MAX
; afi
++)
11486 for (safi
= SAFI_UNICAST
; safi
< SAFI_MAX
; safi
++) {
11487 bgp_table_unlock(bgp_distance_table
[afi
][safi
]);
11488 bgp_distance_table
[afi
][safi
] = NULL
;