diff --git a/python/suricata/sc/suricatasc.py b/python/suricata/sc/suricatasc.py index bc7de375360e..fc07037c3d22 100644 --- a/python/suricata/sc/suricatasc.py +++ b/python/suricata/sc/suricatasc.py @@ -94,6 +94,7 @@ def __init__(self, sck_path, verbose=False): "pcap-last-processed", "pcap-interrupt", "iface-list", + "reload-tenants", ] self.fn_commands = [ "pcap-file", diff --git a/src/detect-engine.c b/src/detect-engine.c index 90296c092721..3810cb0a7af4 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -3986,6 +3986,39 @@ static int DetectLoaderFuncReloadTenant(void *vctx, int loader_id) return 0; } +static int DetectLoaderSetupReloadTenants(const int reload_cnt) +{ + int ret = 0; + DetectEngineMasterCtx *master = &g_master_de_ctx; + SCMutexLock(&master->lock); + + DetectEngineCtx *de_ctx = master->list; + while (de_ctx) { + if (de_ctx->type == DETECT_ENGINE_TYPE_TENANT) { + TenantLoaderCtx *t = SCCalloc(1, sizeof(*t)); + if (t == NULL) { + ret = -1; + goto error; + } + t->tenant_id = de_ctx->tenant_id; + t->reload_cnt = reload_cnt; + int loader_id = de_ctx->loader_id; + + int r = DetectLoaderQueueTask( + loader_id, DetectLoaderFuncReloadTenant, t, DetectLoaderFreeTenant); + if (r < 0) { + ret = -2; + goto error; + } + } + + de_ctx = de_ctx->next; + } +error: + SCMutexUnlock(&master->lock); + return ret; +} + static int DetectLoaderSetupReloadTenant(uint32_t tenant_id, const char *yaml, int reload_cnt) { DetectEngineCtx *old_de_ctx = DetectEngineGetByTenantId(tenant_id); @@ -4042,6 +4075,20 @@ int DetectEngineReloadTenantBlocking(uint32_t tenant_id, const char *yaml, int r return 0; } +/** \brief Reload all tenants and wait for loading to complete + */ +int DetectEngineReloadTenantsBlocking(const int reload_cnt) +{ + int r = DetectLoaderSetupReloadTenants(reload_cnt); + if (r < 0) + return r; + + if (DetectLoadersSync() != 0) + return -1; + + return 0; +} + static int DetectEngineMultiTenantSetupLoadLivedevMappings(const ConfNode *mappings_root_node, bool failure_fatal) { diff --git a/src/detect-engine.h b/src/detect-engine.h index f6b4ba154e10..a1732b16a993 100644 --- a/src/detect-engine.h +++ b/src/detect-engine.h @@ -130,6 +130,7 @@ int DetectEngineReloadIsIdle(void); int DetectEngineLoadTenantBlocking(uint32_t tenant_id, const char *yaml); int DetectEngineReloadTenantBlocking(uint32_t tenant_id, const char *yaml, int reload_cnt); +int DetectEngineReloadTenantsBlocking(const int reload_cnt); int DetectEngineTenantRegisterLivedev(uint32_t tenant_id, int device_id); int DetectEngineTenantRegisterVlanId(uint32_t tenant_id, uint16_t vlan_id); diff --git a/src/runmode-unix-socket.c b/src/runmode-unix-socket.c index 7de884c9279f..e695cb8dfbd6 100644 --- a/src/runmode-unix-socket.c +++ b/src/runmode-unix-socket.c @@ -1124,6 +1124,41 @@ TmEcode UnixSocketReloadTenant(json_t *cmd, json_t* answer, void *data) return TM_ECODE_OK; } +/** + * \brief Command to reload all tenants + * + * \param cmd the content of command Arguments as a json_t object + * \param answer the json_t object that has to be used to answer + * \param data pointer to data defining the context here a PcapCommand:: + */ +TmEcode UnixSocketReloadTenants(json_t *cmd, json_t *answer, void *data) +{ + if (!(DetectEngineMultiTenantEnabled())) { + SCLogInfo("error: multi-tenant support not enabled"); + json_object_set_new(answer, "message", json_string("multi-tenant support not enabled")); + return TM_ECODE_FAILED; + } + + if (DetectEngineReloadTenantsBlocking(reload_cnt) != 0) { + json_object_set_new(answer, "message", json_string("reload tenants failed")); + return TM_ECODE_FAILED; + } + + reload_cnt++; + + /* apply to the running system */ + if (DetectEngineMTApply() < 0) { + json_object_set_new(answer, "message", json_string("couldn't apply settings")); + // TODO cleanup + return TM_ECODE_FAILED; + } + + SCLogNotice("reload-tenants complete"); + + json_object_set_new(answer, "message", json_string("reloading tenants succeeded")); + return TM_ECODE_OK; +} + /** * \brief Command to remove a tenant * diff --git a/src/runmode-unix-socket.h b/src/runmode-unix-socket.h index c2fa84aa3235..af0651f5910b 100644 --- a/src/runmode-unix-socket.h +++ b/src/runmode-unix-socket.h @@ -42,6 +42,7 @@ TmEcode UnixSocketRegisterTenantHandler(json_t *cmd, json_t* answer, void *data) TmEcode UnixSocketUnregisterTenantHandler(json_t *cmd, json_t* answer, void *data); TmEcode UnixSocketRegisterTenant(json_t *cmd, json_t* answer, void *data); TmEcode UnixSocketReloadTenant(json_t *cmd, json_t* answer, void *data); +TmEcode UnixSocketReloadTenants(json_t *cmd, json_t *answer, void *data); TmEcode UnixSocketUnregisterTenant(json_t *cmd, json_t* answer, void *data); TmEcode UnixSocketHostbitAdd(json_t *cmd, json_t* answer, void *data); TmEcode UnixSocketHostbitRemove(json_t *cmd, json_t* answer, void *data); diff --git a/src/unix-manager.c b/src/unix-manager.c index 071bf75a7289..9893553f429e 100644 --- a/src/unix-manager.c +++ b/src/unix-manager.c @@ -1099,6 +1099,7 @@ int UnixManagerInit(void) UnixManagerRegisterCommand("unregister-tenant-handler", UnixSocketUnregisterTenantHandler, &command, UNIX_CMD_TAKE_ARGS); UnixManagerRegisterCommand("register-tenant", UnixSocketRegisterTenant, &command, UNIX_CMD_TAKE_ARGS); UnixManagerRegisterCommand("reload-tenant", UnixSocketReloadTenant, &command, UNIX_CMD_TAKE_ARGS); + UnixManagerRegisterCommand("reload-tenants", UnixSocketReloadTenants, &command, 0); UnixManagerRegisterCommand("unregister-tenant", UnixSocketUnregisterTenant, &command, UNIX_CMD_TAKE_ARGS); UnixManagerRegisterCommand("add-hostbit", UnixSocketHostbitAdd, &command, UNIX_CMD_TAKE_ARGS); UnixManagerRegisterCommand("remove-hostbit", UnixSocketHostbitRemove, &command, UNIX_CMD_TAKE_ARGS);