From 1dd4ea8a1aaf15148f2be11cde6348043cfc5444 Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Fri, 12 Apr 2019 11:27:13 -0400 Subject: [PATCH] zebra: add a start callback for dplane plugins Add a callback called at start time, once the dplane pthread and thread_master are available. The callback is optional. Signed-off-by: Mark Stapp --- zebra/zebra_dplane.c | 30 ++++++++++++++++++++++++++---- zebra/zebra_dplane.h | 9 ++++++++- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 6fc62147c8..92a401b7e8 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -222,6 +222,8 @@ struct zebra_dplane_provider { /* 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); @@ -1823,6 +1825,7 @@ int dplane_show_provs_helper(struct vty *vty, bool detailed) 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), @@ -1853,6 +1856,7 @@ int dplane_provider_register(const char *name, p->dp_priority = prio; p->dp_fp = fp; + p->dp_start = start_fp; p->dp_fini = fini_fp; p->dp_data = data; @@ -2320,7 +2324,7 @@ static void dplane_provider_init(void) ret = dplane_provider_register("Kernel", DPLANE_PRIO_KERNEL, - DPLANE_PROV_FLAGS_DEFAULT, + DPLANE_PROV_FLAGS_DEFAULT, NULL, kernel_dplane_process_func, NULL, NULL, NULL); @@ -2333,7 +2337,7 @@ static void dplane_provider_init(void) /* 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); @@ -2717,13 +2721,14 @@ static void zebra_dplane_init_internal(void) */ 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"); @@ -2735,6 +2740,23 @@ void zebra_dplane_start(void) 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); } diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index d45628fdd0..1d4056c815 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -363,7 +363,13 @@ enum dplane_provider_prio { * 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 @@ -372,6 +378,7 @@ enum dplane_provider_prio { 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), -- 2.39.5