From ec61a01cd8ed73b13ffe042ddff4baf41f6b63e7 Mon Sep 17 00:00:00 2001
From: Ben Pfaff <blp@nicira.com>
Date: Tue, 9 Nov 2010 13:48:57 -0800
Subject: [PATCH] datapath: Use "struct rtnl_link_stats64" instead of "struct
 odp_vport_stats".

Linux 2.6.35 added struct rtnl_link_stats64, which as a set of 64-bit
network device counters is what the OVS datapath needs.  We might as well
use it instead of our own.

This commit moves the if_link.h compat header from datapath/ into the
top-level include/ directory so that it is visible both to kernel and
userspace code.

Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
---
 datapath/vport-internal_dev.c                 |  2 +-
 datapath/vport-netdev.c                       | 22 ++-------
 datapath/vport-netdev.h                       |  2 +-
 datapath/vport.c                              | 45 ++++++++++++-------
 datapath/vport.h                              | 10 ++---
 .../include => include}/linux/if_link.h       |  0
 include/openvswitch/datapath-protocol.h       | 21 +++------
 lib/netdev-vport.c                            | 39 +++++++++-------
 8 files changed, 69 insertions(+), 72 deletions(-)
 rename {datapath/linux-2.6/compat-2.6/include => include}/linux/if_link.h (100%)

diff --git a/datapath/vport-internal_dev.c b/datapath/vport-internal_dev.c
index 11221333a..52bd6ce61 100644
--- a/datapath/vport-internal_dev.c
+++ b/datapath/vport-internal_dev.c
@@ -37,7 +37,7 @@ static struct net_device_stats *internal_dev_sys_stats(struct net_device *netdev
 	struct net_device_stats *stats = &internal_dev_priv(netdev)->stats;
 
 	if (vport) {
-		struct odp_vport_stats vport_stats;
+		struct rtnl_link_stats64 vport_stats;
 
 		vport_get_stats(vport, &vport_stats);
 
diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c
index bc1637b25..c023c8548 100644
--- a/datapath/vport-netdev.c
+++ b/datapath/vport-netdev.c
@@ -118,7 +118,7 @@ static struct vport *netdev_create(const char *name, const void __user *config)
 	/* If we are using the vport stats layer initialize it to the current
 	 * values so we are roughly consistent with the device stats. */
 	if (USE_VPORT_STATS) {
-		struct odp_vport_stats stats;
+		struct rtnl_link_stats64 stats;
 
 		err = netdev_get_stats(vport, &stats);
 		if (!err)
@@ -208,26 +208,10 @@ struct kobject *netdev_get_kobj(const struct vport *vport)
 	return &netdev_vport->dev->NETDEV_DEV_MEMBER.kobj;
 }
 
-int netdev_get_stats(const struct vport *vport, struct odp_vport_stats *stats)
+int netdev_get_stats(const struct vport *vport, struct rtnl_link_stats64 *stats)
 {
 	const struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
-	struct rtnl_link_stats64 netdev_stats;
-
-	dev_get_stats(netdev_vport->dev, &netdev_stats);
-
-	stats->rx_bytes		= netdev_stats.rx_bytes;
-	stats->rx_packets	= netdev_stats.rx_packets;
-	stats->tx_bytes		= netdev_stats.tx_bytes;
-	stats->tx_packets	= netdev_stats.tx_packets;
-	stats->rx_dropped	= netdev_stats.rx_dropped;
-	stats->rx_errors	= netdev_stats.rx_errors;
-	stats->rx_frame_err	= netdev_stats.rx_frame_errors;
-	stats->rx_over_err	= netdev_stats.rx_over_errors;
-	stats->rx_crc_err	= netdev_stats.rx_crc_errors;
-	stats->tx_dropped	= netdev_stats.tx_dropped;
-	stats->tx_errors	= netdev_stats.tx_errors;
-	stats->collisions	= netdev_stats.collisions;
-
+	dev_get_stats(netdev_vport->dev, stats);
 	return 0;
 }
 
diff --git a/datapath/vport-netdev.h b/datapath/vport-netdev.h
index 19f176cda..542ddfdb1 100644
--- a/datapath/vport-netdev.h
+++ b/datapath/vport-netdev.h
@@ -30,7 +30,7 @@ int netdev_set_addr(struct vport *, const unsigned char *addr);
 const char *netdev_get_name(const struct vport *);
 const unsigned char *netdev_get_addr(const struct vport *);
 struct kobject *netdev_get_kobj(const struct vport *);
-int netdev_get_stats(const struct vport *, struct odp_vport_stats *);
+int netdev_get_stats(const struct vport *, struct rtnl_link_stats64 *);
 unsigned netdev_get_dev_flags(const struct vport *);
 int netdev_is_running(const struct vport *);
 unsigned char netdev_get_operstate(const struct vport *);
diff --git a/datapath/vport.c b/datapath/vport.c
index f0c81823f..37d6d8ab0 100644
--- a/datapath/vport.c
+++ b/datapath/vport.c
@@ -904,7 +904,7 @@ int vport_set_addr(struct vport *vport, const unsigned char *addr)
  * support setting the stats, in which case the result will always be
  * -EOPNOTSUPP.  RTNL lock must be held.
  */
-int vport_set_stats(struct vport *vport, struct odp_vport_stats *stats)
+int vport_set_stats(struct vport *vport, struct rtnl_link_stats64 *stats)
 {
 	ASSERT_RTNL();
 
@@ -998,10 +998,10 @@ struct kobject *vport_get_kobj(const struct vport *vport)
  *
  * Retrieves transmit, receive, and error stats for the given device.
  */
-int vport_get_stats(struct vport *vport, struct odp_vport_stats *stats)
+int vport_get_stats(struct vport *vport, struct rtnl_link_stats64 *stats)
 {
-	struct odp_vport_stats dev_stats;
-	struct odp_vport_stats *dev_statsp = NULL;
+	struct rtnl_link_stats64 dev_stats;
+	struct rtnl_link_stats64 *dev_statsp = NULL;
 	int err;
 
 	if (vport->ops->get_stats) {
@@ -1039,22 +1039,37 @@ int vport_get_stats(struct vport *vport, struct odp_vport_stats *stats)
 		stats->tx_errors	+= vport->err_stats.tx_errors;
 		stats->tx_dropped	+= vport->err_stats.tx_dropped;
 		stats->rx_dropped	+= vport->err_stats.rx_dropped;
-		stats->rx_over_err	+= vport->err_stats.rx_over_err;
-		stats->rx_crc_err	+= vport->err_stats.rx_crc_err;
-		stats->rx_frame_err	+= vport->err_stats.rx_frame_err;
+		stats->rx_over_errors	+= vport->err_stats.rx_over_err;
+		stats->rx_crc_errors	+= vport->err_stats.rx_crc_err;
+		stats->rx_frame_errors	+= vport->err_stats.rx_frame_err;
 		stats->collisions	+= vport->err_stats.collisions;
 
 		spin_unlock_bh(&vport->stats_lock);
 
 		if (dev_statsp) {
-			stats->rx_errors	+= dev_statsp->rx_errors;
-			stats->tx_errors	+= dev_statsp->tx_errors;
-			stats->rx_dropped	+= dev_statsp->rx_dropped;
-			stats->tx_dropped	+= dev_statsp->tx_dropped;
-			stats->rx_over_err	+= dev_statsp->rx_over_err;
-			stats->rx_crc_err	+= dev_statsp->rx_crc_err;
-			stats->rx_frame_err	+= dev_statsp->rx_frame_err;
-			stats->collisions	+= dev_statsp->collisions;
+			stats->rx_packets          += dev_statsp->rx_packets;
+			stats->tx_packets          += dev_statsp->tx_packets;
+			stats->rx_bytes            += dev_statsp->rx_bytes;
+			stats->tx_bytes            += dev_statsp->tx_bytes;
+			stats->rx_errors           += dev_statsp->rx_errors;
+			stats->tx_errors           += dev_statsp->tx_errors;
+			stats->rx_dropped          += dev_statsp->rx_dropped;
+			stats->tx_dropped          += dev_statsp->tx_dropped;
+			stats->multicast           += dev_statsp->multicast;
+			stats->collisions          += dev_statsp->collisions;
+			stats->rx_length_errors    += dev_statsp->rx_length_errors;
+			stats->rx_over_errors      += dev_statsp->rx_over_errors;
+			stats->rx_crc_errors       += dev_statsp->rx_crc_errors;
+			stats->rx_frame_errors     += dev_statsp->rx_frame_errors;
+			stats->rx_fifo_errors      += dev_statsp->rx_fifo_errors;
+			stats->rx_missed_errors    += dev_statsp->rx_missed_errors;
+			stats->tx_aborted_errors   += dev_statsp->tx_aborted_errors;
+			stats->tx_carrier_errors   += dev_statsp->tx_carrier_errors;
+			stats->tx_fifo_errors      += dev_statsp->tx_fifo_errors;
+			stats->tx_heartbeat_errors += dev_statsp->tx_heartbeat_errors;
+			stats->tx_window_errors    += dev_statsp->tx_window_errors;
+			stats->rx_compressed       += dev_statsp->rx_compressed;
+			stats->tx_compressed       += dev_statsp->tx_compressed;
 		}
 
 		for_each_possible_cpu(i) {
diff --git a/datapath/vport.h b/datapath/vport.h
index 30b0cc6b3..186d6bf74 100644
--- a/datapath/vport.h
+++ b/datapath/vport.h
@@ -56,7 +56,7 @@ int vport_detach(struct vport *);
 
 int vport_set_mtu(struct vport *, int mtu);
 int vport_set_addr(struct vport *, const unsigned char *);
-int vport_set_stats(struct vport *, struct odp_vport_stats *);
+int vport_set_stats(struct vport *, struct rtnl_link_stats64 *);
 
 const char *vport_get_name(const struct vport *);
 const char *vport_get_type(const struct vport *);
@@ -64,7 +64,7 @@ const unsigned char *vport_get_addr(const struct vport *);
 
 struct dp_port *vport_get_dp_port(const struct vport *);
 struct kobject *vport_get_kobj(const struct vport *);
-int vport_get_stats(struct vport *, struct odp_vport_stats *);
+int vport_get_stats(struct vport *, struct rtnl_link_stats64 *);
 
 unsigned vport_get_flags(const struct vport *);
 int vport_is_running(const struct vport *);
@@ -107,7 +107,7 @@ struct vport {
 
 	spinlock_t stats_lock;
 	struct vport_err_stats err_stats;
-	struct odp_vport_stats offset_stats;
+	struct rtnl_link_stats64 offset_stats;
 };
 
 #define VPORT_F_REQUIRED	(1 << 0) /* If init fails, module loading fails. */
@@ -177,13 +177,13 @@ struct vport_ops {
 
 	int (*set_mtu)(struct vport *, int mtu);
 	int (*set_addr)(struct vport *, const unsigned char *);
-	int (*set_stats)(const struct vport *, struct odp_vport_stats *);
+	int (*set_stats)(const struct vport *, struct rtnl_link_stats64 *);
 
 	/* Called with rcu_read_lock or RTNL lock. */
 	const char *(*get_name)(const struct vport *);
 	const unsigned char *(*get_addr)(const struct vport *);
 	struct kobject *(*get_kobj)(const struct vport *);
-	int (*get_stats)(const struct vport *, struct odp_vport_stats *);
+	int (*get_stats)(const struct vport *, struct rtnl_link_stats64 *);
 
 	unsigned (*get_dev_flags)(const struct vport *);
 	int (*is_running)(const struct vport *);
diff --git a/datapath/linux-2.6/compat-2.6/include/linux/if_link.h b/include/linux/if_link.h
similarity index 100%
rename from datapath/linux-2.6/compat-2.6/include/linux/if_link.h
rename to include/linux/if_link.h
diff --git a/include/openvswitch/datapath-protocol.h b/include/openvswitch/datapath-protocol.h
index 15c05e0d0..488590644 100644
--- a/include/openvswitch/datapath-protocol.h
+++ b/include/openvswitch/datapath-protocol.h
@@ -52,13 +52,17 @@
  * those types when compiling the kernel. */
 #ifdef __KERNEL__
 #include <linux/types.h>
+#include <linux/socket.h>
 #define ovs_be16 __be16
 #define ovs_be32 __be32
 #define ovs_be64 __be64
 #else
 #include "openvswitch/types.h"
+#include <sys/socket.h>
 #endif
 
+#include <linux/if_link.h>
+
 #define ODP_MAX 256             /* Maximum number of datapaths. */
 
 #define ODP_DP_CREATE           _IO('O', 0)
@@ -365,24 +369,9 @@ struct odp_vport_mod {
     void *config;
 };
 
-struct odp_vport_stats {
-    uint64_t rx_packets;
-    uint64_t tx_packets;
-    uint64_t rx_bytes;
-    uint64_t tx_bytes;
-    uint64_t rx_dropped;
-    uint64_t tx_dropped;
-    uint64_t rx_errors;
-    uint64_t tx_errors;
-    uint64_t rx_frame_err;
-    uint64_t rx_over_err;
-    uint64_t rx_crc_err;
-    uint64_t collisions;
-};
-
 struct odp_vport_stats_req {
     char devname[16];           /* IFNAMSIZ */
-    struct odp_vport_stats stats;
+    struct rtnl_link_stats64 stats;
 };
 
 struct odp_vport_ether {
diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
index d0b5e905a..5ea7cbd2d 100644
--- a/lib/netdev-vport.c
+++ b/lib/netdev-vport.c
@@ -293,19 +293,19 @@ netdev_vport_get_stats(const struct netdev *netdev, struct netdev_stats *stats)
     stats->tx_errors = ovsr.stats.tx_errors;
     stats->rx_dropped = ovsr.stats.rx_dropped;
     stats->tx_dropped = ovsr.stats.tx_dropped;
-    stats->multicast = UINT64_MAX;
+    stats->multicast = ovsr.stats.multicast;
     stats->collisions = ovsr.stats.collisions;
-    stats->rx_length_errors = UINT64_MAX;
-    stats->rx_over_errors = ovsr.stats.rx_over_err;
-    stats->rx_crc_errors = ovsr.stats.rx_crc_err;
-    stats->rx_frame_errors = ovsr.stats.rx_frame_err;
-    stats->rx_fifo_errors = UINT64_MAX;
-    stats->rx_missed_errors = UINT64_MAX;
-    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;
+    stats->rx_length_errors = ovsr.stats.rx_length_errors;
+    stats->rx_over_errors = ovsr.stats.rx_over_errors;
+    stats->rx_crc_errors = ovsr.stats.rx_crc_errors;
+    stats->rx_frame_errors = ovsr.stats.rx_frame_errors;
+    stats->rx_fifo_errors = ovsr.stats.rx_fifo_errors;
+    stats->rx_missed_errors = ovsr.stats.rx_missed_errors;
+    stats->tx_aborted_errors = ovsr.stats.tx_aborted_errors;
+    stats->tx_carrier_errors = ovsr.stats.tx_carrier_errors;
+    stats->tx_fifo_errors = ovsr.stats.tx_fifo_errors;
+    stats->tx_heartbeat_errors = ovsr.stats.tx_heartbeat_errors;
+    stats->tx_window_errors = ovsr.stats.tx_window_errors;
 
     return 0;
 }
@@ -326,10 +326,19 @@ netdev_vport_set_stats(struct netdev *netdev, const struct netdev_stats *stats)
     ovsr.stats.tx_errors = stats->tx_errors;
     ovsr.stats.rx_dropped = stats->rx_dropped;
     ovsr.stats.tx_dropped = stats->tx_dropped;
+    ovsr.stats.multicast = stats->multicast;
     ovsr.stats.collisions = stats->collisions;
-    ovsr.stats.rx_over_err = stats->rx_over_errors;
-    ovsr.stats.rx_crc_err = stats->rx_crc_errors;
-    ovsr.stats.rx_frame_err = stats->rx_frame_errors;
+    ovsr.stats.rx_length_errors = stats->rx_length_errors;
+    ovsr.stats.rx_over_errors = stats->rx_over_errors;
+    ovsr.stats.rx_crc_errors = stats->rx_crc_errors;
+    ovsr.stats.rx_frame_errors = stats->rx_frame_errors;
+    ovsr.stats.rx_fifo_errors = stats->rx_fifo_errors;
+    ovsr.stats.rx_missed_errors = stats->rx_missed_errors;
+    ovsr.stats.tx_aborted_errors = stats->tx_aborted_errors;
+    ovsr.stats.tx_carrier_errors = stats->tx_carrier_errors;
+    ovsr.stats.tx_fifo_errors = stats->tx_fifo_errors;
+    ovsr.stats.tx_heartbeat_errors = stats->tx_heartbeat_errors;
+    ovsr.stats.tx_window_errors = stats->tx_window_errors;
 
     err = netdev_vport_do_ioctl(ODP_VPORT_STATS_SET, &ovsr);
 
-- 
2.47.0