diff options
author | Damjan Marion <dmarion@me.com> | 2024-12-16 09:06:42 +0000 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2024-12-18 12:34:55 +0000 |
commit | 0cf4eef73a4c1bd2831a4618af50939a2aab01c6 (patch) | |
tree | 809caae588fa1e12556cb180bc4b253120627134 /src/vnet | |
parent | 4358a18dea319b590da5b64e263439136bd8f806 (diff) |
crypto: move crypto engines outside of plugins
This is first step in process of making crypto engine binaries
less dependant on specific VPP version.
Type: improvement
Change-Id: Ib08135688be409049b660e2b2ac435578b63be65
Signed-off-by: Damjan Marion <dmarion@me.com>
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/crypto/crypto.c | 136 | ||||
-rw-r--r-- | src/vnet/crypto/crypto.h | 3 | ||||
-rw-r--r-- | src/vnet/crypto/engine.h | 41 |
3 files changed, 174 insertions, 6 deletions
diff --git a/src/vnet/crypto/crypto.c b/src/vnet/crypto/crypto.c index c8e7ca90c9d..f46e307af89 100644 --- a/src/vnet/crypto/crypto.c +++ b/src/vnet/crypto/crypto.c @@ -16,9 +16,24 @@ #include <stdbool.h> #include <vlib/vlib.h> #include <vnet/crypto/crypto.h> +#include <vnet/crypto/engine.h> +#include <vppinfra/unix.h> +#include <vlib/log.h> +#include <dlfcn.h> +#include <dirent.h> vnet_crypto_main_t crypto_main; +VLIB_REGISTER_LOG_CLASS (crypto_main_log, static) = { + .class_name = "crypto", + .subclass_name = "main", +}; + +#define log_debug(f, ...) \ + vlib_log (VLIB_LOG_LEVEL_DEBUG, crypto_main_log.class, f, ##__VA_ARGS__) +#define log_err(f, ...) \ + vlib_log (VLIB_LOG_LEVEL_ERR, crypto_main_log.class, f, ##__VA_ARGS__) + static_always_inline void crypto_set_op_status (vnet_crypto_op_t * ops[], u32 n_ops, int status) { @@ -451,7 +466,7 @@ vnet_crypto_key_add (vlib_main_t * vm, vnet_crypto_alg_t alg, u8 * data, clib_memcpy (key->data, data, length); vec_foreach (engine, cm->engines) if (engine->key_op_handler) - engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_ADD, index); + engine->key_op_handler (VNET_CRYPTO_KEY_OP_ADD, index); return index; } @@ -464,7 +479,7 @@ vnet_crypto_key_del (vlib_main_t * vm, vnet_crypto_key_index_t index) vec_foreach (engine, cm->engines) if (engine->key_op_handler) - engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_DEL, index); + engine->key_op_handler (VNET_CRYPTO_KEY_OP_DEL, index); if (key->type == VNET_CRYPTO_KEY_TYPE_DATA) { @@ -487,7 +502,7 @@ vnet_crypto_key_update (vlib_main_t *vm, vnet_crypto_key_index_t index) vec_foreach (engine, cm->engines) if (engine->key_op_handler) - engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_MODIFY, index); + engine->key_op_handler (VNET_CRYPTO_KEY_OP_MODIFY, index); } vnet_crypto_async_alg_t @@ -530,7 +545,7 @@ vnet_crypto_key_add_linked (vlib_main_t * vm, vec_foreach (engine, cm->engines) if (engine->key_op_handler) - engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_ADD, index); + engine->key_op_handler (VNET_CRYPTO_KEY_OP_ADD, index); return index; } @@ -716,6 +731,117 @@ vnet_crypto_init_async_data (vnet_crypto_async_alg_t alg, hash_set_mem (cm->async_alg_index_by_name, name, alg); } +static void +vnet_crypto_load_engines (vlib_main_t *vm) +{ + vlib_thread_main_t *tm = vlib_get_thread_main (); + u8 *path; + char *p; + u32 path_len; + struct dirent *entry; + DIR *dp; + + path = os_get_exec_path (); + log_debug ("exec path is %s", path); + + vec_add1 (path, 0); + if ((p = strrchr ((char *) path, '/')) == 0) + goto done; + *p = 0; + if ((p = strrchr ((char *) path, '/')) == 0) + goto done; + + vec_set_len (path, (u8 *) p - path); + + path = format (path, "/" CLIB_LIB_DIR "/vpp_crypto_engines"); + path_len = vec_len (path); + vec_add1 (path, 0); + + log_debug ("libpath is %s", path); + + dp = opendir ((char *) path); + + if (dp) + { + while ((entry = readdir (dp))) + { + void *handle; + + if (entry->d_type != DT_REG) + continue; + + char *ext = strrchr (entry->d_name, '.'); + if (!ext || strncmp (ext, ".so", 3) != 0) + { + log_debug ("skipping %s, not .so", entry->d_name); + } + vec_set_len (path, path_len); + path = format (path, "/%s%c", entry->d_name, 0); + + handle = dlopen ((char *) path, RTLD_LAZY); + if (!handle) + { + log_err ("failed to dlopen %s", path); + continue; + } + + vnet_crypto_engine_registration_t *r = + dlsym (handle, "__vnet_crypto_engine"); + if (!r) + { + log_err ("%s is not a crypto engine", entry->d_name); + dlclose (handle); + continue; + } + + if (r->per_thread_data_sz) + { + u64 sz = + round_pow2 (r->per_thread_data_sz, CLIB_CACHE_LINE_BYTES); + u64 alloc = sz * tm->n_vlib_mains; + r->per_thread_data = + clib_mem_alloc_aligned (alloc, CLIB_CACHE_LINE_BYTES); + clib_memset (r->per_thread_data, 0, alloc); + log_debug ("%s: allocated %u bytes per thread", r->name, sz); + } + + r->num_threads = tm->n_vlib_mains; + + if (r->init_fn) + { + char *rv = r->init_fn (r); + if (rv) + { + log_err ("%s crypto engine init failed: %s", r->name, rv); + if (r->per_thread_data) + clib_mem_free (r->per_thread_data); + dlclose (handle); + continue; + } + log_debug ("%s crypto engine initialized", r->name); + } + u32 eidx = + vnet_crypto_register_engine (vm, r->name, r->prio, r->desc); + log_debug ("%s crypto engine registered with id %u", r->name, eidx); + typeof (r->op_handlers) oh = r->op_handlers; + + while (oh->opt != VNET_CRYPTO_OP_NONE) + { + vnet_crypto_register_ops_handlers (vm, eidx, oh->opt, oh->fn, + oh->cfn); + oh++; + } + + if (r->key_handler) + vnet_crypto_register_key_handler (vm, eidx, r->key_handler); + } + closedir (dp); + } + +done: + vec_free (path); +} + clib_error_t * vnet_crypto_init (vlib_main_t * vm) { @@ -772,6 +898,8 @@ vnet_crypto_init (vlib_main_t * vm) cm->crypto_node_index = vlib_get_node_by_name (vm, (u8 *) "crypto-dispatch")->index; + vnet_crypto_load_engines (vm); + return 0; } diff --git a/src/vnet/crypto/crypto.h b/src/vnet/crypto/crypto.h index 89cf70d19e3..13d08756109 100644 --- a/src/vnet/crypto/crypto.h +++ b/src/vnet/crypto/crypto.h @@ -392,8 +392,7 @@ typedef u32 (vnet_crypto_chained_ops_handler_t) (vlib_main_t * vm, typedef u32 (vnet_crypto_ops_handler_t) (vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops); -typedef void (vnet_crypto_key_handler_t) (vlib_main_t * vm, - vnet_crypto_key_op_t kop, +typedef void (vnet_crypto_key_handler_t) (vnet_crypto_key_op_t kop, vnet_crypto_key_index_t idx); /** async crypto function handlers **/ diff --git a/src/vnet/crypto/engine.h b/src/vnet/crypto/engine.h new file mode 100644 index 00000000000..993befb393a --- /dev/null +++ b/src/vnet/crypto/engine.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright (c) 2024 Cisco Systems, Inc. + */ + +#ifndef included_vnet_crypto_engine_h +#define included_vnet_crypto_engine_h + +#ifndef included_clib_types_h +typedef unsigned int u32; +#endif + +typedef struct +{ + vnet_crypto_op_id_t opt; + vnet_crypto_ops_handler_t *fn; + vnet_crypto_chained_ops_handler_t *cfn; +} vnet_crypto_engine_op_handlers_t; + +struct vnet_crypto_engine_registration; + +typedef char *( + vnet_crypto_engine_init_fn_t) (struct vnet_crypto_engine_registration *); + +typedef struct vnet_crypto_engine_registration +{ + char name[32]; /* backend name */ + char desc[128]; /* backend name */ + int prio; + u32 version; + u32 per_thread_data_sz; + u32 num_threads; + void *per_thread_data; + vnet_crypto_engine_init_fn_t *init_fn; + vnet_crypto_key_handler_t *key_handler; + vnet_crypto_engine_op_handlers_t *op_handlers; +} vnet_crypto_engine_registration_t; + +#define VNET_CRYPTO_ENGINE_REGISTRATION() \ + __clib_export vnet_crypto_engine_registration_t __vnet_crypto_engine + +#endif |