Implementation of new statistics extension: - new counters definition based on RFC2819, - new statistics are retrieved using experimenter code and are printed as a result to ofctl dump-ports, - new statistics are printed to output via ofctl only if those are present in reply message, - new file header created: include/openflow/intel-ext.h which contains new statistics definition, - new extended statistics calculation is implemented only for dpdk-vhost-enabled ports.
Please note that this is just feature proposal: - experimenter code is hardcoded in ofp-util.c, it will be changed when VENDOR_ID for intel will be defined, - final patch will include also more counters based on RFC2863, RFC3635 and RFC2819. v2: - protocol extension in ofproto has been removed, existing mechanism with experimenter codes has been used, - additional option in ofctl dump-ports-ext has been removed, new counters are retrieved via dump-ports. Signed-off-by: Michal Weglicki <michalx.wegli...@intel.com> Signed-off-by: Timo Puha <timox.p...@intel.com> --- include/openflow/automake.mk | 1 + include/openflow/intel-ext.h | 63 ++++++++++++++++++++++ lib/netdev-bsd.c | 14 +++++ lib/netdev-dpdk.c | 48 +++++++++++++++-- lib/netdev-dummy.c | 14 ++++- lib/netdev-linux.c | 18 +++++++ lib/netdev-vport.c | 13 +++++ lib/netdev.h | 8 +++ lib/ofp-print.c | 22 ++++++++ lib/ofp-util.c | 122 +++++++++++++++++++++++++++++++++++++++++-- vswitchd/bridge.c | 31 ++++++----- 11 files changed, 331 insertions(+), 23 deletions(-) create mode 100644 include/openflow/intel-ext.h diff --git a/include/openflow/automake.mk b/include/openflow/automake.mk index d7dac91..18cc649 100644 --- a/include/openflow/automake.mk +++ b/include/openflow/automake.mk @@ -1,5 +1,6 @@ openflowincludedir = $(includedir)/openflow openflowinclude_HEADERS = \ + include/openflow/intel-ext.h \ include/openflow/netronome-ext.h \ include/openflow/nicira-ext.h \ include/openflow/openflow-1.0.h \ diff --git a/include/openflow/intel-ext.h b/include/openflow/intel-ext.h new file mode 100644 index 0000000..680e499 --- /dev/null +++ b/include/openflow/intel-ext.h @@ -0,0 +1,63 @@ +/* + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OPENFLOW_INTEL_EXT_H +#define OPENFLOW_INTEL_EXT_H 1 + + +/* This file presents Intel vendor extension. It is not anyhow + * standardized, so all those definitions are not part of + * official openflow headers (openflow.h). Nevertheless below + * features introduces real value so it could be suitable for + * standardization */ + + + +/* Intel extended statistics type */ + +enum intel_port_stats_subtype { + INTEL_PORT_STATS_RFC2819 = 1, +}; + +#define INTEL_PORT_STATS_RFC2819_SIZE 64 + +struct intel_port_stats_rfc2819 { + ovs_be16 type; /* OFPPSPT14_EXPERIMENTER. */ + ovs_be16 length; /* Length in bytes of this property + * excluding trailing padding. */ + ovs_be32 experimenter; /* INTEL_VENDOR_ID. */ + ovs_be32 exp_type; /* INTEL_PORT_STATS_*. */ + + /* Followed by: + * - Exactly (length - 12) bytes containing the experimenter data: + * Below counters are just example used in RFC patch based on RFC2819. + * This list can be extended during final patch implementation. */ + uint8_t pad[4]; + + ovs_be64 rx_64_packets; + ovs_be64 rx_65_to_127_packets; + ovs_be64 rx_128_to_255_packets; + ovs_be64 rx_256_to_511_packets; + ovs_be64 rx_512_to_1023_packets; + ovs_be64 rx_1024_to_1518_packets; + + /*, then + * - Exactly (length + 7)/8*8 - (length) (between 0 and 7) + * bytes of all-zero bytes */ +}; +OFP_ASSERT(sizeof(struct intel_port_stats_rfc2819) == INTEL_PORT_STATS_RFC2819_SIZE); + +#endif /* openflow/intel-ext.h */ diff --git a/lib/netdev-bsd.c b/lib/netdev-bsd.c index 60e5615..153687a 100644 --- a/lib/netdev-bsd.c +++ b/lib/netdev-bsd.c @@ -896,6 +896,18 @@ netdev_bsd_get_carrier(const struct netdev *netdev_, bool *carrier) return error; } +/* Initializes unused statistics to default values. */ +static void +netdev_bsd_set_unused_stats(struct netdev_stats *dst) +{ + dst->rx_1024_to_1518_packets = UINT64_MAX; + dst->rx_512_to_1023_packets = UINT64_MAX; + dst->rx_256_to_511_packets = UINT64_MAX; + dst->rx_128_to_255_packets = UINT64_MAX; + dst->rx_65_to_127_packets = UINT64_MAX; + dst->rx_64_packets = UINT64_MAX; +} + static void convert_stats_system(struct netdev_stats *stats, const struct if_data *ifd) { @@ -923,6 +935,7 @@ convert_stats_system(struct netdev_stats *stats, const struct if_data *ifd) stats->tx_fifo_errors = UINT64_MAX; stats->tx_heartbeat_errors = UINT64_MAX; stats->tx_window_errors = UINT64_MAX; + netdev_bsd_set_unused_stats(stats); } static void @@ -957,6 +970,7 @@ convert_stats_tap(struct netdev_stats *stats, const struct if_data *ifd) stats->tx_fifo_errors = UINT64_MAX; stats->tx_heartbeat_errors = UINT64_MAX; stats->tx_window_errors = UINT64_MAX; + netdev_bsd_set_unused_stats(stats); } static void diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 4658416..fc40620 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -954,13 +954,15 @@ netdev_dpdk_vhost_update_rx_counters(struct netdev_stats *stats, struct dp_packet **packets, int count) { int i; + unsigned size; struct dp_packet *packet; stats->rx_packets += count; for (i = 0; i < count; i++) { packet = packets[i]; + size = dp_packet_size(packet); - if (OVS_UNLIKELY(dp_packet_size(packet) < ETH_HEADER_LEN)) { + if (OVS_UNLIKELY(size < ETH_HEADER_LEN)) { /* This only protects the following multicast counting from * too short packets, but it does not stop the packet from * further processing. */ @@ -969,12 +971,32 @@ netdev_dpdk_vhost_update_rx_counters(struct netdev_stats *stats, continue; } + /* Hard-coded binary search for the size bucket. */ + if (size < 256) { + if (size >= 128) { + stats->rx_128_to_255_packets++; + } else if (size <= 64) { + stats->rx_64_packets++; + } else { + stats->rx_65_to_127_packets++; + } + } else { + if (size >= 1024) { + stats->rx_1024_to_1518_packets++; + } else if (size < 512) { + stats->rx_256_to_511_packets++; + } else { + stats->rx_512_to_1023_packets++; + } + } + struct eth_header *eh = (struct eth_header *) dp_packet_data(packet); + if (OVS_UNLIKELY(eth_addr_is_multicast(eh->eth_dst))) { stats->multicast++; } - stats->rx_bytes += dp_packet_size(packet); + stats->rx_bytes += size; } } @@ -1415,8 +1437,9 @@ netdev_dpdk_vhost_get_stats(const struct netdev *netdev, { struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); + memset(stats, 0xFF, sizeof (*stats)); + ovs_mutex_lock(&dev->mutex); - memset(stats, 0, sizeof(*stats)); /* Unsupported Stats */ stats->collisions = UINT64_MAX; stats->rx_crc_errors = UINT64_MAX; @@ -1442,6 +1465,14 @@ netdev_dpdk_vhost_get_stats(const struct netdev *netdev, stats->tx_bytes = dev->stats.tx_bytes; stats->rx_errors = dev->stats.rx_errors; stats->rx_length_errors = dev->stats.rx_length_errors; + + stats->rx_64_packets = dev->stats.rx_64_packets; + stats->rx_65_to_127_packets = dev->stats.rx_65_to_127_packets; + stats->rx_128_to_255_packets = dev->stats.rx_128_to_255_packets; + stats->rx_256_to_511_packets = dev->stats.rx_256_to_511_packets; + stats->rx_512_to_1023_packets = dev->stats.rx_512_to_1023_packets; + stats->rx_1024_to_1518_packets = dev->stats.rx_1024_to_1518_packets; + rte_spinlock_unlock(&dev->stats_lock); ovs_mutex_unlock(&dev->mutex); @@ -1456,12 +1487,12 @@ netdev_dpdk_get_stats(const struct netdev *netdev, struct netdev_stats *stats) struct rte_eth_stats rte_stats; bool gg; + memset(stats, 0xFF, sizeof (*stats)); + netdev_dpdk_get_carrier(netdev, &gg); ovs_mutex_lock(&dev->mutex); rte_eth_stats_get(dev->port_id, &rte_stats); - memset(stats, 0, sizeof(*stats)); - stats->rx_packets = rte_stats.ipackets; stats->tx_packets = rte_stats.opackets; stats->rx_bytes = rte_stats.ibytes; @@ -1495,6 +1526,13 @@ netdev_dpdk_get_stats(const struct netdev *netdev, struct netdev_stats *stats) ovs_mutex_unlock(&dev->mutex); + stats->rx_64_packets = UINT64_MAX; + stats->rx_65_to_127_packets = UINT64_MAX; + stats->rx_128_to_255_packets = UINT64_MAX; + stats->rx_256_to_511_packets = UINT64_MAX; + stats->rx_512_to_1023_packets = UINT64_MAX; + stats->rx_1024_to_1518_packets = UINT64_MAX; + return 0; } diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c index 76815c2..b055abf 100644 --- a/lib/netdev-dummy.c +++ b/lib/netdev-dummy.c @@ -1020,6 +1020,18 @@ netdev_dummy_set_mtu(const struct netdev *netdev, int mtu) return 0; } +/* Initializes unused statistics to default values. */ +static void +netdev_dummy_set_unused_stats(struct netdev_stats *dst) +{ + dst->rx_1024_to_1518_packets = UINT64_MAX; + dst->rx_512_to_1023_packets = UINT64_MAX; + dst->rx_256_to_511_packets = UINT64_MAX; + dst->rx_128_to_255_packets = UINT64_MAX; + dst->rx_65_to_127_packets = UINT64_MAX; + dst->rx_64_packets = UINT64_MAX; +} + static int netdev_dummy_get_stats(const struct netdev *netdev, struct netdev_stats *stats) { @@ -1028,7 +1040,7 @@ netdev_dummy_get_stats(const struct netdev *netdev, struct netdev_stats *stats) ovs_mutex_lock(&dev->mutex); *stats = dev->stats; ovs_mutex_unlock(&dev->mutex); - + netdev_dummy_set_unused_stats(stats); return 0; } diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 584e804..b26343a 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -1550,6 +1550,18 @@ swap_uint64(uint64_t *a, uint64_t *b) *b = tmp; } +/* Initializes unused statistics to default values. */ +static void +netdev_linux_set_unused_stats(struct netdev_stats *dst) +{ + dst->rx_1024_to_1518_packets = UINT64_MAX; + dst->rx_512_to_1023_packets = UINT64_MAX; + dst->rx_256_to_511_packets = UINT64_MAX; + dst->rx_128_to_255_packets = UINT64_MAX; + dst->rx_65_to_127_packets = UINT64_MAX; + dst->rx_64_packets = UINT64_MAX; +} + /* Copies 'src' into 'dst', performing format conversion in the process. * * 'src' is allowed to be misaligned. */ @@ -1671,6 +1683,8 @@ netdev_linux_get_stats(const struct netdev *netdev_, } ovs_mutex_unlock(&netdev->mutex); + netdev_linux_set_unused_stats(stats); + return error; } @@ -1733,6 +1747,8 @@ netdev_tap_get_stats(const struct netdev *netdev_, struct netdev_stats *stats) } ovs_mutex_unlock(&netdev->mutex); + netdev_linux_set_unused_stats(stats); + return error; } @@ -1748,6 +1764,8 @@ netdev_internal_get_stats(const struct netdev *netdev_, error = netdev->vport_stats_error; ovs_mutex_unlock(&netdev->mutex); + netdev_linux_set_unused_stats(stats); + return error; } diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c index 07b72b3..6f640cc 100644 --- a/lib/netdev-vport.c +++ b/lib/netdev-vport.c @@ -812,6 +812,18 @@ set_patch_config(struct netdev *dev_, const struct smap *args) return 0; } +/* Initializes unused statistics to default values. */ +static void +netdev_vport_set_unused_stats(struct netdev_stats *dst) +{ + dst->rx_1024_to_1518_packets = UINT64_MAX; + dst->rx_512_to_1023_packets = UINT64_MAX; + dst->rx_256_to_511_packets = UINT64_MAX; + dst->rx_128_to_255_packets = UINT64_MAX; + dst->rx_65_to_127_packets = UINT64_MAX; + dst->rx_64_packets = UINT64_MAX; +} + static int get_stats(const struct netdev *netdev, struct netdev_stats *stats) { @@ -820,6 +832,7 @@ get_stats(const struct netdev *netdev, struct netdev_stats *stats) ovs_mutex_lock(&dev->mutex); *stats = dev->stats; ovs_mutex_unlock(&dev->mutex); + netdev_vport_set_unused_stats(stats); return 0; } diff --git a/lib/netdev.h b/lib/netdev.h index 0fbcb65..107e81e 100644 --- a/lib/netdev.h +++ b/lib/netdev.h @@ -102,6 +102,14 @@ struct netdev_stats { uint64_t tx_fifo_errors; uint64_t tx_heartbeat_errors; uint64_t tx_window_errors; + + /* Size bucket statistics. Based on RFC2819. */ + uint64_t rx_64_packets; + uint64_t rx_65_to_127_packets; + uint64_t rx_128_to_255_packets; + uint64_t rx_256_to_511_packets; + uint64_t rx_512_to_1023_packets; + uint64_t rx_1024_to_1518_packets; }; /* Configuration specific to tunnels. */ diff --git a/lib/ofp-print.c b/lib/ofp-print.c index d0c94ce..66a4968 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -1611,6 +1611,28 @@ ofp_print_ofpst_port_reply(struct ds *string, const struct ofp_header *oh, ofp_print_duration(string, ps.duration_sec, ps.duration_nsec); ds_put_char(string, '\n'); } + /* Present extended statistics only if anything is reported */ + if ((ps.stats.rx_64_packets != UINT64_MAX) || + (ps.stats.rx_65_to_127_packets != UINT64_MAX) || + (ps.stats.rx_128_to_255_packets != UINT64_MAX) || + (ps.stats.rx_256_to_511_packets != UINT64_MAX) || + (ps.stats.rx_512_to_1023_packets != UINT64_MAX) || + (ps.stats.rx_1024_to_1518_packets != UINT64_MAX)) { + + ds_put_cstr(string, " rx rfc2819 "); + print_port_stat(string, "64_packets=", + ps.stats.rx_64_packets, 1); + print_port_stat(string, "65_to_127_packets=", + ps.stats.rx_65_to_127_packets, 1); + print_port_stat(string, "128_to_255_packets=", + ps.stats.rx_128_to_255_packets, 1); + print_port_stat(string, "256_to_511_packets=", + ps.stats.rx_256_to_511_packets, 1); + print_port_stat(string, "512_to_1023_packets=", + ps.stats.rx_512_to_1023_packets, 1); + print_port_stat(string, "1024_to_1518_packets=", + ps.stats.rx_1024_to_1518_packets, 0); + } } } diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 342be54..dd46a86 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -39,6 +39,7 @@ #include "ofp-util.h" #include "ofpbuf.h" #include "openflow/netronome-ext.h" +#include "openflow/intel-ext.h" #include "packets.h" #include "random.h" #include "tun-metadata.h" @@ -47,6 +48,13 @@ #include "openvswitch/vlog.h" #include "bitmap.h" +/* + * This vendor ID is created only for RFC patch, + * it will be changed when requested ID will be + * added to openflow-common.h. + */ +#define INTEL_VENDOR_ID 0x0000151d + VLOG_DEFINE_THIS_MODULE(ofp_util); /* Rate limit for OpenFlow message parse errors. These always indicate a bug @@ -6852,13 +6860,16 @@ ofputil_append_ofp14_port_stats(const struct ofputil_port_stats *ops, struct ovs_list *replies) { struct ofp14_port_stats_prop_ethernet *eth; + struct intel_port_stats_rfc2819 *stats_rfc2819; struct ofp14_port_stats *ps14; struct ofpbuf *reply; - reply = ofpmp_reserve(replies, sizeof *ps14 + sizeof *eth); + reply = + ofpmp_reserve(replies, + sizeof *ps14 + sizeof *eth + sizeof *stats_rfc2819); ps14 = ofpbuf_put_uninit(reply, sizeof *ps14); - ps14->length = htons(sizeof *ps14 + sizeof *eth); + ps14->length = htons(sizeof *ps14 + sizeof *eth + sizeof *stats_rfc2819); memset(ps14->pad, 0, sizeof ps14->pad); ps14->port_no = ofputil_port_to_ofp11(ops->port_no); ps14->duration_sec = htonl(ops->duration_sec); @@ -6880,6 +6891,24 @@ ofputil_append_ofp14_port_stats(const struct ofputil_port_stats *ops, eth->rx_over_err = htonll(ops->stats.rx_over_errors); eth->rx_crc_err = htonll(ops->stats.rx_crc_errors); eth->collisions = htonll(ops->stats.collisions); + + stats_rfc2819 = ofpbuf_put_uninit(reply, sizeof *stats_rfc2819); + stats_rfc2819->type = htons(OFPPSPT14_EXPERIMENTER); + stats_rfc2819->length = htons(sizeof *stats_rfc2819); + stats_rfc2819->experimenter = htonl(INTEL_VENDOR_ID); + stats_rfc2819->exp_type = htonl(INTEL_PORT_STATS_RFC2819); + memset(stats_rfc2819->pad, 0, sizeof stats_rfc2819->pad); + stats_rfc2819->rx_64_packets = htonll(ops->stats.rx_64_packets); + stats_rfc2819->rx_65_to_127_packets = + htonll(ops->stats.rx_65_to_127_packets); + stats_rfc2819->rx_128_to_255_packets = + htonll(ops->stats.rx_128_to_255_packets); + stats_rfc2819->rx_256_to_511_packets = + htonll(ops->stats.rx_256_to_511_packets); + stats_rfc2819->rx_512_to_1023_packets = + htonll(ops->stats.rx_512_to_1023_packets); + stats_rfc2819->rx_1024_to_1518_packets = + htonll(ops->stats.rx_1024_to_1518_packets); } /* Encode a ports stat for 'ops' and append it to 'replies'. */ @@ -6920,7 +6949,8 @@ static enum ofperr ofputil_port_stats_from_ofp10(struct ofputil_port_stats *ops, const struct ofp10_port_stats *ps10) { - memset(ops, 0, sizeof *ops); + /* Initialize with all ones to filter everything out */ + memset(ops, 0xFF, sizeof *ops); ops->port_no = u16_to_ofp(ntohs(ps10->port_no)); ops->stats.rx_packets = ntohll(get_32aligned_be64(&ps10->rx_packets)); @@ -6947,7 +6977,8 @@ ofputil_port_stats_from_ofp11(struct ofputil_port_stats *ops, { enum ofperr error; - memset(ops, 0, sizeof *ops); + /* Initialize with all ones to filter everything out */ + memset(ops, 0xFF, sizeof *ops); error = ofputil_port_from_ofp11(ps11->port_no, &ops->port_no); if (error) { return error; @@ -7001,6 +7032,79 @@ parse_ofp14_port_stats_ethernet_property(const struct ofpbuf *payload, } static enum ofperr +parse_intel_port_stats_rfc2819_property(const struct ofpbuf *payload, + struct ofputil_port_stats *ops) +{ + const struct intel_port_stats_rfc2819 *rfc2819 = payload->data; + + if (payload->size != sizeof *rfc2819) { + return OFPERR_OFPBPC_BAD_LEN; + } + ops->stats.rx_64_packets = ntohll(rfc2819->rx_64_packets); + ops->stats.rx_65_to_127_packets = ntohll(rfc2819->rx_65_to_127_packets); + ops->stats.rx_128_to_255_packets = ntohll(rfc2819->rx_128_to_255_packets); + ops->stats.rx_256_to_511_packets = ntohll(rfc2819->rx_256_to_511_packets); + ops->stats.rx_512_to_1023_packets = + ntohll(rfc2819->rx_512_to_1023_packets); + ops->stats.rx_1024_to_1518_packets = + ntohll(rfc2819->rx_1024_to_1518_packets); + + return 0; +} + +static enum ofperr +parse_intel_port_stats_property(const struct ofpbuf *payload, uint32_t exp_type, + struct ofputil_port_stats *ops) +{ + enum ofperr error; + + switch (exp_type) { + case INTEL_PORT_STATS_RFC2819: + error = parse_intel_port_stats_rfc2819_property(payload, ops); + break; + default: + log_property(false, "unknown port stats experimenter type %" PRIu32, + exp_type); + error = OFPERR_OFPBPC_BAD_EXP_TYPE; + break; + } + + return error; +} + +static enum ofperr +parse_ofp14_port_stats_exp(struct ofpbuf *payload, + struct ofputil_port_stats *ops) +{ + struct ofp_prop_experimenter *prop = payload->data; + uint16_t experimenter; + uint32_t exp_type; + enum ofperr error; + + if (payload->size < sizeof *prop) { + return OFPERR_OFPBPC_BAD_LEN; + } + + experimenter = ntohl(prop->experimenter); + exp_type = ntohl(prop->exp_type); + + switch (experimenter) { + case INTEL_VENDOR_ID: + error = parse_intel_port_stats_property(payload, exp_type, ops); + break; + + default: + log_property(false, "unknown group property experimenter %" PRIu16, + experimenter); + error = OFPERR_OFPBPC_BAD_EXPERIMENTER; + break; + } + + return error; +} + + +static enum ofperr ofputil_pull_ofp14_port_stats(struct ofputil_port_stats *ops, struct ofpbuf *msg) { @@ -7040,6 +7144,12 @@ ofputil_pull_ofp14_port_stats(struct ofputil_port_stats *ops, ops->stats.rx_over_errors = UINT64_MAX; ops->stats.rx_crc_errors = UINT64_MAX; ops->stats.collisions = UINT64_MAX; + ops->stats.rx_64_packets = UINT64_MAX; + ops->stats.rx_65_to_127_packets = UINT64_MAX; + ops->stats.rx_128_to_255_packets = UINT64_MAX; + ops->stats.rx_256_to_511_packets = UINT64_MAX; + ops->stats.rx_512_to_1023_packets = UINT64_MAX; + ops->stats.rx_1024_to_1518_packets = UINT64_MAX; while (properties.size > 0) { struct ofpbuf payload; @@ -7055,7 +7165,9 @@ ofputil_pull_ofp14_port_stats(struct ofputil_port_stats *ops, case OFPPSPT14_ETHERNET: error = parse_ofp14_port_stats_ethernet_property(&payload, ops); break; - + case OFPPSPT14_EXPERIMENTER: + error = parse_ofp14_port_stats_exp(&payload, ops); + break; default: log_property(true, "unknown port stats property %"PRIu16, type); error = 0; diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index b966d92..28a46e0 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -2336,21 +2336,28 @@ static void iface_refresh_stats(struct iface *iface) { #define IFACE_STATS \ - IFACE_STAT(rx_packets, "rx_packets") \ - IFACE_STAT(tx_packets, "tx_packets") \ - IFACE_STAT(rx_bytes, "rx_bytes") \ - IFACE_STAT(tx_bytes, "tx_bytes") \ - IFACE_STAT(rx_dropped, "rx_dropped") \ - IFACE_STAT(tx_dropped, "tx_dropped") \ - IFACE_STAT(rx_errors, "rx_errors") \ - IFACE_STAT(tx_errors, "tx_errors") \ - IFACE_STAT(rx_frame_errors, "rx_frame_err") \ - IFACE_STAT(rx_over_errors, "rx_over_err") \ - IFACE_STAT(rx_crc_errors, "rx_crc_err") \ - IFACE_STAT(collisions, "collisions") + IFACE_STAT(rx_packets, "rx_packets") \ + IFACE_STAT(tx_packets, "tx_packets") \ + IFACE_STAT(rx_bytes, "rx_bytes") \ + IFACE_STAT(tx_bytes, "tx_bytes") \ + IFACE_STAT(rx_dropped, "rx_dropped") \ + IFACE_STAT(tx_dropped, "tx_dropped") \ + IFACE_STAT(rx_errors, "rx_errors") \ + IFACE_STAT(tx_errors, "tx_errors") \ + IFACE_STAT(rx_frame_errors, "rx_frame_err") \ + IFACE_STAT(rx_over_errors, "rx_over_err") \ + IFACE_STAT(rx_crc_errors, "rx_crc_err") \ + IFACE_STAT(collisions, "collisions") \ + IFACE_STAT(rx_64_packets, "rx_64_packets") \ + IFACE_STAT(rx_65_to_127_packets, "rx_65_to_127_packets") \ + IFACE_STAT(rx_128_to_255_packets, "rx_128_to_255_packets") \ + IFACE_STAT(rx_256_to_511_packets, "rx_256_to_511_packets") \ + IFACE_STAT(rx_512_to_1023_packets, "rx_512_to_1023_packets") \ + IFACE_STAT(rx_1024_to_1518_packets, "rx_1024_to_1518_packets") #define IFACE_STAT(MEMBER, NAME) + 1 enum { N_IFACE_STATS = IFACE_STATS }; + #undef IFACE_STAT int64_t values[N_IFACE_STATS]; const char *keys[N_IFACE_STATS]; -- 1.9.3 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev