return hash;
}
+static inline bool CmpAddrs(const uint32_t addr1[4], const uint32_t addr2[4])
+{
+ return addr1[0] == addr2[0] && addr1[1] == addr2[1] &&
+ addr1[2] == addr2[2] && addr1[3] == addr2[3];
+}
+
+static inline bool CmpAddrsAndPorts(const uint32_t src1[4],
+ const uint32_t dst1[4], Port src_port1, Port dst_port1,
+ const uint32_t src2[4], const uint32_t dst2[4], Port src_port2,
+ Port dst_port2)
+{
+ /* Compare the source and destination addresses. If they are not equal,
+ * compare the first source address with the second destination address,
+ * and vice versa. Likewise for ports. */
+ return (CmpAddrs(src1, src2) && CmpAddrs(dst1, dst2) &&
+ src_port1 == src_port2 && dst_port1 == dst_port2) ||
+ (CmpAddrs(src1, dst2) && CmpAddrs(dst1, src2) &&
+ src_port1 == dst_port2 && dst_port1 == src_port2);
+}
+
+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];
+}
+
/* Since two or more flows can have the same hash key, we need to compare
- * the flow with the current flow key. */
-#define CMP_FLOW(f1,f2) \
- (((CMP_ADDR(&(f1)->src, &(f2)->src) && \
- CMP_ADDR(&(f1)->dst, &(f2)->dst) && \
- CMP_PORT((f1)->sp, (f2)->sp) && CMP_PORT((f1)->dp, (f2)->dp)) || \
- (CMP_ADDR(&(f1)->src, &(f2)->dst) && \
- CMP_ADDR(&(f1)->dst, &(f2)->src) && \
- CMP_PORT((f1)->sp, (f2)->dp) && CMP_PORT((f1)->dp, (f2)->sp))) && \
- (f1)->proto == (f2)->proto && \
- (f1)->recursion_level == (f2)->recursion_level && \
- (f1)->vlan_id[0] == (f2)->vlan_id[0] && \
- (f1)->vlan_id[1] == (f2)->vlan_id[1])
-#define CMP_FLOW_ICMP(f1,f2) \
- (((CMP_ADDR(&(f1)->src, &(f2)->src) && \
- CMP_ADDR(&(f1)->dst, &(f2)->dst) && \
- CMP_PORT((f1)->icmp_s.type, (f2)->icmp_s.type) && CMP_PORT((f1)->icmp_d.type, (f2)->icmp_d.type)) || \
- (CMP_ADDR(&(f1)->src, &(f2)->dst) && \
- CMP_ADDR(&(f1)->dst, &(f2)->src) && \
- CMP_PORT((f1)->icmp_d.type, (f2)->icmp_s.type) && CMP_PORT((f1)->icmp_s.type, (f2)->icmp_d.type))) && \
- (f1)->proto == (f2)->proto && \
- (f1)->recursion_level == (f2)->recursion_level && \
- (f1)->vlan_id[0] == (f2)->vlan_id[0] && \
- (f1)->vlan_id[1] == (f2)->vlan_id[1])
+ * the flow with the current packet or flow key. */
+static inline bool CmpFlowPacket(const Flow *f, const Packet *p)
+{
+ const uint32_t *f_src = f->src.address.address_un_data32;
+ const uint32_t *f_dst = f->dst.address.address_un_data32;
+ 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 &&
+ CmpVlanIds(f->vlan_id, p->vlan_id);
+}
+
+static inline bool CmpFlowKey(const Flow *f, const FlowKey *k)
+{
+ const uint32_t *f_src = f->src.address.address_un_data32;
+ const uint32_t *f_dst = f->dst.address.address_un_data32;
+ 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 &&
+ CmpVlanIds(f->vlan_id, k->vlan_id);
+}
+
+static inline bool CmpAddrsAndICMPTypes(const uint32_t src1[4],
+ const uint32_t dst1[4], uint8_t icmp_s_type1, uint8_t icmp_d_type1,
+ const uint32_t src2[4], const uint32_t dst2[4], uint8_t icmp_s_type2,
+ uint8_t icmp_d_type2)
+{
+ /* Compare the source and destination addresses. If they are not equal,
+ * compare the first source address with the second destination address,
+ * and vice versa. Likewise for icmp types. */
+ return (CmpAddrs(src1, src2) && CmpAddrs(dst1, dst2) &&
+ icmp_s_type1 == icmp_s_type2 && icmp_d_type1 == icmp_d_type2) ||
+ (CmpAddrs(src1, dst2) && CmpAddrs(dst1, src2) &&
+ icmp_s_type1 == icmp_d_type2 && icmp_d_type1 == icmp_s_type2);
+}
+
+static inline bool CmpFlowICMPPacket(const Flow *f, const Packet *p)
+{
+ const uint32_t *f_src = f->src.address.address_un_data32;
+ const uint32_t *f_dst = f->dst.address.address_un_data32;
+ const uint32_t *p_src = p->src.address.address_un_data32;
+ 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 &&
+ CmpVlanIds(f->vlan_id, p->vlan_id);
+}
/**
* \brief See if a ICMP packet belongs to a flow by comparing the embedded
/* no match, fall through */
} else {
/* just treat ICMP as a normal proto for now */
- return CMP_FLOW_ICMP(f, p);
+ return CmpFlowICMPPacket(f, p);
}
return 0;
if (p->proto == IPPROTO_ICMP) {
return FlowCompareICMPv4(f, p);
} else if (p->proto == IPPROTO_TCP) {
- if (CMP_FLOW(f, p) == 0)
+ if (CmpFlowPacket(f, p) == 0)
return 0;
/* if this session is 'reused', we don't return it anymore,
return 1;
} else {
- return CMP_FLOW(f, p);
+ return CmpFlowPacket(f, p);
}
}
{
if ((f->proto != IPPROTO_TCP) && (f->proto != IPPROTO_UDP))
return 0;
- return CMP_FLOW(f, key);
+ return CmpFlowKey(f, key);
}
/** \brief Get or create a Flow using a FlowKey