|
|
|
@ -103,7 +103,7 @@ static DetectEngineThreadCtx *DetectEngineThreadCtxInitForReload(
|
|
|
|
|
|
|
|
|
|
static uint8_t DetectEngineCtxLoadConf(DetectEngineCtx *);
|
|
|
|
|
|
|
|
|
|
static DetectEngineMasterCtx g_master_de_ctx = { SCMUTEX_INITIALIZER, 0, NULL, NULL, };
|
|
|
|
|
static DetectEngineMasterCtx g_master_de_ctx = { SCMUTEX_INITIALIZER, 0, NULL, NULL, TENANT_SELECTOR_UNKNOWN, NULL,};
|
|
|
|
|
|
|
|
|
|
static DetectEngineThreadCtx *DetectEngineThreadCtxInitForMT(ThreadVars *tv);
|
|
|
|
|
|
|
|
|
@ -1474,6 +1474,11 @@ TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
|
|
|
|
|
det_ctx->mt_det_ctxs = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (det_ctx->tenant_array != NULL) {
|
|
|
|
|
SCFree(det_ctx->tenant_array);
|
|
|
|
|
det_ctx->tenant_array = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef PROFILING
|
|
|
|
|
SCProfilingRuleThreadCleanup(det_ctx);
|
|
|
|
|
SCProfilingKeywordThreadCleanup(det_ctx);
|
|
|
|
@ -1683,7 +1688,66 @@ void DetectEngineMultiTenantSetup(void)
|
|
|
|
|
master->multi_tenant_enabled ? "enabled" : "disabled");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t DetectEngineTentantGetIdFromPcap(DetectEngineThreadCtx *det_ctx, const Packet *p)
|
|
|
|
|
uint32_t DetectEngineTentantGetIdFromVlanId(const void *ctx, const Packet *p)
|
|
|
|
|
{
|
|
|
|
|
const DetectEngineThreadCtx *det_ctx = ctx;
|
|
|
|
|
uint32_t x = 0;
|
|
|
|
|
uint32_t vlan_id = 0;
|
|
|
|
|
|
|
|
|
|
if (p->vlan_idx == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
vlan_id = p->vlan_id[0];
|
|
|
|
|
|
|
|
|
|
if (det_ctx == NULL || det_ctx->tenant_array == NULL || det_ctx->tenant_array_size == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* not very efficient, but for now we're targeting only limited amounts.
|
|
|
|
|
* Can use hash/tree approach later. */
|
|
|
|
|
for (x = 0; x < det_ctx->tenant_array_size; x++) {
|
|
|
|
|
if (det_ctx->tenant_array[x].traffic_id == vlan_id)
|
|
|
|
|
return det_ctx->tenant_array[x].tenant_id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int DetectEngineTentantRegisterSelector(enum DetectEngineTenantSelectors selector,
|
|
|
|
|
uint32_t tenant_id, uint32_t traffic_id)
|
|
|
|
|
{
|
|
|
|
|
DetectEngineMasterCtx *master = &g_master_de_ctx;
|
|
|
|
|
SCMutexLock(&master->lock);
|
|
|
|
|
|
|
|
|
|
if (!(master->tenant_selector == TENANT_SELECTOR_UNKNOWN || master->tenant_selector == selector)) {
|
|
|
|
|
SCLogInfo("conflicting selector already set");
|
|
|
|
|
SCMutexUnlock(&master->lock);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DetectEngineTenantMapping *map = SCCalloc(1, sizeof(*map));
|
|
|
|
|
if (map == NULL) {
|
|
|
|
|
SCLogInfo("memory fail");
|
|
|
|
|
SCMutexUnlock(&master->lock);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
map->traffic_id = traffic_id;
|
|
|
|
|
map->tenant_id = tenant_id;
|
|
|
|
|
|
|
|
|
|
map->next = master->tenant_mapping_list;
|
|
|
|
|
master->tenant_mapping_list = map;
|
|
|
|
|
|
|
|
|
|
master->tenant_selector = selector;
|
|
|
|
|
|
|
|
|
|
SCMutexUnlock(&master->lock);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int DetectEngineTentantRegisterVlanId(uint32_t tenant_id, uint16_t vlan_id)
|
|
|
|
|
{
|
|
|
|
|
return DetectEngineTentantRegisterSelector(TENANT_SELECTOR_VLAN, tenant_id, (uint32_t)vlan_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t DetectEngineTentantGetIdFromPcap(const void *ctx, const Packet *p)
|
|
|
|
|
{
|
|
|
|
|
return p->pcap_v.tenant_id;
|
|
|
|
|
}
|
|
|
|
@ -1910,8 +1974,12 @@ int DetectEngineReload(const char *filename)
|
|
|
|
|
static DetectEngineThreadCtx *DetectEngineThreadCtxInitForMT(ThreadVars *tv)
|
|
|
|
|
{
|
|
|
|
|
DetectEngineMasterCtx *master = &g_master_de_ctx;
|
|
|
|
|
DetectEngineTenantMapping *map_array = NULL;
|
|
|
|
|
uint32_t map_array_size = 0;
|
|
|
|
|
uint32_t map_cnt = 0;
|
|
|
|
|
int max_tenant_id = 0;
|
|
|
|
|
DetectEngineCtx *list = master->list;
|
|
|
|
|
|
|
|
|
|
while (list) {
|
|
|
|
|
if (list->tenant_id > max_tenant_id)
|
|
|
|
|
max_tenant_id = list->tenant_id;
|
|
|
|
@ -1926,6 +1994,32 @@ static DetectEngineThreadCtx *DetectEngineThreadCtxInitForMT(ThreadVars *tv)
|
|
|
|
|
|
|
|
|
|
max_tenant_id++;
|
|
|
|
|
|
|
|
|
|
DetectEngineTenantMapping *map = master->tenant_mapping_list;
|
|
|
|
|
while (map) {
|
|
|
|
|
map_cnt++;
|
|
|
|
|
map = map->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (map_cnt > 0) {
|
|
|
|
|
map_array_size = map_cnt + 1;
|
|
|
|
|
|
|
|
|
|
map_array = SCCalloc(map_array_size, sizeof(*map_array));
|
|
|
|
|
if (map_array == NULL)
|
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
|
|
/* fill the array */
|
|
|
|
|
map_cnt = 0;
|
|
|
|
|
map = master->tenant_mapping_list;
|
|
|
|
|
while (map) {
|
|
|
|
|
BUG_ON(map_cnt > map_array_size);
|
|
|
|
|
map_array[map_cnt].traffic_id = map->traffic_id;
|
|
|
|
|
map_array[map_cnt].tenant_id = map->tenant_id;
|
|
|
|
|
map_cnt++;
|
|
|
|
|
map = map->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DetectEngineThreadCtx **tenant_det_ctxs = SCCalloc(max_tenant_id, sizeof(DetectEngineThreadCtx *));
|
|
|
|
|
BUG_ON(tenant_det_ctxs == NULL);
|
|
|
|
|
|
|
|
|
@ -1947,6 +2041,23 @@ static DetectEngineThreadCtx *DetectEngineThreadCtxInitForMT(ThreadVars *tv)
|
|
|
|
|
det_ctx->mt_det_ctxs = tenant_det_ctxs;
|
|
|
|
|
det_ctx->mt_det_ctxs_cnt = max_tenant_id;
|
|
|
|
|
|
|
|
|
|
det_ctx->tenant_array = map_array;
|
|
|
|
|
det_ctx->tenant_array_size = map_array_size;
|
|
|
|
|
|
|
|
|
|
switch (master->tenant_selector) {
|
|
|
|
|
case TENANT_SELECTOR_UNKNOWN:
|
|
|
|
|
SCLogDebug("TENANT_SELECTOR_UNKNOWN");
|
|
|
|
|
break;
|
|
|
|
|
case TENANT_SELECTOR_VLAN:
|
|
|
|
|
det_ctx->TenantGetId = DetectEngineTentantGetIdFromVlanId;
|
|
|
|
|
SCLogDebug("TENANT_SELECTOR_VLAN");
|
|
|
|
|
break;
|
|
|
|
|
case TENANT_SELECTOR_DIRECT:
|
|
|
|
|
det_ctx->TenantGetId = DetectEngineTentantGetIdFromPcap;
|
|
|
|
|
SCLogDebug("TENANT_SELECTOR_DIRECT");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return det_ctx;
|
|
|
|
|
error:
|
|
|
|
|
return NULL;
|
|
|
|
@ -1957,6 +2068,12 @@ int DetectEngineMTApply(void)
|
|
|
|
|
DetectEngineMasterCtx *master = &g_master_de_ctx;
|
|
|
|
|
SCMutexLock(&master->lock);
|
|
|
|
|
|
|
|
|
|
if (master->tenant_selector == TENANT_SELECTOR_UNKNOWN) {
|
|
|
|
|
SCLogInfo("error, no tenant selector");
|
|
|
|
|
SCMutexUnlock(&master->lock);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DetectEngineCtx *minimal_de_ctx = NULL;
|
|
|
|
|
/* if we have no tenants, we need a minimal on */
|
|
|
|
|
if (master->list == NULL) {
|
|
|
|
|