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
, uint32_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 uint32_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
;
405 uint32_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
];
417 uint32_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(uint8_t 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 uint32_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
;
2101 * old_select = The old best path
2102 * new_select = the new best path
2104 * if (!old_select && new_select)
2105 * We are sending new information on.
2107 * if (old_select && new_select) {
2108 * if (new_select != old_select)
2109 * We have a new best path send a change
2111 * We've received a update with new attributes that needs
2115 * if (old_select && !new_select)
2116 * We have no eligible route that we can announce or the rn
2119 static void bgp_process_main_one(struct bgp
*bgp
, struct bgp_node
*rn
,
2120 afi_t afi
, safi_t safi
)
2122 struct prefix
*p
= &rn
->p
;
2123 struct bgp_info
*new_select
;
2124 struct bgp_info
*old_select
;
2125 struct bgp_info_pair old_and_new
;
2126 char pfx_buf
[PREFIX2STR_BUFFER
];
2129 /* Is it end of initial update? (after startup) */
2131 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
2132 sizeof(bgp
->update_delay_zebra_resume_time
));
2134 bgp
->main_zebra_update_hold
= 0;
2135 FOREACH_AFI_SAFI (afi
, safi
) {
2136 if (bgp_fibupd_safi(safi
))
2137 bgp_zebra_announce_table(bgp
, afi
, safi
);
2139 bgp
->main_peers_update_hold
= 0;
2141 bgp_start_routeadv(bgp
);
2145 debug
= bgp_debug_bestpath(&rn
->p
);
2147 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
2148 zlog_debug("%s: p=%s afi=%s, safi=%s start", __func__
, pfx_buf
,
2149 afi2str(afi
), safi2str(safi
));
2152 /* Best path selection. */
2153 bgp_best_selection(bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
,
2155 old_select
= old_and_new
.old
;
2156 new_select
= old_and_new
.new;
2158 /* Do we need to allocate or free labels?
2159 * Right now, since we only deal with per-prefix labels, it is not
2160 * necessary to do this upon changes to best path except if the label
2163 if (bgp
->allocate_mpls_labels
[afi
][safi
]) {
2166 || bgp_label_index_differs(new_select
, old_select
)
2167 || new_select
->sub_type
!= old_select
->sub_type
) {
2168 if (new_select
->sub_type
== BGP_ROUTE_STATIC
2169 && new_select
->attr
->flag
2171 BGP_ATTR_PREFIX_SID
)
2172 && new_select
->attr
->label_index
2173 != BGP_INVALID_LABEL_INDEX
) {
2176 BGP_NODE_REGISTERED_FOR_LABEL
))
2177 bgp_unregister_for_label(rn
);
2178 label_ntop(MPLS_LABEL_IMPLICIT_NULL
, 1,
2180 bgp_set_valid_label(&rn
->local_label
);
2182 bgp_register_for_label(rn
, new_select
);
2184 } else if (CHECK_FLAG(rn
->flags
,
2185 BGP_NODE_REGISTERED_FOR_LABEL
)) {
2186 bgp_unregister_for_label(rn
);
2188 } else if (CHECK_FLAG(rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
)) {
2189 bgp_unregister_for_label(rn
);
2193 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
2195 "%s: p=%s afi=%s, safi=%s, old_select=%p, new_select=%p",
2196 __func__
, pfx_buf
, afi2str(afi
), safi2str(safi
),
2197 old_select
, new_select
);
2200 /* If best route remains the same and this is not due to user-initiated
2201 * clear, see exactly what needs to be done.
2204 if (old_select
&& old_select
== new_select
2205 && !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
)
2206 && !CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
)
2207 && !bgp
->addpath_tx_used
[afi
][safi
]) {
2208 if (bgp_zebra_has_route_changed(rn
, old_select
)) {
2210 vnc_import_bgp_add_route(bgp
, p
, old_select
);
2211 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
2213 if (bgp_fibupd_safi(safi
)
2214 && !bgp_option_check(BGP_OPT_NO_FIB
)) {
2216 if (new_select
->type
== ZEBRA_ROUTE_BGP
2217 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
2218 || new_select
->sub_type
2219 == BGP_ROUTE_IMPORTED
))
2221 bgp_zebra_announce(rn
, p
, old_select
,
2225 UNSET_FLAG(old_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
2226 bgp_zebra_clear_route_change_flags(rn
);
2228 /* If there is a change of interest to peers, reannounce the
2230 if (CHECK_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
)
2231 || CHECK_FLAG(rn
->flags
, BGP_NODE_LABEL_CHANGED
)) {
2232 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2234 /* unicast routes must also be annouced to
2235 * labeled-unicast update-groups */
2236 if (safi
== SAFI_UNICAST
)
2237 group_announce_route(bgp
, afi
,
2238 SAFI_LABELED_UNICAST
, rn
,
2241 UNSET_FLAG(old_select
->flags
, BGP_INFO_ATTR_CHANGED
);
2242 UNSET_FLAG(rn
->flags
, BGP_NODE_LABEL_CHANGED
);
2245 UNSET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2249 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2251 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
2253 /* bestpath has changed; bump version */
2254 if (old_select
|| new_select
) {
2255 bgp_bump_version(rn
);
2257 if (!bgp
->t_rmap_def_originate_eval
) {
2261 update_group_refresh_default_originate_route_map
,
2262 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
,
2263 &bgp
->t_rmap_def_originate_eval
);
2268 bgp_info_unset_flag(rn
, old_select
, BGP_INFO_SELECTED
);
2271 zlog_debug("%s: setting SELECTED flag", __func__
);
2272 bgp_info_set_flag(rn
, new_select
, BGP_INFO_SELECTED
);
2273 bgp_info_unset_flag(rn
, new_select
, BGP_INFO_ATTR_CHANGED
);
2274 UNSET_FLAG(new_select
->flags
, BGP_INFO_MULTIPATH_CHG
);
2278 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2279 if (old_select
!= new_select
) {
2281 vnc_import_bgp_exterior_del_route(bgp
, p
,
2283 vnc_import_bgp_del_route(bgp
, p
, old_select
);
2286 vnc_import_bgp_exterior_add_route(bgp
, p
,
2288 vnc_import_bgp_add_route(bgp
, p
, new_select
);
2294 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2296 /* unicast routes must also be annouced to labeled-unicast update-groups
2298 if (safi
== SAFI_UNICAST
)
2299 group_announce_route(bgp
, afi
, SAFI_LABELED_UNICAST
, rn
,
2303 if (bgp_fibupd_safi(safi
) && (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
2304 && !bgp_option_check(BGP_OPT_NO_FIB
)) {
2305 if (new_select
&& new_select
->type
== ZEBRA_ROUTE_BGP
2306 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
2307 || new_select
->sub_type
== BGP_ROUTE_AGGREGATE
2308 || new_select
->sub_type
== BGP_ROUTE_IMPORTED
))
2310 bgp_zebra_announce(rn
, p
, new_select
, bgp
, afi
, safi
);
2312 /* Withdraw the route from the kernel. */
2313 if (old_select
&& old_select
->type
== ZEBRA_ROUTE_BGP
2314 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
2315 || old_select
->sub_type
== BGP_ROUTE_AGGREGATE
2316 || old_select
->sub_type
== BGP_ROUTE_IMPORTED
))
2318 bgp_zebra_withdraw(p
, old_select
, bgp
, safi
);
2322 /* advertise/withdraw type-5 routes */
2323 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2324 if (advertise_type5_routes(bgp
, afi
) && new_select
&&
2325 (!new_select
->extra
|| !new_select
->extra
->parent
))
2326 bgp_evpn_advertise_type5_route(bgp
, &rn
->p
,
2329 else if (advertise_type5_routes(bgp
, afi
) && old_select
&&
2330 (!old_select
->extra
|| !old_select
->extra
->parent
))
2331 bgp_evpn_withdraw_type5_route(bgp
, &rn
->p
, afi
, safi
);
2334 /* Clear any route change flags. */
2335 bgp_zebra_clear_route_change_flags(rn
);
2337 /* Reap old select bgp_info, if it has been removed */
2338 if (old_select
&& CHECK_FLAG(old_select
->flags
, BGP_INFO_REMOVED
))
2339 bgp_info_reap(rn
, old_select
);
2341 UNSET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2345 static wq_item_status
bgp_process_wq(struct work_queue
*wq
, void *data
)
2347 struct bgp_process_queue
*pqnode
= data
;
2348 struct bgp
*bgp
= pqnode
->bgp
;
2349 struct bgp_table
*table
;
2350 struct bgp_node
*rn
;
2353 if (CHECK_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
)) {
2354 bgp_process_main_one(bgp
, NULL
, 0, 0);
2355 /* should always have dedicated wq call */
2356 assert(STAILQ_FIRST(&pqnode
->pqueue
) == NULL
);
2360 while (!STAILQ_EMPTY(&pqnode
->pqueue
)) {
2361 rn
= STAILQ_FIRST(&pqnode
->pqueue
);
2362 STAILQ_REMOVE_HEAD(&pqnode
->pqueue
, pq
);
2363 STAILQ_NEXT(rn
, pq
) = NULL
; /* complete unlink */
2364 table
= bgp_node_table(rn
);
2365 /* note, new RNs may be added as part of processing */
2366 bgp_process_main_one(bgp
, rn
, table
->afi
, table
->safi
);
2368 bgp_unlock_node(rn
);
2369 bgp_table_unlock(table
);
2375 static void bgp_processq_del(struct work_queue
*wq
, void *data
)
2377 struct bgp_process_queue
*pqnode
= data
;
2379 bgp_unlock(pqnode
->bgp
);
2381 XFREE(MTYPE_BGP_PROCESS_QUEUE
, pqnode
);
2384 void bgp_process_queue_init(void)
2386 if (!bm
->process_main_queue
) {
2387 bm
->process_main_queue
=
2388 work_queue_new(bm
->master
, "process_main_queue");
2390 if (!bm
->process_main_queue
) {
2391 zlog_err("%s: Failed to allocate work queue", __func__
);
2396 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_wq
;
2397 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2398 bm
->process_main_queue
->spec
.max_retries
= 0;
2399 bm
->process_main_queue
->spec
.hold
= 50;
2400 /* Use a higher yield value of 50ms for main queue processing */
2401 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2404 static struct bgp_process_queue
*bgp_processq_alloc(struct bgp
*bgp
)
2406 struct bgp_process_queue
*pqnode
;
2408 pqnode
= XCALLOC(MTYPE_BGP_PROCESS_QUEUE
,
2409 sizeof(struct bgp_process_queue
));
2411 /* unlocked in bgp_processq_del */
2412 pqnode
->bgp
= bgp_lock(bgp
);
2413 STAILQ_INIT(&pqnode
->pqueue
);
2418 void bgp_process(struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2420 #define ARBITRARY_PROCESS_QLEN 10000
2421 struct work_queue
*wq
= bm
->process_main_queue
;
2422 struct bgp_process_queue
*pqnode
;
2423 int pqnode_reuse
= 0;
2425 /* already scheduled for processing? */
2426 if (CHECK_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2432 /* Add route nodes to an existing work queue item until reaching the
2433 limit only if is from the same BGP view and it's not an EOIU marker
2435 if (work_queue_item_count(wq
)) {
2436 struct work_queue_item
*item
= work_queue_last_item(wq
);
2437 pqnode
= item
->data
;
2439 if (CHECK_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
)
2440 || pqnode
->bgp
!= bgp
2441 || pqnode
->queued
>= ARBITRARY_PROCESS_QLEN
)
2442 pqnode
= bgp_processq_alloc(bgp
);
2446 pqnode
= bgp_processq_alloc(bgp
);
2447 /* all unlocked in bgp_process_wq */
2448 bgp_table_lock(bgp_node_table(rn
));
2450 SET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2453 /* can't be enqueued twice */
2454 assert(STAILQ_NEXT(rn
, pq
) == NULL
);
2455 STAILQ_INSERT_TAIL(&pqnode
->pqueue
, rn
, pq
);
2459 work_queue_add(wq
, pqnode
);
2464 void bgp_add_eoiu_mark(struct bgp
*bgp
)
2466 struct bgp_process_queue
*pqnode
;
2468 if (bm
->process_main_queue
== NULL
)
2471 pqnode
= bgp_processq_alloc(bgp
);
2473 SET_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
);
2474 work_queue_add(bm
->process_main_queue
, pqnode
);
2477 static int bgp_maximum_prefix_restart_timer(struct thread
*thread
)
2481 peer
= THREAD_ARG(thread
);
2482 peer
->t_pmax_restart
= NULL
;
2484 if (bgp_debug_neighbor_events(peer
))
2486 "%s Maximum-prefix restart timer expired, restore peering",
2489 peer_clear(peer
, NULL
);
2494 int bgp_maximum_prefix_overflow(struct peer
*peer
, afi_t afi
, safi_t safi
,
2498 iana_safi_t pkt_safi
;
2500 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2503 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
]) {
2504 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2505 PEER_STATUS_PREFIX_LIMIT
)
2510 "%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2512 afi_safi_print(afi
, safi
), peer
->host
,
2513 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2514 SET_FLAG(peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2516 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
2517 PEER_FLAG_MAX_PREFIX_WARNING
))
2520 /* Convert AFI, SAFI to values for packet. */
2521 pkt_afi
= afi_int2iana(afi
);
2522 pkt_safi
= safi_int2iana(safi
);
2526 ndata
[0] = (pkt_afi
>> 8);
2528 ndata
[2] = pkt_safi
;
2529 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2530 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2531 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2532 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2534 SET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2535 bgp_notify_send_with_data(peer
, BGP_NOTIFY_CEASE
,
2536 BGP_NOTIFY_CEASE_MAX_PREFIX
,
2540 /* Dynamic peers will just close their connection. */
2541 if (peer_dynamic_neighbor(peer
))
2544 /* restart timer start */
2545 if (peer
->pmax_restart
[afi
][safi
]) {
2546 peer
->v_pmax_restart
=
2547 peer
->pmax_restart
[afi
][safi
] * 60;
2549 if (bgp_debug_neighbor_events(peer
))
2551 "%s Maximum-prefix restart timer started for %d secs",
2552 peer
->host
, peer
->v_pmax_restart
);
2554 BGP_TIMER_ON(peer
->t_pmax_restart
,
2555 bgp_maximum_prefix_restart_timer
,
2556 peer
->v_pmax_restart
);
2561 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2562 PEER_STATUS_PREFIX_LIMIT
);
2564 if (peer
->pcount
[afi
][safi
]
2565 > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100)) {
2566 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2567 PEER_STATUS_PREFIX_THRESHOLD
)
2572 "%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2573 afi_safi_print(afi
, safi
), peer
->host
,
2574 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2575 SET_FLAG(peer
->af_sflags
[afi
][safi
],
2576 PEER_STATUS_PREFIX_THRESHOLD
);
2578 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2579 PEER_STATUS_PREFIX_THRESHOLD
);
2583 /* Unconditionally remove the route from the RIB, without taking
2584 * damping into consideration (eg, because the session went down)
2586 void bgp_rib_remove(struct bgp_node
*rn
, struct bgp_info
*ri
, struct peer
*peer
,
2587 afi_t afi
, safi_t safi
)
2589 bgp_aggregate_decrement(peer
->bgp
, &rn
->p
, ri
, afi
, safi
);
2591 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
2592 bgp_info_delete(rn
, ri
); /* keep historical info */
2594 bgp_process(peer
->bgp
, rn
, afi
, safi
);
2597 static void bgp_rib_withdraw(struct bgp_node
*rn
, struct bgp_info
*ri
,
2598 struct peer
*peer
, afi_t afi
, safi_t safi
,
2599 struct prefix_rd
*prd
)
2601 int status
= BGP_DAMP_NONE
;
2603 /* apply dampening, if result is suppressed, we'll be retaining
2604 * the bgp_info in the RIB for historical reference.
2606 if (CHECK_FLAG(peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2607 && peer
->sort
== BGP_PEER_EBGP
)
2608 if ((status
= bgp_damp_withdraw(ri
, rn
, afi
, safi
, 0))
2609 == BGP_DAMP_SUPPRESSED
) {
2610 bgp_aggregate_decrement(peer
->bgp
, &rn
->p
, ri
, afi
,
2616 if (safi
== SAFI_MPLS_VPN
) {
2617 struct bgp_node
*prn
= NULL
;
2618 struct bgp_table
*table
= NULL
;
2620 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
],
2621 (struct prefix
*)prd
);
2623 table
= (struct bgp_table
*)(prn
->info
);
2625 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2626 peer
->bgp
, prd
, table
, &rn
->p
, ri
);
2628 bgp_unlock_node(prn
);
2630 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2631 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
2633 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, ri
);
2634 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
,
2640 /* If this is an EVPN route, process for un-import. */
2641 if (safi
== SAFI_EVPN
)
2642 bgp_evpn_unimport_route(peer
->bgp
, afi
, safi
, &rn
->p
, ri
);
2644 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
2647 struct bgp_info
*info_make(int type
, int sub_type
, unsigned short instance
,
2648 struct peer
*peer
, struct attr
*attr
,
2649 struct bgp_node
*rn
)
2651 struct bgp_info
*new;
2653 /* Make new BGP info. */
2654 new = XCALLOC(MTYPE_BGP_ROUTE
, sizeof(struct bgp_info
));
2656 new->instance
= instance
;
2657 new->sub_type
= sub_type
;
2660 new->uptime
= bgp_clock();
2662 new->addpath_tx_id
= ++peer
->bgp
->addpath_tx_id
;
2666 static void overlay_index_update(struct attr
*attr
,
2667 struct eth_segment_id
*eth_s_id
,
2668 union gw_addr
*gw_ip
)
2673 if (eth_s_id
== NULL
) {
2674 memset(&(attr
->evpn_overlay
.eth_s_id
), 0,
2675 sizeof(struct eth_segment_id
));
2677 memcpy(&(attr
->evpn_overlay
.eth_s_id
), eth_s_id
,
2678 sizeof(struct eth_segment_id
));
2680 if (gw_ip
== NULL
) {
2681 memset(&(attr
->evpn_overlay
.gw_ip
), 0, sizeof(union gw_addr
));
2683 memcpy(&(attr
->evpn_overlay
.gw_ip
), gw_ip
,
2684 sizeof(union gw_addr
));
2688 static bool overlay_index_equal(afi_t afi
, struct bgp_info
*info
,
2689 struct eth_segment_id
*eth_s_id
,
2690 union gw_addr
*gw_ip
)
2692 struct eth_segment_id
*info_eth_s_id
, *info_eth_s_id_remote
;
2693 union gw_addr
*info_gw_ip
, *info_gw_ip_remote
;
2696 if (afi
!= AFI_L2VPN
)
2699 memset(&temp
, 0, 16);
2700 info_eth_s_id
= (struct eth_segment_id
*)&temp
;
2701 info_gw_ip
= (union gw_addr
*)&temp
;
2702 if (eth_s_id
== NULL
&& gw_ip
== NULL
)
2705 info_eth_s_id
= &(info
->attr
->evpn_overlay
.eth_s_id
);
2706 info_gw_ip
= &(info
->attr
->evpn_overlay
.gw_ip
);
2709 info_gw_ip_remote
= (union gw_addr
*)&temp
;
2711 info_gw_ip_remote
= gw_ip
;
2712 if (eth_s_id
== NULL
)
2713 info_eth_s_id_remote
= (struct eth_segment_id
*)&temp
;
2715 info_eth_s_id_remote
= eth_s_id
;
2716 if (!memcmp(info_gw_ip
, info_gw_ip_remote
, sizeof(union gw_addr
)))
2718 return !memcmp(info_eth_s_id
, info_eth_s_id_remote
,
2719 sizeof(struct eth_segment_id
));
2722 /* Check if received nexthop is valid or not. */
2723 static int bgp_update_martian_nexthop(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
2728 /* Only validated for unicast and multicast currently. */
2729 /* Also valid for EVPN where the nexthop is an IP address. */
2730 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
&& safi
!= SAFI_EVPN
)
2733 /* If NEXT_HOP is present, validate it. */
2734 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
)) {
2735 if (attr
->nexthop
.s_addr
== 0
2736 || IPV4_CLASS_DE(ntohl(attr
->nexthop
.s_addr
))
2737 || bgp_nexthop_self(bgp
, attr
->nexthop
))
2741 /* If MP_NEXTHOP is present, validate it. */
2742 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2743 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2744 * it is not an IPv6 link-local address.
2746 if (attr
->mp_nexthop_len
) {
2747 switch (attr
->mp_nexthop_len
) {
2748 case BGP_ATTR_NHLEN_IPV4
:
2749 case BGP_ATTR_NHLEN_VPNV4
:
2750 ret
= (attr
->mp_nexthop_global_in
.s_addr
== 0
2751 || IPV4_CLASS_DE(ntohl(
2752 attr
->mp_nexthop_global_in
.s_addr
))
2753 || bgp_nexthop_self(bgp
,
2754 attr
->mp_nexthop_global_in
));
2757 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2758 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2759 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2760 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attr
->mp_nexthop_global
)
2761 || IN6_IS_ADDR_LOOPBACK(&attr
->mp_nexthop_global
)
2762 || IN6_IS_ADDR_MULTICAST(
2763 &attr
->mp_nexthop_global
));
2775 int bgp_update(struct peer
*peer
, struct prefix
*p
, uint32_t addpath_id
,
2776 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2777 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
2778 uint32_t num_labels
, int soft_reconfig
,
2779 struct bgp_route_evpn
*evpn
)
2782 int aspath_loop_count
= 0;
2783 struct bgp_node
*rn
;
2785 struct attr new_attr
;
2786 struct attr
*attr_new
;
2787 struct bgp_info
*ri
;
2788 struct bgp_info
*new;
2789 struct bgp_info_extra
*extra
;
2791 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2793 int do_loop_check
= 1;
2794 int has_valid_label
= 0;
2796 int vnc_implicit_withdraw
= 0;
2800 memset(&new_attr
, 0, sizeof(struct attr
));
2801 new_attr
.label_index
= BGP_INVALID_LABEL_INDEX
;
2802 new_attr
.label
= MPLS_INVALID_LABEL
;
2805 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2806 /* TODO: Check to see if we can get rid of "is_valid_label" */
2807 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
2808 has_valid_label
= (num_labels
> 0) ? 1 : 0;
2810 has_valid_label
= bgp_is_valid_label(label
);
2812 /* When peer's soft reconfiguration enabled. Record input packet in
2815 && CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2816 && peer
!= bgp
->peer_self
)
2817 bgp_adj_in_set(rn
, peer
, attr
, addpath_id
);
2819 /* Check previously received route. */
2820 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
2821 if (ri
->peer
== peer
&& ri
->type
== type
2822 && ri
->sub_type
== sub_type
2823 && ri
->addpath_rx_id
== addpath_id
)
2826 /* AS path local-as loop check. */
2827 if (peer
->change_local_as
) {
2828 if (peer
->allowas_in
[afi
][safi
])
2829 aspath_loop_count
= peer
->allowas_in
[afi
][safi
];
2830 else if (!CHECK_FLAG(peer
->flags
,
2831 PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2832 aspath_loop_count
= 1;
2834 if (aspath_loop_check(attr
->aspath
, peer
->change_local_as
)
2835 > aspath_loop_count
) {
2836 reason
= "as-path contains our own AS;";
2841 /* If the peer is configured for "allowas-in origin" and the last ASN in
2843 * as-path is our ASN then we do not need to call aspath_loop_check
2845 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2846 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2849 /* AS path loop check. */
2850 if (do_loop_check
) {
2851 if (aspath_loop_check(attr
->aspath
, bgp
->as
)
2852 > peer
->allowas_in
[afi
][safi
]
2853 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2854 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
)
2855 > peer
->allowas_in
[afi
][safi
])) {
2856 reason
= "as-path contains our own AS;";
2861 /* Route reflector originator ID check. */
2862 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)
2863 && IPV4_ADDR_SAME(&bgp
->router_id
, &attr
->originator_id
)) {
2864 reason
= "originator is us;";
2868 /* Route reflector cluster ID check. */
2869 if (bgp_cluster_filter(peer
, attr
)) {
2870 reason
= "reflected from the same cluster;";
2874 /* Apply incoming filter. */
2875 if (bgp_input_filter(peer
, p
, attr
, afi
, safi
) == FILTER_DENY
) {
2880 bgp_attr_dup(&new_attr
, attr
);
2882 /* Apply incoming route-map.
2883 * NB: new_attr may now contain newly allocated values from route-map
2885 * commands, so we need bgp_attr_flush in the error paths, until we
2887 * the attr (which takes over the memory references) */
2888 if (bgp_input_modifier(peer
, p
, &new_attr
, afi
, safi
, NULL
)
2890 reason
= "route-map;";
2891 bgp_attr_flush(&new_attr
);
2895 if (peer
->sort
== BGP_PEER_EBGP
) {
2897 /* If we receive the graceful-shutdown community from an eBGP
2898 * peer we must lower local-preference */
2899 if (new_attr
.community
2900 && community_include(new_attr
.community
, COMMUNITY_GSHUT
)) {
2901 new_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
2902 new_attr
.local_pref
= BGP_GSHUT_LOCAL_PREF
;
2904 /* If graceful-shutdown is configured then add the GSHUT
2905 * community to all paths received from eBGP peers */
2906 } else if (bgp_flag_check(peer
->bgp
,
2907 BGP_FLAG_GRACEFUL_SHUTDOWN
)) {
2908 bgp_attr_add_gshut_community(&new_attr
);
2912 /* next hop check. */
2913 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
)
2914 && bgp_update_martian_nexthop(bgp
, afi
, safi
, &new_attr
)) {
2915 reason
= "martian or self next-hop;";
2916 bgp_attr_flush(&new_attr
);
2920 attr_new
= bgp_attr_intern(&new_attr
);
2922 /* If the update is implicit withdraw. */
2924 ri
->uptime
= bgp_clock();
2925 same_attr
= attrhash_cmp(ri
->attr
, attr_new
);
2927 /* Same attribute comes in. */
2928 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)
2929 && attrhash_cmp(ri
->attr
, attr_new
)
2930 && (!has_valid_label
2931 || memcmp(&(bgp_info_extra_get(ri
))->label
, label
,
2932 num_labels
* sizeof(mpls_label_t
))
2934 && (overlay_index_equal(
2935 afi
, ri
, evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
2936 evpn
== NULL
? NULL
: &evpn
->gw_ip
))) {
2937 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
2938 BGP_CONFIG_DAMPENING
)
2939 && peer
->sort
== BGP_PEER_EBGP
2940 && CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
)) {
2941 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2942 bgp_debug_rdpfxpath2str(
2943 afi
, safi
, prd
, p
, label
,
2944 num_labels
, addpath_id
? 1 : 0,
2945 addpath_id
, pfx_buf
,
2947 zlog_debug("%s rcvd %s", peer
->host
,
2951 if (bgp_damp_update(ri
, rn
, afi
, safi
)
2952 != BGP_DAMP_SUPPRESSED
) {
2953 bgp_aggregate_increment(bgp
, p
, ri
, afi
,
2955 bgp_process(bgp
, rn
, afi
, safi
);
2957 } else /* Duplicate - odd */
2959 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2960 if (!peer
->rcvd_attr_printed
) {
2962 "%s rcvd UPDATE w/ attr: %s",
2964 peer
->rcvd_attr_str
);
2965 peer
->rcvd_attr_printed
= 1;
2968 bgp_debug_rdpfxpath2str(
2969 afi
, safi
, prd
, p
, label
,
2970 num_labels
, addpath_id
? 1 : 0,
2971 addpath_id
, pfx_buf
,
2974 "%s rcvd %s...duplicate ignored",
2975 peer
->host
, pfx_buf
);
2978 /* graceful restart STALE flag unset. */
2979 if (CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
)) {
2980 bgp_info_unset_flag(rn
, ri
,
2982 bgp_process(bgp
, rn
, afi
, safi
);
2986 bgp_unlock_node(rn
);
2987 bgp_attr_unintern(&attr_new
);
2992 /* Withdraw/Announce before we fully processed the withdraw */
2993 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
2994 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
2995 bgp_debug_rdpfxpath2str(
2996 afi
, safi
, prd
, p
, label
, num_labels
,
2997 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3000 "%s rcvd %s, flapped quicker than processing",
3001 peer
->host
, pfx_buf
);
3004 bgp_info_restore(rn
, ri
);
3007 /* Received Logging. */
3008 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3009 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
,
3010 num_labels
, addpath_id
? 1 : 0,
3011 addpath_id
, pfx_buf
,
3013 zlog_debug("%s rcvd %s", peer
->host
, pfx_buf
);
3016 /* graceful restart STALE flag unset. */
3017 if (CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
))
3018 bgp_info_unset_flag(rn
, ri
, BGP_INFO_STALE
);
3020 /* The attribute is changed. */
3021 bgp_info_set_flag(rn
, ri
, BGP_INFO_ATTR_CHANGED
);
3023 /* implicit withdraw, decrement aggregate and pcount here.
3024 * only if update is accepted, they'll increment below.
3026 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
3028 /* Update bgp route dampening information. */
3029 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
3030 && peer
->sort
== BGP_PEER_EBGP
) {
3031 /* This is implicit withdraw so we should update
3034 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
3035 bgp_damp_withdraw(ri
, rn
, afi
, safi
, 1);
3038 if (safi
== SAFI_MPLS_VPN
) {
3039 struct bgp_node
*prn
= NULL
;
3040 struct bgp_table
*table
= NULL
;
3042 prn
= bgp_node_get(bgp
->rib
[afi
][safi
],
3043 (struct prefix
*)prd
);
3045 table
= (struct bgp_table
*)(prn
->info
);
3047 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3048 bgp
, prd
, table
, p
, ri
);
3050 bgp_unlock_node(prn
);
3052 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3053 && (safi
== SAFI_UNICAST
)) {
3054 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
3056 * Implicit withdraw case.
3058 ++vnc_implicit_withdraw
;
3059 vnc_import_bgp_del_route(bgp
, p
, ri
);
3060 vnc_import_bgp_exterior_del_route(bgp
, p
, ri
);
3065 /* Special handling for EVPN update of an existing route. If the
3066 * extended community attribute has changed, we need to
3068 * the route using its existing extended community. It will be
3069 * subsequently processed for import with the new extended
3072 if (safi
== SAFI_EVPN
&& !same_attr
) {
3074 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
3076 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))) {
3079 cmp
= ecommunity_cmp(ri
->attr
->ecommunity
,
3080 attr_new
->ecommunity
);
3082 if (bgp_debug_update(peer
, p
, NULL
, 1))
3084 "Change in EXT-COMM, existing %s new %s",
3086 ri
->attr
->ecommunity
),
3088 attr_new
->ecommunity
));
3089 bgp_evpn_unimport_route(bgp
, afi
, safi
,
3095 /* Update to new attribute. */
3096 bgp_attr_unintern(&ri
->attr
);
3097 ri
->attr
= attr_new
;
3099 /* Update MPLS label */
3100 if (has_valid_label
) {
3101 extra
= bgp_info_extra_get(ri
);
3102 memcpy(&extra
->label
, label
,
3103 num_labels
* sizeof(mpls_label_t
));
3104 extra
->num_labels
= num_labels
;
3105 if (!(afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
))
3106 bgp_set_valid_label(&extra
->label
[0]);
3110 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3111 && (safi
== SAFI_UNICAST
)) {
3112 if (vnc_implicit_withdraw
) {
3114 * Add back the route with its new attributes
3116 * The route is still selected, until the route
3118 * queued by bgp_process actually runs. We have
3120 * update to the VNC side immediately to avoid
3122 * configuration changes (e.g., route-map
3124 * trigger re-importation of the entire RIB.
3126 vnc_import_bgp_add_route(bgp
, p
, ri
);
3127 vnc_import_bgp_exterior_add_route(bgp
, p
, ri
);
3131 /* Update Overlay Index */
3132 if (afi
== AFI_L2VPN
) {
3133 overlay_index_update(
3134 ri
->attr
, evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3135 evpn
== NULL
? NULL
: &evpn
->gw_ip
);
3138 /* Update bgp route dampening information. */
3139 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
3140 && peer
->sort
== BGP_PEER_EBGP
) {
3141 /* Now we do normal update dampening. */
3142 ret
= bgp_damp_update(ri
, rn
, afi
, safi
);
3143 if (ret
== BGP_DAMP_SUPPRESSED
) {
3144 bgp_unlock_node(rn
);
3149 /* Nexthop reachability check - for unicast and
3150 * labeled-unicast.. */
3151 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3152 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
3153 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1
3154 && !CHECK_FLAG(peer
->flags
,
3155 PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3157 bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
3162 if (bgp_find_or_add_nexthop(bgp
, afi
, ri
, NULL
,
3164 || CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
))
3165 bgp_info_set_flag(rn
, ri
, BGP_INFO_VALID
);
3167 if (BGP_DEBUG(nht
, NHT
)) {
3168 char buf1
[INET6_ADDRSTRLEN
];
3170 (const void *)&attr_new
3172 buf1
, INET6_ADDRSTRLEN
);
3173 zlog_debug("%s(%s): NH unresolved",
3174 __FUNCTION__
, buf1
);
3176 bgp_info_unset_flag(rn
, ri
, BGP_INFO_VALID
);
3179 bgp_info_set_flag(rn
, ri
, BGP_INFO_VALID
);
3182 if (safi
== SAFI_MPLS_VPN
) {
3183 struct bgp_node
*prn
= NULL
;
3184 struct bgp_table
*table
= NULL
;
3186 prn
= bgp_node_get(bgp
->rib
[afi
][safi
],
3187 (struct prefix
*)prd
);
3189 table
= (struct bgp_table
*)(prn
->info
);
3191 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3192 bgp
, prd
, table
, p
, ri
);
3194 bgp_unlock_node(prn
);
3198 /* If this is an EVPN route and some attribute has changed,
3200 * route for import. If the extended community has changed, we
3202 * have done the un-import earlier and the import would result
3204 * route getting injected into appropriate L2 VNIs. If it is
3206 * some other attribute change, the import will result in
3208 * the attributes for the route in the VNI(s).
3210 if (safi
== SAFI_EVPN
&& !same_attr
)
3211 bgp_evpn_import_route(bgp
, afi
, safi
, p
, ri
);
3213 /* Process change. */
3214 bgp_aggregate_increment(bgp
, p
, ri
, afi
, safi
);
3216 bgp_process(bgp
, rn
, afi
, safi
);
3217 bgp_unlock_node(rn
);
3219 if (SAFI_UNICAST
== safi
3220 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3221 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3223 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, ri
);
3225 if ((SAFI_MPLS_VPN
== safi
)
3226 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3228 vpn_leak_to_vrf_update(bgp
, ri
);
3232 if (SAFI_MPLS_VPN
== safi
) {
3233 mpls_label_t label_decoded
= decode_label(label
);
3235 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
,
3236 type
, sub_type
, &label_decoded
);
3238 if (SAFI_ENCAP
== safi
) {
3239 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
,
3240 type
, sub_type
, NULL
);
3245 } // End of implicit withdraw
3247 /* Received Logging. */
3248 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3249 if (!peer
->rcvd_attr_printed
) {
3250 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
3251 peer
->rcvd_attr_str
);
3252 peer
->rcvd_attr_printed
= 1;
3255 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3256 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3258 zlog_debug("%s rcvd %s", peer
->host
, pfx_buf
);
3261 /* Make new BGP info. */
3262 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
3264 /* Update MPLS label */
3265 if (has_valid_label
) {
3266 extra
= bgp_info_extra_get(new);
3267 memcpy(&extra
->label
, label
, num_labels
* sizeof(mpls_label_t
));
3268 extra
->num_labels
= num_labels
;
3269 if (!(afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
))
3270 bgp_set_valid_label(&extra
->label
[0]);
3273 /* Update Overlay Index */
3274 if (afi
== AFI_L2VPN
) {
3275 overlay_index_update(new->attr
,
3276 evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3277 evpn
== NULL
? NULL
: &evpn
->gw_ip
);
3279 /* Nexthop reachability check. */
3280 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3281 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
3282 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1
3283 && !CHECK_FLAG(peer
->flags
,
3284 PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3285 && !bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
3290 if (bgp_find_or_add_nexthop(bgp
, afi
, new, NULL
, connected
)
3291 || CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
))
3292 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
3294 if (BGP_DEBUG(nht
, NHT
)) {
3295 char buf1
[INET6_ADDRSTRLEN
];
3297 (const void *)&attr_new
->nexthop
,
3298 buf1
, INET6_ADDRSTRLEN
);
3299 zlog_debug("%s(%s): NH unresolved",
3300 __FUNCTION__
, buf1
);
3302 bgp_info_unset_flag(rn
, new, BGP_INFO_VALID
);
3305 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
3308 new->addpath_rx_id
= addpath_id
;
3310 /* Increment prefix */
3311 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
3313 /* Register new BGP information. */
3314 bgp_info_add(rn
, new);
3316 /* route_node_get lock */
3317 bgp_unlock_node(rn
);
3320 if (safi
== SAFI_MPLS_VPN
) {
3321 struct bgp_node
*prn
= NULL
;
3322 struct bgp_table
*table
= NULL
;
3324 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*)prd
);
3326 table
= (struct bgp_table
*)(prn
->info
);
3328 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3329 bgp
, prd
, table
, p
, new);
3331 bgp_unlock_node(prn
);
3335 /* If maximum prefix count is configured and current prefix
3337 if (bgp_maximum_prefix_overflow(peer
, afi
, safi
, 0))
3340 /* If this is an EVPN route, process for import. */
3341 if (safi
== SAFI_EVPN
)
3342 bgp_evpn_import_route(bgp
, afi
, safi
, p
, new);
3344 /* Process change. */
3345 bgp_process(bgp
, rn
, afi
, safi
);
3347 if (SAFI_UNICAST
== safi
3348 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3349 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3350 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
3352 if ((SAFI_MPLS_VPN
== safi
)
3353 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3355 vpn_leak_to_vrf_update(bgp
, new);
3358 if (SAFI_MPLS_VPN
== safi
) {
3359 mpls_label_t label_decoded
= decode_label(label
);
3361 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
,
3362 sub_type
, &label_decoded
);
3364 if (SAFI_ENCAP
== safi
) {
3365 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
,
3372 /* This BGP update is filtered. Log the reason then update BGP
3375 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3376 if (!peer
->rcvd_attr_printed
) {
3377 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
3378 peer
->rcvd_attr_str
);
3379 peer
->rcvd_attr_printed
= 1;
3382 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3383 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3385 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
3386 peer
->host
, pfx_buf
, reason
);
3390 /* If this is an EVPN route, un-import it as it is now filtered.
3392 if (safi
== SAFI_EVPN
)
3393 bgp_evpn_unimport_route(bgp
, afi
, safi
, p
, ri
);
3395 if (SAFI_UNICAST
== safi
3396 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3397 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3399 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, ri
);
3401 if ((SAFI_MPLS_VPN
== safi
)
3402 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3404 vpn_leak_to_vrf_withdraw(bgp
, ri
);
3407 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
3410 bgp_unlock_node(rn
);
3414 * Filtered update is treated as an implicit withdrawal (see
3416 * a few lines above)
3418 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
)) {
3419 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
,
3427 int bgp_withdraw(struct peer
*peer
, struct prefix
*p
, uint32_t addpath_id
,
3428 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
3429 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
3430 uint32_t num_labels
, struct bgp_route_evpn
*evpn
)
3433 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
3434 struct bgp_node
*rn
;
3435 struct bgp_info
*ri
;
3438 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
)) {
3439 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
,
3447 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3449 /* If peer is soft reconfiguration enabled. Record input packet for
3450 * further calculation.
3452 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
3453 * routes that are filtered. This tanks out Quagga RS pretty badly due
3455 * the iteration over all RS clients.
3456 * Since we need to remove the entry from adj_in anyway, do that first
3458 * if there was no entry, we don't need to do anything more.
3460 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
3461 && peer
!= bgp
->peer_self
)
3462 if (!bgp_adj_in_unset(rn
, peer
, addpath_id
)) {
3463 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3464 bgp_debug_rdpfxpath2str(
3465 afi
, safi
, prd
, p
, label
, num_labels
,
3466 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3469 "%s withdrawing route %s not in adj-in",
3470 peer
->host
, pfx_buf
);
3472 bgp_unlock_node(rn
);
3476 /* Lookup withdrawn route. */
3477 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
3478 if (ri
->peer
== peer
&& ri
->type
== type
3479 && ri
->sub_type
== sub_type
3480 && ri
->addpath_rx_id
== addpath_id
)
3484 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3485 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3486 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3488 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer
->host
,
3492 /* Withdraw specified route from routing table. */
3493 if (ri
&& !CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
)) {
3494 bgp_rib_withdraw(rn
, ri
, peer
, afi
, safi
, prd
);
3495 if (SAFI_UNICAST
== safi
3496 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3497 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3498 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, ri
);
3500 if ((SAFI_MPLS_VPN
== safi
)
3501 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3503 vpn_leak_to_vrf_withdraw(bgp
, ri
);
3505 } else if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3506 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3507 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3509 zlog_debug("%s Can't find the route %s", peer
->host
, pfx_buf
);
3512 /* Unlock bgp_node_get() lock. */
3513 bgp_unlock_node(rn
);
3518 void bgp_default_originate(struct peer
*peer
, afi_t afi
, safi_t safi
,
3521 struct update_subgroup
*subgrp
;
3522 subgrp
= peer_subgroup(peer
, afi
, safi
);
3523 subgroup_default_originate(subgrp
, withdraw
);
3528 * bgp_stop_announce_route_timer
3530 void bgp_stop_announce_route_timer(struct peer_af
*paf
)
3532 if (!paf
->t_announce_route
)
3535 THREAD_TIMER_OFF(paf
->t_announce_route
);
3539 * bgp_announce_route_timer_expired
3541 * Callback that is invoked when the route announcement timer for a
3544 static int bgp_announce_route_timer_expired(struct thread
*t
)
3546 struct peer_af
*paf
;
3549 paf
= THREAD_ARG(t
);
3552 if (peer
->status
!= Established
)
3555 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
3558 peer_af_announce_route(paf
, 1);
3563 * bgp_announce_route
3565 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3567 void bgp_announce_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3569 struct peer_af
*paf
;
3570 struct update_subgroup
*subgrp
;
3572 paf
= peer_af_find(peer
, afi
, safi
);
3575 subgrp
= PAF_SUBGRP(paf
);
3578 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3579 * or a refresh has already been triggered.
3581 if (!subgrp
|| paf
->t_announce_route
)
3585 * Start a timer to stagger/delay the announce. This serves
3586 * two purposes - announcement can potentially be combined for
3587 * multiple peers and the announcement doesn't happen in the
3590 thread_add_timer_msec(bm
->master
, bgp_announce_route_timer_expired
, paf
,
3591 (subgrp
->peer_count
== 1)
3592 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
3593 : BGP_ANNOUNCE_ROUTE_DELAY_MS
,
3594 &paf
->t_announce_route
);
3598 * Announce routes from all AF tables to a peer.
3600 * This should ONLY be called when there is a need to refresh the
3601 * routes to the peer based on a policy change for this peer alone
3602 * or a route refresh request received from the peer.
3603 * The operation will result in splitting the peer from its existing
3604 * subgroups and putting it in new subgroups.
3606 void bgp_announce_route_all(struct peer
*peer
)
3611 FOREACH_AFI_SAFI (afi
, safi
)
3612 bgp_announce_route(peer
, afi
, safi
);
3615 static void bgp_soft_reconfig_table(struct peer
*peer
, afi_t afi
, safi_t safi
,
3616 struct bgp_table
*table
,
3617 struct prefix_rd
*prd
)
3620 struct bgp_node
*rn
;
3621 struct bgp_adj_in
*ain
;
3624 table
= peer
->bgp
->rib
[afi
][safi
];
3626 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
3627 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
) {
3628 if (ain
->peer
!= peer
)
3631 struct bgp_info
*ri
= rn
->info
;
3632 uint32_t num_labels
= 0;
3633 mpls_label_t
*label_pnt
= NULL
;
3635 if (ri
&& ri
->extra
)
3636 num_labels
= ri
->extra
->num_labels
;
3638 label_pnt
= &ri
->extra
->label
[0];
3640 ret
= bgp_update(peer
, &rn
->p
, ain
->addpath_rx_id
,
3641 ain
->attr
, afi
, safi
, ZEBRA_ROUTE_BGP
,
3642 BGP_ROUTE_NORMAL
, prd
, label_pnt
,
3643 num_labels
, 1, NULL
);
3646 bgp_unlock_node(rn
);
3652 void bgp_soft_reconfig_in(struct peer
*peer
, afi_t afi
, safi_t safi
)
3654 struct bgp_node
*rn
;
3655 struct bgp_table
*table
;
3657 if (peer
->status
!= Established
)
3660 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
)
3661 && (safi
!= SAFI_EVPN
))
3662 bgp_soft_reconfig_table(peer
, afi
, safi
, NULL
, NULL
);
3664 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3665 rn
= bgp_route_next(rn
))
3666 if ((table
= rn
->info
) != NULL
) {
3667 struct prefix_rd prd
;
3668 prd
.family
= AF_UNSPEC
;
3670 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3672 bgp_soft_reconfig_table(peer
, afi
, safi
, table
,
3678 struct bgp_clear_node_queue
{
3679 struct bgp_node
*rn
;
3682 static wq_item_status
bgp_clear_route_node(struct work_queue
*wq
, void *data
)
3684 struct bgp_clear_node_queue
*cnq
= data
;
3685 struct bgp_node
*rn
= cnq
->rn
;
3686 struct peer
*peer
= wq
->spec
.data
;
3687 struct bgp_info
*ri
;
3689 afi_t afi
= bgp_node_table(rn
)->afi
;
3690 safi_t safi
= bgp_node_table(rn
)->safi
;
3695 /* It is possible that we have multiple paths for a prefix from a peer
3696 * if that peer is using AddPath.
3698 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
3699 if (ri
->peer
!= peer
)
3702 /* graceful restart STALE flag set. */
3703 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3704 && peer
->nsf
[afi
][safi
]
3705 && !CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
)
3706 && !CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
3707 bgp_info_set_flag(rn
, ri
, BGP_INFO_STALE
);
3709 /* If this is an EVPN route, process for
3711 if (safi
== SAFI_EVPN
)
3712 bgp_evpn_unimport_route(bgp
, afi
, safi
,
3714 /* Handle withdraw for VRF route-leaking and L3VPN */
3715 if (SAFI_UNICAST
== safi
3716 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
||
3717 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
))
3718 vpn_leak_from_vrf_withdraw(bgp_get_default(),
3720 if (SAFI_MPLS_VPN
== safi
&&
3721 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
3722 vpn_leak_to_vrf_withdraw(bgp
, ri
);
3724 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
3730 static void bgp_clear_node_queue_del(struct work_queue
*wq
, void *data
)
3732 struct bgp_clear_node_queue
*cnq
= data
;
3733 struct bgp_node
*rn
= cnq
->rn
;
3734 struct bgp_table
*table
= bgp_node_table(rn
);
3736 bgp_unlock_node(rn
);
3737 bgp_table_unlock(table
);
3738 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3741 static void bgp_clear_node_complete(struct work_queue
*wq
)
3743 struct peer
*peer
= wq
->spec
.data
;
3745 /* Tickle FSM to start moving again */
3746 BGP_EVENT_ADD(peer
, Clearing_Completed
);
3748 peer_unlock(peer
); /* bgp_clear_route */
3751 static void bgp_clear_node_queue_init(struct peer
*peer
)
3753 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3755 snprintf(wname
, sizeof(wname
), "clear %s", peer
->host
);
3756 #undef CLEAR_QUEUE_NAME_LEN
3758 if ((peer
->clear_node_queue
= work_queue_new(bm
->master
, wname
))
3760 zlog_err("%s: Failed to allocate work queue", __func__
);
3763 peer
->clear_node_queue
->spec
.hold
= 10;
3764 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3765 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3766 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3767 peer
->clear_node_queue
->spec
.max_retries
= 0;
3769 /* we only 'lock' this peer reference when the queue is actually active
3771 peer
->clear_node_queue
->spec
.data
= peer
;
3774 static void bgp_clear_route_table(struct peer
*peer
, afi_t afi
, safi_t safi
,
3775 struct bgp_table
*table
)
3777 struct bgp_node
*rn
;
3778 int force
= bm
->process_main_queue
? 0 : 1;
3781 table
= peer
->bgp
->rib
[afi
][safi
];
3783 /* If still no table => afi/safi isn't configured at all or smth. */
3787 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
3788 struct bgp_info
*ri
, *next
;
3789 struct bgp_adj_in
*ain
;
3790 struct bgp_adj_in
*ain_next
;
3792 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3793 * queued for every clearing peer, regardless of whether it is
3794 * relevant to the peer at hand.
3796 * Overview: There are 3 different indices which need to be
3797 * scrubbed, potentially, when a peer is removed:
3799 * 1 peer's routes visible via the RIB (ie accepted routes)
3800 * 2 peer's routes visible by the (optional) peer's adj-in index
3801 * 3 other routes visible by the peer's adj-out index
3803 * 3 there is no hurry in scrubbing, once the struct peer is
3804 * removed from bgp->peer, we could just GC such deleted peer's
3805 * adj-outs at our leisure.
3807 * 1 and 2 must be 'scrubbed' in some way, at least made
3808 * invisible via RIB index before peer session is allowed to be
3809 * brought back up. So one needs to know when such a 'search' is
3814 * - there'd be a single global queue or a single RIB walker
3815 * - rather than tracking which route_nodes still need to be
3816 * examined on a peer basis, we'd track which peers still
3819 * Given that our per-peer prefix-counts now should be reliable,
3820 * this may actually be achievable. It doesn't seem to be a huge
3821 * problem at this time,
3823 * It is possible that we have multiple paths for a prefix from
3825 * if that peer is using AddPath.
3829 ain_next
= ain
->next
;
3831 if (ain
->peer
== peer
) {
3832 bgp_adj_in_remove(rn
, ain
);
3833 bgp_unlock_node(rn
);
3839 for (ri
= rn
->info
; ri
; ri
= next
) {
3841 if (ri
->peer
!= peer
)
3845 bgp_info_reap(rn
, ri
);
3847 struct bgp_clear_node_queue
*cnq
;
3849 /* both unlocked in bgp_clear_node_queue_del */
3850 bgp_table_lock(bgp_node_table(rn
));
3853 MTYPE_BGP_CLEAR_NODE_QUEUE
,
3854 sizeof(struct bgp_clear_node_queue
));
3856 work_queue_add(peer
->clear_node_queue
, cnq
);
3864 void bgp_clear_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3866 struct bgp_node
*rn
;
3867 struct bgp_table
*table
;
3869 if (peer
->clear_node_queue
== NULL
)
3870 bgp_clear_node_queue_init(peer
);
3872 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3873 * Idle until it receives a Clearing_Completed event. This protects
3874 * against peers which flap faster than we can we clear, which could
3877 * a) race with routes from the new session being installed before
3878 * clear_route_node visits the node (to delete the route of that
3880 * b) resource exhaustion, clear_route_node likely leads to an entry
3881 * on the process_main queue. Fast-flapping could cause that queue
3885 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3886 * the unlock will happen upon work-queue completion; other wise, the
3887 * unlock happens at the end of this function.
3889 if (!peer
->clear_node_queue
->thread
)
3892 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
&& safi
!= SAFI_EVPN
)
3893 bgp_clear_route_table(peer
, afi
, safi
, NULL
);
3895 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3896 rn
= bgp_route_next(rn
))
3897 if ((table
= rn
->info
) != NULL
)
3898 bgp_clear_route_table(peer
, afi
, safi
, table
);
3900 /* unlock if no nodes got added to the clear-node-queue. */
3901 if (!peer
->clear_node_queue
->thread
)
3905 void bgp_clear_route_all(struct peer
*peer
)
3910 FOREACH_AFI_SAFI (afi
, safi
)
3911 bgp_clear_route(peer
, afi
, safi
);
3914 rfapiProcessPeerDown(peer
);
3918 void bgp_clear_adj_in(struct peer
*peer
, afi_t afi
, safi_t safi
)
3920 struct bgp_table
*table
;
3921 struct bgp_node
*rn
;
3922 struct bgp_adj_in
*ain
;
3923 struct bgp_adj_in
*ain_next
;
3925 table
= peer
->bgp
->rib
[afi
][safi
];
3927 /* It is possible that we have multiple paths for a prefix from a peer
3928 * if that peer is using AddPath.
3930 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
3934 ain_next
= ain
->next
;
3936 if (ain
->peer
== peer
) {
3937 bgp_adj_in_remove(rn
, ain
);
3938 bgp_unlock_node(rn
);
3946 void bgp_clear_stale_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3948 struct bgp_node
*rn
;
3949 struct bgp_info
*ri
;
3950 struct bgp_table
*table
;
3952 if (safi
== SAFI_MPLS_VPN
) {
3953 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3954 rn
= bgp_route_next(rn
)) {
3955 struct bgp_node
*rm
;
3956 struct bgp_info
*ri
;
3958 /* look for neighbor in tables */
3959 if ((table
= rn
->info
) == NULL
)
3962 for (rm
= bgp_table_top(table
); rm
;
3963 rm
= bgp_route_next(rm
))
3964 for (ri
= rm
->info
; ri
; ri
= ri
->next
) {
3965 if (ri
->peer
!= peer
)
3967 if (!CHECK_FLAG(ri
->flags
,
3971 bgp_rib_remove(rm
, ri
, peer
, afi
, safi
);
3976 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3977 rn
= bgp_route_next(rn
))
3978 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
3979 if (ri
->peer
!= peer
)
3981 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
))
3983 bgp_rib_remove(rn
, ri
, peer
, afi
, safi
);
3989 static void bgp_cleanup_table(struct bgp
*bgp
, struct bgp_table
*table
,
3992 struct bgp_node
*rn
;
3993 struct bgp_info
*ri
;
3994 struct bgp_info
*next
;
3996 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
3997 for (ri
= rn
->info
; ri
; ri
= next
) {
3999 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)
4000 && ri
->type
== ZEBRA_ROUTE_BGP
4001 && (ri
->sub_type
== BGP_ROUTE_NORMAL
4002 || ri
->sub_type
== BGP_ROUTE_AGGREGATE
4003 || ri
->sub_type
== BGP_ROUTE_IMPORTED
)) {
4005 if (bgp_fibupd_safi(safi
))
4006 bgp_zebra_withdraw(&rn
->p
, ri
,
4008 bgp_info_reap(rn
, ri
);
4013 /* Delete all kernel routes. */
4014 void bgp_cleanup_routes(struct bgp
*bgp
)
4017 struct bgp_node
*rn
;
4019 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
4020 if (afi
== AFI_L2VPN
)
4022 bgp_cleanup_table(bgp
, bgp
->rib
[afi
][SAFI_UNICAST
],
4025 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
4027 if (afi
!= AFI_L2VPN
) {
4029 safi
= SAFI_MPLS_VPN
;
4030 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
4031 rn
= bgp_route_next(rn
)) {
4033 bgp_cleanup_table(bgp
,
4034 (struct bgp_table
*)(rn
->info
),
4036 bgp_table_finish((struct bgp_table
**)&(
4039 bgp_unlock_node(rn
);
4043 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
4044 rn
= bgp_route_next(rn
)) {
4046 bgp_cleanup_table(bgp
,
4047 (struct bgp_table
*)(rn
->info
),
4049 bgp_table_finish((struct bgp_table
**)&(
4052 bgp_unlock_node(rn
);
4057 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
4058 rn
= bgp_route_next(rn
)) {
4060 bgp_cleanup_table(bgp
,
4061 (struct bgp_table
*)(rn
->info
),
4063 bgp_table_finish((struct bgp_table
**)&(rn
->info
));
4065 bgp_unlock_node(rn
);
4070 void bgp_reset(void)
4073 bgp_zclient_reset();
4074 access_list_reset();
4075 prefix_list_reset();
4078 static int bgp_addpath_encode_rx(struct peer
*peer
, afi_t afi
, safi_t safi
)
4080 return (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
4081 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
4082 PEER_CAP_ADDPATH_AF_TX_RCV
));
4085 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
4087 int bgp_nlri_parse_ip(struct peer
*peer
, struct attr
*attr
,
4088 struct bgp_nlri
*packet
)
4097 int addpath_encoded
;
4098 uint32_t addpath_id
;
4101 lim
= pnt
+ packet
->length
;
4103 safi
= packet
->safi
;
4105 addpath_encoded
= bgp_addpath_encode_rx(peer
, afi
, safi
);
4107 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
4108 syntactic validity. If the field is syntactically incorrect,
4109 then the Error Subcode is set to Invalid Network Field. */
4110 for (; pnt
< lim
; pnt
+= psize
) {
4111 /* Clear prefix structure. */
4112 memset(&p
, 0, sizeof(struct prefix
));
4114 if (addpath_encoded
) {
4116 /* When packet overflow occurs return immediately. */
4117 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
4120 addpath_id
= ntohl(*((uint32_t *)pnt
));
4121 pnt
+= BGP_ADDPATH_ID_LEN
;
4124 /* Fetch prefix length. */
4125 p
.prefixlen
= *pnt
++;
4126 /* afi/safi validity already verified by caller,
4127 * bgp_update_receive */
4128 p
.family
= afi2family(afi
);
4130 /* Prefix length check. */
4131 if (p
.prefixlen
> prefix_blen(&p
) * 8) {
4133 "%s [Error] Update packet error (wrong perfix length %d for afi %u)",
4134 peer
->host
, p
.prefixlen
, packet
->afi
);
4138 /* Packet size overflow check. */
4139 psize
= PSIZE(p
.prefixlen
);
4141 /* When packet overflow occur return immediately. */
4142 if (pnt
+ psize
> lim
) {
4144 "%s [Error] Update packet error (prefix length %d overflows packet)",
4145 peer
->host
, p
.prefixlen
);
4149 /* Defensive coding, double-check the psize fits in a struct
4151 if (psize
> (ssize_t
)sizeof(p
.u
)) {
4153 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
4154 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
4158 /* Fetch prefix from NLRI packet. */
4159 memcpy(&p
.u
.prefix
, pnt
, psize
);
4161 /* Check address. */
4162 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
) {
4163 if (IN_CLASSD(ntohl(p
.u
.prefix4
.s_addr
))) {
4164 /* From RFC4271 Section 6.3:
4166 * If a prefix in the NLRI field is semantically
4168 * (e.g., an unexpected multicast IP address),
4170 * be logged locally, and the prefix SHOULD be
4174 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
4175 peer
->host
, inet_ntoa(p
.u
.prefix4
));
4180 /* Check address. */
4181 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
) {
4182 if (IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
4186 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
4188 inet_ntop(AF_INET6
, &p
.u
.prefix6
, buf
,
4193 if (IN6_IS_ADDR_MULTICAST(&p
.u
.prefix6
)) {
4197 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
4199 inet_ntop(AF_INET6
, &p
.u
.prefix6
, buf
,
4206 /* Normal process. */
4208 ret
= bgp_update(peer
, &p
, addpath_id
, attr
, afi
, safi
,
4209 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
4210 NULL
, NULL
, 0, 0, NULL
);
4212 ret
= bgp_withdraw(peer
, &p
, addpath_id
, attr
, afi
,
4213 safi
, ZEBRA_ROUTE_BGP
,
4214 BGP_ROUTE_NORMAL
, NULL
, NULL
, 0,
4217 /* Address family configuration mismatch or maximum-prefix count
4223 /* Packet length consistency check. */
4226 "%s [Error] Update packet error (prefix length mismatch with total length)",
4234 static struct bgp_static
*bgp_static_new(void)
4236 return XCALLOC(MTYPE_BGP_STATIC
, sizeof(struct bgp_static
));
4239 static void bgp_static_free(struct bgp_static
*bgp_static
)
4241 if (bgp_static
->rmap
.name
)
4242 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4243 if (bgp_static
->eth_s_id
)
4244 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
4245 XFREE(MTYPE_BGP_STATIC
, bgp_static
);
4248 void bgp_static_update(struct bgp
*bgp
, struct prefix
*p
,
4249 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
4251 struct bgp_node
*rn
;
4252 struct bgp_info
*ri
;
4253 struct bgp_info
*new;
4254 struct bgp_info info
;
4256 struct attr
*attr_new
;
4259 int vnc_implicit_withdraw
= 0;
4266 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4268 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
4270 attr
.nexthop
= bgp_static
->igpnexthop
;
4271 attr
.med
= bgp_static
->igpmetric
;
4272 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
4274 if (bgp_static
->atomic
)
4275 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
);
4277 /* Store label index, if required. */
4278 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
) {
4279 attr
.label_index
= bgp_static
->label_index
;
4280 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID
);
4283 /* Apply route-map. */
4284 if (bgp_static
->rmap
.name
) {
4285 struct attr attr_tmp
= attr
;
4286 info
.peer
= bgp
->peer_self
;
4287 info
.attr
= &attr_tmp
;
4289 SET_FLAG(bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4291 ret
= route_map_apply(bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4293 bgp
->peer_self
->rmap_type
= 0;
4295 if (ret
== RMAP_DENYMATCH
) {
4296 /* Free uninterned attribute. */
4297 bgp_attr_flush(&attr_tmp
);
4299 /* Unintern original. */
4300 aspath_unintern(&attr
.aspath
);
4301 bgp_static_withdraw(bgp
, p
, afi
, safi
);
4305 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
4306 bgp_attr_add_gshut_community(&attr_tmp
);
4308 attr_new
= bgp_attr_intern(&attr_tmp
);
4311 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
4312 bgp_attr_add_gshut_community(&attr
);
4314 attr_new
= bgp_attr_intern(&attr
);
4317 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4318 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4319 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4323 if (attrhash_cmp(ri
->attr
, attr_new
)
4324 && !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)
4325 && !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
)) {
4326 bgp_unlock_node(rn
);
4327 bgp_attr_unintern(&attr_new
);
4328 aspath_unintern(&attr
.aspath
);
4331 /* The attribute is changed. */
4332 bgp_info_set_flag(rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4334 /* Rewrite BGP route information. */
4335 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4336 bgp_info_restore(rn
, ri
);
4338 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4340 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
4341 && (safi
== SAFI_UNICAST
)) {
4342 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
4344 * Implicit withdraw case.
4345 * We have to do this before ri is
4348 ++vnc_implicit_withdraw
;
4349 vnc_import_bgp_del_route(bgp
, p
, ri
);
4350 vnc_import_bgp_exterior_del_route(
4355 bgp_attr_unintern(&ri
->attr
);
4356 ri
->attr
= attr_new
;
4357 ri
->uptime
= bgp_clock();
4359 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
4360 && (safi
== SAFI_UNICAST
)) {
4361 if (vnc_implicit_withdraw
) {
4362 vnc_import_bgp_add_route(bgp
, p
, ri
);
4363 vnc_import_bgp_exterior_add_route(
4369 /* Nexthop reachability check. */
4370 if (bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
4371 && (safi
== SAFI_UNICAST
4372 || safi
== SAFI_LABELED_UNICAST
)) {
4373 if (bgp_find_or_add_nexthop(bgp
, afi
, ri
, NULL
,
4375 bgp_info_set_flag(rn
, ri
,
4378 if (BGP_DEBUG(nht
, NHT
)) {
4379 char buf1
[INET6_ADDRSTRLEN
];
4380 inet_ntop(p
->family
,
4384 "%s(%s): Route not in table, not advertising",
4385 __FUNCTION__
, buf1
);
4387 bgp_info_unset_flag(rn
, ri
,
4391 /* Delete the NHT structure if any, if we're
4393 * enabling/disabling import check. We
4394 * deregister the route
4395 * from NHT to avoid overloading NHT and the
4396 * process interaction
4398 bgp_unlink_nexthop(ri
);
4399 bgp_info_set_flag(rn
, ri
, BGP_INFO_VALID
);
4401 /* Process change. */
4402 bgp_aggregate_increment(bgp
, p
, ri
, afi
, safi
);
4403 bgp_process(bgp
, rn
, afi
, safi
);
4405 if (SAFI_UNICAST
== safi
4406 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4408 == BGP_INSTANCE_TYPE_DEFAULT
)) {
4409 vpn_leak_from_vrf_update(bgp_get_default(), bgp
,
4413 bgp_unlock_node(rn
);
4414 aspath_unintern(&attr
.aspath
);
4419 /* Make new BGP info. */
4420 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
,
4422 /* Nexthop reachability check. */
4423 if (bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
4424 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
4425 if (bgp_find_or_add_nexthop(bgp
, afi
, new, NULL
, 0))
4426 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
4428 if (BGP_DEBUG(nht
, NHT
)) {
4429 char buf1
[INET6_ADDRSTRLEN
];
4430 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
4433 "%s(%s): Route not in table, not advertising",
4434 __FUNCTION__
, buf1
);
4436 bgp_info_unset_flag(rn
, new, BGP_INFO_VALID
);
4439 /* Delete the NHT structure if any, if we're toggling between
4440 * enabling/disabling import check. We deregister the route
4441 * from NHT to avoid overloading NHT and the process interaction
4443 bgp_unlink_nexthop(new);
4445 bgp_info_set_flag(rn
, new, BGP_INFO_VALID
);
4448 /* Aggregate address increment. */
4449 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
4451 /* Register new BGP information. */
4452 bgp_info_add(rn
, new);
4454 /* route_node_get lock */
4455 bgp_unlock_node(rn
);
4457 /* Process change. */
4458 bgp_process(bgp
, rn
, afi
, safi
);
4460 if (SAFI_UNICAST
== safi
4461 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4462 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
4463 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
4466 /* Unintern original. */
4467 aspath_unintern(&attr
.aspath
);
4470 void bgp_static_withdraw(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
4473 struct bgp_node
*rn
;
4474 struct bgp_info
*ri
;
4476 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4478 /* Check selected route and self inserted route. */
4479 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4480 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4481 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4484 /* Withdraw static BGP route from routing table. */
4486 if (SAFI_UNICAST
== safi
4487 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4488 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
4489 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, ri
);
4491 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4492 bgp_unlink_nexthop(ri
);
4493 bgp_info_delete(rn
, ri
);
4494 bgp_process(bgp
, rn
, afi
, safi
);
4497 /* Unlock bgp_node_lookup. */
4498 bgp_unlock_node(rn
);
4502 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4504 static void bgp_static_withdraw_safi(struct bgp
*bgp
, struct prefix
*p
,
4505 afi_t afi
, safi_t safi
,
4506 struct prefix_rd
*prd
)
4508 struct bgp_node
*rn
;
4509 struct bgp_info
*ri
;
4511 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
4513 /* Check selected route and self inserted route. */
4514 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4515 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4516 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4519 /* Withdraw static BGP route from routing table. */
4522 rfapiProcessWithdraw(
4523 ri
->peer
, NULL
, p
, prd
, ri
->attr
, afi
, safi
, ri
->type
,
4524 1); /* Kill, since it is an administrative change */
4526 if (SAFI_MPLS_VPN
== safi
4527 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4528 vpn_leak_to_vrf_withdraw(bgp
, ri
);
4530 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4531 bgp_info_delete(rn
, ri
);
4532 bgp_process(bgp
, rn
, afi
, safi
);
4535 /* Unlock bgp_node_lookup. */
4536 bgp_unlock_node(rn
);
4539 static void bgp_static_update_safi(struct bgp
*bgp
, struct prefix
*p
,
4540 struct bgp_static
*bgp_static
, afi_t afi
,
4543 struct bgp_node
*rn
;
4544 struct bgp_info
*new;
4545 struct attr
*attr_new
;
4546 struct attr attr
= {0};
4547 struct bgp_info
*ri
;
4549 mpls_label_t label
= 0;
4551 uint32_t num_labels
= 0;
4556 if (bgp_static
->label
!= MPLS_INVALID_LABEL
)
4558 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
,
4561 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
4563 attr
.nexthop
= bgp_static
->igpnexthop
;
4564 attr
.med
= bgp_static
->igpmetric
;
4565 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
4567 if ((safi
== SAFI_EVPN
) || (safi
== SAFI_MPLS_VPN
)
4568 || (safi
== SAFI_ENCAP
)) {
4569 if (afi
== AFI_IP
) {
4570 attr
.mp_nexthop_global_in
= bgp_static
->igpnexthop
;
4571 attr
.mp_nexthop_len
= IPV4_MAX_BYTELEN
;
4574 if (afi
== AFI_L2VPN
) {
4575 if (bgp_static
->gatewayIp
.family
== AF_INET
)
4577 bgp_static
->gatewayIp
.u
.prefix4
.s_addr
;
4578 else if (bgp_static
->gatewayIp
.family
== AF_INET6
)
4579 memcpy(&(add
.ipv6
), &(bgp_static
->gatewayIp
.u
.prefix6
),
4580 sizeof(struct in6_addr
));
4581 overlay_index_update(&attr
, bgp_static
->eth_s_id
, &add
);
4582 if (bgp_static
->encap_tunneltype
== BGP_ENCAP_TYPE_VXLAN
) {
4583 struct bgp_encap_type_vxlan bet
;
4584 memset(&bet
, 0, sizeof(struct bgp_encap_type_vxlan
));
4585 bet
.vnid
= p
->u
.prefix_evpn
.eth_tag
;
4586 bgp_encap_type_vxlan_to_tlv(&bet
, &attr
);
4588 if (bgp_static
->router_mac
) {
4589 bgp_add_routermac_ecom(&attr
, bgp_static
->router_mac
);
4592 /* Apply route-map. */
4593 if (bgp_static
->rmap
.name
) {
4594 struct attr attr_tmp
= attr
;
4595 struct bgp_info info
;
4598 info
.peer
= bgp
->peer_self
;
4599 info
.attr
= &attr_tmp
;
4601 SET_FLAG(bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4603 ret
= route_map_apply(bgp_static
->rmap
.map
, p
, RMAP_BGP
, &info
);
4605 bgp
->peer_self
->rmap_type
= 0;
4607 if (ret
== RMAP_DENYMATCH
) {
4608 /* Free uninterned attribute. */
4609 bgp_attr_flush(&attr_tmp
);
4611 /* Unintern original. */
4612 aspath_unintern(&attr
.aspath
);
4613 bgp_static_withdraw_safi(bgp
, p
, afi
, safi
,
4618 attr_new
= bgp_attr_intern(&attr_tmp
);
4620 attr_new
= bgp_attr_intern(&attr
);
4623 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
4624 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
4625 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4630 memset(&add
, 0, sizeof(union gw_addr
));
4631 if (attrhash_cmp(ri
->attr
, attr_new
)
4632 && overlay_index_equal(afi
, ri
, bgp_static
->eth_s_id
, &add
)
4633 && !CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
)) {
4634 bgp_unlock_node(rn
);
4635 bgp_attr_unintern(&attr_new
);
4636 aspath_unintern(&attr
.aspath
);
4639 /* The attribute is changed. */
4640 bgp_info_set_flag(rn
, ri
, BGP_INFO_ATTR_CHANGED
);
4642 /* Rewrite BGP route information. */
4643 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
4644 bgp_info_restore(rn
, ri
);
4646 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, safi
);
4647 bgp_attr_unintern(&ri
->attr
);
4648 ri
->attr
= attr_new
;
4649 ri
->uptime
= bgp_clock();
4652 label
= decode_label(&ri
->extra
->label
[0]);
4655 /* Process change. */
4656 bgp_aggregate_increment(bgp
, p
, ri
, afi
, safi
);
4657 bgp_process(bgp
, rn
, afi
, safi
);
4659 if (SAFI_MPLS_VPN
== safi
4660 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4661 vpn_leak_to_vrf_update(bgp
, ri
);
4664 rfapiProcessUpdate(ri
->peer
, NULL
, p
, &bgp_static
->prd
,
4665 ri
->attr
, afi
, safi
, ri
->type
,
4666 ri
->sub_type
, &label
);
4668 bgp_unlock_node(rn
);
4669 aspath_unintern(&attr
.aspath
);
4675 /* Make new BGP info. */
4676 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
,
4678 SET_FLAG(new->flags
, BGP_INFO_VALID
);
4679 new->extra
= bgp_info_extra_new();
4681 new->extra
->label
[0] = bgp_static
->label
;
4682 new->extra
->num_labels
= num_labels
;
4685 label
= decode_label(&bgp_static
->label
);
4688 /* Aggregate address increment. */
4689 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
4691 /* Register new BGP information. */
4692 bgp_info_add(rn
, new);
4693 /* route_node_get lock */
4694 bgp_unlock_node(rn
);
4696 /* Process change. */
4697 bgp_process(bgp
, rn
, afi
, safi
);
4699 if (SAFI_MPLS_VPN
== safi
4700 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4701 vpn_leak_to_vrf_update(bgp
, new);
4704 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
, new->attr
, afi
,
4705 safi
, new->type
, new->sub_type
, &label
);
4708 /* Unintern original. */
4709 aspath_unintern(&attr
.aspath
);
4712 /* Configure static BGP network. When user don't run zebra, static
4713 route should be installed as valid. */
4714 static int bgp_static_set(struct vty
*vty
, const char *negate
,
4715 const char *ip_str
, afi_t afi
, safi_t safi
,
4716 const char *rmap
, int backdoor
, uint32_t label_index
)
4718 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4721 struct bgp_static
*bgp_static
;
4722 struct bgp_node
*rn
;
4723 uint8_t need_update
= 0;
4725 /* Convert IP prefix string to struct prefix. */
4726 ret
= str2prefix(ip_str
, &p
);
4728 vty_out(vty
, "%% Malformed prefix\n");
4729 return CMD_WARNING_CONFIG_FAILED
;
4731 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
4732 vty_out(vty
, "%% Malformed prefix (link-local address)\n");
4733 return CMD_WARNING_CONFIG_FAILED
;
4740 /* Set BGP static route configuration. */
4741 rn
= bgp_node_lookup(bgp
->route
[afi
][safi
], &p
);
4744 vty_out(vty
, "%% Can't find static route specified\n");
4745 return CMD_WARNING_CONFIG_FAILED
;
4748 bgp_static
= rn
->info
;
4750 if ((label_index
!= BGP_INVALID_LABEL_INDEX
)
4751 && (label_index
!= bgp_static
->label_index
)) {
4753 "%% label-index doesn't match static route\n");
4754 return CMD_WARNING_CONFIG_FAILED
;
4757 if ((rmap
&& bgp_static
->rmap
.name
)
4758 && strcmp(rmap
, bgp_static
->rmap
.name
)) {
4760 "%% route-map name doesn't match static route\n");
4761 return CMD_WARNING_CONFIG_FAILED
;
4764 /* Update BGP RIB. */
4765 if (!bgp_static
->backdoor
)
4766 bgp_static_withdraw(bgp
, &p
, afi
, safi
);
4768 /* Clear configuration. */
4769 bgp_static_free(bgp_static
);
4771 bgp_unlock_node(rn
);
4772 bgp_unlock_node(rn
);
4775 /* Set BGP static route configuration. */
4776 rn
= bgp_node_get(bgp
->route
[afi
][safi
], &p
);
4779 /* Configuration change. */
4780 bgp_static
= rn
->info
;
4782 /* Label index cannot be changed. */
4783 if (bgp_static
->label_index
!= label_index
) {
4784 vty_out(vty
, "%% cannot change label-index\n");
4785 return CMD_WARNING_CONFIG_FAILED
;
4788 /* Check previous routes are installed into BGP. */
4789 if (bgp_static
->valid
4790 && bgp_static
->backdoor
!= backdoor
)
4793 bgp_static
->backdoor
= backdoor
;
4796 if (bgp_static
->rmap
.name
)
4797 XFREE(MTYPE_ROUTE_MAP_NAME
,
4798 bgp_static
->rmap
.name
);
4799 bgp_static
->rmap
.name
=
4800 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4801 bgp_static
->rmap
.map
=
4802 route_map_lookup_by_name(rmap
);
4804 if (bgp_static
->rmap
.name
)
4805 XFREE(MTYPE_ROUTE_MAP_NAME
,
4806 bgp_static
->rmap
.name
);
4807 bgp_static
->rmap
.name
= NULL
;
4808 bgp_static
->rmap
.map
= NULL
;
4809 bgp_static
->valid
= 0;
4811 bgp_unlock_node(rn
);
4813 /* New configuration. */
4814 bgp_static
= bgp_static_new();
4815 bgp_static
->backdoor
= backdoor
;
4816 bgp_static
->valid
= 0;
4817 bgp_static
->igpmetric
= 0;
4818 bgp_static
->igpnexthop
.s_addr
= 0;
4819 bgp_static
->label_index
= label_index
;
4822 if (bgp_static
->rmap
.name
)
4823 XFREE(MTYPE_ROUTE_MAP_NAME
,
4824 bgp_static
->rmap
.name
);
4825 bgp_static
->rmap
.name
=
4826 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4827 bgp_static
->rmap
.map
=
4828 route_map_lookup_by_name(rmap
);
4830 rn
->info
= bgp_static
;
4833 bgp_static
->valid
= 1;
4835 bgp_static_withdraw(bgp
, &p
, afi
, safi
);
4837 if (!bgp_static
->backdoor
)
4838 bgp_static_update(bgp
, &p
, bgp_static
, afi
, safi
);
4844 void bgp_static_add(struct bgp
*bgp
)
4848 struct bgp_node
*rn
;
4849 struct bgp_node
*rm
;
4850 struct bgp_table
*table
;
4851 struct bgp_static
*bgp_static
;
4853 FOREACH_AFI_SAFI (afi
, safi
)
4854 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
4855 rn
= bgp_route_next(rn
)) {
4856 if (rn
->info
== NULL
)
4859 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
4860 || (safi
== SAFI_EVPN
)) {
4863 for (rm
= bgp_table_top(table
); rm
;
4864 rm
= bgp_route_next(rm
)) {
4865 bgp_static
= rm
->info
;
4866 bgp_static_update_safi(bgp
, &rm
->p
,
4871 bgp_static_update(bgp
, &rn
->p
, rn
->info
, afi
,
4877 /* Called from bgp_delete(). Delete all static routes from the BGP
4879 void bgp_static_delete(struct bgp
*bgp
)
4883 struct bgp_node
*rn
;
4884 struct bgp_node
*rm
;
4885 struct bgp_table
*table
;
4886 struct bgp_static
*bgp_static
;
4888 FOREACH_AFI_SAFI (afi
, safi
)
4889 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
4890 rn
= bgp_route_next(rn
)) {
4891 if (rn
->info
== NULL
)
4894 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
4895 || (safi
== SAFI_EVPN
)) {
4898 for (rm
= bgp_table_top(table
); rm
;
4899 rm
= bgp_route_next(rm
)) {
4900 bgp_static
= rm
->info
;
4901 bgp_static_withdraw_safi(
4902 bgp
, &rm
->p
, AFI_IP
, safi
,
4903 (struct prefix_rd
*)&rn
->p
);
4904 bgp_static_free(bgp_static
);
4906 bgp_unlock_node(rn
);
4909 bgp_static
= rn
->info
;
4910 bgp_static_withdraw(bgp
, &rn
->p
, afi
, safi
);
4911 bgp_static_free(bgp_static
);
4913 bgp_unlock_node(rn
);
4918 void bgp_static_redo_import_check(struct bgp
*bgp
)
4922 struct bgp_node
*rn
;
4923 struct bgp_node
*rm
;
4924 struct bgp_table
*table
;
4925 struct bgp_static
*bgp_static
;
4927 /* Use this flag to force reprocessing of the route */
4928 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4929 FOREACH_AFI_SAFI (afi
, safi
) {
4930 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
4931 rn
= bgp_route_next(rn
)) {
4932 if (rn
->info
== NULL
)
4935 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
4936 || (safi
== SAFI_EVPN
)) {
4939 for (rm
= bgp_table_top(table
); rm
;
4940 rm
= bgp_route_next(rm
)) {
4941 bgp_static
= rm
->info
;
4942 bgp_static_update_safi(bgp
, &rm
->p
,
4947 bgp_static
= rn
->info
;
4948 bgp_static_update(bgp
, &rn
->p
, bgp_static
, afi
,
4953 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
4956 static void bgp_purge_af_static_redist_routes(struct bgp
*bgp
, afi_t afi
,
4959 struct bgp_table
*table
;
4960 struct bgp_node
*rn
;
4961 struct bgp_info
*ri
;
4963 table
= bgp
->rib
[afi
][safi
];
4964 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
4965 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
4966 if (ri
->peer
== bgp
->peer_self
4967 && ((ri
->type
== ZEBRA_ROUTE_BGP
4968 && ri
->sub_type
== BGP_ROUTE_STATIC
)
4969 || (ri
->type
!= ZEBRA_ROUTE_BGP
4971 == BGP_ROUTE_REDISTRIBUTE
))) {
4972 bgp_aggregate_decrement(bgp
, &rn
->p
, ri
, afi
,
4974 bgp_unlink_nexthop(ri
);
4975 bgp_info_delete(rn
, ri
);
4976 bgp_process(bgp
, rn
, afi
, safi
);
4983 * Purge all networks and redistributed routes from routing table.
4984 * Invoked upon the instance going down.
4986 void bgp_purge_static_redist_routes(struct bgp
*bgp
)
4991 FOREACH_AFI_SAFI (afi
, safi
)
4992 bgp_purge_af_static_redist_routes(bgp
, afi
, safi
);
4997 * Currently this is used to set static routes for VPN and ENCAP.
4998 * I think it can probably be factored with bgp_static_set.
5000 int bgp_static_set_safi(afi_t afi
, safi_t safi
, struct vty
*vty
,
5001 const char *ip_str
, const char *rd_str
,
5002 const char *label_str
, const char *rmap_str
,
5003 int evpn_type
, const char *esi
, const char *gwip
,
5004 const char *ethtag
, const char *routermac
)
5006 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5009 struct prefix_rd prd
;
5010 struct bgp_node
*prn
;
5011 struct bgp_node
*rn
;
5012 struct bgp_table
*table
;
5013 struct bgp_static
*bgp_static
;
5014 mpls_label_t label
= MPLS_INVALID_LABEL
;
5015 struct prefix gw_ip
;
5017 /* validate ip prefix */
5018 ret
= str2prefix(ip_str
, &p
);
5020 vty_out(vty
, "%% Malformed prefix\n");
5021 return CMD_WARNING_CONFIG_FAILED
;
5024 if ((afi
== AFI_L2VPN
)
5025 && (bgp_build_evpn_prefix(evpn_type
,
5026 ethtag
!= NULL
? atol(ethtag
) : 0, &p
))) {
5027 vty_out(vty
, "%% L2VPN prefix could not be forged\n");
5028 return CMD_WARNING_CONFIG_FAILED
;
5031 ret
= str2prefix_rd(rd_str
, &prd
);
5033 vty_out(vty
, "%% Malformed rd\n");
5034 return CMD_WARNING_CONFIG_FAILED
;
5038 unsigned long label_val
;
5039 label_val
= strtoul(label_str
, NULL
, 10);
5040 encode_label(label_val
, &label
);
5043 if (safi
== SAFI_EVPN
) {
5044 if (esi
&& str2esi(esi
, NULL
) == 0) {
5045 vty_out(vty
, "%% Malformed ESI\n");
5046 return CMD_WARNING_CONFIG_FAILED
;
5048 if (routermac
&& prefix_str2mac(routermac
, NULL
) == 0) {
5049 vty_out(vty
, "%% Malformed Router MAC\n");
5050 return CMD_WARNING_CONFIG_FAILED
;
5053 memset(&gw_ip
, 0, sizeof(struct prefix
));
5054 ret
= str2prefix(gwip
, &gw_ip
);
5056 vty_out(vty
, "%% Malformed GatewayIp\n");
5057 return CMD_WARNING_CONFIG_FAILED
;
5059 if ((gw_ip
.family
== AF_INET
5060 && IS_EVPN_PREFIX_IPADDR_V6(
5061 (struct prefix_evpn
*)&p
))
5062 || (gw_ip
.family
== AF_INET6
5063 && IS_EVPN_PREFIX_IPADDR_V4(
5064 (struct prefix_evpn
*)&p
))) {
5066 "%% GatewayIp family differs with IP prefix\n");
5067 return CMD_WARNING_CONFIG_FAILED
;
5071 prn
= bgp_node_get(bgp
->route
[afi
][safi
], (struct prefix
*)&prd
);
5072 if (prn
->info
== NULL
)
5073 prn
->info
= bgp_table_init(afi
, safi
);
5075 bgp_unlock_node(prn
);
5078 rn
= bgp_node_get(table
, &p
);
5081 vty_out(vty
, "%% Same network configuration exists\n");
5082 bgp_unlock_node(rn
);
5084 /* New configuration. */
5085 bgp_static
= bgp_static_new();
5086 bgp_static
->backdoor
= 0;
5087 bgp_static
->valid
= 0;
5088 bgp_static
->igpmetric
= 0;
5089 bgp_static
->igpnexthop
.s_addr
= 0;
5090 bgp_static
->label
= label
;
5091 bgp_static
->prd
= prd
;
5094 if (bgp_static
->rmap
.name
)
5095 XFREE(MTYPE_ROUTE_MAP_NAME
,
5096 bgp_static
->rmap
.name
);
5097 bgp_static
->rmap
.name
=
5098 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_str
);
5099 bgp_static
->rmap
.map
=
5100 route_map_lookup_by_name(rmap_str
);
5103 if (safi
== SAFI_EVPN
) {
5105 bgp_static
->eth_s_id
=
5107 sizeof(struct eth_segment_id
));
5108 str2esi(esi
, bgp_static
->eth_s_id
);
5111 bgp_static
->router_mac
=
5112 XCALLOC(MTYPE_ATTR
, ETH_ALEN
+ 1);
5113 prefix_str2mac(routermac
,
5114 bgp_static
->router_mac
);
5117 prefix_copy(&bgp_static
->gatewayIp
, &gw_ip
);
5119 rn
->info
= bgp_static
;
5121 bgp_static
->valid
= 1;
5122 bgp_static_update_safi(bgp
, &p
, bgp_static
, afi
, safi
);
5128 /* Configure static BGP network. */
5129 int bgp_static_unset_safi(afi_t afi
, safi_t safi
, struct vty
*vty
,
5130 const char *ip_str
, const char *rd_str
,
5131 const char *label_str
, int evpn_type
, const char *esi
,
5132 const char *gwip
, const char *ethtag
)
5134 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5137 struct prefix_rd prd
;
5138 struct bgp_node
*prn
;
5139 struct bgp_node
*rn
;
5140 struct bgp_table
*table
;
5141 struct bgp_static
*bgp_static
;
5142 mpls_label_t label
= MPLS_INVALID_LABEL
;
5144 /* Convert IP prefix string to struct prefix. */
5145 ret
= str2prefix(ip_str
, &p
);
5147 vty_out(vty
, "%% Malformed prefix\n");
5148 return CMD_WARNING_CONFIG_FAILED
;
5151 if ((afi
== AFI_L2VPN
)
5152 && (bgp_build_evpn_prefix(evpn_type
,
5153 ethtag
!= NULL
? atol(ethtag
) : 0, &p
))) {
5154 vty_out(vty
, "%% L2VPN prefix could not be forged\n");
5155 return CMD_WARNING_CONFIG_FAILED
;
5157 ret
= str2prefix_rd(rd_str
, &prd
);
5159 vty_out(vty
, "%% Malformed rd\n");
5160 return CMD_WARNING_CONFIG_FAILED
;
5164 unsigned long label_val
;
5165 label_val
= strtoul(label_str
, NULL
, 10);
5166 encode_label(label_val
, &label
);
5169 prn
= bgp_node_get(bgp
->route
[afi
][safi
], (struct prefix
*)&prd
);
5170 if (prn
->info
== NULL
)
5171 prn
->info
= bgp_table_init(afi
, safi
);
5173 bgp_unlock_node(prn
);
5176 rn
= bgp_node_lookup(table
, &p
);
5179 bgp_static_withdraw_safi(bgp
, &p
, afi
, safi
, &prd
);
5181 bgp_static
= rn
->info
;
5182 bgp_static_free(bgp_static
);
5184 bgp_unlock_node(rn
);
5185 bgp_unlock_node(rn
);
5187 vty_out(vty
, "%% Can't find the route\n");
5192 static int bgp_table_map_set(struct vty
*vty
, afi_t afi
, safi_t safi
,
5193 const char *rmap_name
)
5195 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5196 struct bgp_rmap
*rmap
;
5198 rmap
= &bgp
->table_map
[afi
][safi
];
5201 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5202 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
5203 rmap
->map
= route_map_lookup_by_name(rmap_name
);
5206 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5211 if (bgp_fibupd_safi(safi
))
5212 bgp_zebra_announce_table(bgp
, afi
, safi
);
5217 static int bgp_table_map_unset(struct vty
*vty
, afi_t afi
, safi_t safi
,
5218 const char *rmap_name
)
5220 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5221 struct bgp_rmap
*rmap
;
5223 rmap
= &bgp
->table_map
[afi
][safi
];
5225 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5229 if (bgp_fibupd_safi(safi
))
5230 bgp_zebra_announce_table(bgp
, afi
, safi
);
5235 void bgp_config_write_table_map(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
5238 if (bgp
->table_map
[afi
][safi
].name
) {
5239 vty_out(vty
, " table-map %s\n",
5240 bgp
->table_map
[afi
][safi
].name
);
5244 DEFUN (bgp_table_map
,
5247 "BGP table to RIB route download filter\n"
5248 "Name of the route map\n")
5251 return bgp_table_map_set(vty
, bgp_node_afi(vty
), bgp_node_safi(vty
),
5252 argv
[idx_word
]->arg
);
5254 DEFUN (no_bgp_table_map
,
5255 no_bgp_table_map_cmd
,
5256 "no table-map WORD",
5258 "BGP table to RIB route download filter\n"
5259 "Name of the route map\n")
5262 return bgp_table_map_unset(vty
, bgp_node_afi(vty
), bgp_node_safi(vty
),
5263 argv
[idx_word
]->arg
);
5269 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
5270 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
5271 backdoor$backdoor}]",
5273 "Specify a network to announce via BGP\n"
5278 "Route-map to modify the attributes\n"
5279 "Name of the route map\n"
5280 "Label index to associate with the prefix\n"
5281 "Label index value\n"
5282 "Specify a BGP backdoor route\n")
5284 char addr_prefix_str
[BUFSIZ
];
5289 ret
= netmask_str2prefix_str(address_str
, netmask_str
,
5292 vty_out(vty
, "%% Inconsistent address and mask\n");
5293 return CMD_WARNING_CONFIG_FAILED
;
5297 return bgp_static_set(
5298 vty
, no
, address_str
? addr_prefix_str
: prefix_str
, AFI_IP
,
5299 bgp_node_safi(vty
), map_name
, backdoor
? 1 : 0,
5300 label_index
? (uint32_t)label_index
: BGP_INVALID_LABEL_INDEX
);
5303 DEFPY(ipv6_bgp_network
,
5304 ipv6_bgp_network_cmd
,
5305 "[no] network X:X::X:X/M$prefix \
5306 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
5308 "Specify a network to announce via BGP\n"
5310 "Route-map to modify the attributes\n"
5311 "Name of the route map\n"
5312 "Label index to associate with the prefix\n"
5313 "Label index value\n")
5315 return bgp_static_set(
5316 vty
, no
, prefix_str
, AFI_IP6
, bgp_node_safi(vty
), map_name
, 0,
5317 label_index
? (uint32_t)label_index
: BGP_INVALID_LABEL_INDEX
);
5320 /* Aggreagete address:
5322 advertise-map Set condition to advertise attribute
5323 as-set Generate AS set path information
5324 attribute-map Set attributes of aggregate
5325 route-map Set parameters of aggregate
5326 summary-only Filter more specific routes from updates
5327 suppress-map Conditionally filter more specific routes from updates
5330 struct bgp_aggregate
{
5331 /* Summary-only flag. */
5332 uint8_t summary_only
;
5334 /* AS set generation. */
5337 /* Route-map for aggregated route. */
5338 struct route_map
*map
;
5340 /* Suppress-count. */
5341 unsigned long count
;
5343 /* SAFI configuration. */
5347 static struct bgp_aggregate
*bgp_aggregate_new(void)
5349 return XCALLOC(MTYPE_BGP_AGGREGATE
, sizeof(struct bgp_aggregate
));
5352 static void bgp_aggregate_free(struct bgp_aggregate
*aggregate
)
5354 XFREE(MTYPE_BGP_AGGREGATE
, aggregate
);
5357 /* Update an aggregate as routes are added/removed from the BGP table */
5358 static void bgp_aggregate_route(struct bgp
*bgp
, struct prefix
*p
,
5359 struct bgp_info
*rinew
, afi_t afi
, safi_t safi
,
5360 struct bgp_info
*del
,
5361 struct bgp_aggregate
*aggregate
)
5363 struct bgp_table
*table
;
5364 struct bgp_node
*top
;
5365 struct bgp_node
*rn
;
5367 struct aspath
*aspath
= NULL
;
5368 struct aspath
*asmerge
= NULL
;
5369 struct community
*community
= NULL
;
5370 struct community
*commerge
= NULL
;
5371 #if defined(AGGREGATE_NEXTHOP_CHECK)
5372 struct in_addr nexthop
;
5375 struct bgp_info
*ri
;
5376 struct bgp_info
*new;
5378 unsigned long match
= 0;
5379 uint8_t atomic_aggregate
= 0;
5381 /* Record adding route's nexthop and med. */
5383 #if defined(AGGREGATE_NEXTHOP_CHECK)
5384 nexthop
= rinew
->attr
->nexthop
;
5385 med
= rinew
->attr
->med
;
5389 /* ORIGIN attribute: If at least one route among routes that are
5390 aggregated has ORIGIN with the value INCOMPLETE, then the
5391 aggregated route must have the ORIGIN attribute with the value
5392 INCOMPLETE. Otherwise, if at least one route among routes that
5393 are aggregated has ORIGIN with the value EGP, then the aggregated
5394 route must have the origin attribute with the value EGP. In all
5395 other case the value of the ORIGIN attribute of the aggregated
5396 route is INTERNAL. */
5397 origin
= BGP_ORIGIN_IGP
;
5399 table
= bgp
->rib
[afi
][safi
];
5401 top
= bgp_node_get(table
, p
);
5402 for (rn
= bgp_node_get(table
, p
); rn
;
5403 rn
= bgp_route_next_until(rn
, top
))
5404 if (rn
->p
.prefixlen
> p
->prefixlen
) {
5407 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
5408 if (BGP_INFO_HOLDDOWN(ri
))
5411 if (del
&& ri
== del
)
5414 if (!rinew
&& first
) {
5415 #if defined(AGGREGATE_NEXTHOP_CHECK)
5416 nexthop
= ri
->attr
->nexthop
;
5417 med
= ri
->attr
->med
;
5422 #ifdef AGGREGATE_NEXTHOP_CHECK
5423 if (!IPV4_ADDR_SAME(&ri
->attr
->nexthop
,
5425 || ri
->attr
->med
!= med
) {
5427 aspath_free(aspath
);
5429 community_free(community
);
5430 bgp_unlock_node(rn
);
5431 bgp_unlock_node(top
);
5434 #endif /* AGGREGATE_NEXTHOP_CHECK */
5437 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5438 atomic_aggregate
= 1;
5440 if (ri
->sub_type
!= BGP_ROUTE_AGGREGATE
) {
5441 if (aggregate
->summary_only
) {
5442 (bgp_info_extra_get(ri
))
5446 BGP_INFO_ATTR_CHANGED
);
5452 if (origin
< ri
->attr
->origin
)
5453 origin
= ri
->attr
->origin
;
5455 if (aggregate
->as_set
) {
5457 asmerge
= aspath_aggregate(
5460 aspath_free(aspath
);
5463 aspath
= aspath_dup(
5466 if (ri
->attr
->community
) {
5468 commerge
= community_merge(
5470 ri
->attr
->community
);
5471 community
= community_uniq_sort(
5476 community
= community_dup(
5477 ri
->attr
->community
);
5483 bgp_process(bgp
, rn
, afi
, safi
);
5485 bgp_unlock_node(top
);
5490 if (aggregate
->summary_only
)
5491 (bgp_info_extra_get(rinew
))->suppress
++;
5493 if (origin
< rinew
->attr
->origin
)
5494 origin
= rinew
->attr
->origin
;
5496 if (aggregate
->as_set
) {
5498 asmerge
= aspath_aggregate(aspath
,
5499 rinew
->attr
->aspath
);
5500 aspath_free(aspath
);
5503 aspath
= aspath_dup(rinew
->attr
->aspath
);
5505 if (rinew
->attr
->community
) {
5507 commerge
= community_merge(
5509 rinew
->attr
->community
);
5511 community_uniq_sort(commerge
);
5512 community_free(commerge
);
5514 community
= community_dup(
5515 rinew
->attr
->community
);
5520 if (aggregate
->count
> 0) {
5521 rn
= bgp_node_get(table
, p
);
5523 ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5524 bgp_attr_aggregate_intern(bgp
, origin
, aspath
,
5525 community
, aggregate
->as_set
,
5528 SET_FLAG(new->flags
, BGP_INFO_VALID
);
5530 bgp_info_add(rn
, new);
5531 bgp_unlock_node(rn
);
5532 bgp_process(bgp
, rn
, afi
, safi
);
5535 aspath_free(aspath
);
5537 community_free(community
);
5541 void bgp_aggregate_delete(struct bgp
*, struct prefix
*, afi_t
, safi_t
,
5542 struct bgp_aggregate
*);
5544 void bgp_aggregate_increment(struct bgp
*bgp
, struct prefix
*p
,
5545 struct bgp_info
*ri
, afi_t afi
, safi_t safi
)
5547 struct bgp_node
*child
;
5548 struct bgp_node
*rn
;
5549 struct bgp_aggregate
*aggregate
;
5550 struct bgp_table
*table
;
5552 /* MPLS-VPN aggregation is not yet supported. */
5553 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5554 || (safi
== SAFI_EVPN
))
5557 table
= bgp
->aggregate
[afi
][safi
];
5559 /* No aggregates configured. */
5560 if (bgp_table_top_nolock(table
) == NULL
)
5563 if (p
->prefixlen
== 0)
5566 if (BGP_INFO_HOLDDOWN(ri
))
5569 child
= bgp_node_get(table
, p
);
5571 /* Aggregate address configuration check. */
5572 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock(rn
))
5573 if ((aggregate
= rn
->info
) != NULL
5574 && rn
->p
.prefixlen
< p
->prefixlen
) {
5575 bgp_aggregate_delete(bgp
, &rn
->p
, afi
, safi
, aggregate
);
5576 bgp_aggregate_route(bgp
, &rn
->p
, ri
, afi
, safi
, NULL
,
5579 bgp_unlock_node(child
);
5582 void bgp_aggregate_decrement(struct bgp
*bgp
, struct prefix
*p
,
5583 struct bgp_info
*del
, afi_t afi
, safi_t safi
)
5585 struct bgp_node
*child
;
5586 struct bgp_node
*rn
;
5587 struct bgp_aggregate
*aggregate
;
5588 struct bgp_table
*table
;
5590 /* MPLS-VPN aggregation is not yet supported. */
5591 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5592 || (safi
== SAFI_EVPN
))
5595 table
= bgp
->aggregate
[afi
][safi
];
5597 /* No aggregates configured. */
5598 if (bgp_table_top_nolock(table
) == NULL
)
5601 if (p
->prefixlen
== 0)
5604 child
= bgp_node_get(table
, p
);
5606 /* Aggregate address configuration check. */
5607 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock(rn
))
5608 if ((aggregate
= rn
->info
) != NULL
5609 && rn
->p
.prefixlen
< p
->prefixlen
) {
5610 bgp_aggregate_delete(bgp
, &rn
->p
, afi
, safi
, aggregate
);
5611 bgp_aggregate_route(bgp
, &rn
->p
, NULL
, afi
, safi
, del
,
5614 bgp_unlock_node(child
);
5617 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5618 static void bgp_aggregate_add(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5619 safi_t safi
, struct bgp_aggregate
*aggregate
)
5621 struct bgp_table
*table
;
5622 struct bgp_node
*top
;
5623 struct bgp_node
*rn
;
5624 struct bgp_info
*new;
5625 struct bgp_info
*ri
;
5626 unsigned long match
;
5627 uint8_t origin
= BGP_ORIGIN_IGP
;
5628 struct aspath
*aspath
= NULL
;
5629 struct aspath
*asmerge
= NULL
;
5630 struct community
*community
= NULL
;
5631 struct community
*commerge
= NULL
;
5632 uint8_t atomic_aggregate
= 0;
5634 table
= bgp
->rib
[afi
][safi
];
5637 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5639 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5642 /* If routes exists below this node, generate aggregate routes. */
5643 top
= bgp_node_get(table
, p
);
5644 for (rn
= bgp_node_get(table
, p
); rn
;
5645 rn
= bgp_route_next_until(rn
, top
)) {
5646 if (rn
->p
.prefixlen
<= p
->prefixlen
)
5651 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
5652 if (BGP_INFO_HOLDDOWN(ri
))
5656 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5657 atomic_aggregate
= 1;
5659 if (ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5662 /* summary-only aggregate route suppress
5663 * aggregated route announcement. */
5664 if (aggregate
->summary_only
) {
5665 (bgp_info_extra_get(ri
))->suppress
++;
5666 bgp_info_set_flag(rn
, ri
,
5667 BGP_INFO_ATTR_CHANGED
);
5671 /* If at least one route among routes that are
5672 * aggregated has ORIGIN with the value INCOMPLETE,
5673 * then the aggregated route MUST have the ORIGIN
5674 * attribute with the value INCOMPLETE. Otherwise, if
5675 * at least one route among routes that are aggregated
5676 * has ORIGIN with the value EGP, then the aggregated
5677 * route MUST have the ORIGIN attribute with the value
5680 if (origin
< ri
->attr
->origin
)
5681 origin
= ri
->attr
->origin
;
5683 /* as-set aggregate route generate origin, as path,
5684 * community aggregation. */
5685 if (aggregate
->as_set
) {
5687 asmerge
= aspath_aggregate(
5688 aspath
, ri
->attr
->aspath
);
5689 aspath_free(aspath
);
5692 aspath
= aspath_dup(ri
->attr
->aspath
);
5694 if (ri
->attr
->community
) {
5696 commerge
= community_merge(
5698 ri
->attr
->community
);
5699 community
= community_uniq_sort(
5701 community_free(commerge
);
5703 community
= community_dup(
5704 ri
->attr
->community
);
5710 /* If this node is suppressed, process the change. */
5712 bgp_process(bgp
, rn
, afi
, safi
);
5714 bgp_unlock_node(top
);
5716 /* Add aggregate route to BGP table. */
5717 if (aggregate
->count
) {
5718 rn
= bgp_node_get(table
, p
);
5720 ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0, bgp
->peer_self
,
5721 bgp_attr_aggregate_intern(bgp
, origin
, aspath
,
5722 community
, aggregate
->as_set
,
5725 SET_FLAG(new->flags
, BGP_INFO_VALID
);
5727 bgp_info_add(rn
, new);
5728 bgp_unlock_node(rn
);
5730 /* Process change. */
5731 bgp_process(bgp
, rn
, afi
, safi
);
5734 aspath_free(aspath
);
5736 community_free(community
);
5740 void bgp_aggregate_delete(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5741 safi_t safi
, struct bgp_aggregate
*aggregate
)
5743 struct bgp_table
*table
;
5744 struct bgp_node
*top
;
5745 struct bgp_node
*rn
;
5746 struct bgp_info
*ri
;
5747 unsigned long match
;
5749 table
= bgp
->rib
[afi
][safi
];
5751 if (afi
== AFI_IP
&& p
->prefixlen
== IPV4_MAX_BITLEN
)
5753 if (afi
== AFI_IP6
&& p
->prefixlen
== IPV6_MAX_BITLEN
)
5756 /* If routes exists below this node, generate aggregate routes. */
5757 top
= bgp_node_get(table
, p
);
5758 for (rn
= bgp_node_get(table
, p
); rn
;
5759 rn
= bgp_route_next_until(rn
, top
)) {
5760 if (rn
->p
.prefixlen
<= p
->prefixlen
)
5764 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
5765 if (BGP_INFO_HOLDDOWN(ri
))
5768 if (ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5771 if (aggregate
->summary_only
&& ri
->extra
) {
5772 ri
->extra
->suppress
--;
5774 if (ri
->extra
->suppress
== 0) {
5776 rn
, ri
, BGP_INFO_ATTR_CHANGED
);
5783 /* If this node was suppressed, process the change. */
5785 bgp_process(bgp
, rn
, afi
, safi
);
5787 bgp_unlock_node(top
);
5789 /* Delete aggregate route from BGP table. */
5790 rn
= bgp_node_get(table
, p
);
5792 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
5793 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== ZEBRA_ROUTE_BGP
5794 && ri
->sub_type
== BGP_ROUTE_AGGREGATE
)
5797 /* Withdraw static BGP route from routing table. */
5799 bgp_info_delete(rn
, ri
);
5800 bgp_process(bgp
, rn
, afi
, safi
);
5803 /* Unlock bgp_node_lookup. */
5804 bgp_unlock_node(rn
);
5807 /* Aggregate route attribute. */
5808 #define AGGREGATE_SUMMARY_ONLY 1
5809 #define AGGREGATE_AS_SET 1
5811 static int bgp_aggregate_unset(struct vty
*vty
, const char *prefix_str
,
5812 afi_t afi
, safi_t safi
)
5814 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5817 struct bgp_node
*rn
;
5818 struct bgp_aggregate
*aggregate
;
5820 /* Convert string to prefix structure. */
5821 ret
= str2prefix(prefix_str
, &p
);
5823 vty_out(vty
, "Malformed prefix\n");
5824 return CMD_WARNING_CONFIG_FAILED
;
5828 /* Old configuration check. */
5829 rn
= bgp_node_lookup(bgp
->aggregate
[afi
][safi
], &p
);
5832 "%% There is no aggregate-address configuration.\n");
5833 return CMD_WARNING_CONFIG_FAILED
;
5836 aggregate
= rn
->info
;
5837 if (aggregate
->safi
== SAFI_UNICAST
)
5838 bgp_aggregate_delete(bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5839 if (aggregate
->safi
== SAFI_LABELED_UNICAST
)
5840 bgp_aggregate_delete(bgp
, &p
, afi
, SAFI_LABELED_UNICAST
,
5842 if (aggregate
->safi
== SAFI_MULTICAST
)
5843 bgp_aggregate_delete(bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5845 /* Unlock aggregate address configuration. */
5847 bgp_aggregate_free(aggregate
);
5848 bgp_unlock_node(rn
);
5849 bgp_unlock_node(rn
);
5854 static int bgp_aggregate_set(struct vty
*vty
, const char *prefix_str
, afi_t afi
,
5855 safi_t safi
, uint8_t summary_only
, uint8_t as_set
)
5857 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5860 struct bgp_node
*rn
;
5861 struct bgp_aggregate
*aggregate
;
5863 /* Convert string to prefix structure. */
5864 ret
= str2prefix(prefix_str
, &p
);
5866 vty_out(vty
, "Malformed prefix\n");
5867 return CMD_WARNING_CONFIG_FAILED
;
5871 /* Old configuration check. */
5872 rn
= bgp_node_get(bgp
->aggregate
[afi
][safi
], &p
);
5875 vty_out(vty
, "There is already same aggregate network.\n");
5876 /* try to remove the old entry */
5877 ret
= bgp_aggregate_unset(vty
, prefix_str
, afi
, safi
);
5879 vty_out(vty
, "Error deleting aggregate.\n");
5880 bgp_unlock_node(rn
);
5881 return CMD_WARNING_CONFIG_FAILED
;
5885 /* Make aggregate address structure. */
5886 aggregate
= bgp_aggregate_new();
5887 aggregate
->summary_only
= summary_only
;
5888 aggregate
->as_set
= as_set
;
5889 aggregate
->safi
= safi
;
5890 rn
->info
= aggregate
;
5892 /* Aggregate address insert into BGP routing table. */
5893 if (safi
== SAFI_UNICAST
)
5894 bgp_aggregate_add(bgp
, &p
, afi
, SAFI_UNICAST
, aggregate
);
5895 if (safi
== SAFI_LABELED_UNICAST
)
5896 bgp_aggregate_add(bgp
, &p
, afi
, SAFI_LABELED_UNICAST
,
5898 if (safi
== SAFI_MULTICAST
)
5899 bgp_aggregate_add(bgp
, &p
, afi
, SAFI_MULTICAST
, aggregate
);
5904 DEFUN (aggregate_address
,
5905 aggregate_address_cmd
,
5906 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5907 "Configure BGP aggregate entries\n"
5908 "Aggregate prefix\n"
5909 "Generate AS set path information\n"
5910 "Filter more specific routes from updates\n"
5911 "Filter more specific routes from updates\n"
5912 "Generate AS set path information\n")
5915 argv_find(argv
, argc
, "A.B.C.D/M", &idx
);
5916 char *prefix
= argv
[idx
]->arg
;
5918 argv_find(argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5920 int summary_only
= argv_find(argv
, argc
, "summary-only", &idx
)
5921 ? AGGREGATE_SUMMARY_ONLY
5924 return bgp_aggregate_set(vty
, prefix
, AFI_IP
, bgp_node_safi(vty
),
5925 summary_only
, as_set
);
5928 DEFUN (aggregate_address_mask
,
5929 aggregate_address_mask_cmd
,
5930 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5931 "Configure BGP aggregate entries\n"
5932 "Aggregate address\n"
5934 "Generate AS set path information\n"
5935 "Filter more specific routes from updates\n"
5936 "Filter more specific routes from updates\n"
5937 "Generate AS set path information\n")
5940 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5941 char *prefix
= argv
[idx
]->arg
;
5942 char *mask
= argv
[idx
+ 1]->arg
;
5944 argv_find(argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
5946 int summary_only
= argv_find(argv
, argc
, "summary-only", &idx
)
5947 ? AGGREGATE_SUMMARY_ONLY
5950 char prefix_str
[BUFSIZ
];
5951 int ret
= netmask_str2prefix_str(prefix
, mask
, prefix_str
);
5954 vty_out(vty
, "%% Inconsistent address and mask\n");
5955 return CMD_WARNING_CONFIG_FAILED
;
5958 return bgp_aggregate_set(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
),
5959 summary_only
, as_set
);
5962 DEFUN (no_aggregate_address
,
5963 no_aggregate_address_cmd
,
5964 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5966 "Configure BGP aggregate entries\n"
5967 "Aggregate prefix\n"
5968 "Generate AS set path information\n"
5969 "Filter more specific routes from updates\n"
5970 "Filter more specific routes from updates\n"
5971 "Generate AS set path information\n")
5974 argv_find(argv
, argc
, "A.B.C.D/M", &idx
);
5975 char *prefix
= argv
[idx
]->arg
;
5976 return bgp_aggregate_unset(vty
, prefix
, AFI_IP
, bgp_node_safi(vty
));
5979 DEFUN (no_aggregate_address_mask
,
5980 no_aggregate_address_mask_cmd
,
5981 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5983 "Configure BGP aggregate entries\n"
5984 "Aggregate address\n"
5986 "Generate AS set path information\n"
5987 "Filter more specific routes from updates\n"
5988 "Filter more specific routes from updates\n"
5989 "Generate AS set path information\n")
5992 argv_find(argv
, argc
, "A.B.C.D", &idx
);
5993 char *prefix
= argv
[idx
]->arg
;
5994 char *mask
= argv
[idx
+ 1]->arg
;
5996 char prefix_str
[BUFSIZ
];
5997 int ret
= netmask_str2prefix_str(prefix
, mask
, prefix_str
);
6000 vty_out(vty
, "%% Inconsistent address and mask\n");
6001 return CMD_WARNING_CONFIG_FAILED
;
6004 return bgp_aggregate_unset(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
));
6007 DEFUN (ipv6_aggregate_address
,
6008 ipv6_aggregate_address_cmd
,
6009 "aggregate-address X:X::X:X/M [summary-only]",
6010 "Configure BGP aggregate entries\n"
6011 "Aggregate prefix\n"
6012 "Filter more specific routes from updates\n")
6015 argv_find(argv
, argc
, "X:X::X:X/M", &idx
);
6016 char *prefix
= argv
[idx
]->arg
;
6017 int sum_only
= argv_find(argv
, argc
, "summary-only", &idx
)
6018 ? AGGREGATE_SUMMARY_ONLY
6020 return bgp_aggregate_set(vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
,
6024 DEFUN (no_ipv6_aggregate_address
,
6025 no_ipv6_aggregate_address_cmd
,
6026 "no aggregate-address X:X::X:X/M [summary-only]",
6028 "Configure BGP aggregate entries\n"
6029 "Aggregate prefix\n"
6030 "Filter more specific routes from updates\n")
6033 argv_find(argv
, argc
, "X:X::X:X/M", &idx
);
6034 char *prefix
= argv
[idx
]->arg
;
6035 return bgp_aggregate_unset(vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
6038 /* Redistribute route treatment. */
6039 void bgp_redistribute_add(struct bgp
*bgp
, struct prefix
*p
,
6040 const union g_addr
*nexthop
, ifindex_t ifindex
,
6041 enum nexthop_types_t nhtype
, uint32_t metric
,
6042 uint8_t type
, unsigned short instance
,
6045 struct bgp_info
*new;
6046 struct bgp_info
*bi
;
6047 struct bgp_info info
;
6048 struct bgp_node
*bn
;
6050 struct attr
*new_attr
;
6053 struct bgp_redist
*red
;
6055 /* Make default attribute. */
6056 bgp_attr_default_set(&attr
, BGP_ORIGIN_INCOMPLETE
);
6059 case NEXTHOP_TYPE_IFINDEX
:
6061 case NEXTHOP_TYPE_IPV4
:
6062 case NEXTHOP_TYPE_IPV4_IFINDEX
:
6063 attr
.nexthop
= nexthop
->ipv4
;
6065 case NEXTHOP_TYPE_IPV6
:
6066 case NEXTHOP_TYPE_IPV6_IFINDEX
:
6067 attr
.mp_nexthop_global
= nexthop
->ipv6
;
6068 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
6070 case NEXTHOP_TYPE_BLACKHOLE
:
6071 switch (p
->family
) {
6073 attr
.nexthop
.s_addr
= INADDR_ANY
;
6076 memset(&attr
.mp_nexthop_global
, 0,
6077 sizeof(attr
.mp_nexthop_global
));
6078 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
6083 attr
.nh_ifindex
= ifindex
;
6086 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
6089 afi
= family2afi(p
->family
);
6091 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6093 struct attr attr_new
;
6095 /* Copy attribute for modification. */
6096 bgp_attr_dup(&attr_new
, &attr
);
6098 if (red
->redist_metric_flag
)
6099 attr_new
.med
= red
->redist_metric
;
6101 /* Apply route-map. */
6102 if (red
->rmap
.name
) {
6103 info
.peer
= bgp
->peer_self
;
6104 info
.attr
= &attr_new
;
6106 SET_FLAG(bgp
->peer_self
->rmap_type
,
6107 PEER_RMAP_TYPE_REDISTRIBUTE
);
6109 ret
= route_map_apply(red
->rmap
.map
, p
, RMAP_BGP
,
6112 bgp
->peer_self
->rmap_type
= 0;
6114 if (ret
== RMAP_DENYMATCH
) {
6115 /* Free uninterned attribute. */
6116 bgp_attr_flush(&attr_new
);
6118 /* Unintern original. */
6119 aspath_unintern(&attr
.aspath
);
6120 bgp_redistribute_delete(bgp
, p
, type
, instance
);
6125 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
6126 bgp_attr_add_gshut_community(&attr_new
);
6128 bn
= bgp_afi_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], afi
,
6129 SAFI_UNICAST
, p
, NULL
);
6131 new_attr
= bgp_attr_intern(&attr_new
);
6133 for (bi
= bn
->info
; bi
; bi
= bi
->next
)
6134 if (bi
->peer
== bgp
->peer_self
6135 && bi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
6139 /* Ensure the (source route) type is updated. */
6141 if (attrhash_cmp(bi
->attr
, new_attr
)
6142 && !CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
)) {
6143 bgp_attr_unintern(&new_attr
);
6144 aspath_unintern(&attr
.aspath
);
6145 bgp_unlock_node(bn
);
6148 /* The attribute is changed. */
6149 bgp_info_set_flag(bn
, bi
,
6150 BGP_INFO_ATTR_CHANGED
);
6152 /* Rewrite BGP route information. */
6153 if (CHECK_FLAG(bi
->flags
, BGP_INFO_REMOVED
))
6154 bgp_info_restore(bn
, bi
);
6156 bgp_aggregate_decrement(bgp
, p
, bi
, afi
,
6158 bgp_attr_unintern(&bi
->attr
);
6159 bi
->attr
= new_attr
;
6160 bi
->uptime
= bgp_clock();
6162 /* Process change. */
6163 bgp_aggregate_increment(bgp
, p
, bi
, afi
,
6165 bgp_process(bgp
, bn
, afi
, SAFI_UNICAST
);
6166 bgp_unlock_node(bn
);
6167 aspath_unintern(&attr
.aspath
);
6169 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6171 == BGP_INSTANCE_TYPE_DEFAULT
)) {
6173 vpn_leak_from_vrf_update(
6174 bgp_get_default(), bgp
, bi
);
6180 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
,
6181 bgp
->peer_self
, new_attr
, bn
);
6182 SET_FLAG(new->flags
, BGP_INFO_VALID
);
6184 bgp_aggregate_increment(bgp
, p
, new, afi
, SAFI_UNICAST
);
6185 bgp_info_add(bn
, new);
6186 bgp_unlock_node(bn
);
6187 bgp_process(bgp
, bn
, afi
, SAFI_UNICAST
);
6189 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6190 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6192 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
6196 /* Unintern original. */
6197 aspath_unintern(&attr
.aspath
);
6200 void bgp_redistribute_delete(struct bgp
*bgp
, struct prefix
*p
, uint8_t type
,
6201 unsigned short instance
)
6204 struct bgp_node
*rn
;
6205 struct bgp_info
*ri
;
6206 struct bgp_redist
*red
;
6208 afi
= family2afi(p
->family
);
6210 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6212 rn
= bgp_afi_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], afi
,
6213 SAFI_UNICAST
, p
, NULL
);
6215 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6216 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== type
)
6220 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6221 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6223 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6226 bgp_aggregate_decrement(bgp
, p
, ri
, afi
, SAFI_UNICAST
);
6227 bgp_info_delete(rn
, ri
);
6228 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
6230 bgp_unlock_node(rn
);
6234 /* Withdraw specified route type's route. */
6235 void bgp_redistribute_withdraw(struct bgp
*bgp
, afi_t afi
, int type
,
6236 unsigned short instance
)
6238 struct bgp_node
*rn
;
6239 struct bgp_info
*ri
;
6240 struct bgp_table
*table
;
6242 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
6244 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
6245 for (ri
= rn
->info
; ri
; ri
= ri
->next
)
6246 if (ri
->peer
== bgp
->peer_self
&& ri
->type
== type
6247 && ri
->instance
== instance
)
6251 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6252 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6254 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6257 bgp_aggregate_decrement(bgp
, &rn
->p
, ri
, afi
,
6259 bgp_info_delete(rn
, ri
);
6260 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
6265 /* Static function to display route. */
6266 static void route_vty_out_route(struct prefix
*p
, struct vty
*vty
,
6270 uint32_t destination
;
6273 if (p
->family
== AF_INET
) {
6275 len
= vty_out(vty
, "%s",
6276 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
6278 destination
= ntohl(p
->u
.prefix4
.s_addr
);
6280 if ((IN_CLASSC(destination
) && p
->prefixlen
== 24)
6281 || (IN_CLASSB(destination
) && p
->prefixlen
== 16)
6282 || (IN_CLASSA(destination
) && p
->prefixlen
== 8)
6283 || p
->u
.prefix4
.s_addr
== 0) {
6284 /* When mask is natural,
6285 mask is not displayed. */
6287 len
+= vty_out(vty
, "/%d", p
->prefixlen
);
6289 json_object_string_add(json
, "prefix",
6290 inet_ntop(p
->family
,
6293 json_object_int_add(json
, "prefixLen", p
->prefixlen
);
6295 } else if (p
->family
== AF_ETHERNET
) {
6296 prefix2str(p
, buf
, PREFIX_STRLEN
);
6297 len
= vty_out(vty
, "%s", buf
);
6298 } else if (p
->family
== AF_EVPN
) {
6299 #if defined(HAVE_CUMULUS)
6303 bgp_evpn_route2str((struct prefix_evpn
*)p
, buf
,
6306 bgp_evpn_route2json((struct prefix_evpn
*)p
, json
);
6308 prefix2str(p
, buf
, PREFIX_STRLEN
);
6309 len
= vty_out(vty
, "%s", buf
);
6315 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6322 vty_out(vty
, "\n%*s", 20, " ");
6324 vty_out(vty
, "%*s", len
, " ");
6328 enum bgp_display_type
{
6332 /* Print the short form route status for a bgp_info */
6333 static void route_vty_short_status_out(struct vty
*vty
, struct bgp_info
*binfo
,
6334 json_object
*json_path
)
6338 /* Route status display. */
6339 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_REMOVED
))
6340 json_object_boolean_true_add(json_path
, "removed");
6342 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_STALE
))
6343 json_object_boolean_true_add(json_path
, "stale");
6345 if (binfo
->extra
&& binfo
->extra
->suppress
)
6346 json_object_boolean_true_add(json_path
, "suppressed");
6348 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)
6349 && !CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6350 json_object_boolean_true_add(json_path
, "valid");
6353 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6354 json_object_boolean_true_add(json_path
, "history");
6356 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
))
6357 json_object_boolean_true_add(json_path
, "damped");
6359 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
))
6360 json_object_boolean_true_add(json_path
, "bestpath");
6362 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_MULTIPATH
))
6363 json_object_boolean_true_add(json_path
, "multipath");
6365 /* Internal route. */
6366 if ((binfo
->peer
->as
)
6367 && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6368 json_object_string_add(json_path
, "pathFrom",
6371 json_object_string_add(json_path
, "pathFrom",
6377 /* Route status display. */
6378 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_REMOVED
))
6380 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_STALE
))
6382 else if (binfo
->extra
&& binfo
->extra
->suppress
)
6384 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)
6385 && !CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6391 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
))
6393 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
))
6395 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
))
6397 else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_MULTIPATH
))
6402 /* Internal route. */
6403 if (binfo
->peer
&& (binfo
->peer
->as
)
6404 && (binfo
->peer
->as
== binfo
->peer
->local_as
))
6410 /* called from terminal list command */
6411 void route_vty_out(struct vty
*vty
, struct prefix
*p
, struct bgp_info
*binfo
,
6412 int display
, safi_t safi
, json_object
*json_paths
)
6415 json_object
*json_path
= NULL
;
6416 json_object
*json_nexthops
= NULL
;
6417 json_object
*json_nexthop_global
= NULL
;
6418 json_object
*json_nexthop_ll
= NULL
;
6421 json_path
= json_object_new_object();
6423 /* short status lead text */
6424 route_vty_short_status_out(vty
, binfo
, json_path
);
6427 /* print prefix and mask */
6429 route_vty_out_route(p
, vty
, json_path
);
6431 vty_out(vty
, "%*s", 17, " ");
6433 route_vty_out_route(p
, vty
, json_path
);
6436 /* Print attribute */
6440 json_object_array_add(json_paths
, json_path
);
6448 * For ENCAP and EVPN routes, nexthop address family is not
6449 * neccessarily the same as the prefix address family.
6450 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6451 * EVPN routes are also exchanged with a MP nexthop. Currently,
6453 * is only IPv4, the value will be present in either
6455 * attr->mp_nexthop_global_in
6457 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
)) {
6460 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
6464 sprintf(nexthop
, "%s",
6465 inet_ntop(af
, &attr
->mp_nexthop_global_in
, buf
,
6469 sprintf(nexthop
, "%s",
6470 inet_ntop(af
, &attr
->mp_nexthop_global
, buf
,
6474 sprintf(nexthop
, "?");
6479 json_nexthop_global
= json_object_new_object();
6481 json_object_string_add(json_nexthop_global
, "afi",
6482 (af
== AF_INET
) ? "ip" : "ipv6");
6483 json_object_string_add(json_nexthop_global
,
6484 (af
== AF_INET
) ? "ip" : "ipv6",
6486 json_object_boolean_true_add(json_nexthop_global
,
6489 vty_out(vty
, "%s", nexthop
);
6490 } else if (safi
== SAFI_EVPN
) {
6492 json_nexthop_global
= json_object_new_object();
6494 json_object_string_add(json_nexthop_global
, "ip",
6495 inet_ntoa(attr
->nexthop
));
6496 json_object_string_add(json_nexthop_global
, "afi",
6498 json_object_boolean_true_add(json_nexthop_global
,
6501 vty_out(vty
, "%-16s", inet_ntoa(attr
->nexthop
));
6504 else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6506 json_nexthop_global
= json_object_new_object();
6508 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6509 json_object_string_add(
6510 json_nexthop_global
, "ip",
6511 inet_ntoa(attr
->mp_nexthop_global_in
));
6513 json_object_string_add(
6514 json_nexthop_global
, "ip",
6515 inet_ntoa(attr
->nexthop
));
6517 json_object_string_add(json_nexthop_global
, "afi",
6519 json_object_boolean_true_add(json_nexthop_global
,
6522 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6523 vty_out(vty
, "%-16s",
6524 inet_ntoa(attr
->mp_nexthop_global_in
));
6526 vty_out(vty
, "%-16s", inet_ntoa(attr
->nexthop
));
6531 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6536 json_nexthop_global
= json_object_new_object();
6537 json_object_string_add(
6538 json_nexthop_global
, "ip",
6539 inet_ntop(AF_INET6
, &attr
->mp_nexthop_global
,
6541 json_object_string_add(json_nexthop_global
, "afi",
6543 json_object_string_add(json_nexthop_global
, "scope",
6546 /* We display both LL & GL if both have been
6548 if ((attr
->mp_nexthop_len
== 32)
6549 || (binfo
->peer
->conf_if
)) {
6550 json_nexthop_ll
= json_object_new_object();
6551 json_object_string_add(
6552 json_nexthop_ll
, "ip",
6554 &attr
->mp_nexthop_local
, buf
,
6556 json_object_string_add(json_nexthop_ll
, "afi",
6558 json_object_string_add(json_nexthop_ll
, "scope",
6561 if ((IPV6_ADDR_CMP(&attr
->mp_nexthop_global
,
6562 &attr
->mp_nexthop_local
)
6564 && !attr
->mp_nexthop_prefer_global
)
6565 json_object_boolean_true_add(
6566 json_nexthop_ll
, "used");
6568 json_object_boolean_true_add(
6569 json_nexthop_global
, "used");
6571 json_object_boolean_true_add(
6572 json_nexthop_global
, "used");
6574 /* Display LL if LL/Global both in table unless
6575 * prefer-global is set */
6576 if (((attr
->mp_nexthop_len
== 32)
6577 && !attr
->mp_nexthop_prefer_global
)
6578 || (binfo
->peer
->conf_if
)) {
6579 if (binfo
->peer
->conf_if
) {
6580 len
= vty_out(vty
, "%s",
6581 binfo
->peer
->conf_if
);
6582 len
= 16 - len
; /* len of IPv6
6588 vty_out(vty
, "\n%*s", 36, " ");
6590 vty_out(vty
, "%*s", len
, " ");
6596 &attr
->mp_nexthop_local
,
6601 vty_out(vty
, "\n%*s", 36, " ");
6603 vty_out(vty
, "%*s", len
, " ");
6609 &attr
->mp_nexthop_global
, buf
,
6614 vty_out(vty
, "\n%*s", 36, " ");
6616 vty_out(vty
, "%*s", len
, " ");
6622 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6624 json_object_int_add(json_path
, "med", attr
->med
);
6626 vty_out(vty
, "%10u", attr
->med
);
6627 else if (!json_paths
)
6631 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6633 json_object_int_add(json_path
, "localpref",
6636 vty_out(vty
, "%7u", attr
->local_pref
);
6637 else if (!json_paths
)
6641 json_object_int_add(json_path
, "weight", attr
->weight
);
6643 vty_out(vty
, "%7u ", attr
->weight
);
6647 json_object_string_add(
6648 json_path
, "peerId",
6649 sockunion2str(&binfo
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6655 json_object_string_add(json_path
, "aspath",
6658 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
6663 json_object_string_add(json_path
, "origin",
6664 bgp_origin_long_str
[attr
->origin
]);
6666 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
6669 if (json_nexthop_global
|| json_nexthop_ll
) {
6670 json_nexthops
= json_object_new_array();
6672 if (json_nexthop_global
)
6673 json_object_array_add(json_nexthops
,
6674 json_nexthop_global
);
6676 if (json_nexthop_ll
)
6677 json_object_array_add(json_nexthops
,
6680 json_object_object_add(json_path
, "nexthops",
6684 json_object_array_add(json_paths
, json_path
);
6688 /* prints an additional line, indented, with VNC info, if
6690 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6691 rfapi_vty_out_vncinfo(vty
, p
, binfo
, safi
);
6696 /* called from terminal list command */
6697 void route_vty_out_tmp(struct vty
*vty
, struct prefix
*p
, struct attr
*attr
,
6698 safi_t safi
, uint8_t use_json
, json_object
*json_ar
)
6700 json_object
*json_status
= NULL
;
6701 json_object
*json_net
= NULL
;
6703 /* Route status display. */
6705 json_status
= json_object_new_object();
6706 json_net
= json_object_new_object();
6713 /* print prefix and mask */
6715 json_object_string_add(
6716 json_net
, "addrPrefix",
6717 inet_ntop(p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6719 route_vty_out_route(p
, vty
, NULL
);
6721 /* Print attribute */
6724 if (p
->family
== AF_INET
6725 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6726 || safi
== SAFI_EVPN
6727 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6728 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6729 || safi
== SAFI_EVPN
)
6730 json_object_string_add(
6731 json_net
, "nextHop",
6733 attr
->mp_nexthop_global_in
));
6735 json_object_string_add(
6736 json_net
, "nextHop",
6737 inet_ntoa(attr
->nexthop
));
6738 } else if (p
->family
== AF_INET6
6739 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6742 json_object_string_add(
6743 json_net
, "netHopGloabal",
6745 &attr
->mp_nexthop_global
, buf
,
6750 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6751 json_object_int_add(json_net
, "metric",
6754 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6755 json_object_int_add(json_net
, "localPref",
6758 json_object_int_add(json_net
, "weight", attr
->weight
);
6762 json_object_string_add(json_net
, "asPath",
6766 json_object_string_add(json_net
, "bgpOriginCode",
6767 bgp_origin_str
[attr
->origin
]);
6769 if (p
->family
== AF_INET
6770 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6771 || safi
== SAFI_EVPN
6772 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6773 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6774 || safi
== SAFI_EVPN
)
6775 vty_out(vty
, "%-16s",
6777 attr
->mp_nexthop_global_in
));
6779 vty_out(vty
, "%-16s",
6780 inet_ntoa(attr
->nexthop
));
6781 } else if (p
->family
== AF_INET6
6782 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6789 &attr
->mp_nexthop_global
, buf
,
6793 vty_out(vty
, "\n%*s", 36, " ");
6795 vty_out(vty
, "%*s", len
, " ");
6798 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6799 vty_out(vty
, "%10u", attr
->med
);
6803 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6804 vty_out(vty
, "%7u", attr
->local_pref
);
6808 vty_out(vty
, "%7u ", attr
->weight
);
6812 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
6815 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
6819 json_object_boolean_true_add(json_status
, "*");
6820 json_object_boolean_true_add(json_status
, ">");
6821 json_object_object_add(json_net
, "appliedStatusSymbols",
6823 char buf_cut
[BUFSIZ
];
6824 json_object_object_add(
6826 inet_ntop(p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
),
6832 void route_vty_out_tag(struct vty
*vty
, struct prefix
*p
,
6833 struct bgp_info
*binfo
, int display
, safi_t safi
,
6836 json_object
*json_out
= NULL
;
6838 mpls_label_t label
= MPLS_INVALID_LABEL
;
6844 json_out
= json_object_new_object();
6846 /* short status lead text */
6847 route_vty_short_status_out(vty
, binfo
, json_out
);
6849 /* print prefix and mask */
6852 route_vty_out_route(p
, vty
, NULL
);
6854 vty_out(vty
, "%*s", 17, " ");
6857 /* Print attribute */
6860 if (((p
->family
== AF_INET
)
6861 && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6862 || (safi
== SAFI_EVPN
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6863 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6864 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6865 || safi
== SAFI_EVPN
) {
6867 json_object_string_add(
6868 json_out
, "mpNexthopGlobalIn",
6870 attr
->mp_nexthop_global_in
));
6872 vty_out(vty
, "%-16s",
6874 attr
->mp_nexthop_global_in
));
6877 json_object_string_add(
6878 json_out
, "nexthop",
6879 inet_ntoa(attr
->nexthop
));
6881 vty_out(vty
, "%-16s",
6882 inet_ntoa(attr
->nexthop
));
6884 } else if (((p
->family
== AF_INET6
)
6885 && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
6886 || (safi
== SAFI_EVPN
6887 && BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
6888 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6892 if (attr
->mp_nexthop_len
6893 == BGP_ATTR_NHLEN_IPV6_GLOBAL
) {
6895 json_object_string_add(
6896 json_out
, "mpNexthopGlobalIn",
6899 &attr
->mp_nexthop_global
,
6905 &attr
->mp_nexthop_global
,
6907 } else if (attr
->mp_nexthop_len
6908 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) {
6911 &attr
->mp_nexthop_global
,
6914 &attr
->mp_nexthop_local
,
6916 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
6917 json_object_string_add(
6919 "mpNexthopGlobalLocal", buf_c
);
6921 vty_out(vty
, "%s(%s)",
6924 &attr
->mp_nexthop_global
,
6928 &attr
->mp_nexthop_local
,
6934 label
= decode_label(&binfo
->extra
->label
[0]);
6936 if (bgp_is_valid_label(&label
)) {
6938 json_object_int_add(json_out
, "notag", label
);
6939 json_object_array_add(json
, json_out
);
6941 vty_out(vty
, "notag/%d", label
);
6947 void route_vty_out_overlay(struct vty
*vty
, struct prefix
*p
,
6948 struct bgp_info
*binfo
, int display
,
6949 json_object
*json_paths
)
6953 json_object
*json_path
= NULL
;
6956 json_path
= json_object_new_object();
6961 /* short status lead text */
6962 route_vty_short_status_out(vty
, binfo
, json_path
);
6964 /* print prefix and mask */
6966 route_vty_out_route(p
, vty
, NULL
);
6968 vty_out(vty
, "%*s", 17, " ");
6970 /* Print attribute */
6974 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
6978 vty_out(vty
, "%-16s",
6979 inet_ntop(af
, &attr
->mp_nexthop_global_in
, buf
,
6983 vty_out(vty
, "%s(%s)",
6984 inet_ntop(af
, &attr
->mp_nexthop_global
, buf
,
6986 inet_ntop(af
, &attr
->mp_nexthop_local
, buf1
,
6994 struct eth_segment_id
*id
= &(attr
->evpn_overlay
.eth_s_id
);
6995 char *str
= esi2str(id
);
6996 vty_out(vty
, "%s", str
);
6997 XFREE(MTYPE_TMP
, str
);
6998 if (IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn
*)p
)) {
6999 vty_out(vty
, "/%s", inet_ntoa(attr
->evpn_overlay
.gw_ip
.ipv4
));
7000 } else if (IS_EVPN_PREFIX_IPADDR_V6((struct prefix_evpn
*)p
)) {
7002 inet_ntop(AF_INET6
, &(attr
->evpn_overlay
.gw_ip
.ipv6
),
7005 if (attr
->ecommunity
) {
7007 struct ecommunity_val
*routermac
= ecommunity_lookup(
7008 attr
->ecommunity
, ECOMMUNITY_ENCODE_EVPN
,
7009 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC
);
7011 mac
= ecom_mac2str((char *)routermac
->val
);
7013 vty_out(vty
, "/%s", (char *)mac
);
7014 XFREE(MTYPE_TMP
, mac
);
7020 /* dampening route */
7021 static void damp_route_vty_out(struct vty
*vty
, struct prefix
*p
,
7022 struct bgp_info
*binfo
, int display
, safi_t safi
,
7023 uint8_t use_json
, json_object
*json
)
7027 char timebuf
[BGP_UPTIME_LEN
];
7029 /* short status lead text */
7030 route_vty_short_status_out(vty
, binfo
, json
);
7032 /* print prefix and mask */
7035 route_vty_out_route(p
, vty
, NULL
);
7037 vty_out(vty
, "%*s", 17, " ");
7040 len
= vty_out(vty
, "%s", binfo
->peer
->host
);
7044 vty_out(vty
, "\n%*s", 34, " ");
7047 json_object_int_add(json
, "peerHost", len
);
7049 vty_out(vty
, "%*s", len
, " ");
7053 bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
, BGP_UPTIME_LEN
,
7056 vty_out(vty
, "%s ", bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
,
7060 /* Print attribute */
7066 json_object_string_add(json
, "asPath",
7069 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7074 json_object_string_add(json
, "origin",
7075 bgp_origin_str
[attr
->origin
]);
7077 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7084 static void flap_route_vty_out(struct vty
*vty
, struct prefix
*p
,
7085 struct bgp_info
*binfo
, int display
, safi_t safi
,
7086 uint8_t use_json
, json_object
*json
)
7089 struct bgp_damp_info
*bdi
;
7090 char timebuf
[BGP_UPTIME_LEN
];
7096 bdi
= binfo
->extra
->damp_info
;
7098 /* short status lead text */
7099 route_vty_short_status_out(vty
, binfo
, json
);
7101 /* print prefix and mask */
7104 route_vty_out_route(p
, vty
, NULL
);
7106 vty_out(vty
, "%*s", 17, " ");
7109 len
= vty_out(vty
, "%s", binfo
->peer
->host
);
7113 vty_out(vty
, "\n%*s", 33, " ");
7116 json_object_int_add(json
, "peerHost", len
);
7118 vty_out(vty
, "%*s", len
, " ");
7121 len
= vty_out(vty
, "%d", bdi
->flap
);
7128 json_object_int_add(json
, "bdiFlap", len
);
7130 vty_out(vty
, "%*s", len
, " ");
7134 peer_uptime(bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
,
7137 vty_out(vty
, "%s ", peer_uptime(bdi
->start_time
, timebuf
,
7138 BGP_UPTIME_LEN
, 0, NULL
));
7140 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
)
7141 && !CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
)) {
7143 bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
,
7144 BGP_UPTIME_LEN
, use_json
, json
);
7147 bgp_damp_reuse_time_vty(vty
, binfo
, timebuf
,
7152 vty_out(vty
, "%*s ", 8, " ");
7155 /* Print attribute */
7161 json_object_string_add(json
, "asPath",
7164 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7169 json_object_string_add(json
, "origin",
7170 bgp_origin_str
[attr
->origin
]);
7172 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7178 static void route_vty_out_advertised_to(struct vty
*vty
, struct peer
*peer
,
7179 int *first
, const char *header
,
7180 json_object
*json_adv_to
)
7182 char buf1
[INET6_ADDRSTRLEN
];
7183 json_object
*json_peer
= NULL
;
7186 /* 'advertised-to' is a dictionary of peers we have advertised
7188 * prefix too. The key is the peer's IP or swpX, the value is
7190 * hostname if we know it and "" if not.
7192 json_peer
= json_object_new_object();
7195 json_object_string_add(json_peer
, "hostname",
7199 json_object_object_add(json_adv_to
, peer
->conf_if
,
7202 json_object_object_add(
7204 sockunion2str(&peer
->su
, buf1
, SU_ADDRSTRLEN
),
7208 vty_out(vty
, "%s", header
);
7213 && bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
)) {
7215 vty_out(vty
, " %s(%s)", peer
->hostname
,
7218 vty_out(vty
, " %s(%s)", peer
->hostname
,
7219 sockunion2str(&peer
->su
, buf1
,
7223 vty_out(vty
, " %s", peer
->conf_if
);
7226 sockunion2str(&peer
->su
, buf1
,
7232 void route_vty_out_detail(struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
7233 struct bgp_info
*binfo
, afi_t afi
, safi_t safi
,
7234 json_object
*json_paths
)
7236 char buf
[INET6_ADDRSTRLEN
];
7238 #if defined(HAVE_CUMULUS)
7239 char buf2
[EVPN_ROUTE_STRLEN
];
7242 int sockunion_vty_out(struct vty
*, union sockunion
*);
7244 json_object
*json_bestpath
= NULL
;
7245 json_object
*json_cluster_list
= NULL
;
7246 json_object
*json_cluster_list_list
= NULL
;
7247 json_object
*json_ext_community
= NULL
;
7248 json_object
*json_lcommunity
= NULL
;
7249 json_object
*json_last_update
= NULL
;
7250 json_object
*json_pmsi
= NULL
;
7251 json_object
*json_nexthop_global
= NULL
;
7252 json_object
*json_nexthop_ll
= NULL
;
7253 json_object
*json_nexthops
= NULL
;
7254 json_object
*json_path
= NULL
;
7255 json_object
*json_peer
= NULL
;
7256 json_object
*json_string
= NULL
;
7257 json_object
*json_adv_to
= NULL
;
7259 struct listnode
*node
, *nnode
;
7261 int addpath_capable
;
7263 unsigned int first_as
;
7266 json_path
= json_object_new_object();
7267 json_peer
= json_object_new_object();
7268 json_nexthop_global
= json_object_new_object();
7271 #if defined(HAVE_CUMULUS)
7272 if (!json_paths
&& safi
== SAFI_EVPN
) {
7275 bgp_evpn_route2str((struct prefix_evpn
*)p
, buf2
, sizeof(buf2
));
7276 vty_out(vty
, " Route %s", buf2
);
7278 if (binfo
->extra
&& binfo
->extra
->num_labels
) {
7279 bgp_evpn_label2str(binfo
->extra
->label
,
7280 binfo
->extra
->num_labels
, tag_buf
,
7282 vty_out(vty
, " VNI %s", tag_buf
);
7285 if (binfo
->extra
&& binfo
->extra
->parent
) {
7286 struct bgp_info
*parent_ri
;
7287 struct bgp_node
*rn
, *prn
;
7289 parent_ri
= (struct bgp_info
*)binfo
->extra
->parent
;
7290 rn
= parent_ri
->net
;
7291 if (rn
&& rn
->prn
) {
7293 vty_out(vty
, " Imported from %s:%s\n",
7295 (struct prefix_rd
*)&prn
->p
,
7296 buf1
, sizeof(buf1
)),
7306 /* Line1 display AS-path, Aggregator */
7309 if (!attr
->aspath
->json
)
7310 aspath_str_update(attr
->aspath
, true);
7311 json_object_lock(attr
->aspath
->json
);
7312 json_object_object_add(json_path
, "aspath",
7313 attr
->aspath
->json
);
7315 if (attr
->aspath
->segments
)
7316 aspath_print_vty(vty
, " %s",
7319 vty_out(vty
, " Local");
7323 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_REMOVED
)) {
7325 json_object_boolean_true_add(json_path
,
7328 vty_out(vty
, ", (removed)");
7331 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_STALE
)) {
7333 json_object_boolean_true_add(json_path
,
7336 vty_out(vty
, ", (stale)");
7339 if (CHECK_FLAG(attr
->flag
,
7340 ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR
))) {
7342 json_object_int_add(json_path
, "aggregatorAs",
7343 attr
->aggregator_as
);
7344 json_object_string_add(
7345 json_path
, "aggregatorId",
7346 inet_ntoa(attr
->aggregator_addr
));
7348 vty_out(vty
, ", (aggregated by %u %s)",
7349 attr
->aggregator_as
,
7350 inet_ntoa(attr
->aggregator_addr
));
7354 if (CHECK_FLAG(binfo
->peer
->af_flags
[afi
][safi
],
7355 PEER_FLAG_REFLECTOR_CLIENT
)) {
7357 json_object_boolean_true_add(
7358 json_path
, "rxedFromRrClient");
7360 vty_out(vty
, ", (Received from a RR-client)");
7363 if (CHECK_FLAG(binfo
->peer
->af_flags
[afi
][safi
],
7364 PEER_FLAG_RSERVER_CLIENT
)) {
7366 json_object_boolean_true_add(
7367 json_path
, "rxedFromRsClient");
7369 vty_out(vty
, ", (Received from a RS-client)");
7372 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
)) {
7374 json_object_boolean_true_add(
7375 json_path
, "dampeningHistoryEntry");
7377 vty_out(vty
, ", (history entry)");
7378 } else if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DAMPED
)) {
7380 json_object_boolean_true_add(
7381 json_path
, "dampeningSuppressed");
7383 vty_out(vty
, ", (suppressed due to dampening)");
7389 /* Line2 display Next-hop, Neighbor, Router-id */
7390 /* Display the nexthop */
7391 if ((p
->family
== AF_INET
|| p
->family
== AF_ETHERNET
7392 || p
->family
== AF_EVPN
)
7393 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7394 || safi
== SAFI_EVPN
7395 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7396 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7397 || safi
== SAFI_EVPN
) {
7399 json_object_string_add(
7400 json_nexthop_global
, "ip",
7402 attr
->mp_nexthop_global_in
));
7406 attr
->mp_nexthop_global_in
));
7409 json_object_string_add(
7410 json_nexthop_global
, "ip",
7411 inet_ntoa(attr
->nexthop
));
7414 inet_ntoa(attr
->nexthop
));
7418 json_object_string_add(json_nexthop_global
,
7422 json_object_string_add(
7423 json_nexthop_global
, "ip",
7425 &attr
->mp_nexthop_global
, buf
,
7427 json_object_string_add(json_nexthop_global
,
7429 json_object_string_add(json_nexthop_global
,
7434 &attr
->mp_nexthop_global
, buf
,
7439 /* Display the IGP cost or 'inaccessible' */
7440 if (!CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)) {
7442 json_object_boolean_false_add(
7443 json_nexthop_global
, "accessible");
7445 vty_out(vty
, " (inaccessible)");
7447 if (binfo
->extra
&& binfo
->extra
->igpmetric
) {
7449 json_object_int_add(
7450 json_nexthop_global
, "metric",
7451 binfo
->extra
->igpmetric
);
7453 vty_out(vty
, " (metric %u)",
7454 binfo
->extra
->igpmetric
);
7457 /* IGP cost is 0, display this only for json */
7460 json_object_int_add(json_nexthop_global
,
7465 json_object_boolean_true_add(
7466 json_nexthop_global
, "accessible");
7469 /* Display peer "from" output */
7470 /* This path was originated locally */
7471 if (binfo
->peer
== bgp
->peer_self
) {
7473 if (safi
== SAFI_EVPN
7474 || (p
->family
== AF_INET
7475 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7477 json_object_string_add(
7478 json_peer
, "peerId", "0.0.0.0");
7480 vty_out(vty
, " from 0.0.0.0 ");
7483 json_object_string_add(json_peer
,
7486 vty_out(vty
, " from :: ");
7490 json_object_string_add(
7491 json_peer
, "routerId",
7492 inet_ntoa(bgp
->router_id
));
7494 vty_out(vty
, "(%s)", inet_ntoa(bgp
->router_id
));
7497 /* We RXed this path from one of our peers */
7501 json_object_string_add(
7502 json_peer
, "peerId",
7503 sockunion2str(&binfo
->peer
->su
, buf
,
7505 json_object_string_add(
7506 json_peer
, "routerId",
7508 &binfo
->peer
->remote_id
, buf1
,
7511 if (binfo
->peer
->hostname
)
7512 json_object_string_add(
7513 json_peer
, "hostname",
7514 binfo
->peer
->hostname
);
7516 if (binfo
->peer
->domainname
)
7517 json_object_string_add(
7518 json_peer
, "domainname",
7519 binfo
->peer
->domainname
);
7521 if (binfo
->peer
->conf_if
)
7522 json_object_string_add(
7523 json_peer
, "interface",
7524 binfo
->peer
->conf_if
);
7526 if (binfo
->peer
->conf_if
) {
7527 if (binfo
->peer
->hostname
7530 BGP_FLAG_SHOW_HOSTNAME
))
7531 vty_out(vty
, " from %s(%s)",
7532 binfo
->peer
->hostname
,
7533 binfo
->peer
->conf_if
);
7535 vty_out(vty
, " from %s",
7536 binfo
->peer
->conf_if
);
7538 if (binfo
->peer
->hostname
7541 BGP_FLAG_SHOW_HOSTNAME
))
7542 vty_out(vty
, " from %s(%s)",
7543 binfo
->peer
->hostname
,
7546 vty_out(vty
, " from %s",
7555 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7556 vty_out(vty
, " (%s)",
7557 inet_ntoa(attr
->originator_id
));
7559 vty_out(vty
, " (%s)",
7562 &binfo
->peer
->remote_id
,
7563 buf1
, sizeof(buf1
)));
7570 /* display the link-local nexthop */
7571 if (attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) {
7573 json_nexthop_ll
= json_object_new_object();
7574 json_object_string_add(
7575 json_nexthop_ll
, "ip",
7577 &attr
->mp_nexthop_local
, buf
,
7579 json_object_string_add(json_nexthop_ll
, "afi",
7581 json_object_string_add(json_nexthop_ll
, "scope",
7584 json_object_boolean_true_add(json_nexthop_ll
,
7587 if (!attr
->mp_nexthop_prefer_global
)
7588 json_object_boolean_true_add(
7589 json_nexthop_ll
, "used");
7591 json_object_boolean_true_add(
7592 json_nexthop_global
, "used");
7594 vty_out(vty
, " (%s) %s\n",
7596 &attr
->mp_nexthop_local
, buf
,
7598 attr
->mp_nexthop_prefer_global
7603 /* If we do not have a link-local nexthop then we must flag the
7607 json_object_boolean_true_add(
7608 json_nexthop_global
, "used");
7611 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
7612 * Int/Ext/Local, Atomic, best */
7614 json_object_string_add(
7615 json_path
, "origin",
7616 bgp_origin_long_str
[attr
->origin
]);
7618 vty_out(vty
, " Origin %s",
7619 bgp_origin_long_str
[attr
->origin
]);
7621 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)) {
7623 json_object_int_add(json_path
, "med",
7626 vty_out(vty
, ", metric %u", attr
->med
);
7629 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
7631 json_object_int_add(json_path
, "localpref",
7634 vty_out(vty
, ", localpref %u",
7638 json_object_int_add(json_path
, "localpref",
7639 bgp
->default_local_pref
);
7641 vty_out(vty
, ", localpref %u",
7642 bgp
->default_local_pref
);
7645 if (attr
->weight
!= 0) {
7647 json_object_int_add(json_path
, "weight",
7650 vty_out(vty
, ", weight %u", attr
->weight
);
7653 if (attr
->tag
!= 0) {
7655 json_object_int_add(json_path
, "tag",
7658 vty_out(vty
, ", tag %" ROUTE_TAG_PRI
,
7662 if (!CHECK_FLAG(binfo
->flags
, BGP_INFO_VALID
)) {
7664 json_object_boolean_false_add(json_path
,
7667 vty_out(vty
, ", invalid");
7668 } else if (!CHECK_FLAG(binfo
->flags
, BGP_INFO_HISTORY
)) {
7670 json_object_boolean_true_add(json_path
,
7673 vty_out(vty
, ", valid");
7676 if (binfo
->peer
!= bgp
->peer_self
) {
7677 if (binfo
->peer
->as
== binfo
->peer
->local_as
) {
7678 if (CHECK_FLAG(bgp
->config
,
7679 BGP_CONFIG_CONFEDERATION
)) {
7681 json_object_string_add(
7686 ", confed-internal");
7689 json_object_string_add(
7693 vty_out(vty
, ", internal");
7696 if (bgp_confederation_peers_check(
7697 bgp
, binfo
->peer
->as
)) {
7699 json_object_string_add(
7704 ", confed-external");
7707 json_object_string_add(
7711 vty_out(vty
, ", external");
7714 } else if (binfo
->sub_type
== BGP_ROUTE_AGGREGATE
) {
7716 json_object_boolean_true_add(json_path
,
7718 json_object_boolean_true_add(json_path
,
7721 vty_out(vty
, ", aggregated, local");
7723 } else if (binfo
->type
!= ZEBRA_ROUTE_BGP
) {
7725 json_object_boolean_true_add(json_path
,
7728 vty_out(vty
, ", sourced");
7731 json_object_boolean_true_add(json_path
,
7733 json_object_boolean_true_add(json_path
,
7736 vty_out(vty
, ", sourced, local");
7740 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
)) {
7742 json_object_boolean_true_add(json_path
,
7745 vty_out(vty
, ", atomic-aggregate");
7748 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_MULTIPATH
)
7749 || (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
)
7750 && bgp_info_mpath_count(binfo
))) {
7752 json_object_boolean_true_add(json_path
,
7755 vty_out(vty
, ", multipath");
7758 // Mark the bestpath(s)
7759 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_DMED_SELECTED
)) {
7760 first_as
= aspath_get_first_as(attr
->aspath
);
7765 json_object_new_object();
7766 json_object_int_add(json_bestpath
,
7767 "bestpathFromAs", first_as
);
7770 vty_out(vty
, ", bestpath-from-AS %u",
7774 ", bestpath-from-AS Local");
7778 if (CHECK_FLAG(binfo
->flags
, BGP_INFO_SELECTED
)) {
7782 json_object_new_object();
7783 json_object_boolean_true_add(json_bestpath
,
7786 vty_out(vty
, ", best");
7790 json_object_object_add(json_path
, "bestpath",
7796 /* Line 4 display Community */
7797 if (attr
->community
) {
7799 if (!attr
->community
->json
)
7800 community_str(attr
->community
, true);
7801 json_object_lock(attr
->community
->json
);
7802 json_object_object_add(json_path
, "community",
7803 attr
->community
->json
);
7805 vty_out(vty
, " Community: %s\n",
7806 attr
->community
->str
);
7810 /* Line 5 display Extended-community */
7811 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)) {
7813 json_ext_community
= json_object_new_object();
7814 json_object_string_add(json_ext_community
,
7816 attr
->ecommunity
->str
);
7817 json_object_object_add(json_path
,
7818 "extendedCommunity",
7819 json_ext_community
);
7821 vty_out(vty
, " Extended Community: %s\n",
7822 attr
->ecommunity
->str
);
7826 /* Line 6 display Large community */
7827 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
)) {
7829 json_lcommunity
= json_object_new_object();
7830 json_object_string_add(json_lcommunity
,
7832 attr
->lcommunity
->str
);
7833 json_object_object_add(json_path
,
7837 vty_out(vty
, " Large Community: %s\n",
7838 attr
->lcommunity
->str
);
7842 /* Line 7 display Originator, Cluster-id */
7843 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7844 || (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))) {
7846 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) {
7848 json_object_string_add(
7849 json_path
, "originatorId",
7850 inet_ntoa(attr
->originator_id
));
7852 vty_out(vty
, " Originator: %s",
7853 inet_ntoa(attr
->originator_id
));
7856 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)) {
7861 json_object_new_object();
7862 json_cluster_list_list
=
7863 json_object_new_array();
7866 i
< attr
->cluster
->length
/ 4;
7868 json_string
= json_object_new_string(
7872 json_object_array_add(
7873 json_cluster_list_list
,
7877 /* struct cluster_list does not have
7879 * aspath and community do. Add this
7882 json_object_string_add(json_cluster_list,
7883 "string", attr->cluster->str);
7885 json_object_object_add(
7886 json_cluster_list
, "list",
7887 json_cluster_list_list
);
7888 json_object_object_add(
7889 json_path
, "clusterList",
7892 vty_out(vty
, ", Cluster list: ");
7895 i
< attr
->cluster
->length
/ 4;
7909 if (binfo
->extra
&& binfo
->extra
->damp_info
)
7910 bgp_damp_info_vty(vty
, binfo
, json_path
);
7913 #if defined(HAVE_CUMULUS)
7914 if (binfo
->extra
&& bgp_is_valid_label(&binfo
->extra
->label
[0])
7915 && safi
!= SAFI_EVPN
)
7917 if (binfo
->extra
&& bgp_is_valid_label(&binfo
->extra
->label
[0]))
7920 mpls_label_t label
=
7921 label_pton(&binfo
->extra
->label
[0]);
7923 json_object_int_add(json_path
, "remoteLabel",
7926 vty_out(vty
, " Remote label: %d\n", label
);
7930 if (attr
->label_index
!= BGP_INVALID_LABEL_INDEX
) {
7932 json_object_int_add(json_path
, "labelIndex",
7935 vty_out(vty
, " Label Index: %d\n",
7939 /* Line 8 display Addpath IDs */
7940 if (binfo
->addpath_rx_id
|| binfo
->addpath_tx_id
) {
7942 json_object_int_add(json_path
, "addpathRxId",
7943 binfo
->addpath_rx_id
);
7944 json_object_int_add(json_path
, "addpathTxId",
7945 binfo
->addpath_tx_id
);
7947 vty_out(vty
, " AddPath ID: RX %u, TX %u\n",
7948 binfo
->addpath_rx_id
,
7949 binfo
->addpath_tx_id
);
7953 /* If we used addpath to TX a non-bestpath we need to display
7954 * "Advertised to" on a path-by-path basis */
7955 if (bgp
->addpath_tx_used
[afi
][safi
]) {
7958 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
7960 bgp_addpath_encode_tx(peer
, afi
, safi
);
7961 has_adj
= bgp_adj_out_lookup(
7962 peer
, binfo
->net
, binfo
->addpath_tx_id
);
7964 if ((addpath_capable
&& has_adj
)
7965 || (!addpath_capable
&& has_adj
7966 && CHECK_FLAG(binfo
->flags
,
7967 BGP_INFO_SELECTED
))) {
7968 if (json_path
&& !json_adv_to
)
7970 json_object_new_object();
7972 route_vty_out_advertised_to(
7981 json_object_object_add(json_path
,
7992 /* Line 9 display Uptime */
7993 tbuf
= time(NULL
) - (bgp_clock() - binfo
->uptime
);
7995 json_last_update
= json_object_new_object();
7996 json_object_int_add(json_last_update
, "epoch", tbuf
);
7997 json_object_string_add(json_last_update
, "string",
7999 json_object_object_add(json_path
, "lastUpdate",
8002 vty_out(vty
, " Last update: %s", ctime(&tbuf
));
8004 /* Line 10 display PMSI tunnel attribute, if present */
8005 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL
)) {
8006 const char *str
= lookup_msg(bgp_pmsi_tnltype_str
,
8007 attr
->pmsi_tnl_type
,
8008 PMSI_TNLTYPE_STR_DEFAULT
);
8011 json_pmsi
= json_object_new_object();
8012 json_object_string_add(json_pmsi
,
8014 json_object_object_add(json_path
, "pmsi",
8017 vty_out(vty
, " PMSI Tunnel Type: %s\n",
8023 /* We've constructed the json object for this path, add it to the json
8027 if (json_nexthop_global
|| json_nexthop_ll
) {
8028 json_nexthops
= json_object_new_array();
8030 if (json_nexthop_global
)
8031 json_object_array_add(json_nexthops
,
8032 json_nexthop_global
);
8034 if (json_nexthop_ll
)
8035 json_object_array_add(json_nexthops
,
8038 json_object_object_add(json_path
, "nexthops",
8042 json_object_object_add(json_path
, "peer", json_peer
);
8043 json_object_array_add(json_paths
, json_path
);
8048 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
8049 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
8050 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
8052 static int bgp_show_prefix_list(struct vty
*vty
, struct bgp
*bgp
,
8053 const char *prefix_list_str
, afi_t afi
,
8054 safi_t safi
, enum bgp_show_type type
);
8055 static int bgp_show_filter_list(struct vty
*vty
, struct bgp
*bgp
,
8056 const char *filter
, afi_t afi
, safi_t safi
,
8057 enum bgp_show_type type
);
8058 static int bgp_show_route_map(struct vty
*vty
, struct bgp
*bgp
,
8059 const char *rmap_str
, afi_t afi
, safi_t safi
,
8060 enum bgp_show_type type
);
8061 static int bgp_show_community_list(struct vty
*vty
, struct bgp
*bgp
,
8062 const char *com
, int exact
, afi_t afi
,
8064 static int bgp_show_prefix_longer(struct vty
*vty
, struct bgp
*bgp
,
8065 const char *prefix
, afi_t afi
, safi_t safi
,
8066 enum bgp_show_type type
);
8067 static int bgp_show_regexp(struct vty
*vty
, struct bgp
*bgp
, const char *regstr
,
8068 afi_t afi
, safi_t safi
, enum bgp_show_type type
);
8069 static int bgp_show_community(struct vty
*vty
, struct bgp
*bgp
,
8070 const char *comstr
, int exact
, afi_t afi
,
8074 static int bgp_show_table(struct vty
*vty
, struct bgp
*bgp
, safi_t safi
,
8075 struct bgp_table
*table
, enum bgp_show_type type
,
8076 void *output_arg
, uint8_t use_json
, char *rd
,
8077 int is_last
, unsigned long *output_cum
,
8078 unsigned long *total_cum
,
8079 unsigned long *json_header_depth
)
8081 struct bgp_info
*ri
;
8082 struct bgp_node
*rn
;
8085 unsigned long output_count
= 0;
8086 unsigned long total_count
= 0;
8090 json_object
*json_paths
= NULL
;
8093 if (output_cum
&& *output_cum
!= 0)
8096 if (use_json
&& !*json_header_depth
) {
8098 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
8099 ",\n \"routerId\": \"%s\",\n \"routes\": { ",
8100 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : (int)bgp
->vrf_id
,
8101 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
? "Default"
8103 table
->version
, inet_ntoa(bgp
->router_id
));
8104 *json_header_depth
= 2;
8106 vty_out(vty
, " \"routeDistinguishers\" : {");
8107 ++*json_header_depth
;
8109 json_paths
= json_object_new_object();
8112 if (use_json
&& rd
) {
8113 vty_out(vty
, " \"%s\" : { ", rd
);
8116 /* Start processing of routes. */
8117 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
8118 if (rn
->info
== NULL
)
8123 json_paths
= json_object_new_array();
8127 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
8129 if (type
== bgp_show_type_flap_statistics
8130 || type
== bgp_show_type_flap_neighbor
8131 || type
== bgp_show_type_dampend_paths
8132 || type
== bgp_show_type_damp_neighbor
) {
8133 if (!(ri
->extra
&& ri
->extra
->damp_info
))
8136 if (type
== bgp_show_type_regexp
) {
8137 regex_t
*regex
= output_arg
;
8139 if (bgp_regexec(regex
, ri
->attr
->aspath
)
8143 if (type
== bgp_show_type_prefix_list
) {
8144 struct prefix_list
*plist
= output_arg
;
8146 if (prefix_list_apply(plist
, &rn
->p
)
8150 if (type
== bgp_show_type_filter_list
) {
8151 struct as_list
*as_list
= output_arg
;
8153 if (as_list_apply(as_list
, ri
->attr
->aspath
)
8154 != AS_FILTER_PERMIT
)
8157 if (type
== bgp_show_type_route_map
) {
8158 struct route_map
*rmap
= output_arg
;
8159 struct bgp_info binfo
;
8160 struct attr dummy_attr
;
8163 bgp_attr_dup(&dummy_attr
, ri
->attr
);
8165 binfo
.peer
= ri
->peer
;
8166 binfo
.attr
= &dummy_attr
;
8168 ret
= route_map_apply(rmap
, &rn
->p
, RMAP_BGP
,
8170 if (ret
== RMAP_DENYMATCH
)
8173 if (type
== bgp_show_type_neighbor
8174 || type
== bgp_show_type_flap_neighbor
8175 || type
== bgp_show_type_damp_neighbor
) {
8176 union sockunion
*su
= output_arg
;
8178 if (ri
->peer
== NULL
8179 || ri
->peer
->su_remote
== NULL
8180 || !sockunion_same(ri
->peer
->su_remote
, su
))
8183 if (type
== bgp_show_type_cidr_only
) {
8184 uint32_t destination
;
8186 destination
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
8187 if (IN_CLASSC(destination
)
8188 && rn
->p
.prefixlen
== 24)
8190 if (IN_CLASSB(destination
)
8191 && rn
->p
.prefixlen
== 16)
8193 if (IN_CLASSA(destination
)
8194 && rn
->p
.prefixlen
== 8)
8197 if (type
== bgp_show_type_prefix_longer
) {
8198 struct prefix
*p
= output_arg
;
8200 if (!prefix_match(p
, &rn
->p
))
8203 if (type
== bgp_show_type_community_all
) {
8204 if (!ri
->attr
->community
)
8207 if (type
== bgp_show_type_community
) {
8208 struct community
*com
= output_arg
;
8210 if (!ri
->attr
->community
8211 || !community_match(ri
->attr
->community
,
8215 if (type
== bgp_show_type_community_exact
) {
8216 struct community
*com
= output_arg
;
8218 if (!ri
->attr
->community
8219 || !community_cmp(ri
->attr
->community
, com
))
8222 if (type
== bgp_show_type_community_list
) {
8223 struct community_list
*list
= output_arg
;
8225 if (!community_list_match(ri
->attr
->community
,
8229 if (type
== bgp_show_type_community_list_exact
) {
8230 struct community_list
*list
= output_arg
;
8232 if (!community_list_exact_match(
8233 ri
->attr
->community
, list
))
8236 if (type
== bgp_show_type_lcommunity
) {
8237 struct lcommunity
*lcom
= output_arg
;
8239 if (!ri
->attr
->lcommunity
8240 || !lcommunity_match(ri
->attr
->lcommunity
,
8244 if (type
== bgp_show_type_lcommunity_list
) {
8245 struct community_list
*list
= output_arg
;
8247 if (!lcommunity_list_match(ri
->attr
->lcommunity
,
8251 if (type
== bgp_show_type_lcommunity_all
) {
8252 if (!ri
->attr
->lcommunity
)
8255 if (type
== bgp_show_type_dampend_paths
8256 || type
== bgp_show_type_damp_neighbor
) {
8257 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_DAMPED
)
8258 || CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
8262 if (!use_json
&& header
) {
8263 vty_out(vty
, "BGP table version is %" PRIu64
8264 ", local router ID is %s\n",
8266 inet_ntoa(bgp
->router_id
));
8267 vty_out(vty
, BGP_SHOW_SCODE_HEADER
);
8268 vty_out(vty
, BGP_SHOW_OCODE_HEADER
);
8269 if (type
== bgp_show_type_dampend_paths
8270 || type
== bgp_show_type_damp_neighbor
)
8271 vty_out(vty
, BGP_SHOW_DAMP_HEADER
);
8272 else if (type
== bgp_show_type_flap_statistics
8273 || type
== bgp_show_type_flap_neighbor
)
8274 vty_out(vty
, BGP_SHOW_FLAP_HEADER
);
8276 vty_out(vty
, BGP_SHOW_HEADER
);
8279 if (rd
!= NULL
&& !display
&& !output_count
) {
8282 "Route Distinguisher: %s\n",
8285 if (type
== bgp_show_type_dampend_paths
8286 || type
== bgp_show_type_damp_neighbor
)
8287 damp_route_vty_out(vty
, &rn
->p
, ri
, display
,
8288 safi
, use_json
, json_paths
);
8289 else if (type
== bgp_show_type_flap_statistics
8290 || type
== bgp_show_type_flap_neighbor
)
8291 flap_route_vty_out(vty
, &rn
->p
, ri
, display
,
8292 safi
, use_json
, json_paths
);
8294 route_vty_out(vty
, &rn
->p
, ri
, display
, safi
,
8305 sprintf(buf2
, "%s/%d",
8306 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
8309 vty_out(vty
, "\"%s\": ", buf2
);
8311 vty_out(vty
, ",\"%s\": ", buf2
);
8314 json_object_to_json_string(json_paths
));
8315 json_object_free(json_paths
);
8322 output_count
+= *output_cum
;
8323 *output_cum
= output_count
;
8326 total_count
+= *total_cum
;
8327 *total_cum
= total_count
;
8331 json_object_free(json_paths
);
8333 vty_out(vty
, " }%s ", (is_last
? "" : ","));
8337 for (i
= 0; i
< *json_header_depth
; ++i
)
8338 vty_out(vty
, " } ");
8342 /* No route is displayed */
8343 if (output_count
== 0) {
8344 if (type
== bgp_show_type_normal
)
8346 "No BGP prefixes displayed, %ld exist\n",
8350 "\nDisplayed %ld routes and %ld total paths\n",
8351 output_count
, total_count
);
8358 int bgp_show_table_rd(struct vty
*vty
, struct bgp
*bgp
, safi_t safi
,
8359 struct bgp_table
*table
, struct prefix_rd
*prd_match
,
8360 enum bgp_show_type type
, void *output_arg
,
8363 struct bgp_node
*rn
, *next
;
8364 unsigned long output_cum
= 0;
8365 unsigned long total_cum
= 0;
8366 unsigned long json_header_depth
= 0;
8369 show_msg
= (!use_json
&& type
== bgp_show_type_normal
);
8371 for (rn
= bgp_table_top(table
); rn
; rn
= next
) {
8372 next
= bgp_route_next(rn
);
8373 if (prd_match
&& memcmp(rn
->p
.u
.val
, prd_match
->val
, 8) != 0)
8375 if (rn
->info
!= NULL
) {
8376 struct prefix_rd prd
;
8377 char rd
[RD_ADDRSTRLEN
];
8379 memcpy(&prd
, &(rn
->p
), sizeof(struct prefix_rd
));
8380 prefix_rd2str(&prd
, rd
, sizeof(rd
));
8381 bgp_show_table(vty
, bgp
, safi
, rn
->info
, type
,
8382 output_arg
, use_json
, rd
, next
== NULL
,
8383 &output_cum
, &total_cum
,
8384 &json_header_depth
);
8390 if (output_cum
== 0)
8391 vty_out(vty
, "No BGP prefixes displayed, %ld exist\n",
8395 "\nDisplayed %ld routes and %ld total paths\n",
8396 output_cum
, total_cum
);
8400 static int bgp_show(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
8401 enum bgp_show_type type
, void *output_arg
, uint8_t use_json
)
8403 struct bgp_table
*table
;
8404 unsigned long json_header_depth
= 0;
8407 bgp
= bgp_get_default();
8412 vty_out(vty
, "No BGP process is configured\n");
8414 vty_out(vty
, "{}\n");
8418 table
= bgp
->rib
[afi
][safi
];
8419 /* use MPLS and ENCAP specific shows until they are merged */
8420 if (safi
== SAFI_MPLS_VPN
) {
8421 return bgp_show_table_rd(vty
, bgp
, safi
, table
, NULL
, type
,
8422 output_arg
, use_json
);
8424 /* labeled-unicast routes live in the unicast table */
8425 else if (safi
== SAFI_LABELED_UNICAST
)
8426 safi
= SAFI_UNICAST
;
8428 return bgp_show_table(vty
, bgp
, safi
, table
, type
, output_arg
, use_json
,
8429 NULL
, 1, NULL
, NULL
, &json_header_depth
);
8432 static void bgp_show_all_instances_routes_vty(struct vty
*vty
, afi_t afi
,
8433 safi_t safi
, uint8_t use_json
)
8435 struct listnode
*node
, *nnode
;
8440 vty_out(vty
, "{\n");
8442 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
8445 vty_out(vty
, ",\n");
8449 vty_out(vty
, "\"%s\":",
8450 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8454 vty_out(vty
, "\nInstance %s:\n",
8455 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8459 bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_normal
, NULL
,
8464 vty_out(vty
, "}\n");
8467 /* Header of detailed BGP route information */
8468 void route_vty_out_detail_header(struct vty
*vty
, struct bgp
*bgp
,
8469 struct bgp_node
*rn
, struct prefix_rd
*prd
,
8470 afi_t afi
, safi_t safi
, json_object
*json
)
8472 struct bgp_info
*ri
;
8475 struct listnode
*node
, *nnode
;
8476 char buf1
[RD_ADDRSTRLEN
];
8477 char buf2
[INET6_ADDRSTRLEN
];
8478 #if defined(HAVE_CUMULUS)
8479 char buf3
[EVPN_ROUTE_STRLEN
];
8481 char prefix_str
[BUFSIZ
];
8486 int no_advertise
= 0;
8489 int has_valid_label
= 0;
8490 mpls_label_t label
= 0;
8491 json_object
*json_adv_to
= NULL
;
8494 has_valid_label
= bgp_is_valid_label(&rn
->local_label
);
8496 if (has_valid_label
)
8497 label
= label_pton(&rn
->local_label
);
8500 if (has_valid_label
)
8501 json_object_int_add(json
, "localLabel", label
);
8503 json_object_string_add(
8505 prefix2str(p
, prefix_str
, sizeof(prefix_str
)));
8507 #if defined(HAVE_CUMULUS)
8508 if (safi
== SAFI_EVPN
)
8509 vty_out(vty
, "BGP routing table entry for %s%s%s\n",
8510 prd
? prefix_rd2str(prd
, buf1
, sizeof(buf1
))
8513 bgp_evpn_route2str((struct prefix_evpn
*)p
,
8514 buf3
, sizeof(buf3
)));
8516 vty_out(vty
, "BGP routing table entry for %s%s%s/%d\n",
8517 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
8518 ? prefix_rd2str(prd
, buf1
,
8521 safi
== SAFI_MPLS_VPN
? ":" : "",
8522 inet_ntop(p
->family
, &p
->u
.prefix
, buf2
,
8526 if (p
->family
== AF_ETHERNET
)
8527 prefix2str(p
, buf2
, INET6_ADDRSTRLEN
);
8529 inet_ntop(p
->family
, &p
->u
.prefix
, buf2
,
8531 vty_out(vty
, "BGP routing table entry for %s%s%s/%d\n",
8532 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
8533 || safi
== SAFI_EVPN
)
8534 ? prefix_rd2str(prd
, buf1
, sizeof(buf1
))
8536 ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
)) ? ":"
8538 buf2
, p
->prefixlen
);
8541 if (has_valid_label
)
8542 vty_out(vty
, "Local label: %d\n", label
);
8543 #if defined(HAVE_CUMULUS)
8544 if (bgp_labeled_safi(safi
) && safi
!= SAFI_EVPN
)
8546 if (bgp_labeled_safi(safi
))
8548 vty_out(vty
, "not allocated\n");
8551 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
8553 if (CHECK_FLAG(ri
->flags
, BGP_INFO_SELECTED
)) {
8555 if (ri
->extra
&& ri
->extra
->suppress
)
8557 if (ri
->attr
->community
!= NULL
) {
8558 if (community_include(ri
->attr
->community
,
8559 COMMUNITY_NO_ADVERTISE
))
8561 if (community_include(ri
->attr
->community
,
8562 COMMUNITY_NO_EXPORT
))
8564 if (community_include(ri
->attr
->community
,
8565 COMMUNITY_LOCAL_AS
))
8572 vty_out(vty
, "Paths: (%d available", count
);
8574 vty_out(vty
, ", best #%d", best
);
8575 if (safi
== SAFI_UNICAST
)
8576 vty_out(vty
, ", table %s",
8578 == BGP_INSTANCE_TYPE_DEFAULT
)
8579 ? "Default-IP-Routing-Table"
8582 vty_out(vty
, ", no best path");
8585 vty_out(vty
, ", not advertised to any peer");
8587 vty_out(vty
, ", not advertised to EBGP peer");
8589 vty_out(vty
, ", not advertised outside local AS");
8593 ", Advertisements suppressed by an aggregate.");
8594 vty_out(vty
, ")\n");
8597 /* If we are not using addpath then we can display Advertised to and
8599 * show what peers we advertised the bestpath to. If we are using
8601 * though then we must display Advertised to on a path-by-path basis. */
8602 if (!bgp
->addpath_tx_used
[afi
][safi
]) {
8603 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
8604 if (bgp_adj_out_lookup(peer
, rn
, 0)) {
8605 if (json
&& !json_adv_to
)
8606 json_adv_to
= json_object_new_object();
8608 route_vty_out_advertised_to(
8610 " Advertised to non peer-group peers:\n ",
8617 json_object_object_add(json
, "advertisedTo",
8622 vty_out(vty
, " Not advertised to any peer");
8628 /* Display specified route of BGP table. */
8629 static int bgp_show_route_in_table(struct vty
*vty
, struct bgp
*bgp
,
8630 struct bgp_table
*rib
, const char *ip_str
,
8631 afi_t afi
, safi_t safi
,
8632 struct prefix_rd
*prd
, int prefix_check
,
8633 enum bgp_path_type pathtype
,
8639 struct prefix match
;
8640 struct bgp_node
*rn
;
8641 struct bgp_node
*rm
;
8642 struct bgp_info
*ri
;
8643 struct bgp_table
*table
;
8644 json_object
*json
= NULL
;
8645 json_object
*json_paths
= NULL
;
8647 /* Check IP address argument. */
8648 ret
= str2prefix(ip_str
, &match
);
8650 vty_out(vty
, "address is malformed\n");
8654 match
.family
= afi2family(afi
);
8657 json
= json_object_new_object();
8658 json_paths
= json_object_new_array();
8661 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) {
8662 for (rn
= bgp_table_top(rib
); rn
; rn
= bgp_route_next(rn
)) {
8663 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
8666 if ((table
= rn
->info
) == NULL
)
8671 if ((rm
= bgp_node_match(table
, &match
)) == NULL
)
8675 && rm
->p
.prefixlen
!= match
.prefixlen
) {
8676 bgp_unlock_node(rm
);
8680 for (ri
= rm
->info
; ri
; ri
= ri
->next
) {
8682 route_vty_out_detail_header(
8684 (struct prefix_rd
*)&rn
->p
,
8685 AFI_IP
, safi
, json
);
8690 if (pathtype
== BGP_PATH_ALL
8691 || (pathtype
== BGP_PATH_BESTPATH
8692 && CHECK_FLAG(ri
->flags
,
8694 || (pathtype
== BGP_PATH_MULTIPATH
8695 && (CHECK_FLAG(ri
->flags
,
8697 || CHECK_FLAG(ri
->flags
,
8698 BGP_INFO_SELECTED
))))
8699 route_vty_out_detail(vty
, bgp
, &rm
->p
,
8704 bgp_unlock_node(rm
);
8709 if ((rn
= bgp_node_match(rib
, &match
)) != NULL
) {
8711 || rn
->p
.prefixlen
== match
.prefixlen
) {
8712 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
8714 route_vty_out_detail_header(
8715 vty
, bgp
, rn
, NULL
, afi
,
8721 if (pathtype
== BGP_PATH_ALL
8722 || (pathtype
== BGP_PATH_BESTPATH
8726 || (pathtype
== BGP_PATH_MULTIPATH
8732 BGP_INFO_SELECTED
))))
8733 route_vty_out_detail(
8734 vty
, bgp
, &rn
->p
, ri
,
8735 afi
, safi
, json_paths
);
8739 bgp_unlock_node(rn
);
8745 json_object_object_add(json
, "paths", json_paths
);
8747 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
8748 json
, JSON_C_TO_STRING_PRETTY
));
8749 json_object_free(json
);
8752 vty_out(vty
, "%% Network not in table\n");
8760 /* Display specified route of Main RIB */
8761 static int bgp_show_route(struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
8762 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
8763 int prefix_check
, enum bgp_path_type pathtype
,
8767 bgp
= bgp_get_default();
8770 vty_out(vty
, "No BGP process is configured\n");
8772 vty_out(vty
, "{}\n");
8777 /* labeled-unicast routes live in the unicast table */
8778 if (safi
== SAFI_LABELED_UNICAST
)
8779 safi
= SAFI_UNICAST
;
8781 return bgp_show_route_in_table(vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
8782 afi
, safi
, prd
, prefix_check
, pathtype
,
8786 static int bgp_show_lcommunity(struct vty
*vty
, struct bgp
*bgp
, int argc
,
8787 struct cmd_token
**argv
, afi_t afi
, safi_t safi
,
8790 struct lcommunity
*lcom
;
8796 b
= buffer_new(1024);
8797 for (i
= 0; i
< argc
; i
++) {
8799 buffer_putc(b
, ' ');
8801 if (strmatch(argv
[i
]->text
, "AA:BB:CC")) {
8803 buffer_putstr(b
, argv
[i
]->arg
);
8807 buffer_putc(b
, '\0');
8809 str
= buffer_getstr(b
);
8812 lcom
= lcommunity_str2com(str
);
8813 XFREE(MTYPE_TMP
, str
);
8815 vty_out(vty
, "%% Large-community malformed\n");
8819 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
,
8823 static int bgp_show_lcommunity_list(struct vty
*vty
, struct bgp
*bgp
,
8824 const char *lcom
, afi_t afi
, safi_t safi
,
8827 struct community_list
*list
;
8829 list
= community_list_lookup(bgp_clist
, lcom
,
8830 LARGE_COMMUNITY_LIST_MASTER
);
8832 vty_out(vty
, "%% %s is not a valid large-community-list name\n",
8837 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
,
8841 DEFUN (show_ip_bgp_large_community_list
,
8842 show_ip_bgp_large_community_list_cmd
,
8843 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community-list <(1-500)|WORD> [json]",
8847 BGP_INSTANCE_HELP_STR
8849 BGP_SAFI_WITH_LABEL_HELP_STR
8850 "Display routes matching the large-community-list\n"
8851 "large-community-list number\n"
8852 "large-community-list name\n"
8856 afi_t afi
= AFI_IP6
;
8857 safi_t safi
= SAFI_UNICAST
;
8860 if (argv_find(argv
, argc
, "ip", &idx
))
8862 if (argv_find(argv
, argc
, "view", &idx
)
8863 || argv_find(argv
, argc
, "vrf", &idx
))
8864 vrf
= argv
[++idx
]->arg
;
8865 if (argv_find(argv
, argc
, "ipv4", &idx
)
8866 || argv_find(argv
, argc
, "ipv6", &idx
)) {
8867 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8868 if (argv_find(argv
, argc
, "unicast", &idx
)
8869 || argv_find(argv
, argc
, "multicast", &idx
))
8870 safi
= bgp_vty_safi_from_str(argv
[idx
]->text
);
8873 int uj
= use_json(argc
, argv
);
8875 struct bgp
*bgp
= bgp_lookup_by_name(vrf
);
8877 vty_out(vty
, "Can't find BGP instance %s\n", vrf
);
8881 argv_find(argv
, argc
, "large-community-list", &idx
);
8882 return bgp_show_lcommunity_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
,
8885 DEFUN (show_ip_bgp_large_community
,
8886 show_ip_bgp_large_community_cmd
,
8887 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community [AA:BB:CC] [json]",
8891 BGP_INSTANCE_HELP_STR
8893 BGP_SAFI_WITH_LABEL_HELP_STR
8894 "Display routes matching the large-communities\n"
8895 "List of large-community numbers\n"
8899 afi_t afi
= AFI_IP6
;
8900 safi_t safi
= SAFI_UNICAST
;
8903 if (argv_find(argv
, argc
, "ip", &idx
))
8905 if (argv_find(argv
, argc
, "view", &idx
)
8906 || argv_find(argv
, argc
, "vrf", &idx
))
8907 vrf
= argv
[++idx
]->arg
;
8908 if (argv_find(argv
, argc
, "ipv4", &idx
)
8909 || argv_find(argv
, argc
, "ipv6", &idx
)) {
8910 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
8911 if (argv_find(argv
, argc
, "unicast", &idx
)
8912 || argv_find(argv
, argc
, "multicast", &idx
))
8913 safi
= bgp_vty_safi_from_str(argv
[idx
]->text
);
8916 int uj
= use_json(argc
, argv
);
8918 struct bgp
*bgp
= bgp_lookup_by_name(vrf
);
8920 vty_out(vty
, "Can't find BGP instance %s\n", vrf
);
8924 if (argv_find(argv
, argc
, "AA:BB:CC", &idx
))
8925 return bgp_show_lcommunity(vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
8927 return bgp_show(vty
, bgp
, afi
, safi
,
8928 bgp_show_type_lcommunity_all
, NULL
, uj
);
8931 static int bgp_table_stats(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
8935 /* BGP route print out function without JSON */
8938 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
8939 <dampening <parameters>\
8944 |community <AA:NN|local-AS|no-advertise|no-export|graceful-shutdown> [exact-match]\
8945 |community-list <(1-500)|WORD> [exact-match]\
8946 |A.B.C.D/M longer-prefixes\
8947 |X:X::X:X/M longer-prefixes\
8952 BGP_INSTANCE_HELP_STR
8954 BGP_SAFI_WITH_LABEL_HELP_STR
8955 "Display detailed information about dampening\n"
8956 "Display detail of configured dampening parameters\n"
8957 "Display routes matching the route-map\n"
8958 "A route-map to match on\n"
8959 "Display routes conforming to the prefix-list\n"
8960 "Prefix-list name\n"
8961 "Display routes conforming to the filter-list\n"
8962 "Regular expression access list name\n"
8963 "BGP RIB advertisement statistics\n"
8964 "Display routes matching the communities\n"
8966 "Do not send outside local AS (well-known community)\n"
8967 "Do not advertise to any peer (well-known community)\n"
8968 "Do not export to next AS (well-known community)\n"
8969 "Graceful shutdown (well-known community)\n"
8970 "Exact match of the communities\n"
8971 "Display routes matching the community-list\n"
8972 "community-list number\n"
8973 "community-list name\n"
8974 "Exact match of the communities\n"
8976 "Display route and more specific routes\n"
8978 "Display route and more specific routes\n")
8980 afi_t afi
= AFI_IP6
;
8981 safi_t safi
= SAFI_UNICAST
;
8982 int exact_match
= 0;
8983 struct bgp
*bgp
= NULL
;
8985 int idx_community_type
= 0;
8987 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
8992 if (argv_find(argv
, argc
, "dampening", &idx
)) {
8993 if (argv_find(argv
, argc
, "parameters", &idx
))
8994 return bgp_show_dampening_parameters(vty
, afi
, safi
);
8997 if (argv_find(argv
, argc
, "prefix-list", &idx
))
8998 return bgp_show_prefix_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
8999 safi
, bgp_show_type_prefix_list
);
9001 if (argv_find(argv
, argc
, "filter-list", &idx
))
9002 return bgp_show_filter_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
9003 safi
, bgp_show_type_filter_list
);
9005 if (argv_find(argv
, argc
, "statistics", &idx
))
9006 return bgp_table_stats(vty
, bgp
, afi
, safi
);
9008 if (argv_find(argv
, argc
, "route-map", &idx
))
9009 return bgp_show_route_map(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
9010 safi
, bgp_show_type_route_map
);
9012 if (argv_find(argv
, argc
, "community", &idx
)) {
9013 /* show a specific community */
9014 if (argv_find(argv
, argc
, "local-AS", &idx_community_type
)
9015 || argv_find(argv
, argc
, "no-advertise",
9016 &idx_community_type
)
9017 || argv_find(argv
, argc
, "no-export", &idx_community_type
)
9018 || argv_find(argv
, argc
, "graceful-shutdown",
9019 &idx_community_type
)
9020 || argv_find(argv
, argc
, "AA:NN", &idx_community_type
)) {
9022 if (argv_find(argv
, argc
, "exact-match", &idx
))
9024 return bgp_show_community(vty
, bgp
,
9025 argv
[idx_community_type
]->arg
,
9026 exact_match
, afi
, safi
);
9030 if (argv_find(argv
, argc
, "community-list", &idx
)) {
9031 const char *clist_number_or_name
= argv
[++idx
]->arg
;
9032 if (++idx
< argc
&& strmatch(argv
[idx
]->text
, "exact-match"))
9034 return bgp_show_community_list(vty
, bgp
, clist_number_or_name
,
9035 exact_match
, afi
, safi
);
9038 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)
9039 || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
9040 return bgp_show_prefix_longer(vty
, bgp
, argv
[idx
]->arg
, afi
,
9042 bgp_show_type_prefix_longer
);
9047 /* BGP route print out function with JSON */
9048 DEFUN (show_ip_bgp_json
,
9049 show_ip_bgp_json_cmd
,
9050 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
9053 |dampening <flap-statistics|dampened-paths>\
9059 BGP_INSTANCE_HELP_STR
9061 BGP_SAFI_WITH_LABEL_HELP_STR
9062 "Display only routes with non-natural netmasks\n"
9063 "Display detailed information about dampening\n"
9064 "Display flap statistics of routes\n"
9065 "Display paths suppressed due to dampening\n"
9066 "Display routes matching the communities\n"
9069 afi_t afi
= AFI_IP6
;
9070 safi_t safi
= SAFI_UNICAST
;
9071 enum bgp_show_type sh_type
= bgp_show_type_normal
;
9072 struct bgp
*bgp
= NULL
;
9075 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9080 int uj
= use_json(argc
, argv
);
9084 if (argv_find(argv
, argc
, "cidr-only", &idx
))
9085 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
,
9088 if (argv_find(argv
, argc
, "dampening", &idx
)) {
9089 if (argv_find(argv
, argc
, "dampened-paths", &idx
))
9090 return bgp_show(vty
, bgp
, afi
, safi
,
9091 bgp_show_type_dampend_paths
, NULL
, uj
);
9092 else if (argv_find(argv
, argc
, "flap-statistics", &idx
))
9093 return bgp_show(vty
, bgp
, afi
, safi
,
9094 bgp_show_type_flap_statistics
, NULL
,
9098 if (argv_find(argv
, argc
, "community", &idx
)) {
9099 /* show all communities */
9100 return bgp_show(vty
, bgp
, afi
, safi
,
9101 bgp_show_type_community_all
, NULL
, uj
);
9103 return bgp_show(vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
9106 DEFUN (show_ip_bgp_route
,
9107 show_ip_bgp_route_cmd
,
9108 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]"
9109 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
9113 BGP_INSTANCE_HELP_STR
9115 BGP_SAFI_WITH_LABEL_HELP_STR
9116 "Network in the BGP routing table to display\n"
9118 "Network in the BGP routing table to display\n"
9120 "Display only the bestpath\n"
9121 "Display only multipaths\n"
9124 int prefix_check
= 0;
9126 afi_t afi
= AFI_IP6
;
9127 safi_t safi
= SAFI_UNICAST
;
9128 char *prefix
= NULL
;
9129 struct bgp
*bgp
= NULL
;
9130 enum bgp_path_type path_type
;
9131 uint8_t uj
= use_json(argc
, argv
);
9135 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9142 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
9146 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
9147 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)
9148 || argv_find(argv
, argc
, "X:X::X:X", &idx
))
9150 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)
9151 || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
9154 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
)
9155 && afi
!= AFI_IP6
) {
9157 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
9160 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
)
9163 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
9167 prefix
= argv
[idx
]->arg
;
9169 /* [<bestpath|multipath>] */
9170 if (argv_find(argv
, argc
, "bestpath", &idx
))
9171 path_type
= BGP_PATH_BESTPATH
;
9172 else if (argv_find(argv
, argc
, "multipath", &idx
))
9173 path_type
= BGP_PATH_MULTIPATH
;
9175 path_type
= BGP_PATH_ALL
;
9177 return bgp_show_route(vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
,
9181 DEFUN (show_ip_bgp_regexp
,
9182 show_ip_bgp_regexp_cmd
,
9183 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] regexp REGEX...",
9187 BGP_INSTANCE_HELP_STR
9189 BGP_SAFI_WITH_LABEL_HELP_STR
9190 "Display routes matching the AS path regular expression\n"
9191 "A regular-expression to match the BGP AS paths\n")
9193 afi_t afi
= AFI_IP6
;
9194 safi_t safi
= SAFI_UNICAST
;
9195 struct bgp
*bgp
= NULL
;
9198 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9203 // get index of regex
9204 argv_find(argv
, argc
, "regexp", &idx
);
9207 char *regstr
= argv_concat(argv
, argc
, idx
);
9208 int rc
= bgp_show_regexp(vty
, bgp
, (const char *)regstr
, afi
, safi
,
9209 bgp_show_type_regexp
);
9210 XFREE(MTYPE_TMP
, regstr
);
9214 DEFUN (show_ip_bgp_instance_all
,
9215 show_ip_bgp_instance_all_cmd
,
9216 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] [json]",
9220 BGP_INSTANCE_ALL_HELP_STR
9222 BGP_SAFI_WITH_LABEL_HELP_STR
9226 safi_t safi
= SAFI_UNICAST
;
9227 struct bgp
*bgp
= NULL
;
9230 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9235 int uj
= use_json(argc
, argv
);
9239 bgp_show_all_instances_routes_vty(vty
, afi
, safi
, uj
);
9243 static int bgp_show_regexp(struct vty
*vty
, struct bgp
*bgp
, const char *regstr
,
9244 afi_t afi
, safi_t safi
, enum bgp_show_type type
)
9249 regex
= bgp_regcomp(regstr
);
9251 vty_out(vty
, "Can't compile regexp %s\n", regstr
);
9255 rc
= bgp_show(vty
, bgp
, afi
, safi
, type
, regex
, 0);
9256 bgp_regex_free(regex
);
9260 static int bgp_show_prefix_list(struct vty
*vty
, struct bgp
*bgp
,
9261 const char *prefix_list_str
, afi_t afi
,
9262 safi_t safi
, enum bgp_show_type type
)
9264 struct prefix_list
*plist
;
9266 plist
= prefix_list_lookup(afi
, prefix_list_str
);
9267 if (plist
== NULL
) {
9268 vty_out(vty
, "%% %s is not a valid prefix-list name\n",
9273 return bgp_show(vty
, bgp
, afi
, safi
, type
, plist
, 0);
9276 static int bgp_show_filter_list(struct vty
*vty
, struct bgp
*bgp
,
9277 const char *filter
, afi_t afi
, safi_t safi
,
9278 enum bgp_show_type type
)
9280 struct as_list
*as_list
;
9282 as_list
= as_list_lookup(filter
);
9283 if (as_list
== NULL
) {
9284 vty_out(vty
, "%% %s is not a valid AS-path access-list name\n",
9289 return bgp_show(vty
, bgp
, afi
, safi
, type
, as_list
, 0);
9292 static int bgp_show_route_map(struct vty
*vty
, struct bgp
*bgp
,
9293 const char *rmap_str
, afi_t afi
, safi_t safi
,
9294 enum bgp_show_type type
)
9296 struct route_map
*rmap
;
9298 rmap
= route_map_lookup_by_name(rmap_str
);
9300 vty_out(vty
, "%% %s is not a valid route-map name\n", rmap_str
);
9304 return bgp_show(vty
, bgp
, afi
, safi
, type
, rmap
, 0);
9307 static int bgp_show_community(struct vty
*vty
, struct bgp
*bgp
,
9308 const char *comstr
, int exact
, afi_t afi
,
9311 struct community
*com
;
9314 com
= community_str2com(comstr
);
9316 vty_out(vty
, "%% Community malformed: %s\n", comstr
);
9320 ret
= bgp_show(vty
, bgp
, afi
, safi
,
9321 (exact
? bgp_show_type_community_exact
9322 : bgp_show_type_community
),
9324 community_free(com
);
9329 static int bgp_show_community_list(struct vty
*vty
, struct bgp
*bgp
,
9330 const char *com
, int exact
, afi_t afi
,
9333 struct community_list
*list
;
9335 list
= community_list_lookup(bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
9337 vty_out(vty
, "%% %s is not a valid community-list name\n", com
);
9341 return bgp_show(vty
, bgp
, afi
, safi
,
9342 (exact
? bgp_show_type_community_list_exact
9343 : bgp_show_type_community_list
),
9347 static int bgp_show_prefix_longer(struct vty
*vty
, struct bgp
*bgp
,
9348 const char *prefix
, afi_t afi
, safi_t safi
,
9349 enum bgp_show_type type
)
9356 ret
= str2prefix(prefix
, p
);
9358 vty_out(vty
, "%% Malformed Prefix\n");
9362 ret
= bgp_show(vty
, bgp
, afi
, safi
, type
, p
, 0);
9367 static struct peer
*peer_lookup_in_view(struct vty
*vty
, struct bgp
*bgp
,
9368 const char *ip_str
, uint8_t use_json
)
9374 /* Get peer sockunion. */
9375 ret
= str2sockunion(ip_str
, &su
);
9377 peer
= peer_lookup_by_conf_if(bgp
, ip_str
);
9379 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
9383 json_object
*json_no
= NULL
;
9384 json_no
= json_object_new_object();
9385 json_object_string_add(
9387 "malformedAddressOrName",
9389 vty_out(vty
, "%s\n",
9390 json_object_to_json_string_ext(
9392 JSON_C_TO_STRING_PRETTY
));
9393 json_object_free(json_no
);
9396 "%% Malformed address or name: %s\n",
9404 /* Peer structure lookup. */
9405 peer
= peer_lookup(bgp
, &su
);
9408 json_object
*json_no
= NULL
;
9409 json_no
= json_object_new_object();
9410 json_object_string_add(json_no
, "warning",
9411 "No such neighbor");
9412 vty_out(vty
, "%s\n",
9413 json_object_to_json_string_ext(
9414 json_no
, JSON_C_TO_STRING_PRETTY
));
9415 json_object_free(json_no
);
9417 vty_out(vty
, "No such neighbor\n");
9425 BGP_STATS_MAXBITLEN
= 0,
9429 BGP_STATS_UNAGGREGATEABLE
,
9430 BGP_STATS_MAX_AGGREGATEABLE
,
9431 BGP_STATS_AGGREGATES
,
9433 BGP_STATS_ASPATH_COUNT
,
9434 BGP_STATS_ASPATH_MAXHOPS
,
9435 BGP_STATS_ASPATH_TOTHOPS
,
9436 BGP_STATS_ASPATH_MAXSIZE
,
9437 BGP_STATS_ASPATH_TOTSIZE
,
9438 BGP_STATS_ASN_HIGHEST
,
9442 static const char *table_stats_strs
[] = {
9443 [BGP_STATS_PREFIXES
] = "Total Prefixes",
9444 [BGP_STATS_TOTPLEN
] = "Average prefix length",
9445 [BGP_STATS_RIB
] = "Total Advertisements",
9446 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
9447 [BGP_STATS_MAX_AGGREGATEABLE
] =
9448 "Maximum aggregateable prefixes",
9449 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
9450 [BGP_STATS_SPACE
] = "Address space advertised",
9451 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
9452 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
9453 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
9454 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
9455 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
9456 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
9457 [BGP_STATS_MAX
] = NULL
,
9460 struct bgp_table_stats
{
9461 struct bgp_table
*table
;
9462 unsigned long long counts
[BGP_STATS_MAX
];
9467 #define TALLY_SIGFIG 100000
9468 static unsigned long
9469 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
9471 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
9472 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
9473 unsigned long ret
= newtot
/ count
;
9475 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
9482 static int bgp_table_stats_walker(struct thread
*t
)
9484 struct bgp_node
*rn
;
9485 struct bgp_node
*top
;
9486 struct bgp_table_stats
*ts
= THREAD_ARG(t
);
9487 unsigned int space
= 0;
9489 if (!(top
= bgp_table_top(ts
->table
)))
9492 switch (top
->p
.family
) {
9494 space
= IPV4_MAX_BITLEN
;
9497 space
= IPV6_MAX_BITLEN
;
9501 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
9503 for (rn
= top
; rn
; rn
= bgp_route_next(rn
)) {
9504 struct bgp_info
*ri
;
9505 struct bgp_node
*prn
= bgp_node_parent_nolock(rn
);
9506 unsigned int rinum
= 0;
9514 ts
->counts
[BGP_STATS_PREFIXES
]++;
9515 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
9518 ts
->counts
[BGP_STATS_AVGPLEN
]
9519 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
9520 ts
->counts
[BGP_STATS_AVGPLEN
],
9524 /* check if the prefix is included by any other announcements */
9525 while (prn
&& !prn
->info
)
9526 prn
= bgp_node_parent_nolock(prn
);
9528 if (prn
== NULL
|| prn
== top
) {
9529 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
9530 /* announced address space */
9533 pow(2.0, space
- rn
->p
.prefixlen
);
9534 } else if (prn
->info
)
9535 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
9537 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
9539 ts
->counts
[BGP_STATS_RIB
]++;
9542 && (CHECK_FLAG(ri
->attr
->flag
,
9544 BGP_ATTR_ATOMIC_AGGREGATE
))))
9545 ts
->counts
[BGP_STATS_AGGREGATES
]++;
9548 if (ri
->attr
&& ri
->attr
->aspath
) {
9550 aspath_count_hops(ri
->attr
->aspath
);
9552 aspath_size(ri
->attr
->aspath
);
9553 as_t highest
= aspath_highest(ri
->attr
->aspath
);
9555 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
9557 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
9558 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] =
9561 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
9562 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] =
9565 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
9566 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
9568 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
9569 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9570 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
9572 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
9573 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9574 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
9577 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
9578 ts
->counts
[BGP_STATS_ASN_HIGHEST
] =
9586 static int bgp_table_stats(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
9589 struct bgp_table_stats ts
;
9592 if (!bgp
->rib
[afi
][safi
]) {
9593 vty_out(vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
9598 vty_out(vty
, "BGP %s RIB statistics\n", afi_safi_print(afi
, safi
));
9600 /* labeled-unicast routes live in the unicast table */
9601 if (safi
== SAFI_LABELED_UNICAST
)
9602 safi
= SAFI_UNICAST
;
9604 memset(&ts
, 0, sizeof(ts
));
9605 ts
.table
= bgp
->rib
[afi
][safi
];
9606 thread_execute(bm
->master
, bgp_table_stats_walker
, &ts
, 0);
9608 for (i
= 0; i
< BGP_STATS_MAX
; i
++) {
9609 if (!table_stats_strs
[i
])
9614 case BGP_STATS_ASPATH_AVGHOPS
:
9615 case BGP_STATS_ASPATH_AVGSIZE
:
9616 case BGP_STATS_AVGPLEN
:
9617 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
9618 vty_out (vty
, "%12.2f",
9619 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
9622 case BGP_STATS_ASPATH_TOTHOPS
:
9623 case BGP_STATS_ASPATH_TOTSIZE
:
9624 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9625 vty_out(vty
, "%12.2f",
9627 ? (float)ts
.counts
[i
]
9629 [BGP_STATS_ASPATH_COUNT
]
9632 case BGP_STATS_TOTPLEN
:
9633 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9634 vty_out(vty
, "%12.2f",
9636 ? (float)ts
.counts
[i
]
9638 [BGP_STATS_PREFIXES
]
9641 case BGP_STATS_SPACE
:
9642 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9643 vty_out(vty
, "%12g\n", ts
.total_space
);
9645 if (afi
== AFI_IP6
) {
9646 vty_out(vty
, "%30s: ", "/32 equivalent ");
9647 vty_out(vty
, "%12g\n",
9648 ts
.total_space
* pow(2.0, -128 + 32));
9649 vty_out(vty
, "%30s: ", "/48 equivalent ");
9650 vty_out(vty
, "%12g\n",
9651 ts
.total_space
* pow(2.0, -128 + 48));
9653 vty_out(vty
, "%30s: ", "% announced ");
9654 vty_out(vty
, "%12.2f\n",
9655 ts
.total_space
* 100. * pow(2.0, -32));
9656 vty_out(vty
, "%30s: ", "/8 equivalent ");
9657 vty_out(vty
, "%12.2f\n",
9658 ts
.total_space
* pow(2.0, -32 + 8));
9659 vty_out(vty
, "%30s: ", "/24 equivalent ");
9660 vty_out(vty
, "%12.2f\n",
9661 ts
.total_space
* pow(2.0, -32 + 24));
9665 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
9666 vty_out(vty
, "%12llu", ts
.counts
[i
]);
9683 PCOUNT_PFCNT
, /* the figure we display to users */
9687 static const char *pcount_strs
[] = {
9688 [PCOUNT_ADJ_IN
] = "Adj-in",
9689 [PCOUNT_DAMPED
] = "Damped",
9690 [PCOUNT_REMOVED
] = "Removed",
9691 [PCOUNT_HISTORY
] = "History",
9692 [PCOUNT_STALE
] = "Stale",
9693 [PCOUNT_VALID
] = "Valid",
9694 [PCOUNT_ALL
] = "All RIB",
9695 [PCOUNT_COUNTED
] = "PfxCt counted",
9696 [PCOUNT_PFCNT
] = "Useable",
9697 [PCOUNT_MAX
] = NULL
,
9700 struct peer_pcounts
{
9701 unsigned int count
[PCOUNT_MAX
];
9702 const struct peer
*peer
;
9703 const struct bgp_table
*table
;
9706 static int bgp_peer_count_walker(struct thread
*t
)
9708 struct bgp_node
*rn
;
9709 struct peer_pcounts
*pc
= THREAD_ARG(t
);
9710 const struct peer
*peer
= pc
->peer
;
9712 for (rn
= bgp_table_top(pc
->table
); rn
; rn
= bgp_route_next(rn
)) {
9713 struct bgp_adj_in
*ain
;
9714 struct bgp_info
*ri
;
9716 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
9717 if (ain
->peer
== peer
)
9718 pc
->count
[PCOUNT_ADJ_IN
]++;
9720 for (ri
= rn
->info
; ri
; ri
= ri
->next
) {
9721 char buf
[SU_ADDRSTRLEN
];
9723 if (ri
->peer
!= peer
)
9726 pc
->count
[PCOUNT_ALL
]++;
9728 if (CHECK_FLAG(ri
->flags
, BGP_INFO_DAMPED
))
9729 pc
->count
[PCOUNT_DAMPED
]++;
9730 if (CHECK_FLAG(ri
->flags
, BGP_INFO_HISTORY
))
9731 pc
->count
[PCOUNT_HISTORY
]++;
9732 if (CHECK_FLAG(ri
->flags
, BGP_INFO_REMOVED
))
9733 pc
->count
[PCOUNT_REMOVED
]++;
9734 if (CHECK_FLAG(ri
->flags
, BGP_INFO_STALE
))
9735 pc
->count
[PCOUNT_STALE
]++;
9736 if (CHECK_FLAG(ri
->flags
, BGP_INFO_VALID
))
9737 pc
->count
[PCOUNT_VALID
]++;
9738 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
9739 pc
->count
[PCOUNT_PFCNT
]++;
9741 if (CHECK_FLAG(ri
->flags
, BGP_INFO_COUNTED
)) {
9742 pc
->count
[PCOUNT_COUNTED
]++;
9743 if (CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
9745 "%s [pcount] %s/%d is counted but flags 0x%x",
9747 inet_ntop(rn
->p
.family
,
9748 &rn
->p
.u
.prefix
, buf
,
9750 rn
->p
.prefixlen
, ri
->flags
);
9752 if (!CHECK_FLAG(ri
->flags
, BGP_INFO_UNUSEABLE
))
9754 "%s [pcount] %s/%d not counted but flags 0x%x",
9756 inet_ntop(rn
->p
.family
,
9757 &rn
->p
.u
.prefix
, buf
,
9759 rn
->p
.prefixlen
, ri
->flags
);
9766 static int bgp_peer_counts(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9767 safi_t safi
, uint8_t use_json
)
9769 struct peer_pcounts pcounts
= {.peer
= peer
};
9771 json_object
*json
= NULL
;
9772 json_object
*json_loop
= NULL
;
9775 json
= json_object_new_object();
9776 json_loop
= json_object_new_object();
9779 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
9780 || !peer
->bgp
->rib
[afi
][safi
]) {
9782 json_object_string_add(
9784 "No such neighbor or address family");
9785 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
9786 json_object_free(json
);
9788 vty_out(vty
, "%% No such neighbor or address family\n");
9793 memset(&pcounts
, 0, sizeof(pcounts
));
9794 pcounts
.peer
= peer
;
9795 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
9797 /* in-place call via thread subsystem so as to record execution time
9798 * stats for the thread-walk (i.e. ensure this can't be blamed on
9799 * on just vty_read()).
9801 thread_execute(bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
9804 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
9805 json_object_string_add(json
, "multiProtocol",
9806 afi_safi_print(afi
, safi
));
9807 json_object_int_add(json
, "pfxCounter",
9808 peer
->pcount
[afi
][safi
]);
9810 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9811 json_object_int_add(json_loop
, pcount_strs
[i
],
9814 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
9816 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
]) {
9817 json_object_string_add(json
, "pfxctDriftFor",
9819 json_object_string_add(
9820 json
, "recommended",
9821 "Please report this bug, with the above command output");
9823 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9824 json
, JSON_C_TO_STRING_PRETTY
));
9825 json_object_free(json
);
9829 && bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
)) {
9830 vty_out(vty
, "Prefix counts for %s/%s, %s\n",
9831 peer
->hostname
, peer
->host
,
9832 afi_safi_print(afi
, safi
));
9834 vty_out(vty
, "Prefix counts for %s, %s\n", peer
->host
,
9835 afi_safi_print(afi
, safi
));
9838 vty_out(vty
, "PfxCt: %ld\n", peer
->pcount
[afi
][safi
]);
9839 vty_out(vty
, "\nCounts from RIB table walk:\n\n");
9841 for (i
= 0; i
< PCOUNT_MAX
; i
++)
9842 vty_out(vty
, "%20s: %-10d\n", pcount_strs
[i
],
9845 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
]) {
9846 vty_out(vty
, "%s [pcount] PfxCt drift!\n", peer
->host
);
9848 "Please report this bug, with the above command output\n");
9855 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
9856 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
9857 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
9858 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9862 BGP_INSTANCE_HELP_STR
9865 "Detailed information on TCP and BGP neighbor connections\n"
9866 "Neighbor to display information about\n"
9867 "Neighbor to display information about\n"
9868 "Neighbor on BGP configured interface\n"
9869 "Display detailed prefix count information\n"
9872 afi_t afi
= AFI_IP6
;
9873 safi_t safi
= SAFI_UNICAST
;
9876 struct bgp
*bgp
= NULL
;
9878 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9883 int uj
= use_json(argc
, argv
);
9887 argv_find(argv
, argc
, "neighbors", &idx
);
9888 peer
= peer_lookup_in_view(vty
, bgp
, argv
[idx
+ 1]->arg
, uj
);
9892 return bgp_peer_counts(vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
9895 #ifdef KEEP_OLD_VPN_COMMANDS
9896 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
9897 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
9898 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9903 "Display information about all VPNv4 NLRIs\n"
9904 "Detailed information on TCP and BGP neighbor connections\n"
9905 "Neighbor to display information about\n"
9906 "Neighbor to display information about\n"
9907 "Neighbor on BGP configured interface\n"
9908 "Display detailed prefix count information\n"
9913 uint8_t uj
= use_json(argc
, argv
);
9915 peer
= peer_lookup_in_view(vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
9919 return bgp_peer_counts(vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
9922 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
9923 show_ip_bgp_vpn_all_route_prefix_cmd
,
9924 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9929 "Display information about all VPNv4 NLRIs\n"
9930 "Network in the BGP routing table to display\n"
9931 "Network in the BGP routing table to display\n"
9935 char *network
= NULL
;
9936 struct bgp
*bgp
= bgp_get_default();
9938 vty_out(vty
, "Can't find default instance\n");
9942 if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9943 network
= argv
[idx
]->arg
;
9944 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
))
9945 network
= argv
[idx
]->arg
;
9947 vty_out(vty
, "Unable to figure out Network\n");
9951 return bgp_show_route(vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0,
9952 BGP_PATH_ALL
, use_json(argc
, argv
));
9954 #endif /* KEEP_OLD_VPN_COMMANDS */
9956 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix
,
9957 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
,
9958 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
9964 "Display information about all EVPN NLRIs\n"
9965 "Network in the BGP routing table to display\n"
9966 "Network in the BGP routing table to display\n"
9970 char *network
= NULL
;
9972 if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
9973 network
= argv
[idx
]->arg
;
9974 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
))
9975 network
= argv
[idx
]->arg
;
9977 vty_out(vty
, "Unable to figure out Network\n");
9980 return bgp_show_route(vty
, NULL
, network
, AFI_L2VPN
, SAFI_EVPN
, NULL
, 0,
9981 BGP_PATH_ALL
, use_json(argc
, argv
));
9984 static void show_adj_route(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
9985 safi_t safi
, int in
, const char *rmap_name
,
9986 uint8_t use_json
, json_object
*json
)
9988 struct bgp_table
*table
;
9989 struct bgp_adj_in
*ain
;
9990 struct bgp_adj_out
*adj
;
9991 unsigned long output_count
;
9992 unsigned long filtered_count
;
9993 struct bgp_node
*rn
;
9999 struct update_subgroup
*subgrp
;
10000 json_object
*json_scode
= NULL
;
10001 json_object
*json_ocode
= NULL
;
10002 json_object
*json_ar
= NULL
;
10003 struct peer_af
*paf
;
10006 json_scode
= json_object_new_object();
10007 json_ocode
= json_object_new_object();
10008 json_ar
= json_object_new_object();
10010 json_object_string_add(json_scode
, "suppressed", "s");
10011 json_object_string_add(json_scode
, "damped", "d");
10012 json_object_string_add(json_scode
, "history", "h");
10013 json_object_string_add(json_scode
, "valid", "*");
10014 json_object_string_add(json_scode
, "best", ">");
10015 json_object_string_add(json_scode
, "multipath", "=");
10016 json_object_string_add(json_scode
, "internal", "i");
10017 json_object_string_add(json_scode
, "ribFailure", "r");
10018 json_object_string_add(json_scode
, "stale", "S");
10019 json_object_string_add(json_scode
, "removed", "R");
10021 json_object_string_add(json_ocode
, "igp", "i");
10022 json_object_string_add(json_ocode
, "egp", "e");
10023 json_object_string_add(json_ocode
, "incomplete", "?");
10030 json_object_string_add(json
, "alert", "no BGP");
10031 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10032 json_object_free(json
);
10034 vty_out(vty
, "%% No bgp\n");
10038 table
= bgp
->rib
[afi
][safi
];
10040 output_count
= filtered_count
= 0;
10041 subgrp
= peer_subgroup(peer
, afi
, safi
);
10044 && CHECK_FLAG(subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
)) {
10046 json_object_int_add(json
, "bgpTableVersion",
10048 json_object_string_add(json
, "bgpLocalRouterId",
10049 inet_ntoa(bgp
->router_id
));
10050 json_object_object_add(json
, "bgpStatusCodes",
10052 json_object_object_add(json
, "bgpOriginCodes",
10054 json_object_string_add(json
,
10055 "bgpOriginatingDefaultNetwork",
10058 vty_out(vty
, "BGP table version is %" PRIu64
10059 ", local router ID is %s\n",
10060 table
->version
, inet_ntoa(bgp
->router_id
));
10061 vty_out(vty
, BGP_SHOW_SCODE_HEADER
);
10062 vty_out(vty
, BGP_SHOW_OCODE_HEADER
);
10064 vty_out(vty
, "Originating default network 0.0.0.0\n\n");
10069 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
10071 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
) {
10072 if (ain
->peer
!= peer
)
10076 json_object_int_add(
10077 json
, "bgpTableVersion",
10079 json_object_string_add(
10081 "bgpLocalRouterId",
10084 json_object_object_add(
10085 json
, "bgpStatusCodes",
10087 json_object_object_add(
10088 json
, "bgpOriginCodes",
10092 "BGP table version is 0, local router ID is %s\n",
10096 BGP_SHOW_SCODE_HEADER
);
10098 BGP_SHOW_OCODE_HEADER
);
10104 vty_out(vty
, BGP_SHOW_HEADER
);
10108 bgp_attr_dup(&attr
, ain
->attr
);
10109 if (bgp_input_modifier(peer
, &rn
->p
,
10113 route_vty_out_tmp(vty
, &rn
->p
,
10123 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
10124 SUBGRP_FOREACH_PEER (adj
->subgroup
, paf
) {
10125 if (paf
->peer
!= peer
)
10130 json_object_int_add(
10134 json_object_string_add(
10136 "bgpLocalRouterId",
10139 json_object_object_add(
10143 json_object_object_add(
10149 "BGP table version is %" PRIu64
10150 ", local router ID is %s\n",
10155 BGP_SHOW_SCODE_HEADER
);
10157 BGP_SHOW_OCODE_HEADER
);
10170 bgp_attr_dup(&attr
, adj
->attr
);
10171 ret
= bgp_output_modifier(
10172 peer
, &rn
->p
, &attr
,
10173 afi
, safi
, rmap_name
);
10174 if (ret
!= RMAP_DENY
) {
10184 bgp_attr_undup(&attr
,
10191 json_object_object_add(json
, "advertisedRoutes", json_ar
);
10193 if (output_count
!= 0) {
10195 json_object_int_add(json
, "totalPrefixCounter",
10198 vty_out(vty
, "\nTotal number of prefixes %ld\n",
10202 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10203 json
, JSON_C_TO_STRING_PRETTY
));
10204 json_object_free(json
);
10208 static int peer_adj_routes(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
10209 safi_t safi
, int in
, const char *rmap_name
,
10212 json_object
*json
= NULL
;
10215 json
= json_object_new_object();
10217 /* labeled-unicast routes live in the unicast table */
10218 if (safi
== SAFI_LABELED_UNICAST
)
10219 safi
= SAFI_UNICAST
;
10221 if (!peer
|| !peer
->afc
[afi
][safi
]) {
10223 json_object_string_add(
10225 "No such neighbor or address family");
10226 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10227 json_object_free(json
);
10229 vty_out(vty
, "%% No such neighbor or address family\n");
10231 return CMD_WARNING
;
10235 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
10236 PEER_FLAG_SOFT_RECONFIG
)) {
10238 json_object_string_add(
10240 "Inbound soft reconfiguration not enabled");
10241 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10242 json_object_free(json
);
10245 "%% Inbound soft reconfiguration not enabled\n");
10247 return CMD_WARNING
;
10250 show_adj_route(vty
, peer
, afi
, safi
, in
, rmap_name
, use_json
, json
);
10252 return CMD_SUCCESS
;
10255 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
10256 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
10257 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
10258 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
10262 BGP_INSTANCE_HELP_STR
10264 BGP_SAFI_WITH_LABEL_HELP_STR
10265 "Detailed information on TCP and BGP neighbor connections\n"
10266 "Neighbor to display information about\n"
10267 "Neighbor to display information about\n"
10268 "Neighbor on BGP configured interface\n"
10269 "Display the received routes from neighbor\n"
10270 "Display the routes advertised to a BGP neighbor\n"
10271 "Route-map to modify the attributes\n"
10272 "Name of the route map\n"
10275 afi_t afi
= AFI_IP6
;
10276 safi_t safi
= SAFI_UNICAST
;
10277 char *rmap_name
= NULL
;
10278 char *peerstr
= NULL
;
10280 struct bgp
*bgp
= NULL
;
10285 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10288 return CMD_WARNING
;
10290 int uj
= use_json(argc
, argv
);
10294 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10295 argv_find(argv
, argc
, "neighbors", &idx
);
10296 peerstr
= argv
[++idx
]->arg
;
10298 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
10300 return CMD_WARNING
;
10302 if (argv_find(argv
, argc
, "received-routes", &idx
))
10304 if (argv_find(argv
, argc
, "advertised-routes", &idx
))
10306 if (argv_find(argv
, argc
, "route-map", &idx
))
10307 rmap_name
= argv
[++idx
]->arg
;
10309 return peer_adj_routes(vty
, peer
, afi
, safi
, rcvd
, rmap_name
, uj
);
10312 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
10313 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
10314 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
10320 "Address Family modifier\n"
10321 "Detailed information on TCP and BGP neighbor connections\n"
10322 "Neighbor to display information about\n"
10323 "Neighbor to display information about\n"
10324 "Neighbor on BGP configured interface\n"
10325 "Display information received from a BGP neighbor\n"
10326 "Display the prefixlist filter\n"
10329 afi_t afi
= AFI_IP6
;
10330 safi_t safi
= SAFI_UNICAST
;
10331 char *peerstr
= NULL
;
10334 union sockunion su
;
10340 /* show [ip] bgp */
10341 if (argv_find(argv
, argc
, "ip", &idx
))
10343 /* [<ipv4|ipv6> [unicast]] */
10344 if (argv_find(argv
, argc
, "ipv4", &idx
))
10346 if (argv_find(argv
, argc
, "ipv6", &idx
))
10348 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10349 argv_find(argv
, argc
, "neighbors", &idx
);
10350 peerstr
= argv
[++idx
]->arg
;
10352 uint8_t uj
= use_json(argc
, argv
);
10354 ret
= str2sockunion(peerstr
, &su
);
10356 peer
= peer_lookup_by_conf_if(NULL
, peerstr
);
10359 vty_out(vty
, "{}\n");
10362 "%% Malformed address or name: %s\n",
10364 return CMD_WARNING
;
10367 peer
= peer_lookup(NULL
, &su
);
10370 vty_out(vty
, "{}\n");
10372 vty_out(vty
, "No peer\n");
10373 return CMD_WARNING
;
10377 sprintf(name
, "%s.%d.%d", peer
->host
, afi
, safi
);
10378 count
= prefix_bgp_show_prefix_list(NULL
, afi
, name
, uj
);
10381 vty_out(vty
, "Address Family: %s\n",
10382 afi_safi_print(afi
, safi
));
10383 prefix_bgp_show_prefix_list(vty
, afi
, name
, uj
);
10386 vty_out(vty
, "{}\n");
10388 vty_out(vty
, "No functional output\n");
10391 return CMD_SUCCESS
;
10394 static int bgp_show_neighbor_route(struct vty
*vty
, struct peer
*peer
,
10395 afi_t afi
, safi_t safi
,
10396 enum bgp_show_type type
, uint8_t use_json
)
10398 /* labeled-unicast routes live in the unicast table */
10399 if (safi
== SAFI_LABELED_UNICAST
)
10400 safi
= SAFI_UNICAST
;
10402 if (!peer
|| !peer
->afc
[afi
][safi
]) {
10404 json_object
*json_no
= NULL
;
10405 json_no
= json_object_new_object();
10406 json_object_string_add(
10407 json_no
, "warning",
10408 "No such neighbor or address family");
10409 vty_out(vty
, "%s\n",
10410 json_object_to_json_string(json_no
));
10411 json_object_free(json_no
);
10413 vty_out(vty
, "%% No such neighbor or address family\n");
10414 return CMD_WARNING
;
10417 return bgp_show(vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
10420 DEFUN (show_ip_bgp_neighbor_routes
,
10421 show_ip_bgp_neighbor_routes_cmd
,
10422 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
10423 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
10427 BGP_INSTANCE_HELP_STR
10429 BGP_SAFI_WITH_LABEL_HELP_STR
10430 "Detailed information on TCP and BGP neighbor connections\n"
10431 "Neighbor to display information about\n"
10432 "Neighbor to display information about\n"
10433 "Neighbor on BGP configured interface\n"
10434 "Display flap statistics of the routes learned from neighbor\n"
10435 "Display the dampened routes received from neighbor\n"
10436 "Display routes learned from neighbor\n"
10439 char *peerstr
= NULL
;
10440 struct bgp
*bgp
= NULL
;
10441 afi_t afi
= AFI_IP6
;
10442 safi_t safi
= SAFI_UNICAST
;
10444 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
10448 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10451 return CMD_WARNING
;
10453 int uj
= use_json(argc
, argv
);
10457 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10458 argv_find(argv
, argc
, "neighbors", &idx
);
10459 peerstr
= argv
[++idx
]->arg
;
10461 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
10463 vty_out(vty
, "No such neighbor\n");
10464 return CMD_WARNING
;
10467 if (argv_find(argv
, argc
, "flap-statistics", &idx
))
10468 sh_type
= bgp_show_type_flap_neighbor
;
10469 else if (argv_find(argv
, argc
, "dampened-routes", &idx
))
10470 sh_type
= bgp_show_type_damp_neighbor
;
10471 else if (argv_find(argv
, argc
, "routes", &idx
))
10472 sh_type
= bgp_show_type_neighbor
;
10474 return bgp_show_neighbor_route(vty
, peer
, afi
, safi
, sh_type
, uj
);
10477 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
10479 struct bgp_distance
{
10480 /* Distance value for the IP source prefix. */
10483 /* Name of the access-list to be matched. */
10487 DEFUN (show_bgp_afi_vpn_rd_route
,
10488 show_bgp_afi_vpn_rd_route_cmd
,
10489 "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]",
10493 "Address Family modifier\n"
10494 "Display information for a route distinguisher\n"
10495 "Route Distinguisher\n"
10496 "Network in the BGP routing table to display\n"
10497 "Network in the BGP routing table to display\n"
10501 struct prefix_rd prd
;
10502 afi_t afi
= AFI_MAX
;
10505 if (!argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
10506 vty_out(vty
, "%% Malformed Address Family\n");
10507 return CMD_WARNING
;
10510 ret
= str2prefix_rd(argv
[5]->arg
, &prd
);
10512 vty_out(vty
, "%% Malformed Route Distinguisher\n");
10513 return CMD_WARNING
;
10516 return bgp_show_route(vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
,
10517 0, BGP_PATH_ALL
, use_json(argc
, argv
));
10520 static struct bgp_distance
*bgp_distance_new(void)
10522 return XCALLOC(MTYPE_BGP_DISTANCE
, sizeof(struct bgp_distance
));
10525 static void bgp_distance_free(struct bgp_distance
*bdistance
)
10527 XFREE(MTYPE_BGP_DISTANCE
, bdistance
);
10530 static int bgp_distance_set(struct vty
*vty
, const char *distance_str
,
10531 const char *ip_str
, const char *access_list_str
)
10538 struct bgp_node
*rn
;
10539 struct bgp_distance
*bdistance
;
10541 afi
= bgp_node_afi(vty
);
10542 safi
= bgp_node_safi(vty
);
10544 ret
= str2prefix(ip_str
, &p
);
10546 vty_out(vty
, "Malformed prefix\n");
10547 return CMD_WARNING_CONFIG_FAILED
;
10550 distance
= atoi(distance_str
);
10552 /* Get BGP distance node. */
10553 rn
= bgp_node_get(bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
10555 bdistance
= rn
->info
;
10556 bgp_unlock_node(rn
);
10558 bdistance
= bgp_distance_new();
10559 rn
->info
= bdistance
;
10562 /* Set distance value. */
10563 bdistance
->distance
= distance
;
10565 /* Reset access-list configuration. */
10566 if (bdistance
->access_list
) {
10567 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10568 bdistance
->access_list
= NULL
;
10570 if (access_list_str
)
10571 bdistance
->access_list
=
10572 XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
10574 return CMD_SUCCESS
;
10577 static int bgp_distance_unset(struct vty
*vty
, const char *distance_str
,
10578 const char *ip_str
, const char *access_list_str
)
10585 struct bgp_node
*rn
;
10586 struct bgp_distance
*bdistance
;
10588 afi
= bgp_node_afi(vty
);
10589 safi
= bgp_node_safi(vty
);
10591 ret
= str2prefix(ip_str
, &p
);
10593 vty_out(vty
, "Malformed prefix\n");
10594 return CMD_WARNING_CONFIG_FAILED
;
10597 rn
= bgp_node_lookup(bgp_distance_table
[afi
][safi
],
10598 (struct prefix
*)&p
);
10600 vty_out(vty
, "Can't find specified prefix\n");
10601 return CMD_WARNING_CONFIG_FAILED
;
10604 bdistance
= rn
->info
;
10605 distance
= atoi(distance_str
);
10607 if (bdistance
->distance
!= distance
) {
10608 vty_out(vty
, "Distance does not match configured\n");
10609 return CMD_WARNING_CONFIG_FAILED
;
10612 if (bdistance
->access_list
)
10613 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
10614 bgp_distance_free(bdistance
);
10617 bgp_unlock_node(rn
);
10618 bgp_unlock_node(rn
);
10620 return CMD_SUCCESS
;
10623 /* Apply BGP information to distance method. */
10624 uint8_t bgp_distance_apply(struct prefix
*p
, struct bgp_info
*rinfo
, afi_t afi
,
10625 safi_t safi
, struct bgp
*bgp
)
10627 struct bgp_node
*rn
;
10630 struct bgp_distance
*bdistance
;
10631 struct access_list
*alist
;
10632 struct bgp_static
*bgp_static
;
10637 peer
= rinfo
->peer
;
10639 /* Check source address. */
10640 sockunion2hostprefix(&peer
->su
, &q
);
10641 rn
= bgp_node_match(bgp_distance_table
[afi
][safi
], &q
);
10643 bdistance
= rn
->info
;
10644 bgp_unlock_node(rn
);
10646 if (bdistance
->access_list
) {
10647 alist
= access_list_lookup(afi
, bdistance
->access_list
);
10649 && access_list_apply(alist
, p
) == FILTER_PERMIT
)
10650 return bdistance
->distance
;
10652 return bdistance
->distance
;
10655 /* Backdoor check. */
10656 rn
= bgp_node_lookup(bgp
->route
[afi
][safi
], p
);
10658 bgp_static
= rn
->info
;
10659 bgp_unlock_node(rn
);
10661 if (bgp_static
->backdoor
) {
10662 if (bgp
->distance_local
[afi
][safi
])
10663 return bgp
->distance_local
[afi
][safi
];
10665 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10669 if (peer
->sort
== BGP_PEER_EBGP
) {
10670 if (bgp
->distance_ebgp
[afi
][safi
])
10671 return bgp
->distance_ebgp
[afi
][safi
];
10672 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
10674 if (bgp
->distance_ibgp
[afi
][safi
])
10675 return bgp
->distance_ibgp
[afi
][safi
];
10676 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
10680 DEFUN (bgp_distance
,
10682 "distance bgp (1-255) (1-255) (1-255)",
10683 "Define an administrative distance\n"
10685 "Distance for routes external to the AS\n"
10686 "Distance for routes internal to the AS\n"
10687 "Distance for local routes\n")
10689 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10690 int idx_number
= 2;
10691 int idx_number_2
= 3;
10692 int idx_number_3
= 4;
10696 afi
= bgp_node_afi(vty
);
10697 safi
= bgp_node_safi(vty
);
10699 bgp
->distance_ebgp
[afi
][safi
] = atoi(argv
[idx_number
]->arg
);
10700 bgp
->distance_ibgp
[afi
][safi
] = atoi(argv
[idx_number_2
]->arg
);
10701 bgp
->distance_local
[afi
][safi
] = atoi(argv
[idx_number_3
]->arg
);
10702 return CMD_SUCCESS
;
10705 DEFUN (no_bgp_distance
,
10706 no_bgp_distance_cmd
,
10707 "no distance bgp [(1-255) (1-255) (1-255)]",
10709 "Define an administrative distance\n"
10711 "Distance for routes external to the AS\n"
10712 "Distance for routes internal to the AS\n"
10713 "Distance for local routes\n")
10715 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10719 afi
= bgp_node_afi(vty
);
10720 safi
= bgp_node_safi(vty
);
10722 bgp
->distance_ebgp
[afi
][safi
] = 0;
10723 bgp
->distance_ibgp
[afi
][safi
] = 0;
10724 bgp
->distance_local
[afi
][safi
] = 0;
10725 return CMD_SUCCESS
;
10729 DEFUN (bgp_distance_source
,
10730 bgp_distance_source_cmd
,
10731 "distance (1-255) A.B.C.D/M",
10732 "Define an administrative distance\n"
10733 "Administrative distance\n"
10734 "IP source prefix\n")
10736 int idx_number
= 1;
10737 int idx_ipv4_prefixlen
= 2;
10738 bgp_distance_set(vty
, argv
[idx_number
]->arg
,
10739 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10740 return CMD_SUCCESS
;
10743 DEFUN (no_bgp_distance_source
,
10744 no_bgp_distance_source_cmd
,
10745 "no distance (1-255) A.B.C.D/M",
10747 "Define an administrative distance\n"
10748 "Administrative distance\n"
10749 "IP source prefix\n")
10751 int idx_number
= 2;
10752 int idx_ipv4_prefixlen
= 3;
10753 bgp_distance_unset(vty
, argv
[idx_number
]->arg
,
10754 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
10755 return CMD_SUCCESS
;
10758 DEFUN (bgp_distance_source_access_list
,
10759 bgp_distance_source_access_list_cmd
,
10760 "distance (1-255) A.B.C.D/M WORD",
10761 "Define an administrative distance\n"
10762 "Administrative distance\n"
10763 "IP source prefix\n"
10764 "Access list name\n")
10766 int idx_number
= 1;
10767 int idx_ipv4_prefixlen
= 2;
10769 bgp_distance_set(vty
, argv
[idx_number
]->arg
,
10770 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10771 return CMD_SUCCESS
;
10774 DEFUN (no_bgp_distance_source_access_list
,
10775 no_bgp_distance_source_access_list_cmd
,
10776 "no distance (1-255) A.B.C.D/M WORD",
10778 "Define an administrative distance\n"
10779 "Administrative distance\n"
10780 "IP source prefix\n"
10781 "Access list name\n")
10783 int idx_number
= 2;
10784 int idx_ipv4_prefixlen
= 3;
10786 bgp_distance_unset(vty
, argv
[idx_number
]->arg
,
10787 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
10788 return CMD_SUCCESS
;
10791 DEFUN (ipv6_bgp_distance_source
,
10792 ipv6_bgp_distance_source_cmd
,
10793 "distance (1-255) X:X::X:X/M",
10794 "Define an administrative distance\n"
10795 "Administrative distance\n"
10796 "IP source prefix\n")
10798 bgp_distance_set(vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
10799 return CMD_SUCCESS
;
10802 DEFUN (no_ipv6_bgp_distance_source
,
10803 no_ipv6_bgp_distance_source_cmd
,
10804 "no distance (1-255) X:X::X:X/M",
10806 "Define an administrative distance\n"
10807 "Administrative distance\n"
10808 "IP source prefix\n")
10810 bgp_distance_unset(vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
10811 return CMD_SUCCESS
;
10814 DEFUN (ipv6_bgp_distance_source_access_list
,
10815 ipv6_bgp_distance_source_access_list_cmd
,
10816 "distance (1-255) X:X::X:X/M WORD",
10817 "Define an administrative distance\n"
10818 "Administrative distance\n"
10819 "IP source prefix\n"
10820 "Access list name\n")
10822 bgp_distance_set(vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
10823 return CMD_SUCCESS
;
10826 DEFUN (no_ipv6_bgp_distance_source_access_list
,
10827 no_ipv6_bgp_distance_source_access_list_cmd
,
10828 "no distance (1-255) X:X::X:X/M WORD",
10830 "Define an administrative distance\n"
10831 "Administrative distance\n"
10832 "IP source prefix\n"
10833 "Access list name\n")
10835 bgp_distance_unset(vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
10836 return CMD_SUCCESS
;
10839 DEFUN (bgp_damp_set
,
10841 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10842 "BGP Specific commands\n"
10843 "Enable route-flap dampening\n"
10844 "Half-life time for the penalty\n"
10845 "Value to start reusing a route\n"
10846 "Value to start suppressing a route\n"
10847 "Maximum duration to suppress a stable route\n")
10849 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10850 int idx_half_life
= 2;
10852 int idx_suppress
= 4;
10853 int idx_max_suppress
= 5;
10854 int half
= DEFAULT_HALF_LIFE
* 60;
10855 int reuse
= DEFAULT_REUSE
;
10856 int suppress
= DEFAULT_SUPPRESS
;
10857 int max
= 4 * half
;
10860 half
= atoi(argv
[idx_half_life
]->arg
) * 60;
10861 reuse
= atoi(argv
[idx_reuse
]->arg
);
10862 suppress
= atoi(argv
[idx_suppress
]->arg
);
10863 max
= atoi(argv
[idx_max_suppress
]->arg
) * 60;
10864 } else if (argc
== 3) {
10865 half
= atoi(argv
[idx_half_life
]->arg
) * 60;
10869 if (suppress
< reuse
) {
10871 "Suppress value cannot be less than reuse value \n");
10875 return bgp_damp_enable(bgp
, bgp_node_afi(vty
), bgp_node_safi(vty
), half
,
10876 reuse
, suppress
, max
);
10879 DEFUN (bgp_damp_unset
,
10880 bgp_damp_unset_cmd
,
10881 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10883 "BGP Specific commands\n"
10884 "Enable route-flap dampening\n"
10885 "Half-life time for the penalty\n"
10886 "Value to start reusing a route\n"
10887 "Value to start suppressing a route\n"
10888 "Maximum duration to suppress a stable route\n")
10890 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
10891 return bgp_damp_disable(bgp
, bgp_node_afi(vty
), bgp_node_safi(vty
));
10894 /* Display specified route of BGP table. */
10895 static int bgp_clear_damp_route(struct vty
*vty
, const char *view_name
,
10896 const char *ip_str
, afi_t afi
, safi_t safi
,
10897 struct prefix_rd
*prd
, int prefix_check
)
10900 struct prefix match
;
10901 struct bgp_node
*rn
;
10902 struct bgp_node
*rm
;
10903 struct bgp_info
*ri
;
10904 struct bgp_info
*ri_temp
;
10906 struct bgp_table
*table
;
10908 /* BGP structure lookup. */
10910 bgp
= bgp_lookup_by_name(view_name
);
10912 vty_out(vty
, "%% Can't find BGP instance %s\n",
10914 return CMD_WARNING
;
10917 bgp
= bgp_get_default();
10919 vty_out(vty
, "%% No BGP process is configured\n");
10920 return CMD_WARNING
;
10924 /* Check IP address argument. */
10925 ret
= str2prefix(ip_str
, &match
);
10927 vty_out(vty
, "%% address is malformed\n");
10928 return CMD_WARNING
;
10931 match
.family
= afi2family(afi
);
10933 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
10934 || (safi
== SAFI_EVPN
)) {
10935 for (rn
= bgp_table_top(bgp
->rib
[AFI_IP
][safi
]); rn
;
10936 rn
= bgp_route_next(rn
)) {
10937 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
10939 if ((table
= rn
->info
) == NULL
)
10941 if ((rm
= bgp_node_match(table
, &match
)) == NULL
)
10945 || rm
->p
.prefixlen
== match
.prefixlen
) {
10948 if (ri
->extra
&& ri
->extra
->damp_info
) {
10949 ri_temp
= ri
->next
;
10950 bgp_damp_info_free(
10951 ri
->extra
->damp_info
,
10959 bgp_unlock_node(rm
);
10962 if ((rn
= bgp_node_match(bgp
->rib
[afi
][safi
], &match
))
10965 || rn
->p
.prefixlen
== match
.prefixlen
) {
10968 if (ri
->extra
&& ri
->extra
->damp_info
) {
10969 ri_temp
= ri
->next
;
10970 bgp_damp_info_free(
10971 ri
->extra
->damp_info
,
10979 bgp_unlock_node(rn
);
10983 return CMD_SUCCESS
;
10986 DEFUN (clear_ip_bgp_dampening
,
10987 clear_ip_bgp_dampening_cmd
,
10988 "clear ip bgp dampening",
10992 "Clear route flap dampening information\n")
10994 bgp_damp_info_clean();
10995 return CMD_SUCCESS
;
10998 DEFUN (clear_ip_bgp_dampening_prefix
,
10999 clear_ip_bgp_dampening_prefix_cmd
,
11000 "clear ip bgp dampening A.B.C.D/M",
11004 "Clear route flap dampening information\n"
11007 int idx_ipv4_prefixlen
= 4;
11008 return bgp_clear_damp_route(vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
,
11009 AFI_IP
, SAFI_UNICAST
, NULL
, 1);
11012 DEFUN (clear_ip_bgp_dampening_address
,
11013 clear_ip_bgp_dampening_address_cmd
,
11014 "clear ip bgp dampening A.B.C.D",
11018 "Clear route flap dampening information\n"
11019 "Network to clear damping information\n")
11022 return bgp_clear_damp_route(vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
11023 SAFI_UNICAST
, NULL
, 0);
11026 DEFUN (clear_ip_bgp_dampening_address_mask
,
11027 clear_ip_bgp_dampening_address_mask_cmd
,
11028 "clear ip bgp dampening A.B.C.D A.B.C.D",
11032 "Clear route flap dampening information\n"
11033 "Network to clear damping information\n"
11037 int idx_ipv4_2
= 5;
11039 char prefix_str
[BUFSIZ
];
11041 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
,
11044 vty_out(vty
, "%% Inconsistent address and mask\n");
11045 return CMD_WARNING
;
11048 return bgp_clear_damp_route(vty
, NULL
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
11052 /* also used for encap safi */
11053 static void bgp_config_write_network_vpn(struct vty
*vty
, struct bgp
*bgp
,
11054 afi_t afi
, safi_t safi
)
11056 struct bgp_node
*prn
;
11057 struct bgp_node
*rn
;
11058 struct bgp_table
*table
;
11060 struct prefix_rd
*prd
;
11061 struct bgp_static
*bgp_static
;
11062 mpls_label_t label
;
11063 char buf
[SU_ADDRSTRLEN
];
11064 char rdbuf
[RD_ADDRSTRLEN
];
11066 /* Network configuration. */
11067 for (prn
= bgp_table_top(bgp
->route
[afi
][safi
]); prn
;
11068 prn
= bgp_route_next(prn
)) {
11069 if ((table
= prn
->info
) == NULL
)
11072 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
11073 if ((bgp_static
= rn
->info
) == NULL
)
11077 prd
= (struct prefix_rd
*)&prn
->p
;
11079 /* "network" configuration display. */
11080 prefix_rd2str(prd
, rdbuf
, sizeof(rdbuf
));
11081 label
= decode_label(&bgp_static
->label
);
11083 vty_out(vty
, " network %s/%d rd %s",
11084 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11086 p
->prefixlen
, rdbuf
);
11087 if (safi
== SAFI_MPLS_VPN
)
11088 vty_out(vty
, " label %u", label
);
11090 if (bgp_static
->rmap
.name
)
11091 vty_out(vty
, " route-map %s",
11092 bgp_static
->rmap
.name
);
11094 if (bgp_static
->backdoor
)
11095 vty_out(vty
, " backdoor");
11097 vty_out(vty
, "\n");
11102 static void bgp_config_write_network_evpn(struct vty
*vty
, struct bgp
*bgp
,
11103 afi_t afi
, safi_t safi
)
11105 struct bgp_node
*prn
;
11106 struct bgp_node
*rn
;
11107 struct bgp_table
*table
;
11109 struct prefix_rd
*prd
;
11110 struct bgp_static
*bgp_static
;
11111 char buf
[PREFIX_STRLEN
];
11112 char buf2
[SU_ADDRSTRLEN
];
11113 char rdbuf
[RD_ADDRSTRLEN
];
11115 /* Network configuration. */
11116 for (prn
= bgp_table_top(bgp
->route
[afi
][safi
]); prn
;
11117 prn
= bgp_route_next(prn
)) {
11118 if ((table
= prn
->info
) == NULL
)
11121 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
11122 if ((bgp_static
= rn
->info
) == NULL
)
11125 char *macrouter
= NULL
;
11128 if (bgp_static
->router_mac
)
11129 macrouter
= prefix_mac2str(
11130 bgp_static
->router_mac
, NULL
, 0);
11131 if (bgp_static
->eth_s_id
)
11132 esi
= esi2str(bgp_static
->eth_s_id
);
11134 prd
= (struct prefix_rd
*)&prn
->p
;
11136 /* "network" configuration display. */
11137 prefix_rd2str(prd
, rdbuf
, sizeof(rdbuf
));
11138 if (p
->u
.prefix_evpn
.route_type
== 5) {
11139 char local_buf
[PREFIX_STRLEN
];
11140 uint8_t family
= IS_EVPN_PREFIX_IPADDR_V4((
11141 struct prefix_evpn
*)p
)
11144 inet_ntop(family
, &p
->u
.prefix_evpn
.ip
.ip
.addr
,
11145 local_buf
, PREFIX_STRLEN
);
11146 sprintf(buf
, "%s/%u", local_buf
,
11147 p
->u
.prefix_evpn
.ip_prefix_length
);
11149 prefix2str(p
, buf
, sizeof(buf
));
11152 if (bgp_static
->gatewayIp
.family
== AF_INET
11153 || bgp_static
->gatewayIp
.family
== AF_INET6
)
11154 inet_ntop(bgp_static
->gatewayIp
.family
,
11155 &bgp_static
->gatewayIp
.u
.prefix
, buf2
,
11158 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
11159 buf
, rdbuf
, p
->u
.prefix_evpn
.eth_tag
,
11160 decode_label(&bgp_static
->label
), esi
, buf2
,
11164 XFREE(MTYPE_TMP
, macrouter
);
11166 XFREE(MTYPE_TMP
, esi
);
11171 /* Configuration of static route announcement and aggregate
11173 void bgp_config_write_network(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
11176 struct bgp_node
*rn
;
11178 struct bgp_static
*bgp_static
;
11179 struct bgp_aggregate
*bgp_aggregate
;
11180 char buf
[SU_ADDRSTRLEN
];
11182 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)) {
11183 bgp_config_write_network_vpn(vty
, bgp
, afi
, safi
);
11187 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
11188 bgp_config_write_network_evpn(vty
, bgp
, afi
, safi
);
11192 /* Network configuration. */
11193 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
11194 rn
= bgp_route_next(rn
)) {
11195 if ((bgp_static
= rn
->info
) == NULL
)
11200 /* "network" configuration display. */
11201 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
) {
11202 uint32_t destination
;
11203 struct in_addr netmask
;
11205 destination
= ntohl(p
->u
.prefix4
.s_addr
);
11206 masklen2ip(p
->prefixlen
, &netmask
);
11207 vty_out(vty
, " network %s",
11208 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11211 if ((IN_CLASSC(destination
) && p
->prefixlen
== 24)
11212 || (IN_CLASSB(destination
) && p
->prefixlen
== 16)
11213 || (IN_CLASSA(destination
) && p
->prefixlen
== 8)
11214 || p
->u
.prefix4
.s_addr
== 0) {
11215 /* Natural mask is not display. */
11217 vty_out(vty
, " mask %s", inet_ntoa(netmask
));
11219 vty_out(vty
, " network %s/%d",
11220 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11225 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
11226 vty_out(vty
, " label-index %u",
11227 bgp_static
->label_index
);
11229 if (bgp_static
->rmap
.name
)
11230 vty_out(vty
, " route-map %s", bgp_static
->rmap
.name
);
11232 if (bgp_static
->backdoor
)
11233 vty_out(vty
, " backdoor");
11235 vty_out(vty
, "\n");
11238 /* Aggregate-address configuration. */
11239 for (rn
= bgp_table_top(bgp
->aggregate
[afi
][safi
]); rn
;
11240 rn
= bgp_route_next(rn
)) {
11241 if ((bgp_aggregate
= rn
->info
) == NULL
)
11246 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
) {
11247 struct in_addr netmask
;
11249 masklen2ip(p
->prefixlen
, &netmask
);
11250 vty_out(vty
, " aggregate-address %s %s",
11251 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11253 inet_ntoa(netmask
));
11255 vty_out(vty
, " aggregate-address %s/%d",
11256 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11261 if (bgp_aggregate
->as_set
)
11262 vty_out(vty
, " as-set");
11264 if (bgp_aggregate
->summary_only
)
11265 vty_out(vty
, " summary-only");
11267 vty_out(vty
, "\n");
11271 void bgp_config_write_distance(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
11274 struct bgp_node
*rn
;
11275 struct bgp_distance
*bdistance
;
11277 /* Distance configuration. */
11278 if (bgp
->distance_ebgp
[afi
][safi
] && bgp
->distance_ibgp
[afi
][safi
]
11279 && bgp
->distance_local
[afi
][safi
]
11280 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
11281 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
11282 || bgp
->distance_local
[afi
][safi
]
11283 != ZEBRA_IBGP_DISTANCE_DEFAULT
)) {
11284 vty_out(vty
, " distance bgp %d %d %d\n",
11285 bgp
->distance_ebgp
[afi
][safi
],
11286 bgp
->distance_ibgp
[afi
][safi
],
11287 bgp
->distance_local
[afi
][safi
]);
11290 for (rn
= bgp_table_top(bgp_distance_table
[afi
][safi
]); rn
;
11291 rn
= bgp_route_next(rn
))
11292 if ((bdistance
= rn
->info
) != NULL
) {
11293 char buf
[PREFIX_STRLEN
];
11295 vty_out(vty
, " distance %d %s %s\n",
11296 bdistance
->distance
,
11297 prefix2str(&rn
->p
, buf
, sizeof(buf
)),
11298 bdistance
->access_list
? bdistance
->access_list
11303 /* Allocate routing table structure and install commands. */
11304 void bgp_route_init(void)
11309 /* Init BGP distance table. */
11310 FOREACH_AFI_SAFI (afi
, safi
)
11311 bgp_distance_table
[afi
][safi
] = bgp_table_init(afi
, safi
);
11313 /* IPv4 BGP commands. */
11314 install_element(BGP_NODE
, &bgp_table_map_cmd
);
11315 install_element(BGP_NODE
, &bgp_network_cmd
);
11316 install_element(BGP_NODE
, &no_bgp_table_map_cmd
);
11318 install_element(BGP_NODE
, &aggregate_address_cmd
);
11319 install_element(BGP_NODE
, &aggregate_address_mask_cmd
);
11320 install_element(BGP_NODE
, &no_aggregate_address_cmd
);
11321 install_element(BGP_NODE
, &no_aggregate_address_mask_cmd
);
11323 /* IPv4 unicast configuration. */
11324 install_element(BGP_IPV4_NODE
, &bgp_table_map_cmd
);
11325 install_element(BGP_IPV4_NODE
, &bgp_network_cmd
);
11326 install_element(BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
11328 install_element(BGP_IPV4_NODE
, &aggregate_address_cmd
);
11329 install_element(BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
11330 install_element(BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
11331 install_element(BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
11333 /* IPv4 multicast configuration. */
11334 install_element(BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
11335 install_element(BGP_IPV4M_NODE
, &bgp_network_cmd
);
11336 install_element(BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
11337 install_element(BGP_IPV4M_NODE
, &aggregate_address_cmd
);
11338 install_element(BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
11339 install_element(BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
11340 install_element(BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
11342 /* IPv4 labeled-unicast configuration. */
11343 install_element(VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
11344 install_element(VIEW_NODE
, &show_ip_bgp_cmd
);
11345 install_element(VIEW_NODE
, &show_ip_bgp_json_cmd
);
11346 install_element(VIEW_NODE
, &show_ip_bgp_route_cmd
);
11347 install_element(VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
11349 install_element(VIEW_NODE
,
11350 &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
11351 install_element(VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
11352 install_element(VIEW_NODE
,
11353 &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
11354 #ifdef KEEP_OLD_VPN_COMMANDS
11355 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
11356 #endif /* KEEP_OLD_VPN_COMMANDS */
11357 install_element(VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
11358 install_element(VIEW_NODE
,
11359 &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
);
11361 /* BGP dampening clear commands */
11362 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
11363 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
11365 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
11366 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
11369 install_element(ENABLE_NODE
,
11370 &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
11371 #ifdef KEEP_OLD_VPN_COMMANDS
11372 install_element(ENABLE_NODE
,
11373 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
11374 #endif /* KEEP_OLD_VPN_COMMANDS */
11376 /* New config IPv6 BGP commands. */
11377 install_element(BGP_IPV6_NODE
, &bgp_table_map_cmd
);
11378 install_element(BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
11379 install_element(BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
11381 install_element(BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
11382 install_element(BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
11384 install_element(BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
11386 install_element(BGP_NODE
, &bgp_distance_cmd
);
11387 install_element(BGP_NODE
, &no_bgp_distance_cmd
);
11388 install_element(BGP_NODE
, &bgp_distance_source_cmd
);
11389 install_element(BGP_NODE
, &no_bgp_distance_source_cmd
);
11390 install_element(BGP_NODE
, &bgp_distance_source_access_list_cmd
);
11391 install_element(BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
11392 install_element(BGP_IPV4_NODE
, &bgp_distance_cmd
);
11393 install_element(BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
11394 install_element(BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
11395 install_element(BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
11396 install_element(BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
11397 install_element(BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
11398 install_element(BGP_IPV4M_NODE
, &bgp_distance_cmd
);
11399 install_element(BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
11400 install_element(BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
11401 install_element(BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
11402 install_element(BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
11403 install_element(BGP_IPV4M_NODE
,
11404 &no_bgp_distance_source_access_list_cmd
);
11405 install_element(BGP_IPV6_NODE
, &bgp_distance_cmd
);
11406 install_element(BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
11407 install_element(BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
11408 install_element(BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11409 install_element(BGP_IPV6_NODE
,
11410 &ipv6_bgp_distance_source_access_list_cmd
);
11411 install_element(BGP_IPV6_NODE
,
11412 &no_ipv6_bgp_distance_source_access_list_cmd
);
11413 install_element(BGP_IPV6M_NODE
, &bgp_distance_cmd
);
11414 install_element(BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
11415 install_element(BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
11416 install_element(BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11417 install_element(BGP_IPV6M_NODE
,
11418 &ipv6_bgp_distance_source_access_list_cmd
);
11419 install_element(BGP_IPV6M_NODE
,
11420 &no_ipv6_bgp_distance_source_access_list_cmd
);
11422 install_element(BGP_NODE
, &bgp_damp_set_cmd
);
11423 install_element(BGP_NODE
, &bgp_damp_unset_cmd
);
11424 install_element(BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
11425 install_element(BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
11427 /* IPv4 Multicast Mode */
11428 install_element(BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
11429 install_element(BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
11431 /* Large Communities */
11432 install_element(VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
11433 install_element(VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
11436 void bgp_route_finish(void)
11441 FOREACH_AFI_SAFI (afi
, safi
) {
11442 bgp_table_unlock(bgp_distance_table
[afi
][safi
]);
11443 bgp_distance_table
[afi
][safi
] = NULL
;