diff options
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."); |