netdev: Make carrier status available in device flags.
authorBen Pfaff <blp@nicira.com>
Wed, 7 Jan 2009 01:26:12 +0000 (17:26 -0800)
committerBen Pfaff <blp@nicira.com>
Fri, 23 Jan 2009 18:47:02 +0000 (10:47 -0800)
Before, network device carrier status was available only through
netdev_get_link_status().  However, Linux makes it available in network
device flags, so we might as well use it.

lib/netdev.c
lib/netdev.h
udatapath/datapath.c

index efa86e80c120c58f145c3ee0438c89546fbe9f9a..f9b27aceef151378eabed71a1e604022a7bba72b 100644 (file)
@@ -39,6 +39,7 @@
 #include <fcntl.h>
 #include <arpa/inet.h>
 #include <inttypes.h>
+#include <linux/if.h>
 #include <linux/if_tun.h>
 #include <linux/types.h>
 #include <linux/ethtool.h>
@@ -49,7 +50,6 @@
 #include <sys/socket.h>
 #include <netpacket/packet.h>
 #include <net/ethernet.h>
-#include <net/if.h>
 #include <net/if_arp.h>
 #include <net/if_packet.h>
 #include <net/route.h>
@@ -680,31 +680,6 @@ netdev_get_mtu(const struct netdev *netdev)
     return netdev->mtu;
 }
 
-/* Checks the link status.  Returns 1 or 0 to indicate the link is active 
- * or not, respectively.  Any other return value indicates an error. */
-int
-netdev_get_link_status(const struct netdev *netdev) 
-{
-    struct ifreq ifr;
-    struct ethtool_value edata;
-
-    memset(&ifr, 0, sizeof ifr);
-    strncpy(ifr.ifr_name, netdev->name, sizeof ifr.ifr_name);
-    ifr.ifr_data = (caddr_t) &edata;
-
-    memset(&edata, 0, sizeof edata);
-    edata.cmd = ETHTOOL_GLINK;
-    if (ioctl(netdev->netdev_fd, SIOCETHTOOL, &ifr) == 0) {
-        if (edata.data) {
-            return 1;
-        } else {
-            return 0;
-        }
-    }
-
-    return -1;
-}
-
 /* Returns the features supported by 'netdev' of type 'type', as a bitmap 
  * of bits from enum ofp_phy_features, in host byte order. */
 uint32_t
@@ -982,6 +957,9 @@ netdev_nodev_get_flags(const char *netdev_name, enum netdev_flags *flagsp)
     if (flags & IFF_PROMISC) {
         *flagsp |= NETDEV_PROMISC;
     }
+    if (flags & IFF_LOWER_UP) {
+        *flagsp |= NETDEV_CARRIER;
+    }
     return 0;
 }
 \f
index 0e06e6393256e349ab6a89b711040afd6889a174..28d84321497f929d32636234d0ac5eb3bbd7d119 100644 (file)
@@ -57,7 +57,8 @@ enum netdev_feature_type {
 
 enum netdev_flags {
     NETDEV_UP = 0x0001,         /* Device enabled? */
-    NETDEV_PROMISC = 0x0002     /* Promiscuous mode? */
+    NETDEV_PROMISC = 0x0002,    /* Promiscuous mode? */
+    NETDEV_CARRIER = 0x0004     /* Carrier detected? */
 };
 
 enum netdev_pseudo_ethertype {
@@ -81,7 +82,6 @@ int netdev_set_etheraddr(struct netdev *, const uint8_t mac[6]);
 const uint8_t *netdev_get_etheraddr(const struct netdev *);
 const char *netdev_get_name(const struct netdev *);
 int netdev_get_mtu(const struct netdev *);
-int netdev_get_link_status(const struct netdev *);
 uint32_t netdev_get_features(struct netdev *, int);
 bool netdev_get_in4(const struct netdev *, struct in_addr *);
 int netdev_set_in4(struct netdev *, struct in_addr addr, struct in_addr mask);
index 8e884a43ae4c8b29e8ef8959d324dd088672e11b..61b5c1fdee47c850e7f2083f4d82110e256107dd 100644 (file)
@@ -738,22 +738,19 @@ update_port_status(struct sw_port *p)
         VLOG_WARN_RL(&rl, "could not get netdev flags for %s", 
                      netdev_get_name(p->netdev));
         return 0;
+    }
+
+    if (flags & NETDEV_UP) {
+        p->config &= ~OFPPC_PORT_DOWN;
     } else {
-        if (flags & NETDEV_UP) {
-            p->config &= ~OFPPC_PORT_DOWN;
-        } else {
-            p->config |= OFPPC_PORT_DOWN;
-        } 
+        p->config |= OFPPC_PORT_DOWN;
     }
 
-    /* Not all cards support this getting link status, so don't warn on
-     * error. */
-    retval = netdev_get_link_status(p->netdev);
-    if (retval == 1) {
+    if (flags & NETDEV_CARRIER) {
         p->state &= ~OFPPS_LINK_DOWN;
-    } else if (retval == 0) {
+    } else {
         p->state |= OFPPS_LINK_DOWN;
-    } 
+    }
 
     return ((orig_config != p->config) || (orig_state != p->state));
 }