Open Flow 1.1 and 1.2 make use of 32 bit ports, however Open vSwtich maps
them to 16 bits. Make ovs-ofputl aware of this.

Also, only accept ports that fit into 16 bits for Open Flow 1.0.

Signed-off-by: Simon Horman <ho...@verge.net.au>

---

v13

* str_to_port_no(): Move ovs_fatal() in to be inside if() clause
  as that is the only case where it may be executed
* Add missing space to ovs_fatal() message.

v12
* No change

v11
* No change

v10
* No change

v9
* Manual Rebase

v8
* Omitted

v7
* Omitted

v6
* No change

v5
* Initial post
---
 utilities/ovs-ofctl.c |   39 ++++++++++++++++++++++++++++++++-------
 1 file changed, 32 insertions(+), 7 deletions(-)

diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index 5f61fd6..57fde6a 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -739,16 +739,40 @@ fetch_ofputil_phy_port(const char *vconn_name, const char 
*port_name,
 /* Returns the port number corresponding to 'port_name' (which may be a port
  * name or number) within the switch 'vconn_name'. */
 static uint16_t
-str_to_port_no(const char *vconn_name, const char *port_name)
+str_to_port_no(struct vconn *vconn, const char *port_name)
 {
     unsigned int port_no;
 
     if (str_to_uint(port_name, 10, &port_no)) {
-        return port_no;
+        switch (vconn_get_version(vconn)) {
+        case OFP12_VERSION:
+        case OFP11_VERSION: {
+            enum ofperr error;
+            uint16_t ofp10_port;
+
+            error = ofputil_port_from_ofp11(htonl(port_no), &ofp10_port);
+            if (!error) {
+                return ofp10_port;
+            }
+            break;
+        }
+
+        case OFP10_VERSION:
+            if (port_no <= OFPP_NONE) {
+                return port_no;
+            }
+            break;
+
+        default:
+            NOT_REACHED();
+        }
+
+        ovs_fatal(0, "%s: port out of range `%s'",
+                  vconn_get_name(vconn), port_name);
     } else {
         struct ofputil_phy_port pp;
 
-        fetch_ofputil_phy_port(vconn_name, port_name, &pp);
+        fetch_ofputil_phy_port(vconn_get_name(vconn), port_name, &pp);
         return pp.port_no;
     }
 }
@@ -959,7 +983,7 @@ ofctl_queue_stats(int argc, char *argv[])
     req = ofpbuf_put_zeros(request, sizeof *req);
 
     if (argc > 2 && argv[2][0] && strcasecmp(argv[2], "all")) {
-        req->port_no = htons(str_to_port_no(argv[1], argv[2]));
+        req->port_no = htons(str_to_port_no(vconn, argv[2]));
     } else {
         req->port_no = htons(OFPP_ALL);
     }
@@ -1424,7 +1448,7 @@ ofctl_dump_ports(int argc, char *argv[])
     request = ofpraw_alloc(OFPRAW_OFPST_PORT_REQUEST,
                            vconn_get_version(vconn), 0);
     req = ofpbuf_put_zeros(request, sizeof *req);
-    port = argc > 2 ? str_to_port_no(argv[1], argv[2]) : OFPP_NONE;
+    port = argc > 2 ? str_to_port_no(vconn, argv[2]) : OFPP_NONE;
     req->port_no = htons(port);
     dump_stats_transaction(vconn, request);
     vconn_close(vconn);
@@ -1462,17 +1486,18 @@ ofctl_packet_out(int argc, char *argv[])
     struct vconn *vconn;
     int i;
 
+    protocol = open_vconn(argv[1], &vconn);
+
     ofpbuf_init(&ofpacts, 64);
     parse_ofpacts(argv[3], &ofpacts);
 
     po.buffer_id = UINT32_MAX;
     po.in_port = (!strcasecmp(argv[2], "none") ? OFPP_NONE
                   : !strcasecmp(argv[2], "local") ? OFPP_LOCAL
-                  : str_to_port_no(argv[1], argv[2]));
+                  : str_to_port_no(vconn, argv[2]));
     po.ofpacts = ofpacts.data;
     po.ofpacts_len = ofpacts.size;
 
-    protocol = open_vconn(argv[1], &vconn);
     for (i = 4; i < argc; i++) {
         struct ofpbuf *packet, *opo;
         const char *error_msg;
-- 
1.7.10.4

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to