diff --git a/include/openflow/automake.mk b/include/openflow/automake.mk index d7dac9132..18cc64989 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 000000000..974e63e0d --- /dev/null +++ b/include/openflow/intel-ext.h @@ -0,0 +1,73 @@ +/* + * Copyright(c) 2016 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 + +/* 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 184 + +/* Struct implements custom property type based on + * 'ofp_prop_experimenter'. */ +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_*. */ + + uint8_t pad[4]; + + ovs_be64 rx_1_to_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_1522_packets; + ovs_be64 rx_1523_to_max_packets; + + ovs_be64 tx_1_to_64_packets; + ovs_be64 tx_65_to_127_packets; + ovs_be64 tx_128_to_255_packets; + ovs_be64 tx_256_to_511_packets; + ovs_be64 tx_512_to_1023_packets; + ovs_be64 tx_1024_to_1522_packets; + ovs_be64 tx_1523_to_max_packets; + + ovs_be64 tx_multicast_packets; + ovs_be64 rx_broadcast_packets; + ovs_be64 tx_broadcast_packets; + ovs_be64 rx_undersized_errors; + ovs_be64 rx_oversize_errors; + ovs_be64 rx_fragmented_errors; + ovs_be64 rx_jabber_errors; + +}; +OFP_ASSERT(sizeof (struct intel_port_stats_rfc2819) == + INTEL_PORT_STATS_RFC2819_SIZE); + +#endif /* openflow/intel-ext.h */ diff --git a/include/openflow/openflow-common.h b/include/openflow/openflow-common.h index 089ff1889..7b619a997 100644 --- a/include/openflow/openflow-common.h +++ b/include/openflow/openflow-common.h @@ -108,6 +108,7 @@ enum ofp_version { #define NTR_COMPAT_VENDOR_ID 0x00001540 /* Incorrect value used in v2.4. */ #define NX_VENDOR_ID 0x00002320 /* Nicira. */ #define ONF_VENDOR_ID 0x4f4e4600 /* Open Networking Foundation. */ +#define INTEL_VENDOR_ID 0x0000AA01 /* Intel */ #define OFP_MAX_TABLE_NAME_LEN 32 #define OFP_MAX_PORT_NAME_LEN 16 diff --git a/include/openvswitch/netdev.h b/include/openvswitch/netdev.h index fa5e8f289..88a25dd25 100644 --- a/include/openvswitch/netdev.h +++ b/include/openvswitch/netdev.h @@ -52,6 +52,33 @@ struct netdev_stats { uint64_t tx_fifo_errors; uint64_t tx_heartbeat_errors; uint64_t tx_window_errors; + + /* Extended statistics based on RFC2819. */ + uint64_t rx_1_to_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_1522_packets; + uint64_t rx_1523_to_max_packets; + + uint64_t tx_1_to_64_packets; + uint64_t tx_65_to_127_packets; + uint64_t tx_128_to_255_packets; + uint64_t tx_256_to_511_packets; + uint64_t tx_512_to_1023_packets; + uint64_t tx_1024_to_1522_packets; + uint64_t tx_1523_to_max_packets; + + uint64_t tx_multicast_packets; + + uint64_t rx_broadcast_packets; + uint64_t tx_broadcast_packets; + + uint64_t rx_undersized_errors; + uint64_t rx_oversize_errors; + uint64_t rx_fragmented_errors; + uint64_t rx_jabber_errors; }; /* Features. */ diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index b488c601a..804086676 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -99,6 +99,33 @@ BUILD_ASSERT_DECL(MAX_NB_MBUF % ROUND_DOWN_POW2(MAX_NB_MBUF/MIN_NB_MBUF) == 0); BUILD_ASSERT_DECL((MAX_NB_MBUF / ROUND_DOWN_POW2(MAX_NB_MBUF/MIN_NB_MBUF)) % MP_CACHE_SZ == 0); +/* + * DPDK XSTATS Counter names definition + */ +#define XSTAT_RX_64_PACKETS "rx_size_64_packets" +#define XSTAT_RX_65_TO_127_PACKETS "rx_size_65_to_127_packets" +#define XSTAT_RX_128_TO_255_PACKETS "rx_size_128_to_255_packets" +#define XSTAT_RX_256_TO_511_PACKETS "rx_size_256_to_511_packets" +#define XSTAT_RX_512_TO_1023_PACKETS "rx_size_512_to_1023_packets" +#define XSTAT_RX_1024_TO_1522_PACKETS "rx_size_1024_to_1522_packets" +#define XSTAT_RX_1523_TO_MAX_PACKETS "rx_size_1523_to_max_packets" + +#define XSTAT_TX_64_PACKETS "tx_size_64_packets" +#define XSTAT_TX_65_TO_127_PACKETS "tx_size_65_to_127_packets" +#define XSTAT_TX_128_TO_255_PACKETS "tx_size_128_to_255_packets" +#define XSTAT_TX_256_TO_511_PACKETS "tx_size_256_to_511_packets" +#define XSTAT_TX_512_TO_1023_PACKETS "tx_size_512_to_1023_packets" +#define XSTAT_TX_1024_TO_1522_PACKETS "tx_size_1024_to_1522_packets" +#define XSTAT_TX_1523_TO_MAX_PACKETS "tx_size_1523_to_max_packets" + +#define XSTAT_TX_MULTICAST_PACKETS "tx_multicast_packets" +#define XSTAT_RX_BROADCAST_PACKETS "rx_broadcast_packets" +#define XSTAT_TX_BROADCAST_PACKETS "tx_broadcast_packets" +#define XSTAT_RX_UNDERSIZED_ERRORS "rx_undersized_errors" +#define XSTAT_RX_OVERSIZE_ERRORS "rx_oversize_errors" +#define XSTAT_RX_FRAGMENTED_ERRORS "rx_fragmented_errors" +#define XSTAT_RX_JABBER_ERRORS "rx_jabber_errors" + #define SOCKET0 0 #define NIC_PORT_RX_Q_SIZE 2048 /* Size of Physical NIC RX Queue, Max (n+32<=4096)*/ @@ -1142,18 +1169,46 @@ is_vhost_running(struct virtio_net *virtio_dev) return (virtio_dev != NULL && (virtio_dev->flags & VIRTIO_DEV_RUNNING)); } +static inline void +netdev_dpdk_vhost_update_rx_size_counters(struct netdev_stats *stats, + unsigned int packet_size) +{ + /* Hard-coded search for the size bucket. */ + if (packet_size < 256) { + if (packet_size >= 128) { + stats->rx_128_to_255_packets++; + } else if (packet_size <= 64) { + stats->rx_1_to_64_packets++; + } else { + stats->rx_65_to_127_packets++; + } + } else { + if (packet_size >= 1523) { + stats->rx_1523_to_max_packets++; + } else if (packet_size >= 1024) { + stats->rx_1024_to_1522_packets++; + } else if (packet_size < 512) { + stats->rx_256_to_511_packets++; + } else { + stats->rx_512_to_1023_packets++; + } + } +} + static inline void netdev_dpdk_vhost_update_rx_counters(struct netdev_stats *stats, struct dp_packet **packets, int count) { int i; + unsigned int packet_size; struct dp_packet *packet; stats->rx_packets += count; for (i = 0; i < count; i++) { packet = packets[i]; + packet_size = dp_packet_size(packet); - if (OVS_UNLIKELY(dp_packet_size(packet) < ETH_HEADER_LEN)) { + if (OVS_UNLIKELY(packet_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. */ @@ -1162,12 +1217,14 @@ netdev_dpdk_vhost_update_rx_counters(struct netdev_stats *stats, continue; } + netdev_dpdk_vhost_update_rx_size_counters(stats, packet_size); + 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 += packet_size; } } @@ -1659,21 +1716,6 @@ netdev_dpdk_vhost_get_stats(const struct netdev *netdev, struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); ovs_mutex_lock(&dev->mutex); - memset(stats, 0, sizeof(*stats)); - /* Unsupported Stats */ - stats->collisions = UINT64_MAX; - stats->rx_crc_errors = UINT64_MAX; - stats->rx_fifo_errors = UINT64_MAX; - stats->rx_frame_errors = UINT64_MAX; - stats->rx_missed_errors = UINT64_MAX; - stats->rx_over_errors = UINT64_MAX; - stats->tx_aborted_errors = UINT64_MAX; - stats->tx_carrier_errors = UINT64_MAX; - stats->tx_errors = UINT64_MAX; - stats->tx_fifo_errors = UINT64_MAX; - stats->tx_heartbeat_errors = UINT64_MAX; - stats->tx_window_errors = UINT64_MAX; - stats->rx_dropped += UINT64_MAX; rte_spinlock_lock(&dev->stats_lock); /* Supported Stats */ @@ -1685,6 +1727,15 @@ 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_1_to_64_packets = dev->stats.rx_1_to_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_1522_packets = dev->stats.rx_1024_to_1522_packets; + stats->rx_1523_to_max_packets = dev->stats.rx_1523_to_max_packets; + rte_spinlock_unlock(&dev->stats_lock); ovs_mutex_unlock(&dev->mutex); @@ -1692,6 +1743,67 @@ netdev_dpdk_vhost_get_stats(const struct netdev *netdev, return 0; } +static void +netdev_dpdk_convert_xstats(struct netdev_stats *stats, + const struct rte_eth_xstats *xstats, + const unsigned int size) +{ + /* XXX Current implementation is simple search through an array + * to find hardcoded counter names. In future DPDK release (TBD) + * XSTATS API will change so each counter will be represented by + * unique ID instead of String. */ + + for (unsigned int i = 0; i < size; i++) { + if (strcmp(XSTAT_RX_64_PACKETS, xstats[i].name) == 0) { + stats->rx_1_to_64_packets = xstats[i].value; + } else if (strcmp(XSTAT_RX_65_TO_127_PACKETS, xstats[i].name) == 0) { + stats->rx_65_to_127_packets = xstats[i].value; + } else if (strcmp(XSTAT_RX_128_TO_255_PACKETS, xstats[i].name) == 0) { + stats->rx_128_to_255_packets = xstats[i].value; + } else if (strcmp(XSTAT_RX_256_TO_511_PACKETS, xstats[i].name) == 0) { + stats->rx_256_to_511_packets = xstats[i].value; + } else if (strcmp(XSTAT_RX_512_TO_1023_PACKETS, + xstats[i].name) == 0) { + stats->rx_512_to_1023_packets = xstats[i].value; + } else if (strcmp(XSTAT_RX_1024_TO_1522_PACKETS, + xstats[i].name) == 0) { + stats->rx_1024_to_1522_packets = xstats[i].value; + } else if (strcmp(XSTAT_RX_1523_TO_MAX_PACKETS, + xstats[i].name) == 0) { + stats->rx_1523_to_max_packets = xstats[i].value; + } else if (strcmp(XSTAT_TX_64_PACKETS, xstats[i].name) == 0) { + stats->tx_1_to_64_packets = xstats[i].value; + } else if (strcmp(XSTAT_TX_65_TO_127_PACKETS, xstats[i].name) == 0) { + stats->tx_65_to_127_packets = xstats[i].value; + } else if (strcmp(XSTAT_TX_128_TO_255_PACKETS, xstats[i].name) == 0) { + stats->tx_128_to_255_packets = xstats[i].value; + } else if (strcmp(XSTAT_TX_256_TO_511_PACKETS, xstats[i].name) == 0) { + stats->tx_256_to_511_packets = xstats[i].value; + } else if (strcmp(XSTAT_TX_512_TO_1023_PACKETS, + xstats[i].name) == 0) { + stats->tx_512_to_1023_packets = xstats[i].value; + } else if (strcmp(XSTAT_TX_1024_TO_1522_PACKETS, + xstats[i].name) == 0) { + stats->tx_1024_to_1522_packets = xstats[i].value; + } else if (strcmp(XSTAT_TX_1523_TO_MAX_PACKETS, + xstats[i].name) == 0) { + stats->tx_1523_to_max_packets = xstats[i].value; + } else if (strcmp(XSTAT_TX_MULTICAST_PACKETS, xstats[i].name) == 0) { + stats->tx_multicast_packets = xstats[i].value; + } else if (strcmp(XSTAT_RX_BROADCAST_PACKETS, xstats[i].name) == 0) { + stats->rx_broadcast_packets = xstats[i].value; + } else if (strcmp(XSTAT_TX_BROADCAST_PACKETS, xstats[i].name) == 0) { + stats->tx_broadcast_packets = xstats[i].value; + } else if (strcmp(XSTAT_RX_UNDERSIZED_ERRORS, xstats[i].name) == 0) { + stats->rx_undersized_errors = xstats[i].value; + } else if (strcmp(XSTAT_RX_FRAGMENTED_ERRORS, xstats[i].name) == 0) { + stats->rx_fragmented_errors = xstats[i].value; + } else if (strcmp(XSTAT_RX_JABBER_ERRORS, xstats[i].name) == 0) { + stats->rx_jabber_errors = xstats[i].value; + } + } +} + static int netdev_dpdk_get_stats(const struct netdev *netdev, struct netdev_stats *stats) { @@ -1701,9 +1813,28 @@ netdev_dpdk_get_stats(const struct netdev *netdev, struct netdev_stats *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)); + struct rte_eth_xstats *rte_xstats; + int rte_xstats_len, rte_xstats_ret; + + if (rte_eth_stats_get(dev->port_id, &rte_stats)) { + VLOG_ERR("Can't get ETH statistics for port: %i.", dev->port_id); + return EPROTO; + } + + rte_xstats_len = rte_eth_xstats_get(dev->port_id, NULL, 0); + if (rte_xstats_len > 0) { + rte_xstats = dpdk_rte_mzalloc(sizeof(*rte_xstats) * rte_xstats_len); + memset(rte_xstats, 0xff, sizeof(*rte_xstats) * rte_xstats_len); + rte_xstats_ret = rte_eth_xstats_get(dev->port_id, rte_xstats, + rte_xstats_len); + if (rte_xstats_ret > 0 && rte_xstats_ret <= rte_xstats_len) { + netdev_dpdk_convert_xstats(stats, rte_xstats, rte_xstats_ret); + } + rte_free(rte_xstats); + } else { + VLOG_WARN("Can't get XSTATS counters for port: %i.", dev->port_id); + } stats->rx_packets = rte_stats.ipackets; stats->tx_packets = rte_stats.opackets; @@ -1721,21 +1852,8 @@ netdev_dpdk_get_stats(const struct netdev *netdev, struct netdev_stats *stats) /* These are the available DPDK counters for packets not received due to * local resource constraints in DPDK and NIC respectively. */ stats->rx_dropped = rte_stats.rx_nombuf + rte_stats.imissed; - stats->collisions = UINT64_MAX; - - stats->rx_length_errors = UINT64_MAX; - stats->rx_over_errors = UINT64_MAX; - stats->rx_crc_errors = UINT64_MAX; - stats->rx_frame_errors = UINT64_MAX; - stats->rx_fifo_errors = UINT64_MAX; stats->rx_missed_errors = rte_stats.imissed; - stats->tx_aborted_errors = UINT64_MAX; - stats->tx_carrier_errors = UINT64_MAX; - stats->tx_fifo_errors = UINT64_MAX; - stats->tx_heartbeat_errors = UINT64_MAX; - stats->tx_window_errors = UINT64_MAX; - ovs_mutex_unlock(&dev->mutex); return 0; diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c index 5acb4e194..7f0ee764b 100644 --- a/lib/netdev-dummy.c +++ b/lib/netdev-dummy.c @@ -1075,7 +1075,11 @@ netdev_dummy_get_stats(const struct netdev *netdev, struct netdev_stats *stats) struct netdev_dummy *dev = netdev_dummy_cast(netdev); ovs_mutex_lock(&dev->mutex); - *stats = dev->stats; + /* Passing only collected counters */ + stats->tx_packets = dev->stats.tx_packets; + stats->tx_bytes = dev->stats.tx_bytes; + stats->rx_packets = dev->stats.rx_packets; + stats->rx_bytes = dev->stats.rx_bytes; ovs_mutex_unlock(&dev->mutex); return 0; diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 2953964b6..5db18877d 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -5361,6 +5361,9 @@ get_stats_via_netlink(const struct netdev *netdev_, struct netdev_stats *stats) struct ofpbuf *reply; int error; + /* Filtering all counters by default */ + memset(stats, 0xFF, sizeof(struct netdev_stats)); + ofpbuf_init(&request, 0); nl_msg_put_nlmsghdr(&request, sizeof(struct ifinfomsg) + NL_ATTR_SIZE(IFNAMSIZ), diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c index e398562c6..678c3f9cc 100644 --- a/lib/netdev-vport.c +++ b/lib/netdev-vport.c @@ -851,7 +851,11 @@ get_stats(const struct netdev *netdev, struct netdev_stats *stats) struct netdev_vport *dev = netdev_vport_cast(netdev); ovs_mutex_lock(&dev->mutex); - *stats = dev->stats; + /* Passing only collected counters */ + stats->tx_packets = dev->stats.tx_packets; + stats->tx_bytes = dev->stats.tx_bytes; + stats->rx_packets = dev->stats.rx_packets; + stats->rx_bytes = dev->stats.rx_bytes; ovs_mutex_unlock(&dev->mutex); return 0; diff --git a/lib/netdev.c b/lib/netdev.c index 4fc06ce3b..3aacd9cee 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -1331,11 +1331,16 @@ netdev_get_stats(const struct netdev *netdev, struct netdev_stats *stats) { int error; + /* Statistics are initialized before passing it to particular device + * implementation so all values are filtered out by default. */ + memset(stats, 0xFF, sizeof *stats); + COVERAGE_INC(netdev_get_stats); error = (netdev->netdev_class->get_stats ? netdev->netdev_class->get_stats(netdev, stats) : EOPNOTSUPP); if (error) { + /* In case of error all statistics are filtered out */ memset(stats, 0xff, sizeof *stats); } return error; diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 69f90f301..b21d76f53 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -1684,6 +1684,14 @@ print_port_stat(struct ds *string, const char *leader, uint64_t stat, int more) } } +static void +print_port_stat_cond(struct ds *string, const char *leader, uint64_t stat) +{ + if (stat != UINT64_MAX) { + ds_put_format(string, "%s%"PRIu64", ", leader, stat); + } +} + static void ofp_print_ofpst_port_request(struct ds *string, const struct ofp_header *oh) { @@ -1749,6 +1757,73 @@ 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'); } + struct ds string_ext_stats = DS_EMPTY_INITIALIZER; + + ds_init(&string_ext_stats); + + print_port_stat_cond(&string_ext_stats, "1_to_64_packets=", + ps.stats.rx_1_to_64_packets); + print_port_stat_cond(&string_ext_stats, "65_to_127_packets=", + ps.stats.rx_65_to_127_packets); + print_port_stat_cond(&string_ext_stats, "128_to_255_packets=", + ps.stats.rx_128_to_255_packets); + print_port_stat_cond(&string_ext_stats, "256_to_511_packets=", + ps.stats.rx_256_to_511_packets); + print_port_stat_cond(&string_ext_stats, "512_to_1023_packets=", + ps.stats.rx_512_to_1023_packets); + print_port_stat_cond(&string_ext_stats, "1024_to_1522_packets=", + ps.stats.rx_1024_to_1522_packets); + print_port_stat_cond(&string_ext_stats, "1523_to_max_packets=", + ps.stats.rx_1523_to_max_packets); + print_port_stat_cond(&string_ext_stats, "broadcast_packets=", + ps.stats.rx_broadcast_packets); + print_port_stat_cond(&string_ext_stats, "undersized_errors=", + ps.stats.rx_undersized_errors); + print_port_stat_cond(&string_ext_stats, "oversize_errors=", + ps.stats.rx_oversize_errors); + print_port_stat_cond(&string_ext_stats, "rx_fragmented_errors=", + ps.stats.rx_fragmented_errors); + print_port_stat_cond(&string_ext_stats, "rx_jabber_errors=", + ps.stats.rx_jabber_errors); + + if (string_ext_stats.length != 0) { + /* If at least one statistics counter is reported: */ + ds_put_cstr(string, " rx rfc2819 "); + ds_put_buffer(string, string_ext_stats.string, + string_ext_stats.length); + ds_put_cstr(string, "\n"); + ds_destroy(&string_ext_stats); + } + + ds_init(&string_ext_stats); + + print_port_stat_cond(&string_ext_stats, "1_to_64_packets=", + ps.stats.tx_1_to_64_packets); + print_port_stat_cond(&string_ext_stats, "65_to_127_packets=", + ps.stats.tx_65_to_127_packets); + print_port_stat_cond(&string_ext_stats, "128_to_255_packets=", + ps.stats.tx_128_to_255_packets); + print_port_stat_cond(&string_ext_stats, "256_to_511_packets=", + ps.stats.tx_256_to_511_packets); + print_port_stat_cond(&string_ext_stats, "512_to_1023_packets=", + ps.stats.tx_512_to_1023_packets); + print_port_stat_cond(&string_ext_stats, "1024_to_1522_packets=", + ps.stats.tx_1024_to_1522_packets); + print_port_stat_cond(&string_ext_stats, "1523_to_max_packets=", + ps.stats.tx_1523_to_max_packets); + print_port_stat_cond(&string_ext_stats, "multicast_packets=", + ps.stats.tx_multicast_packets); + print_port_stat_cond(&string_ext_stats, "broadcast_packets=", + ps.stats.tx_broadcast_packets); + + if (string_ext_stats.length != 0) { + /* If at least one statistics counter is reported: */ + ds_put_cstr(string, " tx rfc2819 "); + ds_put_buffer(string, string_ext_stats.string, + string_ext_stats.length); + ds_put_cstr(string, "\n"); + ds_destroy(&string_ext_stats); + } } } diff --git a/lib/ofp-util.c b/lib/ofp-util.c index bb1535dfc..2c6fb1fea 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -43,6 +43,7 @@ #include "openvswitch/ofpbuf.h" #include "openvswitch/type-props.h" #include "openvswitch/vlog.h" +#include "openflow/intel-ext.h" #include "packets.h" #include "pktbuf.h" #include "random.h" @@ -7513,13 +7514,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); @@ -7538,6 +7542,56 @@ 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); + + uint64_t prop_type = OFPPROP_EXP(INTEL_VENDOR_ID, + INTEL_PORT_STATS_RFC2819); + + stats_rfc2819 = ofpprop_put_zeros(reply, prop_type, + sizeof *stats_rfc2819); + + memset(stats_rfc2819->pad, 0, sizeof stats_rfc2819->pad); + stats_rfc2819->rx_1_to_64_packets = htonll(ops->stats.rx_1_to_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_1522_packets = + htonll(ops->stats.rx_1024_to_1522_packets); + stats_rfc2819->rx_1523_to_max_packets = + htonll(ops->stats.rx_1523_to_max_packets); + + stats_rfc2819->tx_1_to_64_packets = htonll(ops->stats.tx_1_to_64_packets); + stats_rfc2819->tx_65_to_127_packets = + htonll(ops->stats.tx_65_to_127_packets); + stats_rfc2819->tx_128_to_255_packets = + htonll(ops->stats.tx_128_to_255_packets); + stats_rfc2819->tx_256_to_511_packets = + htonll(ops->stats.tx_256_to_511_packets); + stats_rfc2819->tx_512_to_1023_packets = + htonll(ops->stats.tx_512_to_1023_packets); + stats_rfc2819->tx_1024_to_1522_packets = + htonll(ops->stats.tx_1024_to_1522_packets); + stats_rfc2819->tx_1523_to_max_packets = + htonll(ops->stats.tx_1523_to_max_packets); + + stats_rfc2819->tx_multicast_packets = + htonll(ops->stats.tx_multicast_packets); + stats_rfc2819->rx_broadcast_packets = + htonll(ops->stats.rx_broadcast_packets); + stats_rfc2819->tx_broadcast_packets = + htonll(ops->stats.tx_broadcast_packets); + stats_rfc2819->rx_undersized_errors = + htonll(ops->stats.rx_undersized_errors); + stats_rfc2819->rx_oversize_errors = + htonll(ops->stats.rx_oversize_errors); + stats_rfc2819->rx_fragmented_errors = + htonll(ops->stats.rx_fragmented_errors); + stats_rfc2819->rx_jabber_errors = + htonll(ops->stats.rx_jabber_errors); } /* Encode a ports stat for 'ops' and append it to 'replies'. */ @@ -7579,7 +7633,6 @@ static enum ofperr ofputil_port_stats_from_ofp10(struct ofputil_port_stats *ops, const struct ofp10_port_stats *ps10) { - memset(ops, 0, sizeof *ops); ops->port_no = u16_to_ofp(ntohs(ps10->port_no)); ops->stats.rx_packets = ntohll(get_32aligned_be64(&ps10->rx_packets)); @@ -7606,7 +7659,6 @@ ofputil_port_stats_from_ofp11(struct ofputil_port_stats *ops, { enum ofperr error; - memset(ops, 0, sizeof *ops); error = ofputil_port_from_ofp11(ps11->port_no, &ops->port_no); if (error) { return error; @@ -7659,6 +7711,68 @@ parse_ofp14_port_stats_ethernet_property(const struct ofpbuf *payload, return 0; } +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_1_to_64_packets = ntohll(rfc2819->rx_1_to_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_1522_packets = + ntohll(rfc2819->rx_1024_to_1522_packets); + ops->stats.rx_1523_to_max_packets = + ntohll(rfc2819->rx_1523_to_max_packets); + + ops->stats.tx_1_to_64_packets = ntohll(rfc2819->tx_1_to_64_packets); + ops->stats.tx_65_to_127_packets = ntohll(rfc2819->tx_65_to_127_packets); + ops->stats.tx_128_to_255_packets = ntohll(rfc2819->tx_128_to_255_packets); + ops->stats.tx_256_to_511_packets = ntohll(rfc2819->tx_256_to_511_packets); + ops->stats.tx_512_to_1023_packets = + ntohll(rfc2819->tx_512_to_1023_packets); + ops->stats.tx_1024_to_1522_packets = + ntohll(rfc2819->tx_1024_to_1522_packets); + ops->stats.tx_1523_to_max_packets = + ntohll(rfc2819->tx_1523_to_max_packets); + + ops->stats.tx_multicast_packets = ntohll(rfc2819->tx_multicast_packets); + ops->stats.rx_broadcast_packets = ntohll(rfc2819->rx_broadcast_packets); + ops->stats.tx_broadcast_packets = ntohll(rfc2819->tx_broadcast_packets); + ops->stats.rx_undersized_errors = ntohll(rfc2819->rx_undersized_errors); + + ops->stats.rx_oversize_errors = ntohll(rfc2819->rx_oversize_errors); + ops->stats.rx_fragmented_errors = ntohll(rfc2819->rx_fragmented_errors); + ops->stats.rx_jabber_errors = ntohll(rfc2819->rx_jabber_errors); + + 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: + error = OFPERR_OFPBPC_BAD_EXP_TYPE; + break; + } + + return error; +} + static enum ofperr ofputil_pull_ofp14_port_stats(struct ofputil_port_stats *ops, struct ofpbuf *msg) @@ -7689,28 +7803,28 @@ ofputil_pull_ofp14_port_stats(struct ofputil_port_stats *ops, ops->stats.tx_dropped = ntohll(ps14->tx_dropped); ops->stats.rx_errors = ntohll(ps14->rx_errors); ops->stats.tx_errors = ntohll(ps14->tx_errors); - ops->stats.rx_frame_errors = UINT64_MAX; - ops->stats.rx_over_errors = UINT64_MAX; - ops->stats.rx_crc_errors = UINT64_MAX; - ops->stats.collisions = UINT64_MAX; + struct ofpbuf properties = ofpbuf_const_initializer(ofpbuf_pull(msg, len), len); while (properties.size > 0) { struct ofpbuf payload; enum ofperr error; - uint64_t type; + uint64_t type = 0; error = ofpprop_pull(&properties, &payload, &type); if (error) { return error; } - switch (type) { case OFPPSPT14_ETHERNET: error = parse_ofp14_port_stats_ethernet_property(&payload, ops); break; - + case OFPPROP_EXP(INTEL_VENDOR_ID, INTEL_PORT_STATS_RFC2819): + error = parse_intel_port_stats_property(&payload, + INTEL_PORT_STATS_RFC2819, + ops); + break; default: error = OFPPROP_UNKNOWN(true, "port stats", type); break; @@ -7756,6 +7870,8 @@ ofputil_decode_port_stats(struct ofputil_port_stats *ps, struct ofpbuf *msg) enum ofperr error; enum ofpraw raw; + memset(&(ps->stats), 0xFF, sizeof (ps->stats)); + error = (msg->header ? ofpraw_decode(&raw, msg->header) : ofpraw_pull(&raw, msg)); if (error) { @@ -7768,7 +7884,6 @@ ofputil_decode_port_stats(struct ofputil_port_stats *ps, struct ofpbuf *msg) return ofputil_pull_ofp14_port_stats(ps, msg); } else if (raw == OFPRAW_OFPST13_PORT_REPLY) { const struct ofp13_port_stats *ps13; - ps13 = ofpbuf_try_pull(msg, sizeof *ps13); if (!ps13) { goto bad_len; diff --git a/tests/learn.at b/tests/learn.at index 31ff4fd0c..68bde874a 100644 --- a/tests/learn.at +++ b/tests/learn.at @@ -329,11 +329,11 @@ NXST_FLOW reply: AT_CHECK( [(ovs-ofctl dump-ports br0 2; ovs-ofctl dump-ports br0 3) | strip_xids], [0], [OFPST_PORT reply: 1 ports - port 2: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0 - tx pkts=1, bytes=60, drop=0, errs=0, coll=0 + port 2: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=? + tx pkts=1, bytes=60, drop=?, errs=?, coll=? OFPST_PORT reply: 1 ports - port 3: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0 - tx pkts=9, bytes=540, drop=0, errs=0, coll=0 + port 3: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=? + tx pkts=9, bytes=540, drop=?, errs=?, coll=? ]) OVS_VSWITCHD_STOP @@ -380,11 +380,11 @@ done AT_CHECK( [(ovs-ofctl dump-ports br0 2; ovs-ofctl dump-ports br0 3) | strip_xids], [0], [OFPST_PORT reply: 1 ports - port 2: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0 - tx pkts=2, bytes=120, drop=0, errs=0, coll=0 + port 2: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=? + tx pkts=2, bytes=120, drop=?, errs=?, coll=? OFPST_PORT reply: 1 ports - port 3: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0 - tx pkts=18, bytes=1080, drop=0, errs=0, coll=0 + port 3: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=? + tx pkts=18, bytes=1080, drop=?, errs=?, coll=? ]) # Check for the learning entry. @@ -466,11 +466,11 @@ done AT_CHECK( [(ovs-ofctl dump-ports br0 2; ovs-ofctl dump-ports br0 3) | strip_xids], [0], [OFPST_PORT reply: 1 ports - port 2: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0 - tx pkts=3, bytes=180, drop=0, errs=0, coll=0 + port 2: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=? + tx pkts=3, bytes=180, drop=?, errs=?, coll=? OFPST_PORT reply: 1 ports - port 3: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0 - tx pkts=17, bytes=1020, drop=0, errs=0, coll=0 + port 3: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=? + tx pkts=17, bytes=1020, drop=?, errs=?, coll=? ]) # Check for the learning entry. diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index 014903beb..29d936998 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -5163,17 +5163,17 @@ IFCOUNTERS status=0 in_octets=0 in_unicasts=0 - in_multicasts=0 + in_multicasts=4294967295 in_broadcasts=4294967295 - in_discards=0 - in_errors=0 + in_discards=4294967295 + in_errors=4294967295 in_unknownprotos=4294967295 out_octets=120 out_unicasts=2 out_multicasts=4294967295 out_broadcasts=4294967295 - out_discards=0 - out_errors=0 + out_discards=4294967295 + out_errors=4294967295 promiscuous=0 IFCOUNTERS dgramSeqNo=2 @@ -5186,17 +5186,17 @@ IFCOUNTERS status=0 in_octets=138 in_unicasts=3 - in_multicasts=0 + in_multicasts=4294967295 in_broadcasts=4294967295 - in_discards=0 - in_errors=0 + in_discards=4294967295 + in_errors=4294967295 in_unknownprotos=4294967295 out_octets=120 out_unicasts=2 out_multicasts=4294967295 out_broadcasts=4294967295 - out_discards=0 - out_errors=0 + out_discards=4294967295 + out_errors=4294967295 promiscuous=0 IFCOUNTERS dgramSeqNo=2 @@ -5209,17 +5209,17 @@ IFCOUNTERS status=0 in_octets=84 in_unicasts=2 - in_multicasts=0 + in_multicasts=4294967295 in_broadcasts=4294967295 - in_discards=0 - in_errors=0 + in_discards=4294967295 + in_errors=4294967295 in_unknownprotos=4294967295 out_octets=180 out_unicasts=3 out_multicasts=4294967295 out_broadcasts=4294967295 - out_discards=0 - out_errors=0 + out_discards=4294967295 + out_errors=4294967295 promiscuous=0 IFCOUNTERS dgramSeqNo=3 @@ -5232,17 +5232,17 @@ IFCOUNTERS status=0 in_octets=0 in_unicasts=0 - in_multicasts=0 + in_multicasts=4294967295 in_broadcasts=4294967295 - in_discards=0 - in_errors=0 + in_discards=4294967295 + in_errors=4294967295 in_unknownprotos=4294967295 out_octets=120 out_unicasts=2 out_multicasts=4294967295 out_broadcasts=4294967295 - out_discards=0 - out_errors=0 + out_discards=4294967295 + out_errors=4294967295 promiscuous=0 IFCOUNTERS dgramSeqNo=3 @@ -5255,17 +5255,17 @@ IFCOUNTERS status=0 in_octets=138 in_unicasts=3 - in_multicasts=0 + in_multicasts=4294967295 in_broadcasts=4294967295 - in_discards=0 - in_errors=0 + in_discards=4294967295 + in_errors=4294967295 in_unknownprotos=4294967295 out_octets=120 out_unicasts=2 out_multicasts=4294967295 out_broadcasts=4294967295 - out_discards=0 - out_errors=0 + out_discards=4294967295 + out_errors=4294967295 promiscuous=0 IFCOUNTERS dgramSeqNo=3 @@ -5278,17 +5278,17 @@ IFCOUNTERS status=0 in_octets=84 in_unicasts=2 - in_multicasts=0 + in_multicasts=4294967295 in_broadcasts=4294967295 - in_discards=0 - in_errors=0 + in_discards=4294967295 + in_errors=4294967295 in_unknownprotos=4294967295 out_octets=180 out_unicasts=3 out_multicasts=4294967295 out_broadcasts=4294967295 - out_discards=0 - out_errors=0 + out_discards=4294967295 + out_errors=4294967295 promiscuous=0 OPENFLOWPORT datapath_id=18364758544493064720 @@ -6212,14 +6212,14 @@ skb_priority(0/0),skb_mark(0/0),recirc_id(0),dp_hash(0/0),in_port(101),eth(src=5 AT_CHECK([ovs-ofctl dump-ports br0 pbr0], [0], [dnl OFPST_PORT reply (xid=0x4): 1 ports - port 1: rx pkts=5, bytes=300, drop=0, errs=0, frame=0, over=0, crc=0 - tx pkts=10, bytes=600, drop=0, errs=0, coll=0 + port 1: rx pkts=5, bytes=300, drop=?, errs=?, frame=?, over=?, crc=? + tx pkts=10, bytes=600, drop=?, errs=?, coll=? ]) AT_CHECK([ovs-ofctl dump-ports br1 pbr1], [0], [dnl OFPST_PORT reply (xid=0x4): 1 ports - port 1: rx pkts=10, bytes=600, drop=0, errs=0, frame=0, over=0, crc=0 - tx pkts=5, bytes=300, drop=0, errs=0, coll=0 + port 1: rx pkts=10, bytes=600, drop=?, errs=?, frame=?, over=?, crc=? + tx pkts=5, bytes=300, drop=?, errs=?, coll=? ]) OVS_VSWITCHD_STOP diff --git a/tests/ofproto.at b/tests/ofproto.at index c4260ab27..f8c0d0732 100644 --- a/tests/ofproto.at +++ b/tests/ofproto.at @@ -84,8 +84,8 @@ OVS_VSWITCHD_START AT_CHECK([ovs-ofctl -vwarn dump-ports br0], [0], [stdout]) AT_CHECK([strip_xids < stdout], [0], [dnl OFPST_PORT reply: 1 ports - port LOCAL: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0 - tx pkts=0, bytes=0, drop=0, errs=0, coll=0 + port LOCAL: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=? + tx pkts=0, bytes=0, drop=?, errs=?, coll=? ]) OVS_VSWITCHD_STOP AT_CLEANUP @@ -95,8 +95,8 @@ OVS_VSWITCHD_START AT_CHECK([ovs-ofctl -O OpenFlow12 -vwarn dump-ports br0], [0], [stdout]) AT_CHECK([strip_xids < stdout], [0], [dnl OFPST_PORT reply (OF1.2): 1 ports - port LOCAL: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0 - tx pkts=0, bytes=0, drop=0, errs=0, coll=0 + port LOCAL: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=? + tx pkts=0, bytes=0, drop=?, errs=?, coll=? ]) OVS_VSWITCHD_STOP AT_CLEANUP @@ -107,8 +107,8 @@ AT_CHECK([ovs-ofctl -O OpenFlow14 -vwarn dump-ports br0], [0], [stdout]) AT_CHECK([strip_xids < stdout | sed 's/duration=[[0-9.]]*s/duration=?s/'], [0], [dnl OFPST_PORT reply (OF1.4): 1 ports - port LOCAL: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0 - tx pkts=0, bytes=0, drop=0, errs=0, coll=0 + port LOCAL: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=? + tx pkts=0, bytes=0, drop=?, errs=?, coll=? duration=?s ]) OVS_VSWITCHD_STOP diff --git a/tests/tunnel-push-pop-ipv6.at b/tests/tunnel-push-pop-ipv6.at index ee8c48f4e..f8bb8004c 100644 --- a/tests/tunnel-push-pop-ipv6.at +++ b/tests/tunnel-push-pop-ipv6.at @@ -129,7 +129,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p0 'aa55aa550000001b213cab6486dd600000 ovs-appctl time/warp 1000 AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port 3'], [0], [dnl - port 3: rx pkts=1, bytes=98, drop=0, errs=0, frame=0, over=0, crc=0 + port 3: rx pkts=1, bytes=98, drop=?, errs=?, frame=?, over=?, crc=? ]) dnl Check GRE only accepts encapsulated Ethernet frames @@ -137,7 +137,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p0 'aa55aa550000001b213cab6486dd600000 ovs-appctl time/warp 1000 AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port 3'], [0], [dnl - port 3: rx pkts=1, bytes=98, drop=0, errs=0, frame=0, over=0, crc=0 + port 3: rx pkts=1, bytes=98, drop=?, errs=?, frame=?, over=?, crc=? ]) dnl Check decapsulation of Geneve packet with options @@ -157,7 +157,7 @@ icmp,vlan_tci=0x0000,dl_src=be:b6:f4:e1:49:4a,dl_dst=fe:71:d8:83:72:4f,nw_src=30 ]) AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port 5'], [0], [dnl - port 5: rx pkts=1, bytes=98, drop=0, errs=0, frame=0, over=0, crc=0 + port 5: rx pkts=1, bytes=98, drop=?, errs=?, frame=?, over=?, crc=? ]) AT_CHECK([ovs-appctl dpif/dump-flows int-br], [0], [dnl tunnel(tun_id=0x7b,ipv6_src=2001:cafe::92,ipv6_dst=2001:cafe::88,geneve({class=0xffff,type=0x80,len=4,0xa/0xf}{class=0xffff,type=0,len=4}),flags(-df-csum+key)),skb_mark(0),recirc_id(0),in_port(6081),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions:userspace(pid=0,slow_path(controller)) diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at index a7909d326..99523067b 100644 --- a/tests/tunnel-push-pop.at +++ b/tests/tunnel-push-pop.at @@ -129,7 +129,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p0 'aa55aa550000001b213cab640800450000 ovs-appctl time/warp 1000 AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port 3'], [0], [dnl - port 3: rx pkts=1, bytes=98, drop=0, errs=0, frame=0, over=0, crc=0 + port 3: rx pkts=1, bytes=98, drop=?, errs=?, frame=?, over=?, crc=? ]) dnl Check GRE only accepts encapsulated Ethernet frames @@ -137,7 +137,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p0 'aa55aa550000001b213cab640800450000 ovs-appctl time/warp 1000 AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port 3'], [0], [dnl - port 3: rx pkts=1, bytes=98, drop=0, errs=0, frame=0, over=0, crc=0 + port 3: rx pkts=1, bytes=98, drop=?, errs=?, frame=?, over=?, crc=? ]) dnl Check decapsulation of Geneve packet with options @@ -157,7 +157,7 @@ icmp,vlan_tci=0x0000,dl_src=be:b6:f4:e1:49:4a,dl_dst=fe:71:d8:83:72:4f,nw_src=30 ]) AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port 5'], [0], [dnl - port 5: rx pkts=1, bytes=98, drop=0, errs=0, frame=0, over=0, crc=0 + port 5: rx pkts=1, bytes=98, drop=?, errs=?, frame=?, over=?, crc=? ]) AT_CHECK([ovs-appctl dpif/dump-flows int-br], [0], [dnl tunnel(tun_id=0x7b,src=1.1.2.92,dst=1.1.2.88,geneve({class=0xffff,type=0x80,len=4,0xa/0xf}{class=0xffff,type=0,len=4}),flags(-df-csum+key)),skb_mark(0),recirc_id(0),in_port(6081),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions:userspace(pid=0,slow_path(controller)) diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index b4e5ea7ff..41ec4ba9a 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -2310,18 +2310,39 @@ 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_1_to_64_packets, "rx_1_to_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_1522_packets, "rx_1024_to_1518_packets") \ + IFACE_STAT(rx_1523_to_max_packets, "rx_1523_to_max_packets") \ + IFACE_STAT(tx_1_to_64_packets, "tx_1_to_64_packets") \ + IFACE_STAT(tx_65_to_127_packets, "tx_65_to_127_packets") \ + IFACE_STAT(tx_128_to_255_packets, "tx_128_to_255_packets") \ + IFACE_STAT(tx_256_to_511_packets, "tx_256_to_511_packets") \ + IFACE_STAT(tx_512_to_1023_packets, "tx_512_to_1023_packets") \ + IFACE_STAT(tx_1024_to_1522_packets, "tx_1024_to_1518_packets") \ + IFACE_STAT(tx_1523_to_max_packets, "tx_1523_to_max_packets") \ + IFACE_STAT(tx_multicast_packets, "tx_multicast_packets") \ + IFACE_STAT(rx_broadcast_packets, "rx_broadcast_packets") \ + IFACE_STAT(tx_broadcast_packets, "tx_broadcast_packets") \ + IFACE_STAT(rx_undersized_errors, "rx_undersized_errors") \ + IFACE_STAT(rx_oversize_errors, "rx_oversize_errors") \ + IFACE_STAT(rx_fragmented_errors, "rx_fragmented_errors") \ + IFACE_STAT(rx_jabber_errors, "rx_jabber_errors") #define IFACE_STAT(MEMBER, NAME) + 1 enum { N_IFACE_STATS = IFACE_STATS };