From: Venkitachalam Gopalakrishnan <[email protected]>
---
lib/ofp-util.c | 32 ++++++++++++++++++++++
lib/ofp-util.h | 5 ++++
ofproto/ofproto.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++-
utilities/ovs-ofctl.c | 42 ++++++++++++++++++++++++++++
4 files changed, 151 insertions(+), 1 deletion(-)
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index b181a0d..93e3f14 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -2185,6 +2185,38 @@ ofputil_decode_nxst_flow_request(struct
ofputil_flow_stats_request *fsr,
return 0;
}
+/* Decode func to decode a queue_get_config_request. */
+enum ofperr
+ofputil_decode_queue_get_config_request
+ (struct ofp11_queue_get_config_request *request,
+ const struct ofp_header *oh)
+{
+ enum ofpraw raw;
+ struct ofpbuf b;
+ enum ofperr status;
+ struct ofp11_queue_get_config_request *inreq;
+ ofp_port_t ofp_port;
+
+ ofpbuf_use_const(&b, oh, ntohs(oh->length));
+ raw = ofpraw_pull_assert(&b);
+
+ switch ((int)raw) {
+ /* There is no 1.0 decode yet. To be added later. */
+
+ case OFPRAW_OFPT11_QUEUE_GET_CONFIG_REQUEST:
+ inreq = (struct ofp11_queue_get_config_request *) (b.data);
+ if ((status = ofputil_port_from_ofp11(inreq->port, &ofp_port)) != 0)
+ return status;
+
+ request->port = ofputil_port_to_ofp11(ofp_port);
+ return 0;
+
+ default:
+ NOT_REACHED();
+ }
+ return 0;
+}
+
/* Converts an OFPST_FLOW, OFPST_AGGREGATE, NXST_FLOW, or NXST_AGGREGATE
* request 'oh', into an abstract flow_stats_request in 'fsr'. Returns 0 if
* successful, otherwise an OpenFlow error code. */
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index 6de2a05..7e2a769 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -26,6 +26,7 @@
#include "match.h"
#include "netdev.h"
#include "openflow/nicira-ext.h"
+#include "openflow/openflow-1.1.h"
#include "openvswitch/types.h"
#include "type-props.h"
@@ -331,6 +332,10 @@ int ofputil_decode_flow_stats_reply(struct
ofputil_flow_stats *,
void ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *,
struct list *replies);
+enum ofperr ofputil_decode_queue_get_config_request(
+ struct ofp11_queue_get_config_request *request,
+ const struct ofp_header *);
+
/* Aggregate stats reply, independent of protocol. */
struct ofputil_aggregate_stats {
uint64_t packet_count; /* Packet count, UINT64_MAX if unknown. */
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index dacbb71..791332e 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -49,6 +49,7 @@
#include "random.h"
#include "shash.h"
#include "simap.h"
+#include "smap.h"
#include "sset.h"
#include "timeval.h"
#include "unaligned.h"
@@ -4880,6 +4881,74 @@ 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)
+{
+ struct ofproto *p = ofconn_get_ofproto(ofconn);
+ struct ofpbuf *msg;
+ struct ofp11_queue_get_config_request request;
+ struct ofp11_queue_get_config_reply reply;
+ struct ofport *ofp_port;
+ enum ofperr oferr;
+ struct netdev_queue_dump queue_dump;
+ unsigned int queue_id;
+ struct smap details;
+
+ /* The reply here has
+ * the port which is queried
+ * A list of queue_properties.
+ * We will add the port to the msg and then
+ * append each queue property via encode and finally send
+ * the reply.
+ */
+
+ /* Decode the request. */
+ oferr = ofputil_decode_queue_get_config_request(&request, oh);
+ if (oferr != 0)
+ return oferr;
+
+ /* Now check whether this port number actually exists. */
+ if (!(ofp_port = ofproto_get_port(p, request.port))) {
+ return OFPERR_OFPQOFC_BAD_PORT;
+ }
+
+ /* Now let us form the reply buffer.
+ * First add the port to it.
+ */
+ msg = ofpraw_alloc_reply(OFPRAW_OFPT11_QUEUE_GET_CONFIG_REPLY,
+ oh, 0);
+
+ memset(&reply, 0x00, sizeof(reply));
+ reply.port = ofputil_port_to_ofp11(request.port);
+ ofpbuf_put(msg, &reply, sizeof(reply));
+
+ /* Now we will loop thro each queue for this port and
+ * add that to the buffer before we reply. */
+
+ smap_init(&details);
+
+ NETDEV_QUEUE_FOR_EACH(&queue_id, &details, &queue_dump, ofp_port->netdev) {
+ struct ofp_packet_queue q;
+ memset(&q, 0x00, sizeof(struct ofp_packet_queue));
+
+ q.queue_id = htonl(queue_id);
+ q.len = htons(sizeof(struct ofp_packet_queue));
+
+ /* Todo - at a later time, if the queue struct adds more fields,
+ * we would have to add an encode API to get the data encoded
+ * which would be added to the msg here.
+ */
+ ofpbuf_put(msg, &q, sizeof(struct ofp_packet_queue));
+ }
+
+ smap_destroy(&details);
+
+ ofconn_send_reply(ofconn, msg);
+
+ return 0;
+}
+
/* Implements OFPGC11_ADD
* in which no matching flow already exists in the flow table.
*
@@ -5230,8 +5299,10 @@ handle_openflow__(struct ofconn *ofconn, const struct
ofpbuf *msg)
case OFPTYPE_GROUP_FEATURES_STATS_REQUEST:
return handle_group_features_stats_request(ofconn, oh);
- /* FIXME: Change the following once they are implemented: */
case OFPTYPE_QUEUE_GET_CONFIG_REQUEST:
+ return handle_queue_get_config_request(ofconn, oh);
+
+ /* FIXME: Change the following once they are implemented: */
case OFPTYPE_GET_ASYNC_REQUEST:
case OFPTYPE_TABLE_FEATURES_STATS_REQUEST:
return OFPERR_OFPBRC_BAD_TYPE;
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index 9294752..10f10fe 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -308,6 +308,7 @@ usage(void)
" dump-group-features SWITCH print group features\n"
" dump-groups SWITCH print group description\n"
" dump-group-stats SWITCH [GROUP] print group statistics\n"
+ " queue-get-config SWITCH PORT print queue information for port\n"
"\nFor OpenFlow switches and controllers:\n"
" probe TARGET probe whether TARGET is up\n"
" ping TARGET [N] latency of N-byte echos\n"
@@ -2935,6 +2936,46 @@ ofctl_parse_ofp11_instructions(int argc OVS_UNUSED, char
*argv[] OVS_UNUSED)
ds_destroy(&in);
}
+static void
+ofctl_queue_get_config(int argc OVS_UNUSED, char *argv[])
+{
+ uint32_t port;
+ const char *vconn_name = argv[1];
+ struct vconn *vconn;
+ struct ofp11_queue_get_config_request ovs_request;
+ struct ofpbuf *request;
+ struct ofpbuf *reply;
+ bool convert = true;
+ uint32_t inport;
+ char *end = NULL;
+
+ open_vconn(vconn_name, &vconn);
+ request = ofpraw_alloc(OFPRAW_OFPT11_QUEUE_GET_CONFIG_REQUEST,
+ vconn_get_version(vconn), 0);
+
+ memset(&ovs_request, 0x00, sizeof(ovs_request));
+
+ VLOG_WARN("Getting queue config for %s %s",
+ argv[1], argv[2]);
+
+ inport = strtoul(argv[2], &end, 10);
+ if (*argv[2] != '\0' && *end == '\0') {
+ convert = false;
+ }
+
+ if (convert) {
+ port = str_to_port_no(argv[1], argv[2]);
+ ovs_request.port = ofputil_port_to_ofp11(port);
+ VLOG_WARN("Converted port is %d", ovs_request.port);
+ } else {
+ ovs_request.port = htonl(inport);
+ VLOG_WARN("Un Converted port is %d", ovs_request.port);
+ }
+ ofpbuf_put(request, &ovs_request, sizeof(ovs_request));
+ run(vconn_transact(vconn, request, &reply), "talking to %s", vconn_name);
+}
+
+
/* "check-vlan VLAN_TCI VLAN_TCI_MASK": converts the specified vlan_tci and
* mask values to and from various formats and prints the results. */
static void
@@ -3179,6 +3220,7 @@ static const struct command all_commands[] = {
{ "parse-ofp11-match", 0, 0, ofctl_parse_ofp11_match },
{ "parse-ofp11-actions", 0, 0, ofctl_parse_ofp11_actions },
{ "parse-ofp11-instructions", 0, 0, ofctl_parse_ofp11_instructions },
+ { "queue-get-config", 2, 2, ofctl_queue_get_config },
{ "check-vlan", 2, 2, ofctl_check_vlan },
{ "print-error", 1, 1, ofctl_print_error },
{ "encode-error-reply", 2, 2, ofctl_encode_error_reply },
--
1.7.10.4
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev