summaryrefslogtreecommitdiff
path: root/lib/nx-match.c
diff options
context:
space:
mode:
authorJarno Rajahalme <jarno@ovn.org>2017-01-04 16:10:56 -0800
committerJarno Rajahalme <jarno@ovn.org>2017-01-04 16:10:56 -0800
commit21b2fa61712684b03c5a5a0dc2090fb5bbf9d1ad (patch)
tree0fcb43076d89406916229ef03f7764094fc7f902 /lib/nx-match.c
parente7dce33f09654f6a3f6b9920c5ce16c9c71ccb7f (diff)
downloadopenvswitch-21b2fa61712684b03c5a5a0dc2090fb5bbf9d1ad.tar.gz
ofp-parse: Allow match field names in actions and brackets in matches.
Allow using match field names in addition to the canonical register names in actions (including 'load', 'move', 'push', 'pop', 'output', 'multipath', 'bundle_load', and 'learn'). Allow also leaving out the trailing '[]' to indicate full field. These changes allow simpler syntax similar to 'set_field' to be used also elsewhere. Correspondingly, allow the '[start..end]' syntax to be used in matches in addition to the more explicit 'value/mask' notation. For example, to match on the value 2 of the bits 14..15 of NXM_NX_REG0, the match could include: ... reg0[14..15]=2 ... instead of ... reg0=0x8000/0xc000 ... Note that only contiguous masks can be specified with the bracket notation. Signed-off-by: Jarno Rajahalme <jarno@ovn.org> Acked-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'lib/nx-match.c')
-rw-r--r--lib/nx-match.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/lib/nx-match.c b/lib/nx-match.c
index 9201aaeac..2fd31b9aa 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -1812,7 +1812,7 @@ mf_parse_subfield_name(const char *name, int name_len, bool *wild)
char * OVS_WARN_UNUSED_RESULT
mf_parse_subfield__(struct mf_subfield *sf, const char **sp)
{
- const struct mf_field *field;
+ const struct mf_field *field = NULL;
const struct nxm_field *f;
const char *name;
int start, end;
@@ -1822,30 +1822,31 @@ mf_parse_subfield__(struct mf_subfield *sf, const char **sp)
s = *sp;
name = s;
- name_len = strcspn(s, "[");
- if (s[name_len] != '[') {
- return xasprintf("%s: missing [ looking for field name", *sp);
- }
+ name_len = strcspn(s, "[-");
f = mf_parse_subfield_name(name, name_len, &wild);
- if (!f) {
+ field = f ? mf_from_id(f->id) : mf_from_name_len(name, name_len);
+ if (!field) {
return xasprintf("%s: unknown field `%.*s'", *sp, name_len, s);
}
- field = mf_from_id(f->id);
s += name_len;
- if (ovs_scan(s, "[%d..%d]", &start, &end)) {
- /* Nothing to do. */
- } else if (ovs_scan(s, "[%d]", &start)) {
- end = start;
- } else if (!strncmp(s, "[]", 2)) {
- start = 0;
- end = field->n_bits - 1;
- } else {
- return xasprintf("%s: syntax error expecting [] or [<bit>] or "
- "[<start>..<end>]", *sp);
+ /* Assume full field. */
+ start = 0;
+ end = field->n_bits - 1;
+ if (*s == '[') {
+ if (!strncmp(s, "[]", 2)) {
+ /* Nothing to do. */
+ } else if (ovs_scan(s, "[%d..%d]", &start, &end)) {
+ /* Nothing to do. */
+ } else if (ovs_scan(s, "[%d]", &start)) {
+ end = start;
+ } else {
+ return xasprintf("%s: syntax error expecting [] or [<bit>] or "
+ "[<start>..<end>]", *sp);
+ }
+ s = strchr(s, ']') + 1;
}
- s = strchr(s, ']') + 1;
if (start > end) {
return xasprintf("%s: starting bit %d is after ending bit %d",