/* Flags */
int dp_flags;
+ int (*dp_start)(struct zebra_dplane_provider *prov);
+
int (*dp_fp)(struct zebra_dplane_provider *prov);
int (*dp_fini)(struct zebra_dplane_provider *prov, bool early_p);
int dplane_provider_register(const char *name,
enum dplane_provider_prio prio,
int flags,
+ int (*start_fp)(struct zebra_dplane_provider *),
int (*fp)(struct zebra_dplane_provider *),
int (*fini_fp)(struct zebra_dplane_provider *,
bool early),
p->dp_priority = prio;
p->dp_fp = fp;
+ p->dp_start = start_fp;
p->dp_fini = fini_fp;
p->dp_data = data;
ret = dplane_provider_register("Kernel",
DPLANE_PRIO_KERNEL,
- DPLANE_PROV_FLAGS_DEFAULT,
+ DPLANE_PROV_FLAGS_DEFAULT, NULL,
kernel_dplane_process_func,
NULL,
NULL, NULL);
/* Optional test provider ... */
ret = dplane_provider_register("Test",
DPLANE_PRIO_PRE_KERNEL,
- DPLANE_PROV_FLAGS_DEFAULT,
+ DPLANE_PROV_FLAGS_DEFAULT, NULL,
test_dplane_process_func,
test_dplane_shutdown_func,
NULL /* data */, NULL);
*/
void zebra_dplane_start(void)
{
- /* Start dataplane pthread */
-
+ struct zebra_dplane_provider *prov;
struct frr_pthread_attr pattr = {
.start = frr_pthread_attr_default.start,
.stop = frr_pthread_attr_default.stop
};
+ /* Start dataplane pthread */
+
zdplane_info.dg_pthread = frr_pthread_new(&pattr, "Zebra dplane thread",
"Zebra dplane");
thread_add_event(zdplane_info.dg_master, dplane_thread_loop, NULL, 0,
&zdplane_info.dg_t_update);
+ /* Call start callbacks for registered providers */
+
+ DPLANE_LOCK();
+ prov = TAILQ_FIRST(&zdplane_info.dg_providers_q);
+ DPLANE_UNLOCK();
+
+ while (prov) {
+
+ if (prov->dp_start)
+ (prov->dp_start)(prov);
+
+ /* Locate next provider */
+ DPLANE_LOCK();
+ prov = TAILQ_NEXT(prov, dp_prov_link);
+ DPLANE_UNLOCK();
+ }
+
frr_pthread_run(zdplane_info.dg_pthread, NULL);
}
* then checks the provider's outbound queue for completed work.
*/
-/* Providers offer an entry-point for shutdown and cleanup. This is called
+/*
+ * Providers can offer a 'start' callback; if present, the dataplane will
+ * call it when it is starting - when its pthread and event-scheduling
+ * thread_master are available.
+ */
+
+/* Providers can offer an entry-point for shutdown and cleanup. This is called
* with 'early' during shutdown, to indicate that the dataplane subsystem
* is allowing work to move through the providers and finish.
* When called without 'early', the provider should release
int dplane_provider_register(const char *name,
enum dplane_provider_prio prio,
int flags,
+ int (*start_fp)(struct zebra_dplane_provider *),
int (*fp)(struct zebra_dplane_provider *),
int (*fini_fp)(struct zebra_dplane_provider *,
bool early),