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"
77 #ifndef VTYSH_EXTRACT_PL
78 #include "bgpd/bgp_route_clippy.c"
81 /* Extern from bgp_dump.c */
82 extern const char *bgp_origin_str
[];
83 extern const char *bgp_origin_long_str
[];
86 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
87 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
88 static const struct message bgp_pmsi_tnltype_str
[] = {
89 {PMSI_TNLTYPE_NO_INFO
, PMSI_TNLTYPE_STR_NO_INFO
},
90 {PMSI_TNLTYPE_RSVP_TE_P2MP
, "RSVP-TE P2MP"},
91 {PMSI_TNLTYPE_MLDP_P2MP
, "mLDP P2MP"},
92 {PMSI_TNLTYPE_PIM_SSM
, "PIM-SSM"},
93 {PMSI_TNLTYPE_PIM_SM
, "PIM-SM"},
94 {PMSI_TNLTYPE_PIM_BIDIR
, "PIM-BIDIR"},
95 {PMSI_TNLTYPE_INGR_REPL
, "Ingress Replication"},
96 {PMSI_TNLTYPE_MLDP_MP2MP
, "mLDP MP2MP"},
100 struct bgp_node
*bgp_afi_node_get(struct bgp_table
*table
, afi_t afi
,
101 safi_t safi
, struct prefix
*p
,
102 struct prefix_rd
*prd
)
105 struct bgp_node
*prn
= NULL
;
111 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
112 || (safi
== SAFI_EVPN
)) {
113 prn
= bgp_node_get(table
, (struct prefix
*)prd
);
115 if (prn
->info
== NULL
)
116 prn
->info
= bgp_table_init(afi
, safi
);
118 bgp_unlock_node(prn
);
122 rn
= bgp_node_get(table
, p
);
124 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
125 || (safi
== SAFI_EVPN
))
131 struct bgp_node
*bgp_afi_node_lookup(struct bgp_table
*table
, afi_t afi
,
132 safi_t safi
, struct prefix
*p
,
133 struct prefix_rd
*prd
)
136 struct bgp_node
*prn
= NULL
;
141 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
142 || (safi
== SAFI_EVPN
)) {
143 prn
= bgp_node_lookup(table
, (struct prefix
*)prd
);
147 if (prn
->info
== NULL
) {
148 bgp_unlock_node(prn
);
155 rn
= bgp_node_lookup(table
, p
);
160 /* Allocate bgp_info_extra */
161 static struct bgp_info_extra
*bgp_info_extra_new(void)
163 struct bgp_info_extra
*new;
164 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA
, sizeof(struct bgp_info_extra
));
165 new->label
[0] = MPLS_INVALID_LABEL
;
170 static void bgp_info_extra_free(struct bgp_info_extra
**extra
)
172 if (extra
&& *extra
) {
173 if ((*extra
)->damp_info
)
174 bgp_damp_info_free((*extra
)->damp_info
, 0);
176 (*extra
)->damp_info
= NULL
;
178 XFREE(MTYPE_BGP_ROUTE_EXTRA
, *extra
);
184 /* Get bgp_info extra information for the given bgp_info, lazy allocated
187 struct bgp_info_extra
*bgp_info_extra_get(struct bgp_info
*ri
)
190 ri
->extra
= bgp_info_extra_new();
194 /* Allocate new bgp info structure. */
195 struct bgp_info
*bgp_info_new(void)
197 return XCALLOC(MTYPE_BGP_ROUTE
, sizeof(struct bgp_info
));
200 /* Free bgp route information. */
201 static void bgp_info_free(struct bgp_info
*binfo
)
204 bgp_attr_unintern(&binfo
->attr
);
206 bgp_unlink_nexthop(binfo
);
207 bgp_info_extra_free(&binfo
->extra
);
208 bgp_info_mpath_free(&binfo
->mpath
);
210 peer_unlock(binfo
->peer
); /* bgp_info peer reference */
212 XFREE(MTYPE_BGP_ROUTE
, binfo
);
215 struct bgp_info
*bgp_info_lock(struct bgp_info
*binfo
)
221 struct bgp_info
*bgp_info_unlock(struct bgp_info
*binfo
)
223 assert(binfo
&& binfo
->lock
> 0);
226 if (binfo
->lock
== 0) {
228 zlog_debug ("%s: unlocked and freeing", __func__
);
229 zlog_backtrace (LOG_DEBUG
);
231 bgp_info_free(binfo
);
236 if (binfo
->lock
== 1)
238 zlog_debug ("%s: unlocked to 1", __func__
);
239 zlog_backtrace (LOG_DEBUG
);
246 void bgp_info_add(struct bgp_node
*rn
, struct bgp_info
*ri
)
248 struct bgp_info
*top
;
260 peer_lock(ri
->peer
); /* bgp_info peer reference */
263 /* Do the actual removal of info from RIB, for use by bgp_process
264 completion callback *only* */
265 void bgp_info_reap(struct bgp_node
*rn
, struct bgp_info
*ri
)
268 ri
->next
->prev
= ri
->prev
;
270 ri
->prev
->next
= ri
->next
;
274 bgp_info_mpath_dequeue(ri
);
279 void bgp_info_delete(struct bgp_node
*rn
, struct bgp_info
*ri
)
281 bgp_info_set_flag(rn
, ri
, BGP_INFO_REMOVED
);
282 /* set of previous already took care of pcount */
283 UNSET_FLAG(ri
->flags
, BGP_INFO_VALID
);
286 /* undo the effects of a previous call to bgp_info_delete; typically
287 called when a route is deleted and then quickly re-added before the
288 deletion has been processed */
289 void bgp_info_restore(struct bgp_node
*rn
, struct bgp_info
*ri
)
291 bgp_info_unset_flag(rn
, ri
, BGP_INFO_REMOVED
);
292 /* unset of previous already took care of pcount */
293 SET_FLAG(ri
->flags
, BGP_INFO_VALID
);
296 /* Adjust pcount as required */
297 static void bgp_pcount_adjust(struct bgp_node
*rn
, struct bgp_info
*ri
)
299 struct bgp_table
*table
;
301 assert(rn
&& bgp_node_table(rn
));
302 assert(ri
&& ri
->peer
&& ri
->peer
->bgp
);
304 table
= bgp_node_table(rn
);
306 if (ri
->peer
== ri
->peer
->bgp
->peer_self
)
309 if (!BGP_INFO_COUNTABLE(ri
)
310 && CHECK_FLAG(ri
->flags
, BGP_INFO_COUNTED
)) {
312 UNSET_FLAG(ri
->flags
, BGP_INFO_COUNTED
);
314 /* slight hack, but more robust against errors. */
315 if (ri
->peer
->pcount
[table
->afi
][table
->safi
])
316 ri
->peer
->pcount
[table
->afi
][table
->safi
]--;
319 "%s: Asked to decrement 0 prefix count for peer %s",
320 __func__
, ri
->peer
->host
);
321 zlog_backtrace(LOG_WARNING
);
322 zlog_warn("%s: Please report to Quagga bugzilla",
325 } else if (BGP_INFO_COUNTABLE(ri
)
326 && !CHECK_FLAG(ri
->flags
, BGP_INFO_COUNTED
)) {
327 SET_FLAG(ri
->flags
, BGP_INFO_COUNTED
);
328 ri
->peer
->pcount
[table
->afi
][table
->safi
]++;
332 static int bgp_label_index_differs(struct bgp_info
*ri1
, struct bgp_info
*ri2
)
334 return (!(ri1
->attr
->label_index
== ri2
->attr
->label_index
));
337 /* Set/unset bgp_info flags, adjusting any other state as needed.
338 * This is here primarily to keep prefix-count in check.
340 void bgp_info_set_flag(struct bgp_node
*rn
, struct bgp_info
*ri
, u_int32_t flag
)
342 SET_FLAG(ri
->flags
, flag
);
344 /* early bath if we know it's not a flag that changes countability state
346 if (!CHECK_FLAG(flag
,
347 BGP_INFO_VALID
| BGP_INFO_HISTORY
| BGP_INFO_REMOVED
))
350 bgp_pcount_adjust(rn
, ri
);
353 void bgp_info_unset_flag(struct bgp_node
*rn
, struct bgp_info
*ri
,
356 UNSET_FLAG(ri
->flags
, flag
);
358 /* early bath if we know it's not a flag that changes countability state
360 if (!CHECK_FLAG(flag
,
361 BGP_INFO_VALID
| BGP_INFO_HISTORY
| BGP_INFO_REMOVED
))
364 bgp_pcount_adjust(rn
, ri
);
367 /* Get MED value. If MED value is missing and "bgp bestpath
368 missing-as-worst" is specified, treat it as the worst value. */
369 static u_int32_t
bgp_med_value(struct attr
*attr
, struct bgp
*bgp
)
371 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
374 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
381 void bgp_info_path_with_addpath_rx_str(struct bgp_info
*ri
, char *buf
)
383 if (ri
->addpath_rx_id
)
384 sprintf(buf
, "path %s (addpath rxid %d)", ri
->peer
->host
,
387 sprintf(buf
, "path %s", ri
->peer
->host
);
390 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
392 static int bgp_info_cmp(struct bgp
*bgp
, struct bgp_info
*new,
393 struct bgp_info
*exist
, int *paths_eq
,
394 struct bgp_maxpaths_cfg
*mpath_cfg
, int debug
,
395 char *pfx_buf
, afi_t afi
, safi_t safi
)
397 struct attr
*newattr
, *existattr
;
398 bgp_peer_sort_t new_sort
;
399 bgp_peer_sort_t exist_sort
;
401 u_int32_t exist_pref
;
404 u_int32_t new_weight
;
405 u_int32_t exist_weight
;
406 uint32_t newm
, existm
;
407 struct in_addr new_id
;
408 struct in_addr exist_id
;
411 int internal_as_route
;
414 char new_buf
[PATH_ADDPATH_STR_BUFFER
];
415 char exist_buf
[PATH_ADDPATH_STR_BUFFER
];
416 u_int32_t new_mm_seq
;
417 u_int32_t exist_mm_seq
;
424 zlog_debug("%s: new is NULL", pfx_buf
);
429 bgp_info_path_with_addpath_rx_str(new, new_buf
);
433 zlog_debug("%s: %s is the initial bestpath", pfx_buf
,
439 bgp_info_path_with_addpath_rx_str(exist
, exist_buf
);
440 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
441 pfx_buf
, new_buf
, new->flags
, exist_buf
,
446 existattr
= exist
->attr
;
448 /* For EVPN routes, we cannot just go by local vs remote, we have to
449 * look at the MAC mobility sequence number, if present.
451 if (safi
== SAFI_EVPN
) {
452 /* This is an error condition described in RFC 7432 Section
454 * states that in this scenario "the PE MUST alert the operator"
456 * does not state what other action to take. In order to provide
458 * consistency in this scenario we are going to prefer the path
462 if (newattr
->sticky
!= existattr
->sticky
) {
464 prefix2str(&new->net
->p
, pfx_buf
,
466 * PREFIX2STR_BUFFER
);
467 bgp_info_path_with_addpath_rx_str(new, new_buf
);
468 bgp_info_path_with_addpath_rx_str(exist
,
472 if (newattr
->sticky
&& !existattr
->sticky
) {
474 "%s: %s wins over %s due to sticky MAC flag",
475 pfx_buf
, new_buf
, exist_buf
);
479 if (!newattr
->sticky
&& existattr
->sticky
) {
481 "%s: %s loses to %s due to sticky MAC flag",
482 pfx_buf
, new_buf
, exist_buf
);
487 new_mm_seq
= mac_mobility_seqnum(newattr
);
488 exist_mm_seq
= mac_mobility_seqnum(existattr
);
490 if (new_mm_seq
> exist_mm_seq
) {
493 "%s: %s wins over %s due to MM seq %u > %u",
494 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
499 if (new_mm_seq
< exist_mm_seq
) {
502 "%s: %s loses to %s due to MM seq %u < %u",
503 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
509 /* 1. Weight check. */
510 new_weight
= newattr
->weight
;
511 exist_weight
= existattr
->weight
;
513 if (new_weight
> exist_weight
) {
515 zlog_debug("%s: %s wins over %s due to weight %d > %d",
516 pfx_buf
, new_buf
, exist_buf
, new_weight
,
521 if (new_weight
< exist_weight
) {
523 zlog_debug("%s: %s loses to %s due to weight %d < %d",
524 pfx_buf
, new_buf
, exist_buf
, new_weight
,
529 /* 2. Local preference check. */
530 new_pref
= exist_pref
= bgp
->default_local_pref
;
532 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
533 new_pref
= newattr
->local_pref
;
534 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
535 exist_pref
= existattr
->local_pref
;
537 if (new_pref
> exist_pref
) {
540 "%s: %s wins over %s due to localpref %d > %d",
541 pfx_buf
, new_buf
, exist_buf
, new_pref
,
546 if (new_pref
< exist_pref
) {
549 "%s: %s loses to %s due to localpref %d < %d",
550 pfx_buf
, new_buf
, exist_buf
, new_pref
,
555 /* 3. Local route check. We prefer:
557 * - BGP_ROUTE_AGGREGATE
558 * - BGP_ROUTE_REDISTRIBUTE
560 if (!(new->sub_type
== BGP_ROUTE_NORMAL
)) {
563 "%s: %s wins over %s due to preferred BGP_ROUTE type",
564 pfx_buf
, new_buf
, exist_buf
);
568 if (!(exist
->sub_type
== BGP_ROUTE_NORMAL
)) {
571 "%s: %s loses to %s due to preferred BGP_ROUTE type",
572 pfx_buf
, new_buf
, exist_buf
);
576 /* 4. AS path length check. */
577 if (!bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
)) {
578 int exist_hops
= aspath_count_hops(existattr
->aspath
);
579 int exist_confeds
= aspath_count_confeds(existattr
->aspath
);
581 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
)) {
584 aspath_hops
= aspath_count_hops(newattr
->aspath
);
585 aspath_hops
+= aspath_count_confeds(newattr
->aspath
);
587 if (aspath_hops
< (exist_hops
+ exist_confeds
)) {
590 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
591 pfx_buf
, new_buf
, exist_buf
,
593 (exist_hops
+ exist_confeds
));
597 if (aspath_hops
> (exist_hops
+ exist_confeds
)) {
600 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
601 pfx_buf
, new_buf
, exist_buf
,
603 (exist_hops
+ exist_confeds
));
607 int newhops
= aspath_count_hops(newattr
->aspath
);
609 if (newhops
< exist_hops
) {
612 "%s: %s wins over %s due to aspath hopcount %d < %d",
613 pfx_buf
, new_buf
, exist_buf
,
614 newhops
, exist_hops
);
618 if (newhops
> exist_hops
) {
621 "%s: %s loses to %s due to aspath hopcount %d > %d",
622 pfx_buf
, new_buf
, exist_buf
,
623 newhops
, exist_hops
);
629 /* 5. Origin check. */
630 if (newattr
->origin
< existattr
->origin
) {
632 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
633 pfx_buf
, new_buf
, exist_buf
,
634 bgp_origin_long_str
[newattr
->origin
],
635 bgp_origin_long_str
[existattr
->origin
]);
639 if (newattr
->origin
> existattr
->origin
) {
641 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
642 pfx_buf
, new_buf
, exist_buf
,
643 bgp_origin_long_str
[newattr
->origin
],
644 bgp_origin_long_str
[existattr
->origin
]);
649 internal_as_route
= (aspath_count_hops(newattr
->aspath
) == 0
650 && aspath_count_hops(existattr
->aspath
) == 0);
651 confed_as_route
= (aspath_count_confeds(newattr
->aspath
) > 0
652 && aspath_count_confeds(existattr
->aspath
) > 0
653 && aspath_count_hops(newattr
->aspath
) == 0
654 && aspath_count_hops(existattr
->aspath
) == 0);
656 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
)
657 || (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
) && confed_as_route
)
658 || aspath_cmp_left(newattr
->aspath
, existattr
->aspath
)
659 || aspath_cmp_left_confed(newattr
->aspath
, existattr
->aspath
)
660 || internal_as_route
) {
661 new_med
= bgp_med_value(new->attr
, bgp
);
662 exist_med
= bgp_med_value(exist
->attr
, bgp
);
664 if (new_med
< exist_med
) {
667 "%s: %s wins over %s due to MED %d < %d",
668 pfx_buf
, new_buf
, exist_buf
, new_med
,
673 if (new_med
> exist_med
) {
676 "%s: %s loses to %s due to MED %d > %d",
677 pfx_buf
, new_buf
, exist_buf
, new_med
,
683 /* 7. Peer type check. */
684 new_sort
= new->peer
->sort
;
685 exist_sort
= exist
->peer
->sort
;
687 if (new_sort
== BGP_PEER_EBGP
688 && (exist_sort
== BGP_PEER_IBGP
|| exist_sort
== BGP_PEER_CONFED
)) {
691 "%s: %s wins over %s due to eBGP peer > iBGP peer",
692 pfx_buf
, new_buf
, exist_buf
);
696 if (exist_sort
== BGP_PEER_EBGP
697 && (new_sort
== BGP_PEER_IBGP
|| new_sort
== BGP_PEER_CONFED
)) {
700 "%s: %s loses to %s due to iBGP peer < eBGP peer",
701 pfx_buf
, new_buf
, exist_buf
);
705 /* 8. IGP metric check. */
709 newm
= new->extra
->igpmetric
;
711 existm
= exist
->extra
->igpmetric
;
716 "%s: %s wins over %s due to IGP metric %d < %d",
717 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
724 "%s: %s loses to %s due to IGP metric %d > %d",
725 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
729 /* 9. Same IGP metric. Compare the cluster list length as
730 representative of IGP hops metric. Rewrite the metric value
731 pair (newm, existm) with the cluster list length. Prefer the
732 path with smaller cluster list length. */
733 if (newm
== existm
) {
734 if (peer_sort(new->peer
) == BGP_PEER_IBGP
735 && peer_sort(exist
->peer
) == BGP_PEER_IBGP
736 && (mpath_cfg
== NULL
738 mpath_cfg
->ibgp_flags
,
739 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN
))) {
740 newm
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
741 existm
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
746 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
747 pfx_buf
, new_buf
, exist_buf
,
755 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
756 pfx_buf
, new_buf
, exist_buf
,
763 /* 10. confed-external vs. confed-internal */
764 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
765 if (new_sort
== BGP_PEER_CONFED
766 && exist_sort
== BGP_PEER_IBGP
) {
769 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
770 pfx_buf
, new_buf
, exist_buf
);
774 if (exist_sort
== BGP_PEER_CONFED
775 && new_sort
== BGP_PEER_IBGP
) {
778 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
779 pfx_buf
, new_buf
, exist_buf
);
784 /* 11. Maximum path check. */
785 if (newm
== existm
) {
786 /* If one path has a label but the other does not, do not treat
787 * them as equals for multipath
789 if ((new->extra
&&bgp_is_valid_label(&new->extra
->label
[0]))
791 && bgp_is_valid_label(&exist
->extra
->label
[0]))) {
794 "%s: %s and %s cannot be multipath, one has a label while the other does not",
795 pfx_buf
, new_buf
, exist_buf
);
796 } else if (bgp_flag_check(bgp
,
797 BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
800 * For the two paths, all comparison steps till IGP
802 * have succeeded - including AS_PATH hop count. Since
804 * bestpath as-path multipath-relax' knob is on, we
806 * an exact match of AS_PATH. Thus, mark the paths are
808 * That will trigger both these paths to get into the
816 "%s: %s and %s are equal via multipath-relax",
817 pfx_buf
, new_buf
, exist_buf
);
818 } else if (new->peer
->sort
== BGP_PEER_IBGP
) {
819 if (aspath_cmp(new->attr
->aspath
,
820 exist
->attr
->aspath
)) {
825 "%s: %s and %s are equal via matching aspaths",
826 pfx_buf
, new_buf
, exist_buf
);
828 } else if (new->peer
->as
== exist
->peer
->as
) {
833 "%s: %s and %s are equal via same remote-as",
834 pfx_buf
, new_buf
, exist_buf
);
838 * TODO: If unequal cost ibgp multipath is enabled we can
839 * mark the paths as equal here instead of returning
844 "%s: %s wins over %s after IGP metric comparison",
845 pfx_buf
, new_buf
, exist_buf
);
848 "%s: %s loses to %s after IGP metric comparison",
849 pfx_buf
, new_buf
, exist_buf
);
854 /* 12. If both paths are external, prefer the path that was received
855 first (the oldest one). This step minimizes route-flap, since a
856 newer path won't displace an older one, even if it was the
857 preferred route based on the additional decision criteria below. */
858 if (!bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
859 && new_sort
== BGP_PEER_EBGP
&& exist_sort
== BGP_PEER_EBGP
) {
860 if (CHECK_FLAG(new->flags
, BGP_INFO_SELECTED
)) {
863 "%s: %s wins over %s due to oldest external",
864 pfx_buf
, new_buf
, exist_buf
);
868 if (CHECK_FLAG(exist
->flags
, BGP_INFO_SELECTED
)) {
871 "%s: %s loses to %s due to oldest external",
872 pfx_buf
, new_buf
, exist_buf
);
877 /* 13. Router-ID comparision. */
878 /* If one of the paths is "stale", the corresponding peer router-id will
879 * be 0 and would always win over the other path. If originator id is
880 * used for the comparision, it will decide which path is better.
882 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
883 new_id
.s_addr
= newattr
->originator_id
.s_addr
;
885 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
886 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
887 exist_id
.s_addr
= existattr
->originator_id
.s_addr
;
889 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
891 if (ntohl(new_id
.s_addr
) < ntohl(exist_id
.s_addr
)) {
894 "%s: %s wins over %s due to Router-ID comparison",
895 pfx_buf
, new_buf
, exist_buf
);
899 if (ntohl(new_id
.s_addr
) > ntohl(exist_id
.s_addr
)) {
902 "%s: %s loses to %s due to Router-ID comparison",
903 pfx_buf
, new_buf
, exist_buf
);
907 /* 14. Cluster length comparision. */
908 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
909 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
911 if (new_cluster
< exist_cluster
) {
914 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
915 pfx_buf
, new_buf
, exist_buf
, new_cluster
,
920 if (new_cluster
> exist_cluster
) {
923 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
924 pfx_buf
, new_buf
, exist_buf
, new_cluster
,
929 /* 15. Neighbor address comparision. */
930 /* Do this only if neither path is "stale" as stale paths do not have
931 * valid peer information (as the connection may or may not be up).
933 if (CHECK_FLAG(exist
->flags
, BGP_INFO_STALE
)) {
936 "%s: %s wins over %s due to latter path being STALE",
937 pfx_buf
, new_buf
, exist_buf
);
941 if (CHECK_FLAG(new->flags
, BGP_INFO_STALE
)) {
944 "%s: %s loses to %s due to former path being STALE",
945 pfx_buf
, new_buf
, exist_buf
);
949 /* locally configured routes to advertise do not have su_remote */
950 if (new->peer
->su_remote
== NULL
)
952 if (exist
->peer
->su_remote
== NULL
)
955 ret
= sockunion_cmp(new->peer
->su_remote
, exist
->peer
->su_remote
);
960 "%s: %s loses to %s due to Neighor IP comparison",
961 pfx_buf
, new_buf
, exist_buf
);
968 "%s: %s wins over %s due to Neighor IP comparison",
969 pfx_buf
, new_buf
, exist_buf
);
974 zlog_debug("%s: %s wins over %s due to nothing left to compare",
975 pfx_buf
, new_buf
, exist_buf
);
980 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
981 * is preferred, or 0 if they are the same (usually will only occur if
982 * multipath is enabled
983 * This version is compatible with */
984 int bgp_info_cmp_compatible(struct bgp
*bgp
, struct bgp_info
*new,
985 struct bgp_info
*exist
, char *pfx_buf
, afi_t afi
,
990 ret
= bgp_info_cmp(bgp
, new, exist
, &paths_eq
, NULL
, 0, pfx_buf
, afi
,
1004 static enum filter_type
bgp_input_filter(struct peer
*peer
, struct prefix
*p
,
1005 struct attr
*attr
, afi_t afi
,
1008 struct bgp_filter
*filter
;
1010 filter
= &peer
->filter
[afi
][safi
];
1012 #define FILTER_EXIST_WARN(F, f, filter) \
1013 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1014 zlog_warn("%s: Could not find configured input %s-list %s!", \
1015 peer->host, #f, F##_IN_NAME(filter));
1017 if (DISTRIBUTE_IN_NAME(filter
)) {
1018 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
1020 if (access_list_apply(DISTRIBUTE_IN(filter
), p
) == FILTER_DENY
)
1024 if (PREFIX_LIST_IN_NAME(filter
)) {
1025 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
1027 if (prefix_list_apply(PREFIX_LIST_IN(filter
), p
) == PREFIX_DENY
)
1031 if (FILTER_LIST_IN_NAME(filter
)) {
1032 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
1034 if (as_list_apply(FILTER_LIST_IN(filter
), attr
->aspath
)
1039 return FILTER_PERMIT
;
1040 #undef FILTER_EXIST_WARN
1043 static enum filter_type
bgp_output_filter(struct peer
*peer
, struct prefix
*p
,
1044 struct attr
*attr
, afi_t afi
,
1047 struct bgp_filter
*filter
;
1049 filter
= &peer
->filter
[afi
][safi
];
1051 #define FILTER_EXIST_WARN(F, f, filter) \
1052 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1053 zlog_warn("%s: Could not find configured output %s-list %s!", \
1054 peer->host, #f, F##_OUT_NAME(filter));
1056 if (DISTRIBUTE_OUT_NAME(filter
)) {
1057 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
1059 if (access_list_apply(DISTRIBUTE_OUT(filter
), p
) == FILTER_DENY
)
1063 if (PREFIX_LIST_OUT_NAME(filter
)) {
1064 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
1066 if (prefix_list_apply(PREFIX_LIST_OUT(filter
), p
)
1071 if (FILTER_LIST_OUT_NAME(filter
)) {
1072 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
1074 if (as_list_apply(FILTER_LIST_OUT(filter
), attr
->aspath
)
1079 return FILTER_PERMIT
;
1080 #undef FILTER_EXIST_WARN
1083 /* If community attribute includes no_export then return 1. */
1084 static int bgp_community_filter(struct peer
*peer
, struct attr
*attr
)
1086 if (attr
->community
) {
1087 /* NO_ADVERTISE check. */
1088 if (community_include(attr
->community
, COMMUNITY_NO_ADVERTISE
))
1091 /* NO_EXPORT check. */
1092 if (peer
->sort
== BGP_PEER_EBGP
1093 && community_include(attr
->community
, COMMUNITY_NO_EXPORT
))
1096 /* NO_EXPORT_SUBCONFED check. */
1097 if (peer
->sort
== BGP_PEER_EBGP
1098 || peer
->sort
== BGP_PEER_CONFED
)
1099 if (community_include(attr
->community
,
1100 COMMUNITY_NO_EXPORT_SUBCONFED
))
1106 /* Route reflection loop check. */
1107 static int bgp_cluster_filter(struct peer
*peer
, struct attr
*attr
)
1109 struct in_addr cluster_id
;
1111 if (attr
->cluster
) {
1112 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
1113 cluster_id
= peer
->bgp
->cluster_id
;
1115 cluster_id
= peer
->bgp
->router_id
;
1117 if (cluster_loop_check(attr
->cluster
, cluster_id
))
1123 static int bgp_input_modifier(struct peer
*peer
, struct prefix
*p
,
1124 struct attr
*attr
, afi_t afi
, safi_t safi
,
1125 const char *rmap_name
)
1127 struct bgp_filter
*filter
;
1128 struct bgp_info info
;
1129 route_map_result_t ret
;
1130 struct route_map
*rmap
= NULL
;
1132 filter
= &peer
->filter
[afi
][safi
];
1134 /* Apply default weight value. */
1135 if (peer
->weight
[afi
][safi
])
1136 attr
->weight
= peer
->weight
[afi
][safi
];
1139 rmap
= route_map_lookup_by_name(rmap_name
);
1144 if (ROUTE_MAP_IN_NAME(filter
)) {
1145 rmap
= ROUTE_MAP_IN(filter
);
1152 /* Route map apply. */
1154 /* Duplicate current value to new strucutre for modification. */
1158 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1160 /* Apply BGP route map to the attribute. */
1161 ret
= route_map_apply(rmap
, p
, RMAP_BGP
, &info
);
1163 peer
->rmap_type
= 0;
1165 if (ret
== RMAP_DENYMATCH
) {
1166 /* Free newly generated AS path and community by
1168 bgp_attr_flush(attr
);
1175 static int bgp_output_modifier(struct peer
*peer
, struct prefix
*p
,
1176 struct attr
*attr
, afi_t afi
, safi_t safi
,
1177 const char *rmap_name
)
1179 struct bgp_info info
;
1180 route_map_result_t ret
;
1181 struct route_map
*rmap
= NULL
;
1185 * So if we get to this point and have no rmap_name
1186 * we want to just show the output as it currently
1192 /* Apply default weight value. */
1193 if (peer
->weight
[afi
][safi
])
1194 attr
->weight
= peer
->weight
[afi
][safi
];
1196 rmap
= route_map_lookup_by_name(rmap_name
);
1199 * If we have a route map name and we do not find
1200 * the routemap that means we have an implicit
1206 /* Route map apply. */
1207 /* Duplicate current value to new strucutre for modification. */
1211 rmap_type
= peer
->rmap_type
;
1212 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1214 /* Apply BGP route map to the attribute. */
1215 ret
= route_map_apply(rmap
, p
, RMAP_BGP
, &info
);
1217 peer
->rmap_type
= rmap_type
;
1219 if (ret
== RMAP_DENYMATCH
)
1221 * caller has multiple error paths with bgp_attr_flush()
1228 /* If this is an EBGP peer with remove-private-AS */
1229 static void bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1230 struct peer
*peer
, struct attr
*attr
)
1232 if (peer
->sort
== BGP_PEER_EBGP
1233 && (peer_af_flag_check(peer
, afi
, safi
,
1234 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)
1235 || peer_af_flag_check(peer
, afi
, safi
,
1236 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)
1237 || peer_af_flag_check(peer
, afi
, safi
,
1238 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)
1239 || peer_af_flag_check(peer
, afi
, safi
,
1240 PEER_FLAG_REMOVE_PRIVATE_AS
))) {
1241 // Take action on the entire aspath
1242 if (peer_af_flag_check(peer
, afi
, safi
,
1243 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)
1244 || peer_af_flag_check(peer
, afi
, safi
,
1245 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
1246 if (peer_af_flag_check(
1248 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1249 attr
->aspath
= aspath_replace_private_asns(
1250 attr
->aspath
, bgp
->as
);
1252 // The entire aspath consists of private ASNs so create
1254 else if (aspath_private_as_check(attr
->aspath
))
1255 attr
->aspath
= aspath_empty_get();
1257 // There are some public and some private ASNs, remove
1260 attr
->aspath
= aspath_remove_private_asns(
1264 // 'all' was not specified so the entire aspath must be private
1266 // for us to do anything
1267 else if (aspath_private_as_check(attr
->aspath
)) {
1268 if (peer_af_flag_check(
1270 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1271 attr
->aspath
= aspath_replace_private_asns(
1272 attr
->aspath
, bgp
->as
);
1274 attr
->aspath
= aspath_empty_get();
1279 /* If this is an EBGP peer with as-override */
1280 static void bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1281 struct peer
*peer
, struct attr
*attr
)
1283 if (peer
->sort
== BGP_PEER_EBGP
1284 && peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
1285 if (aspath_single_asn_check(attr
->aspath
, peer
->as
))
1286 attr
->aspath
= aspath_replace_specific_asn(
1287 attr
->aspath
, peer
->as
, bgp
->as
);
1291 void bgp_attr_add_gshut_community(struct attr
*attr
)
1293 struct community
*old
;
1294 struct community
*new;
1295 struct community
*merge
;
1296 struct community
*gshut
;
1298 old
= attr
->community
;
1299 gshut
= community_str2com("graceful-shutdown");
1302 merge
= community_merge(community_dup(old
), gshut
);
1304 if (old
->refcnt
== 0)
1305 community_free(old
);
1307 new = community_uniq_sort(merge
);
1308 community_free(merge
);
1310 new = community_dup(gshut
);
1313 community_free(gshut
);
1314 attr
->community
= new;
1315 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
);
1317 /* When we add the graceful-shutdown community we must also
1318 * lower the local-preference */
1319 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1320 attr
->local_pref
= BGP_GSHUT_LOCAL_PREF
;
1324 static void subgroup_announce_reset_nhop(u_char family
, struct attr
*attr
)
1326 if (family
== AF_INET
)
1327 attr
->nexthop
.s_addr
= 0;
1328 if (family
== AF_INET6
)
1329 memset(&attr
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1332 int subgroup_announce_check(struct bgp_node
*rn
, struct bgp_info
*ri
,
1333 struct update_subgroup
*subgrp
, struct prefix
*p
,
1336 struct bgp_filter
*filter
;
1339 struct peer
*onlypeer
;
1341 struct attr
*riattr
;
1342 char buf
[PREFIX_STRLEN
];
1348 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1350 if (DISABLE_BGP_ANNOUNCE
)
1353 afi
= SUBGRP_AFI(subgrp
);
1354 safi
= SUBGRP_SAFI(subgrp
);
1355 peer
= SUBGRP_PEER(subgrp
);
1357 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
))
1358 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1361 filter
= &peer
->filter
[afi
][safi
];
1362 bgp
= SUBGRP_INST(subgrp
);
1363 riattr
= bgp_info_mpath_count(ri
) ? bgp_info_mpath_attr(ri
) : ri
->attr
;
1366 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
)
1367 && ((ri
->type
== ZEBRA_ROUTE_BGP_DIRECT
)
1368 || (ri
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1371 * direct and direct_ext type routes originate internally even
1372 * though they can have peer pointers that reference other
1375 prefix2str(p
, buf
, PREFIX_STRLEN
);
1376 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe",
1382 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
))
1383 && ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_UNICAST
))
1384 && (ri
->type
== ZEBRA_ROUTE_BGP
)
1385 && (ri
->sub_type
== BGP_ROUTE_IMPORTED
)) {
1387 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1392 /* With addpath we may be asked to TX all kinds of paths so make sure
1394 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_VALID
)
1395 || CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
)
1396 || CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
1400 /* If this is not the bestpath then check to see if there is an enabled
1402 * feature that requires us to advertise it */
1403 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
1404 if (!bgp_addpath_tx_path(peer
, afi
, safi
, ri
)) {
1409 /* Aggregate-address suppress check. */
1410 if (ri
->extra
&& ri
->extra
->suppress
)
1411 if (!UNSUPPRESS_MAP_NAME(filter
)) {
1415 /* If it's labeled safi, make sure the route has a valid label. */
1416 if (safi
== SAFI_LABELED_UNICAST
) {
1417 mpls_label_t label
= bgp_adv_label(rn
, ri
, peer
, afi
, safi
);
1418 if (!bgp_is_valid_label(&label
)) {
1419 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1420 zlog_debug("u%" PRIu64
":s%" PRIu64
1421 " %s/%d is filtered - no label (%p)",
1422 subgrp
->update_group
->id
, subgrp
->id
,
1423 inet_ntop(p
->family
, &p
->u
.prefix
,
1424 buf
, SU_ADDRSTRLEN
),
1425 p
->prefixlen
, &label
);
1430 /* Do not send back route to sender. */
1431 if (onlypeer
&& from
== onlypeer
) {
1435 /* Do not send the default route in the BGP table if the neighbor is
1436 * configured for default-originate */
1437 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1438 PEER_FLAG_DEFAULT_ORIGINATE
)) {
1439 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1441 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1445 /* Transparency check. */
1446 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1447 && CHECK_FLAG(from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1452 /* If community is not disabled check the no-export and local. */
1453 if (!transparent
&& bgp_community_filter(peer
, riattr
)) {
1454 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1456 "subgrpannouncecheck: community filter check fail");
1460 /* If the attribute has originator-id and it is same as remote
1462 if (onlypeer
&& riattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)
1463 && (IPV4_ADDR_SAME(&onlypeer
->remote_id
, &riattr
->originator_id
))) {
1464 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1466 "%s [Update:SEND] %s originator-id is same as "
1469 prefix2str(p
, buf
, sizeof(buf
)));
1473 /* ORF prefix-list filter check */
1474 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1475 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1476 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
1477 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1478 if (peer
->orf_plist
[afi
][safi
]) {
1479 if (prefix_list_apply(peer
->orf_plist
[afi
][safi
], p
)
1481 if (bgp_debug_update(NULL
, p
,
1482 subgrp
->update_group
, 0))
1484 "%s [Update:SEND] %s is filtered via ORF",
1492 /* Output filter check. */
1493 if (bgp_output_filter(peer
, p
, riattr
, afi
, safi
) == FILTER_DENY
) {
1494 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1495 zlog_debug("%s [Update:SEND] %s is filtered",
1496 peer
->host
, prefix2str(p
, buf
, sizeof(buf
)));
1500 #ifdef BGP_SEND_ASPATH_CHECK
1501 /* AS path loop check. */
1502 if (onlypeer
&& aspath_loop_check(riattr
->aspath
, onlypeer
->as
)) {
1503 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1505 "%s [Update:SEND] suppress announcement to peer AS %u "
1506 "that is part of AS path.",
1507 onlypeer
->host
, onlypeer
->as
);
1510 #endif /* BGP_SEND_ASPATH_CHECK */
1512 /* If we're a CONFED we need to loop check the CONFED ID too */
1513 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
1514 if (aspath_loop_check(riattr
->aspath
, bgp
->confed_id
)) {
1515 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1517 "%s [Update:SEND] suppress announcement to peer AS %u"
1519 peer
->host
, bgp
->confed_id
);
1524 /* Route-Reflect check. */
1525 if (from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1530 /* IBGP reflection check. */
1531 if (reflect
&& !samepeer_safe
) {
1532 /* A route from a Client peer. */
1533 if (CHECK_FLAG(from
->af_flags
[afi
][safi
],
1534 PEER_FLAG_REFLECTOR_CLIENT
)) {
1535 /* Reflect to all the Non-Client peers and also to the
1536 Client peers other than the originator. Originator
1538 is already done. So there is noting to do. */
1539 /* no bgp client-to-client reflection check. */
1540 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
1541 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1542 PEER_FLAG_REFLECTOR_CLIENT
))
1545 /* A route from a Non-client peer. Reflect to all other
1547 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1548 PEER_FLAG_REFLECTOR_CLIENT
))
1553 /* For modify attribute, copy it to temporary structure. */
1554 bgp_attr_dup(attr
, riattr
);
1556 /* If local-preference is not set. */
1557 if ((peer
->sort
== BGP_PEER_IBGP
|| peer
->sort
== BGP_PEER_CONFED
)
1558 && (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)))) {
1559 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1560 attr
->local_pref
= bgp
->default_local_pref
;
1563 /* If originator-id is not set and the route is to be reflected,
1564 set the originator id */
1566 && (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)))) {
1567 IPV4_ADDR_COPY(&(attr
->originator_id
), &(from
->remote_id
));
1568 SET_FLAG(attr
->flag
, BGP_ATTR_ORIGINATOR_ID
);
1571 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
1573 if (peer
->sort
== BGP_PEER_EBGP
1574 && attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)) {
1575 if (from
!= bgp
->peer_self
&& !transparent
1576 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1577 PEER_FLAG_MED_UNCHANGED
))
1579 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
));
1582 /* Since the nexthop attribute can vary per peer, it is not explicitly
1584 * in announce check, only certain flags and length (or number of
1586 * -- for IPv6/MP_REACH) are set here in order to guide the update
1588 * code in setting the nexthop(s) on a per peer basis in
1590 * Typically, the source nexthop in the attribute is preserved but in
1592 * scenarios where we know it will always be overwritten, we reset the
1593 * nexthop to "0" in an attempt to achieve better Update packing. An
1594 * example of this is when a prefix from each of 2 IBGP peers needs to
1596 * announced to an EBGP peer (and they have the same attributes barring
1600 SET_FLAG(attr
->rmap_change_flags
, BATTR_REFLECTED
);
1602 #define NEXTHOP_IS_V6 \
1603 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
1604 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
1605 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
1606 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1608 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
1610 * the peer (group) is configured to receive link-local nexthop
1612 * and it is available in the prefix OR we're not reflecting the route
1614 * the peer (group) to whom we're going to announce is on a shared
1616 * and this is either a self-originated route or the peer is EBGP.
1618 if (NEXTHOP_IS_V6
) {
1619 attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1620 if ((CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1621 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)
1622 && IN6_IS_ADDR_LINKLOCAL(&attr
->mp_nexthop_local
))
1623 || (!reflect
&& peer
->shared_network
1624 && (from
== bgp
->peer_self
1625 || peer
->sort
== BGP_PEER_EBGP
))) {
1626 attr
->mp_nexthop_len
=
1627 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
1630 /* Clear off link-local nexthop in source, whenever it is not
1632 * ensure more prefixes share the same attribute for
1635 if (!(CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1636 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)))
1637 memset(&attr
->mp_nexthop_local
, 0, IPV6_MAX_BYTELEN
);
1640 bgp_peer_remove_private_as(bgp
, afi
, safi
, peer
, attr
);
1641 bgp_peer_as_override(bgp
, afi
, safi
, peer
, attr
);
1643 /* Route map & unsuppress-map apply. */
1644 if (ROUTE_MAP_OUT_NAME(filter
) || (ri
->extra
&& ri
->extra
->suppress
)) {
1645 struct bgp_info info
;
1646 struct bgp_info_extra dummy_info_extra
;
1647 struct attr dummy_attr
;
1653 memcpy(&dummy_info_extra
, ri
->extra
,
1654 sizeof(struct bgp_info_extra
));
1655 info
.extra
= &dummy_info_extra
;
1658 /* don't confuse inbound and outbound setting */
1659 RESET_FLAG(attr
->rmap_change_flags
);
1662 * The route reflector is not allowed to modify the attributes
1663 * of the reflected IBGP routes unless explicitly allowed.
1665 if ((from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1666 && !bgp_flag_check(bgp
,
1667 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
1668 bgp_attr_dup(&dummy_attr
, attr
);
1669 info
.attr
= &dummy_attr
;
1672 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1674 if (ri
->extra
&& ri
->extra
->suppress
)
1675 ret
= route_map_apply(UNSUPPRESS_MAP(filter
), p
,
1678 ret
= route_map_apply(ROUTE_MAP_OUT(filter
), p
,
1681 peer
->rmap_type
= 0;
1683 if (ret
== RMAP_DENYMATCH
) {
1684 bgp_attr_flush(attr
);
1689 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
)) {
1690 if (peer
->sort
== BGP_PEER_IBGP
1691 || peer
->sort
== BGP_PEER_CONFED
) {
1692 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1693 attr
->local_pref
= BGP_GSHUT_LOCAL_PREF
;
1695 bgp_attr_add_gshut_community(attr
);
1699 /* After route-map has been applied, we check to see if the nexthop to
1700 * be carried in the attribute (that is used for the announcement) can
1701 * be cleared off or not. We do this in all cases where we would be
1702 * setting the nexthop to "ourselves". For IPv6, we only need to
1704 * the global nexthop here; the link-local nexthop would have been
1706 * already, and if not, it is required by the update formation code.
1707 * Also see earlier comments in this function.
1710 * If route-map has performed some operation on the nexthop or the peer
1711 * configuration says to pass it unchanged, we cannot reset the nexthop
1712 * here, so only attempt to do it if these aren't true. Note that the
1713 * route-map handler itself might have cleared the nexthop, if for
1715 * it is configured as 'peer-address'.
1717 if (!bgp_rmap_nhop_changed(attr
->rmap_change_flags
,
1718 riattr
->rmap_change_flags
)
1720 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1721 PEER_FLAG_NEXTHOP_UNCHANGED
)) {
1722 /* We can reset the nexthop, if setting (or forcing) it to
1724 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1725 PEER_FLAG_NEXTHOP_SELF
)
1726 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1727 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
1729 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1730 PEER_FLAG_FORCE_NEXTHOP_SELF
))
1731 subgroup_announce_reset_nhop(
1732 (peer_cap_enhe(peer
, afi
, safi
)
1736 } else if (peer
->sort
== BGP_PEER_EBGP
) {
1737 /* Can also reset the nexthop if announcing to EBGP, but
1739 * no peer in the subgroup is on a shared subnet.
1740 * Note: 3rd party nexthop currently implemented for
1743 if (!bgp_subgrp_multiaccess_check_v4(riattr
->nexthop
,
1745 subgroup_announce_reset_nhop(
1746 (peer_cap_enhe(peer
, afi
, safi
)
1751 /* If IPv6/MP and nexthop does not have any override and happens
1753 * be a link-local address, reset it so that we don't pass along
1755 * source's link-local IPv6 address to recipients who may not be
1757 * the same interface.
1759 if (p
->family
== AF_INET6
|| peer_cap_enhe(peer
, afi
, safi
)) {
1760 if (IN6_IS_ADDR_LINKLOCAL(&attr
->mp_nexthop_global
))
1761 subgroup_announce_reset_nhop(AF_INET6
, attr
);
1768 void bgp_best_selection(struct bgp
*bgp
, struct bgp_node
*rn
,
1769 struct bgp_maxpaths_cfg
*mpath_cfg
,
1770 struct bgp_info_pair
*result
, afi_t afi
, safi_t safi
)
1772 struct bgp_info
*new_select
;
1773 struct bgp_info
*old_select
;
1774 struct bgp_info
*ri
;
1775 struct bgp_info
*ri1
;
1776 struct bgp_info
*ri2
;
1777 struct bgp_info
*nextri
= NULL
;
1778 int paths_eq
, do_mpath
, debug
;
1779 struct list mp_list
;
1780 char pfx_buf
[PREFIX2STR_BUFFER
];
1781 char path_buf
[PATH_ADDPATH_STR_BUFFER
];
1783 bgp_mp_list_init(&mp_list
);
1785 (mpath_cfg
->maxpaths_ebgp
> 1 || mpath_cfg
->maxpaths_ibgp
> 1);
1787 debug
= bgp_debug_bestpath(&rn
->p
);
1790 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
1792 /* bgp deterministic-med */
1794 if (bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
1796 /* Clear BGP_INFO_DMED_SELECTED for all paths */
1797 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1798 bgp_info_unset_flag(rn
, ri1
, BGP_INFO_DMED_SELECTED
);
1800 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
) {
1801 if (CHECK_FLAG(ri1
->flags
, BGP_INFO_DMED_CHECK
))
1803 if (BGP_INFO_HOLDDOWN(ri1
))
1805 if (ri1
->peer
&& ri1
->peer
!= bgp
->peer_self
)
1806 if (ri1
->peer
->status
!= Established
)
1811 for (ri2
= ri1
->next
; ri2
; ri2
= ri2
->next
) {
1812 if (CHECK_FLAG(ri2
->flags
,
1813 BGP_INFO_DMED_CHECK
))
1815 if (BGP_INFO_HOLDDOWN(ri2
))
1818 && ri2
->peer
!= bgp
->peer_self
1821 PEER_STATUS_NSF_WAIT
))
1822 if (ri2
->peer
->status
1826 if (aspath_cmp_left(ri1
->attr
->aspath
,
1828 || aspath_cmp_left_confed(
1830 ri2
->attr
->aspath
)) {
1831 if (bgp_info_cmp(bgp
, ri2
,
1837 bgp_info_unset_flag(
1839 BGP_INFO_DMED_SELECTED
);
1845 BGP_INFO_DMED_CHECK
);
1849 bgp_info_set_flag(rn
, new_select
, BGP_INFO_DMED_CHECK
);
1850 bgp_info_set_flag(rn
, new_select
,
1851 BGP_INFO_DMED_SELECTED
);
1854 bgp_info_path_with_addpath_rx_str(new_select
,
1856 zlog_debug("%s: %s is the bestpath from AS %d",
1858 aspath_get_first_as(
1859 new_select
->attr
->aspath
));
1864 /* Check old selected route and new selected route. */
1867 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1);
1869 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
))
1872 if (BGP_INFO_HOLDDOWN(ri
)) {
1873 /* reap REMOVED routes, if needs be
1874 * selected route must stay for a while longer though
1876 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)
1877 && (ri
!= old_select
))
1878 bgp_info_reap(rn
, ri
);
1881 zlog_debug("%s: ri %p in holddown", __func__
,
1887 if (ri
->peer
&& ri
->peer
!= bgp
->peer_self
1888 && !CHECK_FLAG(ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1889 if (ri
->peer
->status
!= Established
) {
1893 "%s: ri %p non self peer %s not estab state",
1894 __func__
, ri
, ri
->peer
->host
);
1899 if (bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
1900 && (!CHECK_FLAG(ri
->flags
, BGP_INFO_DMED_SELECTED
))) {
1901 bgp_info_unset_flag(rn
, ri
, BGP_INFO_DMED_CHECK
);
1903 zlog_debug("%s: ri %p dmed", __func__
, ri
);
1907 bgp_info_unset_flag(rn
, ri
, BGP_INFO_DMED_CHECK
);
1909 if (bgp_info_cmp(bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
,
1910 debug
, pfx_buf
, afi
, safi
)) {
1915 /* Now that we know which path is the bestpath see if any of the other
1917 * qualify as multipaths
1921 bgp_info_path_with_addpath_rx_str(new_select
, path_buf
);
1923 sprintf(path_buf
, "NONE");
1925 "%s: After path selection, newbest is %s oldbest was %s",
1927 old_select
? old_select
->peer
->host
: "NONE");
1930 if (do_mpath
&& new_select
) {
1931 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1);
1935 bgp_info_path_with_addpath_rx_str(ri
, path_buf
);
1937 if (ri
== new_select
) {
1940 "%s: %s is the bestpath, add to the multipath list",
1942 bgp_mp_list_add(&mp_list
, ri
);
1946 if (BGP_INFO_HOLDDOWN(ri
))
1949 if (ri
->peer
&& ri
->peer
!= bgp
->peer_self
1950 && !CHECK_FLAG(ri
->peer
->sflags
,
1951 PEER_STATUS_NSF_WAIT
))
1952 if (ri
->peer
->status
!= Established
)
1955 if (!bgp_info_nexthop_cmp(ri
, new_select
)) {
1958 "%s: %s has the same nexthop as the bestpath, skip it",
1963 bgp_info_cmp(bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
,
1964 debug
, pfx_buf
, afi
, safi
);
1969 "%s: %s is equivalent to the bestpath, add to the multipath list",
1971 bgp_mp_list_add(&mp_list
, ri
);
1976 bgp_info_mpath_update(rn
, new_select
, old_select
, &mp_list
, mpath_cfg
);
1977 bgp_info_mpath_aggregate_update(new_select
, old_select
);
1978 bgp_mp_list_clear(&mp_list
);
1980 result
->old
= old_select
;
1981 result
->new = new_select
;
1987 * A new route/change in bestpath of an existing route. Evaluate the path
1988 * for advertisement to the subgroup.
1990 int subgroup_process_announce_selected(struct update_subgroup
*subgrp
,
1991 struct bgp_info
*selected
,
1992 struct bgp_node
*rn
,
1993 u_int32_t addpath_tx_id
)
1996 struct peer
*onlypeer
;
2002 afi
= SUBGRP_AFI(subgrp
);
2003 safi
= SUBGRP_SAFI(subgrp
);
2004 onlypeer
= ((SUBGRP_PCOUNT(subgrp
) == 1) ? (SUBGRP_PFIRST(subgrp
))->peer
2007 if (BGP_DEBUG(update
, UPDATE_OUT
)) {
2008 char buf_prefix
[PREFIX_STRLEN
];
2009 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
2010 zlog_debug("%s: p=%s, selected=%p", __func__
, buf_prefix
,
2014 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2015 if (onlypeer
&& CHECK_FLAG(onlypeer
->af_sflags
[afi
][safi
],
2016 PEER_STATUS_ORF_WAIT_REFRESH
))
2019 memset(&attr
, 0, sizeof(struct attr
));
2020 /* It's initialized in bgp_announce_check() */
2022 /* Announcement to the subgroup. If the route is filtered withdraw it.
2025 if (subgroup_announce_check(rn
, selected
, subgrp
, p
, &attr
))
2026 bgp_adj_out_set_subgroup(rn
, subgrp
, &attr
, selected
);
2028 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1,
2029 selected
->addpath_tx_id
);
2032 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2034 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, addpath_tx_id
);
2041 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2042 * This is called at the end of route processing.
2044 void bgp_zebra_clear_route_change_flags(struct bgp_node
*rn
)
2046 struct bgp_info
*ri
;
2048 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
2049 if (BGP_INFO_HOLDDOWN(ri
))
2051 UNSET_FLAG(ri
->flags
, BGP_INFO_IGP_CHANGED
);
2052 UNSET_FLAG(ri
->flags
, BGP_INFO_ATTR_CHANGED
);
2057 * Has the route changed from the RIB's perspective? This is invoked only
2058 * if the route selection returns the same best route as earlier - to
2059 * determine if we need to update zebra or not.
2061 int bgp_zebra_has_route_changed(struct bgp_node
*rn
, struct bgp_info
*selected
)
2063 struct bgp_info
*mpinfo
;
2065 /* If this is multipath, check all selected paths for any nexthop change
2067 * attribute change. Some attribute changes (e.g., community) aren't of
2068 * relevance to the RIB, but we'll update zebra to ensure we handle the
2069 * case of BGP nexthop change. This is the behavior when the best path
2071 * an attribute change anyway.
2073 if (CHECK_FLAG(selected
->flags
, BGP_INFO_IGP_CHANGED
)
2074 || CHECK_FLAG(selected
->flags
, BGP_INFO_MULTIPATH_CHG
))
2077 /* If this is multipath, check all selected paths for any nexthop change
2079 for (mpinfo
= bgp_info_mpath_first(selected
); mpinfo
;
2080 mpinfo
= bgp_info_mpath_next(mpinfo
)) {
2081 if (CHECK_FLAG(mpinfo
->flags
, BGP_INFO_IGP_CHANGED
)
2082 || CHECK_FLAG(mpinfo
->flags
, BGP_INFO_ATTR_CHANGED
))
2086 /* Nothing has changed from the RIB's perspective. */
2090 struct bgp_process_queue
{
2092 STAILQ_HEAD(, bgp_node
) pqueue
;
2093 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2095 unsigned int queued
;
2098 static void bgp_process_main_one(struct bgp
*bgp
, struct bgp_node
*rn
,
2099 afi_t afi
, safi_t safi
)
2101 struct prefix
*p
= &rn
->p
;
2102 struct bgp_info
*new_select
;
2103 struct bgp_info
*old_select
;
2104 struct bgp_info_pair old_and_new
;
2105 char pfx_buf
[PREFIX2STR_BUFFER
];
2108 /* Is it end of initial update? (after startup) */
2110 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
2111 sizeof(bgp
->update_delay_zebra_resume_time
));
2113 bgp
->main_zebra_update_hold
= 0;
2114 FOREACH_AFI_SAFI (afi
, safi
) {
2115 if (bgp_fibupd_safi(safi
))
2116 bgp_zebra_announce_table(bgp
, afi
, safi
);
2118 bgp
->main_peers_update_hold
= 0;
2120 bgp_start_routeadv(bgp
);
2124 debug
= bgp_debug_bestpath(&rn
->p
);
2126 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
2127 zlog_debug("%s: p=%s afi=%s, safi=%s start", __func__
, pfx_buf
,
2128 afi2str(afi
), safi2str(safi
));
2131 /* Best path selection. */
2132 bgp_best_selection(bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
,
2134 old_select
= old_and_new
.old
;
2135 new_select
= old_and_new
.new;
2137 /* Do we need to allocate or free labels?
2138 * Right now, since we only deal with per-prefix labels, it is not
2139 * necessary to do this upon changes to best path except if the label
2142 if (bgp
->allocate_mpls_labels
[afi
][safi
]) {
2145 || bgp_label_index_differs(new_select
, old_select
)
2146 || new_select
->sub_type
!= old_select
->sub_type
) {
2147 if (new_select
->sub_type
== BGP_ROUTE_STATIC
2148 && new_select
->attr
->flag
2150 BGP_ATTR_PREFIX_SID
)
2151 && new_select
->attr
->label_index
2152 != BGP_INVALID_LABEL_INDEX
) {
2155 BGP_NODE_REGISTERED_FOR_LABEL
))
2156 bgp_unregister_for_label(rn
);
2157 label_ntop(MPLS_LABEL_IMPLICIT_NULL
, 1,
2159 bgp_set_valid_label(&rn
->local_label
);
2161 bgp_register_for_label(rn
, new_select
);
2163 } else if (CHECK_FLAG(rn
->flags
,
2164 BGP_NODE_REGISTERED_FOR_LABEL
)) {
2165 bgp_unregister_for_label(rn
);
2167 } else if (CHECK_FLAG(rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
)) {
2168 bgp_unregister_for_label(rn
);
2172 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
2174 "%s: p=%s afi=%s, safi=%s, old_select=%p, new_select=%p",
2175 __func__
, pfx_buf
, afi2str(afi
), safi2str(safi
),
2176 old_select
, new_select
);
2179 /* If best route remains the same and this is not due to user-initiated
2180 * clear, see exactly what needs to be done.
2183 if (old_select
&& old_select
== new_select
2184 && !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
)
2185 && !CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
)
2186 && !bgp
->addpath_tx_used
[afi
][safi
]) {
2187 if (bgp_zebra_has_route_changed(rn
, old_select
)) {
2189 vnc_import_bgp_add_route(bgp
, p
, old_select
);
2190 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
2192 if (bgp_fibupd_safi(safi
)
2193 && !bgp_option_check(BGP_OPT_NO_FIB
)) {
2195 if (new_select
->type
== ZEBRA_ROUTE_BGP
2196 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
2197 || new_select
->sub_type
2198 == BGP_ROUTE_IMPORTED
))
2200 bgp_zebra_announce(rn
, p
, old_select
,
2204 UNSET_FLAG(old_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
2205 bgp_zebra_clear_route_change_flags(rn
);
2207 /* If there is a change of interest to peers, reannounce the
2209 if (CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
)
2210 || CHECK_FLAG(rn
->flags
, BGP_NODE_LABEL_CHANGED
)) {
2211 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2213 /* unicast routes must also be annouced to
2214 * labeled-unicast update-groups */
2215 if (safi
== SAFI_UNICAST
)
2216 group_announce_route(bgp
, afi
,
2217 SAFI_LABELED_UNICAST
, rn
,
2220 UNSET_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
);
2221 UNSET_FLAG(rn
->flags
, BGP_NODE_LABEL_CHANGED
);
2224 UNSET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2228 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2230 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
2232 /* bestpath has changed; bump version */
2233 if (old_select
|| new_select
) {
2234 bgp_bump_version(rn
);
2236 if (!bgp
->t_rmap_def_originate_eval
) {
2240 update_group_refresh_default_originate_route_map
,
2241 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
,
2242 &bgp
->t_rmap_def_originate_eval
);
2247 bgp_info_unset_flag(rn
, old_select
, BGP_INFO_SELECTED
);
2250 zlog_debug("%s: setting SELECTED flag", __func__
);
2251 bgp_info_set_flag(rn
, new_select
, BGP_INFO_SELECTED
);
2252 bgp_info_unset_flag(rn
, new_select
, BGP_INFO_ATTR_CHANGED
);
2253 UNSET_FLAG(new_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
2257 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2258 if (old_select
!= new_select
) {
2260 vnc_import_bgp_exterior_del_route(bgp
, p
,
2262 vnc_import_bgp_del_route(bgp
, p
, old_select
);
2265 vnc_import_bgp_exterior_add_route(bgp
, p
,
2267 vnc_import_bgp_add_route(bgp
, p
, new_select
);
2273 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2275 /* unicast routes must also be annouced to labeled-unicast update-groups
2277 if (safi
== SAFI_UNICAST
)
2278 group_announce_route(bgp
, afi
, SAFI_LABELED_UNICAST
, rn
,
2282 if (bgp_fibupd_safi(safi
) && (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
2283 && !bgp_option_check(BGP_OPT_NO_FIB
)) {
2284 if (new_select
&& new_select
->type
== ZEBRA_ROUTE_BGP
2285 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
2286 || new_select
->sub_type
== BGP_ROUTE_AGGREGATE
2287 || new_select
->sub_type
== BGP_ROUTE_IMPORTED
))
2289 bgp_zebra_announce(rn
, p
, new_select
, bgp
, afi
, safi
);
2291 /* Withdraw the route from the kernel. */
2292 if (old_select
&& old_select
->type
== ZEBRA_ROUTE_BGP
2293 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
2294 || old_select
->sub_type
== BGP_ROUTE_AGGREGATE
2295 || old_select
->sub_type
== BGP_ROUTE_IMPORTED
))
2297 bgp_zebra_withdraw(p
, old_select
, safi
);
2301 /* advertise/withdraw type-5 routes */
2302 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2303 if (advertise_type5_routes(bgp
, afi
) && new_select
&&
2304 (!new_select
->extra
|| !new_select
->extra
->parent
))
2305 bgp_evpn_advertise_type5_route(bgp
, &rn
->p
,
2308 else if (advertise_type5_routes(bgp
, afi
) && old_select
&&
2309 (!old_select
->extra
|| !old_select
->extra
->parent
))
2310 bgp_evpn_withdraw_type5_route(bgp
, &rn
->p
, afi
, safi
);
2313 /* Clear any route change flags. */
2314 bgp_zebra_clear_route_change_flags(rn
);
2316 /* Reap old select bgp_info, if it has been removed */
2317 if (old_select
&& CHECK_FLAG(old_select
->flags
, BGP_INFO_REMOVED
))
2318 bgp_info_reap(rn
, old_select
);
2320 UNSET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2324 static wq_item_status
bgp_process_wq(struct work_queue
*wq
, void *data
)
2326 struct bgp_process_queue
*pqnode
= data
;
2327 struct bgp
*bgp
= pqnode
->bgp
;
2328 struct bgp_table
*table
;
2329 struct bgp_node
*rn
;
2332 if (CHECK_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
)) {
2333 bgp_process_main_one(bgp
, NULL
, 0, 0);
2334 /* should always have dedicated wq call */
2335 assert(STAILQ_FIRST(&pqnode
->pqueue
) == NULL
);
2339 while (!STAILQ_EMPTY(&pqnode
->pqueue
)) {
2340 rn
= STAILQ_FIRST(&pqnode
->pqueue
);
2341 STAILQ_REMOVE_HEAD(&pqnode
->pqueue
, pq
);
2342 STAILQ_NEXT(rn
, pq
) = NULL
; /* complete unlink */
2343 table
= bgp_node_table(rn
);
2344 /* note, new RNs may be added as part of processing */
2345 bgp_process_main_one(bgp
, rn
, table
->afi
, table
->safi
);
2347 bgp_unlock_node(rn
);
2348 bgp_table_unlock(table
);
2354 static void bgp_processq_del(struct work_queue
*wq
, void *data
)
2356 struct bgp_process_queue
*pqnode
= data
;
2358 bgp_unlock(pqnode
->bgp
);
2360 XFREE(MTYPE_BGP_PROCESS_QUEUE
, pqnode
);
2363 void bgp_process_queue_init(void)
2365 if (!bm
->process_main_queue
) {
2366 bm
->process_main_queue
=
2367 work_queue_new(bm
->master
, "process_main_queue");
2369 if (!bm
->process_main_queue
) {
2370 zlog_err("%s: Failed to allocate work queue", __func__
);
2375 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_wq
;
2376 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2377 bm
->process_main_queue
->spec
.max_retries
= 0;
2378 bm
->process_main_queue
->spec
.hold
= 50;
2379 /* Use a higher yield value of 50ms for main queue processing */
2380 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2383 static struct bgp_process_queue
*bgp_processq_alloc(struct bgp
*bgp
)
2385 struct bgp_process_queue
*pqnode
;
2387 pqnode
= XCALLOC(MTYPE_BGP_PROCESS_QUEUE
,
2388 sizeof(struct bgp_process_queue
));
2390 /* unlocked in bgp_processq_del */
2391 pqnode
->bgp
= bgp_lock(bgp
);
2392 STAILQ_INIT(&pqnode
->pqueue
);
2397 void bgp_process(struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2399 #define ARBITRARY_PROCESS_QLEN 10000
2400 struct work_queue
*wq
= bm
->process_main_queue
;
2401 struct bgp_process_queue
*pqnode
;
2402 int pqnode_reuse
= 0;
2404 /* already scheduled for processing? */
2405 if (CHECK_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2411 /* Add route nodes to an existing work queue item until reaching the
2412 limit only if is from the same BGP view and it's not an EOIU marker
2414 if (work_queue_item_count(wq
)) {
2415 struct work_queue_item
*item
= work_queue_last_item(wq
);
2416 pqnode
= item
->data
;
2418 if (CHECK_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
)
2419 || pqnode
->bgp
!= bgp
2420 || pqnode
->queued
>= ARBITRARY_PROCESS_QLEN
)
2421 pqnode
= bgp_processq_alloc(bgp
);
2425 pqnode
= bgp_processq_alloc(bgp
);
2426 /* all unlocked in bgp_process_wq */
2427 bgp_table_lock(bgp_node_table(rn
));
2429 SET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2432 /* can't be enqueued twice */
2433 assert(STAILQ_NEXT(rn
, pq
) == NULL
);
2434 STAILQ_INSERT_TAIL(&pqnode
->pqueue
, rn
, pq
);
2438 work_queue_add(wq
, pqnode
);
2443 void bgp_add_eoiu_mark(struct bgp
*bgp
)
2445 struct bgp_process_queue
*pqnode
;
2447 if (bm
->process_main_queue
== NULL
)
2450 pqnode
= bgp_processq_alloc(bgp
);
2452 SET_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
);
2453 work_queue_add(bm
->process_main_queue
, pqnode
);
2456 static int bgp_maximum_prefix_restart_timer(struct thread
*thread
)
2460 peer
= THREAD_ARG(thread
);
2461 peer
->t_pmax_restart
= NULL
;
2463 if (bgp_debug_neighbor_events(peer
))
2465 "%s Maximum-prefix restart timer expired, restore peering",
2468 peer_clear(peer
, NULL
);
2473 int bgp_maximum_prefix_overflow(struct peer
*peer
, afi_t afi
, safi_t safi
,
2477 iana_safi_t pkt_safi
;
2479 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2482 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
]) {
2483 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2484 PEER_STATUS_PREFIX_LIMIT
)
2489 "%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2491 afi_safi_print(afi
, safi
), peer
->host
,
2492 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2493 SET_FLAG(peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2495 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
2496 PEER_FLAG_MAX_PREFIX_WARNING
))
2499 /* Convert AFI, SAFI to values for packet. */
2500 pkt_afi
= afi_int2iana(afi
);
2501 pkt_safi
= safi_int2iana(safi
);
2505 ndata
[0] = (pkt_afi
>> 8);
2507 ndata
[2] = pkt_safi
;
2508 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2509 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2510 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2511 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2513 SET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2514 bgp_notify_send_with_data(peer
, BGP_NOTIFY_CEASE
,
2515 BGP_NOTIFY_CEASE_MAX_PREFIX
,
2519 /* Dynamic peers will just close their connection. */
2520 if (peer_dynamic_neighbor(peer
))
2523 /* restart timer start */
2524 if (peer
->pmax_restart
[afi
][safi
]) {
2525 peer
->v_pmax_restart
=
2526 peer
->pmax_restart
[afi
][safi
] * 60;
2528 if (bgp_debug_neighbor_events(peer
))
2530 "%s Maximum-prefix restart timer started for %d secs",
2531 peer
->host
, peer
->v_pmax_restart
);
2533 BGP_TIMER_ON(peer
->t_pmax_restart
,
2534 bgp_maximum_prefix_restart_timer
,
2535 peer
->v_pmax_restart
);
2540 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2541 PEER_STATUS_PREFIX_LIMIT
);
2543 if (peer
->pcount
[afi
][safi
]
2544 > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100)) {
2545 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2546 PEER_STATUS_PREFIX_THRESHOLD
)
2551 "%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2552 afi_safi_print(afi
, safi
), peer
->host
,
2553 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2554 SET_FLAG(peer
->af_sflags
[afi
][safi
],
2555 PEER_STATUS_PREFIX_THRESHOLD
);
2557 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2558 PEER_STATUS_PREFIX_THRESHOLD
);
2562 /* Unconditionally remove the route from the RIB, without taking
2563 * damping into consideration (eg, because the session went down)
2565 void bgp_rib_remove(struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2566 afi_t afi
, safi_t safi
)
2568 bgp_aggregate_decrement(peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2570 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
2571 bgp_info_delete(rn
, ri
); /* keep historical info */
2573 bgp_process(peer
->bgp
, rn
, afi
, safi
);
2576 static void bgp_rib_withdraw(struct bgp_node
*rn
, struct bgp_info
*ri
,
2577 struct peer
*peer
, afi_t afi
, safi_t safi
,
2578 struct prefix_rd
*prd
)
2580 int status
= BGP_DAMP_NONE
;
2582 /* apply dampening, if result is suppressed, we'll be retaining
2583 * the bgp_info in the RIB for historical reference.
2585 if (CHECK_FLAG(peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2586 && peer
->sort
== BGP_PEER_EBGP
)
2587 if ((status
= bgp_damp_withdraw(ri
, rn
, afi
, safi
, 0))
2588 == BGP_DAMP_SUPPRESSED
) {
2589 bgp_aggregate_decrement(peer
->bgp
, &rn
->p
, ri
, afi
,
2595 if (safi
== SAFI_MPLS_VPN
) {
2596 struct bgp_node
*prn
= NULL
;
2597 struct bgp_table
*table
= NULL
;
2599 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
],
2600 (struct prefix
*)prd
);
2602 table
= (struct bgp_table
*)(prn
->info
);
2604 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2605 peer
->bgp
, prd
, table
, &rn
->p
, ri
);
2607 bgp_unlock_node(prn
);
2609 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2610 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
2612 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, ri
);
2613 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
,
2619 /* If this is an EVPN route, process for un-import. */
2620 if (safi
== SAFI_EVPN
)
2621 bgp_evpn_unimport_route(peer
->bgp
, afi
, safi
, &rn
->p
, ri
);
2623 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
2626 struct bgp_info
*info_make(int type
, int sub_type
, u_short instance
,
2627 struct peer
*peer
, struct attr
*attr
,
2628 struct bgp_node
*rn
)
2630 struct bgp_info
*new;
2632 /* Make new BGP info. */
2633 new = XCALLOC(MTYPE_BGP_ROUTE
, sizeof(struct bgp_info
));
2635 new->instance
= instance
;
2636 new->sub_type
= sub_type
;
2639 new->uptime
= bgp_clock();
2641 new->addpath_tx_id
= ++peer
->bgp
->addpath_tx_id
;
2645 static void overlay_index_update(struct attr
*attr
,
2646 struct eth_segment_id
*eth_s_id
,
2647 union gw_addr
*gw_ip
)
2652 if (eth_s_id
== NULL
) {
2653 memset(&(attr
->evpn_overlay
.eth_s_id
), 0,
2654 sizeof(struct eth_segment_id
));
2656 memcpy(&(attr
->evpn_overlay
.eth_s_id
), eth_s_id
,
2657 sizeof(struct eth_segment_id
));
2659 if (gw_ip
== NULL
) {
2660 memset(&(attr
->evpn_overlay
.gw_ip
), 0, sizeof(union gw_addr
));
2662 memcpy(&(attr
->evpn_overlay
.gw_ip
), gw_ip
,
2663 sizeof(union gw_addr
));
2667 static bool overlay_index_equal(afi_t afi
, struct bgp_info
*info
,
2668 struct eth_segment_id
*eth_s_id
,
2669 union gw_addr
*gw_ip
)
2671 struct eth_segment_id
*info_eth_s_id
, *info_eth_s_id_remote
;
2672 union gw_addr
*info_gw_ip
, *info_gw_ip_remote
;
2675 if (afi
!= AFI_L2VPN
)
2678 memset(&temp
, 0, 16);
2679 info_eth_s_id
= (struct eth_segment_id
*)&temp
;
2680 info_gw_ip
= (union gw_addr
*)&temp
;
2681 if (eth_s_id
== NULL
&& gw_ip
== NULL
)
2684 info_eth_s_id
= &(info
->attr
->evpn_overlay
.eth_s_id
);
2685 info_gw_ip
= &(info
->attr
->evpn_overlay
.gw_ip
);
2688 info_gw_ip_remote
= (union gw_addr
*)&temp
;
2690 info_gw_ip_remote
= gw_ip
;
2691 if (eth_s_id
== NULL
)
2692 info_eth_s_id_remote
= (struct eth_segment_id
*)&temp
;
2694 info_eth_s_id_remote
= eth_s_id
;
2695 if (!memcmp(info_gw_ip
, info_gw_ip_remote
, sizeof(union gw_addr
)))
2697 return !memcmp(info_eth_s_id
, info_eth_s_id_remote
,
2698 sizeof(struct eth_segment_id
));
2701 /* Check if received nexthop is valid or not. */
2702 static int bgp_update_martian_nexthop(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
2707 /* Only validated for unicast and multicast currently. */
2708 /* Also valid for EVPN where the nexthop is an IP address. */
2709 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
&& safi
!= SAFI_EVPN
)
2712 /* If NEXT_HOP is present, validate it. */
2713 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
)) {
2714 if (attr
->nexthop
.s_addr
== 0
2715 || IPV4_CLASS_DE(ntohl(attr
->nexthop
.s_addr
))
2716 || bgp_nexthop_self(bgp
, attr
->nexthop
))
2720 /* If MP_NEXTHOP is present, validate it. */
2721 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2722 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2723 * it is not an IPv6 link-local address.
2725 if (attr
->mp_nexthop_len
) {
2726 switch (attr
->mp_nexthop_len
) {
2727 case BGP_ATTR_NHLEN_IPV4
:
2728 case BGP_ATTR_NHLEN_VPNV4
:
2729 ret
= (attr
->mp_nexthop_global_in
.s_addr
== 0
2730 || IPV4_CLASS_DE(ntohl(
2731 attr
->mp_nexthop_global_in
.s_addr
))
2732 || bgp_nexthop_self(bgp
,
2733 attr
->mp_nexthop_global_in
));
2736 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2737 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2738 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2739 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attr
->mp_nexthop_global
)
2740 || IN6_IS_ADDR_LOOPBACK(&attr
->mp_nexthop_global
)
2741 || IN6_IS_ADDR_MULTICAST(
2742 &attr
->mp_nexthop_global
));
2754 int bgp_update(struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2755 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2756 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
2757 u_int32_t num_labels
, int soft_reconfig
,
2758 struct bgp_route_evpn
*evpn
)
2761 int aspath_loop_count
= 0;
2762 struct bgp_node
*rn
;
2764 struct attr new_attr
;
2765 struct attr
*attr_new
;
2766 struct bgp_info
*ri
;
2767 struct bgp_info
*new;
2768 struct bgp_info_extra
*extra
;
2770 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2772 int do_loop_check
= 1;
2773 int has_valid_label
= 0;
2775 int vnc_implicit_withdraw
= 0;
2779 memset(&new_attr
, 0, sizeof(struct attr
));
2780 new_attr
.label_index
= BGP_INVALID_LABEL_INDEX
;
2781 new_attr
.label
= MPLS_INVALID_LABEL
;
2784 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2785 /* TODO: Check to see if we can get rid of "is_valid_label" */
2786 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
2787 has_valid_label
= (num_labels
> 0) ? 1 : 0;
2789 has_valid_label
= bgp_is_valid_label(label
);
2791 /* When peer's soft reconfiguration enabled. Record input packet in
2794 && CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2795 && peer
!= bgp
->peer_self
)
2796 bgp_adj_in_set(rn
, peer
, attr
, addpath_id
);
2798 /* Check previously received route. */
2799 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2800 if (ri
->peer
== peer
&& ri
->type
== type
2801 && ri
->sub_type
== sub_type
2802 && ri
->addpath_rx_id
== addpath_id
)
2805 /* AS path local-as loop check. */
2806 if (peer
->change_local_as
) {
2807 if (peer
->allowas_in
[afi
][safi
])
2808 aspath_loop_count
= peer
->allowas_in
[afi
][safi
];
2809 else if (!CHECK_FLAG(peer
->flags
,
2810 PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2811 aspath_loop_count
= 1;
2813 if (aspath_loop_check(attr
->aspath
, peer
->change_local_as
)
2814 > aspath_loop_count
) {
2815 reason
= "as-path contains our own AS;";
2820 /* If the peer is configured for "allowas-in origin" and the last ASN in
2822 * as-path is our ASN then we do not need to call aspath_loop_check
2824 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2825 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2828 /* AS path loop check. */
2829 if (do_loop_check
) {
2830 if (aspath_loop_check(attr
->aspath
, bgp
->as
)
2831 > peer
->allowas_in
[afi
][safi
]
2832 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2833 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
)
2834 > peer
->allowas_in
[afi
][safi
])) {
2835 reason
= "as-path contains our own AS;";
2840 /* Route reflector originator ID check. */
2841 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)
2842 && IPV4_ADDR_SAME(&bgp
->router_id
, &attr
->originator_id
)) {
2843 reason
= "originator is us;";
2847 /* Route reflector cluster ID check. */
2848 if (bgp_cluster_filter(peer
, attr
)) {
2849 reason
= "reflected from the same cluster;";
2853 /* Apply incoming filter. */
2854 if (bgp_input_filter(peer
, p
, attr
, afi
, safi
) == FILTER_DENY
) {
2859 bgp_attr_dup(&new_attr
, attr
);
2861 /* Apply incoming route-map.
2862 * NB: new_attr may now contain newly allocated values from route-map
2864 * commands, so we need bgp_attr_flush in the error paths, until we
2866 * the attr (which takes over the memory references) */
2867 if (bgp_input_modifier(peer
, p
, &new_attr
, afi
, safi
, NULL
)
2869 reason
= "route-map;";
2870 bgp_attr_flush(&new_attr
);
2874 if (peer
->sort
== BGP_PEER_EBGP
) {
2876 /* If we receive the graceful-shutdown community from an eBGP
2877 * peer we must lower local-preference */
2878 if (new_attr
.community
2879 && community_include(new_attr
.community
, COMMUNITY_GSHUT
)) {
2880 new_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
2881 new_attr
.local_pref
= BGP_GSHUT_LOCAL_PREF
;
2883 /* If graceful-shutdown is configured then add the GSHUT
2884 * community to all paths received from eBGP peers */
2885 } else if (bgp_flag_check(peer
->bgp
,
2886 BGP_FLAG_GRACEFUL_SHUTDOWN
)) {
2887 bgp_attr_add_gshut_community(&new_attr
);
2891 /* next hop check. */
2892 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
)
2893 && bgp_update_martian_nexthop(bgp
, afi
, safi
, &new_attr
)) {
2894 reason
= "martian or self next-hop;";
2895 bgp_attr_flush(&new_attr
);
2899 attr_new
= bgp_attr_intern(&new_attr
);
2901 /* If the update is implicit withdraw. */
2903 ri
->uptime
= bgp_clock();
2904 same_attr
= attrhash_cmp(ri
->attr
, attr_new
);
2906 /* Same attribute comes in. */
2907 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)
2908 && attrhash_cmp(ri
->attr
, attr_new
)
2909 && (!has_valid_label
2910 || memcmp(&(bgp_info_extra_get(ri
))->label
, label
,
2911 num_labels
* sizeof(mpls_label_t
))
2913 && (overlay_index_equal(
2914 afi
, ri
, evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
2915 evpn
== NULL
? NULL
: &evpn
->gw_ip
))) {
2916 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
2917 BGP_CONFIG_DAMPENING
)
2918 && peer
->sort
== BGP_PEER_EBGP
2919 && CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
)) {
2920 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2921 bgp_debug_rdpfxpath2str(
2922 afi
, safi
, prd
, p
, label
,
2923 num_labels
, addpath_id
? 1 : 0,
2924 addpath_id
, pfx_buf
,
2926 zlog_debug("%s rcvd %s", peer
->host
,
2930 if (bgp_damp_update(ri
, rn
, afi
, safi
)
2931 != BGP_DAMP_SUPPRESSED
) {
2932 bgp_aggregate_increment(bgp
, p
, ri
, afi
,
2934 bgp_process(bgp
, rn
, afi
, safi
);
2936 } else /* Duplicate - odd */
2938 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2939 if (!peer
->rcvd_attr_printed
) {
2941 "%s rcvd UPDATE w/ attr: %s",
2943 peer
->rcvd_attr_str
);
2944 peer
->rcvd_attr_printed
= 1;
2947 bgp_debug_rdpfxpath2str(
2948 afi
, safi
, prd
, p
, label
,
2949 num_labels
, addpath_id
? 1 : 0,
2950 addpath_id
, pfx_buf
,
2953 "%s rcvd %s...duplicate ignored",
2954 peer
->host
, pfx_buf
);
2957 /* graceful restart STALE flag unset. */
2958 if (CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
)) {
2959 bgp_info_unset_flag(rn
, ri
,
2961 bgp_process(bgp
, rn
, afi
, safi
);
2965 bgp_unlock_node(rn
);
2966 bgp_attr_unintern(&attr_new
);
2971 /* Withdraw/Announce before we fully processed the withdraw */
2972 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
2973 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2974 bgp_debug_rdpfxpath2str(
2975 afi
, safi
, prd
, p
, label
, num_labels
,
2976 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
2979 "%s rcvd %s, flapped quicker than processing",
2980 peer
->host
, pfx_buf
);
2983 bgp_info_restore(rn
, ri
);
2986 /* Received Logging. */
2987 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2988 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
,
2989 num_labels
, addpath_id
? 1 : 0,
2990 addpath_id
, pfx_buf
,
2992 zlog_debug("%s rcvd %s", peer
->host
, pfx_buf
);
2995 /* graceful restart STALE flag unset. */
2996 if (CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
))
2997 bgp_info_unset_flag(rn
, ri
, BGP_INFO_STALE
);
2999 /* The attribute is changed. */
3000 bgp_info_set_flag(rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3002 /* implicit withdraw, decrement aggregate and pcount here.
3003 * only if update is accepted, they'll increment below.
3005 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
3007 /* Update bgp route dampening information. */
3008 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
3009 && peer
->sort
== BGP_PEER_EBGP
) {
3010 /* This is implicit withdraw so we should update
3013 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
3014 bgp_damp_withdraw(ri
, rn
, afi
, safi
, 1);
3017 if (safi
== SAFI_MPLS_VPN
) {
3018 struct bgp_node
*prn
= NULL
;
3019 struct bgp_table
*table
= NULL
;
3021 prn
= bgp_node_get(bgp
->rib
[afi
][safi
],
3022 (struct prefix
*)prd
);
3024 table
= (struct bgp_table
*)(prn
->info
);
3026 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3027 bgp
, prd
, table
, p
, ri
);
3029 bgp_unlock_node(prn
);
3031 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3032 && (safi
== SAFI_UNICAST
)) {
3033 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
3035 * Implicit withdraw case.
3037 ++vnc_implicit_withdraw
;
3038 vnc_import_bgp_del_route(bgp
, p
, ri
);
3039 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
3044 /* Special handling for EVPN update of an existing route. If the
3045 * extended community attribute has changed, we need to
3047 * the route using its existing extended community. It will be
3048 * subsequently processed for import with the new extended
3051 if (safi
== SAFI_EVPN
&& !same_attr
) {
3053 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
3055 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))) {
3058 cmp
= ecommunity_cmp(ri
->attr
->ecommunity
,
3059 attr_new
->ecommunity
);
3061 if (bgp_debug_update(peer
, p
, NULL
, 1))
3063 "Change in EXT-COMM, existing %s new %s",
3065 ri
->attr
->ecommunity
),
3067 attr_new
->ecommunity
));
3068 bgp_evpn_unimport_route(bgp
, afi
, safi
,
3074 /* Update to new attribute. */
3075 bgp_attr_unintern(&ri
->attr
);
3076 ri
->attr
= attr_new
;
3078 /* Update MPLS label */
3079 if (has_valid_label
) {
3080 extra
= bgp_info_extra_get(ri
);
3081 memcpy(&extra
->label
, label
,
3082 num_labels
* sizeof(mpls_label_t
));
3083 extra
->num_labels
= num_labels
;
3084 if (!(afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
))
3085 bgp_set_valid_label(&extra
->label
[0]);
3089 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3090 && (safi
== SAFI_UNICAST
)) {
3091 if (vnc_implicit_withdraw
) {
3093 * Add back the route with its new attributes
3095 * The route is still selected, until the route
3097 * queued by bgp_process actually runs. We have
3099 * update to the VNC side immediately to avoid
3101 * configuration changes (e.g., route-map
3103 * trigger re-importation of the entire RIB.
3105 vnc_import_bgp_add_route(bgp
, p
, ri
);
3106 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
3110 /* Update Overlay Index */
3111 if (afi
== AFI_L2VPN
) {
3112 overlay_index_update(
3113 ri
->attr
, evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3114 evpn
== NULL
? NULL
: &evpn
->gw_ip
);
3117 /* Update bgp route dampening information. */
3118 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
3119 && peer
->sort
== BGP_PEER_EBGP
) {
3120 /* Now we do normal update dampening. */
3121 ret
= bgp_damp_update(ri
, rn
, afi
, safi
);
3122 if (ret
== BGP_DAMP_SUPPRESSED
) {
3123 bgp_unlock_node(rn
);
3128 /* Nexthop reachability check - for unicast and
3129 * labeled-unicast.. */
3130 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3131 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
3132 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1
3133 && !CHECK_FLAG(peer
->flags
,
3134 PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3136 bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
3141 if (bgp_find_or_add_nexthop(bgp
, afi
, ri
, NULL
,
3143 || CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
))
3144 bgp_info_set_flag(rn
, ri
, BGP_INFO_VALID
);
3146 if (BGP_DEBUG(nht
, NHT
)) {
3147 char buf1
[INET6_ADDRSTRLEN
];
3149 (const void *)&attr_new
3151 buf1
, INET6_ADDRSTRLEN
);
3152 zlog_debug("%s(%s): NH unresolved",
3153 __FUNCTION__
, buf1
);
3155 bgp_info_unset_flag(rn
, ri
, BGP_INFO_VALID
);
3158 bgp_info_set_flag(rn
, ri
, BGP_INFO_VALID
);
3161 if (safi
== SAFI_MPLS_VPN
) {
3162 struct bgp_node
*prn
= NULL
;
3163 struct bgp_table
*table
= NULL
;
3165 prn
= bgp_node_get(bgp
->rib
[afi
][safi
],
3166 (struct prefix
*)prd
);
3168 table
= (struct bgp_table
*)(prn
->info
);
3170 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3171 bgp
, prd
, table
, p
, ri
);
3173 bgp_unlock_node(prn
);
3177 /* If this is an EVPN route and some attribute has changed,
3179 * route for import. If the extended community has changed, we
3181 * have done the un-import earlier and the import would result
3183 * route getting injected into appropriate L2 VNIs. If it is
3185 * some other attribute change, the import will result in
3187 * the attributes for the route in the VNI(s).
3189 if (safi
== SAFI_EVPN
&& !same_attr
)
3190 bgp_evpn_import_route(bgp
, afi
, safi
, p
, ri
);
3192 /* Process change. */
3193 bgp_aggregate_increment(bgp
, p
, ri
, afi
, safi
);
3195 bgp_process(bgp
, rn
, afi
, safi
);
3196 bgp_unlock_node(rn
);
3198 if (SAFI_UNICAST
== safi
3199 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3200 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3202 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, ri
);
3204 if ((SAFI_MPLS_VPN
== safi
)
3205 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3207 vpn_leak_to_vrf_update(bgp
, ri
);
3211 if (SAFI_MPLS_VPN
== safi
) {
3212 mpls_label_t label_decoded
= decode_label(label
);
3214 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
,
3215 type
, sub_type
, &label_decoded
);
3217 if (SAFI_ENCAP
== safi
) {
3218 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
,
3219 type
, sub_type
, NULL
);
3224 } // End of implicit withdraw
3226 /* Received Logging. */
3227 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3228 if (!peer
->rcvd_attr_printed
) {
3229 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
3230 peer
->rcvd_attr_str
);
3231 peer
->rcvd_attr_printed
= 1;
3234 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3235 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3237 zlog_debug("%s rcvd %s", peer
->host
, pfx_buf
);
3240 /* Make new BGP info. */
3241 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
3243 /* Update MPLS label */
3244 if (has_valid_label
) {
3245 extra
= bgp_info_extra_get(new);
3246 memcpy(&extra
->label
, label
, num_labels
* sizeof(mpls_label_t
));
3247 extra
->num_labels
= num_labels
;
3248 if (!(afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
))
3249 bgp_set_valid_label(&extra
->label
[0]);
3252 /* Update Overlay Index */
3253 if (afi
== AFI_L2VPN
) {
3254 overlay_index_update(new->attr
,
3255 evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3256 evpn
== NULL
? NULL
: &evpn
->gw_ip
);
3258 /* Nexthop reachability check. */
3259 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3260 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
3261 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1
3262 && !CHECK_FLAG(peer
->flags
,
3263 PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3264 && !bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
3269 if (bgp_find_or_add_nexthop(bgp
, afi
, new, NULL
, connected
)
3270 || CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
))
3271 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
3273 if (BGP_DEBUG(nht
, NHT
)) {
3274 char buf1
[INET6_ADDRSTRLEN
];
3276 (const void *)&attr_new
->nexthop
,
3277 buf1
, INET6_ADDRSTRLEN
);
3278 zlog_debug("%s(%s): NH unresolved",
3279 __FUNCTION__
, buf1
);
3281 bgp_info_unset_flag(rn
, new, BGP_INFO_VALID
);
3284 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
3287 new->addpath_rx_id
= addpath_id
;
3289 /* Increment prefix */
3290 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
3292 /* Register new BGP information. */
3293 bgp_info_add(rn
, new);
3295 /* route_node_get lock */
3296 bgp_unlock_node(rn
);
3299 if (safi
== SAFI_MPLS_VPN
) {
3300 struct bgp_node
*prn
= NULL
;
3301 struct bgp_table
*table
= NULL
;
3303 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*)prd
);
3305 table
= (struct bgp_table
*)(prn
->info
);
3307 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3308 bgp
, prd
, table
, p
, new);
3310 bgp_unlock_node(prn
);
3314 /* If maximum prefix count is configured and current prefix
3316 if (bgp_maximum_prefix_overflow(peer
, afi
, safi
, 0))
3319 /* If this is an EVPN route, process for import. */
3320 if (safi
== SAFI_EVPN
)
3321 bgp_evpn_import_route(bgp
, afi
, safi
, p
, new);
3323 /* Process change. */
3324 bgp_process(bgp
, rn
, afi
, safi
);
3326 if (SAFI_UNICAST
== safi
3327 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3328 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3329 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
3331 if ((SAFI_MPLS_VPN
== safi
)
3332 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3334 vpn_leak_to_vrf_update(bgp
, new);
3337 if (SAFI_MPLS_VPN
== safi
) {
3338 mpls_label_t label_decoded
= decode_label(label
);
3340 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
,
3341 sub_type
, &label_decoded
);
3343 if (SAFI_ENCAP
== safi
) {
3344 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
,
3351 /* This BGP update is filtered. Log the reason then update BGP
3354 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3355 if (!peer
->rcvd_attr_printed
) {
3356 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
3357 peer
->rcvd_attr_str
);
3358 peer
->rcvd_attr_printed
= 1;
3361 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3362 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3364 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
3365 peer
->host
, pfx_buf
, reason
);
3369 /* If this is an EVPN route, un-import it as it is now filtered.
3371 if (safi
== SAFI_EVPN
)
3372 bgp_evpn_unimport_route(bgp
, afi
, safi
, p
, ri
);
3374 if (SAFI_UNICAST
== safi
3375 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3376 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3378 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, ri
);
3380 if ((SAFI_MPLS_VPN
== safi
)
3381 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3383 vpn_leak_to_vrf_withdraw(bgp
, ri
);
3386 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
3389 bgp_unlock_node(rn
);
3393 * Filtered update is treated as an implicit withdrawal (see
3395 * a few lines above)
3397 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
)) {
3398 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
,
3406 int bgp_withdraw(struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
3407 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
3408 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
3409 u_int32_t num_labels
, struct bgp_route_evpn
*evpn
)
3412 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
3413 struct bgp_node
*rn
;
3414 struct bgp_info
*ri
;
3417 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
)) {
3418 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
,
3426 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3428 /* If peer is soft reconfiguration enabled. Record input packet for
3429 * further calculation.
3431 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
3432 * routes that are filtered. This tanks out Quagga RS pretty badly due
3434 * the iteration over all RS clients.
3435 * Since we need to remove the entry from adj_in anyway, do that first
3437 * if there was no entry, we don't need to do anything more.
3439 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
3440 && peer
!= bgp
->peer_self
)
3441 if (!bgp_adj_in_unset(rn
, peer
, addpath_id
)) {
3442 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3443 bgp_debug_rdpfxpath2str(
3444 afi
, safi
, prd
, p
, label
, num_labels
,
3445 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3448 "%s withdrawing route %s not in adj-in",
3449 peer
->host
, pfx_buf
);
3451 bgp_unlock_node(rn
);
3455 /* Lookup withdrawn route. */
3456 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3457 if (ri
->peer
== peer
&& ri
->type
== type
3458 && ri
->sub_type
== sub_type
3459 && ri
->addpath_rx_id
== addpath_id
)
3463 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3464 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3465 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3467 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer
->host
,
3471 /* Withdraw specified route from routing table. */
3472 if (ri
&& !CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
)) {
3473 bgp_rib_withdraw(rn
, ri
, peer
, afi
, safi
, prd
);
3474 if (SAFI_UNICAST
== safi
3475 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3476 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3477 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, ri
);
3479 if ((SAFI_MPLS_VPN
== safi
)
3480 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3482 vpn_leak_to_vrf_withdraw(bgp
, ri
);
3484 } else if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3485 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3486 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3488 zlog_debug("%s Can't find the route %s", peer
->host
, pfx_buf
);
3491 /* Unlock bgp_node_get() lock. */
3492 bgp_unlock_node(rn
);
3497 void bgp_default_originate(struct peer
*peer
, afi_t afi
, safi_t safi
,
3500 struct update_subgroup
*subgrp
;
3501 subgrp
= peer_subgroup(peer
, afi
, safi
);
3502 subgroup_default_originate(subgrp
, withdraw
);
3507 * bgp_stop_announce_route_timer
3509 void bgp_stop_announce_route_timer(struct peer_af
*paf
)
3511 if (!paf
->t_announce_route
)
3514 THREAD_TIMER_OFF(paf
->t_announce_route
);
3518 * bgp_announce_route_timer_expired
3520 * Callback that is invoked when the route announcement timer for a
3523 static int bgp_announce_route_timer_expired(struct thread
*t
)
3525 struct peer_af
*paf
;
3528 paf
= THREAD_ARG(t
);
3531 if (peer
->status
!= Established
)
3534 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
3537 peer_af_announce_route(paf
, 1);
3542 * bgp_announce_route
3544 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3546 void bgp_announce_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3548 struct peer_af
*paf
;
3549 struct update_subgroup
*subgrp
;
3551 paf
= peer_af_find(peer
, afi
, safi
);
3554 subgrp
= PAF_SUBGRP(paf
);
3557 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3558 * or a refresh has already been triggered.
3560 if (!subgrp
|| paf
->t_announce_route
)
3564 * Start a timer to stagger/delay the announce. This serves
3565 * two purposes - announcement can potentially be combined for
3566 * multiple peers and the announcement doesn't happen in the
3569 thread_add_timer_msec(bm
->master
, bgp_announce_route_timer_expired
, paf
,
3570 (subgrp
->peer_count
== 1)
3571 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
3572 : BGP_ANNOUNCE_ROUTE_DELAY_MS
,
3573 &paf
->t_announce_route
);
3577 * Announce routes from all AF tables to a peer.
3579 * This should ONLY be called when there is a need to refresh the
3580 * routes to the peer based on a policy change for this peer alone
3581 * or a route refresh request received from the peer.
3582 * The operation will result in splitting the peer from its existing
3583 * subgroups and putting it in new subgroups.
3585 void bgp_announce_route_all(struct peer
*peer
)
3590 FOREACH_AFI_SAFI (afi
, safi
)
3591 bgp_announce_route(peer
, afi
, safi
);
3594 static void bgp_soft_reconfig_table(struct peer
*peer
, afi_t afi
, safi_t safi
,
3595 struct bgp_table
*table
,
3596 struct prefix_rd
*prd
)
3599 struct bgp_node
*rn
;
3600 struct bgp_adj_in
*ain
;
3603 table
= peer
->bgp
->rib
[afi
][safi
];
3605 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
3606 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
) {
3607 if (ain
->peer
!= peer
)
3610 struct bgp_info
*ri
= rn
->info
;
3611 u_int32_t num_labels
= 0;
3612 mpls_label_t
*label_pnt
= NULL
;
3614 if (ri
&& ri
->extra
)
3615 num_labels
= ri
->extra
->num_labels
;
3617 label_pnt
= &ri
->extra
->label
[0];
3619 ret
= bgp_update(peer
, &rn
->p
, ain
->addpath_rx_id
,
3620 ain
->attr
, afi
, safi
, ZEBRA_ROUTE_BGP
,
3621 BGP_ROUTE_NORMAL
, prd
, label_pnt
,
3622 num_labels
, 1, NULL
);
3625 bgp_unlock_node(rn
);
3631 void bgp_soft_reconfig_in(struct peer
*peer
, afi_t afi
, safi_t safi
)
3633 struct bgp_node
*rn
;
3634 struct bgp_table
*table
;
3636 if (peer
->status
!= Established
)
3639 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
)
3640 && (safi
!= SAFI_EVPN
))
3641 bgp_soft_reconfig_table(peer
, afi
, safi
, NULL
, NULL
);
3643 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3644 rn
= bgp_route_next(rn
))
3645 if ((table
= rn
->info
) != NULL
) {
3646 struct prefix_rd prd
;
3647 prd
.family
= AF_UNSPEC
;
3649 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3651 bgp_soft_reconfig_table(peer
, afi
, safi
, table
,
3657 struct bgp_clear_node_queue
{
3658 struct bgp_node
*rn
;
3661 static wq_item_status
bgp_clear_route_node(struct work_queue
*wq
, void *data
)
3663 struct bgp_clear_node_queue
*cnq
= data
;
3664 struct bgp_node
*rn
= cnq
->rn
;
3665 struct peer
*peer
= wq
->spec
.data
;
3666 struct bgp_info
*ri
;
3667 afi_t afi
= bgp_node_table(rn
)->afi
;
3668 safi_t safi
= bgp_node_table(rn
)->safi
;
3672 /* It is possible that we have multiple paths for a prefix from a peer
3673 * if that peer is using AddPath.
3675 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
3676 if (ri
->peer
!= peer
)
3679 /* graceful restart STALE flag set. */
3680 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3681 && peer
->nsf
[afi
][safi
]
3682 && !CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
)
3683 && !CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
3684 bgp_info_set_flag(rn
, ri
, BGP_INFO_STALE
);
3686 /* If this is an EVPN route, process for
3688 if (safi
== SAFI_EVPN
)
3689 bgp_evpn_unimport_route(peer
->bgp
, afi
, safi
,
3691 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
3697 static void bgp_clear_node_queue_del(struct work_queue
*wq
, void *data
)
3699 struct bgp_clear_node_queue
*cnq
= data
;
3700 struct bgp_node
*rn
= cnq
->rn
;
3701 struct bgp_table
*table
= bgp_node_table(rn
);
3703 bgp_unlock_node(rn
);
3704 bgp_table_unlock(table
);
3705 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3708 static void bgp_clear_node_complete(struct work_queue
*wq
)
3710 struct peer
*peer
= wq
->spec
.data
;
3712 /* Tickle FSM to start moving again */
3713 BGP_EVENT_ADD(peer
, Clearing_Completed
);
3715 peer_unlock(peer
); /* bgp_clear_route */
3718 static void bgp_clear_node_queue_init(struct peer
*peer
)
3720 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3722 snprintf(wname
, sizeof(wname
), "clear %s", peer
->host
);
3723 #undef CLEAR_QUEUE_NAME_LEN
3725 if ((peer
->clear_node_queue
= work_queue_new(bm
->master
, wname
))
3727 zlog_err("%s: Failed to allocate work queue", __func__
);
3730 peer
->clear_node_queue
->spec
.hold
= 10;
3731 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3732 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3733 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3734 peer
->clear_node_queue
->spec
.max_retries
= 0;
3736 /* we only 'lock' this peer reference when the queue is actually active
3738 peer
->clear_node_queue
->spec
.data
= peer
;
3741 static void bgp_clear_route_table(struct peer
*peer
, afi_t afi
, safi_t safi
,
3742 struct bgp_table
*table
)
3744 struct bgp_node
*rn
;
3745 int force
= bm
->process_main_queue
? 0 : 1;
3748 table
= peer
->bgp
->rib
[afi
][safi
];
3750 /* If still no table => afi/safi isn't configured at all or smth. */
3754 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
3755 struct bgp_info
*ri
, *next
;
3756 struct bgp_adj_in
*ain
;
3757 struct bgp_adj_in
*ain_next
;
3759 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3760 * queued for every clearing peer, regardless of whether it is
3761 * relevant to the peer at hand.
3763 * Overview: There are 3 different indices which need to be
3764 * scrubbed, potentially, when a peer is removed:
3766 * 1 peer's routes visible via the RIB (ie accepted routes)
3767 * 2 peer's routes visible by the (optional) peer's adj-in index
3768 * 3 other routes visible by the peer's adj-out index
3770 * 3 there is no hurry in scrubbing, once the struct peer is
3771 * removed from bgp->peer, we could just GC such deleted peer's
3772 * adj-outs at our leisure.
3774 * 1 and 2 must be 'scrubbed' in some way, at least made
3775 * invisible via RIB index before peer session is allowed to be
3776 * brought back up. So one needs to know when such a 'search' is
3781 * - there'd be a single global queue or a single RIB walker
3782 * - rather than tracking which route_nodes still need to be
3783 * examined on a peer basis, we'd track which peers still
3786 * Given that our per-peer prefix-counts now should be reliable,
3787 * this may actually be achievable. It doesn't seem to be a huge
3788 * problem at this time,
3790 * It is possible that we have multiple paths for a prefix from
3792 * if that peer is using AddPath.
3796 ain_next
= ain
->next
;
3798 if (ain
->peer
== peer
) {
3799 bgp_adj_in_remove(rn
, ain
);
3800 bgp_unlock_node(rn
);
3806 for (ri
= rn
->info
; ri
; ri
= next
) {
3808 if (ri
->peer
!= peer
)
3812 bgp_info_reap(rn
, ri
);
3814 struct bgp_clear_node_queue
*cnq
;
3816 /* both unlocked in bgp_clear_node_queue_del */
3817 bgp_table_lock(bgp_node_table(rn
));
3820 MTYPE_BGP_CLEAR_NODE_QUEUE
,
3821 sizeof(struct bgp_clear_node_queue
));
3823 work_queue_add(peer
->clear_node_queue
, cnq
);
3831 void bgp_clear_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3833 struct bgp_node
*rn
;
3834 struct bgp_table
*table
;
3836 if (peer
->clear_node_queue
== NULL
)
3837 bgp_clear_node_queue_init(peer
);
3839 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3840 * Idle until it receives a Clearing_Completed event. This protects
3841 * against peers which flap faster than we can we clear, which could
3844 * a) race with routes from the new session being installed before
3845 * clear_route_node visits the node (to delete the route of that
3847 * b) resource exhaustion, clear_route_node likely leads to an entry
3848 * on the process_main queue. Fast-flapping could cause that queue
3852 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3853 * the unlock will happen upon work-queue completion; other wise, the
3854 * unlock happens at the end of this function.
3856 if (!peer
->clear_node_queue
->thread
)
3859 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
&& safi
!= SAFI_EVPN
)
3860 bgp_clear_route_table(peer
, afi
, safi
, NULL
);
3862 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3863 rn
= bgp_route_next(rn
))
3864 if ((table
= rn
->info
) != NULL
)
3865 bgp_clear_route_table(peer
, afi
, safi
, table
);
3867 /* unlock if no nodes got added to the clear-node-queue. */
3868 if (!peer
->clear_node_queue
->thread
)
3872 void bgp_clear_route_all(struct peer
*peer
)
3877 FOREACH_AFI_SAFI (afi
, safi
)
3878 bgp_clear_route(peer
, afi
, safi
);
3881 rfapiProcessPeerDown(peer
);
3885 void bgp_clear_adj_in(struct peer
*peer
, afi_t afi
, safi_t safi
)
3887 struct bgp_table
*table
;
3888 struct bgp_node
*rn
;
3889 struct bgp_adj_in
*ain
;
3890 struct bgp_adj_in
*ain_next
;
3892 table
= peer
->bgp
->rib
[afi
][safi
];
3894 /* It is possible that we have multiple paths for a prefix from a peer
3895 * if that peer is using AddPath.
3897 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
3901 ain_next
= ain
->next
;
3903 if (ain
->peer
== peer
) {
3904 bgp_adj_in_remove(rn
, ain
);
3905 bgp_unlock_node(rn
);
3913 void bgp_clear_stale_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3915 struct bgp_node
*rn
;
3916 struct bgp_info
*ri
;
3917 struct bgp_table
*table
;
3919 if (safi
== SAFI_MPLS_VPN
) {
3920 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3921 rn
= bgp_route_next(rn
)) {
3922 struct bgp_node
*rm
;
3923 struct bgp_info
*ri
;
3925 /* look for neighbor in tables */
3926 if ((table
= rn
->info
) == NULL
)
3929 for (rm
= bgp_table_top(table
); rm
;
3930 rm
= bgp_route_next(rm
))
3931 for (ri
= rm
->info
; ri
; ri
= ri
->next
) {
3932 if (ri
->peer
!= peer
)
3934 if (!CHECK_FLAG(ri
->flags
,
3938 bgp_rib_remove(rm
, ri
, peer
, afi
, safi
);
3943 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3944 rn
= bgp_route_next(rn
))
3945 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
3946 if (ri
->peer
!= peer
)
3948 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
))
3950 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
3956 static void bgp_cleanup_table(struct bgp_table
*table
, safi_t safi
)
3958 struct bgp_node
*rn
;
3959 struct bgp_info
*ri
;
3960 struct bgp_info
*next
;
3962 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
3963 for (ri
= rn
->info
; ri
; ri
= next
) {
3965 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)
3966 && ri
->type
== ZEBRA_ROUTE_BGP
3967 && (ri
->sub_type
== BGP_ROUTE_NORMAL
3968 || ri
->sub_type
== BGP_ROUTE_AGGREGATE
3969 || ri
->sub_type
== BGP_ROUTE_IMPORTED
)) {
3971 if (bgp_fibupd_safi(safi
))
3972 bgp_zebra_withdraw(&rn
->p
, ri
, safi
);
3973 bgp_info_reap(rn
, ri
);
3978 /* Delete all kernel routes. */
3979 void bgp_cleanup_routes(struct bgp
*bgp
)
3982 struct bgp_node
*rn
;
3984 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
3985 if (afi
== AFI_L2VPN
)
3987 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3989 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
3991 if (afi
!= AFI_L2VPN
) {
3993 safi
= SAFI_MPLS_VPN
;
3994 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3995 rn
= bgp_route_next(rn
)) {
3998 (struct bgp_table
*)(rn
->info
),
4000 bgp_table_finish((struct bgp_table
**)&(
4003 bgp_unlock_node(rn
);
4007 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
4008 rn
= bgp_route_next(rn
)) {
4011 (struct bgp_table
*)(rn
->info
),
4013 bgp_table_finish((struct bgp_table
**)&(
4016 bgp_unlock_node(rn
);
4021 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
4022 rn
= bgp_route_next(rn
)) {
4024 bgp_cleanup_table((struct bgp_table
*)(rn
->info
),
4026 bgp_table_finish((struct bgp_table
**)&(rn
->info
));
4028 bgp_unlock_node(rn
);
4033 void bgp_reset(void)
4036 bgp_zclient_reset();
4037 access_list_reset();
4038 prefix_list_reset();
4041 static int bgp_addpath_encode_rx(struct peer
*peer
, afi_t afi
, safi_t safi
)
4043 return (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
4044 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
4045 PEER_CAP_ADDPATH_AF_TX_RCV
));
4048 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
4050 int bgp_nlri_parse_ip(struct peer
*peer
, struct attr
*attr
,
4051 struct bgp_nlri
*packet
)
4060 int addpath_encoded
;
4061 u_int32_t addpath_id
;
4063 /* Check peer status. */
4064 if (peer
->status
!= Established
)
4068 lim
= pnt
+ packet
->length
;
4070 safi
= packet
->safi
;
4072 addpath_encoded
= bgp_addpath_encode_rx(peer
, afi
, safi
);
4074 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
4075 syntactic validity. If the field is syntactically incorrect,
4076 then the Error Subcode is set to Invalid Network Field. */
4077 for (; pnt
< lim
; pnt
+= psize
) {
4078 /* Clear prefix structure. */
4079 memset(&p
, 0, sizeof(struct prefix
));
4081 if (addpath_encoded
) {
4083 /* When packet overflow occurs return immediately. */
4084 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
4087 addpath_id
= ntohl(*((uint32_t *)pnt
));
4088 pnt
+= BGP_ADDPATH_ID_LEN
;
4091 /* Fetch prefix length. */
4092 p
.prefixlen
= *pnt
++;
4093 /* afi/safi validity already verified by caller,
4094 * bgp_update_receive */
4095 p
.family
= afi2family(afi
);
4097 /* Prefix length check. */
4098 if (p
.prefixlen
> prefix_blen(&p
) * 8) {
4100 "%s [Error] Update packet error (wrong perfix length %d for afi %u)",
4101 peer
->host
, p
.prefixlen
, packet
->afi
);
4105 /* Packet size overflow check. */
4106 psize
= PSIZE(p
.prefixlen
);
4108 /* When packet overflow occur return immediately. */
4109 if (pnt
+ psize
> lim
) {
4111 "%s [Error] Update packet error (prefix length %d overflows packet)",
4112 peer
->host
, p
.prefixlen
);
4116 /* Defensive coding, double-check the psize fits in a struct
4118 if (psize
> (ssize_t
)sizeof(p
.u
)) {
4120 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
4121 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
4125 /* Fetch prefix from NLRI packet. */
4126 memcpy(&p
.u
.prefix
, pnt
, psize
);
4128 /* Check address. */
4129 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
) {
4130 if (IN_CLASSD(ntohl(p
.u
.prefix4
.s_addr
))) {
4131 /* From RFC4271 Section 6.3:
4133 * If a prefix in the NLRI field is semantically
4135 * (e.g., an unexpected multicast IP address),
4137 * be logged locally, and the prefix SHOULD be
4141 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
4142 peer
->host
, inet_ntoa(p
.u
.prefix4
));
4147 /* Check address. */
4148 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
) {
4149 if (IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
4153 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
4155 inet_ntop(AF_INET6
, &p
.u
.prefix6
, buf
,
4160 if (IN6_IS_ADDR_MULTICAST(&p
.u
.prefix6
)) {
4164 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
4166 inet_ntop(AF_INET6
, &p
.u
.prefix6
, buf
,
4173 /* Normal process. */
4175 ret
= bgp_update(peer
, &p
, addpath_id
, attr
, afi
, safi
,
4176 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
4177 NULL
, NULL
, 0, 0, NULL
);
4179 ret
= bgp_withdraw(peer
, &p
, addpath_id
, attr
, afi
,
4180 safi
, ZEBRA_ROUTE_BGP
,
4181 BGP_ROUTE_NORMAL
, NULL
, NULL
, 0,
4184 /* Address family configuration mismatch or maximum-prefix count
4190 /* Packet length consistency check. */
4193 "%s [Error] Update packet error (prefix length mismatch with total length)",
4201 static struct bgp_static
*bgp_static_new(void)
4203 return XCALLOC(MTYPE_BGP_STATIC
, sizeof(struct bgp_static
));
4206 static void bgp_static_free(struct bgp_static
*bgp_static
)
4208 if (bgp_static
->rmap
.name
)
4209 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4210 if (bgp_static
->eth_s_id
)
4211 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
4212 XFREE(MTYPE_BGP_STATIC
, bgp_static
);
4215 void bgp_static_update(struct bgp
*bgp
, struct prefix
*p
,
4216 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
4218 struct bgp_node
*rn
;
4219 struct bgp_info
*ri
;
4220 struct bgp_info
*new;
4221 struct bgp_info info
;
4223 struct attr
*attr_new
;
4226 int vnc_implicit_withdraw
= 0;
4233 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4235 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
4237 attr
.nexthop
= bgp_static
->igpnexthop
;
4238 attr
.med
= bgp_static
->igpmetric
;
4239 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
4241 if (bgp_static
->atomic
)
4242 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
);
4244 /* Store label index, if required. */
4245 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
) {
4246 attr
.label_index
= bgp_static
->label_index
;
4247 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID
);
4250 /* Apply route-map. */
4251 if (bgp_static
->rmap
.name
) {
4252 struct attr attr_tmp
= attr
;
4253 info
.peer
= bgp
->peer_self
;
4254 info
.attr
= &attr_tmp
;
4256 SET_FLAG(bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4258 ret
= route_map_apply(bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4260 bgp
->peer_self
->rmap_type
= 0;
4262 if (ret
== RMAP_DENYMATCH
) {
4263 /* Free uninterned attribute. */
4264 bgp_attr_flush(&attr_tmp
);
4266 /* Unintern original. */
4267 aspath_unintern(&attr
.aspath
);
4268 bgp_static_withdraw(bgp
, p
, afi
, safi
);
4272 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
4273 bgp_attr_add_gshut_community(&attr_tmp
);
4275 attr_new
= bgp_attr_intern(&attr_tmp
);
4278 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
4279 bgp_attr_add_gshut_community(&attr
);
4281 attr_new
= bgp_attr_intern(&attr
);
4284 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4285 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4286 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4290 if (attrhash_cmp(ri
->attr
, attr_new
)
4291 && !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)
4292 && !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
)) {
4293 bgp_unlock_node(rn
);
4294 bgp_attr_unintern(&attr_new
);
4295 aspath_unintern(&attr
.aspath
);
4298 /* The attribute is changed. */
4299 bgp_info_set_flag(rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4301 /* Rewrite BGP route information. */
4302 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4303 bgp_info_restore(rn
, ri
);
4305 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4307 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
4308 && (safi
== SAFI_UNICAST
)) {
4309 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
4311 * Implicit withdraw case.
4312 * We have to do this before ri is
4315 ++vnc_implicit_withdraw
;
4316 vnc_import_bgp_del_route(bgp
, p
, ri
);
4317 vnc_import_bgp_exterior_del_route(
4322 bgp_attr_unintern(&ri
->attr
);
4323 ri
->attr
= attr_new
;
4324 ri
->uptime
= bgp_clock();
4326 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
4327 && (safi
== SAFI_UNICAST
)) {
4328 if (vnc_implicit_withdraw
) {
4329 vnc_import_bgp_add_route(bgp
, p
, ri
);
4330 vnc_import_bgp_exterior_add_route(
4336 /* Nexthop reachability check. */
4337 if (bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
4338 && (safi
== SAFI_UNICAST
4339 || safi
== SAFI_LABELED_UNICAST
)) {
4340 if (bgp_find_or_add_nexthop(bgp
, afi
, ri
, NULL
,
4342 bgp_info_set_flag(rn
, ri
,
4345 if (BGP_DEBUG(nht
, NHT
)) {
4346 char buf1
[INET6_ADDRSTRLEN
];
4347 inet_ntop(p
->family
,
4351 "%s(%s): Route not in table, not advertising",
4352 __FUNCTION__
, buf1
);
4354 bgp_info_unset_flag(rn
, ri
,
4358 /* Delete the NHT structure if any, if we're
4360 * enabling/disabling import check. We
4361 * deregister the route
4362 * from NHT to avoid overloading NHT and the
4363 * process interaction
4365 bgp_unlink_nexthop(ri
);
4366 bgp_info_set_flag(rn
, ri
, BGP_INFO_VALID
);
4368 /* Process change. */
4369 bgp_aggregate_increment(bgp
, p
, ri
, afi
, safi
);
4370 bgp_process(bgp
, rn
, afi
, safi
);
4372 if (SAFI_UNICAST
== safi
4373 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4375 == BGP_INSTANCE_TYPE_DEFAULT
)) {
4376 vpn_leak_from_vrf_update(bgp_get_default(), bgp
,
4380 bgp_unlock_node(rn
);
4381 aspath_unintern(&attr
.aspath
);
4386 /* Make new BGP info. */
4387 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
,
4389 /* Nexthop reachability check. */
4390 if (bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
4391 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
4392 if (bgp_find_or_add_nexthop(bgp
, afi
, new, NULL
, 0))
4393 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
4395 if (BGP_DEBUG(nht
, NHT
)) {
4396 char buf1
[INET6_ADDRSTRLEN
];
4397 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
4400 "%s(%s): Route not in table, not advertising",
4401 __FUNCTION__
, buf1
);
4403 bgp_info_unset_flag(rn
, new, BGP_INFO_VALID
);
4406 /* Delete the NHT structure if any, if we're toggling between
4407 * enabling/disabling import check. We deregister the route
4408 * from NHT to avoid overloading NHT and the process interaction
4410 bgp_unlink_nexthop(new);
4412 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
4415 /* Aggregate address increment. */
4416 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
4418 /* Register new BGP information. */
4419 bgp_info_add(rn
, new);
4421 /* route_node_get lock */
4422 bgp_unlock_node(rn
);
4424 /* Process change. */
4425 bgp_process(bgp
, rn
, afi
, safi
);
4427 if (SAFI_UNICAST
== safi
4428 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4429 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
4430 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
4433 /* Unintern original. */
4434 aspath_unintern(&attr
.aspath
);
4437 void bgp_static_withdraw(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
4440 struct bgp_node
*rn
;
4441 struct bgp_info
*ri
;
4443 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4445 /* Check selected route and self inserted route. */
4446 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4447 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4448 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4451 /* Withdraw static BGP route from routing table. */
4453 if (SAFI_UNICAST
== safi
4454 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4455 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
4456 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, ri
);
4458 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4459 bgp_unlink_nexthop(ri
);
4460 bgp_info_delete(rn
, ri
);
4461 bgp_process(bgp
, rn
, afi
, safi
);
4464 /* Unlock bgp_node_lookup. */
4465 bgp_unlock_node(rn
);
4469 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4471 static void bgp_static_withdraw_safi(struct bgp
*bgp
, struct prefix
*p
,
4472 afi_t afi
, safi_t safi
,
4473 struct prefix_rd
*prd
)
4475 struct bgp_node
*rn
;
4476 struct bgp_info
*ri
;
4478 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
4480 /* Check selected route and self inserted route. */
4481 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4482 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4483 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4486 /* Withdraw static BGP route from routing table. */
4489 rfapiProcessWithdraw(
4490 ri
->peer
, NULL
, p
, prd
, ri
->attr
, afi
, safi
, ri
->type
,
4491 1); /* Kill, since it is an administrative change */
4493 if (SAFI_MPLS_VPN
== safi
4494 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4495 vpn_leak_to_vrf_withdraw(bgp
, ri
);
4497 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4498 bgp_info_delete(rn
, ri
);
4499 bgp_process(bgp
, rn
, afi
, safi
);
4502 /* Unlock bgp_node_lookup. */
4503 bgp_unlock_node(rn
);
4506 static void bgp_static_update_safi(struct bgp
*bgp
, struct prefix
*p
,
4507 struct bgp_static
*bgp_static
, afi_t afi
,
4510 struct bgp_node
*rn
;
4511 struct bgp_info
*new;
4512 struct attr
*attr_new
;
4513 struct attr attr
= {0};
4514 struct bgp_info
*ri
;
4516 mpls_label_t label
= 0;
4518 u_int32_t num_labels
= 0;
4523 if (bgp_static
->label
!= MPLS_INVALID_LABEL
)
4525 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
,
4528 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
4530 attr
.nexthop
= bgp_static
->igpnexthop
;
4531 attr
.med
= bgp_static
->igpmetric
;
4532 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
4534 if ((safi
== SAFI_EVPN
) || (safi
== SAFI_MPLS_VPN
)
4535 || (safi
== SAFI_ENCAP
)) {
4536 if (afi
== AFI_IP
) {
4537 attr
.mp_nexthop_global_in
= bgp_static
->igpnexthop
;
4538 attr
.mp_nexthop_len
= IPV4_MAX_BYTELEN
;
4541 if (afi
== AFI_L2VPN
) {
4542 if (bgp_static
->gatewayIp
.family
== AF_INET
)
4544 bgp_static
->gatewayIp
.u
.prefix4
.s_addr
;
4545 else if (bgp_static
->gatewayIp
.family
== AF_INET6
)
4546 memcpy(&(add
.ipv6
), &(bgp_static
->gatewayIp
.u
.prefix6
),
4547 sizeof(struct in6_addr
));
4548 overlay_index_update(&attr
, bgp_static
->eth_s_id
, &add
);
4549 if (bgp_static
->encap_tunneltype
== BGP_ENCAP_TYPE_VXLAN
) {
4550 struct bgp_encap_type_vxlan bet
;
4551 memset(&bet
, 0, sizeof(struct bgp_encap_type_vxlan
));
4552 bet
.vnid
= p
->u
.prefix_evpn
.eth_tag
;
4553 bgp_encap_type_vxlan_to_tlv(&bet
, &attr
);
4555 if (bgp_static
->router_mac
) {
4556 bgp_add_routermac_ecom(&attr
, bgp_static
->router_mac
);
4559 /* Apply route-map. */
4560 if (bgp_static
->rmap
.name
) {
4561 struct attr attr_tmp
= attr
;
4562 struct bgp_info info
;
4565 info
.peer
= bgp
->peer_self
;
4566 info
.attr
= &attr_tmp
;
4568 SET_FLAG(bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4570 ret
= route_map_apply(bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4572 bgp
->peer_self
->rmap_type
= 0;
4574 if (ret
== RMAP_DENYMATCH
) {
4575 /* Free uninterned attribute. */
4576 bgp_attr_flush(&attr_tmp
);
4578 /* Unintern original. */
4579 aspath_unintern(&attr
.aspath
);
4580 bgp_static_withdraw_safi(bgp
, p
, afi
, safi
,
4585 attr_new
= bgp_attr_intern(&attr_tmp
);
4587 attr_new
= bgp_attr_intern(&attr
);
4590 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4591 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4592 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4597 memset(&add
, 0, sizeof(union gw_addr
));
4598 if (attrhash_cmp(ri
->attr
, attr_new
)
4599 && overlay_index_equal(afi
, ri
, bgp_static
->eth_s_id
, &add
)
4600 && !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
4601 bgp_unlock_node(rn
);
4602 bgp_attr_unintern(&attr_new
);
4603 aspath_unintern(&attr
.aspath
);
4606 /* The attribute is changed. */
4607 bgp_info_set_flag(rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4609 /* Rewrite BGP route information. */
4610 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4611 bgp_info_restore(rn
, ri
);
4613 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4614 bgp_attr_unintern(&ri
->attr
);
4615 ri
->attr
= attr_new
;
4616 ri
->uptime
= bgp_clock();
4619 label
= decode_label(&ri
->extra
->label
[0]);
4622 /* Process change. */
4623 bgp_aggregate_increment(bgp
, p
, ri
, afi
, safi
);
4624 bgp_process(bgp
, rn
, afi
, safi
);
4626 if (SAFI_MPLS_VPN
== safi
4627 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4628 vpn_leak_to_vrf_update(bgp
, ri
);
4631 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
4632 ri
->attr
, afi
, safi
, ri
->type
,
4633 ri
->sub_type
, &label
);
4635 bgp_unlock_node(rn
);
4636 aspath_unintern(&attr
.aspath
);
4642 /* Make new BGP info. */
4643 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
,
4645 SET_FLAG(new->flags
, BGP_INFO_VALID
);
4646 new->extra
= bgp_info_extra_new();
4648 new->extra
->label
[0] = bgp_static
->label
;
4649 new->extra
->num_labels
= num_labels
;
4652 label
= decode_label(&bgp_static
->label
);
4655 /* Aggregate address increment. */
4656 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
4658 /* Register new BGP information. */
4659 bgp_info_add(rn
, new);
4660 /* route_node_get lock */
4661 bgp_unlock_node(rn
);
4663 /* Process change. */
4664 bgp_process(bgp
, rn
, afi
, safi
);
4666 if (SAFI_MPLS_VPN
== safi
4667 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4668 vpn_leak_to_vrf_update(bgp
, new);
4671 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
, new->attr
, afi
,
4672 safi
, new->type
, new->sub_type
, &label
);
4675 /* Unintern original. */
4676 aspath_unintern(&attr
.aspath
);
4679 /* Configure static BGP network. When user don't run zebra, static
4680 route should be installed as valid. */
4681 static int bgp_static_set(struct vty
*vty
, const char *negate
,
4682 const char *ip_str
, afi_t afi
, safi_t safi
,
4683 const char *rmap
, int backdoor
, u_int32_t label_index
)
4685 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4688 struct bgp_static
*bgp_static
;
4689 struct bgp_node
*rn
;
4690 u_char need_update
= 0;
4692 /* Convert IP prefix string to struct prefix. */
4693 ret
= str2prefix(ip_str
, &p
);
4695 vty_out(vty
, "%% Malformed prefix\n");
4696 return CMD_WARNING_CONFIG_FAILED
;
4698 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
4699 vty_out(vty
, "%% Malformed prefix (link-local address)\n");
4700 return CMD_WARNING_CONFIG_FAILED
;
4707 /* Set BGP static route configuration. */
4708 rn
= bgp_node_lookup(bgp
->route
[afi
][safi
], &p
);
4711 vty_out(vty
, "%% Can't find static route specified\n");
4712 return CMD_WARNING_CONFIG_FAILED
;
4715 bgp_static
= rn
->info
;
4717 if ((label_index
!= BGP_INVALID_LABEL_INDEX
)
4718 && (label_index
!= bgp_static
->label_index
)) {
4720 "%% label-index doesn't match static route\n");
4721 return CMD_WARNING_CONFIG_FAILED
;
4724 if ((rmap
&& bgp_static
->rmap
.name
)
4725 && strcmp(rmap
, bgp_static
->rmap
.name
)) {
4727 "%% route-map name doesn't match static route\n");
4728 return CMD_WARNING_CONFIG_FAILED
;
4731 /* Update BGP RIB. */
4732 if (!bgp_static
->backdoor
)
4733 bgp_static_withdraw(bgp
, &p
, afi
, safi
);
4735 /* Clear configuration. */
4736 bgp_static_free(bgp_static
);
4738 bgp_unlock_node(rn
);
4739 bgp_unlock_node(rn
);
4742 /* Set BGP static route configuration. */
4743 rn
= bgp_node_get(bgp
->route
[afi
][safi
], &p
);
4746 /* Configuration change. */
4747 bgp_static
= rn
->info
;
4749 /* Label index cannot be changed. */
4750 if (bgp_static
->label_index
!= label_index
) {
4751 vty_out(vty
, "%% cannot change label-index\n");
4752 return CMD_WARNING_CONFIG_FAILED
;
4755 /* Check previous routes are installed into BGP. */
4756 if (bgp_static
->valid
4757 && bgp_static
->backdoor
!= backdoor
)
4760 bgp_static
->backdoor
= backdoor
;
4763 if (bgp_static
->rmap
.name
)
4764 XFREE(MTYPE_ROUTE_MAP_NAME
,
4765 bgp_static
->rmap
.name
);
4766 bgp_static
->rmap
.name
=
4767 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4768 bgp_static
->rmap
.map
=
4769 route_map_lookup_by_name(rmap
);
4771 if (bgp_static
->rmap
.name
)
4772 XFREE(MTYPE_ROUTE_MAP_NAME
,
4773 bgp_static
->rmap
.name
);
4774 bgp_static
->rmap
.name
= NULL
;
4775 bgp_static
->rmap
.map
= NULL
;
4776 bgp_static
->valid
= 0;
4778 bgp_unlock_node(rn
);
4780 /* New configuration. */
4781 bgp_static
= bgp_static_new();
4782 bgp_static
->backdoor
= backdoor
;
4783 bgp_static
->valid
= 0;
4784 bgp_static
->igpmetric
= 0;
4785 bgp_static
->igpnexthop
.s_addr
= 0;
4786 bgp_static
->label_index
= label_index
;
4789 if (bgp_static
->rmap
.name
)
4790 XFREE(MTYPE_ROUTE_MAP_NAME
,
4791 bgp_static
->rmap
.name
);
4792 bgp_static
->rmap
.name
=
4793 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4794 bgp_static
->rmap
.map
=
4795 route_map_lookup_by_name(rmap
);
4797 rn
->info
= bgp_static
;
4800 bgp_static
->valid
= 1;
4802 bgp_static_withdraw(bgp
, &p
, afi
, safi
);
4804 if (!bgp_static
->backdoor
)
4805 bgp_static_update(bgp
, &p
, bgp_static
, afi
, safi
);
4811 void bgp_static_add(struct bgp
*bgp
)
4815 struct bgp_node
*rn
;
4816 struct bgp_node
*rm
;
4817 struct bgp_table
*table
;
4818 struct bgp_static
*bgp_static
;
4820 FOREACH_AFI_SAFI (afi
, safi
)
4821 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
4822 rn
= bgp_route_next(rn
)) {
4823 if (rn
->info
== NULL
)
4826 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
4827 || (safi
== SAFI_EVPN
)) {
4830 for (rm
= bgp_table_top(table
); rm
;
4831 rm
= bgp_route_next(rm
)) {
4832 bgp_static
= rm
->info
;
4833 bgp_static_update_safi(bgp
, &rm
->p
,
4838 bgp_static_update(bgp
, &rn
->p
, rn
->info
, afi
,
4844 /* Called from bgp_delete(). Delete all static routes from the BGP
4846 void bgp_static_delete(struct bgp
*bgp
)
4850 struct bgp_node
*rn
;
4851 struct bgp_node
*rm
;
4852 struct bgp_table
*table
;
4853 struct bgp_static
*bgp_static
;
4855 FOREACH_AFI_SAFI (afi
, safi
)
4856 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
4857 rn
= bgp_route_next(rn
)) {
4858 if (rn
->info
== NULL
)
4861 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
4862 || (safi
== SAFI_EVPN
)) {
4865 for (rm
= bgp_table_top(table
); rm
;
4866 rm
= bgp_route_next(rm
)) {
4867 bgp_static
= rm
->info
;
4868 bgp_static_withdraw_safi(
4869 bgp
, &rm
->p
, AFI_IP
, safi
,
4870 (struct prefix_rd
*)&rn
->p
);
4871 bgp_static_free(bgp_static
);
4873 bgp_unlock_node(rn
);
4876 bgp_static
= rn
->info
;
4877 bgp_static_withdraw(bgp
, &rn
->p
, afi
, safi
);
4878 bgp_static_free(bgp_static
);
4880 bgp_unlock_node(rn
);
4885 void bgp_static_redo_import_check(struct bgp
*bgp
)
4889 struct bgp_node
*rn
;
4890 struct bgp_node
*rm
;
4891 struct bgp_table
*table
;
4892 struct bgp_static
*bgp_static
;
4894 /* Use this flag to force reprocessing of the route */
4895 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4896 FOREACH_AFI_SAFI (afi
, safi
) {
4897 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
4898 rn
= bgp_route_next(rn
)) {
4899 if (rn
->info
== NULL
)
4902 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
4903 || (safi
== SAFI_EVPN
)) {
4906 for (rm
= bgp_table_top(table
); rm
;
4907 rm
= bgp_route_next(rm
)) {
4908 bgp_static
= rm
->info
;
4909 bgp_static_update_safi(bgp
, &rm
->p
,
4914 bgp_static
= rn
->info
;
4915 bgp_static_update(bgp
, &rn
->p
, bgp_static
, afi
,
4920 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4923 static void bgp_purge_af_static_redist_routes(struct bgp
*bgp
, afi_t afi
,
4926 struct bgp_table
*table
;
4927 struct bgp_node
*rn
;
4928 struct bgp_info
*ri
;
4930 table
= bgp
->rib
[afi
][safi
];
4931 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
4932 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
4933 if (ri
->peer
== bgp
->peer_self
4934 && ((ri
->type
== ZEBRA_ROUTE_BGP
4935 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4936 || (ri
->type
!= ZEBRA_ROUTE_BGP
4938 == BGP_ROUTE_REDISTRIBUTE
))) {
4939 bgp_aggregate_decrement(bgp
, &rn
->p
, ri
, afi
,
4941 bgp_unlink_nexthop(ri
);
4942 bgp_info_delete(rn
, ri
);
4943 bgp_process(bgp
, rn
, afi
, safi
);
4950 * Purge all networks and redistributed routes from routing table.
4951 * Invoked upon the instance going down.
4953 void bgp_purge_static_redist_routes(struct bgp
*bgp
)
4958 FOREACH_AFI_SAFI (afi
, safi
)
4959 bgp_purge_af_static_redist_routes(bgp
, afi
, safi
);
4964 * Currently this is used to set static routes for VPN and ENCAP.
4965 * I think it can probably be factored with bgp_static_set.
4967 int bgp_static_set_safi(afi_t afi
, safi_t safi
, struct vty
*vty
,
4968 const char *ip_str
, const char *rd_str
,
4969 const char *label_str
, const char *rmap_str
,
4970 int evpn_type
, const char *esi
, const char *gwip
,
4971 const char *ethtag
, const char *routermac
)
4973 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4976 struct prefix_rd prd
;
4977 struct bgp_node
*prn
;
4978 struct bgp_node
*rn
;
4979 struct bgp_table
*table
;
4980 struct bgp_static
*bgp_static
;
4981 mpls_label_t label
= MPLS_INVALID_LABEL
;
4982 struct prefix gw_ip
;
4984 /* validate ip prefix */
4985 ret
= str2prefix(ip_str
, &p
);
4987 vty_out(vty
, "%% Malformed prefix\n");
4988 return CMD_WARNING_CONFIG_FAILED
;
4991 if ((afi
== AFI_L2VPN
)
4992 && (bgp_build_evpn_prefix(evpn_type
,
4993 ethtag
!= NULL
? atol(ethtag
) : 0, &p
))) {
4994 vty_out(vty
, "%% L2VPN prefix could not be forged\n");
4995 return CMD_WARNING_CONFIG_FAILED
;
4998 ret
= str2prefix_rd(rd_str
, &prd
);
5000 vty_out(vty
, "%% Malformed rd\n");
5001 return CMD_WARNING_CONFIG_FAILED
;
5005 unsigned long label_val
;
5006 label_val
= strtoul(label_str
, NULL
, 10);
5007 encode_label(label_val
, &label
);
5010 if (safi
== SAFI_EVPN
) {
5011 if (esi
&& str2esi(esi
, NULL
) == 0) {
5012 vty_out(vty
, "%% Malformed ESI\n");
5013 return CMD_WARNING_CONFIG_FAILED
;
5015 if (routermac
&& prefix_str2mac(routermac
, NULL
) == 0) {
5016 vty_out(vty
, "%% Malformed Router MAC\n");
5017 return CMD_WARNING_CONFIG_FAILED
;
5020 memset(&gw_ip
, 0, sizeof(struct prefix
));
5021 ret
= str2prefix(gwip
, &gw_ip
);
5023 vty_out(vty
, "%% Malformed GatewayIp\n");
5024 return CMD_WARNING_CONFIG_FAILED
;
5026 if ((gw_ip
.family
== AF_INET
5027 && IS_EVPN_PREFIX_IPADDR_V6(
5028 (struct prefix_evpn
*)&p
))
5029 || (gw_ip
.family
== AF_INET6
5030 && IS_EVPN_PREFIX_IPADDR_V4(
5031 (struct prefix_evpn
*)&p
))) {
5033 "%% GatewayIp family differs with IP prefix\n");
5034 return CMD_WARNING_CONFIG_FAILED
;
5038 prn
= bgp_node_get(bgp
->route
[afi
][safi
], (struct prefix
*)&prd
);
5039 if (prn
->info
== NULL
)
5040 prn
->info
= bgp_table_init(afi
, safi
);
5042 bgp_unlock_node(prn
);
5045 rn
= bgp_node_get(table
, &p
);
5048 vty_out(vty
, "%% Same network configuration exists\n");
5049 bgp_unlock_node(rn
);
5051 /* New configuration. */
5052 bgp_static
= bgp_static_new();
5053 bgp_static
->backdoor
= 0;
5054 bgp_static
->valid
= 0;
5055 bgp_static
->igpmetric
= 0;
5056 bgp_static
->igpnexthop
.s_addr
= 0;
5057 bgp_static
->label
= label
;
5058 bgp_static
->prd
= prd
;
5061 if (bgp_static
->rmap
.name
)
5062 XFREE(MTYPE_ROUTE_MAP_NAME
,
5063 bgp_static
->rmap
.name
);
5064 bgp_static
->rmap
.name
=
5065 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_str
);
5066 bgp_static
->rmap
.map
=
5067 route_map_lookup_by_name(rmap_str
);
5070 if (safi
== SAFI_EVPN
) {
5072 bgp_static
->eth_s_id
=
5074 sizeof(struct eth_segment_id
));
5075 str2esi(esi
, bgp_static
->eth_s_id
);
5078 bgp_static
->router_mac
=
5079 XCALLOC(MTYPE_ATTR
, ETH_ALEN
+ 1);
5080 prefix_str2mac(routermac
,
5081 bgp_static
->router_mac
);
5084 prefix_copy(&bgp_static
->gatewayIp
, &gw_ip
);
5086 rn
->info
= bgp_static
;
5088 bgp_static
->valid
= 1;
5089 bgp_static_update_safi(bgp
, &p
, bgp_static
, afi
, safi
);
5095 /* Configure static BGP network. */
5096 int bgp_static_unset_safi(afi_t afi
, safi_t safi
, struct vty
*vty
,
5097 const char *ip_str
, const char *rd_str
,
5098 const char *label_str
, int evpn_type
, const char *esi
,
5099 const char *gwip
, const char *ethtag
)
5101 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5104 struct prefix_rd prd
;
5105 struct bgp_node
*prn
;
5106 struct bgp_node
*rn
;
5107 struct bgp_table
*table
;
5108 struct bgp_static
*bgp_static
;
5109 mpls_label_t label
= MPLS_INVALID_LABEL
;
5111 /* Convert IP prefix string to struct prefix. */
5112 ret
= str2prefix(ip_str
, &p
);
5114 vty_out(vty
, "%% Malformed prefix\n");
5115 return CMD_WARNING_CONFIG_FAILED
;
5118 if ((afi
== AFI_L2VPN
)
5119 && (bgp_build_evpn_prefix(evpn_type
,
5120 ethtag
!= NULL
? atol(ethtag
) : 0, &p
))) {
5121 vty_out(vty
, "%% L2VPN prefix could not be forged\n");
5122 return CMD_WARNING_CONFIG_FAILED
;
5124 ret
= str2prefix_rd(rd_str
, &prd
);
5126 vty_out(vty
, "%% Malformed rd\n");
5127 return CMD_WARNING_CONFIG_FAILED
;
5131 unsigned long label_val
;
5132 label_val
= strtoul(label_str
, NULL
, 10);
5133 encode_label(label_val
, &label
);
5136 prn
= bgp_node_get(bgp
->route
[afi
][safi
], (struct prefix
*)&prd
);
5137 if (prn
->info
== NULL
)
5138 prn
->info
= bgp_table_init(afi
, safi
);
5140 bgp_unlock_node(prn
);
5143 rn
= bgp_node_lookup(table
, &p
);
5146 bgp_static_withdraw_safi(bgp
, &p
, afi
, safi
, &prd
);
5148 bgp_static
= rn
->info
;
5149 bgp_static_free(bgp_static
);
5151 bgp_unlock_node(rn
);
5152 bgp_unlock_node(rn
);
5154 vty_out(vty
, "%% Can't find the route\n");
5159 static int bgp_table_map_set(struct vty
*vty
, afi_t afi
, safi_t safi
,
5160 const char *rmap_name
)
5162 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5163 struct bgp_rmap
*rmap
;
5165 rmap
= &bgp
->table_map
[afi
][safi
];
5168 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5169 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
5170 rmap
->map
= route_map_lookup_by_name(rmap_name
);
5173 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5178 if (bgp_fibupd_safi(safi
))
5179 bgp_zebra_announce_table(bgp
, afi
, safi
);
5184 static int bgp_table_map_unset(struct vty
*vty
, afi_t afi
, safi_t safi
,
5185 const char *rmap_name
)
5187 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5188 struct bgp_rmap
*rmap
;
5190 rmap
= &bgp
->table_map
[afi
][safi
];
5192 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5196 if (bgp_fibupd_safi(safi
))
5197 bgp_zebra_announce_table(bgp
, afi
, safi
);
5202 void bgp_config_write_table_map(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
5205 if (bgp
->table_map
[afi
][safi
].name
) {
5206 vty_out(vty
, " table-map %s\n",
5207 bgp
->table_map
[afi
][safi
].name
);
5211 DEFUN (bgp_table_map
,
5214 "BGP table to RIB route download filter\n"
5215 "Name of the route map\n")
5218 return bgp_table_map_set(vty
, bgp_node_afi(vty
), bgp_node_safi(vty
),
5219 argv
[idx_word
]->arg
);
5221 DEFUN (no_bgp_table_map
,
5222 no_bgp_table_map_cmd
,
5223 "no table-map WORD",
5225 "BGP table to RIB route download filter\n"
5226 "Name of the route map\n")
5229 return bgp_table_map_unset(vty
, bgp_node_afi(vty
), bgp_node_safi(vty
),
5230 argv
[idx_word
]->arg
);
5236 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
5237 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
5238 backdoor$backdoor}]",
5240 "Specify a network to announce via BGP\n"
5245 "Route-map to modify the attributes\n"
5246 "Name of the route map\n"
5247 "Label index to associate with the prefix\n"
5248 "Label index value\n"
5249 "Specify a BGP backdoor route\n")
5251 char addr_prefix_str
[BUFSIZ
];
5256 ret
= netmask_str2prefix_str(address_str
, netmask_str
,
5259 vty_out(vty
, "%% Inconsistent address and mask\n");
5260 return CMD_WARNING_CONFIG_FAILED
;
5264 return bgp_static_set(
5265 vty
, no
, address_str
? addr_prefix_str
: prefix_str
, AFI_IP
,
5266 bgp_node_safi(vty
), map_name
, backdoor
? 1 : 0,
5267 label_index
? (uint32_t)label_index
: BGP_INVALID_LABEL_INDEX
);
5270 DEFPY(ipv6_bgp_network
,
5271 ipv6_bgp_network_cmd
,
5272 "[no] network X:X::X:X/M$prefix \
5273 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
5275 "Specify a network to announce via BGP\n"
5277 "Route-map to modify the attributes\n"
5278 "Name of the route map\n"
5279 "Label index to associate with the prefix\n"
5280 "Label index value\n")
5282 return bgp_static_set(
5283 vty
, no
, prefix_str
, AFI_IP6
, bgp_node_safi(vty
), map_name
, 0,
5284 label_index
? (uint32_t)label_index
: BGP_INVALID_LABEL_INDEX
);
5287 /* Aggreagete address:
5289 advertise-map Set condition to advertise attribute
5290 as-set Generate AS set path information
5291 attribute-map Set attributes of aggregate
5292 route-map Set parameters of aggregate
5293 summary-only Filter more specific routes from updates
5294 suppress-map Conditionally filter more specific routes from updates
5297 struct bgp_aggregate
{
5298 /* Summary-only flag. */
5299 u_char summary_only
;
5301 /* AS set generation. */
5304 /* Route-map for aggregated route. */
5305 struct route_map
*map
;
5307 /* Suppress-count. */
5308 unsigned long count
;
5310 /* SAFI configuration. */
5314 static struct bgp_aggregate
*bgp_aggregate_new(void)
5316 return XCALLOC(MTYPE_BGP_AGGREGATE
, sizeof(struct bgp_aggregate
));
5319 static void bgp_aggregate_free(struct bgp_aggregate
*aggregate
)
5321 XFREE(MTYPE_BGP_AGGREGATE
, aggregate
);
5324 /* Update an aggregate as routes are added/removed from the BGP table */
5325 static void bgp_aggregate_route(struct bgp
*bgp
, struct prefix
*p
,
5326 struct bgp_info
*rinew
, afi_t afi
, safi_t safi
,
5327 struct bgp_info
*del
,
5328 struct bgp_aggregate
*aggregate
)
5330 struct bgp_table
*table
;
5331 struct bgp_node
*top
;
5332 struct bgp_node
*rn
;
5334 struct aspath
*aspath
= NULL
;
5335 struct aspath
*asmerge
= NULL
;
5336 struct community
*community
= NULL
;
5337 struct community
*commerge
= NULL
;
5338 #if defined(AGGREGATE_NEXTHOP_CHECK)
5339 struct in_addr nexthop
;
5342 struct bgp_info
*ri
;
5343 struct bgp_info
*new;
5345 unsigned long match
= 0;
5346 u_char atomic_aggregate
= 0;
5348 /* Record adding route's nexthop and med. */
5350 #if defined(AGGREGATE_NEXTHOP_CHECK)
5351 nexthop
= rinew
->attr
->nexthop
;
5352 med
= rinew
->attr
->med
;
5356 /* ORIGIN attribute: If at least one route among routes that are
5357 aggregated has ORIGIN with the value INCOMPLETE, then the
5358 aggregated route must have the ORIGIN attribute with the value
5359 INCOMPLETE. Otherwise, if at least one route among routes that
5360 are aggregated has ORIGIN with the value EGP, then the aggregated
5361 route must have the origin attribute with the value EGP. In all
5362 other case the value of the ORIGIN attribute of the aggregated
5363 route is INTERNAL. */
5364 origin
= BGP_ORIGIN_IGP
;
5366 table
= bgp
->rib
[afi
][safi
];
5368 top
= bgp_node_get(table
, p
);
5369 for (rn
= bgp_node_get(table
, p
); rn
;
5370 rn
= bgp_route_next_until(rn
, top
))
5371 if (rn
->p
.prefixlen
> p
->prefixlen
) {
5374 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
5375 if (BGP_INFO_HOLDDOWN(ri
))
5378 if (del
&& ri
== del
)
5381 if (!rinew
&& first
) {
5382 #if defined(AGGREGATE_NEXTHOP_CHECK)
5383 nexthop
= ri
->attr
->nexthop
;
5384 med
= ri
->attr
->med
;
5389 #ifdef AGGREGATE_NEXTHOP_CHECK
5390 if (!IPV4_ADDR_SAME(&ri
->attr
->nexthop
,
5392 || ri
->attr
->med
!= med
) {
5394 aspath_free(aspath
);
5396 community_free(community
);
5397 bgp_unlock_node(rn
);
5398 bgp_unlock_node(top
);
5401 #endif /* AGGREGATE_NEXTHOP_CHECK */
5404 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5405 atomic_aggregate
= 1;
5407 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
) {
5408 if (aggregate
->summary_only
) {
5409 (bgp_info_extra_get(ri
))
5413 BGP_INFO_ATTR_CHANGED
);
5419 if (origin
< ri
->attr
->origin
)
5420 origin
= ri
->attr
->origin
;
5422 if (aggregate
->as_set
) {
5424 asmerge
= aspath_aggregate(
5427 aspath_free(aspath
);
5430 aspath
= aspath_dup(
5433 if (ri
->attr
->community
) {
5435 commerge
= community_merge(
5437 ri
->attr
->community
);
5438 community
= community_uniq_sort(
5443 community
= community_dup(
5444 ri
->attr
->community
);
5450 bgp_process(bgp
, rn
, afi
, safi
);
5452 bgp_unlock_node(top
);
5457 if (aggregate
->summary_only
)
5458 (bgp_info_extra_get(rinew
))->suppress
++;
5460 if (origin
< rinew
->attr
->origin
)
5461 origin
= rinew
->attr
->origin
;
5463 if (aggregate
->as_set
) {
5465 asmerge
= aspath_aggregate(aspath
,
5466 rinew
->attr
->aspath
);
5467 aspath_free(aspath
);
5470 aspath
= aspath_dup(rinew
->attr
->aspath
);
5472 if (rinew
->attr
->community
) {
5474 commerge
= community_merge(
5476 rinew
->attr
->community
);
5478 community_uniq_sort(commerge
);
5479 community_free(commerge
);
5481 community
= community_dup(
5482 rinew
->attr
->community
);
5487 if (aggregate
->count
> 0) {
5488 rn
= bgp_node_get(table
, p
);
5490 ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5491 bgp_attr_aggregate_intern(bgp
, origin
, aspath
,
5492 community
, aggregate
->as_set
,
5495 SET_FLAG(new->flags
, BGP_INFO_VALID
);
5497 bgp_info_add(rn
, new);
5498 bgp_unlock_node(rn
);
5499 bgp_process(bgp
, rn
, afi
, safi
);
5502 aspath_free(aspath
);
5504 community_free(community
);
5508 void bgp_aggregate_delete(struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5509 struct bgp_aggregate
*);
5511 void bgp_aggregate_increment(struct bgp
*bgp
, struct prefix
*p
,
5512 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5514 struct bgp_node
*child
;
5515 struct bgp_node
*rn
;
5516 struct bgp_aggregate
*aggregate
;
5517 struct bgp_table
*table
;
5519 /* MPLS-VPN aggregation is not yet supported. */
5520 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5521 || (safi
== SAFI_EVPN
))
5524 table
= bgp
->aggregate
[afi
][safi
];
5526 /* No aggregates configured. */
5527 if (bgp_table_top_nolock(table
) == NULL
)
5530 if (p
->prefixlen
== 0)
5533 if (BGP_INFO_HOLDDOWN(ri
))
5536 child
= bgp_node_get(table
, p
);
5538 /* Aggregate address configuration check. */
5539 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock(rn
))
5540 if ((aggregate
= rn
->info
) != NULL
5541 && rn
->p
.prefixlen
< p
->prefixlen
) {
5542 bgp_aggregate_delete(bgp
, &rn
->p
, afi
, safi
, aggregate
);
5543 bgp_aggregate_route(bgp
, &rn
->p
, ri
, afi
, safi
, NULL
,
5546 bgp_unlock_node(child
);
5549 void bgp_aggregate_decrement(struct bgp
*bgp
, struct prefix
*p
,
5550 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5552 struct bgp_node
*child
;
5553 struct bgp_node
*rn
;
5554 struct bgp_aggregate
*aggregate
;
5555 struct bgp_table
*table
;
5557 /* MPLS-VPN aggregation is not yet supported. */
5558 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5559 || (safi
== SAFI_EVPN
))
5562 table
= bgp
->aggregate
[afi
][safi
];
5564 /* No aggregates configured. */
5565 if (bgp_table_top_nolock(table
) == NULL
)
5568 if (p
->prefixlen
== 0)
5571 child
= bgp_node_get(table
, p
);
5573 /* Aggregate address configuration check. */
5574 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock(rn
))
5575 if ((aggregate
= rn
->info
) != NULL
5576 && rn
->p
.prefixlen
< p
->prefixlen
) {
5577 bgp_aggregate_delete(bgp
, &rn
->p
, afi
, safi
, aggregate
);
5578 bgp_aggregate_route(bgp
, &rn
->p
, NULL
, afi
, safi
, del
,
5581 bgp_unlock_node(child
);
5584 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5585 static void bgp_aggregate_add(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5586 safi_t safi
, struct bgp_aggregate
*aggregate
)
5588 struct bgp_table
*table
;
5589 struct bgp_node
*top
;
5590 struct bgp_node
*rn
;
5591 struct bgp_info
*new;
5592 struct bgp_info
*ri
;
5593 unsigned long match
;
5594 u_char origin
= BGP_ORIGIN_IGP
;
5595 struct aspath
*aspath
= NULL
;
5596 struct aspath
*asmerge
= NULL
;
5597 struct community
*community
= NULL
;
5598 struct community
*commerge
= NULL
;
5599 u_char atomic_aggregate
= 0;
5601 table
= bgp
->rib
[afi
][safi
];
5604 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5606 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5609 /* If routes exists below this node, generate aggregate routes. */
5610 top
= bgp_node_get(table
, p
);
5611 for (rn
= bgp_node_get(table
, p
); rn
;
5612 rn
= bgp_route_next_until(rn
, top
)) {
5613 if (rn
->p
.prefixlen
<= p
->prefixlen
)
5618 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
5619 if (BGP_INFO_HOLDDOWN(ri
))
5623 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5624 atomic_aggregate
= 1;
5626 if (ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5629 /* summary-only aggregate route suppress
5630 * aggregated route announcement. */
5631 if (aggregate
->summary_only
) {
5632 (bgp_info_extra_get(ri
))->suppress
++;
5633 bgp_info_set_flag(rn
, ri
,
5634 BGP_INFO_ATTR_CHANGED
);
5638 /* If at least one route among routes that are
5639 * aggregated has ORIGIN with the value INCOMPLETE,
5640 * then the aggregated route MUST have the ORIGIN
5641 * attribute with the value INCOMPLETE. Otherwise, if
5642 * at least one route among routes that are aggregated
5643 * has ORIGIN with the value EGP, then the aggregated
5644 * route MUST have the ORIGIN attribute with the value
5647 if (origin
< ri
->attr
->origin
)
5648 origin
= ri
->attr
->origin
;
5650 /* as-set aggregate route generate origin, as path,
5651 * community aggregation. */
5652 if (aggregate
->as_set
) {
5654 asmerge
= aspath_aggregate(
5655 aspath
, ri
->attr
->aspath
);
5656 aspath_free(aspath
);
5659 aspath
= aspath_dup(ri
->attr
->aspath
);
5661 if (ri
->attr
->community
) {
5663 commerge
= community_merge(
5665 ri
->attr
->community
);
5666 community
= community_uniq_sort(
5668 community_free(commerge
);
5670 community
= community_dup(
5671 ri
->attr
->community
);
5677 /* If this node is suppressed, process the change. */
5679 bgp_process(bgp
, rn
, afi
, safi
);
5681 bgp_unlock_node(top
);
5683 /* Add aggregate route to BGP table. */
5684 if (aggregate
->count
) {
5685 rn
= bgp_node_get(table
, p
);
5687 ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5688 bgp_attr_aggregate_intern(bgp
, origin
, aspath
,
5689 community
, aggregate
->as_set
,
5692 SET_FLAG(new->flags
, BGP_INFO_VALID
);
5694 bgp_info_add(rn
, new);
5695 bgp_unlock_node(rn
);
5697 /* Process change. */
5698 bgp_process(bgp
, rn
, afi
, safi
);
5701 aspath_free(aspath
);
5703 community_free(community
);
5707 void bgp_aggregate_delete(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5708 safi_t safi
, struct bgp_aggregate
*aggregate
)
5710 struct bgp_table
*table
;
5711 struct bgp_node
*top
;
5712 struct bgp_node
*rn
;
5713 struct bgp_info
*ri
;
5714 unsigned long match
;
5716 table
= bgp
->rib
[afi
][safi
];
5718 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5720 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5723 /* If routes exists below this node, generate aggregate routes. */
5724 top
= bgp_node_get(table
, p
);
5725 for (rn
= bgp_node_get(table
, p
); rn
;
5726 rn
= bgp_route_next_until(rn
, top
)) {
5727 if (rn
->p
.prefixlen
<= p
->prefixlen
)
5731 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
5732 if (BGP_INFO_HOLDDOWN(ri
))
5735 if (ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5738 if (aggregate
->summary_only
&& ri
->extra
) {
5739 ri
->extra
->suppress
--;
5741 if (ri
->extra
->suppress
== 0) {
5743 rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5750 /* If this node was suppressed, process the change. */
5752 bgp_process(bgp
, rn
, afi
, safi
);
5754 bgp_unlock_node(top
);
5756 /* Delete aggregate route from BGP table. */
5757 rn
= bgp_node_get(table
, p
);
5759 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5760 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
5761 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5764 /* Withdraw static BGP route from routing table. */
5766 bgp_info_delete(rn
, ri
);
5767 bgp_process(bgp
, rn
, afi
, safi
);
5770 /* Unlock bgp_node_lookup. */
5771 bgp_unlock_node(rn
);
5774 /* Aggregate route attribute. */
5775 #define AGGREGATE_SUMMARY_ONLY 1
5776 #define AGGREGATE_AS_SET 1
5778 static int bgp_aggregate_unset(struct vty
*vty
, const char *prefix_str
,
5779 afi_t afi
, safi_t safi
)
5781 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5784 struct bgp_node
*rn
;
5785 struct bgp_aggregate
*aggregate
;
5787 /* Convert string to prefix structure. */
5788 ret
= str2prefix(prefix_str
, &p
);
5790 vty_out(vty
, "Malformed prefix\n");
5791 return CMD_WARNING_CONFIG_FAILED
;
5795 /* Old configuration check. */
5796 rn
= bgp_node_lookup(bgp
->aggregate
[afi
][safi
], &p
);
5799 "%% There is no aggregate-address configuration.\n");
5800 return CMD_WARNING_CONFIG_FAILED
;
5803 aggregate
= rn
->info
;
5804 if (aggregate
->safi
== SAFI_UNICAST
)
5805 bgp_aggregate_delete(bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5806 if (aggregate
->safi
== SAFI_LABELED_UNICAST
)
5807 bgp_aggregate_delete(bgp
, &p
, afi
, SAFI_LABELED_UNICAST
,
5809 if (aggregate
->safi
== SAFI_MULTICAST
)
5810 bgp_aggregate_delete(bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5812 /* Unlock aggregate address configuration. */
5814 bgp_aggregate_free(aggregate
);
5815 bgp_unlock_node(rn
);
5816 bgp_unlock_node(rn
);
5821 static int bgp_aggregate_set(struct vty
*vty
, const char *prefix_str
, afi_t afi
,
5822 safi_t safi
, u_char summary_only
, u_char as_set
)
5824 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5827 struct bgp_node
*rn
;
5828 struct bgp_aggregate
*aggregate
;
5830 /* Convert string to prefix structure. */
5831 ret
= str2prefix(prefix_str
, &p
);
5833 vty_out(vty
, "Malformed prefix\n");
5834 return CMD_WARNING_CONFIG_FAILED
;
5838 /* Old configuration check. */
5839 rn
= bgp_node_get(bgp
->aggregate
[afi
][safi
], &p
);
5842 vty_out(vty
, "There is already same aggregate network.\n");
5843 /* try to remove the old entry */
5844 ret
= bgp_aggregate_unset(vty
, prefix_str
, afi
, safi
);
5846 vty_out(vty
, "Error deleting aggregate.\n");
5847 bgp_unlock_node(rn
);
5848 return CMD_WARNING_CONFIG_FAILED
;
5852 /* Make aggregate address structure. */
5853 aggregate
= bgp_aggregate_new();
5854 aggregate
->summary_only
= summary_only
;
5855 aggregate
->as_set
= as_set
;
5856 aggregate
->safi
= safi
;
5857 rn
->info
= aggregate
;
5859 /* Aggregate address insert into BGP routing table. */
5860 if (safi
== SAFI_UNICAST
)
5861 bgp_aggregate_add(bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5862 if (safi
== SAFI_LABELED_UNICAST
)
5863 bgp_aggregate_add(bgp
, &p
, afi
, SAFI_LABELED_UNICAST
,
5865 if (safi
== SAFI_MULTICAST
)
5866 bgp_aggregate_add(bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5871 DEFUN (aggregate_address
,
5872 aggregate_address_cmd
,
5873 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5874 "Configure BGP aggregate entries\n"
5875 "Aggregate prefix\n"
5876 "Generate AS set path information\n"
5877 "Filter more specific routes from updates\n"
5878 "Filter more specific routes from updates\n"
5879 "Generate AS set path information\n")
5882 argv_find(argv
, argc
, "A.B.C.D/M", &idx
);
5883 char *prefix
= argv
[idx
]->arg
;
5885 argv_find(argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5887 int summary_only
= argv_find(argv
, argc
, "summary-only", &idx
)
5888 ? AGGREGATE_SUMMARY_ONLY
5891 return bgp_aggregate_set(vty
, prefix
, AFI_IP
, bgp_node_safi(vty
),
5892 summary_only
, as_set
);
5895 DEFUN (aggregate_address_mask
,
5896 aggregate_address_mask_cmd
,
5897 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5898 "Configure BGP aggregate entries\n"
5899 "Aggregate address\n"
5901 "Generate AS set path information\n"
5902 "Filter more specific routes from updates\n"
5903 "Filter more specific routes from updates\n"
5904 "Generate AS set path information\n")
5907 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5908 char *prefix
= argv
[idx
]->arg
;
5909 char *mask
= argv
[idx
+ 1]->arg
;
5911 argv_find(argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5913 int summary_only
= argv_find(argv
, argc
, "summary-only", &idx
)
5914 ? AGGREGATE_SUMMARY_ONLY
5917 char prefix_str
[BUFSIZ
];
5918 int ret
= netmask_str2prefix_str(prefix
, mask
, prefix_str
);
5921 vty_out(vty
, "%% Inconsistent address and mask\n");
5922 return CMD_WARNING_CONFIG_FAILED
;
5925 return bgp_aggregate_set(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
),
5926 summary_only
, as_set
);
5929 DEFUN (no_aggregate_address
,
5930 no_aggregate_address_cmd
,
5931 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5933 "Configure BGP aggregate entries\n"
5934 "Aggregate prefix\n"
5935 "Generate AS set path information\n"
5936 "Filter more specific routes from updates\n"
5937 "Filter more specific routes from updates\n"
5938 "Generate AS set path information\n")
5941 argv_find(argv
, argc
, "A.B.C.D/M", &idx
);
5942 char *prefix
= argv
[idx
]->arg
;
5943 return bgp_aggregate_unset(vty
, prefix
, AFI_IP
, bgp_node_safi(vty
));
5946 DEFUN (no_aggregate_address_mask
,
5947 no_aggregate_address_mask_cmd
,
5948 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5950 "Configure BGP aggregate entries\n"
5951 "Aggregate address\n"
5953 "Generate AS set path information\n"
5954 "Filter more specific routes from updates\n"
5955 "Filter more specific routes from updates\n"
5956 "Generate AS set path information\n")
5959 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5960 char *prefix
= argv
[idx
]->arg
;
5961 char *mask
= argv
[idx
+ 1]->arg
;
5963 char prefix_str
[BUFSIZ
];
5964 int ret
= netmask_str2prefix_str(prefix
, mask
, prefix_str
);
5967 vty_out(vty
, "%% Inconsistent address and mask\n");
5968 return CMD_WARNING_CONFIG_FAILED
;
5971 return bgp_aggregate_unset(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
));
5974 DEFUN (ipv6_aggregate_address
,
5975 ipv6_aggregate_address_cmd
,
5976 "aggregate-address X:X::X:X/M [summary-only]",
5977 "Configure BGP aggregate entries\n"
5978 "Aggregate prefix\n"
5979 "Filter more specific routes from updates\n")
5982 argv_find(argv
, argc
, "X:X::X:X/M", &idx
);
5983 char *prefix
= argv
[idx
]->arg
;
5984 int sum_only
= argv_find(argv
, argc
, "summary-only", &idx
)
5985 ? AGGREGATE_SUMMARY_ONLY
5987 return bgp_aggregate_set(vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
,
5991 DEFUN (no_ipv6_aggregate_address
,
5992 no_ipv6_aggregate_address_cmd
,
5993 "no aggregate-address X:X::X:X/M [summary-only]",
5995 "Configure BGP aggregate entries\n"
5996 "Aggregate prefix\n"
5997 "Filter more specific routes from updates\n")
6000 argv_find(argv
, argc
, "X:X::X:X/M", &idx
);
6001 char *prefix
= argv
[idx
]->arg
;
6002 return bgp_aggregate_unset(vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
6005 /* Redistribute route treatment. */
6006 void bgp_redistribute_add(struct bgp
*bgp
, struct prefix
*p
,
6007 const union g_addr
*nexthop
, ifindex_t ifindex
,
6008 enum nexthop_types_t nhtype
, uint32_t metric
,
6009 u_char type
, u_short instance
, route_tag_t tag
)
6011 struct bgp_info
*new;
6012 struct bgp_info
*bi
;
6013 struct bgp_info info
;
6014 struct bgp_node
*bn
;
6016 struct attr
*new_attr
;
6019 struct bgp_redist
*red
;
6021 /* Make default attribute. */
6022 bgp_attr_default_set(&attr
, BGP_ORIGIN_INCOMPLETE
);
6025 case NEXTHOP_TYPE_IFINDEX
:
6027 case NEXTHOP_TYPE_IPV4
:
6028 case NEXTHOP_TYPE_IPV4_IFINDEX
:
6029 attr
.nexthop
= nexthop
->ipv4
;
6031 case NEXTHOP_TYPE_IPV6
:
6032 case NEXTHOP_TYPE_IPV6_IFINDEX
:
6033 attr
.mp_nexthop_global
= nexthop
->ipv6
;
6034 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
6036 case NEXTHOP_TYPE_BLACKHOLE
:
6037 switch (p
->family
) {
6039 attr
.nexthop
.s_addr
= INADDR_ANY
;
6042 memset(&attr
.mp_nexthop_global
, 0,
6043 sizeof(attr
.mp_nexthop_global
));
6044 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
6049 attr
.nh_ifindex
= ifindex
;
6052 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
6055 afi
= family2afi(p
->family
);
6057 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6059 struct attr attr_new
;
6061 /* Copy attribute for modification. */
6062 bgp_attr_dup(&attr_new
, &attr
);
6064 if (red
->redist_metric_flag
)
6065 attr_new
.med
= red
->redist_metric
;
6067 /* Apply route-map. */
6068 if (red
->rmap
.name
) {
6069 info
.peer
= bgp
->peer_self
;
6070 info
.attr
= &attr_new
;
6072 SET_FLAG(bgp
->peer_self
->rmap_type
,
6073 PEER_RMAP_TYPE_REDISTRIBUTE
);
6075 ret
= route_map_apply(red
->rmap
.map
, p
, RMAP_BGP
,
6078 bgp
->peer_self
->rmap_type
= 0;
6080 if (ret
== RMAP_DENYMATCH
) {
6081 /* Free uninterned attribute. */
6082 bgp_attr_flush(&attr_new
);
6084 /* Unintern original. */
6085 aspath_unintern(&attr
.aspath
);
6086 bgp_redistribute_delete(bgp
, p
, type
, instance
);
6091 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
6092 bgp_attr_add_gshut_community(&attr_new
);
6094 bn
= bgp_afi_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], afi
,
6095 SAFI_UNICAST
, p
, NULL
);
6097 new_attr
= bgp_attr_intern(&attr_new
);
6099 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
6100 if (bi
->peer
== bgp
->peer_self
6101 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
6105 /* Ensure the (source route) type is updated. */
6107 if (attrhash_cmp(bi
->attr
, new_attr
)
6108 && !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
)) {
6109 bgp_attr_unintern(&new_attr
);
6110 aspath_unintern(&attr
.aspath
);
6111 bgp_unlock_node(bn
);
6114 /* The attribute is changed. */
6115 bgp_info_set_flag(bn
, bi
,
6116 BGP_INFO_ATTR_CHANGED
);
6118 /* Rewrite BGP route information. */
6119 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6120 bgp_info_restore(bn
, bi
);
6122 bgp_aggregate_decrement(bgp
, p
, bi
, afi
,
6124 bgp_attr_unintern(&bi
->attr
);
6125 bi
->attr
= new_attr
;
6126 bi
->uptime
= bgp_clock();
6128 /* Process change. */
6129 bgp_aggregate_increment(bgp
, p
, bi
, afi
,
6131 bgp_process(bgp
, bn
, afi
, SAFI_UNICAST
);
6132 bgp_unlock_node(bn
);
6133 aspath_unintern(&attr
.aspath
);
6135 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6137 == BGP_INSTANCE_TYPE_DEFAULT
)) {
6139 vpn_leak_from_vrf_update(
6140 bgp_get_default(), bgp
, bi
);
6146 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
,
6147 bgp
->peer_self
, new_attr
, bn
);
6148 SET_FLAG(new->flags
, BGP_INFO_VALID
);
6150 bgp_aggregate_increment(bgp
, p
, new, afi
, SAFI_UNICAST
);
6151 bgp_info_add(bn
, new);
6152 bgp_unlock_node(bn
);
6153 bgp_process(bgp
, bn
, afi
, SAFI_UNICAST
);
6155 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6156 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6158 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
6162 /* Unintern original. */
6163 aspath_unintern(&attr
.aspath
);
6166 void bgp_redistribute_delete(struct bgp
*bgp
, struct prefix
*p
, u_char type
,
6170 struct bgp_node
*rn
;
6171 struct bgp_info
*ri
;
6172 struct bgp_redist
*red
;
6174 afi
= family2afi(p
->family
);
6176 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6178 rn
= bgp_afi_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], afi
,
6179 SAFI_UNICAST
, p
, NULL
);
6181 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6182 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== type
)
6186 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6187 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6189 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6192 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, SAFI_UNICAST
);
6193 bgp_info_delete(rn
, ri
);
6194 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
6196 bgp_unlock_node(rn
);
6200 /* Withdraw specified route type's route. */
6201 void bgp_redistribute_withdraw(struct bgp
*bgp
, afi_t afi
, int type
,
6204 struct bgp_node
*rn
;
6205 struct bgp_info
*ri
;
6206 struct bgp_table
*table
;
6208 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
6210 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
6211 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6212 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== type
6213 && ri
->instance
== instance
)
6217 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6218 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6220 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6223 bgp_aggregate_decrement(bgp
, &rn
->p
, ri
, afi
,
6225 bgp_info_delete(rn
, ri
);
6226 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
6231 /* Static function to display route. */
6232 static void route_vty_out_route(struct prefix
*p
, struct vty
*vty
,
6236 u_int32_t destination
;
6239 if (p
->family
== AF_INET
) {
6241 len
= vty_out(vty
, "%s",
6242 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
6244 destination
= ntohl(p
->u
.prefix4
.s_addr
);
6246 if ((IN_CLASSC(destination
) && p
->prefixlen
== 24)
6247 || (IN_CLASSB(destination
) && p
->prefixlen
== 16)
6248 || (IN_CLASSA(destination
) && p
->prefixlen
== 8)
6249 || p
->u
.prefix4
.s_addr
== 0) {
6250 /* When mask is natural,
6251 mask is not displayed. */
6253 len
+= vty_out(vty
, "/%d", p
->prefixlen
);
6255 json_object_string_add(json
, "prefix",
6256 inet_ntop(p
->family
,
6259 json_object_int_add(json
, "prefixLen", p
->prefixlen
);
6261 } else if (p
->family
== AF_ETHERNET
) {
6262 prefix2str(p
, buf
, PREFIX_STRLEN
);
6263 len
= vty_out(vty
, "%s", buf
);
6264 } else if (p
->family
== AF_EVPN
) {
6265 #if defined(HAVE_CUMULUS)
6269 bgp_evpn_route2str((struct prefix_evpn
*)p
, buf
,
6272 bgp_evpn_route2json((struct prefix_evpn
*)p
, json
);
6274 prefix2str(p
, buf
, PREFIX_STRLEN
);
6275 len
= vty_out(vty
, "%s", buf
);
6281 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6288 vty_out(vty
, "\n%*s", 20, " ");
6290 vty_out(vty
, "%*s", len
, " ");
6294 enum bgp_display_type
{
6298 /* Print the short form route status for a bgp_info */
6299 static void route_vty_short_status_out(struct vty
*vty
, struct bgp_info
*binfo
,
6300 json_object
*json_path
)
6304 /* Route status display. */
6305 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_REMOVED
))
6306 json_object_boolean_true_add(json_path
, "removed");
6308 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_STALE
))
6309 json_object_boolean_true_add(json_path
, "stale");
6311 if (binfo
->extra
&& binfo
->extra
->suppress
)
6312 json_object_boolean_true_add(json_path
, "suppressed");
6314 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)
6315 && !CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6316 json_object_boolean_true_add(json_path
, "valid");
6319 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6320 json_object_boolean_true_add(json_path
, "history");
6322 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
))
6323 json_object_boolean_true_add(json_path
, "damped");
6325 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
))
6326 json_object_boolean_true_add(json_path
, "bestpath");
6328 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_MULTIPATH
))
6329 json_object_boolean_true_add(json_path
, "multipath");
6331 /* Internal route. */
6332 if ((binfo
->peer
->as
)
6333 && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6334 json_object_string_add(json_path
, "pathFrom",
6337 json_object_string_add(json_path
, "pathFrom",
6343 /* Route status display. */
6344 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_REMOVED
))
6346 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_STALE
))
6348 else if (binfo
->extra
&& binfo
->extra
->suppress
)
6350 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)
6351 && !CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6357 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6359 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
))
6361 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
))
6363 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_MULTIPATH
))
6368 /* Internal route. */
6369 if (binfo
->peer
&& (binfo
->peer
->as
)
6370 && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6376 /* called from terminal list command */
6377 void route_vty_out(struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6378 int display
, safi_t safi
, json_object
*json_paths
)
6381 json_object
*json_path
= NULL
;
6382 json_object
*json_nexthops
= NULL
;
6383 json_object
*json_nexthop_global
= NULL
;
6384 json_object
*json_nexthop_ll
= NULL
;
6387 json_path
= json_object_new_object();
6389 /* short status lead text */
6390 route_vty_short_status_out(vty
, binfo
, json_path
);
6393 /* print prefix and mask */
6395 route_vty_out_route(p
, vty
, json_path
);
6397 vty_out(vty
, "%*s", 17, " ");
6399 route_vty_out_route(p
, vty
, json_path
);
6402 /* Print attribute */
6406 json_object_array_add(json_paths
, json_path
);
6414 * For ENCAP and EVPN routes, nexthop address family is not
6415 * neccessarily the same as the prefix address family.
6416 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6417 * EVPN routes are also exchanged with a MP nexthop. Currently,
6419 * is only IPv4, the value will be present in either
6421 * attr->mp_nexthop_global_in
6423 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
)) {
6426 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
6430 sprintf(nexthop
, "%s",
6431 inet_ntop(af
, &attr
->mp_nexthop_global_in
, buf
,
6435 sprintf(nexthop
, "%s",
6436 inet_ntop(af
, &attr
->mp_nexthop_global
, buf
,
6440 sprintf(nexthop
, "?");
6445 json_nexthop_global
= json_object_new_object();
6447 json_object_string_add(json_nexthop_global
, "afi",
6448 (af
== AF_INET
) ? "ip" : "ipv6");
6449 json_object_string_add(json_nexthop_global
,
6450 (af
== AF_INET
) ? "ip" : "ipv6",
6452 json_object_boolean_true_add(json_nexthop_global
,
6455 vty_out(vty
, "%s", nexthop
);
6456 } else if (safi
== SAFI_EVPN
) {
6458 json_nexthop_global
= json_object_new_object();
6460 json_object_string_add(json_nexthop_global
, "ip",
6461 inet_ntoa(attr
->nexthop
));
6462 json_object_string_add(json_nexthop_global
, "afi",
6464 json_object_boolean_true_add(json_nexthop_global
,
6467 vty_out(vty
, "%-16s", inet_ntoa(attr
->nexthop
));
6470 else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6472 json_nexthop_global
= json_object_new_object();
6474 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6475 json_object_string_add(
6476 json_nexthop_global
, "ip",
6477 inet_ntoa(attr
->mp_nexthop_global_in
));
6479 json_object_string_add(
6480 json_nexthop_global
, "ip",
6481 inet_ntoa(attr
->nexthop
));
6483 json_object_string_add(json_nexthop_global
, "afi",
6485 json_object_boolean_true_add(json_nexthop_global
,
6488 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6489 vty_out(vty
, "%-16s",
6490 inet_ntoa(attr
->mp_nexthop_global_in
));
6492 vty_out(vty
, "%-16s", inet_ntoa(attr
->nexthop
));
6497 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6502 json_nexthop_global
= json_object_new_object();
6503 json_object_string_add(
6504 json_nexthop_global
, "ip",
6505 inet_ntop(AF_INET6
, &attr
->mp_nexthop_global
,
6507 json_object_string_add(json_nexthop_global
, "afi",
6509 json_object_string_add(json_nexthop_global
, "scope",
6512 /* We display both LL & GL if both have been
6514 if ((attr
->mp_nexthop_len
== 32)
6515 || (binfo
->peer
->conf_if
)) {
6516 json_nexthop_ll
= json_object_new_object();
6517 json_object_string_add(
6518 json_nexthop_ll
, "ip",
6520 &attr
->mp_nexthop_local
, buf
,
6522 json_object_string_add(json_nexthop_ll
, "afi",
6524 json_object_string_add(json_nexthop_ll
, "scope",
6527 if ((IPV6_ADDR_CMP(&attr
->mp_nexthop_global
,
6528 &attr
->mp_nexthop_local
)
6530 && !attr
->mp_nexthop_prefer_global
)
6531 json_object_boolean_true_add(
6532 json_nexthop_ll
, "used");
6534 json_object_boolean_true_add(
6535 json_nexthop_global
, "used");
6537 json_object_boolean_true_add(
6538 json_nexthop_global
, "used");
6540 /* Display LL if LL/Global both in table unless
6541 * prefer-global is set */
6542 if (((attr
->mp_nexthop_len
== 32)
6543 && !attr
->mp_nexthop_prefer_global
)
6544 || (binfo
->peer
->conf_if
)) {
6545 if (binfo
->peer
->conf_if
) {
6546 len
= vty_out(vty
, "%s",
6547 binfo
->peer
->conf_if
);
6548 len
= 16 - len
; /* len of IPv6
6554 vty_out(vty
, "\n%*s", 36, " ");
6556 vty_out(vty
, "%*s", len
, " ");
6562 &attr
->mp_nexthop_local
,
6567 vty_out(vty
, "\n%*s", 36, " ");
6569 vty_out(vty
, "%*s", len
, " ");
6575 &attr
->mp_nexthop_global
, buf
,
6580 vty_out(vty
, "\n%*s", 36, " ");
6582 vty_out(vty
, "%*s", len
, " ");
6588 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6590 json_object_int_add(json_path
, "med", attr
->med
);
6592 vty_out(vty
, "%10u", attr
->med
);
6593 else if (!json_paths
)
6597 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6599 json_object_int_add(json_path
, "localpref",
6602 vty_out(vty
, "%7u", attr
->local_pref
);
6603 else if (!json_paths
)
6607 json_object_int_add(json_path
, "weight", attr
->weight
);
6609 vty_out(vty
, "%7u ", attr
->weight
);
6613 json_object_string_add(
6614 json_path
, "peerId",
6615 sockunion2str(&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6621 json_object_string_add(json_path
, "aspath",
6624 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
6629 json_object_string_add(json_path
, "origin",
6630 bgp_origin_long_str
[attr
->origin
]);
6632 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
6635 if (json_nexthop_global
|| json_nexthop_ll
) {
6636 json_nexthops
= json_object_new_array();
6638 if (json_nexthop_global
)
6639 json_object_array_add(json_nexthops
,
6640 json_nexthop_global
);
6642 if (json_nexthop_ll
)
6643 json_object_array_add(json_nexthops
,
6646 json_object_object_add(json_path
, "nexthops",
6650 json_object_array_add(json_paths
, json_path
);
6654 /* prints an additional line, indented, with VNC info, if
6656 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6657 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6662 /* called from terminal list command */
6663 void route_vty_out_tmp(struct vty
*vty
, struct prefix
*p
, struct attr
*attr
,
6664 safi_t safi
, u_char use_json
, json_object
*json_ar
)
6666 json_object
*json_status
= NULL
;
6667 json_object
*json_net
= NULL
;
6669 /* Route status display. */
6671 json_status
= json_object_new_object();
6672 json_net
= json_object_new_object();
6679 /* print prefix and mask */
6681 json_object_string_add(
6682 json_net
, "addrPrefix",
6683 inet_ntop(p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6685 route_vty_out_route(p
, vty
, NULL
);
6687 /* Print attribute */
6690 if (p
->family
== AF_INET
6691 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6692 || safi
== SAFI_EVPN
6693 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6694 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6695 || safi
== SAFI_EVPN
)
6696 json_object_string_add(
6697 json_net
, "nextHop",
6699 attr
->mp_nexthop_global_in
));
6701 json_object_string_add(
6702 json_net
, "nextHop",
6703 inet_ntoa(attr
->nexthop
));
6704 } else if (p
->family
== AF_INET6
6705 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6708 json_object_string_add(
6709 json_net
, "netHopGloabal",
6711 &attr
->mp_nexthop_global
, buf
,
6716 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6717 json_object_int_add(json_net
, "metric",
6720 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6721 json_object_int_add(json_net
, "localPref",
6724 json_object_int_add(json_net
, "weight", attr
->weight
);
6728 json_object_string_add(json_net
, "asPath",
6732 json_object_string_add(json_net
, "bgpOriginCode",
6733 bgp_origin_str
[attr
->origin
]);
6735 if (p
->family
== AF_INET
6736 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6737 || safi
== SAFI_EVPN
6738 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6739 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6740 || safi
== SAFI_EVPN
)
6741 vty_out(vty
, "%-16s",
6743 attr
->mp_nexthop_global_in
));
6745 vty_out(vty
, "%-16s",
6746 inet_ntoa(attr
->nexthop
));
6747 } else if (p
->family
== AF_INET6
6748 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6755 &attr
->mp_nexthop_global
, buf
,
6759 vty_out(vty
, "\n%*s", 36, " ");
6761 vty_out(vty
, "%*s", len
, " ");
6764 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6765 vty_out(vty
, "%10u", attr
->med
);
6769 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6770 vty_out(vty
, "%7u", attr
->local_pref
);
6774 vty_out(vty
, "%7u ", attr
->weight
);
6778 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
6781 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
6785 json_object_boolean_true_add(json_status
, "*");
6786 json_object_boolean_true_add(json_status
, ">");
6787 json_object_object_add(json_net
, "appliedStatusSymbols",
6789 char buf_cut
[BUFSIZ
];
6790 json_object_object_add(
6792 inet_ntop(p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
),
6798 void route_vty_out_tag(struct vty
*vty
, struct prefix
*p
,
6799 struct bgp_info
*binfo
, int display
, safi_t safi
,
6802 json_object
*json_out
= NULL
;
6804 mpls_label_t label
= MPLS_INVALID_LABEL
;
6810 json_out
= json_object_new_object();
6812 /* short status lead text */
6813 route_vty_short_status_out(vty
, binfo
, json_out
);
6815 /* print prefix and mask */
6818 route_vty_out_route(p
, vty
, NULL
);
6820 vty_out(vty
, "%*s", 17, " ");
6823 /* Print attribute */
6826 if (((p
->family
== AF_INET
)
6827 && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6828 || (safi
== SAFI_EVPN
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6829 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6830 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6831 || safi
== SAFI_EVPN
) {
6833 json_object_string_add(
6834 json_out
, "mpNexthopGlobalIn",
6836 attr
->mp_nexthop_global_in
));
6838 vty_out(vty
, "%-16s",
6840 attr
->mp_nexthop_global_in
));
6843 json_object_string_add(
6844 json_out
, "nexthop",
6845 inet_ntoa(attr
->nexthop
));
6847 vty_out(vty
, "%-16s",
6848 inet_ntoa(attr
->nexthop
));
6850 } else if (((p
->family
== AF_INET6
)
6851 && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6852 || (safi
== SAFI_EVPN
6853 && BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6854 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6858 if (attr
->mp_nexthop_len
6859 == BGP_ATTR_NHLEN_IPV6_GLOBAL
) {
6861 json_object_string_add(
6862 json_out
, "mpNexthopGlobalIn",
6865 &attr
->mp_nexthop_global
,
6871 &attr
->mp_nexthop_global
,
6873 } else if (attr
->mp_nexthop_len
6874 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) {
6877 &attr
->mp_nexthop_global
,
6880 &attr
->mp_nexthop_local
,
6882 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6883 json_object_string_add(
6885 "mpNexthopGlobalLocal", buf_c
);
6887 vty_out(vty
, "%s(%s)",
6890 &attr
->mp_nexthop_global
,
6894 &attr
->mp_nexthop_local
,
6900 label
= decode_label(&binfo
->extra
->label
[0]);
6902 if (bgp_is_valid_label(&label
)) {
6904 json_object_int_add(json_out
, "notag", label
);
6905 json_object_array_add(json
, json_out
);
6907 vty_out(vty
, "notag/%d", label
);
6913 void route_vty_out_overlay(struct vty
*vty
, struct prefix
*p
,
6914 struct bgp_info
*binfo
, int display
,
6915 json_object
*json_paths
)
6919 json_object
*json_path
= NULL
;
6922 json_path
= json_object_new_object();
6927 /* short status lead text */
6928 route_vty_short_status_out(vty
, binfo
, json_path
);
6930 /* print prefix and mask */
6932 route_vty_out_route(p
, vty
, NULL
);
6934 vty_out(vty
, "%*s", 17, " ");
6936 /* Print attribute */
6940 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
6944 vty_out(vty
, "%-16s",
6945 inet_ntop(af
, &attr
->mp_nexthop_global_in
, buf
,
6949 vty_out(vty
, "%s(%s)",
6950 inet_ntop(af
, &attr
->mp_nexthop_global
, buf
,
6952 inet_ntop(af
, &attr
->mp_nexthop_local
, buf1
,
6960 struct eth_segment_id
*id
= &(attr
->evpn_overlay
.eth_s_id
);
6961 char *str
= esi2str(id
);
6962 vty_out(vty
, "%s", str
);
6963 XFREE(MTYPE_TMP
, str
);
6964 if (IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn
*)p
)) {
6965 vty_out(vty
, "/%s", inet_ntoa(attr
->evpn_overlay
.gw_ip
.ipv4
));
6966 } else if (IS_EVPN_PREFIX_IPADDR_V6((struct prefix_evpn
*)p
)) {
6968 inet_ntop(AF_INET6
, &(attr
->evpn_overlay
.gw_ip
.ipv6
),
6971 if (attr
->ecommunity
) {
6973 struct ecommunity_val
*routermac
= ecommunity_lookup(
6974 attr
->ecommunity
, ECOMMUNITY_ENCODE_EVPN
,
6975 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC
);
6977 mac
= ecom_mac2str((char *)routermac
->val
);
6979 vty_out(vty
, "/%s", (char *)mac
);
6980 XFREE(MTYPE_TMP
, mac
);
6986 /* dampening route */
6987 static void damp_route_vty_out(struct vty
*vty
, struct prefix
*p
,
6988 struct bgp_info
*binfo
, int display
, safi_t safi
,
6989 u_char use_json
, json_object
*json
)
6993 char timebuf
[BGP_UPTIME_LEN
];
6995 /* short status lead text */
6996 route_vty_short_status_out(vty
, binfo
, json
);
6998 /* print prefix and mask */
7001 route_vty_out_route(p
, vty
, NULL
);
7003 vty_out(vty
, "%*s", 17, " ");
7006 len
= vty_out(vty
, "%s", binfo
->peer
->host
);
7010 vty_out(vty
, "\n%*s", 34, " ");
7013 json_object_int_add(json
, "peerHost", len
);
7015 vty_out(vty
, "%*s", len
, " ");
7019 bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
, BGP_UPTIME_LEN
,
7022 vty_out(vty
, "%s ", bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
,
7026 /* Print attribute */
7032 json_object_string_add(json
, "asPath",
7035 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7040 json_object_string_add(json
, "origin",
7041 bgp_origin_str
[attr
->origin
]);
7043 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7050 static void flap_route_vty_out(struct vty
*vty
, struct prefix
*p
,
7051 struct bgp_info
*binfo
, int display
, safi_t safi
,
7052 u_char use_json
, json_object
*json
)
7055 struct bgp_damp_info
*bdi
;
7056 char timebuf
[BGP_UPTIME_LEN
];
7062 bdi
= binfo
->extra
->damp_info
;
7064 /* short status lead text */
7065 route_vty_short_status_out(vty
, binfo
, json
);
7067 /* print prefix and mask */
7070 route_vty_out_route(p
, vty
, NULL
);
7072 vty_out(vty
, "%*s", 17, " ");
7075 len
= vty_out(vty
, "%s", binfo
->peer
->host
);
7079 vty_out(vty
, "\n%*s", 33, " ");
7082 json_object_int_add(json
, "peerHost", len
);
7084 vty_out(vty
, "%*s", len
, " ");
7087 len
= vty_out(vty
, "%d", bdi
->flap
);
7094 json_object_int_add(json
, "bdiFlap", len
);
7096 vty_out(vty
, "%*s", len
, " ");
7100 peer_uptime(bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
,
7103 vty_out(vty
, "%s ", peer_uptime(bdi
->start_time
, timebuf
,
7104 BGP_UPTIME_LEN
, 0, NULL
));
7106 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
)
7107 && !CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
)) {
7109 bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
,
7110 BGP_UPTIME_LEN
, use_json
, json
);
7113 bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
,
7118 vty_out(vty
, "%*s ", 8, " ");
7121 /* Print attribute */
7127 json_object_string_add(json
, "asPath",
7130 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7135 json_object_string_add(json
, "origin",
7136 bgp_origin_str
[attr
->origin
]);
7138 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7144 static void route_vty_out_advertised_to(struct vty
*vty
, struct peer
*peer
,
7145 int *first
, const char *header
,
7146 json_object
*json_adv_to
)
7148 char buf1
[INET6_ADDRSTRLEN
];
7149 json_object
*json_peer
= NULL
;
7152 /* 'advertised-to' is a dictionary of peers we have advertised
7154 * prefix too. The key is the peer's IP or swpX, the value is
7156 * hostname if we know it and "" if not.
7158 json_peer
= json_object_new_object();
7161 json_object_string_add(json_peer
, "hostname",
7165 json_object_object_add(json_adv_to
, peer
->conf_if
,
7168 json_object_object_add(
7170 sockunion2str(&peer
->su
, buf1
, SU_ADDRSTRLEN
),
7174 vty_out(vty
, "%s", header
);
7179 && bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
)) {
7181 vty_out(vty
, " %s(%s)", peer
->hostname
,
7184 vty_out(vty
, " %s(%s)", peer
->hostname
,
7185 sockunion2str(&peer
->su
, buf1
,
7189 vty_out(vty
, " %s", peer
->conf_if
);
7192 sockunion2str(&peer
->su
, buf1
,
7198 void route_vty_out_detail(struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
7199 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
7200 json_object
*json_paths
)
7202 char buf
[INET6_ADDRSTRLEN
];
7204 #if defined(HAVE_CUMULUS)
7205 char buf2
[EVPN_ROUTE_STRLEN
];
7208 int sockunion_vty_out(struct vty
*, union sockunion
*);
7210 json_object
*json_bestpath
= NULL
;
7211 json_object
*json_cluster_list
= NULL
;
7212 json_object
*json_cluster_list_list
= NULL
;
7213 json_object
*json_ext_community
= NULL
;
7214 json_object
*json_lcommunity
= NULL
;
7215 json_object
*json_last_update
= NULL
;
7216 json_object
*json_pmsi
= NULL
;
7217 json_object
*json_nexthop_global
= NULL
;
7218 json_object
*json_nexthop_ll
= NULL
;
7219 json_object
*json_nexthops
= NULL
;
7220 json_object
*json_path
= NULL
;
7221 json_object
*json_peer
= NULL
;
7222 json_object
*json_string
= NULL
;
7223 json_object
*json_adv_to
= NULL
;
7225 struct listnode
*node
, *nnode
;
7227 int addpath_capable
;
7229 unsigned int first_as
;
7232 json_path
= json_object_new_object();
7233 json_peer
= json_object_new_object();
7234 json_nexthop_global
= json_object_new_object();
7237 #if defined(HAVE_CUMULUS)
7238 if (!json_paths
&& safi
== SAFI_EVPN
) {
7241 bgp_evpn_route2str((struct prefix_evpn
*)p
, buf2
, sizeof(buf2
));
7242 vty_out(vty
, " Route %s", buf2
);
7244 if (binfo
->extra
&& binfo
->extra
->num_labels
) {
7245 bgp_evpn_label2str(binfo
->extra
->label
,
7246 binfo
->extra
->num_labels
, tag_buf
,
7248 vty_out(vty
, " VNI %s", tag_buf
);
7251 if (binfo
->extra
&& binfo
->extra
->parent
) {
7252 struct bgp_info
*parent_ri
;
7253 struct bgp_node
*rn
, *prn
;
7255 parent_ri
= (struct bgp_info
*)binfo
->extra
->parent
;
7256 rn
= parent_ri
->net
;
7257 if (rn
&& rn
->prn
) {
7259 vty_out(vty
, " Imported from %s:%s\n",
7261 (struct prefix_rd
*)&prn
->p
,
7262 buf1
, sizeof(buf1
)),
7272 /* Line1 display AS-path, Aggregator */
7275 if (!attr
->aspath
->json
)
7276 aspath_str_update(attr
->aspath
, true);
7277 json_object_lock(attr
->aspath
->json
);
7278 json_object_object_add(json_path
, "aspath",
7279 attr
->aspath
->json
);
7281 if (attr
->aspath
->segments
)
7282 aspath_print_vty(vty
, " %s",
7285 vty_out(vty
, " Local");
7289 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_REMOVED
)) {
7291 json_object_boolean_true_add(json_path
,
7294 vty_out(vty
, ", (removed)");
7297 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_STALE
)) {
7299 json_object_boolean_true_add(json_path
,
7302 vty_out(vty
, ", (stale)");
7305 if (CHECK_FLAG(attr
->flag
,
7306 ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR
))) {
7308 json_object_int_add(json_path
, "aggregatorAs",
7309 attr
->aggregator_as
);
7310 json_object_string_add(
7311 json_path
, "aggregatorId",
7312 inet_ntoa(attr
->aggregator_addr
));
7314 vty_out(vty
, ", (aggregated by %u %s)",
7315 attr
->aggregator_as
,
7316 inet_ntoa(attr
->aggregator_addr
));
7320 if (CHECK_FLAG(binfo
->peer
->af_flags
[afi
][safi
],
7321 PEER_FLAG_REFLECTOR_CLIENT
)) {
7323 json_object_boolean_true_add(
7324 json_path
, "rxedFromRrClient");
7326 vty_out(vty
, ", (Received from a RR-client)");
7329 if (CHECK_FLAG(binfo
->peer
->af_flags
[afi
][safi
],
7330 PEER_FLAG_RSERVER_CLIENT
)) {
7332 json_object_boolean_true_add(
7333 json_path
, "rxedFromRsClient");
7335 vty_out(vty
, ", (Received from a RS-client)");
7338 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
)) {
7340 json_object_boolean_true_add(
7341 json_path
, "dampeningHistoryEntry");
7343 vty_out(vty
, ", (history entry)");
7344 } else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
)) {
7346 json_object_boolean_true_add(
7347 json_path
, "dampeningSuppressed");
7349 vty_out(vty
, ", (suppressed due to dampening)");
7355 /* Line2 display Next-hop, Neighbor, Router-id */
7356 /* Display the nexthop */
7357 if ((p
->family
== AF_INET
|| p
->family
== AF_ETHERNET
7358 || p
->family
== AF_EVPN
)
7359 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7360 || safi
== SAFI_EVPN
7361 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7362 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7363 || safi
== SAFI_EVPN
) {
7365 json_object_string_add(
7366 json_nexthop_global
, "ip",
7368 attr
->mp_nexthop_global_in
));
7372 attr
->mp_nexthop_global_in
));
7375 json_object_string_add(
7376 json_nexthop_global
, "ip",
7377 inet_ntoa(attr
->nexthop
));
7380 inet_ntoa(attr
->nexthop
));
7384 json_object_string_add(json_nexthop_global
,
7388 json_object_string_add(
7389 json_nexthop_global
, "ip",
7391 &attr
->mp_nexthop_global
, buf
,
7393 json_object_string_add(json_nexthop_global
,
7395 json_object_string_add(json_nexthop_global
,
7400 &attr
->mp_nexthop_global
, buf
,
7405 /* Display the IGP cost or 'inaccessible' */
7406 if (!CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)) {
7408 json_object_boolean_false_add(
7409 json_nexthop_global
, "accessible");
7411 vty_out(vty
, " (inaccessible)");
7413 if (binfo
->extra
&& binfo
->extra
->igpmetric
) {
7415 json_object_int_add(
7416 json_nexthop_global
, "metric",
7417 binfo
->extra
->igpmetric
);
7419 vty_out(vty
, " (metric %u)",
7420 binfo
->extra
->igpmetric
);
7423 /* IGP cost is 0, display this only for json */
7426 json_object_int_add(json_nexthop_global
,
7431 json_object_boolean_true_add(
7432 json_nexthop_global
, "accessible");
7435 /* Display peer "from" output */
7436 /* This path was originated locally */
7437 if (binfo
->peer
== bgp
->peer_self
) {
7439 if (safi
== SAFI_EVPN
7440 || (p
->family
== AF_INET
7441 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7443 json_object_string_add(
7444 json_peer
, "peerId", "0.0.0.0");
7446 vty_out(vty
, " from 0.0.0.0 ");
7449 json_object_string_add(json_peer
,
7452 vty_out(vty
, " from :: ");
7456 json_object_string_add(
7457 json_peer
, "routerId",
7458 inet_ntoa(bgp
->router_id
));
7460 vty_out(vty
, "(%s)", inet_ntoa(bgp
->router_id
));
7463 /* We RXed this path from one of our peers */
7467 json_object_string_add(
7468 json_peer
, "peerId",
7469 sockunion2str(&binfo
->peer
->su
, buf
,
7471 json_object_string_add(
7472 json_peer
, "routerId",
7474 &binfo
->peer
->remote_id
, buf1
,
7477 if (binfo
->peer
->hostname
)
7478 json_object_string_add(
7479 json_peer
, "hostname",
7480 binfo
->peer
->hostname
);
7482 if (binfo
->peer
->domainname
)
7483 json_object_string_add(
7484 json_peer
, "domainname",
7485 binfo
->peer
->domainname
);
7487 if (binfo
->peer
->conf_if
)
7488 json_object_string_add(
7489 json_peer
, "interface",
7490 binfo
->peer
->conf_if
);
7492 if (binfo
->peer
->conf_if
) {
7493 if (binfo
->peer
->hostname
7496 BGP_FLAG_SHOW_HOSTNAME
))
7497 vty_out(vty
, " from %s(%s)",
7498 binfo
->peer
->hostname
,
7499 binfo
->peer
->conf_if
);
7501 vty_out(vty
, " from %s",
7502 binfo
->peer
->conf_if
);
7504 if (binfo
->peer
->hostname
7507 BGP_FLAG_SHOW_HOSTNAME
))
7508 vty_out(vty
, " from %s(%s)",
7509 binfo
->peer
->hostname
,
7512 vty_out(vty
, " from %s",
7521 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7522 vty_out(vty
, " (%s)",
7523 inet_ntoa(attr
->originator_id
));
7525 vty_out(vty
, " (%s)",
7528 &binfo
->peer
->remote_id
,
7529 buf1
, sizeof(buf1
)));
7536 /* display the link-local nexthop */
7537 if (attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) {
7539 json_nexthop_ll
= json_object_new_object();
7540 json_object_string_add(
7541 json_nexthop_ll
, "ip",
7543 &attr
->mp_nexthop_local
, buf
,
7545 json_object_string_add(json_nexthop_ll
, "afi",
7547 json_object_string_add(json_nexthop_ll
, "scope",
7550 json_object_boolean_true_add(json_nexthop_ll
,
7553 if (!attr
->mp_nexthop_prefer_global
)
7554 json_object_boolean_true_add(
7555 json_nexthop_ll
, "used");
7557 json_object_boolean_true_add(
7558 json_nexthop_global
, "used");
7560 vty_out(vty
, " (%s) %s\n",
7562 &attr
->mp_nexthop_local
, buf
,
7564 attr
->mp_nexthop_prefer_global
7569 /* If we do not have a link-local nexthop then we must flag the
7573 json_object_boolean_true_add(
7574 json_nexthop_global
, "used");
7577 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
7578 * Int/Ext/Local, Atomic, best */
7580 json_object_string_add(
7581 json_path
, "origin",
7582 bgp_origin_long_str
[attr
->origin
]);
7584 vty_out(vty
, " Origin %s",
7585 bgp_origin_long_str
[attr
->origin
]);
7587 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)) {
7589 json_object_int_add(json_path
, "med",
7592 vty_out(vty
, ", metric %u", attr
->med
);
7595 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
7597 json_object_int_add(json_path
, "localpref",
7600 vty_out(vty
, ", localpref %u",
7604 json_object_int_add(json_path
, "localpref",
7605 bgp
->default_local_pref
);
7607 vty_out(vty
, ", localpref %u",
7608 bgp
->default_local_pref
);
7611 if (attr
->weight
!= 0) {
7613 json_object_int_add(json_path
, "weight",
7616 vty_out(vty
, ", weight %u", attr
->weight
);
7619 if (attr
->tag
!= 0) {
7621 json_object_int_add(json_path
, "tag",
7624 vty_out(vty
, ", tag %" ROUTE_TAG_PRI
,
7628 if (!CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)) {
7630 json_object_boolean_false_add(json_path
,
7633 vty_out(vty
, ", invalid");
7634 } else if (!CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
)) {
7636 json_object_boolean_true_add(json_path
,
7639 vty_out(vty
, ", valid");
7642 if (binfo
->peer
!= bgp
->peer_self
) {
7643 if (binfo
->peer
->as
== binfo
->peer
->local_as
) {
7644 if (CHECK_FLAG(bgp
->config
,
7645 BGP_CONFIG_CONFEDERATION
)) {
7647 json_object_string_add(
7652 ", confed-internal");
7655 json_object_string_add(
7659 vty_out(vty
, ", internal");
7662 if (bgp_confederation_peers_check(
7663 bgp
, binfo
->peer
->as
)) {
7665 json_object_string_add(
7670 ", confed-external");
7673 json_object_string_add(
7677 vty_out(vty
, ", external");
7680 } else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
) {
7682 json_object_boolean_true_add(json_path
,
7684 json_object_boolean_true_add(json_path
,
7687 vty_out(vty
, ", aggregated, local");
7689 } else if (binfo
->type
!= ZEBRA_ROUTE_BGP
) {
7691 json_object_boolean_true_add(json_path
,
7694 vty_out(vty
, ", sourced");
7697 json_object_boolean_true_add(json_path
,
7699 json_object_boolean_true_add(json_path
,
7702 vty_out(vty
, ", sourced, local");
7706 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
)) {
7708 json_object_boolean_true_add(json_path
,
7711 vty_out(vty
, ", atomic-aggregate");
7714 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_MULTIPATH
)
7715 || (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
)
7716 && bgp_info_mpath_count(binfo
))) {
7718 json_object_boolean_true_add(json_path
,
7721 vty_out(vty
, ", multipath");
7724 // Mark the bestpath(s)
7725 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DMED_SELECTED
)) {
7726 first_as
= aspath_get_first_as(attr
->aspath
);
7731 json_object_new_object();
7732 json_object_int_add(json_bestpath
,
7733 "bestpathFromAs", first_as
);
7736 vty_out(vty
, ", bestpath-from-AS %u",
7740 ", bestpath-from-AS Local");
7744 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
)) {
7748 json_object_new_object();
7749 json_object_boolean_true_add(json_bestpath
,
7752 vty_out(vty
, ", best");
7756 json_object_object_add(json_path
, "bestpath",
7762 /* Line 4 display Community */
7763 if (attr
->community
) {
7765 if (!attr
->community
->json
)
7766 community_str(attr
->community
, true);
7767 json_object_lock(attr
->community
->json
);
7768 json_object_object_add(json_path
, "community",
7769 attr
->community
->json
);
7771 vty_out(vty
, " Community: %s\n",
7772 attr
->community
->str
);
7776 /* Line 5 display Extended-community */
7777 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)) {
7779 json_ext_community
= json_object_new_object();
7780 json_object_string_add(json_ext_community
,
7782 attr
->ecommunity
->str
);
7783 json_object_object_add(json_path
,
7784 "extendedCommunity",
7785 json_ext_community
);
7787 vty_out(vty
, " Extended Community: %s\n",
7788 attr
->ecommunity
->str
);
7792 /* Line 6 display Large community */
7793 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
)) {
7795 json_lcommunity
= json_object_new_object();
7796 json_object_string_add(json_lcommunity
,
7798 attr
->lcommunity
->str
);
7799 json_object_object_add(json_path
,
7803 vty_out(vty
, " Large Community: %s\n",
7804 attr
->lcommunity
->str
);
7808 /* Line 7 display Originator, Cluster-id */
7809 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7810 || (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))) {
7812 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) {
7814 json_object_string_add(
7815 json_path
, "originatorId",
7816 inet_ntoa(attr
->originator_id
));
7818 vty_out(vty
, " Originator: %s",
7819 inet_ntoa(attr
->originator_id
));
7822 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)) {
7827 json_object_new_object();
7828 json_cluster_list_list
=
7829 json_object_new_array();
7832 i
< attr
->cluster
->length
/ 4;
7834 json_string
= json_object_new_string(
7838 json_object_array_add(
7839 json_cluster_list_list
,
7843 /* struct cluster_list does not have
7845 * aspath and community do. Add this
7848 json_object_string_add(json_cluster_list,
7849 "string", attr->cluster->str);
7851 json_object_object_add(
7852 json_cluster_list
, "list",
7853 json_cluster_list_list
);
7854 json_object_object_add(
7855 json_path
, "clusterList",
7858 vty_out(vty
, ", Cluster list: ");
7861 i
< attr
->cluster
->length
/ 4;
7875 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7876 bgp_damp_info_vty(vty
, binfo
, json_path
);
7879 #if defined(HAVE_CUMULUS)
7880 if (binfo
->extra
&& bgp_is_valid_label(&binfo
->extra
->label
[0])
7881 && safi
!= SAFI_EVPN
)
7883 if (binfo
->extra
&& bgp_is_valid_label(&binfo
->extra
->label
[0]))
7886 mpls_label_t label
=
7887 label_pton(&binfo
->extra
->label
[0]);
7889 json_object_int_add(json_path
, "remoteLabel",
7892 vty_out(vty
, " Remote label: %d\n", label
);
7896 if (attr
->label_index
!= BGP_INVALID_LABEL_INDEX
) {
7898 json_object_int_add(json_path
, "labelIndex",
7901 vty_out(vty
, " Label Index: %d\n",
7905 /* Line 8 display Addpath IDs */
7906 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
) {
7908 json_object_int_add(json_path
, "addpathRxId",
7909 binfo
->addpath_rx_id
);
7910 json_object_int_add(json_path
, "addpathTxId",
7911 binfo
->addpath_tx_id
);
7913 vty_out(vty
, " AddPath ID: RX %u, TX %u\n",
7914 binfo
->addpath_rx_id
,
7915 binfo
->addpath_tx_id
);
7919 /* If we used addpath to TX a non-bestpath we need to display
7920 * "Advertised to" on a path-by-path basis */
7921 if (bgp
->addpath_tx_used
[afi
][safi
]) {
7924 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7926 bgp_addpath_encode_tx(peer
, afi
, safi
);
7927 has_adj
= bgp_adj_out_lookup(
7928 peer
, binfo
->net
, binfo
->addpath_tx_id
);
7930 if ((addpath_capable
&& has_adj
)
7931 || (!addpath_capable
&& has_adj
7932 && CHECK_FLAG(binfo
->flags
,
7933 BGP_INFO_SELECTED
))) {
7934 if (json_path
&& !json_adv_to
)
7936 json_object_new_object();
7938 route_vty_out_advertised_to(
7947 json_object_object_add(json_path
,
7958 /* Line 9 display Uptime */
7959 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7961 json_last_update
= json_object_new_object();
7962 json_object_int_add(json_last_update
, "epoch", tbuf
);
7963 json_object_string_add(json_last_update
, "string",
7965 json_object_object_add(json_path
, "lastUpdate",
7968 vty_out(vty
, " Last update: %s", ctime(&tbuf
));
7970 /* Line 10 display PMSI tunnel attribute, if present */
7971 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL
)) {
7972 const char *str
= lookup_msg(bgp_pmsi_tnltype_str
,
7973 attr
->pmsi_tnl_type
,
7974 PMSI_TNLTYPE_STR_DEFAULT
);
7977 json_pmsi
= json_object_new_object();
7978 json_object_string_add(json_pmsi
,
7980 json_object_object_add(json_path
, "pmsi",
7983 vty_out(vty
, " PMSI Tunnel Type: %s\n",
7989 /* We've constructed the json object for this path, add it to the json
7993 if (json_nexthop_global
|| json_nexthop_ll
) {
7994 json_nexthops
= json_object_new_array();
7996 if (json_nexthop_global
)
7997 json_object_array_add(json_nexthops
,
7998 json_nexthop_global
);
8000 if (json_nexthop_ll
)
8001 json_object_array_add(json_nexthops
,
8004 json_object_object_add(json_path
, "nexthops",
8008 json_object_object_add(json_path
, "peer", json_peer
);
8009 json_object_array_add(json_paths
, json_path
);
8014 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
8015 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
8016 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
8018 static int bgp_show_prefix_list(struct vty
*vty
, struct bgp
*bgp
,
8019 const char *prefix_list_str
, afi_t afi
,
8020 safi_t safi
, enum bgp_show_type type
);
8021 static int bgp_show_filter_list(struct vty
*vty
, struct bgp
*bgp
,
8022 const char *filter
, afi_t afi
, safi_t safi
,
8023 enum bgp_show_type type
);
8024 static int bgp_show_route_map(struct vty
*vty
, struct bgp
*bgp
,
8025 const char *rmap_str
, afi_t afi
, safi_t safi
,
8026 enum bgp_show_type type
);
8027 static int bgp_show_community_list(struct vty
*vty
, struct bgp
*bgp
,
8028 const char *com
, int exact
, afi_t afi
,
8030 static int bgp_show_prefix_longer(struct vty
*vty
, struct bgp
*bgp
,
8031 const char *prefix
, afi_t afi
, safi_t safi
,
8032 enum bgp_show_type type
);
8033 static int bgp_show_regexp(struct vty
*vty
, struct bgp
*bgp
, const char *regstr
,
8034 afi_t afi
, safi_t safi
, enum bgp_show_type type
);
8035 static int bgp_show_community(struct vty
*vty
, struct bgp
*bgp
,
8036 const char *comstr
, int exact
, afi_t afi
,
8040 static int bgp_show_table(struct vty
*vty
, struct bgp
*bgp
, safi_t safi
,
8041 struct bgp_table
*table
, enum bgp_show_type type
,
8042 void *output_arg
, u_char use_json
, char *rd
,
8043 int is_last
, unsigned long *output_cum
,
8044 unsigned long *total_cum
,
8045 unsigned long *json_header_depth
)
8047 struct bgp_info
*ri
;
8048 struct bgp_node
*rn
;
8051 unsigned long output_count
= 0;
8052 unsigned long total_count
= 0;
8056 json_object
*json_paths
= NULL
;
8059 if (output_cum
&& *output_cum
!= 0)
8062 if (use_json
&& !*json_header_depth
) {
8064 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
8065 ",\n \"routerId\": \"%s\",\n \"routes\": { ",
8066 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : (int)bgp
->vrf_id
,
8067 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default"
8069 table
->version
, inet_ntoa(bgp
->router_id
));
8070 *json_header_depth
= 2;
8072 vty_out(vty
, " \"routeDistinguishers\" : {");
8073 ++*json_header_depth
;
8075 json_paths
= json_object_new_object();
8078 if (use_json
&& rd
) {
8079 vty_out(vty
, " \"%s\" : { ", rd
);
8082 /* Start processing of routes. */
8083 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
8084 if (rn
->info
== NULL
)
8089 json_paths
= json_object_new_array();
8093 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
8095 if (type
== bgp_show_type_flap_statistics
8096 || type
== bgp_show_type_flap_neighbor
8097 || type
== bgp_show_type_dampend_paths
8098 || type
== bgp_show_type_damp_neighbor
) {
8099 if (!(ri
->extra
&& ri
->extra
->damp_info
))
8102 if (type
== bgp_show_type_regexp
) {
8103 regex_t
*regex
= output_arg
;
8105 if (bgp_regexec(regex
, ri
->attr
->aspath
)
8109 if (type
== bgp_show_type_prefix_list
) {
8110 struct prefix_list
*plist
= output_arg
;
8112 if (prefix_list_apply(plist
, &rn
->p
)
8116 if (type
== bgp_show_type_filter_list
) {
8117 struct as_list
*as_list
= output_arg
;
8119 if (as_list_apply(as_list
, ri
->attr
->aspath
)
8120 != AS_FILTER_PERMIT
)
8123 if (type
== bgp_show_type_route_map
) {
8124 struct route_map
*rmap
= output_arg
;
8125 struct bgp_info binfo
;
8126 struct attr dummy_attr
;
8129 bgp_attr_dup(&dummy_attr
, ri
->attr
);
8131 binfo
.peer
= ri
->peer
;
8132 binfo
.attr
= &dummy_attr
;
8134 ret
= route_map_apply(rmap
, &rn
->p
, RMAP_BGP
,
8136 if (ret
== RMAP_DENYMATCH
)
8139 if (type
== bgp_show_type_neighbor
8140 || type
== bgp_show_type_flap_neighbor
8141 || type
== bgp_show_type_damp_neighbor
) {
8142 union sockunion
*su
= output_arg
;
8144 if (ri
->peer
== NULL
8145 || ri
->peer
->su_remote
== NULL
8146 || !sockunion_same(ri
->peer
->su_remote
, su
))
8149 if (type
== bgp_show_type_cidr_only
) {
8150 u_int32_t destination
;
8152 destination
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
8153 if (IN_CLASSC(destination
)
8154 && rn
->p
.prefixlen
== 24)
8156 if (IN_CLASSB(destination
)
8157 && rn
->p
.prefixlen
== 16)
8159 if (IN_CLASSA(destination
)
8160 && rn
->p
.prefixlen
== 8)
8163 if (type
== bgp_show_type_prefix_longer
) {
8164 struct prefix
*p
= output_arg
;
8166 if (!prefix_match(p
, &rn
->p
))
8169 if (type
== bgp_show_type_community_all
) {
8170 if (!ri
->attr
->community
)
8173 if (type
== bgp_show_type_community
) {
8174 struct community
*com
= output_arg
;
8176 if (!ri
->attr
->community
8177 || !community_match(ri
->attr
->community
,
8181 if (type
== bgp_show_type_community_exact
) {
8182 struct community
*com
= output_arg
;
8184 if (!ri
->attr
->community
8185 || !community_cmp(ri
->attr
->community
, com
))
8188 if (type
== bgp_show_type_community_list
) {
8189 struct community_list
*list
= output_arg
;
8191 if (!community_list_match(ri
->attr
->community
,
8195 if (type
== bgp_show_type_community_list_exact
) {
8196 struct community_list
*list
= output_arg
;
8198 if (!community_list_exact_match(
8199 ri
->attr
->community
, list
))
8202 if (type
== bgp_show_type_lcommunity
) {
8203 struct lcommunity
*lcom
= output_arg
;
8205 if (!ri
->attr
->lcommunity
8206 || !lcommunity_match(ri
->attr
->lcommunity
,
8210 if (type
== bgp_show_type_lcommunity_list
) {
8211 struct community_list
*list
= output_arg
;
8213 if (!lcommunity_list_match(ri
->attr
->lcommunity
,
8217 if (type
== bgp_show_type_lcommunity_all
) {
8218 if (!ri
->attr
->lcommunity
)
8221 if (type
== bgp_show_type_dampend_paths
8222 || type
== bgp_show_type_damp_neighbor
) {
8223 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_DAMPED
)
8224 || CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
8228 if (!use_json
&& header
) {
8229 vty_out(vty
, "BGP table version is %" PRIu64
8230 ", local router ID is %s\n",
8232 inet_ntoa(bgp
->router_id
));
8233 vty_out(vty
, BGP_SHOW_SCODE_HEADER
);
8234 vty_out(vty
, BGP_SHOW_OCODE_HEADER
);
8235 if (type
== bgp_show_type_dampend_paths
8236 || type
== bgp_show_type_damp_neighbor
)
8237 vty_out(vty
, BGP_SHOW_DAMP_HEADER
);
8238 else if (type
== bgp_show_type_flap_statistics
8239 || type
== bgp_show_type_flap_neighbor
)
8240 vty_out(vty
, BGP_SHOW_FLAP_HEADER
);
8242 vty_out(vty
, BGP_SHOW_HEADER
);
8245 if (rd
!= NULL
&& !display
&& !output_count
) {
8248 "Route Distinguisher: %s\n",
8251 if (type
== bgp_show_type_dampend_paths
8252 || type
== bgp_show_type_damp_neighbor
)
8253 damp_route_vty_out(vty
, &rn
->p
, ri
, display
,
8254 safi
, use_json
, json_paths
);
8255 else if (type
== bgp_show_type_flap_statistics
8256 || type
== bgp_show_type_flap_neighbor
)
8257 flap_route_vty_out(vty
, &rn
->p
, ri
, display
,
8258 safi
, use_json
, json_paths
);
8260 route_vty_out(vty
, &rn
->p
, ri
, display
, safi
,
8271 sprintf(buf2
, "%s/%d",
8272 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
8275 vty_out(vty
, "\"%s\": ", buf2
);
8277 vty_out(vty
, ",\"%s\": ", buf2
);
8280 json_object_to_json_string(json_paths
));
8281 json_object_free(json_paths
);
8288 output_count
+= *output_cum
;
8289 *output_cum
= output_count
;
8292 total_count
+= *total_cum
;
8293 *total_cum
= total_count
;
8297 json_object_free(json_paths
);
8299 vty_out(vty
, " }%s ", (is_last
? "" : ","));
8303 for (i
= 0; i
< *json_header_depth
; ++i
)
8304 vty_out(vty
, " } ");
8308 /* No route is displayed */
8309 if (output_count
== 0) {
8310 if (type
== bgp_show_type_normal
)
8312 "No BGP prefixes displayed, %ld exist\n",
8316 "\nDisplayed %ld routes and %ld total paths\n",
8317 output_count
, total_count
);
8324 int bgp_show_table_rd(struct vty
*vty
, struct bgp
*bgp
, safi_t safi
,
8325 struct bgp_table
*table
, struct prefix_rd
*prd_match
,
8326 enum bgp_show_type type
, void *output_arg
,
8329 struct bgp_node
*rn
, *next
;
8330 unsigned long output_cum
= 0;
8331 unsigned long total_cum
= 0;
8332 unsigned long json_header_depth
= 0;
8335 show_msg
= (!use_json
&& type
== bgp_show_type_normal
);
8337 for (rn
= bgp_table_top(table
); rn
; rn
= next
) {
8338 next
= bgp_route_next(rn
);
8339 if (prd_match
&& memcmp(rn
->p
.u
.val
, prd_match
->val
, 8) != 0)
8341 if (rn
->info
!= NULL
) {
8342 struct prefix_rd prd
;
8343 char rd
[RD_ADDRSTRLEN
];
8345 memcpy(&prd
, &(rn
->p
), sizeof(struct prefix_rd
));
8346 prefix_rd2str(&prd
, rd
, sizeof(rd
));
8347 bgp_show_table(vty
, bgp
, safi
, rn
->info
, type
,
8348 output_arg
, use_json
, rd
, next
== NULL
,
8349 &output_cum
, &total_cum
,
8350 &json_header_depth
);
8356 if (output_cum
== 0)
8357 vty_out(vty
, "No BGP prefixes displayed, %ld exist\n",
8361 "\nDisplayed %ld routes and %ld total paths\n",
8362 output_cum
, total_cum
);
8366 static int bgp_show(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
8367 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
8369 struct bgp_table
*table
;
8370 unsigned long json_header_depth
= 0;
8373 bgp
= bgp_get_default();
8378 vty_out(vty
, "No BGP process is configured\n");
8380 vty_out(vty
, "{}\n");
8384 table
= bgp
->rib
[afi
][safi
];
8385 /* use MPLS and ENCAP specific shows until they are merged */
8386 if (safi
== SAFI_MPLS_VPN
) {
8387 return bgp_show_table_rd(vty
, bgp
, safi
, table
, NULL
, type
,
8388 output_arg
, use_json
);
8390 /* labeled-unicast routes live in the unicast table */
8391 else if (safi
== SAFI_LABELED_UNICAST
)
8392 safi
= SAFI_UNICAST
;
8394 return bgp_show_table(vty
, bgp
, safi
, table
, type
, output_arg
, use_json
,
8395 NULL
, 1, NULL
, NULL
, &json_header_depth
);
8398 static void bgp_show_all_instances_routes_vty(struct vty
*vty
, afi_t afi
,
8399 safi_t safi
, u_char use_json
)
8401 struct listnode
*node
, *nnode
;
8406 vty_out(vty
, "{\n");
8408 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
8411 vty_out(vty
, ",\n");
8415 vty_out(vty
, "\"%s\":",
8416 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8420 vty_out(vty
, "\nInstance %s:\n",
8421 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8425 bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_normal
, NULL
,
8430 vty_out(vty
, "}\n");
8433 /* Header of detailed BGP route information */
8434 void route_vty_out_detail_header(struct vty
*vty
, struct bgp
*bgp
,
8435 struct bgp_node
*rn
, struct prefix_rd
*prd
,
8436 afi_t afi
, safi_t safi
, json_object
*json
)
8438 struct bgp_info
*ri
;
8441 struct listnode
*node
, *nnode
;
8442 char buf1
[RD_ADDRSTRLEN
];
8443 char buf2
[INET6_ADDRSTRLEN
];
8444 #if defined(HAVE_CUMULUS)
8445 char buf3
[EVPN_ROUTE_STRLEN
];
8447 char prefix_str
[BUFSIZ
];
8452 int no_advertise
= 0;
8455 int has_valid_label
= 0;
8456 mpls_label_t label
= 0;
8457 json_object
*json_adv_to
= NULL
;
8460 has_valid_label
= bgp_is_valid_label(&rn
->local_label
);
8462 if (has_valid_label
)
8463 label
= label_pton(&rn
->local_label
);
8466 if (has_valid_label
)
8467 json_object_int_add(json
, "localLabel", label
);
8469 json_object_string_add(
8471 prefix2str(p
, prefix_str
, sizeof(prefix_str
)));
8473 #if defined(HAVE_CUMULUS)
8474 if (safi
== SAFI_EVPN
)
8475 vty_out(vty
, "BGP routing table entry for %s%s%s\n",
8476 prd
? prefix_rd2str(prd
, buf1
, sizeof(buf1
))
8479 bgp_evpn_route2str((struct prefix_evpn
*)p
,
8480 buf3
, sizeof(buf3
)));
8482 vty_out(vty
, "BGP routing table entry for %s%s%s/%d\n",
8483 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
8484 ? prefix_rd2str(prd
, buf1
,
8487 safi
== SAFI_MPLS_VPN
? ":" : "",
8488 inet_ntop(p
->family
, &p
->u
.prefix
, buf2
,
8492 if (p
->family
== AF_ETHERNET
)
8493 prefix2str(p
, buf2
, INET6_ADDRSTRLEN
);
8495 inet_ntop(p
->family
, &p
->u
.prefix
, buf2
,
8497 vty_out(vty
, "BGP routing table entry for %s%s%s/%d\n",
8498 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
8499 || safi
== SAFI_EVPN
)
8500 ? prefix_rd2str(prd
, buf1
, sizeof(buf1
))
8502 ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
)) ? ":"
8504 buf2
, p
->prefixlen
);
8507 if (has_valid_label
)
8508 vty_out(vty
, "Local label: %d\n", label
);
8509 #if defined(HAVE_CUMULUS)
8510 if (bgp_labeled_safi(safi
) && safi
!= SAFI_EVPN
)
8512 if (bgp_labeled_safi(safi
))
8514 vty_out(vty
, "not allocated\n");
8517 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
8519 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
8521 if (ri
->extra
&& ri
->extra
->suppress
)
8523 if (ri
->attr
->community
!= NULL
) {
8524 if (community_include(ri
->attr
->community
,
8525 COMMUNITY_NO_ADVERTISE
))
8527 if (community_include(ri
->attr
->community
,
8528 COMMUNITY_NO_EXPORT
))
8530 if (community_include(ri
->attr
->community
,
8531 COMMUNITY_LOCAL_AS
))
8538 vty_out(vty
, "Paths: (%d available", count
);
8540 vty_out(vty
, ", best #%d", best
);
8541 if (safi
== SAFI_UNICAST
)
8542 vty_out(vty
, ", table %s",
8544 == BGP_INSTANCE_TYPE_DEFAULT
)
8545 ? "Default-IP-Routing-Table"
8548 vty_out(vty
, ", no best path");
8551 vty_out(vty
, ", not advertised to any peer");
8553 vty_out(vty
, ", not advertised to EBGP peer");
8555 vty_out(vty
, ", not advertised outside local AS");
8559 ", Advertisements suppressed by an aggregate.");
8560 vty_out(vty
, ")\n");
8563 /* If we are not using addpath then we can display Advertised to and
8565 * show what peers we advertised the bestpath to. If we are using
8567 * though then we must display Advertised to on a path-by-path basis. */
8568 if (!bgp
->addpath_tx_used
[afi
][safi
]) {
8569 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
8570 if (bgp_adj_out_lookup(peer
, rn
, 0)) {
8571 if (json
&& !json_adv_to
)
8572 json_adv_to
= json_object_new_object();
8574 route_vty_out_advertised_to(
8576 " Advertised to non peer-group peers:\n ",
8583 json_object_object_add(json
, "advertisedTo",
8588 vty_out(vty
, " Not advertised to any peer");
8594 /* Display specified route of BGP table. */
8595 static int bgp_show_route_in_table(struct vty
*vty
, struct bgp
*bgp
,
8596 struct bgp_table
*rib
, const char *ip_str
,
8597 afi_t afi
, safi_t safi
,
8598 struct prefix_rd
*prd
, int prefix_check
,
8599 enum bgp_path_type pathtype
, u_char use_json
)
8604 struct prefix match
;
8605 struct bgp_node
*rn
;
8606 struct bgp_node
*rm
;
8607 struct bgp_info
*ri
;
8608 struct bgp_table
*table
;
8609 json_object
*json
= NULL
;
8610 json_object
*json_paths
= NULL
;
8612 /* Check IP address argument. */
8613 ret
= str2prefix(ip_str
, &match
);
8615 vty_out(vty
, "address is malformed\n");
8619 match
.family
= afi2family(afi
);
8622 json
= json_object_new_object();
8623 json_paths
= json_object_new_array();
8626 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) {
8627 for (rn
= bgp_table_top(rib
); rn
; rn
= bgp_route_next(rn
)) {
8628 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
8631 if ((table
= rn
->info
) == NULL
)
8636 if ((rm
= bgp_node_match(table
, &match
)) == NULL
)
8640 && rm
->p
.prefixlen
!= match
.prefixlen
) {
8641 bgp_unlock_node(rm
);
8645 for (ri
= rm
->info
; ri
; ri
= ri
->next
) {
8647 route_vty_out_detail_header(
8649 (struct prefix_rd
*)&rn
->p
,
8650 AFI_IP
, safi
, json
);
8655 if (pathtype
== BGP_PATH_ALL
8656 || (pathtype
== BGP_PATH_BESTPATH
8657 && CHECK_FLAG(ri
->flags
,
8659 || (pathtype
== BGP_PATH_MULTIPATH
8660 && (CHECK_FLAG(ri
->flags
,
8662 || CHECK_FLAG(ri
->flags
,
8663 BGP_INFO_SELECTED
))))
8664 route_vty_out_detail(vty
, bgp
, &rm
->p
,
8669 bgp_unlock_node(rm
);
8674 if ((rn
= bgp_node_match(rib
, &match
)) != NULL
) {
8676 || rn
->p
.prefixlen
== match
.prefixlen
) {
8677 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
8679 route_vty_out_detail_header(
8680 vty
, bgp
, rn
, NULL
, afi
,
8686 if (pathtype
== BGP_PATH_ALL
8687 || (pathtype
== BGP_PATH_BESTPATH
8691 || (pathtype
== BGP_PATH_MULTIPATH
8697 BGP_INFO_SELECTED
))))
8698 route_vty_out_detail(
8699 vty
, bgp
, &rn
->p
, ri
,
8700 afi
, safi
, json_paths
);
8704 bgp_unlock_node(rn
);
8710 json_object_object_add(json
, "paths", json_paths
);
8712 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8713 json
, JSON_C_TO_STRING_PRETTY
));
8714 json_object_free(json
);
8717 vty_out(vty
, "%% Network not in table\n");
8725 /* Display specified route of Main RIB */
8726 static int bgp_show_route(struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
8727 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8728 int prefix_check
, enum bgp_path_type pathtype
,
8732 bgp
= bgp_get_default();
8735 vty_out(vty
, "No BGP process is configured\n");
8737 vty_out(vty
, "{}\n");
8742 /* labeled-unicast routes live in the unicast table */
8743 if (safi
== SAFI_LABELED_UNICAST
)
8744 safi
= SAFI_UNICAST
;
8746 return bgp_show_route_in_table(vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
8747 afi
, safi
, prd
, prefix_check
, pathtype
,
8751 static int bgp_show_lcommunity(struct vty
*vty
, struct bgp
*bgp
, int argc
,
8752 struct cmd_token
**argv
, afi_t afi
, safi_t safi
,
8755 struct lcommunity
*lcom
;
8761 b
= buffer_new(1024);
8762 for (i
= 0; i
< argc
; i
++) {
8764 buffer_putc(b
, ' ');
8766 if (strmatch(argv
[i
]->text
, "AA:BB:CC")) {
8768 buffer_putstr(b
, argv
[i
]->arg
);
8772 buffer_putc(b
, '\0');
8774 str
= buffer_getstr(b
);
8777 lcom
= lcommunity_str2com(str
);
8778 XFREE(MTYPE_TMP
, str
);
8780 vty_out(vty
, "%% Large-community malformed\n");
8784 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
,
8788 static int bgp_show_lcommunity_list(struct vty
*vty
, struct bgp
*bgp
,
8789 const char *lcom
, afi_t afi
, safi_t safi
,
8792 struct community_list
*list
;
8794 list
= community_list_lookup(bgp_clist
, lcom
,
8795 LARGE_COMMUNITY_LIST_MASTER
);
8797 vty_out(vty
, "%% %s is not a valid large-community-list name\n",
8802 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
,
8806 DEFUN (show_ip_bgp_large_community_list
,
8807 show_ip_bgp_large_community_list_cmd
,
8808 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community-list <(1-500)|WORD> [json]",
8812 BGP_INSTANCE_HELP_STR
8814 BGP_SAFI_WITH_LABEL_HELP_STR
8815 "Display routes matching the large-community-list\n"
8816 "large-community-list number\n"
8817 "large-community-list name\n"
8821 afi_t afi
= AFI_IP6
;
8822 safi_t safi
= SAFI_UNICAST
;
8825 if (argv_find(argv
, argc
, "ip", &idx
))
8827 if (argv_find(argv
, argc
, "view", &idx
)
8828 || argv_find(argv
, argc
, "vrf", &idx
))
8829 vrf
= argv
[++idx
]->arg
;
8830 if (argv_find(argv
, argc
, "ipv4", &idx
)
8831 || argv_find(argv
, argc
, "ipv6", &idx
)) {
8832 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8833 if (argv_find(argv
, argc
, "unicast", &idx
)
8834 || argv_find(argv
, argc
, "multicast", &idx
))
8835 safi
= bgp_vty_safi_from_str(argv
[idx
]->text
);
8838 int uj
= use_json(argc
, argv
);
8840 struct bgp
*bgp
= bgp_lookup_by_name(vrf
);
8842 vty_out(vty
, "Can't find BGP instance %s\n", vrf
);
8846 argv_find(argv
, argc
, "large-community-list", &idx
);
8847 return bgp_show_lcommunity_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
,
8850 DEFUN (show_ip_bgp_large_community
,
8851 show_ip_bgp_large_community_cmd
,
8852 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community [AA:BB:CC] [json]",
8856 BGP_INSTANCE_HELP_STR
8858 BGP_SAFI_WITH_LABEL_HELP_STR
8859 "Display routes matching the large-communities\n"
8860 "List of large-community numbers\n"
8864 afi_t afi
= AFI_IP6
;
8865 safi_t safi
= SAFI_UNICAST
;
8868 if (argv_find(argv
, argc
, "ip", &idx
))
8870 if (argv_find(argv
, argc
, "view", &idx
)
8871 || argv_find(argv
, argc
, "vrf", &idx
))
8872 vrf
= argv
[++idx
]->arg
;
8873 if (argv_find(argv
, argc
, "ipv4", &idx
)
8874 || argv_find(argv
, argc
, "ipv6", &idx
)) {
8875 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8876 if (argv_find(argv
, argc
, "unicast", &idx
)
8877 || argv_find(argv
, argc
, "multicast", &idx
))
8878 safi
= bgp_vty_safi_from_str(argv
[idx
]->text
);
8881 int uj
= use_json(argc
, argv
);
8883 struct bgp
*bgp
= bgp_lookup_by_name(vrf
);
8885 vty_out(vty
, "Can't find BGP instance %s\n", vrf
);
8889 if (argv_find(argv
, argc
, "AA:BB:CC", &idx
))
8890 return bgp_show_lcommunity(vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
8892 return bgp_show(vty
, bgp
, afi
, safi
,
8893 bgp_show_type_lcommunity_all
, NULL
, uj
);
8896 static int bgp_table_stats(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
8900 /* BGP route print out function without JSON */
8903 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
8904 <dampening <parameters>\
8909 |community <AA:NN|local-AS|no-advertise|no-export|graceful-shutdown> [exact-match]\
8910 |community-list <(1-500)|WORD> [exact-match]\
8911 |A.B.C.D/M longer-prefixes\
8912 |X:X::X:X/M longer-prefixes\
8917 BGP_INSTANCE_HELP_STR
8919 BGP_SAFI_WITH_LABEL_HELP_STR
8920 "Display detailed information about dampening\n"
8921 "Display detail of configured dampening parameters\n"
8922 "Display routes matching the route-map\n"
8923 "A route-map to match on\n"
8924 "Display routes conforming to the prefix-list\n"
8925 "Prefix-list name\n"
8926 "Display routes conforming to the filter-list\n"
8927 "Regular expression access list name\n"
8928 "BGP RIB advertisement statistics\n"
8929 "Display routes matching the communities\n"
8931 "Do not send outside local AS (well-known community)\n"
8932 "Do not advertise to any peer (well-known community)\n"
8933 "Do not export to next AS (well-known community)\n"
8934 "Graceful shutdown (well-known community)\n"
8935 "Exact match of the communities\n"
8936 "Display routes matching the community-list\n"
8937 "community-list number\n"
8938 "community-list name\n"
8939 "Exact match of the communities\n"
8941 "Display route and more specific routes\n"
8943 "Display route and more specific routes\n")
8945 afi_t afi
= AFI_IP6
;
8946 safi_t safi
= SAFI_UNICAST
;
8947 int exact_match
= 0;
8948 struct bgp
*bgp
= NULL
;
8950 int idx_community_type
= 0;
8952 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
8957 if (argv_find(argv
, argc
, "dampening", &idx
)) {
8958 if (argv_find(argv
, argc
, "parameters", &idx
))
8959 return bgp_show_dampening_parameters(vty
, afi
, safi
);
8962 if (argv_find(argv
, argc
, "prefix-list", &idx
))
8963 return bgp_show_prefix_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
8964 safi
, bgp_show_type_prefix_list
);
8966 if (argv_find(argv
, argc
, "filter-list", &idx
))
8967 return bgp_show_filter_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
8968 safi
, bgp_show_type_filter_list
);
8970 if (argv_find(argv
, argc
, "statistics", &idx
))
8971 return bgp_table_stats(vty
, bgp
, afi
, safi
);
8973 if (argv_find(argv
, argc
, "route-map", &idx
))
8974 return bgp_show_route_map(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
8975 safi
, bgp_show_type_route_map
);
8977 if (argv_find(argv
, argc
, "community", &idx
)) {
8978 /* show a specific community */
8979 if (argv_find(argv
, argc
, "local-AS", &idx_community_type
)
8980 || argv_find(argv
, argc
, "no-advertise",
8981 &idx_community_type
)
8982 || argv_find(argv
, argc
, "no-export", &idx_community_type
)
8983 || argv_find(argv
, argc
, "graceful-shutdown",
8984 &idx_community_type
)
8985 || argv_find(argv
, argc
, "AA:NN", &idx_community_type
)) {
8987 if (argv_find(argv
, argc
, "exact-match", &idx
))
8989 return bgp_show_community(vty
, bgp
,
8990 argv
[idx_community_type
]->arg
,
8991 exact_match
, afi
, safi
);
8995 if (argv_find(argv
, argc
, "community-list", &idx
)) {
8996 const char *clist_number_or_name
= argv
[++idx
]->arg
;
8997 if (++idx
< argc
&& strmatch(argv
[idx
]->text
, "exact-match"))
8999 return bgp_show_community_list(vty
, bgp
, clist_number_or_name
,
9000 exact_match
, afi
, safi
);
9003 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)
9004 || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
9005 return bgp_show_prefix_longer(vty
, bgp
, argv
[idx
]->arg
, afi
,
9007 bgp_show_type_prefix_longer
);
9012 /* BGP route print out function with JSON */
9013 DEFUN (show_ip_bgp_json
,
9014 show_ip_bgp_json_cmd
,
9015 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
9018 |dampening <flap-statistics|dampened-paths>\
9024 BGP_INSTANCE_HELP_STR
9026 BGP_SAFI_WITH_LABEL_HELP_STR
9027 "Display only routes with non-natural netmasks\n"
9028 "Display detailed information about dampening\n"
9029 "Display flap statistics of routes\n"
9030 "Display paths suppressed due to dampening\n"
9031 "Display routes matching the communities\n"
9034 afi_t afi
= AFI_IP6
;
9035 safi_t safi
= SAFI_UNICAST
;
9036 enum bgp_show_type sh_type
= bgp_show_type_normal
;
9037 struct bgp
*bgp
= NULL
;
9040 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9045 int uj
= use_json(argc
, argv
);
9049 if (argv_find(argv
, argc
, "cidr-only", &idx
))
9050 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
,
9053 if (argv_find(argv
, argc
, "dampening", &idx
)) {
9054 if (argv_find(argv
, argc
, "dampened-paths", &idx
))
9055 return bgp_show(vty
, bgp
, afi
, safi
,
9056 bgp_show_type_dampend_paths
, NULL
, uj
);
9057 else if (argv_find(argv
, argc
, "flap-statistics", &idx
))
9058 return bgp_show(vty
, bgp
, afi
, safi
,
9059 bgp_show_type_flap_statistics
, NULL
,
9063 if (argv_find(argv
, argc
, "community", &idx
)) {
9064 /* show all communities */
9065 return bgp_show(vty
, bgp
, afi
, safi
,
9066 bgp_show_type_community_all
, NULL
, uj
);
9068 return bgp_show(vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
9071 DEFUN (show_ip_bgp_route
,
9072 show_ip_bgp_route_cmd
,
9073 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]"
9074 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
9078 BGP_INSTANCE_HELP_STR
9080 BGP_SAFI_WITH_LABEL_HELP_STR
9081 "Network in the BGP routing table to display\n"
9083 "Network in the BGP routing table to display\n"
9085 "Display only the bestpath\n"
9086 "Display only multipaths\n"
9089 int prefix_check
= 0;
9091 afi_t afi
= AFI_IP6
;
9092 safi_t safi
= SAFI_UNICAST
;
9093 char *prefix
= NULL
;
9094 struct bgp
*bgp
= NULL
;
9095 enum bgp_path_type path_type
;
9096 u_char uj
= use_json(argc
, argv
);
9100 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9107 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
9111 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
9112 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)
9113 || argv_find(argv
, argc
, "X:X::X:X", &idx
))
9115 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)
9116 || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
9119 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
)
9120 && afi
!= AFI_IP6
) {
9122 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
9125 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
)
9128 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
9132 prefix
= argv
[idx
]->arg
;
9134 /* [<bestpath|multipath>] */
9135 if (argv_find(argv
, argc
, "bestpath", &idx
))
9136 path_type
= BGP_PATH_BESTPATH
;
9137 else if (argv_find(argv
, argc
, "multipath", &idx
))
9138 path_type
= BGP_PATH_MULTIPATH
;
9140 path_type
= BGP_PATH_ALL
;
9142 return bgp_show_route(vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
,
9146 DEFUN (show_ip_bgp_regexp
,
9147 show_ip_bgp_regexp_cmd
,
9148 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] regexp REGEX...",
9152 BGP_INSTANCE_HELP_STR
9154 BGP_SAFI_WITH_LABEL_HELP_STR
9155 "Display routes matching the AS path regular expression\n"
9156 "A regular-expression to match the BGP AS paths\n")
9158 afi_t afi
= AFI_IP6
;
9159 safi_t safi
= SAFI_UNICAST
;
9160 struct bgp
*bgp
= NULL
;
9163 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9168 // get index of regex
9169 argv_find(argv
, argc
, "regexp", &idx
);
9172 char *regstr
= argv_concat(argv
, argc
, idx
);
9173 int rc
= bgp_show_regexp(vty
, bgp
, (const char *)regstr
, afi
, safi
,
9174 bgp_show_type_regexp
);
9175 XFREE(MTYPE_TMP
, regstr
);
9179 DEFUN (show_ip_bgp_instance_all
,
9180 show_ip_bgp_instance_all_cmd
,
9181 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] [json]",
9185 BGP_INSTANCE_ALL_HELP_STR
9187 BGP_SAFI_WITH_LABEL_HELP_STR
9191 safi_t safi
= SAFI_UNICAST
;
9192 struct bgp
*bgp
= NULL
;
9195 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9200 int uj
= use_json(argc
, argv
);
9204 bgp_show_all_instances_routes_vty(vty
, afi
, safi
, uj
);
9208 static int bgp_show_regexp(struct vty
*vty
, struct bgp
*bgp
, const char *regstr
,
9209 afi_t afi
, safi_t safi
, enum bgp_show_type type
)
9214 regex
= bgp_regcomp(regstr
);
9216 vty_out(vty
, "Can't compile regexp %s\n", regstr
);
9220 rc
= bgp_show(vty
, bgp
, afi
, safi
, type
, regex
, 0);
9221 bgp_regex_free(regex
);
9225 static int bgp_show_prefix_list(struct vty
*vty
, struct bgp
*bgp
,
9226 const char *prefix_list_str
, afi_t afi
,
9227 safi_t safi
, enum bgp_show_type type
)
9229 struct prefix_list
*plist
;
9231 plist
= prefix_list_lookup(afi
, prefix_list_str
);
9232 if (plist
== NULL
) {
9233 vty_out(vty
, "%% %s is not a valid prefix-list name\n",
9238 return bgp_show(vty
, bgp
, afi
, safi
, type
, plist
, 0);
9241 static int bgp_show_filter_list(struct vty
*vty
, struct bgp
*bgp
,
9242 const char *filter
, afi_t afi
, safi_t safi
,
9243 enum bgp_show_type type
)
9245 struct as_list
*as_list
;
9247 as_list
= as_list_lookup(filter
);
9248 if (as_list
== NULL
) {
9249 vty_out(vty
, "%% %s is not a valid AS-path access-list name\n",
9254 return bgp_show(vty
, bgp
, afi
, safi
, type
, as_list
, 0);
9257 static int bgp_show_route_map(struct vty
*vty
, struct bgp
*bgp
,
9258 const char *rmap_str
, afi_t afi
, safi_t safi
,
9259 enum bgp_show_type type
)
9261 struct route_map
*rmap
;
9263 rmap
= route_map_lookup_by_name(rmap_str
);
9265 vty_out(vty
, "%% %s is not a valid route-map name\n", rmap_str
);
9269 return bgp_show(vty
, bgp
, afi
, safi
, type
, rmap
, 0);
9272 static int bgp_show_community(struct vty
*vty
, struct bgp
*bgp
,
9273 const char *comstr
, int exact
, afi_t afi
,
9276 struct community
*com
;
9279 com
= community_str2com(comstr
);
9281 vty_out(vty
, "%% Community malformed: %s\n", comstr
);
9285 ret
= bgp_show(vty
, bgp
, afi
, safi
,
9286 (exact
? bgp_show_type_community_exact
9287 : bgp_show_type_community
),
9289 community_free(com
);
9294 static int bgp_show_community_list(struct vty
*vty
, struct bgp
*bgp
,
9295 const char *com
, int exact
, afi_t afi
,
9298 struct community_list
*list
;
9300 list
= community_list_lookup(bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
9302 vty_out(vty
, "%% %s is not a valid community-list name\n", com
);
9306 return bgp_show(vty
, bgp
, afi
, safi
,
9307 (exact
? bgp_show_type_community_list_exact
9308 : bgp_show_type_community_list
),
9312 static int bgp_show_prefix_longer(struct vty
*vty
, struct bgp
*bgp
,
9313 const char *prefix
, afi_t afi
, safi_t safi
,
9314 enum bgp_show_type type
)
9321 ret
= str2prefix(prefix
, p
);
9323 vty_out(vty
, "%% Malformed Prefix\n");
9327 ret
= bgp_show(vty
, bgp
, afi
, safi
, type
, p
, 0);
9332 static struct peer
*peer_lookup_in_view(struct vty
*vty
, struct bgp
*bgp
,
9333 const char *ip_str
, u_char use_json
)
9339 /* Get peer sockunion. */
9340 ret
= str2sockunion(ip_str
, &su
);
9342 peer
= peer_lookup_by_conf_if(bgp
, ip_str
);
9344 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
9348 json_object
*json_no
= NULL
;
9349 json_no
= json_object_new_object();
9350 json_object_string_add(
9352 "malformedAddressOrName",
9354 vty_out(vty
, "%s\n",
9355 json_object_to_json_string_ext(
9357 JSON_C_TO_STRING_PRETTY
));
9358 json_object_free(json_no
);
9361 "%% Malformed address or name: %s\n",
9369 /* Peer structure lookup. */
9370 peer
= peer_lookup(bgp
, &su
);
9373 json_object
*json_no
= NULL
;
9374 json_no
= json_object_new_object();
9375 json_object_string_add(json_no
, "warning",
9376 "No such neighbor");
9377 vty_out(vty
, "%s\n",
9378 json_object_to_json_string_ext(
9379 json_no
, JSON_C_TO_STRING_PRETTY
));
9380 json_object_free(json_no
);
9382 vty_out(vty
, "No such neighbor\n");
9390 BGP_STATS_MAXBITLEN
= 0,
9394 BGP_STATS_UNAGGREGATEABLE
,
9395 BGP_STATS_MAX_AGGREGATEABLE
,
9396 BGP_STATS_AGGREGATES
,
9398 BGP_STATS_ASPATH_COUNT
,
9399 BGP_STATS_ASPATH_MAXHOPS
,
9400 BGP_STATS_ASPATH_TOTHOPS
,
9401 BGP_STATS_ASPATH_MAXSIZE
,
9402 BGP_STATS_ASPATH_TOTSIZE
,
9403 BGP_STATS_ASN_HIGHEST
,
9407 static const char *table_stats_strs
[] = {
9408 [BGP_STATS_PREFIXES
] = "Total Prefixes",
9409 [BGP_STATS_TOTPLEN
] = "Average prefix length",
9410 [BGP_STATS_RIB
] = "Total Advertisements",
9411 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
9412 [BGP_STATS_MAX_AGGREGATEABLE
] =
9413 "Maximum aggregateable prefixes",
9414 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
9415 [BGP_STATS_SPACE
] = "Address space advertised",
9416 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
9417 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
9418 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
9419 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
9420 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
9421 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
9422 [BGP_STATS_MAX
] = NULL
,
9425 struct bgp_table_stats
{
9426 struct bgp_table
*table
;
9427 unsigned long long counts
[BGP_STATS_MAX
];
9432 #define TALLY_SIGFIG 100000
9433 static unsigned long
9434 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
9436 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
9437 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
9438 unsigned long ret
= newtot
/ count
;
9440 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
9447 static int bgp_table_stats_walker(struct thread
*t
)
9449 struct bgp_node
*rn
;
9450 struct bgp_node
*top
;
9451 struct bgp_table_stats
*ts
= THREAD_ARG(t
);
9452 unsigned int space
= 0;
9454 if (!(top
= bgp_table_top(ts
->table
)))
9457 switch (top
->p
.family
) {
9459 space
= IPV4_MAX_BITLEN
;
9462 space
= IPV6_MAX_BITLEN
;
9466 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
9468 for (rn
= top
; rn
; rn
= bgp_route_next(rn
)) {
9469 struct bgp_info
*ri
;
9470 struct bgp_node
*prn
= bgp_node_parent_nolock(rn
);
9471 unsigned int rinum
= 0;
9479 ts
->counts
[BGP_STATS_PREFIXES
]++;
9480 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
9483 ts
->counts
[BGP_STATS_AVGPLEN
]
9484 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
9485 ts
->counts
[BGP_STATS_AVGPLEN
],
9489 /* check if the prefix is included by any other announcements */
9490 while (prn
&& !prn
->info
)
9491 prn
= bgp_node_parent_nolock(prn
);
9493 if (prn
== NULL
|| prn
== top
) {
9494 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
9495 /* announced address space */
9498 pow(2.0, space
- rn
->p
.prefixlen
);
9499 } else if (prn
->info
)
9500 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
9502 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
9504 ts
->counts
[BGP_STATS_RIB
]++;
9507 && (CHECK_FLAG(ri
->attr
->flag
,
9509 BGP_ATTR_ATOMIC_AGGREGATE
))))
9510 ts
->counts
[BGP_STATS_AGGREGATES
]++;
9513 if (ri
->attr
&& ri
->attr
->aspath
) {
9515 aspath_count_hops(ri
->attr
->aspath
);
9517 aspath_size(ri
->attr
->aspath
);
9518 as_t highest
= aspath_highest(ri
->attr
->aspath
);
9520 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
9522 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
9523 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] =
9526 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
9527 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] =
9530 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
9531 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
9533 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
9534 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9535 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
9537 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
9538 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9539 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
9542 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
9543 ts
->counts
[BGP_STATS_ASN_HIGHEST
] =
9551 static int bgp_table_stats(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
9554 struct bgp_table_stats ts
;
9557 if (!bgp
->rib
[afi
][safi
]) {
9558 vty_out(vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
9563 vty_out(vty
, "BGP %s RIB statistics\n", afi_safi_print(afi
, safi
));
9565 /* labeled-unicast routes live in the unicast table */
9566 if (safi
== SAFI_LABELED_UNICAST
)
9567 safi
= SAFI_UNICAST
;
9569 memset(&ts
, 0, sizeof(ts
));
9570 ts
.table
= bgp
->rib
[afi
][safi
];
9571 thread_execute(bm
->master
, bgp_table_stats_walker
, &ts
, 0);
9573 for (i
= 0; i
< BGP_STATS_MAX
; i
++) {
9574 if (!table_stats_strs
[i
])
9579 case BGP_STATS_ASPATH_AVGHOPS
:
9580 case BGP_STATS_ASPATH_AVGSIZE
:
9581 case BGP_STATS_AVGPLEN
:
9582 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9583 vty_out (vty
, "%12.2f",
9584 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
9587 case BGP_STATS_ASPATH_TOTHOPS
:
9588 case BGP_STATS_ASPATH_TOTSIZE
:
9589 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9590 vty_out(vty
, "%12.2f",
9592 ? (float)ts
.counts
[i
]
9594 [BGP_STATS_ASPATH_COUNT
]
9597 case BGP_STATS_TOTPLEN
:
9598 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9599 vty_out(vty
, "%12.2f",
9601 ? (float)ts
.counts
[i
]
9603 [BGP_STATS_PREFIXES
]
9606 case BGP_STATS_SPACE
:
9607 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9608 vty_out(vty
, "%12g\n", ts
.total_space
);
9610 if (afi
== AFI_IP6
) {
9611 vty_out(vty
, "%30s: ", "/32 equivalent ");
9612 vty_out(vty
, "%12g\n",
9613 ts
.total_space
* pow(2.0, -128 + 32));
9614 vty_out(vty
, "%30s: ", "/48 equivalent ");
9615 vty_out(vty
, "%12g\n",
9616 ts
.total_space
* pow(2.0, -128 + 48));
9618 vty_out(vty
, "%30s: ", "% announced ");
9619 vty_out(vty
, "%12.2f\n",
9620 ts
.total_space
* 100. * pow(2.0, -32));
9621 vty_out(vty
, "%30s: ", "/8 equivalent ");
9622 vty_out(vty
, "%12.2f\n",
9623 ts
.total_space
* pow(2.0, -32 + 8));
9624 vty_out(vty
, "%30s: ", "/24 equivalent ");
9625 vty_out(vty
, "%12.2f\n",
9626 ts
.total_space
* pow(2.0, -32 + 24));
9630 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9631 vty_out(vty
, "%12llu", ts
.counts
[i
]);
9648 PCOUNT_PFCNT
, /* the figure we display to users */
9652 static const char *pcount_strs
[] = {
9653 [PCOUNT_ADJ_IN
] = "Adj-in",
9654 [PCOUNT_DAMPED
] = "Damped",
9655 [PCOUNT_REMOVED
] = "Removed",
9656 [PCOUNT_HISTORY
] = "History",
9657 [PCOUNT_STALE
] = "Stale",
9658 [PCOUNT_VALID
] = "Valid",
9659 [PCOUNT_ALL
] = "All RIB",
9660 [PCOUNT_COUNTED
] = "PfxCt counted",
9661 [PCOUNT_PFCNT
] = "Useable",
9662 [PCOUNT_MAX
] = NULL
,
9665 struct peer_pcounts
{
9666 unsigned int count
[PCOUNT_MAX
];
9667 const struct peer
*peer
;
9668 const struct bgp_table
*table
;
9671 static int bgp_peer_count_walker(struct thread
*t
)
9673 struct bgp_node
*rn
;
9674 struct peer_pcounts
*pc
= THREAD_ARG(t
);
9675 const struct peer
*peer
= pc
->peer
;
9677 for (rn
= bgp_table_top(pc
->table
); rn
; rn
= bgp_route_next(rn
)) {
9678 struct bgp_adj_in
*ain
;
9679 struct bgp_info
*ri
;
9681 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9682 if (ain
->peer
== peer
)
9683 pc
->count
[PCOUNT_ADJ_IN
]++;
9685 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
9686 char buf
[SU_ADDRSTRLEN
];
9688 if (ri
->peer
!= peer
)
9691 pc
->count
[PCOUNT_ALL
]++;
9693 if (CHECK_FLAG(ri
->flags
, BGP_INFO_DAMPED
))
9694 pc
->count
[PCOUNT_DAMPED
]++;
9695 if (CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
9696 pc
->count
[PCOUNT_HISTORY
]++;
9697 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
9698 pc
->count
[PCOUNT_REMOVED
]++;
9699 if (CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
))
9700 pc
->count
[PCOUNT_STALE
]++;
9701 if (CHECK_FLAG(ri
->flags
, BGP_INFO_VALID
))
9702 pc
->count
[PCOUNT_VALID
]++;
9703 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
9704 pc
->count
[PCOUNT_PFCNT
]++;
9706 if (CHECK_FLAG(ri
->flags
, BGP_INFO_COUNTED
)) {
9707 pc
->count
[PCOUNT_COUNTED
]++;
9708 if (CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
9710 "%s [pcount] %s/%d is counted but flags 0x%x",
9712 inet_ntop(rn
->p
.family
,
9713 &rn
->p
.u
.prefix
, buf
,
9715 rn
->p
.prefixlen
, ri
->flags
);
9717 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
9719 "%s [pcount] %s/%d not counted but flags 0x%x",
9721 inet_ntop(rn
->p
.family
,
9722 &rn
->p
.u
.prefix
, buf
,
9724 rn
->p
.prefixlen
, ri
->flags
);
9731 static int bgp_peer_counts(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9732 safi_t safi
, u_char use_json
)
9734 struct peer_pcounts pcounts
= {.peer
= peer
};
9736 json_object
*json
= NULL
;
9737 json_object
*json_loop
= NULL
;
9740 json
= json_object_new_object();
9741 json_loop
= json_object_new_object();
9744 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
9745 || !peer
->bgp
->rib
[afi
][safi
]) {
9747 json_object_string_add(
9749 "No such neighbor or address family");
9750 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
9751 json_object_free(json
);
9753 vty_out(vty
, "%% No such neighbor or address family\n");
9758 memset(&pcounts
, 0, sizeof(pcounts
));
9759 pcounts
.peer
= peer
;
9760 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
9762 /* in-place call via thread subsystem so as to record execution time
9763 * stats for the thread-walk (i.e. ensure this can't be blamed on
9764 * on just vty_read()).
9766 thread_execute(bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
9769 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
9770 json_object_string_add(json
, "multiProtocol",
9771 afi_safi_print(afi
, safi
));
9772 json_object_int_add(json
, "pfxCounter",
9773 peer
->pcount
[afi
][safi
]);
9775 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9776 json_object_int_add(json_loop
, pcount_strs
[i
],
9779 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
9781 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
]) {
9782 json_object_string_add(json
, "pfxctDriftFor",
9784 json_object_string_add(
9785 json
, "recommended",
9786 "Please report this bug, with the above command output");
9788 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9789 json
, JSON_C_TO_STRING_PRETTY
));
9790 json_object_free(json
);
9794 && bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
)) {
9795 vty_out(vty
, "Prefix counts for %s/%s, %s\n",
9796 peer
->hostname
, peer
->host
,
9797 afi_safi_print(afi
, safi
));
9799 vty_out(vty
, "Prefix counts for %s, %s\n", peer
->host
,
9800 afi_safi_print(afi
, safi
));
9803 vty_out(vty
, "PfxCt: %ld\n", peer
->pcount
[afi
][safi
]);
9804 vty_out(vty
, "\nCounts from RIB table walk:\n\n");
9806 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9807 vty_out(vty
, "%20s: %-10d\n", pcount_strs
[i
],
9810 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
]) {
9811 vty_out(vty
, "%s [pcount] PfxCt drift!\n", peer
->host
);
9813 "Please report this bug, with the above command output\n");
9820 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9821 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9822 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9823 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9827 BGP_INSTANCE_HELP_STR
9830 "Detailed information on TCP and BGP neighbor connections\n"
9831 "Neighbor to display information about\n"
9832 "Neighbor to display information about\n"
9833 "Neighbor on BGP configured interface\n"
9834 "Display detailed prefix count information\n"
9837 afi_t afi
= AFI_IP6
;
9838 safi_t safi
= SAFI_UNICAST
;
9841 struct bgp
*bgp
= NULL
;
9843 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9848 int uj
= use_json(argc
, argv
);
9852 argv_find(argv
, argc
, "neighbors", &idx
);
9853 peer
= peer_lookup_in_view(vty
, bgp
, argv
[idx
+ 1]->arg
, uj
);
9857 return bgp_peer_counts(vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9860 #ifdef KEEP_OLD_VPN_COMMANDS
9861 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
9862 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
9863 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9868 "Display information about all VPNv4 NLRIs\n"
9869 "Detailed information on TCP and BGP neighbor connections\n"
9870 "Neighbor to display information about\n"
9871 "Neighbor to display information about\n"
9872 "Neighbor on BGP configured interface\n"
9873 "Display detailed prefix count information\n"
9878 u_char uj
= use_json(argc
, argv
);
9880 peer
= peer_lookup_in_view(vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9884 return bgp_peer_counts(vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9887 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
9888 show_ip_bgp_vpn_all_route_prefix_cmd
,
9889 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9894 "Display information about all VPNv4 NLRIs\n"
9895 "Network in the BGP routing table to display\n"
9896 "Network in the BGP routing table to display\n"
9900 char *network
= NULL
;
9901 struct bgp
*bgp
= bgp_get_default();
9903 vty_out(vty
, "Can't find default instance\n");
9907 if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9908 network
= argv
[idx
]->arg
;
9909 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
))
9910 network
= argv
[idx
]->arg
;
9912 vty_out(vty
, "Unable to figure out Network\n");
9916 return bgp_show_route(vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0,
9917 BGP_PATH_ALL
, use_json(argc
, argv
));
9919 #endif /* KEEP_OLD_VPN_COMMANDS */
9921 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix
,
9922 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
,
9923 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
9929 "Display information about all EVPN NLRIs\n"
9930 "Network in the BGP routing table to display\n"
9931 "Network in the BGP routing table to display\n"
9935 char *network
= NULL
;
9937 if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9938 network
= argv
[idx
]->arg
;
9939 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
))
9940 network
= argv
[idx
]->arg
;
9942 vty_out(vty
, "Unable to figure out Network\n");
9945 return bgp_show_route(vty
, NULL
, network
, AFI_L2VPN
, SAFI_EVPN
, NULL
, 0,
9946 BGP_PATH_ALL
, use_json(argc
, argv
));
9949 static void show_adj_route(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9950 safi_t safi
, int in
, const char *rmap_name
,
9951 u_char use_json
, json_object
*json
)
9953 struct bgp_table
*table
;
9954 struct bgp_adj_in
*ain
;
9955 struct bgp_adj_out
*adj
;
9956 unsigned long output_count
;
9957 unsigned long filtered_count
;
9958 struct bgp_node
*rn
;
9964 struct update_subgroup
*subgrp
;
9965 json_object
*json_scode
= NULL
;
9966 json_object
*json_ocode
= NULL
;
9967 json_object
*json_ar
= NULL
;
9968 struct peer_af
*paf
;
9971 json_scode
= json_object_new_object();
9972 json_ocode
= json_object_new_object();
9973 json_ar
= json_object_new_object();
9975 json_object_string_add(json_scode
, "suppressed", "s");
9976 json_object_string_add(json_scode
, "damped", "d");
9977 json_object_string_add(json_scode
, "history", "h");
9978 json_object_string_add(json_scode
, "valid", "*");
9979 json_object_string_add(json_scode
, "best", ">");
9980 json_object_string_add(json_scode
, "multipath", "=");
9981 json_object_string_add(json_scode
, "internal", "i");
9982 json_object_string_add(json_scode
, "ribFailure", "r");
9983 json_object_string_add(json_scode
, "stale", "S");
9984 json_object_string_add(json_scode
, "removed", "R");
9986 json_object_string_add(json_ocode
, "igp", "i");
9987 json_object_string_add(json_ocode
, "egp", "e");
9988 json_object_string_add(json_ocode
, "incomplete", "?");
9995 json_object_string_add(json
, "alert", "no BGP");
9996 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
9997 json_object_free(json
);
9999 vty_out(vty
, "%% No bgp\n");
10003 table
= bgp
->rib
[afi
][safi
];
10005 output_count
= filtered_count
= 0;
10006 subgrp
= peer_subgroup(peer
, afi
, safi
);
10009 && CHECK_FLAG(subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
)) {
10011 json_object_int_add(json
, "bgpTableVersion",
10013 json_object_string_add(json
, "bgpLocalRouterId",
10014 inet_ntoa(bgp
->router_id
));
10015 json_object_object_add(json
, "bgpStatusCodes",
10017 json_object_object_add(json
, "bgpOriginCodes",
10019 json_object_string_add(json
,
10020 "bgpOriginatingDefaultNetwork",
10023 vty_out(vty
, "BGP table version is %" PRIu64
10024 ", local router ID is %s\n",
10025 table
->version
, inet_ntoa(bgp
->router_id
));
10026 vty_out(vty
, BGP_SHOW_SCODE_HEADER
);
10027 vty_out(vty
, BGP_SHOW_OCODE_HEADER
);
10029 vty_out(vty
, "Originating default network 0.0.0.0\n\n");
10034 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
10036 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
) {
10037 if (ain
->peer
!= peer
)
10041 json_object_int_add(
10042 json
, "bgpTableVersion",
10044 json_object_string_add(
10046 "bgpLocalRouterId",
10049 json_object_object_add(
10050 json
, "bgpStatusCodes",
10052 json_object_object_add(
10053 json
, "bgpOriginCodes",
10057 "BGP table version is 0, local router ID is %s\n",
10061 BGP_SHOW_SCODE_HEADER
);
10063 BGP_SHOW_OCODE_HEADER
);
10069 vty_out(vty
, BGP_SHOW_HEADER
);
10073 bgp_attr_dup(&attr
, ain
->attr
);
10074 if (bgp_input_modifier(peer
, &rn
->p
,
10078 route_vty_out_tmp(vty
, &rn
->p
,
10088 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
10089 SUBGRP_FOREACH_PEER (adj
->subgroup
, paf
) {
10090 if (paf
->peer
!= peer
)
10095 json_object_int_add(
10099 json_object_string_add(
10101 "bgpLocalRouterId",
10104 json_object_object_add(
10108 json_object_object_add(
10114 "BGP table version is %" PRIu64
10115 ", local router ID is %s\n",
10120 BGP_SHOW_SCODE_HEADER
);
10122 BGP_SHOW_OCODE_HEADER
);
10135 bgp_attr_dup(&attr
, adj
->attr
);
10136 ret
= bgp_output_modifier(
10137 peer
, &rn
->p
, &attr
,
10138 afi
, safi
, rmap_name
);
10139 if (ret
!= RMAP_DENY
) {
10149 bgp_attr_undup(&attr
,
10156 json_object_object_add(json
, "advertisedRoutes", json_ar
);
10158 if (output_count
!= 0) {
10160 json_object_int_add(json
, "totalPrefixCounter",
10163 vty_out(vty
, "\nTotal number of prefixes %ld\n",
10167 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10168 json
, JSON_C_TO_STRING_PRETTY
));
10169 json_object_free(json
);
10173 static int peer_adj_routes(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
10174 safi_t safi
, int in
, const char *rmap_name
,
10177 json_object
*json
= NULL
;
10180 json
= json_object_new_object();
10182 /* labeled-unicast routes live in the unicast table */
10183 if (safi
== SAFI_LABELED_UNICAST
)
10184 safi
= SAFI_UNICAST
;
10186 if (!peer
|| !peer
->afc
[afi
][safi
]) {
10188 json_object_string_add(
10190 "No such neighbor or address family");
10191 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10192 json_object_free(json
);
10194 vty_out(vty
, "%% No such neighbor or address family\n");
10196 return CMD_WARNING
;
10200 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
10201 PEER_FLAG_SOFT_RECONFIG
)) {
10203 json_object_string_add(
10205 "Inbound soft reconfiguration not enabled");
10206 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10207 json_object_free(json
);
10210 "%% Inbound soft reconfiguration not enabled\n");
10212 return CMD_WARNING
;
10215 show_adj_route(vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
10217 return CMD_SUCCESS
;
10220 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
10221 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
10222 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
10223 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
10227 BGP_INSTANCE_HELP_STR
10229 BGP_SAFI_WITH_LABEL_HELP_STR
10230 "Detailed information on TCP and BGP neighbor connections\n"
10231 "Neighbor to display information about\n"
10232 "Neighbor to display information about\n"
10233 "Neighbor on BGP configured interface\n"
10234 "Display the received routes from neighbor\n"
10235 "Display the routes advertised to a BGP neighbor\n"
10236 "Route-map to modify the attributes\n"
10237 "Name of the route map\n"
10240 afi_t afi
= AFI_IP6
;
10241 safi_t safi
= SAFI_UNICAST
;
10242 char *rmap_name
= NULL
;
10243 char *peerstr
= NULL
;
10245 struct bgp
*bgp
= NULL
;
10250 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10253 return CMD_WARNING
;
10255 int uj
= use_json(argc
, argv
);
10259 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10260 argv_find(argv
, argc
, "neighbors", &idx
);
10261 peerstr
= argv
[++idx
]->arg
;
10263 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
10265 return CMD_WARNING
;
10267 if (argv_find(argv
, argc
, "received-routes", &idx
))
10269 if (argv_find(argv
, argc
, "advertised-routes", &idx
))
10271 if (argv_find(argv
, argc
, "route-map", &idx
))
10272 rmap_name
= argv
[++idx
]->arg
;
10274 return peer_adj_routes(vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
10277 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
10278 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
10279 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
10285 "Address Family modifier\n"
10286 "Detailed information on TCP and BGP neighbor connections\n"
10287 "Neighbor to display information about\n"
10288 "Neighbor to display information about\n"
10289 "Neighbor on BGP configured interface\n"
10290 "Display information received from a BGP neighbor\n"
10291 "Display the prefixlist filter\n"
10294 afi_t afi
= AFI_IP6
;
10295 safi_t safi
= SAFI_UNICAST
;
10296 char *peerstr
= NULL
;
10299 union sockunion su
;
10305 /* show [ip] bgp */
10306 if (argv_find(argv
, argc
, "ip", &idx
))
10308 /* [<ipv4|ipv6> [unicast]] */
10309 if (argv_find(argv
, argc
, "ipv4", &idx
))
10311 if (argv_find(argv
, argc
, "ipv6", &idx
))
10313 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10314 argv_find(argv
, argc
, "neighbors", &idx
);
10315 peerstr
= argv
[++idx
]->arg
;
10317 u_char uj
= use_json(argc
, argv
);
10319 ret
= str2sockunion(peerstr
, &su
);
10321 peer
= peer_lookup_by_conf_if(NULL
, peerstr
);
10324 vty_out(vty
, "{}\n");
10327 "%% Malformed address or name: %s\n",
10329 return CMD_WARNING
;
10332 peer
= peer_lookup(NULL
, &su
);
10335 vty_out(vty
, "{}\n");
10337 vty_out(vty
, "No peer\n");
10338 return CMD_WARNING
;
10342 sprintf(name
, "%s.%d.%d", peer
->host
, afi
, safi
);
10343 count
= prefix_bgp_show_prefix_list(NULL
, afi
, name
, uj
);
10346 vty_out(vty
, "Address Family: %s\n",
10347 afi_safi_print(afi
, safi
));
10348 prefix_bgp_show_prefix_list(vty
, afi
, name
, uj
);
10351 vty_out(vty
, "{}\n");
10353 vty_out(vty
, "No functional output\n");
10356 return CMD_SUCCESS
;
10359 static int bgp_show_neighbor_route(struct vty
*vty
, struct peer
*peer
,
10360 afi_t afi
, safi_t safi
,
10361 enum bgp_show_type type
, u_char use_json
)
10363 /* labeled-unicast routes live in the unicast table */
10364 if (safi
== SAFI_LABELED_UNICAST
)
10365 safi
= SAFI_UNICAST
;
10367 if (!peer
|| !peer
->afc
[afi
][safi
]) {
10369 json_object
*json_no
= NULL
;
10370 json_no
= json_object_new_object();
10371 json_object_string_add(
10372 json_no
, "warning",
10373 "No such neighbor or address family");
10374 vty_out(vty
, "%s\n",
10375 json_object_to_json_string(json_no
));
10376 json_object_free(json_no
);
10378 vty_out(vty
, "%% No such neighbor or address family\n");
10379 return CMD_WARNING
;
10382 return bgp_show(vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
10385 DEFUN (show_ip_bgp_neighbor_routes
,
10386 show_ip_bgp_neighbor_routes_cmd
,
10387 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
10388 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
10392 BGP_INSTANCE_HELP_STR
10394 BGP_SAFI_WITH_LABEL_HELP_STR
10395 "Detailed information on TCP and BGP neighbor connections\n"
10396 "Neighbor to display information about\n"
10397 "Neighbor to display information about\n"
10398 "Neighbor on BGP configured interface\n"
10399 "Display flap statistics of the routes learned from neighbor\n"
10400 "Display the dampened routes received from neighbor\n"
10401 "Display routes learned from neighbor\n"
10404 char *peerstr
= NULL
;
10405 struct bgp
*bgp
= NULL
;
10406 afi_t afi
= AFI_IP6
;
10407 safi_t safi
= SAFI_UNICAST
;
10409 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
10413 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10416 return CMD_WARNING
;
10418 int uj
= use_json(argc
, argv
);
10422 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10423 argv_find(argv
, argc
, "neighbors", &idx
);
10424 peerstr
= argv
[++idx
]->arg
;
10426 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
10428 vty_out(vty
, "No such neighbor\n");
10429 return CMD_WARNING
;
10432 if (argv_find(argv
, argc
, "flap-statistics", &idx
))
10433 sh_type
= bgp_show_type_flap_neighbor
;
10434 else if (argv_find(argv
, argc
, "dampened-routes", &idx
))
10435 sh_type
= bgp_show_type_damp_neighbor
;
10436 else if (argv_find(argv
, argc
, "routes", &idx
))
10437 sh_type
= bgp_show_type_neighbor
;
10439 return bgp_show_neighbor_route(vty
, peer
, afi
, safi
, sh_type
, uj
);
10442 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
10444 struct bgp_distance
{
10445 /* Distance value for the IP source prefix. */
10448 /* Name of the access-list to be matched. */
10452 DEFUN (show_bgp_afi_vpn_rd_route
,
10453 show_bgp_afi_vpn_rd_route_cmd
,
10454 "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]",
10458 "Address Family modifier\n"
10459 "Display information for a route distinguisher\n"
10460 "Route Distinguisher\n"
10461 "Network in the BGP routing table to display\n"
10462 "Network in the BGP routing table to display\n"
10466 struct prefix_rd prd
;
10467 afi_t afi
= AFI_MAX
;
10470 if (!argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
10471 vty_out(vty
, "%% Malformed Address Family\n");
10472 return CMD_WARNING
;
10475 ret
= str2prefix_rd(argv
[5]->arg
, &prd
);
10477 vty_out(vty
, "%% Malformed Route Distinguisher\n");
10478 return CMD_WARNING
;
10481 return bgp_show_route(vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
,
10482 0, BGP_PATH_ALL
, use_json(argc
, argv
));
10485 static struct bgp_distance
*bgp_distance_new(void)
10487 return XCALLOC(MTYPE_BGP_DISTANCE
, sizeof(struct bgp_distance
));
10490 static void bgp_distance_free(struct bgp_distance
*bdistance
)
10492 XFREE(MTYPE_BGP_DISTANCE
, bdistance
);
10495 static int bgp_distance_set(struct vty
*vty
, const char *distance_str
,
10496 const char *ip_str
, const char *access_list_str
)
10503 struct bgp_node
*rn
;
10504 struct bgp_distance
*bdistance
;
10506 afi
= bgp_node_afi(vty
);
10507 safi
= bgp_node_safi(vty
);
10509 ret
= str2prefix(ip_str
, &p
);
10511 vty_out(vty
, "Malformed prefix\n");
10512 return CMD_WARNING_CONFIG_FAILED
;
10515 distance
= atoi(distance_str
);
10517 /* Get BGP distance node. */
10518 rn
= bgp_node_get(bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
10520 bdistance
= rn
->info
;
10521 bgp_unlock_node(rn
);
10523 bdistance
= bgp_distance_new();
10524 rn
->info
= bdistance
;
10527 /* Set distance value. */
10528 bdistance
->distance
= distance
;
10530 /* Reset access-list configuration. */
10531 if (bdistance
->access_list
) {
10532 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10533 bdistance
->access_list
= NULL
;
10535 if (access_list_str
)
10536 bdistance
->access_list
=
10537 XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
10539 return CMD_SUCCESS
;
10542 static int bgp_distance_unset(struct vty
*vty
, const char *distance_str
,
10543 const char *ip_str
, const char *access_list_str
)
10550 struct bgp_node
*rn
;
10551 struct bgp_distance
*bdistance
;
10553 afi
= bgp_node_afi(vty
);
10554 safi
= bgp_node_safi(vty
);
10556 ret
= str2prefix(ip_str
, &p
);
10558 vty_out(vty
, "Malformed prefix\n");
10559 return CMD_WARNING_CONFIG_FAILED
;
10562 rn
= bgp_node_lookup(bgp_distance_table
[afi
][safi
],
10563 (struct prefix
*)&p
);
10565 vty_out(vty
, "Can't find specified prefix\n");
10566 return CMD_WARNING_CONFIG_FAILED
;
10569 bdistance
= rn
->info
;
10570 distance
= atoi(distance_str
);
10572 if (bdistance
->distance
!= distance
) {
10573 vty_out(vty
, "Distance does not match configured\n");
10574 return CMD_WARNING_CONFIG_FAILED
;
10577 if (bdistance
->access_list
)
10578 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10579 bgp_distance_free(bdistance
);
10582 bgp_unlock_node(rn
);
10583 bgp_unlock_node(rn
);
10585 return CMD_SUCCESS
;
10588 /* Apply BGP information to distance method. */
10589 u_char
bgp_distance_apply(struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
10590 safi_t safi
, struct bgp
*bgp
)
10592 struct bgp_node
*rn
;
10595 struct bgp_distance
*bdistance
;
10596 struct access_list
*alist
;
10597 struct bgp_static
*bgp_static
;
10602 peer
= rinfo
->peer
;
10604 /* Check source address. */
10605 sockunion2hostprefix(&peer
->su
, &q
);
10606 rn
= bgp_node_match(bgp_distance_table
[afi
][safi
], &q
);
10608 bdistance
= rn
->info
;
10609 bgp_unlock_node(rn
);
10611 if (bdistance
->access_list
) {
10612 alist
= access_list_lookup(afi
, bdistance
->access_list
);
10614 && access_list_apply(alist
, p
) == FILTER_PERMIT
)
10615 return bdistance
->distance
;
10617 return bdistance
->distance
;
10620 /* Backdoor check. */
10621 rn
= bgp_node_lookup(bgp
->route
[afi
][safi
], p
);
10623 bgp_static
= rn
->info
;
10624 bgp_unlock_node(rn
);
10626 if (bgp_static
->backdoor
) {
10627 if (bgp
->distance_local
[afi
][safi
])
10628 return bgp
->distance_local
[afi
][safi
];
10630 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10634 if (peer
->sort
== BGP_PEER_EBGP
) {
10635 if (bgp
->distance_ebgp
[afi
][safi
])
10636 return bgp
->distance_ebgp
[afi
][safi
];
10637 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
10639 if (bgp
->distance_ibgp
[afi
][safi
])
10640 return bgp
->distance_ibgp
[afi
][safi
];
10641 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10645 DEFUN (bgp_distance
,
10647 "distance bgp (1-255) (1-255) (1-255)",
10648 "Define an administrative distance\n"
10650 "Distance for routes external to the AS\n"
10651 "Distance for routes internal to the AS\n"
10652 "Distance for local routes\n")
10654 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10655 int idx_number
= 2;
10656 int idx_number_2
= 3;
10657 int idx_number_3
= 4;
10661 afi
= bgp_node_afi(vty
);
10662 safi
= bgp_node_safi(vty
);
10664 bgp
->distance_ebgp
[afi
][safi
] = atoi(argv
[idx_number
]->arg
);
10665 bgp
->distance_ibgp
[afi
][safi
] = atoi(argv
[idx_number_2
]->arg
);
10666 bgp
->distance_local
[afi
][safi
] = atoi(argv
[idx_number_3
]->arg
);
10667 return CMD_SUCCESS
;
10670 DEFUN (no_bgp_distance
,
10671 no_bgp_distance_cmd
,
10672 "no distance bgp [(1-255) (1-255) (1-255)]",
10674 "Define an administrative distance\n"
10676 "Distance for routes external to the AS\n"
10677 "Distance for routes internal to the AS\n"
10678 "Distance for local routes\n")
10680 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10684 afi
= bgp_node_afi(vty
);
10685 safi
= bgp_node_safi(vty
);
10687 bgp
->distance_ebgp
[afi
][safi
] = 0;
10688 bgp
->distance_ibgp
[afi
][safi
] = 0;
10689 bgp
->distance_local
[afi
][safi
] = 0;
10690 return CMD_SUCCESS
;
10694 DEFUN (bgp_distance_source
,
10695 bgp_distance_source_cmd
,
10696 "distance (1-255) A.B.C.D/M",
10697 "Define an administrative distance\n"
10698 "Administrative distance\n"
10699 "IP source prefix\n")
10701 int idx_number
= 1;
10702 int idx_ipv4_prefixlen
= 2;
10703 bgp_distance_set(vty
, argv
[idx_number
]->arg
,
10704 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10705 return CMD_SUCCESS
;
10708 DEFUN (no_bgp_distance_source
,
10709 no_bgp_distance_source_cmd
,
10710 "no distance (1-255) A.B.C.D/M",
10712 "Define an administrative distance\n"
10713 "Administrative distance\n"
10714 "IP source prefix\n")
10716 int idx_number
= 2;
10717 int idx_ipv4_prefixlen
= 3;
10718 bgp_distance_unset(vty
, argv
[idx_number
]->arg
,
10719 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10720 return CMD_SUCCESS
;
10723 DEFUN (bgp_distance_source_access_list
,
10724 bgp_distance_source_access_list_cmd
,
10725 "distance (1-255) A.B.C.D/M WORD",
10726 "Define an administrative distance\n"
10727 "Administrative distance\n"
10728 "IP source prefix\n"
10729 "Access list name\n")
10731 int idx_number
= 1;
10732 int idx_ipv4_prefixlen
= 2;
10734 bgp_distance_set(vty
, argv
[idx_number
]->arg
,
10735 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10736 return CMD_SUCCESS
;
10739 DEFUN (no_bgp_distance_source_access_list
,
10740 no_bgp_distance_source_access_list_cmd
,
10741 "no distance (1-255) A.B.C.D/M WORD",
10743 "Define an administrative distance\n"
10744 "Administrative distance\n"
10745 "IP source prefix\n"
10746 "Access list name\n")
10748 int idx_number
= 2;
10749 int idx_ipv4_prefixlen
= 3;
10751 bgp_distance_unset(vty
, argv
[idx_number
]->arg
,
10752 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10753 return CMD_SUCCESS
;
10756 DEFUN (ipv6_bgp_distance_source
,
10757 ipv6_bgp_distance_source_cmd
,
10758 "distance (1-255) X:X::X:X/M",
10759 "Define an administrative distance\n"
10760 "Administrative distance\n"
10761 "IP source prefix\n")
10763 bgp_distance_set(vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
10764 return CMD_SUCCESS
;
10767 DEFUN (no_ipv6_bgp_distance_source
,
10768 no_ipv6_bgp_distance_source_cmd
,
10769 "no distance (1-255) X:X::X:X/M",
10771 "Define an administrative distance\n"
10772 "Administrative distance\n"
10773 "IP source prefix\n")
10775 bgp_distance_unset(vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10776 return CMD_SUCCESS
;
10779 DEFUN (ipv6_bgp_distance_source_access_list
,
10780 ipv6_bgp_distance_source_access_list_cmd
,
10781 "distance (1-255) X:X::X:X/M WORD",
10782 "Define an administrative distance\n"
10783 "Administrative distance\n"
10784 "IP source prefix\n"
10785 "Access list name\n")
10787 bgp_distance_set(vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10788 return CMD_SUCCESS
;
10791 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10792 no_ipv6_bgp_distance_source_access_list_cmd
,
10793 "no distance (1-255) X:X::X:X/M WORD",
10795 "Define an administrative distance\n"
10796 "Administrative distance\n"
10797 "IP source prefix\n"
10798 "Access list name\n")
10800 bgp_distance_unset(vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10801 return CMD_SUCCESS
;
10804 DEFUN (bgp_damp_set
,
10806 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10807 "BGP Specific commands\n"
10808 "Enable route-flap dampening\n"
10809 "Half-life time for the penalty\n"
10810 "Value to start reusing a route\n"
10811 "Value to start suppressing a route\n"
10812 "Maximum duration to suppress a stable route\n")
10814 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10815 int idx_half_life
= 2;
10817 int idx_suppress
= 4;
10818 int idx_max_suppress
= 5;
10819 int half
= DEFAULT_HALF_LIFE
* 60;
10820 int reuse
= DEFAULT_REUSE
;
10821 int suppress
= DEFAULT_SUPPRESS
;
10822 int max
= 4 * half
;
10825 half
= atoi(argv
[idx_half_life
]->arg
) * 60;
10826 reuse
= atoi(argv
[idx_reuse
]->arg
);
10827 suppress
= atoi(argv
[idx_suppress
]->arg
);
10828 max
= atoi(argv
[idx_max_suppress
]->arg
) * 60;
10829 } else if (argc
== 3) {
10830 half
= atoi(argv
[idx_half_life
]->arg
) * 60;
10834 if (suppress
< reuse
) {
10836 "Suppress value cannot be less than reuse value \n");
10840 return bgp_damp_enable(bgp
, bgp_node_afi(vty
), bgp_node_safi(vty
), half
,
10841 reuse
, suppress
, max
);
10844 DEFUN (bgp_damp_unset
,
10845 bgp_damp_unset_cmd
,
10846 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10848 "BGP Specific commands\n"
10849 "Enable route-flap dampening\n"
10850 "Half-life time for the penalty\n"
10851 "Value to start reusing a route\n"
10852 "Value to start suppressing a route\n"
10853 "Maximum duration to suppress a stable route\n")
10855 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10856 return bgp_damp_disable(bgp
, bgp_node_afi(vty
), bgp_node_safi(vty
));
10859 /* Display specified route of BGP table. */
10860 static int bgp_clear_damp_route(struct vty
*vty
, const char *view_name
,
10861 const char *ip_str
, afi_t afi
, safi_t safi
,
10862 struct prefix_rd
*prd
, int prefix_check
)
10865 struct prefix match
;
10866 struct bgp_node
*rn
;
10867 struct bgp_node
*rm
;
10868 struct bgp_info
*ri
;
10869 struct bgp_info
*ri_temp
;
10871 struct bgp_table
*table
;
10873 /* BGP structure lookup. */
10875 bgp
= bgp_lookup_by_name(view_name
);
10877 vty_out(vty
, "%% Can't find BGP instance %s\n",
10879 return CMD_WARNING
;
10882 bgp
= bgp_get_default();
10884 vty_out(vty
, "%% No BGP process is configured\n");
10885 return CMD_WARNING
;
10889 /* Check IP address argument. */
10890 ret
= str2prefix(ip_str
, &match
);
10892 vty_out(vty
, "%% address is malformed\n");
10893 return CMD_WARNING
;
10896 match
.family
= afi2family(afi
);
10898 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
10899 || (safi
== SAFI_EVPN
)) {
10900 for (rn
= bgp_table_top(bgp
->rib
[AFI_IP
][safi
]); rn
;
10901 rn
= bgp_route_next(rn
)) {
10902 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
10904 if ((table
= rn
->info
) == NULL
)
10906 if ((rm
= bgp_node_match(table
, &match
)) == NULL
)
10910 || rm
->p
.prefixlen
== match
.prefixlen
) {
10913 if (ri
->extra
&& ri
->extra
->damp_info
) {
10914 ri_temp
= ri
->next
;
10915 bgp_damp_info_free(
10916 ri
->extra
->damp_info
,
10924 bgp_unlock_node(rm
);
10927 if ((rn
= bgp_node_match(bgp
->rib
[afi
][safi
], &match
))
10930 || rn
->p
.prefixlen
== match
.prefixlen
) {
10933 if (ri
->extra
&& ri
->extra
->damp_info
) {
10934 ri_temp
= ri
->next
;
10935 bgp_damp_info_free(
10936 ri
->extra
->damp_info
,
10944 bgp_unlock_node(rn
);
10948 return CMD_SUCCESS
;
10951 DEFUN (clear_ip_bgp_dampening
,
10952 clear_ip_bgp_dampening_cmd
,
10953 "clear ip bgp dampening",
10957 "Clear route flap dampening information\n")
10959 bgp_damp_info_clean();
10960 return CMD_SUCCESS
;
10963 DEFUN (clear_ip_bgp_dampening_prefix
,
10964 clear_ip_bgp_dampening_prefix_cmd
,
10965 "clear ip bgp dampening A.B.C.D/M",
10969 "Clear route flap dampening information\n"
10972 int idx_ipv4_prefixlen
= 4;
10973 return bgp_clear_damp_route(vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
,
10974 AFI_IP
, SAFI_UNICAST
, NULL
, 1);
10977 DEFUN (clear_ip_bgp_dampening_address
,
10978 clear_ip_bgp_dampening_address_cmd
,
10979 "clear ip bgp dampening A.B.C.D",
10983 "Clear route flap dampening information\n"
10984 "Network to clear damping information\n")
10987 return bgp_clear_damp_route(vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
10988 SAFI_UNICAST
, NULL
, 0);
10991 DEFUN (clear_ip_bgp_dampening_address_mask
,
10992 clear_ip_bgp_dampening_address_mask_cmd
,
10993 "clear ip bgp dampening A.B.C.D A.B.C.D",
10997 "Clear route flap dampening information\n"
10998 "Network to clear damping information\n"
11002 int idx_ipv4_2
= 5;
11004 char prefix_str
[BUFSIZ
];
11006 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
,
11009 vty_out(vty
, "%% Inconsistent address and mask\n");
11010 return CMD_WARNING
;
11013 return bgp_clear_damp_route(vty
, NULL
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
11017 /* also used for encap safi */
11018 static void bgp_config_write_network_vpn(struct vty
*vty
, struct bgp
*bgp
,
11019 afi_t afi
, safi_t safi
)
11021 struct bgp_node
*prn
;
11022 struct bgp_node
*rn
;
11023 struct bgp_table
*table
;
11025 struct prefix_rd
*prd
;
11026 struct bgp_static
*bgp_static
;
11027 mpls_label_t label
;
11028 char buf
[SU_ADDRSTRLEN
];
11029 char rdbuf
[RD_ADDRSTRLEN
];
11031 /* Network configuration. */
11032 for (prn
= bgp_table_top(bgp
->route
[afi
][safi
]); prn
;
11033 prn
= bgp_route_next(prn
)) {
11034 if ((table
= prn
->info
) == NULL
)
11037 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
11038 if ((bgp_static
= rn
->info
) == NULL
)
11042 prd
= (struct prefix_rd
*)&prn
->p
;
11044 /* "network" configuration display. */
11045 prefix_rd2str(prd
, rdbuf
, sizeof(rdbuf
));
11046 label
= decode_label(&bgp_static
->label
);
11048 vty_out(vty
, " network %s/%d rd %s",
11049 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11051 p
->prefixlen
, rdbuf
);
11052 if (safi
== SAFI_MPLS_VPN
)
11053 vty_out(vty
, " label %u", label
);
11055 if (bgp_static
->rmap
.name
)
11056 vty_out(vty
, " route-map %s",
11057 bgp_static
->rmap
.name
);
11059 if (bgp_static
->backdoor
)
11060 vty_out(vty
, " backdoor");
11062 vty_out(vty
, "\n");
11067 static void bgp_config_write_network_evpn(struct vty
*vty
, struct bgp
*bgp
,
11068 afi_t afi
, safi_t safi
)
11070 struct bgp_node
*prn
;
11071 struct bgp_node
*rn
;
11072 struct bgp_table
*table
;
11074 struct prefix_rd
*prd
;
11075 struct bgp_static
*bgp_static
;
11076 char buf
[PREFIX_STRLEN
];
11077 char buf2
[SU_ADDRSTRLEN
];
11078 char rdbuf
[RD_ADDRSTRLEN
];
11080 /* Network configuration. */
11081 for (prn
= bgp_table_top(bgp
->route
[afi
][safi
]); prn
;
11082 prn
= bgp_route_next(prn
)) {
11083 if ((table
= prn
->info
) == NULL
)
11086 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
11087 if ((bgp_static
= rn
->info
) == NULL
)
11090 char *macrouter
= NULL
;
11093 if (bgp_static
->router_mac
)
11094 macrouter
= prefix_mac2str(
11095 bgp_static
->router_mac
, NULL
, 0);
11096 if (bgp_static
->eth_s_id
)
11097 esi
= esi2str(bgp_static
->eth_s_id
);
11099 prd
= (struct prefix_rd
*)&prn
->p
;
11101 /* "network" configuration display. */
11102 prefix_rd2str(prd
, rdbuf
, sizeof(rdbuf
));
11103 if (p
->u
.prefix_evpn
.route_type
== 5) {
11104 char local_buf
[PREFIX_STRLEN
];
11105 uint8_t family
= IS_EVPN_PREFIX_IPADDR_V4((
11106 struct prefix_evpn
*)p
)
11109 inet_ntop(family
, &p
->u
.prefix_evpn
.ip
.ip
.addr
,
11110 local_buf
, PREFIX_STRLEN
);
11111 sprintf(buf
, "%s/%u", local_buf
,
11112 p
->u
.prefix_evpn
.ip_prefix_length
);
11114 prefix2str(p
, buf
, sizeof(buf
));
11117 if (bgp_static
->gatewayIp
.family
== AF_INET
11118 || bgp_static
->gatewayIp
.family
== AF_INET6
)
11119 inet_ntop(bgp_static
->gatewayIp
.family
,
11120 &bgp_static
->gatewayIp
.u
.prefix
, buf2
,
11123 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
11124 buf
, rdbuf
, p
->u
.prefix_evpn
.eth_tag
,
11125 decode_label(&bgp_static
->label
), esi
, buf2
,
11129 XFREE(MTYPE_TMP
, macrouter
);
11131 XFREE(MTYPE_TMP
, esi
);
11136 /* Configuration of static route announcement and aggregate
11138 void bgp_config_write_network(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
11141 struct bgp_node
*rn
;
11143 struct bgp_static
*bgp_static
;
11144 struct bgp_aggregate
*bgp_aggregate
;
11145 char buf
[SU_ADDRSTRLEN
];
11147 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)) {
11148 bgp_config_write_network_vpn(vty
, bgp
, afi
, safi
);
11152 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
11153 bgp_config_write_network_evpn(vty
, bgp
, afi
, safi
);
11157 /* Network configuration. */
11158 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
11159 rn
= bgp_route_next(rn
)) {
11160 if ((bgp_static
= rn
->info
) == NULL
)
11165 /* "network" configuration display. */
11166 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
) {
11167 u_int32_t destination
;
11168 struct in_addr netmask
;
11170 destination
= ntohl(p
->u
.prefix4
.s_addr
);
11171 masklen2ip(p
->prefixlen
, &netmask
);
11172 vty_out(vty
, " network %s",
11173 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11176 if ((IN_CLASSC(destination
) && p
->prefixlen
== 24)
11177 || (IN_CLASSB(destination
) && p
->prefixlen
== 16)
11178 || (IN_CLASSA(destination
) && p
->prefixlen
== 8)
11179 || p
->u
.prefix4
.s_addr
== 0) {
11180 /* Natural mask is not display. */
11182 vty_out(vty
, " mask %s", inet_ntoa(netmask
));
11184 vty_out(vty
, " network %s/%d",
11185 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11190 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
11191 vty_out(vty
, " label-index %u",
11192 bgp_static
->label_index
);
11194 if (bgp_static
->rmap
.name
)
11195 vty_out(vty
, " route-map %s", bgp_static
->rmap
.name
);
11197 if (bgp_static
->backdoor
)
11198 vty_out(vty
, " backdoor");
11200 vty_out(vty
, "\n");
11203 /* Aggregate-address configuration. */
11204 for (rn
= bgp_table_top(bgp
->aggregate
[afi
][safi
]); rn
;
11205 rn
= bgp_route_next(rn
)) {
11206 if ((bgp_aggregate
= rn
->info
) == NULL
)
11211 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
) {
11212 struct in_addr netmask
;
11214 masklen2ip(p
->prefixlen
, &netmask
);
11215 vty_out(vty
, " aggregate-address %s %s",
11216 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11218 inet_ntoa(netmask
));
11220 vty_out(vty
, " aggregate-address %s/%d",
11221 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11226 if (bgp_aggregate
->as_set
)
11227 vty_out(vty
, " as-set");
11229 if (bgp_aggregate
->summary_only
)
11230 vty_out(vty
, " summary-only");
11232 vty_out(vty
, "\n");
11236 void bgp_config_write_distance(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
11239 struct bgp_node
*rn
;
11240 struct bgp_distance
*bdistance
;
11242 /* Distance configuration. */
11243 if (bgp
->distance_ebgp
[afi
][safi
] && bgp
->distance_ibgp
[afi
][safi
]
11244 && bgp
->distance_local
[afi
][safi
]
11245 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
11246 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
11247 || bgp
->distance_local
[afi
][safi
]
11248 != ZEBRA_IBGP_DISTANCE_DEFAULT
)) {
11249 vty_out(vty
, " distance bgp %d %d %d\n",
11250 bgp
->distance_ebgp
[afi
][safi
],
11251 bgp
->distance_ibgp
[afi
][safi
],
11252 bgp
->distance_local
[afi
][safi
]);
11255 for (rn
= bgp_table_top(bgp_distance_table
[afi
][safi
]); rn
;
11256 rn
= bgp_route_next(rn
))
11257 if ((bdistance
= rn
->info
) != NULL
) {
11258 char buf
[PREFIX_STRLEN
];
11260 vty_out(vty
, " distance %d %s %s\n",
11261 bdistance
->distance
,
11262 prefix2str(&rn
->p
, buf
, sizeof(buf
)),
11263 bdistance
->access_list
? bdistance
->access_list
11268 /* Allocate routing table structure and install commands. */
11269 void bgp_route_init(void)
11274 /* Init BGP distance table. */
11275 FOREACH_AFI_SAFI (afi
, safi
)
11276 bgp_distance_table
[afi
][safi
] = bgp_table_init(afi
, safi
);
11278 /* IPv4 BGP commands. */
11279 install_element(BGP_NODE
, &bgp_table_map_cmd
);
11280 install_element(BGP_NODE
, &bgp_network_cmd
);
11281 install_element(BGP_NODE
, &no_bgp_table_map_cmd
);
11283 install_element(BGP_NODE
, &aggregate_address_cmd
);
11284 install_element(BGP_NODE
, &aggregate_address_mask_cmd
);
11285 install_element(BGP_NODE
, &no_aggregate_address_cmd
);
11286 install_element(BGP_NODE
, &no_aggregate_address_mask_cmd
);
11288 /* IPv4 unicast configuration. */
11289 install_element(BGP_IPV4_NODE
, &bgp_table_map_cmd
);
11290 install_element(BGP_IPV4_NODE
, &bgp_network_cmd
);
11291 install_element(BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
11293 install_element(BGP_IPV4_NODE
, &aggregate_address_cmd
);
11294 install_element(BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
11295 install_element(BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
11296 install_element(BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
11298 /* IPv4 multicast configuration. */
11299 install_element(BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
11300 install_element(BGP_IPV4M_NODE
, &bgp_network_cmd
);
11301 install_element(BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
11302 install_element(BGP_IPV4M_NODE
, &aggregate_address_cmd
);
11303 install_element(BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
11304 install_element(BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
11305 install_element(BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
11307 /* IPv4 labeled-unicast configuration. */
11308 install_element(VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
11309 install_element(VIEW_NODE
, &show_ip_bgp_cmd
);
11310 install_element(VIEW_NODE
, &show_ip_bgp_json_cmd
);
11311 install_element(VIEW_NODE
, &show_ip_bgp_route_cmd
);
11312 install_element(VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
11314 install_element(VIEW_NODE
,
11315 &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
11316 install_element(VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
11317 install_element(VIEW_NODE
,
11318 &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
11319 #ifdef KEEP_OLD_VPN_COMMANDS
11320 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
11321 #endif /* KEEP_OLD_VPN_COMMANDS */
11322 install_element(VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
11323 install_element(VIEW_NODE
,
11324 &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
);
11326 /* BGP dampening clear commands */
11327 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
11328 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
11330 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
11331 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
11334 install_element(ENABLE_NODE
,
11335 &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
11336 #ifdef KEEP_OLD_VPN_COMMANDS
11337 install_element(ENABLE_NODE
,
11338 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
11339 #endif /* KEEP_OLD_VPN_COMMANDS */
11341 /* New config IPv6 BGP commands. */
11342 install_element(BGP_IPV6_NODE
, &bgp_table_map_cmd
);
11343 install_element(BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
11344 install_element(BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
11346 install_element(BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
11347 install_element(BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
11349 install_element(BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
11351 install_element(BGP_NODE
, &bgp_distance_cmd
);
11352 install_element(BGP_NODE
, &no_bgp_distance_cmd
);
11353 install_element(BGP_NODE
, &bgp_distance_source_cmd
);
11354 install_element(BGP_NODE
, &no_bgp_distance_source_cmd
);
11355 install_element(BGP_NODE
, &bgp_distance_source_access_list_cmd
);
11356 install_element(BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
11357 install_element(BGP_IPV4_NODE
, &bgp_distance_cmd
);
11358 install_element(BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
11359 install_element(BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
11360 install_element(BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
11361 install_element(BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
11362 install_element(BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
11363 install_element(BGP_IPV4M_NODE
, &bgp_distance_cmd
);
11364 install_element(BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
11365 install_element(BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
11366 install_element(BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
11367 install_element(BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
11368 install_element(BGP_IPV4M_NODE
,
11369 &no_bgp_distance_source_access_list_cmd
);
11370 install_element(BGP_IPV6_NODE
, &bgp_distance_cmd
);
11371 install_element(BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
11372 install_element(BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
11373 install_element(BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11374 install_element(BGP_IPV6_NODE
,
11375 &ipv6_bgp_distance_source_access_list_cmd
);
11376 install_element(BGP_IPV6_NODE
,
11377 &no_ipv6_bgp_distance_source_access_list_cmd
);
11378 install_element(BGP_IPV6M_NODE
, &bgp_distance_cmd
);
11379 install_element(BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
11380 install_element(BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
11381 install_element(BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11382 install_element(BGP_IPV6M_NODE
,
11383 &ipv6_bgp_distance_source_access_list_cmd
);
11384 install_element(BGP_IPV6M_NODE
,
11385 &no_ipv6_bgp_distance_source_access_list_cmd
);
11387 install_element(BGP_NODE
, &bgp_damp_set_cmd
);
11388 install_element(BGP_NODE
, &bgp_damp_unset_cmd
);
11389 install_element(BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
11390 install_element(BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
11392 /* IPv4 Multicast Mode */
11393 install_element(BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
11394 install_element(BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
11396 /* Large Communities */
11397 install_element(VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
11398 install_element(VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
11401 void bgp_route_finish(void)
11406 FOREACH_AFI_SAFI (afi
, safi
) {
11407 bgp_table_unlock(bgp_distance_table
[afi
][safi
]);
11408 bgp_distance_table
[afi
][safi
] = NULL
;