classify: add bpf support to pcap classifier
[vpp.git] / src / vnet / interface_api.c
index 00a1ce3..01f2fd0 100644 (file)
@@ -1214,7 +1214,7 @@ out:
 static void
 send_interface_tx_placement_details (vnet_hw_if_tx_queue_t **all_queues,
                                     u32 index, vl_api_registration_t *rp,
-                                    u32 native_context)
+                                    u32 context)
 {
   vnet_main_t *vnm = vnet_get_main ();
   vl_api_sw_interface_tx_placement_details_t *rmp;
@@ -1223,29 +1223,24 @@ send_interface_tx_placement_details (vnet_hw_if_tx_queue_t **all_queues,
   uword *bitmap = q[0]->threads;
   u32 hw_if_index = q[0]->hw_if_index;
   vnet_hw_interface_t *hw_if = vnet_get_hw_interface (vnm, hw_if_index);
-  u32 context = clib_host_to_net_u32 (native_context);
 
   n_bits = clib_bitmap_count_set_bits (bitmap);
   u32 n = n_bits * sizeof (u32);
 
-  /*
-   * FIXME: Use the REPLY_MACRO_DETAILS5_END once endian handler is registered
-   * and available.
-   */
-  REPLY_MACRO_DETAILS5 (
-    VL_API_SW_INTERFACE_TX_PLACEMENT_DETAILS, n, rp, context, ({
-      rmp->sw_if_index = clib_host_to_net_u32 (hw_if->sw_if_index);
-      rmp->queue_id = clib_host_to_net_u32 (q[0]->queue_id);
-      rmp->shared = q[0]->shared_queue;
-      rmp->array_size = clib_host_to_net_u32 (n_bits);
-
-      v = clib_bitmap_first_set (bitmap);
-      for (u32 i = 0; i < n_bits; i++)
-       {
-         rmp->threads[i] = clib_host_to_net_u32 (v);
-         v = clib_bitmap_next_set (bitmap, v + 1);
-       }
-    }));
+  REPLY_MACRO_DETAILS5_END (VL_API_SW_INTERFACE_TX_PLACEMENT_DETAILS, n, rp,
+                           context, ({
+                             rmp->sw_if_index = hw_if->sw_if_index;
+                             rmp->queue_id = q[0]->queue_id;
+                             rmp->shared = q[0]->shared_queue;
+                             rmp->array_size = n_bits;
+
+                             v = clib_bitmap_first_set (bitmap);
+                             for (u32 i = 0; i < n_bits; i++)
+                               {
+                                 rmp->threads[i] = v;
+                                 v = clib_bitmap_next_set (bitmap, v + 1);
+                               }
+                           }));
 }
 
 static void
@@ -1608,6 +1603,92 @@ 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)
+{
+  vl_api_pcap_trace_on_reply_t *rmp;
+  unformat_input_t filename, drop_err_name;
+  vnet_pcap_dispatch_trace_args_t capture_args;
+  int rv = 0;
+
+  VALIDATE_SW_IF_INDEX (mp);
+
+  unformat_init_cstring (&filename, (char *) mp->filename);
+  if (!unformat_user (&filename, unformat_vlib_tmpfile,
+                     &capture_args.filename))
+    {
+      rv = VNET_API_ERROR_ILLEGAL_NAME;
+      goto out;
+    }
+
+  capture_args.rx_enable = mp->capture_rx;
+  capture_args.tx_enable = mp->capture_tx;
+  capture_args.preallocate_data = mp->preallocate_data;
+  capture_args.free_data = mp->free_data;
+  capture_args.drop_enable = mp->capture_drop;
+  capture_args.status = 0;
+  capture_args.packets_to_capture = ntohl (mp->max_packets);
+  capture_args.sw_if_index = ntohl (mp->sw_if_index);
+  capture_args.filter = mp->filter;
+  capture_args.max_bytes_per_pkt = ntohl (mp->max_bytes_per_packet);
+  capture_args.drop_err = ~0;
+
+  unformat_init_cstring (&drop_err_name, (char *) mp->error);
+  unformat_user (&drop_err_name, unformat_vlib_error, vlib_get_main (),
+                &capture_args.drop_err);
+
+  rv = vnet_pcap_dispatch_trace_configure (&capture_args);
+
+  BAD_SW_IF_INDEX_LABEL;
+
+out:
+  unformat_free (&filename);
+  unformat_free (&drop_err_name);
+
+  REPLY_MACRO (VL_API_PCAP_TRACE_ON_REPLY);
+}
+
+static void
+vl_api_pcap_trace_off_t_handler (vl_api_pcap_trace_off_t *mp)
+{
+  vl_api_pcap_trace_off_reply_t *rmp;
+  vnet_pcap_dispatch_trace_args_t capture_args;
+  int rv = 0;
+
+  clib_memset (&capture_args, 0, sizeof (capture_args));
+
+  rv = vnet_pcap_dispatch_trace_configure (&capture_args);
+
+  REPLY_MACRO (VL_API_PCAP_TRACE_OFF_REPLY);
+}
+
 /*
  * vpe_api_hookup
  * Add vpe's API message handlers to the table.
@@ -1624,23 +1705,30 @@ interface_api_hookup (vlib_main_t * vm)
 {
   api_main_t *am = vlibapi_get_main ();
 
+  /*
+   * Set up the (msg_name, crc, message-id) table
+   */
+  REPLY_MSG_ID_BASE = setup_message_id_table ();
+
   /* Mark these APIs as mp safe */
-  am->is_mp_safe[VL_API_SW_INTERFACE_DUMP] = 1;
-  am->is_mp_safe[VL_API_SW_INTERFACE_DETAILS] = 1;
-  am->is_mp_safe[VL_API_SW_INTERFACE_TAG_ADD_DEL] = 1;
-  am->is_mp_safe[VL_API_SW_INTERFACE_SET_INTERFACE_NAME] = 1;
+  vl_api_set_msg_thread_safe (am, REPLY_MSG_ID_BASE + VL_API_SW_INTERFACE_DUMP,
+                             1);
+  vl_api_set_msg_thread_safe (
+    am, REPLY_MSG_ID_BASE + VL_API_SW_INTERFACE_DETAILS, 1);
+  vl_api_set_msg_thread_safe (
+    am, REPLY_MSG_ID_BASE + VL_API_SW_INTERFACE_TAG_ADD_DEL, 1);
+  vl_api_set_msg_thread_safe (
+    am, REPLY_MSG_ID_BASE + VL_API_SW_INTERFACE_SET_INTERFACE_NAME, 1);
 
   /* Do not replay VL_API_SW_INTERFACE_DUMP messages */
-  am->api_trace_cfg[VL_API_SW_INTERFACE_DUMP].replay_enable = 0;
+  vl_api_allow_msg_replay (am, REPLY_MSG_ID_BASE + VL_API_SW_INTERFACE_DUMP,
+                          0);
 
   /* Mark these APIs as autoendian */
-  am->is_autoendian[VL_API_SW_INTERFACE_SET_TX_PLACEMENT] = 1;
-  am->is_autoendian[VL_API_SW_INTERFACE_TX_PLACEMENT_GET] = 1;
-
-  /*
-   * Set up the (msg_name, crc, message-id) table
-   */
-  REPLY_MSG_ID_BASE = setup_message_id_table ();
+  vl_api_set_msg_autoendian (
+    am, REPLY_MSG_ID_BASE + VL_API_SW_INTERFACE_SET_TX_PLACEMENT, 1);
+  vl_api_set_msg_autoendian (
+    am, REPLY_MSG_ID_BASE + VL_API_SW_INTERFACE_TX_PLACEMENT_GET, 1);
 
   return 0;
 }