[ovs-dev] [PATCH 02/11] ofp-msgs: Open Flow 1.1 and 1.2 Port Status Messages
Simon Horman
horms at verge.net.au
Thu Sep 20 04:10:41 UTC 2012
This allows for encoding and decoding Open Flow 1.1 and 1.2 Port Stats
Request and Reply message
Signed-off-by: Simon Horman <horms at verge.net.au>
---
v14
* Manual rebase
v13
* Merge the following patches
- ofp-msgs: Split OFPRAW_OFPST_PORT_{REQUEST,REPLY}
- ovs-ofctl: Teach dump-ports about Open Flow 1.1 & 1.2
- ofp-util: Allow encoding of Open Flow 1.1 & 1.2 Port Statistics Reply Messages
- ofp-print: Allow printing of Open Flow 1.1 & 1.2 Port Reply Messages
- ofp-util: Allow decoding of Open Flow 1.1 & 1.2 Port Status Request Messages
- ofp-print: Allow printing of Open Flow 1.1 & 1.2 Port Status Request Messages
* Move encoding and decoding into a helper functions
v12
* No change
v11
* No change
v10
* No change
v9
* Update description - this only prepares for both encoding and decoding
* Add ofp-print test
* Make use of enum ofp_version
* Correct printing of port number for Open Flow 1.0
* Replace UINT64_MAX with htonll(UINT64_MAX) in ofp_print_port_stat()
to correct byte-order problem detected by sparse
v8
* Manual rebase
* Make use of enum ofp_version
* Add ofp-print test
v7
* Omitted
v6
* No change
v5
* No change
v4
* Initial post
---
lib/ofp-msgs.h | 14 +++-
lib/ofp-print.c | 58 +++++++------
lib/ofp-util.c | 215 ++++++++++++++++++++++++++++++++++++++++++++++++-
lib/ofp-util.h | 10 +++
ofproto/ofproto.c | 53 +++++++-----
tests/ofp-print.at | 59 +++++++++++++-
utilities/ovs-ofctl.c | 6 +-
7 files changed, 359 insertions(+), 56 deletions(-)
diff --git a/lib/ofp-msgs.h b/lib/ofp-msgs.h
index 752d12c..6420c5d 100644
--- a/lib/ofp-msgs.h
+++ b/lib/ofp-msgs.h
@@ -216,10 +216,14 @@ enum ofpraw {
OFPRAW_OFPST12_TABLE_REPLY,
/* OFPST 1.0 (4): struct ofp10_port_stats_request. */
- OFPRAW_OFPST_PORT_REQUEST,
+ OFPRAW_OFPST10_PORT_REQUEST,
+ /* OFPST 1.1+ (4): struct ofp11_port_stats_request. */
+ OFPRAW_OFPST11_PORT_REQUEST,
/* OFPST 1.0 (4): struct ofp10_port_stats[]. */
- OFPRAW_OFPST_PORT_REPLY,
+ OFPRAW_OFPST10_PORT_REPLY,
+ /* OFPST 1.1+ (4): struct ofp11_port_stats[]. */
+ OFPRAW_OFPST11_PORT_REPLY,
/* OFPST 1.0 (5): struct ofp10_queue_stats_request. */
OFPRAW_OFPST_QUEUE_REQUEST,
@@ -382,8 +386,10 @@ enum ofptype {
OFPTYPE_TABLE_STATS_REPLY, /* OFPRAW_OFPST10_TABLE_REPLY.
* OFPRAW_OFPST11_TABLE_REPLY.
* OFPRAW_OFPST12_TABLE_REPLY. */
- OFPTYPE_PORT_STATS_REQUEST, /* OFPRAW_OFPST_PORT_REQUEST. */
- OFPTYPE_PORT_STATS_REPLY, /* OFPRAW_OFPST_PORT_REPLY. */
+ OFPTYPE_PORT_STATS_REQUEST, /* OFPRAW_OFPST10_PORT_REQUEST.
+ * OFPRAW_OFPST11_PORT_REQUEST. */
+ OFPTYPE_PORT_STATS_REPLY, /* OFPRAW_OFPST10_PORT_REPLY.
+ * OFPRAW_OFPST11_PORT_REPLY. */
OFPTYPE_QUEUE_STATS_REQUEST, /* OFPRAW_OFPST_QUEUE_REQUEST. */
OFPTYPE_QUEUE_STATS_REPLY, /* OFPRAW_OFPST_QUEUE_REPLY. */
OFPTYPE_PORT_DESC_STATS_REQUEST, /* OFPRAW_OFPST_PORT_DESC_REQUEST. */
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 6789625..25aa9b9 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -1061,14 +1061,12 @@ ofp_print_aggregate_stats_reply(struct ds *string, const struct ofp_header *oh)
ds_put_format(string, " flow_count=%"PRIu32, as.flow_count);
}
-static void print_port_stat(struct ds *string, const char *leader,
- const ovs_32aligned_be64 *statp, int more)
+static void ofp_print_port_stat(struct ds *string, const char *leader,
+ ovs_be64 stat, int more)
{
- uint64_t stat = ntohll(get_32aligned_be64(statp));
-
ds_put_cstr(string, leader);
- if (stat != UINT64_MAX) {
- ds_put_format(string, "%"PRIu64, stat);
+ if (stat != htonll(UINT64_MAX)) {
+ ds_put_format(string, "%"PRIu64, ntohll(stat));
} else {
ds_put_char(string, '?');
}
@@ -1079,24 +1077,34 @@ static void print_port_stat(struct ds *string, const char *leader,
}
}
+static void print_port_stat(struct ds *string, const char *leader,
+ const ovs_32aligned_be64 *statp, int more)
+{
+ ofp_print_port_stat(string, leader, get_32aligned_be64(statp), more);
+}
+
static void
ofp_print_ofpst_port_request(struct ds *string, const struct ofp_header *oh)
{
- const struct ofp10_port_stats_request *psr = ofpmsg_body(oh);
- ds_put_format(string, " port_no=%"PRIu16, ntohs(psr->port_no));
+ ovs_be32 ofp11_port = ofptutil_decode_port_stats_request(oh);
+
+ ds_put_cstr(string, " port_no=");
+ assert(!ofputil_format_raw_port(oh->version, ofp11_port, string));
}
static void
ofp_print_ofpst_port_reply(struct ds *string, const struct ofp_header *oh,
int verbosity)
{
- struct ofp10_port_stats *ps;
+ struct ofp11_port_stats *ps;
struct ofpbuf b;
size_t n;
ofpbuf_use_const(&b, oh, ntohs(oh->length));
ofpraw_pull_assert(&b);
+ /* struct ofp10_port_stats and struct ofp11_port_stats are the
+ * same size. */
n = b.size / sizeof *ps;
ds_put_format(string, " %zu ports\n", n);
if (verbosity < 1) {
@@ -1104,28 +1112,30 @@ ofp_print_ofpst_port_reply(struct ds *string, const struct ofp_header *oh,
}
for (;;) {
- ps = ofpbuf_try_pull(&b, sizeof *ps);
+ struct ofp11_port_stats ps_storage;
+ ps = ofptutil_decode_one_port_reply(oh->version, &b, &ps_storage);
if (!ps) {
return;
}
- ds_put_format(string, " port %2"PRIu16": ", ntohs(ps->port_no));
+ ds_put_cstr(string, " port ");
+ assert(!ofputil_format_raw_port(oh->version, ps->port_no, string));
- ds_put_cstr(string, "rx ");
- print_port_stat(string, "pkts=", &ps->rx_packets, 1);
- print_port_stat(string, "bytes=", &ps->rx_bytes, 1);
- print_port_stat(string, "drop=", &ps->rx_dropped, 1);
- print_port_stat(string, "errs=", &ps->rx_errors, 1);
- print_port_stat(string, "frame=", &ps->rx_frame_err, 1);
- print_port_stat(string, "over=", &ps->rx_over_err, 1);
- print_port_stat(string, "crc=", &ps->rx_crc_err, 0);
+ ds_put_cstr(string, ": rx ");
+ ofp_print_port_stat(string, "pkts=", ps->rx_packets, 1);
+ ofp_print_port_stat(string, "bytes=", ps->rx_bytes, 1);
+ ofp_print_port_stat(string, "drop=", ps->rx_dropped, 1);
+ ofp_print_port_stat(string, "errs=", ps->rx_errors, 1);
+ ofp_print_port_stat(string, "frame=", ps->rx_frame_err, 1);
+ ofp_print_port_stat(string, "over=", ps->rx_over_err, 1);
+ ofp_print_port_stat(string, "crc=", ps->rx_crc_err, 0);
ds_put_cstr(string, " tx ");
- print_port_stat(string, "pkts=", &ps->tx_packets, 1);
- print_port_stat(string, "bytes=", &ps->tx_bytes, 1);
- print_port_stat(string, "drop=", &ps->tx_dropped, 1);
- print_port_stat(string, "errs=", &ps->tx_errors, 1);
- print_port_stat(string, "coll=", &ps->collisions, 0);
+ ofp_print_port_stat(string, "pkts=", ps->tx_packets, 1);
+ ofp_print_port_stat(string, "bytes=", ps->tx_bytes, 1);
+ ofp_print_port_stat(string, "drop=", ps->tx_dropped, 1);
+ ofp_print_port_stat(string, "errs=", ps->tx_errors, 1);
+ ofp_print_port_stat(string, "coll=", ps->collisions, 0);
}
}
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index fc98894..e3c4d42 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -3624,6 +3624,42 @@ ofputil_format_port(uint16_t port, struct ds *s)
ds_put_cstr(s, name);
}
+/* Appends to 's' a numeric string representation of the OpenFlow port
+ * number 'port'.
+ * If ofp_version indicates Open Flow 1.0,
+ * then convert 'ofp_port' to an OpenFlow 1.0 using
+ * ofputil_port_from_ofp11(). This converts 'ofp11_port' to
+ * a 16 bit port.
+ * Else if ofp_version indicates Open Flow 1.1,
+ * all 32 bits of ofp11_port are used
+ * Returns 0 if successful, otherwise an OFPERR_* number. */
+enum ofperr
+ofputil_format_raw_port(enum ofp_version ofp_version, ovs_be32 ofp11_port,
+ struct ds *s)
+{
+ switch (ofp_version) {
+ case OFP12_VERSION:
+ case OFP11_VERSION:
+ ds_put_format(s, "%2"PRIu32, ntohl(ofp11_port));
+ break;
+
+ case OFP10_VERSION: {
+ uint16_t ofp10_port;
+ enum ofperr error = ofputil_port_from_ofp11(ofp11_port, &ofp10_port);
+ if (error) {
+ return error;
+ }
+ ds_put_format(s, "%2"PRIu16, ofp10_port);
+ break;
+ }
+
+ default:
+ NOT_REACHED();
+ }
+
+ return 0;
+}
+
/* Given a buffer 'b' that contains an array of OpenFlow ports of type
* 'ofp_version', tries to pull the first element from the array. If
* successful, initializes '*pp' with an abstract representation of the
@@ -3913,8 +3949,7 @@ ofputil_parse_key_value(char **stringp, char **keyp, char **valuep)
level = 0;
break;
- case '(':
- level++;
+ case '(':level++;
break;
case ')':
@@ -3936,3 +3971,179 @@ ofputil_parse_key_value(char **stringp, char **keyp, char **valuep)
*valuep = value;
return true;
}
+
+/* Encode a dump ports request for 'port', the encoded message
+ * will be fore Open Flow version 'ofp_version'. Returns message
+ * as a struct ofpbuf. Returns encoded message on success, NULL on error */
+struct ofpbuf *
+ofputlil_dump_ports(enum ofp_version ofp_version, int16_t port)
+{
+ struct ofpbuf *request;
+ enum ofpraw raw;
+
+ switch (ofp_version) {
+ case OFP10_VERSION:
+ raw = OFPRAW_OFPST10_PORT_REQUEST;
+ break;
+ case OFP11_VERSION:
+ case OFP12_VERSION:
+ raw = OFPRAW_OFPST11_PORT_REQUEST;
+ break;
+ default:
+ NOT_REACHED();
+ }
+
+ request = ofpraw_alloc(raw, ofp_version, 0);
+
+ switch (ofp_version) {
+ case OFP10_VERSION: {
+ struct ofp10_port_stats_request *req;
+ req = ofpbuf_put_zeros(request, sizeof *req);
+ req->port_no = htons(port);
+ break;
+ }
+ case OFP11_VERSION:
+ case OFP12_VERSION: {
+ struct ofp11_port_stats_request *req;
+ req = ofpbuf_put_zeros(request, sizeof *req);
+ req->port_no = ofputil_port_to_ofp11(port);
+ break;
+ }
+ default:
+ NOT_REACHED();
+ }
+
+ return request;
+}
+
+/* Convert a struct ofp10_port_stats to a struct ofp11_port_stats.
+ * The latter may be used as a neutral format as is able to
+ * encode both ofp*_port_stats variants. */
+static void
+ops10_to_ops11(const struct ofp10_port_stats *in,
+ struct ofp11_port_stats *out)
+{
+ /* struct ofp11_port_stats and struct ofp10_port_stats are
+ * the same size and the elements after port_no and pad
+ * are the same */
+ OFP_ASSERT(sizeof *in == sizeof *out);
+ memcpy(out, in, sizeof *in);
+
+ out->port_no = ofputil_port_to_ofp11(ntohs(in->port_no));
+ memset(out->pad, 0, sizeof out->pad);
+}
+
+/* Convert a struct ofp11_port_stats to a struct ofp10_port_stats.
+ * The former may be used as a neutral format as is able to
+ * encode both ofp*_port_stats variants.
+ * Returns 0 on success, an enum ofperr value on error */
+static enum ofperr
+ops11_to_ops10(const struct ofp11_port_stats *in, struct ofp10_port_stats *out)
+{
+ uint16_t ofp10_port;
+ enum ofperr error;
+
+ /* struct ofp11_port_stats and struct ofp10_port_stats are
+ * the same size and the elements after port_no and pad
+ * are the same */
+ OFP_ASSERT(sizeof *in == sizeof *out);
+ memcpy(out, in, sizeof *in);
+
+ error = ofputil_port_from_ofp11(in->port_no, &ofp10_port);
+ if (error) {
+ return error;
+ }
+ out->port_no = htons(ofp10_port);
+ memset(out->pad, 0, sizeof out->pad);
+ return 0;
+}
+
+/* Encode a ports stat for 'opes' and append it to 'replies'.
+ * The encoded message will be fore Open Flow version 'ofp_version'.
+ * Returns 0 on success, an enum ofperr value on error */
+enum ofperr
+ofputil_append_port_stat(struct list *replies,
+ const struct ofp11_port_stats *ops)
+{
+ struct ofpbuf *msg = ofpbuf_from_list(list_back(replies));
+ struct ofp_header *oh = msg->data;
+
+ switch ((enum ofp_version)oh->version) {
+ case OFP12_VERSION:
+ case OFP11_VERSION: {
+ struct ofp11_port_stats *reply;
+
+ reply = ofpmp_append(replies, sizeof *reply);
+ memcpy(reply, ops, sizeof *reply);
+ break;
+ }
+
+ case OFP10_VERSION: {
+ struct ofp10_port_stats *reply;
+
+ reply = ofpmp_append(replies, sizeof *reply);
+ return ops11_to_ops10(ops, reply);
+ }
+
+ default:
+ NOT_REACHED();
+ }
+
+ return 0;
+}
+
+/* Parse a struct one element of a port status reply message into a struct
+ * ofp11_port_stats. struct ofp11_port_status is used as a neutral format
+ * as is able to encode both ofp*_port_stats variants. ps_storage shuold
+ * point to memory for a struct ofp11_port_stats. Returns pointer to
+ * struct ofp11_port_status on success, NULL otherwise. */
+struct ofp11_port_stats *
+ofptutil_decode_one_port_reply(enum ofp_version ofp_version,
+ struct ofpbuf *openflow,
+ struct ofp11_port_stats *ps_storage)
+{
+ switch (ofp_version) {
+ case OFP12_VERSION:
+ case OFP11_VERSION:
+ return ofpbuf_try_pull(openflow, sizeof *ps_storage);
+
+ case OFP10_VERSION: {
+ struct ofp10_port_stats *ps10;
+
+ ps10 = ofpbuf_try_pull(openflow, sizeof *ps10);
+ if (!ps10) {
+ return NULL;
+ }
+ ops10_to_ops11(ps10, ps_storage);
+ return ps_storage;
+ }
+
+ default:
+ NOT_REACHED();
+ }
+}
+
+/* Parse a port status request message into a 32 bit port number
+ * This preserves all the bits of the port number in the message.
+ * In the case of Open Flow 1.0 the 16 bit port number is returned
+ * in the least significant bits. Open Flow 1.1+ port numbers are 32 bits.
+ * Returns port number. */
+ovs_be32
+ofptutil_decode_port_stats_request(const struct ofp_header *request)
+{
+ switch ((enum ofp_version)request->version) {
+ case OFP12_VERSION:
+ case OFP11_VERSION: {
+ const struct ofp11_port_stats_request *psr = ofpmsg_body(request);
+ return psr->port_no;
+ }
+
+ case OFP10_VERSION: {
+ const struct ofp10_port_stats_request *psr = ofpmsg_body(request);
+ return ofputil_port_to_ofp11(ntohs(psr->port_no));
+ }
+
+ default:
+ NOT_REACHED();
+ }
+}
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index 4e9f946..f28d0a3 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -38,6 +38,8 @@ ovs_be32 ofputil_port_to_ofp11(uint16_t ofp10_port);
enum ofperr ofputil_check_output_port(uint16_t ofp_port, int max_ports);
uint16_t ofputil_port_from_string(const char *);
void ofputil_format_port(uint16_t port, struct ds *);
+enum ofperr ofputil_format_raw_port(enum ofp_version ofp_version,
+ ovs_be32 ofp11_port, struct ds *s);
/* Converting OFPFW10_NW_SRC_MASK and OFPFW10_NW_DST_MASK wildcard bit counts
* to and from IP bitmasks. */
@@ -623,4 +625,12 @@ union ofp_action *ofputil_actions_clone(const union ofp_action *, size_t n);
/* Handy utility for parsing flows and actions. */
bool ofputil_parse_key_value(char **stringp, char **keyp, char **valuep);
+struct ofpbuf *ofputlil_dump_ports(enum ofp_version ofp_version, int16_t port);
+enum ofperr ofputil_append_port_stat(struct list *replies,
+ const struct ofp11_port_stats *ops);
+struct ofp11_port_stats *
+ofptutil_decode_one_port_reply(enum ofp_version ofp_version,
+ struct ofpbuf *openflow,
+ struct ofp11_port_stats *ps_storage);
+ovs_be32 ofptutil_decode_port_stats_request(const struct ofp_header *request);
#endif /* ofp-util.h */
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 47cf22b..cf7be02 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -2293,31 +2293,38 @@ handle_table_stats_request(struct ofconn *ofconn,
}
static void
+collate_port_stat(struct ofport *port, struct netdev_stats *stats,
+ struct ofp11_port_stats *ops)
+{
+ ops->port_no = ofputil_port_to_ofp11(port->pp.port_no);
+ memset(ops->pad, 0, sizeof ops->pad);
+ ops->rx_packets = htonll(stats->rx_packets);
+ ops->tx_packets = htonll(stats->tx_packets);
+ ops->rx_bytes = htonll(stats->rx_bytes);
+ ops->tx_bytes = htonll(stats->tx_bytes);
+ ops->rx_dropped = htonll(stats->rx_dropped);
+ ops->tx_dropped = htonll(stats->tx_dropped);
+ ops->rx_errors = htonll(stats->rx_errors);
+ ops->tx_errors = htonll(stats->tx_errors);
+ ops->rx_frame_err = htonll(stats->rx_frame_errors);
+ ops->rx_over_err = htonll(stats->rx_over_errors);
+ ops->rx_crc_err = htonll(stats->rx_crc_errors);
+ ops->collisions = htonll(stats->collisions);
+}
+
+static void
append_port_stat(struct ofport *port, struct list *replies)
{
struct netdev_stats stats;
- struct ofp10_port_stats *ops;
+ struct ofp11_port_stats ops;
/* Intentionally ignore return value, since errors will set
* 'stats' to all-1s, which is correct for OpenFlow, and
* netdev_get_stats() will log errors. */
ofproto_port_get_stats(port, &stats);
- ops = ofpmp_append(replies, sizeof *ops);
- ops->port_no = htons(port->pp.port_no);
- memset(ops->pad, 0, sizeof ops->pad);
- put_32aligned_be64(&ops->rx_packets, htonll(stats.rx_packets));
- put_32aligned_be64(&ops->tx_packets, htonll(stats.tx_packets));
- put_32aligned_be64(&ops->rx_bytes, htonll(stats.rx_bytes));
- put_32aligned_be64(&ops->tx_bytes, htonll(stats.tx_bytes));
- put_32aligned_be64(&ops->rx_dropped, htonll(stats.rx_dropped));
- put_32aligned_be64(&ops->tx_dropped, htonll(stats.tx_dropped));
- put_32aligned_be64(&ops->rx_errors, htonll(stats.rx_errors));
- put_32aligned_be64(&ops->tx_errors, htonll(stats.tx_errors));
- put_32aligned_be64(&ops->rx_frame_err, htonll(stats.rx_frame_errors));
- put_32aligned_be64(&ops->rx_over_err, htonll(stats.rx_over_errors));
- put_32aligned_be64(&ops->rx_crc_err, htonll(stats.rx_crc_errors));
- put_32aligned_be64(&ops->collisions, htonll(stats.collisions));
+ collate_port_stat(port, &stats, &ops);
+ assert(!ofputil_append_port_stat(replies, &ops));
}
static enum ofperr
@@ -2325,13 +2332,21 @@ handle_port_stats_request(struct ofconn *ofconn,
const struct ofp_header *request)
{
struct ofproto *p = ofconn_get_ofproto(ofconn);
- const struct ofp10_port_stats_request *psr = ofpmsg_body(request);
struct ofport *port;
struct list replies;
+ ovs_be32 ofp11_port;
+ uint16_t port_no;
+ enum ofperr error;
+
+ ofp11_port = ofptutil_decode_port_stats_request(request);
+ error = ofputil_port_from_ofp11(ofp11_port, &port_no);
+ if (error) {
+ return error;
+ }
ofpmp_init(&replies, request);
- if (psr->port_no != htons(OFPP_NONE)) {
- port = ofproto_get_port(p, ntohs(psr->port_no));
+ if (port_no != OFPP_NONE) {
+ port = ofproto_get_port(p, port_no);
if (port) {
append_port_stat(port, &replies);
}
diff --git a/tests/ofp-print.at b/tests/ofp-print.at
index a8ace84..f214aa8 100644
--- a/tests/ofp-print.at
+++ b/tests/ofp-print.at
@@ -885,7 +885,7 @@ AT_KEYWORDS([ofp-print OFPT_STATS_REPLY])
AT_CHECK([ovs-ofctl ofp-print "$(cat in)"], [0], [expout])
AT_CLEANUP
-AT_SETUP([OFPST_PORT request])
+AT_SETUP([OFPST_PORT request - 1.0])
AT_KEYWORDS([ofp-print OFPT_STATS_REQUEST])
AT_CHECK([ovs-ofctl ofp-print "\
01 10 00 14 00 00 00 01 00 04 00 00 ff ff 00 00 \
@@ -895,7 +895,27 @@ OFPST_PORT request (xid=0x1): port_no=65535
])
AT_CLEANUP
-AT_SETUP([OFPST_PORT reply])
+AT_SETUP([OFPST_PORT request - 1.1])
+AT_KEYWORDS([ofp-print OFPT_STATS_REQUEST])
+AT_CHECK([ovs-ofctl ofp-print "\
+02 12 00 18 00 00 00 02 00 04 00 00 00 00 00 00 \
+ff ff 00 00 00 00 00 00 \
+"], [0], [dnl
+OFPST_PORT request (OF1.1) (xid=0x2): port_no=4294901760
+])
+AT_CLEANUP
+
+AT_SETUP([OFPST_PORT request - 1.2])
+AT_KEYWORDS([ofp-print OFPT_STATS_REQUEST])
+AT_CHECK([ovs-ofctl ofp-print "\
+03 12 00 18 00 00 00 02 00 04 00 00 00 00 00 00 \
+ff ff 00 00 00 00 00 00 \
+"], [0], [dnl
+OFPST_PORT request (OF1.2) (xid=0x2): port_no=4294901760
+])
+AT_CLEANUP
+
+AT_SETUP([OFPST_PORT reply - OF1.0])
AT_KEYWORDS([ofp-print OFPT_STATS_REPLY])
AT_CHECK([ovs-ofctl ofp-print "\
01 11 01 ac 00 00 00 01 00 04 00 00 00 03 00 00 \
@@ -938,6 +958,41 @@ OFPST_PORT reply (xid=0x1): 4 ports
])
AT_CLEANUP
+AT_SETUP([OFPST_PORT reply - OF1.2])
+AT_KEYWORDS([ofp-print OFPT_STATS_REPLY])
+AT_CHECK([ovs-ofctl ofp-print "\
+03 13 01 48 00 00 00 02 00 04 00 00 00 00 00 00 \
+00 00 00 02 00 00 00 00 00 00 00 00 00 01 95 56 \
+00 00 00 00 00 00 00 88 00 00 00 00 02 5d 08 98 \
+00 00 00 00 00 00 2c f8 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 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 00 00 \
+00 00 00 00 00 00 00 00 ff ff ff fe 00 00 00 00 \
+00 00 00 00 00 00 00 44 00 00 00 00 00 00 9d 2c \
+00 00 00 00 00 00 16 7c 00 00 00 00 01 1e 36 44 \
+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 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 00 00 00 00 00 00 00 00 00 00 \
+00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 44 \
+00 00 00 00 00 00 9d 2c 00 00 00 00 00 00 16 7c \
+00 00 00 00 01 1e 36 44 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 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 00 00 \
+00 00 00 00 00 00 00 00 \
+"], [0], [dnl
+OFPST_PORT reply (OF1.2) (xid=0x2): 3 ports
+ port 2: rx pkts=103766, bytes=39651480, drop=0, errs=0, frame=0, over=0, crc=0
+ tx pkts=136, bytes=11512, drop=0, errs=0, coll=0
+ port 4294967294: rx pkts=68, bytes=5756, drop=0, errs=0, frame=0, over=0, crc=0
+ tx pkts=40236, bytes=18757188, drop=0, errs=0, coll=0
+ port 1: rx pkts=68, bytes=5756, drop=0, errs=0, frame=0, over=0, crc=0
+ tx pkts=40236, bytes=18757188, drop=0, errs=0, coll=0
+])
+AT_CLEANUP
+
AT_SETUP([OFPST_QUEUE request])
AT_KEYWORDS([ofp-print OFPT_STATS_REQUEST])
AT_CHECK([ovs-ofctl ofp-print "\
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index dea8878..0bfdd02 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -1414,17 +1414,13 @@ ofctl_snoop(int argc OVS_UNUSED, char *argv[])
static void
ofctl_dump_ports(int argc, char *argv[])
{
- struct ofp10_port_stats_request *req;
struct ofpbuf *request;
struct vconn *vconn;
uint16_t port;
open_vconn(argv[1], &vconn);
- request = ofpraw_alloc(OFPRAW_OFPST_PORT_REQUEST,
- vconn_get_version(vconn), 0);
- req = ofpbuf_put_zeros(request, sizeof *req);
port = argc > 2 ? str_to_port_no(argv[1], argv[2]) : OFPP_NONE;
- req->port_no = htons(port);
+ request = ofputlil_dump_ports(vconn_get_version(vconn), port);
dump_stats_transaction(vconn, request);
vconn_close(vconn);
}
--
1.7.10.4
More information about the dev
mailing list