Signed-off-by: Ben Pfaff <[email protected]>
---
include/openflow/openflow-1.4.h | 13 ++++++++
lib/ofp-msgs.h | 7 +++--
lib/ofp-util.c | 68 +++++++++++++++++++++++++++--------------
tests/ofp-print.at | 34 +++++++++++++++++++++
tests/ofproto.at | 17 +++++++++++
5 files changed, 114 insertions(+), 25 deletions(-)
diff --git a/include/openflow/openflow-1.4.h b/include/openflow/openflow-1.4.h
index 4a18e1f..f7bdecb 100644
--- a/include/openflow/openflow-1.4.h
+++ b/include/openflow/openflow-1.4.h
@@ -205,6 +205,19 @@ struct ofp14_port_stats {
OFP_ASSERT(sizeof(struct ofp14_port_stats) == 80);
+/* ## ----------------- ## */
+/* ## ofp14_queue_stats ## */
+/* ## ----------------- ## */
+
+struct ofp14_queue_stats {
+ ovs_be16 length; /* Length of this entry. */
+ uint8_t pad[6]; /* Align to 64 bits. */
+ struct ofp13_queue_stats qs;
+ /* Followed by 0 or more properties (none yet defined). */
+};
+OFP_ASSERT(sizeof(struct ofp14_queue_stats) == 48);
+
+
/* ## -------------- ## */
/* ## Miscellaneous. ## */
/* ## -------------- ## */
diff --git a/lib/ofp-msgs.h b/lib/ofp-msgs.h
index 4685354..1687472 100644
--- a/lib/ofp-msgs.h
+++ b/lib/ofp-msgs.h
@@ -316,8 +316,10 @@ enum ofpraw {
OFPRAW_OFPST10_QUEUE_REPLY,
/* OFPST 1.1-1.2 (5): struct ofp11_queue_stats[]. */
OFPRAW_OFPST11_QUEUE_REPLY,
- /* OFPST 1.3+ (5): struct ofp13_queue_stats[]. */
+ /* OFPST 1.3 (5): struct ofp13_queue_stats[]. */
OFPRAW_OFPST13_QUEUE_REPLY,
+ /* OFPST 1.4+ (5): uint8_t[8][]. */
+ OFPRAW_OFPST14_QUEUE_REPLY,
/* OFPST 1.1+ (6): struct ofp11_group_stats_request. */
OFPRAW_OFPST11_GROUP_REQUEST,
@@ -561,7 +563,8 @@ enum ofptype {
* OFPRAW_OFPST11_QUEUE_REQUEST. */
OFPTYPE_QUEUE_STATS_REPLY, /* OFPRAW_OFPST10_QUEUE_REPLY.
* OFPRAW_OFPST11_QUEUE_REPLY.
- * OFPRAW_OFPST13_QUEUE_REPLY. */
+ * OFPRAW_OFPST13_QUEUE_REPLY.
+ * OFPRAW_OFPST14_QUEUE_REPLY. */
OFPTYPE_GROUP_STATS_REQUEST, /* OFPRAW_OFPST11_GROUP_REQUEST. */
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 1728352..0267d8f 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -7132,36 +7132,21 @@ ofputil_encode_queue_stats_request(enum ofp_version
ofp_version,
return request;
}
-static size_t
-ofputil_get_queue_stats_size(enum ofp_version ofp_version)
-{
- switch (ofp_version) {
- case OFP10_VERSION:
- return sizeof(struct ofp10_queue_stats);
- case OFP11_VERSION:
- case OFP12_VERSION:
- return sizeof(struct ofp11_queue_stats);
- case OFP13_VERSION:
- return sizeof(struct ofp13_queue_stats);
- case OFP14_VERSION:
- OVS_NOT_REACHED();
- return 0;
- default:
- OVS_NOT_REACHED();
- }
-}
-
/* 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 ofputil_queue_stats qs;
struct ofpbuf b;
+ size_t n = 0;
ofpbuf_use_const(&b, oh, ntohs(oh->length));
ofpraw_pull_assert(&b);
-
- return ofpbuf_size(&b) / ofputil_get_queue_stats_size(oh->version);
+ while (!ofputil_decode_queue_stats(&qs, &b)) {
+ n++;
+ }
+ return n;
}
static enum ofperr
@@ -7211,6 +7196,29 @@ ofputil_queue_stats_from_ofp13(struct
ofputil_queue_stats *oqs,
return error;
}
+static enum ofperr
+ofputil_pull_ofp14_queue_stats(struct ofputil_queue_stats *oqs,
+ struct ofpbuf *msg)
+{
+ const struct ofp14_queue_stats *qs14;
+ size_t len;
+
+ qs14 = ofpbuf_try_pull(msg, sizeof *qs14);
+ if (!qs14) {
+ return OFPERR_OFPBRC_BAD_LEN;
+ }
+
+ len = ntohs(qs14->length);
+ if (len < sizeof *qs14 || len - sizeof *qs14 > ofpbuf_size(msg)) {
+ return OFPERR_OFPBRC_BAD_LEN;
+ }
+ ofpbuf_pull(msg, len - sizeof *qs14);
+
+ /* No properties yet defined, so ignore them for now. */
+
+ return ofputil_queue_stats_from_ofp13(oqs, &qs14->qs);
+}
+
/* Converts an OFPST_QUEUE_STATS reply in 'msg' into an abstract
* ofputil_queue_stats in 'qs'.
*
@@ -7236,6 +7244,8 @@ ofputil_decode_queue_stats(struct ofputil_queue_stats
*qs, struct ofpbuf *msg)
if (!ofpbuf_size(msg)) {
return EOF;
+ } else if (raw == OFPRAW_OFPST14_QUEUE_REPLY) {
+ return ofputil_pull_ofp14_queue_stats(qs, msg);
} else if (raw == OFPRAW_OFPST13_QUEUE_REPLY) {
const struct ofp13_queue_stats *qs13;
@@ -7307,6 +7317,16 @@ ofputil_queue_stats_to_ofp13(const struct
ofputil_queue_stats *oqs,
}
}
+static void
+ofputil_queue_stats_to_ofp14(const struct ofputil_queue_stats *oqs,
+ struct ofp14_queue_stats *qs14)
+{
+ qs14->length = htons(sizeof *qs14);
+ memset(qs14->pad, 0, sizeof qs14->pad);
+ ofputil_queue_stats_to_ofp13(oqs, &qs14->qs);
+}
+
+
/* Encode a queue stat for 'oqs' and append it to 'replies'. */
void
ofputil_append_queue_stat(struct list *replies,
@@ -7332,9 +7352,11 @@ ofputil_append_queue_stat(struct list *replies,
break;
}
- case OFP14_VERSION:
- OVS_NOT_REACHED();
+ case OFP14_VERSION: {
+ struct ofp14_queue_stats *reply = ofpmp_append(replies, sizeof *reply);
+ ofputil_queue_stats_to_ofp14(oqs, reply);
break;
+ }
default:
OVS_NOT_REACHED();
diff --git a/tests/ofp-print.at b/tests/ofp-print.at
index e90d5bb..a38bd6d 100644
--- a/tests/ofp-print.at
+++ b/tests/ofp-print.at
@@ -1790,6 +1790,40 @@ OFPST_QUEUE reply (OF1.3) (xid=0x1): 6 queues
])
AT_CLEANUP
+AT_SETUP([OFPST_QUEUE reply - OF1.4])
+AT_KEYWORDS([ofp-print OFPT_STATS_REPLY])
+AT_CHECK([ovs-ofctl ofp-print "\
+05 13 01 30 00 00 00 01 00 05 00 00 00 00 00 00 \
+00 30 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 64 1d cd 65 00 00 30 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 64 1d cd 65 00 00 30 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 64 1d cd 65 00 00 30 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 64 1d cd 65 00 00 30 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 64 1d cd 65 00 00 30 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 \
+ff ff ff ff ff ff ff ff \
+"], [0], [dnl
+OFPST_QUEUE reply (OF1.4) (xid=0x1): 6 queues
+ port 3 queue 1: bytes=302, pkts=1, errors=0, duration=100.500s
+ port 3 queue 2: bytes=0, pkts=0, errors=0, duration=100.500s
+ port 2 queue 1: bytes=2100, pkts=20, errors=0, duration=100.500s
+ port 2 queue 2: bytes=0, pkts=0, errors=0, duration=100.500s
+ port 1 queue 1: bytes=0, pkts=0, errors=0, duration=100.500s
+ port 1 queue 2: bytes=0, pkts=0, errors=0, duration=?
+])
+AT_CLEANUP
+
AT_SETUP([OFPST_GROUP request])
AT_KEYWORDS([ofp-print OFPT_STATS_REQUEST])
AT_CHECK([ovs-ofctl ofp-print "\
diff --git a/tests/ofproto.at b/tests/ofproto.at
index 4479c38..b0388c9 100644
--- a/tests/ofproto.at
+++ b/tests/ofproto.at
@@ -180,6 +180,23 @@ OFPST_QUEUE request (OF1.2) (xid=0x2):port=10 queue=ALL
OVS_VSWITCHD_STOP
AT_CLEANUP
+AT_SETUP([ofproto - queue stats - (OpenFlow 1.4)])
+OVS_VSWITCHD_START
+AT_CHECK([ovs-ofctl -O OpenFlow14 -vwarn queue-stats br0], [0], [stdout])
+AT_CHECK([STRIP_XIDS stdout], [0], [dnl
+OFPST_QUEUE reply (OF1.4): 0 queues
+])
+AT_CHECK([ovs-ofctl -O OpenFlow14 -vwarn queue-stats br0 ALL 5], [0],
+ [OFPT_ERROR (OF1.4) (xid=0x2): OFPQOFC_BAD_QUEUE
+OFPST_QUEUE request (OF1.4) (xid=0x2):port=ANY queue=5
+])
+AT_CHECK([ovs-ofctl -O OpenFlow14 -vwarn queue-stats br0 10], [0],
+ [OFPT_ERROR (OF1.4) (xid=0x2): OFPQOFC_BAD_PORT
+OFPST_QUEUE request (OF1.4) (xid=0x2):port=10 queue=ALL
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
dnl This is really bare-bones.
dnl It at least checks request and reply serialization and deserialization.
AT_SETUP([ofproto - queue configuration - (OpenFlow 1.0)])
--
1.9.1
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev