acl-plugin: acl-as-a-service: VPP-1248: fix the error if exports.h included in more... 69/11969/9
authorAndrew Yourtchenko <ayourtch@gmail.com>
Tue, 15 May 2018 15:25:50 +0000 (17:25 +0200)
committerDave Barach <openvpp@barachs.net>
Wed, 20 Jun 2018 13:37:21 +0000 (13:37 +0000)
Including the exports.h from multiple .c files belonging to a single plugin results in an error.

Rework the approach to require the table of function pointers to be filled in by
the initialization function.

Since the inline functions are compiled in the "caller" context,
there is no knowledge about the acl_main structure used by the ACL
plugin. To help with that, the signature of inline functions is slightly
different, taking the p_acl_main pointer as the first parameter.

That pointer is filled into the .p_acl_main field of the method
table during the initialization - since the calling of non-inline variants
would have required filling the method table, this should give
minimal headaches during the use and switch between the two methods.

Change-Id: Icb70695efa23579c46c716944838766cebc8573e
Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
src/plugins/abf/abf_itf_attach.c
src/plugins/acl.am
src/plugins/acl/acl.c
src/plugins/acl/acl.h
src/plugins/acl/acl_lookup_context.md
src/plugins/acl/dataplane_node.c
src/plugins/acl/exported_types.h [new file with mode: 0644]
src/plugins/acl/fa_node.h
src/plugins/acl/lookup_context.c
src/plugins/acl/public_inlines.h

index 2e30db9..5373fc0 100644 (file)
@@ -47,6 +47,11 @@ static u32 *abf_alctx_per_itf[FIB_PROTOCOL_MAX];
  * ABF ACL module user id returned during the initialization
  */
 static u32 abf_acl_user_id;
+/*
+ * ACL plugin method vtable
+ */
+
+static acl_plugin_methods_t acl_plugin;
 
 /**
  * A DB of attachments; key={abf_index,sw_if_index}
@@ -152,7 +157,7 @@ abf_setup_acl_lc (fib_protocol_t fproto, u32 sw_if_index)
     aia = abf_itf_attach_get (*aiai);
     vec_add1 (acl_vec, aia->aia_acl);
   }
-  acl_plugin_set_acl_vec_for_context (abf_alctx_per_itf[fproto][sw_if_index],
+  acl_plugin.set_acl_vec_for_context (abf_alctx_per_itf[fproto][sw_if_index],
                                      acl_vec);
   vec_free (acl_vec);
 }
@@ -219,7 +224,7 @@ abf_itf_attach (fib_protocol_t fproto,
       /* if this is the first ABF policy, we need to acquire an ACL lookup context */
       vec_validate_init_empty (abf_alctx_per_itf[fproto], sw_if_index, ~0);
       abf_alctx_per_itf[fproto][sw_if_index] =
-       acl_plugin_get_lookup_context_index (abf_acl_user_id, sw_if_index, 0);
+       acl_plugin.get_lookup_context_index (abf_acl_user_id, sw_if_index, 0);
     }
   else
     {
@@ -282,7 +287,7 @@ abf_itf_detach (fib_protocol_t fproto, u32 policy_id, u32 sw_if_index)
                                   sw_if_index, 0, NULL, 0);
 
       /* Return the lookup context, invalidate its id in our records */
-      acl_plugin_put_lookup_context_index (abf_alctx_per_itf[fproto]
+      acl_plugin.put_lookup_context_index (abf_alctx_per_itf[fproto]
                                           [sw_if_index]);
       abf_alctx_per_itf[fproto][sw_if_index] = ~0;
     }
@@ -546,13 +551,25 @@ abf_input_inline (vlib_main_t * vm,
           */
          u32 lc_index = abf_alctx_per_itf[fproto][sw_if_index0];
 
-         acl_plugin_fill_5tuple (lc_index, b0, (FIB_PROTOCOL_IP6 == fproto),
-                                 1, 0, &fa_5tuple0);
-
-         if (acl_plugin_match_5tuple
-             (lc_index, &fa_5tuple0, (FIB_PROTOCOL_IP6 == fproto), &action,
-              &match_acl_pos, &match_acl_index, &match_rule_index,
-              &trace_bitmap))
+         /*
+            A non-inline version looks like this:
+
+            acl_plugin.fill_5tuple (lc_index, b0, (FIB_PROTOCOL_IP6 == fproto),
+            1, 0, &fa_5tuple0);
+            if (acl_plugin.match_5tuple
+            (lc_index, &fa_5tuple0, (FIB_PROTOCOL_IP6 == fproto), &action,
+            &match_acl_pos, &match_acl_index, &match_rule_index,
+            &trace_bitmap))
+            . . .
+          */
+         acl_plugin_fill_5tuple_inline (acl_plugin.p_acl_main, lc_index, b0,
+                                        (FIB_PROTOCOL_IP6 == fproto), 1, 0,
+                                        &fa_5tuple0);
+
+         if (acl_plugin_match_5tuple_inline
+             (acl_plugin.p_acl_main, lc_index, &fa_5tuple0,
+              (FIB_PROTOCOL_IP6 == fproto), &action, &match_acl_pos,
+              &match_acl_index, &match_rule_index, &trace_bitmap))
            {
              /*
               * match:
@@ -737,12 +754,12 @@ abf_itf_bond_init (vlib_main_t * vm)
 {
   abf_itf_attach_fib_node_type =
     fib_node_register_new_type (&abf_itf_attach_vft);
-  clib_error_t *acl_init_res = acl_plugin_exports_init ();
+  clib_error_t *acl_init_res = acl_plugin_exports_init (&acl_plugin);
   if (acl_init_res)
     return (acl_init_res);
 
   abf_acl_user_id =
-    acl_plugin_register_user_module ("abp plugin", "sw_if_index", NULL);
+    acl_plugin.register_user_module ("abp plugin", "sw_if_index", NULL);
 
   return (NULL);
 }
index 8508a1d..f73fda6 100644 (file)
@@ -27,7 +27,8 @@ acl_plugin_la_SOURCES =                               \
        acl/lookup_context.c                    \
        acl/sess_mgmt_node.c                    \
        acl/dataplane_node.c                    \
-       acl/l2sess.h                            \
+       acl/public_inlines.h                    \
+       acl/exported_types.h                    \
        acl/manual_fns.h                        \
        acl/acl_plugin.api.h
 
index 4f63a97..aab18c6 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)
 {
@@ -1349,20 +1338,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;
        }
     }
@@ -4164,6 +4153,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 */
index 9d333da..f63771f 100644 (file)
@@ -390,15 +390,7 @@ AH has a special treatment of its length, it is in 32-bit words, not 64-bit word
 
 
 extern acl_main_t acl_main;
-/*
- * pointer to the above.
- * Needed for some gymnastics to be able to provide
- * the inline functions from this plugin to other plugins.
- */
-
-extern acl_main_t *p_acl_main;
 
 void *acl_plugin_set_heap();
 
-
 #endif
index c049aae..53ad1ef 100644 (file)
@@ -52,33 +52,32 @@ Using ACL contexts in your code
 
 In order to use the ACL lookup contexts, you need to include
 plugins/acl/exports.h into your code. This header includes
-all the necessary dependencies required, as well as
-the actual "meat" include file containing the necessary
-definitions - plugins/acl/public_inlines.h
+all the necessary dependencies required.
 
 As you probably will invoke this code from another plugin,
 the non-inline function calls are implemented via function pointers,
-which you need to initialize by calling acl_plugin_exports_init(), which,
-if everything succeeds, returns 0 - else it will return clib_error_t with
+which you need to initialize by calling acl_plugin_exports_init(&acl_plugin), which,
+if everything succeeds, returns 0 and fills in the acl_plugin structure
+with pointers to the exported methods - else it will return clib_error_t with
 more information about what went wrong.
 
 When you have initialized the symbols, you also need to register yourself
 as a user of the ACL lookups - this allows to track the ACL lookup context
 ownership, as well as make the debug show outputs more user friendly.
 
-To do that, call acl_plugin_register_user_module(caller_module_string, val1_label, val2_label) -
+To do that, call acl_plugin.register_user_module(caller_module_string, val1_label, val2_label) -
 and record the returned value. This will bethe first parameter that you pass to create a new
 lookup context. The passed strings must be static, and are used as descriptions for the ACL
 contexts themselves, as well as labels for up to two user-supplied u32 labels, used to
 differentiate the lookup contexts for the debugging purposes.
 
-Creating a new context is done by calling acl_plugin_get_lookup_context_index(user_id, val1, val2).
+Creating a new context is done by calling acl_plugin.get_lookup_context_index(user_id, val1, val2).
 The first argument is your "user" ID obtained in a registration call earlier, the other two
 arguments are u32s with semantics that you designate. They are used purely for debugging purposes
 in the "show acl lookup context" command.
 
 To set the vector of ACL numbers to be looked up within the context, use the function
-acl_plugin_set_acl_vec_for_context(lc_index, acl_list). The first parameter specifies the context
+acl_plugin.set_acl_vec_for_context(lc_index, acl_list). The first parameter specifies the context
 that you have created, the second parameter is a vector of u32s, each u32 being the index of the ACL
 which we should be looking up within this context. The comand is idempotent, i.e.
 it unapplies the previously applied list of ACLs, and then sets the new list of ACLs.
@@ -87,17 +86,30 @@ Subsequent ACL updates for the already applied ACLs will cause the re-applicatio
 on an as-needed basis. Note, that the ACL application is potentially a relatively costly operation,
 so it is only expected that these changes will be done in the control plane, NOT in the datapath.
 
-The matching within the context is done using two functions - acl_plugin_fill_5tuple() and
-acl_plugin_match_5tuple() and their corresponding inline versions, named acl_plugin_fill_5tuple_inline()
+The matching within the context is done using two functions - acl_plugin.fill_5tuple() and
+acl_plugin.match_5tuple() and their corresponding inline versions, named acl_plugin_fill_5tuple_inline()
 and acl_plugin_match_5tuple_inline(). The inline and non-inline versions have the equivalent functionality,
 in that the non-inline version calls the inline version. These two variants are provided
 for debugging/maintenance reasons.
 
 When you no longer need a particular context, you can return the allocated resources by calling
-acl_plugin_put_lookup_context_index() to mark it as free. The lookup structured associated with
+acl_plugin.put_lookup_context_index() to mark it as free. The lookup structured associated with
 the vector of ACLs set for the lookup are cleaned up automatically. However, the ACLs themselves
 are not deleted and are available for subsequent reuse by other lookup contexts if needed.
 
+There is one delicate detail that you might want to be aware of.
+When the non-inline functions reference the inline functions,
+they are compiled as part of ACL plugin; whereas when you refer to the inline
+functions from your code, they are compiled as part of your code.
+This makes referring to a single acl_main structure a little trickier.
+
+It is done by having a static p_acl_main within the .h file, 
+which points to acl_main of the ACL plugin, and is initialized by a static constructor
+function.
+
+This way the multiple includes and inlines will "just work" as one would expect.
+
+
 Debug CLIs
 ==========
 
index a6c7b98..499ad16 100644 (file)
@@ -136,8 +136,8 @@ acl_fa_node_fn (vlib_main_t * vm,
        * Extract the L3/L4 matching info into a 5-tuple structure.
        */
 
-      acl_plugin_fill_5tuple_inline (lc_index0, b[0], is_ip6, is_input,
-                                    is_l2_path,
+      acl_plugin_fill_5tuple_inline (&acl_main, lc_index0, b[0], is_ip6,
+                                    is_input, is_l2_path,
                                     (fa_5tuple_opaque_t *) & fa_5tuple);
       fa_5tuple.l4.lsb_of_sw_if_index = sw_if_index0 & 0xffff;
       fa_5tuple.pkt.mask_type_index_lsb = ~0;
@@ -234,7 +234,7 @@ acl_fa_node_fn (vlib_main_t * vm,
       if (acl_check_needed)
        {
          action = 0;           /* deny by default */
-         acl_plugin_match_5tuple_inline (lc_index0,
+         acl_plugin_match_5tuple_inline (&acl_main, lc_index0,
                                          (fa_5tuple_opaque_t *) &
                                          fa_5tuple, is_ip6, &action,
                                          &match_acl_pos,
diff --git a/src/plugins/acl/exported_types.h b/src/plugins/acl/exported_types.h
new file mode 100644 (file)
index 0000000..cdd1a16
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2018 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef included_acl_exported_types_h
+#define included_acl_exported_types_h
+
+/* 
+ * The overlay struct matching an internal type. Contents/size may change. 
+ * During the compile of the ACL plugin it is checked to have the same size
+ * as the internal structure.
+ */
+
+typedef struct {
+  u64 opaque[6];
+} fa_5tuple_opaque_t;
+
+/*
+ * Use to check if a given acl# exists.
+ */
+
+typedef u8 (*acl_plugin_acl_exists_fn_t) (u32 acl_index);
+
+/*
+ * If you are using ACL plugin, get this unique ID first,
+ * so you can identify yourself when creating the lookup contexts.
+ */
+
+typedef u32 (*acl_plugin_register_user_module_fn_t) (char *caller_module_string, char *val1_label, char *val2_label);
+
+
+/*
+ * Allocate a new lookup context index.
+ * Supply the id assigned to your module during registration,
+ * and two values of your choice identifying instances
+ * of use within your module. They are useful for debugging.
+ */
+
+typedef int (*acl_plugin_get_lookup_context_index_fn_t) (u32 acl_user_id, u32 val1, u32 val2);
+
+/*
+ * Release the lookup context index and destroy
+ * any asssociated data structures.
+ */
+
+typedef void (*acl_plugin_put_lookup_context_index_fn_t) (u32 lc_index);
+
+/*
+ * Prepare the sequential vector of ACL#s to lookup within a given context.
+ * Any existing list will be overwritten. acl_list is a vector.
+ */
+
+typedef int (*acl_plugin_set_acl_vec_for_context_fn_t) (u32 lc_index, u32 *acl_list);
+
+typedef void (*acl_plugin_fill_5tuple_fn_t) (u32 lc_index, vlib_buffer_t * b0, int is_ip6, int is_input,
+                                int is_l2_path, fa_5tuple_opaque_t * p5tuple_pkt);
+
+typedef int (*acl_plugin_match_5tuple_fn_t) (u32 lc_index,
+                                           fa_5tuple_opaque_t * pkt_5tuple,
+                                           int is_ip6, u8 * r_action,
+                                           u32 * r_acl_pos_p,
+                                           u32 * r_acl_match_p,
+                                           u32 * r_rule_match_p,
+                                           u32 * trace_bitmap);
+
+
+#define foreach_acl_plugin_exported_method_name \
+_(acl_exists)                          \
+_(register_user_module)                \
+_(get_lookup_context_index)            \
+_(put_lookup_context_index)            \
+_(set_acl_vec_for_context)             \
+_(fill_5tuple)                         \
+_(match_5tuple)                        
+
+#define _(name) acl_plugin_ ## name ## _fn_t name;
+typedef struct {
+  void *p_acl_main; /* a local copy of a pointer to acl_main */
+  foreach_acl_plugin_exported_method_name
+} acl_plugin_methods_t;
+#undef _
+
+/*
+ * An internally used function to fill in the ACL plugin vtable.
+ * The users should call this one:
+ * static inline clib_error_t * acl_plugin_exports_init (acl_plugin_methods_t *m);
+ */
+
+typedef clib_error_t * (*acl_plugin_methods_vtable_init_fn_t) (acl_plugin_methods_t *m);
+
+#endif
+
index 102922c..e41dd0a 100644 (file)
@@ -5,6 +5,8 @@
 #include <vppinfra/bihash_16_8.h>
 #include <vppinfra/bihash_40_8.h>
 
+#include <plugins/acl/exported_types.h>
+
 // #define FA_NODE_VERBOSE_DEBUG 3
 
 #define TCP_FLAG_FIN    0x01
@@ -77,11 +79,6 @@ typedef union {
   };
 } fa_5tuple_t;
 
-typedef struct {
-  u8 opaque[sizeof(fa_5tuple_t)];
-} fa_5tuple_opaque_t;
-
-
 typedef struct {
   fa_5tuple_t info; /* (5+1)*8 = 48 bytes */
   u64 last_active_time;   /* +8 bytes = 56 */
@@ -139,6 +136,8 @@ CT_ASSERT_EQUAL(fa_session_t_size_is_128, sizeof(fa_session_t), 128);
 
 /* Session ID MUST be the same as u64 */
 CT_ASSERT_EQUAL(fa_full_session_id_size_is_64, sizeof(fa_full_session_id_t), sizeof(u64));
+
+CT_ASSERT_EQUAL(fa_5tuple_opaque_t_must_match_5tuple, sizeof(fa_5tuple_opaque_t), sizeof(fa_5tuple_t));
 #undef CT_ASSERT_EQUAL
 
 #define FA_SESSION_BOGUS_INDEX ~0
index 4af9847..e92642a 100644 (file)
 
 #include <plugins/acl/acl.h>
 #include <plugins/acl/fa_node.h>
-#include <plugins/acl/public_inlines.h>
 #include <vlib/unix/plugin.h>
+#include <plugins/acl/public_inlines.h>
 #include "hash_lookup.h"
 #include "elog_acl_trace.h"
 
 /* check if a given ACL exists */
-u8 acl_plugin_acl_exists (u32 acl_index);
+static 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 u32 get_acl_user_id(acl_main_t *am, char *user_module_name, char *val1_label, char *val2_label)
 {
@@ -64,7 +74,7 @@ static int acl_lc_index_valid(acl_main_t *am, u32 lc_index)
  * so you can identify yourself when creating the lookup contexts.
  */
 
-u32 acl_plugin_register_user_module (char *user_module_name, char *val1_label, char *val2_label)
+static u32 acl_plugin_register_user_module (char *user_module_name, char *val1_label, char *val2_label)
 {
   acl_main_t *am = &acl_main;
   void *oldheap = acl_plugin_set_heap();
@@ -81,7 +91,7 @@ u32 acl_plugin_register_user_module (char *user_module_name, char *val1_label, c
  * If >= 0 - context id. If < 0 - error code.
  */
 
-int acl_plugin_get_lookup_context_index (u32 acl_user_id, u32 val1, u32 val2)
+static int acl_plugin_get_lookup_context_index (u32 acl_user_id, u32 val1, u32 val2)
 {
   acl_main_t *am = &acl_main;
   acl_lookup_context_t *acontext;
@@ -171,7 +181,7 @@ unapply_acl_vec(u32 lc_index, u32 *acls)
  * Release the lookup context index and destroy
  * any asssociated data structures.
  */
-void acl_plugin_put_lookup_context_index (u32 lc_index)
+static void acl_plugin_put_lookup_context_index (u32 lc_index)
 {
   acl_main_t *am = &acl_main;
 
@@ -199,7 +209,7 @@ void acl_plugin_put_lookup_context_index (u32 lc_index)
  * Prepare the sequential vector of ACL#s to lookup within a given context.
  * Any existing list will be overwritten. acl_list is a vector.
  */
-int acl_plugin_set_acl_vec_for_context (u32 lc_index, u32 *acl_list)
+static int acl_plugin_set_acl_vec_for_context (u32 lc_index, u32 *acl_list)
 {
   int rv = 0;
   uword *seen_acl_bitmap = 0;
@@ -274,13 +284,13 @@ void acl_plugin_lookup_context_notify_acl_change(u32 acl_num)
 
 /* Fill the 5-tuple from the packet */
 
-void acl_plugin_fill_5tuple (u32 lc_index, vlib_buffer_t * b0, int is_ip6, int is_input,
+static void acl_plugin_fill_5tuple (u32 lc_index, vlib_buffer_t * b0, int is_ip6, int is_input,
                                 int is_l2_path, fa_5tuple_opaque_t * p5tuple_pkt)
 {
-  acl_plugin_fill_5tuple_inline(lc_index, b0, is_ip6, is_input, is_l2_path, p5tuple_pkt);
+  acl_plugin_fill_5tuple_inline(&acl_main, lc_index, b0, is_ip6, is_input, is_l2_path, p5tuple_pkt);
 }
 
-int acl_plugin_match_5tuple (u32 lc_index,
+static int acl_plugin_match_5tuple (u32 lc_index,
                                            fa_5tuple_opaque_t * pkt_5tuple,
                                            int is_ip6, u8 * r_action,
                                            u32 * r_acl_pos_p,
@@ -288,7 +298,7 @@ int acl_plugin_match_5tuple (u32 lc_index,
                                            u32 * r_rule_match_p,
                                            u32 * trace_bitmap)
 {
-  return acl_plugin_match_5tuple_inline (lc_index, pkt_5tuple, is_ip6, r_action, r_acl_pos_p, r_acl_match_p, r_rule_match_p, trace_bitmap);
+  return acl_plugin_match_5tuple_inline (&acl_main, lc_index, pkt_5tuple, is_ip6, r_action, r_acl_pos_p, r_acl_match_p, r_rule_match_p, trace_bitmap);
 }
 
 
@@ -341,3 +351,18 @@ acl_plugin_show_lookup_context (u32 lc_index)
     }
   }));
 }
+
+void *
+acl_plugin_get_p_acl_main(void)
+{
+  return &acl_main;
+}
+
+clib_error_t *acl_plugin_methods_vtable_init(acl_plugin_methods_t *m)
+{
+  m->p_acl_main = &acl_main;
+#define _(name) m->name = acl_plugin_ ## name; clib_warning("Setting method " #name " to %p\n", acl_plugin_ ## name);
+  foreach_acl_plugin_exported_method_name
+#undef _
+  return 0;
+}
index b358f64..f7d7abb 100644 (file)
 
 #include <stdint.h>
 
+#include <vlib/unix/plugin.h>
 #include <plugins/acl/acl.h>
 #include <plugins/acl/fa_node.h>
 #include <plugins/acl/hash_lookup_private.h>
 
-
-/* check if a given ACL exists */
-
-#ifdef ACL_PLUGIN_EXTERNAL_EXPORTS
-
-/*
- * Define a pointer to the acl_main which will be filled during the initialization.
- */
-acl_main_t *p_acl_main = 0;
-
-/*
- * If the file is included more than once, the symbol collision will make the problem obvious.
- * If the include is done only once, it is just a lonely null var
- * sitting around.
- */
-void *ERROR_ACL_PLUGIN_EXPORTS_FILE_MUST_BE_INCLUDED_ONLY_IN_ONE_PLACE = 0;
-
-u8 (*acl_plugin_acl_exists) (u32 acl_index);
-#else
-u8 acl_plugin_acl_exists (u32 acl_index);
-#endif
-
-
-/*
- * If you are using ACL plugin, get this unique ID first,
- * so you can identify yourself when creating the lookup contexts.
- */
-
-#ifdef ACL_PLUGIN_EXTERNAL_EXPORTS
-u32 (*acl_plugin_register_user_module) (char *caller_module_string, char *val1_label, char *val2_label);
-#else
-u32 acl_plugin_register_user_module (char *caller_module_string, char *val1_label, char *val2_label);
-#endif
-
-/*
- * Allocate a new lookup context index.
- * Supply the id assigned to your module during registration,
- * and two values of your choice identifying instances
- * of use within your module. They are useful for debugging.
- */
-#ifdef ACL_PLUGIN_EXTERNAL_EXPORTS
-int (*acl_plugin_get_lookup_context_index) (u32 acl_user_id, u32 val1, u32 val2);
-#else
-int acl_plugin_get_lookup_context_index (u32 acl_user_id, u32 val1, u32 val2);
-#endif
-
-/*
- * Release the lookup context index and destroy
- * any asssociated data structures.
- */
-#ifdef ACL_PLUGIN_EXTERNAL_EXPORTS
-void (*acl_plugin_put_lookup_context_index) (u32 lc_index);
-#else
-void acl_plugin_put_lookup_context_index (u32 lc_index);
-#endif
-
-/*
- * Prepare the sequential vector of ACL#s to lookup within a given context.
- * Any existing list will be overwritten. acl_list is a vector.
- */
-#ifdef ACL_PLUGIN_EXTERNAL_EXPORTS
-int (*acl_plugin_set_acl_vec_for_context) (u32 lc_index, u32 *acl_list);
-#else
-int acl_plugin_set_acl_vec_for_context (u32 lc_index, u32 *acl_list);
-#endif
-
-/* Fill the 5-tuple from the packet */
-
-#ifdef ACL_PLUGIN_EXTERNAL_EXPORTS
-void (*acl_plugin_fill_5tuple) (u32 lc_index, vlib_buffer_t * b0, int is_ip6, int is_input,
-                                int is_l2_path, fa_5tuple_opaque_t * p5tuple_pkt);
-#else
-void acl_plugin_fill_5tuple (u32 lc_index, vlib_buffer_t * b0, int is_ip6, int is_input,
-                                int is_l2_path, fa_5tuple_opaque_t * p5tuple_pkt);
-#endif
-
-#ifdef ACL_PLUGIN_DEFINED_BELOW_IN_FILE
-static inline
-void acl_plugin_fill_5tuple_inline (u32 lc_index, vlib_buffer_t * b0, int is_ip6, int is_input,
-                                int is_l2_path, fa_5tuple_opaque_t * p5tuple_pkt) {
-  /* FIXME: normally the inlined version of filling in the 5-tuple. But for now just call the non-inlined version */
-  acl_plugin_fill_5tuple(lc_index, b0, is_ip6, is_input, is_l2_path, p5tuple_pkt);
-}
-#endif
-
-
-#ifdef ACL_PLUGIN_EXTERNAL_EXPORTS
-int (*acl_plugin_match_5tuple) (u32 lc_index,
-                                           fa_5tuple_opaque_t * pkt_5tuple,
-                                           int is_ip6, u8 * r_action,
-                                           u32 * r_acl_pos_p,
-                                           u32 * r_acl_match_p,
-                                           u32 * r_rule_match_p,
-                                           u32 * trace_bitmap);
-#else
-int acl_plugin_match_5tuple (u32 lc_index,
-                                           fa_5tuple_opaque_t * pkt_5tuple,
-                                           int is_ip6, u8 * r_action,
-                                           u32 * r_acl_pos_p,
-                                           u32 * r_acl_match_p,
-                                           u32 * r_rule_match_p,
-                                           u32 * trace_bitmap);
-#endif
-
-#ifdef ACL_PLUGIN_DEFINED_BELOW_IN_FILE
-static inline int
-acl_plugin_match_5tuple_inline (u32 lc_index,
-                                           fa_5tuple_opaque_t * pkt_5tuple,
-                                           int is_ip6, u8 * r_action,
-                                           u32 * r_acl_pos_p,
-                                           u32 * r_acl_match_p,
-                                           u32 * r_rule_match_p,
-                                           u32 * trace_bitmap) {
-  return acl_plugin_match_5tuple(lc_index, pkt_5tuple, is_ip6, r_action, r_acl_pos_p, r_acl_match_p, r_rule_match_p, trace_bitmap);
-}
-#endif
-
-#ifdef ACL_PLUGIN_EXTERNAL_EXPORTS
+#include <plugins/acl/exported_types.h>
 
 #define LOAD_SYMBOL_FROM_PLUGIN_TO(p, s, st)                              \
 ({                                                                        \
@@ -151,22 +35,14 @@ acl_plugin_match_5tuple_inline (u32 lc_index,
 
 #define LOAD_SYMBOL(s) LOAD_SYMBOL_FROM_PLUGIN_TO("acl_plugin.so", s, s)
 
-static inline clib_error_t * acl_plugin_exports_init (void)
-{
-    LOAD_SYMBOL_FROM_PLUGIN_TO("acl_plugin.so", acl_main, p_acl_main);
-    LOAD_SYMBOL(acl_plugin_acl_exists);
-    LOAD_SYMBOL(acl_plugin_register_user_module);
-    LOAD_SYMBOL(acl_plugin_get_lookup_context_index);
-    LOAD_SYMBOL(acl_plugin_put_lookup_context_index);
-    LOAD_SYMBOL(acl_plugin_set_acl_vec_for_context);
-    LOAD_SYMBOL(acl_plugin_fill_5tuple);
-    LOAD_SYMBOL(acl_plugin_match_5tuple);
-    return 0;
-}
-
-#endif
 
+static inline clib_error_t * acl_plugin_exports_init (acl_plugin_methods_t *m)
+{
+    acl_plugin_methods_vtable_init_fn_t mvi;
 
+    LOAD_SYMBOL_FROM_PLUGIN_TO("acl_plugin.so", acl_plugin_methods_vtable_init, mvi);
+    return (mvi(m));
+}
 
 always_inline void *
 get_ptr_to_offset (vlib_buffer_t * b0, int offset)
@@ -367,7 +243,7 @@ acl_fill_5tuple (acl_main_t * am, u32 sw_if_index0, vlib_buffer_t * b0, int is_i
 }
 
 always_inline void
-acl_plugin_fill_5tuple_inline (u32 lc_index, vlib_buffer_t * b0, int is_ip6,
+acl_plugin_fill_5tuple_inline (void *p_acl_main, u32 lc_index, vlib_buffer_t * b0, int is_ip6,
                 int is_input, int is_l2_path, fa_5tuple_opaque_t * p5tuple_pkt)
 {
   acl_main_t *am = p_acl_main;
@@ -539,7 +415,7 @@ single_acl_match_5tuple (acl_main_t * am, u32 acl_index, fa_5tuple_t * pkt_5tupl
 }
 
 always_inline int
-acl_plugin_single_acl_match_5tuple (u32 acl_index, fa_5tuple_t * pkt_5tuple,
+acl_plugin_single_acl_match_5tuple (void *p_acl_main, u32 acl_index, fa_5tuple_t * pkt_5tuple,
                  int is_ip6, u8 * r_action, u32 * r_acl_match_p,
                  u32 * r_rule_match_p, u32 * trace_bitmap)
 {
@@ -549,7 +425,7 @@ acl_plugin_single_acl_match_5tuple (u32 acl_index, fa_5tuple_t * pkt_5tuple,
 }
 
 always_inline int
-linear_multi_acl_match_5tuple (u32 lc_index, fa_5tuple_t * pkt_5tuple, 
+linear_multi_acl_match_5tuple (void *p_acl_main, u32 lc_index, fa_5tuple_t * pkt_5tuple,
                       int is_ip6, u8 *r_action, u32 *acl_pos_p, u32 * acl_match_p,
                       u32 * rule_match_p, u32 * trace_bitmap)
 {
@@ -702,7 +578,7 @@ multi_acl_match_get_applied_ace_index(acl_main_t *am, fa_5tuple_t *match)
 }
 
 always_inline int
-hash_multi_acl_match_5tuple (u32 lc_index, fa_5tuple_t * pkt_5tuple,
+hash_multi_acl_match_5tuple (void *p_acl_main, u32 lc_index, fa_5tuple_t * pkt_5tuple,
                        int is_ip6, u8 *action, u32 *acl_pos_p, u32 * acl_match_p,
                        u32 * rule_match_p, u32 * trace_bitmap)
 {
@@ -724,7 +600,7 @@ hash_multi_acl_match_5tuple (u32 lc_index, fa_5tuple_t * pkt_5tuple,
 
 
 always_inline int
-acl_plugin_match_5tuple_inline (u32 lc_index,
+acl_plugin_match_5tuple_inline (void *p_acl_main, u32 lc_index,
                                            fa_5tuple_opaque_t * pkt_5tuple,
                                            int is_ip6, u8 * r_action,
                                            u32 * r_acl_pos_p,
@@ -736,10 +612,10 @@ acl_plugin_match_5tuple_inline (u32 lc_index,
   fa_5tuple_t * pkt_5tuple_internal = (fa_5tuple_t *)pkt_5tuple;
   pkt_5tuple_internal->pkt.lc_index = lc_index;
   if (am->use_hash_acl_matching) {
-    return hash_multi_acl_match_5tuple(lc_index, pkt_5tuple_internal, is_ip6, r_action,
+    return hash_multi_acl_match_5tuple(p_acl_main, lc_index, pkt_5tuple_internal, is_ip6, r_action,
                                  r_acl_pos_p, r_acl_match_p, r_rule_match_p, trace_bitmap);
   } else {
-    return linear_multi_acl_match_5tuple(lc_index, pkt_5tuple_internal, is_ip6, r_action,
+    return linear_multi_acl_match_5tuple(p_acl_main, lc_index, pkt_5tuple_internal, is_ip6, r_action,
                                  r_acl_pos_p, r_acl_match_p, r_rule_match_p, trace_bitmap);
   }
 }