summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEthan Jackson <ethan@nicira.com>2011-02-01 18:50:25 -0800
committerEthan Jackson <ethan@nicira.com>2011-02-02 11:32:40 -0800
commitff55ea1f29360533699edb77747a919505282057 (patch)
tree582f0a88ea2a07f83e2e498baf87ffdb5a4f423e
parent0acae9fdc58c524f0fe6877b3a8197dd09a279d2 (diff)
downloadopenvswitch-ff55ea1f29360533699edb77747a919505282057.tar.gz
lib: Move l4 flow hash to the flow library.
This commit moves hash_symmetric_l4() to the flow library so that it may be used in future patches.
-rw-r--r--lib/flow.c37
-rw-r--r--lib/flow.h1
-rw-r--r--lib/multipath.c38
3 files changed, 39 insertions, 37 deletions
diff --git a/lib/flow.c b/lib/flow.c
index 87ca0f282..6842d3b5a 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -461,3 +461,40 @@ flow_wildcards_set_reg_mask(struct flow_wildcards *wc, int idx, uint32_t mask)
{
wc->reg_masks[idx] = mask;
}
+
+/* Hashes 'flow' based on its L2 through L4 protocol information. */
+uint32_t
+flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis)
+{
+ struct {
+ ovs_be32 ip_addr;
+ ovs_be16 eth_type;
+ ovs_be16 vlan_tci;
+ ovs_be16 tp_addr;
+ uint8_t eth_addr[ETH_ADDR_LEN];
+ uint8_t ip_proto;
+ } fields;
+
+ int i;
+
+ memset(&fields, 0, sizeof fields);
+ for (i = 0; i < ETH_ADDR_LEN; i++) {
+ fields.eth_addr[i] = flow->dl_src[i] ^ flow->dl_dst[i];
+ }
+ fields.vlan_tci = flow->vlan_tci & htons(VLAN_VID_MASK);
+ fields.eth_type = flow->dl_type;
+ if (fields.eth_type == htons(ETH_TYPE_IP)) {
+ fields.ip_addr = flow->nw_src ^ flow->nw_dst;
+ fields.ip_proto = flow->nw_proto;
+ if (fields.ip_proto == IP_TYPE_TCP || fields.ip_proto == IP_TYPE_UDP) {
+ fields.tp_addr = flow->tp_src ^ flow->tp_dst;
+ } else {
+ fields.tp_addr = htons(0);
+ }
+ } else {
+ fields.ip_addr = htonl(0);
+ fields.ip_proto = 0;
+ fields.tp_addr = htons(0);
+ }
+ return hash_bytes(&fields, sizeof fields, basis);
+}
diff --git a/lib/flow.h b/lib/flow.h
index 54f28d583..2dd0c4aec 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -150,5 +150,6 @@ bool flow_wildcards_has_extra(const struct flow_wildcards *,
uint32_t flow_wildcards_hash(const struct flow_wildcards *);
bool flow_wildcards_equal(const struct flow_wildcards *,
const struct flow_wildcards *);
+uint32_t flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis);
#endif /* flow.h */
diff --git a/lib/multipath.c b/lib/multipath.c
index 83df6805d..19e7b3610 100644
--- a/lib/multipath.c
+++ b/lib/multipath.c
@@ -87,42 +87,6 @@ multipath_execute(const struct nx_action_multipath *mp, struct flow *flow)
}
static uint32_t
-hash_symmetric_l4(const struct flow *flow, uint16_t basis)
-{
- struct {
- ovs_be32 ip_addr;
- ovs_be16 eth_type;
- ovs_be16 vlan_tci;
- ovs_be16 tp_addr;
- uint8_t eth_addr[ETH_ADDR_LEN];
- uint8_t ip_proto;
- } fields;
-
- int i;
-
- memset(&fields, 0, sizeof fields);
- for (i = 0; i < ETH_ADDR_LEN; i++) {
- fields.eth_addr[i] = flow->dl_src[i] ^ flow->dl_dst[i];
- }
- fields.vlan_tci = flow->vlan_tci & htons(VLAN_VID_MASK);
- fields.eth_type = flow->dl_type;
- if (fields.eth_type == htons(ETH_TYPE_IP)) {
- fields.ip_addr = flow->nw_src ^ flow->nw_dst;
- fields.ip_proto = flow->nw_proto;
- if (fields.ip_proto == IP_TYPE_TCP || fields.ip_proto == IP_TYPE_UDP) {
- fields.tp_addr = flow->tp_src ^ flow->tp_dst;
- } else {
- fields.tp_addr = htons(0);
- }
- } else {
- fields.ip_addr = htonl(0);
- fields.ip_proto = 0;
- fields.tp_addr = htons(0);
- }
- return hash_bytes(&fields, sizeof fields, basis);
-}
-
-static uint32_t
multipath_hash(const struct flow *flow, enum nx_mp_fields fields,
uint16_t basis)
{
@@ -131,7 +95,7 @@ multipath_hash(const struct flow *flow, enum nx_mp_fields fields,
return hash_bytes(flow->dl_src, sizeof flow->dl_src, basis);
case NX_MP_FIELDS_SYMMETRIC_L4:
- return hash_symmetric_l4(flow, basis);
+ return flow_hash_symmetric_l4(flow, basis);
}
NOT_REACHED();