summaryrefslogtreecommitdiff
path: root/bgpd/bgp_route.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_route.c')
-rw-r--r--bgpd/bgp_route.c188
1 files changed, 141 insertions, 47 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index a13d52b4c9..c4ab223b7f 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -96,7 +96,7 @@
/* Extern from bgp_dump.c */
extern const char *bgp_origin_str[];
extern const char *bgp_origin_long_str[];
-const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json);
+
/* PMSI strings. */
#define PMSI_TNLTYPE_STR_NO_INFO "No info"
#define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
@@ -208,9 +208,6 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
return;
e = *extra;
- if (e->damp_info)
- bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
- e->damp_info->safi);
e->damp_info = NULL;
if (e->parent) {
@@ -2755,7 +2752,10 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
== BGP_ROUTE_REDISTRIBUTE) {
if (CHECK_FLAG(
dest->flags,
- BGP_NODE_REGISTERED_FOR_LABEL))
+ BGP_NODE_REGISTERED_FOR_LABEL)
+ || CHECK_FLAG(
+ dest->flags,
+ BGP_NODE_LABEL_REQUESTED))
bgp_unregister_for_label(dest);
label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1,
&dest->local_label);
@@ -2765,10 +2765,13 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
new_select);
}
} else if (CHECK_FLAG(dest->flags,
- BGP_NODE_REGISTERED_FOR_LABEL)) {
+ BGP_NODE_REGISTERED_FOR_LABEL)
+ || CHECK_FLAG(dest->flags,
+ BGP_NODE_LABEL_REQUESTED)) {
bgp_unregister_for_label(dest);
}
- } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)) {
+ } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
+ || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
bgp_unregister_for_label(dest);
}
@@ -3325,14 +3328,16 @@ static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
/* apply dampening, if result is suppressed, we'll be retaining
* the bgp_path_info in the RIB for historical reference.
*/
- if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
- && peer->sort == BGP_PEER_EBGP)
- if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
- == BGP_DAMP_SUPPRESSED) {
- bgp_aggregate_decrement(peer->bgp, p, pi, afi,
- safi);
- return;
+ if (peer->sort == BGP_PEER_EBGP) {
+ if (get_active_bdc_from_pi(pi, afi, safi)) {
+ if (bgp_damp_withdraw(pi, dest, afi, safi, 0)
+ == BGP_DAMP_SUPPRESSED) {
+ bgp_aggregate_decrement(peer->bgp, p, pi, afi,
+ safi);
+ return;
+ }
}
+ }
#ifdef ENABLE_BGP_VNC
if (safi == SAFI_MPLS_VPN) {
@@ -3757,8 +3762,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
&& (overlay_index_equal(
afi, pi,
evpn == NULL ? NULL : &evpn->gw_ip))) {
- if (CHECK_FLAG(bgp->af_flags[afi][safi],
- BGP_CONFIG_DAMPENING)
+ if (get_active_bdc_from_pi(pi, afi, safi)
&& peer->sort == BGP_PEER_EBGP
&& CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
if (bgp_debug_update(peer, p, NULL, 1)) {
@@ -3852,11 +3856,11 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
bgp_aggregate_decrement(bgp, p, pi, afi, safi);
/* Update bgp route dampening information. */
- if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
+ if (get_active_bdc_from_pi(pi, afi, safi)
&& peer->sort == BGP_PEER_EBGP) {
/* This is implicit withdraw so we should update
- dampening
- information. */
+ * dampening information.
+ */
if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
bgp_damp_withdraw(pi, dest, afi, safi, 1);
}
@@ -3979,7 +3983,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
#endif
/* Update bgp route dampening information. */
- if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
+ if (get_active_bdc_from_pi(pi, afi, safi)
&& peer->sort == BGP_PEER_EBGP) {
/* Now we do normal update dampening. */
ret = bgp_damp_update(pi, dest, afi, safi);
@@ -4595,8 +4599,10 @@ static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
continue;
/* graceful restart STALE flag set. */
- if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
- && peer->nsf[afi][safi]
+ if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
+ && peer->nsf[afi][safi])
+ || CHECK_FLAG(peer->af_sflags[afi][safi],
+ PEER_STATUS_ENHANCED_REFRESH))
&& !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
&& !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
@@ -4847,7 +4853,7 @@ void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
struct bgp_path_info *pi;
struct bgp_table *table;
- if (safi == SAFI_MPLS_VPN) {
+ if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
dest = bgp_route_next(dest)) {
struct bgp_dest *rm;
@@ -4886,6 +4892,81 @@ void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
}
}
+void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
+{
+ struct bgp_dest *dest, *ndest;
+ struct bgp_path_info *pi;
+ struct bgp_table *table;
+
+ if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
+ for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
+ dest = bgp_route_next(dest)) {
+ table = bgp_dest_get_bgp_table_info(dest);
+ if (!table)
+ continue;
+
+ for (ndest = bgp_table_top(table); ndest;
+ ndest = bgp_route_next(ndest)) {
+ for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
+ pi = pi->next) {
+ if (pi->peer != peer)
+ continue;
+
+ if ((CHECK_FLAG(
+ peer->af_sflags[afi][safi],
+ PEER_STATUS_ENHANCED_REFRESH))
+ && !CHECK_FLAG(pi->flags,
+ BGP_PATH_STALE)
+ && !CHECK_FLAG(
+ pi->flags,
+ BGP_PATH_UNUSEABLE)) {
+ if (bgp_debug_neighbor_events(
+ peer))
+ zlog_debug(
+ "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
+ peer->host,
+ afi2str(afi),
+ safi2str(safi),
+ bgp_dest_get_prefix(
+ ndest));
+
+ bgp_path_info_set_flag(
+ ndest, pi,
+ BGP_PATH_STALE);
+ }
+ }
+ }
+ }
+ } else {
+ for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
+ dest = bgp_route_next(dest)) {
+ for (pi = bgp_dest_get_bgp_path_info(dest); pi;
+ pi = pi->next) {
+ if (pi->peer != peer)
+ continue;
+
+ if ((CHECK_FLAG(peer->af_sflags[afi][safi],
+ PEER_STATUS_ENHANCED_REFRESH))
+ && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
+ && !CHECK_FLAG(pi->flags,
+ BGP_PATH_UNUSEABLE)) {
+ if (bgp_debug_neighbor_events(peer))
+ zlog_debug(
+ "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
+ peer->host,
+ afi2str(afi),
+ safi2str(safi),
+ bgp_dest_get_prefix(
+ dest));
+
+ bgp_path_info_set_flag(dest, pi,
+ BGP_PATH_STALE);
+ }
+ }
+ }
+ }
+}
+
bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
{
if (peer->sort == BGP_PEER_IBGP)
@@ -10129,7 +10210,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
}
if (path->extra && path->extra->damp_info)
- bgp_damp_info_vty(vty, path, afi, safi, json_path);
+ bgp_damp_info_vty(vty, bgp, path, afi, safi, json_path);
/* Remote Label */
if (path->extra && bgp_is_valid_label(&path->extra->label[0])
@@ -10261,6 +10342,24 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
str, label2vni(&attr->label));
}
+ /* Output some debug about internal state of the dest flags */
+ if (json_paths) {
+ if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
+ json_object_boolean_true_add(json_path, "processScheduled");
+ if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
+ json_object_boolean_true_add(json_path, "userCleared");
+ if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
+ json_object_boolean_true_add(json_path, "labelChanged");
+ if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
+ json_object_boolean_true_add(json_path, "registeredForLabel");
+ if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
+ json_object_boolean_true_add(json_path, "selectDefered");
+ if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
+ json_object_boolean_true_add(json_path, "fibInstalled");
+ if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
+ json_object_boolean_true_add(json_path, "fibPending");
+ }
+
/* We've constructed the json object for this path, add it to the json
* array of paths
*/
@@ -11739,10 +11838,6 @@ DEFPY (show_ip_bgp_json,
? AFI_IP
: AFI_IP6;
FOREACH_SAFI (safi) {
- if (strmatch(get_afi_safi_str(afi, safi, true),
- "Unknown"))
- continue;
-
if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
continue;
@@ -11773,10 +11868,6 @@ DEFPY (show_ip_bgp_json,
} else {
/* show <ip> bgp all: for each AFI and SAFI*/
FOREACH_AFI_SAFI (afi, safi) {
- if (strmatch(get_afi_safi_str(afi, safi, true),
- "Unknown"))
- continue;
-
if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
continue;
@@ -13318,10 +13409,6 @@ DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
: AFI_IP6;
FOREACH_SAFI (safi) {
- if (strmatch(get_afi_safi_str(afi, safi, true),
- "Unknown"))
- continue;
-
if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
continue;
@@ -13341,10 +13428,6 @@ DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
}
} else {
FOREACH_AFI_SAFI (afi, safi) {
- if (strmatch(get_afi_safi_str(afi, safi, true),
- "Unknown"))
- continue;
-
if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
continue;
@@ -13702,7 +13785,7 @@ uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
afi_t afi, safi_t safi, struct bgp *bgp)
{
struct bgp_dest *dest;
- struct prefix q;
+ struct prefix q = {0};
struct peer *peer;
struct bgp_distance *bdistance;
struct access_list *alist;
@@ -13716,8 +13799,11 @@ uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
if (pinfo->attr->distance)
return pinfo->attr->distance;
- /* Check source address. */
- if (!sockunion2hostprefix(&peer->su, &q))
+ /* Check source address.
+ * Note: for aggregate route, peer can have unspec af type.
+ */
+ if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
+ && !sockunion2hostprefix(&peer->su, &q))
return 0;
dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
@@ -13752,10 +13838,14 @@ uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
if (bgp->distance_ebgp[afi][safi])
return bgp->distance_ebgp[afi][safi];
return ZEBRA_EBGP_DISTANCE_DEFAULT;
- } else {
+ } else if (peer->sort == BGP_PEER_IBGP) {
if (bgp->distance_ibgp[afi][safi])
return bgp->distance_ibgp[afi][safi];
return ZEBRA_IBGP_DISTANCE_DEFAULT;
+ } else {
+ if (bgp->distance_local[afi][safi])
+ return bgp->distance_local[afi][safi];
+ return ZEBRA_IBGP_DISTANCE_DEFAULT;
}
}
@@ -14070,7 +14160,8 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
if (pi->extra && pi->extra->damp_info) {
pi_temp = pi->next;
bgp_damp_info_free(
- pi->extra->damp_info,
+ &pi->extra->damp_info,
+ &bgp->damp[afi][safi],
1, afi, safi);
pi = pi_temp;
} else
@@ -14092,7 +14183,8 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
if (pi->extra && pi->extra->damp_info) {
pi_temp = pi->next;
bgp_damp_info_free(
- pi->extra->damp_info,
+ &pi->extra->damp_info,
+ &bgp->damp[afi][safi],
1, afi, safi);
pi = pi_temp;
} else
@@ -14115,7 +14207,9 @@ DEFUN (clear_ip_bgp_dampening,
BGP_STR
"Clear route flap dampening information\n")
{
- bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ bgp_damp_info_clean(&bgp->damp[AFI_IP][SAFI_UNICAST], AFI_IP,
+ SAFI_UNICAST);
return CMD_SUCCESS;
}