datapath: Add clean compat layer for dev_get_stats().
authorBen Pfaff <blp@nicira.com>
Tue, 9 Nov 2010 20:39:17 +0000 (12:39 -0800)
committerBen Pfaff <blp@nicira.com>
Tue, 9 Nov 2010 21:48:22 +0000 (13:48 -0800)
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@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
datapath/linux-2.6/Modules.mk
datapath/linux-2.6/compat-2.6/include/linux/if_link.h [new file with mode: 0644]
datapath/linux-2.6/compat-2.6/include/linux/netdevice.h
datapath/linux-2.6/compat-2.6/netdevice.c [new file with mode: 0644]
datapath/vport-netdev.c

index 3ffee5004677e07820c83b9fd86b09789c0a3d0b..380f1c15af65a4969b7dc2a982f6f60409d095f7 100644 (file)
@@ -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 (file)
index 0000000..41f1a9c
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef __LINUX_IF_LINK_WRAPPER_H
+#define __LINUX_IF_LINK_WRAPPER_H 1
+
+#include_next <linux/if_link.h>
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
+/* 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 /* linux kernel < 2.6.35 */
+
+#endif
index 11d9f78fdde6dc4763c75eb61331f023ad9fdc59..e8988c909b7963de0e46cc416450423f6fad70e0 100644 (file)
@@ -77,12 +77,17 @@ 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);
-}
+/* Linux 2.6.28 introduced dev_get_stats():
+ * const struct net_device_stats *dev_get_stats(struct net_device *dev);
+ *
+ * Linux 2.6.36 changed dev_get_stats() to:
+ * struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
+ *                                         struct rtnl_link_stats64 *storage);
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
+#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 (file)
index 0000000..2980458
--- /dev/null
@@ -0,0 +1,49 @@
+#include <linux/if_link.h>
+#include <linux/netdevice.h>
+
+/* Linux 2.6.28 introduced dev_get_stats():
+ * const struct net_device_stats *dev_get_stats(struct net_device *dev);
+ *
+ * Linux 2.6.36 changed dev_get_stats() to:
+ * struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
+ *                                         struct rtnl_link_stats64 *storage);
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
+struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
+                                       struct rtnl_link_stats64 *storage)
+{
+       const struct net_device_stats *stats;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
+       stats = dev->get_stats(dev);
+#else  /* 2.6.28 <= kernel version < 2.6.36 */
+       stats = (dev_get_stats)(dev);
+#endif /* 2.6.28 <= kernel version < 2.6.36 */
+
+       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 /* kernel version < 2.6.36 */
index f6709e2a3dfa173c8d7827d0bee75df7b14cabd2..fce9b3978df8cd638cc900b464300319190cc875 100644 (file)
@@ -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;