Skip to content

Commit

Permalink
detect: add multi-detect.config-path
Browse files Browse the repository at this point in the history
Add option to specify path from which to load the tenants.

Mostly meant to be used in testing.
  • Loading branch information
victorjulien committed Aug 11, 2023
1 parent a4d80bc commit c87803e
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 11 deletions.
1 change: 1 addition & 0 deletions doc/userguide/configuration/multi-tenant.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions src/detect-engine-loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}

Expand Down
4 changes: 3 additions & 1 deletion src/detect-engine-loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@
* \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;

Expand All @@ -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);

Expand Down
49 changes: 41 additions & 8 deletions src/detect-engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -3918,9 +3918,18 @@ static int DetectEngineMultiTenantReloadTenant(uint32_t tenant_id, const char *f
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;
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
Expand Down

0 comments on commit c87803e

Please sign in to comment.