Based heavily on work by Isaku Yamahata <yamah...@valinux.co.jp> Cc: Isaku Yamahata <yamah...@valinux.co.jp> Signed-off-by: Simon Horman <ho...@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 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev