X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlib%2Fpunt.c;h=d5e13004cafb5afa6e41a1eedbb70a4c9ed15681;hb=79bfd272546dd436a4d12f0ac98571194965dab0;hp=5f83707c11db2c0645cc146164e382cef0a13d1d;hpb=7f6bd24f7217026131f6b8e1e55f92d2955c883b;p=vpp.git diff --git a/src/vlib/punt.c b/src/vlib/punt.c index 5f83707c11d..d5e13004caf 100644 --- a/src/vlib/punt.c +++ b/src/vlib/punt.c @@ -47,6 +47,21 @@ typedef struct punt_reason_data_t_ * Clients/owners that have registered this reason */ u32 *pd_owners; + + /** + * clients interested/listening to this reason + */ + u32 pd_users; + + /** + * function to invoke if a client becomes interested in the code. + */ + punt_interested_listener_t pd_fn; + + /** + * Data to pass to the callback + */ + void *pd_data; } punt_reason_data_t; /** @@ -249,8 +264,8 @@ punt_reg_mk_dp (vlib_punt_reason_t reason) } int -vlib_punt_register (vlib_punt_hdl_t client, vlib_punt_reason_t reason, - const char *node_name) +vlib_punt_register (vlib_punt_hdl_t client, + vlib_punt_reason_t reason, const char *node_name) { vlib_node_t *punt_to, *punt_from; punt_client_t *pc; @@ -298,6 +313,11 @@ vlib_punt_register (vlib_punt_hdl_t client, vlib_punt_reason_t reason, pri = pr - punt_reg_pool; + if (0 == punt_reason_data[reason].pd_users++ && + NULL != punt_reason_data[reason].pd_fn) + punt_reason_data[reason].pd_fn (VLIB_ENABLE, + punt_reason_data[reason].pd_data); + punt_reg_add (pr); } @@ -353,6 +373,10 @@ vlib_punt_unregister (vlib_punt_hdl_t client, if (0 == pr->pr_locks) { + if (0 == --punt_reason_data[reason].pd_users && + NULL != punt_reason_data[reason].pd_fn) + punt_reason_data[reason].pd_fn (VLIB_DISABLE, + punt_reason_data[reason].pd_data); punt_reg_remove (pr); pool_put (punt_reg_pool, pr); } @@ -366,9 +390,20 @@ vlib_punt_unregister (vlib_punt_hdl_t client, return (0); } +int +vlib_punt_reason_validate (vlib_punt_reason_t reason) +{ + if (reason < punt_reason_last) + return (0); + + return (-1); +} + int vlib_punt_reason_alloc (vlib_punt_hdl_t client, - const char *reason_name, vlib_punt_reason_t * reason) + const char *reason_name, + punt_interested_listener_t fn, + void *data, vlib_punt_reason_t * reason) { vlib_punt_reason_t new; @@ -379,6 +414,8 @@ vlib_punt_reason_alloc (vlib_punt_hdl_t client, vec_validate (punt_reason_data, new); punt_reason_data[new].pd_name = format (NULL, "%s", reason_name); punt_reason_data[new].pd_reason = new; + punt_reason_data[new].pd_fn = fn; + punt_reason_data[new].pd_data = data; vec_add1 (punt_reason_data[new].pd_owners, client); vlib_validate_combined_counter (&punt_counters, new); @@ -392,6 +429,17 @@ vlib_punt_reason_alloc (vlib_punt_hdl_t client, return (0); } +void +punt_reason_walk (punt_reason_walk_cb_t cb, void *ctx) +{ + punt_reason_data_t *pd; + + vec_foreach (pd, punt_reason_data) + { + cb (pd->pd_reason, pd->pd_name, ctx); + } +} + /* Parse node name -> node index. */ uword unformat_punt_client (unformat_input_t * input, va_list * args)