[ovs-dev] [bundle 2/5] nicira-ext: Generalize nx_mp_fields into nx_hash_fields.

Ethan Jackson ethan at nicira.com
Mon Jul 18 21:35:06 UTC 2011


Sounds good to me, here is another version.

--- 
Future patches will use nx_hash_fields for non-multipath related
actions.  This patch renames nx_mp_fields and creates a new
flow_hash_fields() function.
---
 include/openflow/nicira-ext.h |   43 ++++++++++++++++++++---------------------
 lib/flow.c                    |   40 ++++++++++++++++++++++++++++++++++++++
 lib/flow.h                    |    4 +++
 lib/multipath.c               |   38 +++++------------------------------
 4 files changed, 71 insertions(+), 54 deletions(-)

diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h
index d73f3ba..006d27d 100644
--- a/include/openflow/nicira-ext.h
+++ b/include/openflow/nicira-ext.h
@@ -167,6 +167,25 @@ enum nicira_stats_type {
     NXST_AGGREGATE              /* Analogous to OFPST_AGGREGATE. */
 };
 
+/* Fields to use when hashing flows. */
+enum nx_hash_fields {
+    /* Ethernet source address (NXM_OF_ETH_SRC) only. */
+    NX_HASH_FIELDS_ETH_SRC,
+
+    /* L2 through L4, symmetric across src/dst.  Specifically, each of the
+     * following fields, if present, is hashed (slashes separate symmetric
+     * pairs):
+     *
+     *  - NXM_OF_ETH_DST / NXM_OF_ETH_SRC
+     *  - NXM_OF_ETH_TYPE
+     *  - The VID bits from NXM_OF_VLAN_TCI, ignoring PCP and CFI.
+     *  - NXM_OF_IP_PROTO
+     *  - NXM_OF_IP_SRC / NXM_OF_IP_DST
+     *  - NXM_OF_TCP_SRC / NXM_OF_TCP_DST
+     */
+    NX_HASH_FIELDS_SYMMETRIC_L4
+};
+
 /* This command enables or disables an Open vSwitch extension that allows a
  * controller to specify the OpenFlow table to which a flow should be added,
  * instead of having the switch decide which table is most appropriate as
@@ -498,7 +517,7 @@ OFP_ASSERT(sizeof(struct nx_action_note) == 16);
  *
  * This action performs the following steps in sequence:
  *
- *    1. Hashes the fields designated by 'fields', one of NX_MP_FIELDS_*.
+ *    1. Hashes the fields designated by 'fields', one of NX_HASH_FIELDS_*.
  *       Refer to the definition of "enum nx_mp_fields" for details.
  *
  *       The 'basis' value is used as a universal hash parameter, that is,
@@ -535,7 +554,7 @@ struct nx_action_multipath {
     ovs_be16 subtype;           /* NXAST_MULTIPATH. */
 
     /* What fields to hash and how. */
-    ovs_be16 fields;            /* One of NX_MP_FIELDS_*. */
+    ovs_be16 fields;            /* One of NX_HASH_FIELDS_*. */
     ovs_be16 basis;             /* Universal hash parameter. */
     ovs_be16 pad0;
 
@@ -551,26 +570,6 @@ struct nx_action_multipath {
 };
 OFP_ASSERT(sizeof(struct nx_action_multipath) == 32);
 
-/* NXAST_MULTIPATH: Fields to hash. */
-enum nx_mp_fields {
-    /* Ethernet source address (NXM_OF_ETH_SRC) only. */
-    NX_MP_FIELDS_ETH_SRC,
-
-    /* L2 through L4, symmetric across src/dst.  Specifically, each of the
-     * following fields, if present, is hashed (slashes separate symmetric
-     * pairs):
-     *
-     *  - NXM_OF_ETH_DST / NXM_OF_ETH_SRC
-     *  - NXM_OF_ETH_TYPE
-     *  - The VID bits from NXM_OF_VLAN_TCI, ignoring PCP and CFI.
-     *  - NXM_OF_IP_PROTO
-     *  - NXM_OF_IP_SRC / NXM_OF_IP_DST
-     *  - NXM_OF_TCP_SRC / NXM_OF_TCP_DST
-     *  - NXM_OF_UDP_SRC / NXM_OF_UDP_DST
-     */
-    NX_MP_FIELDS_SYMMETRIC_L4
-};
-
 /* NXAST_MULTIPATH: Multipath link choice algorithm to apply.
  *
  * In the descriptions below, 'n_links' is max_link + 1. */
diff --git a/lib/flow.c b/lib/flow.c
index e6607bf..cafc8d7 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -852,3 +852,43 @@ flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis)
     }
     return hash_bytes(&fields, sizeof fields, basis);
 }
+
+/* Hashes the portions of 'flow' designated by 'fields'. */
+uint32_t
+flow_hash_fields(const struct flow *flow, enum nx_hash_fields fields,
+                 uint16_t basis)
+{
+    switch (fields) {
+
+    case NX_HASH_FIELDS_ETH_SRC:
+        return hash_bytes(flow->dl_src, sizeof flow->dl_src, basis);
+
+    case NX_HASH_FIELDS_SYMMETRIC_L4:
+        return flow_hash_symmetric_l4(flow, basis);
+    }
+
+    NOT_REACHED();
+}
+
+/* Returns a string representation of 'fields'. */
+const char *
+flow_hash_fields_to_str(enum nx_hash_fields fields)
+{
+    static char *symmetric_l4 = "symmetric_l4";
+    static char *eth_src = "eth_src";
+    static char *unknown = "<unknown>";
+
+    switch (fields) {
+    case NX_HASH_FIELDS_ETH_SRC: return eth_src;
+    case NX_HASH_FIELDS_SYMMETRIC_L4: return symmetric_l4;
+    default: return unknown;
+    }
+}
+
+/* Returns true if the value of 'fields' is supported. Otherwise false. */
+bool
+flow_hash_fields_valid(enum nx_hash_fields fields)
+{
+    return fields == NX_HASH_FIELDS_ETH_SRC
+        || fields == NX_HASH_FIELDS_SYMMETRIC_L4;
+}
diff --git a/lib/flow.h b/lib/flow.h
index f7a0c23..ba2d806 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -171,5 +171,9 @@ const uint8_t *flow_wildcards_to_dl_dst_mask(flow_wildcards_t);
 bool flow_wildcards_is_dl_dst_mask_valid(const uint8_t[6]);
 flow_wildcards_t flow_wildcards_set_dl_dst_mask(flow_wildcards_t,
                                                 const uint8_t mask[6]);
+uint32_t flow_hash_fields(const struct flow *, enum nx_hash_fields,
+                          uint16_t basis);
+const char *flow_hash_fields_to_str(enum nx_hash_fields);
+bool flow_hash_fields_valid(enum nx_hash_fields);
 
 #endif /* flow.h */
diff --git a/lib/multipath.c b/lib/multipath.c
index 07e0ada..4ee6fd0 100644
--- a/lib/multipath.c
+++ b/lib/multipath.c
@@ -40,8 +40,7 @@ multipath_check(const struct nx_action_multipath *mp)
     int ofs = nxm_decode_ofs(mp->ofs_nbits);
     int n_bits = nxm_decode_n_bits(mp->ofs_nbits);
 
-    if (mp->fields != htons(NX_MP_FIELDS_ETH_SRC)
-        && mp->fields != htons(NX_MP_FIELDS_SYMMETRIC_L4)) {
+    if (!flow_hash_fields_valid(ntohs(mp->fields))) {
         VLOG_WARN_RL(&rl, "unsupported fields %"PRIu16, ntohs(mp->fields));
     } else if (mp->algorithm != htons(NX_MP_ALG_MODULO_N)
                && mp->algorithm != htons(NX_MP_ALG_HASH_THRESHOLD)
@@ -64,8 +63,6 @@ multipath_check(const struct nx_action_multipath *mp)
 
 /* multipath_execute(). */
 
-static uint32_t multipath_hash(const struct flow *, enum nx_mp_fields,
-                               uint16_t basis);
 static uint16_t multipath_algorithm(uint32_t hash, enum nx_mp_algorithm,
                                     unsigned int n_links, unsigned int arg);
 
@@ -73,7 +70,8 @@ void
 multipath_execute(const struct nx_action_multipath *mp, struct flow *flow)
 {
     /* Calculate value to store. */
-    uint32_t hash = multipath_hash(flow, ntohs(mp->fields), ntohs(mp->basis));
+    uint32_t hash = flow_hash_fields(flow, ntohs(mp->fields),
+                                     ntohs(mp->basis));
     uint16_t link = multipath_algorithm(hash, ntohs(mp->algorithm),
                                         ntohs(mp->max_link) + 1,
                                         ntohl(mp->arg));
@@ -86,21 +84,6 @@ multipath_execute(const struct nx_action_multipath *mp, struct flow *flow)
     *reg = (*reg & ~(mask << ofs)) | (link << ofs);
 }
 
-static uint32_t
-multipath_hash(const struct flow *flow, enum nx_mp_fields fields,
-               uint16_t basis)
-{
-    switch (fields) {
-    case NX_MP_FIELDS_ETH_SRC:
-        return hash_bytes(flow->dl_src, sizeof flow->dl_src, basis);
-
-    case NX_MP_FIELDS_SYMMETRIC_L4:
-        return flow_hash_symmetric_l4(flow, basis);
-    }
-
-    NOT_REACHED();
-}
-
 static uint16_t
 algorithm_hrw(uint32_t hash, unsigned int n_links)
 {
@@ -204,9 +187,9 @@ multipath_parse(struct nx_action_multipath *mp, const char *s_)
     mp->vendor = htonl(NX_VENDOR_ID);
     mp->subtype = htons(NXAST_MULTIPATH);
     if (!strcasecmp(fields, "eth_src")) {
-        mp->fields = htons(NX_MP_FIELDS_ETH_SRC);
+        mp->fields = htons(NX_HASH_FIELDS_ETH_SRC);
     } else if (!strcasecmp(fields, "symmetric_l4")) {
-        mp->fields = htons(NX_MP_FIELDS_SYMMETRIC_L4);
+        mp->fields = htons(NX_HASH_FIELDS_SYMMETRIC_L4);
     } else {
         ovs_fatal(0, "%s: unknown fields `%s'", s_, fields);
     }
@@ -253,16 +236,7 @@ multipath_format(const struct nx_action_multipath *mp, struct ds *s)
     uint16_t mp_fields    = ntohs(mp->fields);
     uint16_t mp_algorithm = ntohs(mp->algorithm);
 
-    switch ((enum nx_mp_fields) mp_fields) {
-    case NX_MP_FIELDS_ETH_SRC:
-        fields = "eth_src";
-        break;
-    case NX_MP_FIELDS_SYMMETRIC_L4:
-        fields = "symmetric_l4";
-        break;
-    default:
-        fields = "<unknown>";
-    }
+    fields = flow_hash_fields_to_str(mp_fields);
 
     switch ((enum nx_mp_algorithm) mp_algorithm) {
     case NX_MP_ALG_MODULO_N:
-- 
1.7.6




More information about the dev mailing list