flow hash: Make CMP_FLOW macro an inline function

pull/4016/head
Max Fillinger 6 years ago
parent 7ccf14bc60
commit 38731d30da

@ -274,30 +274,82 @@ uint32_t FlowKeyGetHash(FlowKey *fk)
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
@ -343,7 +395,7 @@ static inline int FlowCompareICMPv4(Flow *f, const Packet *p)
/* 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;
@ -362,7 +414,7 @@ static inline int FlowCompare(Flow *f, const Packet *p)
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,
@ -372,7 +424,7 @@ static inline int FlowCompare(Flow *f, const Packet *p)
return 1;
} else {
return CMP_FLOW(f, p);
return CmpFlowPacket(f, p);
}
}
@ -670,7 +722,7 @@ static inline int FlowCompareKey(Flow *f, FlowKey *key)
{
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

Loading…
Cancel
Save