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 <je...@nicira.com> --- lib/ofp-parse.c | 70 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index a6190ed..855d732 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -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); @@ -372,11 +378,6 @@ parse_ofp_str__(struct ofputil_flow_mod *fm, int command, char *string, value = field; 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 { @@ -774,7 +775,7 @@ parse_flow_monitor_request__(struct ofputil_flow_monitor_request *fmr, { static atomic_count id = ATOMIC_COUNT_INIT(0); char *save_ptr = NULL; - char *name; + char *field; fmr->id = atomic_count_inc(&id); @@ -784,52 +785,53 @@ parse_flow_monitor_request__(struct ofputil_flow_monitor_request *fmr, fmr->table_id = 0xff; match_init_catchall(&fmr->match); - for (name = strtok_r(string, "=, \t\r\n", &save_ptr); name; - name = strtok_r(NULL, "=, \t\r\n", &save_ptr)) { + for (field = strtok_r(string, ", \t\r\n", &save_ptr); field; + field = strtok_r(NULL, ", \t\r\n", &save_ptr)) { const struct protocol *p; - if (!strcmp(name, "!initial")) { + if (!strcmp(field, "!initial")) { fmr->flags &= ~NXFMF_INITIAL; - } else if (!strcmp(name, "!add")) { + } else if (!strcmp(field, "!add")) { fmr->flags &= ~NXFMF_ADD; - } else if (!strcmp(name, "!delete")) { + } else if (!strcmp(field, "!delete")) { fmr->flags &= ~NXFMF_DELETE; - } else if (!strcmp(name, "!modify")) { + } else if (!strcmp(field, "!modify")) { fmr->flags &= ~NXFMF_MODIFY; - } else if (!strcmp(name, "!actions")) { + } else if (!strcmp(field, "!actions")) { fmr->flags &= ~NXFMF_ACTIONS; - } else if (!strcmp(name, "!own")) { + } else if (!strcmp(field, "!own")) { fmr->flags &= ~NXFMF_OWN; - } else if (parse_protocol(name, &p)) { + } else if (parse_protocol(field, &p)) { match_set_dl_type(&fmr->match, htons(p->dl_type)); if (p->nw_proto) { match_set_nw_proto(&fmr->match, p->nw_proto); } } else { - char *value; - - value = strtok_r(NULL, ", \t\r\n", &save_ptr); - if (!value) { - return xasprintf("%s: field %s missing value", str_, name); - } + char *name, *value; + char *error = NULL; - if (!strcmp(name, "table")) { - char *error = str_to_u8(value, "table", &fmr->table_id); - if (error) { - return error; - } - } else if (!strcmp(name, "out_port")) { - fmr->out_port = u16_to_ofp(atoi(value)); - } else if (mf_from_name(name)) { - char *error; + name = strsep(&field, "="); + value = field; + if (mf_from_name(name)) { 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 (!value) { + return xasprintf("%s: field %s missing value", str_, name); + } + + if (!strcmp(name, "table")) { + error = str_to_u8(value, "table", &fmr->table_id); + } else if (!strcmp(name, "out_port")) { + fmr->out_port = u16_to_ofp(atoi(value)); + } else { + return xasprintf("%s: unknown keyword %s", str_, name); + } + } + + if (error) { + return error; } } } -- 2.1.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev