]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
flow: record the flow hash for use as the output flow id 1954/head
authorJason Ish <ish@unx.ca>
Thu, 10 Mar 2016 20:32:06 +0000 (14:32 -0600)
committerVictor Julien <victor@inliniac.net>
Mon, 21 Mar 2016 15:33:19 +0000 (16:33 +0100)
Provides a consistent hash for a flow, as well as a better
distribution than using a memory address.

src/flow-hash.c
src/flow.h
src/output-json.c

index 9ddb3713c47c67816c2bb60be2081dd9f226c9b1..c17e6e4f0973360eb3de8e352ac675d2d5f834c1 100644 (file)
@@ -218,9 +218,9 @@ typedef struct FlowHashKey6_ {
  *
  *  For ICMP we only consider UNREACHABLE errors atm.
  */
-static inline uint32_t FlowGetKey(const Packet *p)
+static inline uint32_t FlowGetHash(const Packet *p)
 {
-    uint32_t key;
+    uint32_t hash = 0;
 
     if (p->ip4h != NULL) {
         if (p->tcph != NULL || p->udph != NULL) {
@@ -244,8 +244,7 @@ static inline uint32_t FlowGetKey(const Packet *p)
             fhk.vlan_id[0] = p->vlan_id[0];
             fhk.vlan_id[1] = p->vlan_id[1];
 
-            uint32_t hash = hashword(fhk.u32, 5, flow_config.hash_rand);
-            key = hash % flow_config.hash_size;
+            hash = hashword(fhk.u32, 5, flow_config.hash_rand);
 
         } else if (ICMPV4_DEST_UNREACH_IS_VALID(p)) {
             uint32_t psrc = IPV4_GET_RAW_IPSRC_U32(ICMPV4_GET_EMB_IPV4(p));
@@ -270,8 +269,7 @@ static inline uint32_t FlowGetKey(const Packet *p)
             fhk.vlan_id[0] = p->vlan_id[0];
             fhk.vlan_id[1] = p->vlan_id[1];
 
-            uint32_t hash = hashword(fhk.u32, 5, flow_config.hash_rand);
-            key = hash % flow_config.hash_size;
+            hash = hashword(fhk.u32, 5, flow_config.hash_rand);
 
         } else {
             FlowHashKey4 fhk;
@@ -289,8 +287,7 @@ static inline uint32_t FlowGetKey(const Packet *p)
             fhk.vlan_id[0] = p->vlan_id[0];
             fhk.vlan_id[1] = p->vlan_id[1];
 
-            uint32_t hash = hashword(fhk.u32, 5, flow_config.hash_rand);
-            key = hash % flow_config.hash_size;
+            hash = hashword(fhk.u32, 5, flow_config.hash_rand);
         }
     } else if (p->ip6h != NULL) {
         FlowHashKey6 fhk;
@@ -325,12 +322,10 @@ static inline uint32_t FlowGetKey(const Packet *p)
         fhk.vlan_id[0] = p->vlan_id[0];
         fhk.vlan_id[1] = p->vlan_id[1];
 
-        uint32_t hash = hashword(fhk.u32, 11, flow_config.hash_rand);
-        key = hash % flow_config.hash_size;
-    } else
-        key = 0;
+        hash = hashword(fhk.u32, 11, flow_config.hash_rand);
+    }
 
-    return key;
+    return hash;
 }
 
 /* Since two or more flows can have the same hash key, we need to compare
@@ -523,9 +518,9 @@ Flow *FlowGetFlowFromHashByPacket(const Packet *p)
     Flow *f = NULL;
 
     /* get the key to our bucket */
-    uint32_t key = FlowGetKey(p);
+    uint32_t hash = FlowGetHash(p);
     /* get our hash bucket and lock it */
-    FlowBucket *fb = &flow_hash[key];
+    FlowBucket *fb = &flow_hash[hash % flow_config.hash_size];
     FBLOCK_LOCK(fb);
 
     SCLogDebug("fb %p fb->head %p", fb, fb->head);
@@ -544,6 +539,7 @@ Flow *FlowGetFlowFromHashByPacket(const Packet *p)
 
         /* got one, now lock, initialize and return */
         FlowInit(f, p);
+        f->flow_hash = hash;
         f->fb = fb;
         /* update the last seen timestamp of this flow */
         COPY_TIMESTAMP(&p->ts,&f->lastts);
@@ -567,9 +563,9 @@ Flow *FlowLookupFlowFromHash(const Packet *p)
     Flow *f = NULL;
 
     /* get the key to our bucket */
-    uint32_t key = FlowGetKey(p);
+    uint32_t hash = FlowGetHash(p);
     /* get our hash bucket and lock it */
-    FlowBucket *fb = &flow_hash[key];
+    FlowBucket *fb = &flow_hash[hash  % flow_config.hash_size];
     FBLOCK_LOCK(fb);
 
     SCLogDebug("fb %p fb->head %p", fb, fb->head);
@@ -656,9 +652,9 @@ Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p
     FlowHashCountInit;
 
     /* get the key to our bucket */
-    uint32_t key = FlowGetKey(p);
+    uint32_t hash = FlowGetHash(p);
     /* get our hash bucket and lock it */
-    FlowBucket *fb = &flow_hash[key];
+    FlowBucket *fb = &flow_hash[hash  % flow_config.hash_size];
     FBLOCK_LOCK(fb);
 
     SCLogDebug("fb %p fb->head %p", fb, fb->head);
@@ -680,6 +676,7 @@ Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p
 
         /* got one, now lock, initialize and return */
         FlowInit(f, p);
+        f->flow_hash = hash;
         f->fb = fb;
 
         /* update the last seen timestamp of this flow */
@@ -718,6 +715,7 @@ Flow *FlowGetFlowFromHash(ThreadVars *tv, DecodeThreadVars *dtv, const Packet *p
 
                 /* initialize and return */
                 FlowInit(f, p);
+                f->flow_hash = hash;
                 f->fb = fb;
 
                 /* update the last seen timestamp of this flow */
index eab737760943bc58550271fb489432350c7cee76..5953b55fcfaec4747c040a974b8964f183cf87fa 100644 (file)
@@ -314,6 +314,14 @@ typedef struct Flow_
     uint8_t recursion_level;
     uint16_t vlan_id[2];
 
+    /** flow hash - the flow hash before hash table size mod. */
+    uint32_t flow_hash;
+
+    /* time stamp of last update (last packet). Set/updated under the
+     * flow and flow hash row locks, safe to read under either the
+     * flow lock or flow hash row lock. */
+    struct timeval lastts;
+
     /* end of flow "header" */
 
     SC_ATOMIC_DECLARE(FlowStateType, flow_state);
@@ -338,11 +346,6 @@ typedef struct Flow_
 
     uint32_t flags;
 
-    /* time stamp of last update (last packet). Set/updated under the
-     * flow and flow hash row locks, safe to read under either the
-     * flow lock or flow hash row lock. */
-    struct timeval lastts;
-
 #ifdef FLOWLOCK_RWLOCK
     SCRWLock r;
 #elif defined FLOWLOCK_MUTEX
index 658ac473d700f927ad8c3218396230b5ac75880e..bcc47840530f8f7936a599dd89a8cd8db2e03949 100644 (file)
@@ -167,12 +167,7 @@ void CreateJSONFlowId(json_t *js, const Flow *f)
 {
     if (f == NULL)
         return;
-#if __WORDSIZE == 64
-    uint64_t addr = (uint64_t)f;
-#else
-    uint32_t addr = (uint32_t)f;
-#endif
-    json_object_set_new(js, "flow_id", json_integer(addr));
+    json_object_set_new(js, "flow_id", json_integer(f->flow_hash));
 }
 
 json_t *CreateJSONHeader(const Packet *p, int direction_sensitive,