From: Ben Pfaff Date: Thu, 16 Sep 2010 22:36:57 +0000 (-0700) Subject: ovs-ofctl: Add "queue-stats" command to print queue stats. X-Git-Tag: v1.1.0~1056 X-Git-Url: http://git.onelab.eu/?p=sliver-openvswitch.git;a=commitdiff_plain;h=d2805da2cb2256e9e2efc5074fbe8df55408213f ovs-ofctl: Add "queue-stats" command to print queue stats. --- diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 78f3649ba..5cbfe6c04 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -38,6 +38,7 @@ #include "xtoxll.h" static void ofp_print_port_name(struct ds *string, uint16_t port); +static void ofp_print_queue_name(struct ds *string, uint32_t port); /* Returns a string that represents the contents of the Ethernet frame in the * 'len' bytes starting at 'data' to 'stream' as output by tcpdump. @@ -1165,6 +1166,53 @@ ofp_table_stats_reply(struct ds *string, const void *body, size_t len, } } +static void +ofp_print_queue_name(struct ds *string, uint32_t queue_id) +{ + if (queue_id == OFPQ_ALL) { + ds_put_cstr(string, "ALL"); + } else { + ds_put_format(string, "%"PRIu32, queue_id); + } +} + +static void +ofp_queue_stats_request(struct ds *string, const void *body_, + size_t len OVS_UNUSED, int verbosity OVS_UNUSED) +{ + const struct ofp_queue_stats_request *qsr = body_; + + ds_put_cstr(string, "port="); + ofp_print_port_name(string, ntohs(qsr->port_no)); + + ds_put_cstr(string, " queue="); + ofp_print_queue_name(string, ntohl(qsr->queue_id)); +} + +static void +ofp_queue_stats_reply(struct ds *string, const void *body, size_t len, + int verbosity) +{ + const struct ofp_queue_stats *qs = body; + size_t n = len / sizeof *qs; + ds_put_format(string, " %zu queues\n", n); + if (verbosity < 1) { + return; + } + + for (; n--; qs++) { + ds_put_cstr(string, " port "); + ofp_print_port_name(string, ntohs(qs->port_no)); + ds_put_cstr(string, " queue "); + ofp_print_queue_name(string, ntohl(qs->queue_id)); + ds_put_cstr(string, ": "); + + print_port_stat(string, "bytes=", ntohll(qs->tx_bytes), 1); + print_port_stat(string, "pkts=", ntohll(qs->tx_packets), 1); + print_port_stat(string, "errors=", ntohll(qs->tx_errors), 0); + } +} + static void vendor_stat(struct ds *string, const void *body, size_t len, int verbosity OVS_UNUSED) @@ -1234,6 +1282,14 @@ print_stats(struct ds *string, int type, const void *body, size_t body_len, ofp_port_stats_request }, { 0, SIZE_MAX, ofp_port_stats_reply }, }, + { + OFPST_QUEUE, + "queue", + { sizeof(struct ofp_queue_stats_request), + sizeof(struct ofp_queue_stats_request), + ofp_queue_stats_request }, + { 0, SIZE_MAX, ofp_queue_stats_reply }, + }, { OFPST_VENDOR, "vendor-specific", diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in index bbe747b21..c12b5f125 100644 --- a/utilities/ovs-ofctl.8.in +++ b/utilities/ovs-ofctl.8.in @@ -115,6 +115,15 @@ the statistics are aggregated across all flows in the switch's flow tables. See \fBFlow Syntax\fR, below, for the syntax of \fIflows\fR. The output format is descrbed in \fBTable Entry Output\fR. . +.IP "\fBqueue\-stats \fIswitch \fR[\fIport \fR[\fIqueue\fR]]" +Prints to the console statistics for the specified \fIqueue\fR on +\fIport\fR within \fIswitch\fR. Either of \fIport\fR or \fIqueue\fR +or both may be omitted (or equivalently specified as \fBALL\fR). If +both are omitted, statistics are printed for all queues on all ports. +If only \fIqueue\fR is omitted, then 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. +. .TP \fBadd\-flow \fIswitch flow\fR Add the flow entry as described by \fIflow\fR to the \fIswitch\fR's diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index dc6d5e31b..55278fb67 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -150,6 +150,7 @@ usage(void) " dump-flows SWITCH FLOW print matching FLOWs\n" " dump-aggregate SWITCH print aggregate flow statistics\n" " dump-aggregate SWITCH FLOW print aggregate stats for FLOWs\n" + " queue-stats SWITCH [PORT [QUEUE]] dump queue stats\n" " add-flow SWITCH FLOW add flow described by FLOW\n" " add-flows SWITCH FILE add flows from FILE\n" " mod-flows SWITCH FLOW modify actions of matching FLOWs\n" @@ -464,6 +465,30 @@ do_dump_aggregate(int argc, char *argv[]) dump_stats_transaction(argv[1], request); } +static void +do_queue_stats(int argc, char *argv[]) +{ + struct ofp_queue_stats_request *req; + struct ofpbuf *request; + + req = alloc_stats_request(sizeof *req, OFPST_QUEUE, &request); + + if (argc > 2 && argv[2][0] && strcasecmp(argv[2], "all")) { + req->port_no = htons(str_to_port_no(argv[1], argv[2])); + } else { + req->port_no = htons(OFPP_ALL); + } + if (argc > 3 && argv[3][0] && strcasecmp(argv[3], "all")) { + req->queue_id = htonl(atoi(argv[3])); + } else { + req->queue_id = htonl(OFPQ_ALL); + } + + memset(req->pad, 0, sizeof req->pad); + + dump_stats_transaction(argv[1], request); +} + static void do_add_flow(int argc OVS_UNUSED, char *argv[]) { @@ -884,6 +909,7 @@ static const struct command all_commands[] = { { "dump-tables", 1, 1, do_dump_tables }, { "dump-flows", 1, 2, do_dump_flows }, { "dump-aggregate", 1, 2, do_dump_aggregate }, + { "queue-stats", 1, 3, do_queue_stats }, { "add-flow", 2, 2, do_add_flow }, { "add-flows", 2, 2, do_add_flows }, { "mod-flows", 2, 2, do_mod_flows },