From 52fa5f21b911aaf1c50feb560dd3683b83625d2f Mon Sep 17 00:00:00 2001 From: Mohammed Hawari Date: Fri, 26 May 2023 14:52:50 +0200 Subject: vlib: introduce trace filter functions Change-Id: I7a988fafe98599e4fcf7cdaa307a69b9d76650f0 Signed-off-by: Mohammed Hawari Type: improvement --- src/vlib/trace.c | 152 +++++++++++++++++++++++++++++++++++++++++++++---- src/vlib/trace.h | 37 ++++++++++++ src/vlib/trace_funcs.h | 7 +-- 3 files changed, 179 insertions(+), 17 deletions(-) (limited to 'src/vlib') diff --git a/src/vlib/trace.c b/src/vlib/trace.c index 49b521eb886..c6a0ef7ec0d 100644 --- a/src/vlib/trace.c +++ b/src/vlib/trace.c @@ -612,18 +612,6 @@ vlib_trace_cli_reference (void) { } -int -vnet_is_packet_traced (vlib_buffer_t * b, - u32 classify_table_index, int func) -__attribute__ ((weak)); - -int -vnet_is_packet_traced (vlib_buffer_t * b, u32 classify_table_index, int func) -{ - clib_warning ("BUG: STUB called"); - return 1; -} - void * vlib_add_trace (vlib_main_t * vm, vlib_node_runtime_t * r, vlib_buffer_t * b, u32 n_data_bytes) @@ -631,8 +619,148 @@ vlib_add_trace (vlib_main_t * vm, return vlib_add_trace_inline (vm, r, b, n_data_bytes); } +vlib_is_packet_traced_fn_t * +vlib_is_packet_traced_function_from_name (const char *name) +{ + vlib_trace_filter_function_registration_t *reg = + vlib_trace_filter_main.trace_filter_registration; + while (reg) + { + if (clib_strcmp (reg->name, name) == 0) + break; + reg = reg->next; + } + if (!reg) + return 0; + return reg->function; +} + +static vlib_is_packet_traced_fn_t * +vlib_is_packet_traced_default_function () +{ + vlib_trace_filter_function_registration_t *reg = + vlib_trace_filter_main.trace_filter_registration; + vlib_trace_filter_function_registration_t *tmp_reg = reg; + while (reg) + { + if (reg->priority > tmp_reg->priority) + tmp_reg = reg; + reg = reg->next; + } + return tmp_reg->function; +} + +static clib_error_t * +vlib_trace_filter_function_init (vlib_main_t *vm) +{ + vlib_is_packet_traced_fn_t *default_fn = + vlib_is_packet_traced_default_function (); + foreach_vlib_main () + { + vlib_trace_main_t *tm = &this_vlib_main->trace_main; + tm->current_trace_filter_function = default_fn; + } + return 0; +} + +vlib_trace_filter_main_t vlib_trace_filter_main; + +VLIB_INIT_FUNCTION (vlib_trace_filter_function_init); + +static clib_error_t * +show_trace_filter_function (vlib_main_t *vm, unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + vlib_trace_filter_main_t *tfm = &vlib_trace_filter_main; + vlib_trace_main_t *tm = &vm->trace_main; + vlib_is_packet_traced_fn_t *current_trace_filter_fn = + tm->current_trace_filter_function; + vlib_trace_filter_function_registration_t *reg = + tfm->trace_filter_registration; + + while (reg) + { + vlib_cli_output (vm, "%sname:%s description: %s priority: %u", + reg->function == current_trace_filter_fn ? "(*) " : "", + reg->name, reg->description, reg->priority); + reg = reg->next; + } + return 0; +} + +VLIB_CLI_COMMAND (show_trace_filter_function_cli, static) = { + .path = "show trace filter function", + .short_help = "show trace filter function", + .function = show_trace_filter_function, +}; + +uword +unformat_vlib_trace_filter_function (unformat_input_t *input, va_list *args) +{ + vlib_is_packet_traced_fn_t **res = + va_arg (*args, vlib_is_packet_traced_fn_t **); + vlib_trace_filter_main_t *tfm = &vlib_trace_filter_main; + + vlib_trace_filter_function_registration_t *reg = + tfm->trace_filter_registration; + while (reg) + { + if (unformat (input, reg->name)) + { + *res = reg->function; + return 1; + } + reg = reg->next; + } + return 0; +} + +void +vlib_set_trace_filter_function (vlib_is_packet_traced_fn_t *x) +{ + foreach_vlib_main () + { + this_vlib_main->trace_main.current_trace_filter_function = x; + } +} + +static clib_error_t * +set_trace_filter_function (vlib_main_t *vm, unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + unformat_input_t _line_input, *line_input = &_line_input; + vlib_is_packet_traced_fn_t *res = 0; + clib_error_t *error = 0; + + if (!unformat_user (input, unformat_line_input, line_input)) + return 0; + while (unformat_check_input (line_input) != (uword) UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "%U", unformat_vlib_trace_filter_function, + &res)) + ; + else + { + error = clib_error_create ( + "expected valid trace filter function, got `%U'", + format_unformat_error, line_input); + goto done; + } + } + vlib_set_trace_filter_function (res); + +done: + unformat_free (line_input); + return error; +} + +VLIB_CLI_COMMAND (set_trace_filter_function_cli, static) = { + .path = "set trace filter function", + .short_help = "set trace filter function ", + .function = set_trace_filter_function, +}; /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vlib/trace.h b/src/vlib/trace.h index d045271f853..46256ce4e9e 100644 --- a/src/vlib/trace.h +++ b/src/vlib/trace.h @@ -80,6 +80,17 @@ typedef void *(vlib_add_trace_callback_t) (struct vlib_main_t *, struct vlib_buffer_t * b, u32 n_data_bytes); +typedef int (vlib_is_packet_traced_fn_t) (vlib_buffer_t *b, + u32 classify_table_index, int func); +typedef struct vlib_trace_filter_function_registration +{ + const char *name; + const char *description; + int priority; + vlib_is_packet_traced_fn_t *function; + struct vlib_trace_filter_function_registration *next; +} vlib_trace_filter_function_registration_t; + typedef struct { /* Pool of trace buffers. */ @@ -109,9 +120,32 @@ typedef struct /* a callback to enable customized addition of a new trace */ vlib_add_trace_callback_t *add_trace_callback; + vlib_is_packet_traced_fn_t *current_trace_filter_function; + } vlib_trace_main_t; format_function_t format_vlib_trace; +typedef struct +{ + vlib_trace_filter_function_registration_t *trace_filter_registration; +} vlib_trace_filter_main_t; + +extern vlib_trace_filter_main_t vlib_trace_filter_main; +#define VLIB_REGISTER_TRACE_FILTER_FUNCTION(x, ...) \ + __VA_ARGS__ vlib_trace_filter_function_registration_t \ + __vlib_trace_filter_function_##x; \ + static void __clib_constructor \ + __vlib_trace_filter_function_registration_##x (void) \ + { \ + vlib_trace_filter_main_t *tfm = &vlib_trace_filter_main; \ + __vlib_trace_filter_function_##x.next = tfm->trace_filter_registration; \ + tfm->trace_filter_registration = &__vlib_trace_filter_function_##x; \ + } \ + __VA_ARGS__ vlib_trace_filter_function_registration_t \ + __vlib_trace_filter_function_##x + +vlib_is_packet_traced_fn_t * +vlib_is_packet_traced_function_from_name (const char *name); void trace_apply_filter (struct vlib_main_t *vm); int trace_time_cmp (void *a1, void *a2); @@ -121,6 +155,9 @@ void trace_update_capture_options (u32 add, u32 node_index, u32 filter, u8 verbose); void trace_filter_set (u32 node_index, u32 flag, u32 count); void clear_trace_buffer (void); +void vlib_set_trace_filter_function (vlib_is_packet_traced_fn_t *x); +uword unformat_vlib_trace_filter_function (unformat_input_t *input, + va_list *args); #endif /* included_vlib_trace_h */ diff --git a/src/vlib/trace_funcs.h b/src/vlib/trace_funcs.h index 3ed4768bc7b..9b45346b467 100644 --- a/src/vlib/trace_funcs.h +++ b/src/vlib/trace_funcs.h @@ -138,10 +138,7 @@ vlib_trace_next_frame (vlib_main_t * vm, nf->flags |= VLIB_FRAME_TRACE; } -void trace_apply_filter (vlib_main_t * vm); -int vnet_is_packet_traced (vlib_buffer_t * b, - u32 classify_table_index, int func); - +void trace_apply_filter (vlib_main_t *vm); /* * Mark buffer as traced and allocate trace buffer. @@ -164,7 +161,7 @@ vlib_trace_buffer (vlib_main_t * vm, if (PREDICT_FALSE (vlib_global_main.trace_filter.trace_filter_enable)) { /* See if we're supposed to trace this packet... */ - if (vnet_is_packet_traced ( + if (tm->current_trace_filter_function ( b, vlib_global_main.trace_filter.classify_table_index, 0 /* full classify */) != 1) return 0; -- cgit 1.2.3-korg