ctx = dplane_ctx_alloc();
ret = dplane_ctx_nexthop_init(ctx, op, nhe);
- if (ret == AOK)
+ if (ret == AOK) {
+ if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INITIAL_DELAY_INSTALL)) {
+ UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_QUEUED);
+ UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_REINSTALL);
+ SET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
+
+ dplane_ctx_free(&ctx);
+ atomic_fetch_add_explicit(&zdplane_info.dg_nexthops_in,
+ 1, memory_order_relaxed);
+
+ return ZEBRA_DPLANE_REQUEST_SUCCESS;
+ }
+
ret = dplane_update_enqueue(ctx);
+ }
/* Update counter */
atomic_fetch_add_explicit(&zdplane_info.dg_nexthops_in, 1,
if (orig->backup_info)
nhe->backup_info = nhg_backup_copy(orig->backup_info);
+ /*
+ * This is a special case, Zebra needs to track
+ * whether or not this flag was set on a initial
+ * unresolved NHG
+ */
+ if (CHECK_FLAG(orig->flags, NEXTHOP_GROUP_INITIAL_DELAY_INSTALL))
+ SET_FLAG(nhe->flags, NEXTHOP_GROUP_INITIAL_DELAY_INSTALL);
+
return nhe;
}
"%s nh id %u (flags 0x%x) associated dependent NHG %pNG install",
__func__, nhe->id, nhe->flags,
rb_node_dep->nhe);
- zebra_nhg_install_kernel(rb_node_dep->nhe);
+ zebra_nhg_install_kernel(rb_node_dep->nhe, true);
}
}
}
(is_delete ? "deleted" : "updated"), nhe);
UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
- zebra_nhg_install_kernel(nhe);
+ zebra_nhg_install_kernel(nhe, ZEBRA_ROUTE_MAX);
} else
zebra_nhg_handle_uninstall(nhe);
}
return zebra_nhg_nhe2grp_internal(grp, 0, nhe, nhe, max_num);
}
-void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe)
+void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe, uint8_t type)
{
struct nhg_connected *rb_node_dep = NULL;
nhe);
}
+ if ((type != ZEBRA_ROUTE_CONNECT && type != ZEBRA_ROUTE_LOCAL &&
+ type != ZEBRA_ROUTE_KERNEL) &&
+ CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INITIAL_DELAY_INSTALL)) {
+ UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INITIAL_DELAY_INSTALL);
+ UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
+ }
+
/* Make sure all depends are installed/queued */
frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) {
- zebra_nhg_install_kernel(rb_node_dep->nhe);
+ zebra_nhg_install_kernel(rb_node_dep->nhe, type);
}
if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_VALID) &&
nhe);
break;
case ZEBRA_DPLANE_REQUEST_SUCCESS:
- flog_err(EC_ZEBRA_DP_INVALID_RC,
- "DPlane returned an invalid result code for attempt of installation of %pNG into the kernel",
- nhe);
break;
}
}
zebra_nhg_set_valid_if_active(new);
- zebra_nhg_install_kernel(new);
+ zebra_nhg_install_kernel(new, ZEBRA_ROUTE_MAX);
if (old) {
/*
"%s install nhe %pNG nh type %u flags 0x%x",
__func__, rb_node_dep->nhe, nh->type,
rb_node_dep->nhe->flags);
- zebra_nhg_install_kernel(rb_node_dep->nhe);
+ zebra_nhg_install_kernel(rb_node_dep->nhe,
+ ZEBRA_ROUTE_MAX);
/* Don't need to modify dependents if installed */
if (CHECK_FLAG(rb_node_dep->nhe->flags,
* when installation is successful.
*/
#define NEXTHOP_GROUP_REINSTALL (1 << 8)
+
+/*
+ * Connected routes and kernel routes received
+ * from the kernel or created by Zebra do no
+ * need to be installed. For connected, this
+ * is because the routes are in the local table
+ * but not imported and we create an amalgram
+ * route for it. For kernel routes if the route
+ * is an pre-nhg route, there is no nexthop associated
+ * with it and we should not create it until it
+ * is used by something else.
+ * The reason for this is because is that this just
+ * fills up the DPlane's nexthop slots when there
+ * are a bunch of interfaces or pre-existing routes
+ * As such let's not initially install it ( but
+ * pretend it was successful ) and if another route
+ * chooses this NHG then we can install it then.
+ */
+#define NEXTHOP_GROUP_INITIAL_DELAY_INSTALL (1 << 9)
};
/* Upper 4 bits of the NHG are reserved for indicating the NHG type */
int size);
/* Dataplane install/uninstall */
-extern void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe);
+extern void zebra_nhg_install_kernel(struct nhg_hash_entry *nhe, uint8_t type);
extern void zebra_nhg_uninstall_kernel(struct nhg_hash_entry *nhe);
extern void zebra_interface_nhg_reinstall(struct interface *ifp);
/*
* Install the resolved nexthop object first.
*/
- zebra_nhg_install_kernel(re->nhe);
+ zebra_nhg_install_kernel(re->nhe, re->type);
/*
* If this is a replace to a new RE let the originator of the RE
* Use a temporary nhe to convey info to the common/main api.
*/
zebra_nhe_init(&nhe, afi, (ng ? ng->nexthop : NULL));
- if (ng)
+ if (ng) {
nhe.nhg.nexthop = ng->nexthop;
- else if (re->nhe_id > 0)
+
+ if (re->type == ZEBRA_ROUTE_CONNECT ||
+ re->type == ZEBRA_ROUTE_LOCAL ||
+ re->type == ZEBRA_ROUTE_KERNEL)
+ SET_FLAG(nhe.flags, NEXTHOP_GROUP_INITIAL_DELAY_INSTALL);
+ } else if (re->nhe_id > 0)
nhe.id = re->nhe_id;
n = zebra_nhe_copy(&nhe, 0);
else
vty_out(vty, ", Installed");
}
+ if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INITIAL_DELAY_INSTALL)) {
+ if (json)
+ json_object_boolean_true_add(json,
+ "initialDelay");
+ else
+ vty_out(vty, ", Initial Delay");
+ }
if (!json)
vty_out(vty, "\n");
}