detect: initial MT lookup logic

In the DetectEngineThreadCtx, store another DetectEngineThreadCtx per
tenant.

Currently it's just a simple array indexed by the tenant id.
pull/1608/head
Victor Julien 10 years ago
parent 147a6d2bfd
commit def2b58725

@ -105,6 +105,8 @@ static uint8_t DetectEngineCtxLoadConf(DetectEngineCtx *);
static DetectEngineMasterCtx g_master_de_ctx = { SCMUTEX_INITIALIZER, NULL, NULL, };
static DetectEngineThreadCtx *DetectEngineThreadCtxInitForMT(ThreadVars *tv);
/* 2 - for each direction */
DetectEngineAppInspectionEngine *app_inspection_engine[FLOW_PROTO_DEFAULT][ALPROTO_MAX][2];
@ -604,7 +606,10 @@ static int DetectEngineReloadThreads(DetectEngineCtx *new_de_ctx)
old_det_ctx[i] = SC_ATOMIC_GET(slots->slot_data);
detect_tvs[i] = tv;
new_det_ctx[i] = DetectEngineThreadCtxInitForReload(tv, new_de_ctx);
if (new_de_ctx != NULL)
new_det_ctx[i] = DetectEngineThreadCtxInitForReload(tv, new_de_ctx);
else
new_det_ctx[i] = DetectEngineThreadCtxInitForMT(tv);
if (new_det_ctx[i] == NULL) {
SCLogError(SC_ERR_LIVE_RULE_SWAP, "Detect engine thread init "
"failure in live rule swap. Let's get out of here");
@ -1450,6 +1455,19 @@ TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
return TM_ECODE_OK;
}
if (det_ctx->mt_det_ctxs != NULL) {
uint32_t x;
for (x = 0; x < det_ctx->mt_det_ctxs_cnt; x++) {
if (det_ctx->mt_det_ctxs[x] == NULL)
continue;
DetectEngineThreadCtxDeinit(tv, det_ctx->mt_det_ctxs[x]);
det_ctx->mt_det_ctxs[x] = NULL;
}
SCFree(det_ctx->mt_det_ctxs);
det_ctx->mt_det_ctxs = NULL;
}
#ifdef PROFILING
SCProfilingRuleThreadCleanup(det_ctx);
SCProfilingKeywordThreadCleanup(det_ctx);
@ -1858,6 +1876,81 @@ int DetectEngineReload(const char *filename)
return 0;
}
/** NOTE: master MUST be locked before calling this */
static DetectEngineThreadCtx *DetectEngineThreadCtxInitForMT(ThreadVars *tv)
{
DetectEngineMasterCtx *master = &g_master_de_ctx;
int max_tenant_id = 0;
DetectEngineCtx *list = master->list;
while (list) {
if (list->tenant_id > max_tenant_id)
max_tenant_id = list->tenant_id;
list = list->next;
}
if (max_tenant_id == 0) {
SCLogInfo("no tenants left");
return NULL;
}
max_tenant_id++;
DetectEngineThreadCtx **tenant_det_ctxs = SCCalloc(max_tenant_id, sizeof(DetectEngineThreadCtx *));
BUG_ON(tenant_det_ctxs == NULL);
list = master->list;
while (list) {
if (list->tenant_id != 0) {
tenant_det_ctxs[list->tenant_id] = DetectEngineThreadCtxInitForReload(tv, list);
if (tenant_det_ctxs[list->tenant_id] == NULL)
goto error;
}
list = list->next;
}
DetectEngineThreadCtx *det_ctx = SCCalloc(1, sizeof(DetectEngineThreadCtx));
if (det_ctx == NULL) {
goto error;
}
det_ctx->mt_det_ctxs = tenant_det_ctxs;
det_ctx->mt_det_ctxs_cnt = max_tenant_id;
return det_ctx;
error:
return NULL;
}
int DetectEngineMTApply(void)
{
DetectEngineMasterCtx *master = &g_master_de_ctx;
SCMutexLock(&master->lock);
DetectEngineCtx *minimal_de_ctx = NULL;
/* if we have no tenants, we need a minimal on */
if (master->list == NULL) {
minimal_de_ctx = master->list = DetectEngineCtxInitMinimal();
SCLogDebug("no tenants, using minimal %p", minimal_de_ctx);
} else if (master->list->next == NULL && master->list->tenant_id == 0) {
minimal_de_ctx = master->list;
SCLogDebug("no tenants, using original %p", minimal_de_ctx);
}
/* update the threads */
SCLogDebug("MT reload starting");
DetectEngineReloadThreads(minimal_de_ctx);
SCLogDebug("MT reload done");
SCMutexUnlock(&master->lock);
/* walk free list, freeing the old_de_ctx */
DetectEnginePruneFreeList();
SCLogDebug("old_de_ctx should have been freed");
return 0;
}
const char *DetectSigmatchListEnumToString(enum DetectSigmatchListEnum type)
{
switch (type) {

@ -77,6 +77,7 @@ DetectEngineCtx *DetectEngineReference(DetectEngineCtx *);
void DetectEngineDeReference(DetectEngineCtx **de_ctx);
int DetectEngineReload(const char *filename);
int DetectEngineEnabled(void);
int DetectEngineMTApply(void);
int DetectEngineReloadStart(void);
int DetectEngineReloadIsStart(void);

@ -1970,16 +1970,27 @@ TmEcode Detect(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQue
goto error;
}
if (SC_ATOMIC_GET(det_ctx->so_far_used_by_detect) == 0) {
(void)SC_ATOMIC_SET(det_ctx->so_far_used_by_detect, 1);
SCLogDebug("Detect Engine using new det_ctx - %p",
det_ctx);
}
DetectEngineCtx *de_ctx = det_ctx->de_ctx;
if (de_ctx == NULL) {
printf("ERROR: Detect has no detection engine ctx\n");
goto error;
}
if (det_ctx->mt_det_ctxs == 0) {
printf("ERROR: Detect has no detection engine ctx\n");
goto error;
}
if (SC_ATOMIC_GET(det_ctx->so_far_used_by_detect) == 0) {
(void)SC_ATOMIC_SET(det_ctx->so_far_used_by_detect, 1);
SCLogDebug("Detect Engine using new det_ctx - %p and de_ctx - %p",
det_ctx, de_ctx);
det_ctx = det_ctx->mt_det_ctxs[1];
BUG_ON(det_ctx == NULL);
de_ctx = det_ctx->de_ctx;
BUG_ON(de_ctx == NULL);
if (SC_ATOMIC_GET(det_ctx->so_far_used_by_detect) == 0) {
(void)SC_ATOMIC_SET(det_ctx->so_far_used_by_detect, 1);
SCLogDebug("MT de_ctx %p det_ctx %p", de_ctx, det_ctx);
}
}
/* see if the packet matches one or more of the sigs */

@ -766,6 +766,9 @@ typedef struct DetectEngineThreadCtx_ {
SigIntId *non_mpm_id_array;
uint32_t non_mpm_id_cnt; // size is cnt * sizeof(uint32_t)
uint32_t mt_det_ctxs_cnt;
struct DetectEngineThreadCtx_ **mt_det_ctxs;
/* detection engine variables */
/** offset into the payload of the last match by:

Loading…
Cancel
Save