[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