diff -urN NetworkManager/ChangeLog NetworkManager-SVN/ChangeLog --- NetworkManager/ChangeLog 2007-09-08 00:09:05.000000000 +0200 +++ NetworkManager-SVN/ChangeLog 2007-09-08 00:07:08.000000000 +0200 @@ -1,3 +1,104 @@ +2007-08-30 Dan Williams + + * libnm-util/sha1.c + - Include config.h to get defines for endiannes (gnome.org #420216) + +2007-07-26 Dan Williams + + Patch from Bernhard Miklautz + + * src/NetworkManagerSystem.c + - (nm_system_device_set_ip4_route): don't add the route if it's on the + same subnet (#437396) + +2007-07-26 Dan Williams + + * src/nm-device-802-11-wireless.c + - (real_start): I hate orinoco; apparently has trouble scanning too soon + after being brought up, so do the initial scan a bit later. + +2007-06-27 Dan Williams + + * src/NetworkManager.c + - (nm_hal_init): set hardware RF to enabled if no killswitches are found + after the initial discovery + +2007-06-21 Dan Williams + + More fixes for Fedora #194124, gnome.org #354565 + + * src/nm-device-802-3-ethernet.c + - (real_act_stage1_prepare): new function; fail activation if device + doesn't have a link + + * src/NetworkManagerPolicy.c + - (nm_policy_activation_finish): ensure device is actually activated + before sending out signals. Fixes a race where device cancellation + would be processed right after finish was scheduled, but not run. + - (nm_policy_device_change_check, nm_policy_schedule_device_change_check): + ensure device change check GSource ID is locked across threads; + allow interruption of activation of 802.3 ethernet devices that no + longer have an active link, and ensure that 802.3 ethernet devices + have an active link before starting activation + +2007-06-21 Dan Williams + + Add HAL-based rfkill support, based on a patch from Benjamin Kahn. + + * src/NetworkManagerDbus.[ch] + - (nm_dbus_signal_wireless_enabled): new function, emit signals when + wireless enabled status changes + + * src/nm-dbus-nm.c + - (nm_dbus_nm_set_wireless_enabled): handle hardware rfkill correctly; + send errors when hardware switch overrides user request, and send + signals when wireless enabled state changes + - (nm_dbus_nm_get_wireless_enabled): send additional 'hardware rf enabled' + argument in method reply + + * src/NetworkManager.c + - (handle_killswitch_pcall_done, nm_killswitch_getpower_reply_cb, + nm_poll_killswitches, nm_add_killswitch_device, + nm_add_initial_killswitch_devices): new functions; detect and handle + hardware killswitches exported by HAL. Unfortunately we have to + poll the switches because HAL doesn't support signals for killswitches + yet. + - (nm_hal_device_new_capability): detect killswitches added asynchronously + - (nm_hal_init): look for killswitches when connecting to HAL + - (nm_hal_deinit): dispose of killswitches when deiniting HAL data + + * src/NetworkManagerMain.h + - Add bits to track killswitches + +2007-06-12 Dan Williams + + * src/nm-device.c + - (real_act_stage3_ip_config_start): sometimes the device gets downed + during the wpa_supplicant association. Ensure the device is up + before it's used for IP configuration. + +2007-06-07 Dan Williams + + Patch from Jon Nettleton + + * src/nm-device-802-11-wireless.c: + - (real_act_stage2_config): sleep 1 second to allow link status + to stabilize + +2007-06-07 Dan Williams + + * (nm_device_802_3_ethernet_link_activated, + nm_device_802_3_ethernet_link_deactivated): fix ethernet link detection + behavior due to races between the netlink code and when the + device thread recognizes the change. Checking the link state + before scheduling the change even on the device thread is wrong. + (gnome.org #354565, rh #194124) + +2007-04-25 Dan Williams + + * initscript/RedHat/NetworkManager.in: remove trailing backslash + (gnome.org #432401) + 2007-04-18 Tambet Ingo * src/nm-dbus-nmi.c (nm_dbus_get_user_key_for_network_cb): Update the security diff -urN NetworkManager/libnm-util/sha1.c NetworkManager-SVN/libnm-util/sha1.c --- NetworkManager/libnm-util/sha1.c 2007-09-08 00:09:05.000000000 +0200 +++ NetworkManager-SVN/libnm-util/sha1.c 2007-09-08 00:07:00.000000000 +0200 @@ -12,6 +12,10 @@ * See README and COPYING for more details. */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include diff -urN NetworkManager/src/NetworkManager.c NetworkManager-SVN/src/NetworkManager.c --- NetworkManager/src/NetworkManager.c 2007-09-08 00:09:05.000000000 +0200 +++ NetworkManager-SVN/src/NetworkManager.c 2007-09-08 00:06:44.000000000 +0200 @@ -67,6 +67,7 @@ static gboolean sigterm_pipe_handler (GIOChannel *src, GIOCondition condition, gpointer data); static void nm_data_free (NMData *data); +static gboolean nm_poll_killswitches(gpointer user_data); /* * nm_get_device_interface_from_hal @@ -274,6 +275,183 @@ } +static void handle_killswitch_pcall_done (NMData *data, DBusPendingCall * pcall) +{ + GSource * source; + gboolean now_enabled = FALSE; + gboolean now_disabled = FALSE; + + data->ks_pcall_list = g_slist_remove (data->ks_pcall_list, pcall); + if (g_slist_length (data->ks_pcall_list) > 0) + return; /* not done with all killswitches yet */ + + if (data->hw_rf_enabled != data->tmp_hw_rf_enabled) { + nm_info ("Wireless now %s by radio killswitch", + data->tmp_hw_rf_enabled ? "enabled" : "disabled"); + if (data->tmp_hw_rf_enabled) + now_enabled = TRUE; + else + now_disabled = TRUE; + + data->hw_rf_enabled = data->tmp_hw_rf_enabled; + } + + if (data->hw_rf_enabled == data->wireless_enabled) + goto out; + + /* Only re-enabled wireless if killswitch just changed, otherwise + * ignore hardware rf enabled state. + */ + if (now_enabled && !data->wireless_enabled) { + data->wireless_enabled = TRUE; + nm_policy_schedule_device_change_check (data); + nm_dbus_signal_wireless_enabled (data); + } else if (!data->hw_rf_enabled && data->wireless_enabled) { + GSList * elt; + + /* Deactivate all wireless devices and force them down so they + * turn off their radios. + */ + nm_lock_mutex (data->dev_list_mutex, __FUNCTION__); + for (elt = data->dev_list; elt; elt = g_slist_next (elt)) { + NMDevice * dev = (NMDevice *) elt->data; + if (nm_device_is_802_11_wireless (dev)) { + nm_device_deactivate (dev); + nm_device_bring_down (dev); + } + } + nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__); + + data->wireless_enabled = FALSE; + nm_policy_schedule_device_change_check (data); + nm_dbus_signal_wireless_enabled (data); + } + +out: + /* Schedule another killswitch poll */ + source = g_timeout_source_new (6000); + g_source_set_callback (source, nm_poll_killswitches, data, NULL); + g_source_attach (source, data->main_context); + g_source_unref (source); +} + +static void nm_killswitch_getpower_reply_cb (DBusPendingCall *pcall, NMData * data) +{ + DBusError err; + DBusMessage * reply = NULL; + guint32 status; + + g_return_if_fail (pcall != NULL); + g_return_if_fail (data != NULL); + + if (!dbus_pending_call_get_completed (pcall)) + goto out; + + if (!(reply = dbus_pending_call_steal_reply (pcall))) + goto out; + + if (message_is_error (reply)) { + dbus_error_init (&err); + dbus_set_error_from_message (&err, reply); + nm_info ("Error getting killswitch power: %s - %s", err.name, err.message); + dbus_error_free (&err); + goto out; + } + + if (!dbus_message_get_args (reply, &err, DBUS_TYPE_UINT32, &status, DBUS_TYPE_INVALID)) { + nm_info ("Error getting killswitch power arguments: %s - %s", err.name, err.message); + dbus_error_free (&err); + goto out; + } + + if (status == 0) + data->tmp_hw_rf_enabled = FALSE; + +out: + if (reply) + dbus_message_unref (reply); + + handle_killswitch_pcall_done (data, pcall); + dbus_pending_call_unref (pcall); +} + + +static gboolean nm_poll_killswitches (gpointer user_data) +{ + NMData * data = (NMData *) user_data; + DBusConnection * connection = data->dbus_connection; + GSList * elt; + + g_return_val_if_fail (data != NULL, FALSE); + + data->tmp_hw_rf_enabled = TRUE; + + for (elt = data->killswitch_list; elt; elt = g_slist_next (elt)) + { + DBusPendingCall * pcall; + DBusMessage * message; + + message = dbus_message_new_method_call ("org.freedesktop.Hal", + elt->data, + "org.freedesktop.Hal.Device.KillSwitch", + "GetPower"); + if (!dbus_connection_send_with_reply (connection, message, &pcall, 5000)) { + nm_warning ("%s(): could not send dbus message", __func__); + } else if (!pcall) { + nm_warning ("%s(): could not send dbus message; pcall was NULL", __func__); + } else { + dbus_pending_call_set_notify (pcall, + (DBusPendingCallNotifyFunction) nm_killswitch_getpower_reply_cb, + data, + NULL); + data->ks_pcall_list = g_slist_append (data->ks_pcall_list, pcall); + } + dbus_message_unref (message); + } + return FALSE; +} + + +/* + * nm_add_killswitch_device + * + * Adds a killswitch device to the list + * + */ +static void nm_add_killswitch_device (NMData * data, const char * udi) +{ + char * type; + GSList * elt; + + type = libhal_device_get_property_string (data->hal_ctx, udi, "killswitch.type", NULL); + if (!type) + return; + + if (strcmp (type, "wlan") != 0) + goto out; + + /* see if it's already in the list */ + for (elt = data->killswitch_list; elt; elt = g_slist_next (elt)) { + const char * list_udi = (const char *) elt->data; + if (strcmp (list_udi, udi) == 0) + goto out; + } + + /* Start polling switches if this is the first switch we've found */ + if (g_slist_length (data->killswitch_list) == 0) { + GSource * source = g_idle_source_new (); + g_source_set_callback (source, nm_poll_killswitches, data, NULL); + g_source_attach (source, data->main_context); + g_source_unref (source); + } + + data->killswitch_list = g_slist_append (data->killswitch_list, g_strdup (udi)); + nm_info ("Found radio killswitch %s", udi); + +out: + libhal_free_string (type); +} + /* * nm_hal_device_new_capability * @@ -283,10 +461,9 @@ NMData *data = (NMData *)libhal_ctx_get_user_data (ctx); g_return_if_fail (data != NULL); + g_return_if_fail (capability != NULL); - /*nm_debug ("nm_hal_device_new_capability() called with udi = %s, capability = %s", udi, capability );*/ - - if (capability && ((strcmp (capability, "net.80203") == 0) || (strcmp (capability, "net.80211") == 0))) + if (((strcmp (capability, "net.80203") == 0) || (strcmp (capability, "net.80211") == 0))) { char *iface; @@ -296,6 +473,10 @@ g_free (iface); } } + else if (strcmp (capability, "killswitch") == 0) + { + nm_add_killswitch_device (data, udi); + } } @@ -340,6 +521,30 @@ libhal_free_string_array (net_devices); } +void nm_add_initial_killswitch_devices (NMData * data) +{ + char ** udis; + int num_udis, i; + DBusError error; + + g_return_if_fail (data != NULL); + + dbus_error_init (&error); + udis = libhal_find_device_by_capability (data->hal_ctx, "killswitch", &num_udis, &error); + if (!udis) + return; + + if (dbus_error_is_set (&error)) { + nm_warning("Could not find killswitch devices: %s", error.message); + dbus_error_free (&error); + return; + } + + for (i = 0; i < num_udis; i++) + nm_add_killswitch_device (data, udis[i]); + libhal_free_string_array (udis); +} + /* * nm_state_change_signal_broadcast @@ -616,28 +821,39 @@ g_return_if_fail (data != NULL); if ((data->hal_ctx = nm_get_hal_ctx (data))) + { + nm_add_initial_killswitch_devices (data); nm_add_initial_devices (data); + } + + /* If there weren't any killswitches, mark hardware RF to on */ + if (g_slist_length (data->killswitch_list) == 0) + data->hw_rf_enabled = TRUE; } void nm_hal_deinit (NMData *data) { + DBusError error; + g_return_if_fail (data != NULL); - if (data->hal_ctx) - { - DBusError error; + if (!data->hal_ctx) + return; - dbus_error_init (&error); - libhal_ctx_shutdown (data->hal_ctx, &error); - if (dbus_error_is_set (&error)) - { - nm_warning ("libhal shutdown failed - %s", error.message); - dbus_error_free (&error); - } - libhal_ctx_free (data->hal_ctx); - data->hal_ctx = NULL; + g_slist_foreach (data->killswitch_list, (GFunc) g_free, NULL); + g_slist_free (data->killswitch_list); + data->killswitch_list = NULL; + + dbus_error_init (&error); + libhal_ctx_shutdown (data->hal_ctx, &error); + if (dbus_error_is_set (&error)) + { + nm_warning ("libhal shutdown failed - %s", error.message); + dbus_error_free (&error); } + libhal_ctx_free (data->hal_ctx); + data->hal_ctx = NULL; } diff -urN NetworkManager/src/NetworkManagerDbus.c NetworkManager-SVN/src/NetworkManagerDbus.c --- NetworkManager/src/NetworkManagerDbus.c 2007-09-08 00:09:05.000000000 +0200 +++ NetworkManager-SVN/src/NetworkManagerDbus.c 2007-09-08 00:06:44.000000000 +0200 @@ -434,6 +434,29 @@ } +void nm_dbus_signal_wireless_enabled (NMData * data) +{ + DBusMessage * message; + + g_return_if_fail (data != NULL); + g_return_if_fail (data->dbus_connection != NULL); + + if (!(message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "WirelessEnabled"))) + { + nm_warning ("%s(): Not enough memory for new dbus message!", __func__); + return; + } + + dbus_message_append_args (message, + DBUS_TYPE_BOOLEAN, &data->wireless_enabled, + DBUS_TYPE_BOOLEAN, &data->hw_rf_enabled, + DBUS_TYPE_INVALID); + if (!dbus_connection_send (data->dbus_connection, message, NULL)) + nm_warning ("%s(): Could not emit the WirelessEnabled signal!", __func__); + + dbus_message_unref (message); +} + /* * nm_dbus_signal_filter * diff -urN NetworkManager/src/NetworkManagerDbus.h NetworkManager-SVN/src/NetworkManagerDbus.h --- NetworkManager/src/NetworkManagerDbus.h 2007-09-08 00:09:05.000000000 +0200 +++ NetworkManager-SVN/src/NetworkManagerDbus.h 2007-09-08 00:06:44.000000000 +0200 @@ -68,6 +68,7 @@ void nm_dbus_signal_wireless_network_change (DBusConnection *connection, NMDevice80211Wireless *dev, NMAccessPoint *ap, NMNetworkStatus status, gint strength); void nm_dbus_signal_device_strength_change (DBusConnection *connection, NMDevice80211Wireless *dev, gint strength); +void nm_dbus_signal_wireless_enabled (NMData * data); NMDevice * nm_dbus_get_device_from_escaped_object_path (NMData *data, const char *path); diff -urN NetworkManager/src/NetworkManagerMain.h NetworkManager-SVN/src/NetworkManagerMain.h --- NetworkManager/src/NetworkManagerMain.h 2007-09-08 00:09:05.000000000 +0200 +++ NetworkManager-SVN/src/NetworkManagerMain.h 2007-09-08 00:06:44.000000000 +0200 @@ -82,6 +82,7 @@ GSList * dev_list; GMutex * dev_list_mutex; + gboolean hw_rf_enabled; gboolean wireless_enabled; gboolean modem_active; gboolean asleep; @@ -90,6 +91,10 @@ GSList * dialup_list; GMutex * dialup_list_mutex; + GSList * killswitch_list; + GSList * ks_pcall_list; /* track killswitch D-Bus pending calls */ + gboolean tmp_hw_rf_enabled; + struct NMAccessPointList *allowed_ap_list; struct NMAccessPointList *invalid_ap_list; } NMData; diff -urN NetworkManager/src/NetworkManagerPolicy.c NetworkManager-SVN/src/NetworkManagerPolicy.c --- NetworkManager/src/NetworkManagerPolicy.c 2007-09-08 00:09:05.000000000 +0200 +++ NetworkManager-SVN/src/NetworkManagerPolicy.c 2007-09-08 00:06:44.000000000 +0200 @@ -52,6 +52,7 @@ NMDevice *dev = NULL; NMData *data = NULL; NMAccessPoint * ap = NULL; + NMActRequest * dev_req; g_return_val_if_fail (req != NULL, FALSE); @@ -61,6 +62,13 @@ dev = nm_act_request_get_dev (req); g_assert (dev); + /* Ensure that inactive devices don't get the activated signal + * sent due to race conditions. + */ + dev_req = nm_device_get_act_request (dev); + if (!dev_req || (dev_req != req)) + return FALSE; + if (nm_device_is_802_11_wireless (dev)) ap = nm_act_request_get_ap (req); @@ -265,14 +273,16 @@ } #if 0 - nm_info ("AUTO: Best wired device = %s, best wireless device = %s (%s)", best_wired_dev ? nm_device_get_iface (best_wired_dev) : "(null)", - best_wireless_dev ? nm_device_get_iface (best_wireless_dev) : "(null)", (best_wireless_dev && *ap) ? nm_ap_get_essid (*ap) : "null" ); + nm_info ("AUTO: Best wired device = %s, best wireless device = %s (%s)", best_wired_dev ? nm_device_get_iface (NM_DEVICE (best_wired_dev)) : "(null)", + best_wireless_dev ? nm_device_get_iface (NM_DEVICE (best_wireless_dev)) : "(null)", (best_wireless_dev && *ap) ? nm_ap_get_essid (*ap) : "null" ); #endif return highest_priority_dev; } +static GStaticMutex dcc_mutex = G_STATIC_MUTEX_INIT; + /* * nm_policy_device_change_check * @@ -294,7 +304,9 @@ g_return_val_if_fail (data != NULL, FALSE); + g_static_mutex_lock (&dcc_mutex); data->dev_change_check_idle_id = 0; + g_static_mutex_unlock (&dcc_mutex); old_dev = nm_get_active_device (data); @@ -303,11 +315,19 @@ if (old_dev) { + gboolean has_link = TRUE; guint32 caps = nm_device_get_capabilities (old_dev); + /* Ensure ethernet devices have a link before starting activation, + * partially works around Fedora #194124. + */ + if (nm_device_is_802_3_ethernet (old_dev)) + has_link = nm_device_has_active_link (old_dev); + /* Don't interrupt a currently activating device. */ if ( nm_device_is_activating (old_dev) - && !nm_device_can_interrupt_activation (old_dev)) + && !nm_device_can_interrupt_activation (old_dev) + && has_link) { nm_info ("Old device '%s' activating, won't change.", nm_device_get_iface (old_dev)); goto out; @@ -425,12 +445,35 @@ if (do_switch && (nm_device_is_802_3_ethernet (new_dev) || (nm_device_is_802_11_wireless (new_dev) && ap))) { NMActRequest * act_req = NULL; + gboolean has_link = TRUE; + + /* Ensure ethernet devices have a link before starting activation, + * partially works around Fedora #194124. + */ + if (nm_device_is_802_3_ethernet (new_dev)) + has_link = nm_device_has_active_link (new_dev); - if ((act_req = nm_act_request_new (data, new_dev, ap, FALSE))) + if (has_link) + { + if ((act_req = nm_act_request_new (data, new_dev, ap, FALSE))) + { + nm_info ("Will activate connection '%s%s%s'.", + nm_device_get_iface (new_dev), + ap ? "/" : "", + ap ? nm_ap_get_essid (ap) : ""); + nm_policy_schedule_device_activation (act_req); + nm_act_request_unref (act_req); + } + else + { + nm_info ("Error creating activation request for %s", + nm_device_get_iface (new_dev)); + } + } + else { - nm_info ("Will activate connection '%s%s%s'.", nm_device_get_iface (new_dev), ap ? "/" : "", ap ? nm_ap_get_essid (ap) : ""); - nm_policy_schedule_device_activation (act_req); - nm_act_request_unref (act_req); + nm_info ("Won't activate %s because it no longer has a link.", + nm_device_get_iface (new_dev)); } } @@ -452,11 +495,9 @@ */ void nm_policy_schedule_device_change_check (NMData *data) { - static GStaticMutex mutex = G_STATIC_MUTEX_INIT; - g_return_if_fail (data != NULL); - g_static_mutex_lock (&mutex); + g_static_mutex_lock (&dcc_mutex); if (data->dev_change_check_idle_id == 0) { @@ -466,8 +507,7 @@ data->dev_change_check_idle_id = g_source_attach (source, data->main_context); g_source_unref (source); } - - g_static_mutex_unlock (&mutex); + g_static_mutex_unlock (&dcc_mutex); } diff -urN NetworkManager/src/NetworkManagerSystem.c NetworkManager-SVN/src/NetworkManagerSystem.c --- NetworkManager/src/NetworkManagerSystem.c 2007-09-08 00:09:05.000000000 +0200 +++ NetworkManager-SVN/src/NetworkManagerSystem.c 2007-09-08 00:06:44.000000000 +0200 @@ -64,6 +64,7 @@ struct sockaddr_in *p; const char * iface; int err; + NMIP4Config * config = NULL; iface = nm_device_get_iface (dev); @@ -75,6 +76,15 @@ if (ip4_gateway == 0) return TRUE; + /* + * Do not add the route if the destination is on the same subnet. + */ + config = nm_device_get_ip4_config(dev); + if (config && + ((guint32)ip4_dest & nm_ip4_config_get_netmask(config)) == + (nm_ip4_config_get_address(config) & nm_ip4_config_get_netmask(config))) + return TRUE; + if ((sk = nm_dev_sock_open (dev, NETWORK_CONTROL, __FUNCTION__, NULL)) == NULL) return FALSE; diff -urN NetworkManager/src/nm-ap-security-wpa-eap.c NetworkManager-SVN/src/nm-ap-security-wpa-eap.c --- NetworkManager/src/nm-ap-security-wpa-eap.c 2007-09-08 00:09:05.000000000 +0200 +++ NetworkManager-SVN/src/nm-ap-security-wpa-eap.c 2007-09-08 00:06:44.000000000 +0200 @@ -57,7 +57,6 @@ NMAPSecurityWPA_EAP * security = NULL; int eap_method; int key_type; - int phase2_type; int wpa_version; char * identity = NULL; char * passwd = NULL; diff -urN NetworkManager/src/nm-dbus-nm.c NetworkManager-SVN/src/nm-dbus-nm.c --- NetworkManager/src/nm-dbus-nm.c 2007-09-08 00:09:05.000000000 +0200 +++ NetworkManager-SVN/src/nm-dbus-nm.c 2007-09-08 00:06:44.000000000 +0200 @@ -483,52 +483,83 @@ return (reply); } -static DBusMessage *nm_dbus_nm_set_wireless_enabled (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) +static DBusMessage *nm_dbus_nm_set_wireless_enabled (DBusConnection *connection, DBusMessage *message, NMDbusCBData *cb_data) { gboolean enabled = FALSE; DBusError err; - NMData *app_data; + NMData * data; + DBusMessage * ret = NULL; - g_return_val_if_fail (data && data->data && connection && message, NULL); + g_return_val_if_fail (cb_data && cb_data->data && connection && message, NULL); dbus_error_init (&err); if (!dbus_message_get_args (message, &err, DBUS_TYPE_BOOLEAN, &enabled, DBUS_TYPE_INVALID)) - return NULL; + goto out; - app_data = data->data; - app_data->wireless_enabled = enabled; + data = cb_data->data; + if (enabled == data->wireless_enabled) + goto out; + + /* Hardware rfkill overrides whatever user wants */ + if (!data->hw_rf_enabled) { + nm_info ("User request to %s wireless overridden by radio killswitch.", + enabled ? "enable" : "disable"); - if (!enabled) - { - GSList *elt; + /* Return error if user tries to re-enable wireless, or just ignore + * a disable wireless request when wireless is already disabled. + */ + if (enabled) { + ret = nm_dbus_create_error_message (message, + NM_DBUS_INTERFACE, + "DisabledBySystem", + "Wireless disabled by hardware switch."); + } + goto out; + } - /* Physically down all wireless devices */ - nm_lock_mutex (app_data->dev_list_mutex, __FUNCTION__); - for (elt = app_data->dev_list; elt; elt = g_slist_next (elt)) - { - NMDevice *dev = (NMDevice *)(elt->data); - if (nm_device_is_802_11_wireless (dev)) - { + nm_info ("User request to %s wireless.", enabled ? "enable" : "disable"); + + data->wireless_enabled = enabled; + if (!data->wireless_enabled) { + GSList * elt; + + /* Deactivate all wireless devices and force them down so they + * turn off their radios. + */ + nm_lock_mutex (data->dev_list_mutex, __FUNCTION__); + for (elt = data->dev_list; elt; elt = g_slist_next (elt)) { + NMDevice * dev = (NMDevice *) elt->data; + if (nm_device_is_802_11_wireless (dev)) { nm_device_deactivate (dev); nm_device_bring_down (dev); } } - nm_unlock_mutex (app_data->dev_list_mutex, __FUNCTION__); + nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__); } - nm_policy_schedule_device_change_check (data->data); + nm_policy_schedule_device_change_check (data); + nm_dbus_signal_wireless_enabled (data); - return NULL; +out: + return ret; } -static DBusMessage *nm_dbus_nm_get_wireless_enabled (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) +static DBusMessage *nm_dbus_nm_get_wireless_enabled (DBusConnection *connection, DBusMessage *message, NMDbusCBData *cb_data) { + NMData * data; DBusMessage *reply = NULL; - g_return_val_if_fail (data && data->data && connection && message, NULL); + g_return_val_if_fail (cb_data && connection && message, NULL); - if ((reply = dbus_message_new_method_return (message))) - dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &data->data->wireless_enabled, DBUS_TYPE_INVALID); + data = cb_data->data; + g_return_val_if_fail (data != NULL, NULL); + + if ((reply = dbus_message_new_method_return (message))) { + dbus_message_append_args (reply, + DBUS_TYPE_BOOLEAN, &data->wireless_enabled, + DBUS_TYPE_BOOLEAN, &data->hw_rf_enabled, + DBUS_TYPE_INVALID); + } return reply; } diff -urN NetworkManager/src/nm-device-802-11-wireless.c NetworkManager-SVN/src/nm-device-802-11-wireless.c --- NetworkManager/src/nm-device-802-11-wireless.c 2007-09-08 00:09:05.000000000 +0200 +++ NetworkManager-SVN/src/nm-device-802-11-wireless.c 2007-09-08 00:06:44.000000000 +0200 @@ -617,7 +617,10 @@ /* Start the scanning timeout for devices that can do scanning */ if (nm_device_get_capabilities (dev) & NM_DEVICE_CAP_WIRELESS_SCAN) { - self->priv->pending_scan = g_idle_source_new (); + /* Stupid orinoco has problems scanning immediately after being up, + * so wait a bit before triggering a scan. + */ + self->priv->pending_scan = g_timeout_source_new (600); g_source_set_callback (self->priv->pending_scan, nm_device_802_11_wireless_scan, self, @@ -2981,6 +2984,9 @@ return NM_ACT_STAGE_RETURN_POSTPONE; } + /* Some cards are dumb. Wait a second */ + sleep (1); + iface = nm_device_get_iface (dev); if (!supplicant_exec (self)) { @@ -3446,10 +3452,9 @@ char *genie, *gpos, *gend, *custom; NMAccessPoint *ap = NULL; size_t clen; - int maxrate; + int maxrate = 0; struct iw_event iwe_buf, *iwe = &iwe_buf; struct stream_descr stream; - struct wireless_scan * wscan = NULL; int ret; g_return_val_if_fail (dev != NULL, FALSE); diff -urN NetworkManager/src/nm-device-802-3-ethernet.c NetworkManager-SVN/src/nm-device-802-3-ethernet.c --- NetworkManager/src/nm-device-802-3-ethernet.c 2007-09-08 00:09:05.000000000 +0200 +++ NetworkManager-SVN/src/nm-device-802-3-ethernet.c 2007-09-08 00:06:44.000000000 +0200 @@ -108,18 +108,16 @@ GObject *obj, NMDevice8023Ethernet *self) { + GSource * source; + /* Make sure signal is for us */ if (NM_DEVICE (self) != NM_DEVICE (obj)) return; - if (!nm_device_has_active_link (NM_DEVICE (self))) - { - GSource * source = g_idle_source_new (); - - g_source_set_callback (source, (GSourceFunc) link_activated_helper, self, NULL); - g_source_attach (source, nm_device_get_main_context (NM_DEVICE (self))); - g_source_unref (source); - } + source = g_idle_source_new (); + g_source_set_callback (source, (GSourceFunc) link_activated_helper, self, NULL); + g_source_attach (source, nm_device_get_main_context (NM_DEVICE (self))); + g_source_unref (source); } @@ -135,18 +133,16 @@ GObject *obj, NMDevice8023Ethernet *self) { + GSource * source; + /* Make sure signal is for us */ if (NM_DEVICE (self) != NM_DEVICE (obj)) return; - if (nm_device_has_active_link (NM_DEVICE (self))) - { - GSource * source = g_idle_source_new (); - - g_source_set_callback (source, (GSourceFunc) link_deactivated_helper, self, NULL); - g_source_attach (source, nm_device_get_main_context (NM_DEVICE (self))); - g_source_unref (source); - } + source = g_idle_source_new (); + g_source_set_callback (source, (GSourceFunc) link_deactivated_helper, self, NULL); + g_source_attach (source, nm_device_get_main_context (NM_DEVICE (self))); + g_source_unref (source); } static void @@ -211,6 +207,26 @@ return caps; } + +static NMActStageReturn +real_act_stage1_prepare (NMDevice *dev, NMActRequest *req) +{ + NMDevice8023Ethernet * self = NM_DEVICE_802_3_ETHERNET (dev); + NMDevice8023EthernetClass * klass; + NMDeviceClass * parent_class; + + /* Ensure ethernet devices have a link before going further with activation, + * partially works around Fedora #194124. + */ + if (!nm_device_has_active_link (dev)) + return NM_ACT_STAGE_RETURN_FAILURE; + + /* Chain up to parent */ + klass = NM_DEVICE_802_3_ETHERNET_GET_CLASS (self); + parent_class = NM_DEVICE_CLASS (g_type_class_peek_parent (klass)); + return parent_class->act_stage1_prepare (dev, req); +} + static void nm_device_802_3_ethernet_dispose (GObject *object) { @@ -275,6 +291,7 @@ parent_class->get_generic_capabilities = real_get_generic_capabilities; parent_class->init = real_init; parent_class->update_link = real_update_link; + parent_class->act_stage1_prepare = real_act_stage1_prepare; g_type_class_add_private (object_class, sizeof (NMDevice8023EthernetPrivate)); } diff -urN NetworkManager/src/nm-device.c NetworkManager-SVN/src/nm-device.c --- NetworkManager/src/nm-device.c 2007-09-08 00:09:05.000000000 +0200 +++ NetworkManager-SVN/src/nm-device.c 2007-09-08 00:06:44.000000000 +0200 @@ -856,6 +856,12 @@ data = nm_act_request_get_data (req); g_assert (data); + /* Sometimes the device gets downed by wpa_supplicant; in any case, make + * sure it's up before anything tries to use it. + */ + if (!nm_device_is_up (self)) + nm_device_bring_up (self); + /* DHCP devices try DHCP, non-DHCP default to SUCCESS */ if (nm_device_get_use_dhcp (self)) {