2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 14:25:26 +00:00

ofp-parse: Allow ofctl flow monitor filtering on field existence.

It is supposed to be possible to allow ovs-ofctl to filter flows
it is monitoring based on a match string. However, the parser will
reject expressions that match only on a field's existence (such as
Geneve options). This relaxes the restriction to bring it in line
with matches supported by other commands.

Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Jesse Gross
2015-09-09 09:30:35 -07:00
parent bc78455bdb
commit 0eede6b600

View File

@@ -221,6 +221,12 @@ parse_field(const struct mf_field *mf, const char *s, struct match *match,
union mf_value value, mask;
char *error;
if (!*s) {
/* If there's no string, we're just trying to match on the
* existence of the field, so use a no-op value. */
s = "0/0";
}
error = mf_parse(mf, s, &value, &mask);
if (!error) {
*usable_protocols &= mf_set(mf, &value, &mask, match);
@@ -365,11 +371,6 @@ parse_ofp_str__(struct ofputil_flow_mod *fm, int command, char *string,
|| !strcmp(name, "allow_hidden_fields")) {
/* ignore these fields. */
} else if (mf_from_name(name)) {
if (!*value) {
/* If there's no value, we're just trying to match on the
* existence of the field, so use a no-op value. */
value = "0/0";
}
error = parse_field(mf_from_name(name), value, &fm->match,
usable_protocols);
} else {
@@ -777,6 +778,7 @@ parse_flow_monitor_request__(struct ofputil_flow_monitor_request *fmr,
while (ofputil_parse_key_value(&string, &name, &value)) {
const struct protocol *p;
char *error = NULL;
if (!strcmp(name, "!initial")) {
fmr->flags &= ~NXFMF_INITIAL;
@@ -795,30 +797,26 @@ parse_flow_monitor_request__(struct ofputil_flow_monitor_request *fmr,
if (p->nw_proto) {
match_set_nw_proto(&fmr->match, p->nw_proto);
}
} else if (mf_from_name(name)) {
error = parse_field(mf_from_name(name), value, &fmr->match,
usable_protocols);
} else {
if (!*value) {
return xasprintf("%s: field %s missing value", str_, name);
}
if (!strcmp(name, "table")) {
char *error = str_to_u8(value, "table", &fmr->table_id);
if (error) {
return error;
}
error = str_to_u8(value, "table", &fmr->table_id);
} else if (!strcmp(name, "out_port")) {
fmr->out_port = u16_to_ofp(atoi(value));
} else if (mf_from_name(name)) {
char *error;
error = parse_field(mf_from_name(name), value, &fmr->match,
usable_protocols);
if (error) {
return error;
}
} else {
return xasprintf("%s: unknown keyword %s", str_, name);
}
}
if (error) {
return error;
}
}
return NULL;
}