* 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;
/**
}
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;
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);
}
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);
}
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;
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);
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)