wifi: let WEXT be disabled with --with-wext=no
authorDan Williams <dcbw@redhat.com>
Thu, 1 Mar 2012 05:11:04 +0000 (23:11 -0600)
committerDan Williams <dcbw@redhat.com>
Thu, 1 Mar 2012 05:11:04 +0000 (23:11 -0600)
It's still enabled by default if you don't pass --with-wext=no.
But now it's possible to build without WEXT entirely.

15 files changed:
Makefile.am
configure.ac
src/Makefile.am
src/nm-manager.c
src/settings/plugins/ifcfg-rh/Makefile.am
src/settings/plugins/ifcfg-rh/reader.c
src/settings/plugins/ifcfg-rh/tests/Makefile.am
src/supplicant-manager/nm-supplicant-interface.c
src/wifi/wifi-utils-nl80211.c [moved from src/wifi-utils-nl80211.c with 87% similarity]
src/wifi/wifi-utils-nl80211.h [moved from src/wifi-utils-nl80211.h with 95% similarity]
src/wifi/wifi-utils-private.h [moved from src/wifi-utils-private.h with 100% similarity]
src/wifi/wifi-utils-wext.c [moved from src/wifi-utils-wext.c with 100% similarity]
src/wifi/wifi-utils-wext.h [moved from src/wifi-utils-wext.h with 100% similarity]
src/wifi/wifi-utils.c [moved from src/wifi-utils.c with 88% similarity]
src/wifi/wifi-utils.h [moved from src/wifi-utils.h with 96% similarity]

index e407d38..bcd403b 100644 (file)
@@ -31,7 +31,8 @@ DISTCHECK_CONFIGURE_FLAGS = \
        --with-docs=yes \
        --enable-more-warnings=yes \
        --with-udev-dir=$$dc_install_base/lib/udev \
-       --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
+       --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir) \
+       --with-wext=no
 
 DISTCLEANFILES = intltool-extract intltool-merge intltool-update
 
index 5bdb6c5..69e0640 100644 (file)
@@ -213,25 +213,35 @@ if ! test x"$ac_distver" = x""; then
   AC_DEFINE_UNQUOTED(NM_DIST_VERSION, "$ac_distver", [Define the distribution version string])
 fi
 
-AC_MSG_CHECKING([Linux kernel WEXT headers])
-AC_COMPILE_IFELSE(
-       [AC_LANG_PROGRAM(
-              [[#ifndef __user
-                #define __user
-                #endif
-                #include <sys/types.h>
-                #include <linux/types.h>
-                #include <sys/socket.h>
-                #include <linux/wireless.h>]],
-              [[#ifndef IWEVGENIE
-                #error "not found"
-                #endif]])],
-        [ac_have_iwevgenie=yes],
-        [ac_have_iwevgenie=no])
-AC_MSG_RESULT($ac_have_iwevgenie)
-if test "$ac_have_iwevgenie" = no; then
-       AC_MSG_ERROR(Linux kernel development header linux/wireless.h not installed or not functional)
+dnl
+dnl Default to using WEXT but allow it to be disabled
+dnl
+AC_ARG_WITH(wext, AS_HELP_STRING([--with-wext=yes], [Enable or disable Linux Wireless Extensions]), ac_with_wext=$withval, ac_with_wext="yes")
+if test x"$ac_with_wext" = x"yes"; then
+       AC_MSG_CHECKING([Linux kernel WEXT headers])
+       AC_COMPILE_IFELSE(
+               [AC_LANG_PROGRAM(
+                     [[#ifndef __user
+                       #define __user
+                       #endif
+                       #include <sys/types.h>
+                       #include <linux/types.h>
+                       #include <sys/socket.h>
+                       #include <linux/wireless.h>]],
+                     [[#ifndef IWEVGENIE
+                       #error "not found"
+                       #endif]])],
+               [ac_have_iwevgenie=yes],
+               [ac_have_iwevgenie=no])
+       AC_MSG_RESULT($ac_have_iwevgenie)
+       if test "$ac_have_iwevgenie" = no; then
+              AC_MSG_ERROR(Linux kernel development header linux/wireless.h not installed or not functional)
+       fi
+       AC_DEFINE(HAVE_WEXT, 1, [Define if you have Linux Wireless Extensions support])
+else
+       AC_DEFINE(HAVE_WEXT, 0, [Define if you have Linux Wireless Extensions support])
 fi
+AM_CONDITIONAL(WITH_WEXT, test x"${ac_with_wext}" = x"yes")
 
 AC_MSG_CHECKING([Linux kernel nl80211 headers])
 AC_COMPILE_IFELSE(
@@ -709,6 +719,7 @@ src/ppp-manager/Makefile
 src/dnsmasq-manager/Makefile
 src/modem-manager/Makefile
 src/bluez-manager/Makefile
+src/wifi/Makefile
 src/firewall-manager/Makefile
 src/settings/Makefile
 src/settings/plugins/Makefile
index 00e1997..2e74f09 100644 (file)
@@ -12,6 +12,7 @@ SUBDIRS= \
        modem-manager \
        bluez-manager \
        firewall-manager \
+       wifi \
        settings
 
 if WITH_WIMAX
@@ -36,6 +37,7 @@ INCLUDES = -I${top_srcdir} \
            -I$(top_srcdir)/src/bluez-manager \
            -I$(top_srcdir)/src/firewall-manager \
            -I$(top_srcdir)/src/settings \
+           -I$(top_srcdir)/src/wifi \
            -I${top_srcdir}/libnm-util \
            -I${top_builddir}/libnm-util \
            -I${top_srcdir}/callouts
@@ -118,13 +120,6 @@ NetworkManager_SOURCES = \
                nm-device-private.h \
                nm-device-ethernet.c \
                nm-device-ethernet.h \
-               wifi-utils.c \
-               wifi-utils.h \
-               wifi-utils-private.h \
-               wifi-utils-wext.c \
-               wifi-utils-wext.h \
-               wifi-utils-nl80211.c \
-               wifi-utils-nl80211.h \
                nm-device-wifi.c \
                nm-device-wifi.h \
                nm-device-wired.c \
@@ -304,6 +299,7 @@ NetworkManager_LDADD = \
        ./ppp-manager/libppp-manager.la \
        ./modem-manager/libmodem-manager.la \
        ./bluez-manager/libbluez-manager.la \
+       ./wifi/libwifi-utils.la \
        ./firewall-manager/libfirewall-manager.la \
        ./settings/libsettings.la \
        ./backends/libnmbackend.la \
index 146d491..e95a92c 100644 (file)
@@ -2115,9 +2115,6 @@ load_device_factories (NMManager *self)
 static gboolean
 is_wireless (GUdevDevice *device)
 {
-       char phy80211_path[255];
-       struct stat s;
-       const char *path;
        const char *tmp;
 
        /* Check devtype, newer kernels (2.6.32+) have this */
@@ -2125,14 +2122,9 @@ is_wireless (GUdevDevice *device)
        if (g_strcmp0 (tmp, "wlan") == 0)
                return TRUE;
 
-       /* Check for nl80211 sysfs paths */
-       path = g_udev_device_get_sysfs_path (device);
-       snprintf (phy80211_path, sizeof (phy80211_path), "%s/phy80211", path);
-       if ((stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR)))
-               return TRUE;
-
        /* Otherwise hit up WEXT directly */
-       return wifi_utils_is_wifi (g_udev_device_get_name (device));
+       return wifi_utils_is_wifi (g_udev_device_get_name (device),
+                                  g_udev_device_get_sysfs_path (device));
 }
 
 static gboolean
index d9008bd..8b5b0f2 100644 (file)
@@ -23,6 +23,7 @@ libifcfg_rh_io_la_SOURCES = \
        utils.h
 
 INCLUDES = \
+       -I$(top_srcdir)/src/wifi \
        -I$(top_srcdir)/src/settings \
        -I$(top_srcdir)/include \
        -I$(top_builddir)/include \
@@ -38,6 +39,7 @@ libifcfg_rh_io_la_CPPFLAGS = \
        -DSBINDIR=\"$(sbindir)\"
 
 libifcfg_rh_io_la_LIBADD = \
+       $(top_builddir)/src/wifi/libwifi-utils.la \
        $(top_builddir)/libnm-util/libnm-util.la \
        $(GLIB_LIBS) \
        $(NSS_LIBS)
index 058385d..22333bd 100644 (file)
@@ -32,7 +32,6 @@
 #include <unistd.h>
 #include <netinet/ether.h>
 #include <linux/if.h>
-#include <linux/wireless.h>
 
 #include <glib.h>
 #include <glib/gi18n.h>
@@ -48,6 +47,8 @@
 #include <nm-setting-bond.h>
 #include <nm-utils.h>
 
+#include "wifi-utils.h"
+
 #include "common.h"
 #include "shvar.h"
 #include "utils.h"
@@ -3544,47 +3545,6 @@ infiniband_connection_from_ifcfg (const char *file,
        return connection;
 }
 
-static gboolean
-is_wireless_device (const char *iface)
-{
-       int fd;
-       struct iw_range range;
-       struct iwreq wrq;
-       gboolean is_wireless = FALSE;
-
-       g_return_val_if_fail (iface != NULL, FALSE);
-
-       fd = socket(AF_INET, SOCK_DGRAM, 0);
-       if (fd == -1)
-               return FALSE;
-
-       memset (&wrq, 0, sizeof (struct iwreq));
-       memset (&range, 0, sizeof (struct iw_range));
-       strncpy (wrq.ifr_name, iface, IFNAMSIZ);
-       wrq.u.data.pointer = (caddr_t) &range;
-       wrq.u.data.length = sizeof (struct iw_range);
-
-       if (ioctl (fd, SIOCGIWRANGE, &wrq) == 0)
-               is_wireless = TRUE;
-       else {
-               if (errno == EOPNOTSUPP)
-                       is_wireless = FALSE;
-               else {
-                       /* Sigh... some wired devices (kvm/qemu) return EINVAL when the
-                        * device is down even though it's not a wireless device.  So try
-                        * IWNAME as a fallback.
-                        */
-                       memset (&wrq, 0, sizeof (struct iwreq));
-                       strncpy (wrq.ifr_name, iface, IFNAMSIZ);
-                       if (ioctl (fd, SIOCGIWNAME, &wrq) == 0)
-                               is_wireless = TRUE;
-               }
-       }
-
-       close (fd);
-       return is_wireless;
-}
-
 static void
 handle_bond_option (NMSettingBond *s_bond,
                     const char *key,
@@ -4012,7 +3972,7 @@ connection_from_file (const char *filename,
                        else if (is_vlan_device (device, parsed))
                                type = g_strdup (TYPE_VLAN);
                        /* Test wireless extensions */
-                       else if (is_wireless_device (device))
+                       else if (wifi_utils_is_wifi (device, NULL))
                                type = g_strdup (TYPE_WIRELESS);
                        else
                                type = g_strdup (TYPE_ETHERNET);
index 6b99561..1c433ff 100644 (file)
@@ -21,6 +21,7 @@ test_ifcfg_rh_CPPFLAGS = \
 test_ifcfg_rh_LDADD = \
        $(top_builddir)/libnm-glib/libnm-glib.la \
        $(top_builddir)/libnm-util/libnm-util.la \
+       $(top_builddir)/src/wifi/libwifi-utils.la \
        $(builddir)/../libifcfg-rh-io.la \
        $(DBUS_LIBS)
 
index b4157a5..042ef9e 100644 (file)
@@ -19,6 +19,7 @@
  * Copyright (C) 2006 - 2008 Novell, Inc.
  */
 
+#include <config.h>
 #include <stdio.h>
 #include <string.h>
 #include <glib.h>
@@ -804,6 +805,12 @@ interface_add_cb (DBusGProxy *proxy,
        }
 }
 
+#if HAVE_WEXT
+#define DEFAULT_WIFI_DRIVER "nl80211,wext"
+#else
+#define DEFAULT_WIFI_DRIVER "nl80211"
+#endif
+
 static void
 interface_add (NMSupplicantInterface *self, gboolean is_wireless)
 {
@@ -832,7 +839,7 @@ interface_add (NMSupplicantInterface *self, gboolean is_wireless)
 
        driver = g_new0 (GValue, 1);
        g_value_init (driver, G_TYPE_STRING);
-       g_value_set_string (driver, is_wireless ? "nl80211,wext" : "wired");
+       g_value_set_string (driver, is_wireless ? DEFAULT_WIFI_DRIVER : "wired");
        g_hash_table_insert (hash, "Driver", driver);
 
        ifname = g_new0 (GValue, 1);
similarity index 87%
rename from src/wifi-utils-nl80211.c
rename to src/wifi/wifi-utils-nl80211.c
index ed26754..6411602 100644 (file)
@@ -73,17 +73,16 @@ static int error_handler (struct sockaddr_nl *nla, struct nlmsgerr *err,
        return NL_SKIP;
 }
 
-static struct nl_msg *nl80211_alloc_msg (WifiDataNl80211 *nl80211,
-                                        guint32 cmd, guint32 flags)
+static struct nl_msg *
+_nl80211_alloc_msg (int id, int ifindex, guint32 cmd, guint32 flags)
 {
-       struct nl_msg *msg = nlmsg_alloc ();
-       if (!msg)
-               return NULL;
-
-       genlmsg_put (msg, 0, 0, nl80211->id, 0, flags, cmd, 0);
-
-       NLA_PUT_U32 (msg, NL80211_ATTR_IFINDEX, nl80211->parent.ifindex);
+       struct nl_msg *msg;
 
+       msg = nlmsg_alloc ();
+       if (msg) {
+               genlmsg_put (msg, 0, 0, id, 0, flags, cmd, 0);
+               NLA_PUT_U32 (msg, NL80211_ATTR_IFINDEX, ifindex);
+       }
        return msg;
 
  nla_put_failure:
@@ -91,44 +90,59 @@ static struct nl_msg *nl80211_alloc_msg (WifiDataNl80211 *nl80211,
        return NULL;
 }
 
-static int nl80211_send_and_recv (WifiDataNl80211 *nl80211,
-                                 struct nl_msg *msg,
-                                 int (*valid_handler)(struct nl_msg *, void *),
-                                 void *valid_data)
+static struct nl_msg *
+nl80211_alloc_msg (WifiDataNl80211 *nl80211, guint32 cmd, guint32 flags)
+{
+       return _nl80211_alloc_msg (nl80211->id, nl80211->parent.ifindex, cmd, flags);
+}
+
+/* NOTE: this function consumes 'msg' */
+static int
+_nl80211_send_and_recv (struct nl_sock *nl_sock, 
+                        struct nl_cb *nl_cb,
+                        struct nl_msg *msg,
+                        int (*valid_handler)(struct nl_msg *, void *),
+                        void *valid_data)
 {
        struct nl_cb *cb;
        int err;
 
-       if (msg == NULL)
-               return -ENOMEM;
-
+       g_return_val_if_fail (msg != NULL, -ENOMEM);
        g_return_val_if_fail (valid_handler != NULL, -EINVAL);
 
-       cb = nl_cb_clone (nl80211->nl_cb);
+       cb = nl_cb_clone (nl_cb);
        if (!cb) {
                err = -ENOMEM;
                goto out;
        }
 
-       err = nl_send_auto_complete (nl80211->nl_sock, msg);
+       err = nl_send_auto_complete (nl_sock, msg);
        if (err < 0)
                goto out;
 
        err = 1;
-
        nl_cb_err (cb, NL_CB_CUSTOM, error_handler, &err);
        nl_cb_set (cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
        nl_cb_set (cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
        nl_cb_set (cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, valid_data);
 
        while (err > 0)
-               nl_recvmsgs (nl80211->nl_sock, cb);
+               nl_recvmsgs (nl_sock, cb);
+
  out:
        nl_cb_put (cb);
        nlmsg_free (msg);
        return err;
 }
 
+static int
+nl80211_send_and_recv (WifiDataNl80211 *nl80211,
+                       struct nl_msg *msg,
+                       int (*valid_handler)(struct nl_msg *, void *),
+                       void *valid_data)
+{
+       return _nl80211_send_and_recv (nl80211->nl_sock, nl80211->nl_cb, msg, valid_handler, valid_data);
+}
 
 static void
 wifi_nl80211_deinit (WifiData *parent)
@@ -186,9 +200,6 @@ wifi_nl80211_get_mode (WifiData *data)
                return NM_802_11_MODE_UNKNOWN;
 
        return iface_info.mode;
-       return NM_802_11_MODE_INFRA;
-       return NM_802_11_MODE_ADHOC;
-       return NM_802_11_MODE_UNKNOWN;
 }
 
 static gboolean
@@ -730,3 +741,69 @@ error:
        wifi_utils_deinit ((WifiData *) nl80211);
        return NULL;
 }
+
+static int
+iface_to_index (struct nl_sock *nl_sock, const char *iface)
+{
+       struct nl_cache *link_cache;
+       int err, ifindex;
+
+       /* name to index */
+       err = rtnl_link_alloc_cache (nl_sock, &link_cache);
+       if (err < 0) {
+               nm_log_warn (LOGD_HW, "failed to allocate link cache");
+               return -1;
+       }
+       nl_cache_mngt_provide (link_cache);
+       nl_cache_refill (nl_sock, link_cache);
+       ifindex = rtnl_link_name2i (link_cache, iface);
+       nl_cache_free (link_cache);
+
+       return ifindex;
+}
+
+gboolean
+wifi_nl80211_is_wifi (const char *iface)
+{
+       struct nl_sock *nl_sock;
+       struct nl_cb *nl_cb = NULL;
+       struct nl_msg *msg = NULL;
+       int id, ifindex;
+       struct nl80211_iface_info iface_info = {
+               .mode = NM_802_11_MODE_UNKNOWN,
+       };
+       gboolean is_wifi = FALSE;
+
+       nl_sock = nl_socket_alloc ();
+       if (nl_sock == NULL)
+               return FALSE;
+
+       ifindex = iface_to_index (nl_sock, iface);
+       if (index < 0)
+               return FALSE;
+
+       if (genl_connect (nl_sock))
+               goto error;
+
+       id = genl_ctrl_resolve (nl_sock, "nl80211");
+       if (id < 0)
+               goto error;
+
+       nl_cb = nl_cb_alloc (NL_CB_DEFAULT);
+       if (nl_cb) {
+               msg = _nl80211_alloc_msg (id, ifindex, NL80211_CMD_GET_INTERFACE, 0);
+               if (_nl80211_send_and_recv (nl_sock,
+                                               nl_cb,
+                                               msg,
+                                               nl80211_iface_info_handler,
+                                               &iface_info) >= 0)
+                       is_wifi = (iface_info.mode != NM_802_11_MODE_UNKNOWN);
+       }
+
+ error:
+       if (nl_cb)
+               nl_cb_put (nl_cb);
+       nl_socket_free (nl_sock);
+       return is_wifi;
+}
+
similarity index 95%
rename from src/wifi-utils-nl80211.h
rename to src/wifi/wifi-utils-nl80211.h
index 371aa4e..2a7fe87 100644 (file)
@@ -25,4 +25,6 @@
 
 WifiData *wifi_nl80211_init (const char *iface, int ifindex);
 
+gboolean wifi_nl80211_is_wifi (const char *iface);
+
 #endif  /* WIFI_UTILS_NL80211_H */
similarity index 88%
rename from src/wifi-utils.c
rename to src/wifi/wifi-utils.c
index a9b946f..a99a4b7 100644 (file)
  */
 
 #include <config.h>
+#include <sys/stat.h>
+#include <stdio.h>
 #include <string.h>
 #include <glib.h>
 
 #include "wifi-utils.h"
 #include "wifi-utils-private.h"
-#include "wifi-utils-wext.h"
 #include "wifi-utils-nl80211.h"
+#if HAVE_WEXT
+#include "wifi-utils-wext.h"
+#endif
 
 gpointer
 wifi_data_new (const char *iface, int ifindex, gsize len)
@@ -58,10 +62,12 @@ wifi_utils_init (const char *iface, int ifindex, gboolean check_scan)
        g_return_val_if_fail (ifindex > 0, NULL);
 
        ret = wifi_nl80211_init (iface, ifindex);
-       if (ret != NULL)
-               return ret;
-
-       return wifi_wext_init (iface, ifindex, check_scan);
+       if (ret == NULL) {
+#if HAVE_WEXT
+               ret = wifi_wext_init (iface, ifindex, check_scan);
+#endif
+       }
+       return ret;
 }
 
 NMDeviceWifiCapabilities
@@ -151,12 +157,27 @@ wifi_utils_deinit (WifiData *data)
 }
 
 gboolean
-wifi_utils_is_wifi (const char *iface)
+wifi_utils_is_wifi (const char *iface, const char *sysfs_path)
 {
+       char phy80211_path[255];
+       struct stat s;
+
        g_return_val_if_fail (iface != NULL, FALSE);
 
+       if (sysfs_path) {
+               /* Check for nl80211 sysfs paths */
+               snprintf (phy80211_path, sizeof (phy80211_path), "%s/phy80211", sysfs_path);
+               if ((stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR)))
+                       return TRUE;
+       }
+
+       if (wifi_nl80211_is_wifi (iface))
+               return TRUE;
+
+#if HAVE_WEXT
        if (wifi_wext_is_wifi (iface))
                return TRUE;
+#endif
 
        return FALSE;
 }
similarity index 96%
rename from src/wifi-utils.h
rename to src/wifi/wifi-utils.h
index 66bb097..09583e7 100644 (file)
@@ -29,7 +29,7 @@
 
 typedef struct WifiData WifiData;
 
-gboolean wifi_utils_is_wifi (const char *iface);
+gboolean wifi_utils_is_wifi (const char *iface, const char *sysfs_path);
 
 WifiData *wifi_utils_init (const char *iface, int ifindex, gboolean check_scan);