Skip to content

Commit

Permalink
ofp-actions: Extend reg_load parsing to >64bits.
Browse files Browse the repository at this point in the history
Previously, reg_load would only understand 64-bit values passed to it.
This patch extends the parsing to handle larger fields, if they are
specified in hexadecimal. Internally they are stored as a single action,
but they are converted into multiple 64-bit modifications when
re-serialised.

Signed-off-by: Joe Stringer <[email protected]>
Acked-by: Ben Pfaff <[email protected]>
  • Loading branch information
joestringer committed Oct 13, 2015
1 parent 36b43aa commit 8127099
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions lib/ofp-actions.c
Original file line number Diff line number Diff line change
Expand Up @@ -2571,10 +2571,9 @@ static char * OVS_WARN_UNUSED_RESULT
parse_reg_load(char *arg, struct ofpbuf *ofpacts)
{
struct ofpact_set_field *sf = ofpact_put_reg_load(ofpacts);
const char *full_arg = arg;
uint64_t value = strtoull(arg, (char **) &arg, 0);
struct mf_subfield dst;
char *key, *value_str;
union mf_value value;
char *error;

error = set_field_split_str(arg, &key, &value_str, NULL);
Expand All @@ -2587,16 +2586,29 @@ parse_reg_load(char *arg, struct ofpbuf *ofpacts)
return error;
}

if (dst.n_bits < 64 && (value >> dst.n_bits) != 0) {
return xasprintf("%s: value %"PRIu64" does not fit into %d bits",
full_arg, value, dst.n_bits);
if (parse_int_string(value_str, (uint8_t *)&value, dst.field->n_bytes,
&key)) {
return xasprintf("%s: cannot parse integer value", arg);
}

if (!bitwise_is_all_zeros(&value, dst.field->n_bytes, dst.n_bits,
dst.field->n_bytes * 8 - dst.n_bits)) {
struct ds ds;

ds_init(&ds);
mf_format(dst.field, &value, NULL, &ds);
error = xasprintf("%s: value %s does not fit into %d bits",
arg, ds_cstr(&ds), dst.n_bits);
ds_destroy(&ds);
return error;
}

sf->field = dst.field;
memset(&sf->value, 0, sizeof sf->value);
bitwise_put(value, &sf->value, dst.field->n_bytes, dst.ofs, dst.n_bits);
bitwise_put(UINT64_MAX, &sf->mask,
dst.field->n_bytes, dst.ofs, dst.n_bits);
bitwise_copy(&value, dst.field->n_bytes, 0, &sf->value,
dst.field->n_bytes, dst.ofs, dst.n_bits);
bitwise_one(&sf->mask, dst.field->n_bytes, dst.ofs, dst.n_bits);

return NULL;
}

Expand Down

0 comments on commit 8127099

Please sign in to comment.