platform: don't use udev for link type determination
authorDan Williams <dcbw@redhat.com>
Mon, 13 Apr 2015 20:44:10 +0000 (15:44 -0500)
committerDan Williams <dcbw@redhat.com>
Fri, 1 May 2015 19:18:28 +0000 (14:18 -0500)
This allows us to always announce links when the kernel advertises
them, instead of waiting for udev.

data/77-nm-olpc-mesh.rules [deleted file]
data/Makefile.am
src/platform/nm-linux-platform.c

diff --git a/data/77-nm-olpc-mesh.rules b/data/77-nm-olpc-mesh.rules
deleted file mode 100644 (file)
index a1a1554..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# do not edit this file, it will be overwritten on update
-
-# The fact that this device is driven by libertas is not currently exposed
-# in the sysfs tree..?
-KERNEL=="msh*", SUBSYSTEM=="net", DRIVERS=="usb", ATTRS{idVendor}=="1286", ATTRS{idProduct}=="2001", ENV{ID_NM_OLPC_MESH}="1"
-
index 5a95ea2..64ff337 100644 (file)
@@ -37,8 +37,7 @@ examples_DATA = server.conf
 if WITH_UDEV_DIR
 udevrulesdir = $(UDEV_DIR)/rules.d
 udevrules_DATA = \
-       85-nm-unmanaged.rules \
-       77-nm-olpc-mesh.rules
+       85-nm-unmanaged.rules
 endif
 
 server.conf: server.conf.in
@@ -59,7 +58,6 @@ EXTRA_DIST = \
        NetworkManager-dispatcher.service.in \
        org.freedesktop.NetworkManager.service.in \
        85-nm-unmanaged.rules \
-       77-nm-olpc-mesh.rules \
        server.conf.in
 
 CLEANFILES = \
index ed22fe2..8671635 100644 (file)
@@ -496,35 +496,6 @@ udev_get_driver (GUdevDevice *device, int ifindex)
        return driver;
 }
 
-static NMLinkType
-udev_detect_link_type_from_device (GUdevDevice *udev_device, const char *ifname, int arptype, const char **out_name)
-{
-       const char *prop, *sysfs_path;
-
-       g_assert (ifname);
-
-       if (!udev_device)
-               return_type (NM_LINK_TYPE_UNKNOWN, "unknown");
-
-       if (   g_udev_device_get_property (udev_device, "ID_NM_OLPC_MESH")
-           || g_udev_device_get_sysfs_attr (udev_device, "anycast_mask"))
-               return_type (NM_LINK_TYPE_OLPC_MESH, "olpc-mesh");
-
-       prop = g_udev_device_get_property (udev_device, "DEVTYPE");
-       sysfs_path = g_udev_device_get_sysfs_path (udev_device);
-       if (wifi_utils_is_wifi (ifname, sysfs_path, prop))
-               return_type (NM_LINK_TYPE_WIFI, "wifi");
-       else if (g_strcmp0 (prop, "wwan") == 0)
-               return_type (NM_LINK_TYPE_WWAN_ETHERNET, "wwan");
-       else if (g_strcmp0 (prop, "wimax") == 0)
-               return_type (NM_LINK_TYPE_WIMAX, "wimax");
-
-       if (arptype == ARPHRD_ETHER)
-               return_type (NM_LINK_TYPE_ETHERNET, "ethernet");
-
-       return_type (NM_LINK_TYPE_UNKNOWN, "unknown");
-}
-
 /******************************************************************
  * NMPlatform types and functions
  ******************************************************************/
@@ -929,6 +900,31 @@ link_is_announceable (NMPlatform *platform, struct rtnl_link *rtnllink)
        return FALSE;
 }
 
+#define DEVTYPE_PREFIX "DEVTYPE="
+
+static char *
+read_devtype (const char *sysfs_path)
+{
+       gs_free char *uevent = g_strdup_printf ("%s/uevent", sysfs_path);
+       char *contents = NULL;
+       char *cont, *end;
+
+       if (!g_file_get_contents (uevent, &contents, NULL, NULL))
+               return NULL;
+       for (cont = contents; cont; cont = end) {
+               end = strpbrk (cont, "\r\n");
+               if (end)
+                       *end++ = '\0';
+               if (strncmp (cont, DEVTYPE_PREFIX, STRLEN (DEVTYPE_PREFIX)) == 0) {
+                       cont += STRLEN (DEVTYPE_PREFIX);
+                       memmove (contents, cont, strlen (cont) + 1);
+                       return contents;
+               }
+       }
+       g_free (contents);
+       return NULL;
+}
+
 static NMLinkType
 link_extract_type (NMPlatform *platform, struct rtnl_link *rtnllink, const char **out_name)
 {
@@ -943,7 +939,9 @@ link_extract_type (NMPlatform *platform, struct rtnl_link *rtnllink, const char
                int arptype = rtnl_link_get_arptype (rtnllink);
                const char *driver;
                const char *ifname;
-               GUdevDevice *udev_device = NULL;
+               gs_free char *anycast_mask = NULL;
+               gs_free char *sysfs_path = NULL;
+               gs_free char *devtype = NULL;
 
                if (arptype == ARPHRD_LOOPBACK)
                        return_type (NM_LINK_TYPE_LOOPBACK, "loopback");
@@ -966,14 +964,25 @@ link_extract_type (NMPlatform *platform, struct rtnl_link *rtnllink, const char
                if (!g_strcmp0 (driver, "openvswitch"))
                        return_type (NM_LINK_TYPE_OPENVSWITCH, "openvswitch");
 
-               if (platform) {
-                       udev_device = g_hash_table_lookup (NM_LINUX_PLATFORM_GET_PRIVATE (platform)->udev_devices,
-                                                          GINT_TO_POINTER (rtnl_link_get_ifindex (rtnllink)));
+               sysfs_path = g_strdup_printf ("/sys/class/net/%s", ifname);
+               anycast_mask = g_strdup_printf ("%s/anycast_mask", sysfs_path);
+               if (g_file_test (anycast_mask, G_FILE_TEST_EXISTS))
+                       return_type (NM_LINK_TYPE_OLPC_MESH, "olpc-mesh");
+
+               devtype = read_devtype (sysfs_path);
+               if (devtype) {
+                       if (wifi_utils_is_wifi (ifname, sysfs_path, devtype))
+                               return_type (NM_LINK_TYPE_WIFI, "wifi");
+                       else if (g_strcmp0 (devtype, "wwan") == 0)
+                               return_type (NM_LINK_TYPE_WWAN_ETHERNET, "wwan");
+                       else if (g_strcmp0 (devtype, "wimax") == 0)
+                               return_type (NM_LINK_TYPE_WIMAX, "wimax");
                }
-               return udev_detect_link_type_from_device (udev_device,
-                                                         ifname,
-                                                         arptype,
-                                                         out_name);
+
+               if (arptype == ARPHRD_ETHER)
+                       return_type (NM_LINK_TYPE_ETHERNET, "ethernet");
+
+               return_type (NM_LINK_TYPE_UNKNOWN, "unknown");
        } else if (!strcmp (type, "dummy"))
                return_type (NM_LINK_TYPE_DUMMY, "dummy");
        else if (!strcmp (type, "gre"))