[ovs-dev] [PATCH 3/5] netdev-linux: Cache error code from ether-addr ioctl.

Pravin B Shelar pshelar at nicira.com
Tue Mar 6 22:37:16 UTC 2012


Signed-off-by: Pravin B Shelar <pshelar at nicira.com>
---
 lib/netdev-linux.c |   85 ++++++++++++++++++++++++++++++----------------------
 1 files changed, 49 insertions(+), 36 deletions(-)

diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index 3067953..c7991ac 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -378,6 +378,7 @@ struct netdev_dev_linux {
     int vport_stats_error;      /* Cached error code from vport_get_stats().
                                    0 or an errno value. */
     int netdev_mtu_error;       /* Cached error code from SIOCGIFMTU or SIOCSIFMTU. */
+    int ether_addr_error;       /* Cached error code from set/get etheraddr. */
 
     struct ethtool_drvinfo drvinfo;  /* Cached from ETHTOOL_GDRVINFO. */
     struct tc *tc;
@@ -417,8 +418,8 @@ static int get_ifindex(const struct netdev *, int *ifindexp);
 static int do_set_addr(struct netdev *netdev,
                        int ioctl_nr, const char *ioctl_name,
                        struct in_addr addr);
-static int get_etheraddr(const char *netdev_name, uint8_t ea[ETH_ADDR_LEN]);
-static int set_etheraddr(const char *netdev_name, int hwaddr_family,
+static void get_etheraddr(struct netdev_dev_linux *);
+static void set_etheraddr(struct netdev_dev_linux *, int hwaddr_family,
                          const uint8_t[ETH_ADDR_LEN]);
 static int get_stats_via_netlink(int ifindex, struct netdev_stats *stats);
 static int get_stats_via_proc(const char *netdev_name, struct netdev_stats *stats);
@@ -1022,19 +1023,20 @@ netdev_linux_set_etheraddr(struct netdev *netdev_,
 {
     struct netdev_dev_linux *netdev_dev =
                                 netdev_dev_linux_cast(netdev_get_dev(netdev_));
-    int error;
 
-    if (!(netdev_dev->cache_valid & VALID_ETHERADDR)
-        || !eth_addr_equals(netdev_dev->etheraddr, mac)) {
-        error = set_etheraddr(netdev_get_name(netdev_), ARPHRD_ETHER, mac);
-        if (!error) {
-            netdev_dev->cache_valid |= VALID_ETHERADDR;
-            memcpy(netdev_dev->etheraddr, mac, ETH_ADDR_LEN);
-        }
-    } else {
-        error = 0;
+    if (netdev_dev->cache_valid & VALID_ETHERADDR) {
+         if (netdev_dev->ether_addr_error) {
+            goto out;
+         }
+         if (eth_addr_equals(netdev_dev->etheraddr, mac)) {
+            goto out;
+         }
     }
-    return error;
+
+    set_etheraddr(netdev_dev, ARPHRD_ETHER, mac);
+
+out:
+    return netdev_dev->ether_addr_error;
 }
 
 /* Returns a pointer to 'netdev''s MAC address.  The caller must not modify or
@@ -1045,16 +1047,19 @@ netdev_linux_get_etheraddr(const struct netdev *netdev_,
 {
     struct netdev_dev_linux *netdev_dev =
                                 netdev_dev_linux_cast(netdev_get_dev(netdev_));
-    if (!(netdev_dev->cache_valid & VALID_ETHERADDR)) {
-        int error = get_etheraddr(netdev_get_name(netdev_),
-                                  netdev_dev->etheraddr);
-        if (error) {
-            return error;
-        }
-        netdev_dev->cache_valid |= VALID_ETHERADDR;
+
+    if (netdev_dev->cache_valid & VALID_ETHERADDR) {
+        goto out;
     }
-    memcpy(mac, netdev_dev->etheraddr, ETH_ADDR_LEN);
-    return 0;
+
+    get_etheraddr(netdev_dev);
+
+out:
+    if (!netdev_dev->ether_addr_error) {
+        memcpy(mac, netdev_dev->etheraddr, ETH_ADDR_LEN);
+    }
+
+    return netdev_dev->ether_addr_error;
 }
 
 /* Returns the maximum size of transmitted (and received) packets on 'netdev',
@@ -4368,14 +4373,14 @@ get_ifindex(const struct netdev *netdev_, int *ifindexp)
     return 0;
 }
 
-static int
-get_etheraddr(const char *netdev_name, uint8_t ea[ETH_ADDR_LEN])
+static void
+get_etheraddr(struct netdev_dev_linux *netdev_dev)
 {
     struct ifreq ifr;
     int hwaddr_family;
 
     memset(&ifr, 0, sizeof ifr);
-    ovs_strzcpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name);
+    ovs_strzcpy(ifr.ifr_name, netdev_dev->netdev_dev.name, sizeof ifr.ifr_name);
     COVERAGE_INC(netdev_get_hwaddr);
     if (ioctl(af_inet_sock, SIOCGIFHWADDR, &ifr) < 0) {
         /* ENODEV probably means that a vif disappeared asynchronously and
@@ -4383,35 +4388,43 @@ get_etheraddr(const char *netdev_name, uint8_t ea[ETH_ADDR_LEN])
          * to INFO for that case. */
         VLOG(errno == ENODEV ? VLL_INFO : VLL_ERR,
              "ioctl(SIOCGIFHWADDR) on %s device failed: %s",
-             netdev_name, strerror(errno));
-        return errno;
+             netdev_dev->netdev_dev.name, strerror(errno));
+        netdev_dev->ether_addr_error = errno;
+        goto out;
     }
     hwaddr_family = ifr.ifr_hwaddr.sa_family;
     if (hwaddr_family != AF_UNSPEC && hwaddr_family != ARPHRD_ETHER) {
         VLOG_WARN("%s device has unknown hardware address family %d",
-                  netdev_name, hwaddr_family);
+                  netdev_dev->netdev_dev.name, hwaddr_family);
     }
-    memcpy(ea, ifr.ifr_hwaddr.sa_data, ETH_ADDR_LEN);
-    return 0;
+    memcpy(netdev_dev->etheraddr, ifr.ifr_hwaddr.sa_data, ETH_ADDR_LEN);
+    netdev_dev->ether_addr_error = 0;
+
+out:
+    netdev_dev->cache_valid |= VALID_ETHERADDR;
 }
 
-static int
-set_etheraddr(const char *netdev_name, int hwaddr_family,
+static void
+set_etheraddr(struct netdev_dev_linux *netdev_dev, int hwaddr_family,
               const uint8_t mac[ETH_ADDR_LEN])
 {
     struct ifreq ifr;
 
     memset(&ifr, 0, sizeof ifr);
-    ovs_strzcpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name);
+    ovs_strzcpy(ifr.ifr_name, netdev_dev->netdev_dev.name, sizeof ifr.ifr_name);
     ifr.ifr_hwaddr.sa_family = hwaddr_family;
     memcpy(ifr.ifr_hwaddr.sa_data, mac, ETH_ADDR_LEN);
     COVERAGE_INC(netdev_set_hwaddr);
     if (ioctl(af_inet_sock, SIOCSIFHWADDR, &ifr) < 0) {
         VLOG_ERR("ioctl(SIOCSIFHWADDR) on %s device failed: %s",
-                 netdev_name, strerror(errno));
-        return errno;
+                 netdev_dev->netdev_dev.name, strerror(errno));
+        netdev_dev->ether_addr_error = errno;
+        goto out;
     }
-    return 0;
+    memcpy(netdev_dev->etheraddr, mac, ETH_ADDR_LEN);
+    netdev_dev->ether_addr_error = 0;
+out:
+    netdev_dev->cache_valid |= VALID_ETHERADDR;
 }
 
 static int
-- 
1.7.1




More information about the dev mailing list