[ovs-dev] [PATCH v2] bundle: add nw_src/dst hash method

wenxu at ucloud.cn wenxu at ucloud.cn
Thu Mar 9 04:01:02 UTC 2017


From: wenxu <wenxu at ucloud.cn>

Add only nw_src or nw_dst hash feature to bundle and multipath.

Signed-off-by: wenxu <wenxu at ucloud.cn>
---
 NEWS                          |  2 ++
 include/openflow/nicira-ext.h |  7 ++++++-
 lib/bundle.c                  |  4 ++++
 lib/flow.c                    | 44 ++++++++++++++++++++++++++++++++++++++++++-
 lib/multipath.c               |  4 ++++
 utilities/ovs-ofctl.8.in      |  8 ++++++--
 6 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/NEWS b/NEWS
index ce9fe88..358140d 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ Post-v2.7.0
        `egress_pkt_mark` OVSDB option.
    - EMC insertion probability is reduced to 1% and is configurable via
      the new 'other_config:emc-insert-inv-prob' option.
+   - ovs-ofctl:
+     * Support nw_src and nw_dst in fields for command 'multipath/bundle'.
 
 v2.7.0 - xx xxx xxxx
 ---------------------
diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h
index 9d53623..71a1de0 100644
--- a/include/openflow/nicira-ext.h
+++ b/include/openflow/nicira-ext.h
@@ -103,8 +103,13 @@ enum nx_hash_fields {
      *  - NXM_OF_TCP_SRC / NXM_OF_TCP_DST
      *  - NXM_OF_UDP_SRC / NXM_OF_UDP_DST
      */
-    NX_HASH_FIELDS_SYMMETRIC_L3L4_UDP
+    NX_HASH_FIELDS_SYMMETRIC_L3L4_UDP,
 
+    /* Network source address (NXM_OF_IP_SRC) only. */
+    NX_HASH_FIELDS_NW_SRC,
+
+    /* Network destination address (NXM_OF_IP_DST) only. */
+    NX_HASH_FIELDS_NW_DST
 
 };
 
diff --git a/lib/bundle.c b/lib/bundle.c
index 620318e..1bacb37 100644
--- a/lib/bundle.c
+++ b/lib/bundle.c
@@ -191,6 +191,10 @@ bundle_parse__(const char *s, char **save_ptr,
         bundle->fields = NX_HASH_FIELDS_SYMMETRIC_L3L4;
     } else if (!strcasecmp(fields, "symmetric_l3l4+udp")) {
         bundle->fields = NX_HASH_FIELDS_SYMMETRIC_L3L4_UDP;
+    } else if (!strcasecmp(fields, "nw_src")) {
+        bundle->fields = NX_HASH_FIELDS_NW_SRC;
+    } else if (!strcasecmp(fields, "nw_dst")) {
+        bundle->fields = NX_HASH_FIELDS_NW_DST;
     } else {
         return xasprintf("%s: unknown fields `%s'", s, fields);
     }
diff --git a/lib/flow.c b/lib/flow.c
index b476fce..6efc21f 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -1974,6 +1974,22 @@ flow_mask_hash_fields(const struct flow *flow, struct flow_wildcards *wc,
         }
         break;
 
+    case NX_HASH_FIELDS_NW_SRC:
+        if (flow->dl_type == htons(ETH_TYPE_IP)) {
+            memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src);
+        } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
+            memset(&wc->masks.ipv6_src, 0xff, sizeof wc->masks.ipv6_src);
+        }
+        break;
+
+    case NX_HASH_FIELDS_NW_DST:
+        if (flow->dl_type == htons(ETH_TYPE_IP)) {
+            memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst);
+        } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
+            memset(&wc->masks.ipv6_dst, 0xff, sizeof wc->masks.ipv6_dst);
+        }
+        break;
+
     default:
         OVS_NOT_REACHED();
     }
@@ -1998,6 +2014,28 @@ flow_hash_fields(const struct flow *flow, enum nx_hash_fields fields,
     case NX_HASH_FIELDS_SYMMETRIC_L3L4_UDP:
         return flow_hash_symmetric_l3l4(flow, basis, true);
 
+    case NX_HASH_FIELDS_NW_SRC:
+        if (flow->dl_type == htons(ETH_TYPE_IP)) {
+            return jhash_bytes(&flow->nw_src, sizeof flow->nw_src, basis);
+        }
+        else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
+            return jhash_bytes(&flow->ipv6_src, sizeof flow->ipv6_src, basis);
+        }
+        else {
+            return basis;
+        }
+
+    case NX_HASH_FIELDS_NW_DST:
+        if (flow->dl_type == htons(ETH_TYPE_IP)) {
+            return jhash_bytes(&flow->nw_dst, sizeof flow->nw_dst, basis);
+        }
+        else if (flow->dl_type == htons(ETH_TYPE_IPV6)) {
+            return jhash_bytes(&flow->ipv6_dst, sizeof flow->ipv6_dst, basis);
+        }
+        else {
+            return basis;
+        }
+
     }
 
     OVS_NOT_REACHED();
@@ -2012,6 +2050,8 @@ flow_hash_fields_to_str(enum nx_hash_fields fields)
     case NX_HASH_FIELDS_SYMMETRIC_L4: return "symmetric_l4";
     case NX_HASH_FIELDS_SYMMETRIC_L3L4: return "symmetric_l3l4";
     case NX_HASH_FIELDS_SYMMETRIC_L3L4_UDP: return "symmetric_l3l4+udp";
+    case NX_HASH_FIELDS_NW_SRC: return "nw_src";
+    case NX_HASH_FIELDS_NW_DST: return "nw_dst";
     default: return "<unknown>";
     }
 }
@@ -2023,7 +2063,9 @@ flow_hash_fields_valid(enum nx_hash_fields fields)
     return fields == NX_HASH_FIELDS_ETH_SRC
         || fields == NX_HASH_FIELDS_SYMMETRIC_L4
         || fields == NX_HASH_FIELDS_SYMMETRIC_L3L4
-        || fields == NX_HASH_FIELDS_SYMMETRIC_L3L4_UDP;
+        || fields == NX_HASH_FIELDS_SYMMETRIC_L3L4_UDP
+        || fields == NX_HASH_FIELDS_NW_SRC
+        || fields == NX_HASH_FIELDS_NW_DST;
 }
 
 /* Returns a hash value for the bits of 'flow' that are active based on
diff --git a/lib/multipath.c b/lib/multipath.c
index e855a88..385624e 100644
--- a/lib/multipath.c
+++ b/lib/multipath.c
@@ -168,6 +168,10 @@ multipath_parse__(struct ofpact_multipath *mp, const char *s_, char *s)
         mp->fields = NX_HASH_FIELDS_SYMMETRIC_L3L4;
     } else if (!strcasecmp(fields, "symmetric_l3l4+udp")) {
         mp->fields = NX_HASH_FIELDS_SYMMETRIC_L3L4_UDP;
+    } else if (!strcasecmp(fields, "nw_src")) {
+        mp->fields = NX_HASH_FIELDS_NW_SRC;
+    } else if (!strcasecmp(fields, "nw_dst")) {
+        mp->fields = NX_HASH_FIELDS_NW_DST;
     } else {
         return xasprintf("%s: unknown fields `%s'", s_, fields);
     }
diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in
index 14db85e..ddafd1a 100644
--- a/utilities/ovs-ofctl.8.in
+++ b/utilities/ovs-ofctl.8.in
@@ -1382,6 +1382,10 @@ and IPv6, which hash to a constant zero.
 Like \fBsymmetric_l3l4+udp\fR, but UDP ports are included in the hash.
 This is a more effective hash when asymmetric UDP protocols such as
 VXLAN are not a consideration.
+.IP \fBnw_src\fR
+Hashes Network source address only.
+.IP \fBnw_dst\fR
+Hashes Network destination address only.
 .RE
 .IP
 \fIalgorithm\fR must be one of \fBmodulo_n\fR,
@@ -1397,8 +1401,8 @@ slaves represented as \fIslave_type\fR.  Currently the only supported
 \fIslave_type\fR is \fBofport\fR.  Thus, each \fIs1\fR through \fIsN\fR should
 be an OpenFlow port number. Outputs to the selected slave.
 .IP
-Currently, \fIfields\fR must be either \fBeth_src\fR, \fBsymmetric_l4\fR, \fBsymmetric_l3l4\fR, or \fBsymmetric_l3l4+udp\fR, 
-and \fIalgorithm\fR must be one of \fBhrw\fR and \fBactive_backup\fR.
+Currently, \fIfields\fR must be either \fBeth_src\fR, \fBsymmetric_l4\fR, \fBsymmetric_l3l4\fR, \fBsymmetric_l3l4+udp\fR, 
+\fBnw_src\fR, or \fBnw_dst\fR, and \fIalgorithm\fR must be one of \fBhrw\fR and \fBactive_backup\fR.
 .IP
 Example: \fBbundle(eth_src,0,hrw,ofport,slaves:4,8)\fR uses an Ethernet source
 hash with basis 0, to select between OpenFlow ports 4 and 8 using the Highest
-- 
1.8.3.1




More information about the dev mailing list