[ovs-dev,1/2] ofp-actions: Refactor set_field_parse__().
diff mbox

Message ID 1443214186-50469-1-git-send-email-joestringer@nicira.com
State Superseded
Headers show

Commit Message

Joe Stringer Sept. 25, 2015, 8:49 p.m. UTC
Split out some common functions that may be used by REG_LOAD in the
following patch.

Signed-off-by: Joe Stringer <joestringer@nicira.com>
---
 lib/ofp-actions.c | 81 ++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 56 insertions(+), 25 deletions(-)

Comments

Joe Stringer Sept. 29, 2015, 8:53 p.m. UTC | #1
On 25 September 2015 at 13:49, Joe Stringer <joestringer@nicira.com> wrote:
> Split out some common functions that may be used by REG_LOAD in the
> following patch.
>
> Signed-off-by: Joe Stringer <joestringer@nicira.com>

I folded this series into the conntrack series I just posted:
https://patchwork.ozlabs.org/patch/524014/

Patch
diff mbox

diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 88f0f85..d33e429 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -2476,51 +2476,58 @@  encode_SET_FIELD(const struct ofpact_set_field *sf,
     }
 }
 
-/* Parses a "set_field" action with argument 'arg', appending the parsed
- * action to 'ofpacts'.
+/* Parses the input argument 'arg' into the key, value, and delimiter
+ * components that are common across the reg_load and set_field action format.
+ *
+ * With an argument like "1->metadata", sets the following pointers to
+ * point within 'arg':
+ * key: "metadata"
+ * value: "1"
+ * delim: "->"
  *
  * Returns NULL if successful, otherwise a malloc()'d string describing the
  * error.  The caller is responsible for freeing the returned string. */
 static char * OVS_WARN_UNUSED_RESULT
-set_field_parse__(char *arg, struct ofpbuf *ofpacts,
-                  enum ofputil_protocol *usable_protocols)
+set_field_split_str(char *arg, char **key, char **value, char **delim)
 {
-    struct ofpact_set_field *sf = ofpact_put_SET_FIELD(ofpacts);
-    char *value;
-    char *delim;
-    char *key;
-    const struct mf_field *mf;
-    char *error;
+    *value = arg;
+    *delim = strstr(arg, "->");
+    *key = *delim + strlen("->");
 
-    value = arg;
-    delim = strstr(arg, "->");
-    if (!delim) {
+    if (!*delim) {
         return xasprintf("%s: missing `->'", arg);
     }
-    if (strlen(delim) <= strlen("->")) {
+    if (strlen(*delim) <= strlen("->")) {
         return xasprintf("%s: missing field name following `->'", arg);
     }
 
-    key = delim + strlen("->");
-    mf = mf_from_name(key);
-    if (!mf) {
-        return xasprintf("%s is not a valid OXM field name", key);
-    }
+    return NULL;
+}
+
+/* Wraps mf_parse() to parse the input field 'mf' from the 'key' and 'value'
+ * strings, placing the output into 'dst' and (optionally) 'mask'.
+ *
+ * Returns NULL if successful, otherwise a malloc()'d string describing the
+ * error.  The caller is responsible for freeing the returned string. */
+static char * OVS_WARN_UNUSED_RESULT
+set_field_parse__(const struct mf_field *mf, const char *key,
+                  const char *value, union mf_value *dst, union mf_value *mask)
+{
+    char *error;
+
     if (!mf->writable) {
         return xasprintf("%s is read-only", key);
     }
-    sf->field = mf;
-    delim[0] = '\0';
-    error = mf_parse(mf, value, &sf->value, &sf->mask);
+
+    error = mf_parse(mf, value, dst, mask);
     if (error) {
         return error;
     }
 
-    if (!mf_is_value_valid(mf, &sf->value)) {
+    if (!mf_is_value_valid(mf, dst)) {
         return xasprintf("%s is not a valid value for field %s", value, key);
     }
 
-    *usable_protocols &= mf->usable_protocols_exact;
     return NULL;
 }
 
@@ -2533,8 +2540,32 @@  static char * OVS_WARN_UNUSED_RESULT
 parse_SET_FIELD(const char *arg, struct ofpbuf *ofpacts,
                 enum ofputil_protocol *usable_protocols)
 {
+    struct ofpact_set_field *sf = ofpact_put_SET_FIELD(ofpacts);
     char *copy = xstrdup(arg);
-    char *error = set_field_parse__(copy, ofpacts, usable_protocols);
+    char *key, *value, *delim;
+    const struct mf_field *mf;
+    char *error = NULL;
+
+    error = set_field_split_str(copy, &key, &value, &delim);
+    if (error) {
+        goto error;
+    }
+
+    mf = mf_from_name(key);
+    if (!mf) {
+        error = xasprintf("%s is not a valid OXM field name", key);
+        goto error;
+    }
+    delim[0] = '\0';
+
+    error = set_field_parse__(mf, key, value, &sf->value, &sf->mask);
+    if (error) {
+        goto error;
+    }
+    sf->field = mf;
+    *usable_protocols &= mf->usable_protocols_exact;
+
+error:
     free(copy);
     return error;
 }