[ovs-dev] [rtnl_link_stats64 v2 2/4] datapath: Add clean compat layer for dev_get_stats().

Ben Pfaff blp at nicira.com
Thu Nov 4 21:37:55 UTC 2010


Build tested (only) only on i386 for 2.6.26, 2.6.29, 2.6.33, 2.6.34,
and 2.6.36, and on x86-64 for 2.6.31 and 2.6.36.

Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 acinclude.m4                                       |   12 ++++++
 datapath/linux-2.6/Modules.mk                      |    1 +
 .../linux-2.6/compat-2.6/include/linux/if_link.h   |   42 ++++++++++++++++++++
 .../linux-2.6/compat-2.6/include/linux/netdevice.h |   10 ++---
 datapath/linux-2.6/compat-2.6/netdevice.c          |   42 ++++++++++++++++++++
 datapath/vport-netdev.c                            |    6 ---
 include/linux/if_link.h                            |   42 ++++++++++++++++++++
 7 files changed, 143 insertions(+), 12 deletions(-)
 create mode 100644 datapath/linux-2.6/compat-2.6/include/linux/if_link.h
 create mode 100644 datapath/linux-2.6/compat-2.6/netdevice.c
 create mode 100644 include/linux/if_link.h

diff --git a/acinclude.m4 b/acinclude.m4
index 565ca6d..c0c0b94 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -166,7 +166,17 @@ AC_DEFUN([OVS_CHECK_LINUX26_COMPAT], [
   OVS_GREP_IFELSE([$KSRC26/include/linux/in.h], [ipv4_is_multicast])
 
   OVS_GREP_IFELSE([$KSRC26/include/linux/netdevice.h], [dev_disable_lro])
+
+  # Linux 2.6.28 introduced dev_get_stats():
+  #     extern const struct net_device_stats *dev_get_stats(struct net_device *dev);
+  #
+  # Linux 2.6.36 changed dev_get_stats() to:
+  #     extern struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
+  #                                                    struct rtnl_link_stats64 *storage);
   OVS_GREP_IFELSE([$KSRC26/include/linux/netdevice.h], [dev_get_stats])
+  OVS_GREP_IFELSE([$KSRC26/include/linux/netdevice.h],
+                   [rtnl_link_stats64.*dev_get_stats],
+                   [OVS_DEFINE([HAVE_DEV_GET_STATS64])])
 
   # Check for the proto_data_valid member in struct sk_buff.  The [^@]
   # is necessary because some versions of this header remove the
@@ -200,6 +210,8 @@ AC_DEFUN([OVS_CHECK_LINUX26_COMPAT], [
   OVS_GREP_IFELSE([$KSRC26/include/net/netlink.h], [NLA_NUL_STRING])
   OVS_GREP_IFELSE([$KSRC26/include/net/netlink.h], [nla_get_be16])
 
+  OVS_GREP_IFELSE([$KSRC26/include/linux/if_link.h], [rtnl_link_stats64])
+
   OVS_CHECK_LOG2_H
 
   if cmp -s datapath/linux-2.6/kcompat.h.new \
diff --git a/datapath/linux-2.6/Modules.mk b/datapath/linux-2.6/Modules.mk
index 3ffee50..380f1c1 100644
--- a/datapath/linux-2.6/Modules.mk
+++ b/datapath/linux-2.6/Modules.mk
@@ -4,6 +4,7 @@ openvswitch_sources += \
 	linux-2.6/compat-2.6/genetlink-openvswitch.c \
 	linux-2.6/compat-2.6/ip_output-openvswitch.c \
 	linux-2.6/compat-2.6/kmemdup.c \
+	linux-2.6/compat-2.6/netdevice.c \
 	linux-2.6/compat-2.6/skbuff-openvswitch.c \
 	linux-2.6/compat-2.6/time.c
 openvswitch_headers += \
diff --git a/datapath/linux-2.6/compat-2.6/include/linux/if_link.h b/datapath/linux-2.6/compat-2.6/include/linux/if_link.h
new file mode 100644
index 0000000..8bc88cc
--- /dev/null
+++ b/datapath/linux-2.6/compat-2.6/include/linux/if_link.h
@@ -0,0 +1,42 @@
+#ifndef __LINUX_IF_LINK_WRAPPER_H
+#define __LINUX_IF_LINK_WRAPPER_H 1
+
+#include_next <linux/if_link.h>
+
+#ifndef HAVE_RTNL_LINK_STATS64
+#define HAVE_RTNL_LINK_STATS64
+/* The main device statistics structure */
+struct rtnl_link_stats64 {
+	__u64	rx_packets;		/* total packets received	*/
+	__u64	tx_packets;		/* total packets transmitted	*/
+	__u64	rx_bytes;		/* total bytes received 	*/
+	__u64	tx_bytes;		/* total bytes transmitted	*/
+	__u64	rx_errors;		/* bad packets received		*/
+	__u64	tx_errors;		/* packet transmit problems	*/
+	__u64	rx_dropped;		/* no space in linux buffers	*/
+	__u64	tx_dropped;		/* no space available in linux	*/
+	__u64	multicast;		/* multicast packets received	*/
+	__u64	collisions;
+
+	/* detailed rx_errors: */
+	__u64	rx_length_errors;
+	__u64	rx_over_errors;		/* receiver ring buff overflow	*/
+	__u64	rx_crc_errors;		/* recved pkt with crc error	*/
+	__u64	rx_frame_errors;	/* recv'd frame alignment error */
+	__u64	rx_fifo_errors;		/* recv'r fifo overrun		*/
+	__u64	rx_missed_errors;	/* receiver missed packet	*/
+
+	/* detailed tx_errors */
+	__u64	tx_aborted_errors;
+	__u64	tx_carrier_errors;
+	__u64	tx_fifo_errors;
+	__u64	tx_heartbeat_errors;
+	__u64	tx_window_errors;
+
+	/* for cslip etc */
+	__u64	rx_compressed;
+	__u64	tx_compressed;
+};
+#endif	/* !HAVE_RTNL_LINK_STATS64 */
+
+#endif
diff --git a/datapath/linux-2.6/compat-2.6/include/linux/netdevice.h b/datapath/linux-2.6/compat-2.6/include/linux/netdevice.h
index 11d9f78..03c95b2 100644
--- a/datapath/linux-2.6/compat-2.6/include/linux/netdevice.h
+++ b/datapath/linux-2.6/compat-2.6/include/linux/netdevice.h
@@ -77,12 +77,10 @@ extern void unregister_netdevice_many(struct list_head *head);
 extern void dev_disable_lro(struct net_device *dev);
 #endif
 
-#ifndef HAVE_DEV_GET_STATS
-static inline const struct net_device_stats *
-dev_get_stats(struct net_device *dev)
-{
-	return dev->get_stats(dev);
-}
+#ifndef HAVE_DEV_GET_STATS64
+#define dev_get_stats(dev, storage) rpl_dev_get_stats(dev, storage)
+struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
+					struct rtnl_link_stats64 *storage);
 #endif
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
diff --git a/datapath/linux-2.6/compat-2.6/netdevice.c b/datapath/linux-2.6/compat-2.6/netdevice.c
new file mode 100644
index 0000000..c3a2d25
--- /dev/null
+++ b/datapath/linux-2.6/compat-2.6/netdevice.c
@@ -0,0 +1,42 @@
+#include <linux/if_link.h>
+#include <linux/netdevice.h>
+
+#ifndef HAVE_DEV_GET_STATS64
+struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
+					struct rtnl_link_stats64 *storage)
+{
+	const struct net_device_stats *stats;
+
+#ifdef HAVE_DEV_GET_STATS
+	stats = (dev_get_stats)(dev);
+#else
+	stats = dev->get_stats(dev);
+#endif
+
+	storage->rx_packets = stats->rx_packets;
+	storage->tx_packets = stats->tx_packets;
+	storage->rx_bytes = stats->rx_bytes;
+	storage->tx_bytes = stats->tx_bytes;
+	storage->rx_errors = stats->rx_errors;
+	storage->tx_errors = stats->tx_errors;
+	storage->rx_dropped = stats->rx_dropped;
+	storage->tx_dropped = stats->tx_dropped;
+	storage->multicast = stats->multicast;
+	storage->collisions = stats->collisions;
+	storage->rx_length_errors = stats->rx_length_errors;
+	storage->rx_over_errors = stats->rx_over_errors;
+	storage->rx_crc_errors = stats->rx_crc_errors;
+	storage->rx_frame_errors = stats->rx_frame_errors;
+	storage->rx_fifo_errors = stats->rx_fifo_errors;
+	storage->rx_missed_errors = stats->rx_missed_errors;
+	storage->tx_aborted_errors = stats->tx_aborted_errors;
+	storage->tx_carrier_errors = stats->tx_carrier_errors;
+	storage->tx_fifo_errors = stats->tx_fifo_errors;
+	storage->tx_heartbeat_errors = stats->tx_heartbeat_errors;
+	storage->tx_window_errors = stats->tx_window_errors;
+	storage->rx_compressed = stats->rx_compressed;
+	storage->tx_compressed = stats->tx_compressed;
+
+	return storage;
+}
+#endif
diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c
index f6709e2..fce9b39 100644
--- a/datapath/vport-netdev.c
+++ b/datapath/vport-netdev.c
@@ -211,15 +211,9 @@ struct kobject *netdev_get_kobj(const struct vport *vport)
 int netdev_get_stats(const struct vport *vport, struct odp_vport_stats *stats)
 {
 	const struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
 	struct rtnl_link_stats64 *netdev_stats, storage;
 
 	netdev_stats = dev_get_stats(netdev_vport->dev, &storage);
-#else
-	const struct net_device_stats *netdev_stats;
-
-	netdev_stats = dev_get_stats(netdev_vport->dev);
-#endif
 
 	stats->rx_bytes		= netdev_stats->rx_bytes;
 	stats->rx_packets	= netdev_stats->rx_packets;
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
new file mode 100644
index 0000000..02d4eb4
--- /dev/null
+++ b/include/linux/if_link.h
@@ -0,0 +1,42 @@
+#ifndef __IF_LINK_WRAPPER_H
+#define __IF_LINK_WRAPPER_H
+
+#include_next <linux/if_link.h>
+
+#ifndef HAVE_RTNL_LINK_STATS64
+#define HAVE_RTNL_LINK_STATS64
+/* The main device statistics structure */
+struct rtnl_link_stats64 {
+	__u64	rx_packets;		/* total packets received	*/
+	__u64	tx_packets;		/* total packets transmitted	*/
+	__u64	rx_bytes;		/* total bytes received 	*/
+	__u64	tx_bytes;		/* total bytes transmitted	*/
+	__u64	rx_errors;		/* bad packets received		*/
+	__u64	tx_errors;		/* packet transmit problems	*/
+	__u64	rx_dropped;		/* no space in linux buffers	*/
+	__u64	tx_dropped;		/* no space available in linux	*/
+	__u64	multicast;		/* multicast packets received	*/
+	__u64	collisions;
+
+	/* detailed rx_errors: */
+	__u64	rx_length_errors;
+	__u64	rx_over_errors;		/* receiver ring buff overflow	*/
+	__u64	rx_crc_errors;		/* recved pkt with crc error	*/
+	__u64	rx_frame_errors;	/* recv'd frame alignment error */
+	__u64	rx_fifo_errors;		/* recv'r fifo overrun		*/
+	__u64	rx_missed_errors;	/* receiver missed packet	*/
+
+	/* detailed tx_errors */
+	__u64	tx_aborted_errors;
+	__u64	tx_carrier_errors;
+	__u64	tx_fifo_errors;
+	__u64	tx_heartbeat_errors;
+	__u64	tx_window_errors;
+
+	/* for cslip etc */
+	__u64	rx_compressed;
+	__u64	tx_compressed;
+};
+#endif	/* !HAVE_RTNL_LINK_STATS64 */
+
+#endif /* linux/if_link.h wrapper */
-- 
1.7.1





More information about the dev mailing list