X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fflow.c;h=093dec8407c8141b574d3329719a70aba5492229;hb=a5ed8fe32cb3c996837c61af2e358fa34dc9936f;hp=03d86aeb8f391f7972d45c87c0f5031dee62bd04;hpb=b570c52cc2d0033f36056f43e8d43ed3b01bf186;p=sliver-openvswitch.git diff --git a/lib/flow.c b/lib/flow.c index 03d86aeb8..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); @@ -1813,28 +1840,10 @@ 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; - const uint32_t *fp = flow->values; - uint64_t fmap = flow->map; - uint64_t rm1bit; - - hash = basis; - - for (map = mask->masks.map; map; map -= rm1bit) { - uint32_t flow_u32 = 0; - - rm1bit = rightmost_1bit(map); - if (fmap & rm1bit) { - uint64_t trash = fmap & (rm1bit - 1); + uint32_t hash = basis; + uint32_t flow_u32; - /* Skip data in 'flow' that is of no interest, once. */ - if (trash) { - fp += count_1bits(trash); - fmap -= trash; - } - flow_u32 = *fp; - } + MINIFLOW_FOR_EACH_IN_MAP(flow_u32, flow, mask->masks.map) { hash = mhash_add(hash, flow_u32 & *p++); }