]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect: add multi-detect.config-path
authorVictor Julien <vjulien@oisf.net>
Tue, 8 Aug 2023 13:56:12 +0000 (15:56 +0200)
committerVictor Julien <vjulien@oisf.net>
Fri, 11 Aug 2023 05:02:06 +0000 (07:02 +0200)
Add option to specify path from which to load the tenants.

Mostly meant to be used in testing.

doc/userguide/configuration/multi-tenant.rst
src/detect-engine-loader.c
src/detect-engine-loader.h
src/detect-engine.c

index e727facf5d9ec8c50c798aab5f0aa72514cc7c67..dcd7c29affca926eecdba603136fd8206ea1fcd8 100644 (file)
@@ -21,6 +21,7 @@ Settings:
 * `selector`: direct (for unix socket pcap processing, see below), VLAN or device
 * `loaders`: number of `loader` threads, for parallel tenant loading at startup
 * `tenants`: list of tenants
+* `config-path`: path from where the tenant yamls are loaded
 
   * id: tenant id (numeric values only)
   * yaml: separate yaml file with the tenant specific settings
index b216112a3bd060e3e7d705706d00edc7b23eb6dc..5a5e79c09934da593c436da8b36d583c147dff92 100644 (file)
@@ -401,7 +401,7 @@ static int num_loaders = NLOADERS;
 
 /** \param loader -1 for auto select
  *  \retval loader_id or negative in case of error */
-int DetectLoaderQueueTask(int loader_id, LoaderFunc Func, void *func_ctx)
+int DetectLoaderQueueTask(int loader_id, LoaderFunc Func, void *func_ctx, LoaderFreeFunc FreeFunc)
 {
     if (loader_id == -1) {
         loader_id = cur_loader;
@@ -421,6 +421,7 @@ int DetectLoaderQueueTask(int loader_id, LoaderFunc Func, void *func_ctx)
 
     t->Func = Func;
     t->ctx = func_ctx;
+    t->FreeFunc = FreeFunc;
 
     SCMutexLock(&loader->m);
     TAILQ_INSERT_TAIL(&loader->task_list, t, next);
@@ -596,7 +597,7 @@ static TmEcode DetectLoader(ThreadVars *th_v, void *thread_data)
             int r = task->Func(task->ctx, ftd->instance);
             loader->result |= r;
             TAILQ_REMOVE(&loader->task_list, task, next);
-            SCFree(task->ctx);
+            task->FreeFunc(task->ctx);
             SCFree(task);
         }
 
index 6b8aa5cf9e0542343faa807661a41187705157e4..7ffb8c8648a08c8cb4ebf0edaf7db7fc32de4a74 100644 (file)
  * \param loader_id id of the loader that executed the task
  */
 typedef int (*LoaderFunc)(void *ctx, int loader_id);
+typedef void (*LoaderFreeFunc)(void *ctx);
 
 typedef struct DetectLoaderTask_ {
     LoaderFunc Func;
     void *ctx;
+    LoaderFreeFunc FreeFunc;
     TAILQ_ENTRY(DetectLoaderTask_) next;
 } DetectLoaderTask;
 
@@ -46,7 +48,7 @@ typedef struct DetectLoaderControl_ {
     TAILQ_HEAD(, DetectLoaderTask_) task_list;
 } DetectLoaderControl;
 
-int DetectLoaderQueueTask(int loader_id, LoaderFunc Func, void *func_ctx);
+int DetectLoaderQueueTask(int loader_id, LoaderFunc Func, void *func_ctx, LoaderFreeFunc FreeFunc);
 int DetectLoadersSync(void);
 void DetectLoadersInit(void);
 
index 4e75fa13a8d76f19f17f95c7579e26bbb36ea522..251c586bc0610b7b6071b2caaa84c63bb76afcd3 100644 (file)
@@ -3918,9 +3918,18 @@ error:
 typedef struct TenantLoaderCtx_ {
     uint32_t tenant_id;
     int reload_cnt; /**< used by reload */
-    const char *yaml;
+    char *yaml;     /**< heap alloc'd copy of file path for the yaml */
 } TenantLoaderCtx;
 
+static void DetectLoaderFreeTenant(void *ctx)
+{
+    TenantLoaderCtx *t = (TenantLoaderCtx *)ctx;
+    if (t->yaml != NULL) {
+        SCFree(t->yaml);
+    }
+    SCFree(t);
+}
+
 static int DetectLoaderFuncLoadTenant(void *vctx, int loader_id)
 {
     TenantLoaderCtx *ctx = (TenantLoaderCtx *)vctx;
@@ -3939,9 +3948,13 @@ static int DetectLoaderSetupLoadTenant(uint32_t tenant_id, const char *yaml)
         return -ENOMEM;
 
     t->tenant_id = tenant_id;
-    t->yaml = yaml;
+    t->yaml = SCStrdup(yaml);
+    if (t->yaml == NULL) {
+        SCFree(t);
+        return -ENOMEM;
+    }
 
-    return DetectLoaderQueueTask(-1, DetectLoaderFuncLoadTenant, t);
+    return DetectLoaderQueueTask(-1, DetectLoaderFuncLoadTenant, t, DetectLoaderFreeTenant);
 }
 
 static int DetectLoaderFuncReloadTenant(void *vctx, int loader_id)
@@ -3969,12 +3982,17 @@ static int DetectLoaderSetupReloadTenant(uint32_t tenant_id, const char *yaml, i
         return -ENOMEM;
 
     t->tenant_id = tenant_id;
-    t->yaml = yaml;
+    t->yaml = SCStrdup(yaml);
+    if (t->yaml == NULL) {
+        SCFree(t);
+        return -ENOMEM;
+    }
     t->reload_cnt = reload_cnt;
 
     SCLogDebug("loader_id %d", loader_id);
 
-    return DetectLoaderQueueTask(loader_id, DetectLoaderFuncReloadTenant, t);
+    return DetectLoaderQueueTask(
+            loader_id, DetectLoaderFuncReloadTenant, t, DetectLoaderFreeTenant);
 }
 
 /** \brief Load a tenant and wait for loading to complete
@@ -4223,6 +4241,13 @@ int DetectEngineMultiTenantSetup(const bool unix_socket)
         ConfNode *tenant_node = NULL;
 
         if (tenants_root_node != NULL) {
+            const char *path = NULL;
+            ConfNode *path_node = ConfGetNode("multi-detect.config-path");
+            if (path_node) {
+                path = path_node->val;
+                SCLogConfig("tenants config path: %s", path);
+            }
+
             TAILQ_FOREACH(tenant_node, &tenants_root_node->head, next) {
                 ConfNode *id_node = ConfNodeLookupChild(tenant_node, "id");
                 if (id_node == NULL) {
@@ -4243,16 +4268,24 @@ int DetectEngineMultiTenantSetup(const bool unix_socket)
                 }
                 SCLogDebug("tenant id: %u, %s", tenant_id, yaml_node->val);
 
+                char yaml_path[PATH_MAX] = "";
+                if (path) {
+                    PathMerge(yaml_path, PATH_MAX, path, yaml_node->val);
+                } else {
+                    strlcpy(yaml_path, yaml_node->val, sizeof(yaml_path));
+                }
+                SCLogDebug("tenant path: %s", yaml_path);
+
                 /* setup the yaml in this loop so that it's not done by the loader
                  * threads. ConfYamlLoadFileWithPrefix is not thread safe. */
                 char prefix[64];
                 snprintf(prefix, sizeof(prefix), "multi-detect.%u", tenant_id);
-                if (ConfYamlLoadFileWithPrefix(yaml_node->val, prefix) != 0) {
-                    SCLogError("failed to load yaml %s", yaml_node->val);
+                if (ConfYamlLoadFileWithPrefix(yaml_path, prefix) != 0) {
+                    SCLogError("failed to load yaml %s", yaml_path);
                     goto bad_tenant;
                 }
 
-                int r = DetectLoaderSetupLoadTenant(tenant_id, yaml_node->val);
+                int r = DetectLoaderSetupLoadTenant(tenant_id, yaml_path);
                 if (r < 0) {
                     /* error logged already */
                     goto bad_tenant;