multi-detect: initial selectors for tenants

The Detection Thread has the TenantGetId pointer which allows it
to select a tenant id based on the packet.
pull/1608/head
Victor Julien 10 years ago
parent 0ff6d3dcfd
commit 1893c5edb1

@ -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) {

@ -86,9 +86,6 @@ int DetectEngineReloadIsStart(void);
void DetectEngineReloadSetDone(void);
int DetectEngineReloadIsDone(void);
/* TODO move elsewhere? */
uint32_t DetectEngineTentantGetIdFromPcap(DetectEngineThreadCtx *, const Packet *p);
/**
* \brief Registers an app inspection engine.
*

@ -1977,13 +1977,14 @@ TmEcode Detect(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQue
}
DetectEngineCtx *de_ctx = det_ctx->de_ctx;
if (de_ctx == NULL) {
if (det_ctx->TenantGetId != NULL) {
if (det_ctx->mt_det_ctxs == 0) {
printf("ERROR: Detect has no detection engine ctx\n");
goto error;
}
uint32_t tenant_id = DetectEngineTentantGetIdFromPcap(det_ctx, p);
uint32_t tenant_id = det_ctx->TenantGetId(det_ctx, p);
if (tenant_id > 0 && tenant_id < det_ctx->mt_det_ctxs_cnt) {
det_ctx = det_ctx->mt_det_ctxs[tenant_id];
BUG_ON(det_ctx == NULL);

@ -769,6 +769,11 @@ typedef struct DetectEngineThreadCtx_ {
uint32_t mt_det_ctxs_cnt;
struct DetectEngineThreadCtx_ **mt_det_ctxs;
struct DetectEngineTenantMapping_ *tenant_array;
uint32_t tenant_array_size;
uint32_t (*TenantGetId)(const void *, const Packet *p);
/* detection engine variables */
/** offset into the payload of the last match by:
@ -1044,6 +1049,22 @@ typedef struct SigGroupHead_ {
* deal with both cases */
#define SIGMATCH_OPTIONAL_OPT (1 << 5)
enum DetectEngineTenantSelectors
{
TENANT_SELECTOR_UNKNOWN = 0, /**< not set */
TENANT_SELECTOR_DIRECT, /**< method provides direct tenant id */
TENANT_SELECTOR_VLAN, /**< map vlan to tenant id */
};
typedef struct DetectEngineTenantMapping_ {
uint32_t tenant_id;
/* traffic id that maps to the tenant id */
uint32_t traffic_id;
struct DetectEngineTenantMapping_ *next;
} DetectEngineTenantMapping;
typedef struct DetectEngineMasterCtx_ {
SCMutex lock;
@ -1058,6 +1079,13 @@ typedef struct DetectEngineMasterCtx_ {
* still be referenced by det_ctx's. Freed as soon as all references are
* gone. */
DetectEngineCtx *free_list;
enum DetectEngineTenantSelectors tenant_selector;
/** list of tenant mappings. Updated under lock. Used to generate lookup
* structures. */
DetectEngineTenantMapping *tenant_mapping_list;
} DetectEngineMasterCtx;
/** \brief Signature loader statistics */

Loading…
Cancel
Save