Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/flowbit prefilter/v26 #12662

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/detect-engine-build.c
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ static JsonBuilder *RulesGroupPrintSghStats(const DetectEngineCtx *de_ctx, const
any5_cnt++;
}

prefilter_cnt += (s->init_data->prefilter_sm != 0);
prefilter_cnt += (s->init_data->prefilter_sm != NULL);
if (s->init_data->mpm_sm == NULL) {
nonmpm_cnt++;

Expand Down
117 changes: 117 additions & 0 deletions src/detect-engine-prefilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,35 @@ void DetectRunPrefilterTx(DetectEngineThreadCtx *det_ctx,
}
}

/** \brief invoke post-rule match "prefilter" engines
*
* Invoke prefilter engines that depend on a rule match to run.
* e.g. the flowbits:set prefilter that adds sids that depend on
* a flowbit "set" to the match array.
*/
void PrefilterPostRuleMatch(
DetectEngineThreadCtx *det_ctx, const SigGroupHead *sgh, Packet *p, Flow *f)
{
SCLogDebug("post-rule-match engines %p", sgh->post_rule_match_engines);
if (sgh->post_rule_match_engines) {
PrefilterEngine *engine = sgh->post_rule_match_engines;
do {
SCLogDebug("running post-rule-match engine");
PREFILTER_PROFILING_START(det_ctx);
engine->cb.PrefilterPostRule(det_ctx, engine->pectx, p, f);
PREFILTER_PROFILING_END(det_ctx, engine->gid);

if (engine->is_last)
break;
engine++;
} while (1);

if (det_ctx->pmq.rule_id_array_cnt > 1) {
QuickSortSigIntId(det_ctx->pmq.rule_id_array, det_ctx->pmq.rule_id_array_cnt);
}
}
}

void Prefilter(DetectEngineThreadCtx *det_ctx, const SigGroupHead *sgh, Packet *p,
const uint8_t flags, const SignatureMask mask)
{
Expand Down Expand Up @@ -342,6 +371,39 @@ int PrefilterAppendFrameEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
return 0;
}

int PrefilterAppendPostRuleEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
void (*PrefilterPostRuleFunc)(
DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, Flow *f),
void *pectx, void (*FreeFunc)(void *pectx), const char *name)
{
if (sgh == NULL || PrefilterPostRuleFunc == NULL || pectx == NULL)
return -1;

PrefilterEngineList *e = SCMallocAligned(sizeof(*e), CLS);
if (e == NULL)
return -1;
memset(e, 0x00, sizeof(*e));
e->PrefilterPostRule = PrefilterPostRuleFunc;
e->pectx = pectx;
e->Free = FreeFunc;

if (sgh->init->post_rule_match_engines == NULL) {
sgh->init->post_rule_match_engines = e;
} else {
PrefilterEngineList *t = sgh->init->post_rule_match_engines;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this list expected to be more than a few items? If so, would a list/queue that allows tail adds be more efficient?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently just one I think.

while (t->next != NULL) {
t = t->next;
}

t->next = e;
e->id = t->id + 1;
}

e->name = name;
e->gid = PrefilterStoreGetId(de_ctx, e->name, e->Free);
return 0;
}

static void PrefilterFreeEngineList(PrefilterEngineList *e)
{
if (e->Free && e->pectx) {
Expand Down Expand Up @@ -396,6 +458,10 @@ void PrefilterCleanupRuleGroup(const DetectEngineCtx *de_ctx, SigGroupHead *sgh)
PrefilterFreeEngines(de_ctx, sgh->frame_engines);
sgh->frame_engines = NULL;
}
if (sgh->post_rule_match_engines) {
PrefilterFreeEngines(de_ctx, sgh->post_rule_match_engines);
sgh->post_rule_match_engines = NULL;
}
}

static int PrefilterSetupRuleGroupSortHelper(const void *a, const void *b)
Expand Down Expand Up @@ -589,6 +655,30 @@ void PrefilterSetupRuleGroup(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
e++;
}
}
if (sgh->init->post_rule_match_engines != NULL) {
uint32_t cnt = 0;
for (el = sgh->init->post_rule_match_engines; el != NULL; el = el->next) {
cnt++;
}
sgh->post_rule_match_engines = SCMallocAligned(cnt * sizeof(PrefilterEngine), CLS);
if (sgh->post_rule_match_engines == NULL) {
return;
}
memset(sgh->post_rule_match_engines, 0x00, (cnt * sizeof(PrefilterEngine)));

uint16_t local_id = 0;
PrefilterEngine *e = sgh->post_rule_match_engines;
for (el = sgh->init->post_rule_match_engines; el != NULL; el = el->next) {
e->local_id = local_id++;
e->cb.PrefilterPostRule = el->PrefilterPostRule;
e->pectx = el->pectx;
el->pectx = NULL; // e now owns the ctx
e->gid = el->gid;
e->is_last = (el->next == NULL);
e++;
}
SCLogDebug("sgh %p max local_id %u", sgh, local_id);
}
}

/* hash table for assigning a unique id to each engine type. */
Expand Down Expand Up @@ -889,3 +979,30 @@ int PrefilterGenericMpmPktRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, M
}
return r;
}

#define QUEUE_STEP 16

void PostRuleMatchWorkQueueAppend(
DetectEngineThreadCtx *det_ctx, const Signature *s, const int type, const uint32_t value)
{
if (det_ctx->post_rule_work_queue.q == NULL) {
det_ctx->post_rule_work_queue.q =
SCCalloc(1, sizeof(PostRuleMatchWorkQueueItem) * QUEUE_STEP);
BUG_ON(det_ctx->post_rule_work_queue.q == NULL);
det_ctx->post_rule_work_queue.size = QUEUE_STEP;
} else if (det_ctx->post_rule_work_queue.len == det_ctx->post_rule_work_queue.size) {
void *ptr = SCRealloc(
det_ctx->post_rule_work_queue.q, (det_ctx->post_rule_work_queue.size + QUEUE_STEP) *
sizeof(PostRuleMatchWorkQueueItem));
BUG_ON(ptr == NULL);
det_ctx->post_rule_work_queue.q = ptr;
det_ctx->post_rule_work_queue.size += QUEUE_STEP;
}
det_ctx->post_rule_work_queue.q[det_ctx->post_rule_work_queue.len].sm_type = type;
det_ctx->post_rule_work_queue.q[det_ctx->post_rule_work_queue.len].value = value;
#ifdef DEBUG
det_ctx->post_rule_work_queue.q[det_ctx->post_rule_work_queue.len].id = s->num;
#endif
det_ctx->post_rule_work_queue.len++;
SCLogDebug("det_ctx->post_rule_work_queue.len %u", det_ctx->post_rule_work_queue.len);
}
13 changes: 12 additions & 1 deletion src/detect-engine-prefilter.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2016 Open Information Security Foundation
/* Copyright (C) 2016-2020 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
Expand Down Expand Up @@ -52,6 +52,10 @@ void Prefilter(DetectEngineThreadCtx *, const SigGroupHead *, Packet *p, const u

int PrefilterAppendEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh, PrefilterPktFn PrefilterFunc,
SignatureMask mask, void *pectx, void (*FreeFunc)(void *pectx), const char *name);

void PrefilterPostRuleMatch(
DetectEngineThreadCtx *det_ctx, const SigGroupHead *sgh, Packet *p, Flow *f);

int PrefilterAppendPayloadEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
PrefilterPktFn PrefilterFunc, void *pectx, void (*FreeFunc)(void *pectx), const char *name);
int PrefilterAppendTxEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
Expand All @@ -60,6 +64,10 @@ int PrefilterAppendTxEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
int PrefilterAppendFrameEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
PrefilterFrameFn PrefilterFrameFunc, AppProto alproto, uint8_t frame_type, void *pectx,
void (*FreeFunc)(void *pectx), const char *name);
int PrefilterAppendPostRuleEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
void (*PrefilterPostRuleFunc)(
DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, Flow *f),
void *pectx, void (*FreeFunc)(void *pectx), const char *name);

void DetectRunPrefilterTx(DetectEngineThreadCtx *det_ctx,
const SigGroupHead *sgh,
Expand Down Expand Up @@ -91,4 +99,7 @@ int PrefilterMultiGenericMpmRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
int PrefilterGenericMpmPktRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx,
const DetectBufferMpmRegistry *mpm_reg, int list_id);

void PostRuleMatchWorkQueueAppend(
DetectEngineThreadCtx *det_ctx, const Signature *s, const int type, const uint32_t value);

#endif
1 change: 1 addition & 0 deletions src/detect-engine-siggroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ void SigGroupHeadInitDataFree(SigGroupHeadInitData *sghid)
PrefilterFreeEnginesList(sghid->pkt_engines);
PrefilterFreeEnginesList(sghid->payload_engines);
PrefilterFreeEnginesList(sghid->frame_engines);
PrefilterFreeEnginesList(sghid->post_rule_match_engines);

SCFree(sghid);
}
Expand Down
3 changes: 3 additions & 0 deletions src/detect-engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -3564,6 +3564,9 @@ static void DetectEngineThreadCtxFree(DetectEngineThreadCtx *det_ctx)

AlertQueueFree(det_ctx);

if (det_ctx->post_rule_work_queue.q)
SCFree(det_ctx->post_rule_work_queue.q);

if (det_ctx->byte_values != NULL)
SCFree(det_ctx->byte_values);

Expand Down
Loading
Loading