odp-util: Add support for named ports to odp_flow_key_from_string().
authorBen Pfaff <blp@nicira.com>
Wed, 26 Oct 2011 17:01:32 +0000 (10:01 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 17 Nov 2011 18:11:54 +0000 (10:11 -0800)
Really the "trace" command should support this but in fact I need it for
an upcoming update to a test.

lib/odp-util.c
lib/odp-util.h
ofproto/ofproto-dpif.c
tests/test-odp.c

index b4ebd79..c13f7a6 100644 (file)
 #include "ofpbuf.h"
 #include "openvswitch/tunnel.h"
 #include "packets.h"
+#include "shash.h"
 #include "timeval.h"
 #include "util.h"
 #include "vlog.h"
 
 VLOG_DEFINE_THIS_MODULE(odp_util);
 
+static int parse_odp_key_attr(const char *, const struct shash *port_names,
+                              struct ofpbuf *);
+
 /* The interface between userspace and kernel uses an "OVS_*" prefix.
  * Since this is fairly non-specific for the OVS userspace components,
  * "ODP_*" (Open vSwitch Datapath) is used as the prefix for
@@ -564,7 +568,8 @@ ovs_frag_type_from_string(const char *s, enum ovs_frag_type *type)
 }
 
 static int
-parse_odp_key_attr(const char *s, struct ofpbuf *key)
+parse_odp_key_attr(const char *s, const struct shash *port_names,
+                   struct ofpbuf *key)
 {
     /* Many of the sscanf calls in this function use oversized destination
      * fields because some sscanf() implementations truncate the range of %i
@@ -608,6 +613,20 @@ parse_odp_key_attr(const char *s, struct ofpbuf *key)
         }
     }
 
+    if (port_names && !strncmp(s, "in_port(", 8)) {
+        const char *name;
+        const struct shash_node *node;
+        int name_len;
+
+        name = s + 8;
+        name_len = strcspn(s, ")");
+        node = shash_find_len(port_names, name, name_len);
+        if (node) {
+            nl_msg_put_u32(key, OVS_KEY_ATTR_IN_PORT, (uintptr_t) node->data);
+            return 8 + name_len + 1;
+        }
+    }
+
     {
         struct ovs_key_ethernet eth_key;
         int n = -1;
@@ -880,11 +899,16 @@ parse_odp_key_attr(const char *s, struct ofpbuf *key)
  * data is appended to 'key'.  Either way, 'key''s data might be
  * reallocated.
  *
+ * If 'port_names' is nonnull, it points to an shash that maps from a port name
+ * to a port number cast to void *.  (Port names may be used instead of port
+ * numbers in in_port.)
+ *
  * On success, the attributes appended to 'key' are individually syntactically
  * valid, but they may not be valid as a sequence.  'key' might, for example,
  * have duplicated keys.  odp_flow_key_to_flow() will detect those errors. */
 int
-odp_flow_key_from_string(const char *s, struct ofpbuf *key)
+odp_flow_key_from_string(const char *s, const struct shash *port_names,
+                         struct ofpbuf *key)
 {
     const size_t old_size = key->size;
     for (;;) {
@@ -895,7 +919,7 @@ odp_flow_key_from_string(const char *s, struct ofpbuf *key)
             return 0;
         }
 
-        retval = parse_odp_key_attr(s, key);
+        retval = parse_odp_key_attr(s, port_names, key);
         if (retval < 0) {
             key->size = old_size;
             return -retval;
index 3003f61..b943c8c 100644 (file)
@@ -30,6 +30,7 @@ struct ds;
 struct flow;
 struct nlattr;
 struct ofpbuf;
+struct shash;
 
 #define OVSP_NONE ((uint16_t) -1)
 
@@ -88,7 +89,8 @@ struct odputil_keybuf {
 };
 
 void odp_flow_key_format(const struct nlattr *, size_t, struct ds *);
-int odp_flow_key_from_string(const char *s, struct ofpbuf *);
+int odp_flow_key_from_string(const char *s, const struct shash *port_names,
+                             struct ofpbuf *);
 
 void odp_flow_key_from_flow(struct ofpbuf *, const struct flow *);
 int odp_flow_key_to_flow(const struct nlattr *, size_t, struct flow *);
index 8ce2a34..bd8c75c 100644 (file)
@@ -5290,7 +5290,7 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, const char *args_,
 
         /* Convert string to datapath key. */
         ofpbuf_init(&odp_key, 0);
-        error = odp_flow_key_from_string(arg1, &odp_key);
+        error = odp_flow_key_from_string(arg1, NULL, &odp_key);
         if (error) {
             unixctl_command_reply(conn, 501, "Bad flow syntax");
             goto exit;
index 9a2bc0a..0656bf4 100644 (file)
@@ -52,7 +52,7 @@ main(void)
 
         /* Convert string to OVS DP key. */
         ofpbuf_init(&odp_key, 0);
-        error = odp_flow_key_from_string(ds_cstr(&in), &odp_key);
+        error = odp_flow_key_from_string(ds_cstr(&in), NULL, &odp_key);
         if (error) {
             printf("odp_flow_key_from_string: error\n");
             goto next;