static void
append_port_stat(struct ofport *port, struct list *replies)
{
- struct netdev_stats stats;
- struct ofp10_port_stats *ops;
+ struct ofputil_port_stats ops = { .port_no = port->pp.port_no };
/* 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));
+ ofproto_port_get_stats(port, &ops.stats);
+
+ ofputil_append_port_stat(replies, &ops);
}
static enum ofperr
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;
+ uint16_t port_no;
+ enum ofperr error;
+
+ error = ofputil_decode_port_stats_request(request, &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);
}