diff options
author | Dan Williams <dcbw@redhat.com> | 2005-10-09 04:39:49 +0000 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2005-10-09 04:39:49 +0000 |
commit | 69d77f6b56ebddfcfbc1cf0e618d66035d8cf609 (patch) | |
tree | 9c9dcf45eaa458d26e085222ffc409a1568eecff /src | |
parent | fad78837c6a3c0fdd243abc655f214752d73ed22 (diff) | |
download | NetworkManager-69d77f6b56ebddfcfbc1cf0e618d66035d8cf609.tar.gz |
2005-10-09 Dan Williams <dcbw@redhat.com>
* Replace the "driver support level" stuff with capabilities. The
capability field is a bitfield that is more flexible than the
old driver support level thing. It's mostly so we can easily
figure out what supports WPA and what doesn't, but should be
quite useful later.
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1007 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
Diffstat (limited to 'src')
-rw-r--r-- | src/NetworkManagerDevice.c | 348 | ||||
-rw-r--r-- | src/NetworkManagerDevice.h | 4 | ||||
-rw-r--r-- | src/NetworkManagerDevicePrivate.h | 48 | ||||
-rw-r--r-- | src/NetworkManagerPolicy.c | 38 | ||||
-rw-r--r-- | src/NetworkManagerUtils.c | 193 | ||||
-rw-r--r-- | src/NetworkManagerUtils.h | 26 | ||||
-rw-r--r-- | src/nm-dbus-device.c | 35 | ||||
-rw-r--r-- | src/nm-dbus-nm.c | 20 |
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."); |