summaryrefslogtreecommitdiff
path: root/lib/ofp-queue.c
diff options
context:
space:
mode:
authorBen Pfaff <blp@ovn.org>2018-06-15 17:06:56 -0700
committerBen Pfaff <blp@ovn.org>2018-06-18 15:25:44 -0700
commitfe2c69f49cb3cb0ab2cc2ae84b364970f5e77392 (patch)
treed2f803e322099a4d8e754b3d36ce43cc4c94007d /lib/ofp-queue.c
parent16ee87263e31dc6520937a0dcefd676f3582d8ee (diff)
downloadopenvswitch-fe2c69f49cb3cb0ab2cc2ae84b364970f5e77392.tar.gz
ofp-print: Move significant formatting code into more specific .c files.
Signed-off-by: Ben Pfaff <blp@ovn.org> Acked-by: Justin Pettit <jpettit@ovn.org>
Diffstat (limited to 'lib/ofp-queue.c')
-rw-r--r--lib/ofp-queue.c196
1 files changed, 196 insertions, 0 deletions
diff --git a/lib/ofp-queue.c b/lib/ofp-queue.c
index b3f681b0d..1c939878e 100644
--- a/lib/ofp-queue.c
+++ b/lib/ofp-queue.c
@@ -19,6 +19,7 @@
#include "byte-order.h"
#include "flow.h"
#include "openvswitch/ofp-msgs.h"
+#include "openvswitch/ofp-print.h"
#include "openvswitch/ofp-port.h"
#include "openvswitch/ofp-prop.h"
#include "openvswitch/ofpbuf.h"
@@ -29,6 +30,18 @@ VLOG_DEFINE_THIS_MODULE(ofp_queue);
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
+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);
+ }
+}
+
+/* OFPT_QUEUE_GET_CONFIG request and reply. */
+
/* Constructs and returns an OFPT_QUEUE_GET_CONFIG request for the specified
* 'port' and 'queue', suitable for OpenFlow version 'version'.
*
@@ -111,6 +124,31 @@ ofputil_decode_queue_get_config_request(const struct ofp_header *oh,
: OFPERR_OFPQOFC_BAD_PORT);
}
+enum ofperr
+ofputil_queue_get_config_request_format(
+ struct ds *string, const struct ofp_header *oh,
+ const struct ofputil_port_map *port_map)
+{
+ enum ofperr error;
+ ofp_port_t port;
+ uint32_t queue;
+
+ error = ofputil_decode_queue_get_config_request(oh, &port, &queue);
+ if (error) {
+ return error;
+ }
+
+ ds_put_cstr(string, " port=");
+ ofputil_format_port(port, port_map, string);
+
+ if (queue != OFPQ_ALL) {
+ ds_put_cstr(string, " queue=");
+ ofp_print_queue_name(string, queue);
+ }
+
+ return 0;
+}
+
/* Constructs and returns the beginning of a reply to
* OFPT_QUEUE_GET_CONFIG_REQUEST or OFPMP_QUEUE_DESC request 'oh'. The caller
* may append information about individual queues with
@@ -419,6 +457,83 @@ ofputil_pull_queue_get_config_reply(struct ofpbuf *msg,
return ofputil_pull_queue_get_config_reply10(msg, queue);
}
}
+
+static void
+print_queue_rate(struct ds *string, const char *name, unsigned int rate)
+{
+ if (rate <= 1000) {
+ ds_put_format(string, " %s:%u.%u%%", name, rate / 10, rate % 10);
+ } else if (rate < UINT16_MAX) {
+ ds_put_format(string, " %s:(disabled)", name);
+ }
+}
+
+/* qsort comparison function. */
+static int
+compare_queues(const void *a_, const void *b_)
+{
+ const struct ofputil_queue_config *a = a_;
+ const struct ofputil_queue_config *b = b_;
+
+ uint16_t ap = ofp_to_u16(a->port);
+ uint16_t bp = ofp_to_u16(b->port);
+ if (ap != bp) {
+ return ap < bp ? -1 : 1;
+ }
+
+ uint32_t aq = a->queue;
+ uint32_t bq = b->queue;
+ return aq < bq ? -1 : aq > bq;
+}
+
+enum ofperr
+ofputil_queue_get_config_reply_format(struct ds *string,
+ const struct ofp_header *oh,
+ const struct ofputil_port_map *port_map)
+{
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
+
+ struct ofputil_queue_config *queues = NULL;
+ size_t allocated_queues = 0;
+ size_t n = 0;
+
+ int retval = 0;
+ for (;;) {
+ if (n >= allocated_queues) {
+ queues = x2nrealloc(queues, &allocated_queues, sizeof *queues);
+ }
+ retval = ofputil_pull_queue_get_config_reply(&b, &queues[n]);
+ if (retval) {
+ break;
+ }
+ n++;
+ }
+
+ qsort(queues, n, sizeof *queues, compare_queues);
+
+ ds_put_char(string, ' ');
+
+ ofp_port_t port = 0;
+ for (const struct ofputil_queue_config *q = queues; q < &queues[n]; q++) {
+ if (q->port != port) {
+ port = q->port;
+
+ ds_put_cstr(string, "port=");
+ ofputil_format_port(port, port_map, string);
+ ds_put_char(string, '\n');
+ }
+
+ ds_put_format(string, "queue %"PRIu32":", q->queue);
+ print_queue_rate(string, "min_rate", q->min_rate);
+ print_queue_rate(string, "max_rate", q->max_rate);
+ ds_put_char(string, '\n');
+ }
+
+ ds_chomp(string, ' ');
+ free(queues);
+
+ return retval != EOF ? retval : 0;
+}
/* Parse a queue status request message into 'oqsr'.
* Returns 0 if successful, otherwise an OFPERR_* number. */
@@ -495,6 +610,28 @@ ofputil_encode_queue_stats_request(
return request;
}
+enum ofperr
+ofputil_queue_stats_request_format(struct ds *string,
+ const struct ofp_header *oh,
+ const struct ofputil_port_map *port_map)
+{
+ struct ofputil_queue_stats_request oqsr;
+ enum ofperr error;
+
+ error = ofputil_decode_queue_stats_request(oh, &oqsr);
+ if (error) {
+ return error;
+ }
+
+ ds_put_cstr(string, " port=");
+ ofputil_format_port(oqsr.port_no, port_map, string);
+
+ ds_put_cstr(string, " queue=");
+ ofp_print_queue_name(string, oqsr.queue_id);
+
+ return 0;
+}
+
/* Returns the number of queue stats elements in OFPTYPE_QUEUE_STATS_REPLY
* message 'oh'. */
size_t
@@ -726,3 +863,62 @@ ofputil_append_queue_stat(struct ovs_list *replies,
}
}
+static void
+print_queue_stat(struct ds *string, const char *leader, uint64_t stat,
+ int more)
+{
+ ds_put_cstr(string, leader);
+ if (stat != UINT64_MAX) {
+ ds_put_format(string, "%"PRIu64, stat);
+ } else {
+ ds_put_char(string, '?');
+ }
+ if (more) {
+ ds_put_cstr(string, ", ");
+ } else {
+ ds_put_cstr(string, "\n");
+ }
+}
+
+enum ofperr
+ofputil_queue_stats_reply_format(struct ds *string,
+ const struct ofp_header *oh,
+ const struct ofputil_port_map *port_map,
+ int verbosity)
+{
+ ds_put_format(string, " %"PRIuSIZE" queues\n",
+ ofputil_count_queue_stats(oh));
+ if (verbosity < 1) {
+ return 0;
+ }
+
+ struct ofpbuf b = ofpbuf_const_initializer(oh, ntohs(oh->length));
+ for (;;) {
+ struct ofputil_queue_stats qs;
+ int retval;
+
+ retval = ofputil_decode_queue_stats(&qs, &b);
+ if (retval) {
+ return retval != EOF ? retval : 0;
+ }
+
+ ds_put_cstr(string, " port ");
+ ofputil_format_port(qs.port_no, port_map, string);
+ ds_put_cstr(string, " queue ");
+ 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, 1);
+
+ ds_put_cstr(string, "duration=");
+ if (qs.duration_sec != UINT32_MAX) {
+ ofp_print_duration(string, qs.duration_sec, qs.duration_nsec);
+ } else {
+ ds_put_char(string, '?');
+ }
+ ds_put_char(string, '\n');
+ }
+}
+