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