summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/NetworkManagerDevice.c348
-rw-r--r--src/NetworkManagerDevice.h4
-rw-r--r--src/NetworkManagerDevicePrivate.h48
-rw-r--r--src/NetworkManagerPolicy.c38
-rw-r--r--src/NetworkManagerUtils.c193
-rw-r--r--src/NetworkManagerUtils.h26
-rw-r--r--src/nm-dbus-device.c35
-rw-r--r--src/nm-dbus-nm.c20
8 files changed, 364 insertions, 348 deletions
diff --git a/src/NetworkManagerDevice.c b/src/NetworkManagerDevice.c
index 9c52a21a08..dae40d325e 100644
--- a/src/NetworkManagerDevice.c
+++ b/src/NetworkManagerDevice.c
@@ -52,6 +52,9 @@ static gboolean supports_mii_carrier_detect (NMDevice *dev);
static gboolean supports_ethtool_carrier_detect (NMDevice *dev);
static gboolean nm_device_bring_up_wait (NMDevice *dev, gboolean cancelable);
static gboolean link_to_specific_ap (NMDevice *dev, NMAccessPoint *ap, gboolean default_link);
+static guint32 nm_device_discover_capabilities (NMDevice *dev);
+static gboolean nm_is_driver_supported (NMDevice *dev);
+static guint32 nm_device_wireless_discover_capabilities (NMDevice *dev);
static void nm_device_activate_schedule_stage1_device_prepare (NMActRequest *req);
static void nm_device_activate_schedule_stage2_device_config (NMActRequest *req);
@@ -114,34 +117,65 @@ static gboolean nm_device_test_wireless_extensions (NMDevice *dev)
/*
- * nm_device_supports_wireless_scan
+ * nm_get_device_driver_name
*
- * Test whether a given device is a wireless one or not.
+ * Get the device's driver name from HAL.
*
*/
-static gboolean nm_device_supports_wireless_scan (NMDevice *dev)
+static char *nm_get_device_driver_name (NMDevice *dev)
{
- NMSock *sk;
- int err;
- gboolean can_scan = TRUE;
- wireless_scan_head scan_data;
-
- g_return_val_if_fail (dev != NULL, FALSE);
- g_return_val_if_fail (dev->type == DEVICE_TYPE_WIRELESS_ETHERNET, FALSE);
+ char * udi = NULL;
+ char * driver_name = NULL;
+ LibHalContext *ctx = NULL;
- /* A test wireless device can always scan (we generate fake scan data for it) */
- if (dev->test_device)
- return (TRUE);
+ g_return_val_if_fail (dev != NULL, NULL);
+ g_return_val_if_fail (dev->app_data != NULL, NULL);
- if ((sk = nm_dev_sock_open (dev, DEV_WIRELESS, __FUNCTION__, NULL)))
+ ctx = dev->app_data->hal_ctx;
+ g_return_val_if_fail (ctx != NULL, NULL);
+
+ if ((udi = nm_device_get_udi (dev)))
{
- err = iw_scan (nm_dev_sock_get_fd (sk), (char *)nm_device_get_iface (dev), WIRELESS_EXT, &scan_data);
- nm_dispose_scan_results (scan_data.result);
- if ((err == -1) && (errno == EOPNOTSUPP))
- can_scan = FALSE;
- nm_dev_sock_close (sk);
+ char *parent_udi = libhal_device_get_property_string (ctx, udi, "info.parent", NULL);
+
+ if (parent_udi && libhal_device_property_exists (ctx, parent_udi, "info.linux.driver", NULL))
+ {
+ char *drv = libhal_device_get_property_string (ctx, parent_udi, "info.linux.driver", NULL);
+ driver_name = g_strdup (drv);
+ g_free (drv);
+ }
+ g_free (parent_udi);
}
- return (can_scan);
+
+ return driver_name;
+}
+
+/* Blacklist of unsupported drivers */
+static char * driver_blacklist[] =
+{
+ NULL
+};
+
+
+/*
+ * nm_is_driver_supported
+ *
+ * Check device's driver against a blacklist of unsupported drivers.
+ *
+ */
+static gboolean nm_is_driver_supported (NMDevice *dev)
+{
+ char ** drv = NULL;
+
+ g_return_val_if_fail (dev != NULL, FALSE);
+ g_return_val_if_fail (dev->driver != NULL, FALSE);
+
+ for (drv = &driver_blacklist[0]; *drv; drv++)
+ {
+ if (!strcmp (*drv, dev->driver))
+ return FALSE;
+ }
+ return TRUE;
}
@@ -259,6 +293,64 @@ void nm_device_copy_allowed_to_dev_list (NMDevice *dev, NMAccessPointList *allow
/*
+ * nm_device_wireless_init
+ *
+ * Initialize a new wireless device with wireless-specific settings.
+ *
+ */
+static gboolean nm_device_wireless_init (NMDevice *dev)
+{
+ NMSock *sk;
+ NMDeviceWirelessOptions *opts = &(dev->options.wireless);
+
+ g_return_val_if_fail (dev != NULL, FALSE);
+ g_return_val_if_fail (nm_device_is_wireless (dev), FALSE);
+
+ opts->scan_mutex = g_mutex_new ();
+ opts->ap_list = nm_ap_list_new (NETWORK_TYPE_DEVICE);
+ if (!opts->scan_mutex || !opts->ap_list)
+ return FALSE;
+
+ nm_register_mutex_desc (opts->scan_mutex, "Scan Mutex");
+ nm_wireless_set_scan_interval (dev->app_data, dev, NM_WIRELESS_SCAN_INTERVAL_ACTIVE);
+
+ nm_device_set_mode (dev, NETWORK_MODE_INFRA);
+
+ /* Non-scanning devices show the entire allowed AP list as their
+ * available networks.
+ */
+ if (!(dev->capabilities & NM_DEVICE_CAP_WIRELESS_SCAN))
+ nm_device_copy_allowed_to_dev_list (dev, dev->app_data->allowed_ap_list);
+
+ if ((sk = nm_dev_sock_open (dev, DEV_WIRELESS, __FUNCTION__, NULL)))
+ {
+ iwrange range;
+ if (iw_get_range_info (nm_dev_sock_get_fd (sk), nm_device_get_iface (dev), &range) >= 0)
+ {
+ int i;
+
+ opts->max_qual.qual = range.max_qual.qual;
+ opts->max_qual.level = range.max_qual.level;
+ opts->max_qual.noise = range.max_qual.noise;
+ opts->max_qual.updated = range.max_qual.updated;
+
+ opts->avg_qual.qual = range.avg_qual.qual;
+ opts->avg_qual.level = range.avg_qual.level;
+ opts->avg_qual.noise = range.avg_qual.noise;
+ opts->avg_qual.updated = range.avg_qual.updated;
+
+ opts->num_freqs = MIN (range.num_frequency, IW_MAX_FREQUENCIES);
+ for (i = 0; i < opts->num_freqs; i++)
+ opts->freqs[i] = iw_freq2float (&(range.freq[i]));
+ }
+ nm_dev_sock_close (sk);
+ }
+
+ return TRUE;
+}
+
+
+/*
* nm_device_new
*
* Creates and initializes the structure representation of an NM device. For test
@@ -296,7 +388,8 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
dev->app_data = app_data;
dev->iface = g_strdup (iface);
dev->test_device = test_dev;
- nm_device_set_udi (dev, udi);
+ dev->udi = g_strdup (udi);
+ dev->driver = nm_get_device_driver_name (dev);
dev->use_dhcp = TRUE;
/* Real hardware devices are probed for their type, test devices must have
@@ -318,66 +411,19 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
/* Have to bring the device up before checking link status and other stuff */
nm_device_bring_up_wait (dev, 0);
- /* Initialize wireless-specific options */
- if (nm_device_is_wireless (dev))
- {
- NMSock *sk;
- NMDeviceWirelessOptions *opts = &(dev->options.wireless);
-
- nm_device_set_mode (dev, NETWORK_MODE_INFRA);
-
- nm_wireless_set_scan_interval (dev->app_data, dev, NM_WIRELESS_SCAN_INTERVAL_ACTIVE);
-
- opts->scan_mutex = g_mutex_new ();
- opts->ap_list = nm_ap_list_new (NETWORK_TYPE_DEVICE);
- if (!opts->scan_mutex || !opts->ap_list)
- goto err;
-
- nm_register_mutex_desc (opts->scan_mutex, "Scan Mutex");
-
- opts->supports_wireless_scan = nm_device_supports_wireless_scan (dev);
-
- /* Non-scanning devices show the entire allowed AP list as their
- * available networks.
- */
- if (opts->supports_wireless_scan == FALSE)
- nm_device_copy_allowed_to_dev_list (dev, app_data->allowed_ap_list);
-
- if ((sk = nm_dev_sock_open (dev, DEV_WIRELESS, __FUNCTION__, NULL)))
- {
- iwrange range;
- if (iw_get_range_info (nm_dev_sock_get_fd (sk), nm_device_get_iface (dev), &range) >= 0)
- {
- int i;
-
- opts->max_qual.qual = range.max_qual.qual;
- opts->max_qual.level = range.max_qual.level;
- opts->max_qual.noise = range.max_qual.noise;
- opts->max_qual.updated = range.max_qual.updated;
-
- opts->avg_qual.qual = range.avg_qual.qual;
- opts->avg_qual.level = range.avg_qual.level;
- opts->avg_qual.noise = range.avg_qual.noise;
- opts->avg_qual.updated = range.avg_qual.updated;
+ /* First check for driver support */
+ if (nm_is_driver_supported (dev))
+ dev->capabilities |= NM_DEVICE_CAP_NM_SUPPORTED;
- opts->num_freqs = MIN (range.num_frequency, IW_MAX_FREQUENCIES);
- for (i = 0; i < opts->num_freqs; i++)
- opts->freqs[i] = iw_freq2float (&(range.freq[i]));
- }
- nm_dev_sock_close (sk);
- }
- }
- else if (nm_device_is_wired (dev))
+ /* Then discover devices-specific capabilities */
+ if (dev->capabilities & NM_DEVICE_CAP_NM_SUPPORTED)
{
- if (supports_ethtool_carrier_detect (dev) || supports_mii_carrier_detect (dev))
- dev->options.wired.has_carrier_detect = TRUE;
- }
+ dev->capabilities |= nm_device_discover_capabilities (dev);
- /* Must be called after carrier detect or wireless scan detect. */
- dev->driver_support_level = nm_get_driver_support_level (dev->app_data->hal_ctx, dev);
+ /* Initialize wireless-specific options */
+ if (nm_device_is_wireless (dev) && !nm_device_wireless_init (dev))
+ goto err;
- if (nm_device_get_driver_support_level (dev) != NM_DRIVER_UNSUPPORTED)
- {
nm_device_set_link_active (dev, nm_device_probe_link_state (dev));
nm_device_update_ip4_address (dev);
nm_device_update_hw_address (dev);
@@ -387,6 +433,8 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
dev->use_dhcp = nm_system_device_get_use_dhcp (dev);
}
+ nm_print_device_capabilities (dev);
+
dev->worker = g_thread_create (nm_device_worker, dev, TRUE, &error);
if (!dev->worker)
{
@@ -463,6 +511,7 @@ gboolean nm_device_unref (NMDevice *dev)
g_free (dev->udi);
g_free (dev->iface);
+ g_free (dev->driver);
memset (dev, 0, sizeof (NMDevice));
g_free (dev);
deleted = TRUE;
@@ -536,6 +585,105 @@ void nm_device_worker_thread_stop (NMDevice *dev)
/*
+ * nm_device_wireless_discover_capabilities
+ *
+ * Figure out wireless-specific capabilities
+ *
+ */
+static guint32 nm_device_wireless_discover_capabilities (NMDevice *dev)
+{
+ NMSock * sk;
+ int err;
+ wireless_scan_head scan_data;
+ guint32 caps = NM_DEVICE_CAP_NONE;
+
+ g_return_val_if_fail (dev != NULL, NM_DEVICE_CAP_NONE);
+ g_return_val_if_fail (nm_device_is_wireless (dev), NM_DEVICE_CAP_NONE);
+
+ /* A test wireless device can always scan (we generate fake scan data for it) */
+ if (dev->test_device)
+ caps |= NM_DEVICE_CAP_WIRELESS_SCAN;
+ else
+ {
+ if ((sk = nm_dev_sock_open (dev, DEV_WIRELESS, __FUNCTION__, NULL)))
+ {
+ err = iw_scan (nm_dev_sock_get_fd (sk), (char *)nm_device_get_iface (dev), WIRELESS_EXT, &scan_data);
+ nm_dispose_scan_results (scan_data.result);
+ if (!((err == -1) && (errno == EOPNOTSUPP)))
+ caps |= NM_DEVICE_CAP_WIRELESS_SCAN;
+ nm_dev_sock_close (sk);
+ }
+ }
+
+ return caps;
+}
+
+
+/*
+ * nm_device_wireless_discover_capabilities
+ *
+ * Figure out wireless-specific capabilities
+ *
+ */
+static guint32 nm_device_wired_discover_capabilities (NMDevice *dev)
+{
+ guint32 caps = NM_DEVICE_CAP_NONE;
+ const char * udi = NULL;
+ char * usb_test = NULL;
+ LibHalContext *ctx = NULL;
+
+ g_return_val_if_fail (dev != NULL, NM_DEVICE_CAP_NONE);
+ g_return_val_if_fail (nm_device_is_wired (dev), NM_DEVICE_CAP_NONE);
+ g_return_val_if_fail (dev->app_data != NULL, NM_DEVICE_CAP_NONE);
+
+ /* cipsec devices are also explicitly unsupported at this time */
+ if (strstr (nm_device_get_iface (dev), "cipsec"))
+ return NM_DEVICE_CAP_NONE;
+
+ /* Ignore Ethernet-over-USB devices too for the moment (Red Hat #135722) */
+ ctx = dev->app_data->hal_ctx;
+ udi = nm_device_get_udi (dev);
+ if ( libhal_device_property_exists (ctx, udi, "usb.interface.class", NULL)
+ && (usb_test = libhal_device_get_property_string (ctx, udi, "usb.interface.class", NULL)))
+ {
+ libhal_free_string (usb_test);
+ return NM_DEVICE_CAP_NONE;
+ }
+
+ if (supports_ethtool_carrier_detect (dev) || supports_mii_carrier_detect (dev))
+ caps |= NM_DEVICE_CAP_CARRIER_DETECT;
+
+ return caps;
+}
+
+
+/*
+ * nm_device_discover_capabilities
+ *
+ * Called only at device initialization time to discover device-specific
+ * capabilities.
+ *
+ */
+static guint32 nm_device_discover_capabilities (NMDevice *dev)
+{
+ guint32 caps = NM_DEVICE_CAP_NONE;
+
+ g_return_val_if_fail (dev != NULL, NM_DEVICE_CAP_NONE);
+
+ /* Don't touch devices that we already don't support */
+ if (!(dev->capabilities & NM_DEVICE_CAP_NM_SUPPORTED))
+ return NM_DEVICE_CAP_NONE;
+
+ if (nm_device_is_wired (dev))
+ caps |= nm_device_wired_discover_capabilities (dev);
+ else if (nm_device_is_wireless (dev))
+ caps |= nm_device_wireless_discover_capabilities (dev);
+
+ return caps;
+}
+
+
+/*
* nm_device_get_app_data
*
*/
@@ -621,6 +769,17 @@ const char * nm_device_get_iface (NMDevice *dev)
/*
+ * Get/set functions for driver
+ */
+const char * nm_device_get_driver (NMDevice *dev)
+{
+ g_return_val_if_fail (dev != NULL, NULL);
+
+ return (dev->driver);
+}
+
+
+/*
* Get/set functions for type
*/
guint nm_device_get_type (NMDevice *dev)
@@ -646,13 +805,13 @@ gboolean nm_device_is_wired (NMDevice *dev)
/*
- * Accessor for driver support level
+ * Accessor for device capabilities
*/
-NMDriverSupportLevel nm_device_get_driver_support_level (NMDevice *dev)
+guint32 nm_device_get_capabilities (NMDevice *dev)
{
- g_return_val_if_fail (dev != NULL, NM_DRIVER_UNSUPPORTED);
+ g_return_val_if_fail (dev != NULL, NM_DEVICE_CAP_NONE);
- return (dev->driver_support_level);
+ return dev->capabilities;
}
@@ -695,7 +854,7 @@ void nm_device_set_link_active (NMDevice *dev, const gboolean link_active)
* must manually choose semi-supported devices.
*
*/
- if (nm_device_is_wired (dev) && (nm_device_get_driver_support_level (dev) == NM_DRIVER_FULLY_SUPPORTED))
+ if (nm_device_is_wired (dev) && (nm_device_get_capabilities (dev) & NM_DEVICE_CAP_CARRIER_DETECT))
{
gboolean do_switch = act_dev ? FALSE : TRUE; /* If no currently active device, switch to this one */
NMActRequest * act_req;
@@ -726,7 +885,7 @@ gboolean nm_device_get_supports_wireless_scan (NMDevice *dev)
if (!nm_device_is_wireless (dev))
return (FALSE);
- return (dev->options.wireless.supports_wireless_scan);
+ return (dev->capabilities & NM_DEVICE_CAP_WIRELESS_SCAN);
}
@@ -740,7 +899,7 @@ gboolean nm_device_get_supports_carrier_detect (NMDevice *dev)
if (!nm_device_is_wired (dev))
return (FALSE);
- return (dev->options.wired.has_carrier_detect);
+ return (dev->capabilities & NM_DEVICE_CAP_CARRIER_DETECT);
}
/*
@@ -866,7 +1025,7 @@ static gboolean nm_device_probe_wired_link_state (NMDevice *dev)
* they never get auto-selected by NM. User has to force them on us,
* so we just hope the user knows whether or not the cable's plugged in.
*/
- if (dev->options.wired.has_carrier_detect != TRUE)
+ if (!(dev->capabilities & NM_DEVICE_CAP_CARRIER_DETECT))
link = TRUE;
return link;
@@ -1850,9 +2009,6 @@ gboolean nm_device_activation_start (NMActRequest *req)
g_return_val_if_fail (!nm_device_is_activating (dev), TRUE); /* Return if activation has already begun */
- if (nm_device_get_driver_support_level (dev) == NM_DRIVER_UNSUPPORTED)
- return FALSE;
-
nm_act_request_ref (req);
dev->act_request = req;
dev->quit_activation = FALSE;
@@ -3212,7 +3368,7 @@ gboolean nm_device_deactivate (NMDevice *dev)
nm_device_deactivate_quickly (dev);
- if (nm_device_get_driver_support_level (dev) == NM_DRIVER_UNSUPPORTED)
+ if (!(nm_device_get_capabilities (dev) & NM_DEVICE_CAP_NM_SUPPORTED))
return TRUE;
/* Remove any device nameservers and domains */
@@ -3971,9 +4127,10 @@ static gboolean nm_completion_scan_has_results (int tries, nm_completion_args ar
*/
static gboolean nm_device_wireless_scan (gpointer user_data)
{
- NMWirelessScanCB *scan_cb = (NMWirelessScanCB *)(user_data);
- NMDevice *dev = NULL;
- NMWirelessScanResults *scan_results = NULL;
+ NMWirelessScanCB * scan_cb = (NMWirelessScanCB *)(user_data);
+ NMDevice * dev = NULL;
+ NMWirelessScanResults * scan_results = NULL;
+ guint32 caps;
g_return_val_if_fail (scan_cb != NULL, FALSE);
@@ -3984,6 +4141,13 @@ static gboolean nm_device_wireless_scan (gpointer user_data)
return FALSE;
}
+ caps = nm_device_get_capabilities (dev);
+ if (!(caps & NM_DEVICE_CAP_NM_SUPPORTED) || !(caps & NM_DEVICE_CAP_WIRELESS_SCAN))
+ {
+ g_free (scan_cb);
+ return FALSE;
+ }
+
/* Reschedule ourselves if all wireless is disabled, we're asleep,
* or we are currently activating.
*/
diff --git a/src/NetworkManagerDevice.h b/src/NetworkManagerDevice.h
index adad15cd3f..fb436964e6 100644
--- a/src/NetworkManagerDevice.h
+++ b/src/NetworkManagerDevice.h
@@ -55,8 +55,10 @@ void nm_device_set_udi (NMDevice *dev, const char *udi);
const char * nm_device_get_iface (NMDevice *dev);
+const char * nm_device_get_driver (NMDevice *dev);
+
NMDeviceType nm_device_get_type (NMDevice *dev);
-NMDriverSupportLevel nm_device_get_driver_support_level (NMDevice *dev);
+guint32 nm_device_get_capabilities (NMDevice *dev);
gboolean nm_device_is_wireless (NMDevice *dev);
gboolean nm_device_is_wired (NMDevice *dev);
diff --git a/src/NetworkManagerDevicePrivate.h b/src/NetworkManagerDevicePrivate.h
index fa7091e9a6..c96b48a56b 100644
--- a/src/NetworkManagerDevicePrivate.h
+++ b/src/NetworkManagerDevicePrivate.h
@@ -37,7 +37,6 @@
typedef struct NMDeviceWirelessOptions
{
char * cur_essid; /* Mainly for test devices */
- gboolean supports_wireless_scan;
gint8 strength;
gint8 invalid_strength_counter;
iwqual max_qual;
@@ -57,7 +56,7 @@ typedef struct NMDeviceWirelessOptions
/* Wired device specific options */
typedef struct NMDeviceWiredOptions
{
- gboolean has_carrier_detect;
+ guint32 unused;
} NMDeviceWiredOptions;
/* General options structure */
@@ -73,35 +72,36 @@ typedef union NMDeviceOptions
*/
struct NMDevice
{
- guint refcount;
+ guint refcount;
- char * udi;
- char * iface;
- NMDeviceType type;
- NMDriverSupportLevel driver_support_level;
- gboolean removed;
+ char * udi;
+ char * iface;
+ NMDeviceType type;
+ guint32 capabilities;
+ char * driver;
+ gboolean removed;
- gboolean link_active;
- guint32 ip4_address;
+ gboolean link_active;
+ guint32 ip4_address;
/* FIXME: ipv6 address too */
- struct ether_addr hw_addr;
- NMData * app_data;
- NMDeviceOptions options;
+ struct ether_addr hw_addr;
+ NMData * app_data;
+ NMDeviceOptions options;
/* IP configuration info */
- void * system_config_data; /* Distro-specific config data (parsed config file, etc) */
- gboolean use_dhcp;
- NMIP4Config * ip4_config; /* Config from DHCP, PPP, or system config files */
+ void * system_config_data; /* Distro-specific config data (parsed config file, etc) */
+ gboolean use_dhcp;
+ NMIP4Config * ip4_config; /* Config from DHCP, PPP, or system config files */
- GMainContext * context;
- GMainLoop * loop;
- GThread * worker;
- gboolean worker_started;
+ GMainContext * context;
+ GMainLoop * loop;
+ GThread * worker;
+ gboolean worker_started;
- NMActRequest * act_request;
- gboolean quit_activation; /* Flag to signal activation thread to stop activating */
+ NMActRequest * act_request;
+ gboolean quit_activation; /* Flag to signal activation thread to stop activating */
- gboolean test_device;
- gboolean test_device_up;
+ gboolean test_device;
+ gboolean test_device_up;
};
diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c
index 0a8153d679..bd6df8f4d5 100644
--- a/src/NetworkManagerPolicy.c
+++ b/src/NetworkManagerPolicy.c
@@ -222,22 +222,24 @@ static NMDevice * nm_policy_auto_get_best_device (NMData *data, NMAccessPoint **
for (elt = data->dev_list; elt != NULL; elt = g_slist_next (elt))
{
- guint dev_type;
- gboolean link_active;
- guint prio = 0;
- NMDevice *dev = (NMDevice *)(elt->data);
-
- /* Skip devices that can't do carrier detect or can't do wireless scanning */
- if (nm_device_get_driver_support_level (dev) != NM_DRIVER_FULLY_SUPPORTED)
- continue;
+ guint dev_type;
+ gboolean link_active;
+ guint prio = 0;
+ NMDevice * dev = (NMDevice *)(elt->data);
+ guint32 caps;
dev_type = nm_device_get_type (dev);
link_active = nm_device_has_active_link (dev);
+ caps = nm_device_get_capabilities (dev);
+
+ /* Don't use devices that SUCK */
+ if (!(caps & NM_DEVICE_CAP_NM_SUPPORTED))
+ continue;
if (nm_device_is_wired (dev))
{
/* We never automatically choose devices that don't support carrier detect */
- if (!nm_device_get_supports_carrier_detect (dev))
+ if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT))
continue;
if (link_active)
@@ -254,21 +256,16 @@ static NMDevice * nm_policy_auto_get_best_device (NMData *data, NMAccessPoint **
}
else if (nm_device_is_wireless (dev) && data->wireless_enabled)
{
- if (link_active)
- prio += 1;
+ /* Don't automatically choose a device that doesn't support wireless scanning */
+ if (!(caps & NM_DEVICE_CAP_WIRELESS_SCAN))
+ continue;
- if (nm_device_get_supports_wireless_scan (dev))
- prio += 2;
- else
+ if (link_active)
prio += 1;
if (nm_device_get_act_request (dev) && link_active)
prio += 3;
- /* Stick with an already active non-scanning device if the user chose one */
- if (!nm_device_get_supports_wireless_scan (dev) && nm_device_get_act_request (dev))
- prio += 2;
-
if (prio > best_wireless_prio)
{
best_wireless_dev = dev;
@@ -326,6 +323,8 @@ static gboolean nm_policy_device_change_check (NMData *data)
if (old_dev)
{
+ guint32 caps = nm_device_get_capabilities (old_dev);
+
/* Don't interrupt a currently activating device. */
if (nm_device_is_activating (old_dev))
{
@@ -336,7 +335,8 @@ static gboolean nm_policy_device_change_check (NMData *data)
/* Don't interrupt semi-supported devices either. If the user chose one, they must
* explicitly choose to move to another device, we're not going to move for them.
*/
- if (nm_device_get_driver_support_level (old_dev) != NM_DRIVER_FULLY_SUPPORTED)
+ if ((nm_device_is_wireless (old_dev) && !(caps & NM_DEVICE_CAP_CARRIER_DETECT))
+ || (nm_device_is_wireless (old_dev) && !(caps & NM_DEVICE_CAP_WIRELESS_SCAN)))
{
nm_info ("Old device '%s' was semi-supported and user chosen, won't change unless told to.",
nm_device_get_iface (old_dev));
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c
index 8201b5a7de..b46ba2d79a 100644
--- a/src/NetworkManagerUtils.c
+++ b/src/NetworkManagerUtils.c
@@ -407,191 +407,56 @@ int nm_spawn_process (const char *args)
}
-typedef struct driver_support
-{
- char *name;
- NMDriverSupportLevel level;
-} driver_support;
-
-
-/* Blacklist of unsupported wireless drivers */
-static driver_support wireless_driver_blacklist[] =
-{
- {NULL, NM_DRIVER_UNSUPPORTED}
-};
-
-
-/* Blacklist of unsupported wired drivers. Drivers/cards that don't support
- * link detection should be blacklisted.
- */
-static driver_support wired_driver_blacklist[] =
-{
-/* Completely unsupported drivers */
- {NULL, NM_DRIVER_UNSUPPORTED}
-};
-
-
/*
- * nm_get_device_driver_name
+ * nm_print_device_capabilities
*
- * Get the device's driver name from HAL.
+ * Return the capabilities for a particular device.
*
*/
-static char *nm_get_device_driver_name (LibHalContext *ctx, NMDevice *dev)
+void nm_print_device_capabilities (NMDevice *dev)
{
- char *udi = NULL;
- char *driver_name = NULL;
+ gboolean full_support = TRUE;
+ guint32 caps;
+ const char * driver = NULL;
- g_return_val_if_fail (ctx != NULL, NULL);
- g_return_val_if_fail (dev != NULL, NULL);
+ g_return_if_fail (dev != NULL);
- if ((udi = nm_device_get_udi (dev)))
- {
- char *parent_udi = libhal_device_get_property_string (ctx, udi, "info.parent", NULL);
+ caps = nm_device_get_capabilities (dev);
+ driver = nm_device_get_driver (dev);
- if (parent_udi && libhal_device_property_exists (ctx, parent_udi, "info.linux.driver", NULL))
- driver_name = libhal_device_get_property_string (ctx, parent_udi, "info.linux.driver", NULL);
- g_free(parent_udi);
+ if (caps == NM_DEVICE_CAP_NONE || !(NM_DEVICE_CAP_NM_SUPPORTED))
+ {
+ nm_info ("%s: Driver support level for '%s' is unsupported",
+ nm_device_get_iface (dev), driver);
+ return;
}
- return (driver_name);
-}
-
-/*
- * nm_get_wireless_driver_support_level
- *
- * Blacklist certain wireless devices.
- *
- */
-static NMDriverSupportLevel nm_get_wireless_driver_support_level (LibHalContext *ctx, NMDevice *dev, char **driver)
-{
- NMDriverSupportLevel level = NM_DRIVER_FULLY_SUPPORTED;
- char *driver_name = NULL;
-
- g_return_val_if_fail (ctx != NULL, NM_DRIVER_UNSUPPORTED);
- g_return_val_if_fail (dev != NULL, NM_DRIVER_UNSUPPORTED);
- g_return_val_if_fail (driver != NULL, NM_DRIVER_UNSUPPORTED);
- g_return_val_if_fail (*driver == NULL, NM_DRIVER_UNSUPPORTED);
-
- if ((driver_name = nm_get_device_driver_name (ctx, dev)))
+ if (nm_device_is_wired (dev))
{
- driver_support *drv;
- for (drv = &wireless_driver_blacklist[0]; drv->name; drv++)
+ if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT))
{
- if (!strcmp (drv->name, driver_name))
- {
- level = drv->level;
- break;
- }
+ nm_info ("%s: Driver '%s' does not support carrier detection.\n"
+ "\tYou must switch to it manually.",
+ nm_device_get_iface (dev), driver);
+ full_support = FALSE;
}
- *driver = g_strdup (driver_name);
- g_free (driver_name);
}
-
- /* Check for carrier detection support */
- if ((level != NM_DRIVER_UNSUPPORTED) && !nm_device_get_supports_wireless_scan (dev))
- level = NM_DRIVER_NO_WIRELESS_SCAN;
-
- return (level);
-}
-
-
-/*
- * nm_get_wired_driver_support_level
- *
- * Blacklist certain devices.
- *
- */
-static NMDriverSupportLevel nm_get_wired_driver_support_level (LibHalContext *ctx, NMDevice *dev, char **driver)
-{
- NMDriverSupportLevel level = NM_DRIVER_FULLY_SUPPORTED;
- char *driver_name = NULL;
- char *usb_test;
- char *udi;
-
- g_return_val_if_fail (ctx != NULL, NM_DRIVER_UNSUPPORTED);
- g_return_val_if_fail (dev != NULL, NM_DRIVER_UNSUPPORTED);
- g_return_val_if_fail (driver != NULL, NM_DRIVER_UNSUPPORTED);
- g_return_val_if_fail (*driver == NULL, NM_DRIVER_UNSUPPORTED);
-
- if ((driver_name = nm_get_device_driver_name (ctx, dev)))
+ else if (nm_device_is_wireless (dev))
{
- driver_support *drv;
- for (drv = &wired_driver_blacklist[0]; drv->name; drv++)
+ if (!(caps & NM_DEVICE_CAP_WIRELESS_SCAN))
{
- if (!strcmp (drv->name, driver_name))
- {
- level = drv->level;
- break;
- }
+ nm_info ("%s: Driver '%s' does not support wireless scanning.\n"
+ "\tSome features will not be available.",
+ nm_device_get_iface (dev), driver);
+ full_support = FALSE;
}
- *driver = g_strdup (driver_name);
- g_free (driver_name);
}
- /* cipsec devices are also explicitly unsupported at this time */
- if (strstr (nm_device_get_iface (dev), "cipsec"))
- level = NM_DRIVER_UNSUPPORTED;
-
- /* Ignore Ethernet-over-USB devices too for the moment (Red Hat #135722) */
- udi = nm_device_get_udi (dev);
- if ( libhal_device_property_exists (ctx, udi, "usb.interface.class", NULL)
- && (usb_test = libhal_device_get_property_string (ctx, udi, "usb.interface.class", NULL)))
+ if (full_support)
{
- libhal_free_string (usb_test);
- level = NM_DRIVER_UNSUPPORTED;
+ nm_info ("%s: Device is fully-supported using driver '%s'.",
+ nm_device_get_iface (dev), driver);
}
-
- /* Check for carrier detection support */
- if ((level != NM_DRIVER_UNSUPPORTED) && !nm_device_get_supports_carrier_detect(dev))
- level = NM_DRIVER_NO_CARRIER_DETECT;
-
- return (level);
-}
-
-
-/*
- * nm_get_driver_support_level
- *
- * Return the driver support level for a particular device.
- *
- */
-NMDriverSupportLevel nm_get_driver_support_level (LibHalContext *ctx, NMDevice *dev)
-{
- char *driver = NULL;
- NMDriverSupportLevel level = NM_DRIVER_UNSUPPORTED;
-
- g_return_val_if_fail (ctx != NULL, NM_DRIVER_UNSUPPORTED);
- g_return_val_if_fail (dev != NULL, NM_DRIVER_UNSUPPORTED);
-
- if (nm_device_is_wireless (dev))
- level = nm_get_wireless_driver_support_level (ctx, dev, &driver);
- else if (nm_device_is_wired (dev))
- level = nm_get_wired_driver_support_level (ctx, dev, &driver);
-
- switch (level)
- {
- case NM_DRIVER_NO_CARRIER_DETECT:
- nm_info ("%s: Driver '%s' does not support carrier detection.\n"
- "\tYou must switch to it manually.", nm_device_get_iface (dev), driver);
- break;
- case NM_DRIVER_NO_WIRELESS_SCAN:
- nm_info ("%s: Driver '%s' does not support wireless scanning.\n"
- "\tNetworkManager will not be able to fully use the card.",
- nm_device_get_iface (dev), driver);
- break;
- case NM_DRIVER_FULLY_SUPPORTED:
- nm_info ("%s: Driver support level for '%s' is fully-supported",
- nm_device_get_iface (dev), driver);
- break;
- default:
- nm_info ("%s: Driver support level for '%s' is unsupported",
- nm_device_get_iface (dev), driver);
- break;
- }
-
- g_free (driver);
- return (level);
}
static inline int nm_timeval_cmp(const struct timeval *a,
diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h
index 66a54f7497..ebf533fe40 100644
--- a/src/NetworkManagerUtils.h
+++ b/src/NetworkManagerUtils.h
@@ -44,25 +44,25 @@ typedef enum SockType
typedef struct NMSock NMSock;
-gboolean nm_try_acquire_mutex (GMutex *mutex, const char *func);
-void nm_lock_mutex (GMutex *mutex, const char *func);
-void nm_unlock_mutex (GMutex *mutex, const char *func);
-void nm_register_mutex_desc (GMutex *mutex, const char *string);
+gboolean nm_try_acquire_mutex (GMutex *mutex, const char *func);
+void nm_lock_mutex (GMutex *mutex, const char *func);
+void nm_unlock_mutex (GMutex *mutex, const char *func);
+void nm_register_mutex_desc (GMutex *mutex, const char *string);
-NMSock * nm_dev_sock_open (NMDevice *dev, SockType type, const char *func_name, const char *desc);
-void nm_dev_sock_close (NMSock *sock);
-int nm_dev_sock_get_fd (NMSock *sock);
-void nm_print_open_socks (void);
+NMSock * nm_dev_sock_open (NMDevice *dev, SockType type, const char *func_name, const char *desc);
+void nm_dev_sock_close (NMSock *sock);
+int nm_dev_sock_get_fd (NMSock *sock);
+void nm_print_open_socks (void);
-int nm_null_safe_strcmp (const char *s1, const char *s2);
+int nm_null_safe_strcmp (const char *s1, const char *s2);
-gboolean nm_ethernet_address_is_valid (const struct ether_addr *test_addr);
+gboolean nm_ethernet_address_is_valid (const struct ether_addr *test_addr);
-void nm_dispose_scan_results (wireless_scan *result_list);
+void nm_dispose_scan_results (wireless_scan *result_list);
-int nm_spawn_process (const char *args);
+int nm_spawn_process (const char *args);
-NMDriverSupportLevel nm_get_driver_support_level (LibHalContext *ctx, NMDevice *dev);
+void nm_print_device_capabilities (NMDevice *dev);
#define NM_COMPLETION_TRIES_INFINITY -1
diff --git a/src/nm-dbus-device.c b/src/nm-dbus-device.c
index 2db3c9c276..9a15741522 100644
--- a/src/nm-dbus-device.c
+++ b/src/nm-dbus-device.c
@@ -265,7 +265,7 @@ static DBusMessage *nm_dbus_device_get_networks (DBusConnection *connection, DBu
return reply;
}
-static DBusMessage *nm_dbus_device_get_driver_support_level (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
+static DBusMessage *nm_dbus_device_get_capabilities (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
DBusMessage *reply = NULL;
NMDevice *dev;
@@ -275,8 +275,8 @@ static DBusMessage *nm_dbus_device_get_driver_support_level (DBusConnection *con
dev = data->dev;
if ((reply = dbus_message_new_method_return (message)))
{
- dbus_uint32_t driver_support_level = nm_device_get_driver_support_level (dev);
- dbus_message_append_args (reply, DBUS_TYPE_UINT32, &driver_support_level, DBUS_TYPE_INVALID);
+ dbus_uint32_t capabilities = nm_device_get_capabilities (dev);
+ dbus_message_append_args (reply, DBUS_TYPE_UINT32, &capabilities, DBUS_TYPE_INVALID);
}
return reply;
@@ -339,7 +339,7 @@ static DBusMessage *nm_dbus_device_get_properties (DBusConnection *connection, D
dbus_int32_t strength = -1;
char * active_network_path = NULL;
dbus_bool_t link_active = (dbus_bool_t) nm_device_has_active_link (dev);
- dbus_uint32_t driver_support_level = (dbus_uint32_t) nm_device_get_driver_support_level (dev);
+ dbus_uint32_t capabilities = (dbus_uint32_t) nm_device_get_capabilities (dev);
char ** networks = NULL;
int num_networks = 0;
dbus_bool_t active = nm_device_get_act_request (dev) ? TRUE : FALSE;
@@ -435,7 +435,7 @@ static DBusMessage *nm_dbus_device_get_properties (DBusConnection *connection, D
DBUS_TYPE_UINT32, &mode,
DBUS_TYPE_INT32, &strength,
DBUS_TYPE_BOOLEAN,&link_active,
- DBUS_TYPE_UINT32, &driver_support_level,
+ DBUS_TYPE_UINT32, &capabilities,
DBUS_TYPE_STRING, &active_network_path,
DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &networks, num_networks,
DBUS_TYPE_INVALID);
@@ -462,19 +462,18 @@ NMDbusMethodList *nm_dbus_device_methods_setup (void)
{
NMDbusMethodList *list = nm_dbus_method_list_new (NULL);
- nm_dbus_method_list_add_method (list, "getProperties", nm_dbus_device_get_properties);
-
- nm_dbus_method_list_add_method (list, "getName", nm_dbus_device_get_name);
- nm_dbus_method_list_add_method (list, "getType", nm_dbus_device_get_type);
- nm_dbus_method_list_add_method (list, "getHalUdi", nm_dbus_device_get_hal_udi);
- nm_dbus_method_list_add_method (list, "getIP4Address", nm_dbus_device_get_ip4_address);
- nm_dbus_method_list_add_method (list, "getHWAddress", nm_dbus_device_get_hw_address);
- nm_dbus_method_list_add_method (list, "getMode", nm_dbus_device_get_mode);
- nm_dbus_method_list_add_method (list, "getActiveNetwork", nm_dbus_device_get_active_network);
- nm_dbus_method_list_add_method (list, "getNetworks", nm_dbus_device_get_networks);
- nm_dbus_method_list_add_method (list, "getLinkActive", nm_dbus_device_get_link_active);
- nm_dbus_method_list_add_method (list, "setLinkActive", nm_dbus_device_set_link_active);
- nm_dbus_method_list_add_method (list, "getDriverSupportLevel", nm_dbus_device_get_driver_support_level);
+ nm_dbus_method_list_add_method (list, "getProperties", nm_dbus_device_get_properties);
+ nm_dbus_method_list_add_method (list, "getName", nm_dbus_device_get_name);
+ nm_dbus_method_list_add_method (list, "getType", nm_dbus_device_get_type);
+ nm_dbus_method_list_add_method (list, "getHalUdi", nm_dbus_device_get_hal_udi);
+ nm_dbus_method_list_add_method (list, "getIP4Address", nm_dbus_device_get_ip4_address);
+ nm_dbus_method_list_add_method (list, "getHWAddress", nm_dbus_device_get_hw_address);
+ nm_dbus_method_list_add_method (list, "getMode", nm_dbus_device_get_mode);
+ nm_dbus_method_list_add_method (list, "getActiveNetwork", nm_dbus_device_get_active_network);
+ nm_dbus_method_list_add_method (list, "getNetworks", nm_dbus_device_get_networks);
+ nm_dbus_method_list_add_method (list, "getLinkActive", nm_dbus_device_get_link_active);
+ nm_dbus_method_list_add_method (list, "setLinkActive", nm_dbus_device_set_link_active);
+ nm_dbus_method_list_add_method (list, "getCapabilities", nm_dbus_device_get_capabilities);
return (list);
}
diff --git a/src/nm-dbus-nm.c b/src/nm-dbus-nm.c
index 7b11543f97..fa6a28993f 100644
--- a/src/nm-dbus-nm.c
+++ b/src/nm-dbus-nm.c
@@ -63,37 +63,23 @@ static DBusMessage *nm_dbus_nm_get_devices (DBusConnection *connection, DBusMess
return NULL;
dbus_message_iter_init_append (reply, &iter);
- /* Iterate over device list and grab index of "active device" */
if (nm_try_acquire_mutex (data->data->dev_list_mutex, __FUNCTION__))
{
GSList *elt;
- gboolean appended = FALSE;
dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter_array);
-
for (elt = data->data->dev_list; elt; elt = g_slist_next (elt))
{
NMDevice *dev = (NMDevice *)(elt->data);
- if (dev && (nm_device_get_driver_support_level (dev) != NM_DRIVER_UNSUPPORTED))
+ if (dev)
{
char *op = nm_dbus_get_object_path_for_device (dev);
dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_OBJECT_PATH, &op);
g_free (op);
- appended = TRUE;
}
}
-
- /* If by some chance there is a device list, but it has no devices in it
- * (something which should never happen), die.
- */
- if (!appended)
- {
- nm_warning ("Device list existed, but no devices were in it.");
- g_assert_not_reached ();
- }
-
dbus_message_iter_close_container (&iter, &iter_array);
nm_unlock_mutex (data->data->dev_list_mutex, __FUNCTION__);
}
@@ -229,7 +215,7 @@ static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DB
dev_path = nm_dbus_unescape_object_path (dev_path);
dev = nm_dbus_get_device_from_object_path (data->data, dev_path);
g_free (dev_path);
- if (!dev || (nm_device_get_driver_support_level (dev) == NM_DRIVER_UNSUPPORTED))
+ if (!dev || !(nm_device_get_capabilities (dev) & NM_DEVICE_CAP_NM_SUPPORTED))
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound",
"The requested network device does not exist.");
@@ -293,7 +279,7 @@ static DBusMessage *nm_dbus_nm_create_wireless_network (DBusConnection *connecti
dev_path = nm_dbus_unescape_object_path (dev_path);
dev = nm_dbus_get_device_from_object_path (data->data, dev_path);
g_free (dev_path);
- if (!dev || (nm_device_get_driver_support_level (dev) == NM_DRIVER_UNSUPPORTED))
+ if (!dev || !(nm_device_get_capabilities (dev) & NM_DEVICE_CAP_NM_SUPPORTED))
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound",
"The requested network device does not exist.");