c11 safe string handling support
[vpp.git] / src / plugins / dpdk / device / flow.c
index a9ba1d0..6612ce4 100644 (file)
@@ -179,12 +179,14 @@ dpdk_flow_add (dpdk_device_t * xd, vnet_flow_t * f, dpdk_flow_entry_t * fe)
        .vni_reserved = clib_host_to_net_u32 (((u32) - 1) << 8)
       };
 
-      memset (raw, 0, sizeof raw);
+      clib_memset (raw, 0, sizeof raw);
       raw[0].item.relative = 1;
       raw[0].item.length = vxlan_hdr_sz;
 
       clib_memcpy (raw[0].val + raw_sz, &spec_hdr, vxlan_hdr_sz);
-      clib_memcpy (raw[1].val + raw_sz, &mask_hdr, vxlan_hdr_sz);;
+      raw[0].item.pattern = raw[0].val + raw_sz;
+      clib_memcpy (raw[1].val + raw_sz, &mask_hdr, vxlan_hdr_sz);
+      raw[1].item.pattern = raw[1].val + raw_sz;
 
       vec_add2 (items, item, 1);
       item->type = RTE_FLOW_ITEM_TYPE_RAW;
@@ -230,6 +232,18 @@ dpdk_flow_ops_fn (vnet_main_t * vnm, vnet_flow_dev_op_t op, u32 dev_instance,
   dpdk_flow_lookup_entry_t *fle = 0;
   int rv;
 
+  /* recycle old flow lookup entries only after the main loop counter
+     increases - i.e. previously DMA'ed packets were handled */
+  if (vec_len (xd->parked_lookup_indexes) > 0 &&
+      xd->parked_loop_count != dm->vlib_main->main_loop_count)
+    {
+      u32 *fl_index;
+
+      vec_foreach (fl_index, xd->parked_lookup_indexes)
+       pool_put_index (xd->flow_lookup_entries, *fl_index);
+      vec_reset_length (xd->flow_lookup_entries);
+    }
+
   if (op == VNET_FLOW_DEV_OP_DEL_FLOW)
     {
       ASSERT (*private_data >= vec_len (xd->flow_entries));
@@ -240,7 +254,16 @@ dpdk_flow_ops_fn (vnet_main_t * vnm, vnet_flow_dev_op_t op, u32 dev_instance,
                                  &xd->last_flow_error)))
        return VNET_FLOW_ERROR_INTERNAL;
 
-      memset (fe, 0, sizeof (*fe));
+      if (fe->mark)
+       {
+         /* make sure no action is taken for in-flight (marked) packets */
+         fle = pool_elt_at_index (xd->flow_lookup_entries, fe->mark);
+         clib_memset (fle, -1, sizeof (*fle));
+         vec_add1 (xd->parked_lookup_indexes, fe->mark);
+         xd->parked_loop_count = dm->vlib_main->main_loop_count;
+       }
+
+      clib_memset (fe, 0, sizeof (*fe));
       pool_put (xd->flow_entries, fe);
 
       goto disable_rx_offload;
@@ -269,6 +292,15 @@ dpdk_flow_ops_fn (vnet_main_t * vnm, vnet_flow_dev_op_t op, u32 dev_instance,
                          CLIB_CACHE_LINE_BYTES);
       pool_get_aligned (xd->flow_lookup_entries, fle, CLIB_CACHE_LINE_BYTES);
       fe->mark = fle - xd->flow_lookup_entries;
+
+      /* install entry in the lookup table */
+      clib_memset (fle, -1, sizeof (*fle));
+      if (flow->actions & VNET_FLOW_ACTION_MARK)
+       fle->flow_id = flow->mark_flow_id;
+      if (flow->actions & VNET_FLOW_ACTION_REDIRECT_TO_NODE)
+       fle->next_index = flow->redirect_device_input_next_index;
+      if (flow->actions & VNET_FLOW_ACTION_BUFFER_ADVANCE)
+       fle->buffer_advance = flow->buffer_advance;
     }
   else
     fe->mark = 0;
@@ -294,23 +326,14 @@ dpdk_flow_ops_fn (vnet_main_t * vnm, vnet_flow_dev_op_t op, u32 dev_instance,
 
   *private_data = fe - xd->flow_entries;
 
-  /* install entry in the lookup table */
-  memset (fle, -1, sizeof (*fle));
-  if (flow->actions & VNET_FLOW_ACTION_MARK)
-    fle->flow_id = flow->mark_flow_id;
-  if (flow->actions & VNET_FLOW_ACTION_REDIRECT_TO_NODE)
-    fle->next_index = flow->redirect_device_input_next_index;
-  if (flow->actions & VNET_FLOW_ACTION_BUFFER_ADVANCE)
-    fle->buffer_advance = flow->buffer_advance;
-
 done:
   if (rv)
     {
-      memset (fe, 0, sizeof (*fe));
+      clib_memset (fe, 0, sizeof (*fe));
       pool_put (xd->flow_entries, fe);
       if (fle)
        {
-         memset (fle, 0, sizeof (*fle));
+         clib_memset (fle, -1, sizeof (*fle));
          pool_put (xd->flow_lookup_entries, fle);
        }
     }
@@ -347,11 +370,10 @@ format_dpdk_flow (u8 * s, va_list * args)
       return s;
     }
 
-  fe = vec_elt_at_index (xd->flow_entries, private_data);
-
-  if (!fe)
+  if (private_data >= vec_len (xd->flow_entries))
     return format (s, "unknown flow");
 
+  fe = vec_elt_at_index (xd->flow_entries, private_data);
   s = format (s, "mark %u", fe->mark);
   return s;
 }