pg: add GSO support
[vpp.git] / src / vnet / pg / stream.c
index c46875e..c4a57ea 100644 (file)
@@ -100,11 +100,11 @@ format_pg_output_trace (u8 * s, va_list * va)
   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
   CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
   pg_output_trace_t *t = va_arg (*va, pg_output_trace_t *);
-  uword indent = format_get_indent (s);
+  u32 indent = format_get_indent (s);
 
   s = format (s, "%Ubuffer 0x%x: %U",
              format_white_space, indent,
-             t->buffer_index, format_vlib_buffer, &t->buffer);
+             t->buffer_index, format_vnet_buffer, &t->buffer);
 
   s = format (s, "\n%U%U", format_white_space, indent,
              format_ethernet_header_with_length, t->buffer.pre_data,
@@ -179,7 +179,8 @@ pg_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi, u32 flags)
 }
 
 u32
-pg_interface_add_or_get (pg_main_t * pg, uword if_id)
+pg_interface_add_or_get (pg_main_t * pg, uword if_id, u8 gso_enabled,
+                        u32 gso_size)
 {
   vnet_main_t *vnm = vnet_get_main ();
   vlib_main_t *vm = vlib_get_main ();
@@ -205,7 +206,7 @@ pg_interface_add_or_get (pg_main_t * pg, uword if_id)
 
       rnd = (u32) (now * 1e6);
       rnd = random_u32 (&rnd);
-      clib_memcpy (hw_addr + 2, &rnd, sizeof (rnd));
+      clib_memcpy_fast (hw_addr + 2, &rnd, sizeof (rnd));
       hw_addr[0] = 2;
       hw_addr[1] = 0xfe;
 
@@ -213,6 +214,13 @@ pg_interface_add_or_get (pg_main_t * pg, uword if_id)
       ethernet_register_interface (vnm, pg_dev_class.index, i, hw_addr,
                                   &pi->hw_if_index, pg_eth_flag_change);
       hi = vnet_get_hw_interface (vnm, pi->hw_if_index);
+      if (gso_enabled)
+       {
+         hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_GSO;
+         vnm->interface_main.gso_interface_count++;
+         pi->gso_enabled = 1;
+         pi->gso_size = gso_size;
+       }
       pi->sw_if_index = hi->sw_if_index;
 
       hash_set (pg->if_index_by_if_id, if_id, i);
@@ -223,10 +231,6 @@ pg_interface_add_or_get (pg_main_t * pg, uword if_id)
                                              CLIB_CACHE_LINE_BYTES);
          *pi->lockp = 0;
        }
-
-      ip4_sw_interface_enable_disable (pi->hw_if_index, 1);
-      ip6_sw_interface_enable_disable (pi->hw_if_index, 1);
-      mpls_sw_interface_enable_disable (&mpls_main, pi->hw_if_index, 1);
     }
 
   return i;
@@ -337,10 +341,10 @@ pg_edit_group_get_fixed_packet_data (pg_stream_t * s,
 
   vec_foreach (e, g->edits) do_edit (s, g, e, /* want_commit */ 0);
 
-  clib_memcpy (packet_data, g->fixed_packet_data,
-              vec_len (g->fixed_packet_data));
-  clib_memcpy (packet_data_mask, g->fixed_packet_data_mask,
-              vec_len (g->fixed_packet_data_mask));
+  clib_memcpy_fast (packet_data, g->fixed_packet_data,
+                   vec_len (g->fixed_packet_data));
+  clib_memcpy_fast (packet_data_mask, g->fixed_packet_data_mask,
+                   vec_len (g->fixed_packet_data_mask));
 }
 
 static void
@@ -439,46 +443,30 @@ pg_stream_add (pg_main_t * pg, pg_stream_t * s_init)
   s->last_increment_packet_size = s->min_packet_bytes;
 
   {
-    pg_buffer_index_t *bi;
     int n;
 
-#if DPDK > 0
-    s->buffer_bytes = VLIB_BUFFER_DATA_SIZE;
-#endif
-
-    if (!s->buffer_bytes)
-      s->buffer_bytes = s->max_packet_bytes;
-
-    s->buffer_bytes = vlib_buffer_round_size (s->buffer_bytes);
-
+    s->buffer_bytes = vlib_buffer_get_default_data_size (vm);
     n = s->max_packet_bytes / s->buffer_bytes;
     n += (s->max_packet_bytes % s->buffer_bytes) != 0;
 
     vec_resize (s->buffer_indices, n);
-
-    vec_foreach (bi, s->buffer_indices)
-    {
-      bi->free_list_index =
-       vlib_buffer_create_free_list (vm, s->buffer_bytes,
-                                     "pg stream %d buffer #%d",
-                                     s - pg->streams,
-                                     1 + (bi - s->buffer_indices));
-    }
   }
 
   /* Find an interface to use. */
-  s->pg_if_index = pg_interface_add_or_get (pg, s->if_id);
+  s->pg_if_index =
+    pg_interface_add_or_get (pg, s->if_id, 0 /* gso_enabled */ ,
+                            0 /* gso_size */ );
 
-  {
-    pg_interface_t *pi = pool_elt_at_index (pg->interfaces, s->pg_if_index);
-    vlib_rx_or_tx_t rx_or_tx;
-
-    vlib_foreach_rx_tx (rx_or_tx)
+  if (s->sw_if_index[VLIB_RX] == ~0)
     {
-      if (s->sw_if_index[rx_or_tx] == ~0)
-       s->sw_if_index[rx_or_tx] = pi->sw_if_index;
+      pg_interface_t *pi = pool_elt_at_index (pg->interfaces, s->pg_if_index);
+      /*
+       * Default the RX interface if unset. It's a bad mistake to
+       * set [VLIB_TX] prior to ip lookup, since the ip lookup code
+       * interprets [VLIB_TX] as a fib index...
+       */
+      s->sw_if_index[VLIB_RX] = pi->sw_if_index;
     }
-  }
 
   /* Connect the graph. */
   s->next_index = vlib_node_add_next (vm, device_input_node.index,
@@ -488,7 +476,6 @@ pg_stream_add (pg_main_t * pg, pg_stream_t * s_init)
 void
 pg_stream_del (pg_main_t * pg, uword index)
 {
-  vlib_main_t *vm = vlib_get_main ();
   pg_stream_t *s;
   pg_buffer_index_t *bi;
 
@@ -499,7 +486,6 @@ pg_stream_del (pg_main_t * pg, uword index)
 
   vec_foreach (bi, s->buffer_indices)
   {
-    vlib_buffer_delete_free_list (vm, bi->free_list_index);
     clib_fifo_free (bi->buffer_fifo);
   }
 
@@ -507,6 +493,31 @@ pg_stream_del (pg_main_t * pg, uword index)
   pool_put (pg->streams, s);
 }
 
+void
+pg_stream_change (pg_main_t * pg, pg_stream_t * s)
+{
+  /* Determine packet size. */
+  switch (s->packet_size_edit_type)
+    {
+    case PG_EDIT_INCREMENT:
+    case PG_EDIT_RANDOM:
+      if (s->min_packet_bytes == s->max_packet_bytes)
+       s->packet_size_edit_type = PG_EDIT_FIXED;
+    case PG_EDIT_FIXED:
+      break;
+
+    default:
+      /* Get packet size from fixed edits. */
+      s->packet_size_edit_type = PG_EDIT_FIXED;
+      if (!s->replay_packet_templates)
+       s->min_packet_bytes = s->max_packet_bytes =
+         vec_len (s->fixed_packet_data);
+      break;
+    }
+
+  s->last_increment_packet_size = s->min_packet_bytes;
+}
+
 
 /*
  * fd.io coding-style-patch-verification: ON