]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Prefetch the next signature pointer
authorKen Steele <ken@tilera.com>
Mon, 6 Oct 2014 14:00:36 +0000 (10:00 -0400)
committerVictor Julien <victor@inliniac.net>
Thu, 15 Jan 2015 10:52:03 +0000 (11:52 +0100)
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.

src/detect.c

index 430986aea78fb2bbfe189a724a61b0d40806a8c9..ae5c7b0e7ac31fd8a0770729c5b99401974926df 100644 (file)
@@ -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);