[ovs-dev] [PATCH 3/3] ofp-actions: Add parsing of set_field actions

Simon Horman horms at verge.net.au
Thu Sep 13 12:45:12 UTC 2012


Based heavily on work by Isaku Yamahata <yamahata at valinux.co.jp>

Cc: Isaku Yamahata <yamahata at valinux.co.jp>
Signed-off-by: Simon Horman <horms at verge.net.au>
---
 lib/nx-match.c    |    7 +------
 lib/ofp-actions.c |   12 ++++++++++++
 lib/ofp-actions.h |    3 +++
 lib/ofp-parse.c   |   46 +++++++++++++++++++++++++++++++++++++++++++---
 lib/ofp-util.def  |    3 +--
 5 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/lib/nx-match.c b/lib/nx-match.c
index e1b3c61..0bc9234 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -1119,12 +1119,7 @@ nxm_reg_load_from_openflow12_set_field(
         return OFPERR_OFPBAC_BAD_ARGUMENT;
     }
     load = ofpact_put_REG_LOAD(ofpacts);
-    load->ofpact.compat = OFPUTIL_OFPAT12_SET_FIELD;
-    load->dst.field = mf;
-    load->dst.ofs = 0;
-    load->dst.n_bits = mf->n_bits;
-    bitwise_copy(oasf + 1, mf->n_bytes, load->dst.ofs,
-                 &load->subvalue, sizeof load->subvalue, 0, mf->n_bits);
+    ofpact_set_field_init(load, mf, oasf + 1);
 
     return nxm_reg_load_check(load, NULL);
 }
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 9686d5d..644f732 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -1968,3 +1968,15 @@ ofpact_pad(struct ofpbuf *ofpacts)
         ofpbuf_put_zeros(ofpacts, OFPACT_ALIGNTO - rem);
     }
 }
+
+void
+ofpact_set_field_init(struct ofpact_reg_load *load, const struct mf_field *mf,
+                      const void *src)
+{
+    load->ofpact.compat = OFPUTIL_OFPAT12_SET_FIELD;
+    load->dst.field = mf;
+    load->dst.ofs = 0;
+    load->dst.n_bits = mf->n_bits;
+    bitwise_copy(src, mf->n_bytes, load->dst.ofs,
+                 &load->subvalue, sizeof load->subvalue, 0, mf->n_bits);
+}
diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h
index 082df7b..60a8df9 100644
--- a/lib/ofp-actions.h
+++ b/lib/ofp-actions.h
@@ -546,4 +546,7 @@ enum {
 const char *ofpact_instruction_name_from_type(enum ovs_instruction_type type);
 int ofpact_instruction_type_from_name(const char *name);
 
+void ofpact_set_field_init(struct ofpact_reg_load *load,
+                           const struct mf_field *mf, const void *src);
+
 #endif /* ofp-actions.h */
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index 622f022..84f276c 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -314,6 +314,48 @@ parse_dec_ttl(struct ofpbuf *b, char *arg)
 }
 
 static void
+set_field_parse(const char *arg, struct ofpbuf *ofpacts)
+{
+    char *orig = xstrdup(arg);
+    struct ofpact_reg_load *load = ofpact_put_REG_LOAD(ofpacts);
+    char *value;
+    char *delim;
+    char *key;
+    const struct mf_field *mf;
+    const char *error;
+    union mf_value mf_value;
+
+    value = orig;
+    delim = strstr(orig, "->");
+    if (!delim) {
+        ovs_fatal(0, "%s: missing `->'", orig);
+    }
+    if (strlen(delim) <= strlen("->")) {
+        ovs_fatal(0, "%s: missing field name following `->'", orig);
+    }
+
+    key = delim + strlen("->");
+    mf = mf_from_name(key);
+    if (!mf) {
+        ovs_fatal(0, "%s is not valid oxm field name", key);
+    }
+    if (!mf->writable) {
+        ovs_fatal(0, "%s is not allowed to set", key);
+    }
+
+    delim[0] = '\0';
+    error = mf_parse_value(mf, value, &mf_value);
+    if (error) {
+        ovs_fatal(0, "%s", error);
+    }
+    if (!mf_is_value_valid(mf, &mf_value)) {
+        ovs_fatal(0, "%s is not valid valid for field %s", value, key);
+    }
+    ofpact_set_field_init(load, mf, &mf_value);
+    free(orig);
+}
+
+static void
 parse_named_action(enum ofputil_action_code code, const struct flow *flow,
                    char *arg, struct ofpbuf *ofpacts)
 {
@@ -352,9 +394,7 @@ parse_named_action(enum ofputil_action_code code, const struct flow *flow,
         break;
 
     case OFPUTIL_OFPAT12_SET_FIELD:
-        NOT_REACHED();  /* This will be implemented by later patch and
-                         * enabled using a non-NULL name in
-                         * OFPAT12_ACTION(OFPAT12_SET_FIELD, ...) */
+        set_field_parse(arg, ofpacts);
         break;
 
     case OFPUTIL_OFPAT10_STRIP_VLAN:
diff --git a/lib/ofp-util.def b/lib/ofp-util.def
index 42b399a..17f09f5 100644
--- a/lib/ofp-util.def
+++ b/lib/ofp-util.def
@@ -54,8 +54,7 @@ OFPAT12_ACTION(OFPAT12_OUTPUT, ofp11_action_output, "output")
 //OFPAT12_ACTION(OFPAT12_DEC_NW_TTL, ofp_action_header, "dec_ttl")
 //Use non-NULL name for OFPAT12_SET_FIELD once the code for
 //the OFPUTIL_OFPAT12_SET_FIELD case in parse_named_action() is implemented
-//OFPAT12_ACTION(OFPAT12_SET_FIELD, ofp12_action_set_field, "set_field")
-OFPAT12_ACTION(OFPAT12_SET_FIELD, ofp12_action_set_field, NULL)
+OFPAT12_ACTION(OFPAT12_SET_FIELD, ofp12_action_set_field, "set_field")
 //OFPAT12_ACTION(OFPAT12_EXPERIMENTER, , )
 
 #ifndef NXAST_ACTION
-- 
1.7.10.4




More information about the dev mailing list