interface: fix issue that pcap rx/tx trace not available when there are worker threads
[vpp.git] / src / vnet / ethernet / node.c
index 3264bdc..4640540 100755 (executable)
@@ -963,29 +963,55 @@ ethernet_input_trace (vlib_main_t * vm, vlib_node_runtime_t * node,
                      vlib_frame_t * from_frame)
 {
   u32 *from, n_left;
-  if ((node->flags & VLIB_NODE_FLAG_TRACE) == 0)
-    return;
+  if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
+    {
+      from = vlib_frame_vector_args (from_frame);
+      n_left = from_frame->n_vectors;
 
-  from = vlib_frame_vector_args (from_frame);
-  n_left = from_frame->n_vectors;
+      while (n_left)
+       {
+         ethernet_input_trace_t *t0;
+         vlib_buffer_t *b0 = vlib_get_buffer (vm, from[0]);
 
-  while (n_left)
+         if (b0->flags & VLIB_BUFFER_IS_TRACED)
+           {
+             t0 = vlib_add_trace (vm, node, b0,
+                                  sizeof (ethernet_input_trace_t));
+             clib_memcpy_fast (t0->packet_data, b0->data + b0->current_data,
+                               sizeof (t0->packet_data));
+             t0->frame_flags = from_frame->flags;
+             clib_memcpy_fast (&t0->frame_data,
+                               vlib_frame_scalar_args (from_frame),
+                               sizeof (ethernet_input_frame_t));
+           }
+         from += 1;
+         n_left -= 1;
+       }
+    }
+
+  /* rx pcap capture if enabled */
+  if (PREDICT_FALSE (vlib_global_main.pcap[VLIB_RX].pcap_enable))
     {
-      ethernet_input_trace_t *t0;
-      vlib_buffer_t *b0 = vlib_get_buffer (vm, from[0]);
+      u32 bi0;
 
-      if (b0->flags & VLIB_BUFFER_IS_TRACED)
+      from = vlib_frame_vector_args (from_frame);
+      n_left = from_frame->n_vectors;
+      while (n_left > 0)
        {
-         t0 = vlib_add_trace (vm, node, b0, sizeof (ethernet_input_trace_t));
-         clib_memcpy_fast (t0->packet_data, b0->data + b0->current_data,
-                           sizeof (t0->packet_data));
-         t0->frame_flags = from_frame->flags;
-         clib_memcpy_fast (&t0->frame_data,
-                           vlib_frame_scalar_args (from_frame),
-                           sizeof (ethernet_input_frame_t));
+         vlib_buffer_t *b0;
+         bi0 = from[0];
+         from++;
+         b0 = vlib_get_buffer (vm, bi0);
+
+         if (vlib_global_main.pcap[VLIB_RX].pcap_sw_if_index == 0 ||
+             vlib_global_main.pcap[VLIB_RX].pcap_sw_if_index
+             == vnet_buffer (b0)->sw_if_index[VLIB_RX])
+           {
+             pcap_add_buffer (&vlib_global_main.pcap[VLIB_RX].pcap_main, vm,
+                              bi0, 512);
+           }
+         n_left--;
        }
-      from += 1;
-      n_left -= 1;
     }
 }
 
@@ -1004,6 +1030,8 @@ ethernet_input_inline (vlib_main_t * vm,
   u32 cached_sw_if_index = ~0;
   u32 cached_is_l2 = 0;                /* shut up gcc */
   vnet_hw_interface_t *hi = NULL;      /* used for main interface only */
+  vlib_buffer_t *bufs[VLIB_FRAME_SIZE];
+  vlib_buffer_t **b = bufs;
 
   if (variant != ETHERNET_INPUT_VARIANT_ETHERNET)
     error_node = vlib_node_get_runtime (vm, ethernet_input_node.index);
@@ -1015,6 +1043,7 @@ ethernet_input_inline (vlib_main_t * vm,
   next_index = node->cached_next_index;
   stats_sw_if_index = node->runtime_data[0];
   stats_n_packets = stats_n_bytes = 0;
+  vlib_get_buffers (vm, from, bufs, n_left_from);
 
   while (n_left_from > 0)
     {
@@ -1041,16 +1070,11 @@ ethernet_input_inline (vlib_main_t * vm,
 
          /* Prefetch next iteration. */
          {
-           vlib_buffer_t *b2, *b3;
-
-           b2 = vlib_get_buffer (vm, from[2]);
-           b3 = vlib_get_buffer (vm, from[3]);
-
-           vlib_prefetch_buffer_header (b2, STORE);
-           vlib_prefetch_buffer_header (b3, STORE);
+           vlib_prefetch_buffer_header (b[2], STORE);
+           vlib_prefetch_buffer_header (b[3], STORE);
 
-           CLIB_PREFETCH (b2->data, sizeof (ethernet_header_t), LOAD);
-           CLIB_PREFETCH (b3->data, sizeof (ethernet_header_t), LOAD);
+           CLIB_PREFETCH (b[2]->data, sizeof (ethernet_header_t), LOAD);
+           CLIB_PREFETCH (b[3]->data, sizeof (ethernet_header_t), LOAD);
          }
 
          bi0 = from[0];
@@ -1062,8 +1086,9 @@ ethernet_input_inline (vlib_main_t * vm,
          n_left_to_next -= 2;
          n_left_from -= 2;
 
-         b0 = vlib_get_buffer (vm, bi0);
-         b1 = vlib_get_buffer (vm, bi1);
+         b0 = b[0];
+         b1 = b[1];
+         b += 2;
 
          error0 = error1 = ETHERNET_ERROR_NONE;
          e0 = vlib_buffer_get_current (b0);
@@ -1289,11 +1314,8 @@ ethernet_input_inline (vlib_main_t * vm,
          // Prefetch next iteration
          if (n_left_from > 1)
            {
-             vlib_buffer_t *p2;
-
-             p2 = vlib_get_buffer (vm, from[1]);
-             vlib_prefetch_buffer_header (p2, STORE);
-             CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, LOAD);
+             vlib_prefetch_buffer_header (b[1], STORE);
+             CLIB_PREFETCH (b[1]->data, CLIB_CACHE_LINE_BYTES, LOAD);
            }
 
          bi0 = from[0];
@@ -1303,7 +1325,8 @@ ethernet_input_inline (vlib_main_t * vm,
          n_left_from -= 1;
          n_left_to_next -= 1;
 
-         b0 = vlib_get_buffer (vm, bi0);
+         b0 = b[0];
+         b += 1;
 
          error0 = ETHERNET_ERROR_NONE;
          e0 = vlib_buffer_get_current (b0);
@@ -2003,11 +2026,9 @@ next_by_ethertype_register (next_by_ethertype_t * l3_next,
   return 0;
 }
 
-
-static clib_error_t *
-ethernet_input_init (vlib_main_t * vm)
+void
+ethernet_input_init (vlib_main_t * vm, ethernet_main_t * em)
 {
-  ethernet_main_t *em = &ethernet_main;
   __attribute__ ((unused)) vlan_table_t *invalid_vlan_table;
   __attribute__ ((unused)) qinq_table_t *invalid_qinq_table;
 
@@ -2026,12 +2047,8 @@ ethernet_input_init (vlib_main_t * vm)
   pool_get (em->vlan_pool, invalid_vlan_table);        // first id = 0
   // The first qinq pool will always be reserved for an invalid table
   pool_get (em->qinq_pool, invalid_qinq_table);        // first id = 0
-
-  return 0;
 }
 
-VLIB_INIT_FUNCTION (ethernet_input_init);
-
 void
 ethernet_register_input_type (vlib_main_t * vm,
                              ethernet_type_t type, u32 node_index)
@@ -2047,6 +2064,11 @@ ethernet_register_input_type (vlib_main_t * vm,
   }
 
   ti = ethernet_get_type_info (em, type);
+  if (ti == 0)
+    {
+      clib_warning ("type_info NULL for type %d", type);
+      return;
+    }
   ti->node_index = node_index;
   ti->next_index = vlib_node_add_next (vm,
                                       ethernet_input_node.index, node_index);