case OFPP_IN_PORT:
/* Send it out the port it came in on, which is already set in
* the skb. */
- if (!skb->dev) {
+ if (!skb->dev) {
if (net_ratelimit())
printk("skb device not set forwarding to in_port\n");
kfree(skb);
stats = p->dev->get_stats(p->dev);
ops->port_no = htons(p->port_no);
memset(ops->pad, 0, sizeof ops->pad);
- ops->rx_count = cpu_to_be64(stats->rx_packets);
- ops->tx_count = cpu_to_be64(stats->tx_packets);
- ops->drop_count = cpu_to_be64(stats->rx_dropped
- + stats->tx_dropped);
+ ops->rx_packets = cpu_to_be64(stats->rx_packets);
+ ops->tx_packets = cpu_to_be64(stats->tx_packets);
+ ops->rx_bytes = cpu_to_be64(stats->rx_bytes);
+ ops->tx_bytes = cpu_to_be64(stats->tx_bytes);
+ ops->rx_dropped = cpu_to_be64(stats->rx_dropped);
+ ops->tx_dropped = cpu_to_be64(stats->tx_dropped);
+ ops->rx_errors = cpu_to_be64(stats->rx_errors);
+ ops->tx_errors = cpu_to_be64(stats->tx_errors);
+ ops->rx_frame_err = cpu_to_be64(stats->rx_frame_errors);
+ ops->rx_over_err = cpu_to_be64(stats->rx_over_errors);
+ ops->rx_crc_err = cpu_to_be64(stats->rx_crc_errors);
+ ops->collisions = cpu_to_be64(stats->collisions);
n_ports++;
ops++;
}
/* The most significant bit being set in the version field indicates an
* experimental OpenFlow version.
*/
-#define OFP_VERSION 0x87
+#define OFP_VERSION 0x88
#define OFP_MAX_TABLE_NAME_LEN 32
#define OFP_MAX_PORT_NAME_LEN 16
};
OFP_ASSERT(sizeof(struct ofp_table_stats) == 56);
-/* Statistics about a particular port */
+/* Statistics about a particular port. If a counter is unsupported, set
+ * the field to all ones. */
struct ofp_port_stats {
uint16_t port_no;
- uint8_t pad[6]; /* Align to 64-bits */
- uint64_t rx_count; /* Number of received packets */
- uint64_t tx_count; /* Number of transmitted packets */
- uint64_t drop_count; /* Number of packets dropped by interface */
-};
-OFP_ASSERT(sizeof(struct ofp_port_stats) == 32);
+ uint8_t pad[6]; /* Align to 64-bits. */
+ uint64_t rx_packets; /* Number of received packets. */
+ uint64_t tx_packets; /* Number of transmitted packets. */
+ uint64_t rx_bytes; /* Number of received bytes. */
+ uint64_t tx_bytes; /* Number of transmitted bytes. */
+ uint64_t rx_dropped; /* Number of packets dropped by RX. */
+ uint64_t tx_dropped; /* Number of packets dropped by TX. */
+ uint64_t rx_errors; /* Number of receive errors. This is a super-set
+ of receive errors and should be great than or
+ equal to the sum of al rx_*_err values. */
+ uint64_t tx_errors; /* Number of transmit errors. This is a super-set
+ of transmit errors. */
+ uint64_t rx_frame_err; /* Number of frame alignment errors. */
+ uint64_t rx_over_err; /* Number of packets with RX overrun. */
+ uint64_t rx_crc_err; /* Number of CRC errors. */
+ uint64_t collisions; /* Number of collisions. */
+};
+OFP_ASSERT(sizeof(struct ofp_port_stats) == 104);
#endif /* openflow.h */
ds_put_format(string, " flow_count=%"PRIu32, ntohl(asr->flow_count));
}
+static void print_port_stat(struct ds *string, const char *leader,
+ uint64_t stat, int more)
+{
+ ds_put_cstr(string, leader);
+ if (stat != -1) {
+ ds_put_format(string, "%"PRIu64, stat);
+ } else {
+ ds_put_char(string, '?');
+ }
+ if (more) {
+ ds_put_cstr(string, ", ");
+ } else {
+ ds_put_cstr(string, "\n");
+ }
+}
+
static void
ofp_port_stats_reply(struct ds *string, const void *body, size_t len,
int verbosity)
}
for (; n--; ps++) {
- ds_put_format(string, " port %"PRIu16": ", ntohs(ps->port_no));
- ds_put_format(string, "rx %"PRIu64", ", ntohll(ps->rx_count));
- ds_put_format(string, "tx %"PRIu64", ", ntohll(ps->tx_count));
- ds_put_format(string, "dropped %"PRIu64"\n", ntohll(ps->drop_count));
+ ds_put_format(string, " port %2"PRIu16": ", ntohs(ps->port_no));
+
+ ds_put_cstr(string, "rx ");
+ print_port_stat(string, "pkts=", ntohll(ps->rx_packets), 1);
+ print_port_stat(string, "bytes=", ntohll(ps->rx_bytes), 1);
+ print_port_stat(string, "drop=", ntohll(ps->rx_dropped), 1);
+ print_port_stat(string, "errs=", ntohll(ps->rx_errors), 1);
+ print_port_stat(string, "frame=", ntohll(ps->rx_frame_err), 1);
+ print_port_stat(string, "over=", ntohll(ps->rx_over_err), 1);
+ print_port_stat(string, "crc=", ntohll(ps->rx_crc_err), 0);
+
+ ds_put_cstr(string, " tx ");
+ print_port_stat(string, "pkts=", ntohll(ps->tx_packets), 1);
+ print_port_stat(string, "bytes=", ntohll(ps->tx_bytes), 1);
+ print_port_stat(string, "drop=", ntohll(ps->tx_dropped), 1);
+ print_port_stat(string, "errs=", ntohll(ps->tx_errors), 1);
+ print_port_stat(string, "coll=", ntohll(ps->collisions), 0);
}
}
struct datapath *dp;
struct netdev *netdev;
struct list node; /* Element in datapath.ports. */
- unsigned long long int rx_count, tx_count, drop_count;
+ unsigned long long int rx_packets, tx_packets;
+ unsigned long long int rx_bytes, tx_bytes;
+ unsigned long long int tx_dropped;
};
/* The origin of a received OpenFlow message, to enable sending a reply. */
}
}
+ memset(p, '\0', sizeof *p);
+
p->dp = dp;
p->netdev = netdev;
- p->tx_count = 0;
- p->rx_count = 0;
- p->drop_count = 0;
list_push_back(&dp->port_list, &p->node);
/* Notify the ctlpath that this port has been added */
}
error = netdev_recv(p->netdev, buffer);
if (!error) {
- p->rx_count++;
+ p->rx_packets++;
+ p->rx_bytes += buffer->size;
fwd_port_input(dp, buffer, port_no(dp, p));
buffer = NULL;
} else if (error != EAGAIN) {
struct sw_port *p = &dp->ports[out_port];
if (p->netdev != NULL) {
if (!netdev_send(p->netdev, buffer)) {
- p->tx_count++;
+ p->tx_packets++;
+ p->tx_bytes += buffer->size;
} else {
- p->drop_count++;
+ p->tx_dropped++;
}
return;
}
ops = buffer_put_uninit(buffer, sizeof *ops);
ops->port_no = htons(port_no(dp, p));
memset(ops->pad, 0, sizeof ops->pad);
- ops->rx_count = htonll(p->rx_count);
- ops->tx_count = htonll(p->tx_count);
- ops->drop_count = htonll(p->drop_count);
+ ops->rx_packets = htonll(p->rx_packets);
+ ops->tx_packets = htonll(p->tx_packets);
+ ops->rx_bytes = htonll(p->rx_bytes);
+ ops->tx_bytes = htonll(p->tx_bytes);
+ ops->rx_dropped = htonll(-1);
+ ops->tx_dropped = htonll(p->tx_dropped);
+ ops->rx_errors = htonll(-1);
+ ops->tx_errors = htonll(-1);
+ ops->rx_frame_err = htonll(-1);
+ ops->rx_over_err = htonll(-1);
+ ops->rx_crc_err = htonll(-1);
+ ops->collisions = htonll(-1);
ops++;
}
s->port = i;