1 /* BGP routing information
2 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 * Copyright (C) 2016 Job Snijders <job@instituut.net>
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "sockunion.h"
37 #include "workqueue.h"
41 #include "lib_errors.h"
43 #include "bgpd/bgpd.h"
44 #include "bgpd/bgp_table.h"
45 #include "bgpd/bgp_route.h"
46 #include "bgpd/bgp_attr.h"
47 #include "bgpd/bgp_debug.h"
48 #include "bgpd/bgp_errors.h"
49 #include "bgpd/bgp_aspath.h"
50 #include "bgpd/bgp_regex.h"
51 #include "bgpd/bgp_community.h"
52 #include "bgpd/bgp_ecommunity.h"
53 #include "bgpd/bgp_lcommunity.h"
54 #include "bgpd/bgp_clist.h"
55 #include "bgpd/bgp_packet.h"
56 #include "bgpd/bgp_filter.h"
57 #include "bgpd/bgp_fsm.h"
58 #include "bgpd/bgp_mplsvpn.h"
59 #include "bgpd/bgp_nexthop.h"
60 #include "bgpd/bgp_damp.h"
61 #include "bgpd/bgp_advertise.h"
62 #include "bgpd/bgp_zebra.h"
63 #include "bgpd/bgp_vty.h"
64 #include "bgpd/bgp_mpath.h"
65 #include "bgpd/bgp_nht.h"
66 #include "bgpd/bgp_updgrp.h"
67 #include "bgpd/bgp_label.h"
68 #include "bgpd/bgp_addpath.h"
71 #include "bgpd/rfapi/rfapi_backend.h"
72 #include "bgpd/rfapi/vnc_import_bgp.h"
73 #include "bgpd/rfapi/vnc_export_bgp.h"
75 #include "bgpd/bgp_encap_types.h"
76 #include "bgpd/bgp_encap_tlv.h"
77 #include "bgpd/bgp_evpn.h"
78 #include "bgpd/bgp_evpn_vty.h"
79 #include "bgpd/bgp_flowspec.h"
80 #include "bgpd/bgp_flowspec_util.h"
81 #include "bgpd/bgp_pbr.h"
83 #ifndef VTYSH_EXTRACT_PL
84 #include "bgpd/bgp_route_clippy.c"
87 /* Extern from bgp_dump.c */
88 extern const char *bgp_origin_str
[];
89 extern const char *bgp_origin_long_str
[];
92 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
93 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
94 static const struct message bgp_pmsi_tnltype_str
[] = {
95 {PMSI_TNLTYPE_NO_INFO
, PMSI_TNLTYPE_STR_NO_INFO
},
96 {PMSI_TNLTYPE_RSVP_TE_P2MP
, "RSVP-TE P2MP"},
97 {PMSI_TNLTYPE_MLDP_P2MP
, "mLDP P2MP"},
98 {PMSI_TNLTYPE_PIM_SSM
, "PIM-SSM"},
99 {PMSI_TNLTYPE_PIM_SM
, "PIM-SM"},
100 {PMSI_TNLTYPE_PIM_BIDIR
, "PIM-BIDIR"},
101 {PMSI_TNLTYPE_INGR_REPL
, "Ingress Replication"},
102 {PMSI_TNLTYPE_MLDP_MP2MP
, "mLDP MP2MP"},
106 #define VRFID_NONE_STR "-"
108 struct bgp_node
*bgp_afi_node_get(struct bgp_table
*table
, afi_t afi
,
109 safi_t safi
, struct prefix
*p
,
110 struct prefix_rd
*prd
)
113 struct bgp_node
*prn
= NULL
;
119 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
120 || (safi
== SAFI_EVPN
)) {
121 prn
= bgp_node_get(table
, (struct prefix
*)prd
);
123 if (prn
->info
== NULL
)
124 prn
->info
= bgp_table_init(table
->bgp
, afi
, safi
);
126 bgp_unlock_node(prn
);
130 rn
= bgp_node_get(table
, p
);
132 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
133 || (safi
== SAFI_EVPN
))
139 struct bgp_node
*bgp_afi_node_lookup(struct bgp_table
*table
, afi_t afi
,
140 safi_t safi
, struct prefix
*p
,
141 struct prefix_rd
*prd
)
144 struct bgp_node
*prn
= NULL
;
149 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
150 || (safi
== SAFI_EVPN
)) {
151 prn
= bgp_node_lookup(table
, (struct prefix
*)prd
);
155 if (prn
->info
== NULL
) {
156 bgp_unlock_node(prn
);
163 rn
= bgp_node_lookup(table
, p
);
168 /* Allocate bgp_path_info_extra */
169 static struct bgp_path_info_extra
*bgp_path_info_extra_new(void)
171 struct bgp_path_info_extra
*new;
172 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA
,
173 sizeof(struct bgp_path_info_extra
));
174 new->label
[0] = MPLS_INVALID_LABEL
;
179 static void bgp_path_info_extra_free(struct bgp_path_info_extra
**extra
)
181 struct bgp_path_info_extra
*e
;
183 if (!extra
|| !*extra
)
188 bgp_damp_info_free(e
->damp_info
, 0);
192 struct bgp_path_info
*bpi
= (struct bgp_path_info
*)e
->parent
;
195 /* FIXME: since multiple e may have the same e->parent
196 * and e->parent->net is holding a refcount for each
197 * of them, we need to do some fudging here.
199 * WARNING: if bpi->net->lock drops to 0, bpi may be
200 * freed as well (because bpi->net was holding the
201 * last reference to bpi) => write after free!
205 bpi
= bgp_path_info_lock(bpi
);
206 refcount
= bpi
->net
->lock
- 1;
207 bgp_unlock_node((struct bgp_node
*)bpi
->net
);
210 bgp_path_info_unlock(bpi
);
212 bgp_path_info_unlock(e
->parent
);
217 bgp_unlock(e
->bgp_orig
);
219 if ((*extra
)->bgp_fs_pbr
)
220 list_delete(&((*extra
)->bgp_fs_pbr
));
221 XFREE(MTYPE_BGP_ROUTE_EXTRA
, *extra
);
226 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
227 * allocated if required.
229 struct bgp_path_info_extra
*bgp_path_info_extra_get(struct bgp_path_info
*pi
)
232 pi
->extra
= bgp_path_info_extra_new();
236 /* Allocate new bgp info structure. */
237 struct bgp_path_info
*bgp_path_info_new(void)
239 return XCALLOC(MTYPE_BGP_ROUTE
, sizeof(struct bgp_path_info
));
242 /* Free bgp route information. */
243 static void bgp_path_info_free(struct bgp_path_info
*path
)
246 bgp_attr_unintern(&path
->attr
);
248 bgp_unlink_nexthop(path
);
249 bgp_path_info_extra_free(&path
->extra
);
250 bgp_path_info_mpath_free(&path
->mpath
);
251 bgp_addpath_free_info_data(&path
->tx_addpath
,
252 path
->net
? &path
->net
->tx_addpath
: NULL
);
254 peer_unlock(path
->peer
); /* bgp_path_info peer reference */
256 XFREE(MTYPE_BGP_ROUTE
, path
);
259 struct bgp_path_info
*bgp_path_info_lock(struct bgp_path_info
*path
)
265 struct bgp_path_info
*bgp_path_info_unlock(struct bgp_path_info
*path
)
267 assert(path
&& path
->lock
> 0);
270 if (path
->lock
== 0) {
272 zlog_debug ("%s: unlocked and freeing", __func__
);
273 zlog_backtrace (LOG_DEBUG
);
275 bgp_path_info_free(path
);
282 zlog_debug ("%s: unlocked to 1", __func__
);
283 zlog_backtrace (LOG_DEBUG
);
290 void bgp_path_info_add(struct bgp_node
*rn
, struct bgp_path_info
*pi
)
292 struct bgp_path_info
*top
;
302 bgp_path_info_lock(pi
);
304 peer_lock(pi
->peer
); /* bgp_path_info peer reference */
307 /* Do the actual removal of info from RIB, for use by bgp_process
308 completion callback *only* */
309 void bgp_path_info_reap(struct bgp_node
*rn
, struct bgp_path_info
*pi
)
312 pi
->next
->prev
= pi
->prev
;
314 pi
->prev
->next
= pi
->next
;
318 bgp_path_info_mpath_dequeue(pi
);
319 bgp_path_info_unlock(pi
);
323 void bgp_path_info_delete(struct bgp_node
*rn
, struct bgp_path_info
*pi
)
325 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_REMOVED
);
326 /* set of previous already took care of pcount */
327 UNSET_FLAG(pi
->flags
, BGP_PATH_VALID
);
330 /* undo the effects of a previous call to bgp_path_info_delete; typically
331 called when a route is deleted and then quickly re-added before the
332 deletion has been processed */
333 void bgp_path_info_restore(struct bgp_node
*rn
, struct bgp_path_info
*pi
)
335 bgp_path_info_unset_flag(rn
, pi
, BGP_PATH_REMOVED
);
336 /* unset of previous already took care of pcount */
337 SET_FLAG(pi
->flags
, BGP_PATH_VALID
);
340 /* Adjust pcount as required */
341 static void bgp_pcount_adjust(struct bgp_node
*rn
, struct bgp_path_info
*pi
)
343 struct bgp_table
*table
;
345 assert(rn
&& bgp_node_table(rn
));
346 assert(pi
&& pi
->peer
&& pi
->peer
->bgp
);
348 table
= bgp_node_table(rn
);
350 if (pi
->peer
== pi
->peer
->bgp
->peer_self
)
353 if (!BGP_PATH_COUNTABLE(pi
)
354 && CHECK_FLAG(pi
->flags
, BGP_PATH_COUNTED
)) {
356 UNSET_FLAG(pi
->flags
, BGP_PATH_COUNTED
);
358 /* slight hack, but more robust against errors. */
359 if (pi
->peer
->pcount
[table
->afi
][table
->safi
])
360 pi
->peer
->pcount
[table
->afi
][table
->safi
]--;
362 flog_err(EC_LIB_DEVELOPMENT
,
363 "Asked to decrement 0 prefix count for peer");
364 } else if (BGP_PATH_COUNTABLE(pi
)
365 && !CHECK_FLAG(pi
->flags
, BGP_PATH_COUNTED
)) {
366 SET_FLAG(pi
->flags
, BGP_PATH_COUNTED
);
367 pi
->peer
->pcount
[table
->afi
][table
->safi
]++;
371 static int bgp_label_index_differs(struct bgp_path_info
*pi1
,
372 struct bgp_path_info
*pi2
)
374 return (!(pi1
->attr
->label_index
== pi2
->attr
->label_index
));
377 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
378 * This is here primarily to keep prefix-count in check.
380 void bgp_path_info_set_flag(struct bgp_node
*rn
, struct bgp_path_info
*pi
,
383 SET_FLAG(pi
->flags
, flag
);
385 /* early bath if we know it's not a flag that changes countability state
387 if (!CHECK_FLAG(flag
,
388 BGP_PATH_VALID
| BGP_PATH_HISTORY
| BGP_PATH_REMOVED
))
391 bgp_pcount_adjust(rn
, pi
);
394 void bgp_path_info_unset_flag(struct bgp_node
*rn
, struct bgp_path_info
*pi
,
397 UNSET_FLAG(pi
->flags
, flag
);
399 /* early bath if we know it's not a flag that changes countability state
401 if (!CHECK_FLAG(flag
,
402 BGP_PATH_VALID
| BGP_PATH_HISTORY
| BGP_PATH_REMOVED
))
405 bgp_pcount_adjust(rn
, pi
);
408 /* Get MED value. If MED value is missing and "bgp bestpath
409 missing-as-worst" is specified, treat it as the worst value. */
410 static uint32_t bgp_med_value(struct attr
*attr
, struct bgp
*bgp
)
412 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
415 if (bgp_flag_check(bgp
, BGP_FLAG_MED_MISSING_AS_WORST
))
422 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info
*pi
, char *buf
)
424 if (pi
->addpath_rx_id
)
425 sprintf(buf
, "path %s (addpath rxid %d)", pi
->peer
->host
,
428 sprintf(buf
, "path %s", pi
->peer
->host
);
431 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
433 static int bgp_path_info_cmp(struct bgp
*bgp
, struct bgp_path_info
*new,
434 struct bgp_path_info
*exist
, int *paths_eq
,
435 struct bgp_maxpaths_cfg
*mpath_cfg
, int debug
,
436 char *pfx_buf
, afi_t afi
, safi_t safi
)
438 struct attr
*newattr
, *existattr
;
439 bgp_peer_sort_t new_sort
;
440 bgp_peer_sort_t exist_sort
;
446 uint32_t exist_weight
;
447 uint32_t newm
, existm
;
448 struct in_addr new_id
;
449 struct in_addr exist_id
;
452 int internal_as_route
;
455 char new_buf
[PATH_ADDPATH_STR_BUFFER
];
456 char exist_buf
[PATH_ADDPATH_STR_BUFFER
];
458 uint32_t exist_mm_seq
;
466 zlog_debug("%s: new is NULL", pfx_buf
);
471 bgp_path_info_path_with_addpath_rx_str(new, new_buf
);
475 zlog_debug("%s: %s is the initial bestpath", pfx_buf
,
481 bgp_path_info_path_with_addpath_rx_str(exist
, exist_buf
);
482 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
483 pfx_buf
, new_buf
, new->flags
, exist_buf
,
488 existattr
= exist
->attr
;
490 /* For EVPN routes, we cannot just go by local vs remote, we have to
491 * look at the MAC mobility sequence number, if present.
493 if (safi
== SAFI_EVPN
) {
494 /* This is an error condition described in RFC 7432 Section
496 * states that in this scenario "the PE MUST alert the operator"
498 * does not state what other action to take. In order to provide
500 * consistency in this scenario we are going to prefer the path
504 if (newattr
->sticky
!= existattr
->sticky
) {
506 prefix2str(&new->net
->p
, pfx_buf
,
508 * PREFIX2STR_BUFFER
);
509 bgp_path_info_path_with_addpath_rx_str(new,
511 bgp_path_info_path_with_addpath_rx_str(
515 if (newattr
->sticky
&& !existattr
->sticky
) {
518 "%s: %s wins over %s due to sticky MAC flag",
519 pfx_buf
, new_buf
, exist_buf
);
523 if (!newattr
->sticky
&& existattr
->sticky
) {
526 "%s: %s loses to %s due to sticky MAC flag",
527 pfx_buf
, new_buf
, exist_buf
);
532 new_mm_seq
= mac_mobility_seqnum(newattr
);
533 exist_mm_seq
= mac_mobility_seqnum(existattr
);
535 if (new_mm_seq
> exist_mm_seq
) {
538 "%s: %s wins over %s due to MM seq %u > %u",
539 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
544 if (new_mm_seq
< exist_mm_seq
) {
547 "%s: %s loses to %s due to MM seq %u < %u",
548 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
554 * if sequence numbers are the same path with the lowest IP
557 nh_cmp
= bgp_path_info_nexthop_cmp(new, exist
);
561 "%s: %s wins over %s due to same MM seq %u and lower IP %s",
562 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
563 inet_ntoa(new->attr
->nexthop
));
569 "%s: %s loses to %s due to same MM seq %u and higher IP %s",
570 pfx_buf
, new_buf
, exist_buf
, new_mm_seq
,
571 inet_ntoa(new->attr
->nexthop
));
576 /* 1. Weight check. */
577 new_weight
= newattr
->weight
;
578 exist_weight
= existattr
->weight
;
580 if (new_weight
> exist_weight
) {
582 zlog_debug("%s: %s wins over %s due to weight %d > %d",
583 pfx_buf
, new_buf
, exist_buf
, new_weight
,
588 if (new_weight
< exist_weight
) {
590 zlog_debug("%s: %s loses to %s due to weight %d < %d",
591 pfx_buf
, new_buf
, exist_buf
, new_weight
,
596 /* 2. Local preference check. */
597 new_pref
= exist_pref
= bgp
->default_local_pref
;
599 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
600 new_pref
= newattr
->local_pref
;
601 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
602 exist_pref
= existattr
->local_pref
;
604 if (new_pref
> exist_pref
) {
607 "%s: %s wins over %s due to localpref %d > %d",
608 pfx_buf
, new_buf
, exist_buf
, new_pref
,
613 if (new_pref
< exist_pref
) {
616 "%s: %s loses to %s due to localpref %d < %d",
617 pfx_buf
, new_buf
, exist_buf
, new_pref
,
622 /* 3. Local route check. We prefer:
624 * - BGP_ROUTE_AGGREGATE
625 * - BGP_ROUTE_REDISTRIBUTE
627 if (!(new->sub_type
== BGP_ROUTE_NORMAL
||
628 new->sub_type
== BGP_ROUTE_IMPORTED
)) {
631 "%s: %s wins over %s due to preferred BGP_ROUTE type",
632 pfx_buf
, new_buf
, exist_buf
);
636 if (!(exist
->sub_type
== BGP_ROUTE_NORMAL
||
637 exist
->sub_type
== BGP_ROUTE_IMPORTED
)) {
640 "%s: %s loses to %s due to preferred BGP_ROUTE type",
641 pfx_buf
, new_buf
, exist_buf
);
645 /* 4. AS path length check. */
646 if (!bgp_flag_check(bgp
, BGP_FLAG_ASPATH_IGNORE
)) {
647 int exist_hops
= aspath_count_hops(existattr
->aspath
);
648 int exist_confeds
= aspath_count_confeds(existattr
->aspath
);
650 if (bgp_flag_check(bgp
, BGP_FLAG_ASPATH_CONFED
)) {
653 aspath_hops
= aspath_count_hops(newattr
->aspath
);
654 aspath_hops
+= aspath_count_confeds(newattr
->aspath
);
656 if (aspath_hops
< (exist_hops
+ exist_confeds
)) {
659 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
660 pfx_buf
, new_buf
, exist_buf
,
662 (exist_hops
+ exist_confeds
));
666 if (aspath_hops
> (exist_hops
+ exist_confeds
)) {
669 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
670 pfx_buf
, new_buf
, exist_buf
,
672 (exist_hops
+ exist_confeds
));
676 int newhops
= aspath_count_hops(newattr
->aspath
);
678 if (newhops
< exist_hops
) {
681 "%s: %s wins over %s due to aspath hopcount %d < %d",
682 pfx_buf
, new_buf
, exist_buf
,
683 newhops
, exist_hops
);
687 if (newhops
> exist_hops
) {
690 "%s: %s loses to %s due to aspath hopcount %d > %d",
691 pfx_buf
, new_buf
, exist_buf
,
692 newhops
, exist_hops
);
698 /* 5. Origin check. */
699 if (newattr
->origin
< existattr
->origin
) {
701 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
702 pfx_buf
, new_buf
, exist_buf
,
703 bgp_origin_long_str
[newattr
->origin
],
704 bgp_origin_long_str
[existattr
->origin
]);
708 if (newattr
->origin
> existattr
->origin
) {
710 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
711 pfx_buf
, new_buf
, exist_buf
,
712 bgp_origin_long_str
[newattr
->origin
],
713 bgp_origin_long_str
[existattr
->origin
]);
718 internal_as_route
= (aspath_count_hops(newattr
->aspath
) == 0
719 && aspath_count_hops(existattr
->aspath
) == 0);
720 confed_as_route
= (aspath_count_confeds(newattr
->aspath
) > 0
721 && aspath_count_confeds(existattr
->aspath
) > 0
722 && aspath_count_hops(newattr
->aspath
) == 0
723 && aspath_count_hops(existattr
->aspath
) == 0);
725 if (bgp_flag_check(bgp
, BGP_FLAG_ALWAYS_COMPARE_MED
)
726 || (bgp_flag_check(bgp
, BGP_FLAG_MED_CONFED
) && confed_as_route
)
727 || aspath_cmp_left(newattr
->aspath
, existattr
->aspath
)
728 || aspath_cmp_left_confed(newattr
->aspath
, existattr
->aspath
)
729 || internal_as_route
) {
730 new_med
= bgp_med_value(new->attr
, bgp
);
731 exist_med
= bgp_med_value(exist
->attr
, bgp
);
733 if (new_med
< exist_med
) {
736 "%s: %s wins over %s due to MED %d < %d",
737 pfx_buf
, new_buf
, exist_buf
, new_med
,
742 if (new_med
> exist_med
) {
745 "%s: %s loses to %s due to MED %d > %d",
746 pfx_buf
, new_buf
, exist_buf
, new_med
,
752 /* 7. Peer type check. */
753 new_sort
= new->peer
->sort
;
754 exist_sort
= exist
->peer
->sort
;
756 if (new_sort
== BGP_PEER_EBGP
757 && (exist_sort
== BGP_PEER_IBGP
|| exist_sort
== BGP_PEER_CONFED
)) {
760 "%s: %s wins over %s due to eBGP peer > iBGP peer",
761 pfx_buf
, new_buf
, exist_buf
);
765 if (exist_sort
== BGP_PEER_EBGP
766 && (new_sort
== BGP_PEER_IBGP
|| new_sort
== BGP_PEER_CONFED
)) {
769 "%s: %s loses to %s due to iBGP peer < eBGP peer",
770 pfx_buf
, new_buf
, exist_buf
);
774 /* 8. IGP metric check. */
778 newm
= new->extra
->igpmetric
;
780 existm
= exist
->extra
->igpmetric
;
785 "%s: %s wins over %s due to IGP metric %d < %d",
786 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
793 "%s: %s loses to %s due to IGP metric %d > %d",
794 pfx_buf
, new_buf
, exist_buf
, newm
, existm
);
798 /* 9. Same IGP metric. Compare the cluster list length as
799 representative of IGP hops metric. Rewrite the metric value
800 pair (newm, existm) with the cluster list length. Prefer the
801 path with smaller cluster list length. */
802 if (newm
== existm
) {
803 if (peer_sort(new->peer
) == BGP_PEER_IBGP
804 && peer_sort(exist
->peer
) == BGP_PEER_IBGP
805 && (mpath_cfg
== NULL
807 mpath_cfg
->ibgp_flags
,
808 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN
))) {
809 newm
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
810 existm
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
815 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
816 pfx_buf
, new_buf
, exist_buf
,
824 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
825 pfx_buf
, new_buf
, exist_buf
,
832 /* 10. confed-external vs. confed-internal */
833 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
834 if (new_sort
== BGP_PEER_CONFED
835 && exist_sort
== BGP_PEER_IBGP
) {
838 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
839 pfx_buf
, new_buf
, exist_buf
);
843 if (exist_sort
== BGP_PEER_CONFED
844 && new_sort
== BGP_PEER_IBGP
) {
847 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
848 pfx_buf
, new_buf
, exist_buf
);
853 /* 11. Maximum path check. */
854 if (newm
== existm
) {
855 /* If one path has a label but the other does not, do not treat
856 * them as equals for multipath
858 if ((new->extra
&&bgp_is_valid_label(&new->extra
->label
[0]))
860 && bgp_is_valid_label(&exist
->extra
->label
[0]))) {
863 "%s: %s and %s cannot be multipath, one has a label while the other does not",
864 pfx_buf
, new_buf
, exist_buf
);
865 } else if (bgp_flag_check(bgp
,
866 BGP_FLAG_ASPATH_MULTIPATH_RELAX
)) {
869 * For the two paths, all comparison steps till IGP
871 * have succeeded - including AS_PATH hop count. Since
873 * bestpath as-path multipath-relax' knob is on, we
875 * an exact match of AS_PATH. Thus, mark the paths are
877 * That will trigger both these paths to get into the
885 "%s: %s and %s are equal via multipath-relax",
886 pfx_buf
, new_buf
, exist_buf
);
887 } else if (new->peer
->sort
== BGP_PEER_IBGP
) {
888 if (aspath_cmp(new->attr
->aspath
,
889 exist
->attr
->aspath
)) {
894 "%s: %s and %s are equal via matching aspaths",
895 pfx_buf
, new_buf
, exist_buf
);
897 } else if (new->peer
->as
== exist
->peer
->as
) {
902 "%s: %s and %s are equal via same remote-as",
903 pfx_buf
, new_buf
, exist_buf
);
907 * TODO: If unequal cost ibgp multipath is enabled we can
908 * mark the paths as equal here instead of returning
913 "%s: %s wins over %s after IGP metric comparison",
914 pfx_buf
, new_buf
, exist_buf
);
917 "%s: %s loses to %s after IGP metric comparison",
918 pfx_buf
, new_buf
, exist_buf
);
923 /* 12. If both paths are external, prefer the path that was received
924 first (the oldest one). This step minimizes route-flap, since a
925 newer path won't displace an older one, even if it was the
926 preferred route based on the additional decision criteria below. */
927 if (!bgp_flag_check(bgp
, BGP_FLAG_COMPARE_ROUTER_ID
)
928 && new_sort
== BGP_PEER_EBGP
&& exist_sort
== BGP_PEER_EBGP
) {
929 if (CHECK_FLAG(new->flags
, BGP_PATH_SELECTED
)) {
932 "%s: %s wins over %s due to oldest external",
933 pfx_buf
, new_buf
, exist_buf
);
937 if (CHECK_FLAG(exist
->flags
, BGP_PATH_SELECTED
)) {
940 "%s: %s loses to %s due to oldest external",
941 pfx_buf
, new_buf
, exist_buf
);
946 /* 13. Router-ID comparision. */
947 /* If one of the paths is "stale", the corresponding peer router-id will
948 * be 0 and would always win over the other path. If originator id is
949 * used for the comparision, it will decide which path is better.
951 if (newattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
952 new_id
.s_addr
= newattr
->originator_id
.s_addr
;
954 new_id
.s_addr
= new->peer
->remote_id
.s_addr
;
955 if (existattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
956 exist_id
.s_addr
= existattr
->originator_id
.s_addr
;
958 exist_id
.s_addr
= exist
->peer
->remote_id
.s_addr
;
960 if (ntohl(new_id
.s_addr
) < ntohl(exist_id
.s_addr
)) {
963 "%s: %s wins over %s due to Router-ID comparison",
964 pfx_buf
, new_buf
, exist_buf
);
968 if (ntohl(new_id
.s_addr
) > ntohl(exist_id
.s_addr
)) {
971 "%s: %s loses to %s due to Router-ID comparison",
972 pfx_buf
, new_buf
, exist_buf
);
976 /* 14. Cluster length comparision. */
977 new_cluster
= BGP_CLUSTER_LIST_LENGTH(new->attr
);
978 exist_cluster
= BGP_CLUSTER_LIST_LENGTH(exist
->attr
);
980 if (new_cluster
< exist_cluster
) {
983 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
984 pfx_buf
, new_buf
, exist_buf
, new_cluster
,
989 if (new_cluster
> exist_cluster
) {
992 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
993 pfx_buf
, new_buf
, exist_buf
, new_cluster
,
998 /* 15. Neighbor address comparision. */
999 /* Do this only if neither path is "stale" as stale paths do not have
1000 * valid peer information (as the connection may or may not be up).
1002 if (CHECK_FLAG(exist
->flags
, BGP_PATH_STALE
)) {
1005 "%s: %s wins over %s due to latter path being STALE",
1006 pfx_buf
, new_buf
, exist_buf
);
1010 if (CHECK_FLAG(new->flags
, BGP_PATH_STALE
)) {
1013 "%s: %s loses to %s due to former path being STALE",
1014 pfx_buf
, new_buf
, exist_buf
);
1018 /* locally configured routes to advertise do not have su_remote */
1019 if (new->peer
->su_remote
== NULL
)
1021 if (exist
->peer
->su_remote
== NULL
)
1024 ret
= sockunion_cmp(new->peer
->su_remote
, exist
->peer
->su_remote
);
1029 "%s: %s loses to %s due to Neighor IP comparison",
1030 pfx_buf
, new_buf
, exist_buf
);
1037 "%s: %s wins over %s due to Neighor IP comparison",
1038 pfx_buf
, new_buf
, exist_buf
);
1043 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1044 pfx_buf
, new_buf
, exist_buf
);
1049 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1050 * is preferred, or 0 if they are the same (usually will only occur if
1051 * multipath is enabled
1052 * This version is compatible with */
1053 int bgp_path_info_cmp_compatible(struct bgp
*bgp
, struct bgp_path_info
*new,
1054 struct bgp_path_info
*exist
, char *pfx_buf
,
1055 afi_t afi
, safi_t safi
)
1059 ret
= bgp_path_info_cmp(bgp
, new, exist
, &paths_eq
, NULL
, 0, pfx_buf
,
1073 static enum filter_type
bgp_input_filter(struct peer
*peer
, struct prefix
*p
,
1074 struct attr
*attr
, afi_t afi
,
1077 struct bgp_filter
*filter
;
1079 filter
= &peer
->filter
[afi
][safi
];
1081 #define FILTER_EXIST_WARN(F, f, filter) \
1082 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1083 zlog_debug("%s: Could not find configured input %s-list %s!", \
1084 peer->host, #f, F##_IN_NAME(filter));
1086 if (DISTRIBUTE_IN_NAME(filter
)) {
1087 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
1089 if (access_list_apply(DISTRIBUTE_IN(filter
), p
) == FILTER_DENY
)
1093 if (PREFIX_LIST_IN_NAME(filter
)) {
1094 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
1096 if (prefix_list_apply(PREFIX_LIST_IN(filter
), p
) == PREFIX_DENY
)
1100 if (FILTER_LIST_IN_NAME(filter
)) {
1101 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
1103 if (as_list_apply(FILTER_LIST_IN(filter
), attr
->aspath
)
1108 return FILTER_PERMIT
;
1109 #undef FILTER_EXIST_WARN
1112 static enum filter_type
bgp_output_filter(struct peer
*peer
, struct prefix
*p
,
1113 struct attr
*attr
, afi_t afi
,
1116 struct bgp_filter
*filter
;
1118 filter
= &peer
->filter
[afi
][safi
];
1120 #define FILTER_EXIST_WARN(F, f, filter) \
1121 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1122 zlog_debug("%s: Could not find configured output %s-list %s!", \
1123 peer->host, #f, F##_OUT_NAME(filter));
1125 if (DISTRIBUTE_OUT_NAME(filter
)) {
1126 FILTER_EXIST_WARN(DISTRIBUTE
, distribute
, filter
);
1128 if (access_list_apply(DISTRIBUTE_OUT(filter
), p
) == FILTER_DENY
)
1132 if (PREFIX_LIST_OUT_NAME(filter
)) {
1133 FILTER_EXIST_WARN(PREFIX_LIST
, prefix
, filter
);
1135 if (prefix_list_apply(PREFIX_LIST_OUT(filter
), p
)
1140 if (FILTER_LIST_OUT_NAME(filter
)) {
1141 FILTER_EXIST_WARN(FILTER_LIST
, as
, filter
);
1143 if (as_list_apply(FILTER_LIST_OUT(filter
), attr
->aspath
)
1148 return FILTER_PERMIT
;
1149 #undef FILTER_EXIST_WARN
1152 /* If community attribute includes no_export then return 1. */
1153 static int bgp_community_filter(struct peer
*peer
, struct attr
*attr
)
1155 if (attr
->community
) {
1156 /* NO_ADVERTISE check. */
1157 if (community_include(attr
->community
, COMMUNITY_NO_ADVERTISE
))
1160 /* NO_EXPORT check. */
1161 if (peer
->sort
== BGP_PEER_EBGP
1162 && community_include(attr
->community
, COMMUNITY_NO_EXPORT
))
1165 /* NO_EXPORT_SUBCONFED check. */
1166 if (peer
->sort
== BGP_PEER_EBGP
1167 || peer
->sort
== BGP_PEER_CONFED
)
1168 if (community_include(attr
->community
,
1169 COMMUNITY_NO_EXPORT_SUBCONFED
))
1175 /* Route reflection loop check. */
1176 static int bgp_cluster_filter(struct peer
*peer
, struct attr
*attr
)
1178 struct in_addr cluster_id
;
1180 if (attr
->cluster
) {
1181 if (peer
->bgp
->config
& BGP_CONFIG_CLUSTER_ID
)
1182 cluster_id
= peer
->bgp
->cluster_id
;
1184 cluster_id
= peer
->bgp
->router_id
;
1186 if (cluster_loop_check(attr
->cluster
, cluster_id
))
1192 static int bgp_input_modifier(struct peer
*peer
, struct prefix
*p
,
1193 struct attr
*attr
, afi_t afi
, safi_t safi
,
1194 const char *rmap_name
)
1196 struct bgp_filter
*filter
;
1197 struct bgp_path_info rmap_path
;
1198 route_map_result_t ret
;
1199 struct route_map
*rmap
= NULL
;
1201 filter
= &peer
->filter
[afi
][safi
];
1203 /* Apply default weight value. */
1204 if (peer
->weight
[afi
][safi
])
1205 attr
->weight
= peer
->weight
[afi
][safi
];
1208 rmap
= route_map_lookup_by_name(rmap_name
);
1213 if (ROUTE_MAP_IN_NAME(filter
)) {
1214 rmap
= ROUTE_MAP_IN(filter
);
1221 /* Route map apply. */
1223 memset(&rmap_path
, 0, sizeof(struct bgp_path_info
));
1224 /* Duplicate current value to new strucutre for modification. */
1225 rmap_path
.peer
= peer
;
1226 rmap_path
.attr
= attr
;
1228 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_IN
);
1230 /* Apply BGP route map to the attribute. */
1231 ret
= route_map_apply(rmap
, p
, RMAP_BGP
, &rmap_path
);
1233 peer
->rmap_type
= 0;
1235 if (ret
== RMAP_DENYMATCH
)
1241 static int bgp_output_modifier(struct peer
*peer
, struct prefix
*p
,
1242 struct attr
*attr
, afi_t afi
, safi_t safi
,
1243 const char *rmap_name
)
1245 struct bgp_path_info rmap_path
;
1246 route_map_result_t ret
;
1247 struct route_map
*rmap
= NULL
;
1251 * So if we get to this point and have no rmap_name
1252 * we want to just show the output as it currently
1258 /* Apply default weight value. */
1259 if (peer
->weight
[afi
][safi
])
1260 attr
->weight
= peer
->weight
[afi
][safi
];
1262 rmap
= route_map_lookup_by_name(rmap_name
);
1265 * If we have a route map name and we do not find
1266 * the routemap that means we have an implicit
1272 memset(&rmap_path
, 0, sizeof(struct bgp_path_info
));
1273 /* Route map apply. */
1274 /* Duplicate current value to new strucutre for modification. */
1275 rmap_path
.peer
= peer
;
1276 rmap_path
.attr
= attr
;
1278 rmap_type
= peer
->rmap_type
;
1279 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1281 /* Apply BGP route map to the attribute. */
1282 ret
= route_map_apply(rmap
, p
, RMAP_BGP
, &rmap_path
);
1284 peer
->rmap_type
= rmap_type
;
1286 if (ret
== RMAP_DENYMATCH
)
1288 * caller has multiple error paths with bgp_attr_flush()
1295 /* If this is an EBGP peer with remove-private-AS */
1296 static void bgp_peer_remove_private_as(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1297 struct peer
*peer
, struct attr
*attr
)
1299 if (peer
->sort
== BGP_PEER_EBGP
1300 && (peer_af_flag_check(peer
, afi
, safi
,
1301 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)
1302 || peer_af_flag_check(peer
, afi
, safi
,
1303 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
)
1304 || peer_af_flag_check(peer
, afi
, safi
,
1305 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)
1306 || peer_af_flag_check(peer
, afi
, safi
,
1307 PEER_FLAG_REMOVE_PRIVATE_AS
))) {
1308 // Take action on the entire aspath
1309 if (peer_af_flag_check(peer
, afi
, safi
,
1310 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
)
1311 || peer_af_flag_check(peer
, afi
, safi
,
1312 PEER_FLAG_REMOVE_PRIVATE_AS_ALL
)) {
1313 if (peer_af_flag_check(
1315 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
))
1316 attr
->aspath
= aspath_replace_private_asns(
1317 attr
->aspath
, bgp
->as
);
1319 // The entire aspath consists of private ASNs so create
1321 else if (aspath_private_as_check(attr
->aspath
))
1322 attr
->aspath
= aspath_empty_get();
1324 // There are some public and some private ASNs, remove
1327 attr
->aspath
= aspath_remove_private_asns(
1331 // 'all' was not specified so the entire aspath must be private
1333 // for us to do anything
1334 else if (aspath_private_as_check(attr
->aspath
)) {
1335 if (peer_af_flag_check(
1337 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
))
1338 attr
->aspath
= aspath_replace_private_asns(
1339 attr
->aspath
, bgp
->as
);
1341 attr
->aspath
= aspath_empty_get();
1346 /* If this is an EBGP peer with as-override */
1347 static void bgp_peer_as_override(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
1348 struct peer
*peer
, struct attr
*attr
)
1350 if (peer
->sort
== BGP_PEER_EBGP
1351 && peer_af_flag_check(peer
, afi
, safi
, PEER_FLAG_AS_OVERRIDE
)) {
1352 if (aspath_single_asn_check(attr
->aspath
, peer
->as
))
1353 attr
->aspath
= aspath_replace_specific_asn(
1354 attr
->aspath
, peer
->as
, bgp
->as
);
1358 void bgp_attr_add_gshut_community(struct attr
*attr
)
1360 struct community
*old
;
1361 struct community
*new;
1362 struct community
*merge
;
1363 struct community
*gshut
;
1365 old
= attr
->community
;
1366 gshut
= community_str2com("graceful-shutdown");
1371 merge
= community_merge(community_dup(old
), gshut
);
1373 if (old
->refcnt
== 0)
1374 community_free(&old
);
1376 new = community_uniq_sort(merge
);
1377 community_free(&merge
);
1379 new = community_dup(gshut
);
1382 community_free(&gshut
);
1383 attr
->community
= new;
1384 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES
);
1386 /* When we add the graceful-shutdown community we must also
1387 * lower the local-preference */
1388 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1389 attr
->local_pref
= BGP_GSHUT_LOCAL_PREF
;
1393 static void subgroup_announce_reset_nhop(uint8_t family
, struct attr
*attr
)
1395 if (family
== AF_INET
) {
1396 attr
->nexthop
.s_addr
= 0;
1397 attr
->mp_nexthop_global_in
.s_addr
= 0;
1399 if (family
== AF_INET6
)
1400 memset(&attr
->mp_nexthop_global
, 0, IPV6_MAX_BYTELEN
);
1401 if (family
== AF_EVPN
)
1402 memset(&attr
->mp_nexthop_global_in
, 0, BGP_ATTR_NHLEN_IPV4
);
1405 int subgroup_announce_check(struct bgp_node
*rn
, struct bgp_path_info
*pi
,
1406 struct update_subgroup
*subgrp
, struct prefix
*p
,
1409 struct bgp_filter
*filter
;
1412 struct peer
*onlypeer
;
1414 struct attr
*piattr
;
1415 char buf
[PREFIX_STRLEN
];
1421 int samepeer_safe
= 0; /* for synthetic mplsvpns routes */
1423 if (DISABLE_BGP_ANNOUNCE
)
1426 afi
= SUBGRP_AFI(subgrp
);
1427 safi
= SUBGRP_SAFI(subgrp
);
1428 peer
= SUBGRP_PEER(subgrp
);
1430 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_LONESOUL
))
1431 onlypeer
= SUBGRP_PFIRST(subgrp
)->peer
;
1434 filter
= &peer
->filter
[afi
][safi
];
1435 bgp
= SUBGRP_INST(subgrp
);
1436 piattr
= bgp_path_info_mpath_count(pi
) ? bgp_path_info_mpath_attr(pi
)
1440 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
)) && (safi
== SAFI_MPLS_VPN
)
1441 && ((pi
->type
== ZEBRA_ROUTE_BGP_DIRECT
)
1442 || (pi
->type
== ZEBRA_ROUTE_BGP_DIRECT_EXT
))) {
1445 * direct and direct_ext type routes originate internally even
1446 * though they can have peer pointers that reference other
1449 prefix2str(p
, buf
, PREFIX_STRLEN
);
1450 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe",
1456 if (((afi
== AFI_IP
) || (afi
== AFI_IP6
))
1457 && ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_UNICAST
))
1458 && (pi
->type
== ZEBRA_ROUTE_BGP
)
1459 && (pi
->sub_type
== BGP_ROUTE_IMPORTED
)) {
1461 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1466 /* With addpath we may be asked to TX all kinds of paths so make sure
1468 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_VALID
)
1469 || CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
)
1470 || CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)) {
1474 /* If this is not the bestpath then check to see if there is an enabled
1476 * feature that requires us to advertise it */
1477 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)) {
1478 if (!bgp_addpath_tx_path(peer
->addpath_type
[afi
][safi
], pi
)) {
1483 /* Aggregate-address suppress check. */
1484 if (pi
->extra
&& pi
->extra
->suppress
)
1485 if (!UNSUPPRESS_MAP_NAME(filter
)) {
1490 * If we are doing VRF 2 VRF leaking via the import
1491 * statement, we want to prevent the route going
1492 * off box as that the RT and RD created are localy
1493 * significant and globaly useless.
1495 if (safi
== SAFI_MPLS_VPN
&& pi
->extra
&& pi
->extra
->num_labels
1496 && pi
->extra
->label
[0] == BGP_PREVENT_VRF_2_VRF_LEAK
)
1499 /* If it's labeled safi, make sure the route has a valid label. */
1500 if (safi
== SAFI_LABELED_UNICAST
) {
1501 mpls_label_t label
= bgp_adv_label(rn
, pi
, peer
, afi
, safi
);
1502 if (!bgp_is_valid_label(&label
)) {
1503 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1504 zlog_debug("u%" PRIu64
":s%" PRIu64
1505 " %s/%d is filtered - no label (%p)",
1506 subgrp
->update_group
->id
, subgrp
->id
,
1507 inet_ntop(p
->family
, &p
->u
.prefix
,
1508 buf
, SU_ADDRSTRLEN
),
1509 p
->prefixlen
, &label
);
1514 /* Do not send back route to sender. */
1515 if (onlypeer
&& from
== onlypeer
) {
1519 /* Do not send the default route in the BGP table if the neighbor is
1520 * configured for default-originate */
1521 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1522 PEER_FLAG_DEFAULT_ORIGINATE
)) {
1523 if (p
->family
== AF_INET
&& p
->u
.prefix4
.s_addr
== INADDR_ANY
)
1525 else if (p
->family
== AF_INET6
&& p
->prefixlen
== 0)
1529 /* Transparency check. */
1530 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
)
1531 && CHECK_FLAG(from
->af_flags
[afi
][safi
], PEER_FLAG_RSERVER_CLIENT
))
1536 /* If community is not disabled check the no-export and local. */
1537 if (!transparent
&& bgp_community_filter(peer
, piattr
)) {
1538 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1540 "subgrpannouncecheck: community filter check fail");
1544 /* If the attribute has originator-id and it is same as remote
1546 if (onlypeer
&& piattr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)
1547 && (IPV4_ADDR_SAME(&onlypeer
->remote_id
, &piattr
->originator_id
))) {
1548 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1550 "%s [Update:SEND] %s originator-id is same as "
1553 prefix2str(p
, buf
, sizeof(buf
)));
1557 /* ORF prefix-list filter check */
1558 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_RM_ADV
)
1559 && (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ORF_PREFIX_SM_RCV
)
1560 || CHECK_FLAG(peer
->af_cap
[afi
][safi
],
1561 PEER_CAP_ORF_PREFIX_SM_OLD_RCV
)))
1562 if (peer
->orf_plist
[afi
][safi
]) {
1563 if (prefix_list_apply(peer
->orf_plist
[afi
][safi
], p
)
1565 if (bgp_debug_update(NULL
, p
,
1566 subgrp
->update_group
, 0))
1568 "%s [Update:SEND] %s is filtered via ORF",
1576 /* Output filter check. */
1577 if (bgp_output_filter(peer
, p
, piattr
, afi
, safi
) == FILTER_DENY
) {
1578 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1579 zlog_debug("%s [Update:SEND] %s is filtered",
1580 peer
->host
, prefix2str(p
, buf
, sizeof(buf
)));
1584 #ifdef BGP_SEND_ASPATH_CHECK
1585 /* AS path loop check. */
1586 if (onlypeer
&& aspath_loop_check(piattr
->aspath
, onlypeer
->as
)) {
1587 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1589 "%s [Update:SEND] suppress announcement to peer AS %u "
1590 "that is part of AS path.",
1591 onlypeer
->host
, onlypeer
->as
);
1594 #endif /* BGP_SEND_ASPATH_CHECK */
1596 /* If we're a CONFED we need to loop check the CONFED ID too */
1597 if (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)) {
1598 if (aspath_loop_check(piattr
->aspath
, bgp
->confed_id
)) {
1599 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1601 "%s [Update:SEND] suppress announcement to peer AS %u"
1603 peer
->host
, bgp
->confed_id
);
1608 /* Route-Reflect check. */
1609 if (from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1614 /* IBGP reflection check. */
1615 if (reflect
&& !samepeer_safe
) {
1616 /* A route from a Client peer. */
1617 if (CHECK_FLAG(from
->af_flags
[afi
][safi
],
1618 PEER_FLAG_REFLECTOR_CLIENT
)) {
1619 /* Reflect to all the Non-Client peers and also to the
1620 Client peers other than the originator. Originator
1622 is already done. So there is noting to do. */
1623 /* no bgp client-to-client reflection check. */
1624 if (bgp_flag_check(bgp
, BGP_FLAG_NO_CLIENT_TO_CLIENT
))
1625 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1626 PEER_FLAG_REFLECTOR_CLIENT
))
1629 /* A route from a Non-client peer. Reflect to all other
1631 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1632 PEER_FLAG_REFLECTOR_CLIENT
))
1637 /* For modify attribute, copy it to temporary structure. */
1638 bgp_attr_dup(attr
, piattr
);
1640 /* If local-preference is not set. */
1641 if ((peer
->sort
== BGP_PEER_IBGP
|| peer
->sort
== BGP_PEER_CONFED
)
1642 && (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)))) {
1643 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1644 attr
->local_pref
= bgp
->default_local_pref
;
1647 /* If originator-id is not set and the route is to be reflected,
1648 set the originator id */
1650 && (!(attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)))) {
1651 IPV4_ADDR_COPY(&(attr
->originator_id
), &(from
->remote_id
));
1652 SET_FLAG(attr
->flag
, BGP_ATTR_ORIGINATOR_ID
);
1655 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
1657 if (peer
->sort
== BGP_PEER_EBGP
1658 && attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)) {
1659 if (from
!= bgp
->peer_self
&& !transparent
1660 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1661 PEER_FLAG_MED_UNCHANGED
))
1663 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
));
1666 /* Since the nexthop attribute can vary per peer, it is not explicitly
1668 * in announce check, only certain flags and length (or number of
1670 * -- for IPv6/MP_REACH) are set here in order to guide the update
1672 * code in setting the nexthop(s) on a per peer basis in
1674 * Typically, the source nexthop in the attribute is preserved but in
1676 * scenarios where we know it will always be overwritten, we reset the
1677 * nexthop to "0" in an attempt to achieve better Update packing. An
1678 * example of this is when a prefix from each of 2 IBGP peers needs to
1680 * announced to an EBGP peer (and they have the same attributes barring
1684 SET_FLAG(attr
->rmap_change_flags
, BATTR_REFLECTED
);
1686 #define NEXTHOP_IS_V6 \
1687 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
1688 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
1689 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
1690 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1692 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
1694 * the peer (group) is configured to receive link-local nexthop
1696 * and it is available in the prefix OR we're not reflecting the route
1698 * the peer (group) to whom we're going to announce is on a shared
1700 * and this is either a self-originated route or the peer is EBGP.
1702 if (NEXTHOP_IS_V6
) {
1703 attr
->mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
1704 if ((CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1705 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)
1706 && IN6_IS_ADDR_LINKLOCAL(&attr
->mp_nexthop_local
))
1707 || (!reflect
&& peer
->shared_network
1708 && (from
== bgp
->peer_self
1709 || peer
->sort
== BGP_PEER_EBGP
))) {
1710 attr
->mp_nexthop_len
=
1711 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
;
1714 /* Clear off link-local nexthop in source, whenever it is not
1716 * ensure more prefixes share the same attribute for
1719 if (!(CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1720 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED
)))
1721 memset(&attr
->mp_nexthop_local
, 0, IPV6_MAX_BYTELEN
);
1724 bgp_peer_remove_private_as(bgp
, afi
, safi
, peer
, attr
);
1725 bgp_peer_as_override(bgp
, afi
, safi
, peer
, attr
);
1727 /* Route map & unsuppress-map apply. */
1728 if (ROUTE_MAP_OUT_NAME(filter
) || (pi
->extra
&& pi
->extra
->suppress
)) {
1729 struct bgp_path_info rmap_path
;
1730 struct bgp_path_info_extra dummy_rmap_path_extra
;
1731 struct attr dummy_attr
;
1733 memset(&rmap_path
, 0, sizeof(struct bgp_path_info
));
1734 rmap_path
.peer
= peer
;
1735 rmap_path
.attr
= attr
;
1738 memcpy(&dummy_rmap_path_extra
, pi
->extra
,
1739 sizeof(struct bgp_path_info_extra
));
1740 rmap_path
.extra
= &dummy_rmap_path_extra
;
1743 /* don't confuse inbound and outbound setting */
1744 RESET_FLAG(attr
->rmap_change_flags
);
1747 * The route reflector is not allowed to modify the attributes
1748 * of the reflected IBGP routes unless explicitly allowed.
1750 if ((from
->sort
== BGP_PEER_IBGP
&& peer
->sort
== BGP_PEER_IBGP
)
1751 && !bgp_flag_check(bgp
,
1752 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY
)) {
1753 bgp_attr_dup(&dummy_attr
, attr
);
1754 rmap_path
.attr
= &dummy_attr
;
1757 SET_FLAG(peer
->rmap_type
, PEER_RMAP_TYPE_OUT
);
1759 if (pi
->extra
&& pi
->extra
->suppress
)
1760 ret
= route_map_apply(UNSUPPRESS_MAP(filter
), p
,
1761 RMAP_BGP
, &rmap_path
);
1763 ret
= route_map_apply(ROUTE_MAP_OUT(filter
), p
,
1764 RMAP_BGP
, &rmap_path
);
1766 peer
->rmap_type
= 0;
1768 if (ret
== RMAP_DENYMATCH
) {
1769 bgp_attr_flush(attr
);
1774 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
)) {
1775 if (peer
->sort
== BGP_PEER_IBGP
1776 || peer
->sort
== BGP_PEER_CONFED
) {
1777 attr
->flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
1778 attr
->local_pref
= BGP_GSHUT_LOCAL_PREF
;
1780 bgp_attr_add_gshut_community(attr
);
1784 /* After route-map has been applied, we check to see if the nexthop to
1785 * be carried in the attribute (that is used for the announcement) can
1786 * be cleared off or not. We do this in all cases where we would be
1787 * setting the nexthop to "ourselves". For IPv6, we only need to
1789 * the global nexthop here; the link-local nexthop would have been
1791 * already, and if not, it is required by the update formation code.
1792 * Also see earlier comments in this function.
1795 * If route-map has performed some operation on the nexthop or the peer
1796 * configuration says to pass it unchanged, we cannot reset the nexthop
1797 * here, so only attempt to do it if these aren't true. Note that the
1798 * route-map handler itself might have cleared the nexthop, if for
1800 * it is configured as 'peer-address'.
1802 if (!bgp_rmap_nhop_changed(attr
->rmap_change_flags
,
1803 piattr
->rmap_change_flags
)
1805 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1806 PEER_FLAG_NEXTHOP_UNCHANGED
)) {
1807 /* We can reset the nexthop, if setting (or forcing) it to
1809 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1810 PEER_FLAG_NEXTHOP_SELF
)
1811 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1812 PEER_FLAG_FORCE_NEXTHOP_SELF
)) {
1814 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1815 PEER_FLAG_FORCE_NEXTHOP_SELF
))
1816 subgroup_announce_reset_nhop(
1817 (peer_cap_enhe(peer
, afi
, safi
)
1821 } else if (peer
->sort
== BGP_PEER_EBGP
) {
1822 /* Can also reset the nexthop if announcing to EBGP, but
1824 * no peer in the subgroup is on a shared subnet.
1825 * Note: 3rd party nexthop currently implemented for
1828 if (!bgp_subgrp_multiaccess_check_v4(piattr
->nexthop
,
1830 subgroup_announce_reset_nhop(
1831 (peer_cap_enhe(peer
, afi
, safi
)
1835 } else if (CHECK_FLAG(pi
->flags
, BGP_PATH_ANNC_NH_SELF
)) {
1837 * This flag is used for leaked vpn-vrf routes
1839 int family
= p
->family
;
1841 if (peer_cap_enhe(peer
, afi
, safi
))
1844 if (bgp_debug_update(NULL
, p
, subgrp
->update_group
, 0))
1846 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
1847 __func__
, family2str(family
));
1848 subgroup_announce_reset_nhop(family
, attr
);
1851 /* If IPv6/MP and nexthop does not have any override and happens
1853 * be a link-local address, reset it so that we don't pass along
1855 * source's link-local IPv6 address to recipients who may not be
1857 * the same interface.
1859 if (p
->family
== AF_INET6
|| peer_cap_enhe(peer
, afi
, safi
)) {
1860 if (IN6_IS_ADDR_LINKLOCAL(&attr
->mp_nexthop_global
))
1861 subgroup_announce_reset_nhop(AF_INET6
, attr
);
1868 void bgp_best_selection(struct bgp
*bgp
, struct bgp_node
*rn
,
1869 struct bgp_maxpaths_cfg
*mpath_cfg
,
1870 struct bgp_path_info_pair
*result
, afi_t afi
,
1873 struct bgp_path_info
*new_select
;
1874 struct bgp_path_info
*old_select
;
1875 struct bgp_path_info
*pi
;
1876 struct bgp_path_info
*pi1
;
1877 struct bgp_path_info
*pi2
;
1878 struct bgp_path_info
*nextpi
= NULL
;
1879 int paths_eq
, do_mpath
, debug
;
1880 struct list mp_list
;
1881 char pfx_buf
[PREFIX2STR_BUFFER
];
1882 char path_buf
[PATH_ADDPATH_STR_BUFFER
];
1884 bgp_mp_list_init(&mp_list
);
1886 (mpath_cfg
->maxpaths_ebgp
> 1 || mpath_cfg
->maxpaths_ibgp
> 1);
1888 debug
= bgp_debug_bestpath(&rn
->p
);
1891 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
1893 /* bgp deterministic-med */
1895 if (bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)) {
1897 /* Clear BGP_PATH_DMED_SELECTED for all paths */
1898 for (pi1
= rn
->info
; pi1
; pi1
= pi1
->next
)
1899 bgp_path_info_unset_flag(rn
, pi1
,
1900 BGP_PATH_DMED_SELECTED
);
1902 for (pi1
= rn
->info
; pi1
; pi1
= pi1
->next
) {
1903 if (CHECK_FLAG(pi1
->flags
, BGP_PATH_DMED_CHECK
))
1905 if (BGP_PATH_HOLDDOWN(pi1
))
1907 if (pi1
->peer
&& pi1
->peer
!= bgp
->peer_self
)
1908 if (pi1
->peer
->status
!= Established
)
1913 for (pi2
= pi1
->next
; pi2
; pi2
= pi2
->next
) {
1914 if (CHECK_FLAG(pi2
->flags
,
1915 BGP_PATH_DMED_CHECK
))
1917 if (BGP_PATH_HOLDDOWN(pi2
))
1920 && pi2
->peer
!= bgp
->peer_self
1923 PEER_STATUS_NSF_WAIT
))
1924 if (pi2
->peer
->status
1928 if (!aspath_cmp_left(pi1
->attr
->aspath
,
1930 && !aspath_cmp_left_confed(
1935 if (bgp_path_info_cmp(
1936 bgp
, pi2
, new_select
,
1937 &paths_eq
, mpath_cfg
, debug
,
1938 pfx_buf
, afi
, safi
)) {
1939 bgp_path_info_unset_flag(
1941 BGP_PATH_DMED_SELECTED
);
1945 bgp_path_info_set_flag(
1946 rn
, pi2
, BGP_PATH_DMED_CHECK
);
1949 bgp_path_info_set_flag(rn
, new_select
,
1950 BGP_PATH_DMED_CHECK
);
1951 bgp_path_info_set_flag(rn
, new_select
,
1952 BGP_PATH_DMED_SELECTED
);
1955 bgp_path_info_path_with_addpath_rx_str(
1956 new_select
, path_buf
);
1957 zlog_debug("%s: %s is the bestpath from AS %u",
1959 aspath_get_first_as(
1960 new_select
->attr
->aspath
));
1965 /* Check old selected route and new selected route. */
1968 for (pi
= rn
->info
; (pi
!= NULL
) && (nextpi
= pi
->next
, 1);
1970 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
))
1973 if (BGP_PATH_HOLDDOWN(pi
)) {
1974 /* reap REMOVED routes, if needs be
1975 * selected route must stay for a while longer though
1977 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)
1978 && (pi
!= old_select
))
1979 bgp_path_info_reap(rn
, pi
);
1982 zlog_debug("%s: pi %p in holddown", __func__
,
1988 if (pi
->peer
&& pi
->peer
!= bgp
->peer_self
1989 && !CHECK_FLAG(pi
->peer
->sflags
, PEER_STATUS_NSF_WAIT
))
1990 if (pi
->peer
->status
!= Established
) {
1994 "%s: pi %p non self peer %s not estab state",
1995 __func__
, pi
, pi
->peer
->host
);
2000 if (bgp_flag_check(bgp
, BGP_FLAG_DETERMINISTIC_MED
)
2001 && (!CHECK_FLAG(pi
->flags
, BGP_PATH_DMED_SELECTED
))) {
2002 bgp_path_info_unset_flag(rn
, pi
, BGP_PATH_DMED_CHECK
);
2004 zlog_debug("%s: pi %p dmed", __func__
, pi
);
2008 bgp_path_info_unset_flag(rn
, pi
, BGP_PATH_DMED_CHECK
);
2010 if (bgp_path_info_cmp(bgp
, pi
, new_select
, &paths_eq
, mpath_cfg
,
2011 debug
, pfx_buf
, afi
, safi
)) {
2016 /* Now that we know which path is the bestpath see if any of the other
2018 * qualify as multipaths
2022 bgp_path_info_path_with_addpath_rx_str(new_select
,
2025 sprintf(path_buf
, "NONE");
2027 "%s: After path selection, newbest is %s oldbest was %s",
2029 old_select
? old_select
->peer
->host
: "NONE");
2032 if (do_mpath
&& new_select
) {
2033 for (pi
= rn
->info
; (pi
!= NULL
) && (nextpi
= pi
->next
, 1);
2037 bgp_path_info_path_with_addpath_rx_str(
2040 if (pi
== new_select
) {
2043 "%s: %s is the bestpath, add to the multipath list",
2045 bgp_mp_list_add(&mp_list
, pi
);
2049 if (BGP_PATH_HOLDDOWN(pi
))
2052 if (pi
->peer
&& pi
->peer
!= bgp
->peer_self
2053 && !CHECK_FLAG(pi
->peer
->sflags
,
2054 PEER_STATUS_NSF_WAIT
))
2055 if (pi
->peer
->status
!= Established
)
2058 if (!bgp_path_info_nexthop_cmp(pi
, new_select
)) {
2061 "%s: %s has the same nexthop as the bestpath, skip it",
2066 bgp_path_info_cmp(bgp
, pi
, new_select
, &paths_eq
,
2067 mpath_cfg
, debug
, pfx_buf
, afi
, safi
);
2072 "%s: %s is equivalent to the bestpath, add to the multipath list",
2074 bgp_mp_list_add(&mp_list
, pi
);
2079 bgp_path_info_mpath_update(rn
, new_select
, old_select
, &mp_list
,
2081 bgp_path_info_mpath_aggregate_update(new_select
, old_select
);
2082 bgp_mp_list_clear(&mp_list
);
2084 bgp_addpath_update_ids(bgp
, rn
, afi
, safi
);
2086 result
->old
= old_select
;
2087 result
->new = new_select
;
2093 * A new route/change in bestpath of an existing route. Evaluate the path
2094 * for advertisement to the subgroup.
2096 int subgroup_process_announce_selected(struct update_subgroup
*subgrp
,
2097 struct bgp_path_info
*selected
,
2098 struct bgp_node
*rn
,
2099 uint32_t addpath_tx_id
)
2102 struct peer
*onlypeer
;
2108 afi
= SUBGRP_AFI(subgrp
);
2109 safi
= SUBGRP_SAFI(subgrp
);
2110 onlypeer
= ((SUBGRP_PCOUNT(subgrp
) == 1) ? (SUBGRP_PFIRST(subgrp
))->peer
2113 if (BGP_DEBUG(update
, UPDATE_OUT
)) {
2114 char buf_prefix
[PREFIX_STRLEN
];
2115 prefix2str(p
, buf_prefix
, sizeof(buf_prefix
));
2116 zlog_debug("%s: p=%s, selected=%p", __func__
, buf_prefix
,
2120 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2121 if (onlypeer
&& CHECK_FLAG(onlypeer
->af_sflags
[afi
][safi
],
2122 PEER_STATUS_ORF_WAIT_REFRESH
))
2125 memset(&attr
, 0, sizeof(struct attr
));
2126 /* It's initialized in bgp_announce_check() */
2128 /* Announcement to the subgroup. If the route is filtered withdraw it.
2131 if (subgroup_announce_check(rn
, selected
, subgrp
, p
, &attr
))
2132 bgp_adj_out_set_subgroup(rn
, subgrp
, &attr
, selected
);
2134 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1,
2138 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2140 bgp_adj_out_unset_subgroup(rn
, subgrp
, 1, addpath_tx_id
);
2147 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2148 * This is called at the end of route processing.
2150 void bgp_zebra_clear_route_change_flags(struct bgp_node
*rn
)
2152 struct bgp_path_info
*pi
;
2154 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
2155 if (BGP_PATH_HOLDDOWN(pi
))
2157 UNSET_FLAG(pi
->flags
, BGP_PATH_IGP_CHANGED
);
2158 UNSET_FLAG(pi
->flags
, BGP_PATH_ATTR_CHANGED
);
2163 * Has the route changed from the RIB's perspective? This is invoked only
2164 * if the route selection returns the same best route as earlier - to
2165 * determine if we need to update zebra or not.
2167 int bgp_zebra_has_route_changed(struct bgp_node
*rn
,
2168 struct bgp_path_info
*selected
)
2170 struct bgp_path_info
*mpinfo
;
2172 /* If this is multipath, check all selected paths for any nexthop
2173 * change or attribute change. Some attribute changes (e.g., community)
2174 * aren't of relevance to the RIB, but we'll update zebra to ensure
2175 * we handle the case of BGP nexthop change. This is the behavior
2176 * when the best path has an attribute change anyway.
2178 if (CHECK_FLAG(selected
->flags
, BGP_PATH_IGP_CHANGED
)
2179 || CHECK_FLAG(selected
->flags
, BGP_PATH_MULTIPATH_CHG
))
2183 * If this is multipath, check all selected paths for any nexthop change
2185 for (mpinfo
= bgp_path_info_mpath_first(selected
); mpinfo
;
2186 mpinfo
= bgp_path_info_mpath_next(mpinfo
)) {
2187 if (CHECK_FLAG(mpinfo
->flags
, BGP_PATH_IGP_CHANGED
)
2188 || CHECK_FLAG(mpinfo
->flags
, BGP_PATH_ATTR_CHANGED
))
2192 /* Nothing has changed from the RIB's perspective. */
2196 struct bgp_process_queue
{
2198 STAILQ_HEAD(, bgp_node
) pqueue
;
2199 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2201 unsigned int queued
;
2205 * old_select = The old best path
2206 * new_select = the new best path
2208 * if (!old_select && new_select)
2209 * We are sending new information on.
2211 * if (old_select && new_select) {
2212 * if (new_select != old_select)
2213 * We have a new best path send a change
2215 * We've received a update with new attributes that needs
2219 * if (old_select && !new_select)
2220 * We have no eligible route that we can announce or the rn
2223 static void bgp_process_main_one(struct bgp
*bgp
, struct bgp_node
*rn
,
2224 afi_t afi
, safi_t safi
)
2226 struct bgp_path_info
*new_select
;
2227 struct bgp_path_info
*old_select
;
2228 struct bgp_path_info_pair old_and_new
;
2229 char pfx_buf
[PREFIX2STR_BUFFER
];
2232 /* Is it end of initial update? (after startup) */
2234 quagga_timestamp(3, bgp
->update_delay_zebra_resume_time
,
2235 sizeof(bgp
->update_delay_zebra_resume_time
));
2237 bgp
->main_zebra_update_hold
= 0;
2238 FOREACH_AFI_SAFI (afi
, safi
) {
2239 if (bgp_fibupd_safi(safi
))
2240 bgp_zebra_announce_table(bgp
, afi
, safi
);
2242 bgp
->main_peers_update_hold
= 0;
2244 bgp_start_routeadv(bgp
);
2248 struct prefix
*p
= &rn
->p
;
2250 debug
= bgp_debug_bestpath(&rn
->p
);
2252 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
2253 zlog_debug("%s: p=%s afi=%s, safi=%s start", __func__
, pfx_buf
,
2254 afi2str(afi
), safi2str(safi
));
2257 /* Best path selection. */
2258 bgp_best_selection(bgp
, rn
, &bgp
->maxpaths
[afi
][safi
], &old_and_new
,
2260 old_select
= old_and_new
.old
;
2261 new_select
= old_and_new
.new;
2263 /* Do we need to allocate or free labels?
2264 * Right now, since we only deal with per-prefix labels, it is not
2265 * necessary to do this upon changes to best path except if the label
2268 if (bgp
->allocate_mpls_labels
[afi
][safi
]) {
2271 || bgp_label_index_differs(new_select
, old_select
)
2272 || new_select
->sub_type
!= old_select
->sub_type
) {
2273 if (new_select
->sub_type
== BGP_ROUTE_STATIC
2274 && new_select
->attr
->flag
2276 BGP_ATTR_PREFIX_SID
)
2277 && new_select
->attr
->label_index
2278 != BGP_INVALID_LABEL_INDEX
) {
2281 BGP_NODE_REGISTERED_FOR_LABEL
))
2282 bgp_unregister_for_label(rn
);
2283 label_ntop(MPLS_LABEL_IMPLICIT_NULL
, 1,
2285 bgp_set_valid_label(&rn
->local_label
);
2287 bgp_register_for_label(rn
, new_select
);
2289 } else if (CHECK_FLAG(rn
->flags
,
2290 BGP_NODE_REGISTERED_FOR_LABEL
)) {
2291 bgp_unregister_for_label(rn
);
2293 } else if (CHECK_FLAG(rn
->flags
, BGP_NODE_REGISTERED_FOR_LABEL
)) {
2294 bgp_unregister_for_label(rn
);
2298 prefix2str(&rn
->p
, pfx_buf
, sizeof(pfx_buf
));
2300 "%s: p=%s afi=%s, safi=%s, old_select=%p, new_select=%p",
2301 __func__
, pfx_buf
, afi2str(afi
), safi2str(safi
),
2302 old_select
, new_select
);
2305 /* If best route remains the same and this is not due to user-initiated
2306 * clear, see exactly what needs to be done.
2308 if (old_select
&& old_select
== new_select
2309 && !CHECK_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
)
2310 && !CHECK_FLAG(old_select
->flags
, BGP_PATH_ATTR_CHANGED
)
2311 && !bgp_addpath_is_addpath_used(&bgp
->tx_addpath
, afi
, safi
)) {
2312 if (bgp_zebra_has_route_changed(rn
, old_select
)) {
2314 vnc_import_bgp_add_route(bgp
, p
, old_select
);
2315 vnc_import_bgp_exterior_add_route(bgp
, p
, old_select
);
2317 if (bgp_fibupd_safi(safi
)
2318 && !bgp_option_check(BGP_OPT_NO_FIB
)) {
2320 if (new_select
->type
== ZEBRA_ROUTE_BGP
2321 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
2322 || new_select
->sub_type
2323 == BGP_ROUTE_IMPORTED
))
2325 bgp_zebra_announce(rn
, p
, old_select
,
2329 UNSET_FLAG(old_select
->flags
, BGP_PATH_MULTIPATH_CHG
);
2330 bgp_zebra_clear_route_change_flags(rn
);
2332 /* If there is a change of interest to peers, reannounce the
2334 if (CHECK_FLAG(old_select
->flags
, BGP_PATH_ATTR_CHANGED
)
2335 || CHECK_FLAG(rn
->flags
, BGP_NODE_LABEL_CHANGED
)) {
2336 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2338 /* unicast routes must also be annouced to
2339 * labeled-unicast update-groups */
2340 if (safi
== SAFI_UNICAST
)
2341 group_announce_route(bgp
, afi
,
2342 SAFI_LABELED_UNICAST
, rn
,
2345 UNSET_FLAG(old_select
->flags
, BGP_PATH_ATTR_CHANGED
);
2346 UNSET_FLAG(rn
->flags
, BGP_NODE_LABEL_CHANGED
);
2349 UNSET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2353 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2355 UNSET_FLAG(rn
->flags
, BGP_NODE_USER_CLEAR
);
2357 /* bestpath has changed; bump version */
2358 if (old_select
|| new_select
) {
2359 bgp_bump_version(rn
);
2361 if (!bgp
->t_rmap_def_originate_eval
) {
2365 update_group_refresh_default_originate_route_map
,
2366 bgp
, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER
,
2367 &bgp
->t_rmap_def_originate_eval
);
2372 bgp_path_info_unset_flag(rn
, old_select
, BGP_PATH_SELECTED
);
2375 zlog_debug("%s: setting SELECTED flag", __func__
);
2376 bgp_path_info_set_flag(rn
, new_select
, BGP_PATH_SELECTED
);
2377 bgp_path_info_unset_flag(rn
, new_select
, BGP_PATH_ATTR_CHANGED
);
2378 UNSET_FLAG(new_select
->flags
, BGP_PATH_MULTIPATH_CHG
);
2382 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2383 if (old_select
!= new_select
) {
2385 vnc_import_bgp_exterior_del_route(bgp
, p
,
2387 vnc_import_bgp_del_route(bgp
, p
, old_select
);
2390 vnc_import_bgp_exterior_add_route(bgp
, p
,
2392 vnc_import_bgp_add_route(bgp
, p
, new_select
);
2398 group_announce_route(bgp
, afi
, safi
, rn
, new_select
);
2400 /* unicast routes must also be annouced to labeled-unicast update-groups
2402 if (safi
== SAFI_UNICAST
)
2403 group_announce_route(bgp
, afi
, SAFI_LABELED_UNICAST
, rn
,
2407 if (bgp_fibupd_safi(safi
) && (bgp
->inst_type
!= BGP_INSTANCE_TYPE_VIEW
)
2408 && !bgp_option_check(BGP_OPT_NO_FIB
)) {
2409 if (new_select
&& new_select
->type
== ZEBRA_ROUTE_BGP
2410 && (new_select
->sub_type
== BGP_ROUTE_NORMAL
2411 || new_select
->sub_type
== BGP_ROUTE_AGGREGATE
2412 || new_select
->sub_type
== BGP_ROUTE_IMPORTED
)) {
2414 /* if this is an evpn imported type-5 prefix,
2415 * we need to withdraw the route first to clear
2416 * the nh neigh and the RMAC entry.
2419 is_route_parent_evpn(old_select
))
2420 bgp_zebra_withdraw(p
, old_select
, bgp
, safi
);
2422 bgp_zebra_announce(rn
, p
, new_select
, bgp
, afi
, safi
);
2424 /* Withdraw the route from the kernel. */
2425 if (old_select
&& old_select
->type
== ZEBRA_ROUTE_BGP
2426 && (old_select
->sub_type
== BGP_ROUTE_NORMAL
2427 || old_select
->sub_type
== BGP_ROUTE_AGGREGATE
2428 || old_select
->sub_type
== BGP_ROUTE_IMPORTED
))
2430 bgp_zebra_withdraw(p
, old_select
, bgp
, safi
);
2434 /* advertise/withdraw type-5 routes */
2435 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2436 if (advertise_type5_routes(bgp
, afi
) && new_select
&&
2437 (!new_select
->extra
|| !new_select
->extra
->parent
)) {
2439 /* apply the route-map */
2440 if (bgp
->adv_cmd_rmap
[afi
][safi
].map
) {
2443 ret
= route_map_apply(
2444 bgp
->adv_cmd_rmap
[afi
][safi
].map
,
2445 &rn
->p
, RMAP_BGP
, new_select
);
2446 if (ret
== RMAP_MATCH
)
2447 bgp_evpn_advertise_type5_route(
2448 bgp
, &rn
->p
, new_select
->attr
,
2451 bgp_evpn_advertise_type5_route(bgp
,
2457 } else if (advertise_type5_routes(bgp
, afi
) && old_select
&&
2458 (!old_select
->extra
|| !old_select
->extra
->parent
))
2459 bgp_evpn_withdraw_type5_route(bgp
, &rn
->p
, afi
, safi
);
2462 /* Clear any route change flags. */
2463 bgp_zebra_clear_route_change_flags(rn
);
2465 /* Reap old select bgp_path_info, if it has been removed */
2466 if (old_select
&& CHECK_FLAG(old_select
->flags
, BGP_PATH_REMOVED
))
2467 bgp_path_info_reap(rn
, old_select
);
2469 UNSET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2473 static wq_item_status
bgp_process_wq(struct work_queue
*wq
, void *data
)
2475 struct bgp_process_queue
*pqnode
= data
;
2476 struct bgp
*bgp
= pqnode
->bgp
;
2477 struct bgp_table
*table
;
2478 struct bgp_node
*rn
;
2481 if (CHECK_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
)) {
2482 bgp_process_main_one(bgp
, NULL
, 0, 0);
2483 /* should always have dedicated wq call */
2484 assert(STAILQ_FIRST(&pqnode
->pqueue
) == NULL
);
2488 while (!STAILQ_EMPTY(&pqnode
->pqueue
)) {
2489 rn
= STAILQ_FIRST(&pqnode
->pqueue
);
2490 STAILQ_REMOVE_HEAD(&pqnode
->pqueue
, pq
);
2491 STAILQ_NEXT(rn
, pq
) = NULL
; /* complete unlink */
2492 table
= bgp_node_table(rn
);
2493 /* note, new RNs may be added as part of processing */
2494 bgp_process_main_one(bgp
, rn
, table
->afi
, table
->safi
);
2496 bgp_unlock_node(rn
);
2497 bgp_table_unlock(table
);
2503 static void bgp_processq_del(struct work_queue
*wq
, void *data
)
2505 struct bgp_process_queue
*pqnode
= data
;
2507 bgp_unlock(pqnode
->bgp
);
2509 XFREE(MTYPE_BGP_PROCESS_QUEUE
, pqnode
);
2512 void bgp_process_queue_init(void)
2514 if (!bm
->process_main_queue
)
2515 bm
->process_main_queue
=
2516 work_queue_new(bm
->master
, "process_main_queue");
2518 bm
->process_main_queue
->spec
.workfunc
= &bgp_process_wq
;
2519 bm
->process_main_queue
->spec
.del_item_data
= &bgp_processq_del
;
2520 bm
->process_main_queue
->spec
.max_retries
= 0;
2521 bm
->process_main_queue
->spec
.hold
= 50;
2522 /* Use a higher yield value of 50ms for main queue processing */
2523 bm
->process_main_queue
->spec
.yield
= 50 * 1000L;
2526 static struct bgp_process_queue
*bgp_processq_alloc(struct bgp
*bgp
)
2528 struct bgp_process_queue
*pqnode
;
2530 pqnode
= XCALLOC(MTYPE_BGP_PROCESS_QUEUE
,
2531 sizeof(struct bgp_process_queue
));
2533 /* unlocked in bgp_processq_del */
2534 pqnode
->bgp
= bgp_lock(bgp
);
2535 STAILQ_INIT(&pqnode
->pqueue
);
2540 void bgp_process(struct bgp
*bgp
, struct bgp_node
*rn
, afi_t afi
, safi_t safi
)
2542 #define ARBITRARY_PROCESS_QLEN 10000
2543 struct work_queue
*wq
= bm
->process_main_queue
;
2544 struct bgp_process_queue
*pqnode
;
2545 int pqnode_reuse
= 0;
2547 /* already scheduled for processing? */
2548 if (CHECK_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
))
2554 /* Add route nodes to an existing work queue item until reaching the
2555 limit only if is from the same BGP view and it's not an EOIU marker
2557 if (work_queue_item_count(wq
)) {
2558 struct work_queue_item
*item
= work_queue_last_item(wq
);
2559 pqnode
= item
->data
;
2561 if (CHECK_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
)
2562 || pqnode
->bgp
!= bgp
2563 || pqnode
->queued
>= ARBITRARY_PROCESS_QLEN
)
2564 pqnode
= bgp_processq_alloc(bgp
);
2568 pqnode
= bgp_processq_alloc(bgp
);
2569 /* all unlocked in bgp_process_wq */
2570 bgp_table_lock(bgp_node_table(rn
));
2572 SET_FLAG(rn
->flags
, BGP_NODE_PROCESS_SCHEDULED
);
2575 /* can't be enqueued twice */
2576 assert(STAILQ_NEXT(rn
, pq
) == NULL
);
2577 STAILQ_INSERT_TAIL(&pqnode
->pqueue
, rn
, pq
);
2581 work_queue_add(wq
, pqnode
);
2586 void bgp_add_eoiu_mark(struct bgp
*bgp
)
2588 struct bgp_process_queue
*pqnode
;
2590 if (bm
->process_main_queue
== NULL
)
2593 pqnode
= bgp_processq_alloc(bgp
);
2595 SET_FLAG(pqnode
->flags
, BGP_PROCESS_QUEUE_EOIU_MARKER
);
2596 work_queue_add(bm
->process_main_queue
, pqnode
);
2599 static int bgp_maximum_prefix_restart_timer(struct thread
*thread
)
2603 peer
= THREAD_ARG(thread
);
2604 peer
->t_pmax_restart
= NULL
;
2606 if (bgp_debug_neighbor_events(peer
))
2608 "%s Maximum-prefix restart timer expired, restore peering",
2611 if ((peer_clear(peer
, NULL
) < 0) && bgp_debug_neighbor_events(peer
))
2612 zlog_debug("%s: %s peer_clear failed",
2613 __PRETTY_FUNCTION__
, peer
->host
);
2618 int bgp_maximum_prefix_overflow(struct peer
*peer
, afi_t afi
, safi_t safi
,
2622 iana_safi_t pkt_safi
;
2624 if (!CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_MAX_PREFIX
))
2627 if (peer
->pcount
[afi
][safi
] > peer
->pmax
[afi
][safi
]) {
2628 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2629 PEER_STATUS_PREFIX_LIMIT
)
2634 "%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2636 afi_safi_print(afi
, safi
), peer
->host
,
2637 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2638 SET_FLAG(peer
->af_sflags
[afi
][safi
], PEER_STATUS_PREFIX_LIMIT
);
2640 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
2641 PEER_FLAG_MAX_PREFIX_WARNING
))
2644 /* Convert AFI, SAFI to values for packet. */
2645 pkt_afi
= afi_int2iana(afi
);
2646 pkt_safi
= safi_int2iana(safi
);
2650 ndata
[0] = (pkt_afi
>> 8);
2652 ndata
[2] = pkt_safi
;
2653 ndata
[3] = (peer
->pmax
[afi
][safi
] >> 24);
2654 ndata
[4] = (peer
->pmax
[afi
][safi
] >> 16);
2655 ndata
[5] = (peer
->pmax
[afi
][safi
] >> 8);
2656 ndata
[6] = (peer
->pmax
[afi
][safi
]);
2658 SET_FLAG(peer
->sflags
, PEER_STATUS_PREFIX_OVERFLOW
);
2659 bgp_notify_send_with_data(peer
, BGP_NOTIFY_CEASE
,
2660 BGP_NOTIFY_CEASE_MAX_PREFIX
,
2664 /* Dynamic peers will just close their connection. */
2665 if (peer_dynamic_neighbor(peer
))
2668 /* restart timer start */
2669 if (peer
->pmax_restart
[afi
][safi
]) {
2670 peer
->v_pmax_restart
=
2671 peer
->pmax_restart
[afi
][safi
] * 60;
2673 if (bgp_debug_neighbor_events(peer
))
2675 "%s Maximum-prefix restart timer started for %d secs",
2676 peer
->host
, peer
->v_pmax_restart
);
2678 BGP_TIMER_ON(peer
->t_pmax_restart
,
2679 bgp_maximum_prefix_restart_timer
,
2680 peer
->v_pmax_restart
);
2685 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2686 PEER_STATUS_PREFIX_LIMIT
);
2688 if (peer
->pcount
[afi
][safi
]
2689 > (peer
->pmax
[afi
][safi
] * peer
->pmax_threshold
[afi
][safi
] / 100)) {
2690 if (CHECK_FLAG(peer
->af_sflags
[afi
][safi
],
2691 PEER_STATUS_PREFIX_THRESHOLD
)
2696 "%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2697 afi_safi_print(afi
, safi
), peer
->host
,
2698 peer
->pcount
[afi
][safi
], peer
->pmax
[afi
][safi
]);
2699 SET_FLAG(peer
->af_sflags
[afi
][safi
],
2700 PEER_STATUS_PREFIX_THRESHOLD
);
2702 UNSET_FLAG(peer
->af_sflags
[afi
][safi
],
2703 PEER_STATUS_PREFIX_THRESHOLD
);
2707 /* Unconditionally remove the route from the RIB, without taking
2708 * damping into consideration (eg, because the session went down)
2710 void bgp_rib_remove(struct bgp_node
*rn
, struct bgp_path_info
*pi
,
2711 struct peer
*peer
, afi_t afi
, safi_t safi
)
2713 bgp_aggregate_decrement(peer
->bgp
, &rn
->p
, pi
, afi
, safi
);
2715 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
))
2716 bgp_path_info_delete(rn
, pi
); /* keep historical info */
2718 bgp_process(peer
->bgp
, rn
, afi
, safi
);
2721 static void bgp_rib_withdraw(struct bgp_node
*rn
, struct bgp_path_info
*pi
,
2722 struct peer
*peer
, afi_t afi
, safi_t safi
,
2723 struct prefix_rd
*prd
)
2725 /* apply dampening, if result is suppressed, we'll be retaining
2726 * the bgp_path_info in the RIB for historical reference.
2728 if (CHECK_FLAG(peer
->bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
2729 && peer
->sort
== BGP_PEER_EBGP
)
2730 if ((bgp_damp_withdraw(pi
, rn
, afi
, safi
, 0))
2731 == BGP_DAMP_SUPPRESSED
) {
2732 bgp_aggregate_decrement(peer
->bgp
, &rn
->p
, pi
, afi
,
2738 if (safi
== SAFI_MPLS_VPN
) {
2739 struct bgp_node
*prn
= NULL
;
2740 struct bgp_table
*table
= NULL
;
2742 prn
= bgp_node_get(peer
->bgp
->rib
[afi
][safi
],
2743 (struct prefix
*)prd
);
2745 table
= (struct bgp_table
*)(prn
->info
);
2747 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2748 peer
->bgp
, prd
, table
, &rn
->p
, pi
);
2750 bgp_unlock_node(prn
);
2752 if ((afi
== AFI_IP
|| afi
== AFI_IP6
) && (safi
== SAFI_UNICAST
)) {
2753 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)) {
2755 vnc_import_bgp_del_route(peer
->bgp
, &rn
->p
, pi
);
2756 vnc_import_bgp_exterior_del_route(peer
->bgp
, &rn
->p
,
2762 /* If this is an EVPN route, process for un-import. */
2763 if (safi
== SAFI_EVPN
)
2764 bgp_evpn_unimport_route(peer
->bgp
, afi
, safi
, &rn
->p
, pi
);
2766 bgp_rib_remove(rn
, pi
, peer
, afi
, safi
);
2769 struct bgp_path_info
*info_make(int type
, int sub_type
, unsigned short instance
,
2770 struct peer
*peer
, struct attr
*attr
,
2771 struct bgp_node
*rn
)
2773 struct bgp_path_info
*new;
2775 /* Make new BGP info. */
2776 new = XCALLOC(MTYPE_BGP_ROUTE
, sizeof(struct bgp_path_info
));
2778 new->instance
= instance
;
2779 new->sub_type
= sub_type
;
2782 new->uptime
= bgp_clock();
2787 static void overlay_index_update(struct attr
*attr
,
2788 struct eth_segment_id
*eth_s_id
,
2789 union gw_addr
*gw_ip
)
2794 if (eth_s_id
== NULL
) {
2795 memset(&(attr
->evpn_overlay
.eth_s_id
), 0,
2796 sizeof(struct eth_segment_id
));
2798 memcpy(&(attr
->evpn_overlay
.eth_s_id
), eth_s_id
,
2799 sizeof(struct eth_segment_id
));
2801 if (gw_ip
== NULL
) {
2802 memset(&(attr
->evpn_overlay
.gw_ip
), 0, sizeof(union gw_addr
));
2804 memcpy(&(attr
->evpn_overlay
.gw_ip
), gw_ip
,
2805 sizeof(union gw_addr
));
2809 static bool overlay_index_equal(afi_t afi
, struct bgp_path_info
*path
,
2810 struct eth_segment_id
*eth_s_id
,
2811 union gw_addr
*gw_ip
)
2813 struct eth_segment_id
*path_eth_s_id
, *path_eth_s_id_remote
;
2814 union gw_addr
*path_gw_ip
, *path_gw_ip_remote
;
2816 struct eth_segment_id esi
;
2820 if (afi
!= AFI_L2VPN
)
2823 memset(&temp
, 0, sizeof(temp
));
2824 path_eth_s_id
= &temp
.esi
;
2825 path_gw_ip
= &temp
.ip
;
2827 if (eth_s_id
== NULL
&& gw_ip
== NULL
)
2830 path_eth_s_id
= &(path
->attr
->evpn_overlay
.eth_s_id
);
2831 path_gw_ip
= &(path
->attr
->evpn_overlay
.gw_ip
);
2834 if (gw_ip
== NULL
) {
2835 memset(&temp
, 0, sizeof(temp
));
2836 path_gw_ip_remote
= &temp
.ip
;
2838 path_gw_ip_remote
= gw_ip
;
2840 if (eth_s_id
== NULL
) {
2841 memset(&temp
, 0, sizeof(temp
));
2842 path_eth_s_id_remote
= &temp
.esi
;
2844 path_eth_s_id_remote
= eth_s_id
;
2846 if (!memcmp(path_gw_ip
, path_gw_ip_remote
, sizeof(union gw_addr
)))
2849 return !memcmp(path_eth_s_id
, path_eth_s_id_remote
,
2850 sizeof(struct eth_segment_id
));
2853 /* Check if received nexthop is valid or not. */
2854 static int bgp_update_martian_nexthop(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
2859 /* Only validated for unicast and multicast currently. */
2860 /* Also valid for EVPN where the nexthop is an IP address. */
2861 if (safi
!= SAFI_UNICAST
&& safi
!= SAFI_MULTICAST
&& safi
!= SAFI_EVPN
)
2864 /* If NEXT_HOP is present, validate it. */
2865 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP
)) {
2866 if (attr
->nexthop
.s_addr
== 0
2867 || IPV4_CLASS_DE(ntohl(attr
->nexthop
.s_addr
))
2868 || bgp_nexthop_self(bgp
, attr
->nexthop
))
2872 /* If MP_NEXTHOP is present, validate it. */
2873 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2874 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2875 * it is not an IPv6 link-local address.
2877 if (attr
->mp_nexthop_len
) {
2878 switch (attr
->mp_nexthop_len
) {
2879 case BGP_ATTR_NHLEN_IPV4
:
2880 case BGP_ATTR_NHLEN_VPNV4
:
2881 ret
= (attr
->mp_nexthop_global_in
.s_addr
== 0
2882 || IPV4_CLASS_DE(ntohl(
2883 attr
->mp_nexthop_global_in
.s_addr
))
2884 || bgp_nexthop_self(bgp
,
2885 attr
->mp_nexthop_global_in
));
2888 case BGP_ATTR_NHLEN_IPV6_GLOBAL
:
2889 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
:
2890 case BGP_ATTR_NHLEN_VPNV6_GLOBAL
:
2891 ret
= (IN6_IS_ADDR_UNSPECIFIED(&attr
->mp_nexthop_global
)
2892 || IN6_IS_ADDR_LOOPBACK(&attr
->mp_nexthop_global
)
2893 || IN6_IS_ADDR_MULTICAST(
2894 &attr
->mp_nexthop_global
));
2906 int bgp_update(struct peer
*peer
, struct prefix
*p
, uint32_t addpath_id
,
2907 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
2908 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
2909 uint32_t num_labels
, int soft_reconfig
,
2910 struct bgp_route_evpn
*evpn
)
2913 int aspath_loop_count
= 0;
2914 struct bgp_node
*rn
;
2916 struct attr new_attr
;
2917 struct attr
*attr_new
;
2918 struct bgp_path_info
*pi
;
2919 struct bgp_path_info
*new;
2920 struct bgp_path_info_extra
*extra
;
2922 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
2924 int do_loop_check
= 1;
2925 int has_valid_label
= 0;
2927 int vnc_implicit_withdraw
= 0;
2931 memset(&new_attr
, 0, sizeof(struct attr
));
2932 new_attr
.label_index
= BGP_INVALID_LABEL_INDEX
;
2933 new_attr
.label
= MPLS_INVALID_LABEL
;
2936 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
2937 /* TODO: Check to see if we can get rid of "is_valid_label" */
2938 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
)
2939 has_valid_label
= (num_labels
> 0) ? 1 : 0;
2941 has_valid_label
= bgp_is_valid_label(label
);
2943 /* When peer's soft reconfiguration enabled. Record input packet in
2946 && CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
2947 && peer
!= bgp
->peer_self
)
2948 bgp_adj_in_set(rn
, peer
, attr
, addpath_id
);
2950 /* Check previously received route. */
2951 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
2952 if (pi
->peer
== peer
&& pi
->type
== type
2953 && pi
->sub_type
== sub_type
2954 && pi
->addpath_rx_id
== addpath_id
)
2957 /* AS path local-as loop check. */
2958 if (peer
->change_local_as
) {
2959 if (peer
->allowas_in
[afi
][safi
])
2960 aspath_loop_count
= peer
->allowas_in
[afi
][safi
];
2961 else if (!CHECK_FLAG(peer
->flags
,
2962 PEER_FLAG_LOCAL_AS_NO_PREPEND
))
2963 aspath_loop_count
= 1;
2965 if (aspath_loop_check(attr
->aspath
, peer
->change_local_as
)
2966 > aspath_loop_count
) {
2967 reason
= "as-path contains our own AS;";
2972 /* If the peer is configured for "allowas-in origin" and the last ASN in
2974 * as-path is our ASN then we do not need to call aspath_loop_check
2976 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ALLOWAS_IN_ORIGIN
))
2977 if (aspath_get_last_as(attr
->aspath
) == bgp
->as
)
2980 /* AS path loop check. */
2981 if (do_loop_check
) {
2982 if (aspath_loop_check(attr
->aspath
, bgp
->as
)
2983 > peer
->allowas_in
[afi
][safi
]
2984 || (CHECK_FLAG(bgp
->config
, BGP_CONFIG_CONFEDERATION
)
2985 && aspath_loop_check(attr
->aspath
, bgp
->confed_id
)
2986 > peer
->allowas_in
[afi
][safi
])) {
2987 reason
= "as-path contains our own AS;";
2992 /* Route reflector originator ID check. */
2993 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)
2994 && IPV4_ADDR_SAME(&bgp
->router_id
, &attr
->originator_id
)) {
2995 reason
= "originator is us;";
2999 /* Route reflector cluster ID check. */
3000 if (bgp_cluster_filter(peer
, attr
)) {
3001 reason
= "reflected from the same cluster;";
3005 /* Apply incoming filter. */
3006 if (bgp_input_filter(peer
, p
, attr
, afi
, safi
) == FILTER_DENY
) {
3011 bgp_attr_dup(&new_attr
, attr
);
3013 /* Apply incoming route-map.
3014 * NB: new_attr may now contain newly allocated values from route-map
3016 * commands, so we need bgp_attr_flush in the error paths, until we
3018 * the attr (which takes over the memory references) */
3019 if (bgp_input_modifier(peer
, p
, &new_attr
, afi
, safi
, NULL
)
3021 reason
= "route-map;";
3022 bgp_attr_flush(&new_attr
);
3026 if (peer
->sort
== BGP_PEER_EBGP
) {
3028 /* If we receive the graceful-shutdown community from an eBGP
3029 * peer we must lower local-preference */
3030 if (new_attr
.community
3031 && community_include(new_attr
.community
, COMMUNITY_GSHUT
)) {
3032 new_attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
);
3033 new_attr
.local_pref
= BGP_GSHUT_LOCAL_PREF
;
3035 /* If graceful-shutdown is configured then add the GSHUT
3036 * community to all paths received from eBGP peers */
3037 } else if (bgp_flag_check(peer
->bgp
,
3038 BGP_FLAG_GRACEFUL_SHUTDOWN
)) {
3039 bgp_attr_add_gshut_community(&new_attr
);
3043 /* next hop check. */
3044 if (!CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
)
3045 && bgp_update_martian_nexthop(bgp
, afi
, safi
, &new_attr
)) {
3046 reason
= "martian or self next-hop;";
3047 bgp_attr_flush(&new_attr
);
3051 attr_new
= bgp_attr_intern(&new_attr
);
3053 /* If the update is implicit withdraw. */
3055 pi
->uptime
= bgp_clock();
3056 same_attr
= attrhash_cmp(pi
->attr
, attr_new
);
3058 /* Same attribute comes in. */
3059 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)
3060 && attrhash_cmp(pi
->attr
, attr_new
)
3061 && (!has_valid_label
3062 || memcmp(&(bgp_path_info_extra_get(pi
))->label
, label
,
3063 num_labels
* sizeof(mpls_label_t
))
3065 && (overlay_index_equal(
3066 afi
, pi
, evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3067 evpn
== NULL
? NULL
: &evpn
->gw_ip
))) {
3068 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
],
3069 BGP_CONFIG_DAMPENING
)
3070 && peer
->sort
== BGP_PEER_EBGP
3071 && CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
)) {
3072 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3073 bgp_debug_rdpfxpath2str(
3074 afi
, safi
, prd
, p
, label
,
3075 num_labels
, addpath_id
? 1 : 0,
3076 addpath_id
, pfx_buf
,
3078 zlog_debug("%s rcvd %s", peer
->host
,
3082 if (bgp_damp_update(pi
, rn
, afi
, safi
)
3083 != BGP_DAMP_SUPPRESSED
) {
3084 bgp_aggregate_increment(bgp
, p
, pi
, afi
,
3086 bgp_process(bgp
, rn
, afi
, safi
);
3088 } else /* Duplicate - odd */
3090 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3091 if (!peer
->rcvd_attr_printed
) {
3093 "%s rcvd UPDATE w/ attr: %s",
3095 peer
->rcvd_attr_str
);
3096 peer
->rcvd_attr_printed
= 1;
3099 bgp_debug_rdpfxpath2str(
3100 afi
, safi
, prd
, p
, label
,
3101 num_labels
, addpath_id
? 1 : 0,
3102 addpath_id
, pfx_buf
,
3105 "%s rcvd %s...duplicate ignored",
3106 peer
->host
, pfx_buf
);
3109 /* graceful restart STALE flag unset. */
3110 if (CHECK_FLAG(pi
->flags
, BGP_PATH_STALE
)) {
3111 bgp_path_info_unset_flag(
3112 rn
, pi
, BGP_PATH_STALE
);
3113 bgp_process(bgp
, rn
, afi
, safi
);
3117 bgp_unlock_node(rn
);
3118 bgp_attr_unintern(&attr_new
);
3123 /* Withdraw/Announce before we fully processed the withdraw */
3124 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)) {
3125 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3126 bgp_debug_rdpfxpath2str(
3127 afi
, safi
, prd
, p
, label
, num_labels
,
3128 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3131 "%s rcvd %s, flapped quicker than processing",
3132 peer
->host
, pfx_buf
);
3135 bgp_path_info_restore(rn
, pi
);
3138 /* Received Logging. */
3139 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3140 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
,
3141 num_labels
, addpath_id
? 1 : 0,
3142 addpath_id
, pfx_buf
,
3144 zlog_debug("%s rcvd %s", peer
->host
, pfx_buf
);
3147 /* graceful restart STALE flag unset. */
3148 if (CHECK_FLAG(pi
->flags
, BGP_PATH_STALE
))
3149 bgp_path_info_unset_flag(rn
, pi
, BGP_PATH_STALE
);
3151 /* The attribute is changed. */
3152 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_ATTR_CHANGED
);
3154 /* implicit withdraw, decrement aggregate and pcount here.
3155 * only if update is accepted, they'll increment below.
3157 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, safi
);
3159 /* Update bgp route dampening information. */
3160 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
3161 && peer
->sort
== BGP_PEER_EBGP
) {
3162 /* This is implicit withdraw so we should update
3165 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
))
3166 bgp_damp_withdraw(pi
, rn
, afi
, safi
, 1);
3169 if (safi
== SAFI_MPLS_VPN
) {
3170 struct bgp_node
*prn
= NULL
;
3171 struct bgp_table
*table
= NULL
;
3173 prn
= bgp_node_get(bgp
->rib
[afi
][safi
],
3174 (struct prefix
*)prd
);
3176 table
= (struct bgp_table
*)(prn
->info
);
3178 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3179 bgp
, prd
, table
, p
, pi
);
3181 bgp_unlock_node(prn
);
3183 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3184 && (safi
== SAFI_UNICAST
)) {
3185 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)) {
3187 * Implicit withdraw case.
3189 ++vnc_implicit_withdraw
;
3190 vnc_import_bgp_del_route(bgp
, p
, pi
);
3191 vnc_import_bgp_exterior_del_route(bgp
, p
, pi
);
3196 /* Special handling for EVPN update of an existing route. If the
3197 * extended community attribute has changed, we need to
3199 * the route using its existing extended community. It will be
3200 * subsequently processed for import with the new extended
3203 if (safi
== SAFI_EVPN
&& !same_attr
) {
3205 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))
3207 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
))) {
3210 cmp
= ecommunity_cmp(pi
->attr
->ecommunity
,
3211 attr_new
->ecommunity
);
3213 if (bgp_debug_update(peer
, p
, NULL
, 1))
3215 "Change in EXT-COMM, existing %s new %s",
3217 pi
->attr
->ecommunity
),
3219 attr_new
->ecommunity
));
3220 bgp_evpn_unimport_route(bgp
, afi
, safi
,
3226 /* Update to new attribute. */
3227 bgp_attr_unintern(&pi
->attr
);
3228 pi
->attr
= attr_new
;
3230 /* Update MPLS label */
3231 if (has_valid_label
) {
3232 extra
= bgp_path_info_extra_get(pi
);
3233 memcpy(&extra
->label
, label
,
3234 num_labels
* sizeof(mpls_label_t
));
3235 extra
->num_labels
= num_labels
;
3236 if (!(afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
))
3237 bgp_set_valid_label(&extra
->label
[0]);
3241 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3242 && (safi
== SAFI_UNICAST
)) {
3243 if (vnc_implicit_withdraw
) {
3245 * Add back the route with its new attributes
3247 * The route is still selected, until the route
3249 * queued by bgp_process actually runs. We have
3251 * update to the VNC side immediately to avoid
3253 * configuration changes (e.g., route-map
3255 * trigger re-importation of the entire RIB.
3257 vnc_import_bgp_add_route(bgp
, p
, pi
);
3258 vnc_import_bgp_exterior_add_route(bgp
, p
, pi
);
3262 /* Update Overlay Index */
3263 if (afi
== AFI_L2VPN
) {
3264 overlay_index_update(
3265 pi
->attr
, evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3266 evpn
== NULL
? NULL
: &evpn
->gw_ip
);
3269 /* Update bgp route dampening information. */
3270 if (CHECK_FLAG(bgp
->af_flags
[afi
][safi
], BGP_CONFIG_DAMPENING
)
3271 && peer
->sort
== BGP_PEER_EBGP
) {
3272 /* Now we do normal update dampening. */
3273 ret
= bgp_damp_update(pi
, rn
, afi
, safi
);
3274 if (ret
== BGP_DAMP_SUPPRESSED
) {
3275 bgp_unlock_node(rn
);
3280 /* Nexthop reachability check - for unicast and
3281 * labeled-unicast.. */
3282 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3283 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
3284 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1
3285 && !CHECK_FLAG(peer
->flags
,
3286 PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3288 bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
3293 struct bgp
*bgp_nexthop
= bgp
;
3295 if (pi
->extra
&& pi
->extra
->bgp_orig
)
3296 bgp_nexthop
= pi
->extra
->bgp_orig
;
3298 if (bgp_find_or_add_nexthop(bgp
, bgp_nexthop
, afi
, pi
,
3300 || CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
))
3301 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_VALID
);
3303 if (BGP_DEBUG(nht
, NHT
)) {
3304 char buf1
[INET6_ADDRSTRLEN
];
3306 (const void *)&attr_new
3308 buf1
, INET6_ADDRSTRLEN
);
3309 zlog_debug("%s(%s): NH unresolved",
3310 __FUNCTION__
, buf1
);
3312 bgp_path_info_unset_flag(rn
, pi
,
3316 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_VALID
);
3319 if (safi
== SAFI_MPLS_VPN
) {
3320 struct bgp_node
*prn
= NULL
;
3321 struct bgp_table
*table
= NULL
;
3323 prn
= bgp_node_get(bgp
->rib
[afi
][safi
],
3324 (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
, pi
);
3331 bgp_unlock_node(prn
);
3335 /* If this is an EVPN route and some attribute has changed,
3337 * route for import. If the extended community has changed, we
3339 * have done the un-import earlier and the import would result
3341 * route getting injected into appropriate L2 VNIs. If it is
3343 * some other attribute change, the import will result in
3345 * the attributes for the route in the VNI(s).
3347 if (safi
== SAFI_EVPN
&& !same_attr
)
3348 bgp_evpn_import_route(bgp
, afi
, safi
, p
, pi
);
3350 /* Process change. */
3351 bgp_aggregate_increment(bgp
, p
, pi
, afi
, safi
);
3353 bgp_process(bgp
, rn
, afi
, safi
);
3354 bgp_unlock_node(rn
);
3356 if (SAFI_UNICAST
== safi
3357 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3358 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3360 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, pi
);
3362 if ((SAFI_MPLS_VPN
== safi
)
3363 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3365 vpn_leak_to_vrf_update(bgp
, pi
);
3369 if (SAFI_MPLS_VPN
== safi
) {
3370 mpls_label_t label_decoded
= decode_label(label
);
3372 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
,
3373 type
, sub_type
, &label_decoded
);
3375 if (SAFI_ENCAP
== safi
) {
3376 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
,
3377 type
, sub_type
, NULL
);
3382 } // End of implicit withdraw
3384 /* Received Logging. */
3385 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3386 if (!peer
->rcvd_attr_printed
) {
3387 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
3388 peer
->rcvd_attr_str
);
3389 peer
->rcvd_attr_printed
= 1;
3392 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3393 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3395 zlog_debug("%s rcvd %s", peer
->host
, pfx_buf
);
3398 /* Make new BGP info. */
3399 new = info_make(type
, sub_type
, 0, peer
, attr_new
, rn
);
3401 /* Update MPLS label */
3402 if (has_valid_label
) {
3403 extra
= bgp_path_info_extra_get(new);
3404 memcpy(&extra
->label
, label
, num_labels
* sizeof(mpls_label_t
));
3405 extra
->num_labels
= num_labels
;
3406 if (!(afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
))
3407 bgp_set_valid_label(&extra
->label
[0]);
3410 /* Update Overlay Index */
3411 if (afi
== AFI_L2VPN
) {
3412 overlay_index_update(new->attr
,
3413 evpn
== NULL
? NULL
: &evpn
->eth_s_id
,
3414 evpn
== NULL
? NULL
: &evpn
->gw_ip
);
3416 /* Nexthop reachability check. */
3417 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
3418 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
3419 if (peer
->sort
== BGP_PEER_EBGP
&& peer
->ttl
== 1
3420 && !CHECK_FLAG(peer
->flags
,
3421 PEER_FLAG_DISABLE_CONNECTED_CHECK
)
3422 && !bgp_flag_check(bgp
, BGP_FLAG_DISABLE_NH_CONNECTED_CHK
))
3427 if (bgp_find_or_add_nexthop(bgp
, bgp
, afi
, new, NULL
, connected
)
3428 || CHECK_FLAG(peer
->flags
, PEER_FLAG_IS_RFAPI_HD
))
3429 bgp_path_info_set_flag(rn
, new, BGP_PATH_VALID
);
3431 if (BGP_DEBUG(nht
, NHT
)) {
3432 char buf1
[INET6_ADDRSTRLEN
];
3434 (const void *)&attr_new
->nexthop
,
3435 buf1
, INET6_ADDRSTRLEN
);
3436 zlog_debug("%s(%s): NH unresolved",
3437 __FUNCTION__
, buf1
);
3439 bgp_path_info_unset_flag(rn
, new, BGP_PATH_VALID
);
3442 bgp_path_info_set_flag(rn
, new, BGP_PATH_VALID
);
3445 new->addpath_rx_id
= addpath_id
;
3447 /* Increment prefix */
3448 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
3450 /* Register new BGP information. */
3451 bgp_path_info_add(rn
, new);
3453 /* route_node_get lock */
3454 bgp_unlock_node(rn
);
3457 if (safi
== SAFI_MPLS_VPN
) {
3458 struct bgp_node
*prn
= NULL
;
3459 struct bgp_table
*table
= NULL
;
3461 prn
= bgp_node_get(bgp
->rib
[afi
][safi
], (struct prefix
*)prd
);
3463 table
= (struct bgp_table
*)(prn
->info
);
3465 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
3466 bgp
, prd
, table
, p
, new);
3468 bgp_unlock_node(prn
);
3472 /* If maximum prefix count is configured and current prefix
3474 if (bgp_maximum_prefix_overflow(peer
, afi
, safi
, 0))
3477 /* If this is an EVPN route, process for import. */
3478 if (safi
== SAFI_EVPN
)
3479 bgp_evpn_import_route(bgp
, afi
, safi
, p
, new);
3481 /* Process change. */
3482 bgp_process(bgp
, rn
, afi
, safi
);
3484 if (SAFI_UNICAST
== safi
3485 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3486 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3487 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
3489 if ((SAFI_MPLS_VPN
== safi
)
3490 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3492 vpn_leak_to_vrf_update(bgp
, new);
3495 if (SAFI_MPLS_VPN
== safi
) {
3496 mpls_label_t label_decoded
= decode_label(label
);
3498 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
,
3499 sub_type
, &label_decoded
);
3501 if (SAFI_ENCAP
== safi
) {
3502 rfapiProcessUpdate(peer
, NULL
, p
, prd
, attr
, afi
, safi
, type
,
3509 /* This BGP update is filtered. Log the reason then update BGP
3512 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3513 if (!peer
->rcvd_attr_printed
) {
3514 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer
->host
,
3515 peer
->rcvd_attr_str
);
3516 peer
->rcvd_attr_printed
= 1;
3519 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3520 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3522 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
3523 peer
->host
, pfx_buf
, reason
);
3527 /* If this is an EVPN route, un-import it as it is now filtered.
3529 if (safi
== SAFI_EVPN
)
3530 bgp_evpn_unimport_route(bgp
, afi
, safi
, p
, pi
);
3532 if (SAFI_UNICAST
== safi
3533 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3534 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3536 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, pi
);
3538 if ((SAFI_MPLS_VPN
== safi
)
3539 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3541 vpn_leak_to_vrf_withdraw(bgp
, pi
);
3544 bgp_rib_remove(rn
, pi
, peer
, afi
, safi
);
3547 bgp_unlock_node(rn
);
3551 * Filtered update is treated as an implicit withdrawal (see
3553 * a few lines above)
3555 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
)) {
3556 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
,
3564 int bgp_withdraw(struct peer
*peer
, struct prefix
*p
, uint32_t addpath_id
,
3565 struct attr
*attr
, afi_t afi
, safi_t safi
, int type
,
3566 int sub_type
, struct prefix_rd
*prd
, mpls_label_t
*label
,
3567 uint32_t num_labels
, struct bgp_route_evpn
*evpn
)
3570 char pfx_buf
[BGP_PRD_PATH_STRLEN
];
3571 struct bgp_node
*rn
;
3572 struct bgp_path_info
*pi
;
3575 if ((SAFI_MPLS_VPN
== safi
) || (SAFI_ENCAP
== safi
)) {
3576 rfapiProcessWithdraw(peer
, NULL
, p
, prd
, NULL
, afi
, safi
, type
,
3584 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
3586 /* If peer is soft reconfiguration enabled. Record input packet for
3587 * further calculation.
3589 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
3590 * routes that are filtered. This tanks out Quagga RS pretty badly due
3592 * the iteration over all RS clients.
3593 * Since we need to remove the entry from adj_in anyway, do that first
3595 * if there was no entry, we don't need to do anything more.
3597 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_SOFT_RECONFIG
)
3598 && peer
!= bgp
->peer_self
)
3599 if (!bgp_adj_in_unset(rn
, peer
, addpath_id
)) {
3600 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3601 bgp_debug_rdpfxpath2str(
3602 afi
, safi
, prd
, p
, label
, num_labels
,
3603 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3606 "%s withdrawing route %s not in adj-in",
3607 peer
->host
, pfx_buf
);
3609 bgp_unlock_node(rn
);
3613 /* Lookup withdrawn route. */
3614 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
3615 if (pi
->peer
== peer
&& pi
->type
== type
3616 && pi
->sub_type
== sub_type
3617 && pi
->addpath_rx_id
== addpath_id
)
3621 if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3622 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3623 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3625 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer
->host
,
3629 /* Withdraw specified route from routing table. */
3630 if (pi
&& !CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
)) {
3631 bgp_rib_withdraw(rn
, pi
, peer
, afi
, safi
, prd
);
3632 if (SAFI_UNICAST
== safi
3633 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
3634 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3635 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, pi
);
3637 if ((SAFI_MPLS_VPN
== safi
)
3638 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3640 vpn_leak_to_vrf_withdraw(bgp
, pi
);
3642 } else if (bgp_debug_update(peer
, p
, NULL
, 1)) {
3643 bgp_debug_rdpfxpath2str(afi
, safi
, prd
, p
, label
, num_labels
,
3644 addpath_id
? 1 : 0, addpath_id
, pfx_buf
,
3646 zlog_debug("%s Can't find the route %s", peer
->host
, pfx_buf
);
3649 /* Unlock bgp_node_get() lock. */
3650 bgp_unlock_node(rn
);
3655 void bgp_default_originate(struct peer
*peer
, afi_t afi
, safi_t safi
,
3658 struct update_subgroup
*subgrp
;
3659 subgrp
= peer_subgroup(peer
, afi
, safi
);
3660 subgroup_default_originate(subgrp
, withdraw
);
3665 * bgp_stop_announce_route_timer
3667 void bgp_stop_announce_route_timer(struct peer_af
*paf
)
3669 if (!paf
->t_announce_route
)
3672 THREAD_TIMER_OFF(paf
->t_announce_route
);
3676 * bgp_announce_route_timer_expired
3678 * Callback that is invoked when the route announcement timer for a
3681 static int bgp_announce_route_timer_expired(struct thread
*t
)
3683 struct peer_af
*paf
;
3686 paf
= THREAD_ARG(t
);
3689 if (peer
->status
!= Established
)
3692 if (!peer
->afc_nego
[paf
->afi
][paf
->safi
])
3695 peer_af_announce_route(paf
, 1);
3700 * bgp_announce_route
3702 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3704 void bgp_announce_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
3706 struct peer_af
*paf
;
3707 struct update_subgroup
*subgrp
;
3709 paf
= peer_af_find(peer
, afi
, safi
);
3712 subgrp
= PAF_SUBGRP(paf
);
3715 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3716 * or a refresh has already been triggered.
3718 if (!subgrp
|| paf
->t_announce_route
)
3722 * Start a timer to stagger/delay the announce. This serves
3723 * two purposes - announcement can potentially be combined for
3724 * multiple peers and the announcement doesn't happen in the
3727 thread_add_timer_msec(bm
->master
, bgp_announce_route_timer_expired
, paf
,
3728 (subgrp
->peer_count
== 1)
3729 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
3730 : BGP_ANNOUNCE_ROUTE_DELAY_MS
,
3731 &paf
->t_announce_route
);
3735 * Announce routes from all AF tables to a peer.
3737 * This should ONLY be called when there is a need to refresh the
3738 * routes to the peer based on a policy change for this peer alone
3739 * or a route refresh request received from the peer.
3740 * The operation will result in splitting the peer from its existing
3741 * subgroups and putting it in new subgroups.
3743 void bgp_announce_route_all(struct peer
*peer
)
3748 FOREACH_AFI_SAFI (afi
, safi
)
3749 bgp_announce_route(peer
, afi
, safi
);
3752 static void bgp_soft_reconfig_table(struct peer
*peer
, afi_t afi
, safi_t safi
,
3753 struct bgp_table
*table
,
3754 struct prefix_rd
*prd
)
3757 struct bgp_node
*rn
;
3758 struct bgp_adj_in
*ain
;
3761 table
= peer
->bgp
->rib
[afi
][safi
];
3763 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
3764 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
) {
3765 if (ain
->peer
!= peer
)
3768 struct bgp_path_info
*pi
= rn
->info
;
3769 uint32_t num_labels
= 0;
3770 mpls_label_t
*label_pnt
= NULL
;
3772 if (pi
&& pi
->extra
)
3773 num_labels
= pi
->extra
->num_labels
;
3775 label_pnt
= &pi
->extra
->label
[0];
3777 ret
= bgp_update(peer
, &rn
->p
, ain
->addpath_rx_id
,
3778 ain
->attr
, afi
, safi
, ZEBRA_ROUTE_BGP
,
3779 BGP_ROUTE_NORMAL
, prd
, label_pnt
,
3780 num_labels
, 1, NULL
);
3783 bgp_unlock_node(rn
);
3789 void bgp_soft_reconfig_in(struct peer
*peer
, afi_t afi
, safi_t safi
)
3791 struct bgp_node
*rn
;
3792 struct bgp_table
*table
;
3794 if (peer
->status
!= Established
)
3797 if ((safi
!= SAFI_MPLS_VPN
) && (safi
!= SAFI_ENCAP
)
3798 && (safi
!= SAFI_EVPN
))
3799 bgp_soft_reconfig_table(peer
, afi
, safi
, NULL
, NULL
);
3801 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
3802 rn
= bgp_route_next(rn
))
3803 if ((table
= rn
->info
) != NULL
) {
3804 struct prefix_rd prd
;
3805 prd
.family
= AF_UNSPEC
;
3807 memcpy(&prd
.val
, rn
->p
.u
.val
, 8);
3809 bgp_soft_reconfig_table(peer
, afi
, safi
, table
,
3815 struct bgp_clear_node_queue
{
3816 struct bgp_node
*rn
;
3819 static wq_item_status
bgp_clear_route_node(struct work_queue
*wq
, void *data
)
3821 struct bgp_clear_node_queue
*cnq
= data
;
3822 struct bgp_node
*rn
= cnq
->rn
;
3823 struct peer
*peer
= wq
->spec
.data
;
3824 struct bgp_path_info
*pi
;
3826 afi_t afi
= bgp_node_table(rn
)->afi
;
3827 safi_t safi
= bgp_node_table(rn
)->safi
;
3832 /* It is possible that we have multiple paths for a prefix from a peer
3833 * if that peer is using AddPath.
3835 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
3836 if (pi
->peer
!= peer
)
3839 /* graceful restart STALE flag set. */
3840 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_NSF_WAIT
)
3841 && peer
->nsf
[afi
][safi
]
3842 && !CHECK_FLAG(pi
->flags
, BGP_PATH_STALE
)
3843 && !CHECK_FLAG(pi
->flags
, BGP_PATH_UNUSEABLE
))
3844 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_STALE
);
3846 /* If this is an EVPN route, process for
3848 if (safi
== SAFI_EVPN
)
3849 bgp_evpn_unimport_route(bgp
, afi
, safi
, &rn
->p
,
3851 /* Handle withdraw for VRF route-leaking and L3VPN */
3852 if (SAFI_UNICAST
== safi
3853 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
||
3854 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
3855 vpn_leak_from_vrf_withdraw(bgp_get_default(),
3858 if (SAFI_MPLS_VPN
== safi
&&
3859 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
3860 vpn_leak_to_vrf_withdraw(bgp
, pi
);
3863 bgp_rib_remove(rn
, pi
, peer
, afi
, safi
);
3869 static void bgp_clear_node_queue_del(struct work_queue
*wq
, void *data
)
3871 struct bgp_clear_node_queue
*cnq
= data
;
3872 struct bgp_node
*rn
= cnq
->rn
;
3873 struct bgp_table
*table
= bgp_node_table(rn
);
3875 bgp_unlock_node(rn
);
3876 bgp_table_unlock(table
);
3877 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE
, cnq
);
3880 static void bgp_clear_node_complete(struct work_queue
*wq
)
3882 struct peer
*peer
= wq
->spec
.data
;
3884 /* Tickle FSM to start moving again */
3885 BGP_EVENT_ADD(peer
, Clearing_Completed
);
3887 peer_unlock(peer
); /* bgp_clear_route */
3890 static void bgp_clear_node_queue_init(struct peer
*peer
)
3892 char wname
[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3894 snprintf(wname
, sizeof(wname
), "clear %s", peer
->host
);
3895 #undef CLEAR_QUEUE_NAME_LEN
3897 peer
->clear_node_queue
= work_queue_new(bm
->master
, wname
);
3898 peer
->clear_node_queue
->spec
.hold
= 10;
3899 peer
->clear_node_queue
->spec
.workfunc
= &bgp_clear_route_node
;
3900 peer
->clear_node_queue
->spec
.del_item_data
= &bgp_clear_node_queue_del
;
3901 peer
->clear_node_queue
->spec
.completion_func
= &bgp_clear_node_complete
;
3902 peer
->clear_node_queue
->spec
.max_retries
= 0;
3904 /* we only 'lock' this peer reference when the queue is actually active
3906 peer
->clear_node_queue
->spec
.data
= peer
;
3909 static void bgp_clear_route_table(struct peer
*peer
, afi_t afi
, safi_t safi
,
3910 struct bgp_table
*table
)
3912 struct bgp_node
*rn
;
3913 int force
= bm
->process_main_queue
? 0 : 1;
3916 table
= peer
->bgp
->rib
[afi
][safi
];
3918 /* If still no table => afi/safi isn't configured at all or smth. */
3922 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
3923 struct bgp_path_info
*pi
, *next
;
3924 struct bgp_adj_in
*ain
;
3925 struct bgp_adj_in
*ain_next
;
3927 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3928 * queued for every clearing peer, regardless of whether it is
3929 * relevant to the peer at hand.
3931 * Overview: There are 3 different indices which need to be
3932 * scrubbed, potentially, when a peer is removed:
3934 * 1 peer's routes visible via the RIB (ie accepted routes)
3935 * 2 peer's routes visible by the (optional) peer's adj-in index
3936 * 3 other routes visible by the peer's adj-out index
3938 * 3 there is no hurry in scrubbing, once the struct peer is
3939 * removed from bgp->peer, we could just GC such deleted peer's
3940 * adj-outs at our leisure.
3942 * 1 and 2 must be 'scrubbed' in some way, at least made
3943 * invisible via RIB index before peer session is allowed to be
3944 * brought back up. So one needs to know when such a 'search' is
3949 * - there'd be a single global queue or a single RIB walker
3950 * - rather than tracking which route_nodes still need to be
3951 * examined on a peer basis, we'd track which peers still
3954 * Given that our per-peer prefix-counts now should be reliable,
3955 * this may actually be achievable. It doesn't seem to be a huge
3956 * problem at this time,
3958 * It is possible that we have multiple paths for a prefix from
3960 * if that peer is using AddPath.
3964 ain_next
= ain
->next
;
3966 if (ain
->peer
== peer
) {
3967 bgp_adj_in_remove(rn
, ain
);
3968 bgp_unlock_node(rn
);
3974 for (pi
= rn
->info
; pi
; pi
= next
) {
3976 if (pi
->peer
!= peer
)
3980 bgp_path_info_reap(rn
, pi
);
3982 struct bgp_clear_node_queue
*cnq
;
3984 /* both unlocked in bgp_clear_node_queue_del */
3985 bgp_table_lock(bgp_node_table(rn
));
3988 MTYPE_BGP_CLEAR_NODE_QUEUE
,
3989 sizeof(struct bgp_clear_node_queue
));
3991 work_queue_add(peer
->clear_node_queue
, cnq
);
3999 void bgp_clear_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
4001 struct bgp_node
*rn
;
4002 struct bgp_table
*table
;
4004 if (peer
->clear_node_queue
== NULL
)
4005 bgp_clear_node_queue_init(peer
);
4007 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
4008 * Idle until it receives a Clearing_Completed event. This protects
4009 * against peers which flap faster than we can we clear, which could
4012 * a) race with routes from the new session being installed before
4013 * clear_route_node visits the node (to delete the route of that
4015 * b) resource exhaustion, clear_route_node likely leads to an entry
4016 * on the process_main queue. Fast-flapping could cause that queue
4020 /* lock peer in assumption that clear-node-queue will get nodes; if so,
4021 * the unlock will happen upon work-queue completion; other wise, the
4022 * unlock happens at the end of this function.
4024 if (!peer
->clear_node_queue
->thread
)
4027 if (safi
!= SAFI_MPLS_VPN
&& safi
!= SAFI_ENCAP
&& safi
!= SAFI_EVPN
)
4028 bgp_clear_route_table(peer
, afi
, safi
, NULL
);
4030 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
4031 rn
= bgp_route_next(rn
))
4032 if ((table
= rn
->info
) != NULL
)
4033 bgp_clear_route_table(peer
, afi
, safi
, table
);
4035 /* unlock if no nodes got added to the clear-node-queue. */
4036 if (!peer
->clear_node_queue
->thread
)
4040 void bgp_clear_route_all(struct peer
*peer
)
4045 FOREACH_AFI_SAFI (afi
, safi
)
4046 bgp_clear_route(peer
, afi
, safi
);
4049 rfapiProcessPeerDown(peer
);
4053 void bgp_clear_adj_in(struct peer
*peer
, afi_t afi
, safi_t safi
)
4055 struct bgp_table
*table
;
4056 struct bgp_node
*rn
;
4057 struct bgp_adj_in
*ain
;
4058 struct bgp_adj_in
*ain_next
;
4060 table
= peer
->bgp
->rib
[afi
][safi
];
4062 /* It is possible that we have multiple paths for a prefix from a peer
4063 * if that peer is using AddPath.
4065 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
4069 ain_next
= ain
->next
;
4071 if (ain
->peer
== peer
) {
4072 bgp_adj_in_remove(rn
, ain
);
4073 bgp_unlock_node(rn
);
4081 void bgp_clear_stale_route(struct peer
*peer
, afi_t afi
, safi_t safi
)
4083 struct bgp_node
*rn
;
4084 struct bgp_path_info
*pi
;
4085 struct bgp_table
*table
;
4087 if (safi
== SAFI_MPLS_VPN
) {
4088 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
4089 rn
= bgp_route_next(rn
)) {
4090 struct bgp_node
*rm
;
4092 /* look for neighbor in tables */
4093 if ((table
= rn
->info
) == NULL
)
4096 for (rm
= bgp_table_top(table
); rm
;
4097 rm
= bgp_route_next(rm
))
4098 for (pi
= rm
->info
; pi
; pi
= pi
->next
) {
4099 if (pi
->peer
!= peer
)
4101 if (!CHECK_FLAG(pi
->flags
,
4105 bgp_rib_remove(rm
, pi
, peer
, afi
, safi
);
4110 for (rn
= bgp_table_top(peer
->bgp
->rib
[afi
][safi
]); rn
;
4111 rn
= bgp_route_next(rn
))
4112 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
4113 if (pi
->peer
!= peer
)
4115 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_STALE
))
4117 bgp_rib_remove(rn
, pi
, peer
, afi
, safi
);
4123 static void bgp_cleanup_table(struct bgp
*bgp
, struct bgp_table
*table
,
4126 struct bgp_node
*rn
;
4127 struct bgp_path_info
*pi
;
4128 struct bgp_path_info
*next
;
4130 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
))
4131 for (pi
= rn
->info
; pi
; pi
= next
) {
4133 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)
4134 && pi
->type
== ZEBRA_ROUTE_BGP
4135 && (pi
->sub_type
== BGP_ROUTE_NORMAL
4136 || pi
->sub_type
== BGP_ROUTE_AGGREGATE
4137 || pi
->sub_type
== BGP_ROUTE_IMPORTED
)) {
4139 if (bgp_fibupd_safi(safi
))
4140 bgp_zebra_withdraw(&rn
->p
, pi
, bgp
,
4142 bgp_path_info_reap(rn
, pi
);
4147 /* Delete all kernel routes. */
4148 void bgp_cleanup_routes(struct bgp
*bgp
)
4151 struct bgp_node
*rn
;
4153 for (afi
= AFI_IP
; afi
< AFI_MAX
; ++afi
) {
4154 if (afi
== AFI_L2VPN
)
4156 bgp_cleanup_table(bgp
, bgp
->rib
[afi
][SAFI_UNICAST
],
4159 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
4161 if (afi
!= AFI_L2VPN
) {
4163 safi
= SAFI_MPLS_VPN
;
4164 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
4165 rn
= bgp_route_next(rn
)) {
4167 bgp_cleanup_table(bgp
,
4168 (struct bgp_table
*)(rn
->info
),
4170 bgp_table_finish((struct bgp_table
**)&(
4173 bgp_unlock_node(rn
);
4177 for (rn
= bgp_table_top(bgp
->rib
[afi
][safi
]); rn
;
4178 rn
= bgp_route_next(rn
)) {
4180 bgp_cleanup_table(bgp
,
4181 (struct bgp_table
*)(rn
->info
),
4183 bgp_table_finish((struct bgp_table
**)&(
4186 bgp_unlock_node(rn
);
4191 for (rn
= bgp_table_top(bgp
->rib
[AFI_L2VPN
][SAFI_EVPN
]); rn
;
4192 rn
= bgp_route_next(rn
)) {
4194 bgp_cleanup_table(bgp
,
4195 (struct bgp_table
*)(rn
->info
),
4197 bgp_table_finish((struct bgp_table
**)&(rn
->info
));
4199 bgp_unlock_node(rn
);
4204 void bgp_reset(void)
4207 bgp_zclient_reset();
4208 access_list_reset();
4209 prefix_list_reset();
4212 static int bgp_addpath_encode_rx(struct peer
*peer
, afi_t afi
, safi_t safi
)
4214 return (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ADDPATH_AF_RX_ADV
)
4215 && CHECK_FLAG(peer
->af_cap
[afi
][safi
],
4216 PEER_CAP_ADDPATH_AF_TX_RCV
));
4219 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
4221 int bgp_nlri_parse_ip(struct peer
*peer
, struct attr
*attr
,
4222 struct bgp_nlri
*packet
)
4231 int addpath_encoded
;
4232 uint32_t addpath_id
;
4235 lim
= pnt
+ packet
->length
;
4237 safi
= packet
->safi
;
4239 addpath_encoded
= bgp_addpath_encode_rx(peer
, afi
, safi
);
4241 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
4242 syntactic validity. If the field is syntactically incorrect,
4243 then the Error Subcode is set to Invalid Network Field. */
4244 for (; pnt
< lim
; pnt
+= psize
) {
4245 /* Clear prefix structure. */
4246 memset(&p
, 0, sizeof(struct prefix
));
4248 if (addpath_encoded
) {
4250 /* When packet overflow occurs return immediately. */
4251 if (pnt
+ BGP_ADDPATH_ID_LEN
> lim
)
4254 addpath_id
= ntohl(*((uint32_t *)pnt
));
4255 pnt
+= BGP_ADDPATH_ID_LEN
;
4258 /* Fetch prefix length. */
4259 p
.prefixlen
= *pnt
++;
4260 /* afi/safi validity already verified by caller,
4261 * bgp_update_receive */
4262 p
.family
= afi2family(afi
);
4264 /* Prefix length check. */
4265 if (p
.prefixlen
> prefix_blen(&p
) * 8) {
4268 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
4269 peer
->host
, p
.prefixlen
, packet
->afi
);
4273 /* Packet size overflow check. */
4274 psize
= PSIZE(p
.prefixlen
);
4276 /* When packet overflow occur return immediately. */
4277 if (pnt
+ psize
> lim
) {
4280 "%s [Error] Update packet error (prefix length %d overflows packet)",
4281 peer
->host
, p
.prefixlen
);
4285 /* Defensive coding, double-check the psize fits in a struct
4287 if (psize
> (ssize_t
)sizeof(p
.u
)) {
4290 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
4291 peer
->host
, p
.prefixlen
, sizeof(p
.u
));
4295 /* Fetch prefix from NLRI packet. */
4296 memcpy(p
.u
.val
, pnt
, psize
);
4298 /* Check address. */
4299 if (afi
== AFI_IP
&& safi
== SAFI_UNICAST
) {
4300 if (IN_CLASSD(ntohl(p
.u
.prefix4
.s_addr
))) {
4301 /* From RFC4271 Section 6.3:
4303 * If a prefix in the NLRI field is semantically
4305 * (e.g., an unexpected multicast IP address),
4307 * be logged locally, and the prefix SHOULD be
4312 "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
4313 peer
->host
, inet_ntoa(p
.u
.prefix4
));
4318 /* Check address. */
4319 if (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
) {
4320 if (IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
4325 "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
4327 inet_ntop(AF_INET6
, &p
.u
.prefix6
, buf
,
4332 if (IN6_IS_ADDR_MULTICAST(&p
.u
.prefix6
)) {
4337 "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
4339 inet_ntop(AF_INET6
, &p
.u
.prefix6
, buf
,
4346 /* Normal process. */
4348 ret
= bgp_update(peer
, &p
, addpath_id
, attr
, afi
, safi
,
4349 ZEBRA_ROUTE_BGP
, BGP_ROUTE_NORMAL
,
4350 NULL
, NULL
, 0, 0, NULL
);
4352 ret
= bgp_withdraw(peer
, &p
, addpath_id
, attr
, afi
,
4353 safi
, ZEBRA_ROUTE_BGP
,
4354 BGP_ROUTE_NORMAL
, NULL
, NULL
, 0,
4357 /* Address family configuration mismatch or maximum-prefix count
4363 /* Packet length consistency check. */
4367 "%s [Error] Update packet error (prefix length mismatch with total length)",
4375 static struct bgp_static
*bgp_static_new(void)
4377 return XCALLOC(MTYPE_BGP_STATIC
, sizeof(struct bgp_static
));
4380 static void bgp_static_free(struct bgp_static
*bgp_static
)
4382 if (bgp_static
->rmap
.name
)
4383 XFREE(MTYPE_ROUTE_MAP_NAME
, bgp_static
->rmap
.name
);
4384 if (bgp_static
->eth_s_id
)
4385 XFREE(MTYPE_ATTR
, bgp_static
->eth_s_id
);
4386 XFREE(MTYPE_BGP_STATIC
, bgp_static
);
4389 void bgp_static_update(struct bgp
*bgp
, struct prefix
*p
,
4390 struct bgp_static
*bgp_static
, afi_t afi
, safi_t safi
)
4392 struct bgp_node
*rn
;
4393 struct bgp_path_info
*pi
;
4394 struct bgp_path_info
*new;
4395 struct bgp_path_info rmap_path
;
4397 struct attr
*attr_new
;
4400 int vnc_implicit_withdraw
= 0;
4407 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4409 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
4411 attr
.nexthop
= bgp_static
->igpnexthop
;
4412 attr
.med
= bgp_static
->igpmetric
;
4413 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
4415 if (bgp_static
->atomic
)
4416 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
);
4418 /* Store label index, if required. */
4419 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
) {
4420 attr
.label_index
= bgp_static
->label_index
;
4421 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID
);
4424 /* Apply route-map. */
4425 if (bgp_static
->rmap
.name
) {
4426 struct attr attr_tmp
= attr
;
4428 memset(&rmap_path
, 0, sizeof(struct bgp_path_info
));
4429 rmap_path
.peer
= bgp
->peer_self
;
4430 rmap_path
.attr
= &attr_tmp
;
4432 SET_FLAG(bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4434 ret
= route_map_apply(bgp_static
->rmap
.map
, p
, RMAP_BGP
,
4437 bgp
->peer_self
->rmap_type
= 0;
4439 if (ret
== RMAP_DENYMATCH
) {
4440 /* Free uninterned attribute. */
4441 bgp_attr_flush(&attr_tmp
);
4443 /* Unintern original. */
4444 aspath_unintern(&attr
.aspath
);
4445 bgp_static_withdraw(bgp
, p
, afi
, safi
);
4449 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
4450 bgp_attr_add_gshut_community(&attr_tmp
);
4452 attr_new
= bgp_attr_intern(&attr_tmp
);
4455 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
4456 bgp_attr_add_gshut_community(&attr
);
4458 attr_new
= bgp_attr_intern(&attr
);
4461 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
4462 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== ZEBRA_ROUTE_BGP
4463 && pi
->sub_type
== BGP_ROUTE_STATIC
)
4467 if (attrhash_cmp(pi
->attr
, attr_new
)
4468 && !CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)
4469 && !bgp_flag_check(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
)) {
4470 bgp_unlock_node(rn
);
4471 bgp_attr_unintern(&attr_new
);
4472 aspath_unintern(&attr
.aspath
);
4475 /* The attribute is changed. */
4476 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_ATTR_CHANGED
);
4478 /* Rewrite BGP route information. */
4479 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
))
4480 bgp_path_info_restore(rn
, pi
);
4482 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, safi
);
4484 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
4485 && (safi
== SAFI_UNICAST
)) {
4486 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)) {
4488 * Implicit withdraw case.
4489 * We have to do this before pi is
4492 ++vnc_implicit_withdraw
;
4493 vnc_import_bgp_del_route(bgp
, p
, pi
);
4494 vnc_import_bgp_exterior_del_route(
4499 bgp_attr_unintern(&pi
->attr
);
4500 pi
->attr
= attr_new
;
4501 pi
->uptime
= bgp_clock();
4503 if ((afi
== AFI_IP
|| afi
== AFI_IP6
)
4504 && (safi
== SAFI_UNICAST
)) {
4505 if (vnc_implicit_withdraw
) {
4506 vnc_import_bgp_add_route(bgp
, p
, pi
);
4507 vnc_import_bgp_exterior_add_route(
4513 /* Nexthop reachability check. */
4514 if (bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
4515 && (safi
== SAFI_UNICAST
4516 || safi
== SAFI_LABELED_UNICAST
)) {
4518 struct bgp
*bgp_nexthop
= bgp
;
4520 if (pi
->extra
&& pi
->extra
->bgp_orig
)
4521 bgp_nexthop
= pi
->extra
->bgp_orig
;
4523 if (bgp_find_or_add_nexthop(bgp
, bgp_nexthop
,
4525 bgp_path_info_set_flag(rn
, pi
,
4528 if (BGP_DEBUG(nht
, NHT
)) {
4529 char buf1
[INET6_ADDRSTRLEN
];
4530 inet_ntop(p
->family
,
4534 "%s(%s): Route not in table, not advertising",
4535 __FUNCTION__
, buf1
);
4537 bgp_path_info_unset_flag(
4538 rn
, pi
, BGP_PATH_VALID
);
4541 /* Delete the NHT structure if any, if we're
4543 * enabling/disabling import check. We
4544 * deregister the route
4545 * from NHT to avoid overloading NHT and the
4546 * process interaction
4548 bgp_unlink_nexthop(pi
);
4549 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_VALID
);
4551 /* Process change. */
4552 bgp_aggregate_increment(bgp
, p
, pi
, afi
, safi
);
4553 bgp_process(bgp
, rn
, afi
, safi
);
4555 if (SAFI_UNICAST
== safi
4556 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4558 == BGP_INSTANCE_TYPE_DEFAULT
)) {
4559 vpn_leak_from_vrf_update(bgp_get_default(), bgp
,
4563 bgp_unlock_node(rn
);
4564 aspath_unintern(&attr
.aspath
);
4569 /* Make new BGP info. */
4570 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
,
4572 /* Nexthop reachability check. */
4573 if (bgp_flag_check(bgp
, BGP_FLAG_IMPORT_CHECK
)
4574 && (safi
== SAFI_UNICAST
|| safi
== SAFI_LABELED_UNICAST
)) {
4575 if (bgp_find_or_add_nexthop(bgp
, bgp
, afi
, new, NULL
, 0))
4576 bgp_path_info_set_flag(rn
, new, BGP_PATH_VALID
);
4578 if (BGP_DEBUG(nht
, NHT
)) {
4579 char buf1
[INET6_ADDRSTRLEN
];
4580 inet_ntop(p
->family
, &p
->u
.prefix
, buf1
,
4583 "%s(%s): Route not in table, not advertising",
4584 __FUNCTION__
, buf1
);
4586 bgp_path_info_unset_flag(rn
, new, BGP_PATH_VALID
);
4589 /* Delete the NHT structure if any, if we're toggling between
4590 * enabling/disabling import check. We deregister the route
4591 * from NHT to avoid overloading NHT and the process interaction
4593 bgp_unlink_nexthop(new);
4595 bgp_path_info_set_flag(rn
, new, BGP_PATH_VALID
);
4598 /* Aggregate address increment. */
4599 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
4601 /* Register new BGP information. */
4602 bgp_path_info_add(rn
, new);
4604 /* route_node_get lock */
4605 bgp_unlock_node(rn
);
4607 /* Process change. */
4608 bgp_process(bgp
, rn
, afi
, safi
);
4610 if (SAFI_UNICAST
== safi
4611 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4612 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
4613 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
4616 /* Unintern original. */
4617 aspath_unintern(&attr
.aspath
);
4620 void bgp_static_withdraw(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
4623 struct bgp_node
*rn
;
4624 struct bgp_path_info
*pi
;
4626 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, NULL
);
4628 /* Check selected route and self inserted route. */
4629 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
4630 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== ZEBRA_ROUTE_BGP
4631 && pi
->sub_type
== BGP_ROUTE_STATIC
)
4634 /* Withdraw static BGP route from routing table. */
4636 if (SAFI_UNICAST
== safi
4637 && (bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
4638 || bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
4639 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp
, pi
);
4641 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, safi
);
4642 bgp_unlink_nexthop(pi
);
4643 bgp_path_info_delete(rn
, pi
);
4644 bgp_process(bgp
, rn
, afi
, safi
);
4647 /* Unlock bgp_node_lookup. */
4648 bgp_unlock_node(rn
);
4652 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4654 static void bgp_static_withdraw_safi(struct bgp
*bgp
, struct prefix
*p
,
4655 afi_t afi
, safi_t safi
,
4656 struct prefix_rd
*prd
)
4658 struct bgp_node
*rn
;
4659 struct bgp_path_info
*pi
;
4661 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
, prd
);
4663 /* Check selected route and self inserted route. */
4664 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
4665 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== ZEBRA_ROUTE_BGP
4666 && pi
->sub_type
== BGP_ROUTE_STATIC
)
4669 /* Withdraw static BGP route from routing table. */
4672 rfapiProcessWithdraw(
4673 pi
->peer
, NULL
, p
, prd
, pi
->attr
, afi
, safi
, pi
->type
,
4674 1); /* Kill, since it is an administrative change */
4676 if (SAFI_MPLS_VPN
== safi
4677 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4678 vpn_leak_to_vrf_withdraw(bgp
, pi
);
4680 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, safi
);
4681 bgp_path_info_delete(rn
, pi
);
4682 bgp_process(bgp
, rn
, afi
, safi
);
4685 /* Unlock bgp_node_lookup. */
4686 bgp_unlock_node(rn
);
4689 static void bgp_static_update_safi(struct bgp
*bgp
, struct prefix
*p
,
4690 struct bgp_static
*bgp_static
, afi_t afi
,
4693 struct bgp_node
*rn
;
4694 struct bgp_path_info
*new;
4695 struct attr
*attr_new
;
4696 struct attr attr
= {0};
4697 struct bgp_path_info
*pi
;
4699 mpls_label_t label
= 0;
4701 uint32_t num_labels
= 0;
4706 if (bgp_static
->label
!= MPLS_INVALID_LABEL
)
4708 rn
= bgp_afi_node_get(bgp
->rib
[afi
][safi
], afi
, safi
, p
,
4711 bgp_attr_default_set(&attr
, BGP_ORIGIN_IGP
);
4713 attr
.nexthop
= bgp_static
->igpnexthop
;
4714 attr
.med
= bgp_static
->igpmetric
;
4715 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
4717 if ((safi
== SAFI_EVPN
) || (safi
== SAFI_MPLS_VPN
)
4718 || (safi
== SAFI_ENCAP
)) {
4719 if (afi
== AFI_IP
) {
4720 attr
.mp_nexthop_global_in
= bgp_static
->igpnexthop
;
4721 attr
.mp_nexthop_len
= IPV4_MAX_BYTELEN
;
4724 if (afi
== AFI_L2VPN
) {
4725 if (bgp_static
->gatewayIp
.family
== AF_INET
)
4727 bgp_static
->gatewayIp
.u
.prefix4
.s_addr
;
4728 else if (bgp_static
->gatewayIp
.family
== AF_INET6
)
4729 memcpy(&(add
.ipv6
), &(bgp_static
->gatewayIp
.u
.prefix6
),
4730 sizeof(struct in6_addr
));
4731 overlay_index_update(&attr
, bgp_static
->eth_s_id
, &add
);
4732 if (bgp_static
->encap_tunneltype
== BGP_ENCAP_TYPE_VXLAN
) {
4733 struct bgp_encap_type_vxlan bet
;
4734 memset(&bet
, 0, sizeof(struct bgp_encap_type_vxlan
));
4735 bet
.vnid
= p
->u
.prefix_evpn
.prefix_addr
.eth_tag
;
4736 bgp_encap_type_vxlan_to_tlv(&bet
, &attr
);
4738 if (bgp_static
->router_mac
) {
4739 bgp_add_routermac_ecom(&attr
, bgp_static
->router_mac
);
4742 /* Apply route-map. */
4743 if (bgp_static
->rmap
.name
) {
4744 struct attr attr_tmp
= attr
;
4745 struct bgp_path_info rmap_path
;
4748 rmap_path
.peer
= bgp
->peer_self
;
4749 rmap_path
.attr
= &attr_tmp
;
4751 SET_FLAG(bgp
->peer_self
->rmap_type
, PEER_RMAP_TYPE_NETWORK
);
4753 ret
= route_map_apply(bgp_static
->rmap
.map
, p
, RMAP_BGP
,
4756 bgp
->peer_self
->rmap_type
= 0;
4758 if (ret
== RMAP_DENYMATCH
) {
4759 /* Free uninterned attribute. */
4760 bgp_attr_flush(&attr_tmp
);
4762 /* Unintern original. */
4763 aspath_unintern(&attr
.aspath
);
4764 bgp_static_withdraw_safi(bgp
, p
, afi
, safi
,
4769 attr_new
= bgp_attr_intern(&attr_tmp
);
4771 attr_new
= bgp_attr_intern(&attr
);
4774 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
4775 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== ZEBRA_ROUTE_BGP
4776 && pi
->sub_type
== BGP_ROUTE_STATIC
)
4780 memset(&add
, 0, sizeof(union gw_addr
));
4781 if (attrhash_cmp(pi
->attr
, attr_new
)
4782 && overlay_index_equal(afi
, pi
, bgp_static
->eth_s_id
, &add
)
4783 && !CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
)) {
4784 bgp_unlock_node(rn
);
4785 bgp_attr_unintern(&attr_new
);
4786 aspath_unintern(&attr
.aspath
);
4789 /* The attribute is changed. */
4790 bgp_path_info_set_flag(rn
, pi
, BGP_PATH_ATTR_CHANGED
);
4792 /* Rewrite BGP route information. */
4793 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
))
4794 bgp_path_info_restore(rn
, pi
);
4796 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, safi
);
4797 bgp_attr_unintern(&pi
->attr
);
4798 pi
->attr
= attr_new
;
4799 pi
->uptime
= bgp_clock();
4802 label
= decode_label(&pi
->extra
->label
[0]);
4805 /* Process change. */
4806 bgp_aggregate_increment(bgp
, p
, pi
, afi
, safi
);
4807 bgp_process(bgp
, rn
, afi
, safi
);
4809 if (SAFI_MPLS_VPN
== safi
4810 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4811 vpn_leak_to_vrf_update(bgp
, pi
);
4814 rfapiProcessUpdate(pi
->peer
, NULL
, p
, &bgp_static
->prd
,
4815 pi
->attr
, afi
, safi
, pi
->type
,
4816 pi
->sub_type
, &label
);
4818 bgp_unlock_node(rn
);
4819 aspath_unintern(&attr
.aspath
);
4825 /* Make new BGP info. */
4826 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_STATIC
, 0, bgp
->peer_self
,
4828 SET_FLAG(new->flags
, BGP_PATH_VALID
);
4829 new->extra
= bgp_path_info_extra_new();
4831 new->extra
->label
[0] = bgp_static
->label
;
4832 new->extra
->num_labels
= num_labels
;
4835 label
= decode_label(&bgp_static
->label
);
4838 /* Aggregate address increment. */
4839 bgp_aggregate_increment(bgp
, p
, new, afi
, safi
);
4841 /* Register new BGP information. */
4842 bgp_path_info_add(rn
, new);
4843 /* route_node_get lock */
4844 bgp_unlock_node(rn
);
4846 /* Process change. */
4847 bgp_process(bgp
, rn
, afi
, safi
);
4849 if (SAFI_MPLS_VPN
== safi
4850 && bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
) {
4851 vpn_leak_to_vrf_update(bgp
, new);
4854 rfapiProcessUpdate(new->peer
, NULL
, p
, &bgp_static
->prd
, new->attr
, afi
,
4855 safi
, new->type
, new->sub_type
, &label
);
4858 /* Unintern original. */
4859 aspath_unintern(&attr
.aspath
);
4862 /* Configure static BGP network. When user don't run zebra, static
4863 route should be installed as valid. */
4864 static int bgp_static_set(struct vty
*vty
, const char *negate
,
4865 const char *ip_str
, afi_t afi
, safi_t safi
,
4866 const char *rmap
, int backdoor
, uint32_t label_index
)
4868 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
4871 struct bgp_static
*bgp_static
;
4872 struct bgp_node
*rn
;
4873 uint8_t need_update
= 0;
4875 /* Convert IP prefix string to struct prefix. */
4876 ret
= str2prefix(ip_str
, &p
);
4878 vty_out(vty
, "%% Malformed prefix\n");
4879 return CMD_WARNING_CONFIG_FAILED
;
4881 if (afi
== AFI_IP6
&& IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
)) {
4882 vty_out(vty
, "%% Malformed prefix (link-local address)\n");
4883 return CMD_WARNING_CONFIG_FAILED
;
4890 /* Set BGP static route configuration. */
4891 rn
= bgp_node_lookup(bgp
->route
[afi
][safi
], &p
);
4894 vty_out(vty
, "%% Can't find static route specified\n");
4895 return CMD_WARNING_CONFIG_FAILED
;
4898 bgp_static
= bgp_static_get_node_info(rn
);
4900 if ((label_index
!= BGP_INVALID_LABEL_INDEX
)
4901 && (label_index
!= bgp_static
->label_index
)) {
4903 "%% label-index doesn't match static route\n");
4904 return CMD_WARNING_CONFIG_FAILED
;
4907 if ((rmap
&& bgp_static
->rmap
.name
)
4908 && strcmp(rmap
, bgp_static
->rmap
.name
)) {
4910 "%% route-map name doesn't match static route\n");
4911 return CMD_WARNING_CONFIG_FAILED
;
4914 /* Update BGP RIB. */
4915 if (!bgp_static
->backdoor
)
4916 bgp_static_withdraw(bgp
, &p
, afi
, safi
);
4918 /* Clear configuration. */
4919 bgp_static_free(bgp_static
);
4920 bgp_static_set_node_info(rn
, NULL
);
4921 bgp_unlock_node(rn
);
4922 bgp_unlock_node(rn
);
4925 /* Set BGP static route configuration. */
4926 rn
= bgp_node_get(bgp
->route
[afi
][safi
], &p
);
4928 bgp_static
= bgp_static_get_node_info(rn
);
4930 /* Configuration change. */
4931 /* Label index cannot be changed. */
4932 if (bgp_static
->label_index
!= label_index
) {
4933 vty_out(vty
, "%% cannot change label-index\n");
4934 return CMD_WARNING_CONFIG_FAILED
;
4937 /* Check previous routes are installed into BGP. */
4938 if (bgp_static
->valid
4939 && bgp_static
->backdoor
!= backdoor
)
4942 bgp_static
->backdoor
= backdoor
;
4945 if (bgp_static
->rmap
.name
)
4946 XFREE(MTYPE_ROUTE_MAP_NAME
,
4947 bgp_static
->rmap
.name
);
4948 bgp_static
->rmap
.name
=
4949 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4950 bgp_static
->rmap
.map
=
4951 route_map_lookup_by_name(rmap
);
4953 if (bgp_static
->rmap
.name
)
4954 XFREE(MTYPE_ROUTE_MAP_NAME
,
4955 bgp_static
->rmap
.name
);
4956 bgp_static
->rmap
.name
= NULL
;
4957 bgp_static
->rmap
.map
= NULL
;
4958 bgp_static
->valid
= 0;
4960 bgp_unlock_node(rn
);
4962 /* New configuration. */
4963 bgp_static
= bgp_static_new();
4964 bgp_static
->backdoor
= backdoor
;
4965 bgp_static
->valid
= 0;
4966 bgp_static
->igpmetric
= 0;
4967 bgp_static
->igpnexthop
.s_addr
= 0;
4968 bgp_static
->label_index
= label_index
;
4971 if (bgp_static
->rmap
.name
)
4972 XFREE(MTYPE_ROUTE_MAP_NAME
,
4973 bgp_static
->rmap
.name
);
4974 bgp_static
->rmap
.name
=
4975 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap
);
4976 bgp_static
->rmap
.map
=
4977 route_map_lookup_by_name(rmap
);
4979 bgp_static_set_node_info(rn
, bgp_static
);
4982 bgp_static
->valid
= 1;
4984 bgp_static_withdraw(bgp
, &p
, afi
, safi
);
4986 if (!bgp_static
->backdoor
)
4987 bgp_static_update(bgp
, &p
, bgp_static
, afi
, safi
);
4993 void bgp_static_add(struct bgp
*bgp
)
4997 struct bgp_node
*rn
;
4998 struct bgp_node
*rm
;
4999 struct bgp_table
*table
;
5000 struct bgp_static
*bgp_static
;
5002 FOREACH_AFI_SAFI (afi
, safi
)
5003 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
5004 rn
= bgp_route_next(rn
)) {
5005 if (rn
->info
== NULL
)
5008 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5009 || (safi
== SAFI_EVPN
)) {
5012 for (rm
= bgp_table_top(table
); rm
;
5013 rm
= bgp_route_next(rm
)) {
5015 bgp_static_get_node_info(rm
);
5016 bgp_static_update_safi(bgp
, &rm
->p
,
5021 bgp_static_update(bgp
, &rn
->p
,
5022 bgp_static_get_node_info(rn
),
5028 /* Called from bgp_delete(). Delete all static routes from the BGP
5030 void bgp_static_delete(struct bgp
*bgp
)
5034 struct bgp_node
*rn
;
5035 struct bgp_node
*rm
;
5036 struct bgp_table
*table
;
5037 struct bgp_static
*bgp_static
;
5039 FOREACH_AFI_SAFI (afi
, safi
)
5040 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
5041 rn
= bgp_route_next(rn
)) {
5042 if (rn
->info
== NULL
)
5045 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5046 || (safi
== SAFI_EVPN
)) {
5049 for (rm
= bgp_table_top(table
); rm
;
5050 rm
= bgp_route_next(rm
)) {
5052 bgp_static_get_node_info(rm
);
5053 bgp_static_withdraw_safi(
5054 bgp
, &rm
->p
, AFI_IP
, safi
,
5055 (struct prefix_rd
*)&rn
->p
);
5056 bgp_static_free(bgp_static
);
5057 bgp_static_set_node_info(rn
, NULL
);
5058 bgp_unlock_node(rn
);
5061 bgp_static
= bgp_static_get_node_info(rn
);
5062 bgp_static_withdraw(bgp
, &rn
->p
, afi
, safi
);
5063 bgp_static_free(bgp_static
);
5064 bgp_static_set_node_info(rn
, NULL
);
5065 bgp_unlock_node(rn
);
5070 void bgp_static_redo_import_check(struct bgp
*bgp
)
5074 struct bgp_node
*rn
;
5075 struct bgp_node
*rm
;
5076 struct bgp_table
*table
;
5077 struct bgp_static
*bgp_static
;
5079 /* Use this flag to force reprocessing of the route */
5080 bgp_flag_set(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
5081 FOREACH_AFI_SAFI (afi
, safi
) {
5082 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
5083 rn
= bgp_route_next(rn
)) {
5084 if (rn
->info
== NULL
)
5087 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
5088 || (safi
== SAFI_EVPN
)) {
5091 for (rm
= bgp_table_top(table
); rm
;
5092 rm
= bgp_route_next(rm
)) {
5094 bgp_static_get_node_info(rm
);
5095 bgp_static_update_safi(bgp
, &rm
->p
,
5100 bgp_static
= bgp_static_get_node_info(rn
);
5101 bgp_static_update(bgp
, &rn
->p
, bgp_static
, afi
,
5106 bgp_flag_unset(bgp
, BGP_FLAG_FORCE_STATIC_PROCESS
);
5109 static void bgp_purge_af_static_redist_routes(struct bgp
*bgp
, afi_t afi
,
5112 struct bgp_table
*table
;
5113 struct bgp_node
*rn
;
5114 struct bgp_path_info
*pi
;
5116 table
= bgp
->rib
[afi
][safi
];
5117 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
5118 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
5119 if (pi
->peer
== bgp
->peer_self
5120 && ((pi
->type
== ZEBRA_ROUTE_BGP
5121 && pi
->sub_type
== BGP_ROUTE_STATIC
)
5122 || (pi
->type
!= ZEBRA_ROUTE_BGP
5124 == BGP_ROUTE_REDISTRIBUTE
))) {
5125 bgp_aggregate_decrement(bgp
, &rn
->p
, pi
, afi
,
5127 bgp_unlink_nexthop(pi
);
5128 bgp_path_info_delete(rn
, pi
);
5129 bgp_process(bgp
, rn
, afi
, safi
);
5136 * Purge all networks and redistributed routes from routing table.
5137 * Invoked upon the instance going down.
5139 void bgp_purge_static_redist_routes(struct bgp
*bgp
)
5144 FOREACH_AFI_SAFI (afi
, safi
)
5145 bgp_purge_af_static_redist_routes(bgp
, afi
, safi
);
5150 * Currently this is used to set static routes for VPN and ENCAP.
5151 * I think it can probably be factored with bgp_static_set.
5153 int bgp_static_set_safi(afi_t afi
, safi_t safi
, struct vty
*vty
,
5154 const char *ip_str
, const char *rd_str
,
5155 const char *label_str
, const char *rmap_str
,
5156 int evpn_type
, const char *esi
, const char *gwip
,
5157 const char *ethtag
, const char *routermac
)
5159 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5162 struct prefix_rd prd
;
5163 struct bgp_node
*prn
;
5164 struct bgp_node
*rn
;
5165 struct bgp_table
*table
;
5166 struct bgp_static
*bgp_static
;
5167 mpls_label_t label
= MPLS_INVALID_LABEL
;
5168 struct prefix gw_ip
;
5170 /* validate ip prefix */
5171 ret
= str2prefix(ip_str
, &p
);
5173 vty_out(vty
, "%% Malformed prefix\n");
5174 return CMD_WARNING_CONFIG_FAILED
;
5177 if ((afi
== AFI_L2VPN
)
5178 && (bgp_build_evpn_prefix(evpn_type
,
5179 ethtag
!= NULL
? atol(ethtag
) : 0, &p
))) {
5180 vty_out(vty
, "%% L2VPN prefix could not be forged\n");
5181 return CMD_WARNING_CONFIG_FAILED
;
5184 ret
= str2prefix_rd(rd_str
, &prd
);
5186 vty_out(vty
, "%% Malformed rd\n");
5187 return CMD_WARNING_CONFIG_FAILED
;
5191 unsigned long label_val
;
5192 label_val
= strtoul(label_str
, NULL
, 10);
5193 encode_label(label_val
, &label
);
5196 if (safi
== SAFI_EVPN
) {
5197 if (esi
&& str2esi(esi
, NULL
) == 0) {
5198 vty_out(vty
, "%% Malformed ESI\n");
5199 return CMD_WARNING_CONFIG_FAILED
;
5201 if (routermac
&& prefix_str2mac(routermac
, NULL
) == 0) {
5202 vty_out(vty
, "%% Malformed Router MAC\n");
5203 return CMD_WARNING_CONFIG_FAILED
;
5206 memset(&gw_ip
, 0, sizeof(struct prefix
));
5207 ret
= str2prefix(gwip
, &gw_ip
);
5209 vty_out(vty
, "%% Malformed GatewayIp\n");
5210 return CMD_WARNING_CONFIG_FAILED
;
5212 if ((gw_ip
.family
== AF_INET
5213 && is_evpn_prefix_ipaddr_v6(
5214 (struct prefix_evpn
*)&p
))
5215 || (gw_ip
.family
== AF_INET6
5216 && is_evpn_prefix_ipaddr_v4(
5217 (struct prefix_evpn
*)&p
))) {
5219 "%% GatewayIp family differs with IP prefix\n");
5220 return CMD_WARNING_CONFIG_FAILED
;
5224 prn
= bgp_node_get(bgp
->route
[afi
][safi
], (struct prefix
*)&prd
);
5225 if (prn
->info
== NULL
)
5226 prn
->info
= bgp_table_init(bgp
, afi
, safi
);
5228 bgp_unlock_node(prn
);
5231 rn
= bgp_node_get(table
, &p
);
5234 vty_out(vty
, "%% Same network configuration exists\n");
5235 bgp_unlock_node(rn
);
5237 /* New configuration. */
5238 bgp_static
= bgp_static_new();
5239 bgp_static
->backdoor
= 0;
5240 bgp_static
->valid
= 0;
5241 bgp_static
->igpmetric
= 0;
5242 bgp_static
->igpnexthop
.s_addr
= 0;
5243 bgp_static
->label
= label
;
5244 bgp_static
->prd
= prd
;
5247 if (bgp_static
->rmap
.name
)
5248 XFREE(MTYPE_ROUTE_MAP_NAME
,
5249 bgp_static
->rmap
.name
);
5250 bgp_static
->rmap
.name
=
5251 XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_str
);
5252 bgp_static
->rmap
.map
=
5253 route_map_lookup_by_name(rmap_str
);
5256 if (safi
== SAFI_EVPN
) {
5258 bgp_static
->eth_s_id
=
5260 sizeof(struct eth_segment_id
));
5261 str2esi(esi
, bgp_static
->eth_s_id
);
5264 bgp_static
->router_mac
=
5265 XCALLOC(MTYPE_ATTR
, ETH_ALEN
+ 1);
5266 (void)prefix_str2mac(routermac
,
5267 bgp_static
->router_mac
);
5270 prefix_copy(&bgp_static
->gatewayIp
, &gw_ip
);
5272 bgp_static_set_node_info(rn
, bgp_static
);
5274 bgp_static
->valid
= 1;
5275 bgp_static_update_safi(bgp
, &p
, bgp_static
, afi
, safi
);
5281 /* Configure static BGP network. */
5282 int bgp_static_unset_safi(afi_t afi
, safi_t safi
, struct vty
*vty
,
5283 const char *ip_str
, const char *rd_str
,
5284 const char *label_str
, int evpn_type
, const char *esi
,
5285 const char *gwip
, const char *ethtag
)
5287 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5290 struct prefix_rd prd
;
5291 struct bgp_node
*prn
;
5292 struct bgp_node
*rn
;
5293 struct bgp_table
*table
;
5294 struct bgp_static
*bgp_static
;
5295 mpls_label_t label
= MPLS_INVALID_LABEL
;
5297 /* Convert IP prefix string to struct prefix. */
5298 ret
= str2prefix(ip_str
, &p
);
5300 vty_out(vty
, "%% Malformed prefix\n");
5301 return CMD_WARNING_CONFIG_FAILED
;
5304 if ((afi
== AFI_L2VPN
)
5305 && (bgp_build_evpn_prefix(evpn_type
,
5306 ethtag
!= NULL
? atol(ethtag
) : 0, &p
))) {
5307 vty_out(vty
, "%% L2VPN prefix could not be forged\n");
5308 return CMD_WARNING_CONFIG_FAILED
;
5310 ret
= str2prefix_rd(rd_str
, &prd
);
5312 vty_out(vty
, "%% Malformed rd\n");
5313 return CMD_WARNING_CONFIG_FAILED
;
5317 unsigned long label_val
;
5318 label_val
= strtoul(label_str
, NULL
, 10);
5319 encode_label(label_val
, &label
);
5322 prn
= bgp_node_get(bgp
->route
[afi
][safi
], (struct prefix
*)&prd
);
5323 if (prn
->info
== NULL
)
5324 prn
->info
= bgp_table_init(bgp
, afi
, safi
);
5326 bgp_unlock_node(prn
);
5329 rn
= bgp_node_lookup(table
, &p
);
5332 bgp_static_withdraw_safi(bgp
, &p
, afi
, safi
, &prd
);
5334 bgp_static
= bgp_static_get_node_info(rn
);
5335 bgp_static_free(bgp_static
);
5336 bgp_static_set_node_info(rn
, NULL
);
5337 bgp_unlock_node(rn
);
5338 bgp_unlock_node(rn
);
5340 vty_out(vty
, "%% Can't find the route\n");
5345 static int bgp_table_map_set(struct vty
*vty
, afi_t afi
, safi_t safi
,
5346 const char *rmap_name
)
5348 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5349 struct bgp_rmap
*rmap
;
5351 rmap
= &bgp
->table_map
[afi
][safi
];
5354 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5355 rmap
->name
= XSTRDUP(MTYPE_ROUTE_MAP_NAME
, rmap_name
);
5356 rmap
->map
= route_map_lookup_by_name(rmap_name
);
5359 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5364 if (bgp_fibupd_safi(safi
))
5365 bgp_zebra_announce_table(bgp
, afi
, safi
);
5370 static int bgp_table_map_unset(struct vty
*vty
, afi_t afi
, safi_t safi
,
5371 const char *rmap_name
)
5373 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5374 struct bgp_rmap
*rmap
;
5376 rmap
= &bgp
->table_map
[afi
][safi
];
5378 XFREE(MTYPE_ROUTE_MAP_NAME
, rmap
->name
);
5382 if (bgp_fibupd_safi(safi
))
5383 bgp_zebra_announce_table(bgp
, afi
, safi
);
5388 void bgp_config_write_table_map(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
5391 if (bgp
->table_map
[afi
][safi
].name
) {
5392 vty_out(vty
, " table-map %s\n",
5393 bgp
->table_map
[afi
][safi
].name
);
5397 DEFUN (bgp_table_map
,
5400 "BGP table to RIB route download filter\n"
5401 "Name of the route map\n")
5404 return bgp_table_map_set(vty
, bgp_node_afi(vty
), bgp_node_safi(vty
),
5405 argv
[idx_word
]->arg
);
5407 DEFUN (no_bgp_table_map
,
5408 no_bgp_table_map_cmd
,
5409 "no table-map WORD",
5411 "BGP table to RIB route download filter\n"
5412 "Name of the route map\n")
5415 return bgp_table_map_unset(vty
, bgp_node_afi(vty
), bgp_node_safi(vty
),
5416 argv
[idx_word
]->arg
);
5422 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
5423 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
5424 backdoor$backdoor}]",
5426 "Specify a network to announce via BGP\n"
5431 "Route-map to modify the attributes\n"
5432 "Name of the route map\n"
5433 "Label index to associate with the prefix\n"
5434 "Label index value\n"
5435 "Specify a BGP backdoor route\n")
5437 char addr_prefix_str
[BUFSIZ
];
5442 ret
= netmask_str2prefix_str(address_str
, netmask_str
,
5445 vty_out(vty
, "%% Inconsistent address and mask\n");
5446 return CMD_WARNING_CONFIG_FAILED
;
5450 return bgp_static_set(
5451 vty
, no
, address_str
? addr_prefix_str
: prefix_str
, AFI_IP
,
5452 bgp_node_safi(vty
), map_name
, backdoor
? 1 : 0,
5453 label_index
? (uint32_t)label_index
: BGP_INVALID_LABEL_INDEX
);
5456 DEFPY(ipv6_bgp_network
,
5457 ipv6_bgp_network_cmd
,
5458 "[no] network X:X::X:X/M$prefix \
5459 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
5461 "Specify a network to announce via BGP\n"
5463 "Route-map to modify the attributes\n"
5464 "Name of the route map\n"
5465 "Label index to associate with the prefix\n"
5466 "Label index value\n")
5468 return bgp_static_set(
5469 vty
, no
, prefix_str
, AFI_IP6
, bgp_node_safi(vty
), map_name
, 0,
5470 label_index
? (uint32_t)label_index
: BGP_INVALID_LABEL_INDEX
);
5473 /* Aggreagete address:
5475 advertise-map Set condition to advertise attribute
5476 as-set Generate AS set path information
5477 attribute-map Set attributes of aggregate
5478 route-map Set parameters of aggregate
5479 summary-only Filter more specific routes from updates
5480 suppress-map Conditionally filter more specific routes from updates
5483 struct bgp_aggregate
{
5484 /* Summary-only flag. */
5485 uint8_t summary_only
;
5487 /* AS set generation. */
5490 /* Route-map for aggregated route. */
5491 struct route_map
*map
;
5493 /* Suppress-count. */
5494 unsigned long count
;
5496 /* SAFI configuration. */
5500 static struct bgp_aggregate
*bgp_aggregate_new(void)
5502 return XCALLOC(MTYPE_BGP_AGGREGATE
, sizeof(struct bgp_aggregate
));
5505 static void bgp_aggregate_free(struct bgp_aggregate
*aggregate
)
5507 XFREE(MTYPE_BGP_AGGREGATE
, aggregate
);
5510 static int bgp_aggregate_info_same(struct bgp_path_info
*pi
, uint8_t origin
,
5511 struct aspath
*aspath
,
5512 struct community
*comm
,
5513 struct ecommunity
*ecomm
,
5514 struct lcommunity
*lcomm
)
5516 static struct aspath
*ae
= NULL
;
5519 ae
= aspath_empty();
5524 if (origin
!= pi
->attr
->origin
)
5527 if (!aspath_cmp(pi
->attr
->aspath
, (aspath
) ? aspath
: ae
))
5530 if (!community_cmp(pi
->attr
->community
, comm
))
5533 if (!ecommunity_cmp(pi
->attr
->ecommunity
, ecomm
))
5536 if (!lcommunity_cmp(pi
->attr
->lcommunity
, lcomm
))
5539 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_VALID
))
5545 static void bgp_aggregate_install(struct bgp
*bgp
, afi_t afi
, safi_t safi
,
5546 struct prefix
*p
, uint8_t origin
,
5547 struct aspath
*aspath
,
5548 struct community
*community
,
5549 struct ecommunity
*ecommunity
,
5550 struct lcommunity
*lcommunity
,
5551 uint8_t atomic_aggregate
,
5552 struct bgp_aggregate
*aggregate
)
5554 struct bgp_node
*rn
;
5555 struct bgp_table
*table
;
5556 struct bgp_path_info
*pi
, *new;
5558 table
= bgp
->rib
[afi
][safi
];
5560 rn
= bgp_node_get(table
, p
);
5562 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
5563 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== ZEBRA_ROUTE_BGP
5564 && pi
->sub_type
== BGP_ROUTE_AGGREGATE
)
5567 if (aggregate
->count
> 0) {
5569 * If the aggregate information has not changed
5570 * no need to re-install it again.
5572 if (bgp_aggregate_info_same(rn
->info
, origin
, aspath
, community
,
5573 ecommunity
, lcommunity
)) {
5574 bgp_unlock_node(rn
);
5577 aspath_free(aspath
);
5579 community_free(&community
);
5581 ecommunity_free(&ecommunity
);
5583 lcommunity_free(&lcommunity
);
5589 * Mark the old as unusable
5592 bgp_path_info_delete(rn
, pi
);
5594 new = info_make(ZEBRA_ROUTE_BGP
, BGP_ROUTE_AGGREGATE
, 0,
5596 bgp_attr_aggregate_intern(bgp
, origin
, aspath
,
5597 community
, ecommunity
,
5602 SET_FLAG(new->flags
, BGP_PATH_VALID
);
5604 bgp_path_info_add(rn
, new);
5605 bgp_process(bgp
, rn
, afi
, safi
);
5607 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
5608 if (pi
->peer
== bgp
->peer_self
5609 && pi
->type
== ZEBRA_ROUTE_BGP
5610 && pi
->sub_type
== BGP_ROUTE_AGGREGATE
)
5613 /* Withdraw static BGP route from routing table. */
5615 bgp_path_info_delete(rn
, pi
);
5616 bgp_process(bgp
, rn
, afi
, safi
);
5620 bgp_unlock_node(rn
);
5623 /* Update an aggregate as routes are added/removed from the BGP table */
5624 static void bgp_aggregate_route(struct bgp
*bgp
, struct prefix
*p
,
5625 struct bgp_path_info
*pinew
, afi_t afi
,
5626 safi_t safi
, struct bgp_path_info
*del
,
5627 struct bgp_aggregate
*aggregate
)
5629 struct bgp_table
*table
;
5630 struct bgp_node
*top
;
5631 struct bgp_node
*rn
;
5633 struct aspath
*aspath
= NULL
;
5634 struct aspath
*asmerge
= NULL
;
5635 struct community
*community
= NULL
;
5636 struct community
*commerge
= NULL
;
5637 struct ecommunity
*ecommunity
= NULL
;
5638 struct ecommunity
*ecommerge
= NULL
;
5639 struct lcommunity
*lcommunity
= NULL
;
5640 struct lcommunity
*lcommerge
= NULL
;
5641 struct bgp_path_info
*pi
;
5642 unsigned long match
= 0;
5643 uint8_t atomic_aggregate
= 0;
5645 /* ORIGIN attribute: If at least one route among routes that are
5646 aggregated has ORIGIN with the value INCOMPLETE, then the
5647 aggregated route must have the ORIGIN attribute with the value
5648 INCOMPLETE. Otherwise, if at least one route among routes that
5649 are aggregated has ORIGIN with the value EGP, then the aggregated
5650 route must have the origin attribute with the value EGP. In all
5651 other case the value of the ORIGIN attribute of the aggregated
5652 route is INTERNAL. */
5653 origin
= BGP_ORIGIN_IGP
;
5655 table
= bgp
->rib
[afi
][safi
];
5657 top
= bgp_node_get(table
, p
);
5658 for (rn
= bgp_node_get(table
, p
); rn
;
5659 rn
= bgp_route_next_until(rn
, top
)) {
5660 if (rn
->p
.prefixlen
<= p
->prefixlen
)
5665 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
5666 if (BGP_PATH_HOLDDOWN(pi
))
5669 if (del
&& pi
== del
)
5673 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
))
5674 atomic_aggregate
= 1;
5676 if (pi
->sub_type
== BGP_ROUTE_AGGREGATE
)
5680 * summary-only aggregate route suppress
5681 * aggregated route announcements.
5683 if (aggregate
->summary_only
) {
5684 (bgp_path_info_extra_get(pi
))->suppress
++;
5685 bgp_path_info_set_flag(rn
, pi
,
5686 BGP_PATH_ATTR_CHANGED
);
5693 * If at least one route among routes that are
5694 * aggregated has ORIGIN with the value INCOMPLETE,
5695 * then the aggregated route MUST have the ORIGIN
5696 * attribute with the value INCOMPLETE. Otherwise, if
5697 * at least one route among routes that are aggregated
5698 * has ORIGIN with the value EGP, then the aggregated
5699 * route MUST have the ORIGIN attribute with the value
5702 if (origin
< pi
->attr
->origin
)
5703 origin
= pi
->attr
->origin
;
5705 if (!aggregate
->as_set
)
5709 * as-set aggregate route generate origin, as path,
5710 * and community aggregation.
5713 asmerge
= aspath_aggregate(aspath
,
5715 aspath_free(aspath
);
5718 aspath
= aspath_dup(pi
->attr
->aspath
);
5720 if (pi
->attr
->community
) {
5722 commerge
= community_merge(
5723 community
, pi
->attr
->community
);
5725 community_uniq_sort(commerge
);
5726 community_free(&commerge
);
5728 community
= community_dup(
5729 pi
->attr
->community
);
5732 if (pi
->attr
->ecommunity
) {
5734 ecommerge
= ecommunity_merge(
5736 pi
->attr
->ecommunity
);
5738 ecommunity_uniq_sort(ecommerge
);
5739 ecommunity_free(&ecommerge
);
5741 ecommunity
= ecommunity_dup(
5742 pi
->attr
->ecommunity
);
5745 if (pi
->attr
->lcommunity
) {
5747 lcommerge
= lcommunity_merge(
5749 pi
->attr
->lcommunity
);
5751 lcommunity_uniq_sort(lcommerge
);
5752 lcommunity_free(&lcommerge
);
5754 lcommunity
= lcommunity_dup(
5755 pi
->attr
->lcommunity
);
5759 bgp_process(bgp
, rn
, afi
, safi
);
5761 bgp_unlock_node(top
);
5766 if (aggregate
->summary_only
)
5767 (bgp_path_info_extra_get(pinew
))->suppress
++;
5769 if (origin
< pinew
->attr
->origin
)
5770 origin
= pinew
->attr
->origin
;
5772 if (aggregate
->as_set
) {
5774 asmerge
= aspath_aggregate(aspath
,
5775 pinew
->attr
->aspath
);
5776 aspath_free(aspath
);
5779 aspath
= aspath_dup(pinew
->attr
->aspath
);
5781 if (pinew
->attr
->community
) {
5783 commerge
= community_merge(
5785 pinew
->attr
->community
);
5787 community_uniq_sort(commerge
);
5788 community_free(&commerge
);
5790 community
= community_dup(
5791 pinew
->attr
->community
);
5794 if (pinew
->attr
->ecommunity
) {
5796 ecommerge
= ecommunity_merge(
5798 pinew
->attr
->ecommunity
);
5800 ecommunity_uniq_sort(ecommerge
);
5801 ecommunity_free(&ecommerge
);
5803 ecommunity
= ecommunity_dup(
5804 pinew
->attr
->ecommunity
);
5807 if (pinew
->attr
->lcommunity
) {
5809 lcommerge
= lcommunity_merge(
5811 pinew
->attr
->lcommunity
);
5813 lcommunity_uniq_sort(lcommerge
);
5814 lcommunity_free(&lcommerge
);
5816 lcommunity
= lcommunity_dup(
5817 pinew
->attr
->lcommunity
);
5822 bgp_aggregate_install(bgp
, afi
, safi
, p
, origin
, aspath
, community
,
5823 ecommunity
, lcommunity
, atomic_aggregate
,
5826 if (aggregate
->count
== 0) {
5828 aspath_free(aspath
);
5830 community_free(&community
);
5832 ecommunity_free(&ecommunity
);
5834 lcommunity_free(&lcommunity
);
5838 static void bgp_aggregate_delete(struct bgp
*bgp
, struct prefix
*p
, afi_t afi
,
5839 safi_t safi
, struct bgp_aggregate
*aggregate
)
5841 struct bgp_table
*table
;
5842 struct bgp_node
*top
;
5843 struct bgp_node
*rn
;
5844 struct bgp_path_info
*pi
;
5845 unsigned long match
;
5847 table
= bgp
->rib
[afi
][safi
];
5849 /* If routes exists below this node, generate aggregate routes. */
5850 top
= bgp_node_get(table
, p
);
5851 for (rn
= bgp_node_get(table
, p
); rn
;
5852 rn
= bgp_route_next_until(rn
, top
)) {
5853 if (rn
->p
.prefixlen
<= p
->prefixlen
)
5857 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
5858 if (BGP_PATH_HOLDDOWN(pi
))
5861 if (pi
->sub_type
== BGP_ROUTE_AGGREGATE
)
5864 if (aggregate
->summary_only
&& pi
->extra
) {
5865 pi
->extra
->suppress
--;
5867 if (pi
->extra
->suppress
== 0) {
5868 bgp_path_info_set_flag(
5869 rn
, pi
, BGP_PATH_ATTR_CHANGED
);
5876 /* If this node was suppressed, process the change. */
5878 bgp_process(bgp
, rn
, afi
, safi
);
5880 bgp_unlock_node(top
);
5883 void bgp_aggregate_increment(struct bgp
*bgp
, struct prefix
*p
,
5884 struct bgp_path_info
*pi
, afi_t afi
, safi_t safi
)
5886 struct bgp_node
*child
;
5887 struct bgp_node
*rn
;
5888 struct bgp_aggregate
*aggregate
;
5889 struct bgp_table
*table
;
5891 table
= bgp
->aggregate
[afi
][safi
];
5893 /* No aggregates configured. */
5894 if (bgp_table_top_nolock(table
) == NULL
)
5897 if (p
->prefixlen
== 0)
5900 if (BGP_PATH_HOLDDOWN(pi
))
5903 child
= bgp_node_get(table
, p
);
5905 /* Aggregate address configuration check. */
5906 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock(rn
)) {
5907 aggregate
= bgp_aggregate_get_node_info(rn
);
5908 if (aggregate
!= NULL
&& rn
->p
.prefixlen
< p
->prefixlen
) {
5909 bgp_aggregate_delete(bgp
, &rn
->p
, afi
, safi
, aggregate
);
5910 bgp_aggregate_route(bgp
, &rn
->p
, pi
, afi
, safi
, NULL
,
5914 bgp_unlock_node(child
);
5917 void bgp_aggregate_decrement(struct bgp
*bgp
, struct prefix
*p
,
5918 struct bgp_path_info
*del
, afi_t afi
, safi_t safi
)
5920 struct bgp_node
*child
;
5921 struct bgp_node
*rn
;
5922 struct bgp_aggregate
*aggregate
;
5923 struct bgp_table
*table
;
5925 table
= bgp
->aggregate
[afi
][safi
];
5927 /* No aggregates configured. */
5928 if (bgp_table_top_nolock(table
) == NULL
)
5931 if (p
->prefixlen
== 0)
5934 child
= bgp_node_get(table
, p
);
5936 /* Aggregate address configuration check. */
5937 for (rn
= child
; rn
; rn
= bgp_node_parent_nolock(rn
)) {
5938 aggregate
= bgp_aggregate_get_node_info(rn
);
5939 if (aggregate
!= NULL
&& rn
->p
.prefixlen
< p
->prefixlen
) {
5940 bgp_aggregate_delete(bgp
, &rn
->p
, afi
, safi
, aggregate
);
5941 bgp_aggregate_route(bgp
, &rn
->p
, NULL
, afi
, safi
, del
,
5945 bgp_unlock_node(child
);
5948 /* Aggregate route attribute. */
5949 #define AGGREGATE_SUMMARY_ONLY 1
5950 #define AGGREGATE_AS_SET 1
5952 static int bgp_aggregate_unset(struct vty
*vty
, const char *prefix_str
,
5953 afi_t afi
, safi_t safi
)
5955 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5958 struct bgp_node
*rn
;
5959 struct bgp_aggregate
*aggregate
;
5961 /* Convert string to prefix structure. */
5962 ret
= str2prefix(prefix_str
, &p
);
5964 vty_out(vty
, "Malformed prefix\n");
5965 return CMD_WARNING_CONFIG_FAILED
;
5969 /* Old configuration check. */
5970 rn
= bgp_node_lookup(bgp
->aggregate
[afi
][safi
], &p
);
5973 "%% There is no aggregate-address configuration.\n");
5974 return CMD_WARNING_CONFIG_FAILED
;
5977 aggregate
= bgp_aggregate_get_node_info(rn
);
5978 bgp_aggregate_delete(bgp
, &p
, afi
, safi
, aggregate
);
5979 bgp_aggregate_install(bgp
, afi
, safi
, &p
, 0, NULL
, NULL
,
5980 NULL
, NULL
, 0, aggregate
);
5982 /* Unlock aggregate address configuration. */
5983 bgp_aggregate_set_node_info(rn
, NULL
);
5984 bgp_aggregate_free(aggregate
);
5985 bgp_unlock_node(rn
);
5986 bgp_unlock_node(rn
);
5991 static int bgp_aggregate_set(struct vty
*vty
, const char *prefix_str
, afi_t afi
,
5992 safi_t safi
, uint8_t summary_only
, uint8_t as_set
)
5994 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
5997 struct bgp_node
*rn
;
5998 struct bgp_aggregate
*aggregate
;
6000 /* Convert string to prefix structure. */
6001 ret
= str2prefix(prefix_str
, &p
);
6003 vty_out(vty
, "Malformed prefix\n");
6004 return CMD_WARNING_CONFIG_FAILED
;
6008 if ((afi
== AFI_IP
&& p
.prefixlen
== IPV4_MAX_BITLEN
) ||
6009 (afi
== AFI_IP6
&& p
.prefixlen
== IPV6_MAX_BITLEN
)) {
6010 vty_out(vty
, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
6012 return CMD_WARNING_CONFIG_FAILED
;
6015 /* Old configuration check. */
6016 rn
= bgp_node_get(bgp
->aggregate
[afi
][safi
], &p
);
6019 vty_out(vty
, "There is already same aggregate network.\n");
6020 /* try to remove the old entry */
6021 ret
= bgp_aggregate_unset(vty
, prefix_str
, afi
, safi
);
6023 vty_out(vty
, "Error deleting aggregate.\n");
6024 bgp_unlock_node(rn
);
6025 return CMD_WARNING_CONFIG_FAILED
;
6029 /* Make aggregate address structure. */
6030 aggregate
= bgp_aggregate_new();
6031 aggregate
->summary_only
= summary_only
;
6032 aggregate
->as_set
= as_set
;
6033 aggregate
->safi
= safi
;
6034 bgp_aggregate_set_node_info(rn
, aggregate
);
6036 /* Aggregate address insert into BGP routing table. */
6037 bgp_aggregate_route(bgp
, &p
, NULL
, afi
, safi
, NULL
, aggregate
);
6042 DEFUN (aggregate_address
,
6043 aggregate_address_cmd
,
6044 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
6045 "Configure BGP aggregate entries\n"
6046 "Aggregate prefix\n"
6047 "Generate AS set path information\n"
6048 "Filter more specific routes from updates\n"
6049 "Filter more specific routes from updates\n"
6050 "Generate AS set path information\n")
6053 argv_find(argv
, argc
, "A.B.C.D/M", &idx
);
6054 char *prefix
= argv
[idx
]->arg
;
6056 argv_find(argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
6058 int summary_only
= argv_find(argv
, argc
, "summary-only", &idx
)
6059 ? AGGREGATE_SUMMARY_ONLY
6062 return bgp_aggregate_set(vty
, prefix
, AFI_IP
, bgp_node_safi(vty
),
6063 summary_only
, as_set
);
6066 DEFUN (aggregate_address_mask
,
6067 aggregate_address_mask_cmd
,
6068 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
6069 "Configure BGP aggregate entries\n"
6070 "Aggregate address\n"
6072 "Generate AS set path information\n"
6073 "Filter more specific routes from updates\n"
6074 "Filter more specific routes from updates\n"
6075 "Generate AS set path information\n")
6078 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6079 char *prefix
= argv
[idx
]->arg
;
6080 char *mask
= argv
[idx
+ 1]->arg
;
6082 argv_find(argv
, argc
, "as-set", &idx
) ? AGGREGATE_AS_SET
: 0;
6084 int summary_only
= argv_find(argv
, argc
, "summary-only", &idx
)
6085 ? AGGREGATE_SUMMARY_ONLY
6088 char prefix_str
[BUFSIZ
];
6089 int ret
= netmask_str2prefix_str(prefix
, mask
, prefix_str
);
6092 vty_out(vty
, "%% Inconsistent address and mask\n");
6093 return CMD_WARNING_CONFIG_FAILED
;
6096 return bgp_aggregate_set(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
),
6097 summary_only
, as_set
);
6100 DEFUN (no_aggregate_address
,
6101 no_aggregate_address_cmd
,
6102 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
6104 "Configure BGP aggregate entries\n"
6105 "Aggregate prefix\n"
6106 "Generate AS set path information\n"
6107 "Filter more specific routes from updates\n"
6108 "Filter more specific routes from updates\n"
6109 "Generate AS set path information\n")
6112 argv_find(argv
, argc
, "A.B.C.D/M", &idx
);
6113 char *prefix
= argv
[idx
]->arg
;
6114 return bgp_aggregate_unset(vty
, prefix
, AFI_IP
, bgp_node_safi(vty
));
6117 DEFUN (no_aggregate_address_mask
,
6118 no_aggregate_address_mask_cmd
,
6119 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
6121 "Configure BGP aggregate entries\n"
6122 "Aggregate address\n"
6124 "Generate AS set path information\n"
6125 "Filter more specific routes from updates\n"
6126 "Filter more specific routes from updates\n"
6127 "Generate AS set path information\n")
6130 argv_find(argv
, argc
, "A.B.C.D", &idx
);
6131 char *prefix
= argv
[idx
]->arg
;
6132 char *mask
= argv
[idx
+ 1]->arg
;
6134 char prefix_str
[BUFSIZ
];
6135 int ret
= netmask_str2prefix_str(prefix
, mask
, prefix_str
);
6138 vty_out(vty
, "%% Inconsistent address and mask\n");
6139 return CMD_WARNING_CONFIG_FAILED
;
6142 return bgp_aggregate_unset(vty
, prefix_str
, AFI_IP
, bgp_node_safi(vty
));
6145 DEFUN (ipv6_aggregate_address
,
6146 ipv6_aggregate_address_cmd
,
6147 "aggregate-address X:X::X:X/M [summary-only]",
6148 "Configure BGP aggregate entries\n"
6149 "Aggregate prefix\n"
6150 "Filter more specific routes from updates\n")
6153 argv_find(argv
, argc
, "X:X::X:X/M", &idx
);
6154 char *prefix
= argv
[idx
]->arg
;
6155 int sum_only
= argv_find(argv
, argc
, "summary-only", &idx
)
6156 ? AGGREGATE_SUMMARY_ONLY
6158 return bgp_aggregate_set(vty
, prefix
, AFI_IP6
, SAFI_UNICAST
, sum_only
,
6162 DEFUN (no_ipv6_aggregate_address
,
6163 no_ipv6_aggregate_address_cmd
,
6164 "no aggregate-address X:X::X:X/M [summary-only]",
6166 "Configure BGP aggregate entries\n"
6167 "Aggregate prefix\n"
6168 "Filter more specific routes from updates\n")
6171 argv_find(argv
, argc
, "X:X::X:X/M", &idx
);
6172 char *prefix
= argv
[idx
]->arg
;
6173 return bgp_aggregate_unset(vty
, prefix
, AFI_IP6
, SAFI_UNICAST
);
6176 /* Redistribute route treatment. */
6177 void bgp_redistribute_add(struct bgp
*bgp
, struct prefix
*p
,
6178 const union g_addr
*nexthop
, ifindex_t ifindex
,
6179 enum nexthop_types_t nhtype
, uint32_t metric
,
6180 uint8_t type
, unsigned short instance
,
6183 struct bgp_path_info
*new;
6184 struct bgp_path_info
*bpi
;
6185 struct bgp_path_info rmap_path
;
6186 struct bgp_node
*bn
;
6188 struct attr
*new_attr
;
6191 struct bgp_redist
*red
;
6193 /* Make default attribute. */
6194 bgp_attr_default_set(&attr
, BGP_ORIGIN_INCOMPLETE
);
6197 case NEXTHOP_TYPE_IFINDEX
:
6199 case NEXTHOP_TYPE_IPV4
:
6200 case NEXTHOP_TYPE_IPV4_IFINDEX
:
6201 attr
.nexthop
= nexthop
->ipv4
;
6203 case NEXTHOP_TYPE_IPV6
:
6204 case NEXTHOP_TYPE_IPV6_IFINDEX
:
6205 attr
.mp_nexthop_global
= nexthop
->ipv6
;
6206 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
6208 case NEXTHOP_TYPE_BLACKHOLE
:
6209 switch (p
->family
) {
6211 attr
.nexthop
.s_addr
= INADDR_ANY
;
6214 memset(&attr
.mp_nexthop_global
, 0,
6215 sizeof(attr
.mp_nexthop_global
));
6216 attr
.mp_nexthop_len
= BGP_ATTR_NHLEN_IPV6_GLOBAL
;
6221 attr
.nh_ifindex
= ifindex
;
6224 attr
.flag
|= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
);
6227 afi
= family2afi(p
->family
);
6229 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6231 struct attr attr_new
;
6233 /* Copy attribute for modification. */
6234 bgp_attr_dup(&attr_new
, &attr
);
6236 if (red
->redist_metric_flag
)
6237 attr_new
.med
= red
->redist_metric
;
6239 /* Apply route-map. */
6240 if (red
->rmap
.name
) {
6241 memset(&rmap_path
, 0, sizeof(struct bgp_path_info
));
6242 rmap_path
.peer
= bgp
->peer_self
;
6243 rmap_path
.attr
= &attr_new
;
6245 SET_FLAG(bgp
->peer_self
->rmap_type
,
6246 PEER_RMAP_TYPE_REDISTRIBUTE
);
6248 ret
= route_map_apply(red
->rmap
.map
, p
, RMAP_BGP
,
6251 bgp
->peer_self
->rmap_type
= 0;
6253 if (ret
== RMAP_DENYMATCH
) {
6254 /* Free uninterned attribute. */
6255 bgp_attr_flush(&attr_new
);
6257 /* Unintern original. */
6258 aspath_unintern(&attr
.aspath
);
6259 bgp_redistribute_delete(bgp
, p
, type
, instance
);
6264 if (bgp_flag_check(bgp
, BGP_FLAG_GRACEFUL_SHUTDOWN
))
6265 bgp_attr_add_gshut_community(&attr_new
);
6267 bn
= bgp_afi_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], afi
,
6268 SAFI_UNICAST
, p
, NULL
);
6270 new_attr
= bgp_attr_intern(&attr_new
);
6272 for (bpi
= bn
->info
; bpi
; bpi
= bpi
->next
)
6273 if (bpi
->peer
== bgp
->peer_self
6274 && bpi
->sub_type
== BGP_ROUTE_REDISTRIBUTE
)
6278 /* Ensure the (source route) type is updated. */
6280 if (attrhash_cmp(bpi
->attr
, new_attr
)
6281 && !CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
)) {
6282 bgp_attr_unintern(&new_attr
);
6283 aspath_unintern(&attr
.aspath
);
6284 bgp_unlock_node(bn
);
6287 /* The attribute is changed. */
6288 bgp_path_info_set_flag(bn
, bpi
,
6289 BGP_PATH_ATTR_CHANGED
);
6291 /* Rewrite BGP route information. */
6292 if (CHECK_FLAG(bpi
->flags
, BGP_PATH_REMOVED
))
6293 bgp_path_info_restore(bn
, bpi
);
6295 bgp_aggregate_decrement(
6296 bgp
, p
, bpi
, afi
, SAFI_UNICAST
);
6297 bgp_attr_unintern(&bpi
->attr
);
6298 bpi
->attr
= new_attr
;
6299 bpi
->uptime
= bgp_clock();
6301 /* Process change. */
6302 bgp_aggregate_increment(bgp
, p
, bpi
, afi
,
6304 bgp_process(bgp
, bn
, afi
, SAFI_UNICAST
);
6305 bgp_unlock_node(bn
);
6306 aspath_unintern(&attr
.aspath
);
6308 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6310 == BGP_INSTANCE_TYPE_DEFAULT
)) {
6312 vpn_leak_from_vrf_update(
6313 bgp_get_default(), bgp
, bpi
);
6319 new = info_make(type
, BGP_ROUTE_REDISTRIBUTE
, instance
,
6320 bgp
->peer_self
, new_attr
, bn
);
6321 SET_FLAG(new->flags
, BGP_PATH_VALID
);
6323 bgp_aggregate_increment(bgp
, p
, new, afi
, SAFI_UNICAST
);
6324 bgp_path_info_add(bn
, new);
6325 bgp_unlock_node(bn
);
6326 bgp_process(bgp
, bn
, afi
, SAFI_UNICAST
);
6328 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6329 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6331 vpn_leak_from_vrf_update(bgp_get_default(), bgp
, new);
6335 /* Unintern original. */
6336 aspath_unintern(&attr
.aspath
);
6339 void bgp_redistribute_delete(struct bgp
*bgp
, struct prefix
*p
, uint8_t type
,
6340 unsigned short instance
)
6343 struct bgp_node
*rn
;
6344 struct bgp_path_info
*pi
;
6345 struct bgp_redist
*red
;
6347 afi
= family2afi(p
->family
);
6349 red
= bgp_redist_lookup(bgp
, afi
, type
, instance
);
6351 rn
= bgp_afi_node_get(bgp
->rib
[afi
][SAFI_UNICAST
], afi
,
6352 SAFI_UNICAST
, p
, NULL
);
6354 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
6355 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== type
)
6359 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6360 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6362 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6365 bgp_aggregate_decrement(bgp
, p
, pi
, afi
, SAFI_UNICAST
);
6366 bgp_path_info_delete(rn
, pi
);
6367 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
6369 bgp_unlock_node(rn
);
6373 /* Withdraw specified route type's route. */
6374 void bgp_redistribute_withdraw(struct bgp
*bgp
, afi_t afi
, int type
,
6375 unsigned short instance
)
6377 struct bgp_node
*rn
;
6378 struct bgp_path_info
*pi
;
6379 struct bgp_table
*table
;
6381 table
= bgp
->rib
[afi
][SAFI_UNICAST
];
6383 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
6384 for (pi
= rn
->info
; pi
; pi
= pi
->next
)
6385 if (pi
->peer
== bgp
->peer_self
&& pi
->type
== type
6386 && pi
->instance
== instance
)
6390 if ((bgp
->inst_type
== BGP_INSTANCE_TYPE_VRF
)
6391 || (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)) {
6393 vpn_leak_from_vrf_withdraw(bgp_get_default(),
6396 bgp_aggregate_decrement(bgp
, &rn
->p
, pi
, afi
,
6398 bgp_path_info_delete(rn
, pi
);
6399 bgp_process(bgp
, rn
, afi
, SAFI_UNICAST
);
6404 /* Static function to display route. */
6405 static void route_vty_out_route(struct prefix
*p
, struct vty
*vty
,
6412 if (p
->family
== AF_INET
) {
6416 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6419 json_object_string_add(json
, "prefix",
6420 inet_ntop(p
->family
,
6423 json_object_int_add(json
, "prefixLen", p
->prefixlen
);
6424 prefix2str(p
, buf2
, PREFIX_STRLEN
);
6425 json_object_string_add(json
, "network", buf2
);
6427 } else if (p
->family
== AF_ETHERNET
) {
6428 prefix2str(p
, buf
, PREFIX_STRLEN
);
6429 len
= vty_out(vty
, "%s", buf
);
6430 } else if (p
->family
== AF_EVPN
) {
6434 bgp_evpn_route2str((struct prefix_evpn
*)p
, buf
,
6437 bgp_evpn_route2json((struct prefix_evpn
*)p
, json
);
6438 } else if (p
->family
== AF_FLOWSPEC
) {
6439 route_vty_out_flowspec(vty
, p
, NULL
,
6441 NLRI_STRING_FORMAT_JSON_SIMPLE
:
6442 NLRI_STRING_FORMAT_MIN
, json
);
6447 inet_ntop(p
->family
, &p
->u
.prefix
, buf
, BUFSIZ
),
6450 json_object_string_add(json
, "prefix",
6451 inet_ntop(p
->family
,
6454 json_object_int_add(json
, "prefixLen", p
->prefixlen
);
6455 prefix2str(p
, buf2
, PREFIX_STRLEN
);
6456 json_object_string_add(json
, "network", buf2
);
6463 vty_out(vty
, "\n%*s", 20, " ");
6465 vty_out(vty
, "%*s", len
, " ");
6469 enum bgp_display_type
{
6473 /* Print the short form route status for a bgp_path_info */
6474 static void route_vty_short_status_out(struct vty
*vty
,
6475 struct bgp_path_info
*path
,
6476 json_object
*json_path
)
6480 /* Route status display. */
6481 if (CHECK_FLAG(path
->flags
, BGP_PATH_REMOVED
))
6482 json_object_boolean_true_add(json_path
, "removed");
6484 if (CHECK_FLAG(path
->flags
, BGP_PATH_STALE
))
6485 json_object_boolean_true_add(json_path
, "stale");
6487 if (path
->extra
&& path
->extra
->suppress
)
6488 json_object_boolean_true_add(json_path
, "suppressed");
6490 if (CHECK_FLAG(path
->flags
, BGP_PATH_VALID
)
6491 && !CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
))
6492 json_object_boolean_true_add(json_path
, "valid");
6495 if (CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
))
6496 json_object_boolean_true_add(json_path
, "history");
6498 if (CHECK_FLAG(path
->flags
, BGP_PATH_DAMPED
))
6499 json_object_boolean_true_add(json_path
, "damped");
6501 if (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
))
6502 json_object_boolean_true_add(json_path
, "bestpath");
6504 if (CHECK_FLAG(path
->flags
, BGP_PATH_MULTIPATH
))
6505 json_object_boolean_true_add(json_path
, "multipath");
6507 /* Internal route. */
6508 if ((path
->peer
->as
)
6509 && (path
->peer
->as
== path
->peer
->local_as
))
6510 json_object_string_add(json_path
, "pathFrom",
6513 json_object_string_add(json_path
, "pathFrom",
6519 /* Route status display. */
6520 if (CHECK_FLAG(path
->flags
, BGP_PATH_REMOVED
))
6522 else if (CHECK_FLAG(path
->flags
, BGP_PATH_STALE
))
6524 else if (path
->extra
&& path
->extra
->suppress
)
6526 else if (CHECK_FLAG(path
->flags
, BGP_PATH_VALID
)
6527 && !CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
))
6533 if (CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
))
6535 else if (CHECK_FLAG(path
->flags
, BGP_PATH_DAMPED
))
6537 else if (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
))
6539 else if (CHECK_FLAG(path
->flags
, BGP_PATH_MULTIPATH
))
6544 /* Internal route. */
6545 if (path
->peer
&& (path
->peer
->as
)
6546 && (path
->peer
->as
== path
->peer
->local_as
))
6552 /* called from terminal list command */
6553 void route_vty_out(struct vty
*vty
, struct prefix
*p
,
6554 struct bgp_path_info
*path
, int display
, safi_t safi
,
6555 json_object
*json_paths
)
6558 json_object
*json_path
= NULL
;
6559 json_object
*json_nexthops
= NULL
;
6560 json_object
*json_nexthop_global
= NULL
;
6561 json_object
*json_nexthop_ll
= NULL
;
6562 char vrf_id_str
[VRF_NAMSIZ
] = {0};
6564 CHECK_FLAG(path
->flags
, BGP_PATH_ANNC_NH_SELF
) ? true : false;
6565 bool nexthop_othervrf
= false;
6566 vrf_id_t nexthop_vrfid
= VRF_DEFAULT
;
6567 const char *nexthop_vrfname
= "Default";
6570 json_path
= json_object_new_object();
6572 /* short status lead text */
6573 route_vty_short_status_out(vty
, path
, json_path
);
6576 /* print prefix and mask */
6578 route_vty_out_route(p
, vty
, json_path
);
6580 vty_out(vty
, "%*s", 17, " ");
6582 route_vty_out_route(p
, vty
, json_path
);
6585 /* Print attribute */
6589 json_object_array_add(json_paths
, json_path
);
6597 * If vrf id of nexthop is different from that of prefix,
6598 * set up printable string to append
6600 if (path
->extra
&& path
->extra
->bgp_orig
) {
6601 const char *self
= "";
6606 nexthop_othervrf
= true;
6607 nexthop_vrfid
= path
->extra
->bgp_orig
->vrf_id
;
6609 if (path
->extra
->bgp_orig
->vrf_id
== VRF_UNKNOWN
)
6610 snprintf(vrf_id_str
, sizeof(vrf_id_str
),
6611 "@%s%s", VRFID_NONE_STR
, self
);
6613 snprintf(vrf_id_str
, sizeof(vrf_id_str
), "@%u%s",
6614 path
->extra
->bgp_orig
->vrf_id
, self
);
6616 if (path
->extra
->bgp_orig
->inst_type
6617 != BGP_INSTANCE_TYPE_DEFAULT
)
6619 nexthop_vrfname
= path
->extra
->bgp_orig
->name
;
6621 const char *self
= "";
6626 snprintf(vrf_id_str
, sizeof(vrf_id_str
), "%s", self
);
6630 * For ENCAP and EVPN routes, nexthop address family is not
6631 * neccessarily the same as the prefix address family.
6632 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6633 * EVPN routes are also exchanged with a MP nexthop. Currently,
6635 * is only IPv4, the value will be present in either
6637 * attr->mp_nexthop_global_in
6639 if ((safi
== SAFI_ENCAP
) || (safi
== SAFI_MPLS_VPN
)) {
6642 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
6646 sprintf(nexthop
, "%s",
6647 inet_ntop(af
, &attr
->mp_nexthop_global_in
, buf
,
6651 sprintf(nexthop
, "%s",
6652 inet_ntop(af
, &attr
->mp_nexthop_global
, buf
,
6656 sprintf(nexthop
, "?");
6661 json_nexthop_global
= json_object_new_object();
6663 json_object_string_add(json_nexthop_global
, "afi",
6664 (af
== AF_INET
) ? "ip" : "ipv6");
6665 json_object_string_add(json_nexthop_global
,
6666 (af
== AF_INET
) ? "ip" : "ipv6",
6668 json_object_boolean_true_add(json_nexthop_global
,
6671 vty_out(vty
, "%s%s", nexthop
, vrf_id_str
);
6672 } else if (safi
== SAFI_EVPN
) {
6674 json_nexthop_global
= json_object_new_object();
6676 json_object_string_add(json_nexthop_global
, "ip",
6677 inet_ntoa(attr
->nexthop
));
6678 json_object_string_add(json_nexthop_global
, "afi",
6680 json_object_boolean_true_add(json_nexthop_global
,
6683 vty_out(vty
, "%-16s%s", inet_ntoa(attr
->nexthop
),
6685 } else if (safi
== SAFI_FLOWSPEC
) {
6686 if (attr
->nexthop
.s_addr
!= 0) {
6688 json_nexthop_global
= json_object_new_object();
6689 json_object_string_add(
6690 json_nexthop_global
, "ip",
6691 inet_ntoa(attr
->nexthop
));
6692 json_object_string_add(json_nexthop_global
,
6694 json_object_boolean_true_add(
6695 json_nexthop_global
,
6698 vty_out(vty
, "%-16s", inet_ntoa(attr
->nexthop
));
6701 } else if (p
->family
== AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6703 json_nexthop_global
= json_object_new_object();
6705 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_EVPN
))
6706 json_object_string_add(
6707 json_nexthop_global
, "ip",
6708 inet_ntoa(attr
->mp_nexthop_global_in
));
6710 json_object_string_add(
6711 json_nexthop_global
, "ip",
6712 inet_ntoa(attr
->nexthop
));
6714 json_object_string_add(json_nexthop_global
, "afi",
6716 json_object_boolean_true_add(json_nexthop_global
,
6721 snprintf(buf
, sizeof(buf
), "%s%s",
6722 inet_ntoa(attr
->nexthop
), vrf_id_str
);
6723 vty_out(vty
, "%-16s", buf
);
6728 else if (p
->family
== AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6733 json_nexthop_global
= json_object_new_object();
6734 json_object_string_add(
6735 json_nexthop_global
, "ip",
6736 inet_ntop(AF_INET6
, &attr
->mp_nexthop_global
,
6738 json_object_string_add(json_nexthop_global
, "afi",
6740 json_object_string_add(json_nexthop_global
, "scope",
6743 /* We display both LL & GL if both have been
6745 if ((attr
->mp_nexthop_len
== 32)
6746 || (path
->peer
->conf_if
)) {
6747 json_nexthop_ll
= json_object_new_object();
6748 json_object_string_add(
6749 json_nexthop_ll
, "ip",
6751 &attr
->mp_nexthop_local
, buf
,
6753 json_object_string_add(json_nexthop_ll
, "afi",
6755 json_object_string_add(json_nexthop_ll
, "scope",
6758 if ((IPV6_ADDR_CMP(&attr
->mp_nexthop_global
,
6759 &attr
->mp_nexthop_local
)
6761 && !attr
->mp_nexthop_prefer_global
)
6762 json_object_boolean_true_add(
6763 json_nexthop_ll
, "used");
6765 json_object_boolean_true_add(
6766 json_nexthop_global
, "used");
6768 json_object_boolean_true_add(
6769 json_nexthop_global
, "used");
6771 /* Display LL if LL/Global both in table unless
6772 * prefer-global is set */
6773 if (((attr
->mp_nexthop_len
== 32)
6774 && !attr
->mp_nexthop_prefer_global
)
6775 || (path
->peer
->conf_if
)) {
6776 if (path
->peer
->conf_if
) {
6777 len
= vty_out(vty
, "%s",
6778 path
->peer
->conf_if
);
6779 len
= 16 - len
; /* len of IPv6
6785 vty_out(vty
, "\n%*s", 36, " ");
6787 vty_out(vty
, "%*s", len
, " ");
6793 &attr
->mp_nexthop_local
,
6799 vty_out(vty
, "\n%*s", 36, " ");
6801 vty_out(vty
, "%*s", len
, " ");
6807 &attr
->mp_nexthop_global
, buf
,
6813 vty_out(vty
, "\n%*s", 36, " ");
6815 vty_out(vty
, "%*s", len
, " ");
6821 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6825 * Adding "metric" field to match with corresponding
6826 * CLI. "med" will be deprecated in future.
6828 json_object_int_add(json_path
, "med", attr
->med
);
6829 json_object_int_add(json_path
, "metric", attr
->med
);
6831 vty_out(vty
, "%10u", attr
->med
);
6832 else if (!json_paths
)
6836 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
6840 * Adding "locPrf" field to match with corresponding
6841 * CLI. "localPref" will be deprecated in future.
6843 json_object_int_add(json_path
, "localpref",
6845 json_object_int_add(json_path
, "locPrf",
6848 vty_out(vty
, "%7u", attr
->local_pref
);
6849 else if (!json_paths
)
6853 json_object_int_add(json_path
, "weight", attr
->weight
);
6855 vty_out(vty
, "%7u ", attr
->weight
);
6859 json_object_string_add(
6860 json_path
, "peerId",
6861 sockunion2str(&path
->peer
->su
, buf
, SU_ADDRSTRLEN
));
6869 * Adding "path" field to match with corresponding
6870 * CLI. "aspath" will be deprecated in future.
6872 json_object_string_add(json_path
, "aspath",
6874 json_object_string_add(json_path
, "path",
6877 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
6882 json_object_string_add(json_path
, "origin",
6883 bgp_origin_long_str
[attr
->origin
]);
6885 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
6889 json_object_boolean_true_add(json_path
,
6890 "announceNexthopSelf");
6891 if (nexthop_othervrf
) {
6892 json_object_string_add(json_path
, "nhVrfName",
6895 json_object_int_add(json_path
, "nhVrfId",
6896 ((nexthop_vrfid
== VRF_UNKNOWN
)
6898 : (int)nexthop_vrfid
));
6903 if (json_nexthop_global
|| json_nexthop_ll
) {
6904 json_nexthops
= json_object_new_array();
6906 if (json_nexthop_global
)
6907 json_object_array_add(json_nexthops
,
6908 json_nexthop_global
);
6910 if (json_nexthop_ll
)
6911 json_object_array_add(json_nexthops
,
6914 json_object_object_add(json_path
, "nexthops",
6918 json_object_array_add(json_paths
, json_path
);
6922 /* prints an additional line, indented, with VNC info, if
6924 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
))
6925 rfapi_vty_out_vncinfo(vty
, p
, path
, safi
);
6930 /* called from terminal list command */
6931 void route_vty_out_tmp(struct vty
*vty
, struct prefix
*p
, struct attr
*attr
,
6932 safi_t safi
, bool use_json
, json_object
*json_ar
)
6934 json_object
*json_status
= NULL
;
6935 json_object
*json_net
= NULL
;
6938 /* Route status display. */
6940 json_status
= json_object_new_object();
6941 json_net
= json_object_new_object();
6948 /* print prefix and mask */
6950 json_object_string_add(
6951 json_net
, "addrPrefix",
6952 inet_ntop(p
->family
, &p
->u
.prefix
, buff
, BUFSIZ
));
6953 json_object_int_add(json_net
, "prefixLen", p
->prefixlen
);
6954 prefix2str(p
, buf2
, PREFIX_STRLEN
);
6955 json_object_string_add(json_net
, "network", buf2
);
6957 route_vty_out_route(p
, vty
, NULL
);
6959 /* Print attribute */
6962 if (p
->family
== AF_INET
6963 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6964 || safi
== SAFI_EVPN
6965 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
6966 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
6967 || safi
== SAFI_EVPN
)
6968 json_object_string_add(
6969 json_net
, "nextHop",
6971 attr
->mp_nexthop_global_in
));
6973 json_object_string_add(
6974 json_net
, "nextHop",
6975 inet_ntoa(attr
->nexthop
));
6976 } else if (p
->family
== AF_INET6
6977 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
6980 json_object_string_add(
6981 json_net
, "nextHopGlobal",
6983 &attr
->mp_nexthop_global
, buf
,
6988 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
6989 json_object_int_add(json_net
, "metric",
6992 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
6995 * Adding "locPrf" field to match with
6996 * corresponding CLI. "localPref" will be
6997 * deprecated in future.
6999 json_object_int_add(json_net
, "localPref",
7001 json_object_int_add(json_net
, "locPrf",
7005 json_object_int_add(json_net
, "weight", attr
->weight
);
7011 * Adding "path" field to match with
7012 * corresponding CLI. "localPref" will be
7013 * deprecated in future.
7015 json_object_string_add(json_net
, "asPath",
7017 json_object_string_add(json_net
, "path",
7022 json_object_string_add(json_net
, "bgpOriginCode",
7023 bgp_origin_str
[attr
->origin
]);
7025 if (p
->family
== AF_INET
7026 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7027 || safi
== SAFI_EVPN
7028 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7029 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7030 || safi
== SAFI_EVPN
)
7031 vty_out(vty
, "%-16s",
7033 attr
->mp_nexthop_global_in
));
7035 vty_out(vty
, "%-16s",
7036 inet_ntoa(attr
->nexthop
));
7037 } else if (p
->family
== AF_INET6
7038 || BGP_ATTR_NEXTHOP_AFI_IP6(attr
)) {
7045 &attr
->mp_nexthop_global
, buf
,
7049 vty_out(vty
, "\n%*s", 36, " ");
7051 vty_out(vty
, "%*s", len
, " ");
7054 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
))
7055 vty_out(vty
, "%10u", attr
->med
);
7059 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
))
7060 vty_out(vty
, "%7u", attr
->local_pref
);
7064 vty_out(vty
, "%7u ", attr
->weight
);
7068 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7071 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7075 json_object_boolean_true_add(json_status
, "*");
7076 json_object_boolean_true_add(json_status
, ">");
7077 json_object_object_add(json_net
, "appliedStatusSymbols",
7079 char buf_cut
[BUFSIZ
];
7080 json_object_object_add(
7082 inet_ntop(p
->family
, &p
->u
.prefix
, buf_cut
, BUFSIZ
),
7088 void route_vty_out_tag(struct vty
*vty
, struct prefix
*p
,
7089 struct bgp_path_info
*path
, int display
, safi_t safi
,
7092 json_object
*json_out
= NULL
;
7094 mpls_label_t label
= MPLS_INVALID_LABEL
;
7100 json_out
= json_object_new_object();
7102 /* short status lead text */
7103 route_vty_short_status_out(vty
, path
, json_out
);
7105 /* print prefix and mask */
7108 route_vty_out_route(p
, vty
, NULL
);
7110 vty_out(vty
, "%*s", 17, " ");
7113 /* Print attribute */
7116 if (((p
->family
== AF_INET
)
7117 && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
7118 || (safi
== SAFI_EVPN
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
7119 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7120 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7121 || safi
== SAFI_EVPN
) {
7123 json_object_string_add(
7124 json_out
, "mpNexthopGlobalIn",
7126 attr
->mp_nexthop_global_in
));
7128 vty_out(vty
, "%-16s",
7130 attr
->mp_nexthop_global_in
));
7133 json_object_string_add(
7134 json_out
, "nexthop",
7135 inet_ntoa(attr
->nexthop
));
7137 vty_out(vty
, "%-16s",
7138 inet_ntoa(attr
->nexthop
));
7140 } else if (((p
->family
== AF_INET6
)
7141 && ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)))
7142 || (safi
== SAFI_EVPN
7143 && BGP_ATTR_NEXTHOP_AFI_IP6(attr
))
7144 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7148 if (attr
->mp_nexthop_len
7149 == BGP_ATTR_NHLEN_IPV6_GLOBAL
) {
7151 json_object_string_add(
7152 json_out
, "mpNexthopGlobalIn",
7155 &attr
->mp_nexthop_global
,
7156 buf_a
, sizeof(buf_a
)));
7161 &attr
->mp_nexthop_global
,
7162 buf_a
, sizeof(buf_a
)));
7163 } else if (attr
->mp_nexthop_len
7164 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) {
7167 &attr
->mp_nexthop_global
,
7168 buf_a
, sizeof(buf_a
));
7170 &attr
->mp_nexthop_local
,
7171 buf_b
, sizeof(buf_b
));
7172 sprintf(buf_c
, "%s(%s)", buf_a
, buf_b
);
7173 json_object_string_add(
7175 "mpNexthopGlobalLocal", buf_c
);
7177 vty_out(vty
, "%s(%s)",
7180 &attr
->mp_nexthop_global
,
7181 buf_a
, sizeof(buf_a
)),
7184 &attr
->mp_nexthop_local
,
7185 buf_b
, sizeof(buf_b
)));
7190 label
= decode_label(&path
->extra
->label
[0]);
7192 if (bgp_is_valid_label(&label
)) {
7194 json_object_int_add(json_out
, "notag", label
);
7195 json_object_array_add(json
, json_out
);
7197 vty_out(vty
, "notag/%d", label
);
7203 void route_vty_out_overlay(struct vty
*vty
, struct prefix
*p
,
7204 struct bgp_path_info
*path
, int display
,
7205 json_object
*json_paths
)
7209 json_object
*json_path
= NULL
;
7212 json_path
= json_object_new_object();
7217 /* short status lead text */
7218 route_vty_short_status_out(vty
, path
, json_path
);
7220 /* print prefix and mask */
7222 route_vty_out_route(p
, vty
, NULL
);
7224 vty_out(vty
, "%*s", 17, " ");
7226 /* Print attribute */
7230 int af
= NEXTHOP_FAMILY(attr
->mp_nexthop_len
);
7234 vty_out(vty
, "%-16s",
7235 inet_ntop(af
, &attr
->mp_nexthop_global_in
, buf
,
7239 vty_out(vty
, "%s(%s)",
7240 inet_ntop(af
, &attr
->mp_nexthop_global
, buf
,
7242 inet_ntop(af
, &attr
->mp_nexthop_local
, buf1
,
7249 char *str
= esi2str(&(attr
->evpn_overlay
.eth_s_id
));
7251 vty_out(vty
, "%s", str
);
7252 XFREE(MTYPE_TMP
, str
);
7254 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn
*)p
)) {
7256 inet_ntoa(attr
->evpn_overlay
.gw_ip
.ipv4
));
7257 } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn
*)p
)) {
7260 &(attr
->evpn_overlay
.gw_ip
.ipv6
), buf
,
7263 if (attr
->ecommunity
) {
7265 struct ecommunity_val
*routermac
= ecommunity_lookup(
7266 attr
->ecommunity
, ECOMMUNITY_ENCODE_EVPN
,
7267 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC
);
7269 mac
= ecom_mac2str((char *)routermac
->val
);
7271 vty_out(vty
, "/%s", (char *)mac
);
7272 XFREE(MTYPE_TMP
, mac
);
7280 /* dampening route */
7281 static void damp_route_vty_out(struct vty
*vty
, struct prefix
*p
,
7282 struct bgp_path_info
*path
, int display
,
7283 safi_t safi
, bool use_json
, json_object
*json
)
7287 char timebuf
[BGP_UPTIME_LEN
];
7289 /* short status lead text */
7290 route_vty_short_status_out(vty
, path
, json
);
7292 /* print prefix and mask */
7295 route_vty_out_route(p
, vty
, NULL
);
7297 vty_out(vty
, "%*s", 17, " ");
7300 len
= vty_out(vty
, "%s", path
->peer
->host
);
7304 vty_out(vty
, "\n%*s", 34, " ");
7307 json_object_int_add(json
, "peerHost", len
);
7309 vty_out(vty
, "%*s", len
, " ");
7313 bgp_damp_reuse_time_vty(vty
, path
, timebuf
, BGP_UPTIME_LEN
,
7317 bgp_damp_reuse_time_vty(vty
, path
, timebuf
,
7318 BGP_UPTIME_LEN
, use_json
,
7321 /* Print attribute */
7327 json_object_string_add(json
, "asPath",
7330 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7335 json_object_string_add(json
, "origin",
7336 bgp_origin_str
[attr
->origin
]);
7338 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7345 static void flap_route_vty_out(struct vty
*vty
, struct prefix
*p
,
7346 struct bgp_path_info
*path
, int display
,
7347 safi_t safi
, bool use_json
, json_object
*json
)
7350 struct bgp_damp_info
*bdi
;
7351 char timebuf
[BGP_UPTIME_LEN
];
7357 bdi
= path
->extra
->damp_info
;
7359 /* short status lead text */
7360 route_vty_short_status_out(vty
, path
, json
);
7362 /* print prefix and mask */
7365 route_vty_out_route(p
, vty
, NULL
);
7367 vty_out(vty
, "%*s", 17, " ");
7370 len
= vty_out(vty
, "%s", path
->peer
->host
);
7374 vty_out(vty
, "\n%*s", 33, " ");
7377 json_object_int_add(json
, "peerHost", len
);
7379 vty_out(vty
, "%*s", len
, " ");
7382 len
= vty_out(vty
, "%d", bdi
->flap
);
7389 json_object_int_add(json
, "bdiFlap", len
);
7391 vty_out(vty
, "%*s", len
, " ");
7395 peer_uptime(bdi
->start_time
, timebuf
, BGP_UPTIME_LEN
, use_json
,
7398 vty_out(vty
, "%s ", peer_uptime(bdi
->start_time
, timebuf
,
7399 BGP_UPTIME_LEN
, 0, NULL
));
7401 if (CHECK_FLAG(path
->flags
, BGP_PATH_DAMPED
)
7402 && !CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
)) {
7404 bgp_damp_reuse_time_vty(vty
, path
, timebuf
,
7405 BGP_UPTIME_LEN
, use_json
, json
);
7408 bgp_damp_reuse_time_vty(vty
, path
, timebuf
,
7413 vty_out(vty
, "%*s ", 8, " ");
7416 /* Print attribute */
7422 json_object_string_add(json
, "asPath",
7425 aspath_print_vty(vty
, "%s", attr
->aspath
, " ");
7430 json_object_string_add(json
, "origin",
7431 bgp_origin_str
[attr
->origin
]);
7433 vty_out(vty
, "%s", bgp_origin_str
[attr
->origin
]);
7439 static void route_vty_out_advertised_to(struct vty
*vty
, struct peer
*peer
,
7440 int *first
, const char *header
,
7441 json_object
*json_adv_to
)
7443 char buf1
[INET6_ADDRSTRLEN
];
7444 json_object
*json_peer
= NULL
;
7447 /* 'advertised-to' is a dictionary of peers we have advertised
7449 * prefix too. The key is the peer's IP or swpX, the value is
7451 * hostname if we know it and "" if not.
7453 json_peer
= json_object_new_object();
7456 json_object_string_add(json_peer
, "hostname",
7460 json_object_object_add(json_adv_to
, peer
->conf_if
,
7463 json_object_object_add(
7465 sockunion2str(&peer
->su
, buf1
, SU_ADDRSTRLEN
),
7469 vty_out(vty
, "%s", header
);
7474 && bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
)) {
7476 vty_out(vty
, " %s(%s)", peer
->hostname
,
7479 vty_out(vty
, " %s(%s)", peer
->hostname
,
7480 sockunion2str(&peer
->su
, buf1
,
7484 vty_out(vty
, " %s", peer
->conf_if
);
7487 sockunion2str(&peer
->su
, buf1
,
7493 static void route_vty_out_tx_ids(struct vty
*vty
,
7494 struct bgp_addpath_info_data
*d
)
7498 for (i
= 0; i
< BGP_ADDPATH_MAX
; i
++) {
7499 vty_out(vty
, "TX-%s %u%s", bgp_addpath_names(i
)->human_name
,
7500 d
->addpath_tx_id
[i
],
7501 i
< BGP_ADDPATH_MAX
- 1 ? " " : "\n");
7505 void route_vty_out_detail(struct vty
*vty
, struct bgp
*bgp
, struct prefix
*p
,
7506 struct bgp_path_info
*path
, afi_t afi
, safi_t safi
,
7507 json_object
*json_paths
)
7509 char buf
[INET6_ADDRSTRLEN
];
7511 char buf2
[EVPN_ROUTE_STRLEN
];
7513 int sockunion_vty_out(struct vty
*, union sockunion
*);
7515 json_object
*json_bestpath
= NULL
;
7516 json_object
*json_cluster_list
= NULL
;
7517 json_object
*json_cluster_list_list
= NULL
;
7518 json_object
*json_ext_community
= NULL
;
7519 json_object
*json_last_update
= NULL
;
7520 json_object
*json_pmsi
= NULL
;
7521 json_object
*json_nexthop_global
= NULL
;
7522 json_object
*json_nexthop_ll
= NULL
;
7523 json_object
*json_nexthops
= NULL
;
7524 json_object
*json_path
= NULL
;
7525 json_object
*json_peer
= NULL
;
7526 json_object
*json_string
= NULL
;
7527 json_object
*json_adv_to
= NULL
;
7529 struct listnode
*node
, *nnode
;
7531 int addpath_capable
;
7533 unsigned int first_as
;
7535 CHECK_FLAG(path
->flags
, BGP_PATH_ANNC_NH_SELF
) ? true : false;
7539 json_path
= json_object_new_object();
7540 json_peer
= json_object_new_object();
7541 json_nexthop_global
= json_object_new_object();
7544 if (!json_paths
&& safi
== SAFI_EVPN
) {
7547 bgp_evpn_route2str((struct prefix_evpn
*)p
, buf2
, sizeof(buf2
));
7548 vty_out(vty
, " Route %s", buf2
);
7550 if (path
->extra
&& path
->extra
->num_labels
) {
7551 bgp_evpn_label2str(path
->extra
->label
,
7552 path
->extra
->num_labels
, tag_buf
,
7554 vty_out(vty
, " VNI %s", tag_buf
);
7557 if (path
->extra
&& path
->extra
->parent
) {
7558 struct bgp_path_info
*parent_ri
;
7559 struct bgp_node
*rn
, *prn
;
7561 parent_ri
= (struct bgp_path_info
*)path
->extra
->parent
;
7562 rn
= parent_ri
->net
;
7563 if (rn
&& rn
->prn
) {
7565 vty_out(vty
, " Imported from %s:%s\n",
7567 (struct prefix_rd
*)&prn
->p
,
7568 buf1
, sizeof(buf1
)),
7577 /* Line1 display AS-path, Aggregator */
7580 if (!attr
->aspath
->json
)
7581 aspath_str_update(attr
->aspath
, true);
7582 json_object_lock(attr
->aspath
->json
);
7583 json_object_object_add(json_path
, "aspath",
7584 attr
->aspath
->json
);
7586 if (attr
->aspath
->segments
)
7587 aspath_print_vty(vty
, " %s",
7590 vty_out(vty
, " Local");
7594 if (CHECK_FLAG(path
->flags
, BGP_PATH_REMOVED
)) {
7596 json_object_boolean_true_add(json_path
,
7599 vty_out(vty
, ", (removed)");
7602 if (CHECK_FLAG(path
->flags
, BGP_PATH_STALE
)) {
7604 json_object_boolean_true_add(json_path
,
7607 vty_out(vty
, ", (stale)");
7610 if (CHECK_FLAG(attr
->flag
,
7611 ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR
))) {
7613 json_object_int_add(json_path
, "aggregatorAs",
7614 attr
->aggregator_as
);
7615 json_object_string_add(
7616 json_path
, "aggregatorId",
7617 inet_ntoa(attr
->aggregator_addr
));
7619 vty_out(vty
, ", (aggregated by %u %s)",
7620 attr
->aggregator_as
,
7621 inet_ntoa(attr
->aggregator_addr
));
7625 if (CHECK_FLAG(path
->peer
->af_flags
[afi
][safi
],
7626 PEER_FLAG_REFLECTOR_CLIENT
)) {
7628 json_object_boolean_true_add(
7629 json_path
, "rxedFromRrClient");
7631 vty_out(vty
, ", (Received from a RR-client)");
7634 if (CHECK_FLAG(path
->peer
->af_flags
[afi
][safi
],
7635 PEER_FLAG_RSERVER_CLIENT
)) {
7637 json_object_boolean_true_add(
7638 json_path
, "rxedFromRsClient");
7640 vty_out(vty
, ", (Received from a RS-client)");
7643 if (CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
)) {
7645 json_object_boolean_true_add(
7646 json_path
, "dampeningHistoryEntry");
7648 vty_out(vty
, ", (history entry)");
7649 } else if (CHECK_FLAG(path
->flags
, BGP_PATH_DAMPED
)) {
7651 json_object_boolean_true_add(
7652 json_path
, "dampeningSuppressed");
7654 vty_out(vty
, ", (suppressed due to dampening)");
7660 /* Line2 display Next-hop, Neighbor, Router-id */
7661 /* Display the nexthop */
7662 if ((p
->family
== AF_INET
|| p
->family
== AF_ETHERNET
7663 || p
->family
== AF_EVPN
)
7664 && (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7665 || safi
== SAFI_EVPN
7666 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7667 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
7668 || safi
== SAFI_EVPN
) {
7670 json_object_string_add(
7671 json_nexthop_global
, "ip",
7673 attr
->mp_nexthop_global_in
));
7677 attr
->mp_nexthop_global_in
));
7680 json_object_string_add(
7681 json_nexthop_global
, "ip",
7682 inet_ntoa(attr
->nexthop
));
7685 inet_ntoa(attr
->nexthop
));
7689 json_object_string_add(json_nexthop_global
,
7693 json_object_string_add(
7694 json_nexthop_global
, "ip",
7696 &attr
->mp_nexthop_global
, buf
,
7698 json_object_string_add(json_nexthop_global
,
7700 json_object_string_add(json_nexthop_global
,
7705 &attr
->mp_nexthop_global
, buf
,
7710 /* Display the IGP cost or 'inaccessible' */
7711 if (!CHECK_FLAG(path
->flags
, BGP_PATH_VALID
)) {
7713 json_object_boolean_false_add(
7714 json_nexthop_global
, "accessible");
7716 vty_out(vty
, " (inaccessible)");
7718 if (path
->extra
&& path
->extra
->igpmetric
) {
7720 json_object_int_add(
7721 json_nexthop_global
, "metric",
7722 path
->extra
->igpmetric
);
7724 vty_out(vty
, " (metric %u)",
7725 path
->extra
->igpmetric
);
7728 /* IGP cost is 0, display this only for json */
7731 json_object_int_add(json_nexthop_global
,
7736 json_object_boolean_true_add(
7737 json_nexthop_global
, "accessible");
7740 /* Display peer "from" output */
7741 /* This path was originated locally */
7742 if (path
->peer
== bgp
->peer_self
) {
7744 if (safi
== SAFI_EVPN
7745 || (p
->family
== AF_INET
7746 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr
))) {
7748 json_object_string_add(
7749 json_peer
, "peerId", "0.0.0.0");
7751 vty_out(vty
, " from 0.0.0.0 ");
7754 json_object_string_add(json_peer
,
7757 vty_out(vty
, " from :: ");
7761 json_object_string_add(
7762 json_peer
, "routerId",
7763 inet_ntoa(bgp
->router_id
));
7765 vty_out(vty
, "(%s)", inet_ntoa(bgp
->router_id
));
7768 /* We RXed this path from one of our peers */
7772 json_object_string_add(
7773 json_peer
, "peerId",
7774 sockunion2str(&path
->peer
->su
, buf
,
7776 json_object_string_add(
7777 json_peer
, "routerId",
7779 &path
->peer
->remote_id
, buf1
,
7782 if (path
->peer
->hostname
)
7783 json_object_string_add(
7784 json_peer
, "hostname",
7785 path
->peer
->hostname
);
7787 if (path
->peer
->domainname
)
7788 json_object_string_add(
7789 json_peer
, "domainname",
7790 path
->peer
->domainname
);
7792 if (path
->peer
->conf_if
)
7793 json_object_string_add(
7794 json_peer
, "interface",
7795 path
->peer
->conf_if
);
7797 if (path
->peer
->conf_if
) {
7798 if (path
->peer
->hostname
7801 BGP_FLAG_SHOW_HOSTNAME
))
7802 vty_out(vty
, " from %s(%s)",
7803 path
->peer
->hostname
,
7804 path
->peer
->conf_if
);
7806 vty_out(vty
, " from %s",
7807 path
->peer
->conf_if
);
7809 if (path
->peer
->hostname
7812 BGP_FLAG_SHOW_HOSTNAME
))
7813 vty_out(vty
, " from %s(%s)",
7814 path
->peer
->hostname
,
7817 vty_out(vty
, " from %s",
7825 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
7826 vty_out(vty
, " (%s)",
7827 inet_ntoa(attr
->originator_id
));
7829 vty_out(vty
, " (%s)",
7832 &path
->peer
->remote_id
,
7833 buf1
, sizeof(buf1
)));
7838 * Note when vrfid of nexthop is different from that of prefix
7840 if (path
->extra
&& path
->extra
->bgp_orig
) {
7841 vrf_id_t nexthop_vrfid
= path
->extra
->bgp_orig
->vrf_id
;
7846 if (path
->extra
->bgp_orig
->inst_type
7847 == BGP_INSTANCE_TYPE_DEFAULT
)
7851 vn
= path
->extra
->bgp_orig
->name
;
7853 json_object_string_add(json_path
, "nhVrfName",
7856 if (nexthop_vrfid
== VRF_UNKNOWN
) {
7857 json_object_int_add(json_path
,
7860 json_object_int_add(json_path
,
7861 "nhVrfId", (int)nexthop_vrfid
);
7864 if (nexthop_vrfid
== VRF_UNKNOWN
)
7865 vty_out(vty
, " vrf ?");
7867 vty_out(vty
, " vrf %u", nexthop_vrfid
);
7873 json_object_boolean_true_add(json_path
,
7874 "announceNexthopSelf");
7876 vty_out(vty
, " announce-nh-self");
7883 /* display the link-local nexthop */
7884 if (attr
->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL
) {
7886 json_nexthop_ll
= json_object_new_object();
7887 json_object_string_add(
7888 json_nexthop_ll
, "ip",
7890 &attr
->mp_nexthop_local
, buf
,
7892 json_object_string_add(json_nexthop_ll
, "afi",
7894 json_object_string_add(json_nexthop_ll
, "scope",
7897 json_object_boolean_true_add(json_nexthop_ll
,
7900 if (!attr
->mp_nexthop_prefer_global
)
7901 json_object_boolean_true_add(
7902 json_nexthop_ll
, "used");
7904 json_object_boolean_true_add(
7905 json_nexthop_global
, "used");
7907 vty_out(vty
, " (%s) %s\n",
7909 &attr
->mp_nexthop_local
, buf
,
7911 attr
->mp_nexthop_prefer_global
7916 /* If we do not have a link-local nexthop then we must flag the
7920 json_object_boolean_true_add(
7921 json_nexthop_global
, "used");
7924 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
7925 * Int/Ext/Local, Atomic, best */
7927 json_object_string_add(
7928 json_path
, "origin",
7929 bgp_origin_long_str
[attr
->origin
]);
7931 vty_out(vty
, " Origin %s",
7932 bgp_origin_long_str
[attr
->origin
]);
7934 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC
)) {
7938 * Adding "metric" field to match with
7939 * corresponding CLI. "med" will be
7940 * deprecated in future.
7942 json_object_int_add(json_path
, "med",
7944 json_object_int_add(json_path
, "metric",
7947 vty_out(vty
, ", metric %u", attr
->med
);
7950 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF
)) {
7952 json_object_int_add(json_path
, "localpref",
7955 vty_out(vty
, ", localpref %u",
7959 if (attr
->weight
!= 0) {
7961 json_object_int_add(json_path
, "weight",
7964 vty_out(vty
, ", weight %u", attr
->weight
);
7967 if (attr
->tag
!= 0) {
7969 json_object_int_add(json_path
, "tag",
7972 vty_out(vty
, ", tag %" ROUTE_TAG_PRI
,
7976 if (!CHECK_FLAG(path
->flags
, BGP_PATH_VALID
)) {
7978 json_object_boolean_false_add(json_path
,
7981 vty_out(vty
, ", invalid");
7982 } else if (!CHECK_FLAG(path
->flags
, BGP_PATH_HISTORY
)) {
7984 json_object_boolean_true_add(json_path
,
7987 vty_out(vty
, ", valid");
7990 if (path
->peer
!= bgp
->peer_self
) {
7991 if (path
->peer
->as
== path
->peer
->local_as
) {
7992 if (CHECK_FLAG(bgp
->config
,
7993 BGP_CONFIG_CONFEDERATION
)) {
7995 json_object_string_add(
8000 ", confed-internal");
8003 json_object_string_add(
8007 vty_out(vty
, ", internal");
8010 if (bgp_confederation_peers_check(
8011 bgp
, path
->peer
->as
)) {
8013 json_object_string_add(
8018 ", confed-external");
8021 json_object_string_add(
8025 vty_out(vty
, ", external");
8028 } else if (path
->sub_type
== BGP_ROUTE_AGGREGATE
) {
8030 json_object_boolean_true_add(json_path
,
8032 json_object_boolean_true_add(json_path
,
8035 vty_out(vty
, ", aggregated, local");
8037 } else if (path
->type
!= ZEBRA_ROUTE_BGP
) {
8039 json_object_boolean_true_add(json_path
,
8042 vty_out(vty
, ", sourced");
8045 json_object_boolean_true_add(json_path
,
8047 json_object_boolean_true_add(json_path
,
8050 vty_out(vty
, ", sourced, local");
8054 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE
)) {
8056 json_object_boolean_true_add(json_path
,
8059 vty_out(vty
, ", atomic-aggregate");
8062 if (CHECK_FLAG(path
->flags
, BGP_PATH_MULTIPATH
)
8063 || (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
)
8064 && bgp_path_info_mpath_count(path
))) {
8066 json_object_boolean_true_add(json_path
,
8069 vty_out(vty
, ", multipath");
8072 // Mark the bestpath(s)
8073 if (CHECK_FLAG(path
->flags
, BGP_PATH_DMED_SELECTED
)) {
8074 first_as
= aspath_get_first_as(attr
->aspath
);
8079 json_object_new_object();
8080 json_object_int_add(json_bestpath
,
8081 "bestpathFromAs", first_as
);
8084 vty_out(vty
, ", bestpath-from-AS %u",
8088 ", bestpath-from-AS Local");
8092 if (CHECK_FLAG(path
->flags
, BGP_PATH_SELECTED
)) {
8096 json_object_new_object();
8097 json_object_boolean_true_add(json_bestpath
,
8100 vty_out(vty
, ", best");
8104 json_object_object_add(json_path
, "bestpath",
8110 /* Line 4 display Community */
8111 if (attr
->community
) {
8113 if (!attr
->community
->json
)
8114 community_str(attr
->community
, true);
8115 json_object_lock(attr
->community
->json
);
8116 json_object_object_add(json_path
, "community",
8117 attr
->community
->json
);
8119 vty_out(vty
, " Community: %s\n",
8120 attr
->community
->str
);
8124 /* Line 5 display Extended-community */
8125 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES
)) {
8127 json_ext_community
= json_object_new_object();
8128 json_object_string_add(json_ext_community
,
8130 attr
->ecommunity
->str
);
8131 json_object_object_add(json_path
,
8132 "extendedCommunity",
8133 json_ext_community
);
8135 vty_out(vty
, " Extended Community: %s\n",
8136 attr
->ecommunity
->str
);
8140 /* Line 6 display Large community */
8141 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES
)) {
8143 if (!attr
->lcommunity
->json
)
8144 lcommunity_str(attr
->lcommunity
, true);
8145 json_object_lock(attr
->lcommunity
->json
);
8146 json_object_object_add(json_path
,
8148 attr
->lcommunity
->json
);
8150 vty_out(vty
, " Large Community: %s\n",
8151 attr
->lcommunity
->str
);
8155 /* Line 7 display Originator, Cluster-id */
8156 if ((attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
))
8157 || (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
))) {
8159 & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID
)) {
8161 json_object_string_add(
8162 json_path
, "originatorId",
8163 inet_ntoa(attr
->originator_id
));
8165 vty_out(vty
, " Originator: %s",
8166 inet_ntoa(attr
->originator_id
));
8169 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST
)) {
8174 json_object_new_object();
8175 json_cluster_list_list
=
8176 json_object_new_array();
8179 i
< attr
->cluster
->length
/ 4;
8181 json_string
= json_object_new_string(
8185 json_object_array_add(
8186 json_cluster_list_list
,
8190 /* struct cluster_list does not have
8192 * aspath and community do. Add this
8195 json_object_string_add(json_cluster_list,
8196 "string", attr->cluster->str);
8198 json_object_object_add(
8199 json_cluster_list
, "list",
8200 json_cluster_list_list
);
8201 json_object_object_add(
8202 json_path
, "clusterList",
8205 vty_out(vty
, ", Cluster list: ");
8208 i
< attr
->cluster
->length
/ 4;
8222 if (path
->extra
&& path
->extra
->damp_info
)
8223 bgp_damp_info_vty(vty
, path
, json_path
);
8226 if (path
->extra
&& bgp_is_valid_label(&path
->extra
->label
[0])
8227 && safi
!= SAFI_EVPN
) {
8228 mpls_label_t label
= label_pton(&path
->extra
->label
[0]);
8231 json_object_int_add(json_path
, "remoteLabel",
8234 vty_out(vty
, " Remote label: %d\n", label
);
8238 if (attr
->label_index
!= BGP_INVALID_LABEL_INDEX
) {
8240 json_object_int_add(json_path
, "labelIndex",
8243 vty_out(vty
, " Label Index: %d\n",
8247 /* Line 8 display Addpath IDs */
8248 if (path
->addpath_rx_id
8249 || bgp_addpath_info_has_ids(&path
->tx_addpath
)) {
8251 json_object_int_add(json_path
, "addpathRxId",
8252 path
->addpath_rx_id
);
8254 /* Keep backwards compatibility with the old API
8255 * by putting TX All's ID in the old field
8257 json_object_int_add(
8258 json_path
, "addpathTxId",
8259 path
->tx_addpath
.addpath_tx_id
8262 /* ... but create a specific field for each
8265 for (i
= 0; i
< BGP_ADDPATH_MAX
; i
++) {
8266 json_object_int_add(
8268 bgp_addpath_names(i
)
8274 vty_out(vty
, " AddPath ID: RX %u, ",
8275 path
->addpath_rx_id
);
8277 route_vty_out_tx_ids(vty
, &path
->tx_addpath
);
8281 /* If we used addpath to TX a non-bestpath we need to display
8282 * "Advertised to" on a path-by-path basis
8284 if (bgp_addpath_is_addpath_used(&bgp
->tx_addpath
, afi
, safi
)) {
8287 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
8289 bgp_addpath_encode_tx(peer
, afi
, safi
);
8290 has_adj
= bgp_adj_out_lookup(
8292 bgp_addpath_id_for_peer(
8294 &path
->tx_addpath
));
8296 if ((addpath_capable
&& has_adj
)
8297 || (!addpath_capable
&& has_adj
8298 && CHECK_FLAG(path
->flags
,
8299 BGP_PATH_SELECTED
))) {
8300 if (json_path
&& !json_adv_to
)
8302 json_object_new_object();
8304 route_vty_out_advertised_to(
8313 json_object_object_add(json_path
,
8324 /* Line 9 display Uptime */
8325 tbuf
= time(NULL
) - (bgp_clock() - path
->uptime
);
8327 json_last_update
= json_object_new_object();
8328 json_object_int_add(json_last_update
, "epoch", tbuf
);
8329 json_object_string_add(json_last_update
, "string",
8331 json_object_object_add(json_path
, "lastUpdate",
8334 vty_out(vty
, " Last update: %s", ctime(&tbuf
));
8336 /* Line 10 display PMSI tunnel attribute, if present */
8337 if (attr
->flag
& ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL
)) {
8338 const char *str
= lookup_msg(bgp_pmsi_tnltype_str
,
8339 attr
->pmsi_tnl_type
,
8340 PMSI_TNLTYPE_STR_DEFAULT
);
8343 json_pmsi
= json_object_new_object();
8344 json_object_string_add(json_pmsi
,
8346 json_object_object_add(json_path
, "pmsi",
8349 vty_out(vty
, " PMSI Tunnel Type: %s\n",
8355 /* We've constructed the json object for this path, add it to the json
8359 if (json_nexthop_global
|| json_nexthop_ll
) {
8360 json_nexthops
= json_object_new_array();
8362 if (json_nexthop_global
)
8363 json_object_array_add(json_nexthops
,
8364 json_nexthop_global
);
8366 if (json_nexthop_ll
)
8367 json_object_array_add(json_nexthops
,
8370 json_object_object_add(json_path
, "nexthops",
8374 json_object_object_add(json_path
, "peer", json_peer
);
8375 json_object_array_add(json_paths
, json_path
);
8380 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
8381 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
8382 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
8384 static int bgp_show_prefix_list(struct vty
*vty
, struct bgp
*bgp
,
8385 const char *prefix_list_str
, afi_t afi
,
8386 safi_t safi
, enum bgp_show_type type
);
8387 static int bgp_show_filter_list(struct vty
*vty
, struct bgp
*bgp
,
8388 const char *filter
, afi_t afi
, safi_t safi
,
8389 enum bgp_show_type type
);
8390 static int bgp_show_route_map(struct vty
*vty
, struct bgp
*bgp
,
8391 const char *rmap_str
, afi_t afi
, safi_t safi
,
8392 enum bgp_show_type type
);
8393 static int bgp_show_community_list(struct vty
*vty
, struct bgp
*bgp
,
8394 const char *com
, int exact
, afi_t afi
,
8396 static int bgp_show_prefix_longer(struct vty
*vty
, struct bgp
*bgp
,
8397 const char *prefix
, afi_t afi
, safi_t safi
,
8398 enum bgp_show_type type
);
8399 static int bgp_show_regexp(struct vty
*vty
, struct bgp
*bgp
, const char *regstr
,
8400 afi_t afi
, safi_t safi
, enum bgp_show_type type
);
8401 static int bgp_show_community(struct vty
*vty
, struct bgp
*bgp
,
8402 const char *comstr
, int exact
, afi_t afi
,
8403 safi_t safi
, bool use_json
);
8406 static int bgp_show_table(struct vty
*vty
, struct bgp
*bgp
, safi_t safi
,
8407 struct bgp_table
*table
, enum bgp_show_type type
,
8408 void *output_arg
, bool use_json
, char *rd
,
8409 int is_last
, unsigned long *output_cum
,
8410 unsigned long *total_cum
,
8411 unsigned long *json_header_depth
)
8413 struct bgp_path_info
*pi
;
8414 struct bgp_node
*rn
;
8417 unsigned long output_count
= 0;
8418 unsigned long total_count
= 0;
8421 json_object
*json_paths
= NULL
;
8424 if (output_cum
&& *output_cum
!= 0)
8427 if (use_json
&& !*json_header_depth
) {
8429 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
8430 ",\n \"routerId\": \"%s\",\n \"routes\": { ",
8431 bgp
->vrf_id
== VRF_UNKNOWN
? -1 : (int)bgp
->vrf_id
,
8432 bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
8435 table
->version
, inet_ntoa(bgp
->router_id
));
8436 *json_header_depth
= 2;
8438 vty_out(vty
, " \"routeDistinguishers\" : {");
8439 ++*json_header_depth
;
8443 if (use_json
&& rd
) {
8444 vty_out(vty
, " \"%s\" : { ", rd
);
8447 /* Start processing of routes. */
8448 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
8449 if (rn
->info
== NULL
)
8454 json_paths
= json_object_new_array();
8458 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
8460 if (type
== bgp_show_type_flap_statistics
8461 || type
== bgp_show_type_flap_neighbor
8462 || type
== bgp_show_type_dampend_paths
8463 || type
== bgp_show_type_damp_neighbor
) {
8464 if (!(pi
->extra
&& pi
->extra
->damp_info
))
8467 if (type
== bgp_show_type_regexp
) {
8468 regex_t
*regex
= output_arg
;
8470 if (bgp_regexec(regex
, pi
->attr
->aspath
)
8474 if (type
== bgp_show_type_prefix_list
) {
8475 struct prefix_list
*plist
= output_arg
;
8477 if (prefix_list_apply(plist
, &rn
->p
)
8481 if (type
== bgp_show_type_filter_list
) {
8482 struct as_list
*as_list
= output_arg
;
8484 if (as_list_apply(as_list
, pi
->attr
->aspath
)
8485 != AS_FILTER_PERMIT
)
8488 if (type
== bgp_show_type_route_map
) {
8489 struct route_map
*rmap
= output_arg
;
8490 struct bgp_path_info path
;
8491 struct attr dummy_attr
;
8494 bgp_attr_dup(&dummy_attr
, pi
->attr
);
8496 path
.peer
= pi
->peer
;
8497 path
.attr
= &dummy_attr
;
8499 ret
= route_map_apply(rmap
, &rn
->p
, RMAP_BGP
,
8501 if (ret
== RMAP_DENYMATCH
)
8504 if (type
== bgp_show_type_neighbor
8505 || type
== bgp_show_type_flap_neighbor
8506 || type
== bgp_show_type_damp_neighbor
) {
8507 union sockunion
*su
= output_arg
;
8509 if (pi
->peer
== NULL
8510 || pi
->peer
->su_remote
== NULL
8511 || !sockunion_same(pi
->peer
->su_remote
, su
))
8514 if (type
== bgp_show_type_cidr_only
) {
8515 uint32_t destination
;
8517 destination
= ntohl(rn
->p
.u
.prefix4
.s_addr
);
8518 if (IN_CLASSC(destination
)
8519 && rn
->p
.prefixlen
== 24)
8521 if (IN_CLASSB(destination
)
8522 && rn
->p
.prefixlen
== 16)
8524 if (IN_CLASSA(destination
)
8525 && rn
->p
.prefixlen
== 8)
8528 if (type
== bgp_show_type_prefix_longer
) {
8530 if (!prefix_match(p
, &rn
->p
))
8533 if (type
== bgp_show_type_community_all
) {
8534 if (!pi
->attr
->community
)
8537 if (type
== bgp_show_type_community
) {
8538 struct community
*com
= output_arg
;
8540 if (!pi
->attr
->community
8541 || !community_match(pi
->attr
->community
,
8545 if (type
== bgp_show_type_community_exact
) {
8546 struct community
*com
= output_arg
;
8548 if (!pi
->attr
->community
8549 || !community_cmp(pi
->attr
->community
, com
))
8552 if (type
== bgp_show_type_community_list
) {
8553 struct community_list
*list
= output_arg
;
8555 if (!community_list_match(pi
->attr
->community
,
8559 if (type
== bgp_show_type_community_list_exact
) {
8560 struct community_list
*list
= output_arg
;
8562 if (!community_list_exact_match(
8563 pi
->attr
->community
, list
))
8566 if (type
== bgp_show_type_lcommunity
) {
8567 struct lcommunity
*lcom
= output_arg
;
8569 if (!pi
->attr
->lcommunity
8570 || !lcommunity_match(pi
->attr
->lcommunity
,
8574 if (type
== bgp_show_type_lcommunity_list
) {
8575 struct community_list
*list
= output_arg
;
8577 if (!lcommunity_list_match(pi
->attr
->lcommunity
,
8581 if (type
== bgp_show_type_lcommunity_all
) {
8582 if (!pi
->attr
->lcommunity
)
8585 if (type
== bgp_show_type_dampend_paths
8586 || type
== bgp_show_type_damp_neighbor
) {
8587 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_DAMPED
)
8588 || CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
))
8592 if (!use_json
&& header
) {
8593 vty_out(vty
, "BGP table version is %" PRIu64
8594 ", local router ID is %s, vrf id ",
8596 inet_ntoa(bgp
->router_id
));
8597 if (bgp
->vrf_id
== VRF_UNKNOWN
)
8598 vty_out(vty
, "%s", VRFID_NONE_STR
);
8600 vty_out(vty
, "%u", bgp
->vrf_id
);
8602 vty_out(vty
, BGP_SHOW_SCODE_HEADER
);
8603 vty_out(vty
, BGP_SHOW_NCODE_HEADER
);
8604 vty_out(vty
, BGP_SHOW_OCODE_HEADER
);
8605 if (type
== bgp_show_type_dampend_paths
8606 || type
== bgp_show_type_damp_neighbor
)
8607 vty_out(vty
, BGP_SHOW_DAMP_HEADER
);
8608 else if (type
== bgp_show_type_flap_statistics
8609 || type
== bgp_show_type_flap_neighbor
)
8610 vty_out(vty
, BGP_SHOW_FLAP_HEADER
);
8612 vty_out(vty
, BGP_SHOW_HEADER
);
8615 if (rd
!= NULL
&& !display
&& !output_count
) {
8618 "Route Distinguisher: %s\n",
8621 if (type
== bgp_show_type_dampend_paths
8622 || type
== bgp_show_type_damp_neighbor
)
8623 damp_route_vty_out(vty
, &rn
->p
, pi
, display
,
8624 safi
, use_json
, json_paths
);
8625 else if (type
== bgp_show_type_flap_statistics
8626 || type
== bgp_show_type_flap_neighbor
)
8627 flap_route_vty_out(vty
, &rn
->p
, pi
, display
,
8628 safi
, use_json
, json_paths
);
8630 route_vty_out(vty
, &rn
->p
, pi
, display
, safi
,
8642 if (p
->family
== AF_FLOWSPEC
) {
8643 char retstr
[BGP_FLOWSPEC_STRING_DISPLAY_MAX
];
8645 bgp_fs_nlri_get_string((unsigned char *)
8646 p
->u
.prefix_flowspec
.ptr
,
8647 p
->u
.prefix_flowspec
8650 NLRI_STRING_FORMAT_MIN
,
8653 vty_out(vty
, "\"%s/%d\": ",
8655 p
->u
.prefix_flowspec
.prefixlen
);
8657 vty_out(vty
, ",\"%s/%d\": ",
8659 p
->u
.prefix_flowspec
.prefixlen
);
8661 prefix2str(p
, buf2
, sizeof(buf2
));
8663 vty_out(vty
, "\"%s\": ", buf2
);
8665 vty_out(vty
, ",\"%s\": ", buf2
);
8668 json_object_to_json_string(json_paths
));
8669 json_object_free(json_paths
);
8676 output_count
+= *output_cum
;
8677 *output_cum
= output_count
;
8680 total_count
+= *total_cum
;
8681 *total_cum
= total_count
;
8685 vty_out(vty
, " }%s ", (is_last
? "" : ","));
8689 for (i
= 0; i
< *json_header_depth
; ++i
)
8690 vty_out(vty
, " } ");
8694 /* No route is displayed */
8695 if (output_count
== 0) {
8696 if (type
== bgp_show_type_normal
)
8698 "No BGP prefixes displayed, %ld exist\n",
8702 "\nDisplayed %ld routes and %ld total paths\n",
8703 output_count
, total_count
);
8710 int bgp_show_table_rd(struct vty
*vty
, struct bgp
*bgp
, safi_t safi
,
8711 struct bgp_table
*table
, struct prefix_rd
*prd_match
,
8712 enum bgp_show_type type
, void *output_arg
, bool use_json
)
8714 struct bgp_node
*rn
, *next
;
8715 unsigned long output_cum
= 0;
8716 unsigned long total_cum
= 0;
8717 unsigned long json_header_depth
= 0;
8720 show_msg
= (!use_json
&& type
== bgp_show_type_normal
);
8722 for (rn
= bgp_table_top(table
); rn
; rn
= next
) {
8723 next
= bgp_route_next(rn
);
8724 if (prd_match
&& memcmp(rn
->p
.u
.val
, prd_match
->val
, 8) != 0)
8726 if (rn
->info
!= NULL
) {
8727 struct prefix_rd prd
;
8728 char rd
[RD_ADDRSTRLEN
];
8730 memcpy(&prd
, &(rn
->p
), sizeof(struct prefix_rd
));
8731 prefix_rd2str(&prd
, rd
, sizeof(rd
));
8732 bgp_show_table(vty
, bgp
, safi
, rn
->info
, type
,
8733 output_arg
, use_json
, rd
, next
== NULL
,
8734 &output_cum
, &total_cum
,
8735 &json_header_depth
);
8741 if (output_cum
== 0)
8742 vty_out(vty
, "No BGP prefixes displayed, %ld exist\n",
8746 "\nDisplayed %ld routes and %ld total paths\n",
8747 output_cum
, total_cum
);
8751 static int bgp_show(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
, safi_t safi
,
8752 enum bgp_show_type type
, void *output_arg
, bool use_json
)
8754 struct bgp_table
*table
;
8755 unsigned long json_header_depth
= 0;
8758 bgp
= bgp_get_default();
8763 vty_out(vty
, "No BGP process is configured\n");
8765 vty_out(vty
, "{}\n");
8769 table
= bgp
->rib
[afi
][safi
];
8770 /* use MPLS and ENCAP specific shows until they are merged */
8771 if (safi
== SAFI_MPLS_VPN
) {
8772 return bgp_show_table_rd(vty
, bgp
, safi
, table
, NULL
, type
,
8773 output_arg
, use_json
);
8776 if (safi
== SAFI_FLOWSPEC
&& type
== bgp_show_type_detail
) {
8777 return bgp_show_table_flowspec(vty
, bgp
, afi
, table
, type
,
8778 output_arg
, use_json
,
8781 /* labeled-unicast routes live in the unicast table */
8782 else if (safi
== SAFI_LABELED_UNICAST
)
8783 safi
= SAFI_UNICAST
;
8785 return bgp_show_table(vty
, bgp
, safi
, table
, type
, output_arg
, use_json
,
8786 NULL
, 1, NULL
, NULL
, &json_header_depth
);
8789 static void bgp_show_all_instances_routes_vty(struct vty
*vty
, afi_t afi
,
8790 safi_t safi
, bool use_json
)
8792 struct listnode
*node
, *nnode
;
8795 bool route_output
= false;
8798 vty_out(vty
, "{\n");
8800 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
)) {
8801 route_output
= true;
8804 vty_out(vty
, ",\n");
8808 vty_out(vty
, "\"%s\":",
8809 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8813 vty_out(vty
, "\nInstance %s:\n",
8814 (bgp
->inst_type
== BGP_INSTANCE_TYPE_DEFAULT
)
8818 bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_normal
, NULL
,
8823 vty_out(vty
, "}\n");
8824 else if (!route_output
)
8825 vty_out(vty
, "%% BGP instance not found\n");
8828 /* Header of detailed BGP route information */
8829 void route_vty_out_detail_header(struct vty
*vty
, struct bgp
*bgp
,
8830 struct bgp_node
*rn
, struct prefix_rd
*prd
,
8831 afi_t afi
, safi_t safi
, json_object
*json
)
8833 struct bgp_path_info
*pi
;
8836 struct listnode
*node
, *nnode
;
8837 char buf1
[RD_ADDRSTRLEN
];
8838 char buf2
[INET6_ADDRSTRLEN
];
8839 char buf3
[EVPN_ROUTE_STRLEN
];
8840 char prefix_str
[BUFSIZ
];
8845 int route_filter_translated_v4
= 0;
8846 int route_filter_v4
= 0;
8847 int route_filter_translated_v6
= 0;
8848 int route_filter_v6
= 0;
8851 int accept_own_nexthop
= 0;
8854 int no_advertise
= 0;
8858 int has_valid_label
= 0;
8859 mpls_label_t label
= 0;
8860 json_object
*json_adv_to
= NULL
;
8863 has_valid_label
= bgp_is_valid_label(&rn
->local_label
);
8865 if (has_valid_label
)
8866 label
= label_pton(&rn
->local_label
);
8869 if (has_valid_label
)
8870 json_object_int_add(json
, "localLabel", label
);
8872 json_object_string_add(
8874 prefix2str(p
, prefix_str
, sizeof(prefix_str
)));
8876 if (safi
== SAFI_EVPN
)
8877 vty_out(vty
, "BGP routing table entry for %s%s%s\n",
8878 prd
? prefix_rd2str(prd
, buf1
, sizeof(buf1
))
8881 bgp_evpn_route2str((struct prefix_evpn
*)p
,
8882 buf3
, sizeof(buf3
)));
8884 vty_out(vty
, "BGP routing table entry for %s%s%s/%d\n",
8885 ((safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
)
8886 ? prefix_rd2str(prd
, buf1
,
8889 safi
== SAFI_MPLS_VPN
? ":" : "",
8890 inet_ntop(p
->family
, &p
->u
.prefix
, buf2
,
8894 if (has_valid_label
)
8895 vty_out(vty
, "Local label: %d\n", label
);
8896 if (bgp_labeled_safi(safi
) && safi
!= SAFI_EVPN
)
8897 vty_out(vty
, "not allocated\n");
8900 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
8902 if (CHECK_FLAG(pi
->flags
, BGP_PATH_SELECTED
)) {
8904 if (pi
->extra
&& pi
->extra
->suppress
)
8907 if (pi
->attr
->community
== NULL
)
8910 no_advertise
+= community_include(
8911 pi
->attr
->community
, COMMUNITY_NO_ADVERTISE
);
8912 no_export
+= community_include(pi
->attr
->community
,
8913 COMMUNITY_NO_EXPORT
);
8914 local_as
+= community_include(pi
->attr
->community
,
8915 COMMUNITY_LOCAL_AS
);
8916 accept_own
+= community_include(pi
->attr
->community
,
8917 COMMUNITY_ACCEPT_OWN
);
8918 route_filter_translated_v4
+= community_include(
8919 pi
->attr
->community
,
8920 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4
);
8921 route_filter_translated_v6
+= community_include(
8922 pi
->attr
->community
,
8923 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6
);
8924 route_filter_v4
+= community_include(
8925 pi
->attr
->community
, COMMUNITY_ROUTE_FILTER_v4
);
8926 route_filter_v6
+= community_include(
8927 pi
->attr
->community
, COMMUNITY_ROUTE_FILTER_v6
);
8928 llgr_stale
+= community_include(pi
->attr
->community
,
8929 COMMUNITY_LLGR_STALE
);
8930 no_llgr
+= community_include(pi
->attr
->community
,
8932 accept_own_nexthop
+=
8933 community_include(pi
->attr
->community
,
8934 COMMUNITY_ACCEPT_OWN_NEXTHOP
);
8935 blackhole
+= community_include(pi
->attr
->community
,
8936 COMMUNITY_BLACKHOLE
);
8937 no_peer
+= community_include(pi
->attr
->community
,
8943 vty_out(vty
, "Paths: (%d available", count
);
8945 vty_out(vty
, ", best #%d", best
);
8946 if (safi
== SAFI_UNICAST
)
8947 vty_out(vty
, ", table %s",
8949 == BGP_INSTANCE_TYPE_DEFAULT
)
8953 vty_out(vty
, ", no best path");
8957 ", accept own local route exported and imported in different VRF");
8958 else if (route_filter_translated_v4
)
8960 ", mark translated RTs for VPNv4 route filtering");
8961 else if (route_filter_v4
)
8963 ", attach RT as-is for VPNv4 route filtering");
8964 else if (route_filter_translated_v6
)
8966 ", mark translated RTs for VPNv6 route filtering");
8967 else if (route_filter_v6
)
8969 ", attach RT as-is for VPNv6 route filtering");
8970 else if (llgr_stale
)
8972 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
8975 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
8976 else if (accept_own_nexthop
)
8978 ", accept local nexthop");
8980 vty_out(vty
, ", inform peer to blackhole prefix");
8982 vty_out(vty
, ", not advertised to EBGP peer");
8983 else if (no_advertise
)
8984 vty_out(vty
, ", not advertised to any peer");
8986 vty_out(vty
, ", not advertised outside local AS");
8989 ", inform EBGP peer not to advertise to their EBGP peers");
8993 ", Advertisements suppressed by an aggregate.");
8994 vty_out(vty
, ")\n");
8997 /* If we are not using addpath then we can display Advertised to and
8999 * show what peers we advertised the bestpath to. If we are using
9001 * though then we must display Advertised to on a path-by-path basis. */
9002 if (!bgp_addpath_is_addpath_used(&bgp
->tx_addpath
, afi
, safi
)) {
9003 for (ALL_LIST_ELEMENTS(bgp
->peer
, node
, nnode
, peer
)) {
9004 if (bgp_adj_out_lookup(peer
, rn
, 0)) {
9005 if (json
&& !json_adv_to
)
9006 json_adv_to
= json_object_new_object();
9008 route_vty_out_advertised_to(
9010 " Advertised to non peer-group peers:\n ",
9017 json_object_object_add(json
, "advertisedTo",
9022 vty_out(vty
, " Not advertised to any peer");
9028 /* Display specified route of BGP table. */
9029 static int bgp_show_route_in_table(struct vty
*vty
, struct bgp
*bgp
,
9030 struct bgp_table
*rib
, const char *ip_str
,
9031 afi_t afi
, safi_t safi
,
9032 struct prefix_rd
*prd
, int prefix_check
,
9033 enum bgp_path_type pathtype
, bool use_json
)
9038 struct prefix match
;
9039 struct bgp_node
*rn
;
9040 struct bgp_node
*rm
;
9041 struct bgp_path_info
*pi
;
9042 struct bgp_table
*table
;
9043 json_object
*json
= NULL
;
9044 json_object
*json_paths
= NULL
;
9046 /* Check IP address argument. */
9047 ret
= str2prefix(ip_str
, &match
);
9049 vty_out(vty
, "address is malformed\n");
9053 match
.family
= afi2family(afi
);
9056 json
= json_object_new_object();
9057 json_paths
= json_object_new_array();
9060 if (safi
== SAFI_MPLS_VPN
|| safi
== SAFI_ENCAP
|| safi
== SAFI_EVPN
) {
9061 for (rn
= bgp_table_top(rib
); rn
; rn
= bgp_route_next(rn
)) {
9062 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
9065 if ((table
= rn
->info
) == NULL
)
9070 if ((rm
= bgp_node_match(table
, &match
)) == NULL
)
9074 && rm
->p
.prefixlen
!= match
.prefixlen
) {
9075 bgp_unlock_node(rm
);
9079 for (pi
= rm
->info
; pi
; pi
= pi
->next
) {
9081 route_vty_out_detail_header(
9083 (struct prefix_rd
*)&rn
->p
,
9084 AFI_IP
, safi
, json
);
9089 if (pathtype
== BGP_PATH_SHOW_ALL
9090 || (pathtype
== BGP_PATH_SHOW_BESTPATH
9091 && CHECK_FLAG(pi
->flags
,
9093 || (pathtype
== BGP_PATH_SHOW_MULTIPATH
9094 && (CHECK_FLAG(pi
->flags
,
9096 || CHECK_FLAG(pi
->flags
,
9097 BGP_PATH_SELECTED
))))
9098 route_vty_out_detail(vty
, bgp
, &rm
->p
,
9103 bgp_unlock_node(rm
);
9105 } else if (safi
== SAFI_FLOWSPEC
) {
9106 display
= bgp_flowspec_display_match_per_ip(afi
, rib
,
9107 &match
, prefix_check
,
9114 if ((rn
= bgp_node_match(rib
, &match
)) != NULL
) {
9116 || rn
->p
.prefixlen
== match
.prefixlen
) {
9117 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
9119 route_vty_out_detail_header(
9120 vty
, bgp
, rn
, NULL
, afi
,
9126 if (pathtype
== BGP_PATH_SHOW_ALL
9128 == BGP_PATH_SHOW_BESTPATH
9133 == BGP_PATH_SHOW_MULTIPATH
9139 BGP_PATH_SELECTED
))))
9140 route_vty_out_detail(
9141 vty
, bgp
, &rn
->p
, pi
,
9142 afi
, safi
, json_paths
);
9146 bgp_unlock_node(rn
);
9152 json_object_object_add(json
, "paths", json_paths
);
9154 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
9155 json
, JSON_C_TO_STRING_PRETTY
));
9156 json_object_free(json
);
9159 vty_out(vty
, "%% Network not in table\n");
9167 /* Display specified route of Main RIB */
9168 static int bgp_show_route(struct vty
*vty
, struct bgp
*bgp
, const char *ip_str
,
9169 afi_t afi
, safi_t safi
, struct prefix_rd
*prd
,
9170 int prefix_check
, enum bgp_path_type pathtype
,
9174 bgp
= bgp_get_default();
9177 vty_out(vty
, "No BGP process is configured\n");
9179 vty_out(vty
, "{}\n");
9184 /* labeled-unicast routes live in the unicast table */
9185 if (safi
== SAFI_LABELED_UNICAST
)
9186 safi
= SAFI_UNICAST
;
9188 return bgp_show_route_in_table(vty
, bgp
, bgp
->rib
[afi
][safi
], ip_str
,
9189 afi
, safi
, prd
, prefix_check
, pathtype
,
9193 static int bgp_show_lcommunity(struct vty
*vty
, struct bgp
*bgp
, int argc
,
9194 struct cmd_token
**argv
, afi_t afi
, safi_t safi
,
9197 struct lcommunity
*lcom
;
9203 b
= buffer_new(1024);
9204 for (i
= 0; i
< argc
; i
++) {
9206 buffer_putc(b
, ' ');
9208 if (strmatch(argv
[i
]->text
, "AA:BB:CC")) {
9210 buffer_putstr(b
, argv
[i
]->arg
);
9214 buffer_putc(b
, '\0');
9216 str
= buffer_getstr(b
);
9219 lcom
= lcommunity_str2com(str
);
9220 XFREE(MTYPE_TMP
, str
);
9222 vty_out(vty
, "%% Large-community malformed\n");
9226 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity
, lcom
,
9230 static int bgp_show_lcommunity_list(struct vty
*vty
, struct bgp
*bgp
,
9231 const char *lcom
, afi_t afi
, safi_t safi
,
9234 struct community_list
*list
;
9236 list
= community_list_lookup(bgp_clist
, lcom
,
9237 LARGE_COMMUNITY_LIST_MASTER
);
9239 vty_out(vty
, "%% %s is not a valid large-community-list name\n",
9244 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_lcommunity_list
,
9248 DEFUN (show_ip_bgp_large_community_list
,
9249 show_ip_bgp_large_community_list_cmd
,
9250 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community-list <(1-500)|WORD> [json]",
9254 BGP_INSTANCE_HELP_STR
9256 BGP_SAFI_WITH_LABEL_HELP_STR
9257 "Display routes matching the large-community-list\n"
9258 "large-community-list number\n"
9259 "large-community-list name\n"
9263 afi_t afi
= AFI_IP6
;
9264 safi_t safi
= SAFI_UNICAST
;
9267 if (argv_find(argv
, argc
, "ip", &idx
))
9269 if (argv_find(argv
, argc
, "view", &idx
)
9270 || argv_find(argv
, argc
, "vrf", &idx
))
9271 vrf
= argv
[++idx
]->arg
;
9272 if (argv_find(argv
, argc
, "ipv4", &idx
)
9273 || argv_find(argv
, argc
, "ipv6", &idx
)) {
9274 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
9275 if (argv_find(argv
, argc
, "unicast", &idx
)
9276 || argv_find(argv
, argc
, "multicast", &idx
))
9277 safi
= bgp_vty_safi_from_str(argv
[idx
]->text
);
9280 bool uj
= use_json(argc
, argv
);
9282 struct bgp
*bgp
= bgp_lookup_by_name(vrf
);
9284 vty_out(vty
, "Can't find BGP instance %s\n", vrf
);
9288 argv_find(argv
, argc
, "large-community-list", &idx
);
9289 return bgp_show_lcommunity_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
, safi
,
9292 DEFUN (show_ip_bgp_large_community
,
9293 show_ip_bgp_large_community_cmd
,
9294 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] large-community [AA:BB:CC] [json]",
9298 BGP_INSTANCE_HELP_STR
9300 BGP_SAFI_WITH_LABEL_HELP_STR
9301 "Display routes matching the large-communities\n"
9302 "List of large-community numbers\n"
9306 afi_t afi
= AFI_IP6
;
9307 safi_t safi
= SAFI_UNICAST
;
9310 if (argv_find(argv
, argc
, "ip", &idx
))
9312 if (argv_find(argv
, argc
, "view", &idx
)
9313 || argv_find(argv
, argc
, "vrf", &idx
))
9314 vrf
= argv
[++idx
]->arg
;
9315 if (argv_find(argv
, argc
, "ipv4", &idx
)
9316 || argv_find(argv
, argc
, "ipv6", &idx
)) {
9317 afi
= strmatch(argv
[idx
]->text
, "ipv6") ? AFI_IP6
: AFI_IP
;
9318 if (argv_find(argv
, argc
, "unicast", &idx
)
9319 || argv_find(argv
, argc
, "multicast", &idx
))
9320 safi
= bgp_vty_safi_from_str(argv
[idx
]->text
);
9323 bool uj
= use_json(argc
, argv
);
9325 struct bgp
*bgp
= bgp_lookup_by_name(vrf
);
9327 vty_out(vty
, "Can't find BGP instance %s\n", vrf
);
9331 if (argv_find(argv
, argc
, "AA:BB:CC", &idx
))
9332 return bgp_show_lcommunity(vty
, bgp
, argc
, argv
, afi
, safi
, uj
);
9334 return bgp_show(vty
, bgp
, afi
, safi
,
9335 bgp_show_type_lcommunity_all
, NULL
, uj
);
9338 static int bgp_table_stats(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
9342 /* BGP route print out function without JSON */
9345 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
9346 <dampening <parameters>\
9351 |community-list <(1-500)|WORD> [exact-match]\
9352 |A.B.C.D/M longer-prefixes\
9353 |X:X::X:X/M longer-prefixes\
9358 BGP_INSTANCE_HELP_STR
9360 BGP_SAFI_WITH_LABEL_HELP_STR
9361 "Display detailed information about dampening\n"
9362 "Display detail of configured dampening parameters\n"
9363 "Display routes matching the route-map\n"
9364 "A route-map to match on\n"
9365 "Display routes conforming to the prefix-list\n"
9366 "Prefix-list name\n"
9367 "Display routes conforming to the filter-list\n"
9368 "Regular expression access list name\n"
9369 "BGP RIB advertisement statistics\n"
9370 "Display routes matching the community-list\n"
9371 "community-list number\n"
9372 "community-list name\n"
9373 "Exact match of the communities\n"
9375 "Display route and more specific routes\n"
9377 "Display route and more specific routes\n")
9379 afi_t afi
= AFI_IP6
;
9380 safi_t safi
= SAFI_UNICAST
;
9381 int exact_match
= 0;
9382 struct bgp
*bgp
= NULL
;
9385 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9390 if (argv_find(argv
, argc
, "dampening", &idx
)) {
9391 if (argv_find(argv
, argc
, "parameters", &idx
))
9392 return bgp_show_dampening_parameters(vty
, afi
, safi
);
9395 if (argv_find(argv
, argc
, "prefix-list", &idx
))
9396 return bgp_show_prefix_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
9397 safi
, bgp_show_type_prefix_list
);
9399 if (argv_find(argv
, argc
, "filter-list", &idx
))
9400 return bgp_show_filter_list(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
9401 safi
, bgp_show_type_filter_list
);
9403 if (argv_find(argv
, argc
, "statistics", &idx
))
9404 return bgp_table_stats(vty
, bgp
, afi
, safi
);
9406 if (argv_find(argv
, argc
, "route-map", &idx
))
9407 return bgp_show_route_map(vty
, bgp
, argv
[idx
+ 1]->arg
, afi
,
9408 safi
, bgp_show_type_route_map
);
9410 if (argv_find(argv
, argc
, "community-list", &idx
)) {
9411 const char *clist_number_or_name
= argv
[++idx
]->arg
;
9412 if (++idx
< argc
&& strmatch(argv
[idx
]->text
, "exact-match"))
9414 return bgp_show_community_list(vty
, bgp
, clist_number_or_name
,
9415 exact_match
, afi
, safi
);
9418 if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)
9419 || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
9420 return bgp_show_prefix_longer(vty
, bgp
, argv
[idx
]->arg
, afi
,
9422 bgp_show_type_prefix_longer
);
9427 /* BGP route print out function with JSON */
9428 DEFUN (show_ip_bgp_json
,
9429 show_ip_bgp_json_cmd
,
9430 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
9432 |dampening <flap-statistics|dampened-paths>\
9433 |community [AA:NN|local-AS|no-advertise|no-export\
9434 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
9435 |accept-own|accept-own-nexthop|route-filter-v6\
9436 |route-filter-v4|route-filter-translated-v6\
9437 |route-filter-translated-v4] [exact-match]\
9442 BGP_INSTANCE_HELP_STR
9444 BGP_SAFI_WITH_LABEL_HELP_STR
9445 "Display only routes with non-natural netmasks\n"
9446 "Display detailed information about dampening\n"
9447 "Display flap statistics of routes\n"
9448 "Display paths suppressed due to dampening\n"
9449 "Display routes matching the communities\n"
9451 "Do not send outside local AS (well-known community)\n"
9452 "Do not advertise to any peer (well-known community)\n"
9453 "Do not export to next AS (well-known community)\n"
9454 "Graceful shutdown (well-known community)\n"
9455 "Do not export to any peer (well-known community)\n"
9456 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
9457 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
9458 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
9459 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
9460 "Should accept VPN route with local nexthop (well-known community)\n"
9461 "RT VPNv6 route filtering (well-known community)\n"
9462 "RT VPNv4 route filtering (well-known community)\n"
9463 "RT translated VPNv6 route filtering (well-known community)\n"
9464 "RT translated VPNv4 route filtering (well-known community)\n"
9465 "Exact match of the communities\n"
9468 afi_t afi
= AFI_IP6
;
9469 safi_t safi
= SAFI_UNICAST
;
9470 enum bgp_show_type sh_type
= bgp_show_type_normal
;
9471 struct bgp
*bgp
= NULL
;
9473 int exact_match
= 0;
9474 bool uj
= use_json(argc
, argv
);
9479 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9484 if (argv_find(argv
, argc
, "cidr-only", &idx
))
9485 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_cidr_only
,
9488 if (argv_find(argv
, argc
, "dampening", &idx
)) {
9489 if (argv_find(argv
, argc
, "dampened-paths", &idx
))
9490 return bgp_show(vty
, bgp
, afi
, safi
,
9491 bgp_show_type_dampend_paths
, NULL
, uj
);
9492 else if (argv_find(argv
, argc
, "flap-statistics", &idx
))
9493 return bgp_show(vty
, bgp
, afi
, safi
,
9494 bgp_show_type_flap_statistics
, NULL
,
9498 if (argv_find(argv
, argc
, "community", &idx
)) {
9499 char *maybecomm
= idx
+ 1 < argc
? argv
[idx
+ 1]->text
: NULL
;
9500 char *community
= NULL
;
9502 if (maybecomm
&& !strmatch(maybecomm
, "json")
9503 && !strmatch(maybecomm
, "exact-match"))
9504 community
= maybecomm
;
9506 if (argv_find(argv
, argc
, "exact-match", &idx
))
9510 return bgp_show_community(vty
, bgp
, community
,
9511 exact_match
, afi
, safi
, uj
);
9513 return (bgp_show(vty
, bgp
, afi
, safi
,
9514 bgp_show_type_community_all
, NULL
,
9518 return bgp_show(vty
, bgp
, afi
, safi
, sh_type
, NULL
, uj
);
9521 DEFUN (show_ip_bgp_route
,
9522 show_ip_bgp_route_cmd
,
9523 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]]"
9524 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
9528 BGP_INSTANCE_HELP_STR
9530 BGP_SAFI_WITH_LABEL_HELP_STR
9531 "Network in the BGP routing table to display\n"
9533 "Network in the BGP routing table to display\n"
9535 "Display only the bestpath\n"
9536 "Display only multipaths\n"
9539 int prefix_check
= 0;
9541 afi_t afi
= AFI_IP6
;
9542 safi_t safi
= SAFI_UNICAST
;
9543 char *prefix
= NULL
;
9544 struct bgp
*bgp
= NULL
;
9545 enum bgp_path_type path_type
;
9546 bool uj
= use_json(argc
, argv
);
9550 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9557 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
9561 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
9562 if (argv_find(argv
, argc
, "A.B.C.D", &idx
)
9563 || argv_find(argv
, argc
, "X:X::X:X", &idx
))
9565 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
)
9566 || argv_find(argv
, argc
, "X:X::X:X/M", &idx
))
9569 if ((argv
[idx
]->type
== IPV6_TKN
|| argv
[idx
]->type
== IPV6_PREFIX_TKN
)
9570 && afi
!= AFI_IP6
) {
9572 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
9575 if ((argv
[idx
]->type
== IPV4_TKN
|| argv
[idx
]->type
== IPV4_PREFIX_TKN
)
9578 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
9582 prefix
= argv
[idx
]->arg
;
9584 /* [<bestpath|multipath>] */
9585 if (argv_find(argv
, argc
, "bestpath", &idx
))
9586 path_type
= BGP_PATH_SHOW_BESTPATH
;
9587 else if (argv_find(argv
, argc
, "multipath", &idx
))
9588 path_type
= BGP_PATH_SHOW_MULTIPATH
;
9590 path_type
= BGP_PATH_SHOW_ALL
;
9592 return bgp_show_route(vty
, bgp
, prefix
, afi
, safi
, NULL
, prefix_check
,
9596 DEFUN (show_ip_bgp_regexp
,
9597 show_ip_bgp_regexp_cmd
,
9598 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] regexp REGEX...",
9602 BGP_INSTANCE_HELP_STR
9604 BGP_SAFI_WITH_LABEL_HELP_STR
9605 "Display routes matching the AS path regular expression\n"
9606 "A regular-expression to match the BGP AS paths\n")
9608 afi_t afi
= AFI_IP6
;
9609 safi_t safi
= SAFI_UNICAST
;
9610 struct bgp
*bgp
= NULL
;
9613 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9618 // get index of regex
9619 argv_find(argv
, argc
, "regexp", &idx
);
9622 char *regstr
= argv_concat(argv
, argc
, idx
);
9623 int rc
= bgp_show_regexp(vty
, bgp
, (const char *)regstr
, afi
, safi
,
9624 bgp_show_type_regexp
);
9625 XFREE(MTYPE_TMP
, regstr
);
9629 DEFUN (show_ip_bgp_instance_all
,
9630 show_ip_bgp_instance_all_cmd
,
9631 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] [json]",
9635 BGP_INSTANCE_ALL_HELP_STR
9637 BGP_SAFI_WITH_LABEL_HELP_STR
9641 safi_t safi
= SAFI_UNICAST
;
9642 struct bgp
*bgp
= NULL
;
9644 bool uj
= use_json(argc
, argv
);
9649 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
9654 bgp_show_all_instances_routes_vty(vty
, afi
, safi
, uj
);
9658 static int bgp_show_regexp(struct vty
*vty
, struct bgp
*bgp
, const char *regstr
,
9659 afi_t afi
, safi_t safi
, enum bgp_show_type type
)
9664 regex
= bgp_regcomp(regstr
);
9666 vty_out(vty
, "Can't compile regexp %s\n", regstr
);
9670 rc
= bgp_show(vty
, bgp
, afi
, safi
, type
, regex
, 0);
9671 bgp_regex_free(regex
);
9675 static int bgp_show_prefix_list(struct vty
*vty
, struct bgp
*bgp
,
9676 const char *prefix_list_str
, afi_t afi
,
9677 safi_t safi
, enum bgp_show_type type
)
9679 struct prefix_list
*plist
;
9681 plist
= prefix_list_lookup(afi
, prefix_list_str
);
9682 if (plist
== NULL
) {
9683 vty_out(vty
, "%% %s is not a valid prefix-list name\n",
9688 return bgp_show(vty
, bgp
, afi
, safi
, type
, plist
, 0);
9691 static int bgp_show_filter_list(struct vty
*vty
, struct bgp
*bgp
,
9692 const char *filter
, afi_t afi
, safi_t safi
,
9693 enum bgp_show_type type
)
9695 struct as_list
*as_list
;
9697 as_list
= as_list_lookup(filter
);
9698 if (as_list
== NULL
) {
9699 vty_out(vty
, "%% %s is not a valid AS-path access-list name\n",
9704 return bgp_show(vty
, bgp
, afi
, safi
, type
, as_list
, 0);
9707 static int bgp_show_route_map(struct vty
*vty
, struct bgp
*bgp
,
9708 const char *rmap_str
, afi_t afi
, safi_t safi
,
9709 enum bgp_show_type type
)
9711 struct route_map
*rmap
;
9713 rmap
= route_map_lookup_by_name(rmap_str
);
9715 vty_out(vty
, "%% %s is not a valid route-map name\n", rmap_str
);
9719 return bgp_show(vty
, bgp
, afi
, safi
, type
, rmap
, 0);
9722 static int bgp_show_community(struct vty
*vty
, struct bgp
*bgp
,
9723 const char *comstr
, int exact
, afi_t afi
,
9724 safi_t safi
, bool use_json
)
9726 struct community
*com
;
9729 com
= community_str2com(comstr
);
9731 vty_out(vty
, "%% Community malformed: %s\n", comstr
);
9735 ret
= bgp_show(vty
, bgp
, afi
, safi
,
9736 (exact
? bgp_show_type_community_exact
9737 : bgp_show_type_community
),
9739 community_free(&com
);
9744 static int bgp_show_community_list(struct vty
*vty
, struct bgp
*bgp
,
9745 const char *com
, int exact
, afi_t afi
,
9748 struct community_list
*list
;
9750 list
= community_list_lookup(bgp_clist
, com
, COMMUNITY_LIST_MASTER
);
9752 vty_out(vty
, "%% %s is not a valid community-list name\n", com
);
9756 return bgp_show(vty
, bgp
, afi
, safi
,
9757 (exact
? bgp_show_type_community_list_exact
9758 : bgp_show_type_community_list
),
9762 static int bgp_show_prefix_longer(struct vty
*vty
, struct bgp
*bgp
,
9763 const char *prefix
, afi_t afi
, safi_t safi
,
9764 enum bgp_show_type type
)
9771 ret
= str2prefix(prefix
, p
);
9773 vty_out(vty
, "%% Malformed Prefix\n");
9777 ret
= bgp_show(vty
, bgp
, afi
, safi
, type
, p
, 0);
9782 static struct peer
*peer_lookup_in_view(struct vty
*vty
, struct bgp
*bgp
,
9783 const char *ip_str
, bool use_json
)
9789 /* Get peer sockunion. */
9790 ret
= str2sockunion(ip_str
, &su
);
9792 peer
= peer_lookup_by_conf_if(bgp
, ip_str
);
9794 peer
= peer_lookup_by_hostname(bgp
, ip_str
);
9798 json_object
*json_no
= NULL
;
9799 json_no
= json_object_new_object();
9800 json_object_string_add(
9802 "malformedAddressOrName",
9804 vty_out(vty
, "%s\n",
9805 json_object_to_json_string_ext(
9807 JSON_C_TO_STRING_PRETTY
));
9808 json_object_free(json_no
);
9811 "%% Malformed address or name: %s\n",
9819 /* Peer structure lookup. */
9820 peer
= peer_lookup(bgp
, &su
);
9823 json_object
*json_no
= NULL
;
9824 json_no
= json_object_new_object();
9825 json_object_string_add(json_no
, "warning",
9826 "No such neighbor in this view/vrf");
9827 vty_out(vty
, "%s\n",
9828 json_object_to_json_string_ext(
9829 json_no
, JSON_C_TO_STRING_PRETTY
));
9830 json_object_free(json_no
);
9832 vty_out(vty
, "No such neighbor in this view/vrf\n");
9840 BGP_STATS_MAXBITLEN
= 0,
9844 BGP_STATS_UNAGGREGATEABLE
,
9845 BGP_STATS_MAX_AGGREGATEABLE
,
9846 BGP_STATS_AGGREGATES
,
9848 BGP_STATS_ASPATH_COUNT
,
9849 BGP_STATS_ASPATH_MAXHOPS
,
9850 BGP_STATS_ASPATH_TOTHOPS
,
9851 BGP_STATS_ASPATH_MAXSIZE
,
9852 BGP_STATS_ASPATH_TOTSIZE
,
9853 BGP_STATS_ASN_HIGHEST
,
9857 static const char *table_stats_strs
[] = {
9858 [BGP_STATS_PREFIXES
] = "Total Prefixes",
9859 [BGP_STATS_TOTPLEN
] = "Average prefix length",
9860 [BGP_STATS_RIB
] = "Total Advertisements",
9861 [BGP_STATS_UNAGGREGATEABLE
] = "Unaggregateable prefixes",
9862 [BGP_STATS_MAX_AGGREGATEABLE
] =
9863 "Maximum aggregateable prefixes",
9864 [BGP_STATS_AGGREGATES
] = "BGP Aggregate advertisements",
9865 [BGP_STATS_SPACE
] = "Address space advertised",
9866 [BGP_STATS_ASPATH_COUNT
] = "Advertisements with paths",
9867 [BGP_STATS_ASPATH_MAXHOPS
] = "Longest AS-Path (hops)",
9868 [BGP_STATS_ASPATH_MAXSIZE
] = "Largest AS-Path (bytes)",
9869 [BGP_STATS_ASPATH_TOTHOPS
] = "Average AS-Path length (hops)",
9870 [BGP_STATS_ASPATH_TOTSIZE
] = "Average AS-Path size (bytes)",
9871 [BGP_STATS_ASN_HIGHEST
] = "Highest public ASN",
9872 [BGP_STATS_MAX
] = NULL
,
9875 struct bgp_table_stats
{
9876 struct bgp_table
*table
;
9877 unsigned long long counts
[BGP_STATS_MAX
];
9882 #define TALLY_SIGFIG 100000
9883 static unsigned long
9884 ravg_tally (unsigned long count
, unsigned long oldavg
, unsigned long newval
)
9886 unsigned long newtot
= (count
-1) * oldavg
+ (newval
* TALLY_SIGFIG
);
9887 unsigned long res
= (newtot
* TALLY_SIGFIG
) / count
;
9888 unsigned long ret
= newtot
/ count
;
9890 if ((res
% TALLY_SIGFIG
) > (TALLY_SIGFIG
/2))
9897 static int bgp_table_stats_walker(struct thread
*t
)
9899 struct bgp_node
*rn
;
9900 struct bgp_node
*top
;
9901 struct bgp_table_stats
*ts
= THREAD_ARG(t
);
9902 unsigned int space
= 0;
9904 if (!(top
= bgp_table_top(ts
->table
)))
9907 switch (top
->p
.family
) {
9909 space
= IPV4_MAX_BITLEN
;
9912 space
= IPV6_MAX_BITLEN
;
9916 ts
->counts
[BGP_STATS_MAXBITLEN
] = space
;
9918 for (rn
= top
; rn
; rn
= bgp_route_next(rn
)) {
9919 struct bgp_path_info
*pi
;
9920 struct bgp_node
*prn
= bgp_node_parent_nolock(rn
);
9921 unsigned int pinum
= 0;
9929 ts
->counts
[BGP_STATS_PREFIXES
]++;
9930 ts
->counts
[BGP_STATS_TOTPLEN
] += rn
->p
.prefixlen
;
9933 ts
->counts
[BGP_STATS_AVGPLEN
]
9934 = ravg_tally (ts
->counts
[BGP_STATS_PREFIXES
],
9935 ts
->counts
[BGP_STATS_AVGPLEN
],
9939 /* check if the prefix is included by any other announcements */
9940 while (prn
&& !prn
->info
)
9941 prn
= bgp_node_parent_nolock(prn
);
9943 if (prn
== NULL
|| prn
== top
) {
9944 ts
->counts
[BGP_STATS_UNAGGREGATEABLE
]++;
9945 /* announced address space */
9948 pow(2.0, space
- rn
->p
.prefixlen
);
9949 } else if (prn
->info
)
9950 ts
->counts
[BGP_STATS_MAX_AGGREGATEABLE
]++;
9952 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
9954 ts
->counts
[BGP_STATS_RIB
]++;
9957 && (CHECK_FLAG(pi
->attr
->flag
,
9959 BGP_ATTR_ATOMIC_AGGREGATE
))))
9960 ts
->counts
[BGP_STATS_AGGREGATES
]++;
9963 if (pi
->attr
&& pi
->attr
->aspath
) {
9965 aspath_count_hops(pi
->attr
->aspath
);
9967 aspath_size(pi
->attr
->aspath
);
9968 as_t highest
= aspath_highest(pi
->attr
->aspath
);
9970 ts
->counts
[BGP_STATS_ASPATH_COUNT
]++;
9972 if (hops
> ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
])
9973 ts
->counts
[BGP_STATS_ASPATH_MAXHOPS
] =
9976 if (size
> ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
])
9977 ts
->counts
[BGP_STATS_ASPATH_MAXSIZE
] =
9980 ts
->counts
[BGP_STATS_ASPATH_TOTHOPS
] += hops
;
9981 ts
->counts
[BGP_STATS_ASPATH_TOTSIZE
] += size
;
9983 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
]
9984 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9985 ts
->counts
[BGP_STATS_ASPATH_AVGHOPS
],
9987 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
]
9988 = ravg_tally (ts
->counts
[BGP_STATS_ASPATH_COUNT
],
9989 ts
->counts
[BGP_STATS_ASPATH_AVGSIZE
],
9992 if (highest
> ts
->counts
[BGP_STATS_ASN_HIGHEST
])
9993 ts
->counts
[BGP_STATS_ASN_HIGHEST
] =
10001 static int bgp_table_stats(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
10004 struct bgp_table_stats ts
;
10007 if (!bgp
->rib
[afi
][safi
]) {
10008 vty_out(vty
, "%% No RIB exist's for the AFI(%d)/SAFI(%d)\n",
10010 return CMD_WARNING
;
10013 vty_out(vty
, "BGP %s RIB statistics\n", afi_safi_print(afi
, safi
));
10015 /* labeled-unicast routes live in the unicast table */
10016 if (safi
== SAFI_LABELED_UNICAST
)
10017 safi
= SAFI_UNICAST
;
10019 memset(&ts
, 0, sizeof(ts
));
10020 ts
.table
= bgp
->rib
[afi
][safi
];
10021 thread_execute(bm
->master
, bgp_table_stats_walker
, &ts
, 0);
10023 for (i
= 0; i
< BGP_STATS_MAX
; i
++) {
10024 if (!table_stats_strs
[i
])
10029 case BGP_STATS_ASPATH_AVGHOPS
:
10030 case BGP_STATS_ASPATH_AVGSIZE
:
10031 case BGP_STATS_AVGPLEN
:
10032 vty_out (vty
, "%-30s: ", table_stats_strs
[i
]);
10033 vty_out (vty
, "%12.2f",
10034 (float)ts
.counts
[i
] / (float)TALLY_SIGFIG
);
10037 case BGP_STATS_ASPATH_TOTHOPS
:
10038 case BGP_STATS_ASPATH_TOTSIZE
:
10039 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
10040 vty_out(vty
, "%12.2f",
10042 ? (float)ts
.counts
[i
]
10044 [BGP_STATS_ASPATH_COUNT
]
10047 case BGP_STATS_TOTPLEN
:
10048 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
10049 vty_out(vty
, "%12.2f",
10051 ? (float)ts
.counts
[i
]
10053 [BGP_STATS_PREFIXES
]
10056 case BGP_STATS_SPACE
:
10057 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
10058 vty_out(vty
, "%12g\n", ts
.total_space
);
10060 if (afi
== AFI_IP6
) {
10061 vty_out(vty
, "%30s: ", "/32 equivalent ");
10062 vty_out(vty
, "%12g\n",
10063 ts
.total_space
* pow(2.0, -128 + 32));
10064 vty_out(vty
, "%30s: ", "/48 equivalent ");
10065 vty_out(vty
, "%12g\n",
10066 ts
.total_space
* pow(2.0, -128 + 48));
10068 vty_out(vty
, "%30s: ", "% announced ");
10069 vty_out(vty
, "%12.2f\n",
10070 ts
.total_space
* 100. * pow(2.0, -32));
10071 vty_out(vty
, "%30s: ", "/8 equivalent ");
10072 vty_out(vty
, "%12.2f\n",
10073 ts
.total_space
* pow(2.0, -32 + 8));
10074 vty_out(vty
, "%30s: ", "/24 equivalent ");
10075 vty_out(vty
, "%12.2f\n",
10076 ts
.total_space
* pow(2.0, -32 + 24));
10080 vty_out(vty
, "%-30s: ", table_stats_strs
[i
]);
10081 vty_out(vty
, "%12llu", ts
.counts
[i
]);
10084 vty_out(vty
, "\n");
10086 return CMD_SUCCESS
;
10098 PCOUNT_PFCNT
, /* the figure we display to users */
10102 static const char *pcount_strs
[] = {
10103 [PCOUNT_ADJ_IN
] = "Adj-in",
10104 [PCOUNT_DAMPED
] = "Damped",
10105 [PCOUNT_REMOVED
] = "Removed",
10106 [PCOUNT_HISTORY
] = "History",
10107 [PCOUNT_STALE
] = "Stale",
10108 [PCOUNT_VALID
] = "Valid",
10109 [PCOUNT_ALL
] = "All RIB",
10110 [PCOUNT_COUNTED
] = "PfxCt counted",
10111 [PCOUNT_PFCNT
] = "Useable",
10112 [PCOUNT_MAX
] = NULL
,
10115 struct peer_pcounts
{
10116 unsigned int count
[PCOUNT_MAX
];
10117 const struct peer
*peer
;
10118 const struct bgp_table
*table
;
10121 static int bgp_peer_count_walker(struct thread
*t
)
10123 struct bgp_node
*rn
;
10124 struct peer_pcounts
*pc
= THREAD_ARG(t
);
10125 const struct peer
*peer
= pc
->peer
;
10127 for (rn
= bgp_table_top(pc
->table
); rn
; rn
= bgp_route_next(rn
)) {
10128 struct bgp_adj_in
*ain
;
10129 struct bgp_path_info
*pi
;
10131 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
)
10132 if (ain
->peer
== peer
)
10133 pc
->count
[PCOUNT_ADJ_IN
]++;
10135 for (pi
= rn
->info
; pi
; pi
= pi
->next
) {
10136 if (pi
->peer
!= peer
)
10139 pc
->count
[PCOUNT_ALL
]++;
10141 if (CHECK_FLAG(pi
->flags
, BGP_PATH_DAMPED
))
10142 pc
->count
[PCOUNT_DAMPED
]++;
10143 if (CHECK_FLAG(pi
->flags
, BGP_PATH_HISTORY
))
10144 pc
->count
[PCOUNT_HISTORY
]++;
10145 if (CHECK_FLAG(pi
->flags
, BGP_PATH_REMOVED
))
10146 pc
->count
[PCOUNT_REMOVED
]++;
10147 if (CHECK_FLAG(pi
->flags
, BGP_PATH_STALE
))
10148 pc
->count
[PCOUNT_STALE
]++;
10149 if (CHECK_FLAG(pi
->flags
, BGP_PATH_VALID
))
10150 pc
->count
[PCOUNT_VALID
]++;
10151 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_UNUSEABLE
))
10152 pc
->count
[PCOUNT_PFCNT
]++;
10154 if (CHECK_FLAG(pi
->flags
, BGP_PATH_COUNTED
)) {
10155 pc
->count
[PCOUNT_COUNTED
]++;
10156 if (CHECK_FLAG(pi
->flags
, BGP_PATH_UNUSEABLE
))
10158 EC_LIB_DEVELOPMENT
,
10159 "Attempting to count but flags say it is unusable");
10161 if (!CHECK_FLAG(pi
->flags
, BGP_PATH_UNUSEABLE
))
10163 EC_LIB_DEVELOPMENT
,
10164 "Not counted but flags say we should");
10171 static int bgp_peer_counts(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
10172 safi_t safi
, bool use_json
)
10174 struct peer_pcounts pcounts
= {.peer
= peer
};
10176 json_object
*json
= NULL
;
10177 json_object
*json_loop
= NULL
;
10180 json
= json_object_new_object();
10181 json_loop
= json_object_new_object();
10184 if (!peer
|| !peer
->bgp
|| !peer
->afc
[afi
][safi
]
10185 || !peer
->bgp
->rib
[afi
][safi
]) {
10187 json_object_string_add(
10189 "No such neighbor or address family");
10190 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10191 json_object_free(json
);
10193 vty_out(vty
, "%% No such neighbor or address family\n");
10195 return CMD_WARNING
;
10198 memset(&pcounts
, 0, sizeof(pcounts
));
10199 pcounts
.peer
= peer
;
10200 pcounts
.table
= peer
->bgp
->rib
[afi
][safi
];
10202 /* in-place call via thread subsystem so as to record execution time
10203 * stats for the thread-walk (i.e. ensure this can't be blamed on
10204 * on just vty_read()).
10206 thread_execute(bm
->master
, bgp_peer_count_walker
, &pcounts
, 0);
10209 json_object_string_add(json
, "prefixCountsFor", peer
->host
);
10210 json_object_string_add(json
, "multiProtocol",
10211 afi_safi_print(afi
, safi
));
10212 json_object_int_add(json
, "pfxCounter",
10213 peer
->pcount
[afi
][safi
]);
10215 for (i
= 0; i
< PCOUNT_MAX
; i
++)
10216 json_object_int_add(json_loop
, pcount_strs
[i
],
10219 json_object_object_add(json
, "ribTableWalkCounters", json_loop
);
10221 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
]) {
10222 json_object_string_add(json
, "pfxctDriftFor",
10224 json_object_string_add(
10225 json
, "recommended",
10226 "Please report this bug, with the above command output");
10228 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10229 json
, JSON_C_TO_STRING_PRETTY
));
10230 json_object_free(json
);
10234 && bgp_flag_check(peer
->bgp
, BGP_FLAG_SHOW_HOSTNAME
)) {
10235 vty_out(vty
, "Prefix counts for %s/%s, %s\n",
10236 peer
->hostname
, peer
->host
,
10237 afi_safi_print(afi
, safi
));
10239 vty_out(vty
, "Prefix counts for %s, %s\n", peer
->host
,
10240 afi_safi_print(afi
, safi
));
10243 vty_out(vty
, "PfxCt: %ld\n", peer
->pcount
[afi
][safi
]);
10244 vty_out(vty
, "\nCounts from RIB table walk:\n\n");
10246 for (i
= 0; i
< PCOUNT_MAX
; i
++)
10247 vty_out(vty
, "%20s: %-10d\n", pcount_strs
[i
],
10250 if (pcounts
.count
[PCOUNT_PFCNT
] != peer
->pcount
[afi
][safi
]) {
10251 vty_out(vty
, "%s [pcount] PfxCt drift!\n", peer
->host
);
10253 "Please report this bug, with the above command output\n");
10257 return CMD_SUCCESS
;
10260 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts
,
10261 show_ip_bgp_instance_neighbor_prefix_counts_cmd
,
10262 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_CMD_STR
"]] "
10263 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
10267 BGP_INSTANCE_HELP_STR
10270 "Detailed information on TCP and BGP neighbor connections\n"
10271 "Neighbor to display information about\n"
10272 "Neighbor to display information about\n"
10273 "Neighbor on BGP configured interface\n"
10274 "Display detailed prefix count information\n"
10277 afi_t afi
= AFI_IP6
;
10278 safi_t safi
= SAFI_UNICAST
;
10281 struct bgp
*bgp
= NULL
;
10282 bool uj
= use_json(argc
, argv
);
10287 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10290 return CMD_WARNING
;
10292 argv_find(argv
, argc
, "neighbors", &idx
);
10293 peer
= peer_lookup_in_view(vty
, bgp
, argv
[idx
+ 1]->arg
, uj
);
10295 return CMD_WARNING
;
10297 return bgp_peer_counts(vty
, peer
, AFI_IP
, SAFI_UNICAST
, uj
);
10300 #ifdef KEEP_OLD_VPN_COMMANDS
10301 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts
,
10302 show_ip_bgp_vpn_neighbor_prefix_counts_cmd
,
10303 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
10308 "Display information about all VPNv4 NLRIs\n"
10309 "Detailed information on TCP and BGP neighbor connections\n"
10310 "Neighbor to display information about\n"
10311 "Neighbor to display information about\n"
10312 "Neighbor on BGP configured interface\n"
10313 "Display detailed prefix count information\n"
10318 bool uj
= use_json(argc
, argv
);
10320 peer
= peer_lookup_in_view(vty
, NULL
, argv
[idx_peer
]->arg
, uj
);
10322 return CMD_WARNING
;
10324 return bgp_peer_counts(vty
, peer
, AFI_IP
, SAFI_MPLS_VPN
, uj
);
10327 DEFUN (show_ip_bgp_vpn_all_route_prefix
,
10328 show_ip_bgp_vpn_all_route_prefix_cmd
,
10329 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
10334 "Display information about all VPNv4 NLRIs\n"
10335 "Network in the BGP routing table to display\n"
10336 "Network in the BGP routing table to display\n"
10340 char *network
= NULL
;
10341 struct bgp
*bgp
= bgp_get_default();
10343 vty_out(vty
, "Can't find default instance\n");
10344 return CMD_WARNING
;
10347 if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
10348 network
= argv
[idx
]->arg
;
10349 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
))
10350 network
= argv
[idx
]->arg
;
10352 vty_out(vty
, "Unable to figure out Network\n");
10353 return CMD_WARNING
;
10356 return bgp_show_route(vty
, bgp
, network
, AFI_IP
, SAFI_MPLS_VPN
, NULL
, 0,
10357 BGP_PATH_SHOW_ALL
, use_json(argc
, argv
));
10359 #endif /* KEEP_OLD_VPN_COMMANDS */
10361 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix
,
10362 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
,
10363 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
10369 "Display information about all EVPN NLRIs\n"
10370 "Network in the BGP routing table to display\n"
10371 "Network in the BGP routing table to display\n"
10375 char *network
= NULL
;
10377 if (argv_find(argv
, argc
, "A.B.C.D", &idx
))
10378 network
= argv
[idx
]->arg
;
10379 else if (argv_find(argv
, argc
, "A.B.C.D/M", &idx
))
10380 network
= argv
[idx
]->arg
;
10382 vty_out(vty
, "Unable to figure out Network\n");
10383 return CMD_WARNING
;
10385 return bgp_show_route(vty
, NULL
, network
, AFI_L2VPN
, SAFI_EVPN
, NULL
, 0,
10386 BGP_PATH_SHOW_ALL
, use_json(argc
, argv
));
10389 static void show_adj_route(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
10390 safi_t safi
, enum bgp_show_adj_route_type type
,
10391 const char *rmap_name
, bool use_json
,
10394 struct bgp_table
*table
;
10395 struct bgp_adj_in
*ain
;
10396 struct bgp_adj_out
*adj
;
10397 unsigned long output_count
;
10398 unsigned long filtered_count
;
10399 struct bgp_node
*rn
;
10405 struct update_subgroup
*subgrp
;
10406 json_object
*json_scode
= NULL
;
10407 json_object
*json_ocode
= NULL
;
10408 json_object
*json_ar
= NULL
;
10409 struct peer_af
*paf
;
10410 bool route_filtered
;
10413 json_scode
= json_object_new_object();
10414 json_ocode
= json_object_new_object();
10415 json_ar
= json_object_new_object();
10417 json_object_string_add(json_scode
, "suppressed", "s");
10418 json_object_string_add(json_scode
, "damped", "d");
10419 json_object_string_add(json_scode
, "history", "h");
10420 json_object_string_add(json_scode
, "valid", "*");
10421 json_object_string_add(json_scode
, "best", ">");
10422 json_object_string_add(json_scode
, "multipath", "=");
10423 json_object_string_add(json_scode
, "internal", "i");
10424 json_object_string_add(json_scode
, "ribFailure", "r");
10425 json_object_string_add(json_scode
, "stale", "S");
10426 json_object_string_add(json_scode
, "removed", "R");
10428 json_object_string_add(json_ocode
, "igp", "i");
10429 json_object_string_add(json_ocode
, "egp", "e");
10430 json_object_string_add(json_ocode
, "incomplete", "?");
10437 json_object_string_add(json
, "alert", "no BGP");
10438 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10439 json_object_free(json
);
10441 vty_out(vty
, "%% No bgp\n");
10445 table
= bgp
->rib
[afi
][safi
];
10447 output_count
= filtered_count
= 0;
10448 subgrp
= peer_subgroup(peer
, afi
, safi
);
10450 if (type
== bgp_show_adj_route_advertised
&& subgrp
10451 && CHECK_FLAG(subgrp
->sflags
, SUBGRP_STATUS_DEFAULT_ORIGINATE
)) {
10453 json_object_int_add(json
, "bgpTableVersion",
10455 json_object_string_add(json
, "bgpLocalRouterId",
10456 inet_ntoa(bgp
->router_id
));
10457 json_object_object_add(json
, "bgpStatusCodes",
10459 json_object_object_add(json
, "bgpOriginCodes",
10461 json_object_string_add(
10462 json
, "bgpOriginatingDefaultNetwork",
10463 (afi
== AFI_IP
) ? "0.0.0.0/0" : "::/0");
10465 vty_out(vty
, "BGP table version is %" PRIu64
10466 ", local router ID is %s, vrf id ",
10467 table
->version
, inet_ntoa(bgp
->router_id
));
10468 if (bgp
->vrf_id
== VRF_UNKNOWN
)
10469 vty_out(vty
, "%s", VRFID_NONE_STR
);
10471 vty_out(vty
, "%u", bgp
->vrf_id
);
10472 vty_out(vty
, "\n");
10473 vty_out(vty
, BGP_SHOW_SCODE_HEADER
);
10474 vty_out(vty
, BGP_SHOW_NCODE_HEADER
);
10475 vty_out(vty
, BGP_SHOW_OCODE_HEADER
);
10477 vty_out(vty
, "Originating default network %s\n\n",
10478 (afi
== AFI_IP
) ? "0.0.0.0/0" : "::/0");
10483 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
10484 if (type
== bgp_show_adj_route_received
10485 || type
== bgp_show_adj_route_filtered
) {
10486 for (ain
= rn
->adj_in
; ain
; ain
= ain
->next
) {
10487 if (ain
->peer
!= peer
|| !ain
->attr
)
10492 json_object_int_add(
10493 json
, "bgpTableVersion",
10495 json_object_string_add(
10497 "bgpLocalRouterId",
10500 json_object_object_add(
10501 json
, "bgpStatusCodes",
10503 json_object_object_add(
10504 json
, "bgpOriginCodes",
10508 "BGP table version is 0, local router ID is %s, vrf id ",
10511 if (bgp
->vrf_id
== VRF_UNKNOWN
)
10517 vty_out(vty
, "\n");
10519 BGP_SHOW_SCODE_HEADER
);
10521 BGP_SHOW_NCODE_HEADER
);
10523 BGP_SHOW_OCODE_HEADER
);
10529 vty_out(vty
, BGP_SHOW_HEADER
);
10533 bgp_attr_dup(&attr
, ain
->attr
);
10534 route_filtered
= false;
10536 /* Filter prefix using distribute list,
10537 * filter list or prefix list
10539 if ((bgp_input_filter(peer
, &rn
->p
, &attr
, afi
,
10540 safi
)) == FILTER_DENY
)
10541 route_filtered
= true;
10543 /* Filter prefix using route-map */
10544 ret
= bgp_input_modifier(peer
, &rn
->p
, &attr
,
10545 afi
, safi
, rmap_name
);
10547 if (type
== bgp_show_adj_route_filtered
&&
10548 !route_filtered
&& ret
!= RMAP_DENY
) {
10549 bgp_attr_undup(&attr
, ain
->attr
);
10553 if (type
== bgp_show_adj_route_received
&&
10554 (route_filtered
|| ret
== RMAP_DENY
))
10557 route_vty_out_tmp(vty
, &rn
->p
, &attr
, safi
,
10558 use_json
, json_ar
);
10559 bgp_attr_undup(&attr
, ain
->attr
);
10562 } else if (type
== bgp_show_adj_route_advertised
) {
10563 for (adj
= rn
->adj_out
; adj
; adj
= adj
->next
)
10564 SUBGRP_FOREACH_PEER (adj
->subgroup
, paf
) {
10565 if (paf
->peer
!= peer
|| !adj
->attr
)
10570 json_object_int_add(
10574 json_object_string_add(
10576 "bgpLocalRouterId",
10579 json_object_object_add(
10583 json_object_object_add(
10589 "BGP table version is %" PRIu64
10590 ", local router ID is %s, vrf id ",
10603 vty_out(vty
, "\n");
10605 BGP_SHOW_SCODE_HEADER
);
10607 BGP_SHOW_NCODE_HEADER
);
10609 BGP_SHOW_OCODE_HEADER
);
10620 bgp_attr_dup(&attr
, adj
->attr
);
10621 ret
= bgp_output_modifier(
10622 peer
, &rn
->p
, &attr
, afi
, safi
,
10625 if (ret
!= RMAP_DENY
) {
10626 route_vty_out_tmp(vty
, &rn
->p
,
10635 bgp_attr_undup(&attr
, adj
->attr
);
10641 json_object_object_add(json
, "advertisedRoutes", json_ar
);
10642 json_object_int_add(json
, "totalPrefixCounter", output_count
);
10643 json_object_int_add(json
, "filteredPrefixCounter",
10646 vty_out(vty
, "%s\n", json_object_to_json_string_ext(
10647 json
, JSON_C_TO_STRING_PRETTY
));
10648 json_object_free(json
);
10649 } else if (output_count
> 0) {
10650 if (filtered_count
> 0)
10652 "\nTotal number of prefixes %ld (%ld filtered)\n",
10653 output_count
, filtered_count
);
10655 vty_out(vty
, "\nTotal number of prefixes %ld\n",
10660 static int peer_adj_routes(struct vty
*vty
, struct peer
*peer
, afi_t afi
,
10661 safi_t safi
, enum bgp_show_adj_route_type type
,
10662 const char *rmap_name
, bool use_json
)
10664 json_object
*json
= NULL
;
10667 json
= json_object_new_object();
10669 /* labeled-unicast routes live in the unicast table */
10670 if (safi
== SAFI_LABELED_UNICAST
)
10671 safi
= SAFI_UNICAST
;
10673 if (!peer
|| !peer
->afc
[afi
][safi
]) {
10675 json_object_string_add(
10677 "No such neighbor or address family");
10678 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10679 json_object_free(json
);
10681 vty_out(vty
, "%% No such neighbor or address family\n");
10683 return CMD_WARNING
;
10686 if ((type
== bgp_show_adj_route_received
10687 || type
== bgp_show_adj_route_filtered
)
10688 && !CHECK_FLAG(peer
->af_flags
[afi
][safi
],
10689 PEER_FLAG_SOFT_RECONFIG
)) {
10691 json_object_string_add(
10693 "Inbound soft reconfiguration not enabled");
10694 vty_out(vty
, "%s\n", json_object_to_json_string(json
));
10695 json_object_free(json
);
10698 "%% Inbound soft reconfiguration not enabled\n");
10700 return CMD_WARNING
;
10703 show_adj_route(vty
, peer
, afi
, safi
, type
, rmap_name
, use_json
, json
);
10705 return CMD_SUCCESS
;
10708 DEFUN (show_ip_bgp_instance_neighbor_advertised_route
,
10709 show_ip_bgp_instance_neighbor_advertised_route_cmd
,
10710 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
10711 "neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map WORD] [json]",
10715 BGP_INSTANCE_HELP_STR
10717 BGP_SAFI_WITH_LABEL_HELP_STR
10718 "Detailed information on TCP and BGP neighbor connections\n"
10719 "Neighbor to display information about\n"
10720 "Neighbor to display information about\n"
10721 "Neighbor on BGP configured interface\n"
10722 "Display the routes advertised to a BGP neighbor\n"
10723 "Display the received routes from neighbor\n"
10724 "Display the filtered routes received from neighbor\n"
10725 "Route-map to modify the attributes\n"
10726 "Name of the route map\n"
10729 afi_t afi
= AFI_IP6
;
10730 safi_t safi
= SAFI_UNICAST
;
10731 char *rmap_name
= NULL
;
10732 char *peerstr
= NULL
;
10733 struct bgp
*bgp
= NULL
;
10735 enum bgp_show_adj_route_type type
= bgp_show_adj_route_advertised
;
10737 bool uj
= use_json(argc
, argv
);
10742 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10745 return CMD_WARNING
;
10747 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10748 argv_find(argv
, argc
, "neighbors", &idx
);
10749 peerstr
= argv
[++idx
]->arg
;
10751 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
10753 return CMD_WARNING
;
10755 if (argv_find(argv
, argc
, "advertised-routes", &idx
))
10756 type
= bgp_show_adj_route_advertised
;
10757 else if (argv_find(argv
, argc
, "received-routes", &idx
))
10758 type
= bgp_show_adj_route_received
;
10759 else if (argv_find(argv
, argc
, "filtered-routes", &idx
))
10760 type
= bgp_show_adj_route_filtered
;
10762 if (argv_find(argv
, argc
, "route-map", &idx
))
10763 rmap_name
= argv
[++idx
]->arg
;
10765 return peer_adj_routes(vty
, peer
, afi
, safi
, type
, rmap_name
, uj
);
10768 DEFUN (show_ip_bgp_neighbor_received_prefix_filter
,
10769 show_ip_bgp_neighbor_received_prefix_filter_cmd
,
10770 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
10776 "Address Family modifier\n"
10777 "Detailed information on TCP and BGP neighbor connections\n"
10778 "Neighbor to display information about\n"
10779 "Neighbor to display information about\n"
10780 "Neighbor on BGP configured interface\n"
10781 "Display information received from a BGP neighbor\n"
10782 "Display the prefixlist filter\n"
10785 afi_t afi
= AFI_IP6
;
10786 safi_t safi
= SAFI_UNICAST
;
10787 char *peerstr
= NULL
;
10790 union sockunion su
;
10796 /* show [ip] bgp */
10797 if (argv_find(argv
, argc
, "ip", &idx
))
10799 /* [<ipv4|ipv6> [unicast]] */
10800 if (argv_find(argv
, argc
, "ipv4", &idx
))
10802 if (argv_find(argv
, argc
, "ipv6", &idx
))
10804 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10805 argv_find(argv
, argc
, "neighbors", &idx
);
10806 peerstr
= argv
[++idx
]->arg
;
10808 bool uj
= use_json(argc
, argv
);
10810 ret
= str2sockunion(peerstr
, &su
);
10812 peer
= peer_lookup_by_conf_if(NULL
, peerstr
);
10815 vty_out(vty
, "{}\n");
10818 "%% Malformed address or name: %s\n",
10820 return CMD_WARNING
;
10823 peer
= peer_lookup(NULL
, &su
);
10826 vty_out(vty
, "{}\n");
10828 vty_out(vty
, "No peer\n");
10829 return CMD_WARNING
;
10833 sprintf(name
, "%s.%d.%d", peer
->host
, afi
, safi
);
10834 count
= prefix_bgp_show_prefix_list(NULL
, afi
, name
, uj
);
10837 vty_out(vty
, "Address Family: %s\n",
10838 afi_safi_print(afi
, safi
));
10839 prefix_bgp_show_prefix_list(vty
, afi
, name
, uj
);
10842 vty_out(vty
, "{}\n");
10844 vty_out(vty
, "No functional output\n");
10847 return CMD_SUCCESS
;
10850 static int bgp_show_neighbor_route(struct vty
*vty
, struct peer
*peer
,
10851 afi_t afi
, safi_t safi
,
10852 enum bgp_show_type type
, bool use_json
)
10854 /* labeled-unicast routes live in the unicast table */
10855 if (safi
== SAFI_LABELED_UNICAST
)
10856 safi
= SAFI_UNICAST
;
10858 if (!peer
|| !peer
->afc
[afi
][safi
]) {
10860 json_object
*json_no
= NULL
;
10861 json_no
= json_object_new_object();
10862 json_object_string_add(
10863 json_no
, "warning",
10864 "No such neighbor or address family");
10865 vty_out(vty
, "%s\n",
10866 json_object_to_json_string(json_no
));
10867 json_object_free(json_no
);
10869 vty_out(vty
, "%% No such neighbor or address family\n");
10870 return CMD_WARNING
;
10873 return bgp_show(vty
, peer
->bgp
, afi
, safi
, type
, &peer
->su
, use_json
);
10876 DEFUN (show_ip_bgp_flowspec_routes_detailed
,
10877 show_ip_bgp_flowspec_routes_detailed_cmd
,
10878 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" flowspec] detail [json]",
10882 BGP_INSTANCE_HELP_STR
10885 "Detailed information on flowspec entries\n"
10888 afi_t afi
= AFI_IP
;
10889 safi_t safi
= SAFI_UNICAST
;
10890 struct bgp
*bgp
= NULL
;
10892 bool uj
= use_json(argc
, argv
);
10897 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10900 return CMD_WARNING
;
10902 return bgp_show(vty
, bgp
, afi
, safi
, bgp_show_type_detail
, NULL
, uj
);
10905 DEFUN (show_ip_bgp_neighbor_routes
,
10906 show_ip_bgp_neighbor_routes_cmd
,
10907 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR
" ["BGP_SAFI_WITH_LABEL_CMD_STR
"]] "
10908 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
10912 BGP_INSTANCE_HELP_STR
10914 BGP_SAFI_WITH_LABEL_HELP_STR
10915 "Detailed information on TCP and BGP neighbor connections\n"
10916 "Neighbor to display information about\n"
10917 "Neighbor to display information about\n"
10918 "Neighbor on BGP configured interface\n"
10919 "Display flap statistics of the routes learned from neighbor\n"
10920 "Display the dampened routes received from neighbor\n"
10921 "Display routes learned from neighbor\n"
10924 char *peerstr
= NULL
;
10925 struct bgp
*bgp
= NULL
;
10926 afi_t afi
= AFI_IP6
;
10927 safi_t safi
= SAFI_UNICAST
;
10929 enum bgp_show_type sh_type
= bgp_show_type_neighbor
;
10931 bool uj
= use_json(argc
, argv
);
10936 bgp_vty_find_and_parse_afi_safi_bgp(vty
, argv
, argc
, &idx
, &afi
, &safi
,
10939 return CMD_WARNING
;
10941 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10942 argv_find(argv
, argc
, "neighbors", &idx
);
10943 peerstr
= argv
[++idx
]->arg
;
10945 peer
= peer_lookup_in_view(vty
, bgp
, peerstr
, uj
);
10947 return CMD_WARNING
;
10949 if (argv_find(argv
, argc
, "flap-statistics", &idx
))
10950 sh_type
= bgp_show_type_flap_neighbor
;
10951 else if (argv_find(argv
, argc
, "dampened-routes", &idx
))
10952 sh_type
= bgp_show_type_damp_neighbor
;
10953 else if (argv_find(argv
, argc
, "routes", &idx
))
10954 sh_type
= bgp_show_type_neighbor
;
10956 return bgp_show_neighbor_route(vty
, peer
, afi
, safi
, sh_type
, uj
);
10959 struct bgp_table
*bgp_distance_table
[AFI_MAX
][SAFI_MAX
];
10961 struct bgp_distance
{
10962 /* Distance value for the IP source prefix. */
10965 /* Name of the access-list to be matched. */
10969 DEFUN (show_bgp_afi_vpn_rd_route
,
10970 show_bgp_afi_vpn_rd_route_cmd
,
10971 "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]",
10975 "Address Family modifier\n"
10976 "Display information for a route distinguisher\n"
10977 "Route Distinguisher\n"
10978 "Network in the BGP routing table to display\n"
10979 "Network in the BGP routing table to display\n"
10983 struct prefix_rd prd
;
10984 afi_t afi
= AFI_MAX
;
10987 if (!argv_find_and_parse_afi(argv
, argc
, &idx
, &afi
)) {
10988 vty_out(vty
, "%% Malformed Address Family\n");
10989 return CMD_WARNING
;
10992 ret
= str2prefix_rd(argv
[5]->arg
, &prd
);
10994 vty_out(vty
, "%% Malformed Route Distinguisher\n");
10995 return CMD_WARNING
;
10998 return bgp_show_route(vty
, NULL
, argv
[6]->arg
, afi
, SAFI_MPLS_VPN
, &prd
,
10999 0, BGP_PATH_SHOW_ALL
, use_json(argc
, argv
));
11002 static struct bgp_distance
*bgp_distance_new(void)
11004 return XCALLOC(MTYPE_BGP_DISTANCE
, sizeof(struct bgp_distance
));
11007 static void bgp_distance_free(struct bgp_distance
*bdistance
)
11009 XFREE(MTYPE_BGP_DISTANCE
, bdistance
);
11012 static int bgp_distance_set(struct vty
*vty
, const char *distance_str
,
11013 const char *ip_str
, const char *access_list_str
)
11020 struct bgp_node
*rn
;
11021 struct bgp_distance
*bdistance
;
11023 afi
= bgp_node_afi(vty
);
11024 safi
= bgp_node_safi(vty
);
11026 ret
= str2prefix(ip_str
, &p
);
11028 vty_out(vty
, "Malformed prefix\n");
11029 return CMD_WARNING_CONFIG_FAILED
;
11032 distance
= atoi(distance_str
);
11034 /* Get BGP distance node. */
11035 rn
= bgp_node_get(bgp_distance_table
[afi
][safi
], (struct prefix
*)&p
);
11036 bdistance
= bgp_distance_get_node(rn
);
11038 bgp_unlock_node(rn
);
11040 bdistance
= bgp_distance_new();
11041 bgp_distance_set_node_info(rn
, bdistance
);
11044 /* Set distance value. */
11045 bdistance
->distance
= distance
;
11047 /* Reset access-list configuration. */
11048 if (bdistance
->access_list
) {
11049 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
11050 bdistance
->access_list
= NULL
;
11052 if (access_list_str
)
11053 bdistance
->access_list
=
11054 XSTRDUP(MTYPE_AS_LIST
, access_list_str
);
11056 return CMD_SUCCESS
;
11059 static int bgp_distance_unset(struct vty
*vty
, const char *distance_str
,
11060 const char *ip_str
, const char *access_list_str
)
11067 struct bgp_node
*rn
;
11068 struct bgp_distance
*bdistance
;
11070 afi
= bgp_node_afi(vty
);
11071 safi
= bgp_node_safi(vty
);
11073 ret
= str2prefix(ip_str
, &p
);
11075 vty_out(vty
, "Malformed prefix\n");
11076 return CMD_WARNING_CONFIG_FAILED
;
11079 rn
= bgp_node_lookup(bgp_distance_table
[afi
][safi
],
11080 (struct prefix
*)&p
);
11082 vty_out(vty
, "Can't find specified prefix\n");
11083 return CMD_WARNING_CONFIG_FAILED
;
11086 bdistance
= bgp_distance_get_node(rn
);
11087 distance
= atoi(distance_str
);
11089 if (bdistance
->distance
!= distance
) {
11090 vty_out(vty
, "Distance does not match configured\n");
11091 return CMD_WARNING_CONFIG_FAILED
;
11094 if (bdistance
->access_list
)
11095 XFREE(MTYPE_AS_LIST
, bdistance
->access_list
);
11096 bgp_distance_free(bdistance
);
11099 bgp_unlock_node(rn
);
11100 bgp_unlock_node(rn
);
11102 return CMD_SUCCESS
;
11105 /* Apply BGP information to distance method. */
11106 uint8_t bgp_distance_apply(struct prefix
*p
, struct bgp_path_info
*pinfo
,
11107 afi_t afi
, safi_t safi
, struct bgp
*bgp
)
11109 struct bgp_node
*rn
;
11112 struct bgp_distance
*bdistance
;
11113 struct access_list
*alist
;
11114 struct bgp_static
*bgp_static
;
11119 peer
= pinfo
->peer
;
11121 /* Check source address. */
11122 sockunion2hostprefix(&peer
->su
, &q
);
11123 rn
= bgp_node_match(bgp_distance_table
[afi
][safi
], &q
);
11125 bdistance
= bgp_distance_get_node(rn
);
11126 bgp_unlock_node(rn
);
11128 if (bdistance
->access_list
) {
11129 alist
= access_list_lookup(afi
, bdistance
->access_list
);
11131 && access_list_apply(alist
, p
) == FILTER_PERMIT
)
11132 return bdistance
->distance
;
11134 return bdistance
->distance
;
11137 /* Backdoor check. */
11138 rn
= bgp_node_lookup(bgp
->route
[afi
][safi
], p
);
11140 bgp_static
= bgp_static_get_node_info(rn
);
11141 bgp_unlock_node(rn
);
11143 if (bgp_static
->backdoor
) {
11144 if (bgp
->distance_local
[afi
][safi
])
11145 return bgp
->distance_local
[afi
][safi
];
11147 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
11151 if (peer
->sort
== BGP_PEER_EBGP
) {
11152 if (bgp
->distance_ebgp
[afi
][safi
])
11153 return bgp
->distance_ebgp
[afi
][safi
];
11154 return ZEBRA_EBGP_DISTANCE_DEFAULT
;
11156 if (bgp
->distance_ibgp
[afi
][safi
])
11157 return bgp
->distance_ibgp
[afi
][safi
];
11158 return ZEBRA_IBGP_DISTANCE_DEFAULT
;
11162 DEFUN (bgp_distance
,
11164 "distance bgp (1-255) (1-255) (1-255)",
11165 "Define an administrative distance\n"
11167 "Distance for routes external to the AS\n"
11168 "Distance for routes internal to the AS\n"
11169 "Distance for local routes\n")
11171 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
11172 int idx_number
= 2;
11173 int idx_number_2
= 3;
11174 int idx_number_3
= 4;
11178 afi
= bgp_node_afi(vty
);
11179 safi
= bgp_node_safi(vty
);
11181 bgp
->distance_ebgp
[afi
][safi
] = atoi(argv
[idx_number
]->arg
);
11182 bgp
->distance_ibgp
[afi
][safi
] = atoi(argv
[idx_number_2
]->arg
);
11183 bgp
->distance_local
[afi
][safi
] = atoi(argv
[idx_number_3
]->arg
);
11184 return CMD_SUCCESS
;
11187 DEFUN (no_bgp_distance
,
11188 no_bgp_distance_cmd
,
11189 "no distance bgp [(1-255) (1-255) (1-255)]",
11191 "Define an administrative distance\n"
11193 "Distance for routes external to the AS\n"
11194 "Distance for routes internal to the AS\n"
11195 "Distance for local routes\n")
11197 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
11201 afi
= bgp_node_afi(vty
);
11202 safi
= bgp_node_safi(vty
);
11204 bgp
->distance_ebgp
[afi
][safi
] = 0;
11205 bgp
->distance_ibgp
[afi
][safi
] = 0;
11206 bgp
->distance_local
[afi
][safi
] = 0;
11207 return CMD_SUCCESS
;
11211 DEFUN (bgp_distance_source
,
11212 bgp_distance_source_cmd
,
11213 "distance (1-255) A.B.C.D/M",
11214 "Define an administrative distance\n"
11215 "Administrative distance\n"
11216 "IP source prefix\n")
11218 int idx_number
= 1;
11219 int idx_ipv4_prefixlen
= 2;
11220 bgp_distance_set(vty
, argv
[idx_number
]->arg
,
11221 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
11222 return CMD_SUCCESS
;
11225 DEFUN (no_bgp_distance_source
,
11226 no_bgp_distance_source_cmd
,
11227 "no distance (1-255) A.B.C.D/M",
11229 "Define an administrative distance\n"
11230 "Administrative distance\n"
11231 "IP source prefix\n")
11233 int idx_number
= 2;
11234 int idx_ipv4_prefixlen
= 3;
11235 bgp_distance_unset(vty
, argv
[idx_number
]->arg
,
11236 argv
[idx_ipv4_prefixlen
]->arg
, NULL
);
11237 return CMD_SUCCESS
;
11240 DEFUN (bgp_distance_source_access_list
,
11241 bgp_distance_source_access_list_cmd
,
11242 "distance (1-255) A.B.C.D/M WORD",
11243 "Define an administrative distance\n"
11244 "Administrative distance\n"
11245 "IP source prefix\n"
11246 "Access list name\n")
11248 int idx_number
= 1;
11249 int idx_ipv4_prefixlen
= 2;
11251 bgp_distance_set(vty
, argv
[idx_number
]->arg
,
11252 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
11253 return CMD_SUCCESS
;
11256 DEFUN (no_bgp_distance_source_access_list
,
11257 no_bgp_distance_source_access_list_cmd
,
11258 "no distance (1-255) A.B.C.D/M WORD",
11260 "Define an administrative distance\n"
11261 "Administrative distance\n"
11262 "IP source prefix\n"
11263 "Access list name\n")
11265 int idx_number
= 2;
11266 int idx_ipv4_prefixlen
= 3;
11268 bgp_distance_unset(vty
, argv
[idx_number
]->arg
,
11269 argv
[idx_ipv4_prefixlen
]->arg
, argv
[idx_word
]->arg
);
11270 return CMD_SUCCESS
;
11273 DEFUN (ipv6_bgp_distance_source
,
11274 ipv6_bgp_distance_source_cmd
,
11275 "distance (1-255) X:X::X:X/M",
11276 "Define an administrative distance\n"
11277 "Administrative distance\n"
11278 "IP source prefix\n")
11280 bgp_distance_set(vty
, argv
[1]->arg
, argv
[2]->arg
, NULL
);
11281 return CMD_SUCCESS
;
11284 DEFUN (no_ipv6_bgp_distance_source
,
11285 no_ipv6_bgp_distance_source_cmd
,
11286 "no distance (1-255) X:X::X:X/M",
11288 "Define an administrative distance\n"
11289 "Administrative distance\n"
11290 "IP source prefix\n")
11292 bgp_distance_unset(vty
, argv
[2]->arg
, argv
[3]->arg
, NULL
);
11293 return CMD_SUCCESS
;
11296 DEFUN (ipv6_bgp_distance_source_access_list
,
11297 ipv6_bgp_distance_source_access_list_cmd
,
11298 "distance (1-255) X:X::X:X/M WORD",
11299 "Define an administrative distance\n"
11300 "Administrative distance\n"
11301 "IP source prefix\n"
11302 "Access list name\n")
11304 bgp_distance_set(vty
, argv
[1]->arg
, argv
[2]->arg
, argv
[3]->arg
);
11305 return CMD_SUCCESS
;
11308 DEFUN (no_ipv6_bgp_distance_source_access_list
,
11309 no_ipv6_bgp_distance_source_access_list_cmd
,
11310 "no distance (1-255) X:X::X:X/M WORD",
11312 "Define an administrative distance\n"
11313 "Administrative distance\n"
11314 "IP source prefix\n"
11315 "Access list name\n")
11317 bgp_distance_unset(vty
, argv
[2]->arg
, argv
[3]->arg
, argv
[4]->arg
);
11318 return CMD_SUCCESS
;
11321 DEFUN (bgp_damp_set
,
11323 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
11324 "BGP Specific commands\n"
11325 "Enable route-flap dampening\n"
11326 "Half-life time for the penalty\n"
11327 "Value to start reusing a route\n"
11328 "Value to start suppressing a route\n"
11329 "Maximum duration to suppress a stable route\n")
11331 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
11332 int idx_half_life
= 2;
11334 int idx_suppress
= 4;
11335 int idx_max_suppress
= 5;
11336 int half
= DEFAULT_HALF_LIFE
* 60;
11337 int reuse
= DEFAULT_REUSE
;
11338 int suppress
= DEFAULT_SUPPRESS
;
11339 int max
= 4 * half
;
11342 half
= atoi(argv
[idx_half_life
]->arg
) * 60;
11343 reuse
= atoi(argv
[idx_reuse
]->arg
);
11344 suppress
= atoi(argv
[idx_suppress
]->arg
);
11345 max
= atoi(argv
[idx_max_suppress
]->arg
) * 60;
11346 } else if (argc
== 3) {
11347 half
= atoi(argv
[idx_half_life
]->arg
) * 60;
11351 if (suppress
< reuse
) {
11353 "Suppress value cannot be less than reuse value \n");
11357 return bgp_damp_enable(bgp
, bgp_node_afi(vty
), bgp_node_safi(vty
), half
,
11358 reuse
, suppress
, max
);
11361 DEFUN (bgp_damp_unset
,
11362 bgp_damp_unset_cmd
,
11363 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
11365 "BGP Specific commands\n"
11366 "Enable route-flap dampening\n"
11367 "Half-life time for the penalty\n"
11368 "Value to start reusing a route\n"
11369 "Value to start suppressing a route\n"
11370 "Maximum duration to suppress a stable route\n")
11372 VTY_DECLVAR_CONTEXT(bgp
, bgp
);
11373 return bgp_damp_disable(bgp
, bgp_node_afi(vty
), bgp_node_safi(vty
));
11376 /* Display specified route of BGP table. */
11377 static int bgp_clear_damp_route(struct vty
*vty
, const char *view_name
,
11378 const char *ip_str
, afi_t afi
, safi_t safi
,
11379 struct prefix_rd
*prd
, int prefix_check
)
11382 struct prefix match
;
11383 struct bgp_node
*rn
;
11384 struct bgp_node
*rm
;
11385 struct bgp_path_info
*pi
;
11386 struct bgp_path_info
*pi_temp
;
11388 struct bgp_table
*table
;
11390 /* BGP structure lookup. */
11392 bgp
= bgp_lookup_by_name(view_name
);
11394 vty_out(vty
, "%% Can't find BGP instance %s\n",
11396 return CMD_WARNING
;
11399 bgp
= bgp_get_default();
11401 vty_out(vty
, "%% No BGP process is configured\n");
11402 return CMD_WARNING
;
11406 /* Check IP address argument. */
11407 ret
= str2prefix(ip_str
, &match
);
11409 vty_out(vty
, "%% address is malformed\n");
11410 return CMD_WARNING
;
11413 match
.family
= afi2family(afi
);
11415 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)
11416 || (safi
== SAFI_EVPN
)) {
11417 for (rn
= bgp_table_top(bgp
->rib
[AFI_IP
][safi
]); rn
;
11418 rn
= bgp_route_next(rn
)) {
11419 if (prd
&& memcmp(rn
->p
.u
.val
, prd
->val
, 8) != 0)
11421 if ((table
= rn
->info
) == NULL
)
11423 if ((rm
= bgp_node_match(table
, &match
)) == NULL
)
11427 || rm
->p
.prefixlen
== match
.prefixlen
) {
11430 if (pi
->extra
&& pi
->extra
->damp_info
) {
11431 pi_temp
= pi
->next
;
11432 bgp_damp_info_free(
11433 pi
->extra
->damp_info
,
11441 bgp_unlock_node(rm
);
11444 if ((rn
= bgp_node_match(bgp
->rib
[afi
][safi
], &match
))
11447 || rn
->p
.prefixlen
== match
.prefixlen
) {
11450 if (pi
->extra
&& pi
->extra
->damp_info
) {
11451 pi_temp
= pi
->next
;
11452 bgp_damp_info_free(
11453 pi
->extra
->damp_info
,
11461 bgp_unlock_node(rn
);
11465 return CMD_SUCCESS
;
11468 DEFUN (clear_ip_bgp_dampening
,
11469 clear_ip_bgp_dampening_cmd
,
11470 "clear ip bgp dampening",
11474 "Clear route flap dampening information\n")
11476 bgp_damp_info_clean();
11477 return CMD_SUCCESS
;
11480 DEFUN (clear_ip_bgp_dampening_prefix
,
11481 clear_ip_bgp_dampening_prefix_cmd
,
11482 "clear ip bgp dampening A.B.C.D/M",
11486 "Clear route flap dampening information\n"
11489 int idx_ipv4_prefixlen
= 4;
11490 return bgp_clear_damp_route(vty
, NULL
, argv
[idx_ipv4_prefixlen
]->arg
,
11491 AFI_IP
, SAFI_UNICAST
, NULL
, 1);
11494 DEFUN (clear_ip_bgp_dampening_address
,
11495 clear_ip_bgp_dampening_address_cmd
,
11496 "clear ip bgp dampening A.B.C.D",
11500 "Clear route flap dampening information\n"
11501 "Network to clear damping information\n")
11504 return bgp_clear_damp_route(vty
, NULL
, argv
[idx_ipv4
]->arg
, AFI_IP
,
11505 SAFI_UNICAST
, NULL
, 0);
11508 DEFUN (clear_ip_bgp_dampening_address_mask
,
11509 clear_ip_bgp_dampening_address_mask_cmd
,
11510 "clear ip bgp dampening A.B.C.D A.B.C.D",
11514 "Clear route flap dampening information\n"
11515 "Network to clear damping information\n"
11519 int idx_ipv4_2
= 5;
11521 char prefix_str
[BUFSIZ
];
11523 ret
= netmask_str2prefix_str(argv
[idx_ipv4
]->arg
, argv
[idx_ipv4_2
]->arg
,
11526 vty_out(vty
, "%% Inconsistent address and mask\n");
11527 return CMD_WARNING
;
11530 return bgp_clear_damp_route(vty
, NULL
, prefix_str
, AFI_IP
, SAFI_UNICAST
,
11534 static void show_bgp_peerhash_entry(struct hash_backet
*backet
, void *arg
)
11536 struct vty
*vty
= arg
;
11537 struct peer
*peer
= backet
->data
;
11538 char buf
[SU_ADDRSTRLEN
];
11540 vty_out(vty
, "\tPeer: %s %s\n", peer
->host
,
11541 sockunion2str(&peer
->su
, buf
, sizeof(buf
)));
11544 DEFUN (show_bgp_peerhash
,
11545 show_bgp_peerhash_cmd
,
11546 "show bgp peerhash",
11549 "Display information about the BGP peerhash\n")
11551 struct list
*instances
= bm
->bgp
;
11552 struct listnode
*node
;
11555 for (ALL_LIST_ELEMENTS_RO(instances
, node
, bgp
)) {
11556 vty_out(vty
, "BGP: %s\n", bgp
->name
);
11557 hash_iterate(bgp
->peerhash
, show_bgp_peerhash_entry
,
11561 return CMD_SUCCESS
;
11564 /* also used for encap safi */
11565 static void bgp_config_write_network_vpn(struct vty
*vty
, struct bgp
*bgp
,
11566 afi_t afi
, safi_t safi
)
11568 struct bgp_node
*prn
;
11569 struct bgp_node
*rn
;
11570 struct bgp_table
*table
;
11572 struct prefix_rd
*prd
;
11573 struct bgp_static
*bgp_static
;
11574 mpls_label_t label
;
11575 char buf
[SU_ADDRSTRLEN
];
11576 char rdbuf
[RD_ADDRSTRLEN
];
11578 /* Network configuration. */
11579 for (prn
= bgp_table_top(bgp
->route
[afi
][safi
]); prn
;
11580 prn
= bgp_route_next(prn
)) {
11581 if ((table
= prn
->info
) == NULL
)
11584 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
11585 bgp_static
= bgp_static_get_node_info(rn
);
11586 if (bgp_static
== NULL
)
11590 prd
= (struct prefix_rd
*)&prn
->p
;
11592 /* "network" configuration display. */
11593 prefix_rd2str(prd
, rdbuf
, sizeof(rdbuf
));
11594 label
= decode_label(&bgp_static
->label
);
11596 vty_out(vty
, " network %s/%d rd %s",
11597 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11599 p
->prefixlen
, rdbuf
);
11600 if (safi
== SAFI_MPLS_VPN
)
11601 vty_out(vty
, " label %u", label
);
11603 if (bgp_static
->rmap
.name
)
11604 vty_out(vty
, " route-map %s",
11605 bgp_static
->rmap
.name
);
11607 if (bgp_static
->backdoor
)
11608 vty_out(vty
, " backdoor");
11610 vty_out(vty
, "\n");
11615 static void bgp_config_write_network_evpn(struct vty
*vty
, struct bgp
*bgp
,
11616 afi_t afi
, safi_t safi
)
11618 struct bgp_node
*prn
;
11619 struct bgp_node
*rn
;
11620 struct bgp_table
*table
;
11622 struct prefix_rd
*prd
;
11623 struct bgp_static
*bgp_static
;
11624 char buf
[PREFIX_STRLEN
* 2];
11625 char buf2
[SU_ADDRSTRLEN
];
11626 char rdbuf
[RD_ADDRSTRLEN
];
11628 /* Network configuration. */
11629 for (prn
= bgp_table_top(bgp
->route
[afi
][safi
]); prn
;
11630 prn
= bgp_route_next(prn
)) {
11631 if ((table
= prn
->info
) == NULL
)
11634 for (rn
= bgp_table_top(table
); rn
; rn
= bgp_route_next(rn
)) {
11635 bgp_static
= bgp_static_get_node_info(rn
);
11636 if (bgp_static
== NULL
)
11639 char *macrouter
= NULL
;
11642 if (bgp_static
->router_mac
)
11643 macrouter
= prefix_mac2str(
11644 bgp_static
->router_mac
, NULL
, 0);
11645 if (bgp_static
->eth_s_id
)
11646 esi
= esi2str(bgp_static
->eth_s_id
);
11648 prd
= (struct prefix_rd
*)&prn
->p
;
11650 /* "network" configuration display. */
11651 prefix_rd2str(prd
, rdbuf
, sizeof(rdbuf
));
11652 if (p
->u
.prefix_evpn
.route_type
== 5) {
11653 char local_buf
[PREFIX_STRLEN
];
11654 uint8_t family
= is_evpn_prefix_ipaddr_v4((
11655 struct prefix_evpn
*)p
)
11659 &p
->u
.prefix_evpn
.prefix_addr
.ip
.ip
.addr
,
11660 local_buf
, PREFIX_STRLEN
);
11661 sprintf(buf
, "%s/%u", local_buf
,
11662 p
->u
.prefix_evpn
.prefix_addr
.ip_prefix_length
);
11664 prefix2str(p
, buf
, sizeof(buf
));
11667 if (bgp_static
->gatewayIp
.family
== AF_INET
11668 || bgp_static
->gatewayIp
.family
== AF_INET6
)
11669 inet_ntop(bgp_static
->gatewayIp
.family
,
11670 &bgp_static
->gatewayIp
.u
.prefix
, buf2
,
11673 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
11675 p
->u
.prefix_evpn
.prefix_addr
.eth_tag
,
11676 decode_label(&bgp_static
->label
), esi
, buf2
,
11680 XFREE(MTYPE_TMP
, macrouter
);
11682 XFREE(MTYPE_TMP
, esi
);
11687 /* Configuration of static route announcement and aggregate
11689 void bgp_config_write_network(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
11692 struct bgp_node
*rn
;
11694 struct bgp_static
*bgp_static
;
11695 struct bgp_aggregate
*bgp_aggregate
;
11696 char buf
[SU_ADDRSTRLEN
];
11698 if ((safi
== SAFI_MPLS_VPN
) || (safi
== SAFI_ENCAP
)) {
11699 bgp_config_write_network_vpn(vty
, bgp
, afi
, safi
);
11703 if (afi
== AFI_L2VPN
&& safi
== SAFI_EVPN
) {
11704 bgp_config_write_network_evpn(vty
, bgp
, afi
, safi
);
11708 /* Network configuration. */
11709 for (rn
= bgp_table_top(bgp
->route
[afi
][safi
]); rn
;
11710 rn
= bgp_route_next(rn
)) {
11711 bgp_static
= bgp_static_get_node_info(rn
);
11712 if (bgp_static
== NULL
)
11717 /* "network" configuration display. */
11718 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
) {
11719 uint32_t destination
;
11720 struct in_addr netmask
;
11722 destination
= ntohl(p
->u
.prefix4
.s_addr
);
11723 masklen2ip(p
->prefixlen
, &netmask
);
11724 vty_out(vty
, " network %s",
11725 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11728 if ((IN_CLASSC(destination
) && p
->prefixlen
== 24)
11729 || (IN_CLASSB(destination
) && p
->prefixlen
== 16)
11730 || (IN_CLASSA(destination
) && p
->prefixlen
== 8)
11731 || p
->u
.prefix4
.s_addr
== 0) {
11732 /* Natural mask is not display. */
11734 vty_out(vty
, " mask %s", inet_ntoa(netmask
));
11736 vty_out(vty
, " network %s/%d",
11737 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11742 if (bgp_static
->label_index
!= BGP_INVALID_LABEL_INDEX
)
11743 vty_out(vty
, " label-index %u",
11744 bgp_static
->label_index
);
11746 if (bgp_static
->rmap
.name
)
11747 vty_out(vty
, " route-map %s", bgp_static
->rmap
.name
);
11749 if (bgp_static
->backdoor
)
11750 vty_out(vty
, " backdoor");
11752 vty_out(vty
, "\n");
11755 /* Aggregate-address configuration. */
11756 for (rn
= bgp_table_top(bgp
->aggregate
[afi
][safi
]); rn
;
11757 rn
= bgp_route_next(rn
)) {
11758 bgp_aggregate
= bgp_aggregate_get_node_info(rn
);
11759 if (bgp_aggregate
== NULL
)
11764 if (bgp_option_check(BGP_OPT_CONFIG_CISCO
) && afi
== AFI_IP
) {
11765 struct in_addr netmask
;
11767 masklen2ip(p
->prefixlen
, &netmask
);
11768 vty_out(vty
, " aggregate-address %s %s",
11769 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11771 inet_ntoa(netmask
));
11773 vty_out(vty
, " aggregate-address %s/%d",
11774 inet_ntop(p
->family
, &p
->u
.prefix
, buf
,
11779 if (bgp_aggregate
->as_set
)
11780 vty_out(vty
, " as-set");
11782 if (bgp_aggregate
->summary_only
)
11783 vty_out(vty
, " summary-only");
11785 vty_out(vty
, "\n");
11789 void bgp_config_write_distance(struct vty
*vty
, struct bgp
*bgp
, afi_t afi
,
11792 struct bgp_node
*rn
;
11793 struct bgp_distance
*bdistance
;
11795 /* Distance configuration. */
11796 if (bgp
->distance_ebgp
[afi
][safi
] && bgp
->distance_ibgp
[afi
][safi
]
11797 && bgp
->distance_local
[afi
][safi
]
11798 && (bgp
->distance_ebgp
[afi
][safi
] != ZEBRA_EBGP_DISTANCE_DEFAULT
11799 || bgp
->distance_ibgp
[afi
][safi
] != ZEBRA_IBGP_DISTANCE_DEFAULT
11800 || bgp
->distance_local
[afi
][safi
]
11801 != ZEBRA_IBGP_DISTANCE_DEFAULT
)) {
11802 vty_out(vty
, " distance bgp %d %d %d\n",
11803 bgp
->distance_ebgp
[afi
][safi
],
11804 bgp
->distance_ibgp
[afi
][safi
],
11805 bgp
->distance_local
[afi
][safi
]);
11808 for (rn
= bgp_table_top(bgp_distance_table
[afi
][safi
]); rn
;
11809 rn
= bgp_route_next(rn
)) {
11810 bdistance
= bgp_distance_get_node(rn
);
11811 if (bdistance
!= NULL
) {
11812 char buf
[PREFIX_STRLEN
];
11814 vty_out(vty
, " distance %d %s %s\n",
11815 bdistance
->distance
,
11816 prefix2str(&rn
->p
, buf
, sizeof(buf
)),
11817 bdistance
->access_list
? bdistance
->access_list
11823 /* Allocate routing table structure and install commands. */
11824 void bgp_route_init(void)
11829 /* Init BGP distance table. */
11830 FOREACH_AFI_SAFI (afi
, safi
)
11831 bgp_distance_table
[afi
][safi
] = bgp_table_init(NULL
, afi
, safi
);
11833 /* IPv4 BGP commands. */
11834 install_element(BGP_NODE
, &bgp_table_map_cmd
);
11835 install_element(BGP_NODE
, &bgp_network_cmd
);
11836 install_element(BGP_NODE
, &no_bgp_table_map_cmd
);
11838 install_element(BGP_NODE
, &aggregate_address_cmd
);
11839 install_element(BGP_NODE
, &aggregate_address_mask_cmd
);
11840 install_element(BGP_NODE
, &no_aggregate_address_cmd
);
11841 install_element(BGP_NODE
, &no_aggregate_address_mask_cmd
);
11843 /* IPv4 unicast configuration. */
11844 install_element(BGP_IPV4_NODE
, &bgp_table_map_cmd
);
11845 install_element(BGP_IPV4_NODE
, &bgp_network_cmd
);
11846 install_element(BGP_IPV4_NODE
, &no_bgp_table_map_cmd
);
11848 install_element(BGP_IPV4_NODE
, &aggregate_address_cmd
);
11849 install_element(BGP_IPV4_NODE
, &aggregate_address_mask_cmd
);
11850 install_element(BGP_IPV4_NODE
, &no_aggregate_address_cmd
);
11851 install_element(BGP_IPV4_NODE
, &no_aggregate_address_mask_cmd
);
11853 /* IPv4 multicast configuration. */
11854 install_element(BGP_IPV4M_NODE
, &bgp_table_map_cmd
);
11855 install_element(BGP_IPV4M_NODE
, &bgp_network_cmd
);
11856 install_element(BGP_IPV4M_NODE
, &no_bgp_table_map_cmd
);
11857 install_element(BGP_IPV4M_NODE
, &aggregate_address_cmd
);
11858 install_element(BGP_IPV4M_NODE
, &aggregate_address_mask_cmd
);
11859 install_element(BGP_IPV4M_NODE
, &no_aggregate_address_cmd
);
11860 install_element(BGP_IPV4M_NODE
, &no_aggregate_address_mask_cmd
);
11862 /* IPv4 labeled-unicast configuration. */
11863 install_element(VIEW_NODE
, &show_ip_bgp_instance_all_cmd
);
11864 install_element(VIEW_NODE
, &show_ip_bgp_cmd
);
11865 install_element(VIEW_NODE
, &show_ip_bgp_json_cmd
);
11866 install_element(VIEW_NODE
, &show_ip_bgp_route_cmd
);
11867 install_element(VIEW_NODE
, &show_ip_bgp_regexp_cmd
);
11869 install_element(VIEW_NODE
,
11870 &show_ip_bgp_instance_neighbor_advertised_route_cmd
);
11871 install_element(VIEW_NODE
, &show_ip_bgp_neighbor_routes_cmd
);
11872 install_element(VIEW_NODE
,
11873 &show_ip_bgp_neighbor_received_prefix_filter_cmd
);
11874 #ifdef KEEP_OLD_VPN_COMMANDS
11875 install_element(VIEW_NODE
, &show_ip_bgp_vpn_all_route_prefix_cmd
);
11876 #endif /* KEEP_OLD_VPN_COMMANDS */
11877 install_element(VIEW_NODE
, &show_bgp_afi_vpn_rd_route_cmd
);
11878 install_element(VIEW_NODE
,
11879 &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd
);
11881 /* BGP dampening clear commands */
11882 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_cmd
);
11883 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_prefix_cmd
);
11885 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_address_cmd
);
11886 install_element(ENABLE_NODE
, &clear_ip_bgp_dampening_address_mask_cmd
);
11889 install_element(ENABLE_NODE
,
11890 &show_ip_bgp_instance_neighbor_prefix_counts_cmd
);
11891 #ifdef KEEP_OLD_VPN_COMMANDS
11892 install_element(ENABLE_NODE
,
11893 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd
);
11894 #endif /* KEEP_OLD_VPN_COMMANDS */
11896 /* New config IPv6 BGP commands. */
11897 install_element(BGP_IPV6_NODE
, &bgp_table_map_cmd
);
11898 install_element(BGP_IPV6_NODE
, &ipv6_bgp_network_cmd
);
11899 install_element(BGP_IPV6_NODE
, &no_bgp_table_map_cmd
);
11901 install_element(BGP_IPV6_NODE
, &ipv6_aggregate_address_cmd
);
11902 install_element(BGP_IPV6_NODE
, &no_ipv6_aggregate_address_cmd
);
11904 install_element(BGP_IPV6M_NODE
, &ipv6_bgp_network_cmd
);
11906 install_element(BGP_NODE
, &bgp_distance_cmd
);
11907 install_element(BGP_NODE
, &no_bgp_distance_cmd
);
11908 install_element(BGP_NODE
, &bgp_distance_source_cmd
);
11909 install_element(BGP_NODE
, &no_bgp_distance_source_cmd
);
11910 install_element(BGP_NODE
, &bgp_distance_source_access_list_cmd
);
11911 install_element(BGP_NODE
, &no_bgp_distance_source_access_list_cmd
);
11912 install_element(BGP_IPV4_NODE
, &bgp_distance_cmd
);
11913 install_element(BGP_IPV4_NODE
, &no_bgp_distance_cmd
);
11914 install_element(BGP_IPV4_NODE
, &bgp_distance_source_cmd
);
11915 install_element(BGP_IPV4_NODE
, &no_bgp_distance_source_cmd
);
11916 install_element(BGP_IPV4_NODE
, &bgp_distance_source_access_list_cmd
);
11917 install_element(BGP_IPV4_NODE
, &no_bgp_distance_source_access_list_cmd
);
11918 install_element(BGP_IPV4M_NODE
, &bgp_distance_cmd
);
11919 install_element(BGP_IPV4M_NODE
, &no_bgp_distance_cmd
);
11920 install_element(BGP_IPV4M_NODE
, &bgp_distance_source_cmd
);
11921 install_element(BGP_IPV4M_NODE
, &no_bgp_distance_source_cmd
);
11922 install_element(BGP_IPV4M_NODE
, &bgp_distance_source_access_list_cmd
);
11923 install_element(BGP_IPV4M_NODE
,
11924 &no_bgp_distance_source_access_list_cmd
);
11925 install_element(BGP_IPV6_NODE
, &bgp_distance_cmd
);
11926 install_element(BGP_IPV6_NODE
, &no_bgp_distance_cmd
);
11927 install_element(BGP_IPV6_NODE
, &ipv6_bgp_distance_source_cmd
);
11928 install_element(BGP_IPV6_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11929 install_element(BGP_IPV6_NODE
,
11930 &ipv6_bgp_distance_source_access_list_cmd
);
11931 install_element(BGP_IPV6_NODE
,
11932 &no_ipv6_bgp_distance_source_access_list_cmd
);
11933 install_element(BGP_IPV6M_NODE
, &bgp_distance_cmd
);
11934 install_element(BGP_IPV6M_NODE
, &no_bgp_distance_cmd
);
11935 install_element(BGP_IPV6M_NODE
, &ipv6_bgp_distance_source_cmd
);
11936 install_element(BGP_IPV6M_NODE
, &no_ipv6_bgp_distance_source_cmd
);
11937 install_element(BGP_IPV6M_NODE
,
11938 &ipv6_bgp_distance_source_access_list_cmd
);
11939 install_element(BGP_IPV6M_NODE
,
11940 &no_ipv6_bgp_distance_source_access_list_cmd
);
11942 install_element(BGP_NODE
, &bgp_damp_set_cmd
);
11943 install_element(BGP_NODE
, &bgp_damp_unset_cmd
);
11944 install_element(BGP_IPV4_NODE
, &bgp_damp_set_cmd
);
11945 install_element(BGP_IPV4_NODE
, &bgp_damp_unset_cmd
);
11947 /* IPv4 Multicast Mode */
11948 install_element(BGP_IPV4M_NODE
, &bgp_damp_set_cmd
);
11949 install_element(BGP_IPV4M_NODE
, &bgp_damp_unset_cmd
);
11951 /* Large Communities */
11952 install_element(VIEW_NODE
, &show_ip_bgp_large_community_list_cmd
);
11953 install_element(VIEW_NODE
, &show_ip_bgp_large_community_cmd
);
11955 /* show bgp ipv4 flowspec detailed */
11956 install_element(VIEW_NODE
, &show_ip_bgp_flowspec_routes_detailed_cmd
);
11958 install_element(VIEW_NODE
, &show_bgp_peerhash_cmd
);
11961 void bgp_route_finish(void)
11966 FOREACH_AFI_SAFI (afi
, safi
) {
11967 bgp_table_unlock(bgp_distance_table
[afi
][safi
]);
11968 bgp_distance_table
[afi
][safi
] = NULL
;