diff --git a/src/flow-hash.c b/src/flow-hash.c index 5afa154304..8492706aff 100644 --- a/src/flow-hash.c +++ b/src/flow-hash.c @@ -135,8 +135,10 @@ static inline uint32_t FlowGetHash(const Packet *p) fhk.proto = (uint16_t)p->proto; fhk.recur = (uint16_t)p->recursion_level; - fhk.vlan_id[0] = p->vlan_id[0]; - fhk.vlan_id[1] = p->vlan_id[1]; + /* g_vlan_mask sets the vlan_ids to 0 if vlan.use-for-tracking + * is disabled. */ + fhk.vlan_id[0] = p->vlan_id[0] & g_vlan_mask; + fhk.vlan_id[1] = p->vlan_id[1] & g_vlan_mask; hash = hashword(fhk.u32, 5, flow_config.hash_rand); @@ -155,8 +157,8 @@ static inline uint32_t FlowGetHash(const Packet *p) fhk.proto = (uint16_t)ICMPV4_GET_EMB_PROTO(p); fhk.recur = (uint16_t)p->recursion_level; - fhk.vlan_id[0] = p->vlan_id[0]; - fhk.vlan_id[1] = p->vlan_id[1]; + fhk.vlan_id[0] = p->vlan_id[0] & g_vlan_mask; + fhk.vlan_id[1] = p->vlan_id[1] & g_vlan_mask; hash = hashword(fhk.u32, 5, flow_config.hash_rand); @@ -169,8 +171,8 @@ static inline uint32_t FlowGetHash(const Packet *p) fhk.ports[1] = 0xbeef; fhk.proto = (uint16_t)p->proto; fhk.recur = (uint16_t)p->recursion_level; - fhk.vlan_id[0] = p->vlan_id[0]; - fhk.vlan_id[1] = p->vlan_id[1]; + fhk.vlan_id[0] = p->vlan_id[0] & g_vlan_mask; + fhk.vlan_id[1] = p->vlan_id[1] & g_vlan_mask; hash = hashword(fhk.u32, 5, flow_config.hash_rand); } @@ -201,8 +203,8 @@ static inline uint32_t FlowGetHash(const Packet *p) fhk.ports[pi] = p->dp; fhk.proto = (uint16_t)p->proto; fhk.recur = (uint16_t)p->recursion_level; - fhk.vlan_id[0] = p->vlan_id[0]; - fhk.vlan_id[1] = p->vlan_id[1]; + fhk.vlan_id[0] = p->vlan_id[0] & g_vlan_mask; + fhk.vlan_id[1] = p->vlan_id[1] & g_vlan_mask; hash = hashword(fhk.u32, 11, flow_config.hash_rand); } @@ -234,8 +236,8 @@ uint32_t FlowKeyGetHash(FlowKey *fk) fhk.proto = (uint16_t)fk->proto; fhk.recur = (uint16_t)fk->recursion_level; - fhk.vlan_id[0] = fk->vlan_id[0]; - fhk.vlan_id[1] = fk->vlan_id[1]; + fhk.vlan_id[0] = fk->vlan_id[0] & g_vlan_mask; + fhk.vlan_id[1] = fk->vlan_id[1] & g_vlan_mask; hash = hashword(fhk.u32, 5, flow_config.hash_rand); } else { @@ -266,8 +268,8 @@ uint32_t FlowKeyGetHash(FlowKey *fk) fhk.ports[pi] = fk->dp; fhk.proto = (uint16_t)fk->proto; fhk.recur = (uint16_t)fk->recursion_level; - fhk.vlan_id[0] = fk->vlan_id[0]; - fhk.vlan_id[1] = fk->vlan_id[1]; + fhk.vlan_id[0] = fk->vlan_id[0] & g_vlan_mask; + fhk.vlan_id[1] = fk->vlan_id[1] & g_vlan_mask; hash = hashword(fhk.u32, 11, flow_config.hash_rand); } @@ -296,7 +298,8 @@ static inline bool CmpAddrsAndPorts(const uint32_t src1[4], static inline bool CmpVlanIds(const uint16_t vlan_id1[2], const uint16_t vlan_id2[2]) { - return vlan_id1[0] == vlan_id2[0] && vlan_id1[1] == vlan_id2[1]; + return ((vlan_id1[0] ^ vlan_id2[0]) & g_vlan_mask) == 0 && + ((vlan_id1[1] ^ vlan_id2[1]) & g_vlan_mask) == 0; } /* Since two or more flows can have the same hash key, we need to compare diff --git a/src/suricata.c b/src/suricata.c index f970d82463..49eadee5e5 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -230,6 +230,10 @@ int g_disable_randomness = 0; int g_disable_randomness = 1; #endif +/** determine (without branching) if we include the vlan_ids when hashing or + * comparing flows */ +uint16_t g_vlan_mask = 0xffff; + /** Suricata instance */ SCInstance suricata; @@ -2967,6 +2971,12 @@ int main(int argc, char **argv) exit(EXIT_SUCCESS); } + int vlan_tracking = 1; + if (ConfGetBool("vlan.use-for-tracking", &vlan_tracking) == 1 && !vlan_tracking) { + /* Ignore vlan_ids when comparing flows. */ + g_vlan_mask = 0x0000; + } + SetupUserMode(&suricata); /* Since our config is now loaded we can finish configurating the diff --git a/src/suricata.h b/src/suricata.h index bbd2a3aafa..1b0e72a99e 100644 --- a/src/suricata.h +++ b/src/suricata.h @@ -174,6 +174,7 @@ void GlobalsInitPreConfig(void); extern volatile uint8_t suricata_ctl_flags; extern int g_disable_randomness; +extern uint16_t g_vlan_mask; #include #define u8_tolower(c) tolower((uint8_t)(c))