Rather than using ETHTOOL_GDRVINFO to check status, use get-stats from ovs since it is more consistent.
Signed-off-by: Pravin B Shelar <pshe...@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 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev