dpctl: Accept port names (e.g. "NORMAL") on in_port in flow specifications.
authorBen Pfaff <blp@nicira.com>
Tue, 10 Mar 2009 22:23:14 +0000 (15:23 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 10 Mar 2009 22:23:14 +0000 (15:23 -0700)
utilities/dpctl.c

index 7aed03c151fae227a26787124446aea49f7b2eeb..06012a728262fe2aa658cf6c8f6f4f619088049a 100644 (file)
@@ -734,6 +734,37 @@ put_output_action(struct ofpbuf *b, uint16_t port)
     return oao;
 }
 
+static bool
+parse_port_name(const char *name, uint16_t *port)
+{
+    struct pair {
+        const char *name;
+        uint16_t value;
+    };
+    static const struct pair pairs[] = {
+#define DEF_PAIR(NAME) {#NAME, OFPP_##NAME}
+        DEF_PAIR(IN_PORT),
+        DEF_PAIR(TABLE),
+        DEF_PAIR(NORMAL),
+        DEF_PAIR(FLOOD),
+        DEF_PAIR(ALL),
+        DEF_PAIR(CONTROLLER),
+        DEF_PAIR(LOCAL),
+        DEF_PAIR(NONE),
+#undef DEF_PAIR
+    };
+    static const int n_pairs = ARRAY_SIZE(pairs);
+    size_t i;
+
+    for (i = 0; i < n_pairs; i++) {
+        if (!strcasecmp(name, pairs[i].name)) {
+            *port = pairs[i].value;
+            return true;
+        }
+    }
+    return false;
+}
+
 static void
 str_to_action(char *str, struct ofpbuf *b)
 {
@@ -743,6 +774,8 @@ str_to_action(char *str, struct ofpbuf *b)
     for (act = strtok_r(str, ", \t\r\n", &saveptr); act;
          act = strtok_r(NULL, ", \t\r\n", &saveptr)) 
     {
+        uint16_t port;
+
         /* Arguments are separated by colons */
         arg = strchr(act, ':');
         if (arg) {
@@ -777,14 +810,6 @@ str_to_action(char *str, struct ofpbuf *b)
             sa->subtype = htons(NXAST_SNAT);
             sa->port = htons(str_to_u32(arg));
 #endif
-        } else if (!strcasecmp(act, "TABLE")) {
-            put_output_action(b, OFPP_TABLE);
-        } else if (!strcasecmp(act, "NORMAL")) {
-            put_output_action(b, OFPP_NORMAL);
-        } else if (!strcasecmp(act, "FLOOD")) {
-            put_output_action(b, OFPP_FLOOD);
-        } else if (!strcasecmp(act, "ALL")) {
-            put_output_action(b, OFPP_ALL);
         } else if (!strcasecmp(act, "CONTROLLER")) {
             struct ofp_action_output *oao;
             oao = put_output_action(b, OFPP_CONTROLLER);
@@ -794,8 +819,8 @@ str_to_action(char *str, struct ofpbuf *b)
             if (arg && (strspn(act, "0123456789") == strlen(act))) {
                oao->max_len = htons(str_to_u32(arg));
             }
-        } else if (!strcasecmp(act, "LOCAL")) {
-            put_output_action(b, OFPP_LOCAL);
+        } else if (parse_port_name(act, &port)) {
+            put_output_action(b, port);
         } else if (strspn(act, "0123456789") == strlen(act)) {
             put_output_action(b, str_to_u32(act));
         } else {
@@ -949,7 +974,10 @@ str_to_flow(char *string, struct ofp_match *match, struct ofpbuf *actions,
                     wildcards |= f->wildcard;
                 } else {
                     wildcards &= ~f->wildcard;
-                    if (f->type == F_U8) {
+                    if (f->wildcard == OFPFW_IN_PORT
+                        && parse_port_name(value, (uint16_t *) data)) {
+                        /* Nothing to do. */
+                    } else if (f->type == F_U8) {
                         *(uint8_t *) data = str_to_u32(value);
                     } else if (f->type == F_U16) {
                         *(uint16_t *) data = htons(str_to_u32(value));