aboutsummaryrefslogtreecommitdiffstats
path: root/src/vlib/punt.c
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2020-02-20 09:45:16 +0000
committerNeale Ranns <nranns@cisco.com>2020-02-25 10:48:52 +0000
commit8d6d74cdf43d7560eab3cf609cab27e5deb816e0 (patch)
treefe3d7328edbb9b8e6d7d8e3b0cea7fd7307d78e5 /src/vlib/punt.c
parent719ef39d988182d1297dc9c3f06b7bbda3043d47 (diff)
vlib: Punt reason allocation listener enable/disable callback
Type: improvement allow clients that allocate punt reasons to pass a callback function that is invoked when the first/last client registers to use/listen on that punt reason. This allows the client to perform some necessary configs that might not otherwise be enabled. IPSec uses this callback to register the ESP proto and UDP handling nodes, that would not otherwise be enabled unless a tunnel was present. Change-Id: I9759349903f21ffeeb253d4271e619e6bf46054b Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vlib/punt.c')
-rw-r--r--src/vlib/punt.c34
1 files changed, 31 insertions, 3 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);