Prefetch the next signature pointer

Read one signature pointer ahead to prefetch the value.
Use a variable, sflags, for s->flags, since it is used many times and the
compiles doesn't know that the signatures structure doesn't change, so it
will reload s->flags.
pull/1295/head
Ken Steele 11 years ago committed by Victor Julien
parent fa51118dfe
commit 1c76fa50b1

@ -1190,10 +1190,10 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
#ifdef PROFILING
int smatch = 0; /* signature match: 1, no match: 0 */
#endif
uint32_t idx;
uint8_t flags = 0; /* flow/state flags */
StreamMsg *smsg = NULL;
Signature *s = NULL;
Signature *next_s = NULL;
SigMatch *sm = NULL;
uint16_t alversion = 0;
int reset_de_state = 0;
@ -1405,22 +1405,37 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
DetectPrefilterMergeSort(de_ctx, det_ctx, det_ctx->sgh);
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_PREFILTER);
SCLogDebug("match array count %d", det_ctx->match_array_cnt);
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_RULES);
/* inspect the sigs against the packet */
for (idx = 0; idx < det_ctx->match_array_cnt; idx++) {
/* Prefetch the next signature. */
SigIntId match_cnt = det_ctx->match_array_cnt;
Signature **match_array = det_ctx->match_array;
uint32_t sflags, next_sflags = 0;
if (match_cnt) {
next_s = *match_array++;
next_sflags = next_s->flags;
}
while (match_cnt--) {
RULE_PROFILING_START(p);
state_alert = 0;
#ifdef PROFILING
smatch = 0;
#endif
s = det_ctx->match_array[idx];
s = next_s;
sflags = next_sflags;
if (match_cnt) {
next_s = *match_array++;
next_sflags = next_s->flags;
}
uint8_t s_proto_flags = s->proto.flags;
SCLogDebug("inspecting signature id %"PRIu32"", s->id);
/* if the sig has alproto and the session as well they should match */
if (likely(s->flags & SIG_FLAG_APPLAYER)) {
if (likely(sflags & SIG_FLAG_APPLAYER)) {
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != alproto) {
if (s->alproto == ALPROTO_DCERPC) {
if (alproto != ALPROTO_SMB && alproto != ALPROTO_SMB2) {
@ -1434,7 +1449,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
}
}
if (unlikely(s->flags & SIG_FLAG_DSIZE)) {
if (unlikely(sflags & SIG_FLAG_DSIZE)) {
if (likely(p->payload_len < s->dsize_low || p->payload_len > s->dsize_high)) {
SCLogDebug("kicked out as p->payload_len %u, dsize low %u, hi %u",
p->payload_len, s->dsize_low, s->dsize_high);
@ -1443,30 +1458,29 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
}
/* check for a pattern match of the one pattern in this sig. */
if (likely(s->flags & (SIG_FLAG_MPM_PACKET|SIG_FLAG_MPM_STREAM|SIG_FLAG_MPM_APPLAYER)))
if (likely(sflags & (SIG_FLAG_MPM_PACKET|SIG_FLAG_MPM_STREAM|SIG_FLAG_MPM_APPLAYER)))
{
/* filter out sigs that want pattern matches, but
* have no matches */
if (!(det_ctx->pmq.pattern_id_bitarray[(s->mpm_pattern_id_div_8)] & s->mpm_pattern_id_mod_8)) {
if (s->flags & SIG_FLAG_MPM_PACKET) {
if (!(s->flags & SIG_FLAG_MPM_PACKET_NEG)) {
if (sflags & SIG_FLAG_MPM_PACKET) {
if (!(sflags & SIG_FLAG_MPM_PACKET_NEG)) {
goto next;
}
} else if (s->flags & SIG_FLAG_MPM_STREAM) {
} else if (sflags & SIG_FLAG_MPM_STREAM) {
/* filter out sigs that want pattern matches, but
* have no matches */
if (!(s->flags & SIG_FLAG_MPM_STREAM_NEG)) {
if (!(sflags & SIG_FLAG_MPM_STREAM_NEG)) {
goto next;
}
} else if (s->flags & SIG_FLAG_MPM_APPLAYER) {
if (!(s->flags & SIG_FLAG_MPM_APPLAYER_NEG)) {
} else if (sflags & SIG_FLAG_MPM_APPLAYER) {
if (!(sflags & SIG_FLAG_MPM_APPLAYER_NEG)) {
goto next;
}
}
}
}
if (s->flags & SIG_FLAG_STATE_MATCH) {
if (sflags & SIG_FLAG_STATE_MATCH) {
if (det_ctx->de_state_sig_array[s->num] == DE_STATE_MATCH_NO_NEW_STATE)
goto next;
}
@ -1474,7 +1488,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
/* check if this signature has a requirement for flowvars of some type
* and if so, if we actually have any in the flow. If not, the sig
* can't match and we skip it. */
if ((p->flags & PKT_HAS_FLOW) && (s->flags & SIG_FLAG_REQUIRE_FLOWVAR)) {
if ((p->flags & PKT_HAS_FLOW) && (sflags & SIG_FLAG_REQUIRE_FLOWVAR)) {
FLOWLOCK_RDLOCK(pflow);
int m = pflow->flowvar ? 1 : 0;
FLOWLOCK_UNLOCK(pflow);
@ -1487,11 +1501,11 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
}
}
if ((s->proto.flags & DETECT_PROTO_IPV4) && !PKT_IS_IPV4(p)) {
if ((s_proto_flags & DETECT_PROTO_IPV4) && !PKT_IS_IPV4(p)) {
SCLogDebug("ip version didn't match");
goto next;
}
if ((s->proto.flags & DETECT_PROTO_IPV6) && !PKT_IS_IPV6(p)) {
if ((s_proto_flags & DETECT_PROTO_IPV6) && !PKT_IS_IPV6(p)) {
SCLogDebug("ip version didn't match");
goto next;
}
@ -1503,7 +1517,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
/* check the source & dst port in the sig */
if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP || p->proto == IPPROTO_SCTP) {
if (!(s->flags & SIG_FLAG_DP_ANY)) {
if (!(sflags & SIG_FLAG_DP_ANY)) {
if (p->flags & PKT_IS_FRAGMENT)
goto next;
DetectPort *dport = DetectPortLookupGroup(s->dp,p->dp);
@ -1512,7 +1526,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
goto next;
}
}
if (!(s->flags & SIG_FLAG_SP_ANY)) {
if (!(sflags & SIG_FLAG_SP_ANY)) {
if (p->flags & PKT_IS_FRAGMENT)
goto next;
DetectPort *sport = DetectPortLookupGroup(s->sp,p->sp);
@ -1521,13 +1535,13 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
goto next;
}
}
} else if ((s->flags & (SIG_FLAG_DP_ANY|SIG_FLAG_SP_ANY)) != (SIG_FLAG_DP_ANY|SIG_FLAG_SP_ANY)) {
} else if ((sflags & (SIG_FLAG_DP_ANY|SIG_FLAG_SP_ANY)) != (SIG_FLAG_DP_ANY|SIG_FLAG_SP_ANY)) {
SCLogDebug("port-less protocol and sig needs ports");
goto next;
}
/* check the destination address */
if (!(s->flags & SIG_FLAG_DST_ANY)) {
if (!(sflags & SIG_FLAG_DST_ANY)) {
if (PKT_IS_IPV4(p)) {
if (DetectAddressMatchIPv4(s->addr_dst_match4, s->addr_dst_match4_cnt, &p->dst) == 0)
goto next;
@ -1537,7 +1551,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
}
}
/* check the source address */
if (!(s->flags & SIG_FLAG_SRC_ANY)) {
if (!(sflags & SIG_FLAG_SRC_ANY)) {
if (PKT_IS_IPV4(p)) {
if (DetectAddressMatchIPv4(s->addr_src_match4, s->addr_src_match4_cnt, &p->src) == 0)
goto next;
@ -1553,7 +1567,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_PMATCH);
/* if we have stream msgs, inspect against those first,
* but not for a "dsize" signature */
if (s->flags & SIG_FLAG_REQUIRE_STREAM) {
if (sflags & SIG_FLAG_REQUIRE_STREAM) {
char pmatch = 0;
if (smsg != NULL) {
uint8_t pmq_idx = 0;
@ -1561,7 +1575,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
for ( ; smsg_inspect != NULL; smsg_inspect = smsg_inspect->next, pmq_idx++) {
/* filter out sigs that want pattern matches, but
* have no matches */
if ((s->flags & SIG_FLAG_MPM_STREAM) && !(s->flags & SIG_FLAG_MPM_STREAM_NEG) &&
if ((sflags & SIG_FLAG_MPM_STREAM) && !(sflags & SIG_FLAG_MPM_STREAM_NEG) &&
!(det_ctx->smsg_pmq[pmq_idx].pattern_id_bitarray[(s->mpm_pattern_id_div_8)] & s->mpm_pattern_id_mod_8)) {
SCLogDebug("no match in this smsg");
continue;
@ -1587,13 +1601,13 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
if (pmatch == 0) {
SCLogDebug("no match in smsg, fall back to packet payload");
if (!(s->flags & SIG_FLAG_REQUIRE_PACKET)) {
if (!(sflags & SIG_FLAG_REQUIRE_PACKET)) {
if (p->flags & PKT_STREAM_ADD)
goto next;
}
if (sms_runflags & SMS_USED_PM) {
if ((s->flags & SIG_FLAG_MPM_PACKET) && !(s->flags & SIG_FLAG_MPM_PACKET_NEG) &&
if ((sflags & SIG_FLAG_MPM_PACKET) && !(sflags & SIG_FLAG_MPM_PACKET_NEG) &&
!(det_ctx->pmq.pattern_id_bitarray[(s->mpm_pattern_id_div_8)] &
s->mpm_pattern_id_mod_8)) {
goto next;
@ -1609,7 +1623,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
}
} else {
if (sms_runflags & SMS_USED_PM) {
if ((s->flags & SIG_FLAG_MPM_PACKET) && !(s->flags & SIG_FLAG_MPM_PACKET_NEG) &&
if ((sflags & SIG_FLAG_MPM_PACKET) && !(sflags & SIG_FLAG_MPM_PACKET_NEG) &&
!(det_ctx->pmq.pattern_id_bitarray[(s->mpm_pattern_id_div_8)] &
s->mpm_pattern_id_mod_8)) {
goto next;
@ -1651,7 +1665,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
s->sm_lists[DETECT_SM_LIST_HCDMATCH]);
/* consider stateful sig matches */
if (s->flags & SIG_FLAG_STATE_MATCH) {
if (sflags & SIG_FLAG_STATE_MATCH) {
if (has_state == 0) {
SCLogDebug("state matches but no state, we can't match");
goto next;
@ -1683,7 +1697,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
SigMatchSignaturesRunPostMatch(th_v, de_ctx, det_ctx, p, s);
if (!(s->flags & SIG_FLAG_NOALERT)) {
if (!(sflags & SIG_FLAG_NOALERT)) {
/* stateful sigs call PacketAlertAppend from DeStateDetectStartDetection */
if (!state_alert)
PacketAlertAppend(det_ctx, s, p, 0, alert_flags);

Loading…
Cancel
Save