crypto: make configurable crypto engines 45/42445/8
authorNicolas PLANEL <[email protected]>
Fri, 28 Feb 2025 18:59:14 +0000 (19:59 +0100)
committerDamjan Marion <[email protected]>
Fri, 4 Apr 2025 15:02:44 +0000 (15:02 +0000)
Add a configuration sections crypto-engines, it works like plugins syntax :

The following configuration will load and register only openssl engine

'''
crypto-engines {
        default {disable}
        openssl {enable}
}
'''

And this one will load all engines except openssl

'''
crypto-engines {
        default {enable}
        openssl {disable}
}
'''

Type: feature
Change-Id: Ia637db93b497d0c4333704f3c024e85de3941791
Signed-off-by: Nicolas PLANEL <[email protected]>
Signed-off-by: Nicolas PLANEL <[email protected]>
Signed-off-by: Nicolas PLANEL <[email protected]>
src/vnet/CMakeLists.txt
src/vnet/crypto/config.c [new file with mode: 0644]
src/vnet/crypto/crypto.c
src/vnet/crypto/crypto.h

index 9e7734e..5c9c5cc 100644 (file)
@@ -522,6 +522,7 @@ list(APPEND VNET_API_FILES bfd/bfd.api)
 
 list(APPEND VNET_SOURCES
   crypto/cli.c
+  crypto/config.c
   crypto/crypto.c
   crypto/format.c
   crypto/main.c
diff --git a/src/vnet/crypto/config.c b/src/vnet/crypto/config.c
new file mode 100644 (file)
index 0000000..09f39b3
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * config.c: crypto engines configuration
+ *
+ * Copyright (c) 2025 Cisco and/or its affiliates.
+ * SPDX-License-Identifier: Apache-2.0
+ * https://spdx.org/licenses/Apache-2.0.html
+ */
+
+#include <vlib/vlib.h>
+#include <vnet/crypto/crypto.h>
+
+static clib_error_t *
+config_one_crypto (vlib_main_t *vm, char *name, unformat_input_t *input)
+{
+  vnet_crypto_main_t *cm = &crypto_main;
+  vnet_crypto_config_t *pc;
+  clib_error_t *error = 0;
+  uword *p;
+  int is_enable = 0;
+  int is_disable = 0;
+
+  if (cm->config_index_by_name == 0)
+    cm->config_index_by_name = hash_create_string (0, sizeof (uword));
+
+  p = hash_get_mem (cm->config_index_by_name, name);
+  if (p)
+    {
+      error = clib_error_return (0, "crypto '%s' already configured", name);
+      goto done;
+    }
+
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (input, "enable"))
+       is_enable = 1;
+      else if (unformat (input, "disable"))
+       is_disable = 1;
+      else
+       {
+         error = clib_error_return (0, "unknown input '%U'",
+                                    format_unformat_error, input);
+         goto done;
+       }
+    }
+
+  if (is_enable && is_disable)
+    {
+      error = clib_error_return (0,
+                                "please specify either enable or disable"
+                                " for crypto '%s'",
+                                name);
+      goto done;
+    }
+
+  vec_add2 (cm->configs, pc, 1);
+  pc->is_enabled = is_enable;
+  pc->is_disabled = is_disable;
+  pc->name = vec_dup (name);
+  hash_set_mem (cm->config_index_by_name, pc->name, pc - cm->configs);
+
+done:
+  return error;
+}
+
+static clib_error_t *
+crypto_engines_config (vlib_main_t *vm, unformat_input_t *input)
+{
+  vnet_crypto_main_t *cm = &crypto_main;
+  clib_error_t *error = 0;
+
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+    {
+      unformat_input_t sub_input;
+      u8 *s = 0;
+      if (unformat (input, "default %U", unformat_vlib_cli_sub_input,
+                   &sub_input))
+       {
+         cm->default_disabled = unformat (&sub_input, "disable") ? 1 : 0;
+         unformat_free (&sub_input);
+       }
+      else if (unformat (input, "%s %U", &s, unformat_vlib_cli_sub_input,
+                        &sub_input))
+       {
+         error = config_one_crypto (vm, (char *) s, &sub_input);
+         vec_free (s);
+         unformat_free (&sub_input);
+         if (error)
+           goto done;
+       }
+      else
+       {
+         error = clib_error_return (0, "unknown input '%U'",
+                                    format_unformat_error, input);
+         {
+           vec_free (s);
+           goto done;
+         }
+       }
+    }
+
+done:
+  return error;
+}
+
+VLIB_EARLY_CONFIG_FUNCTION (crypto_engines_config, "crypto-engines");
index d1a6a6b..765dc49 100644 (file)
@@ -18,6 +18,8 @@ VLIB_REGISTER_LOG_CLASS (crypto_main_log, static) = {
 
 #define log_debug(f, ...)                                                     \
   vlib_log (VLIB_LOG_LEVEL_DEBUG, crypto_main_log.class, f, ##__VA_ARGS__)
+#define log_notice(f, ...)                                                    \
+  vlib_log (VLIB_LOG_LEVEL_NOTICE, crypto_main_log.class, f, ##__VA_ARGS__)
 #define log_err(f, ...)                                                       \
   vlib_log (VLIB_LOG_LEVEL_ERR, crypto_main_log.class, f, ##__VA_ARGS__)
 
@@ -564,11 +566,14 @@ static void
 vnet_crypto_load_engines (vlib_main_t *vm)
 {
   vlib_thread_main_t *tm = vlib_get_thread_main ();
+  vnet_crypto_main_t *cm = &crypto_main;
+  vnet_crypto_config_t *pc;
   u8 *path;
   char *p;
   u32 path_len;
   struct dirent *entry;
   DIR *dp;
+  uword *config_index;
 
   path = os_get_exec_path ();
   log_debug ("exec path is %s", path);
@@ -623,6 +628,31 @@ vnet_crypto_load_engines (vlib_main_t *vm)
              continue;
            }
 
+         /* follow crypto-engines config section directive */
+         config_index = hash_get_mem (cm->config_index_by_name, r->name);
+         if (config_index)
+           {
+             pc = vec_elt_at_index (cm->configs, config_index[0]);
+             if (pc->is_disabled)
+               {
+                 log_notice ("crypto disabled: %s", r->name);
+                 dlclose (handle);
+                 continue;
+               }
+             if (cm->default_disabled && pc->is_enabled == 0)
+               {
+                 log_notice ("crypto disabled (default): %s", r->name);
+                 dlclose (handle);
+                 continue;
+               }
+           }
+         else if (cm->default_disabled)
+           {
+             log_notice ("crypto disabled (default): %s", r->name);
+             dlclose (handle);
+             continue;
+           }
+
          if (r->per_thread_data_sz)
            {
              u64 sz =
index 0a02128..c80987e 100644 (file)
@@ -418,6 +418,13 @@ typedef struct
   void *handlers[VNET_CRYPTO_HANDLER_N_TYPES];
 } vnet_crypto_op_data_t;
 
+typedef struct
+{
+  char *name;
+  u8 is_disabled;
+  u8 is_enabled;
+} vnet_crypto_config_t;
+
 typedef struct
 {
   vnet_crypto_key_t **keys;
@@ -426,11 +433,15 @@ typedef struct
   vnet_crypto_thread_t *threads;
   vnet_crypto_frame_dequeue_t **dequeue_handlers;
   vnet_crypto_engine_t *engines;
+  /* configs and hash by name */
+  vnet_crypto_config_t *configs;
+  uword *config_index_by_name;
   uword *engine_index_by_name;
   uword *alg_index_by_name;
   vnet_crypto_async_next_node_t *next_nodes;
   vnet_crypto_alg_data_t algs[VNET_CRYPTO_N_ALGS];
   vnet_crypto_op_data_t opt_data[VNET_CRYPTO_N_OP_IDS];
+  u8 default_disabled;
 } vnet_crypto_main_t;
 
 extern vnet_crypto_main_t crypto_main;