Commit ca3c39ab authored by Dan Williams's avatar Dan Williams

wifi: let WEXT be disabled with --with-wext=no

It's still enabled by default if you don't pass --with-wext=no.
But now it's possible to build without WEXT entirely.
parent aef4340e
......@@ -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
......
......@@ -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
......
......@@ -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 \
......
......@@ -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
......
......@@ -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)
......
......@@ -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);
......
......@@ -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)
......
......@@ -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);
......
......@@ -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;
}
......@@ -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 */
......@@ -20,13 +20,17 @@
*/
#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;
}
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment