From 64626975103668a5662622819536780ba87bef79 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Fri, 12 Oct 2012 13:03:04 +0900 Subject: [PATCH] ofp-msgs: Open Flow 1.1 and 1.2 Queue Status Messages This allows for encoding and decoding Open Flow 1.1 and 1.2 Queue Stats Request and Reply messages. Signed-off-by: Simon Horman Signed-off-by: Ben Pfaff --- lib/ofp-msgs.h | 15 ++- lib/ofp-print.c | 49 +++++----- lib/ofp-util.c | 207 ++++++++++++++++++++++++++++++++++++++++++ lib/ofp-util.h | 24 +++++ ofproto/ofproto.c | 33 ++++--- tests/ofp-print.at | 78 +++++++++++++++- utilities/ovs-ofctl.c | 16 ++-- 7 files changed, 365 insertions(+), 57 deletions(-) diff --git a/lib/ofp-msgs.h b/lib/ofp-msgs.h index 4bcc1b435..f8ac4cd6f 100644 --- a/lib/ofp-msgs.h +++ b/lib/ofp-msgs.h @@ -226,10 +226,14 @@ enum ofpraw { OFPRAW_OFPST11_PORT_REPLY, /* OFPST 1.0 (5): struct ofp10_queue_stats_request. */ - OFPRAW_OFPST_QUEUE_REQUEST, + OFPRAW_OFPST10_QUEUE_REQUEST, + /* OFPST 1.1+ (5): struct ofp11_queue_stats_request. */ + OFPRAW_OFPST11_QUEUE_REQUEST, /* OFPST 1.0 (5): struct ofp10_queue_stats[]. */ - OFPRAW_OFPST_QUEUE_REPLY, + OFPRAW_OFPST10_QUEUE_REPLY, + /* OFPST 1.1+ (5): struct ofp11_queue_stats[]. */ + OFPRAW_OFPST11_QUEUE_REPLY, /* OFPST 1.0+ (13): void. */ OFPRAW_OFPST_PORT_DESC_REQUEST, @@ -392,9 +396,12 @@ enum ofptype { * OFPRAW_OFPST11_PORT_REQUEST. */ OFPTYPE_PORT_STATS_REPLY, /* OFPRAW_OFPST10_PORT_REPLY. * OFPRAW_OFPST11_PORT_REPLY. */ - OFPTYPE_QUEUE_STATS_REQUEST, /* OFPRAW_OFPST_QUEUE_REQUEST. */ - OFPTYPE_QUEUE_STATS_REPLY, /* OFPRAW_OFPST_QUEUE_REPLY. */ + OFPTYPE_QUEUE_STATS_REQUEST, /* OFPRAW_OFPST10_QUEUE_REQUEST. + * OFPRAW_OFPST11_QUEUE_REQUEST. */ + OFPTYPE_QUEUE_STATS_REPLY, /* OFPRAW_OFPST10_QUEUE_REPLY. + * OFPRAW_OFPST11_QUEUE_REPLY. */ OFPTYPE_PORT_DESC_STATS_REQUEST, /* OFPRAW_OFPST_PORT_DESC_REQUEST. */ + OFPTYPE_PORT_DESC_STATS_REPLY, /* OFPRAW_OFPST10_PORT_DESC_REPLY. * OFPRAW_OFPST11_PORT_DESC_REPLY. */ diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 8eb5de4d6..0970a9222 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -1326,54 +1326,55 @@ ofp_print_queue_name(struct ds *string, uint32_t queue_id) static void ofp_print_ofpst_queue_request(struct ds *string, const struct ofp_header *oh) { - const struct ofp10_queue_stats_request *qsr = ofpmsg_body(oh); + struct ofputil_queue_stats_request oqsr; + enum ofperr error; + + error = ofputil_decode_queue_stats_request(oh, &oqsr); + if (error) { + ds_put_format(string, "***decode error: %s***\n", ofperr_get_name(error)); + return; + } ds_put_cstr(string, "port="); - ofputil_format_port(ntohs(qsr->port_no), string); + ofputil_format_port(oqsr.port_no, string); ds_put_cstr(string, " queue="); - ofp_print_queue_name(string, ntohl(qsr->queue_id)); -} - -static void -print_queue_stat(struct ds *string, const char *leader, - const ovs_32aligned_be64 *statp, int more) -{ - print_port_stat(string, leader, ntohll(get_32aligned_be64(statp)), more); + ofp_print_queue_name(string, oqsr.queue_id); } static void ofp_print_ofpst_queue_reply(struct ds *string, const struct ofp_header *oh, int verbosity) { - struct ofp10_queue_stats *qs; struct ofpbuf b; - size_t n; - ofpbuf_use_const(&b, oh, ntohs(oh->length)); - ofpraw_pull_assert(&b); - - n = b.size / sizeof *qs; - ds_put_format(string, " %zu queues\n", n); + ds_put_format(string, " %zu queues\n", ofputil_count_queue_stats(oh)); if (verbosity < 1) { return; } + ofpbuf_use_const(&b, oh, ntohs(oh->length)); for (;;) { - qs = ofpbuf_try_pull(&b, sizeof *qs); - if (!qs) { + struct ofputil_queue_stats qs; + int retval; + + retval = ofputil_decode_queue_stats(&qs, &b); + if (retval) { + if (retval != EOF) { + ds_put_cstr(string, " ***parse error***"); + } return; } ds_put_cstr(string, " port "); - ofputil_format_port(ntohs(qs->port_no), string); + ofputil_format_port(qs.port_no, string); ds_put_cstr(string, " queue "); - ofp_print_queue_name(string, ntohl(qs->queue_id)); + ofp_print_queue_name(string, qs.queue_id); ds_put_cstr(string, ": "); - print_queue_stat(string, "bytes=", &qs->tx_bytes, 1); - print_queue_stat(string, "pkts=", &qs->tx_packets, 1); - print_queue_stat(string, "errors=", &qs->tx_errors, 0); + print_port_stat(string, "bytes=", qs.stats.tx_bytes, 1); + print_port_stat(string, "pkts=", qs.stats.tx_packets, 1); + print_port_stat(string, "errors=", qs.stats.tx_errors, 0); } } diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 848455d12..0f49cdcf9 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -4179,3 +4179,210 @@ ofputil_decode_port_stats_request(const struct ofp_header *request, NOT_REACHED(); } } + +/* Parse a queue status request message into 'oqsr'. + * Returns 0 if successful, otherwise an OFPERR_* number. */ +enum ofperr +ofputil_decode_queue_stats_request(const struct ofp_header *request, + struct ofputil_queue_stats_request *oqsr) +{ + switch ((enum ofp_version)request->version) { + case OFP12_VERSION: + case OFP11_VERSION: { + const struct ofp11_queue_stats_request *qsr11 = ofpmsg_body(request); + oqsr->queue_id = ntohl(qsr11->queue_id); + return ofputil_port_from_ofp11(qsr11->port_no, &oqsr->port_no); + } + + case OFP10_VERSION: { + const struct ofp10_queue_stats_request *qsr11 = ofpmsg_body(request); + oqsr->queue_id = ntohl(qsr11->queue_id); + oqsr->port_no = ntohs(qsr11->port_no); + return 0; + } + + default: + NOT_REACHED(); + } +} + +/* Encode a queue statsrequest for 'oqsr', the encoded message + * will be fore Open Flow version 'ofp_version'. Returns message + * as a struct ofpbuf. Returns encoded message on success, NULL on error */ +struct ofpbuf * +ofputil_encode_queue_stats_request(enum ofp_version ofp_version, + const struct ofputil_queue_stats_request *oqsr) +{ + struct ofpbuf *request; + + switch (ofp_version) { + case OFP11_VERSION: + case OFP12_VERSION: { + struct ofp11_queue_stats_request *req; + request = ofpraw_alloc(OFPRAW_OFPST11_QUEUE_REQUEST, ofp_version, 0); + req = ofpbuf_put_zeros(request, sizeof *req); + req->port_no = ofputil_port_to_ofp11(oqsr->port_no); + req->queue_id = htonl(oqsr->queue_id); + break; + } + case OFP10_VERSION: { + struct ofp10_queue_stats_request *req; + request = ofpraw_alloc(OFPRAW_OFPST10_QUEUE_REQUEST, ofp_version, 0); + req = ofpbuf_put_zeros(request, sizeof *req); + req->port_no = htons(oqsr->port_no); + req->queue_id = htonl(oqsr->queue_id); + break; + } + default: + NOT_REACHED(); + } + + return request; +} + +/* Returns the number of queue stats elements in OFPTYPE_QUEUE_STATS_REPLY + * message 'oh'. */ +size_t +ofputil_count_queue_stats(const struct ofp_header *oh) +{ + struct ofpbuf b; + + ofpbuf_use_const(&b, oh, ntohs(oh->length)); + ofpraw_pull_assert(&b); + + BUILD_ASSERT(sizeof(struct ofp10_queue_stats) == + sizeof(struct ofp11_queue_stats)); + return b.size / sizeof(struct ofp10_queue_stats); +} + +static enum ofperr +ofputil_queue_stats_from_ofp10(struct ofputil_queue_stats *oqs, + const struct ofp10_queue_stats *qs10) +{ + oqs->port_no = ntohs(qs10->port_no); + oqs->queue_id = ntohl(qs10->queue_id); + oqs->stats.tx_bytes = ntohll(get_32aligned_be64(&qs10->tx_bytes)); + oqs->stats.tx_packets = ntohll(get_32aligned_be64(&qs10->tx_packets)); + oqs->stats.tx_errors = ntohll(get_32aligned_be64(&qs10->tx_errors)); + + return 0; +} + +static enum ofperr +ofputil_queue_stats_from_ofp11(struct ofputil_queue_stats *oqs, + const struct ofp11_queue_stats *qs11) +{ + enum ofperr error; + + error = ofputil_port_from_ofp11(qs11->port_no, &oqs->port_no); + if (error) { + return error; + } + + oqs->queue_id = ntohl(qs11->queue_id); + oqs->stats.tx_bytes = ntohll(qs11->tx_bytes); + oqs->stats.tx_packets = ntohll(qs11->tx_packets); + oqs->stats.tx_errors = ntohll(qs11->tx_errors); + + return 0; +} + +/* Converts an OFPST_QUEUE_STATS reply in 'msg' into an abstract + * ofputil_queue_stats in 'qs'. + * + * Multiple OFPST_QUEUE_STATS replies can be packed into a single OpenFlow + * message. Calling this function multiple times for a single 'msg' iterates + * through the replies. The caller must initially leave 'msg''s layer pointers + * null and not modify them between calls. + * + * Returns 0 if successful, EOF if no replies were left in this 'msg', + * otherwise a positive errno value. */ +int +ofputil_decode_queue_stats(struct ofputil_queue_stats *qs, struct ofpbuf *msg) +{ + enum ofperr error; + enum ofpraw raw; + + error = (msg->l2 + ? ofpraw_decode(&raw, msg->l2) + : ofpraw_pull(&raw, msg)); + if (error) { + return error; + } + + if (!msg->size) { + return EOF; + } else if (raw == OFPRAW_OFPST11_QUEUE_REPLY) { + const struct ofp11_queue_stats *qs11; + + qs11 = ofpbuf_try_pull(msg, sizeof *qs11); + if (!qs11) { + VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_QUEUE reply has %zu leftover " + "bytes at end", msg->size); + return OFPERR_OFPBRC_BAD_LEN; + } + return ofputil_queue_stats_from_ofp11(qs, qs11); + } else if (raw == OFPRAW_OFPST10_QUEUE_REPLY) { + const struct ofp10_queue_stats *qs10; + + qs10 = ofpbuf_try_pull(msg, sizeof *qs10); + if (!qs10) { + VLOG_WARN_RL(&bad_ofmsg_rl, "OFPST_QUEUE reply has %zu leftover " + "bytes at end", msg->size); + return OFPERR_OFPBRC_BAD_LEN; + } + return ofputil_queue_stats_from_ofp10(qs, qs10); + } else { + NOT_REACHED(); + } +} + +static void +ofputil_queue_stats_to_ofp10(const struct ofputil_queue_stats *oqs, + struct ofp10_queue_stats *qs10) +{ + qs10->port_no = htons(oqs->port_no); + memset(qs10->pad, 0, sizeof qs10->pad); + qs10->queue_id = htonl(oqs->queue_id); + put_32aligned_be64(&qs10->tx_bytes, htonll(oqs->stats.tx_bytes)); + put_32aligned_be64(&qs10->tx_packets, htonll(oqs->stats.tx_packets)); + put_32aligned_be64(&qs10->tx_errors, htonll(oqs->stats.tx_errors)); +} + +static void +ofputil_queue_stats_to_ofp11(const struct ofputil_queue_stats *oqs, + struct ofp11_queue_stats *qs11) +{ + qs11->port_no = ofputil_port_to_ofp11(oqs->port_no); + qs11->queue_id = htonl(oqs->queue_id); + qs11->tx_bytes = htonll(oqs->stats.tx_bytes); + qs11->tx_packets = htonll(oqs->stats.tx_packets); + qs11->tx_errors = htonll(oqs->stats.tx_errors); +} + +/* Encode a queue stat for 'oqs' and append it to 'replies'. */ +void +ofputil_append_queue_stat(struct list *replies, + const struct ofputil_queue_stats *oqs) +{ + struct ofpbuf *msg = ofpbuf_from_list(list_back(replies)); + struct ofp_header *oh = msg->data; + + switch ((enum ofp_version)oh->version) { + case OFP12_VERSION: + case OFP11_VERSION: { + struct ofp11_queue_stats *reply = ofpmp_append(replies, sizeof *reply);; + ofputil_queue_stats_to_ofp11(oqs, reply); + break; + } + + case OFP10_VERSION: { + struct ofp10_queue_stats *reply = ofpmp_append(replies, sizeof *reply);; + ofputil_queue_stats_to_ofp10(oqs, reply); + break; + } + + default: + NOT_REACHED(); + } +} diff --git a/lib/ofp-util.h b/lib/ofp-util.h index edfe076f1..2f73ec2bf 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -635,4 +635,28 @@ size_t ofputil_count_port_stats(const struct ofp_header *); int ofputil_decode_port_stats(struct ofputil_port_stats *, struct ofpbuf *msg); enum ofperr ofputil_decode_port_stats_request(const struct ofp_header *request, uint16_t *ofp10_port); + +struct ofputil_queue_stats_request { + uint16_t port_no; + uint32_t queue_id; +}; + +enum ofperr +ofputil_decode_queue_stats_request(const struct ofp_header *request, + struct ofputil_queue_stats_request *oqsr); +struct ofpbuf * +ofputil_encode_queue_stats_request(enum ofp_version ofp_version, + const struct ofputil_queue_stats_request *oqsr); + +struct ofputil_queue_stats { + uint16_t port_no; + uint32_t queue_id; + struct netdev_queue_stats stats; +}; + +size_t ofputil_count_queue_stats(const struct ofp_header *); +int ofputil_decode_queue_stats(struct ofputil_queue_stats *qs, struct ofpbuf *msg); +void ofputil_append_queue_stat(struct list *replies, + const struct ofputil_queue_stats *oqs); + #endif /* ofp-util.h */ diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 97e00ab4f..a128a6d9c 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -2775,15 +2775,13 @@ static void put_queue_stats(struct queue_stats_cbdata *cbdata, uint32_t queue_id, const struct netdev_queue_stats *stats) { - struct ofp10_queue_stats *reply; - reply = ofpmp_append(&cbdata->replies, sizeof *reply); - reply->port_no = htons(cbdata->ofport->pp.port_no); - memset(reply->pad, 0, sizeof reply->pad); - reply->queue_id = htonl(queue_id); - put_32aligned_be64(&reply->tx_bytes, htonll(stats->tx_bytes)); - put_32aligned_be64(&reply->tx_packets, htonll(stats->tx_packets)); - put_32aligned_be64(&reply->tx_errors, htonll(stats->tx_errors)); + struct ofputil_queue_stats oqs = { + .port_no = cbdata->ofport->pp.port_no, + .queue_id = queue_id, + .stats = *stats, + }; + ofputil_append_queue_stat(&cbdata->replies, &oqs); } static void @@ -2821,30 +2819,31 @@ handle_queue_stats_request(struct ofconn *ofconn, const struct ofp_header *rq) { struct ofproto *ofproto = ofconn_get_ofproto(ofconn); - const struct ofp10_queue_stats_request *qsr = ofpmsg_body(rq); struct queue_stats_cbdata cbdata; - unsigned int port_no; struct ofport *port; - uint32_t queue_id; enum ofperr error; + struct ofputil_queue_stats_request oqsr; COVERAGE_INC(ofproto_queue_req); ofpmp_init(&cbdata.replies, rq); - port_no = ntohs(qsr->port_no); - queue_id = ntohl(qsr->queue_id); - if (port_no == OFPP_ALL) { + error = ofputil_decode_queue_stats_request(rq, &oqsr); + if (error) { + return error; + } + + if (oqsr.port_no == OFPP_ALL) { error = OFPERR_OFPQOFC_BAD_QUEUE; HMAP_FOR_EACH (port, hmap_node, &ofproto->ports) { - if (!handle_queue_stats_for_port(port, queue_id, &cbdata)) { + if (!handle_queue_stats_for_port(port, oqsr.queue_id, &cbdata)) { error = 0; } } } else { - port = ofproto_get_port(ofproto, port_no); + port = ofproto_get_port(ofproto, oqsr.port_no); error = (port - ? handle_queue_stats_for_port(port, queue_id, &cbdata) + ? handle_queue_stats_for_port(port, oqsr.queue_id, &cbdata) : OFPERR_OFPQOFC_BAD_PORT); } if (!error) { diff --git a/tests/ofp-print.at b/tests/ofp-print.at index ad366174e..f1fdefb4f 100644 --- a/tests/ofp-print.at +++ b/tests/ofp-print.at @@ -1057,7 +1057,7 @@ OFPST_PORT reply (OF1.2) (xid=0x2): 3 ports ]) AT_CLEANUP -AT_SETUP([OFPST_QUEUE request]) +AT_SETUP([OFPST_QUEUE request - OF1.0]) AT_KEYWORDS([ofp-print OFPT_STATS_REQUEST]) AT_CHECK([ovs-ofctl ofp-print "\ 01 10 00 14 00 00 00 01 00 05 00 00 ff fc 00 00 \ @@ -1067,7 +1067,27 @@ OFPST_QUEUE request (xid=0x1):port=ALL queue=ALL ]) AT_CLEANUP -AT_SETUP([OFPST_QUEUE reply]) +AT_SETUP([OFPST_QUEUE request - OF1.1]) +AT_KEYWORDS([ofp-print OFPT_STATS_REQUEST]) +AT_CHECK([ovs-ofctl ofp-print "\ +02 12 00 18 00 00 00 02 00 05 00 00 00 00 00 00 \ +ff ff ff fc ff ff ff ff \ +"], [0], [dnl +OFPST_QUEUE request (OF1.1) (xid=0x2):port=ALL queue=ALL +]) +AT_CLEANUP + +AT_SETUP([OFPST_QUEUE request - OF1.2]) +AT_KEYWORDS([ofp-print OFPT_STATS_REQUEST]) +AT_CHECK([ovs-ofctl ofp-print "\ +03 12 00 18 00 00 00 02 00 05 00 00 00 00 00 00 \ +ff ff ff fc ff ff ff ff \ +"], [0], [dnl +OFPST_QUEUE request (OF1.2) (xid=0x2):port=ALL queue=ALL +]) +AT_CLEANUP + +AT_SETUP([OFPST_QUEUE reply - OF1.0]) AT_KEYWORDS([ofp-print OFPT_STATS_REPLY]) AT_CHECK([ovs-ofctl ofp-print "\ 01 11 00 cc 00 00 00 01 00 05 00 00 00 03 00 00 \ @@ -1101,6 +1121,60 @@ OFPST_PORT_DESC request (xid=0x1): ]) AT_CLEANUP +AT_SETUP([OFPST_QUEUE reply - OF1.1]) +AT_KEYWORDS([ofp-print OFPT_STATS_REPLY]) +AT_CHECK([ovs-ofctl ofp-print "\ +02 13 00 d0 00 00 00 01 00 05 00 00 00 00 00 00 \ +00 00 00 03 00 00 00 01 00 00 00 00 00 00 01 2e \ +00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 \ +00 00 00 03 00 00 00 02 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ +00 00 00 02 00 00 00 01 00 00 00 00 00 00 08 34 \ +00 00 00 00 00 00 00 14 00 00 00 00 00 00 00 00 \ +00 00 00 02 00 00 00 02 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ +00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ +00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ +"], [0], [dnl +OFPST_QUEUE reply (OF1.1) (xid=0x1): 6 queues + port 3 queue 1: bytes=302, pkts=1, errors=0 + port 3 queue 2: bytes=0, pkts=0, errors=0 + port 2 queue 1: bytes=2100, pkts=20, errors=0 + port 2 queue 2: bytes=0, pkts=0, errors=0 + port 1 queue 1: bytes=0, pkts=0, errors=0 + port 1 queue 2: bytes=0, pkts=0, errors=0 +]) +AT_CLEANUP + +AT_SETUP([OFPST_QUEUE reply - OF1.2]) +AT_KEYWORDS([ofp-print OFPT_STATS_REPLY]) +AT_CHECK([ovs-ofctl ofp-print "\ +03 13 00 d0 00 00 00 01 00 05 00 00 00 00 00 00 \ +00 00 00 03 00 00 00 01 00 00 00 00 00 00 01 2e \ +00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 \ +00 00 00 03 00 00 00 02 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ +00 00 00 02 00 00 00 01 00 00 00 00 00 00 08 34 \ +00 00 00 00 00 00 00 14 00 00 00 00 00 00 00 00 \ +00 00 00 02 00 00 00 02 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ +00 00 00 01 00 00 00 01 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ +00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 00 \ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ +"], [0], [dnl +OFPST_QUEUE reply (OF1.2) (xid=0x1): 6 queues + port 3 queue 1: bytes=302, pkts=1, errors=0 + port 3 queue 2: bytes=0, pkts=0, errors=0 + port 2 queue 1: bytes=2100, pkts=20, errors=0 + port 2 queue 2: bytes=0, pkts=0, errors=0 + port 1 queue 1: bytes=0, pkts=0, errors=0 + port 1 queue 2: bytes=0, pkts=0, errors=0 +]) +AT_CLEANUP + AT_SETUP([OFPST_PORT_DESC reply - OF1.0]) AT_KEYWORDS([ofp-print OFPT_STATS_REPLY]) AT_CHECK([ovs-ofctl ofp-print "\ diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 5a1f10658..a0b70793b 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -948,28 +948,24 @@ ofctl_dump_aggregate(int argc, char *argv[]) static void ofctl_queue_stats(int argc, char *argv[]) { - struct ofp10_queue_stats_request *req; struct ofpbuf *request; struct vconn *vconn; + struct ofputil_queue_stats_request oqs; open_vconn(argv[1], &vconn); - request = ofpraw_alloc(OFPRAW_OFPST_QUEUE_REQUEST, - vconn_get_version(vconn), 0); - 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])); + oqs.port_no = str_to_port_no(argv[1], argv[2]); } else { - req->port_no = htons(OFPP_ALL); + oqs.port_no = OFPP_ALL; } if (argc > 3 && argv[3][0] && strcasecmp(argv[3], "all")) { - req->queue_id = htonl(atoi(argv[3])); + oqs.queue_id = atoi(argv[3]); } else { - req->queue_id = htonl(OFPQ_ALL); + oqs.queue_id = OFPQ_ALL; } - memset(req->pad, 0, sizeof req->pad); - + request = ofputil_encode_queue_stats_request(vconn_get_version(vconn), &oqs); dump_stats_transaction(vconn, request); vconn_close(vconn); } -- 2.20.1