classify: add bpf support to pcap classifier 96/39196/4
authorMaxime Peim <mpeim@cisco.com>
Mon, 3 Jul 2023 15:45:51 +0000 (17:45 +0200)
committerMohammed HAWARI <momohawari@gmail.com>
Tue, 25 Jul 2023 10:06:16 +0000 (10:06 +0000)
Type: feature
Change-Id: I28fb38e49c89f4c4d4cc58c1a5c0aa8502678472
Signed-off-by: Maxime Peim <mpeim@cisco.com>
src/vlib/trace.c
src/vlib/trace.h
src/vnet/classify/pcap_classify.h
src/vnet/interface.api
src/vnet/interface_api.c
src/vnet/interface_cli.c
src/vnet/interface_test.c
src/vnet/misc.c
src/vnet/vnet.h

index c6a0ef7..96da497 100644 (file)
@@ -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 =
index 46256ce..196c691 100644 (file)
@@ -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);
index e079816..a4ebcd1 100644 (file)
@@ -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;
 }
 
 /*
index 4d28332..eea86aa 100644 (file)
@@ -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
index 5b48fea..01f2fd0 100644 (file)
@@ -1603,6 +1603,33 @@ static void
   REPLY_MACRO (VL_API_SW_INTERFACE_ADDRESS_REPLACE_END_REPLY);
 }
 
+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)
 {
index 627af6f..74ac325 100644 (file)
@@ -2439,6 +2439,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)
index cc406be..2d0c0ee 100644 (file)
@@ -1283,6 +1283,18 @@ api_sw_interface_set_interface_name (vat_main_t *vam)
   return -1;
 }
 
+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)
 {
index 18d4651..d1dcd6e 100644 (file)
@@ -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;
 }
 
index 227fa5b..54988ae 100644 (file)
@@ -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;