X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlib%2Fpunt.c;h=4a5e42db20394fbc2fa7f69ce30836a7fedd2c47;hb=45723b8d3;hp=5f83707c11db2c0645cc146164e382cef0a13d1d;hpb=7f6bd24f7217026131f6b8e1e55f92d2955c883b;p=vpp.git diff --git a/src/vlib/punt.c b/src/vlib/punt.c index 5f83707c11d..4a5e42db203 100644 --- a/src/vlib/punt.c +++ b/src/vlib/punt.c @@ -17,8 +17,9 @@ /** * The last allocated punt reason + * Value 0 is reserved for invalid index. */ -static vlib_punt_reason_t punt_reason_last; +static vlib_punt_reason_t punt_reason_last = 1; /** * Counters per punt-reason @@ -47,6 +48,31 @@ 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; + + /** + * Flags associated to the reason + */ + u32 flags; + + /** + * Formatting function for flags; + */ + format_function_t *flags_format; } punt_reason_data_t; /** @@ -132,8 +158,13 @@ u8 * format_vlib_punt_reason (u8 * s, va_list * args) { vlib_punt_reason_t pr = va_arg (*args, int); - - return (format (s, "[%d] %v", pr, punt_reason_data[pr].pd_name)); + format_function_t *flags_format = punt_reason_data[pr].flags_format; + u32 flags = punt_reason_data[pr].flags; + if (flags_format) + return (format (s, "[%d] %v flags: %U", pr, punt_reason_data[pr].pd_name, + flags_format, flags)); + else + return (format (s, "[%d] %v", pr, punt_reason_data[pr].pd_name)); } vlib_punt_hdl_t @@ -249,8 +280,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 +329,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 +389,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); } @@ -367,8 +407,25 @@ vlib_punt_unregister (vlib_punt_hdl_t client, } int -vlib_punt_reason_alloc (vlib_punt_hdl_t client, - const char *reason_name, vlib_punt_reason_t * reason) +vlib_punt_reason_validate (vlib_punt_reason_t reason) +{ + if (reason < punt_reason_last) + return (0); + + return (-1); +} + +u32 +vlib_punt_reason_get_flags (vlib_punt_reason_t pr) +{ + return pr < punt_reason_last ? punt_reason_data[pr].flags : 0; +} + +int +vlib_punt_reason_alloc (vlib_punt_hdl_t client, const char *reason_name, + punt_interested_listener_t fn, void *data, + vlib_punt_reason_t *reason, u32 flags, + format_function_t *flags_format) { vlib_punt_reason_t new; @@ -379,6 +436,10 @@ 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; + punt_reason_data[new].flags = flags; + punt_reason_data[new].flags_format = flags_format; vec_add1 (punt_reason_data[new].pd_owners, client); vlib_validate_combined_counter (&punt_counters, new); @@ -392,6 +453,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; + + for (pd = punt_reason_data + 1; pd < vec_end (punt_reason_data); pd++) + { + cb (pd->pd_reason, pd->pd_name, ctx); + } +} + /* Parse node name -> node index. */ uword unformat_punt_client (unformat_input_t * input, va_list * args) @@ -402,6 +474,29 @@ unformat_punt_client (unformat_input_t * input, va_list * args) punt_client_db, result); } +/* Parse punt reason */ +uword +unformat_punt_reason (unformat_input_t *input, va_list *args) +{ + u32 *result = va_arg (*args, u32 *); + u8 *s = 0; + u8 found = 0; + for (int i = 0; i < punt_reason_last - 1; i++) + { + punt_reason_data_t *pd = vec_elt_at_index (punt_reason_data, 1 + i); + vec_reset_length (s); + s = format (0, "%v%c", pd->pd_name, 0); + if (unformat (input, (const char *) s)) + { + *result = pd->pd_reason; + found = 1; + break; + } + } + vec_free (s); + return found; +} + u8 * format_punt_reg (u8 * s, va_list * args) { @@ -423,8 +518,11 @@ format_punt_reason_data (u8 * s, va_list * args) punt_reason_data_t *pd = va_arg (*args, punt_reason_data_t *); punt_client_t *pc; u32 *pci; - - s = format (s, "[%d] %v from:[", pd->pd_reason, pd->pd_name); + if (pd->flags_format) + s = format (s, "[%d] %v flags: %U from:[", pd->pd_reason, pd->pd_name, + pd->flags_format, pd->flags); + else + s = format (s, "[%d] %v from:[", pd->pd_reason, pd->pd_name); vec_foreach (pci, pd->pd_owners) { pc = pool_elt_at_index (punt_client_pool, *pci);