-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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/v24 #12132
Feat/flowbit prefilter/v24 #12132
Conversation
In preparation of flowbit prefilter work that needs this info earlier. Track potential prefilter sm's to avoid unnecessary looping during setup.
Allow for more efficient rules that 'prefilter' on flowbits with 'isset' logic. This prefilter is enabled by default, which means that if no mpm is present or no explicit prefilter is used, the flowbits prefilter will be set up for a rule. flowbits 'isset' prefilter For rules that have a 'flowbits:isset,<bit>' statement, a "regular" prefilter facility is created. It means that the rules are removed from the normal match list(s) and added to a prefilter engine that runs prior to the individual rule inspection stage. Implementation: the prefilter is implemented as an RB_TREE of flowbits, with the rule id's they "enable" stored per tree node. The matching logic is walking the list of bits set in the flow and looking each of them up in the RB_TREE, adding the rule ids of each of the matching bits to the list of rule candidates. The 'isset' prefilter has one important corner case, which is that bits can in fact be set during the rule evaluation stage. This is different from all other prefilter engines, that evaluate an immutable state (for the lifetime of the packets inspection). flowbits 'set' post-match prefilter For flowbits 'set' action, special post-match 'prefilter' facilities deal with this corner case. The high level logic is that these track which 'isset' sigs depend on them, and add these dependencies to the candidates list when a 'set' action occurs. This is implemented in a few steps: 1. flowbits 'set' is flagged 2. when 'set' action occurs the flowbit is added to a "post rule match work queue" 3. when the rule evaluation ends, the post-match "prefilter" engine is run on each of the flowbits in the "post rule match work queue" 4. these engines ammend the candidates list with the rule id dependencies for the flowbit 5. the candidates list is sorted to make sure within the execution for that packet the inspection order is maintained Ticket: OISF#2486.
@@ -2523,6 +2523,9 @@ static DetectEngineCtx *DetectEngineCtxInitReal( | |||
goto error; | |||
} | |||
|
|||
// TODO test enable flowbits prefilter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still need to check how we may enable a selection of prefilter engines for keywords, but not all.
src/detect-flowbits.c
Outdated
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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
todo: error handle
return 0; | ||
} | ||
|
||
// TODO misses IPOnly rules. IPOnly flowbit rules are set only though. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tests appear to show this is not an issue
src/detect-flowbits.c
Outdated
|
||
#define BLOCK_SIZE 8 | ||
|
||
static int AddBitIsset(const DetectEngineCtx *de_ctx, struct PrefilterEngineFlowbits *ctx, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
func needs docs and error handling
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also needs cleanup as there is duplication between or and non-or support
return added; | ||
} | ||
|
||
/* TODO shouldn't add sids for which Signature::num is < our num. Is this possible after sorting? */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to see if I can reach this condition in a test
src/detect-flowbits.c
Outdated
if (fb->cmd == DETECT_FLOWBITS_CMD_SET) { | ||
SCLogDebug( | ||
"DETECT_SM_LIST_POSTMATCH: sid %u DETECT_FLOWBITS set %u", s->id, fb->idx); | ||
// else if (fb->cmd == DETECT_FLOWBITS_CMD_TOGGLE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
todo: review 'toggle' support
} | ||
|
||
SCLogDebug("setting up sets/toggles for sid %u", s->id); | ||
if (AddBitSetToggle(de_ctx, &fb_analysis, set_ctx, fb, s) == 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so this builds a post-rule-match state, that looks at which isset flowbits depend on the current "set" flowbit. Need to make this code clearer, and doc it
fb->prefilter = true; // flag the set/toggle to trigger the post-rule match logic | ||
} | ||
|
||
// TODO don't add for sigs that don't have isset in this sgh. Reasoning: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
todo: this is essentially done in AddSids above
src/detect-flowbits.c
Outdated
} | ||
|
||
const DetectFlowbitsData *fb = (DetectFlowbitsData *)s->init_data->prefilter_sm->ctx; | ||
if (fb_analysis.array[fb->idx].toggle_sids_idx || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this uses the per sgh analysis, but maybe we need to check this for all groups?
} | ||
|
||
if (set_ctx == NULL) { | ||
set_ctx = SCCalloc(1, sizeof(*set_ctx)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this "set" post-rule-prefilter state should only be built if there are isset flowbit rules, with prefilter enabled, in the same sgh. Need to review is this is checked correctly.
/* rewrite match_array to include the new additions */ | ||
Signature **m = match_array; | ||
for (uint32_t x = 0; x < match_cnt; x++) { | ||
*m++ = (Signature *)replace[x]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
memcpy?
/* run post match prefilter engines on work queue */ | ||
PrefilterPostRuleMatch(det_ctx, scratch->sgh, p, pflow); | ||
|
||
if (det_ctx->pmq.rule_id_array_cnt > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should probably move this into a helper func
de_ctx->sig_array_len, det_ctx->pmq.rule_id_array_cnt); | ||
const Signature **r = replace; | ||
for (uint32_t x = 0; x < match_cnt; x++) { | ||
*r++ = match_array[x]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
memcpy?
} | ||
/* append the prefilter results, then sort it */ | ||
for (uint32_t x = 0; x < det_ctx->pmq.rule_id_array_cnt; x++) { | ||
// TODO what happens if a tx engine is added? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to look into this
match_cnt++; | ||
} | ||
} | ||
// TODO if sid 12 is added twice, how do we dedup |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will try to add a test for this
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #12132 +/- ##
===========================================
+ Coverage 62.68% 83.01% +20.32%
===========================================
Files 840 909 +69
Lines 153669 258309 +104640
===========================================
+ Hits 96323 214427 +118104
+ Misses 57346 43882 -13464
Flags with carried forward coverage won't be shown. Click here to find out more. |
Information: QA ran without warnings. Pipeline 23430 |
Information: ERROR: QA failed on SURI_TLPR1_alerts_cmp.
Pipeline 23439 |
Information: ERROR: QA failed on SURI_TLPR1_alerts_cmp.
Pipeline 23467 |
f6b294b
to
c036600
Compare
Information: ERROR: QA failed on SURI_TLPR1_alerts_cmp.
Pipeline 23475 |
replaced by #12380 |
Draft for QA/CI & review. Not fully ready yet.
SV_BRANCH=OISF/suricata-verify#2131
https://redmine.openinfosecfoundation.org/issues/2486