summaryrefslogtreecommitdiffstats
path: root/src/vlib
diff options
context:
space:
mode:
Diffstat (limited to 'src/vlib')
-rw-r--r--src/vlib/punt.c34
-rw-r--r--src/vlib/punt.h9
2 files changed, 39 insertions, 4 deletions
diff --git a/src/vlib/punt.c b/src/vlib/punt.c
index 7c2daf25ee4..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);
}
@@ -377,7 +401,9 @@ vlib_punt_reason_validate (vlib_punt_reason_t reason)
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;
@@ -388,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);
diff --git a/src/vlib/punt.h b/src/vlib/punt.h
index 7a3e5da2da6..d93b5eac599 100644
--- a/src/vlib/punt.h
+++ b/src/vlib/punt.h
@@ -56,12 +56,19 @@ typedef int vlib_punt_hdl_t;
*/
vlib_punt_hdl_t vlib_punt_client_register (const char *who);
+typedef void (*punt_interested_listener_t) (vlib_enable_or_disable_t i,
+ void *data);
+
/**
* Allocate a new punt reason
+ * @param fn - A callback to invoke when an entity becomes [un]interested
+ * in the punt code.
+ * @param data - To be passed in the callback function.
*/
extern int vlib_punt_reason_alloc (vlib_punt_hdl_t client,
const char *reason_name,
- vlib_punt_reason_t * reason);
+ punt_interested_listener_t fn,
+ void *data, vlib_punt_reason_t * reason);
/**
* Validate that a punt reason is assigned