ofp-parse: Allow ofctl flow monitor filtering on field existence.
authorJesse Gross <jesse@nicira.com>
Wed, 9 Sep 2015 16:30:35 +0000 (09:30 -0700)
committerJesse Gross <jesse@nicira.com>
Wed, 9 Sep 2015 16:43:43 +0000 (09:43 -0700)
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>
lib/ofp-parse.c

index a18bd9c..4e59f7d 100644 (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;
 }