From 754f80fb5810dc2c3878df22aa88404c113e7dce Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 16 Oct 2003 11:09:43 -0700 Subject: [PATCH] [NET]: Catch buggy net drivers changing getstats op after registry. --- include/linux/netdevice.h | 1 + net/core/dev.c | 29 +++++++++++++++++++++++++++++ net/core/net-sysfs.c | 1 + 3 files changed, 31 insertions(+) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 2a53de551b53..cf00126c50ed 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -469,6 +469,7 @@ struct net_device /* class/net/name entry */ struct class_device class_dev; + struct net_device_stats* (*last_stats)(struct net_device *); }; #define SET_MODULE_OWNER(dev) do { } while (0) diff --git a/net/core/dev.c b/net/core/dev.c index 7cf411e5eb5c..7ba82b6a6429 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -713,6 +713,19 @@ static int default_rebuild_header(struct sk_buff *skb) return 1; } + +/* + * Some old buggy device drivers change get_stats after registering + * the device. Try and trap them here. + * This can be elimnated when all devices are known fixed. + */ +static inline int get_stats_changed(struct net_device *dev) +{ + int changed = dev->last_stats != dev->get_stats; + dev->last_stats = dev->get_stats; + return changed; +} + /** * dev_open - prepare an interface for use. * @dev: device to open @@ -736,6 +749,14 @@ int dev_open(struct net_device *dev) if (dev->flags & IFF_UP) return 0; + /* + * Check for broken device drivers. + */ + if (get_stats_changed(dev) && net_ratelimit()) { + printk(KERN_ERR "%s: driver changed get_stats after register\n", + dev->name); + } + /* * Is it even present? */ @@ -753,6 +774,14 @@ int dev_open(struct net_device *dev) } /* + * Check for more broken device drivers. + */ + if (get_stats_changed(dev) && net_ratelimit()) { + printk(KERN_ERR "%s: driver changed get_stats in open\n", + dev->name); + } + + /* * If it went open OK then: */ diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index b1fa8f6ccc2a..ae9b5c8e8098 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -419,6 +419,7 @@ int netdev_register_sysfs(struct net_device *net) } + net->last_stats = net->get_stats; if (net->get_stats && (ret = sysfs_create_group(&class_dev->kobj, &netstat_group))) goto out_unreg; -- 2.39.5