From a6fcbb1ab7c1edd02871dc250bb0e6541e11d5af Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Fri, 23 May 2025 08:58:12 +0200 Subject: [PATCH] flow: factorize duplicated code for hashing --- src/flow-hash.c | 109 ++++++++++++++++++++---------------------------- 1 file changed, 46 insertions(+), 63 deletions(-) diff --git a/src/flow-hash.c b/src/flow-hash.c index 0eafa3cb36..e2bf1a97a4 100644 --- a/src/flow-hash.c +++ b/src/flow-hash.c @@ -114,6 +114,35 @@ typedef struct FlowHashKey6_ { }; } FlowHashKey6; +static inline void FlowHashIp4Fill(FlowHashKey4 *fhk, const Packet *p) +{ + fhk->proto = p->proto; + /* g_recurlvl_mask sets the recursion_level to 0 if + * decoder.recursion-level.use-for-tracking is disabled. + */ + fhk->recur = (uint8_t)p->recursion_level & g_recurlvl_mask; + /* g_livedev_mask sets the livedev ids to 0 if livedev.use-for-tracking + * is disabled. */ + uint16_t devid = p->livedev_id; + fhk->livedev = devid & g_livedev_mask; + /* 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; + fhk->vlan_id[2] = p->vlan_id[2] & g_vlan_mask; +} + +static inline void FlowHashIp6Fill(FlowHashKey6 *fhk, const Packet *p) +{ + fhk->proto = p->proto; + fhk->recur = (uint8_t)p->recursion_level & g_recurlvl_mask; + uint16_t devid = p->livedev_id; + fhk->livedev = devid & g_livedev_mask; + fhk->vlan_id[0] = p->vlan_id[0] & g_vlan_mask; + fhk->vlan_id[1] = p->vlan_id[1] & g_vlan_mask; + fhk->vlan_id[2] = p->vlan_id[2] & g_vlan_mask; +} + uint32_t FlowGetIpPairProtoHash(const Packet *p) { uint32_t hash = 0; @@ -129,17 +158,7 @@ uint32_t FlowGetIpPairProtoHash(const Packet *p) fhk.ports[0] = 0xfedc; fhk.ports[1] = 0xba98; - fhk.proto = (uint8_t)p->proto; - fhk.livedev = p->livedev_id & g_livedev_mask; - /* g_recurlvl_mask sets the recursion_level to 0 if - * decoder.recursion-level.use-for-tracking is disabled. - */ - fhk.recur = (uint8_t)p->recursion_level & g_recurlvl_mask; - /* 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; - fhk.vlan_id[2] = p->vlan_id[2] & g_vlan_mask; + FlowHashIp4Fill(&fhk, p); hash = hashword(fhk.u32, ARRAY_SIZE(fhk.u32), flow_config.hash_rand); } else if (PacketIsIPv6(p)) { @@ -168,12 +187,8 @@ uint32_t FlowGetIpPairProtoHash(const Packet *p) fhk.ports[0] = 0xfedc; fhk.ports[1] = 0xba98; - fhk.proto = (uint8_t)p->proto; - fhk.livedev = p->livedev_id & g_livedev_mask; - fhk.recur = (uint8_t)p->recursion_level & g_recurlvl_mask; - fhk.vlan_id[0] = p->vlan_id[0] & g_vlan_mask; - fhk.vlan_id[1] = p->vlan_id[1] & g_vlan_mask; - fhk.vlan_id[2] = p->vlan_id[2] & g_vlan_mask; + + FlowHashIp6Fill(&fhk, p); hash = hashword(fhk.u32, ARRAY_SIZE(fhk.u32), flow_config.hash_rand); } @@ -209,20 +224,7 @@ static inline uint32_t FlowGetHash(const Packet *p) fhk.ports[1-pi] = p->sp; fhk.ports[pi] = p->dp; - fhk.proto = p->proto; - /* g_recurlvl_mask sets the recursion_level to 0 if - * decoder.recursion-level.use-for-tracking is disabled. - */ - fhk.recur = p->recursion_level & g_recurlvl_mask; - /* g_livedev_mask sets the livedev ids to 0 if livedev.use-for-tracking - * is disabled. */ - uint16_t devid = p->livedev_id; - fhk.livedev = devid & g_livedev_mask; - /* 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; - fhk.vlan_id[2] = p->vlan_id[2] & g_vlan_mask; + FlowHashIp4Fill(&fhk, p); hash = hashword(fhk.u32, ARRAY_SIZE(fhk.u32), flow_config.hash_rand); @@ -239,13 +241,8 @@ static inline uint32_t FlowGetHash(const Packet *p) fhk.ports[1 - pi] = p->l4.vars.icmpv4.emb_sport; fhk.ports[pi] = p->l4.vars.icmpv4.emb_dport; + FlowHashIp4Fill(&fhk, p); fhk.proto = ICMPV4_GET_EMB_PROTO(p); - fhk.recur = p->recursion_level & g_recurlvl_mask; - uint16_t devid = p->livedev_id; - fhk.livedev = devid & g_livedev_mask; - fhk.vlan_id[0] = p->vlan_id[0] & g_vlan_mask; - fhk.vlan_id[1] = p->vlan_id[1] & g_vlan_mask; - fhk.vlan_id[2] = p->vlan_id[2] & g_vlan_mask; hash = hashword(fhk.u32, ARRAY_SIZE(fhk.u32), flow_config.hash_rand); @@ -256,13 +253,7 @@ static inline uint32_t FlowGetHash(const Packet *p) fhk.addrs[ai] = p->dst.addr_data32[0]; fhk.ports[0] = 0xfeed; fhk.ports[1] = 0xbeef; - fhk.proto = p->proto; - fhk.recur = p->recursion_level & g_recurlvl_mask; - uint16_t devid = p->livedev_id; - fhk.livedev = devid & g_livedev_mask; - fhk.vlan_id[0] = p->vlan_id[0] & g_vlan_mask; - fhk.vlan_id[1] = p->vlan_id[1] & g_vlan_mask; - fhk.vlan_id[2] = p->vlan_id[2] & g_vlan_mask; + FlowHashIp4Fill(&fhk, p); hash = hashword(fhk.u32, ARRAY_SIZE(fhk.u32), flow_config.hash_rand); } @@ -291,13 +282,7 @@ static inline uint32_t FlowGetHash(const Packet *p) const int pi = (p->sp > p->dp); fhk.ports[1-pi] = p->sp; fhk.ports[pi] = p->dp; - fhk.proto = p->proto; - fhk.recur = p->recursion_level & g_recurlvl_mask; - uint16_t devid = p->livedev_id; - fhk.livedev = devid & g_livedev_mask; - fhk.vlan_id[0] = p->vlan_id[0] & g_vlan_mask; - fhk.vlan_id[1] = p->vlan_id[1] & g_vlan_mask; - fhk.vlan_id[2] = p->vlan_id[2] & g_vlan_mask; + FlowHashIp6Fill(&fhk, p); hash = hashword(fhk.u32, ARRAY_SIZE(fhk.u32), flow_config.hash_rand); } @@ -410,6 +395,11 @@ static inline bool CmpLiveDevIds(const uint16_t id1, const uint16_t id2) return (((id1 ^ id2) & g_livedev_mask) == 0); } +#define CmpFlowMisc(x, y) \ + (((x)->proto == (y)->proto) && \ + ((x)->recursion_level == (y)->recursion_level || g_recurlvl_mask == 0) && \ + CmpVlanIds((x)->vlan_id, (y)->vlan_id)) + /* Since two or more flows can have the same hash key, we need to compare * the flow with the current packet or flow key. */ static inline bool CmpFlowPacket(const Flow *f, const Packet *p) @@ -419,9 +409,7 @@ static inline bool CmpFlowPacket(const Flow *f, const Packet *p) const uint32_t *p_src = p->src.address.address_un_data32; const uint32_t *p_dst = p->dst.address.address_un_data32; return CmpAddrsAndPorts(f_src, f_dst, f->sp, f->dp, p_src, p_dst, p->sp, p->dp) && - f->proto == p->proto && - (f->recursion_level == p->recursion_level || g_recurlvl_mask == 0) && - CmpVlanIds(f->vlan_id, p->vlan_id) && CmpLiveDevIds(p->livedev_id, f->livedev_id); + CmpFlowMisc(f, p) && CmpLiveDevIds(p->livedev_id, f->livedev_id); } static inline bool CmpFlowKey(const Flow *f, const FlowKey *k) @@ -431,9 +419,7 @@ static inline bool CmpFlowKey(const Flow *f, const FlowKey *k) const uint32_t *k_src = k->src.address.address_un_data32; const uint32_t *k_dst = k->dst.address.address_un_data32; return CmpAddrsAndPorts(f_src, f_dst, f->sp, f->dp, k_src, k_dst, k->sp, k->dp) && - f->proto == k->proto && - (f->recursion_level == k->recursion_level || g_recurlvl_mask == 0) && - CmpVlanIds(f->vlan_id, k->vlan_id) && CmpLiveDevIds(f->livedev_id, k->livedev_id); + CmpFlowMisc(f, k) && CmpLiveDevIds(f->livedev_id, k->livedev_id); } static inline bool CmpAddrsAndICMPTypes(const uint32_t src1[4], @@ -458,9 +444,7 @@ static inline bool CmpFlowICMPPacket(const Flow *f, const Packet *p) const uint32_t *p_dst = p->dst.address.address_un_data32; return CmpAddrsAndICMPTypes(f_src, f_dst, f->icmp_s.type, f->icmp_d.type, p_src, p_dst, p->icmp_s.type, p->icmp_d.type) && - f->proto == p->proto && - (f->recursion_level == p->recursion_level || g_recurlvl_mask == 0) && - CmpVlanIds(f->vlan_id, p->vlan_id) && CmpLiveDevIds(p->livedev_id, f->livedev_id); + CmpFlowMisc(f, p) && CmpLiveDevIds(p->livedev_id, f->livedev_id); } /** @@ -524,9 +508,8 @@ static inline int FlowCompareESP(Flow *f, const Packet *p) const uint32_t *p_src = p->src.address.address_un_data32; const uint32_t *p_dst = p->dst.address.address_un_data32; - return CmpAddrs(f_src, p_src) && CmpAddrs(f_dst, p_dst) && f->proto == p->proto && - (f->recursion_level == p->recursion_level || g_recurlvl_mask == 0) && - CmpVlanIds(f->vlan_id, p->vlan_id) && f->esp.spi == ESP_GET_SPI(PacketGetESP(p)) && + return CmpAddrs(f_src, p_src) && CmpAddrs(f_dst, p_dst) && CmpFlowMisc(f, p) && + f->esp.spi == ESP_GET_SPI(PacketGetESP(p)) && CmpLiveDevIds(p->livedev_id, f->livedev_id); }