netdev-linux: favor netlink stats for physical ports
[sliver-openvswitch.git] / lib / netdev-linux.c
index 5c7065f..c1d9323 100644 (file)
@@ -1563,9 +1563,17 @@ netdev_linux_get_stats(const struct netdev *netdev_,
             error = 0;
         }
     } else if (netdev->vport_stats_error) {
-        /* stats not available from OVS then use ioctl stats. */
+        /* stats not available from OVS then use netdev stats. */
         *stats = dev_stats;
     } else {
+        /* Use kernel netdev's packet and byte counts since vport's counters
+         * do not reflect packet counts on the wire when GSO, TSO or GRO are
+         * enabled. */
+        stats->rx_packets = dev_stats.rx_packets;
+        stats->rx_bytes = dev_stats.rx_bytes;
+        stats->tx_packets = dev_stats.tx_packets;
+        stats->tx_bytes = dev_stats.tx_bytes;
+
         stats->rx_errors           += dev_stats.rx_errors;
         stats->tx_errors           += dev_stats.tx_errors;
         stats->rx_dropped          += dev_stats.rx_dropped;
@@ -1629,6 +1637,14 @@ netdev_tap_get_stats(const struct netdev *netdev_, struct netdev_stats *stats)
         stats->tx_heartbeat_errors = 0;
         stats->tx_window_errors = 0;
     } else {
+        /* Use kernel netdev's packet and byte counts since vport counters
+         * do not reflect packet counts on the wire when GSO, TSO or GRO
+         * are enabled. */
+        stats->rx_packets = dev_stats.tx_packets;
+        stats->rx_bytes = dev_stats.tx_bytes;
+        stats->tx_packets = dev_stats.rx_packets;
+        stats->tx_bytes = dev_stats.rx_bytes;
+
         stats->rx_dropped          += dev_stats.tx_dropped;
         stats->tx_dropped          += dev_stats.rx_dropped;