summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxime Peim <mpeim@cisco.com>2023-07-03 17:45:51 +0200
committerMohammed HAWARI <momohawari@gmail.com>2023-07-25 10:06:16 +0000
commit3f40755749b07e5a936ad6d15622e371e7e5c25e (patch)
treecb5082a978b29c3c79c8d6d802b935ff23d727c7
parent4ab1aa31451c0db5deb9c726e82de241da126107 (diff)
classify: add bpf support to pcap classifier
Type: feature Change-Id: I28fb38e49c89f4c4d4cc58c1a5c0aa8502678472 Signed-off-by: Maxime Peim <mpeim@cisco.com>
-rw-r--r--src/vlib/trace.c2
-rw-r--r--src/vlib/trace.h2
-rw-r--r--src/vnet/classify/pcap_classify.h6
-rw-r--r--src/vnet/interface.api14
-rw-r--r--src/vnet/interface_api.c27
-rw-r--r--src/vnet/interface_cli.c66
-rw-r--r--src/vnet/interface_test.c12
-rw-r--r--src/vnet/misc.c3
-rw-r--r--src/vnet/vnet.h1
9 files changed, 128 insertions, 5 deletions
diff --git a/src/vlib/trace.c b/src/vlib/trace.c
index c6a0ef7ec0d..96da4975bc2 100644
--- a/src/vlib/trace.c
+++ b/src/vlib/trace.c
@@ -635,7 +635,7 @@ vlib_is_packet_traced_function_from_name (const char *name)
return reg->function;
}
-static vlib_is_packet_traced_fn_t *
+vlib_is_packet_traced_fn_t *
vlib_is_packet_traced_default_function ()
{
vlib_trace_filter_function_registration_t *reg =
diff --git a/src/vlib/trace.h b/src/vlib/trace.h
index 46256ce4e9e..196c691ece6 100644
--- a/src/vlib/trace.h
+++ b/src/vlib/trace.h
@@ -146,7 +146,7 @@ extern vlib_trace_filter_main_t vlib_trace_filter_main;
vlib_is_packet_traced_fn_t *
vlib_is_packet_traced_function_from_name (const char *name);
-
+vlib_is_packet_traced_fn_t *vlib_is_packet_traced_default_function ();
void trace_apply_filter (struct vlib_main_t *vm);
int trace_time_cmp (void *a1, void *a2);
void vlib_trace_stop_and_clear (void);
diff --git a/src/vnet/classify/pcap_classify.h b/src/vnet/classify/pcap_classify.h
index e079816f62c..a4ebcd1241c 100644
--- a/src/vnet/classify/pcap_classify.h
+++ b/src/vnet/classify/pcap_classify.h
@@ -47,11 +47,11 @@ vnet_is_packet_pcaped (vnet_pcap_t *pp, vlib_buffer_t *b, u32 sw_if_index)
return 0; /* wrong error */
if (filter_classify_table_index != ~0 &&
- vnet_is_packet_traced_inline (b, filter_classify_table_index,
- 0 /* full classify */) != 1)
+ pp->current_filter_function (b, filter_classify_table_index,
+ 0 /* full classify */) != 1)
return 0; /* not matching the filter, skip */
- return 1; /* success */
+ return 1;
}
/*
diff --git a/src/vnet/interface.api b/src/vnet/interface.api
index 4d28332a639..eea86aa1ac8 100644
--- a/src/vnet/interface.api
+++ b/src/vnet/interface.api
@@ -733,6 +733,20 @@ autoreply define collect_detailed_interface_stats
bool enable_disable;
};
+/** \brief pcap_set_filter_function
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param filter_function_name - the name of the filter function
+ to set for pcap capture
+*/
+autoreply define pcap_set_filter_function
+{
+ u32 client_index;
+ u32 context;
+
+ string filter_function_name[];
+};
+
/** \brief pcap_trace_on
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
diff --git a/src/vnet/interface_api.c b/src/vnet/interface_api.c
index 5b48fea02eb..01f2fd0c8b2 100644
--- a/src/vnet/interface_api.c
+++ b/src/vnet/interface_api.c
@@ -1604,6 +1604,33 @@ static void
}
static void
+vl_api_pcap_set_filter_function_t_handler (
+ vl_api_pcap_set_filter_function_t *mp)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+ vnet_pcap_t *pp = &vnm->pcap;
+ vl_api_pcap_set_filter_function_reply_t *rmp;
+ unformat_input_t input = { 0 };
+ vlib_is_packet_traced_fn_t *f;
+ char *filter_name;
+ int rv = 0;
+ filter_name = vl_api_from_api_to_new_c_string (&mp->filter_function_name);
+ unformat_init_cstring (&input, filter_name);
+ if (unformat (&input, "%U", unformat_vlib_trace_filter_function, &f) == 0)
+ {
+ rv = -1;
+ goto done;
+ }
+
+ pp->current_filter_function = f;
+
+done:
+ unformat_free (&input);
+ vec_free (filter_name);
+ REPLY_MACRO (VL_API_PCAP_SET_FILTER_FUNCTION_REPLY);
+}
+
+static void
vl_api_pcap_trace_on_t_handler (vl_api_pcap_trace_on_t *mp)
{
vl_api_pcap_trace_on_reply_t *rmp;
diff --git a/src/vnet/interface_cli.c b/src/vnet/interface_cli.c
index 627af6f2b0d..74ac32522d7 100644
--- a/src/vnet/interface_cli.c
+++ b/src/vnet/interface_cli.c
@@ -2440,6 +2440,72 @@ VLIB_CLI_COMMAND (pcap_tx_trace_command, static) = {
/* *INDENT-ON* */
static clib_error_t *
+set_pcap_filter_function (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ vnet_pcap_t *pp = &vnet_get_main ()->pcap;
+ 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;
+ }
+ }
+ pp->current_filter_function = res;
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+VLIB_CLI_COMMAND (set_pcap_filter_function_cli, static) = {
+ .path = "set pcap filter function",
+ .short_help = "set pcap filter function <func_name>",
+ .function = set_pcap_filter_function,
+};
+
+static clib_error_t *
+show_pcap_filter_function (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ vnet_pcap_t *pp = &vnet_get_main ()->pcap;
+ vlib_trace_filter_main_t *tfm = &vlib_trace_filter_main;
+ vlib_is_packet_traced_fn_t *current_trace_filter_fn =
+ pp->current_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_pcap_filter_function_cli, static) = {
+ .path = "show pcap filter function",
+ .short_help = "show pcap filter function",
+ .function = show_pcap_filter_function,
+};
+
+static clib_error_t *
set_interface_name (vlib_main_t *vm, unformat_input_t *input,
vlib_cli_command_t *cmd)
{
diff --git a/src/vnet/interface_test.c b/src/vnet/interface_test.c
index cc406bef23d..2d0c0ee81d1 100644
--- a/src/vnet/interface_test.c
+++ b/src/vnet/interface_test.c
@@ -1284,6 +1284,18 @@ api_sw_interface_set_interface_name (vat_main_t *vam)
}
static int
+api_pcap_set_filter_function (vat_main_t *vam)
+{
+ vl_api_pcap_set_filter_function_t *mp;
+ int ret;
+
+ M (PCAP_SET_FILTER_FUNCTION, mp);
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
api_pcap_trace_on (vat_main_t *vam)
{
return -1;
diff --git a/src/vnet/misc.c b/src/vnet/misc.c
index 18d4651cff3..d1dcd6ecb23 100644
--- a/src/vnet/misc.c
+++ b/src/vnet/misc.c
@@ -86,6 +86,9 @@ vnet_main_init (vlib_main_t * vm)
vnm->local_interface_hw_if_index = hw_if_index;
vnm->local_interface_sw_if_index = hw->sw_if_index;
+ vnm->pcap.current_filter_function =
+ vlib_is_packet_traced_default_function ();
+
return 0;
}
diff --git a/src/vnet/vnet.h b/src/vnet/vnet.h
index 227fa5be30c..54988aec667 100644
--- a/src/vnet/vnet.h
+++ b/src/vnet/vnet.h
@@ -71,6 +71,7 @@ typedef struct
u32 pcap_sw_if_index;
pcap_main_t pcap_main;
u32 filter_classify_table_index;
+ vlib_is_packet_traced_fn_t *current_filter_function;
vlib_error_t pcap_error_index;
} vnet_pcap_t;