Signed-off-by: Ben Pfaff <b...@nicira.com>
---
 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
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to