X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fflow.c;h=093dec8407c8141b574d3329719a70aba5492229;hb=cfc50ae514f805dcd9c14589f21158185424daf6;hp=8cb2b3783d72aaad648b83d0475930b228f7daa5;hpb=419681daf125576d25839eaefbb179b65e19c091;p=sliver-openvswitch.git diff --git a/lib/flow.c b/lib/flow.c index 8cb2b3783..093dec840 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -943,10 +943,38 @@ flow_wildcards_set_reg_mask(struct flow_wildcards *wc, int idx, uint32_t mask) 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) { @@ -955,8 +983,7 @@ flow_hash_5tuple(const struct flow *flow, uint32_t basis) 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); @@ -1692,42 +1719,15 @@ miniflow_expand(const struct miniflow *src, struct flow *dst) 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. */ @@ -1840,13 +1840,11 @@ miniflow_hash_in_minimask(const struct miniflow *flow, 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); @@ -1976,14 +1974,6 @@ minimask_get(const struct minimask *mask, unsigned int u32_ofs) 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)