map: use ip6-full-reassembly instead of own code
[vpp.git] / src / vnet / ip / reass / ip6_full_reass.c
index 0b41dea..bba11e5 100644 (file)
@@ -164,6 +164,8 @@ typedef struct
   u32 fq_index;
   u32 fq_feature_index;
 
+  // reference count for enabling/disabling feature - per interface
+  u32 *feature_use_refcount_per_intf;
 } ip6_full_reass_main_t;
 
 extern ip6_full_reass_main_t ip6_full_reass_main;
@@ -885,13 +887,13 @@ ip6_full_reass_update (vlib_main_t * vm, vlib_node_runtime_t * node,
       else
        {
          // overlapping fragment - not allowed by RFC 8200
-         ip6_full_reass_drop_all (vm, node, rm, reass);
-         ip6_full_reass_free (rm, rt, reass);
          if (PREDICT_FALSE (fb->flags & VLIB_BUFFER_IS_TRACED))
            {
              ip6_full_reass_add_trace (vm, node, rm, reass, *bi0,
                                        RANGE_OVERLAP, ~0);
            }
+         ip6_full_reass_drop_all (vm, node, rm, reass);
+         ip6_full_reass_free (rm, rt, reass);
          *next0 = IP6_FULL_REASSEMBLY_NEXT_DROP;
          *error0 = IP6_ERROR_REASS_OVERLAPPING_FRAGMENT;
          return IP6_FULL_REASS_RC_OK;
@@ -911,11 +913,12 @@ check_if_done_maybe:
       reass->data_len == reass->last_packet_octet + 1)
     {
       *handoff_thread_idx = reass->sendout_thread_index;
+      int handoff =
+       reass->memory_owner_thread_index != reass->sendout_thread_index;
       ip6_full_reass_rc_t rc =
        ip6_full_reass_finalize (vm, node, rm, rt, reass, bi0, next0, error0,
                                 is_custom_app);
-      if (IP6_FULL_REASS_RC_OK == rc
-         && reass->memory_owner_thread_index != reass->sendout_thread_index)
+      if (IP6_FULL_REASS_RC_OK == rc && handoff)
        {
          return IP6_FULL_REASS_RC_HANDOFF;
        }
@@ -1426,6 +1429,7 @@ ip6_full_reass_init_function (vlib_main_t * vm)
   rm->fq_feature_index =
     vlib_frame_queue_main_init (ip6_full_reass_node_feature.index, 0);
 
+  rm->feature_use_refcount_per_intf = NULL;
   return error;
 }
 
@@ -1789,6 +1793,35 @@ VLIB_REGISTER_NODE (ip6_full_reassembly_feature_handoff_node) = {
 };
 /* *INDENT-ON* */
 
+#ifndef CLIB_MARCH_VARIANT
+int
+ip6_full_reass_enable_disable_with_refcnt (u32 sw_if_index, int is_enable)
+{
+  ip6_full_reass_main_t *rm = &ip6_full_reass_main;
+  vec_validate (rm->feature_use_refcount_per_intf, sw_if_index);
+  if (is_enable)
+    {
+      if (!rm->feature_use_refcount_per_intf[sw_if_index])
+       {
+         ++rm->feature_use_refcount_per_intf[sw_if_index];
+         return vnet_feature_enable_disable ("ip6-unicast",
+                                             "ip6-full-reassembly-feature",
+                                             sw_if_index, 1, 0, 0);
+       }
+      ++rm->feature_use_refcount_per_intf[sw_if_index];
+    }
+  else
+    {
+      --rm->feature_use_refcount_per_intf[sw_if_index];
+      if (!rm->feature_use_refcount_per_intf[sw_if_index])
+       return vnet_feature_enable_disable ("ip6-unicast",
+                                           "ip6-full-reassembly-feature",
+                                           sw_if_index, 0, 0, 0);
+    }
+  return -1;
+}
+#endif
+
 /*
  * fd.io coding-style-patch-verification: ON
  *