From patchwork Wed Nov 4 01:10:23 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 539669 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (li376-54.members.linode.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 1C7A01402D6 for ; Wed, 4 Nov 2015 12:10:34 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=nicira_com.20150623.gappssmtp.com header.i=@nicira_com.20150623.gappssmtp.com header.b=CgdGynQ/; dkim-atps=neutral Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id 8A7BB106E4; Tue, 3 Nov 2015 17:10:31 -0800 (PST) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e3.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id 9DA01106D0 for ; Tue, 3 Nov 2015 17:10:30 -0800 (PST) Received: from bar5.cudamail.com (localhost [127.0.0.1]) by mx1e3.cudamail.com (Postfix) with ESMTPS id E44374200B3 for ; Tue, 3 Nov 2015 18:10:29 -0700 (MST) X-ASG-Debug-ID: 1446599427-09eadd7e75d3120001-byXFYA Received: from mx1-pf2.cudamail.com ([192.168.24.2]) by bar5.cudamail.com with ESMTP id 3QtnD86AL3v3Ew73 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 03 Nov 2015 18:10:27 -0700 (MST) X-Barracuda-Envelope-From: blp@nicira.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.24.2 Received: from unknown (HELO mail-pa0-f51.google.com) (209.85.220.51) by mx1-pf2.cudamail.com with ESMTPS (RC4-SHA encrypted); 4 Nov 2015 01:10:27 -0000 Received-SPF: unknown (mx1-pf2.cudamail.com: Multiple SPF records returned) X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.51 Received: by pabfh17 with SMTP id fh17so34651993pab.0 for ; Tue, 03 Nov 2015 17:10:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nicira_com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=fOe8lpCkaziJOZ/VMM0lioe+SGr0Of4jA7isvjZN+M8=; b=CgdGynQ/g3DpUXzkdOton/vDnoNHZJUdafK5YjdCUks8hDpZNLbLfWS4GDI5jdFBAr YyZ6Sq7+uekwmfxH2gyteIYwZH5ySAzT9oXhlxMTXhou12b5altMZaRb1OaUHVjHT52a 42MXBsdDQg81rjSucjsr89nP8FtuqyJeBBqXWzlau5JC1dl/Fm5U/J/c0tTP3IOaeNds JubCxkUNpP3AoLFYiAYXCwlhJqRG8urbOWa8jv+m415e+e5uwxOu0rx+o9cEGfWnqy5H UVg3RpueE/4Tq/oxZtMQE7jL5D8BDnutoT2mJHscfKV7xOA90QNBC2BA88mc4XVqzH+W eASA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=fOe8lpCkaziJOZ/VMM0lioe+SGr0Of4jA7isvjZN+M8=; b=edUmDQgZUWv4zPm3MTL2UMmfRsXT3cOT4DO2miQCB7mo3Gq2WeKc+H0ENyPzZCJPNN lyhJP50pzpUXbuSTWmQcfEySjyt8/dOyR/RUjExa9uBTxqcRMjqTktumdKl4Zz2gPAB1 mvoOGnKlvIQtZAWxO+HNaZ2ofR1kIb42Lo9VeepuHkYOeFJJq2TZu63aUfYvflgXgWCD 3DVpJE/nvcXmSkhYn8WctSbh3vC8AV0UrdaUgE3sBlGQmDK4Q6c60mign5xJz0iyQHn5 tjP3unRPNLD1mAXcLCJWOXW4stQW3dYp2EZ3Tp/bnNRGBqqjpmBye8H6DLD0lM/9p7AY t3GA== X-Gm-Message-State: ALoCoQlqqW9RG1zpQHugsW2KsnDuYk8WQRDZk+wFz26r/dx5ZFeXpc7PYO3jBWlnrF1RaqpH6Xk8 X-Received: by 10.66.66.196 with SMTP id h4mr36757255pat.113.1446599426713; Tue, 03 Nov 2015 17:10:26 -0800 (PST) Received: from sigabrt.gateway.sonic.net (173-228-112-197.dsl.dynamic.fusionbroadband.com. [173.228.112.197]) by smtp.gmail.com with ESMTPSA id wq1sm31719004pbc.49.2015.11.03.17.10.25 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 03 Nov 2015 17:10:25 -0800 (PST) X-CudaMail-Envelope-Sender: blp@nicira.com X-Barracuda-Apparent-Source-IP: 173.228.112.197 From: Ben Pfaff To: dev@openvswitch.org X-CudaMail-Whitelist-To: dev@openvswitch.org X-CudaMail-MID: CM-E2-1102108305 X-CudaMail-DTE: 110315 X-CudaMail-Originating-IP: 209.85.220.51 Date: Tue, 3 Nov 2015 17:10:23 -0800 X-ASG-Orig-Subj: [##CM-E2-1102108305##][PATCH 2/2] ofproto: Implement OFPT_QUEUE_GET_CONFIG_REQUEST for OFPP_ANY in OF1.1+. Message-Id: <1446599423-31564-2-git-send-email-blp@nicira.com> X-Mailer: git-send-email 2.1.3 In-Reply-To: <1446599423-31564-1-git-send-email-blp@nicira.com> References: <1446599423-31564-1-git-send-email-blp@nicira.com> X-Barracuda-Connect: UNKNOWN[192.168.24.2] X-Barracuda-Start-Time: 1446599427 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-ASG-Whitelist: Header =?UTF-8?B?eFwtY3VkYW1haWxcLXdoaXRlbGlzdFwtdG8=?= X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 Cc: Ben Pfaff , Minoru TAKAHASHI Subject: [ovs-dev] [PATCH 2/2] ofproto: Implement OFPT_QUEUE_GET_CONFIG_REQUEST for OFPP_ANY in OF1.1+. X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dev-bounces@openvswitch.org Sender: "dev" I was not previously aware that this feature was missing. Reported-by: Minoru TAKAHASHI Reported-at: http://openvswitch.org/pipermail/discuss/2015-October/019229.html Signed-off-by: Ben Pfaff --- NEWS | 1 + lib/ofp-util.c | 22 ++++++++++++--------- lib/ofp-util.h | 1 + ofproto/ofproto.c | 51 +++++++++++++++++++++++++++++------------------- tests/ofproto.at | 9 +++++++++ utilities/ovs-ofctl.8.in | 11 +++++++++++ utilities/ovs-ofctl.c | 51 ++++++++++++++++++++++++++++++++++-------------- 7 files changed, 102 insertions(+), 44 deletions(-) diff --git a/NEWS b/NEWS index 9b9dff2..abd7d9a 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ Post-v2.4.0 - OpenFlow: * Group chaining (where one OpenFlow group triggers another) is now supported. + * OpenFlow 1.1+ OFPT_QUEUE_GET_CONFIG_REQUEST now supports OFPP_ANY. * OpenFlow 1.4+ "importance" is now considered for flow eviction. * OpenFlow 1.4+ OFPTC_EVICTION is now implemented. * OpenFlow 1.4+ OFPMP_TABLE_DESC is now implemented. diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 342be54..99e8e52 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -2437,14 +2437,23 @@ ofputil_decode_queue_get_config_request(const struct ofp_header *oh, case OFPRAW_OFPT10_QUEUE_GET_CONFIG_REQUEST: qgcr10 = b.data; *port = u16_to_ofp(ntohs(qgcr10->port)); - return 0; + break; case OFPRAW_OFPT11_QUEUE_GET_CONFIG_REQUEST: qgcr11 = b.data; - return ofputil_port_from_ofp11(qgcr11->port, port); + enum ofperr error = ofputil_port_from_ofp11(qgcr11->port, port); + if (error || *port == OFPP_ANY) { + return error; + } + break; + + default: + OVS_NOT_REACHED(); } - OVS_NOT_REACHED(); + return (ofp_to_u16(*port) < ofp_to_u16(OFPP_MAX) + ? 0 + : OFPERR_OFPQOFC_BAD_PORT); } /* Constructs and returns the beginning of a reply to @@ -2521,15 +2530,10 @@ ofputil_append_queue_get_config_reply(struct ofpbuf *reply, opq10->queue_id = htonl(oqc->queue_id); len_ofs = (char *) &opq10->len - (char *) reply->data; } else { - struct ofp11_queue_get_config_reply *qgcr11; struct ofp12_packet_queue *opq12; - ovs_be32 port; - - qgcr11 = reply->msg; - port = qgcr11->port; opq12 = ofpbuf_put_zeros(reply, sizeof *opq12); - opq12->port = port; + opq12->port = ofputil_port_to_ofp11(oqc->port); opq12->queue_id = htonl(oqc->queue_id); len_ofs = (char *) &opq12->len - (char *) reply->data; } diff --git a/lib/ofp-util.h b/lib/ofp-util.h index 8914342..81a62ba 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -894,6 +894,7 @@ enum ofperr ofputil_decode_queue_get_config_request(const struct ofp_header *, /* Queue configuration reply. */ struct ofputil_queue_config { + ofp_port_t port; uint32_t queue_id; /* Each of these optional values is expressed in tenths of a percent. diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index c7dd8a2..471db9d 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -6204,30 +6204,12 @@ handle_group_features_stats_request(struct ofconn *ofconn, return 0; } -static enum ofperr -handle_queue_get_config_request(struct ofconn *ofconn, - const struct ofp_header *oh) +static void +put_queue_config(struct ofport *ofport, struct ofpbuf *reply) { - struct ofproto *p = ofconn_get_ofproto(ofconn); struct netdev_queue_dump queue_dump; - struct ofport *ofport; unsigned int queue_id; - struct ofpbuf *reply; struct smap details; - ofp_port_t request; - enum ofperr error; - - error = ofputil_decode_queue_get_config_request(oh, &request); - if (error) { - return error; - } - - ofport = ofproto_get_port(p, request); - if (!ofport) { - return OFPERR_OFPQOFC_BAD_PORT; - } - - reply = ofputil_encode_queue_get_config_reply(oh); smap_init(&details); NETDEV_QUEUE_FOR_EACH (&queue_id, &details, &queue_dump, ofport->netdev) { @@ -6235,13 +6217,42 @@ handle_queue_get_config_request(struct ofconn *ofconn, /* None of the existing queues have compatible properties, so we * hard-code omitting min_rate and max_rate. */ + queue.port = ofport->ofp_port; queue.queue_id = queue_id; queue.min_rate = UINT16_MAX; queue.max_rate = UINT16_MAX; ofputil_append_queue_get_config_reply(reply, &queue); } smap_destroy(&details); +} + +static enum ofperr +handle_queue_get_config_request(struct ofconn *ofconn, + const struct ofp_header *oh) +{ + struct ofproto *ofproto = ofconn_get_ofproto(ofconn); + ofp_port_t port; + enum ofperr error; + error = ofputil_decode_queue_get_config_request(oh, &port); + if (error) { + return error; + } + + struct ofpbuf *reply = ofputil_encode_queue_get_config_reply(oh); + struct ofport *ofport; + if (port == OFPP_ANY) { + HMAP_FOR_EACH (ofport, hmap_node, &ofproto->ports) { + put_queue_config(ofport, reply); + } + } else { + ofport = ofproto_get_port(ofproto, port); + if (!ofport) { + ofpbuf_delete(reply); + return OFPERR_OFPQOFC_BAD_PORT; + } + put_queue_config(ofport, reply); + } ofconn_send_reply(ofconn, reply); return 0; diff --git a/tests/ofproto.at b/tests/ofproto.at index 732c1a9..c530b81 100644 --- a/tests/ofproto.at +++ b/tests/ofproto.at @@ -240,6 +240,11 @@ AT_CHECK([ovs-ofctl queue-get-config br0 1], [0], [stdout]) AT_CHECK([STRIP_XIDS stdout], [0], [dnl OFPT_QUEUE_GET_CONFIG_REPLY: port=1 ]) +AT_CHECK([ovs-ofctl queue-get-config br0], [0], [stdout]) +AT_CHECK([STRIP_XIDS stdout | sort], [0], [dnl +OFPT_QUEUE_GET_CONFIG_REPLY: port=1 +OFPT_QUEUE_GET_CONFIG_REPLY: port=2 +]) AT_CHECK([ovs-ofctl queue-get-config br0 10], [0], [OFPT_ERROR (xid=0x2): OFPQOFC_BAD_PORT OFPT_QUEUE_GET_CONFIG_REQUEST (xid=0x2): port=10 @@ -254,6 +259,10 @@ AT_CHECK([ovs-ofctl -O OpenFlow12 queue-get-config br0 1], [0], [stdout]) AT_CHECK([STRIP_XIDS stdout], [0], [dnl OFPT_QUEUE_GET_CONFIG_REPLY (OF1.2): port=1 ]) +AT_CHECK([ovs-ofctl -O OpenFlow12 queue-get-config br0 ANY], [0], [stdout]) +AT_CHECK([STRIP_XIDS stdout], [0], [dnl +OFPT_QUEUE_GET_CONFIG_REPLY (OF1.2): port=ANY +]) AT_CHECK([ovs-ofctl -O OpenFlow12 queue-get-config br0 10], [0], [OFPT_ERROR (OF1.2) (xid=0x2): OFPQOFC_BAD_PORT OFPT_QUEUE_GET_CONFIG_REQUEST (OF1.2) (xid=0x2): port=10 diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in index a6087f6..800ae1a 100644 --- a/utilities/ovs-ofctl.8.in +++ b/utilities/ovs-ofctl.8.in @@ -239,6 +239,17 @@ statistics are printed for all queues on \fIport\fR; if only \fIport\fR is omitted, then statistics are printed for \fIqueue\fR on every port where it exists. . +.IP "\fBqueue\-get\-config \fIswitch \fR[\fIport\fR]" +Prints to the console information about all of the queues configured +on \fIport\fR within \fIswitch\fR. If \fIport\fR is \fBANY\fR or if +it is omitted, prints information about queues on every port. The +OpenFlow specification says that only physical ports have queues; in +particular, \fBLOCAL\fR is not valid for \fIport\fR. +.IP +This command has limited usefulness, because ports often have no +configured queues and because the OpenFlow protocol provides only very +limited information about the configuration of a queue. +. .SS "OpenFlow 1.1+ Group Table Commands" . The following commands work only with switches that support OpenFlow diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index c3892c7..ece705c 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -378,7 +378,7 @@ usage(void) " dump-group-features SWITCH print group features\n" " dump-groups SWITCH [GROUP] print group description\n" " dump-group-stats SWITCH [GROUP] print group statistics\n" - " queue-get-config SWITCH PORT print queue information for port\n" + " queue-get-config SWITCH [PORT] print queue config for PORT\n" " add-meter SWITCH METER add meter described by METER\n" " mod-meter SWITCH METER modify specific METER\n" " del-meter SWITCH METER delete METER\n" @@ -1252,19 +1252,40 @@ static void ofctl_queue_get_config(struct ovs_cmdl_context *ctx) { const char *vconn_name = ctx->argv[1]; - const char *port_name = ctx->argv[2]; - enum ofputil_protocol protocol; - enum ofp_version version; - struct ofpbuf *request; - struct vconn *vconn; - ofp_port_t port; - - port = str_to_port_no(vconn_name, port_name); + const char *port_name = ctx->argc >= 3 ? ctx->argv[2] : NULL; + ofp_port_t port = (port_name + ? str_to_port_no(vconn_name, port_name) + : OFPP_ANY); - protocol = open_vconn(vconn_name, &vconn); - version = ofputil_protocol_to_ofp_version(protocol); - request = ofputil_encode_queue_get_config_request(version, port); - dump_transaction(vconn, request); + struct vconn *vconn; + enum ofputil_protocol protocol = open_vconn(vconn_name, &vconn); + enum ofp_version version = ofputil_protocol_to_ofp_version(protocol); + if (port == OFPP_ANY && version == OFP10_VERSION) { + /* The user requested all queues on all ports. OpenFlow 1.0 only + * supports getting queues for an individual port, so to implement the + * user's request we have to get a list of all the ports. + * + * We use a second vconn to avoid having to accumulate a list of all of + * the ports. */ + struct vconn *vconn2; + enum ofputil_protocol protocol2 = open_vconn(vconn_name, &vconn2); + enum ofp_version version2 = ofputil_protocol_to_ofp_version(protocol2); + + struct port_iterator pi; + struct ofputil_phy_port pp; + for (port_iterator_init(&pi, vconn); port_iterator_next(&pi, &pp); ) { + if (ofp_to_u16(pp.port_no) < ofp_to_u16(OFPP_MAX)) { + dump_transaction(vconn2, + ofputil_encode_queue_get_config_request( + version2, pp.port_no)); + } + } + port_iterator_destroy(&pi); + vconn_close(vconn2); + } else { + dump_transaction(vconn, ofputil_encode_queue_get_config_request( + version, port)); + } vconn_close(vconn); } @@ -3722,8 +3743,8 @@ static const struct ovs_cmdl_command all_commands[] = { 1, 2, ofctl_dump_aggregate }, { "queue-stats", "switch [port [queue]]", 1, 3, ofctl_queue_stats }, - { "queue-get-config", "switch port", - 2, 2, ofctl_queue_get_config }, + { "queue-get-config", "switch [port]", + 1, 2, ofctl_queue_get_config }, { "add-flow", "switch flow", 2, 2, ofctl_add_flow }, { "add-flows", "switch file",