diff options
author | Joe Stringer <joestringer@nicira.com> | 2015-09-30 13:54:12 -0700 |
---|---|---|
committer | Joe Stringer <joestringer@nicira.com> | 2015-10-13 15:34:14 -0700 |
commit | 36b43aa6500124578b75a8c3cb6417201b58cce2 (patch) | |
tree | 81402952ca17af18965e714d425b239524296a09 | |
parent | 293a104b1dd31133497c15618969cdc9db6ada46 (diff) | |
download | openvswitch-36b43aa6500124578b75a8c3cb6417201b58cce2.tar.gz |
ofp-actions: Refactor set_field tokenization.
Combine the codepaths for splitting "set_field" and "reg_load" string
arguments into the value, key, and delimiter component. The only
user-visible change is that reg_load will now provide a more meaningful
error message when parsing input such as "reg_load:1".
Signed-off-by: Joe Stringer <joestringer@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
-rw-r--r-- | lib/ofp-actions.c | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index 88f0f858e..6c9e1cbc2 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c @@ -2476,6 +2476,39 @@ encode_SET_FIELD(const struct ofpact_set_field *sf, } } +/* 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_split_str(char *arg, char **key, char **value, char **delim) +{ + char *value_end; + + *value = arg; + value_end = strstr(arg, "->"); + *key = value_end + strlen("->"); + if (delim) { + *delim = value_end; + } + + if (!value_end) { + return xasprintf("%s: missing `->'", arg); + } + if (strlen(value_end) <= strlen("->")) { + return xasprintf("%s: missing field name following `->'", arg); + } + + return NULL; +} + /* Parses a "set_field" action with argument 'arg', appending the parsed * action to 'ofpacts'. * @@ -2492,16 +2525,11 @@ set_field_parse__(char *arg, struct ofpbuf *ofpacts, const struct mf_field *mf; char *error; - value = arg; - delim = strstr(arg, "->"); - if (!delim) { - return xasprintf("%s: missing `->'", arg); - } - if (strlen(delim) <= strlen("->")) { - return xasprintf("%s: missing field name following `->'", arg); + error = set_field_split_str(arg, &key, &value, &delim); + if (error) { + return error; } - key = delim + strlen("->"); mf = mf_from_name(key); if (!mf) { return xasprintf("%s is not a valid OXM field name", key); @@ -2546,13 +2574,15 @@ parse_reg_load(char *arg, struct ofpbuf *ofpacts) const char *full_arg = arg; uint64_t value = strtoull(arg, (char **) &arg, 0); struct mf_subfield dst; + char *key, *value_str; char *error; - if (strncmp(arg, "->", 2)) { - return xasprintf("%s: missing `->' following value", full_arg); + error = set_field_split_str(arg, &key, &value_str, NULL); + if (error) { + return error; } - arg += 2; - error = mf_parse_subfield(&dst, arg); + + error = mf_parse_subfield(&dst, key); if (error) { return error; } |