Based heavily on work by Isaku Yamahata <[email protected]>
Cc: Isaku Yamahata <[email protected]>
Signed-off-by: Simon Horman <[email protected]>
--
v2
* Manual rebase
This patch is based on top of Ben Pfaff's series,
"set-field action support"
---
lib/nx-match.c | 7 +------
lib/ofp-actions.c | 12 ++++++++++++
lib/ofp-actions.h | 3 +++
lib/ofp-parse.c | 46 +++++++++++++++++++++++++++++++++++++++++++---
lib/ofp-util.def | 2 +-
5 files changed, 60 insertions(+), 10 deletions(-)
diff --git a/lib/nx-match.c b/lib/nx-match.c
index 6ea0642..4254747 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 9b7dead..9452ebc 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -1889,3 +1889,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 75ccc26..8ba3a7e 100644
--- a/lib/ofp-actions.h
+++ b/lib/ofp-actions.h
@@ -545,4 +545,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 165a36e..0c0aaaf 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)
{
@@ -351,9 +393,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 79ae01d..4d451b0 100644
--- a/lib/ofp-util.def
+++ b/lib/ofp-util.def
@@ -35,7 +35,7 @@ OFPAT11_ACTION(OFPAT11_SET_TP_DST, ofp_action_tp_port, 0,
"mod_tp_dst")
//OFPAT11_ACTION(OFPAT11_SET_QUEUE, ofp11_action_set_queue, 0, "set_queue")
//OFPAT11_ACTION(OFPAT11_SET_NW_TTL, ofp11_action_nw_ttl, 0, "set_nw_ttl")
//OFPAT11_ACTION(OFPAT11_DEC_NW_TTL, ofp_action_header, 0, "dec_ttl")
-OFPAT11_ACTION(OFPAT12_SET_FIELD, ofp12_action_set_field, 1, NULL)
+OFPAT11_ACTION(OFPAT12_SET_FIELD, ofp12_action_set_field, 1, "set_field")
#ifndef NXAST_ACTION
#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME)
--
1.7.10.4
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev