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