[ovs-dev] [PATCH/RFC 8/9] Support NMX selection method in ovs-ofctl group commands

Simon Horman simon.horman at netronome.com
Wed Nov 19 00:45:02 UTC 2014


NMX selection method
Signed-off-by: Simon Horman <simon.horman at netronome.com>
---
 lib/ofp-parse.c          | 103 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/ofproto.at         |   4 +-
 utilities/ovs-ofctl.8.in |  23 ++++++++++-
 3 files changed, 127 insertions(+), 3 deletions(-)

diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index 16c7cdc..ad14d42 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -1159,6 +1159,75 @@ parse_bucket_str(struct ofputil_bucket *bucket, char *str_,
 }
 
 static char * WARN_UNUSED_RESULT
+parse_select_group_field(char *s, struct flow *flow, struct mf_bitmap *bm,
+                         enum ofputil_protocol *usable_protocols)
+{
+    char *save_ptr = NULL;
+    char *name;
+    struct match match;
+
+    match_init_catchall(&match);
+
+    for (name = strtok_r(s, "=, \t\r\n", &save_ptr); name;
+         name = strtok_r(NULL, "=, \t\r\n", &save_ptr)) {
+        const struct mf_field *mf = mf_from_name(name);
+
+        if (mf) {
+            char *error;
+            const char *value_str;
+            union mf_value value, mask;
+
+            value_str = strtok_r(NULL, ", \t\r\n", &save_ptr);
+            if (value_str) {
+                error = mf_parse(mf, value_str, &value, &mask);
+                if (error) {
+                    return error;
+                }
+
+                /* The mask cannot be all-zeros */
+                if (is_all_zeros(&value, mf->n_bytes)) {
+                    return xasprintf("%s: values are wildcards here "
+                                     "and must not be all-zeros", s);
+                }
+
+                /* The values parsed are masks for fields used
+                 * by the selection method */
+                if (!mf_is_mask_valid(mf, &value)) {
+                    return xasprintf("%s: invalid mask for field %s",
+                                     value_str, mf->name);
+                }
+
+                /* The mask cannot have a mask */
+                if (!is_all_ones(&mask, mf->n_bytes)) {
+                    return xasprintf("%s: values are wildcards here "
+                                     "and cannot in turn be wildcarded", s);
+                }
+            } else {
+                memset(&value, '1', mf->n_bytes);
+            }
+
+            mf_set_value(mf, &value, &match);
+            bitmap_set1(bm->bm, mf->id);
+
+            if (is_all_ones(&value, mf->n_bytes)) {
+                *usable_protocols &= mf->usable_protocols_exact;
+            } else if (mf->usable_protocols_bitwise == mf->usable_protocols_cidr
+                       || ip_is_cidr(value.be32)) {
+                *usable_protocols &= mf->usable_protocols_cidr;
+            } else {
+                *usable_protocols &= mf->usable_protocols_bitwise;
+            }
+        } else {
+            return xasprintf("%s: unknown field %s", s, name);
+        }
+    }
+
+    *flow = match.flow;
+
+    return NULL;
+}
+
+static char * WARN_UNUSED_RESULT
 parse_ofp_group_mod_str__(struct ofputil_group_mod *gm, uint16_t command,
                           char *string,
                           enum ofputil_protocol *usable_protocols)
@@ -1328,6 +1397,40 @@ parse_ofp_group_mod_str__(struct ofputil_group_mod *gm, uint16_t command,
         } else if (!strcmp(name, "bucket")) {
             error = xstrdup("bucket is not needed");
             goto out;
+        } else if (!strcmp(name, "selection_method")) {
+            if (!(fields & F_GROUP_TYPE)) {
+                error = xstrdup("selection method is not needed");
+                goto out;
+            }
+            if (strlen(value) >= NMX_MAX_SELECTION_METHOD_LEN) {
+                error = xasprintf("selection method is longer than %u"
+                                  " bytes long",
+                                  NMX_MAX_SELECTION_METHOD_LEN - 1);
+                goto out;
+            }
+            memset(gm->props.selection_method, '0',
+                   NMX_MAX_SELECTION_METHOD_LEN);
+            strcpy(gm->props.selection_method, value);
+            *usable_protocols &= OFPUTIL_P_OF15_UP;
+        } else if (!strcmp(name, "selection_method_param")) {
+            if (!(fields & F_GROUP_TYPE)) {
+                error = xstrdup("selection method param is not needed");
+                goto out;
+            }
+            error = str_to_u64(value, &gm->props.selection_method_param);
+            *usable_protocols &= OFPUTIL_P_OF15_UP;
+        } else if (!strcmp(name, "fields")) {
+            if (!(fields & F_GROUP_TYPE)) {
+                error = xstrdup("fields are not needed");
+                goto out;
+            }
+            error = parse_select_group_field(value, &gm->props.fields.flow,
+                                             &gm->props.fields.bm,
+                                             usable_protocols);
+            if (error) {
+                goto out;
+            }
+            *usable_protocols &= OFPUTIL_P_OF15_UP;
         } else {
             error = xasprintf("unknown keyword %s", name);
             goto out;
diff --git a/tests/ofproto.at b/tests/ofproto.at
index 8cfecc6..585d4cf 100644
--- a/tests/ofproto.at
+++ b/tests/ofproto.at
@@ -338,14 +338,14 @@ dnl Actions definition listed in both supported formats (w/ actions=)
 AT_SETUP([ofproto - del group (OpenFlow 1.5)])
 OVS_VSWITCHD_START
 AT_DATA([groups.txt], [dnl
-group_id=1234,type=all,bucket=output:10,bucket=output:11
+group_id=1234,type=select,selection_method=hash,bucket=output:10,bucket=output:11
 group_id=1235,type=all,bucket=actions=output:12,bucket=bucket_id:0,actions=output:10,bucket=bucket_id:1,actions=output:11
 ])
 AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn add-groups br0 groups.txt])
 AT_CHECK([ovs-ofctl -F OXM-OpenFlow15 -O OpenFlow15 -vwarn dump-groups br0 1234], [0], [stdout])
 AT_CHECK([STRIP_XIDS stdout], [0], [dnl
 OFPST_GROUP_DESC reply (OF1.5):
- group_id=1234,type=all,bucket=bucket_id:0,actions=output:10,bucket=bucket_id:1,actions=output:11
+ group_id=1234,type=select,selection_method=hash,bucket=bucket_id:0,actions=output:10,bucket=bucket_id:1,actions=output:11
 ])
 AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn del-groups br0 group_id=1234])
 AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn dump-groups br0], [0], [stdout])
diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in
index 4641461..9522c55 100644
--- a/utilities/ovs-ofctl.8.in
+++ b/utilities/ovs-ofctl.8.in
@@ -1999,7 +1999,28 @@ In case of the \fBiremove-buckets\fR command the effect is to
 remove the in the group whose \fBbucket_id\fR is \fIid\fR.
 It is an error if there is no bucket persent group in whose \fBbucket_id\fR is
 \fIid\fR.
-
+.IP \fBselection_method\fR=\fImethod\fR
+The selection method used to select a bucket for a select group.
+This is a string of 1 to 15 bytes in length known to lower layers.
+This field is optional for \fBadd\-group\fR, \fBadd\-groups\fR and
+\fBmod\-group\fR commands on groups of type \fBselect\fR. Prohibited
+otherwise. The default value is the empty string.
+.IP \fBselection_method_param\fR=\fIparam\fR
+64-bit integer parameter to the selection method selected by the
+\fBselection_method\fR field.  The parameter's use is defined by the
+lower-layer that implements the \fBselection_method\fR.  It is optional if
+the \fBselection_method\fR field is specified as a non-empty string.
+Prohibited otherwise. The default value is zero.
+.IP \fBfields\fR=\fIparam\fR
+The field parameters to selection method selected by the
+\fBselection_method\fR field.  The syntax is described in \fBFlow Syntax\fR
+with the additional restriction that the if a value is provided it is
+treated as a wildcard mask and wildcard masks following a slash are
+prohibited.  The pre-requisites of fields must be povided by any flows that
+output to the group. The use of the fields is defined by the lower-layer
+that implements the \fBselection_method\fR.  They are optional if the
+\fBselection_method\fR field is specified as a non-empty string.
+Prohibited otherwise. The default is no fields.
 .IP \fBbucket\fR=\fIbucket_parameters\fR
 The \fBadd-group\fR, \fBadd-groups\fR and \fBmod-group\fR commands
 require at least one bucket field. Bucket fields must appear after
-- 
2.1.1




More information about the dev mailing list