wc->masks.regs[idx] = mask;
}
+/* Calculates the 5-tuple hash from the given flow. */
+uint32_t
+miniflow_hash_5tuple(const struct miniflow *flow, uint32_t basis)
+{
+ uint32_t hash = 0;
+
+ if (!flow) {
+ return 0;
+ }
+
+ hash = mhash_add(basis,
+ miniflow_get_u32(flow, offsetof(struct flow, nw_src)));
+ hash = mhash_add(hash,
+ miniflow_get_u32(flow, offsetof(struct flow, nw_dst)));
+ hash = mhash_add(hash,
+ miniflow_get_u32(flow, offsetof(struct flow, tp_src)));
+ hash = mhash_add(hash,
+ miniflow_get_u8(flow, offsetof(struct flow, nw_proto)));
+
+ return mhash_finish(hash, 13);
+}
+
+BUILD_ASSERT_DECL(offsetof(struct flow, tp_src) + 2
+ == offsetof(struct flow, tp_dst) &&
+ offsetof(struct flow, tp_src) / 4
+ == offsetof(struct flow, tp_dst) / 4);
+
/* Calculates the 5-tuple hash from the given flow. */
uint32_t
flow_hash_5tuple(const struct flow *flow, uint32_t basis)
{
+ const uint32_t *flow_u32 = (const uint32_t *)flow;
uint32_t hash = 0;
if (!flow) {
hash = mhash_add(basis, (OVS_FORCE uint32_t) flow->nw_src);
hash = mhash_add(hash, (OVS_FORCE uint32_t) flow->nw_dst);
- hash = mhash_add(hash, ((OVS_FORCE uint32_t) flow->tp_src << 16)
- | (OVS_FORCE uint32_t) flow->tp_dst);
+ hash = mhash_add(hash, flow_u32[offsetof(struct flow, tp_src) / 4]);
hash = mhash_add(hash, flow->nw_proto);
return mhash_finish(hash, 13);
flow_union_with_miniflow(dst, src);
}
-static const uint32_t *
-miniflow_get__(const struct miniflow *flow, unsigned int u32_ofs)
-{
- if (!(flow->map & (UINT64_C(1) << u32_ofs))) {
- static const uint32_t zero = 0;
- return &zero;
- }
- return flow->values +
- count_1bits(flow->map & ((UINT64_C(1) << u32_ofs) - 1));
-}
-
/* Returns the uint32_t that would be at byte offset '4 * u32_ofs' if 'flow'
* were expanded into a "struct flow". */
-uint32_t
+static uint32_t
miniflow_get(const struct miniflow *flow, unsigned int u32_ofs)
{
- return *miniflow_get__(flow, u32_ofs);
-}
-
-/* Returns the ovs_be16 that would be at byte offset 'u8_ofs' if 'flow' were
- * expanded into a "struct flow". */
-static ovs_be16
-miniflow_get_be16(const struct miniflow *flow, unsigned int u8_ofs)
-{
- const uint32_t *u32p = miniflow_get__(flow, u8_ofs / 4);
- const ovs_be16 *be16p = (const ovs_be16 *) u32p;
- return be16p[u8_ofs % 4 != 0];
-}
-
-/* Returns the VID within the vlan_tci member of the "struct flow" represented
- * by 'flow'. */
-uint16_t
-miniflow_get_vid(const struct miniflow *flow)
-{
- ovs_be16 tci = miniflow_get_be16(flow, offsetof(struct flow, vlan_tci));
- return vlan_tci_to_vid(tci);
+ return (flow->map & UINT64_C(1) << u32_ofs)
+ ? *(flow->values +
+ count_1bits(flow->map & ((UINT64_C(1) << u32_ofs) - 1)))
+ : 0;
}
/* Returns true if 'a' and 'b' are the same flow, false otherwise. */
const struct minimask *mask, uint32_t basis)
{
const uint32_t *p = mask->masks.values;
- uint32_t hash;
- uint64_t map;
-
- hash = basis;
+ uint32_t hash = basis;
+ uint32_t flow_u32;
- for (map = mask->masks.map; map; map = zero_rightmost_1bit(map)) {
- hash = mhash_add(hash, miniflow_get(flow, raw_ctz(map)) & *p++);
+ MINIFLOW_FOR_EACH_IN_MAP(flow_u32, flow, mask->masks.map) {
+ hash = mhash_add(hash, flow_u32 & *p++);
}
return mhash_finish(hash, (p - mask->masks.values) * 4);
return miniflow_get(&mask->masks, u32_ofs);
}
-/* Returns the VID mask within the vlan_tci member of the "struct
- * flow_wildcards" represented by 'mask'. */
-uint16_t
-minimask_get_vid_mask(const struct minimask *mask)
-{
- return miniflow_get_vid(&mask->masks);
-}
-
/* Returns true if 'a' and 'b' are the same flow mask, false otherwise. */
bool
minimask_equal(const struct minimask *a, const struct minimask *b)