[ovs-dev] [PATCH] netdev-linux: Use get-stats to check status on internal devices.
Pravin B Shelar
pshelar at nicira.com
Wed Feb 29 18:04:01 PST 2012
Rather than using ETHTOOL_GDRVINFO to check status, use get-stats from ovs
since it is more consistent.
Signed-off-by: Pravin B Shelar <pshelar at nicira.com>
---
lib/netdev-linux.c | 69 +++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 52 insertions(+), 17 deletions(-)
diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index 5c322ca..e980373 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -114,7 +114,8 @@ enum {
VALID_IN6 = 1 << 3,
VALID_MTU = 1 << 4,
VALID_POLICING = 1 << 5,
- VALID_VPORT_STAT_ERROR = 1 << 6
+ VALID_VPORT_STAT_ERROR = 1 << 6,
+ VALID_GDRVINFO = 1 << 7,
};
struct tap_state {
@@ -374,6 +375,7 @@ struct netdev_dev_linux {
uint32_t kbits_burst;
int vport_stats_error; /* Cached error code from vport_get_stats().
0 or an errno value. */
+ struct ethtool_drvinfo drvinfo;
struct tc *tc;
union {
@@ -483,8 +485,32 @@ netdev_linux_wait(void)
netdev_linux_miimon_wait();
}
+static int
+netdev_linux_get_drvinfo(struct netdev_dev_linux *netdev_dev)
+{
+
+ int error;
+
+ if (netdev_dev->cache_valid & VALID_GDRVINFO) {
+ return 0;
+ }
+
+ memset(&netdev_dev->drvinfo, 0, sizeof netdev_dev->drvinfo);
+ error = netdev_linux_do_ethtool(netdev_dev->netdev_dev.name,
+ (struct ethtool_cmd *)&netdev_dev->drvinfo,
+ ETHTOOL_GDRVINFO,
+ "ETHTOOL_GDRVINFO");
+ if (!error) {
+ netdev_dev->cache_valid |= VALID_GDRVINFO;
+ }
+ return error;
+}
+
+
static void
-netdev_dev_linux_changed(struct netdev_dev_linux *dev, unsigned int ifi_flags)
+netdev_dev_linux_changed(struct netdev_dev_linux *dev,
+ unsigned int ifi_flags,
+ uint16_t change)
{
dev->change_seq++;
if (!dev->change_seq) {
@@ -496,7 +522,12 @@ netdev_dev_linux_changed(struct netdev_dev_linux *dev, unsigned int ifi_flags)
}
dev->ifi_flags = ifi_flags;
- dev->cache_valid = 0;
+ if (change == RTM_NEWLINK) {
+ dev->cache_valid = 0;
+ netdev_linux_get_drvinfo(dev);
+ } else {
+ dev->cache_valid &= VALID_GDRVINFO;
+ }
}
static void
@@ -512,7 +543,7 @@ netdev_linux_cache_cb(const struct rtnetlink_link_change *change,
if (is_netdev_linux_class(netdev_class)) {
dev = netdev_dev_linux_cast(base_dev);
- netdev_dev_linux_changed(dev, change->ifi_flags);
+ netdev_dev_linux_changed(dev, change->ifi_flags, change->nlmsg_type);
}
}
} else {
@@ -527,7 +558,7 @@ netdev_linux_cache_cb(const struct rtnetlink_link_change *change,
dev = node->data;
get_flags(&dev->netdev_dev, &flags);
- netdev_dev_linux_changed(dev, flags);
+ netdev_dev_linux_changed(dev, flags, change->nlmsg_type);
}
shash_destroy(&device_shash);
}
@@ -1167,7 +1198,7 @@ netdev_linux_miimon_run(void)
netdev_linux_get_miimon(dev->netdev_dev.name, &miimon);
if (miimon != dev->miimon) {
dev->miimon = miimon;
- netdev_dev_linux_changed(dev, dev->ifi_flags);
+ netdev_dev_linux_changed(dev, dev->ifi_flags, 0);
}
timer_set_duration(&dev->miimon_timer, dev->miimon_interval);
@@ -2140,21 +2171,25 @@ netdev_linux_get_next_hop(const struct in_addr *host, struct in_addr *next_hop,
static int
netdev_linux_get_status(const struct netdev *netdev, struct shash *sh)
{
- struct ethtool_drvinfo drvinfo;
+ struct netdev_stats stats;
int error;
+ struct netdev_dev_linux *netdev_dev =
+ netdev_dev_linux_cast(netdev_get_dev(netdev));
- memset(&drvinfo, 0, sizeof drvinfo);
- error = netdev_linux_do_ethtool(netdev_get_name(netdev),
- (struct ethtool_cmd *)&drvinfo,
- ETHTOOL_GDRVINFO,
- "ETHTOOL_GDRVINFO");
- if (!error) {
- shash_add(sh, "driver_name", xstrdup(drvinfo.driver));
- shash_add(sh, "driver_version", xstrdup(drvinfo.version));
- shash_add(sh, "firmware_version", xstrdup(drvinfo.fw_version));
+ error = netdev_linux_get_drvinfo(netdev_dev);
+ if (error) {
+ return error;
}
- return error;
+ /* Use vport-stats for checking status of internal device. */
+ get_stats_via_vport(netdev, &stats);
+
+ if (!netdev_dev->vport_stats_error) {
+ shash_add(sh, "driver_name", xstrdup(netdev_dev->drvinfo.driver));
+ shash_add(sh, "driver_version", xstrdup(netdev_dev->drvinfo.version));
+ shash_add(sh, "firmware_version", xstrdup(netdev_dev->drvinfo.fw_version));
+ }
+ return netdev_dev->vport_stats_error;
}
/* Looks up the ARP table entry for 'ip' on 'netdev'. If one exists and can be
--
1.7.1
More information about the dev
mailing list