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
||
561 new->sub_type
== BGP_ROUTE_IMPORTED
)) {
564 "%s: %s wins over %s due to preferred BGP_ROUTE type",
565 pfx_buf
, new_buf
, exist_buf
);
569 if (!(exist
->sub_type
== BGP_ROUTE_NORMAL
||
570 new->sub_type
== BGP_ROUTE_IMPORTED
)) {
573 "%s: %s loses to %s due to preferred BGP_ROUTE type",
574 pfx_buf
, new_buf
, exist_buf
);
578 /* 4. AS path length check. */
579 if (!bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
)) {
580 int exist_hops
= aspath_count_hops(existattr
->aspath
);
581 int exist_confeds
= aspath_count_confeds(existattr
->aspath
);
583 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
)) {
586 aspath_hops
= aspath_count_hops(newattr
->aspath
);
587 aspath_hops
+= aspath_count_confeds(newattr
->aspath
);
589 if (aspath_hops
< (exist_hops
+ exist_confeds
)) {
592 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
593 pfx_buf
, new_buf
, exist_buf
,
595 (exist_hops
+ exist_confeds
));
599 if (aspath_hops
> (exist_hops
+ exist_confeds
)) {
602 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
603 pfx_buf
, new_buf
, exist_buf
,
605 (exist_hops
+ exist_confeds
));
609 int newhops
= aspath_count_hops(newattr
->aspath
);
611 if (newhops
< exist_hops
) {
614 "%s: %s wins over %s due to aspath hopcount %d < %d",
615 pfx_buf
, new_buf
, exist_buf
,
616 newhops
, exist_hops
);
620 if (newhops
> exist_hops
) {
623 "%s: %s loses to %s due to aspath hopcount %d > %d",
624 pfx_buf
, new_buf
, exist_buf
,
625 newhops
, exist_hops
);
631 /* 5. Origin check. */
632 if (newattr
->origin
< existattr
->origin
) {
634 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
635 pfx_buf
, new_buf
, exist_buf
,
636 bgp_origin_long_str
[newattr
->origin
],
637 bgp_origin_long_str
[existattr
->origin
]);
641 if (newattr
->origin
> existattr
->origin
) {
643 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
644 pfx_buf
, new_buf
, exist_buf
,
645 bgp_origin_long_str
[newattr
->origin
],
646 bgp_origin_long_str
[existattr
->origin
]);
651 internal_as_route
= (aspath_count_hops(newattr
->aspath
) == 0
652 && aspath_count_hops(existattr
->aspath
) == 0);
653 confed_as_route
= (aspath_count_confeds(newattr
->aspath
) > 0
654 && aspath_count_confeds(existattr
->aspath
) > 0
655 && aspath_count_hops(newattr
->aspath
) == 0
656 && aspath_count_hops(existattr
->aspath
) == 0);
658 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
)
659 || (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
) && confed_as_route
)
660 || aspath_cmp_left(newattr
->aspath
, existattr
->aspath
)
661 || aspath_cmp_left_confed(newattr
->aspath
, existattr
->aspath
)
662 || internal_as_route
) {
663 new_med
= bgp_med_value(new->attr
, bgp
);
664 exist_med
= bgp_med_value(exist
->attr
, bgp
);
666 if (new_med
< exist_med
) {
669 "%s: %s wins over %s due to MED %d < %d",
670 pfx_buf
, new_buf
, exist_buf
, new_med
,
675 if (new_med
> exist_med
) {
678 "%s: %s loses to %s due to MED %d > %d",
679 pfx_buf
, new_buf
, exist_buf
, new_med
,
685 /* 7. Peer type check. */
686 new_sort
= new->peer
->sort
;
687 exist_sort
= exist
->peer
->sort
;
689 if (new_sort
== BGP_PEER_EBGP
690 && (exist_sort
== BGP_PEER_IBGP
|| exist_sort
== BGP_PEER_CONFED
)) {
693 "%s: %s wins over %s due to eBGP peer > iBGP peer",
694 pfx_buf
, new_buf
, exist_buf
);
698 if (exist_sort
== BGP_PEER_EBGP
699 && (new_sort
== BGP_PEER_IBGP
|| new_sort
== BGP_PEER_CONFED
)) {
702 "%s: %s loses to %s due to iBGP peer < eBGP peer",
703 pfx_buf
, new_buf
, exist_buf
);
707 /* 8. IGP metric check. */
711 newm
= new->extra
->igpmetric
;
713 existm
= exist
->extra
->igpmetric
;
718 "%s: %s wins over %s due to IGP metric %d < %d",
719 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
726 "%s: %s loses to %s due to IGP metric %d > %d",
727 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
731 /* 9. Same IGP metric. Compare the cluster list length as
732 representative of IGP hops metric. Rewrite the metric value
733 pair (newm, existm) with the cluster list length. Prefer the
734 path with smaller cluster list length. */
735 if (newm
== existm
) {
736 if (peer_sort(new->peer
) == BGP_PEER_IBGP
737 && peer_sort(exist
->peer
) == BGP_PEER_IBGP
738 && (mpath_cfg
== NULL
740 mpath_cfg
->ibgp_flags
,
741 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN
))) {
742 newm
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
743 existm
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
748 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
749 pfx_buf
, new_buf
, exist_buf
,
757 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
758 pfx_buf
, new_buf
, exist_buf
,
765 /* 10. confed-external vs. confed-internal */
766 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
767 if (new_sort
== BGP_PEER_CONFED
768 && exist_sort
== BGP_PEER_IBGP
) {
771 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
772 pfx_buf
, new_buf
, exist_buf
);
776 if (exist_sort
== BGP_PEER_CONFED
777 && new_sort
== BGP_PEER_IBGP
) {
780 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
781 pfx_buf
, new_buf
, exist_buf
);
786 /* 11. Maximum path check. */
787 if (newm
== existm
) {
788 /* If one path has a label but the other does not, do not treat
789 * them as equals for multipath
791 if ((new->extra
&&bgp_is_valid_label(&new->extra
->label
[0]))
793 && bgp_is_valid_label(&exist
->extra
->label
[0]))) {
796 "%s: %s and %s cannot be multipath, one has a label while the other does not",
797 pfx_buf
, new_buf
, exist_buf
);
798 } else if (bgp_flag_check(bgp
,
799 BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
802 * For the two paths, all comparison steps till IGP
804 * have succeeded - including AS_PATH hop count. Since
806 * bestpath as-path multipath-relax' knob is on, we
808 * an exact match of AS_PATH. Thus, mark the paths are
810 * That will trigger both these paths to get into the
818 "%s: %s and %s are equal via multipath-relax",
819 pfx_buf
, new_buf
, exist_buf
);
820 } else if (new->peer
->sort
== BGP_PEER_IBGP
) {
821 if (aspath_cmp(new->attr
->aspath
,
822 exist
->attr
->aspath
)) {
827 "%s: %s and %s are equal via matching aspaths",
828 pfx_buf
, new_buf
, exist_buf
);
830 } else if (new->peer
->as
== exist
->peer
->as
) {
835 "%s: %s and %s are equal via same remote-as",
836 pfx_buf
, new_buf
, exist_buf
);
840 * TODO: If unequal cost ibgp multipath is enabled we can
841 * mark the paths as equal here instead of returning
846 "%s: %s wins over %s after IGP metric comparison",
847 pfx_buf
, new_buf
, exist_buf
);
850 "%s: %s loses to %s after IGP metric comparison",
851 pfx_buf
, new_buf
, exist_buf
);
856 /* 12. If both paths are external, prefer the path that was received
857 first (the oldest one). This step minimizes route-flap, since a
858 newer path won't displace an older one, even if it was the
859 preferred route based on the additional decision criteria below. */
860 if (!bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
861 && new_sort
== BGP_PEER_EBGP
&& exist_sort
== BGP_PEER_EBGP
) {
862 if (CHECK_FLAG(new->flags
, BGP_INFO_SELECTED
)) {
865 "%s: %s wins over %s due to oldest external",
866 pfx_buf
, new_buf
, exist_buf
);
870 if (CHECK_FLAG(exist
->flags
, BGP_INFO_SELECTED
)) {
873 "%s: %s loses to %s due to oldest external",
874 pfx_buf
, new_buf
, exist_buf
);
879 /* 13. Router-ID comparision. */
880 /* If one of the paths is "stale", the corresponding peer router-id will
881 * be 0 and would always win over the other path. If originator id is
882 * used for the comparision, it will decide which path is better.
884 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
885 new_id
.s_addr
= newattr
->originator_id
.s_addr
;
887 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
888 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
889 exist_id
.s_addr
= existattr
->originator_id
.s_addr
;
891 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
893 if (ntohl(new_id
.s_addr
) < ntohl(exist_id
.s_addr
)) {
896 "%s: %s wins over %s due to Router-ID comparison",
897 pfx_buf
, new_buf
, exist_buf
);
901 if (ntohl(new_id
.s_addr
) > ntohl(exist_id
.s_addr
)) {
904 "%s: %s loses to %s due to Router-ID comparison",
905 pfx_buf
, new_buf
, exist_buf
);
909 /* 14. Cluster length comparision. */
910 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
911 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
913 if (new_cluster
< exist_cluster
) {
916 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
917 pfx_buf
, new_buf
, exist_buf
, new_cluster
,
922 if (new_cluster
> exist_cluster
) {
925 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
926 pfx_buf
, new_buf
, exist_buf
, new_cluster
,
931 /* 15. Neighbor address comparision. */
932 /* Do this only if neither path is "stale" as stale paths do not have
933 * valid peer information (as the connection may or may not be up).
935 if (CHECK_FLAG(exist
->flags
, BGP_INFO_STALE
)) {
938 "%s: %s wins over %s due to latter path being STALE",
939 pfx_buf
, new_buf
, exist_buf
);
943 if (CHECK_FLAG(new->flags
, BGP_INFO_STALE
)) {
946 "%s: %s loses to %s due to former path being STALE",
947 pfx_buf
, new_buf
, exist_buf
);
951 /* locally configured routes to advertise do not have su_remote */
952 if (new->peer
->su_remote
== NULL
)
954 if (exist
->peer
->su_remote
== NULL
)
957 ret
= sockunion_cmp(new->peer
->su_remote
, exist
->peer
->su_remote
);
962 "%s: %s loses to %s due to Neighor IP comparison",
963 pfx_buf
, new_buf
, exist_buf
);
970 "%s: %s wins over %s due to Neighor IP comparison",
971 pfx_buf
, new_buf
, exist_buf
);
976 zlog_debug("%s: %s wins over %s due to nothing left to compare",
977 pfx_buf
, new_buf
, exist_buf
);
982 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
983 * is preferred, or 0 if they are the same (usually will only occur if
984 * multipath is enabled
985 * This version is compatible with */
986 int bgp_info_cmp_compatible(struct bgp
*bgp
, struct bgp_info
*new,
987 struct bgp_info
*exist
, char *pfx_buf
, afi_t afi
,
992 ret
= bgp_info_cmp(bgp
, new, exist
, &paths_eq
, NULL
, 0, pfx_buf
, afi
,
1006 static enum filter_type
bgp_input_filter(struct peer
*peer
, struct prefix
*p
,
1007 struct attr
*attr
, afi_t afi
,
1010 struct bgp_filter
*filter
;
1012 filter
= &peer
->filter
[afi
][safi
];
1014 #define FILTER_EXIST_WARN(F, f, filter) \
1015 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1016 zlog_warn("%s: Could not find configured input %s-list %s!", \
1017 peer->host, #f, F##_IN_NAME(filter));
1019 if (DISTRIBUTE_IN_NAME(filter
)) {
1020 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
1022 if (access_list_apply(DISTRIBUTE_IN(filter
), p
) == FILTER_DENY
)
1026 if (PREFIX_LIST_IN_NAME(filter
)) {
1027 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
1029 if (prefix_list_apply(PREFIX_LIST_IN(filter
), p
) == PREFIX_DENY
)
1033 if (FILTER_LIST_IN_NAME(filter
)) {
1034 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
1036 if (as_list_apply(FILTER_LIST_IN(filter
), attr
->aspath
)
1041 return FILTER_PERMIT
;
1042 #undef FILTER_EXIST_WARN
1045 static enum filter_type
bgp_output_filter(struct peer
*peer
, struct prefix
*p
,
1046 struct attr
*attr
, afi_t afi
,
1049 struct bgp_filter
*filter
;
1051 filter
= &peer
->filter
[afi
][safi
];
1053 #define FILTER_EXIST_WARN(F, f, filter) \
1054 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1055 zlog_warn("%s: Could not find configured output %s-list %s!", \
1056 peer->host, #f, F##_OUT_NAME(filter));
1058 if (DISTRIBUTE_OUT_NAME(filter
)) {
1059 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
1061 if (access_list_apply(DISTRIBUTE_OUT(filter
), p
) == FILTER_DENY
)
1065 if (PREFIX_LIST_OUT_NAME(filter
)) {
1066 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
1068 if (prefix_list_apply(PREFIX_LIST_OUT(filter
), p
)
1073 if (FILTER_LIST_OUT_NAME(filter
)) {
1074 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
1076 if (as_list_apply(FILTER_LIST_OUT(filter
), attr
->aspath
)
1081 return FILTER_PERMIT
;
1082 #undef FILTER_EXIST_WARN
1085 /* If community attribute includes no_export then return 1. */
1086 static int bgp_community_filter(struct peer
*peer
, struct attr
*attr
)
1088 if (attr
->community
) {
1089 /* NO_ADVERTISE check. */
1090 if (community_include(attr
->community
, COMMUNITY_NO_ADVERTISE
))
1093 /* NO_EXPORT check. */
1094 if (peer
->sort
== BGP_PEER_EBGP
1095 && community_include(attr
->community
, COMMUNITY_NO_EXPORT
))
1098 /* NO_EXPORT_SUBCONFED check. */
1099 if (peer
->sort
== BGP_PEER_EBGP
1100 || peer
->sort
== BGP_PEER_CONFED
)
1101 if (community_include(attr
->community
,
1102 COMMUNITY_NO_EXPORT_SUBCONFED
))
1108 /* Route reflection loop check. */
1109 static int bgp_cluster_filter(struct peer
*peer
, struct attr
*attr
)
1111 struct in_addr cluster_id
;
1113 if (attr
->cluster
) {
1114 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
1115 cluster_id
= peer
->bgp
->cluster_id
;
1117 cluster_id
= peer
->bgp
->router_id
;
1119 if (cluster_loop_check(attr
->cluster
, cluster_id
))
1125 static int bgp_input_modifier(struct peer
*peer
, struct prefix
*p
,
1126 struct attr
*attr
, afi_t afi
, safi_t safi
,
1127 const char *rmap_name
)
1129 struct bgp_filter
*filter
;
1130 struct bgp_info info
;
1131 route_map_result_t ret
;
1132 struct route_map
*rmap
= NULL
;
1134 filter
= &peer
->filter
[afi
][safi
];
1136 /* Apply default weight value. */
1137 if (peer
->weight
[afi
][safi
])
1138 attr
->weight
= peer
->weight
[afi
][safi
];
1141 rmap
= route_map_lookup_by_name(rmap_name
);
1146 if (ROUTE_MAP_IN_NAME(filter
)) {
1147 rmap
= ROUTE_MAP_IN(filter
);
1154 /* Route map apply. */
1156 /* Duplicate current value to new strucutre for modification. */
1160 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1162 /* Apply BGP route map to the attribute. */
1163 ret
= route_map_apply(rmap
, p
, RMAP_BGP
, &info
);
1165 peer
->rmap_type
= 0;
1167 if (ret
== RMAP_DENYMATCH
) {
1168 /* Free newly generated AS path and community by
1170 bgp_attr_flush(attr
);
1177 static int bgp_output_modifier(struct peer
*peer
, struct prefix
*p
,
1178 struct attr
*attr
, afi_t afi
, safi_t safi
,
1179 const char *rmap_name
)
1181 struct bgp_info info
;
1182 route_map_result_t ret
;
1183 struct route_map
*rmap
= NULL
;
1187 * So if we get to this point and have no rmap_name
1188 * we want to just show the output as it currently
1194 /* Apply default weight value. */
1195 if (peer
->weight
[afi
][safi
])
1196 attr
->weight
= peer
->weight
[afi
][safi
];
1198 rmap
= route_map_lookup_by_name(rmap_name
);
1201 * If we have a route map name and we do not find
1202 * the routemap that means we have an implicit
1208 /* Route map apply. */
1209 /* Duplicate current value to new strucutre for modification. */
1213 rmap_type
= peer
->rmap_type
;
1214 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1216 /* Apply BGP route map to the attribute. */
1217 ret
= route_map_apply(rmap
, p
, RMAP_BGP
, &info
);
1219 peer
->rmap_type
= rmap_type
;
1221 if (ret
== RMAP_DENYMATCH
)
1223 * caller has multiple error paths with bgp_attr_flush()
1230 /* If this is an EBGP peer with remove-private-AS */
1231 static void bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1232 struct peer
*peer
, struct attr
*attr
)
1234 if (peer
->sort
== BGP_PEER_EBGP
1235 && (peer_af_flag_check(peer
, afi
, safi
,
1236 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)
1237 || peer_af_flag_check(peer
, afi
, safi
,
1238 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)
1239 || peer_af_flag_check(peer
, afi
, safi
,
1240 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)
1241 || peer_af_flag_check(peer
, afi
, safi
,
1242 PEER_FLAG_REMOVE_PRIVATE_AS
))) {
1243 // Take action on the entire aspath
1244 if (peer_af_flag_check(peer
, afi
, safi
,
1245 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)
1246 || peer_af_flag_check(peer
, afi
, safi
,
1247 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
1248 if (peer_af_flag_check(
1250 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1251 attr
->aspath
= aspath_replace_private_asns(
1252 attr
->aspath
, bgp
->as
);
1254 // The entire aspath consists of private ASNs so create
1256 else if (aspath_private_as_check(attr
->aspath
))
1257 attr
->aspath
= aspath_empty_get();
1259 // There are some public and some private ASNs, remove
1262 attr
->aspath
= aspath_remove_private_asns(
1266 // 'all' was not specified so the entire aspath must be private
1268 // for us to do anything
1269 else if (aspath_private_as_check(attr
->aspath
)) {
1270 if (peer_af_flag_check(
1272 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1273 attr
->aspath
= aspath_replace_private_asns(
1274 attr
->aspath
, bgp
->as
);
1276 attr
->aspath
= aspath_empty_get();
1281 /* If this is an EBGP peer with as-override */
1282 static void bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1283 struct peer
*peer
, struct attr
*attr
)
1285 if (peer
->sort
== BGP_PEER_EBGP
1286 && peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
1287 if (aspath_single_asn_check(attr
->aspath
, peer
->as
))
1288 attr
->aspath
= aspath_replace_specific_asn(
1289 attr
->aspath
, peer
->as
, bgp
->as
);
1293 void bgp_attr_add_gshut_community(struct attr
*attr
)
1295 struct community
*old
;
1296 struct community
*new;
1297 struct community
*merge
;
1298 struct community
*gshut
;
1300 old
= attr
->community
;
1301 gshut
= community_str2com("graceful-shutdown");
1304 merge
= community_merge(community_dup(old
), gshut
);
1306 if (old
->refcnt
== 0)
1307 community_free(old
);
1309 new = community_uniq_sort(merge
);
1310 community_free(merge
);
1312 new = community_dup(gshut
);
1315 community_free(gshut
);
1316 attr
->community
= new;
1317 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
);
1319 /* When we add the graceful-shutdown community we must also
1320 * lower the local-preference */
1321 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1322 attr
->local_pref
= BGP_GSHUT_LOCAL_PREF
;
1326 static void subgroup_announce_reset_nhop(u_char family
, struct attr
*attr
)
1328 if (family
== AF_INET
)
1329 attr
->nexthop
.s_addr
= 0;
1330 if (family
== AF_INET6
)
1331 memset(&attr
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1334 int subgroup_announce_check(struct bgp_node
*rn
, struct bgp_info
*ri
,
1335 struct update_subgroup
*subgrp
, struct prefix
*p
,
1338 struct bgp_filter
*filter
;
1341 struct peer
*onlypeer
;
1343 struct attr
*riattr
;
1344 char buf
[PREFIX_STRLEN
];
1350 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1352 if (DISABLE_BGP_ANNOUNCE
)
1355 afi
= SUBGRP_AFI(subgrp
);
1356 safi
= SUBGRP_SAFI(subgrp
);
1357 peer
= SUBGRP_PEER(subgrp
);
1359 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
))
1360 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1363 filter
= &peer
->filter
[afi
][safi
];
1364 bgp
= SUBGRP_INST(subgrp
);
1365 riattr
= bgp_info_mpath_count(ri
) ? bgp_info_mpath_attr(ri
) : ri
->attr
;
1368 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
)
1369 && ((ri
->type
== ZEBRA_ROUTE_BGP_DIRECT
)
1370 || (ri
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1373 * direct and direct_ext type routes originate internally even
1374 * though they can have peer pointers that reference other
1377 prefix2str(p
, buf
, PREFIX_STRLEN
);
1378 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe",
1384 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
))
1385 && ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_UNICAST
))
1386 && (ri
->type
== ZEBRA_ROUTE_BGP
)
1387 && (ri
->sub_type
== BGP_ROUTE_IMPORTED
)) {
1389 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1394 /* With addpath we may be asked to TX all kinds of paths so make sure
1396 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_VALID
)
1397 || CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
)
1398 || CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
1402 /* If this is not the bestpath then check to see if there is an enabled
1404 * feature that requires us to advertise it */
1405 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
1406 if (!bgp_addpath_tx_path(peer
, afi
, safi
, ri
)) {
1411 /* Aggregate-address suppress check. */
1412 if (ri
->extra
&& ri
->extra
->suppress
)
1413 if (!UNSUPPRESS_MAP_NAME(filter
)) {
1417 /* If it's labeled safi, make sure the route has a valid label. */
1418 if (safi
== SAFI_LABELED_UNICAST
) {
1419 mpls_label_t label
= bgp_adv_label(rn
, ri
, peer
, afi
, safi
);
1420 if (!bgp_is_valid_label(&label
)) {
1421 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1422 zlog_debug("u%" PRIu64
":s%" PRIu64
1423 " %s/%d is filtered - no label (%p)",
1424 subgrp
->update_group
->id
, subgrp
->id
,
1425 inet_ntop(p
->family
, &p
->u
.prefix
,
1426 buf
, SU_ADDRSTRLEN
),
1427 p
->prefixlen
, &label
);
1432 /* Do not send back route to sender. */
1433 if (onlypeer
&& from
== onlypeer
) {
1437 /* Do not send the default route in the BGP table if the neighbor is
1438 * configured for default-originate */
1439 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1440 PEER_FLAG_DEFAULT_ORIGINATE
)) {
1441 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1443 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1447 /* Transparency check. */
1448 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1449 && CHECK_FLAG(from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1454 /* If community is not disabled check the no-export and local. */
1455 if (!transparent
&& bgp_community_filter(peer
, riattr
)) {
1456 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1458 "subgrpannouncecheck: community filter check fail");
1462 /* If the attribute has originator-id and it is same as remote
1464 if (onlypeer
&& riattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)
1465 && (IPV4_ADDR_SAME(&onlypeer
->remote_id
, &riattr
->originator_id
))) {
1466 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1468 "%s [Update:SEND] %s originator-id is same as "
1471 prefix2str(p
, buf
, sizeof(buf
)));
1475 /* ORF prefix-list filter check */
1476 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1477 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1478 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
1479 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1480 if (peer
->orf_plist
[afi
][safi
]) {
1481 if (prefix_list_apply(peer
->orf_plist
[afi
][safi
], p
)
1483 if (bgp_debug_update(NULL
, p
,
1484 subgrp
->update_group
, 0))
1486 "%s [Update:SEND] %s is filtered via ORF",
1494 /* Output filter check. */
1495 if (bgp_output_filter(peer
, p
, riattr
, afi
, safi
) == FILTER_DENY
) {
1496 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1497 zlog_debug("%s [Update:SEND] %s is filtered",
1498 peer
->host
, prefix2str(p
, buf
, sizeof(buf
)));
1502 #ifdef BGP_SEND_ASPATH_CHECK
1503 /* AS path loop check. */
1504 if (onlypeer
&& aspath_loop_check(riattr
->aspath
, onlypeer
->as
)) {
1505 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1507 "%s [Update:SEND] suppress announcement to peer AS %u "
1508 "that is part of AS path.",
1509 onlypeer
->host
, onlypeer
->as
);
1512 #endif /* BGP_SEND_ASPATH_CHECK */
1514 /* If we're a CONFED we need to loop check the CONFED ID too */
1515 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
1516 if (aspath_loop_check(riattr
->aspath
, bgp
->confed_id
)) {
1517 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1519 "%s [Update:SEND] suppress announcement to peer AS %u"
1521 peer
->host
, bgp
->confed_id
);
1526 /* Route-Reflect check. */
1527 if (from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1532 /* IBGP reflection check. */
1533 if (reflect
&& !samepeer_safe
) {
1534 /* A route from a Client peer. */
1535 if (CHECK_FLAG(from
->af_flags
[afi
][safi
],
1536 PEER_FLAG_REFLECTOR_CLIENT
)) {
1537 /* Reflect to all the Non-Client peers and also to the
1538 Client peers other than the originator. Originator
1540 is already done. So there is noting to do. */
1541 /* no bgp client-to-client reflection check. */
1542 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
1543 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1544 PEER_FLAG_REFLECTOR_CLIENT
))
1547 /* A route from a Non-client peer. Reflect to all other
1549 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1550 PEER_FLAG_REFLECTOR_CLIENT
))
1555 /* For modify attribute, copy it to temporary structure. */
1556 bgp_attr_dup(attr
, riattr
);
1558 /* If local-preference is not set. */
1559 if ((peer
->sort
== BGP_PEER_IBGP
|| peer
->sort
== BGP_PEER_CONFED
)
1560 && (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)))) {
1561 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1562 attr
->local_pref
= bgp
->default_local_pref
;
1565 /* If originator-id is not set and the route is to be reflected,
1566 set the originator id */
1568 && (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)))) {
1569 IPV4_ADDR_COPY(&(attr
->originator_id
), &(from
->remote_id
));
1570 SET_FLAG(attr
->flag
, BGP_ATTR_ORIGINATOR_ID
);
1573 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
1575 if (peer
->sort
== BGP_PEER_EBGP
1576 && attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)) {
1577 if (from
!= bgp
->peer_self
&& !transparent
1578 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1579 PEER_FLAG_MED_UNCHANGED
))
1581 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
));
1584 /* Since the nexthop attribute can vary per peer, it is not explicitly
1586 * in announce check, only certain flags and length (or number of
1588 * -- for IPv6/MP_REACH) are set here in order to guide the update
1590 * code in setting the nexthop(s) on a per peer basis in
1592 * Typically, the source nexthop in the attribute is preserved but in
1594 * scenarios where we know it will always be overwritten, we reset the
1595 * nexthop to "0" in an attempt to achieve better Update packing. An
1596 * example of this is when a prefix from each of 2 IBGP peers needs to
1598 * announced to an EBGP peer (and they have the same attributes barring
1602 SET_FLAG(attr
->rmap_change_flags
, BATTR_REFLECTED
);
1604 #define NEXTHOP_IS_V6 \
1605 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
1606 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
1607 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
1608 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1610 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
1612 * the peer (group) is configured to receive link-local nexthop
1614 * and it is available in the prefix OR we're not reflecting the route
1616 * the peer (group) to whom we're going to announce is on a shared
1618 * and this is either a self-originated route or the peer is EBGP.
1620 if (NEXTHOP_IS_V6
) {
1621 attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1622 if ((CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1623 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)
1624 && IN6_IS_ADDR_LINKLOCAL(&attr
->mp_nexthop_local
))
1625 || (!reflect
&& peer
->shared_network
1626 && (from
== bgp
->peer_self
1627 || peer
->sort
== BGP_PEER_EBGP
))) {
1628 attr
->mp_nexthop_len
=
1629 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
1632 /* Clear off link-local nexthop in source, whenever it is not
1634 * ensure more prefixes share the same attribute for
1637 if (!(CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1638 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)))
1639 memset(&attr
->mp_nexthop_local
, 0, IPV6_MAX_BYTELEN
);
1642 bgp_peer_remove_private_as(bgp
, afi
, safi
, peer
, attr
);
1643 bgp_peer_as_override(bgp
, afi
, safi
, peer
, attr
);
1645 /* Route map & unsuppress-map apply. */
1646 if (ROUTE_MAP_OUT_NAME(filter
) || (ri
->extra
&& ri
->extra
->suppress
)) {
1647 struct bgp_info info
;
1648 struct bgp_info_extra dummy_info_extra
;
1649 struct attr dummy_attr
;
1655 memcpy(&dummy_info_extra
, ri
->extra
,
1656 sizeof(struct bgp_info_extra
));
1657 info
.extra
= &dummy_info_extra
;
1660 /* don't confuse inbound and outbound setting */
1661 RESET_FLAG(attr
->rmap_change_flags
);
1664 * The route reflector is not allowed to modify the attributes
1665 * of the reflected IBGP routes unless explicitly allowed.
1667 if ((from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1668 && !bgp_flag_check(bgp
,
1669 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
1670 bgp_attr_dup(&dummy_attr
, attr
);
1671 info
.attr
= &dummy_attr
;
1674 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1676 if (ri
->extra
&& ri
->extra
->suppress
)
1677 ret
= route_map_apply(UNSUPPRESS_MAP(filter
), p
,
1680 ret
= route_map_apply(ROUTE_MAP_OUT(filter
), p
,
1683 peer
->rmap_type
= 0;
1685 if (ret
== RMAP_DENYMATCH
) {
1686 bgp_attr_flush(attr
);
1691 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
)) {
1692 if (peer
->sort
== BGP_PEER_IBGP
1693 || peer
->sort
== BGP_PEER_CONFED
) {
1694 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1695 attr
->local_pref
= BGP_GSHUT_LOCAL_PREF
;
1697 bgp_attr_add_gshut_community(attr
);
1701 /* After route-map has been applied, we check to see if the nexthop to
1702 * be carried in the attribute (that is used for the announcement) can
1703 * be cleared off or not. We do this in all cases where we would be
1704 * setting the nexthop to "ourselves". For IPv6, we only need to
1706 * the global nexthop here; the link-local nexthop would have been
1708 * already, and if not, it is required by the update formation code.
1709 * Also see earlier comments in this function.
1712 * If route-map has performed some operation on the nexthop or the peer
1713 * configuration says to pass it unchanged, we cannot reset the nexthop
1714 * here, so only attempt to do it if these aren't true. Note that the
1715 * route-map handler itself might have cleared the nexthop, if for
1717 * it is configured as 'peer-address'.
1719 if (!bgp_rmap_nhop_changed(attr
->rmap_change_flags
,
1720 riattr
->rmap_change_flags
)
1722 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1723 PEER_FLAG_NEXTHOP_UNCHANGED
)) {
1724 /* We can reset the nexthop, if setting (or forcing) it to
1726 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1727 PEER_FLAG_NEXTHOP_SELF
)
1728 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1729 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
1731 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1732 PEER_FLAG_FORCE_NEXTHOP_SELF
))
1733 subgroup_announce_reset_nhop(
1734 (peer_cap_enhe(peer
, afi
, safi
)
1738 } else if (peer
->sort
== BGP_PEER_EBGP
) {
1739 /* Can also reset the nexthop if announcing to EBGP, but
1741 * no peer in the subgroup is on a shared subnet.
1742 * Note: 3rd party nexthop currently implemented for
1745 if (!bgp_subgrp_multiaccess_check_v4(riattr
->nexthop
,
1747 subgroup_announce_reset_nhop(
1748 (peer_cap_enhe(peer
, afi
, safi
)
1753 /* If IPv6/MP and nexthop does not have any override and happens
1755 * be a link-local address, reset it so that we don't pass along
1757 * source's link-local IPv6 address to recipients who may not be
1759 * the same interface.
1761 if (p
->family
== AF_INET6
|| peer_cap_enhe(peer
, afi
, safi
)) {
1762 if (IN6_IS_ADDR_LINKLOCAL(&attr
->mp_nexthop_global
))
1763 subgroup_announce_reset_nhop(AF_INET6
, attr
);
1770 void bgp_best_selection(struct bgp
*bgp
, struct bgp_node
*rn
,
1771 struct bgp_maxpaths_cfg
*mpath_cfg
,
1772 struct bgp_info_pair
*result
, afi_t afi
, safi_t safi
)
1774 struct bgp_info
*new_select
;
1775 struct bgp_info
*old_select
;
1776 struct bgp_info
*ri
;
1777 struct bgp_info
*ri1
;
1778 struct bgp_info
*ri2
;
1779 struct bgp_info
*nextri
= NULL
;
1780 int paths_eq
, do_mpath
, debug
;
1781 struct list mp_list
;
1782 char pfx_buf
[PREFIX2STR_BUFFER
];
1783 char path_buf
[PATH_ADDPATH_STR_BUFFER
];
1785 bgp_mp_list_init(&mp_list
);
1787 (mpath_cfg
->maxpaths_ebgp
> 1 || mpath_cfg
->maxpaths_ibgp
> 1);
1789 debug
= bgp_debug_bestpath(&rn
->p
);
1792 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
1794 /* bgp deterministic-med */
1796 if (bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
1798 /* Clear BGP_INFO_DMED_SELECTED for all paths */
1799 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
)
1800 bgp_info_unset_flag(rn
, ri1
, BGP_INFO_DMED_SELECTED
);
1802 for (ri1
= rn
->info
; ri1
; ri1
= ri1
->next
) {
1803 if (CHECK_FLAG(ri1
->flags
, BGP_INFO_DMED_CHECK
))
1805 if (BGP_INFO_HOLDDOWN(ri1
))
1807 if (ri1
->peer
&& ri1
->peer
!= bgp
->peer_self
)
1808 if (ri1
->peer
->status
!= Established
)
1813 for (ri2
= ri1
->next
; ri2
; ri2
= ri2
->next
) {
1814 if (CHECK_FLAG(ri2
->flags
,
1815 BGP_INFO_DMED_CHECK
))
1817 if (BGP_INFO_HOLDDOWN(ri2
))
1820 && ri2
->peer
!= bgp
->peer_self
1823 PEER_STATUS_NSF_WAIT
))
1824 if (ri2
->peer
->status
1828 if (aspath_cmp_left(ri1
->attr
->aspath
,
1830 || aspath_cmp_left_confed(
1832 ri2
->attr
->aspath
)) {
1833 if (bgp_info_cmp(bgp
, ri2
,
1839 bgp_info_unset_flag(
1841 BGP_INFO_DMED_SELECTED
);
1847 BGP_INFO_DMED_CHECK
);
1851 bgp_info_set_flag(rn
, new_select
, BGP_INFO_DMED_CHECK
);
1852 bgp_info_set_flag(rn
, new_select
,
1853 BGP_INFO_DMED_SELECTED
);
1856 bgp_info_path_with_addpath_rx_str(new_select
,
1858 zlog_debug("%s: %s is the bestpath from AS %d",
1860 aspath_get_first_as(
1861 new_select
->attr
->aspath
));
1866 /* Check old selected route and new selected route. */
1869 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1);
1871 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
))
1874 if (BGP_INFO_HOLDDOWN(ri
)) {
1875 /* reap REMOVED routes, if needs be
1876 * selected route must stay for a while longer though
1878 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)
1879 && (ri
!= old_select
))
1880 bgp_info_reap(rn
, ri
);
1883 zlog_debug("%s: ri %p in holddown", __func__
,
1889 if (ri
->peer
&& ri
->peer
!= bgp
->peer_self
1890 && !CHECK_FLAG(ri
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1891 if (ri
->peer
->status
!= Established
) {
1895 "%s: ri %p non self peer %s not estab state",
1896 __func__
, ri
, ri
->peer
->host
);
1901 if (bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
1902 && (!CHECK_FLAG(ri
->flags
, BGP_INFO_DMED_SELECTED
))) {
1903 bgp_info_unset_flag(rn
, ri
, BGP_INFO_DMED_CHECK
);
1905 zlog_debug("%s: ri %p dmed", __func__
, ri
);
1909 bgp_info_unset_flag(rn
, ri
, BGP_INFO_DMED_CHECK
);
1911 if (bgp_info_cmp(bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
,
1912 debug
, pfx_buf
, afi
, safi
)) {
1917 /* Now that we know which path is the bestpath see if any of the other
1919 * qualify as multipaths
1923 bgp_info_path_with_addpath_rx_str(new_select
, path_buf
);
1925 sprintf(path_buf
, "NONE");
1927 "%s: After path selection, newbest is %s oldbest was %s",
1929 old_select
? old_select
->peer
->host
: "NONE");
1932 if (do_mpath
&& new_select
) {
1933 for (ri
= rn
->info
; (ri
!= NULL
) && (nextri
= ri
->next
, 1);
1937 bgp_info_path_with_addpath_rx_str(ri
, path_buf
);
1939 if (ri
== new_select
) {
1942 "%s: %s is the bestpath, add to the multipath list",
1944 bgp_mp_list_add(&mp_list
, ri
);
1948 if (BGP_INFO_HOLDDOWN(ri
))
1951 if (ri
->peer
&& ri
->peer
!= bgp
->peer_self
1952 && !CHECK_FLAG(ri
->peer
->sflags
,
1953 PEER_STATUS_NSF_WAIT
))
1954 if (ri
->peer
->status
!= Established
)
1957 if (!bgp_info_nexthop_cmp(ri
, new_select
)) {
1960 "%s: %s has the same nexthop as the bestpath, skip it",
1965 bgp_info_cmp(bgp
, ri
, new_select
, &paths_eq
, mpath_cfg
,
1966 debug
, pfx_buf
, afi
, safi
);
1971 "%s: %s is equivalent to the bestpath, add to the multipath list",
1973 bgp_mp_list_add(&mp_list
, ri
);
1978 bgp_info_mpath_update(rn
, new_select
, old_select
, &mp_list
, mpath_cfg
);
1979 bgp_info_mpath_aggregate_update(new_select
, old_select
);
1980 bgp_mp_list_clear(&mp_list
);
1982 result
->old
= old_select
;
1983 result
->new = new_select
;
1989 * A new route/change in bestpath of an existing route. Evaluate the path
1990 * for advertisement to the subgroup.
1992 int subgroup_process_announce_selected(struct update_subgroup
*subgrp
,
1993 struct bgp_info
*selected
,
1994 struct bgp_node
*rn
,
1995 u_int32_t addpath_tx_id
)
1998 struct peer
*onlypeer
;
2004 afi
= SUBGRP_AFI(subgrp
);
2005 safi
= SUBGRP_SAFI(subgrp
);
2006 onlypeer
= ((SUBGRP_PCOUNT(subgrp
) == 1) ? (SUBGRP_PFIRST(subgrp
))->peer
2009 if (BGP_DEBUG(update
, UPDATE_OUT
)) {
2010 char buf_prefix
[PREFIX_STRLEN
];
2011 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
2012 zlog_debug("%s: p=%s, selected=%p", __func__
, buf_prefix
,
2016 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2017 if (onlypeer
&& CHECK_FLAG(onlypeer
->af_sflags
[afi
][safi
],
2018 PEER_STATUS_ORF_WAIT_REFRESH
))
2021 memset(&attr
, 0, sizeof(struct attr
));
2022 /* It's initialized in bgp_announce_check() */
2024 /* Announcement to the subgroup. If the route is filtered withdraw it.
2027 if (subgroup_announce_check(rn
, selected
, subgrp
, p
, &attr
))
2028 bgp_adj_out_set_subgroup(rn
, subgrp
, &attr
, selected
);
2030 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1,
2031 selected
->addpath_tx_id
);
2034 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2036 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, addpath_tx_id
);
2043 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2044 * This is called at the end of route processing.
2046 void bgp_zebra_clear_route_change_flags(struct bgp_node
*rn
)
2048 struct bgp_info
*ri
;
2050 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
2051 if (BGP_INFO_HOLDDOWN(ri
))
2053 UNSET_FLAG(ri
->flags
, BGP_INFO_IGP_CHANGED
);
2054 UNSET_FLAG(ri
->flags
, BGP_INFO_ATTR_CHANGED
);
2059 * Has the route changed from the RIB's perspective? This is invoked only
2060 * if the route selection returns the same best route as earlier - to
2061 * determine if we need to update zebra or not.
2063 int bgp_zebra_has_route_changed(struct bgp_node
*rn
, struct bgp_info
*selected
)
2065 struct bgp_info
*mpinfo
;
2067 /* If this is multipath, check all selected paths for any nexthop change
2069 * attribute change. Some attribute changes (e.g., community) aren't of
2070 * relevance to the RIB, but we'll update zebra to ensure we handle the
2071 * case of BGP nexthop change. This is the behavior when the best path
2073 * an attribute change anyway.
2075 if (CHECK_FLAG(selected
->flags
, BGP_INFO_IGP_CHANGED
)
2076 || CHECK_FLAG(selected
->flags
, BGP_INFO_MULTIPATH_CHG
))
2079 /* If this is multipath, check all selected paths for any nexthop change
2081 for (mpinfo
= bgp_info_mpath_first(selected
); mpinfo
;
2082 mpinfo
= bgp_info_mpath_next(mpinfo
)) {
2083 if (CHECK_FLAG(mpinfo
->flags
, BGP_INFO_IGP_CHANGED
)
2084 || CHECK_FLAG(mpinfo
->flags
, BGP_INFO_ATTR_CHANGED
))
2088 /* Nothing has changed from the RIB's perspective. */
2092 struct bgp_process_queue
{
2094 STAILQ_HEAD(, bgp_node
) pqueue
;
2095 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2097 unsigned int queued
;
2100 static void bgp_process_main_one(struct bgp
*bgp
, struct bgp_node
*rn
,
2101 afi_t afi
, safi_t safi
)
2103 struct prefix
*p
= &rn
->p
;
2104 struct bgp_info
*new_select
;
2105 struct bgp_info
*old_select
;
2106 struct bgp_info_pair old_and_new
;
2107 char pfx_buf
[PREFIX2STR_BUFFER
];
2110 /* Is it end of initial update? (after startup) */
2112 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
2113 sizeof(bgp
->update_delay_zebra_resume_time
));
2115 bgp
->main_zebra_update_hold
= 0;
2116 FOREACH_AFI_SAFI (afi
, safi
) {
2117 if (bgp_fibupd_safi(safi
))
2118 bgp_zebra_announce_table(bgp
, afi
, safi
);
2120 bgp
->main_peers_update_hold
= 0;
2122 bgp_start_routeadv(bgp
);
2126 debug
= bgp_debug_bestpath(&rn
->p
);
2128 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
2129 zlog_debug("%s: p=%s afi=%s, safi=%s start", __func__
, pfx_buf
,
2130 afi2str(afi
), safi2str(safi
));
2133 /* Best path selection. */
2134 bgp_best_selection(bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
,
2136 old_select
= old_and_new
.old
;
2137 new_select
= old_and_new
.new;
2139 /* Do we need to allocate or free labels?
2140 * Right now, since we only deal with per-prefix labels, it is not
2141 * necessary to do this upon changes to best path except if the label
2144 if (bgp
->allocate_mpls_labels
[afi
][safi
]) {
2147 || bgp_label_index_differs(new_select
, old_select
)
2148 || new_select
->sub_type
!= old_select
->sub_type
) {
2149 if (new_select
->sub_type
== BGP_ROUTE_STATIC
2150 && new_select
->attr
->flag
2152 BGP_ATTR_PREFIX_SID
)
2153 && new_select
->attr
->label_index
2154 != BGP_INVALID_LABEL_INDEX
) {
2157 BGP_NODE_REGISTERED_FOR_LABEL
))
2158 bgp_unregister_for_label(rn
);
2159 label_ntop(MPLS_LABEL_IMPLICIT_NULL
, 1,
2161 bgp_set_valid_label(&rn
->local_label
);
2163 bgp_register_for_label(rn
, new_select
);
2165 } else if (CHECK_FLAG(rn
->flags
,
2166 BGP_NODE_REGISTERED_FOR_LABEL
)) {
2167 bgp_unregister_for_label(rn
);
2169 } else if (CHECK_FLAG(rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
)) {
2170 bgp_unregister_for_label(rn
);
2174 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
2176 "%s: p=%s afi=%s, safi=%s, old_select=%p, new_select=%p",
2177 __func__
, pfx_buf
, afi2str(afi
), safi2str(safi
),
2178 old_select
, new_select
);
2181 /* If best route remains the same and this is not due to user-initiated
2182 * clear, see exactly what needs to be done.
2185 if (old_select
&& old_select
== new_select
2186 && !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
)
2187 && !CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
)
2188 && !bgp
->addpath_tx_used
[afi
][safi
]) {
2189 if (bgp_zebra_has_route_changed(rn
, old_select
)) {
2191 vnc_import_bgp_add_route(bgp
, p
, old_select
);
2192 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
2194 if (bgp_fibupd_safi(safi
)
2195 && !bgp_option_check(BGP_OPT_NO_FIB
)) {
2197 if (new_select
->type
== ZEBRA_ROUTE_BGP
2198 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
2199 || new_select
->sub_type
2200 == BGP_ROUTE_IMPORTED
))
2202 bgp_zebra_announce(rn
, p
, old_select
,
2206 UNSET_FLAG(old_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
2207 bgp_zebra_clear_route_change_flags(rn
);
2209 /* If there is a change of interest to peers, reannounce the
2211 if (CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
)
2212 || CHECK_FLAG(rn
->flags
, BGP_NODE_LABEL_CHANGED
)) {
2213 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2215 /* unicast routes must also be annouced to
2216 * labeled-unicast update-groups */
2217 if (safi
== SAFI_UNICAST
)
2218 group_announce_route(bgp
, afi
,
2219 SAFI_LABELED_UNICAST
, rn
,
2222 UNSET_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
);
2223 UNSET_FLAG(rn
->flags
, BGP_NODE_LABEL_CHANGED
);
2226 UNSET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2230 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2232 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
2234 /* bestpath has changed; bump version */
2235 if (old_select
|| new_select
) {
2236 bgp_bump_version(rn
);
2238 if (!bgp
->t_rmap_def_originate_eval
) {
2242 update_group_refresh_default_originate_route_map
,
2243 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
,
2244 &bgp
->t_rmap_def_originate_eval
);
2249 bgp_info_unset_flag(rn
, old_select
, BGP_INFO_SELECTED
);
2252 zlog_debug("%s: setting SELECTED flag", __func__
);
2253 bgp_info_set_flag(rn
, new_select
, BGP_INFO_SELECTED
);
2254 bgp_info_unset_flag(rn
, new_select
, BGP_INFO_ATTR_CHANGED
);
2255 UNSET_FLAG(new_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
2259 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2260 if (old_select
!= new_select
) {
2262 vnc_import_bgp_exterior_del_route(bgp
, p
,
2264 vnc_import_bgp_del_route(bgp
, p
, old_select
);
2267 vnc_import_bgp_exterior_add_route(bgp
, p
,
2269 vnc_import_bgp_add_route(bgp
, p
, new_select
);
2275 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2277 /* unicast routes must also be annouced to labeled-unicast update-groups
2279 if (safi
== SAFI_UNICAST
)
2280 group_announce_route(bgp
, afi
, SAFI_LABELED_UNICAST
, rn
,
2284 if (bgp_fibupd_safi(safi
) && (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
2285 && !bgp_option_check(BGP_OPT_NO_FIB
)) {
2286 if (new_select
&& new_select
->type
== ZEBRA_ROUTE_BGP
2287 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
2288 || new_select
->sub_type
== BGP_ROUTE_AGGREGATE
2289 || new_select
->sub_type
== BGP_ROUTE_IMPORTED
))
2291 bgp_zebra_announce(rn
, p
, new_select
, bgp
, afi
, safi
);
2293 /* Withdraw the route from the kernel. */
2294 if (old_select
&& old_select
->type
== ZEBRA_ROUTE_BGP
2295 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
2296 || old_select
->sub_type
== BGP_ROUTE_AGGREGATE
2297 || old_select
->sub_type
== BGP_ROUTE_IMPORTED
))
2299 bgp_zebra_withdraw(p
, old_select
, safi
);
2303 /* advertise/withdraw type-5 routes */
2304 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2305 if (advertise_type5_routes(bgp
, afi
) && new_select
&&
2306 (!new_select
->extra
|| !new_select
->extra
->parent
))
2307 bgp_evpn_advertise_type5_route(bgp
, &rn
->p
,
2310 else if (advertise_type5_routes(bgp
, afi
) && old_select
&&
2311 (!old_select
->extra
|| !old_select
->extra
->parent
))
2312 bgp_evpn_withdraw_type5_route(bgp
, &rn
->p
, afi
, safi
);
2315 /* Clear any route change flags. */
2316 bgp_zebra_clear_route_change_flags(rn
);
2318 /* Reap old select bgp_info, if it has been removed */
2319 if (old_select
&& CHECK_FLAG(old_select
->flags
, BGP_INFO_REMOVED
))
2320 bgp_info_reap(rn
, old_select
);
2322 UNSET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2326 static wq_item_status
bgp_process_wq(struct work_queue
*wq
, void *data
)
2328 struct bgp_process_queue
*pqnode
= data
;
2329 struct bgp
*bgp
= pqnode
->bgp
;
2330 struct bgp_table
*table
;
2331 struct bgp_node
*rn
;
2334 if (CHECK_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
)) {
2335 bgp_process_main_one(bgp
, NULL
, 0, 0);
2336 /* should always have dedicated wq call */
2337 assert(STAILQ_FIRST(&pqnode
->pqueue
) == NULL
);
2341 while (!STAILQ_EMPTY(&pqnode
->pqueue
)) {
2342 rn
= STAILQ_FIRST(&pqnode
->pqueue
);
2343 STAILQ_REMOVE_HEAD(&pqnode
->pqueue
, pq
);
2344 STAILQ_NEXT(rn
, pq
) = NULL
; /* complete unlink */
2345 table
= bgp_node_table(rn
);
2346 /* note, new RNs may be added as part of processing */
2347 bgp_process_main_one(bgp
, rn
, table
->afi
, table
->safi
);
2349 bgp_unlock_node(rn
);
2350 bgp_table_unlock(table
);
2356 static void bgp_processq_del(struct work_queue
*wq
, void *data
)
2358 struct bgp_process_queue
*pqnode
= data
;
2360 bgp_unlock(pqnode
->bgp
);
2362 XFREE(MTYPE_BGP_PROCESS_QUEUE
, pqnode
);
2365 void bgp_process_queue_init(void)
2367 if (!bm
->process_main_queue
) {
2368 bm
->process_main_queue
=
2369 work_queue_new(bm
->master
, "process_main_queue");
2371 if (!bm
->process_main_queue
) {
2372 zlog_err("%s: Failed to allocate work queue", __func__
);
2377 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_wq
;
2378 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2379 bm
->process_main_queue
->spec
.max_retries
= 0;
2380 bm
->process_main_queue
->spec
.hold
= 50;
2381 /* Use a higher yield value of 50ms for main queue processing */
2382 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2385 static struct bgp_process_queue
*bgp_processq_alloc(struct bgp
*bgp
)
2387 struct bgp_process_queue
*pqnode
;
2389 pqnode
= XCALLOC(MTYPE_BGP_PROCESS_QUEUE
,
2390 sizeof(struct bgp_process_queue
));
2392 /* unlocked in bgp_processq_del */
2393 pqnode
->bgp
= bgp_lock(bgp
);
2394 STAILQ_INIT(&pqnode
->pqueue
);
2399 void bgp_process(struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2401 #define ARBITRARY_PROCESS_QLEN 10000
2402 struct work_queue
*wq
= bm
->process_main_queue
;
2403 struct bgp_process_queue
*pqnode
;
2404 int pqnode_reuse
= 0;
2406 /* already scheduled for processing? */
2407 if (CHECK_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2413 /* Add route nodes to an existing work queue item until reaching the
2414 limit only if is from the same BGP view and it's not an EOIU marker
2416 if (work_queue_item_count(wq
)) {
2417 struct work_queue_item
*item
= work_queue_last_item(wq
);
2418 pqnode
= item
->data
;
2420 if (CHECK_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
)
2421 || pqnode
->bgp
!= bgp
2422 || pqnode
->queued
>= ARBITRARY_PROCESS_QLEN
)
2423 pqnode
= bgp_processq_alloc(bgp
);
2427 pqnode
= bgp_processq_alloc(bgp
);
2428 /* all unlocked in bgp_process_wq */
2429 bgp_table_lock(bgp_node_table(rn
));
2431 SET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2434 /* can't be enqueued twice */
2435 assert(STAILQ_NEXT(rn
, pq
) == NULL
);
2436 STAILQ_INSERT_TAIL(&pqnode
->pqueue
, rn
, pq
);
2440 work_queue_add(wq
, pqnode
);
2445 void bgp_add_eoiu_mark(struct bgp
*bgp
)
2447 struct bgp_process_queue
*pqnode
;
2449 if (bm
->process_main_queue
== NULL
)
2452 pqnode
= bgp_processq_alloc(bgp
);
2454 SET_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
);
2455 work_queue_add(bm
->process_main_queue
, pqnode
);
2458 static int bgp_maximum_prefix_restart_timer(struct thread
*thread
)
2462 peer
= THREAD_ARG(thread
);
2463 peer
->t_pmax_restart
= NULL
;
2465 if (bgp_debug_neighbor_events(peer
))
2467 "%s Maximum-prefix restart timer expired, restore peering",
2470 peer_clear(peer
, NULL
);
2475 int bgp_maximum_prefix_overflow(struct peer
*peer
, afi_t afi
, safi_t safi
,
2479 iana_safi_t pkt_safi
;
2481 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2484 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
]) {
2485 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2486 PEER_STATUS_PREFIX_LIMIT
)
2491 "%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2493 afi_safi_print(afi
, safi
), peer
->host
,
2494 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2495 SET_FLAG(peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2497 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
2498 PEER_FLAG_MAX_PREFIX_WARNING
))
2501 /* Convert AFI, SAFI to values for packet. */
2502 pkt_afi
= afi_int2iana(afi
);
2503 pkt_safi
= safi_int2iana(safi
);
2507 ndata
[0] = (pkt_afi
>> 8);
2509 ndata
[2] = pkt_safi
;
2510 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2511 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2512 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2513 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2515 SET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2516 bgp_notify_send_with_data(peer
, BGP_NOTIFY_CEASE
,
2517 BGP_NOTIFY_CEASE_MAX_PREFIX
,
2521 /* Dynamic peers will just close their connection. */
2522 if (peer_dynamic_neighbor(peer
))
2525 /* restart timer start */
2526 if (peer
->pmax_restart
[afi
][safi
]) {
2527 peer
->v_pmax_restart
=
2528 peer
->pmax_restart
[afi
][safi
] * 60;
2530 if (bgp_debug_neighbor_events(peer
))
2532 "%s Maximum-prefix restart timer started for %d secs",
2533 peer
->host
, peer
->v_pmax_restart
);
2535 BGP_TIMER_ON(peer
->t_pmax_restart
,
2536 bgp_maximum_prefix_restart_timer
,
2537 peer
->v_pmax_restart
);
2542 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2543 PEER_STATUS_PREFIX_LIMIT
);
2545 if (peer
->pcount
[afi
][safi
]
2546 > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100)) {
2547 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2548 PEER_STATUS_PREFIX_THRESHOLD
)
2553 "%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2554 afi_safi_print(afi
, safi
), peer
->host
,
2555 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2556 SET_FLAG(peer
->af_sflags
[afi
][safi
],
2557 PEER_STATUS_PREFIX_THRESHOLD
);
2559 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2560 PEER_STATUS_PREFIX_THRESHOLD
);
2564 /* Unconditionally remove the route from the RIB, without taking
2565 * damping into consideration (eg, because the session went down)
2567 void bgp_rib_remove(struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2568 afi_t afi
, safi_t safi
)
2570 bgp_aggregate_decrement(peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2572 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
2573 bgp_info_delete(rn
, ri
); /* keep historical info */
2575 bgp_process(peer
->bgp
, rn
, afi
, safi
);
2578 static void bgp_rib_withdraw(struct bgp_node
*rn
, struct bgp_info
*ri
,
2579 struct peer
*peer
, afi_t afi
, safi_t safi
,
2580 struct prefix_rd
*prd
)
2582 int status
= BGP_DAMP_NONE
;
2584 /* apply dampening, if result is suppressed, we'll be retaining
2585 * the bgp_info in the RIB for historical reference.
2587 if (CHECK_FLAG(peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2588 && peer
->sort
== BGP_PEER_EBGP
)
2589 if ((status
= bgp_damp_withdraw(ri
, rn
, afi
, safi
, 0))
2590 == BGP_DAMP_SUPPRESSED
) {
2591 bgp_aggregate_decrement(peer
->bgp
, &rn
->p
, ri
, afi
,
2597 if (safi
== SAFI_MPLS_VPN
) {
2598 struct bgp_node
*prn
= NULL
;
2599 struct bgp_table
*table
= NULL
;
2601 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
],
2602 (struct prefix
*)prd
);
2604 table
= (struct bgp_table
*)(prn
->info
);
2606 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2607 peer
->bgp
, prd
, table
, &rn
->p
, ri
);
2609 bgp_unlock_node(prn
);
2611 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2612 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
2614 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, ri
);
2615 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
,
2621 /* If this is an EVPN route, process for un-import. */
2622 if (safi
== SAFI_EVPN
)
2623 bgp_evpn_unimport_route(peer
->bgp
, afi
, safi
, &rn
->p
, ri
);
2625 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
2628 struct bgp_info
*info_make(int type
, int sub_type
, u_short instance
,
2629 struct peer
*peer
, struct attr
*attr
,
2630 struct bgp_node
*rn
)
2632 struct bgp_info
*new;
2634 /* Make new BGP info. */
2635 new = XCALLOC(MTYPE_BGP_ROUTE
, sizeof(struct bgp_info
));
2637 new->instance
= instance
;
2638 new->sub_type
= sub_type
;
2641 new->uptime
= bgp_clock();
2643 new->addpath_tx_id
= ++peer
->bgp
->addpath_tx_id
;
2647 static void overlay_index_update(struct attr
*attr
,
2648 struct eth_segment_id
*eth_s_id
,
2649 union gw_addr
*gw_ip
)
2654 if (eth_s_id
== NULL
) {
2655 memset(&(attr
->evpn_overlay
.eth_s_id
), 0,
2656 sizeof(struct eth_segment_id
));
2658 memcpy(&(attr
->evpn_overlay
.eth_s_id
), eth_s_id
,
2659 sizeof(struct eth_segment_id
));
2661 if (gw_ip
== NULL
) {
2662 memset(&(attr
->evpn_overlay
.gw_ip
), 0, sizeof(union gw_addr
));
2664 memcpy(&(attr
->evpn_overlay
.gw_ip
), gw_ip
,
2665 sizeof(union gw_addr
));
2669 static bool overlay_index_equal(afi_t afi
, struct bgp_info
*info
,
2670 struct eth_segment_id
*eth_s_id
,
2671 union gw_addr
*gw_ip
)
2673 struct eth_segment_id
*info_eth_s_id
, *info_eth_s_id_remote
;
2674 union gw_addr
*info_gw_ip
, *info_gw_ip_remote
;
2677 if (afi
!= AFI_L2VPN
)
2680 memset(&temp
, 0, 16);
2681 info_eth_s_id
= (struct eth_segment_id
*)&temp
;
2682 info_gw_ip
= (union gw_addr
*)&temp
;
2683 if (eth_s_id
== NULL
&& gw_ip
== NULL
)
2686 info_eth_s_id
= &(info
->attr
->evpn_overlay
.eth_s_id
);
2687 info_gw_ip
= &(info
->attr
->evpn_overlay
.gw_ip
);
2690 info_gw_ip_remote
= (union gw_addr
*)&temp
;
2692 info_gw_ip_remote
= gw_ip
;
2693 if (eth_s_id
== NULL
)
2694 info_eth_s_id_remote
= (struct eth_segment_id
*)&temp
;
2696 info_eth_s_id_remote
= eth_s_id
;
2697 if (!memcmp(info_gw_ip
, info_gw_ip_remote
, sizeof(union gw_addr
)))
2699 return !memcmp(info_eth_s_id
, info_eth_s_id_remote
,
2700 sizeof(struct eth_segment_id
));
2703 /* Check if received nexthop is valid or not. */
2704 static int bgp_update_martian_nexthop(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
2709 /* Only validated for unicast and multicast currently. */
2710 /* Also valid for EVPN where the nexthop is an IP address. */
2711 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
&& safi
!= SAFI_EVPN
)
2714 /* If NEXT_HOP is present, validate it. */
2715 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
)) {
2716 if (attr
->nexthop
.s_addr
== 0
2717 || IPV4_CLASS_DE(ntohl(attr
->nexthop
.s_addr
))
2718 || bgp_nexthop_self(bgp
, attr
->nexthop
))
2722 /* If MP_NEXTHOP is present, validate it. */
2723 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2724 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2725 * it is not an IPv6 link-local address.
2727 if (attr
->mp_nexthop_len
) {
2728 switch (attr
->mp_nexthop_len
) {
2729 case BGP_ATTR_NHLEN_IPV4
:
2730 case BGP_ATTR_NHLEN_VPNV4
:
2731 ret
= (attr
->mp_nexthop_global_in
.s_addr
== 0
2732 || IPV4_CLASS_DE(ntohl(
2733 attr
->mp_nexthop_global_in
.s_addr
))
2734 || bgp_nexthop_self(bgp
,
2735 attr
->mp_nexthop_global_in
));
2738 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2739 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2740 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2741 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attr
->mp_nexthop_global
)
2742 || IN6_IS_ADDR_LOOPBACK(&attr
->mp_nexthop_global
)
2743 || IN6_IS_ADDR_MULTICAST(
2744 &attr
->mp_nexthop_global
));
2756 int bgp_update(struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
2757 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2758 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
2759 u_int32_t num_labels
, int soft_reconfig
,
2760 struct bgp_route_evpn
*evpn
)
2763 int aspath_loop_count
= 0;
2764 struct bgp_node
*rn
;
2766 struct attr new_attr
;
2767 struct attr
*attr_new
;
2768 struct bgp_info
*ri
;
2769 struct bgp_info
*new;
2770 struct bgp_info_extra
*extra
;
2772 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2774 int do_loop_check
= 1;
2775 int has_valid_label
= 0;
2777 int vnc_implicit_withdraw
= 0;
2781 memset(&new_attr
, 0, sizeof(struct attr
));
2782 new_attr
.label_index
= BGP_INVALID_LABEL_INDEX
;
2783 new_attr
.label
= MPLS_INVALID_LABEL
;
2786 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2787 /* TODO: Check to see if we can get rid of "is_valid_label" */
2788 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
2789 has_valid_label
= (num_labels
> 0) ? 1 : 0;
2791 has_valid_label
= bgp_is_valid_label(label
);
2793 /* When peer's soft reconfiguration enabled. Record input packet in
2796 && CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2797 && peer
!= bgp
->peer_self
)
2798 bgp_adj_in_set(rn
, peer
, attr
, addpath_id
);
2800 /* Check previously received route. */
2801 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2802 if (ri
->peer
== peer
&& ri
->type
== type
2803 && ri
->sub_type
== sub_type
2804 && ri
->addpath_rx_id
== addpath_id
)
2807 /* AS path local-as loop check. */
2808 if (peer
->change_local_as
) {
2809 if (peer
->allowas_in
[afi
][safi
])
2810 aspath_loop_count
= peer
->allowas_in
[afi
][safi
];
2811 else if (!CHECK_FLAG(peer
->flags
,
2812 PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2813 aspath_loop_count
= 1;
2815 if (aspath_loop_check(attr
->aspath
, peer
->change_local_as
)
2816 > aspath_loop_count
) {
2817 reason
= "as-path contains our own AS;";
2822 /* If the peer is configured for "allowas-in origin" and the last ASN in
2824 * as-path is our ASN then we do not need to call aspath_loop_check
2826 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2827 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2830 /* AS path loop check. */
2831 if (do_loop_check
) {
2832 if (aspath_loop_check(attr
->aspath
, bgp
->as
)
2833 > peer
->allowas_in
[afi
][safi
]
2834 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2835 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
)
2836 > peer
->allowas_in
[afi
][safi
])) {
2837 reason
= "as-path contains our own AS;";
2842 /* Route reflector originator ID check. */
2843 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)
2844 && IPV4_ADDR_SAME(&bgp
->router_id
, &attr
->originator_id
)) {
2845 reason
= "originator is us;";
2849 /* Route reflector cluster ID check. */
2850 if (bgp_cluster_filter(peer
, attr
)) {
2851 reason
= "reflected from the same cluster;";
2855 /* Apply incoming filter. */
2856 if (bgp_input_filter(peer
, p
, attr
, afi
, safi
) == FILTER_DENY
) {
2861 bgp_attr_dup(&new_attr
, attr
);
2863 /* Apply incoming route-map.
2864 * NB: new_attr may now contain newly allocated values from route-map
2866 * commands, so we need bgp_attr_flush in the error paths, until we
2868 * the attr (which takes over the memory references) */
2869 if (bgp_input_modifier(peer
, p
, &new_attr
, afi
, safi
, NULL
)
2871 reason
= "route-map;";
2872 bgp_attr_flush(&new_attr
);
2876 if (peer
->sort
== BGP_PEER_EBGP
) {
2878 /* If we receive the graceful-shutdown community from an eBGP
2879 * peer we must lower local-preference */
2880 if (new_attr
.community
2881 && community_include(new_attr
.community
, COMMUNITY_GSHUT
)) {
2882 new_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
2883 new_attr
.local_pref
= BGP_GSHUT_LOCAL_PREF
;
2885 /* If graceful-shutdown is configured then add the GSHUT
2886 * community to all paths received from eBGP peers */
2887 } else if (bgp_flag_check(peer
->bgp
,
2888 BGP_FLAG_GRACEFUL_SHUTDOWN
)) {
2889 bgp_attr_add_gshut_community(&new_attr
);
2893 /* next hop check. */
2894 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
)
2895 && bgp_update_martian_nexthop(bgp
, afi
, safi
, &new_attr
)) {
2896 reason
= "martian or self next-hop;";
2897 bgp_attr_flush(&new_attr
);
2901 attr_new
= bgp_attr_intern(&new_attr
);
2903 /* If the update is implicit withdraw. */
2905 ri
->uptime
= bgp_clock();
2906 same_attr
= attrhash_cmp(ri
->attr
, attr_new
);
2908 /* Same attribute comes in. */
2909 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)
2910 && attrhash_cmp(ri
->attr
, attr_new
)
2911 && (!has_valid_label
2912 || memcmp(&(bgp_info_extra_get(ri
))->label
, label
,
2913 num_labels
* sizeof(mpls_label_t
))
2915 && (overlay_index_equal(
2916 afi
, ri
, evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
2917 evpn
== NULL
? NULL
: &evpn
->gw_ip
))) {
2918 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
2919 BGP_CONFIG_DAMPENING
)
2920 && peer
->sort
== BGP_PEER_EBGP
2921 && CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
)) {
2922 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2923 bgp_debug_rdpfxpath2str(
2924 afi
, safi
, prd
, p
, label
,
2925 num_labels
, addpath_id
? 1 : 0,
2926 addpath_id
, pfx_buf
,
2928 zlog_debug("%s rcvd %s", peer
->host
,
2932 if (bgp_damp_update(ri
, rn
, afi
, safi
)
2933 != BGP_DAMP_SUPPRESSED
) {
2934 bgp_aggregate_increment(bgp
, p
, ri
, afi
,
2936 bgp_process(bgp
, rn
, afi
, safi
);
2938 } else /* Duplicate - odd */
2940 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2941 if (!peer
->rcvd_attr_printed
) {
2943 "%s rcvd UPDATE w/ attr: %s",
2945 peer
->rcvd_attr_str
);
2946 peer
->rcvd_attr_printed
= 1;
2949 bgp_debug_rdpfxpath2str(
2950 afi
, safi
, prd
, p
, label
,
2951 num_labels
, addpath_id
? 1 : 0,
2952 addpath_id
, pfx_buf
,
2955 "%s rcvd %s...duplicate ignored",
2956 peer
->host
, pfx_buf
);
2959 /* graceful restart STALE flag unset. */
2960 if (CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
)) {
2961 bgp_info_unset_flag(rn
, ri
,
2963 bgp_process(bgp
, rn
, afi
, safi
);
2967 bgp_unlock_node(rn
);
2968 bgp_attr_unintern(&attr_new
);
2973 /* Withdraw/Announce before we fully processed the withdraw */
2974 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
2975 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2976 bgp_debug_rdpfxpath2str(
2977 afi
, safi
, prd
, p
, label
, num_labels
,
2978 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
2981 "%s rcvd %s, flapped quicker than processing",
2982 peer
->host
, pfx_buf
);
2985 bgp_info_restore(rn
, ri
);
2988 /* Received Logging. */
2989 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2990 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
,
2991 num_labels
, addpath_id
? 1 : 0,
2992 addpath_id
, pfx_buf
,
2994 zlog_debug("%s rcvd %s", peer
->host
, pfx_buf
);
2997 /* graceful restart STALE flag unset. */
2998 if (CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
))
2999 bgp_info_unset_flag(rn
, ri
, BGP_INFO_STALE
);
3001 /* The attribute is changed. */
3002 bgp_info_set_flag(rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3004 /* implicit withdraw, decrement aggregate and pcount here.
3005 * only if update is accepted, they'll increment below.
3007 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
3009 /* Update bgp route dampening information. */
3010 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
3011 && peer
->sort
== BGP_PEER_EBGP
) {
3012 /* This is implicit withdraw so we should update
3015 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
3016 bgp_damp_withdraw(ri
, rn
, afi
, safi
, 1);
3019 if (safi
== SAFI_MPLS_VPN
) {
3020 struct bgp_node
*prn
= NULL
;
3021 struct bgp_table
*table
= NULL
;
3023 prn
= bgp_node_get(bgp
->rib
[afi
][safi
],
3024 (struct prefix
*)prd
);
3026 table
= (struct bgp_table
*)(prn
->info
);
3028 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3029 bgp
, prd
, table
, p
, ri
);
3031 bgp_unlock_node(prn
);
3033 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3034 && (safi
== SAFI_UNICAST
)) {
3035 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
3037 * Implicit withdraw case.
3039 ++vnc_implicit_withdraw
;
3040 vnc_import_bgp_del_route(bgp
, p
, ri
);
3041 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
3046 /* Special handling for EVPN update of an existing route. If the
3047 * extended community attribute has changed, we need to
3049 * the route using its existing extended community. It will be
3050 * subsequently processed for import with the new extended
3053 if (safi
== SAFI_EVPN
&& !same_attr
) {
3055 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
3057 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))) {
3060 cmp
= ecommunity_cmp(ri
->attr
->ecommunity
,
3061 attr_new
->ecommunity
);
3063 if (bgp_debug_update(peer
, p
, NULL
, 1))
3065 "Change in EXT-COMM, existing %s new %s",
3067 ri
->attr
->ecommunity
),
3069 attr_new
->ecommunity
));
3070 bgp_evpn_unimport_route(bgp
, afi
, safi
,
3076 /* Update to new attribute. */
3077 bgp_attr_unintern(&ri
->attr
);
3078 ri
->attr
= attr_new
;
3080 /* Update MPLS label */
3081 if (has_valid_label
) {
3082 extra
= bgp_info_extra_get(ri
);
3083 memcpy(&extra
->label
, label
,
3084 num_labels
* sizeof(mpls_label_t
));
3085 extra
->num_labels
= num_labels
;
3086 if (!(afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
))
3087 bgp_set_valid_label(&extra
->label
[0]);
3091 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3092 && (safi
== SAFI_UNICAST
)) {
3093 if (vnc_implicit_withdraw
) {
3095 * Add back the route with its new attributes
3097 * The route is still selected, until the route
3099 * queued by bgp_process actually runs. We have
3101 * update to the VNC side immediately to avoid
3103 * configuration changes (e.g., route-map
3105 * trigger re-importation of the entire RIB.
3107 vnc_import_bgp_add_route(bgp
, p
, ri
);
3108 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
3112 /* Update Overlay Index */
3113 if (afi
== AFI_L2VPN
) {
3114 overlay_index_update(
3115 ri
->attr
, evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3116 evpn
== NULL
? NULL
: &evpn
->gw_ip
);
3119 /* Update bgp route dampening information. */
3120 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
3121 && peer
->sort
== BGP_PEER_EBGP
) {
3122 /* Now we do normal update dampening. */
3123 ret
= bgp_damp_update(ri
, rn
, afi
, safi
);
3124 if (ret
== BGP_DAMP_SUPPRESSED
) {
3125 bgp_unlock_node(rn
);
3130 /* Nexthop reachability check - for unicast and
3131 * labeled-unicast.. */
3132 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3133 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
3134 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1
3135 && !CHECK_FLAG(peer
->flags
,
3136 PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3138 bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
3143 if (bgp_find_or_add_nexthop(bgp
, afi
, ri
, NULL
,
3145 || CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
))
3146 bgp_info_set_flag(rn
, ri
, BGP_INFO_VALID
);
3148 if (BGP_DEBUG(nht
, NHT
)) {
3149 char buf1
[INET6_ADDRSTRLEN
];
3151 (const void *)&attr_new
3153 buf1
, INET6_ADDRSTRLEN
);
3154 zlog_debug("%s(%s): NH unresolved",
3155 __FUNCTION__
, buf1
);
3157 bgp_info_unset_flag(rn
, ri
, BGP_INFO_VALID
);
3160 bgp_info_set_flag(rn
, ri
, BGP_INFO_VALID
);
3163 if (safi
== SAFI_MPLS_VPN
) {
3164 struct bgp_node
*prn
= NULL
;
3165 struct bgp_table
*table
= NULL
;
3167 prn
= bgp_node_get(bgp
->rib
[afi
][safi
],
3168 (struct prefix
*)prd
);
3170 table
= (struct bgp_table
*)(prn
->info
);
3172 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3173 bgp
, prd
, table
, p
, ri
);
3175 bgp_unlock_node(prn
);
3179 /* If this is an EVPN route and some attribute has changed,
3181 * route for import. If the extended community has changed, we
3183 * have done the un-import earlier and the import would result
3185 * route getting injected into appropriate L2 VNIs. If it is
3187 * some other attribute change, the import will result in
3189 * the attributes for the route in the VNI(s).
3191 if (safi
== SAFI_EVPN
&& !same_attr
)
3192 bgp_evpn_import_route(bgp
, afi
, safi
, p
, ri
);
3194 /* Process change. */
3195 bgp_aggregate_increment(bgp
, p
, ri
, afi
, safi
);
3197 bgp_process(bgp
, rn
, afi
, safi
);
3198 bgp_unlock_node(rn
);
3200 if (SAFI_UNICAST
== safi
3201 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3202 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3204 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, ri
);
3206 if ((SAFI_MPLS_VPN
== safi
)
3207 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3209 vpn_leak_to_vrf_update(bgp
, ri
);
3213 if (SAFI_MPLS_VPN
== safi
) {
3214 mpls_label_t label_decoded
= decode_label(label
);
3216 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
,
3217 type
, sub_type
, &label_decoded
);
3219 if (SAFI_ENCAP
== safi
) {
3220 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
,
3221 type
, sub_type
, NULL
);
3226 } // End of implicit withdraw
3228 /* Received Logging. */
3229 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3230 if (!peer
->rcvd_attr_printed
) {
3231 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
3232 peer
->rcvd_attr_str
);
3233 peer
->rcvd_attr_printed
= 1;
3236 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3237 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3239 zlog_debug("%s rcvd %s", peer
->host
, pfx_buf
);
3242 /* Make new BGP info. */
3243 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
3245 /* Update MPLS label */
3246 if (has_valid_label
) {
3247 extra
= bgp_info_extra_get(new);
3248 memcpy(&extra
->label
, label
, num_labels
* sizeof(mpls_label_t
));
3249 extra
->num_labels
= num_labels
;
3250 if (!(afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
))
3251 bgp_set_valid_label(&extra
->label
[0]);
3254 /* Update Overlay Index */
3255 if (afi
== AFI_L2VPN
) {
3256 overlay_index_update(new->attr
,
3257 evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3258 evpn
== NULL
? NULL
: &evpn
->gw_ip
);
3260 /* Nexthop reachability check. */
3261 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3262 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
3263 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1
3264 && !CHECK_FLAG(peer
->flags
,
3265 PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3266 && !bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
3271 if (bgp_find_or_add_nexthop(bgp
, afi
, new, NULL
, connected
)
3272 || CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
))
3273 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
3275 if (BGP_DEBUG(nht
, NHT
)) {
3276 char buf1
[INET6_ADDRSTRLEN
];
3278 (const void *)&attr_new
->nexthop
,
3279 buf1
, INET6_ADDRSTRLEN
);
3280 zlog_debug("%s(%s): NH unresolved",
3281 __FUNCTION__
, buf1
);
3283 bgp_info_unset_flag(rn
, new, BGP_INFO_VALID
);
3286 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
3289 new->addpath_rx_id
= addpath_id
;
3291 /* Increment prefix */
3292 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
3294 /* Register new BGP information. */
3295 bgp_info_add(rn
, new);
3297 /* route_node_get lock */
3298 bgp_unlock_node(rn
);
3301 if (safi
== SAFI_MPLS_VPN
) {
3302 struct bgp_node
*prn
= NULL
;
3303 struct bgp_table
*table
= NULL
;
3305 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*)prd
);
3307 table
= (struct bgp_table
*)(prn
->info
);
3309 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3310 bgp
, prd
, table
, p
, new);
3312 bgp_unlock_node(prn
);
3316 /* If maximum prefix count is configured and current prefix
3318 if (bgp_maximum_prefix_overflow(peer
, afi
, safi
, 0))
3321 /* If this is an EVPN route, process for import. */
3322 if (safi
== SAFI_EVPN
)
3323 bgp_evpn_import_route(bgp
, afi
, safi
, p
, new);
3325 /* Process change. */
3326 bgp_process(bgp
, rn
, afi
, safi
);
3328 if (SAFI_UNICAST
== safi
3329 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3330 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3331 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
3333 if ((SAFI_MPLS_VPN
== safi
)
3334 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3336 vpn_leak_to_vrf_update(bgp
, new);
3339 if (SAFI_MPLS_VPN
== safi
) {
3340 mpls_label_t label_decoded
= decode_label(label
);
3342 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
,
3343 sub_type
, &label_decoded
);
3345 if (SAFI_ENCAP
== safi
) {
3346 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
,
3353 /* This BGP update is filtered. Log the reason then update BGP
3356 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3357 if (!peer
->rcvd_attr_printed
) {
3358 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
3359 peer
->rcvd_attr_str
);
3360 peer
->rcvd_attr_printed
= 1;
3363 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3364 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3366 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
3367 peer
->host
, pfx_buf
, reason
);
3371 /* If this is an EVPN route, un-import it as it is now filtered.
3373 if (safi
== SAFI_EVPN
)
3374 bgp_evpn_unimport_route(bgp
, afi
, safi
, p
, ri
);
3376 if (SAFI_UNICAST
== safi
3377 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3378 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3380 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, ri
);
3382 if ((SAFI_MPLS_VPN
== safi
)
3383 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3385 vpn_leak_to_vrf_withdraw(bgp
, ri
);
3388 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
3391 bgp_unlock_node(rn
);
3395 * Filtered update is treated as an implicit withdrawal (see
3397 * a few lines above)
3399 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
)) {
3400 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
,
3408 int bgp_withdraw(struct peer
*peer
, struct prefix
*p
, u_int32_t addpath_id
,
3409 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
3410 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
3411 u_int32_t num_labels
, struct bgp_route_evpn
*evpn
)
3414 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
3415 struct bgp_node
*rn
;
3416 struct bgp_info
*ri
;
3419 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
)) {
3420 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
,
3428 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3430 /* If peer is soft reconfiguration enabled. Record input packet for
3431 * further calculation.
3433 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
3434 * routes that are filtered. This tanks out Quagga RS pretty badly due
3436 * the iteration over all RS clients.
3437 * Since we need to remove the entry from adj_in anyway, do that first
3439 * if there was no entry, we don't need to do anything more.
3441 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
3442 && peer
!= bgp
->peer_self
)
3443 if (!bgp_adj_in_unset(rn
, peer
, addpath_id
)) {
3444 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3445 bgp_debug_rdpfxpath2str(
3446 afi
, safi
, prd
, p
, label
, num_labels
,
3447 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3450 "%s withdrawing route %s not in adj-in",
3451 peer
->host
, pfx_buf
);
3453 bgp_unlock_node(rn
);
3457 /* Lookup withdrawn route. */
3458 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3459 if (ri
->peer
== peer
&& ri
->type
== type
3460 && ri
->sub_type
== sub_type
3461 && ri
->addpath_rx_id
== addpath_id
)
3465 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3466 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3467 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3469 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer
->host
,
3473 /* Withdraw specified route from routing table. */
3474 if (ri
&& !CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
)) {
3475 bgp_rib_withdraw(rn
, ri
, peer
, afi
, safi
, prd
);
3476 if (SAFI_UNICAST
== safi
3477 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3478 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3479 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, ri
);
3481 if ((SAFI_MPLS_VPN
== safi
)
3482 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3484 vpn_leak_to_vrf_withdraw(bgp
, ri
);
3486 } else if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3487 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3488 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3490 zlog_debug("%s Can't find the route %s", peer
->host
, pfx_buf
);
3493 /* Unlock bgp_node_get() lock. */
3494 bgp_unlock_node(rn
);
3499 void bgp_default_originate(struct peer
*peer
, afi_t afi
, safi_t safi
,
3502 struct update_subgroup
*subgrp
;
3503 subgrp
= peer_subgroup(peer
, afi
, safi
);
3504 subgroup_default_originate(subgrp
, withdraw
);
3509 * bgp_stop_announce_route_timer
3511 void bgp_stop_announce_route_timer(struct peer_af
*paf
)
3513 if (!paf
->t_announce_route
)
3516 THREAD_TIMER_OFF(paf
->t_announce_route
);
3520 * bgp_announce_route_timer_expired
3522 * Callback that is invoked when the route announcement timer for a
3525 static int bgp_announce_route_timer_expired(struct thread
*t
)
3527 struct peer_af
*paf
;
3530 paf
= THREAD_ARG(t
);
3533 if (peer
->status
!= Established
)
3536 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
3539 peer_af_announce_route(paf
, 1);
3544 * bgp_announce_route
3546 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3548 void bgp_announce_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3550 struct peer_af
*paf
;
3551 struct update_subgroup
*subgrp
;
3553 paf
= peer_af_find(peer
, afi
, safi
);
3556 subgrp
= PAF_SUBGRP(paf
);
3559 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3560 * or a refresh has already been triggered.
3562 if (!subgrp
|| paf
->t_announce_route
)
3566 * Start a timer to stagger/delay the announce. This serves
3567 * two purposes - announcement can potentially be combined for
3568 * multiple peers and the announcement doesn't happen in the
3571 thread_add_timer_msec(bm
->master
, bgp_announce_route_timer_expired
, paf
,
3572 (subgrp
->peer_count
== 1)
3573 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
3574 : BGP_ANNOUNCE_ROUTE_DELAY_MS
,
3575 &paf
->t_announce_route
);
3579 * Announce routes from all AF tables to a peer.
3581 * This should ONLY be called when there is a need to refresh the
3582 * routes to the peer based on a policy change for this peer alone
3583 * or a route refresh request received from the peer.
3584 * The operation will result in splitting the peer from its existing
3585 * subgroups and putting it in new subgroups.
3587 void bgp_announce_route_all(struct peer
*peer
)
3592 FOREACH_AFI_SAFI (afi
, safi
)
3593 bgp_announce_route(peer
, afi
, safi
);
3596 static void bgp_soft_reconfig_table(struct peer
*peer
, afi_t afi
, safi_t safi
,
3597 struct bgp_table
*table
,
3598 struct prefix_rd
*prd
)
3601 struct bgp_node
*rn
;
3602 struct bgp_adj_in
*ain
;
3605 table
= peer
->bgp
->rib
[afi
][safi
];
3607 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
3608 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
) {
3609 if (ain
->peer
!= peer
)
3612 struct bgp_info
*ri
= rn
->info
;
3613 u_int32_t num_labels
= 0;
3614 mpls_label_t
*label_pnt
= NULL
;
3616 if (ri
&& ri
->extra
)
3617 num_labels
= ri
->extra
->num_labels
;
3619 label_pnt
= &ri
->extra
->label
[0];
3621 ret
= bgp_update(peer
, &rn
->p
, ain
->addpath_rx_id
,
3622 ain
->attr
, afi
, safi
, ZEBRA_ROUTE_BGP
,
3623 BGP_ROUTE_NORMAL
, prd
, label_pnt
,
3624 num_labels
, 1, NULL
);
3627 bgp_unlock_node(rn
);
3633 void bgp_soft_reconfig_in(struct peer
*peer
, afi_t afi
, safi_t safi
)
3635 struct bgp_node
*rn
;
3636 struct bgp_table
*table
;
3638 if (peer
->status
!= Established
)
3641 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
)
3642 && (safi
!= SAFI_EVPN
))
3643 bgp_soft_reconfig_table(peer
, afi
, safi
, NULL
, NULL
);
3645 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3646 rn
= bgp_route_next(rn
))
3647 if ((table
= rn
->info
) != NULL
) {
3648 struct prefix_rd prd
;
3649 prd
.family
= AF_UNSPEC
;
3651 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3653 bgp_soft_reconfig_table(peer
, afi
, safi
, table
,
3659 struct bgp_clear_node_queue
{
3660 struct bgp_node
*rn
;
3663 static wq_item_status
bgp_clear_route_node(struct work_queue
*wq
, void *data
)
3665 struct bgp_clear_node_queue
*cnq
= data
;
3666 struct bgp_node
*rn
= cnq
->rn
;
3667 struct peer
*peer
= wq
->spec
.data
;
3668 struct bgp_info
*ri
;
3669 afi_t afi
= bgp_node_table(rn
)->afi
;
3670 safi_t safi
= bgp_node_table(rn
)->safi
;
3674 /* It is possible that we have multiple paths for a prefix from a peer
3675 * if that peer is using AddPath.
3677 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
3678 if (ri
->peer
!= peer
)
3681 /* graceful restart STALE flag set. */
3682 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3683 && peer
->nsf
[afi
][safi
]
3684 && !CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
)
3685 && !CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
3686 bgp_info_set_flag(rn
, ri
, BGP_INFO_STALE
);
3688 /* If this is an EVPN route, process for
3690 if (safi
== SAFI_EVPN
)
3691 bgp_evpn_unimport_route(peer
->bgp
, afi
, safi
,
3693 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
3699 static void bgp_clear_node_queue_del(struct work_queue
*wq
, void *data
)
3701 struct bgp_clear_node_queue
*cnq
= data
;
3702 struct bgp_node
*rn
= cnq
->rn
;
3703 struct bgp_table
*table
= bgp_node_table(rn
);
3705 bgp_unlock_node(rn
);
3706 bgp_table_unlock(table
);
3707 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3710 static void bgp_clear_node_complete(struct work_queue
*wq
)
3712 struct peer
*peer
= wq
->spec
.data
;
3714 /* Tickle FSM to start moving again */
3715 BGP_EVENT_ADD(peer
, Clearing_Completed
);
3717 peer_unlock(peer
); /* bgp_clear_route */
3720 static void bgp_clear_node_queue_init(struct peer
*peer
)
3722 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3724 snprintf(wname
, sizeof(wname
), "clear %s", peer
->host
);
3725 #undef CLEAR_QUEUE_NAME_LEN
3727 if ((peer
->clear_node_queue
= work_queue_new(bm
->master
, wname
))
3729 zlog_err("%s: Failed to allocate work queue", __func__
);
3732 peer
->clear_node_queue
->spec
.hold
= 10;
3733 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3734 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3735 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3736 peer
->clear_node_queue
->spec
.max_retries
= 0;
3738 /* we only 'lock' this peer reference when the queue is actually active
3740 peer
->clear_node_queue
->spec
.data
= peer
;
3743 static void bgp_clear_route_table(struct peer
*peer
, afi_t afi
, safi_t safi
,
3744 struct bgp_table
*table
)
3746 struct bgp_node
*rn
;
3747 int force
= bm
->process_main_queue
? 0 : 1;
3750 table
= peer
->bgp
->rib
[afi
][safi
];
3752 /* If still no table => afi/safi isn't configured at all or smth. */
3756 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
3757 struct bgp_info
*ri
, *next
;
3758 struct bgp_adj_in
*ain
;
3759 struct bgp_adj_in
*ain_next
;
3761 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3762 * queued for every clearing peer, regardless of whether it is
3763 * relevant to the peer at hand.
3765 * Overview: There are 3 different indices which need to be
3766 * scrubbed, potentially, when a peer is removed:
3768 * 1 peer's routes visible via the RIB (ie accepted routes)
3769 * 2 peer's routes visible by the (optional) peer's adj-in index
3770 * 3 other routes visible by the peer's adj-out index
3772 * 3 there is no hurry in scrubbing, once the struct peer is
3773 * removed from bgp->peer, we could just GC such deleted peer's
3774 * adj-outs at our leisure.
3776 * 1 and 2 must be 'scrubbed' in some way, at least made
3777 * invisible via RIB index before peer session is allowed to be
3778 * brought back up. So one needs to know when such a 'search' is
3783 * - there'd be a single global queue or a single RIB walker
3784 * - rather than tracking which route_nodes still need to be
3785 * examined on a peer basis, we'd track which peers still
3788 * Given that our per-peer prefix-counts now should be reliable,
3789 * this may actually be achievable. It doesn't seem to be a huge
3790 * problem at this time,
3792 * It is possible that we have multiple paths for a prefix from
3794 * if that peer is using AddPath.
3798 ain_next
= ain
->next
;
3800 if (ain
->peer
== peer
) {
3801 bgp_adj_in_remove(rn
, ain
);
3802 bgp_unlock_node(rn
);
3808 for (ri
= rn
->info
; ri
; ri
= next
) {
3810 if (ri
->peer
!= peer
)
3814 bgp_info_reap(rn
, ri
);
3816 struct bgp_clear_node_queue
*cnq
;
3818 /* both unlocked in bgp_clear_node_queue_del */
3819 bgp_table_lock(bgp_node_table(rn
));
3822 MTYPE_BGP_CLEAR_NODE_QUEUE
,
3823 sizeof(struct bgp_clear_node_queue
));
3825 work_queue_add(peer
->clear_node_queue
, cnq
);
3833 void bgp_clear_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3835 struct bgp_node
*rn
;
3836 struct bgp_table
*table
;
3838 if (peer
->clear_node_queue
== NULL
)
3839 bgp_clear_node_queue_init(peer
);
3841 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3842 * Idle until it receives a Clearing_Completed event. This protects
3843 * against peers which flap faster than we can we clear, which could
3846 * a) race with routes from the new session being installed before
3847 * clear_route_node visits the node (to delete the route of that
3849 * b) resource exhaustion, clear_route_node likely leads to an entry
3850 * on the process_main queue. Fast-flapping could cause that queue
3854 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3855 * the unlock will happen upon work-queue completion; other wise, the
3856 * unlock happens at the end of this function.
3858 if (!peer
->clear_node_queue
->thread
)
3861 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
&& safi
!= SAFI_EVPN
)
3862 bgp_clear_route_table(peer
, afi
, safi
, NULL
);
3864 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3865 rn
= bgp_route_next(rn
))
3866 if ((table
= rn
->info
) != NULL
)
3867 bgp_clear_route_table(peer
, afi
, safi
, table
);
3869 /* unlock if no nodes got added to the clear-node-queue. */
3870 if (!peer
->clear_node_queue
->thread
)
3874 void bgp_clear_route_all(struct peer
*peer
)
3879 FOREACH_AFI_SAFI (afi
, safi
)
3880 bgp_clear_route(peer
, afi
, safi
);
3883 rfapiProcessPeerDown(peer
);
3887 void bgp_clear_adj_in(struct peer
*peer
, afi_t afi
, safi_t safi
)
3889 struct bgp_table
*table
;
3890 struct bgp_node
*rn
;
3891 struct bgp_adj_in
*ain
;
3892 struct bgp_adj_in
*ain_next
;
3894 table
= peer
->bgp
->rib
[afi
][safi
];
3896 /* It is possible that we have multiple paths for a prefix from a peer
3897 * if that peer is using AddPath.
3899 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
3903 ain_next
= ain
->next
;
3905 if (ain
->peer
== peer
) {
3906 bgp_adj_in_remove(rn
, ain
);
3907 bgp_unlock_node(rn
);
3915 void bgp_clear_stale_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3917 struct bgp_node
*rn
;
3918 struct bgp_info
*ri
;
3919 struct bgp_table
*table
;
3921 if (safi
== SAFI_MPLS_VPN
) {
3922 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3923 rn
= bgp_route_next(rn
)) {
3924 struct bgp_node
*rm
;
3925 struct bgp_info
*ri
;
3927 /* look for neighbor in tables */
3928 if ((table
= rn
->info
) == NULL
)
3931 for (rm
= bgp_table_top(table
); rm
;
3932 rm
= bgp_route_next(rm
))
3933 for (ri
= rm
->info
; ri
; ri
= ri
->next
) {
3934 if (ri
->peer
!= peer
)
3936 if (!CHECK_FLAG(ri
->flags
,
3940 bgp_rib_remove(rm
, ri
, peer
, afi
, safi
);
3945 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3946 rn
= bgp_route_next(rn
))
3947 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
3948 if (ri
->peer
!= peer
)
3950 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
))
3952 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
3958 static void bgp_cleanup_table(struct bgp_table
*table
, safi_t safi
)
3960 struct bgp_node
*rn
;
3961 struct bgp_info
*ri
;
3962 struct bgp_info
*next
;
3964 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
3965 for (ri
= rn
->info
; ri
; ri
= next
) {
3967 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)
3968 && ri
->type
== ZEBRA_ROUTE_BGP
3969 && (ri
->sub_type
== BGP_ROUTE_NORMAL
3970 || ri
->sub_type
== BGP_ROUTE_AGGREGATE
3971 || ri
->sub_type
== BGP_ROUTE_IMPORTED
)) {
3973 if (bgp_fibupd_safi(safi
))
3974 bgp_zebra_withdraw(&rn
->p
, ri
, safi
);
3975 bgp_info_reap(rn
, ri
);
3980 /* Delete all kernel routes. */
3981 void bgp_cleanup_routes(struct bgp
*bgp
)
3984 struct bgp_node
*rn
;
3986 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
3987 if (afi
== AFI_L2VPN
)
3989 bgp_cleanup_table(bgp
->rib
[afi
][SAFI_UNICAST
], SAFI_UNICAST
);
3991 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
3993 if (afi
!= AFI_L2VPN
) {
3995 safi
= SAFI_MPLS_VPN
;
3996 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
3997 rn
= bgp_route_next(rn
)) {
4000 (struct bgp_table
*)(rn
->info
),
4002 bgp_table_finish((struct bgp_table
**)&(
4005 bgp_unlock_node(rn
);
4009 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
4010 rn
= bgp_route_next(rn
)) {
4013 (struct bgp_table
*)(rn
->info
),
4015 bgp_table_finish((struct bgp_table
**)&(
4018 bgp_unlock_node(rn
);
4023 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
4024 rn
= bgp_route_next(rn
)) {
4026 bgp_cleanup_table((struct bgp_table
*)(rn
->info
),
4028 bgp_table_finish((struct bgp_table
**)&(rn
->info
));
4030 bgp_unlock_node(rn
);
4035 void bgp_reset(void)
4038 bgp_zclient_reset();
4039 access_list_reset();
4040 prefix_list_reset();
4043 static int bgp_addpath_encode_rx(struct peer
*peer
, afi_t afi
, safi_t safi
)
4045 return (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
4046 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
4047 PEER_CAP_ADDPATH_AF_TX_RCV
));
4050 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
4052 int bgp_nlri_parse_ip(struct peer
*peer
, struct attr
*attr
,
4053 struct bgp_nlri
*packet
)
4062 int addpath_encoded
;
4063 u_int32_t addpath_id
;
4065 /* Check peer status. */
4066 if (peer
->status
!= Established
)
4070 lim
= pnt
+ packet
->length
;
4072 safi
= packet
->safi
;
4074 addpath_encoded
= bgp_addpath_encode_rx(peer
, afi
, safi
);
4076 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
4077 syntactic validity. If the field is syntactically incorrect,
4078 then the Error Subcode is set to Invalid Network Field. */
4079 for (; pnt
< lim
; pnt
+= psize
) {
4080 /* Clear prefix structure. */
4081 memset(&p
, 0, sizeof(struct prefix
));
4083 if (addpath_encoded
) {
4085 /* When packet overflow occurs return immediately. */
4086 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
4089 addpath_id
= ntohl(*((uint32_t *)pnt
));
4090 pnt
+= BGP_ADDPATH_ID_LEN
;
4093 /* Fetch prefix length. */
4094 p
.prefixlen
= *pnt
++;
4095 /* afi/safi validity already verified by caller,
4096 * bgp_update_receive */
4097 p
.family
= afi2family(afi
);
4099 /* Prefix length check. */
4100 if (p
.prefixlen
> prefix_blen(&p
) * 8) {
4102 "%s [Error] Update packet error (wrong perfix length %d for afi %u)",
4103 peer
->host
, p
.prefixlen
, packet
->afi
);
4107 /* Packet size overflow check. */
4108 psize
= PSIZE(p
.prefixlen
);
4110 /* When packet overflow occur return immediately. */
4111 if (pnt
+ psize
> lim
) {
4113 "%s [Error] Update packet error (prefix length %d overflows packet)",
4114 peer
->host
, p
.prefixlen
);
4118 /* Defensive coding, double-check the psize fits in a struct
4120 if (psize
> (ssize_t
)sizeof(p
.u
)) {
4122 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
4123 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
4127 /* Fetch prefix from NLRI packet. */
4128 memcpy(&p
.u
.prefix
, pnt
, psize
);
4130 /* Check address. */
4131 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
) {
4132 if (IN_CLASSD(ntohl(p
.u
.prefix4
.s_addr
))) {
4133 /* From RFC4271 Section 6.3:
4135 * If a prefix in the NLRI field is semantically
4137 * (e.g., an unexpected multicast IP address),
4139 * be logged locally, and the prefix SHOULD be
4143 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
4144 peer
->host
, inet_ntoa(p
.u
.prefix4
));
4149 /* Check address. */
4150 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
) {
4151 if (IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
4155 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
4157 inet_ntop(AF_INET6
, &p
.u
.prefix6
, buf
,
4162 if (IN6_IS_ADDR_MULTICAST(&p
.u
.prefix6
)) {
4166 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
4168 inet_ntop(AF_INET6
, &p
.u
.prefix6
, buf
,
4175 /* Normal process. */
4177 ret
= bgp_update(peer
, &p
, addpath_id
, attr
, afi
, safi
,
4178 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
4179 NULL
, NULL
, 0, 0, NULL
);
4181 ret
= bgp_withdraw(peer
, &p
, addpath_id
, attr
, afi
,
4182 safi
, ZEBRA_ROUTE_BGP
,
4183 BGP_ROUTE_NORMAL
, NULL
, NULL
, 0,
4186 /* Address family configuration mismatch or maximum-prefix count
4192 /* Packet length consistency check. */
4195 "%s [Error] Update packet error (prefix length mismatch with total length)",
4203 static struct bgp_static
*bgp_static_new(void)
4205 return XCALLOC(MTYPE_BGP_STATIC
, sizeof(struct bgp_static
));
4208 static void bgp_static_free(struct bgp_static
*bgp_static
)
4210 if (bgp_static
->rmap
.name
)
4211 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4212 if (bgp_static
->eth_s_id
)
4213 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
4214 XFREE(MTYPE_BGP_STATIC
, bgp_static
);
4217 void bgp_static_update(struct bgp
*bgp
, struct prefix
*p
,
4218 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
4220 struct bgp_node
*rn
;
4221 struct bgp_info
*ri
;
4222 struct bgp_info
*new;
4223 struct bgp_info info
;
4225 struct attr
*attr_new
;
4228 int vnc_implicit_withdraw
= 0;
4235 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4237 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
4239 attr
.nexthop
= bgp_static
->igpnexthop
;
4240 attr
.med
= bgp_static
->igpmetric
;
4241 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
4243 if (bgp_static
->atomic
)
4244 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
);
4246 /* Store label index, if required. */
4247 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
) {
4248 attr
.label_index
= bgp_static
->label_index
;
4249 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID
);
4252 /* Apply route-map. */
4253 if (bgp_static
->rmap
.name
) {
4254 struct attr attr_tmp
= attr
;
4255 info
.peer
= bgp
->peer_self
;
4256 info
.attr
= &attr_tmp
;
4258 SET_FLAG(bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4260 ret
= route_map_apply(bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4262 bgp
->peer_self
->rmap_type
= 0;
4264 if (ret
== RMAP_DENYMATCH
) {
4265 /* Free uninterned attribute. */
4266 bgp_attr_flush(&attr_tmp
);
4268 /* Unintern original. */
4269 aspath_unintern(&attr
.aspath
);
4270 bgp_static_withdraw(bgp
, p
, afi
, safi
);
4274 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
4275 bgp_attr_add_gshut_community(&attr_tmp
);
4277 attr_new
= bgp_attr_intern(&attr_tmp
);
4280 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
4281 bgp_attr_add_gshut_community(&attr
);
4283 attr_new
= bgp_attr_intern(&attr
);
4286 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4287 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4288 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4292 if (attrhash_cmp(ri
->attr
, attr_new
)
4293 && !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)
4294 && !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
)) {
4295 bgp_unlock_node(rn
);
4296 bgp_attr_unintern(&attr_new
);
4297 aspath_unintern(&attr
.aspath
);
4300 /* The attribute is changed. */
4301 bgp_info_set_flag(rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4303 /* Rewrite BGP route information. */
4304 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4305 bgp_info_restore(rn
, ri
);
4307 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4309 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
4310 && (safi
== SAFI_UNICAST
)) {
4311 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
4313 * Implicit withdraw case.
4314 * We have to do this before ri is
4317 ++vnc_implicit_withdraw
;
4318 vnc_import_bgp_del_route(bgp
, p
, ri
);
4319 vnc_import_bgp_exterior_del_route(
4324 bgp_attr_unintern(&ri
->attr
);
4325 ri
->attr
= attr_new
;
4326 ri
->uptime
= bgp_clock();
4328 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
4329 && (safi
== SAFI_UNICAST
)) {
4330 if (vnc_implicit_withdraw
) {
4331 vnc_import_bgp_add_route(bgp
, p
, ri
);
4332 vnc_import_bgp_exterior_add_route(
4338 /* Nexthop reachability check. */
4339 if (bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
4340 && (safi
== SAFI_UNICAST
4341 || safi
== SAFI_LABELED_UNICAST
)) {
4342 if (bgp_find_or_add_nexthop(bgp
, afi
, ri
, NULL
,
4344 bgp_info_set_flag(rn
, ri
,
4347 if (BGP_DEBUG(nht
, NHT
)) {
4348 char buf1
[INET6_ADDRSTRLEN
];
4349 inet_ntop(p
->family
,
4353 "%s(%s): Route not in table, not advertising",
4354 __FUNCTION__
, buf1
);
4356 bgp_info_unset_flag(rn
, ri
,
4360 /* Delete the NHT structure if any, if we're
4362 * enabling/disabling import check. We
4363 * deregister the route
4364 * from NHT to avoid overloading NHT and the
4365 * process interaction
4367 bgp_unlink_nexthop(ri
);
4368 bgp_info_set_flag(rn
, ri
, BGP_INFO_VALID
);
4370 /* Process change. */
4371 bgp_aggregate_increment(bgp
, p
, ri
, afi
, safi
);
4372 bgp_process(bgp
, rn
, afi
, safi
);
4374 if (SAFI_UNICAST
== safi
4375 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4377 == BGP_INSTANCE_TYPE_DEFAULT
)) {
4378 vpn_leak_from_vrf_update(bgp_get_default(), bgp
,
4382 bgp_unlock_node(rn
);
4383 aspath_unintern(&attr
.aspath
);
4388 /* Make new BGP info. */
4389 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
,
4391 /* Nexthop reachability check. */
4392 if (bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
4393 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
4394 if (bgp_find_or_add_nexthop(bgp
, afi
, new, NULL
, 0))
4395 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
4397 if (BGP_DEBUG(nht
, NHT
)) {
4398 char buf1
[INET6_ADDRSTRLEN
];
4399 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
4402 "%s(%s): Route not in table, not advertising",
4403 __FUNCTION__
, buf1
);
4405 bgp_info_unset_flag(rn
, new, BGP_INFO_VALID
);
4408 /* Delete the NHT structure if any, if we're toggling between
4409 * enabling/disabling import check. We deregister the route
4410 * from NHT to avoid overloading NHT and the process interaction
4412 bgp_unlink_nexthop(new);
4414 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
4417 /* Aggregate address increment. */
4418 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
4420 /* Register new BGP information. */
4421 bgp_info_add(rn
, new);
4423 /* route_node_get lock */
4424 bgp_unlock_node(rn
);
4426 /* Process change. */
4427 bgp_process(bgp
, rn
, afi
, safi
);
4429 if (SAFI_UNICAST
== safi
4430 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4431 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
4432 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
4435 /* Unintern original. */
4436 aspath_unintern(&attr
.aspath
);
4439 void bgp_static_withdraw(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
4442 struct bgp_node
*rn
;
4443 struct bgp_info
*ri
;
4445 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4447 /* Check selected route and self inserted route. */
4448 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4449 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4450 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4453 /* Withdraw static BGP route from routing table. */
4455 if (SAFI_UNICAST
== safi
4456 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4457 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
4458 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, ri
);
4460 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4461 bgp_unlink_nexthop(ri
);
4462 bgp_info_delete(rn
, ri
);
4463 bgp_process(bgp
, rn
, afi
, safi
);
4466 /* Unlock bgp_node_lookup. */
4467 bgp_unlock_node(rn
);
4471 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4473 static void bgp_static_withdraw_safi(struct bgp
*bgp
, struct prefix
*p
,
4474 afi_t afi
, safi_t safi
,
4475 struct prefix_rd
*prd
)
4477 struct bgp_node
*rn
;
4478 struct bgp_info
*ri
;
4480 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
4482 /* Check selected route and self inserted route. */
4483 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4484 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4485 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4488 /* Withdraw static BGP route from routing table. */
4491 rfapiProcessWithdraw(
4492 ri
->peer
, NULL
, p
, prd
, ri
->attr
, afi
, safi
, ri
->type
,
4493 1); /* Kill, since it is an administrative change */
4495 if (SAFI_MPLS_VPN
== safi
4496 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4497 vpn_leak_to_vrf_withdraw(bgp
, ri
);
4499 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4500 bgp_info_delete(rn
, ri
);
4501 bgp_process(bgp
, rn
, afi
, safi
);
4504 /* Unlock bgp_node_lookup. */
4505 bgp_unlock_node(rn
);
4508 static void bgp_static_update_safi(struct bgp
*bgp
, struct prefix
*p
,
4509 struct bgp_static
*bgp_static
, afi_t afi
,
4512 struct bgp_node
*rn
;
4513 struct bgp_info
*new;
4514 struct attr
*attr_new
;
4515 struct attr attr
= {0};
4516 struct bgp_info
*ri
;
4518 mpls_label_t label
= 0;
4520 u_int32_t num_labels
= 0;
4525 if (bgp_static
->label
!= MPLS_INVALID_LABEL
)
4527 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
,
4530 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
4532 attr
.nexthop
= bgp_static
->igpnexthop
;
4533 attr
.med
= bgp_static
->igpmetric
;
4534 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
4536 if ((safi
== SAFI_EVPN
) || (safi
== SAFI_MPLS_VPN
)
4537 || (safi
== SAFI_ENCAP
)) {
4538 if (afi
== AFI_IP
) {
4539 attr
.mp_nexthop_global_in
= bgp_static
->igpnexthop
;
4540 attr
.mp_nexthop_len
= IPV4_MAX_BYTELEN
;
4543 if (afi
== AFI_L2VPN
) {
4544 if (bgp_static
->gatewayIp
.family
== AF_INET
)
4546 bgp_static
->gatewayIp
.u
.prefix4
.s_addr
;
4547 else if (bgp_static
->gatewayIp
.family
== AF_INET6
)
4548 memcpy(&(add
.ipv6
), &(bgp_static
->gatewayIp
.u
.prefix6
),
4549 sizeof(struct in6_addr
));
4550 overlay_index_update(&attr
, bgp_static
->eth_s_id
, &add
);
4551 if (bgp_static
->encap_tunneltype
== BGP_ENCAP_TYPE_VXLAN
) {
4552 struct bgp_encap_type_vxlan bet
;
4553 memset(&bet
, 0, sizeof(struct bgp_encap_type_vxlan
));
4554 bet
.vnid
= p
->u
.prefix_evpn
.eth_tag
;
4555 bgp_encap_type_vxlan_to_tlv(&bet
, &attr
);
4557 if (bgp_static
->router_mac
) {
4558 bgp_add_routermac_ecom(&attr
, bgp_static
->router_mac
);
4561 /* Apply route-map. */
4562 if (bgp_static
->rmap
.name
) {
4563 struct attr attr_tmp
= attr
;
4564 struct bgp_info info
;
4567 info
.peer
= bgp
->peer_self
;
4568 info
.attr
= &attr_tmp
;
4570 SET_FLAG(bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4572 ret
= route_map_apply(bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4574 bgp
->peer_self
->rmap_type
= 0;
4576 if (ret
== RMAP_DENYMATCH
) {
4577 /* Free uninterned attribute. */
4578 bgp_attr_flush(&attr_tmp
);
4580 /* Unintern original. */
4581 aspath_unintern(&attr
.aspath
);
4582 bgp_static_withdraw_safi(bgp
, p
, afi
, safi
,
4587 attr_new
= bgp_attr_intern(&attr_tmp
);
4589 attr_new
= bgp_attr_intern(&attr
);
4592 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4593 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4594 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4599 memset(&add
, 0, sizeof(union gw_addr
));
4600 if (attrhash_cmp(ri
->attr
, attr_new
)
4601 && overlay_index_equal(afi
, ri
, bgp_static
->eth_s_id
, &add
)
4602 && !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
4603 bgp_unlock_node(rn
);
4604 bgp_attr_unintern(&attr_new
);
4605 aspath_unintern(&attr
.aspath
);
4608 /* The attribute is changed. */
4609 bgp_info_set_flag(rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4611 /* Rewrite BGP route information. */
4612 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4613 bgp_info_restore(rn
, ri
);
4615 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4616 bgp_attr_unintern(&ri
->attr
);
4617 ri
->attr
= attr_new
;
4618 ri
->uptime
= bgp_clock();
4621 label
= decode_label(&ri
->extra
->label
[0]);
4624 /* Process change. */
4625 bgp_aggregate_increment(bgp
, p
, ri
, afi
, safi
);
4626 bgp_process(bgp
, rn
, afi
, safi
);
4628 if (SAFI_MPLS_VPN
== safi
4629 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4630 vpn_leak_to_vrf_update(bgp
, ri
);
4633 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
4634 ri
->attr
, afi
, safi
, ri
->type
,
4635 ri
->sub_type
, &label
);
4637 bgp_unlock_node(rn
);
4638 aspath_unintern(&attr
.aspath
);
4644 /* Make new BGP info. */
4645 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
,
4647 SET_FLAG(new->flags
, BGP_INFO_VALID
);
4648 new->extra
= bgp_info_extra_new();
4650 new->extra
->label
[0] = bgp_static
->label
;
4651 new->extra
->num_labels
= num_labels
;
4654 label
= decode_label(&bgp_static
->label
);
4657 /* Aggregate address increment. */
4658 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
4660 /* Register new BGP information. */
4661 bgp_info_add(rn
, new);
4662 /* route_node_get lock */
4663 bgp_unlock_node(rn
);
4665 /* Process change. */
4666 bgp_process(bgp
, rn
, afi
, safi
);
4668 if (SAFI_MPLS_VPN
== safi
4669 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4670 vpn_leak_to_vrf_update(bgp
, new);
4673 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
, new->attr
, afi
,
4674 safi
, new->type
, new->sub_type
, &label
);
4677 /* Unintern original. */
4678 aspath_unintern(&attr
.aspath
);
4681 /* Configure static BGP network. When user don't run zebra, static
4682 route should be installed as valid. */
4683 static int bgp_static_set(struct vty
*vty
, const char *negate
,
4684 const char *ip_str
, afi_t afi
, safi_t safi
,
4685 const char *rmap
, int backdoor
, u_int32_t label_index
)
4687 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4690 struct bgp_static
*bgp_static
;
4691 struct bgp_node
*rn
;
4692 u_char need_update
= 0;
4694 /* Convert IP prefix string to struct prefix. */
4695 ret
= str2prefix(ip_str
, &p
);
4697 vty_out(vty
, "%% Malformed prefix\n");
4698 return CMD_WARNING_CONFIG_FAILED
;
4700 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
4701 vty_out(vty
, "%% Malformed prefix (link-local address)\n");
4702 return CMD_WARNING_CONFIG_FAILED
;
4709 /* Set BGP static route configuration. */
4710 rn
= bgp_node_lookup(bgp
->route
[afi
][safi
], &p
);
4713 vty_out(vty
, "%% Can't find static route specified\n");
4714 return CMD_WARNING_CONFIG_FAILED
;
4717 bgp_static
= rn
->info
;
4719 if ((label_index
!= BGP_INVALID_LABEL_INDEX
)
4720 && (label_index
!= bgp_static
->label_index
)) {
4722 "%% label-index doesn't match static route\n");
4723 return CMD_WARNING_CONFIG_FAILED
;
4726 if ((rmap
&& bgp_static
->rmap
.name
)
4727 && strcmp(rmap
, bgp_static
->rmap
.name
)) {
4729 "%% route-map name doesn't match static route\n");
4730 return CMD_WARNING_CONFIG_FAILED
;
4733 /* Update BGP RIB. */
4734 if (!bgp_static
->backdoor
)
4735 bgp_static_withdraw(bgp
, &p
, afi
, safi
);
4737 /* Clear configuration. */
4738 bgp_static_free(bgp_static
);
4740 bgp_unlock_node(rn
);
4741 bgp_unlock_node(rn
);
4744 /* Set BGP static route configuration. */
4745 rn
= bgp_node_get(bgp
->route
[afi
][safi
], &p
);
4748 /* Configuration change. */
4749 bgp_static
= rn
->info
;
4751 /* Label index cannot be changed. */
4752 if (bgp_static
->label_index
!= label_index
) {
4753 vty_out(vty
, "%% cannot change label-index\n");
4754 return CMD_WARNING_CONFIG_FAILED
;
4757 /* Check previous routes are installed into BGP. */
4758 if (bgp_static
->valid
4759 && bgp_static
->backdoor
!= backdoor
)
4762 bgp_static
->backdoor
= backdoor
;
4765 if (bgp_static
->rmap
.name
)
4766 XFREE(MTYPE_ROUTE_MAP_NAME
,
4767 bgp_static
->rmap
.name
);
4768 bgp_static
->rmap
.name
=
4769 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4770 bgp_static
->rmap
.map
=
4771 route_map_lookup_by_name(rmap
);
4773 if (bgp_static
->rmap
.name
)
4774 XFREE(MTYPE_ROUTE_MAP_NAME
,
4775 bgp_static
->rmap
.name
);
4776 bgp_static
->rmap
.name
= NULL
;
4777 bgp_static
->rmap
.map
= NULL
;
4778 bgp_static
->valid
= 0;
4780 bgp_unlock_node(rn
);
4782 /* New configuration. */
4783 bgp_static
= bgp_static_new();
4784 bgp_static
->backdoor
= backdoor
;
4785 bgp_static
->valid
= 0;
4786 bgp_static
->igpmetric
= 0;
4787 bgp_static
->igpnexthop
.s_addr
= 0;
4788 bgp_static
->label_index
= label_index
;
4791 if (bgp_static
->rmap
.name
)
4792 XFREE(MTYPE_ROUTE_MAP_NAME
,
4793 bgp_static
->rmap
.name
);
4794 bgp_static
->rmap
.name
=
4795 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4796 bgp_static
->rmap
.map
=
4797 route_map_lookup_by_name(rmap
);
4799 rn
->info
= bgp_static
;
4802 bgp_static
->valid
= 1;
4804 bgp_static_withdraw(bgp
, &p
, afi
, safi
);
4806 if (!bgp_static
->backdoor
)
4807 bgp_static_update(bgp
, &p
, bgp_static
, afi
, safi
);
4813 void bgp_static_add(struct bgp
*bgp
)
4817 struct bgp_node
*rn
;
4818 struct bgp_node
*rm
;
4819 struct bgp_table
*table
;
4820 struct bgp_static
*bgp_static
;
4822 FOREACH_AFI_SAFI (afi
, safi
)
4823 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
4824 rn
= bgp_route_next(rn
)) {
4825 if (rn
->info
== NULL
)
4828 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
4829 || (safi
== SAFI_EVPN
)) {
4832 for (rm
= bgp_table_top(table
); rm
;
4833 rm
= bgp_route_next(rm
)) {
4834 bgp_static
= rm
->info
;
4835 bgp_static_update_safi(bgp
, &rm
->p
,
4840 bgp_static_update(bgp
, &rn
->p
, rn
->info
, afi
,
4846 /* Called from bgp_delete(). Delete all static routes from the BGP
4848 void bgp_static_delete(struct bgp
*bgp
)
4852 struct bgp_node
*rn
;
4853 struct bgp_node
*rm
;
4854 struct bgp_table
*table
;
4855 struct bgp_static
*bgp_static
;
4857 FOREACH_AFI_SAFI (afi
, safi
)
4858 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
4859 rn
= bgp_route_next(rn
)) {
4860 if (rn
->info
== NULL
)
4863 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
4864 || (safi
== SAFI_EVPN
)) {
4867 for (rm
= bgp_table_top(table
); rm
;
4868 rm
= bgp_route_next(rm
)) {
4869 bgp_static
= rm
->info
;
4870 bgp_static_withdraw_safi(
4871 bgp
, &rm
->p
, AFI_IP
, safi
,
4872 (struct prefix_rd
*)&rn
->p
);
4873 bgp_static_free(bgp_static
);
4875 bgp_unlock_node(rn
);
4878 bgp_static
= rn
->info
;
4879 bgp_static_withdraw(bgp
, &rn
->p
, afi
, safi
);
4880 bgp_static_free(bgp_static
);
4882 bgp_unlock_node(rn
);
4887 void bgp_static_redo_import_check(struct bgp
*bgp
)
4891 struct bgp_node
*rn
;
4892 struct bgp_node
*rm
;
4893 struct bgp_table
*table
;
4894 struct bgp_static
*bgp_static
;
4896 /* Use this flag to force reprocessing of the route */
4897 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4898 FOREACH_AFI_SAFI (afi
, safi
) {
4899 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
4900 rn
= bgp_route_next(rn
)) {
4901 if (rn
->info
== NULL
)
4904 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
4905 || (safi
== SAFI_EVPN
)) {
4908 for (rm
= bgp_table_top(table
); rm
;
4909 rm
= bgp_route_next(rm
)) {
4910 bgp_static
= rm
->info
;
4911 bgp_static_update_safi(bgp
, &rm
->p
,
4916 bgp_static
= rn
->info
;
4917 bgp_static_update(bgp
, &rn
->p
, bgp_static
, afi
,
4922 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4925 static void bgp_purge_af_static_redist_routes(struct bgp
*bgp
, afi_t afi
,
4928 struct bgp_table
*table
;
4929 struct bgp_node
*rn
;
4930 struct bgp_info
*ri
;
4932 table
= bgp
->rib
[afi
][safi
];
4933 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
4934 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
4935 if (ri
->peer
== bgp
->peer_self
4936 && ((ri
->type
== ZEBRA_ROUTE_BGP
4937 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4938 || (ri
->type
!= ZEBRA_ROUTE_BGP
4940 == BGP_ROUTE_REDISTRIBUTE
))) {
4941 bgp_aggregate_decrement(bgp
, &rn
->p
, ri
, afi
,
4943 bgp_unlink_nexthop(ri
);
4944 bgp_info_delete(rn
, ri
);
4945 bgp_process(bgp
, rn
, afi
, safi
);
4952 * Purge all networks and redistributed routes from routing table.
4953 * Invoked upon the instance going down.
4955 void bgp_purge_static_redist_routes(struct bgp
*bgp
)
4960 FOREACH_AFI_SAFI (afi
, safi
)
4961 bgp_purge_af_static_redist_routes(bgp
, afi
, safi
);
4966 * Currently this is used to set static routes for VPN and ENCAP.
4967 * I think it can probably be factored with bgp_static_set.
4969 int bgp_static_set_safi(afi_t afi
, safi_t safi
, struct vty
*vty
,
4970 const char *ip_str
, const char *rd_str
,
4971 const char *label_str
, const char *rmap_str
,
4972 int evpn_type
, const char *esi
, const char *gwip
,
4973 const char *ethtag
, const char *routermac
)
4975 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4978 struct prefix_rd prd
;
4979 struct bgp_node
*prn
;
4980 struct bgp_node
*rn
;
4981 struct bgp_table
*table
;
4982 struct bgp_static
*bgp_static
;
4983 mpls_label_t label
= MPLS_INVALID_LABEL
;
4984 struct prefix gw_ip
;
4986 /* validate ip prefix */
4987 ret
= str2prefix(ip_str
, &p
);
4989 vty_out(vty
, "%% Malformed prefix\n");
4990 return CMD_WARNING_CONFIG_FAILED
;
4993 if ((afi
== AFI_L2VPN
)
4994 && (bgp_build_evpn_prefix(evpn_type
,
4995 ethtag
!= NULL
? atol(ethtag
) : 0, &p
))) {
4996 vty_out(vty
, "%% L2VPN prefix could not be forged\n");
4997 return CMD_WARNING_CONFIG_FAILED
;
5000 ret
= str2prefix_rd(rd_str
, &prd
);
5002 vty_out(vty
, "%% Malformed rd\n");
5003 return CMD_WARNING_CONFIG_FAILED
;
5007 unsigned long label_val
;
5008 label_val
= strtoul(label_str
, NULL
, 10);
5009 encode_label(label_val
, &label
);
5012 if (safi
== SAFI_EVPN
) {
5013 if (esi
&& str2esi(esi
, NULL
) == 0) {
5014 vty_out(vty
, "%% Malformed ESI\n");
5015 return CMD_WARNING_CONFIG_FAILED
;
5017 if (routermac
&& prefix_str2mac(routermac
, NULL
) == 0) {
5018 vty_out(vty
, "%% Malformed Router MAC\n");
5019 return CMD_WARNING_CONFIG_FAILED
;
5022 memset(&gw_ip
, 0, sizeof(struct prefix
));
5023 ret
= str2prefix(gwip
, &gw_ip
);
5025 vty_out(vty
, "%% Malformed GatewayIp\n");
5026 return CMD_WARNING_CONFIG_FAILED
;
5028 if ((gw_ip
.family
== AF_INET
5029 && IS_EVPN_PREFIX_IPADDR_V6(
5030 (struct prefix_evpn
*)&p
))
5031 || (gw_ip
.family
== AF_INET6
5032 && IS_EVPN_PREFIX_IPADDR_V4(
5033 (struct prefix_evpn
*)&p
))) {
5035 "%% GatewayIp family differs with IP prefix\n");
5036 return CMD_WARNING_CONFIG_FAILED
;
5040 prn
= bgp_node_get(bgp
->route
[afi
][safi
], (struct prefix
*)&prd
);
5041 if (prn
->info
== NULL
)
5042 prn
->info
= bgp_table_init(afi
, safi
);
5044 bgp_unlock_node(prn
);
5047 rn
= bgp_node_get(table
, &p
);
5050 vty_out(vty
, "%% Same network configuration exists\n");
5051 bgp_unlock_node(rn
);
5053 /* New configuration. */
5054 bgp_static
= bgp_static_new();
5055 bgp_static
->backdoor
= 0;
5056 bgp_static
->valid
= 0;
5057 bgp_static
->igpmetric
= 0;
5058 bgp_static
->igpnexthop
.s_addr
= 0;
5059 bgp_static
->label
= label
;
5060 bgp_static
->prd
= prd
;
5063 if (bgp_static
->rmap
.name
)
5064 XFREE(MTYPE_ROUTE_MAP_NAME
,
5065 bgp_static
->rmap
.name
);
5066 bgp_static
->rmap
.name
=
5067 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_str
);
5068 bgp_static
->rmap
.map
=
5069 route_map_lookup_by_name(rmap_str
);
5072 if (safi
== SAFI_EVPN
) {
5074 bgp_static
->eth_s_id
=
5076 sizeof(struct eth_segment_id
));
5077 str2esi(esi
, bgp_static
->eth_s_id
);
5080 bgp_static
->router_mac
=
5081 XCALLOC(MTYPE_ATTR
, ETH_ALEN
+ 1);
5082 prefix_str2mac(routermac
,
5083 bgp_static
->router_mac
);
5086 prefix_copy(&bgp_static
->gatewayIp
, &gw_ip
);
5088 rn
->info
= bgp_static
;
5090 bgp_static
->valid
= 1;
5091 bgp_static_update_safi(bgp
, &p
, bgp_static
, afi
, safi
);
5097 /* Configure static BGP network. */
5098 int bgp_static_unset_safi(afi_t afi
, safi_t safi
, struct vty
*vty
,
5099 const char *ip_str
, const char *rd_str
,
5100 const char *label_str
, int evpn_type
, const char *esi
,
5101 const char *gwip
, const char *ethtag
)
5103 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5106 struct prefix_rd prd
;
5107 struct bgp_node
*prn
;
5108 struct bgp_node
*rn
;
5109 struct bgp_table
*table
;
5110 struct bgp_static
*bgp_static
;
5111 mpls_label_t label
= MPLS_INVALID_LABEL
;
5113 /* Convert IP prefix string to struct prefix. */
5114 ret
= str2prefix(ip_str
, &p
);
5116 vty_out(vty
, "%% Malformed prefix\n");
5117 return CMD_WARNING_CONFIG_FAILED
;
5120 if ((afi
== AFI_L2VPN
)
5121 && (bgp_build_evpn_prefix(evpn_type
,
5122 ethtag
!= NULL
? atol(ethtag
) : 0, &p
))) {
5123 vty_out(vty
, "%% L2VPN prefix could not be forged\n");
5124 return CMD_WARNING_CONFIG_FAILED
;
5126 ret
= str2prefix_rd(rd_str
, &prd
);
5128 vty_out(vty
, "%% Malformed rd\n");
5129 return CMD_WARNING_CONFIG_FAILED
;
5133 unsigned long label_val
;
5134 label_val
= strtoul(label_str
, NULL
, 10);
5135 encode_label(label_val
, &label
);
5138 prn
= bgp_node_get(bgp
->route
[afi
][safi
], (struct prefix
*)&prd
);
5139 if (prn
->info
== NULL
)
5140 prn
->info
= bgp_table_init(afi
, safi
);
5142 bgp_unlock_node(prn
);
5145 rn
= bgp_node_lookup(table
, &p
);
5148 bgp_static_withdraw_safi(bgp
, &p
, afi
, safi
, &prd
);
5150 bgp_static
= rn
->info
;
5151 bgp_static_free(bgp_static
);
5153 bgp_unlock_node(rn
);
5154 bgp_unlock_node(rn
);
5156 vty_out(vty
, "%% Can't find the route\n");
5161 static int bgp_table_map_set(struct vty
*vty
, afi_t afi
, safi_t safi
,
5162 const char *rmap_name
)
5164 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5165 struct bgp_rmap
*rmap
;
5167 rmap
= &bgp
->table_map
[afi
][safi
];
5170 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5171 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
5172 rmap
->map
= route_map_lookup_by_name(rmap_name
);
5175 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5180 if (bgp_fibupd_safi(safi
))
5181 bgp_zebra_announce_table(bgp
, afi
, safi
);
5186 static int bgp_table_map_unset(struct vty
*vty
, afi_t afi
, safi_t safi
,
5187 const char *rmap_name
)
5189 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5190 struct bgp_rmap
*rmap
;
5192 rmap
= &bgp
->table_map
[afi
][safi
];
5194 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5198 if (bgp_fibupd_safi(safi
))
5199 bgp_zebra_announce_table(bgp
, afi
, safi
);
5204 void bgp_config_write_table_map(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
5207 if (bgp
->table_map
[afi
][safi
].name
) {
5208 vty_out(vty
, " table-map %s\n",
5209 bgp
->table_map
[afi
][safi
].name
);
5213 DEFUN (bgp_table_map
,
5216 "BGP table to RIB route download filter\n"
5217 "Name of the route map\n")
5220 return bgp_table_map_set(vty
, bgp_node_afi(vty
), bgp_node_safi(vty
),
5221 argv
[idx_word
]->arg
);
5223 DEFUN (no_bgp_table_map
,
5224 no_bgp_table_map_cmd
,
5225 "no table-map WORD",
5227 "BGP table to RIB route download filter\n"
5228 "Name of the route map\n")
5231 return bgp_table_map_unset(vty
, bgp_node_afi(vty
), bgp_node_safi(vty
),
5232 argv
[idx_word
]->arg
);
5238 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
5239 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
5240 backdoor$backdoor}]",
5242 "Specify a network to announce via BGP\n"
5247 "Route-map to modify the attributes\n"
5248 "Name of the route map\n"
5249 "Label index to associate with the prefix\n"
5250 "Label index value\n"
5251 "Specify a BGP backdoor route\n")
5253 char addr_prefix_str
[BUFSIZ
];
5258 ret
= netmask_str2prefix_str(address_str
, netmask_str
,
5261 vty_out(vty
, "%% Inconsistent address and mask\n");
5262 return CMD_WARNING_CONFIG_FAILED
;
5266 return bgp_static_set(
5267 vty
, no
, address_str
? addr_prefix_str
: prefix_str
, AFI_IP
,
5268 bgp_node_safi(vty
), map_name
, backdoor
? 1 : 0,
5269 label_index
? (uint32_t)label_index
: BGP_INVALID_LABEL_INDEX
);
5272 DEFPY(ipv6_bgp_network
,
5273 ipv6_bgp_network_cmd
,
5274 "[no] network X:X::X:X/M$prefix \
5275 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
5277 "Specify a network to announce via BGP\n"
5279 "Route-map to modify the attributes\n"
5280 "Name of the route map\n"
5281 "Label index to associate with the prefix\n"
5282 "Label index value\n")
5284 return bgp_static_set(
5285 vty
, no
, prefix_str
, AFI_IP6
, bgp_node_safi(vty
), map_name
, 0,
5286 label_index
? (uint32_t)label_index
: BGP_INVALID_LABEL_INDEX
);
5289 /* Aggreagete address:
5291 advertise-map Set condition to advertise attribute
5292 as-set Generate AS set path information
5293 attribute-map Set attributes of aggregate
5294 route-map Set parameters of aggregate
5295 summary-only Filter more specific routes from updates
5296 suppress-map Conditionally filter more specific routes from updates
5299 struct bgp_aggregate
{
5300 /* Summary-only flag. */
5301 u_char summary_only
;
5303 /* AS set generation. */
5306 /* Route-map for aggregated route. */
5307 struct route_map
*map
;
5309 /* Suppress-count. */
5310 unsigned long count
;
5312 /* SAFI configuration. */
5316 static struct bgp_aggregate
*bgp_aggregate_new(void)
5318 return XCALLOC(MTYPE_BGP_AGGREGATE
, sizeof(struct bgp_aggregate
));
5321 static void bgp_aggregate_free(struct bgp_aggregate
*aggregate
)
5323 XFREE(MTYPE_BGP_AGGREGATE
, aggregate
);
5326 /* Update an aggregate as routes are added/removed from the BGP table */
5327 static void bgp_aggregate_route(struct bgp
*bgp
, struct prefix
*p
,
5328 struct bgp_info
*rinew
, afi_t afi
, safi_t safi
,
5329 struct bgp_info
*del
,
5330 struct bgp_aggregate
*aggregate
)
5332 struct bgp_table
*table
;
5333 struct bgp_node
*top
;
5334 struct bgp_node
*rn
;
5336 struct aspath
*aspath
= NULL
;
5337 struct aspath
*asmerge
= NULL
;
5338 struct community
*community
= NULL
;
5339 struct community
*commerge
= NULL
;
5340 #if defined(AGGREGATE_NEXTHOP_CHECK)
5341 struct in_addr nexthop
;
5344 struct bgp_info
*ri
;
5345 struct bgp_info
*new;
5347 unsigned long match
= 0;
5348 u_char atomic_aggregate
= 0;
5350 /* Record adding route's nexthop and med. */
5352 #if defined(AGGREGATE_NEXTHOP_CHECK)
5353 nexthop
= rinew
->attr
->nexthop
;
5354 med
= rinew
->attr
->med
;
5358 /* ORIGIN attribute: If at least one route among routes that are
5359 aggregated has ORIGIN with the value INCOMPLETE, then the
5360 aggregated route must have the ORIGIN attribute with the value
5361 INCOMPLETE. Otherwise, if at least one route among routes that
5362 are aggregated has ORIGIN with the value EGP, then the aggregated
5363 route must have the origin attribute with the value EGP. In all
5364 other case the value of the ORIGIN attribute of the aggregated
5365 route is INTERNAL. */
5366 origin
= BGP_ORIGIN_IGP
;
5368 table
= bgp
->rib
[afi
][safi
];
5370 top
= bgp_node_get(table
, p
);
5371 for (rn
= bgp_node_get(table
, p
); rn
;
5372 rn
= bgp_route_next_until(rn
, top
))
5373 if (rn
->p
.prefixlen
> p
->prefixlen
) {
5376 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
5377 if (BGP_INFO_HOLDDOWN(ri
))
5380 if (del
&& ri
== del
)
5383 if (!rinew
&& first
) {
5384 #if defined(AGGREGATE_NEXTHOP_CHECK)
5385 nexthop
= ri
->attr
->nexthop
;
5386 med
= ri
->attr
->med
;
5391 #ifdef AGGREGATE_NEXTHOP_CHECK
5392 if (!IPV4_ADDR_SAME(&ri
->attr
->nexthop
,
5394 || ri
->attr
->med
!= med
) {
5396 aspath_free(aspath
);
5398 community_free(community
);
5399 bgp_unlock_node(rn
);
5400 bgp_unlock_node(top
);
5403 #endif /* AGGREGATE_NEXTHOP_CHECK */
5406 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5407 atomic_aggregate
= 1;
5409 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
) {
5410 if (aggregate
->summary_only
) {
5411 (bgp_info_extra_get(ri
))
5415 BGP_INFO_ATTR_CHANGED
);
5421 if (origin
< ri
->attr
->origin
)
5422 origin
= ri
->attr
->origin
;
5424 if (aggregate
->as_set
) {
5426 asmerge
= aspath_aggregate(
5429 aspath_free(aspath
);
5432 aspath
= aspath_dup(
5435 if (ri
->attr
->community
) {
5437 commerge
= community_merge(
5439 ri
->attr
->community
);
5440 community
= community_uniq_sort(
5445 community
= community_dup(
5446 ri
->attr
->community
);
5452 bgp_process(bgp
, rn
, afi
, safi
);
5454 bgp_unlock_node(top
);
5459 if (aggregate
->summary_only
)
5460 (bgp_info_extra_get(rinew
))->suppress
++;
5462 if (origin
< rinew
->attr
->origin
)
5463 origin
= rinew
->attr
->origin
;
5465 if (aggregate
->as_set
) {
5467 asmerge
= aspath_aggregate(aspath
,
5468 rinew
->attr
->aspath
);
5469 aspath_free(aspath
);
5472 aspath
= aspath_dup(rinew
->attr
->aspath
);
5474 if (rinew
->attr
->community
) {
5476 commerge
= community_merge(
5478 rinew
->attr
->community
);
5480 community_uniq_sort(commerge
);
5481 community_free(commerge
);
5483 community
= community_dup(
5484 rinew
->attr
->community
);
5489 if (aggregate
->count
> 0) {
5490 rn
= bgp_node_get(table
, p
);
5492 ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5493 bgp_attr_aggregate_intern(bgp
, origin
, aspath
,
5494 community
, aggregate
->as_set
,
5497 SET_FLAG(new->flags
, BGP_INFO_VALID
);
5499 bgp_info_add(rn
, new);
5500 bgp_unlock_node(rn
);
5501 bgp_process(bgp
, rn
, afi
, safi
);
5504 aspath_free(aspath
);
5506 community_free(community
);
5510 void bgp_aggregate_delete(struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5511 struct bgp_aggregate
*);
5513 void bgp_aggregate_increment(struct bgp
*bgp
, struct prefix
*p
,
5514 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5516 struct bgp_node
*child
;
5517 struct bgp_node
*rn
;
5518 struct bgp_aggregate
*aggregate
;
5519 struct bgp_table
*table
;
5521 /* MPLS-VPN aggregation is not yet supported. */
5522 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5523 || (safi
== SAFI_EVPN
))
5526 table
= bgp
->aggregate
[afi
][safi
];
5528 /* No aggregates configured. */
5529 if (bgp_table_top_nolock(table
) == NULL
)
5532 if (p
->prefixlen
== 0)
5535 if (BGP_INFO_HOLDDOWN(ri
))
5538 child
= bgp_node_get(table
, p
);
5540 /* Aggregate address configuration check. */
5541 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock(rn
))
5542 if ((aggregate
= rn
->info
) != NULL
5543 && rn
->p
.prefixlen
< p
->prefixlen
) {
5544 bgp_aggregate_delete(bgp
, &rn
->p
, afi
, safi
, aggregate
);
5545 bgp_aggregate_route(bgp
, &rn
->p
, ri
, afi
, safi
, NULL
,
5548 bgp_unlock_node(child
);
5551 void bgp_aggregate_decrement(struct bgp
*bgp
, struct prefix
*p
,
5552 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5554 struct bgp_node
*child
;
5555 struct bgp_node
*rn
;
5556 struct bgp_aggregate
*aggregate
;
5557 struct bgp_table
*table
;
5559 /* MPLS-VPN aggregation is not yet supported. */
5560 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5561 || (safi
== SAFI_EVPN
))
5564 table
= bgp
->aggregate
[afi
][safi
];
5566 /* No aggregates configured. */
5567 if (bgp_table_top_nolock(table
) == NULL
)
5570 if (p
->prefixlen
== 0)
5573 child
= bgp_node_get(table
, p
);
5575 /* Aggregate address configuration check. */
5576 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock(rn
))
5577 if ((aggregate
= rn
->info
) != NULL
5578 && rn
->p
.prefixlen
< p
->prefixlen
) {
5579 bgp_aggregate_delete(bgp
, &rn
->p
, afi
, safi
, aggregate
);
5580 bgp_aggregate_route(bgp
, &rn
->p
, NULL
, afi
, safi
, del
,
5583 bgp_unlock_node(child
);
5586 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5587 static void bgp_aggregate_add(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5588 safi_t safi
, struct bgp_aggregate
*aggregate
)
5590 struct bgp_table
*table
;
5591 struct bgp_node
*top
;
5592 struct bgp_node
*rn
;
5593 struct bgp_info
*new;
5594 struct bgp_info
*ri
;
5595 unsigned long match
;
5596 u_char origin
= BGP_ORIGIN_IGP
;
5597 struct aspath
*aspath
= NULL
;
5598 struct aspath
*asmerge
= NULL
;
5599 struct community
*community
= NULL
;
5600 struct community
*commerge
= NULL
;
5601 u_char atomic_aggregate
= 0;
5603 table
= bgp
->rib
[afi
][safi
];
5606 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5608 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5611 /* If routes exists below this node, generate aggregate routes. */
5612 top
= bgp_node_get(table
, p
);
5613 for (rn
= bgp_node_get(table
, p
); rn
;
5614 rn
= bgp_route_next_until(rn
, top
)) {
5615 if (rn
->p
.prefixlen
<= p
->prefixlen
)
5620 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
5621 if (BGP_INFO_HOLDDOWN(ri
))
5625 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5626 atomic_aggregate
= 1;
5628 if (ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5631 /* summary-only aggregate route suppress
5632 * aggregated route announcement. */
5633 if (aggregate
->summary_only
) {
5634 (bgp_info_extra_get(ri
))->suppress
++;
5635 bgp_info_set_flag(rn
, ri
,
5636 BGP_INFO_ATTR_CHANGED
);
5640 /* If at least one route among routes that are
5641 * aggregated has ORIGIN with the value INCOMPLETE,
5642 * then the aggregated route MUST have the ORIGIN
5643 * attribute with the value INCOMPLETE. Otherwise, if
5644 * at least one route among routes that are aggregated
5645 * has ORIGIN with the value EGP, then the aggregated
5646 * route MUST have the ORIGIN attribute with the value
5649 if (origin
< ri
->attr
->origin
)
5650 origin
= ri
->attr
->origin
;
5652 /* as-set aggregate route generate origin, as path,
5653 * community aggregation. */
5654 if (aggregate
->as_set
) {
5656 asmerge
= aspath_aggregate(
5657 aspath
, ri
->attr
->aspath
);
5658 aspath_free(aspath
);
5661 aspath
= aspath_dup(ri
->attr
->aspath
);
5663 if (ri
->attr
->community
) {
5665 commerge
= community_merge(
5667 ri
->attr
->community
);
5668 community
= community_uniq_sort(
5670 community_free(commerge
);
5672 community
= community_dup(
5673 ri
->attr
->community
);
5679 /* If this node is suppressed, process the change. */
5681 bgp_process(bgp
, rn
, afi
, safi
);
5683 bgp_unlock_node(top
);
5685 /* Add aggregate route to BGP table. */
5686 if (aggregate
->count
) {
5687 rn
= bgp_node_get(table
, p
);
5689 ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5690 bgp_attr_aggregate_intern(bgp
, origin
, aspath
,
5691 community
, aggregate
->as_set
,
5694 SET_FLAG(new->flags
, BGP_INFO_VALID
);
5696 bgp_info_add(rn
, new);
5697 bgp_unlock_node(rn
);
5699 /* Process change. */
5700 bgp_process(bgp
, rn
, afi
, safi
);
5703 aspath_free(aspath
);
5705 community_free(community
);
5709 void bgp_aggregate_delete(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5710 safi_t safi
, struct bgp_aggregate
*aggregate
)
5712 struct bgp_table
*table
;
5713 struct bgp_node
*top
;
5714 struct bgp_node
*rn
;
5715 struct bgp_info
*ri
;
5716 unsigned long match
;
5718 table
= bgp
->rib
[afi
][safi
];
5720 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5722 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5725 /* If routes exists below this node, generate aggregate routes. */
5726 top
= bgp_node_get(table
, p
);
5727 for (rn
= bgp_node_get(table
, p
); rn
;
5728 rn
= bgp_route_next_until(rn
, top
)) {
5729 if (rn
->p
.prefixlen
<= p
->prefixlen
)
5733 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
5734 if (BGP_INFO_HOLDDOWN(ri
))
5737 if (ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5740 if (aggregate
->summary_only
&& ri
->extra
) {
5741 ri
->extra
->suppress
--;
5743 if (ri
->extra
->suppress
== 0) {
5745 rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5752 /* If this node was suppressed, process the change. */
5754 bgp_process(bgp
, rn
, afi
, safi
);
5756 bgp_unlock_node(top
);
5758 /* Delete aggregate route from BGP table. */
5759 rn
= bgp_node_get(table
, p
);
5761 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5762 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
5763 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5766 /* Withdraw static BGP route from routing table. */
5768 bgp_info_delete(rn
, ri
);
5769 bgp_process(bgp
, rn
, afi
, safi
);
5772 /* Unlock bgp_node_lookup. */
5773 bgp_unlock_node(rn
);
5776 /* Aggregate route attribute. */
5777 #define AGGREGATE_SUMMARY_ONLY 1
5778 #define AGGREGATE_AS_SET 1
5780 static int bgp_aggregate_unset(struct vty
*vty
, const char *prefix_str
,
5781 afi_t afi
, safi_t safi
)
5783 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5786 struct bgp_node
*rn
;
5787 struct bgp_aggregate
*aggregate
;
5789 /* Convert string to prefix structure. */
5790 ret
= str2prefix(prefix_str
, &p
);
5792 vty_out(vty
, "Malformed prefix\n");
5793 return CMD_WARNING_CONFIG_FAILED
;
5797 /* Old configuration check. */
5798 rn
= bgp_node_lookup(bgp
->aggregate
[afi
][safi
], &p
);
5801 "%% There is no aggregate-address configuration.\n");
5802 return CMD_WARNING_CONFIG_FAILED
;
5805 aggregate
= rn
->info
;
5806 if (aggregate
->safi
== SAFI_UNICAST
)
5807 bgp_aggregate_delete(bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5808 if (aggregate
->safi
== SAFI_LABELED_UNICAST
)
5809 bgp_aggregate_delete(bgp
, &p
, afi
, SAFI_LABELED_UNICAST
,
5811 if (aggregate
->safi
== SAFI_MULTICAST
)
5812 bgp_aggregate_delete(bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5814 /* Unlock aggregate address configuration. */
5816 bgp_aggregate_free(aggregate
);
5817 bgp_unlock_node(rn
);
5818 bgp_unlock_node(rn
);
5823 static int bgp_aggregate_set(struct vty
*vty
, const char *prefix_str
, afi_t afi
,
5824 safi_t safi
, u_char summary_only
, u_char as_set
)
5826 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5829 struct bgp_node
*rn
;
5830 struct bgp_aggregate
*aggregate
;
5832 /* Convert string to prefix structure. */
5833 ret
= str2prefix(prefix_str
, &p
);
5835 vty_out(vty
, "Malformed prefix\n");
5836 return CMD_WARNING_CONFIG_FAILED
;
5840 /* Old configuration check. */
5841 rn
= bgp_node_get(bgp
->aggregate
[afi
][safi
], &p
);
5844 vty_out(vty
, "There is already same aggregate network.\n");
5845 /* try to remove the old entry */
5846 ret
= bgp_aggregate_unset(vty
, prefix_str
, afi
, safi
);
5848 vty_out(vty
, "Error deleting aggregate.\n");
5849 bgp_unlock_node(rn
);
5850 return CMD_WARNING_CONFIG_FAILED
;
5854 /* Make aggregate address structure. */
5855 aggregate
= bgp_aggregate_new();
5856 aggregate
->summary_only
= summary_only
;
5857 aggregate
->as_set
= as_set
;
5858 aggregate
->safi
= safi
;
5859 rn
->info
= aggregate
;
5861 /* Aggregate address insert into BGP routing table. */
5862 if (safi
== SAFI_UNICAST
)
5863 bgp_aggregate_add(bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5864 if (safi
== SAFI_LABELED_UNICAST
)
5865 bgp_aggregate_add(bgp
, &p
, afi
, SAFI_LABELED_UNICAST
,
5867 if (safi
== SAFI_MULTICAST
)
5868 bgp_aggregate_add(bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5873 DEFUN (aggregate_address
,
5874 aggregate_address_cmd
,
5875 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5876 "Configure BGP aggregate entries\n"
5877 "Aggregate prefix\n"
5878 "Generate AS set path information\n"
5879 "Filter more specific routes from updates\n"
5880 "Filter more specific routes from updates\n"
5881 "Generate AS set path information\n")
5884 argv_find(argv
, argc
, "A.B.C.D/M", &idx
);
5885 char *prefix
= argv
[idx
]->arg
;
5887 argv_find(argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5889 int summary_only
= argv_find(argv
, argc
, "summary-only", &idx
)
5890 ? AGGREGATE_SUMMARY_ONLY
5893 return bgp_aggregate_set(vty
, prefix
, AFI_IP
, bgp_node_safi(vty
),
5894 summary_only
, as_set
);
5897 DEFUN (aggregate_address_mask
,
5898 aggregate_address_mask_cmd
,
5899 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5900 "Configure BGP aggregate entries\n"
5901 "Aggregate address\n"
5903 "Generate AS set path information\n"
5904 "Filter more specific routes from updates\n"
5905 "Filter more specific routes from updates\n"
5906 "Generate AS set path information\n")
5909 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5910 char *prefix
= argv
[idx
]->arg
;
5911 char *mask
= argv
[idx
+ 1]->arg
;
5913 argv_find(argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5915 int summary_only
= argv_find(argv
, argc
, "summary-only", &idx
)
5916 ? AGGREGATE_SUMMARY_ONLY
5919 char prefix_str
[BUFSIZ
];
5920 int ret
= netmask_str2prefix_str(prefix
, mask
, prefix_str
);
5923 vty_out(vty
, "%% Inconsistent address and mask\n");
5924 return CMD_WARNING_CONFIG_FAILED
;
5927 return bgp_aggregate_set(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
),
5928 summary_only
, as_set
);
5931 DEFUN (no_aggregate_address
,
5932 no_aggregate_address_cmd
,
5933 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5935 "Configure BGP aggregate entries\n"
5936 "Aggregate prefix\n"
5937 "Generate AS set path information\n"
5938 "Filter more specific routes from updates\n"
5939 "Filter more specific routes from updates\n"
5940 "Generate AS set path information\n")
5943 argv_find(argv
, argc
, "A.B.C.D/M", &idx
);
5944 char *prefix
= argv
[idx
]->arg
;
5945 return bgp_aggregate_unset(vty
, prefix
, AFI_IP
, bgp_node_safi(vty
));
5948 DEFUN (no_aggregate_address_mask
,
5949 no_aggregate_address_mask_cmd
,
5950 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5952 "Configure BGP aggregate entries\n"
5953 "Aggregate address\n"
5955 "Generate AS set path information\n"
5956 "Filter more specific routes from updates\n"
5957 "Filter more specific routes from updates\n"
5958 "Generate AS set path information\n")
5961 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5962 char *prefix
= argv
[idx
]->arg
;
5963 char *mask
= argv
[idx
+ 1]->arg
;
5965 char prefix_str
[BUFSIZ
];
5966 int ret
= netmask_str2prefix_str(prefix
, mask
, prefix_str
);
5969 vty_out(vty
, "%% Inconsistent address and mask\n");
5970 return CMD_WARNING_CONFIG_FAILED
;
5973 return bgp_aggregate_unset(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
));
5976 DEFUN (ipv6_aggregate_address
,
5977 ipv6_aggregate_address_cmd
,
5978 "aggregate-address X:X::X:X/M [summary-only]",
5979 "Configure BGP aggregate entries\n"
5980 "Aggregate prefix\n"
5981 "Filter more specific routes from updates\n")
5984 argv_find(argv
, argc
, "X:X::X:X/M", &idx
);
5985 char *prefix
= argv
[idx
]->arg
;
5986 int sum_only
= argv_find(argv
, argc
, "summary-only", &idx
)
5987 ? AGGREGATE_SUMMARY_ONLY
5989 return bgp_aggregate_set(vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
,
5993 DEFUN (no_ipv6_aggregate_address
,
5994 no_ipv6_aggregate_address_cmd
,
5995 "no aggregate-address X:X::X:X/M [summary-only]",
5997 "Configure BGP aggregate entries\n"
5998 "Aggregate prefix\n"
5999 "Filter more specific routes from updates\n")
6002 argv_find(argv
, argc
, "X:X::X:X/M", &idx
);
6003 char *prefix
= argv
[idx
]->arg
;
6004 return bgp_aggregate_unset(vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
6007 /* Redistribute route treatment. */
6008 void bgp_redistribute_add(struct bgp
*bgp
, struct prefix
*p
,
6009 const union g_addr
*nexthop
, ifindex_t ifindex
,
6010 enum nexthop_types_t nhtype
, uint32_t metric
,
6011 u_char type
, u_short instance
, route_tag_t tag
)
6013 struct bgp_info
*new;
6014 struct bgp_info
*bi
;
6015 struct bgp_info info
;
6016 struct bgp_node
*bn
;
6018 struct attr
*new_attr
;
6021 struct bgp_redist
*red
;
6023 /* Make default attribute. */
6024 bgp_attr_default_set(&attr
, BGP_ORIGIN_INCOMPLETE
);
6027 case NEXTHOP_TYPE_IFINDEX
:
6029 case NEXTHOP_TYPE_IPV4
:
6030 case NEXTHOP_TYPE_IPV4_IFINDEX
:
6031 attr
.nexthop
= nexthop
->ipv4
;
6033 case NEXTHOP_TYPE_IPV6
:
6034 case NEXTHOP_TYPE_IPV6_IFINDEX
:
6035 attr
.mp_nexthop_global
= nexthop
->ipv6
;
6036 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
6038 case NEXTHOP_TYPE_BLACKHOLE
:
6039 switch (p
->family
) {
6041 attr
.nexthop
.s_addr
= INADDR_ANY
;
6044 memset(&attr
.mp_nexthop_global
, 0,
6045 sizeof(attr
.mp_nexthop_global
));
6046 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
6051 attr
.nh_ifindex
= ifindex
;
6054 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
6057 afi
= family2afi(p
->family
);
6059 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6061 struct attr attr_new
;
6063 /* Copy attribute for modification. */
6064 bgp_attr_dup(&attr_new
, &attr
);
6066 if (red
->redist_metric_flag
)
6067 attr_new
.med
= red
->redist_metric
;
6069 /* Apply route-map. */
6070 if (red
->rmap
.name
) {
6071 info
.peer
= bgp
->peer_self
;
6072 info
.attr
= &attr_new
;
6074 SET_FLAG(bgp
->peer_self
->rmap_type
,
6075 PEER_RMAP_TYPE_REDISTRIBUTE
);
6077 ret
= route_map_apply(red
->rmap
.map
, p
, RMAP_BGP
,
6080 bgp
->peer_self
->rmap_type
= 0;
6082 if (ret
== RMAP_DENYMATCH
) {
6083 /* Free uninterned attribute. */
6084 bgp_attr_flush(&attr_new
);
6086 /* Unintern original. */
6087 aspath_unintern(&attr
.aspath
);
6088 bgp_redistribute_delete(bgp
, p
, type
, instance
);
6093 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
6094 bgp_attr_add_gshut_community(&attr_new
);
6096 bn
= bgp_afi_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], afi
,
6097 SAFI_UNICAST
, p
, NULL
);
6099 new_attr
= bgp_attr_intern(&attr_new
);
6101 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
6102 if (bi
->peer
== bgp
->peer_self
6103 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
6107 /* Ensure the (source route) type is updated. */
6109 if (attrhash_cmp(bi
->attr
, new_attr
)
6110 && !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
)) {
6111 bgp_attr_unintern(&new_attr
);
6112 aspath_unintern(&attr
.aspath
);
6113 bgp_unlock_node(bn
);
6116 /* The attribute is changed. */
6117 bgp_info_set_flag(bn
, bi
,
6118 BGP_INFO_ATTR_CHANGED
);
6120 /* Rewrite BGP route information. */
6121 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6122 bgp_info_restore(bn
, bi
);
6124 bgp_aggregate_decrement(bgp
, p
, bi
, afi
,
6126 bgp_attr_unintern(&bi
->attr
);
6127 bi
->attr
= new_attr
;
6128 bi
->uptime
= bgp_clock();
6130 /* Process change. */
6131 bgp_aggregate_increment(bgp
, p
, bi
, afi
,
6133 bgp_process(bgp
, bn
, afi
, SAFI_UNICAST
);
6134 bgp_unlock_node(bn
);
6135 aspath_unintern(&attr
.aspath
);
6137 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6139 == BGP_INSTANCE_TYPE_DEFAULT
)) {
6141 vpn_leak_from_vrf_update(
6142 bgp_get_default(), bgp
, bi
);
6148 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
,
6149 bgp
->peer_self
, new_attr
, bn
);
6150 SET_FLAG(new->flags
, BGP_INFO_VALID
);
6152 bgp_aggregate_increment(bgp
, p
, new, afi
, SAFI_UNICAST
);
6153 bgp_info_add(bn
, new);
6154 bgp_unlock_node(bn
);
6155 bgp_process(bgp
, bn
, afi
, SAFI_UNICAST
);
6157 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6158 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6160 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
6164 /* Unintern original. */
6165 aspath_unintern(&attr
.aspath
);
6168 void bgp_redistribute_delete(struct bgp
*bgp
, struct prefix
*p
, u_char type
,
6172 struct bgp_node
*rn
;
6173 struct bgp_info
*ri
;
6174 struct bgp_redist
*red
;
6176 afi
= family2afi(p
->family
);
6178 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6180 rn
= bgp_afi_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], afi
,
6181 SAFI_UNICAST
, p
, NULL
);
6183 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6184 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== type
)
6188 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6189 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6191 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6194 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, SAFI_UNICAST
);
6195 bgp_info_delete(rn
, ri
);
6196 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
6198 bgp_unlock_node(rn
);
6202 /* Withdraw specified route type's route. */
6203 void bgp_redistribute_withdraw(struct bgp
*bgp
, afi_t afi
, int type
,
6206 struct bgp_node
*rn
;
6207 struct bgp_info
*ri
;
6208 struct bgp_table
*table
;
6210 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
6212 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
6213 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6214 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== type
6215 && ri
->instance
== instance
)
6219 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6220 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6222 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6225 bgp_aggregate_decrement(bgp
, &rn
->p
, ri
, afi
,
6227 bgp_info_delete(rn
, ri
);
6228 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
6233 /* Static function to display route. */
6234 static void route_vty_out_route(struct prefix
*p
, struct vty
*vty
,
6238 u_int32_t destination
;
6241 if (p
->family
== AF_INET
) {
6243 len
= vty_out(vty
, "%s",
6244 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
6246 destination
= ntohl(p
->u
.prefix4
.s_addr
);
6248 if ((IN_CLASSC(destination
) && p
->prefixlen
== 24)
6249 || (IN_CLASSB(destination
) && p
->prefixlen
== 16)
6250 || (IN_CLASSA(destination
) && p
->prefixlen
== 8)
6251 || p
->u
.prefix4
.s_addr
== 0) {
6252 /* When mask is natural,
6253 mask is not displayed. */
6255 len
+= vty_out(vty
, "/%d", p
->prefixlen
);
6257 json_object_string_add(json
, "prefix",
6258 inet_ntop(p
->family
,
6261 json_object_int_add(json
, "prefixLen", p
->prefixlen
);
6263 } else if (p
->family
== AF_ETHERNET
) {
6264 prefix2str(p
, buf
, PREFIX_STRLEN
);
6265 len
= vty_out(vty
, "%s", buf
);
6266 } else if (p
->family
== AF_EVPN
) {
6267 #if defined(HAVE_CUMULUS)
6271 bgp_evpn_route2str((struct prefix_evpn
*)p
, buf
,
6274 bgp_evpn_route2json((struct prefix_evpn
*)p
, json
);
6276 prefix2str(p
, buf
, PREFIX_STRLEN
);
6277 len
= vty_out(vty
, "%s", buf
);
6283 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6290 vty_out(vty
, "\n%*s", 20, " ");
6292 vty_out(vty
, "%*s", len
, " ");
6296 enum bgp_display_type
{
6300 /* Print the short form route status for a bgp_info */
6301 static void route_vty_short_status_out(struct vty
*vty
, struct bgp_info
*binfo
,
6302 json_object
*json_path
)
6306 /* Route status display. */
6307 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_REMOVED
))
6308 json_object_boolean_true_add(json_path
, "removed");
6310 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_STALE
))
6311 json_object_boolean_true_add(json_path
, "stale");
6313 if (binfo
->extra
&& binfo
->extra
->suppress
)
6314 json_object_boolean_true_add(json_path
, "suppressed");
6316 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)
6317 && !CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6318 json_object_boolean_true_add(json_path
, "valid");
6321 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6322 json_object_boolean_true_add(json_path
, "history");
6324 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
))
6325 json_object_boolean_true_add(json_path
, "damped");
6327 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
))
6328 json_object_boolean_true_add(json_path
, "bestpath");
6330 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_MULTIPATH
))
6331 json_object_boolean_true_add(json_path
, "multipath");
6333 /* Internal route. */
6334 if ((binfo
->peer
->as
)
6335 && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6336 json_object_string_add(json_path
, "pathFrom",
6339 json_object_string_add(json_path
, "pathFrom",
6345 /* Route status display. */
6346 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_REMOVED
))
6348 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_STALE
))
6350 else if (binfo
->extra
&& binfo
->extra
->suppress
)
6352 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)
6353 && !CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6359 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6361 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
))
6363 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
))
6365 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_MULTIPATH
))
6370 /* Internal route. */
6371 if (binfo
->peer
&& (binfo
->peer
->as
)
6372 && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6378 /* called from terminal list command */
6379 void route_vty_out(struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6380 int display
, safi_t safi
, json_object
*json_paths
)
6383 json_object
*json_path
= NULL
;
6384 json_object
*json_nexthops
= NULL
;
6385 json_object
*json_nexthop_global
= NULL
;
6386 json_object
*json_nexthop_ll
= NULL
;
6389 json_path
= json_object_new_object();
6391 /* short status lead text */
6392 route_vty_short_status_out(vty
, binfo
, json_path
);
6395 /* print prefix and mask */
6397 route_vty_out_route(p
, vty
, json_path
);
6399 vty_out(vty
, "%*s", 17, " ");
6401 route_vty_out_route(p
, vty
, json_path
);
6404 /* Print attribute */
6408 json_object_array_add(json_paths
, json_path
);
6416 * For ENCAP and EVPN routes, nexthop address family is not
6417 * neccessarily the same as the prefix address family.
6418 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6419 * EVPN routes are also exchanged with a MP nexthop. Currently,
6421 * is only IPv4, the value will be present in either
6423 * attr->mp_nexthop_global_in
6425 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
)) {
6428 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
6432 sprintf(nexthop
, "%s",
6433 inet_ntop(af
, &attr
->mp_nexthop_global_in
, buf
,
6437 sprintf(nexthop
, "%s",
6438 inet_ntop(af
, &attr
->mp_nexthop_global
, buf
,
6442 sprintf(nexthop
, "?");
6447 json_nexthop_global
= json_object_new_object();
6449 json_object_string_add(json_nexthop_global
, "afi",
6450 (af
== AF_INET
) ? "ip" : "ipv6");
6451 json_object_string_add(json_nexthop_global
,
6452 (af
== AF_INET
) ? "ip" : "ipv6",
6454 json_object_boolean_true_add(json_nexthop_global
,
6457 vty_out(vty
, "%s", nexthop
);
6458 } else if (safi
== SAFI_EVPN
) {
6460 json_nexthop_global
= json_object_new_object();
6462 json_object_string_add(json_nexthop_global
, "ip",
6463 inet_ntoa(attr
->nexthop
));
6464 json_object_string_add(json_nexthop_global
, "afi",
6466 json_object_boolean_true_add(json_nexthop_global
,
6469 vty_out(vty
, "%-16s", inet_ntoa(attr
->nexthop
));
6472 else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6474 json_nexthop_global
= json_object_new_object();
6476 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6477 json_object_string_add(
6478 json_nexthop_global
, "ip",
6479 inet_ntoa(attr
->mp_nexthop_global_in
));
6481 json_object_string_add(
6482 json_nexthop_global
, "ip",
6483 inet_ntoa(attr
->nexthop
));
6485 json_object_string_add(json_nexthop_global
, "afi",
6487 json_object_boolean_true_add(json_nexthop_global
,
6490 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6491 vty_out(vty
, "%-16s",
6492 inet_ntoa(attr
->mp_nexthop_global_in
));
6494 vty_out(vty
, "%-16s", inet_ntoa(attr
->nexthop
));
6499 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6504 json_nexthop_global
= json_object_new_object();
6505 json_object_string_add(
6506 json_nexthop_global
, "ip",
6507 inet_ntop(AF_INET6
, &attr
->mp_nexthop_global
,
6509 json_object_string_add(json_nexthop_global
, "afi",
6511 json_object_string_add(json_nexthop_global
, "scope",
6514 /* We display both LL & GL if both have been
6516 if ((attr
->mp_nexthop_len
== 32)
6517 || (binfo
->peer
->conf_if
)) {
6518 json_nexthop_ll
= json_object_new_object();
6519 json_object_string_add(
6520 json_nexthop_ll
, "ip",
6522 &attr
->mp_nexthop_local
, buf
,
6524 json_object_string_add(json_nexthop_ll
, "afi",
6526 json_object_string_add(json_nexthop_ll
, "scope",
6529 if ((IPV6_ADDR_CMP(&attr
->mp_nexthop_global
,
6530 &attr
->mp_nexthop_local
)
6532 && !attr
->mp_nexthop_prefer_global
)
6533 json_object_boolean_true_add(
6534 json_nexthop_ll
, "used");
6536 json_object_boolean_true_add(
6537 json_nexthop_global
, "used");
6539 json_object_boolean_true_add(
6540 json_nexthop_global
, "used");
6542 /* Display LL if LL/Global both in table unless
6543 * prefer-global is set */
6544 if (((attr
->mp_nexthop_len
== 32)
6545 && !attr
->mp_nexthop_prefer_global
)
6546 || (binfo
->peer
->conf_if
)) {
6547 if (binfo
->peer
->conf_if
) {
6548 len
= vty_out(vty
, "%s",
6549 binfo
->peer
->conf_if
);
6550 len
= 16 - len
; /* len of IPv6
6556 vty_out(vty
, "\n%*s", 36, " ");
6558 vty_out(vty
, "%*s", len
, " ");
6564 &attr
->mp_nexthop_local
,
6569 vty_out(vty
, "\n%*s", 36, " ");
6571 vty_out(vty
, "%*s", len
, " ");
6577 &attr
->mp_nexthop_global
, buf
,
6582 vty_out(vty
, "\n%*s", 36, " ");
6584 vty_out(vty
, "%*s", len
, " ");
6590 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6592 json_object_int_add(json_path
, "med", attr
->med
);
6594 vty_out(vty
, "%10u", attr
->med
);
6595 else if (!json_paths
)
6599 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6601 json_object_int_add(json_path
, "localpref",
6604 vty_out(vty
, "%7u", attr
->local_pref
);
6605 else if (!json_paths
)
6609 json_object_int_add(json_path
, "weight", attr
->weight
);
6611 vty_out(vty
, "%7u ", attr
->weight
);
6615 json_object_string_add(
6616 json_path
, "peerId",
6617 sockunion2str(&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6623 json_object_string_add(json_path
, "aspath",
6626 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
6631 json_object_string_add(json_path
, "origin",
6632 bgp_origin_long_str
[attr
->origin
]);
6634 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
6637 if (json_nexthop_global
|| json_nexthop_ll
) {
6638 json_nexthops
= json_object_new_array();
6640 if (json_nexthop_global
)
6641 json_object_array_add(json_nexthops
,
6642 json_nexthop_global
);
6644 if (json_nexthop_ll
)
6645 json_object_array_add(json_nexthops
,
6648 json_object_object_add(json_path
, "nexthops",
6652 json_object_array_add(json_paths
, json_path
);
6656 /* prints an additional line, indented, with VNC info, if
6658 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6659 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6664 /* called from terminal list command */
6665 void route_vty_out_tmp(struct vty
*vty
, struct prefix
*p
, struct attr
*attr
,
6666 safi_t safi
, u_char use_json
, json_object
*json_ar
)
6668 json_object
*json_status
= NULL
;
6669 json_object
*json_net
= NULL
;
6671 /* Route status display. */
6673 json_status
= json_object_new_object();
6674 json_net
= json_object_new_object();
6681 /* print prefix and mask */
6683 json_object_string_add(
6684 json_net
, "addrPrefix",
6685 inet_ntop(p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6687 route_vty_out_route(p
, vty
, NULL
);
6689 /* Print attribute */
6692 if (p
->family
== AF_INET
6693 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6694 || safi
== SAFI_EVPN
6695 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6696 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6697 || safi
== SAFI_EVPN
)
6698 json_object_string_add(
6699 json_net
, "nextHop",
6701 attr
->mp_nexthop_global_in
));
6703 json_object_string_add(
6704 json_net
, "nextHop",
6705 inet_ntoa(attr
->nexthop
));
6706 } else if (p
->family
== AF_INET6
6707 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6710 json_object_string_add(
6711 json_net
, "netHopGloabal",
6713 &attr
->mp_nexthop_global
, buf
,
6718 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6719 json_object_int_add(json_net
, "metric",
6722 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6723 json_object_int_add(json_net
, "localPref",
6726 json_object_int_add(json_net
, "weight", attr
->weight
);
6730 json_object_string_add(json_net
, "asPath",
6734 json_object_string_add(json_net
, "bgpOriginCode",
6735 bgp_origin_str
[attr
->origin
]);
6737 if (p
->family
== AF_INET
6738 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6739 || safi
== SAFI_EVPN
6740 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6741 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6742 || safi
== SAFI_EVPN
)
6743 vty_out(vty
, "%-16s",
6745 attr
->mp_nexthop_global_in
));
6747 vty_out(vty
, "%-16s",
6748 inet_ntoa(attr
->nexthop
));
6749 } else if (p
->family
== AF_INET6
6750 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6757 &attr
->mp_nexthop_global
, buf
,
6761 vty_out(vty
, "\n%*s", 36, " ");
6763 vty_out(vty
, "%*s", len
, " ");
6766 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6767 vty_out(vty
, "%10u", attr
->med
);
6771 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6772 vty_out(vty
, "%7u", attr
->local_pref
);
6776 vty_out(vty
, "%7u ", attr
->weight
);
6780 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
6783 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
6787 json_object_boolean_true_add(json_status
, "*");
6788 json_object_boolean_true_add(json_status
, ">");
6789 json_object_object_add(json_net
, "appliedStatusSymbols",
6791 char buf_cut
[BUFSIZ
];
6792 json_object_object_add(
6794 inet_ntop(p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
),
6800 void route_vty_out_tag(struct vty
*vty
, struct prefix
*p
,
6801 struct bgp_info
*binfo
, int display
, safi_t safi
,
6804 json_object
*json_out
= NULL
;
6806 mpls_label_t label
= MPLS_INVALID_LABEL
;
6812 json_out
= json_object_new_object();
6814 /* short status lead text */
6815 route_vty_short_status_out(vty
, binfo
, json_out
);
6817 /* print prefix and mask */
6820 route_vty_out_route(p
, vty
, NULL
);
6822 vty_out(vty
, "%*s", 17, " ");
6825 /* Print attribute */
6828 if (((p
->family
== AF_INET
)
6829 && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6830 || (safi
== SAFI_EVPN
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6831 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6832 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6833 || safi
== SAFI_EVPN
) {
6835 json_object_string_add(
6836 json_out
, "mpNexthopGlobalIn",
6838 attr
->mp_nexthop_global_in
));
6840 vty_out(vty
, "%-16s",
6842 attr
->mp_nexthop_global_in
));
6845 json_object_string_add(
6846 json_out
, "nexthop",
6847 inet_ntoa(attr
->nexthop
));
6849 vty_out(vty
, "%-16s",
6850 inet_ntoa(attr
->nexthop
));
6852 } else if (((p
->family
== AF_INET6
)
6853 && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6854 || (safi
== SAFI_EVPN
6855 && BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6856 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6860 if (attr
->mp_nexthop_len
6861 == BGP_ATTR_NHLEN_IPV6_GLOBAL
) {
6863 json_object_string_add(
6864 json_out
, "mpNexthopGlobalIn",
6867 &attr
->mp_nexthop_global
,
6873 &attr
->mp_nexthop_global
,
6875 } else if (attr
->mp_nexthop_len
6876 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) {
6879 &attr
->mp_nexthop_global
,
6882 &attr
->mp_nexthop_local
,
6884 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6885 json_object_string_add(
6887 "mpNexthopGlobalLocal", buf_c
);
6889 vty_out(vty
, "%s(%s)",
6892 &attr
->mp_nexthop_global
,
6896 &attr
->mp_nexthop_local
,
6902 label
= decode_label(&binfo
->extra
->label
[0]);
6904 if (bgp_is_valid_label(&label
)) {
6906 json_object_int_add(json_out
, "notag", label
);
6907 json_object_array_add(json
, json_out
);
6909 vty_out(vty
, "notag/%d", label
);
6915 void route_vty_out_overlay(struct vty
*vty
, struct prefix
*p
,
6916 struct bgp_info
*binfo
, int display
,
6917 json_object
*json_paths
)
6921 json_object
*json_path
= NULL
;
6924 json_path
= json_object_new_object();
6929 /* short status lead text */
6930 route_vty_short_status_out(vty
, binfo
, json_path
);
6932 /* print prefix and mask */
6934 route_vty_out_route(p
, vty
, NULL
);
6936 vty_out(vty
, "%*s", 17, " ");
6938 /* Print attribute */
6942 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
6946 vty_out(vty
, "%-16s",
6947 inet_ntop(af
, &attr
->mp_nexthop_global_in
, buf
,
6951 vty_out(vty
, "%s(%s)",
6952 inet_ntop(af
, &attr
->mp_nexthop_global
, buf
,
6954 inet_ntop(af
, &attr
->mp_nexthop_local
, buf1
,
6962 struct eth_segment_id
*id
= &(attr
->evpn_overlay
.eth_s_id
);
6963 char *str
= esi2str(id
);
6964 vty_out(vty
, "%s", str
);
6965 XFREE(MTYPE_TMP
, str
);
6966 if (IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn
*)p
)) {
6967 vty_out(vty
, "/%s", inet_ntoa(attr
->evpn_overlay
.gw_ip
.ipv4
));
6968 } else if (IS_EVPN_PREFIX_IPADDR_V6((struct prefix_evpn
*)p
)) {
6970 inet_ntop(AF_INET6
, &(attr
->evpn_overlay
.gw_ip
.ipv6
),
6973 if (attr
->ecommunity
) {
6975 struct ecommunity_val
*routermac
= ecommunity_lookup(
6976 attr
->ecommunity
, ECOMMUNITY_ENCODE_EVPN
,
6977 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC
);
6979 mac
= ecom_mac2str((char *)routermac
->val
);
6981 vty_out(vty
, "/%s", (char *)mac
);
6982 XFREE(MTYPE_TMP
, mac
);
6988 /* dampening route */
6989 static void damp_route_vty_out(struct vty
*vty
, struct prefix
*p
,
6990 struct bgp_info
*binfo
, int display
, safi_t safi
,
6991 u_char use_json
, json_object
*json
)
6995 char timebuf
[BGP_UPTIME_LEN
];
6997 /* short status lead text */
6998 route_vty_short_status_out(vty
, binfo
, json
);
7000 /* print prefix and mask */
7003 route_vty_out_route(p
, vty
, NULL
);
7005 vty_out(vty
, "%*s", 17, " ");
7008 len
= vty_out(vty
, "%s", binfo
->peer
->host
);
7012 vty_out(vty
, "\n%*s", 34, " ");
7015 json_object_int_add(json
, "peerHost", len
);
7017 vty_out(vty
, "%*s", len
, " ");
7021 bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
, BGP_UPTIME_LEN
,
7024 vty_out(vty
, "%s ", bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
,
7028 /* Print attribute */
7034 json_object_string_add(json
, "asPath",
7037 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7042 json_object_string_add(json
, "origin",
7043 bgp_origin_str
[attr
->origin
]);
7045 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7052 static void flap_route_vty_out(struct vty
*vty
, struct prefix
*p
,
7053 struct bgp_info
*binfo
, int display
, safi_t safi
,
7054 u_char use_json
, json_object
*json
)
7057 struct bgp_damp_info
*bdi
;
7058 char timebuf
[BGP_UPTIME_LEN
];
7064 bdi
= binfo
->extra
->damp_info
;
7066 /* short status lead text */
7067 route_vty_short_status_out(vty
, binfo
, json
);
7069 /* print prefix and mask */
7072 route_vty_out_route(p
, vty
, NULL
);
7074 vty_out(vty
, "%*s", 17, " ");
7077 len
= vty_out(vty
, "%s", binfo
->peer
->host
);
7081 vty_out(vty
, "\n%*s", 33, " ");
7084 json_object_int_add(json
, "peerHost", len
);
7086 vty_out(vty
, "%*s", len
, " ");
7089 len
= vty_out(vty
, "%d", bdi
->flap
);
7096 json_object_int_add(json
, "bdiFlap", len
);
7098 vty_out(vty
, "%*s", len
, " ");
7102 peer_uptime(bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
,
7105 vty_out(vty
, "%s ", peer_uptime(bdi
->start_time
, timebuf
,
7106 BGP_UPTIME_LEN
, 0, NULL
));
7108 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
)
7109 && !CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
)) {
7111 bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
,
7112 BGP_UPTIME_LEN
, use_json
, json
);
7115 bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
,
7120 vty_out(vty
, "%*s ", 8, " ");
7123 /* Print attribute */
7129 json_object_string_add(json
, "asPath",
7132 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7137 json_object_string_add(json
, "origin",
7138 bgp_origin_str
[attr
->origin
]);
7140 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7146 static void route_vty_out_advertised_to(struct vty
*vty
, struct peer
*peer
,
7147 int *first
, const char *header
,
7148 json_object
*json_adv_to
)
7150 char buf1
[INET6_ADDRSTRLEN
];
7151 json_object
*json_peer
= NULL
;
7154 /* 'advertised-to' is a dictionary of peers we have advertised
7156 * prefix too. The key is the peer's IP or swpX, the value is
7158 * hostname if we know it and "" if not.
7160 json_peer
= json_object_new_object();
7163 json_object_string_add(json_peer
, "hostname",
7167 json_object_object_add(json_adv_to
, peer
->conf_if
,
7170 json_object_object_add(
7172 sockunion2str(&peer
->su
, buf1
, SU_ADDRSTRLEN
),
7176 vty_out(vty
, "%s", header
);
7181 && bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
)) {
7183 vty_out(vty
, " %s(%s)", peer
->hostname
,
7186 vty_out(vty
, " %s(%s)", peer
->hostname
,
7187 sockunion2str(&peer
->su
, buf1
,
7191 vty_out(vty
, " %s", peer
->conf_if
);
7194 sockunion2str(&peer
->su
, buf1
,
7200 void route_vty_out_detail(struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
7201 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
7202 json_object
*json_paths
)
7204 char buf
[INET6_ADDRSTRLEN
];
7206 #if defined(HAVE_CUMULUS)
7207 char buf2
[EVPN_ROUTE_STRLEN
];
7210 int sockunion_vty_out(struct vty
*, union sockunion
*);
7212 json_object
*json_bestpath
= NULL
;
7213 json_object
*json_cluster_list
= NULL
;
7214 json_object
*json_cluster_list_list
= NULL
;
7215 json_object
*json_ext_community
= NULL
;
7216 json_object
*json_lcommunity
= NULL
;
7217 json_object
*json_last_update
= NULL
;
7218 json_object
*json_pmsi
= NULL
;
7219 json_object
*json_nexthop_global
= NULL
;
7220 json_object
*json_nexthop_ll
= NULL
;
7221 json_object
*json_nexthops
= NULL
;
7222 json_object
*json_path
= NULL
;
7223 json_object
*json_peer
= NULL
;
7224 json_object
*json_string
= NULL
;
7225 json_object
*json_adv_to
= NULL
;
7227 struct listnode
*node
, *nnode
;
7229 int addpath_capable
;
7231 unsigned int first_as
;
7234 json_path
= json_object_new_object();
7235 json_peer
= json_object_new_object();
7236 json_nexthop_global
= json_object_new_object();
7239 #if defined(HAVE_CUMULUS)
7240 if (!json_paths
&& safi
== SAFI_EVPN
) {
7243 bgp_evpn_route2str((struct prefix_evpn
*)p
, buf2
, sizeof(buf2
));
7244 vty_out(vty
, " Route %s", buf2
);
7246 if (binfo
->extra
&& binfo
->extra
->num_labels
) {
7247 bgp_evpn_label2str(binfo
->extra
->label
,
7248 binfo
->extra
->num_labels
, tag_buf
,
7250 vty_out(vty
, " VNI %s", tag_buf
);
7253 if (binfo
->extra
&& binfo
->extra
->parent
) {
7254 struct bgp_info
*parent_ri
;
7255 struct bgp_node
*rn
, *prn
;
7257 parent_ri
= (struct bgp_info
*)binfo
->extra
->parent
;
7258 rn
= parent_ri
->net
;
7259 if (rn
&& rn
->prn
) {
7261 vty_out(vty
, " Imported from %s:%s\n",
7263 (struct prefix_rd
*)&prn
->p
,
7264 buf1
, sizeof(buf1
)),
7274 /* Line1 display AS-path, Aggregator */
7277 if (!attr
->aspath
->json
)
7278 aspath_str_update(attr
->aspath
, true);
7279 json_object_lock(attr
->aspath
->json
);
7280 json_object_object_add(json_path
, "aspath",
7281 attr
->aspath
->json
);
7283 if (attr
->aspath
->segments
)
7284 aspath_print_vty(vty
, " %s",
7287 vty_out(vty
, " Local");
7291 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_REMOVED
)) {
7293 json_object_boolean_true_add(json_path
,
7296 vty_out(vty
, ", (removed)");
7299 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_STALE
)) {
7301 json_object_boolean_true_add(json_path
,
7304 vty_out(vty
, ", (stale)");
7307 if (CHECK_FLAG(attr
->flag
,
7308 ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR
))) {
7310 json_object_int_add(json_path
, "aggregatorAs",
7311 attr
->aggregator_as
);
7312 json_object_string_add(
7313 json_path
, "aggregatorId",
7314 inet_ntoa(attr
->aggregator_addr
));
7316 vty_out(vty
, ", (aggregated by %u %s)",
7317 attr
->aggregator_as
,
7318 inet_ntoa(attr
->aggregator_addr
));
7322 if (CHECK_FLAG(binfo
->peer
->af_flags
[afi
][safi
],
7323 PEER_FLAG_REFLECTOR_CLIENT
)) {
7325 json_object_boolean_true_add(
7326 json_path
, "rxedFromRrClient");
7328 vty_out(vty
, ", (Received from a RR-client)");
7331 if (CHECK_FLAG(binfo
->peer
->af_flags
[afi
][safi
],
7332 PEER_FLAG_RSERVER_CLIENT
)) {
7334 json_object_boolean_true_add(
7335 json_path
, "rxedFromRsClient");
7337 vty_out(vty
, ", (Received from a RS-client)");
7340 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
)) {
7342 json_object_boolean_true_add(
7343 json_path
, "dampeningHistoryEntry");
7345 vty_out(vty
, ", (history entry)");
7346 } else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
)) {
7348 json_object_boolean_true_add(
7349 json_path
, "dampeningSuppressed");
7351 vty_out(vty
, ", (suppressed due to dampening)");
7357 /* Line2 display Next-hop, Neighbor, Router-id */
7358 /* Display the nexthop */
7359 if ((p
->family
== AF_INET
|| p
->family
== AF_ETHERNET
7360 || p
->family
== AF_EVPN
)
7361 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7362 || safi
== SAFI_EVPN
7363 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7364 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7365 || safi
== SAFI_EVPN
) {
7367 json_object_string_add(
7368 json_nexthop_global
, "ip",
7370 attr
->mp_nexthop_global_in
));
7374 attr
->mp_nexthop_global_in
));
7377 json_object_string_add(
7378 json_nexthop_global
, "ip",
7379 inet_ntoa(attr
->nexthop
));
7382 inet_ntoa(attr
->nexthop
));
7386 json_object_string_add(json_nexthop_global
,
7390 json_object_string_add(
7391 json_nexthop_global
, "ip",
7393 &attr
->mp_nexthop_global
, buf
,
7395 json_object_string_add(json_nexthop_global
,
7397 json_object_string_add(json_nexthop_global
,
7402 &attr
->mp_nexthop_global
, buf
,
7407 /* Display the IGP cost or 'inaccessible' */
7408 if (!CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)) {
7410 json_object_boolean_false_add(
7411 json_nexthop_global
, "accessible");
7413 vty_out(vty
, " (inaccessible)");
7415 if (binfo
->extra
&& binfo
->extra
->igpmetric
) {
7417 json_object_int_add(
7418 json_nexthop_global
, "metric",
7419 binfo
->extra
->igpmetric
);
7421 vty_out(vty
, " (metric %u)",
7422 binfo
->extra
->igpmetric
);
7425 /* IGP cost is 0, display this only for json */
7428 json_object_int_add(json_nexthop_global
,
7433 json_object_boolean_true_add(
7434 json_nexthop_global
, "accessible");
7437 /* Display peer "from" output */
7438 /* This path was originated locally */
7439 if (binfo
->peer
== bgp
->peer_self
) {
7441 if (safi
== SAFI_EVPN
7442 || (p
->family
== AF_INET
7443 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7445 json_object_string_add(
7446 json_peer
, "peerId", "0.0.0.0");
7448 vty_out(vty
, " from 0.0.0.0 ");
7451 json_object_string_add(json_peer
,
7454 vty_out(vty
, " from :: ");
7458 json_object_string_add(
7459 json_peer
, "routerId",
7460 inet_ntoa(bgp
->router_id
));
7462 vty_out(vty
, "(%s)", inet_ntoa(bgp
->router_id
));
7465 /* We RXed this path from one of our peers */
7469 json_object_string_add(
7470 json_peer
, "peerId",
7471 sockunion2str(&binfo
->peer
->su
, buf
,
7473 json_object_string_add(
7474 json_peer
, "routerId",
7476 &binfo
->peer
->remote_id
, buf1
,
7479 if (binfo
->peer
->hostname
)
7480 json_object_string_add(
7481 json_peer
, "hostname",
7482 binfo
->peer
->hostname
);
7484 if (binfo
->peer
->domainname
)
7485 json_object_string_add(
7486 json_peer
, "domainname",
7487 binfo
->peer
->domainname
);
7489 if (binfo
->peer
->conf_if
)
7490 json_object_string_add(
7491 json_peer
, "interface",
7492 binfo
->peer
->conf_if
);
7494 if (binfo
->peer
->conf_if
) {
7495 if (binfo
->peer
->hostname
7498 BGP_FLAG_SHOW_HOSTNAME
))
7499 vty_out(vty
, " from %s(%s)",
7500 binfo
->peer
->hostname
,
7501 binfo
->peer
->conf_if
);
7503 vty_out(vty
, " from %s",
7504 binfo
->peer
->conf_if
);
7506 if (binfo
->peer
->hostname
7509 BGP_FLAG_SHOW_HOSTNAME
))
7510 vty_out(vty
, " from %s(%s)",
7511 binfo
->peer
->hostname
,
7514 vty_out(vty
, " from %s",
7523 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7524 vty_out(vty
, " (%s)",
7525 inet_ntoa(attr
->originator_id
));
7527 vty_out(vty
, " (%s)",
7530 &binfo
->peer
->remote_id
,
7531 buf1
, sizeof(buf1
)));
7538 /* display the link-local nexthop */
7539 if (attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) {
7541 json_nexthop_ll
= json_object_new_object();
7542 json_object_string_add(
7543 json_nexthop_ll
, "ip",
7545 &attr
->mp_nexthop_local
, buf
,
7547 json_object_string_add(json_nexthop_ll
, "afi",
7549 json_object_string_add(json_nexthop_ll
, "scope",
7552 json_object_boolean_true_add(json_nexthop_ll
,
7555 if (!attr
->mp_nexthop_prefer_global
)
7556 json_object_boolean_true_add(
7557 json_nexthop_ll
, "used");
7559 json_object_boolean_true_add(
7560 json_nexthop_global
, "used");
7562 vty_out(vty
, " (%s) %s\n",
7564 &attr
->mp_nexthop_local
, buf
,
7566 attr
->mp_nexthop_prefer_global
7571 /* If we do not have a link-local nexthop then we must flag the
7575 json_object_boolean_true_add(
7576 json_nexthop_global
, "used");
7579 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
7580 * Int/Ext/Local, Atomic, best */
7582 json_object_string_add(
7583 json_path
, "origin",
7584 bgp_origin_long_str
[attr
->origin
]);
7586 vty_out(vty
, " Origin %s",
7587 bgp_origin_long_str
[attr
->origin
]);
7589 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)) {
7591 json_object_int_add(json_path
, "med",
7594 vty_out(vty
, ", metric %u", attr
->med
);
7597 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
7599 json_object_int_add(json_path
, "localpref",
7602 vty_out(vty
, ", localpref %u",
7606 json_object_int_add(json_path
, "localpref",
7607 bgp
->default_local_pref
);
7609 vty_out(vty
, ", localpref %u",
7610 bgp
->default_local_pref
);
7613 if (attr
->weight
!= 0) {
7615 json_object_int_add(json_path
, "weight",
7618 vty_out(vty
, ", weight %u", attr
->weight
);
7621 if (attr
->tag
!= 0) {
7623 json_object_int_add(json_path
, "tag",
7626 vty_out(vty
, ", tag %" ROUTE_TAG_PRI
,
7630 if (!CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)) {
7632 json_object_boolean_false_add(json_path
,
7635 vty_out(vty
, ", invalid");
7636 } else if (!CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
)) {
7638 json_object_boolean_true_add(json_path
,
7641 vty_out(vty
, ", valid");
7644 if (binfo
->peer
!= bgp
->peer_self
) {
7645 if (binfo
->peer
->as
== binfo
->peer
->local_as
) {
7646 if (CHECK_FLAG(bgp
->config
,
7647 BGP_CONFIG_CONFEDERATION
)) {
7649 json_object_string_add(
7654 ", confed-internal");
7657 json_object_string_add(
7661 vty_out(vty
, ", internal");
7664 if (bgp_confederation_peers_check(
7665 bgp
, binfo
->peer
->as
)) {
7667 json_object_string_add(
7672 ", confed-external");
7675 json_object_string_add(
7679 vty_out(vty
, ", external");
7682 } else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
) {
7684 json_object_boolean_true_add(json_path
,
7686 json_object_boolean_true_add(json_path
,
7689 vty_out(vty
, ", aggregated, local");
7691 } else if (binfo
->type
!= ZEBRA_ROUTE_BGP
) {
7693 json_object_boolean_true_add(json_path
,
7696 vty_out(vty
, ", sourced");
7699 json_object_boolean_true_add(json_path
,
7701 json_object_boolean_true_add(json_path
,
7704 vty_out(vty
, ", sourced, local");
7708 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
)) {
7710 json_object_boolean_true_add(json_path
,
7713 vty_out(vty
, ", atomic-aggregate");
7716 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_MULTIPATH
)
7717 || (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
)
7718 && bgp_info_mpath_count(binfo
))) {
7720 json_object_boolean_true_add(json_path
,
7723 vty_out(vty
, ", multipath");
7726 // Mark the bestpath(s)
7727 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DMED_SELECTED
)) {
7728 first_as
= aspath_get_first_as(attr
->aspath
);
7733 json_object_new_object();
7734 json_object_int_add(json_bestpath
,
7735 "bestpathFromAs", first_as
);
7738 vty_out(vty
, ", bestpath-from-AS %u",
7742 ", bestpath-from-AS Local");
7746 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
)) {
7750 json_object_new_object();
7751 json_object_boolean_true_add(json_bestpath
,
7754 vty_out(vty
, ", best");
7758 json_object_object_add(json_path
, "bestpath",
7764 /* Line 4 display Community */
7765 if (attr
->community
) {
7767 if (!attr
->community
->json
)
7768 community_str(attr
->community
, true);
7769 json_object_lock(attr
->community
->json
);
7770 json_object_object_add(json_path
, "community",
7771 attr
->community
->json
);
7773 vty_out(vty
, " Community: %s\n",
7774 attr
->community
->str
);
7778 /* Line 5 display Extended-community */
7779 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)) {
7781 json_ext_community
= json_object_new_object();
7782 json_object_string_add(json_ext_community
,
7784 attr
->ecommunity
->str
);
7785 json_object_object_add(json_path
,
7786 "extendedCommunity",
7787 json_ext_community
);
7789 vty_out(vty
, " Extended Community: %s\n",
7790 attr
->ecommunity
->str
);
7794 /* Line 6 display Large community */
7795 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
)) {
7797 json_lcommunity
= json_object_new_object();
7798 json_object_string_add(json_lcommunity
,
7800 attr
->lcommunity
->str
);
7801 json_object_object_add(json_path
,
7805 vty_out(vty
, " Large Community: %s\n",
7806 attr
->lcommunity
->str
);
7810 /* Line 7 display Originator, Cluster-id */
7811 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7812 || (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))) {
7814 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) {
7816 json_object_string_add(
7817 json_path
, "originatorId",
7818 inet_ntoa(attr
->originator_id
));
7820 vty_out(vty
, " Originator: %s",
7821 inet_ntoa(attr
->originator_id
));
7824 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)) {
7829 json_object_new_object();
7830 json_cluster_list_list
=
7831 json_object_new_array();
7834 i
< attr
->cluster
->length
/ 4;
7836 json_string
= json_object_new_string(
7840 json_object_array_add(
7841 json_cluster_list_list
,
7845 /* struct cluster_list does not have
7847 * aspath and community do. Add this
7850 json_object_string_add(json_cluster_list,
7851 "string", attr->cluster->str);
7853 json_object_object_add(
7854 json_cluster_list
, "list",
7855 json_cluster_list_list
);
7856 json_object_object_add(
7857 json_path
, "clusterList",
7860 vty_out(vty
, ", Cluster list: ");
7863 i
< attr
->cluster
->length
/ 4;
7877 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7878 bgp_damp_info_vty(vty
, binfo
, json_path
);
7881 #if defined(HAVE_CUMULUS)
7882 if (binfo
->extra
&& bgp_is_valid_label(&binfo
->extra
->label
[0])
7883 && safi
!= SAFI_EVPN
)
7885 if (binfo
->extra
&& bgp_is_valid_label(&binfo
->extra
->label
[0]))
7888 mpls_label_t label
=
7889 label_pton(&binfo
->extra
->label
[0]);
7891 json_object_int_add(json_path
, "remoteLabel",
7894 vty_out(vty
, " Remote label: %d\n", label
);
7898 if (attr
->label_index
!= BGP_INVALID_LABEL_INDEX
) {
7900 json_object_int_add(json_path
, "labelIndex",
7903 vty_out(vty
, " Label Index: %d\n",
7907 /* Line 8 display Addpath IDs */
7908 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
) {
7910 json_object_int_add(json_path
, "addpathRxId",
7911 binfo
->addpath_rx_id
);
7912 json_object_int_add(json_path
, "addpathTxId",
7913 binfo
->addpath_tx_id
);
7915 vty_out(vty
, " AddPath ID: RX %u, TX %u\n",
7916 binfo
->addpath_rx_id
,
7917 binfo
->addpath_tx_id
);
7921 /* If we used addpath to TX a non-bestpath we need to display
7922 * "Advertised to" on a path-by-path basis */
7923 if (bgp
->addpath_tx_used
[afi
][safi
]) {
7926 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7928 bgp_addpath_encode_tx(peer
, afi
, safi
);
7929 has_adj
= bgp_adj_out_lookup(
7930 peer
, binfo
->net
, binfo
->addpath_tx_id
);
7932 if ((addpath_capable
&& has_adj
)
7933 || (!addpath_capable
&& has_adj
7934 && CHECK_FLAG(binfo
->flags
,
7935 BGP_INFO_SELECTED
))) {
7936 if (json_path
&& !json_adv_to
)
7938 json_object_new_object();
7940 route_vty_out_advertised_to(
7949 json_object_object_add(json_path
,
7960 /* Line 9 display Uptime */
7961 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7963 json_last_update
= json_object_new_object();
7964 json_object_int_add(json_last_update
, "epoch", tbuf
);
7965 json_object_string_add(json_last_update
, "string",
7967 json_object_object_add(json_path
, "lastUpdate",
7970 vty_out(vty
, " Last update: %s", ctime(&tbuf
));
7972 /* Line 10 display PMSI tunnel attribute, if present */
7973 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL
)) {
7974 const char *str
= lookup_msg(bgp_pmsi_tnltype_str
,
7975 attr
->pmsi_tnl_type
,
7976 PMSI_TNLTYPE_STR_DEFAULT
);
7979 json_pmsi
= json_object_new_object();
7980 json_object_string_add(json_pmsi
,
7982 json_object_object_add(json_path
, "pmsi",
7985 vty_out(vty
, " PMSI Tunnel Type: %s\n",
7991 /* We've constructed the json object for this path, add it to the json
7995 if (json_nexthop_global
|| json_nexthop_ll
) {
7996 json_nexthops
= json_object_new_array();
7998 if (json_nexthop_global
)
7999 json_object_array_add(json_nexthops
,
8000 json_nexthop_global
);
8002 if (json_nexthop_ll
)
8003 json_object_array_add(json_nexthops
,
8006 json_object_object_add(json_path
, "nexthops",
8010 json_object_object_add(json_path
, "peer", json_peer
);
8011 json_object_array_add(json_paths
, json_path
);
8016 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
8017 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
8018 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
8020 static int bgp_show_prefix_list(struct vty
*vty
, struct bgp
*bgp
,
8021 const char *prefix_list_str
, afi_t afi
,
8022 safi_t safi
, enum bgp_show_type type
);
8023 static int bgp_show_filter_list(struct vty
*vty
, struct bgp
*bgp
,
8024 const char *filter
, afi_t afi
, safi_t safi
,
8025 enum bgp_show_type type
);
8026 static int bgp_show_route_map(struct vty
*vty
, struct bgp
*bgp
,
8027 const char *rmap_str
, afi_t afi
, safi_t safi
,
8028 enum bgp_show_type type
);
8029 static int bgp_show_community_list(struct vty
*vty
, struct bgp
*bgp
,
8030 const char *com
, int exact
, afi_t afi
,
8032 static int bgp_show_prefix_longer(struct vty
*vty
, struct bgp
*bgp
,
8033 const char *prefix
, afi_t afi
, safi_t safi
,
8034 enum bgp_show_type type
);
8035 static int bgp_show_regexp(struct vty
*vty
, struct bgp
*bgp
, const char *regstr
,
8036 afi_t afi
, safi_t safi
, enum bgp_show_type type
);
8037 static int bgp_show_community(struct vty
*vty
, struct bgp
*bgp
,
8038 const char *comstr
, int exact
, afi_t afi
,
8042 static int bgp_show_table(struct vty
*vty
, struct bgp
*bgp
, safi_t safi
,
8043 struct bgp_table
*table
, enum bgp_show_type type
,
8044 void *output_arg
, u_char use_json
, char *rd
,
8045 int is_last
, unsigned long *output_cum
,
8046 unsigned long *total_cum
,
8047 unsigned long *json_header_depth
)
8049 struct bgp_info
*ri
;
8050 struct bgp_node
*rn
;
8053 unsigned long output_count
= 0;
8054 unsigned long total_count
= 0;
8058 json_object
*json_paths
= NULL
;
8061 if (output_cum
&& *output_cum
!= 0)
8064 if (use_json
&& !*json_header_depth
) {
8066 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
8067 ",\n \"routerId\": \"%s\",\n \"routes\": { ",
8068 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : (int)bgp
->vrf_id
,
8069 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default"
8071 table
->version
, inet_ntoa(bgp
->router_id
));
8072 *json_header_depth
= 2;
8074 vty_out(vty
, " \"routeDistinguishers\" : {");
8075 ++*json_header_depth
;
8077 json_paths
= json_object_new_object();
8080 if (use_json
&& rd
) {
8081 vty_out(vty
, " \"%s\" : { ", rd
);
8084 /* Start processing of routes. */
8085 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
8086 if (rn
->info
== NULL
)
8091 json_paths
= json_object_new_array();
8095 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
8097 if (type
== bgp_show_type_flap_statistics
8098 || type
== bgp_show_type_flap_neighbor
8099 || type
== bgp_show_type_dampend_paths
8100 || type
== bgp_show_type_damp_neighbor
) {
8101 if (!(ri
->extra
&& ri
->extra
->damp_info
))
8104 if (type
== bgp_show_type_regexp
) {
8105 regex_t
*regex
= output_arg
;
8107 if (bgp_regexec(regex
, ri
->attr
->aspath
)
8111 if (type
== bgp_show_type_prefix_list
) {
8112 struct prefix_list
*plist
= output_arg
;
8114 if (prefix_list_apply(plist
, &rn
->p
)
8118 if (type
== bgp_show_type_filter_list
) {
8119 struct as_list
*as_list
= output_arg
;
8121 if (as_list_apply(as_list
, ri
->attr
->aspath
)
8122 != AS_FILTER_PERMIT
)
8125 if (type
== bgp_show_type_route_map
) {
8126 struct route_map
*rmap
= output_arg
;
8127 struct bgp_info binfo
;
8128 struct attr dummy_attr
;
8131 bgp_attr_dup(&dummy_attr
, ri
->attr
);
8133 binfo
.peer
= ri
->peer
;
8134 binfo
.attr
= &dummy_attr
;
8136 ret
= route_map_apply(rmap
, &rn
->p
, RMAP_BGP
,
8138 if (ret
== RMAP_DENYMATCH
)
8141 if (type
== bgp_show_type_neighbor
8142 || type
== bgp_show_type_flap_neighbor
8143 || type
== bgp_show_type_damp_neighbor
) {
8144 union sockunion
*su
= output_arg
;
8146 if (ri
->peer
== NULL
8147 || ri
->peer
->su_remote
== NULL
8148 || !sockunion_same(ri
->peer
->su_remote
, su
))
8151 if (type
== bgp_show_type_cidr_only
) {
8152 u_int32_t destination
;
8154 destination
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
8155 if (IN_CLASSC(destination
)
8156 && rn
->p
.prefixlen
== 24)
8158 if (IN_CLASSB(destination
)
8159 && rn
->p
.prefixlen
== 16)
8161 if (IN_CLASSA(destination
)
8162 && rn
->p
.prefixlen
== 8)
8165 if (type
== bgp_show_type_prefix_longer
) {
8166 struct prefix
*p
= output_arg
;
8168 if (!prefix_match(p
, &rn
->p
))
8171 if (type
== bgp_show_type_community_all
) {
8172 if (!ri
->attr
->community
)
8175 if (type
== bgp_show_type_community
) {
8176 struct community
*com
= output_arg
;
8178 if (!ri
->attr
->community
8179 || !community_match(ri
->attr
->community
,
8183 if (type
== bgp_show_type_community_exact
) {
8184 struct community
*com
= output_arg
;
8186 if (!ri
->attr
->community
8187 || !community_cmp(ri
->attr
->community
, com
))
8190 if (type
== bgp_show_type_community_list
) {
8191 struct community_list
*list
= output_arg
;
8193 if (!community_list_match(ri
->attr
->community
,
8197 if (type
== bgp_show_type_community_list_exact
) {
8198 struct community_list
*list
= output_arg
;
8200 if (!community_list_exact_match(
8201 ri
->attr
->community
, list
))
8204 if (type
== bgp_show_type_lcommunity
) {
8205 struct lcommunity
*lcom
= output_arg
;
8207 if (!ri
->attr
->lcommunity
8208 || !lcommunity_match(ri
->attr
->lcommunity
,
8212 if (type
== bgp_show_type_lcommunity_list
) {
8213 struct community_list
*list
= output_arg
;
8215 if (!lcommunity_list_match(ri
->attr
->lcommunity
,
8219 if (type
== bgp_show_type_lcommunity_all
) {
8220 if (!ri
->attr
->lcommunity
)
8223 if (type
== bgp_show_type_dampend_paths
8224 || type
== bgp_show_type_damp_neighbor
) {
8225 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_DAMPED
)
8226 || CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
8230 if (!use_json
&& header
) {
8231 vty_out(vty
, "BGP table version is %" PRIu64
8232 ", local router ID is %s\n",
8234 inet_ntoa(bgp
->router_id
));
8235 vty_out(vty
, BGP_SHOW_SCODE_HEADER
);
8236 vty_out(vty
, BGP_SHOW_OCODE_HEADER
);
8237 if (type
== bgp_show_type_dampend_paths
8238 || type
== bgp_show_type_damp_neighbor
)
8239 vty_out(vty
, BGP_SHOW_DAMP_HEADER
);
8240 else if (type
== bgp_show_type_flap_statistics
8241 || type
== bgp_show_type_flap_neighbor
)
8242 vty_out(vty
, BGP_SHOW_FLAP_HEADER
);
8244 vty_out(vty
, BGP_SHOW_HEADER
);
8247 if (rd
!= NULL
&& !display
&& !output_count
) {
8250 "Route Distinguisher: %s\n",
8253 if (type
== bgp_show_type_dampend_paths
8254 || type
== bgp_show_type_damp_neighbor
)
8255 damp_route_vty_out(vty
, &rn
->p
, ri
, display
,
8256 safi
, use_json
, json_paths
);
8257 else if (type
== bgp_show_type_flap_statistics
8258 || type
== bgp_show_type_flap_neighbor
)
8259 flap_route_vty_out(vty
, &rn
->p
, ri
, display
,
8260 safi
, use_json
, json_paths
);
8262 route_vty_out(vty
, &rn
->p
, ri
, display
, safi
,
8273 sprintf(buf2
, "%s/%d",
8274 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
8277 vty_out(vty
, "\"%s\": ", buf2
);
8279 vty_out(vty
, ",\"%s\": ", buf2
);
8282 json_object_to_json_string(json_paths
));
8283 json_object_free(json_paths
);
8290 output_count
+= *output_cum
;
8291 *output_cum
= output_count
;
8294 total_count
+= *total_cum
;
8295 *total_cum
= total_count
;
8299 json_object_free(json_paths
);
8301 vty_out(vty
, " }%s ", (is_last
? "" : ","));
8305 for (i
= 0; i
< *json_header_depth
; ++i
)
8306 vty_out(vty
, " } ");
8310 /* No route is displayed */
8311 if (output_count
== 0) {
8312 if (type
== bgp_show_type_normal
)
8314 "No BGP prefixes displayed, %ld exist\n",
8318 "\nDisplayed %ld routes and %ld total paths\n",
8319 output_count
, total_count
);
8326 int bgp_show_table_rd(struct vty
*vty
, struct bgp
*bgp
, safi_t safi
,
8327 struct bgp_table
*table
, struct prefix_rd
*prd_match
,
8328 enum bgp_show_type type
, void *output_arg
,
8331 struct bgp_node
*rn
, *next
;
8332 unsigned long output_cum
= 0;
8333 unsigned long total_cum
= 0;
8334 unsigned long json_header_depth
= 0;
8337 show_msg
= (!use_json
&& type
== bgp_show_type_normal
);
8339 for (rn
= bgp_table_top(table
); rn
; rn
= next
) {
8340 next
= bgp_route_next(rn
);
8341 if (prd_match
&& memcmp(rn
->p
.u
.val
, prd_match
->val
, 8) != 0)
8343 if (rn
->info
!= NULL
) {
8344 struct prefix_rd prd
;
8345 char rd
[RD_ADDRSTRLEN
];
8347 memcpy(&prd
, &(rn
->p
), sizeof(struct prefix_rd
));
8348 prefix_rd2str(&prd
, rd
, sizeof(rd
));
8349 bgp_show_table(vty
, bgp
, safi
, rn
->info
, type
,
8350 output_arg
, use_json
, rd
, next
== NULL
,
8351 &output_cum
, &total_cum
,
8352 &json_header_depth
);
8358 if (output_cum
== 0)
8359 vty_out(vty
, "No BGP prefixes displayed, %ld exist\n",
8363 "\nDisplayed %ld routes and %ld total paths\n",
8364 output_cum
, total_cum
);
8368 static int bgp_show(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
8369 enum bgp_show_type type
, void *output_arg
, u_char use_json
)
8371 struct bgp_table
*table
;
8372 unsigned long json_header_depth
= 0;
8375 bgp
= bgp_get_default();
8380 vty_out(vty
, "No BGP process is configured\n");
8382 vty_out(vty
, "{}\n");
8386 table
= bgp
->rib
[afi
][safi
];
8387 /* use MPLS and ENCAP specific shows until they are merged */
8388 if (safi
== SAFI_MPLS_VPN
) {
8389 return bgp_show_table_rd(vty
, bgp
, safi
, table
, NULL
, type
,
8390 output_arg
, use_json
);
8392 /* labeled-unicast routes live in the unicast table */
8393 else if (safi
== SAFI_LABELED_UNICAST
)
8394 safi
= SAFI_UNICAST
;
8396 return bgp_show_table(vty
, bgp
, safi
, table
, type
, output_arg
, use_json
,
8397 NULL
, 1, NULL
, NULL
, &json_header_depth
);
8400 static void bgp_show_all_instances_routes_vty(struct vty
*vty
, afi_t afi
,
8401 safi_t safi
, u_char use_json
)
8403 struct listnode
*node
, *nnode
;
8408 vty_out(vty
, "{\n");
8410 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
8413 vty_out(vty
, ",\n");
8417 vty_out(vty
, "\"%s\":",
8418 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8422 vty_out(vty
, "\nInstance %s:\n",
8423 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8427 bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_normal
, NULL
,
8432 vty_out(vty
, "}\n");
8435 /* Header of detailed BGP route information */
8436 void route_vty_out_detail_header(struct vty
*vty
, struct bgp
*bgp
,
8437 struct bgp_node
*rn
, struct prefix_rd
*prd
,
8438 afi_t afi
, safi_t safi
, json_object
*json
)
8440 struct bgp_info
*ri
;
8443 struct listnode
*node
, *nnode
;
8444 char buf1
[RD_ADDRSTRLEN
];
8445 char buf2
[INET6_ADDRSTRLEN
];
8446 #if defined(HAVE_CUMULUS)
8447 char buf3
[EVPN_ROUTE_STRLEN
];
8449 char prefix_str
[BUFSIZ
];
8454 int no_advertise
= 0;
8457 int has_valid_label
= 0;
8458 mpls_label_t label
= 0;
8459 json_object
*json_adv_to
= NULL
;
8462 has_valid_label
= bgp_is_valid_label(&rn
->local_label
);
8464 if (has_valid_label
)
8465 label
= label_pton(&rn
->local_label
);
8468 if (has_valid_label
)
8469 json_object_int_add(json
, "localLabel", label
);
8471 json_object_string_add(
8473 prefix2str(p
, prefix_str
, sizeof(prefix_str
)));
8475 #if defined(HAVE_CUMULUS)
8476 if (safi
== SAFI_EVPN
)
8477 vty_out(vty
, "BGP routing table entry for %s%s%s\n",
8478 prd
? prefix_rd2str(prd
, buf1
, sizeof(buf1
))
8481 bgp_evpn_route2str((struct prefix_evpn
*)p
,
8482 buf3
, sizeof(buf3
)));
8484 vty_out(vty
, "BGP routing table entry for %s%s%s/%d\n",
8485 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
8486 ? prefix_rd2str(prd
, buf1
,
8489 safi
== SAFI_MPLS_VPN
? ":" : "",
8490 inet_ntop(p
->family
, &p
->u
.prefix
, buf2
,
8494 if (p
->family
== AF_ETHERNET
)
8495 prefix2str(p
, buf2
, INET6_ADDRSTRLEN
);
8497 inet_ntop(p
->family
, &p
->u
.prefix
, buf2
,
8499 vty_out(vty
, "BGP routing table entry for %s%s%s/%d\n",
8500 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
8501 || safi
== SAFI_EVPN
)
8502 ? prefix_rd2str(prd
, buf1
, sizeof(buf1
))
8504 ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
)) ? ":"
8506 buf2
, p
->prefixlen
);
8509 if (has_valid_label
)
8510 vty_out(vty
, "Local label: %d\n", label
);
8511 #if defined(HAVE_CUMULUS)
8512 if (bgp_labeled_safi(safi
) && safi
!= SAFI_EVPN
)
8514 if (bgp_labeled_safi(safi
))
8516 vty_out(vty
, "not allocated\n");
8519 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
8521 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
8523 if (ri
->extra
&& ri
->extra
->suppress
)
8525 if (ri
->attr
->community
!= NULL
) {
8526 if (community_include(ri
->attr
->community
,
8527 COMMUNITY_NO_ADVERTISE
))
8529 if (community_include(ri
->attr
->community
,
8530 COMMUNITY_NO_EXPORT
))
8532 if (community_include(ri
->attr
->community
,
8533 COMMUNITY_LOCAL_AS
))
8540 vty_out(vty
, "Paths: (%d available", count
);
8542 vty_out(vty
, ", best #%d", best
);
8543 if (safi
== SAFI_UNICAST
)
8544 vty_out(vty
, ", table %s",
8546 == BGP_INSTANCE_TYPE_DEFAULT
)
8547 ? "Default-IP-Routing-Table"
8550 vty_out(vty
, ", no best path");
8553 vty_out(vty
, ", not advertised to any peer");
8555 vty_out(vty
, ", not advertised to EBGP peer");
8557 vty_out(vty
, ", not advertised outside local AS");
8561 ", Advertisements suppressed by an aggregate.");
8562 vty_out(vty
, ")\n");
8565 /* If we are not using addpath then we can display Advertised to and
8567 * show what peers we advertised the bestpath to. If we are using
8569 * though then we must display Advertised to on a path-by-path basis. */
8570 if (!bgp
->addpath_tx_used
[afi
][safi
]) {
8571 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
8572 if (bgp_adj_out_lookup(peer
, rn
, 0)) {
8573 if (json
&& !json_adv_to
)
8574 json_adv_to
= json_object_new_object();
8576 route_vty_out_advertised_to(
8578 " Advertised to non peer-group peers:\n ",
8585 json_object_object_add(json
, "advertisedTo",
8590 vty_out(vty
, " Not advertised to any peer");
8596 /* Display specified route of BGP table. */
8597 static int bgp_show_route_in_table(struct vty
*vty
, struct bgp
*bgp
,
8598 struct bgp_table
*rib
, const char *ip_str
,
8599 afi_t afi
, safi_t safi
,
8600 struct prefix_rd
*prd
, int prefix_check
,
8601 enum bgp_path_type pathtype
, u_char use_json
)
8606 struct prefix match
;
8607 struct bgp_node
*rn
;
8608 struct bgp_node
*rm
;
8609 struct bgp_info
*ri
;
8610 struct bgp_table
*table
;
8611 json_object
*json
= NULL
;
8612 json_object
*json_paths
= NULL
;
8614 /* Check IP address argument. */
8615 ret
= str2prefix(ip_str
, &match
);
8617 vty_out(vty
, "address is malformed\n");
8621 match
.family
= afi2family(afi
);
8624 json
= json_object_new_object();
8625 json_paths
= json_object_new_array();
8628 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) {
8629 for (rn
= bgp_table_top(rib
); rn
; rn
= bgp_route_next(rn
)) {
8630 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
8633 if ((table
= rn
->info
) == NULL
)
8638 if ((rm
= bgp_node_match(table
, &match
)) == NULL
)
8642 && rm
->p
.prefixlen
!= match
.prefixlen
) {
8643 bgp_unlock_node(rm
);
8647 for (ri
= rm
->info
; ri
; ri
= ri
->next
) {
8649 route_vty_out_detail_header(
8651 (struct prefix_rd
*)&rn
->p
,
8652 AFI_IP
, safi
, json
);
8657 if (pathtype
== BGP_PATH_ALL
8658 || (pathtype
== BGP_PATH_BESTPATH
8659 && CHECK_FLAG(ri
->flags
,
8661 || (pathtype
== BGP_PATH_MULTIPATH
8662 && (CHECK_FLAG(ri
->flags
,
8664 || CHECK_FLAG(ri
->flags
,
8665 BGP_INFO_SELECTED
))))
8666 route_vty_out_detail(vty
, bgp
, &rm
->p
,
8671 bgp_unlock_node(rm
);
8676 if ((rn
= bgp_node_match(rib
, &match
)) != NULL
) {
8678 || rn
->p
.prefixlen
== match
.prefixlen
) {
8679 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
8681 route_vty_out_detail_header(
8682 vty
, bgp
, rn
, NULL
, afi
,
8688 if (pathtype
== BGP_PATH_ALL
8689 || (pathtype
== BGP_PATH_BESTPATH
8693 || (pathtype
== BGP_PATH_MULTIPATH
8699 BGP_INFO_SELECTED
))))
8700 route_vty_out_detail(
8701 vty
, bgp
, &rn
->p
, ri
,
8702 afi
, safi
, json_paths
);
8706 bgp_unlock_node(rn
);
8712 json_object_object_add(json
, "paths", json_paths
);
8714 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8715 json
, JSON_C_TO_STRING_PRETTY
));
8716 json_object_free(json
);
8719 vty_out(vty
, "%% Network not in table\n");
8727 /* Display specified route of Main RIB */
8728 static int bgp_show_route(struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
8729 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8730 int prefix_check
, enum bgp_path_type pathtype
,
8734 bgp
= bgp_get_default();
8737 vty_out(vty
, "No BGP process is configured\n");
8739 vty_out(vty
, "{}\n");
8744 /* labeled-unicast routes live in the unicast table */
8745 if (safi
== SAFI_LABELED_UNICAST
)
8746 safi
= SAFI_UNICAST
;
8748 return bgp_show_route_in_table(vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
8749 afi
, safi
, prd
, prefix_check
, pathtype
,
8753 static int bgp_show_lcommunity(struct vty
*vty
, struct bgp
*bgp
, int argc
,
8754 struct cmd_token
**argv
, afi_t afi
, safi_t safi
,
8757 struct lcommunity
*lcom
;
8763 b
= buffer_new(1024);
8764 for (i
= 0; i
< argc
; i
++) {
8766 buffer_putc(b
, ' ');
8768 if (strmatch(argv
[i
]->text
, "AA:BB:CC")) {
8770 buffer_putstr(b
, argv
[i
]->arg
);
8774 buffer_putc(b
, '\0');
8776 str
= buffer_getstr(b
);
8779 lcom
= lcommunity_str2com(str
);
8780 XFREE(MTYPE_TMP
, str
);
8782 vty_out(vty
, "%% Large-community malformed\n");
8786 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
,
8790 static int bgp_show_lcommunity_list(struct vty
*vty
, struct bgp
*bgp
,
8791 const char *lcom
, afi_t afi
, safi_t safi
,
8794 struct community_list
*list
;
8796 list
= community_list_lookup(bgp_clist
, lcom
,
8797 LARGE_COMMUNITY_LIST_MASTER
);
8799 vty_out(vty
, "%% %s is not a valid large-community-list name\n",
8804 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
,
8808 DEFUN (show_ip_bgp_large_community_list
,
8809 show_ip_bgp_large_community_list_cmd
,
8810 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community-list <(1-500)|WORD> [json]",
8814 BGP_INSTANCE_HELP_STR
8816 BGP_SAFI_WITH_LABEL_HELP_STR
8817 "Display routes matching the large-community-list\n"
8818 "large-community-list number\n"
8819 "large-community-list name\n"
8823 afi_t afi
= AFI_IP6
;
8824 safi_t safi
= SAFI_UNICAST
;
8827 if (argv_find(argv
, argc
, "ip", &idx
))
8829 if (argv_find(argv
, argc
, "view", &idx
)
8830 || argv_find(argv
, argc
, "vrf", &idx
))
8831 vrf
= argv
[++idx
]->arg
;
8832 if (argv_find(argv
, argc
, "ipv4", &idx
)
8833 || argv_find(argv
, argc
, "ipv6", &idx
)) {
8834 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8835 if (argv_find(argv
, argc
, "unicast", &idx
)
8836 || argv_find(argv
, argc
, "multicast", &idx
))
8837 safi
= bgp_vty_safi_from_str(argv
[idx
]->text
);
8840 int uj
= use_json(argc
, argv
);
8842 struct bgp
*bgp
= bgp_lookup_by_name(vrf
);
8844 vty_out(vty
, "Can't find BGP instance %s\n", vrf
);
8848 argv_find(argv
, argc
, "large-community-list", &idx
);
8849 return bgp_show_lcommunity_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
,
8852 DEFUN (show_ip_bgp_large_community
,
8853 show_ip_bgp_large_community_cmd
,
8854 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community [AA:BB:CC] [json]",
8858 BGP_INSTANCE_HELP_STR
8860 BGP_SAFI_WITH_LABEL_HELP_STR
8861 "Display routes matching the large-communities\n"
8862 "List of large-community numbers\n"
8866 afi_t afi
= AFI_IP6
;
8867 safi_t safi
= SAFI_UNICAST
;
8870 if (argv_find(argv
, argc
, "ip", &idx
))
8872 if (argv_find(argv
, argc
, "view", &idx
)
8873 || argv_find(argv
, argc
, "vrf", &idx
))
8874 vrf
= argv
[++idx
]->arg
;
8875 if (argv_find(argv
, argc
, "ipv4", &idx
)
8876 || argv_find(argv
, argc
, "ipv6", &idx
)) {
8877 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8878 if (argv_find(argv
, argc
, "unicast", &idx
)
8879 || argv_find(argv
, argc
, "multicast", &idx
))
8880 safi
= bgp_vty_safi_from_str(argv
[idx
]->text
);
8883 int uj
= use_json(argc
, argv
);
8885 struct bgp
*bgp
= bgp_lookup_by_name(vrf
);
8887 vty_out(vty
, "Can't find BGP instance %s\n", vrf
);
8891 if (argv_find(argv
, argc
, "AA:BB:CC", &idx
))
8892 return bgp_show_lcommunity(vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
8894 return bgp_show(vty
, bgp
, afi
, safi
,
8895 bgp_show_type_lcommunity_all
, NULL
, uj
);
8898 static int bgp_table_stats(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
8902 /* BGP route print out function without JSON */
8905 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
8906 <dampening <parameters>\
8911 |community <AA:NN|local-AS|no-advertise|no-export|graceful-shutdown> [exact-match]\
8912 |community-list <(1-500)|WORD> [exact-match]\
8913 |A.B.C.D/M longer-prefixes\
8914 |X:X::X:X/M longer-prefixes\
8919 BGP_INSTANCE_HELP_STR
8921 BGP_SAFI_WITH_LABEL_HELP_STR
8922 "Display detailed information about dampening\n"
8923 "Display detail of configured dampening parameters\n"
8924 "Display routes matching the route-map\n"
8925 "A route-map to match on\n"
8926 "Display routes conforming to the prefix-list\n"
8927 "Prefix-list name\n"
8928 "Display routes conforming to the filter-list\n"
8929 "Regular expression access list name\n"
8930 "BGP RIB advertisement statistics\n"
8931 "Display routes matching the communities\n"
8933 "Do not send outside local AS (well-known community)\n"
8934 "Do not advertise to any peer (well-known community)\n"
8935 "Do not export to next AS (well-known community)\n"
8936 "Graceful shutdown (well-known community)\n"
8937 "Exact match of the communities\n"
8938 "Display routes matching the community-list\n"
8939 "community-list number\n"
8940 "community-list name\n"
8941 "Exact match of the communities\n"
8943 "Display route and more specific routes\n"
8945 "Display route and more specific routes\n")
8947 afi_t afi
= AFI_IP6
;
8948 safi_t safi
= SAFI_UNICAST
;
8949 int exact_match
= 0;
8950 struct bgp
*bgp
= NULL
;
8952 int idx_community_type
= 0;
8954 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
8959 if (argv_find(argv
, argc
, "dampening", &idx
)) {
8960 if (argv_find(argv
, argc
, "parameters", &idx
))
8961 return bgp_show_dampening_parameters(vty
, afi
, safi
);
8964 if (argv_find(argv
, argc
, "prefix-list", &idx
))
8965 return bgp_show_prefix_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
8966 safi
, bgp_show_type_prefix_list
);
8968 if (argv_find(argv
, argc
, "filter-list", &idx
))
8969 return bgp_show_filter_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
8970 safi
, bgp_show_type_filter_list
);
8972 if (argv_find(argv
, argc
, "statistics", &idx
))
8973 return bgp_table_stats(vty
, bgp
, afi
, safi
);
8975 if (argv_find(argv
, argc
, "route-map", &idx
))
8976 return bgp_show_route_map(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
8977 safi
, bgp_show_type_route_map
);
8979 if (argv_find(argv
, argc
, "community", &idx
)) {
8980 /* show a specific community */
8981 if (argv_find(argv
, argc
, "local-AS", &idx_community_type
)
8982 || argv_find(argv
, argc
, "no-advertise",
8983 &idx_community_type
)
8984 || argv_find(argv
, argc
, "no-export", &idx_community_type
)
8985 || argv_find(argv
, argc
, "graceful-shutdown",
8986 &idx_community_type
)
8987 || argv_find(argv
, argc
, "AA:NN", &idx_community_type
)) {
8989 if (argv_find(argv
, argc
, "exact-match", &idx
))
8991 return bgp_show_community(vty
, bgp
,
8992 argv
[idx_community_type
]->arg
,
8993 exact_match
, afi
, safi
);
8997 if (argv_find(argv
, argc
, "community-list", &idx
)) {
8998 const char *clist_number_or_name
= argv
[++idx
]->arg
;
8999 if (++idx
< argc
&& strmatch(argv
[idx
]->text
, "exact-match"))
9001 return bgp_show_community_list(vty
, bgp
, clist_number_or_name
,
9002 exact_match
, afi
, safi
);
9005 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)
9006 || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
9007 return bgp_show_prefix_longer(vty
, bgp
, argv
[idx
]->arg
, afi
,
9009 bgp_show_type_prefix_longer
);
9014 /* BGP route print out function with JSON */
9015 DEFUN (show_ip_bgp_json
,
9016 show_ip_bgp_json_cmd
,
9017 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
9020 |dampening <flap-statistics|dampened-paths>\
9026 BGP_INSTANCE_HELP_STR
9028 BGP_SAFI_WITH_LABEL_HELP_STR
9029 "Display only routes with non-natural netmasks\n"
9030 "Display detailed information about dampening\n"
9031 "Display flap statistics of routes\n"
9032 "Display paths suppressed due to dampening\n"
9033 "Display routes matching the communities\n"
9036 afi_t afi
= AFI_IP6
;
9037 safi_t safi
= SAFI_UNICAST
;
9038 enum bgp_show_type sh_type
= bgp_show_type_normal
;
9039 struct bgp
*bgp
= NULL
;
9042 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9047 int uj
= use_json(argc
, argv
);
9051 if (argv_find(argv
, argc
, "cidr-only", &idx
))
9052 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
,
9055 if (argv_find(argv
, argc
, "dampening", &idx
)) {
9056 if (argv_find(argv
, argc
, "dampened-paths", &idx
))
9057 return bgp_show(vty
, bgp
, afi
, safi
,
9058 bgp_show_type_dampend_paths
, NULL
, uj
);
9059 else if (argv_find(argv
, argc
, "flap-statistics", &idx
))
9060 return bgp_show(vty
, bgp
, afi
, safi
,
9061 bgp_show_type_flap_statistics
, NULL
,
9065 if (argv_find(argv
, argc
, "community", &idx
)) {
9066 /* show all communities */
9067 return bgp_show(vty
, bgp
, afi
, safi
,
9068 bgp_show_type_community_all
, NULL
, uj
);
9070 return bgp_show(vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
9073 DEFUN (show_ip_bgp_route
,
9074 show_ip_bgp_route_cmd
,
9075 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]"
9076 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
9080 BGP_INSTANCE_HELP_STR
9082 BGP_SAFI_WITH_LABEL_HELP_STR
9083 "Network in the BGP routing table to display\n"
9085 "Network in the BGP routing table to display\n"
9087 "Display only the bestpath\n"
9088 "Display only multipaths\n"
9091 int prefix_check
= 0;
9093 afi_t afi
= AFI_IP6
;
9094 safi_t safi
= SAFI_UNICAST
;
9095 char *prefix
= NULL
;
9096 struct bgp
*bgp
= NULL
;
9097 enum bgp_path_type path_type
;
9098 u_char uj
= use_json(argc
, argv
);
9102 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9109 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
9113 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
9114 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)
9115 || argv_find(argv
, argc
, "X:X::X:X", &idx
))
9117 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)
9118 || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
9121 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
)
9122 && afi
!= AFI_IP6
) {
9124 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
9127 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
)
9130 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
9134 prefix
= argv
[idx
]->arg
;
9136 /* [<bestpath|multipath>] */
9137 if (argv_find(argv
, argc
, "bestpath", &idx
))
9138 path_type
= BGP_PATH_BESTPATH
;
9139 else if (argv_find(argv
, argc
, "multipath", &idx
))
9140 path_type
= BGP_PATH_MULTIPATH
;
9142 path_type
= BGP_PATH_ALL
;
9144 return bgp_show_route(vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
,
9148 DEFUN (show_ip_bgp_regexp
,
9149 show_ip_bgp_regexp_cmd
,
9150 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] regexp REGEX...",
9154 BGP_INSTANCE_HELP_STR
9156 BGP_SAFI_WITH_LABEL_HELP_STR
9157 "Display routes matching the AS path regular expression\n"
9158 "A regular-expression to match the BGP AS paths\n")
9160 afi_t afi
= AFI_IP6
;
9161 safi_t safi
= SAFI_UNICAST
;
9162 struct bgp
*bgp
= NULL
;
9165 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9170 // get index of regex
9171 argv_find(argv
, argc
, "regexp", &idx
);
9174 char *regstr
= argv_concat(argv
, argc
, idx
);
9175 int rc
= bgp_show_regexp(vty
, bgp
, (const char *)regstr
, afi
, safi
,
9176 bgp_show_type_regexp
);
9177 XFREE(MTYPE_TMP
, regstr
);
9181 DEFUN (show_ip_bgp_instance_all
,
9182 show_ip_bgp_instance_all_cmd
,
9183 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] [json]",
9187 BGP_INSTANCE_ALL_HELP_STR
9189 BGP_SAFI_WITH_LABEL_HELP_STR
9193 safi_t safi
= SAFI_UNICAST
;
9194 struct bgp
*bgp
= NULL
;
9197 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9202 int uj
= use_json(argc
, argv
);
9206 bgp_show_all_instances_routes_vty(vty
, afi
, safi
, uj
);
9210 static int bgp_show_regexp(struct vty
*vty
, struct bgp
*bgp
, const char *regstr
,
9211 afi_t afi
, safi_t safi
, enum bgp_show_type type
)
9216 regex
= bgp_regcomp(regstr
);
9218 vty_out(vty
, "Can't compile regexp %s\n", regstr
);
9222 rc
= bgp_show(vty
, bgp
, afi
, safi
, type
, regex
, 0);
9223 bgp_regex_free(regex
);
9227 static int bgp_show_prefix_list(struct vty
*vty
, struct bgp
*bgp
,
9228 const char *prefix_list_str
, afi_t afi
,
9229 safi_t safi
, enum bgp_show_type type
)
9231 struct prefix_list
*plist
;
9233 plist
= prefix_list_lookup(afi
, prefix_list_str
);
9234 if (plist
== NULL
) {
9235 vty_out(vty
, "%% %s is not a valid prefix-list name\n",
9240 return bgp_show(vty
, bgp
, afi
, safi
, type
, plist
, 0);
9243 static int bgp_show_filter_list(struct vty
*vty
, struct bgp
*bgp
,
9244 const char *filter
, afi_t afi
, safi_t safi
,
9245 enum bgp_show_type type
)
9247 struct as_list
*as_list
;
9249 as_list
= as_list_lookup(filter
);
9250 if (as_list
== NULL
) {
9251 vty_out(vty
, "%% %s is not a valid AS-path access-list name\n",
9256 return bgp_show(vty
, bgp
, afi
, safi
, type
, as_list
, 0);
9259 static int bgp_show_route_map(struct vty
*vty
, struct bgp
*bgp
,
9260 const char *rmap_str
, afi_t afi
, safi_t safi
,
9261 enum bgp_show_type type
)
9263 struct route_map
*rmap
;
9265 rmap
= route_map_lookup_by_name(rmap_str
);
9267 vty_out(vty
, "%% %s is not a valid route-map name\n", rmap_str
);
9271 return bgp_show(vty
, bgp
, afi
, safi
, type
, rmap
, 0);
9274 static int bgp_show_community(struct vty
*vty
, struct bgp
*bgp
,
9275 const char *comstr
, int exact
, afi_t afi
,
9278 struct community
*com
;
9281 com
= community_str2com(comstr
);
9283 vty_out(vty
, "%% Community malformed: %s\n", comstr
);
9287 ret
= bgp_show(vty
, bgp
, afi
, safi
,
9288 (exact
? bgp_show_type_community_exact
9289 : bgp_show_type_community
),
9291 community_free(com
);
9296 static int bgp_show_community_list(struct vty
*vty
, struct bgp
*bgp
,
9297 const char *com
, int exact
, afi_t afi
,
9300 struct community_list
*list
;
9302 list
= community_list_lookup(bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
9304 vty_out(vty
, "%% %s is not a valid community-list name\n", com
);
9308 return bgp_show(vty
, bgp
, afi
, safi
,
9309 (exact
? bgp_show_type_community_list_exact
9310 : bgp_show_type_community_list
),
9314 static int bgp_show_prefix_longer(struct vty
*vty
, struct bgp
*bgp
,
9315 const char *prefix
, afi_t afi
, safi_t safi
,
9316 enum bgp_show_type type
)
9323 ret
= str2prefix(prefix
, p
);
9325 vty_out(vty
, "%% Malformed Prefix\n");
9329 ret
= bgp_show(vty
, bgp
, afi
, safi
, type
, p
, 0);
9334 static struct peer
*peer_lookup_in_view(struct vty
*vty
, struct bgp
*bgp
,
9335 const char *ip_str
, u_char use_json
)
9341 /* Get peer sockunion. */
9342 ret
= str2sockunion(ip_str
, &su
);
9344 peer
= peer_lookup_by_conf_if(bgp
, ip_str
);
9346 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
9350 json_object
*json_no
= NULL
;
9351 json_no
= json_object_new_object();
9352 json_object_string_add(
9354 "malformedAddressOrName",
9356 vty_out(vty
, "%s\n",
9357 json_object_to_json_string_ext(
9359 JSON_C_TO_STRING_PRETTY
));
9360 json_object_free(json_no
);
9363 "%% Malformed address or name: %s\n",
9371 /* Peer structure lookup. */
9372 peer
= peer_lookup(bgp
, &su
);
9375 json_object
*json_no
= NULL
;
9376 json_no
= json_object_new_object();
9377 json_object_string_add(json_no
, "warning",
9378 "No such neighbor");
9379 vty_out(vty
, "%s\n",
9380 json_object_to_json_string_ext(
9381 json_no
, JSON_C_TO_STRING_PRETTY
));
9382 json_object_free(json_no
);
9384 vty_out(vty
, "No such neighbor\n");
9392 BGP_STATS_MAXBITLEN
= 0,
9396 BGP_STATS_UNAGGREGATEABLE
,
9397 BGP_STATS_MAX_AGGREGATEABLE
,
9398 BGP_STATS_AGGREGATES
,
9400 BGP_STATS_ASPATH_COUNT
,
9401 BGP_STATS_ASPATH_MAXHOPS
,
9402 BGP_STATS_ASPATH_TOTHOPS
,
9403 BGP_STATS_ASPATH_MAXSIZE
,
9404 BGP_STATS_ASPATH_TOTSIZE
,
9405 BGP_STATS_ASN_HIGHEST
,
9409 static const char *table_stats_strs
[] = {
9410 [BGP_STATS_PREFIXES
] = "Total Prefixes",
9411 [BGP_STATS_TOTPLEN
] = "Average prefix length",
9412 [BGP_STATS_RIB
] = "Total Advertisements",
9413 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
9414 [BGP_STATS_MAX_AGGREGATEABLE
] =
9415 "Maximum aggregateable prefixes",
9416 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
9417 [BGP_STATS_SPACE
] = "Address space advertised",
9418 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
9419 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
9420 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
9421 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
9422 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
9423 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
9424 [BGP_STATS_MAX
] = NULL
,
9427 struct bgp_table_stats
{
9428 struct bgp_table
*table
;
9429 unsigned long long counts
[BGP_STATS_MAX
];
9434 #define TALLY_SIGFIG 100000
9435 static unsigned long
9436 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
9438 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
9439 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
9440 unsigned long ret
= newtot
/ count
;
9442 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
9449 static int bgp_table_stats_walker(struct thread
*t
)
9451 struct bgp_node
*rn
;
9452 struct bgp_node
*top
;
9453 struct bgp_table_stats
*ts
= THREAD_ARG(t
);
9454 unsigned int space
= 0;
9456 if (!(top
= bgp_table_top(ts
->table
)))
9459 switch (top
->p
.family
) {
9461 space
= IPV4_MAX_BITLEN
;
9464 space
= IPV6_MAX_BITLEN
;
9468 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
9470 for (rn
= top
; rn
; rn
= bgp_route_next(rn
)) {
9471 struct bgp_info
*ri
;
9472 struct bgp_node
*prn
= bgp_node_parent_nolock(rn
);
9473 unsigned int rinum
= 0;
9481 ts
->counts
[BGP_STATS_PREFIXES
]++;
9482 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
9485 ts
->counts
[BGP_STATS_AVGPLEN
]
9486 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
9487 ts
->counts
[BGP_STATS_AVGPLEN
],
9491 /* check if the prefix is included by any other announcements */
9492 while (prn
&& !prn
->info
)
9493 prn
= bgp_node_parent_nolock(prn
);
9495 if (prn
== NULL
|| prn
== top
) {
9496 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
9497 /* announced address space */
9500 pow(2.0, space
- rn
->p
.prefixlen
);
9501 } else if (prn
->info
)
9502 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
9504 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
9506 ts
->counts
[BGP_STATS_RIB
]++;
9509 && (CHECK_FLAG(ri
->attr
->flag
,
9511 BGP_ATTR_ATOMIC_AGGREGATE
))))
9512 ts
->counts
[BGP_STATS_AGGREGATES
]++;
9515 if (ri
->attr
&& ri
->attr
->aspath
) {
9517 aspath_count_hops(ri
->attr
->aspath
);
9519 aspath_size(ri
->attr
->aspath
);
9520 as_t highest
= aspath_highest(ri
->attr
->aspath
);
9522 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
9524 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
9525 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] =
9528 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
9529 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] =
9532 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
9533 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
9535 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
9536 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9537 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
9539 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
9540 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9541 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
9544 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
9545 ts
->counts
[BGP_STATS_ASN_HIGHEST
] =
9553 static int bgp_table_stats(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
9556 struct bgp_table_stats ts
;
9559 if (!bgp
->rib
[afi
][safi
]) {
9560 vty_out(vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
9565 vty_out(vty
, "BGP %s RIB statistics\n", afi_safi_print(afi
, safi
));
9567 /* labeled-unicast routes live in the unicast table */
9568 if (safi
== SAFI_LABELED_UNICAST
)
9569 safi
= SAFI_UNICAST
;
9571 memset(&ts
, 0, sizeof(ts
));
9572 ts
.table
= bgp
->rib
[afi
][safi
];
9573 thread_execute(bm
->master
, bgp_table_stats_walker
, &ts
, 0);
9575 for (i
= 0; i
< BGP_STATS_MAX
; i
++) {
9576 if (!table_stats_strs
[i
])
9581 case BGP_STATS_ASPATH_AVGHOPS
:
9582 case BGP_STATS_ASPATH_AVGSIZE
:
9583 case BGP_STATS_AVGPLEN
:
9584 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9585 vty_out (vty
, "%12.2f",
9586 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
9589 case BGP_STATS_ASPATH_TOTHOPS
:
9590 case BGP_STATS_ASPATH_TOTSIZE
:
9591 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9592 vty_out(vty
, "%12.2f",
9594 ? (float)ts
.counts
[i
]
9596 [BGP_STATS_ASPATH_COUNT
]
9599 case BGP_STATS_TOTPLEN
:
9600 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9601 vty_out(vty
, "%12.2f",
9603 ? (float)ts
.counts
[i
]
9605 [BGP_STATS_PREFIXES
]
9608 case BGP_STATS_SPACE
:
9609 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9610 vty_out(vty
, "%12g\n", ts
.total_space
);
9612 if (afi
== AFI_IP6
) {
9613 vty_out(vty
, "%30s: ", "/32 equivalent ");
9614 vty_out(vty
, "%12g\n",
9615 ts
.total_space
* pow(2.0, -128 + 32));
9616 vty_out(vty
, "%30s: ", "/48 equivalent ");
9617 vty_out(vty
, "%12g\n",
9618 ts
.total_space
* pow(2.0, -128 + 48));
9620 vty_out(vty
, "%30s: ", "% announced ");
9621 vty_out(vty
, "%12.2f\n",
9622 ts
.total_space
* 100. * pow(2.0, -32));
9623 vty_out(vty
, "%30s: ", "/8 equivalent ");
9624 vty_out(vty
, "%12.2f\n",
9625 ts
.total_space
* pow(2.0, -32 + 8));
9626 vty_out(vty
, "%30s: ", "/24 equivalent ");
9627 vty_out(vty
, "%12.2f\n",
9628 ts
.total_space
* pow(2.0, -32 + 24));
9632 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9633 vty_out(vty
, "%12llu", ts
.counts
[i
]);
9650 PCOUNT_PFCNT
, /* the figure we display to users */
9654 static const char *pcount_strs
[] = {
9655 [PCOUNT_ADJ_IN
] = "Adj-in",
9656 [PCOUNT_DAMPED
] = "Damped",
9657 [PCOUNT_REMOVED
] = "Removed",
9658 [PCOUNT_HISTORY
] = "History",
9659 [PCOUNT_STALE
] = "Stale",
9660 [PCOUNT_VALID
] = "Valid",
9661 [PCOUNT_ALL
] = "All RIB",
9662 [PCOUNT_COUNTED
] = "PfxCt counted",
9663 [PCOUNT_PFCNT
] = "Useable",
9664 [PCOUNT_MAX
] = NULL
,
9667 struct peer_pcounts
{
9668 unsigned int count
[PCOUNT_MAX
];
9669 const struct peer
*peer
;
9670 const struct bgp_table
*table
;
9673 static int bgp_peer_count_walker(struct thread
*t
)
9675 struct bgp_node
*rn
;
9676 struct peer_pcounts
*pc
= THREAD_ARG(t
);
9677 const struct peer
*peer
= pc
->peer
;
9679 for (rn
= bgp_table_top(pc
->table
); rn
; rn
= bgp_route_next(rn
)) {
9680 struct bgp_adj_in
*ain
;
9681 struct bgp_info
*ri
;
9683 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9684 if (ain
->peer
== peer
)
9685 pc
->count
[PCOUNT_ADJ_IN
]++;
9687 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
9688 char buf
[SU_ADDRSTRLEN
];
9690 if (ri
->peer
!= peer
)
9693 pc
->count
[PCOUNT_ALL
]++;
9695 if (CHECK_FLAG(ri
->flags
, BGP_INFO_DAMPED
))
9696 pc
->count
[PCOUNT_DAMPED
]++;
9697 if (CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
9698 pc
->count
[PCOUNT_HISTORY
]++;
9699 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
9700 pc
->count
[PCOUNT_REMOVED
]++;
9701 if (CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
))
9702 pc
->count
[PCOUNT_STALE
]++;
9703 if (CHECK_FLAG(ri
->flags
, BGP_INFO_VALID
))
9704 pc
->count
[PCOUNT_VALID
]++;
9705 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
9706 pc
->count
[PCOUNT_PFCNT
]++;
9708 if (CHECK_FLAG(ri
->flags
, BGP_INFO_COUNTED
)) {
9709 pc
->count
[PCOUNT_COUNTED
]++;
9710 if (CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
9712 "%s [pcount] %s/%d is counted but flags 0x%x",
9714 inet_ntop(rn
->p
.family
,
9715 &rn
->p
.u
.prefix
, buf
,
9717 rn
->p
.prefixlen
, ri
->flags
);
9719 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
9721 "%s [pcount] %s/%d not counted but flags 0x%x",
9723 inet_ntop(rn
->p
.family
,
9724 &rn
->p
.u
.prefix
, buf
,
9726 rn
->p
.prefixlen
, ri
->flags
);
9733 static int bgp_peer_counts(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9734 safi_t safi
, u_char use_json
)
9736 struct peer_pcounts pcounts
= {.peer
= peer
};
9738 json_object
*json
= NULL
;
9739 json_object
*json_loop
= NULL
;
9742 json
= json_object_new_object();
9743 json_loop
= json_object_new_object();
9746 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
9747 || !peer
->bgp
->rib
[afi
][safi
]) {
9749 json_object_string_add(
9751 "No such neighbor or address family");
9752 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
9753 json_object_free(json
);
9755 vty_out(vty
, "%% No such neighbor or address family\n");
9760 memset(&pcounts
, 0, sizeof(pcounts
));
9761 pcounts
.peer
= peer
;
9762 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
9764 /* in-place call via thread subsystem so as to record execution time
9765 * stats for the thread-walk (i.e. ensure this can't be blamed on
9766 * on just vty_read()).
9768 thread_execute(bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
9771 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
9772 json_object_string_add(json
, "multiProtocol",
9773 afi_safi_print(afi
, safi
));
9774 json_object_int_add(json
, "pfxCounter",
9775 peer
->pcount
[afi
][safi
]);
9777 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9778 json_object_int_add(json_loop
, pcount_strs
[i
],
9781 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
9783 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
]) {
9784 json_object_string_add(json
, "pfxctDriftFor",
9786 json_object_string_add(
9787 json
, "recommended",
9788 "Please report this bug, with the above command output");
9790 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9791 json
, JSON_C_TO_STRING_PRETTY
));
9792 json_object_free(json
);
9796 && bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
)) {
9797 vty_out(vty
, "Prefix counts for %s/%s, %s\n",
9798 peer
->hostname
, peer
->host
,
9799 afi_safi_print(afi
, safi
));
9801 vty_out(vty
, "Prefix counts for %s, %s\n", peer
->host
,
9802 afi_safi_print(afi
, safi
));
9805 vty_out(vty
, "PfxCt: %ld\n", peer
->pcount
[afi
][safi
]);
9806 vty_out(vty
, "\nCounts from RIB table walk:\n\n");
9808 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9809 vty_out(vty
, "%20s: %-10d\n", pcount_strs
[i
],
9812 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
]) {
9813 vty_out(vty
, "%s [pcount] PfxCt drift!\n", peer
->host
);
9815 "Please report this bug, with the above command output\n");
9822 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9823 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9824 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9825 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9829 BGP_INSTANCE_HELP_STR
9832 "Detailed information on TCP and BGP neighbor connections\n"
9833 "Neighbor to display information about\n"
9834 "Neighbor to display information about\n"
9835 "Neighbor on BGP configured interface\n"
9836 "Display detailed prefix count information\n"
9839 afi_t afi
= AFI_IP6
;
9840 safi_t safi
= SAFI_UNICAST
;
9843 struct bgp
*bgp
= NULL
;
9845 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9850 int uj
= use_json(argc
, argv
);
9854 argv_find(argv
, argc
, "neighbors", &idx
);
9855 peer
= peer_lookup_in_view(vty
, bgp
, argv
[idx
+ 1]->arg
, uj
);
9859 return bgp_peer_counts(vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9862 #ifdef KEEP_OLD_VPN_COMMANDS
9863 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
9864 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
9865 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9870 "Display information about all VPNv4 NLRIs\n"
9871 "Detailed information on TCP and BGP neighbor connections\n"
9872 "Neighbor to display information about\n"
9873 "Neighbor to display information about\n"
9874 "Neighbor on BGP configured interface\n"
9875 "Display detailed prefix count information\n"
9880 u_char uj
= use_json(argc
, argv
);
9882 peer
= peer_lookup_in_view(vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9886 return bgp_peer_counts(vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9889 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
9890 show_ip_bgp_vpn_all_route_prefix_cmd
,
9891 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9896 "Display information about all VPNv4 NLRIs\n"
9897 "Network in the BGP routing table to display\n"
9898 "Network in the BGP routing table to display\n"
9902 char *network
= NULL
;
9903 struct bgp
*bgp
= bgp_get_default();
9905 vty_out(vty
, "Can't find default instance\n");
9909 if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9910 network
= argv
[idx
]->arg
;
9911 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
))
9912 network
= argv
[idx
]->arg
;
9914 vty_out(vty
, "Unable to figure out Network\n");
9918 return bgp_show_route(vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0,
9919 BGP_PATH_ALL
, use_json(argc
, argv
));
9921 #endif /* KEEP_OLD_VPN_COMMANDS */
9923 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix
,
9924 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
,
9925 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
9931 "Display information about all EVPN NLRIs\n"
9932 "Network in the BGP routing table to display\n"
9933 "Network in the BGP routing table to display\n"
9937 char *network
= NULL
;
9939 if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9940 network
= argv
[idx
]->arg
;
9941 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
))
9942 network
= argv
[idx
]->arg
;
9944 vty_out(vty
, "Unable to figure out Network\n");
9947 return bgp_show_route(vty
, NULL
, network
, AFI_L2VPN
, SAFI_EVPN
, NULL
, 0,
9948 BGP_PATH_ALL
, use_json(argc
, argv
));
9951 static void show_adj_route(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9952 safi_t safi
, int in
, const char *rmap_name
,
9953 u_char use_json
, json_object
*json
)
9955 struct bgp_table
*table
;
9956 struct bgp_adj_in
*ain
;
9957 struct bgp_adj_out
*adj
;
9958 unsigned long output_count
;
9959 unsigned long filtered_count
;
9960 struct bgp_node
*rn
;
9966 struct update_subgroup
*subgrp
;
9967 json_object
*json_scode
= NULL
;
9968 json_object
*json_ocode
= NULL
;
9969 json_object
*json_ar
= NULL
;
9970 struct peer_af
*paf
;
9973 json_scode
= json_object_new_object();
9974 json_ocode
= json_object_new_object();
9975 json_ar
= json_object_new_object();
9977 json_object_string_add(json_scode
, "suppressed", "s");
9978 json_object_string_add(json_scode
, "damped", "d");
9979 json_object_string_add(json_scode
, "history", "h");
9980 json_object_string_add(json_scode
, "valid", "*");
9981 json_object_string_add(json_scode
, "best", ">");
9982 json_object_string_add(json_scode
, "multipath", "=");
9983 json_object_string_add(json_scode
, "internal", "i");
9984 json_object_string_add(json_scode
, "ribFailure", "r");
9985 json_object_string_add(json_scode
, "stale", "S");
9986 json_object_string_add(json_scode
, "removed", "R");
9988 json_object_string_add(json_ocode
, "igp", "i");
9989 json_object_string_add(json_ocode
, "egp", "e");
9990 json_object_string_add(json_ocode
, "incomplete", "?");
9997 json_object_string_add(json
, "alert", "no BGP");
9998 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
9999 json_object_free(json
);
10001 vty_out(vty
, "%% No bgp\n");
10005 table
= bgp
->rib
[afi
][safi
];
10007 output_count
= filtered_count
= 0;
10008 subgrp
= peer_subgroup(peer
, afi
, safi
);
10011 && CHECK_FLAG(subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
)) {
10013 json_object_int_add(json
, "bgpTableVersion",
10015 json_object_string_add(json
, "bgpLocalRouterId",
10016 inet_ntoa(bgp
->router_id
));
10017 json_object_object_add(json
, "bgpStatusCodes",
10019 json_object_object_add(json
, "bgpOriginCodes",
10021 json_object_string_add(json
,
10022 "bgpOriginatingDefaultNetwork",
10025 vty_out(vty
, "BGP table version is %" PRIu64
10026 ", local router ID is %s\n",
10027 table
->version
, inet_ntoa(bgp
->router_id
));
10028 vty_out(vty
, BGP_SHOW_SCODE_HEADER
);
10029 vty_out(vty
, BGP_SHOW_OCODE_HEADER
);
10031 vty_out(vty
, "Originating default network 0.0.0.0\n\n");
10036 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
10038 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
) {
10039 if (ain
->peer
!= peer
)
10043 json_object_int_add(
10044 json
, "bgpTableVersion",
10046 json_object_string_add(
10048 "bgpLocalRouterId",
10051 json_object_object_add(
10052 json
, "bgpStatusCodes",
10054 json_object_object_add(
10055 json
, "bgpOriginCodes",
10059 "BGP table version is 0, local router ID is %s\n",
10063 BGP_SHOW_SCODE_HEADER
);
10065 BGP_SHOW_OCODE_HEADER
);
10071 vty_out(vty
, BGP_SHOW_HEADER
);
10075 bgp_attr_dup(&attr
, ain
->attr
);
10076 if (bgp_input_modifier(peer
, &rn
->p
,
10080 route_vty_out_tmp(vty
, &rn
->p
,
10090 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
10091 SUBGRP_FOREACH_PEER (adj
->subgroup
, paf
) {
10092 if (paf
->peer
!= peer
)
10097 json_object_int_add(
10101 json_object_string_add(
10103 "bgpLocalRouterId",
10106 json_object_object_add(
10110 json_object_object_add(
10116 "BGP table version is %" PRIu64
10117 ", local router ID is %s\n",
10122 BGP_SHOW_SCODE_HEADER
);
10124 BGP_SHOW_OCODE_HEADER
);
10137 bgp_attr_dup(&attr
, adj
->attr
);
10138 ret
= bgp_output_modifier(
10139 peer
, &rn
->p
, &attr
,
10140 afi
, safi
, rmap_name
);
10141 if (ret
!= RMAP_DENY
) {
10151 bgp_attr_undup(&attr
,
10158 json_object_object_add(json
, "advertisedRoutes", json_ar
);
10160 if (output_count
!= 0) {
10162 json_object_int_add(json
, "totalPrefixCounter",
10165 vty_out(vty
, "\nTotal number of prefixes %ld\n",
10169 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10170 json
, JSON_C_TO_STRING_PRETTY
));
10171 json_object_free(json
);
10175 static int peer_adj_routes(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
10176 safi_t safi
, int in
, const char *rmap_name
,
10179 json_object
*json
= NULL
;
10182 json
= json_object_new_object();
10184 /* labeled-unicast routes live in the unicast table */
10185 if (safi
== SAFI_LABELED_UNICAST
)
10186 safi
= SAFI_UNICAST
;
10188 if (!peer
|| !peer
->afc
[afi
][safi
]) {
10190 json_object_string_add(
10192 "No such neighbor or address family");
10193 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10194 json_object_free(json
);
10196 vty_out(vty
, "%% No such neighbor or address family\n");
10198 return CMD_WARNING
;
10202 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
10203 PEER_FLAG_SOFT_RECONFIG
)) {
10205 json_object_string_add(
10207 "Inbound soft reconfiguration not enabled");
10208 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10209 json_object_free(json
);
10212 "%% Inbound soft reconfiguration not enabled\n");
10214 return CMD_WARNING
;
10217 show_adj_route(vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
10219 return CMD_SUCCESS
;
10222 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
10223 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
10224 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
10225 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
10229 BGP_INSTANCE_HELP_STR
10231 BGP_SAFI_WITH_LABEL_HELP_STR
10232 "Detailed information on TCP and BGP neighbor connections\n"
10233 "Neighbor to display information about\n"
10234 "Neighbor to display information about\n"
10235 "Neighbor on BGP configured interface\n"
10236 "Display the received routes from neighbor\n"
10237 "Display the routes advertised to a BGP neighbor\n"
10238 "Route-map to modify the attributes\n"
10239 "Name of the route map\n"
10242 afi_t afi
= AFI_IP6
;
10243 safi_t safi
= SAFI_UNICAST
;
10244 char *rmap_name
= NULL
;
10245 char *peerstr
= NULL
;
10247 struct bgp
*bgp
= NULL
;
10252 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10255 return CMD_WARNING
;
10257 int uj
= use_json(argc
, argv
);
10261 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10262 argv_find(argv
, argc
, "neighbors", &idx
);
10263 peerstr
= argv
[++idx
]->arg
;
10265 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
10267 return CMD_WARNING
;
10269 if (argv_find(argv
, argc
, "received-routes", &idx
))
10271 if (argv_find(argv
, argc
, "advertised-routes", &idx
))
10273 if (argv_find(argv
, argc
, "route-map", &idx
))
10274 rmap_name
= argv
[++idx
]->arg
;
10276 return peer_adj_routes(vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
10279 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
10280 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
10281 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
10287 "Address Family modifier\n"
10288 "Detailed information on TCP and BGP neighbor connections\n"
10289 "Neighbor to display information about\n"
10290 "Neighbor to display information about\n"
10291 "Neighbor on BGP configured interface\n"
10292 "Display information received from a BGP neighbor\n"
10293 "Display the prefixlist filter\n"
10296 afi_t afi
= AFI_IP6
;
10297 safi_t safi
= SAFI_UNICAST
;
10298 char *peerstr
= NULL
;
10301 union sockunion su
;
10307 /* show [ip] bgp */
10308 if (argv_find(argv
, argc
, "ip", &idx
))
10310 /* [<ipv4|ipv6> [unicast]] */
10311 if (argv_find(argv
, argc
, "ipv4", &idx
))
10313 if (argv_find(argv
, argc
, "ipv6", &idx
))
10315 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10316 argv_find(argv
, argc
, "neighbors", &idx
);
10317 peerstr
= argv
[++idx
]->arg
;
10319 u_char uj
= use_json(argc
, argv
);
10321 ret
= str2sockunion(peerstr
, &su
);
10323 peer
= peer_lookup_by_conf_if(NULL
, peerstr
);
10326 vty_out(vty
, "{}\n");
10329 "%% Malformed address or name: %s\n",
10331 return CMD_WARNING
;
10334 peer
= peer_lookup(NULL
, &su
);
10337 vty_out(vty
, "{}\n");
10339 vty_out(vty
, "No peer\n");
10340 return CMD_WARNING
;
10344 sprintf(name
, "%s.%d.%d", peer
->host
, afi
, safi
);
10345 count
= prefix_bgp_show_prefix_list(NULL
, afi
, name
, uj
);
10348 vty_out(vty
, "Address Family: %s\n",
10349 afi_safi_print(afi
, safi
));
10350 prefix_bgp_show_prefix_list(vty
, afi
, name
, uj
);
10353 vty_out(vty
, "{}\n");
10355 vty_out(vty
, "No functional output\n");
10358 return CMD_SUCCESS
;
10361 static int bgp_show_neighbor_route(struct vty
*vty
, struct peer
*peer
,
10362 afi_t afi
, safi_t safi
,
10363 enum bgp_show_type type
, u_char use_json
)
10365 /* labeled-unicast routes live in the unicast table */
10366 if (safi
== SAFI_LABELED_UNICAST
)
10367 safi
= SAFI_UNICAST
;
10369 if (!peer
|| !peer
->afc
[afi
][safi
]) {
10371 json_object
*json_no
= NULL
;
10372 json_no
= json_object_new_object();
10373 json_object_string_add(
10374 json_no
, "warning",
10375 "No such neighbor or address family");
10376 vty_out(vty
, "%s\n",
10377 json_object_to_json_string(json_no
));
10378 json_object_free(json_no
);
10380 vty_out(vty
, "%% No such neighbor or address family\n");
10381 return CMD_WARNING
;
10384 return bgp_show(vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
10387 DEFUN (show_ip_bgp_neighbor_routes
,
10388 show_ip_bgp_neighbor_routes_cmd
,
10389 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
10390 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
10394 BGP_INSTANCE_HELP_STR
10396 BGP_SAFI_WITH_LABEL_HELP_STR
10397 "Detailed information on TCP and BGP neighbor connections\n"
10398 "Neighbor to display information about\n"
10399 "Neighbor to display information about\n"
10400 "Neighbor on BGP configured interface\n"
10401 "Display flap statistics of the routes learned from neighbor\n"
10402 "Display the dampened routes received from neighbor\n"
10403 "Display routes learned from neighbor\n"
10406 char *peerstr
= NULL
;
10407 struct bgp
*bgp
= NULL
;
10408 afi_t afi
= AFI_IP6
;
10409 safi_t safi
= SAFI_UNICAST
;
10411 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
10415 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10418 return CMD_WARNING
;
10420 int uj
= use_json(argc
, argv
);
10424 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10425 argv_find(argv
, argc
, "neighbors", &idx
);
10426 peerstr
= argv
[++idx
]->arg
;
10428 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
10430 vty_out(vty
, "No such neighbor\n");
10431 return CMD_WARNING
;
10434 if (argv_find(argv
, argc
, "flap-statistics", &idx
))
10435 sh_type
= bgp_show_type_flap_neighbor
;
10436 else if (argv_find(argv
, argc
, "dampened-routes", &idx
))
10437 sh_type
= bgp_show_type_damp_neighbor
;
10438 else if (argv_find(argv
, argc
, "routes", &idx
))
10439 sh_type
= bgp_show_type_neighbor
;
10441 return bgp_show_neighbor_route(vty
, peer
, afi
, safi
, sh_type
, uj
);
10444 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
10446 struct bgp_distance
{
10447 /* Distance value for the IP source prefix. */
10450 /* Name of the access-list to be matched. */
10454 DEFUN (show_bgp_afi_vpn_rd_route
,
10455 show_bgp_afi_vpn_rd_route_cmd
,
10456 "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]",
10460 "Address Family modifier\n"
10461 "Display information for a route distinguisher\n"
10462 "Route Distinguisher\n"
10463 "Network in the BGP routing table to display\n"
10464 "Network in the BGP routing table to display\n"
10468 struct prefix_rd prd
;
10469 afi_t afi
= AFI_MAX
;
10472 if (!argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
10473 vty_out(vty
, "%% Malformed Address Family\n");
10474 return CMD_WARNING
;
10477 ret
= str2prefix_rd(argv
[5]->arg
, &prd
);
10479 vty_out(vty
, "%% Malformed Route Distinguisher\n");
10480 return CMD_WARNING
;
10483 return bgp_show_route(vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
,
10484 0, BGP_PATH_ALL
, use_json(argc
, argv
));
10487 static struct bgp_distance
*bgp_distance_new(void)
10489 return XCALLOC(MTYPE_BGP_DISTANCE
, sizeof(struct bgp_distance
));
10492 static void bgp_distance_free(struct bgp_distance
*bdistance
)
10494 XFREE(MTYPE_BGP_DISTANCE
, bdistance
);
10497 static int bgp_distance_set(struct vty
*vty
, const char *distance_str
,
10498 const char *ip_str
, const char *access_list_str
)
10505 struct bgp_node
*rn
;
10506 struct bgp_distance
*bdistance
;
10508 afi
= bgp_node_afi(vty
);
10509 safi
= bgp_node_safi(vty
);
10511 ret
= str2prefix(ip_str
, &p
);
10513 vty_out(vty
, "Malformed prefix\n");
10514 return CMD_WARNING_CONFIG_FAILED
;
10517 distance
= atoi(distance_str
);
10519 /* Get BGP distance node. */
10520 rn
= bgp_node_get(bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
10522 bdistance
= rn
->info
;
10523 bgp_unlock_node(rn
);
10525 bdistance
= bgp_distance_new();
10526 rn
->info
= bdistance
;
10529 /* Set distance value. */
10530 bdistance
->distance
= distance
;
10532 /* Reset access-list configuration. */
10533 if (bdistance
->access_list
) {
10534 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10535 bdistance
->access_list
= NULL
;
10537 if (access_list_str
)
10538 bdistance
->access_list
=
10539 XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
10541 return CMD_SUCCESS
;
10544 static int bgp_distance_unset(struct vty
*vty
, const char *distance_str
,
10545 const char *ip_str
, const char *access_list_str
)
10552 struct bgp_node
*rn
;
10553 struct bgp_distance
*bdistance
;
10555 afi
= bgp_node_afi(vty
);
10556 safi
= bgp_node_safi(vty
);
10558 ret
= str2prefix(ip_str
, &p
);
10560 vty_out(vty
, "Malformed prefix\n");
10561 return CMD_WARNING_CONFIG_FAILED
;
10564 rn
= bgp_node_lookup(bgp_distance_table
[afi
][safi
],
10565 (struct prefix
*)&p
);
10567 vty_out(vty
, "Can't find specified prefix\n");
10568 return CMD_WARNING_CONFIG_FAILED
;
10571 bdistance
= rn
->info
;
10572 distance
= atoi(distance_str
);
10574 if (bdistance
->distance
!= distance
) {
10575 vty_out(vty
, "Distance does not match configured\n");
10576 return CMD_WARNING_CONFIG_FAILED
;
10579 if (bdistance
->access_list
)
10580 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10581 bgp_distance_free(bdistance
);
10584 bgp_unlock_node(rn
);
10585 bgp_unlock_node(rn
);
10587 return CMD_SUCCESS
;
10590 /* Apply BGP information to distance method. */
10591 u_char
bgp_distance_apply(struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
10592 safi_t safi
, struct bgp
*bgp
)
10594 struct bgp_node
*rn
;
10597 struct bgp_distance
*bdistance
;
10598 struct access_list
*alist
;
10599 struct bgp_static
*bgp_static
;
10604 peer
= rinfo
->peer
;
10606 /* Check source address. */
10607 sockunion2hostprefix(&peer
->su
, &q
);
10608 rn
= bgp_node_match(bgp_distance_table
[afi
][safi
], &q
);
10610 bdistance
= rn
->info
;
10611 bgp_unlock_node(rn
);
10613 if (bdistance
->access_list
) {
10614 alist
= access_list_lookup(afi
, bdistance
->access_list
);
10616 && access_list_apply(alist
, p
) == FILTER_PERMIT
)
10617 return bdistance
->distance
;
10619 return bdistance
->distance
;
10622 /* Backdoor check. */
10623 rn
= bgp_node_lookup(bgp
->route
[afi
][safi
], p
);
10625 bgp_static
= rn
->info
;
10626 bgp_unlock_node(rn
);
10628 if (bgp_static
->backdoor
) {
10629 if (bgp
->distance_local
[afi
][safi
])
10630 return bgp
->distance_local
[afi
][safi
];
10632 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10636 if (peer
->sort
== BGP_PEER_EBGP
) {
10637 if (bgp
->distance_ebgp
[afi
][safi
])
10638 return bgp
->distance_ebgp
[afi
][safi
];
10639 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
10641 if (bgp
->distance_ibgp
[afi
][safi
])
10642 return bgp
->distance_ibgp
[afi
][safi
];
10643 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10647 DEFUN (bgp_distance
,
10649 "distance bgp (1-255) (1-255) (1-255)",
10650 "Define an administrative distance\n"
10652 "Distance for routes external to the AS\n"
10653 "Distance for routes internal to the AS\n"
10654 "Distance for local routes\n")
10656 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10657 int idx_number
= 2;
10658 int idx_number_2
= 3;
10659 int idx_number_3
= 4;
10663 afi
= bgp_node_afi(vty
);
10664 safi
= bgp_node_safi(vty
);
10666 bgp
->distance_ebgp
[afi
][safi
] = atoi(argv
[idx_number
]->arg
);
10667 bgp
->distance_ibgp
[afi
][safi
] = atoi(argv
[idx_number_2
]->arg
);
10668 bgp
->distance_local
[afi
][safi
] = atoi(argv
[idx_number_3
]->arg
);
10669 return CMD_SUCCESS
;
10672 DEFUN (no_bgp_distance
,
10673 no_bgp_distance_cmd
,
10674 "no distance bgp [(1-255) (1-255) (1-255)]",
10676 "Define an administrative distance\n"
10678 "Distance for routes external to the AS\n"
10679 "Distance for routes internal to the AS\n"
10680 "Distance for local routes\n")
10682 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10686 afi
= bgp_node_afi(vty
);
10687 safi
= bgp_node_safi(vty
);
10689 bgp
->distance_ebgp
[afi
][safi
] = 0;
10690 bgp
->distance_ibgp
[afi
][safi
] = 0;
10691 bgp
->distance_local
[afi
][safi
] = 0;
10692 return CMD_SUCCESS
;
10696 DEFUN (bgp_distance_source
,
10697 bgp_distance_source_cmd
,
10698 "distance (1-255) A.B.C.D/M",
10699 "Define an administrative distance\n"
10700 "Administrative distance\n"
10701 "IP source prefix\n")
10703 int idx_number
= 1;
10704 int idx_ipv4_prefixlen
= 2;
10705 bgp_distance_set(vty
, argv
[idx_number
]->arg
,
10706 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10707 return CMD_SUCCESS
;
10710 DEFUN (no_bgp_distance_source
,
10711 no_bgp_distance_source_cmd
,
10712 "no distance (1-255) A.B.C.D/M",
10714 "Define an administrative distance\n"
10715 "Administrative distance\n"
10716 "IP source prefix\n")
10718 int idx_number
= 2;
10719 int idx_ipv4_prefixlen
= 3;
10720 bgp_distance_unset(vty
, argv
[idx_number
]->arg
,
10721 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10722 return CMD_SUCCESS
;
10725 DEFUN (bgp_distance_source_access_list
,
10726 bgp_distance_source_access_list_cmd
,
10727 "distance (1-255) A.B.C.D/M WORD",
10728 "Define an administrative distance\n"
10729 "Administrative distance\n"
10730 "IP source prefix\n"
10731 "Access list name\n")
10733 int idx_number
= 1;
10734 int idx_ipv4_prefixlen
= 2;
10736 bgp_distance_set(vty
, argv
[idx_number
]->arg
,
10737 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10738 return CMD_SUCCESS
;
10741 DEFUN (no_bgp_distance_source_access_list
,
10742 no_bgp_distance_source_access_list_cmd
,
10743 "no distance (1-255) A.B.C.D/M WORD",
10745 "Define an administrative distance\n"
10746 "Administrative distance\n"
10747 "IP source prefix\n"
10748 "Access list name\n")
10750 int idx_number
= 2;
10751 int idx_ipv4_prefixlen
= 3;
10753 bgp_distance_unset(vty
, argv
[idx_number
]->arg
,
10754 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10755 return CMD_SUCCESS
;
10758 DEFUN (ipv6_bgp_distance_source
,
10759 ipv6_bgp_distance_source_cmd
,
10760 "distance (1-255) X:X::X:X/M",
10761 "Define an administrative distance\n"
10762 "Administrative distance\n"
10763 "IP source prefix\n")
10765 bgp_distance_set(vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
10766 return CMD_SUCCESS
;
10769 DEFUN (no_ipv6_bgp_distance_source
,
10770 no_ipv6_bgp_distance_source_cmd
,
10771 "no distance (1-255) X:X::X:X/M",
10773 "Define an administrative distance\n"
10774 "Administrative distance\n"
10775 "IP source prefix\n")
10777 bgp_distance_unset(vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10778 return CMD_SUCCESS
;
10781 DEFUN (ipv6_bgp_distance_source_access_list
,
10782 ipv6_bgp_distance_source_access_list_cmd
,
10783 "distance (1-255) X:X::X:X/M WORD",
10784 "Define an administrative distance\n"
10785 "Administrative distance\n"
10786 "IP source prefix\n"
10787 "Access list name\n")
10789 bgp_distance_set(vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10790 return CMD_SUCCESS
;
10793 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10794 no_ipv6_bgp_distance_source_access_list_cmd
,
10795 "no distance (1-255) X:X::X:X/M WORD",
10797 "Define an administrative distance\n"
10798 "Administrative distance\n"
10799 "IP source prefix\n"
10800 "Access list name\n")
10802 bgp_distance_unset(vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10803 return CMD_SUCCESS
;
10806 DEFUN (bgp_damp_set
,
10808 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10809 "BGP Specific commands\n"
10810 "Enable route-flap dampening\n"
10811 "Half-life time for the penalty\n"
10812 "Value to start reusing a route\n"
10813 "Value to start suppressing a route\n"
10814 "Maximum duration to suppress a stable route\n")
10816 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10817 int idx_half_life
= 2;
10819 int idx_suppress
= 4;
10820 int idx_max_suppress
= 5;
10821 int half
= DEFAULT_HALF_LIFE
* 60;
10822 int reuse
= DEFAULT_REUSE
;
10823 int suppress
= DEFAULT_SUPPRESS
;
10824 int max
= 4 * half
;
10827 half
= atoi(argv
[idx_half_life
]->arg
) * 60;
10828 reuse
= atoi(argv
[idx_reuse
]->arg
);
10829 suppress
= atoi(argv
[idx_suppress
]->arg
);
10830 max
= atoi(argv
[idx_max_suppress
]->arg
) * 60;
10831 } else if (argc
== 3) {
10832 half
= atoi(argv
[idx_half_life
]->arg
) * 60;
10836 if (suppress
< reuse
) {
10838 "Suppress value cannot be less than reuse value \n");
10842 return bgp_damp_enable(bgp
, bgp_node_afi(vty
), bgp_node_safi(vty
), half
,
10843 reuse
, suppress
, max
);
10846 DEFUN (bgp_damp_unset
,
10847 bgp_damp_unset_cmd
,
10848 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10850 "BGP Specific commands\n"
10851 "Enable route-flap dampening\n"
10852 "Half-life time for the penalty\n"
10853 "Value to start reusing a route\n"
10854 "Value to start suppressing a route\n"
10855 "Maximum duration to suppress a stable route\n")
10857 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10858 return bgp_damp_disable(bgp
, bgp_node_afi(vty
), bgp_node_safi(vty
));
10861 /* Display specified route of BGP table. */
10862 static int bgp_clear_damp_route(struct vty
*vty
, const char *view_name
,
10863 const char *ip_str
, afi_t afi
, safi_t safi
,
10864 struct prefix_rd
*prd
, int prefix_check
)
10867 struct prefix match
;
10868 struct bgp_node
*rn
;
10869 struct bgp_node
*rm
;
10870 struct bgp_info
*ri
;
10871 struct bgp_info
*ri_temp
;
10873 struct bgp_table
*table
;
10875 /* BGP structure lookup. */
10877 bgp
= bgp_lookup_by_name(view_name
);
10879 vty_out(vty
, "%% Can't find BGP instance %s\n",
10881 return CMD_WARNING
;
10884 bgp
= bgp_get_default();
10886 vty_out(vty
, "%% No BGP process is configured\n");
10887 return CMD_WARNING
;
10891 /* Check IP address argument. */
10892 ret
= str2prefix(ip_str
, &match
);
10894 vty_out(vty
, "%% address is malformed\n");
10895 return CMD_WARNING
;
10898 match
.family
= afi2family(afi
);
10900 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
10901 || (safi
== SAFI_EVPN
)) {
10902 for (rn
= bgp_table_top(bgp
->rib
[AFI_IP
][safi
]); rn
;
10903 rn
= bgp_route_next(rn
)) {
10904 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
10906 if ((table
= rn
->info
) == NULL
)
10908 if ((rm
= bgp_node_match(table
, &match
)) == NULL
)
10912 || rm
->p
.prefixlen
== match
.prefixlen
) {
10915 if (ri
->extra
&& ri
->extra
->damp_info
) {
10916 ri_temp
= ri
->next
;
10917 bgp_damp_info_free(
10918 ri
->extra
->damp_info
,
10926 bgp_unlock_node(rm
);
10929 if ((rn
= bgp_node_match(bgp
->rib
[afi
][safi
], &match
))
10932 || rn
->p
.prefixlen
== match
.prefixlen
) {
10935 if (ri
->extra
&& ri
->extra
->damp_info
) {
10936 ri_temp
= ri
->next
;
10937 bgp_damp_info_free(
10938 ri
->extra
->damp_info
,
10946 bgp_unlock_node(rn
);
10950 return CMD_SUCCESS
;
10953 DEFUN (clear_ip_bgp_dampening
,
10954 clear_ip_bgp_dampening_cmd
,
10955 "clear ip bgp dampening",
10959 "Clear route flap dampening information\n")
10961 bgp_damp_info_clean();
10962 return CMD_SUCCESS
;
10965 DEFUN (clear_ip_bgp_dampening_prefix
,
10966 clear_ip_bgp_dampening_prefix_cmd
,
10967 "clear ip bgp dampening A.B.C.D/M",
10971 "Clear route flap dampening information\n"
10974 int idx_ipv4_prefixlen
= 4;
10975 return bgp_clear_damp_route(vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
,
10976 AFI_IP
, SAFI_UNICAST
, NULL
, 1);
10979 DEFUN (clear_ip_bgp_dampening_address
,
10980 clear_ip_bgp_dampening_address_cmd
,
10981 "clear ip bgp dampening A.B.C.D",
10985 "Clear route flap dampening information\n"
10986 "Network to clear damping information\n")
10989 return bgp_clear_damp_route(vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
10990 SAFI_UNICAST
, NULL
, 0);
10993 DEFUN (clear_ip_bgp_dampening_address_mask
,
10994 clear_ip_bgp_dampening_address_mask_cmd
,
10995 "clear ip bgp dampening A.B.C.D A.B.C.D",
10999 "Clear route flap dampening information\n"
11000 "Network to clear damping information\n"
11004 int idx_ipv4_2
= 5;
11006 char prefix_str
[BUFSIZ
];
11008 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
,
11011 vty_out(vty
, "%% Inconsistent address and mask\n");
11012 return CMD_WARNING
;
11015 return bgp_clear_damp_route(vty
, NULL
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
11019 /* also used for encap safi */
11020 static void bgp_config_write_network_vpn(struct vty
*vty
, struct bgp
*bgp
,
11021 afi_t afi
, safi_t safi
)
11023 struct bgp_node
*prn
;
11024 struct bgp_node
*rn
;
11025 struct bgp_table
*table
;
11027 struct prefix_rd
*prd
;
11028 struct bgp_static
*bgp_static
;
11029 mpls_label_t label
;
11030 char buf
[SU_ADDRSTRLEN
];
11031 char rdbuf
[RD_ADDRSTRLEN
];
11033 /* Network configuration. */
11034 for (prn
= bgp_table_top(bgp
->route
[afi
][safi
]); prn
;
11035 prn
= bgp_route_next(prn
)) {
11036 if ((table
= prn
->info
) == NULL
)
11039 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
11040 if ((bgp_static
= rn
->info
) == NULL
)
11044 prd
= (struct prefix_rd
*)&prn
->p
;
11046 /* "network" configuration display. */
11047 prefix_rd2str(prd
, rdbuf
, sizeof(rdbuf
));
11048 label
= decode_label(&bgp_static
->label
);
11050 vty_out(vty
, " network %s/%d rd %s",
11051 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11053 p
->prefixlen
, rdbuf
);
11054 if (safi
== SAFI_MPLS_VPN
)
11055 vty_out(vty
, " label %u", label
);
11057 if (bgp_static
->rmap
.name
)
11058 vty_out(vty
, " route-map %s",
11059 bgp_static
->rmap
.name
);
11061 if (bgp_static
->backdoor
)
11062 vty_out(vty
, " backdoor");
11064 vty_out(vty
, "\n");
11069 static void bgp_config_write_network_evpn(struct vty
*vty
, struct bgp
*bgp
,
11070 afi_t afi
, safi_t safi
)
11072 struct bgp_node
*prn
;
11073 struct bgp_node
*rn
;
11074 struct bgp_table
*table
;
11076 struct prefix_rd
*prd
;
11077 struct bgp_static
*bgp_static
;
11078 char buf
[PREFIX_STRLEN
];
11079 char buf2
[SU_ADDRSTRLEN
];
11080 char rdbuf
[RD_ADDRSTRLEN
];
11082 /* Network configuration. */
11083 for (prn
= bgp_table_top(bgp
->route
[afi
][safi
]); prn
;
11084 prn
= bgp_route_next(prn
)) {
11085 if ((table
= prn
->info
) == NULL
)
11088 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
11089 if ((bgp_static
= rn
->info
) == NULL
)
11092 char *macrouter
= NULL
;
11095 if (bgp_static
->router_mac
)
11096 macrouter
= prefix_mac2str(
11097 bgp_static
->router_mac
, NULL
, 0);
11098 if (bgp_static
->eth_s_id
)
11099 esi
= esi2str(bgp_static
->eth_s_id
);
11101 prd
= (struct prefix_rd
*)&prn
->p
;
11103 /* "network" configuration display. */
11104 prefix_rd2str(prd
, rdbuf
, sizeof(rdbuf
));
11105 if (p
->u
.prefix_evpn
.route_type
== 5) {
11106 char local_buf
[PREFIX_STRLEN
];
11107 uint8_t family
= IS_EVPN_PREFIX_IPADDR_V4((
11108 struct prefix_evpn
*)p
)
11111 inet_ntop(family
, &p
->u
.prefix_evpn
.ip
.ip
.addr
,
11112 local_buf
, PREFIX_STRLEN
);
11113 sprintf(buf
, "%s/%u", local_buf
,
11114 p
->u
.prefix_evpn
.ip_prefix_length
);
11116 prefix2str(p
, buf
, sizeof(buf
));
11119 if (bgp_static
->gatewayIp
.family
== AF_INET
11120 || bgp_static
->gatewayIp
.family
== AF_INET6
)
11121 inet_ntop(bgp_static
->gatewayIp
.family
,
11122 &bgp_static
->gatewayIp
.u
.prefix
, buf2
,
11125 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
11126 buf
, rdbuf
, p
->u
.prefix_evpn
.eth_tag
,
11127 decode_label(&bgp_static
->label
), esi
, buf2
,
11131 XFREE(MTYPE_TMP
, macrouter
);
11133 XFREE(MTYPE_TMP
, esi
);
11138 /* Configuration of static route announcement and aggregate
11140 void bgp_config_write_network(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
11143 struct bgp_node
*rn
;
11145 struct bgp_static
*bgp_static
;
11146 struct bgp_aggregate
*bgp_aggregate
;
11147 char buf
[SU_ADDRSTRLEN
];
11149 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)) {
11150 bgp_config_write_network_vpn(vty
, bgp
, afi
, safi
);
11154 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
11155 bgp_config_write_network_evpn(vty
, bgp
, afi
, safi
);
11159 /* Network configuration. */
11160 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
11161 rn
= bgp_route_next(rn
)) {
11162 if ((bgp_static
= rn
->info
) == NULL
)
11167 /* "network" configuration display. */
11168 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
) {
11169 u_int32_t destination
;
11170 struct in_addr netmask
;
11172 destination
= ntohl(p
->u
.prefix4
.s_addr
);
11173 masklen2ip(p
->prefixlen
, &netmask
);
11174 vty_out(vty
, " network %s",
11175 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11178 if ((IN_CLASSC(destination
) && p
->prefixlen
== 24)
11179 || (IN_CLASSB(destination
) && p
->prefixlen
== 16)
11180 || (IN_CLASSA(destination
) && p
->prefixlen
== 8)
11181 || p
->u
.prefix4
.s_addr
== 0) {
11182 /* Natural mask is not display. */
11184 vty_out(vty
, " mask %s", inet_ntoa(netmask
));
11186 vty_out(vty
, " network %s/%d",
11187 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11192 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
11193 vty_out(vty
, " label-index %u",
11194 bgp_static
->label_index
);
11196 if (bgp_static
->rmap
.name
)
11197 vty_out(vty
, " route-map %s", bgp_static
->rmap
.name
);
11199 if (bgp_static
->backdoor
)
11200 vty_out(vty
, " backdoor");
11202 vty_out(vty
, "\n");
11205 /* Aggregate-address configuration. */
11206 for (rn
= bgp_table_top(bgp
->aggregate
[afi
][safi
]); rn
;
11207 rn
= bgp_route_next(rn
)) {
11208 if ((bgp_aggregate
= rn
->info
) == NULL
)
11213 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
) {
11214 struct in_addr netmask
;
11216 masklen2ip(p
->prefixlen
, &netmask
);
11217 vty_out(vty
, " aggregate-address %s %s",
11218 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11220 inet_ntoa(netmask
));
11222 vty_out(vty
, " aggregate-address %s/%d",
11223 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11228 if (bgp_aggregate
->as_set
)
11229 vty_out(vty
, " as-set");
11231 if (bgp_aggregate
->summary_only
)
11232 vty_out(vty
, " summary-only");
11234 vty_out(vty
, "\n");
11238 void bgp_config_write_distance(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
11241 struct bgp_node
*rn
;
11242 struct bgp_distance
*bdistance
;
11244 /* Distance configuration. */
11245 if (bgp
->distance_ebgp
[afi
][safi
] && bgp
->distance_ibgp
[afi
][safi
]
11246 && bgp
->distance_local
[afi
][safi
]
11247 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
11248 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
11249 || bgp
->distance_local
[afi
][safi
]
11250 != ZEBRA_IBGP_DISTANCE_DEFAULT
)) {
11251 vty_out(vty
, " distance bgp %d %d %d\n",
11252 bgp
->distance_ebgp
[afi
][safi
],
11253 bgp
->distance_ibgp
[afi
][safi
],
11254 bgp
->distance_local
[afi
][safi
]);
11257 for (rn
= bgp_table_top(bgp_distance_table
[afi
][safi
]); rn
;
11258 rn
= bgp_route_next(rn
))
11259 if ((bdistance
= rn
->info
) != NULL
) {
11260 char buf
[PREFIX_STRLEN
];
11262 vty_out(vty
, " distance %d %s %s\n",
11263 bdistance
->distance
,
11264 prefix2str(&rn
->p
, buf
, sizeof(buf
)),
11265 bdistance
->access_list
? bdistance
->access_list
11270 /* Allocate routing table structure and install commands. */
11271 void bgp_route_init(void)
11276 /* Init BGP distance table. */
11277 FOREACH_AFI_SAFI (afi
, safi
)
11278 bgp_distance_table
[afi
][safi
] = bgp_table_init(afi
, safi
);
11280 /* IPv4 BGP commands. */
11281 install_element(BGP_NODE
, &bgp_table_map_cmd
);
11282 install_element(BGP_NODE
, &bgp_network_cmd
);
11283 install_element(BGP_NODE
, &no_bgp_table_map_cmd
);
11285 install_element(BGP_NODE
, &aggregate_address_cmd
);
11286 install_element(BGP_NODE
, &aggregate_address_mask_cmd
);
11287 install_element(BGP_NODE
, &no_aggregate_address_cmd
);
11288 install_element(BGP_NODE
, &no_aggregate_address_mask_cmd
);
11290 /* IPv4 unicast configuration. */
11291 install_element(BGP_IPV4_NODE
, &bgp_table_map_cmd
);
11292 install_element(BGP_IPV4_NODE
, &bgp_network_cmd
);
11293 install_element(BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
11295 install_element(BGP_IPV4_NODE
, &aggregate_address_cmd
);
11296 install_element(BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
11297 install_element(BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
11298 install_element(BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
11300 /* IPv4 multicast configuration. */
11301 install_element(BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
11302 install_element(BGP_IPV4M_NODE
, &bgp_network_cmd
);
11303 install_element(BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
11304 install_element(BGP_IPV4M_NODE
, &aggregate_address_cmd
);
11305 install_element(BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
11306 install_element(BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
11307 install_element(BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
11309 /* IPv4 labeled-unicast configuration. */
11310 install_element(VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
11311 install_element(VIEW_NODE
, &show_ip_bgp_cmd
);
11312 install_element(VIEW_NODE
, &show_ip_bgp_json_cmd
);
11313 install_element(VIEW_NODE
, &show_ip_bgp_route_cmd
);
11314 install_element(VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
11316 install_element(VIEW_NODE
,
11317 &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
11318 install_element(VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
11319 install_element(VIEW_NODE
,
11320 &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
11321 #ifdef KEEP_OLD_VPN_COMMANDS
11322 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
11323 #endif /* KEEP_OLD_VPN_COMMANDS */
11324 install_element(VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
11325 install_element(VIEW_NODE
,
11326 &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
);
11328 /* BGP dampening clear commands */
11329 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
11330 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
11332 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
11333 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
11336 install_element(ENABLE_NODE
,
11337 &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
11338 #ifdef KEEP_OLD_VPN_COMMANDS
11339 install_element(ENABLE_NODE
,
11340 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
11341 #endif /* KEEP_OLD_VPN_COMMANDS */
11343 /* New config IPv6 BGP commands. */
11344 install_element(BGP_IPV6_NODE
, &bgp_table_map_cmd
);
11345 install_element(BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
11346 install_element(BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
11348 install_element(BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
11349 install_element(BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
11351 install_element(BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
11353 install_element(BGP_NODE
, &bgp_distance_cmd
);
11354 install_element(BGP_NODE
, &no_bgp_distance_cmd
);
11355 install_element(BGP_NODE
, &bgp_distance_source_cmd
);
11356 install_element(BGP_NODE
, &no_bgp_distance_source_cmd
);
11357 install_element(BGP_NODE
, &bgp_distance_source_access_list_cmd
);
11358 install_element(BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
11359 install_element(BGP_IPV4_NODE
, &bgp_distance_cmd
);
11360 install_element(BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
11361 install_element(BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
11362 install_element(BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
11363 install_element(BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
11364 install_element(BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
11365 install_element(BGP_IPV4M_NODE
, &bgp_distance_cmd
);
11366 install_element(BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
11367 install_element(BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
11368 install_element(BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
11369 install_element(BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
11370 install_element(BGP_IPV4M_NODE
,
11371 &no_bgp_distance_source_access_list_cmd
);
11372 install_element(BGP_IPV6_NODE
, &bgp_distance_cmd
);
11373 install_element(BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
11374 install_element(BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
11375 install_element(BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11376 install_element(BGP_IPV6_NODE
,
11377 &ipv6_bgp_distance_source_access_list_cmd
);
11378 install_element(BGP_IPV6_NODE
,
11379 &no_ipv6_bgp_distance_source_access_list_cmd
);
11380 install_element(BGP_IPV6M_NODE
, &bgp_distance_cmd
);
11381 install_element(BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
11382 install_element(BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
11383 install_element(BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11384 install_element(BGP_IPV6M_NODE
,
11385 &ipv6_bgp_distance_source_access_list_cmd
);
11386 install_element(BGP_IPV6M_NODE
,
11387 &no_ipv6_bgp_distance_source_access_list_cmd
);
11389 install_element(BGP_NODE
, &bgp_damp_set_cmd
);
11390 install_element(BGP_NODE
, &bgp_damp_unset_cmd
);
11391 install_element(BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
11392 install_element(BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
11394 /* IPv4 Multicast Mode */
11395 install_element(BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
11396 install_element(BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
11398 /* Large Communities */
11399 install_element(VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
11400 install_element(VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
11403 void bgp_route_finish(void)
11408 FOREACH_AFI_SAFI (afi
, safi
) {
11409 bgp_table_unlock(bgp_distance_table
[afi
][safi
]);
11410 bgp_distance_table
[afi
][safi
] = NULL
;