interface: use the correct condition for checking if the pcap fd is open
[vpp.git] / src / vnet / interface_output.c
index 60953b0..721236a 100644 (file)
@@ -43,6 +43,7 @@
 #include <vnet/ip/ip6.h>
 #include <vnet/udp/udp_packet.h>
 #include <vnet/feature/feature.h>
+#include <vnet/classify/trace_classify.h>
 
 typedef struct
 {
@@ -235,8 +236,11 @@ tso_alloc_tx_bufs (vlib_main_t * vm,
                   vlib_buffer_t * b0, u32 n_bytes_b0, u16 l234_sz,
                   u16 gso_size)
 {
+  u16 size =
+    clib_min (gso_size, vlib_buffer_get_default_data_size (vm) - l234_sz);
+
   /* rounded-up division */
-  u16 n_bufs = (n_bytes_b0 - l234_sz + (gso_size - 1)) / gso_size;
+  u16 n_bufs = (n_bytes_b0 - l234_sz + (size - 1)) / size;
   u16 n_alloc;
 
   ASSERT (n_bufs > 0);
@@ -503,8 +507,7 @@ vnet_interface_output_node_inline_gso (vlib_main_t * vm,
 
   si = vnet_get_sw_interface (vnm, rt->sw_if_index);
   hi = vnet_get_sup_hw_interface (vnm, rt->sw_if_index);
-  if (!(si->flags & (VNET_SW_INTERFACE_FLAG_ADMIN_UP |
-                    VNET_SW_INTERFACE_FLAG_BOND_SLAVE)) ||
+  if (!(si->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ||
       !(hi->flags & VNET_HW_INTERFACE_FLAG_LINK_UP))
     {
       vlib_simple_counter_main_t *cm;
@@ -811,13 +814,29 @@ static_always_inline void vnet_interface_pcap_tx_trace
   else
     sw_if_index = ~0;
 
+  vnet_main_t *vnm = vnet_get_main ();
   n_left_from = frame->n_vectors;
   from = vlib_frame_vector_args (frame);
 
   while (n_left_from > 0)
     {
+      int classify_filter_result;
       u32 bi0 = from[0];
       vlib_buffer_t *b0 = vlib_get_buffer (vm, bi0);
+      from++;
+      n_left_from--;
+
+      if (vec_len (vnm->classify_filter_table_indices))
+       {
+         classify_filter_result =
+           vnet_is_packet_traced_inline
+           (b0, vnm->classify_filter_table_indices[0],
+            0 /* full classify */ );
+         if (classify_filter_result)
+           pcap_add_buffer (&vlib_global_main.pcap[VLIB_TX].pcap_main, vm,
+                            bi0, 512);
+         continue;
+       }
 
       if (sw_if_index_from_buffer)
        sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
@@ -826,8 +845,6 @@ static_always_inline void vnet_interface_pcap_tx_trace
          vlib_global_main.pcap[VLIB_TX].pcap_sw_if_index == sw_if_index)
        pcap_add_buffer (&vlib_global_main.pcap[VLIB_TX].pcap_main, vm, bi0,
                         512);
-      from++;
-      n_left_from--;
     }
 }
 
@@ -1190,8 +1207,19 @@ pcap_drop_trace (vlib_main_t * vm,
 
          /*
           * Typically, we'll need to rewind the buffer
+          * if l2_hdr_offset is valid, make sure to rewind to the start of
+          * the L2 header. This may not be the buffer start in case we pop-ed
+          * vlan tags.
+          * Otherwise, rewind to buffer start and hope for the best.
           */
-         if (b0->current_data > 0)
+         if (b0->flags & VNET_BUFFER_F_L2_HDR_OFFSET_VALID)
+           {
+             if (b0->current_data > vnet_buffer (b0)->l2_hdr_offset)
+               vlib_buffer_advance (b0,
+                                    vnet_buffer (b0)->l2_hdr_offset -
+                                    b0->current_data);
+           }
+         else if (b0->current_data > 0)
            vlib_buffer_advance (b0, (word) - b0->current_data);
 
          pcap_add_buffer (&im->pcap_main, vm, bi0, 512);
@@ -1315,7 +1343,7 @@ interface_tx_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
 }
 
 /* *INDENT-OFF* */
-VLIB_REGISTER_NODE (interface_tx, static) = {
+VLIB_REGISTER_NODE (interface_tx) = {
   .function = interface_tx_node_fn,
   .name = "interface-tx",
   .vector_size = sizeof (u32),
@@ -1439,6 +1467,8 @@ pcap_drop_trace_command_fn (vlib_main_t * vm,
                  im->pcap_main.n_packets_to_capture =
                    im->pcap_main.n_packets_captured;
                  error = pcap_write (&im->pcap_main);
+                 if (im->pcap_main.flags & PCAP_MAIN_INIT_DONE)
+                   pcap_close (&im->pcap_main);
                  if (error)
                    clib_error_report (error);
                  else