acl-plugin: optimize session idle timer checks
[vpp.git] / src / plugins / acl / acl.c
index 4f63a97..866c6ff 100644 (file)
@@ -54,7 +54,6 @@
 #include "public_inlines.h"
 
 acl_main_t acl_main;
-acl_main_t *p_acl_main = &acl_main;
 
 #define REPLY_MSG_ID_BASE am->msg_id_base
 #include <vlibapi/api_helper_macros.h>
@@ -95,6 +94,9 @@ VLIB_PLUGIN_REGISTER () = {
 };
 /* *INDENT-ON* */
 
+/* methods exported from ACL-as-a-service */
+static acl_plugin_methods_t acl_plugin;
+
 /* Format vec16. */
 u8 *
 format_vec16 (u8 * s, va_list * va)
@@ -111,19 +113,6 @@ format_vec16 (u8 * s, va_list * va)
   return s;
 }
 
-
-
-u8
-acl_plugin_acl_exists (u32 acl_index)
-{
-  acl_main_t *am = &acl_main;
-
-  if (pool_is_free_index (am->acls, acl_index))
-    return 0;
-
-  return 1;
-}
-
 static void *
 acl_set_heap (acl_main_t * am)
 {
@@ -150,15 +139,16 @@ acl_set_heap (acl_main_t * am)
          clib_warning ("ACL heap size requested: %lld, max possible %lld",
                        am->acl_mheap_size, max_possible);
        }
-      am->acl_mheap = mheap_alloc (0 /* use VM */ , am->acl_mheap_size);
+
+      am->acl_mheap = mheap_alloc_with_lock (0 /* use VM */ ,
+                                            am->acl_mheap_size,
+                                            1 /* locked */ );
       if (0 == am->acl_mheap)
        {
          clib_error
            ("ACL plugin failed to allocate main heap of %U bytes, abort",
             format_memory_size, am->acl_mheap_size);
        }
-      mheap_t *h = mheap_header (am->acl_mheap);
-      h->flags |= MHEAP_FLAG_THREAD_SAFE;
     }
   void *oldheap = clib_mem_set_heap (am->acl_mheap);
   return oldheap;
@@ -175,6 +165,7 @@ void
 acl_plugin_acl_set_validate_heap (acl_main_t * am, int on)
 {
   clib_mem_set_heap (acl_set_heap (am));
+#if USE_DLMALLOC == 0
   mheap_t *h = mheap_header (am->acl_mheap);
   if (on)
     {
@@ -187,12 +178,14 @@ acl_plugin_acl_set_validate_heap (acl_main_t * am, int on)
       h->flags &= ~MHEAP_FLAG_VALIDATE;
       h->flags |= MHEAP_FLAG_SMALL_OBJECT_CACHE;
     }
+#endif
 }
 
 void
 acl_plugin_acl_set_trace_heap (acl_main_t * am, int on)
 {
   clib_mem_set_heap (acl_set_heap (am));
+#if USE_DLMALLOC == 0
   mheap_t *h = mheap_header (am->acl_mheap);
   if (on)
     {
@@ -202,6 +195,7 @@ acl_plugin_acl_set_trace_heap (acl_main_t * am, int on)
     {
       h->flags &= ~MHEAP_FLAG_TRACE;
     }
+#endif
 }
 
 static void
@@ -478,7 +472,7 @@ acl_del_list (u32 acl_list_index)
     return VNET_API_ERROR_ACL_IN_USE_INBOUND;
   if (acl_is_used_by (acl_list_index, am->output_sw_if_index_vec_by_acl))
     return VNET_API_ERROR_ACL_IN_USE_OUTBOUND;
-  /* lookup contexts cover other cases, not just inbound/oubound, so check that */
+  /* lookup contexts cover other cases, not just inbound/outbound, so check that */
   if (acl_is_used_by (acl_list_index, am->lc_index_vec_by_acl))
     return VNET_API_ERROR_ACL_IN_USE_BY_LOOKUP_CONTEXT;
 
@@ -1349,20 +1343,20 @@ acl_interface_set_inout_acl_list (acl_main_t * am, u32 sw_if_index,
        {
          if (~0 == am->interface_acl_user_id)
            am->interface_acl_user_id =
-             acl_plugin_register_user_module ("interface ACL", "sw_if_index",
+             acl_plugin.register_user_module ("interface ACL", "sw_if_index",
                                               "is_input");
          lc_index =
-           acl_plugin_get_lookup_context_index (am->interface_acl_user_id,
+           acl_plugin.get_lookup_context_index (am->interface_acl_user_id,
                                                 sw_if_index, is_input);
          (*pinout_lc_index_by_sw_if_index)[sw_if_index] = lc_index;
        }
-      acl_plugin_set_acl_vec_for_context (lc_index, vec_acl_list_index);
+      acl_plugin.set_acl_vec_for_context (lc_index, vec_acl_list_index);
     }
   else
     {
       if (~0 != (*pinout_lc_index_by_sw_if_index)[sw_if_index])
        {
-         acl_plugin_put_lookup_context_index ((*pinout_lc_index_by_sw_if_index)[sw_if_index]);
+         acl_plugin.put_lookup_context_index ((*pinout_lc_index_by_sw_if_index)[sw_if_index]);
          (*pinout_lc_index_by_sw_if_index)[sw_if_index] = ~0;
        }
     }
@@ -1424,7 +1418,7 @@ acl_interface_add_del_inout_acl (u32 sw_if_index, u8 is_add, u8 is_input,
     }
   else
     {
-      if (sw_if_index > vec_len (*pinout_acl_vec_by_sw_if_index))
+      if (sw_if_index >= vec_len (*pinout_acl_vec_by_sw_if_index))
        {
          rv = VNET_API_ERROR_NO_SUCH_ENTRY;
          goto done;
@@ -2245,7 +2239,7 @@ macip_acl_add_list (u32 count, vl_api_macip_acl_rule_t rules[],
   a->count = count;
   memcpy (a->tag, tag, sizeof (a->tag));
 
-  /* Create and populate the classifer tables */
+  /* Create and populate the classifier tables */
   macip_create_classify_tables (am, *acl_list_index);
   clib_mem_set_heap (oldheap);
   /* If the ACL was already applied somewhere, reapply the newly created tables */
@@ -3463,7 +3457,7 @@ macip_acl_print (acl_main_t * am, u32 macip_acl_index)
   int i;
 
   /* Don't try to print someone else's memory */
-  if (macip_acl_index > vec_len (am->macip_acls))
+  if (macip_acl_index >= vec_len (am->macip_acls))
     return;
 
   macip_acl_list_t *a = vec_elt_at_index (am->macip_acls, macip_acl_index);
@@ -3906,6 +3900,10 @@ acl_plugin_show_sessions (acl_main_t * am,
                       pw->interrupt_is_unwanted);
       vlib_cli_output (vm, "  interrupt generation: %d",
                       pw->interrupt_generation);
+      vlib_cli_output (vm, "  received session change requests: %d",
+                      pw->rcvd_session_change_requests);
+      vlib_cli_output (vm, "  sent session change requests: %d",
+                      pw->sent_session_change_requests);
     }
   vlib_cli_output (vm, "\n\nConn cleaner thread counters:");
 #define _(cnt, desc) vlib_cli_output(vm, "             %20lu: %s", am->cnt, desc);
@@ -4100,6 +4098,8 @@ acl_plugin_config (vlib_main_t * vm, unformat_input_t * input)
   u32 hash_lookup_hash_buckets;
   u32 hash_lookup_hash_memory;
   u32 reclassify_sessions;
+  u32 use_tuple_merge;
+  u32 tuple_merge_split_threshold;
 
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
@@ -4128,6 +4128,14 @@ acl_plugin_config (vlib_main_t * vm, unformat_input_t * input)
       else if (unformat (input, "hash lookup hash memory %d",
                         &hash_lookup_hash_memory))
        am->hash_lookup_hash_memory = hash_lookup_hash_memory;
+      else if (unformat (input, "use tuple merge %d", &use_tuple_merge))
+       am->use_tuple_merge = use_tuple_merge;
+      else
+       if (unformat
+           (input, "tuple merge split threshold %d",
+            &tuple_merge_split_threshold))
+       am->tuple_merge_split_threshold = tuple_merge_split_threshold;
+
       else if (unformat (input, "reclassify sessions %d",
                         &reclassify_sessions))
        am->reclassify_sessions = reclassify_sessions;
@@ -4164,6 +4172,14 @@ acl_init (vlib_main_t * vm)
 
   vec_free (name);
 
+  if (error)
+    return error;
+
+  error = acl_plugin_exports_init (&acl_plugin);
+
+  if (error)
+    return error;
+
   acl_setup_fa_nodes ();
 
   am->acl_mheap_size = 0;      /* auto size when initializing */
@@ -4200,6 +4216,10 @@ acl_init (vlib_main_t * vm)
     for (wk = 0; wk < vec_len (am->per_worker_data); wk++)
       {
        acl_fa_per_worker_data_t *pw = &am->per_worker_data[wk];
+       if (tm->n_vlib_mains > 1)
+         {
+           clib_spinlock_init (&pw->pending_session_change_request_lock);
+         }
        vec_validate (pw->expired,
                      ACL_N_TIMEOUTS *
                      am->fa_max_deleted_sessions_per_interval);
@@ -4227,6 +4247,10 @@ acl_init (vlib_main_t * vm)
 
   /* use the new fancy hash-based matching */
   am->use_hash_acl_matching = 1;
+  /* use tuplemerge by default */
+  am->use_tuple_merge = 1;
+  /* Set the default threshold */
+  am->tuple_merge_split_threshold = TM_SPLIT_THRESHOLD;
 
   am->interface_acl_user_id = ~0;      /* defer till the first use */