diff options
| author | Michael Biebl <biebl@debian.org> | 2007-08-26 22:59:14 +0000 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2007-08-26 22:59:14 +0000 |
| commit | f04dbc618f4a8ef079e0acc1a185b0c7bf5eb2f6 (patch) | |
| tree | ee37df19eab38c44e05eed0f9bebc698794e395c | |
| parent | 614e759115bb291136e155f2b37af80780ef0ab3 (diff) | |
* debian/patches/20-stable_branch_updates_r2652.patch
- Pull updates from the stable branch up until revision 2652. - Fixes broken link detection and a couple of smaller issues. - Adds support for the rfkill switch. git-svn-id: svn+ssh://svn.debian.org/svn/pkg-utopia/packages/unstable/networkmanager@1676 ceb527fc-18e6-0310-9fe2-813c157c29e7
| -rw-r--r-- | debian/changelog | 6 | ||||
| -rw-r--r-- | debian/patches/20-stable_branch_updates_r2652.patch | 914 |
2 files changed, 919 insertions, 1 deletions
diff --git a/debian/changelog b/debian/changelog index 121895f8..656772f6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -36,8 +36,12 @@ network-manager (0.6.5-1) unstable; urgency=low + Exclude nm-vpn-properties from dh_shlibdeps. This is a temporary workaround until this binary has also been moved into the nm-applet source package. + * debian/patches/20-stable_branch_updates_r2652.patch + - Pull updates from the stable branch up until revision 2652. + - Fixes broken link detection and a couple of smaller issues. + - Adds support for the rfkill switch. - -- Michael Biebl <biebl@debian.org> Sun, 26 Aug 2007 23:55:17 +0200 + -- Michael Biebl <biebl@debian.org> Mon, 27 Aug 2007 00:39:16 +0200 network-manager (0.6.4-8) unstable; urgency=low diff --git a/debian/patches/20-stable_branch_updates_r2652.patch b/debian/patches/20-stable_branch_updates_r2652.patch new file mode 100644 index 00000000..aea8e86f --- /dev/null +++ b/debian/patches/20-stable_branch_updates_r2652.patch @@ -0,0 +1,914 @@ +Index: ChangeLog +=================================================================== +--- ChangeLog (Revision 2558) ++++ ChangeLog (Revision 2652) +@@ -1,3 +1,99 @@ ++2007-07-26 Dan Williams <dcbw@redhat.com> ++ ++ Patch from Bernhard Miklautz <bernhard.miklautz@shacknet.at> ++ ++ * 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 <dcbw@redhat.com> ++ ++ * 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 <dcbw@redhat.com> ++ ++ * 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 <dcbw@redhat.com> ++ ++ 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 <dcbw@redhat.com> ++ ++ 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 <dcbw@redhat.com> ++ ++ * 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 <dcbw@redhat.com> ++ ++ Patch from Jon Nettleton <jon.nettleton@gmail.com> ++ ++ * 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 <dcbw@redhat.com> ++ ++ * (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 <dcbw@redhat.com> ++ ++ * initscript/RedHat/NetworkManager.in: remove trailing backslash ++ (gnome.org #432401) ++ + 2007-04-18 Tambet Ingo <tambet@ximian.com> + + * src/nm-dbus-nmi.c (nm_dbus_get_user_key_for_network_cb): Update the security +Index: src/NetworkManagerDbus.c +=================================================================== +--- src/NetworkManagerDbus.c (Revision 2558) ++++ src/NetworkManagerDbus.c (Revision 2652) +@@ -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 + * +Index: src/NetworkManagerDbus.h +=================================================================== +--- src/NetworkManagerDbus.h (Revision 2558) ++++ src/NetworkManagerDbus.h (Revision 2652) +@@ -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); + +Index: src/nm-dbus-nm.c +=================================================================== +--- src/nm-dbus-nm.c (Revision 2558) ++++ src/nm-dbus-nm.c (Revision 2652) +@@ -483,53 +483,84 @@ + 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; + +- if (!enabled) +- { +- GSList *elt; ++ /* 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"); + +- /* 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)) +- { ++ /* 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; ++ } ++ ++ 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; + } + +Index: src/nm-device-802-3-ethernet.c +=================================================================== +--- src/nm-device-802-3-ethernet.c (Revision 2558) ++++ src/nm-device-802-3-ethernet.c (Revision 2652) +@@ -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)); + } +Index: src/NetworkManagerPolicy.c +=================================================================== +--- src/NetworkManagerPolicy.c (Revision 2558) ++++ src/NetworkManagerPolicy.c (Revision 2652) +@@ -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,13 +445,36 @@ + 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; + +- if ((act_req = nm_act_request_new (data, new_dev, ap, FALSE))) ++ /* 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 (has_link) + { +- 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); ++ 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 ("Won't activate %s because it no longer has a link.", ++ nm_device_get_iface (new_dev)); ++ } + } + + if (ap) +@@ -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); + } + + +Index: src/nm-ap-security-wpa-eap.c +=================================================================== +--- src/nm-ap-security-wpa-eap.c (Revision 2558) ++++ src/nm-ap-security-wpa-eap.c (Revision 2652) +@@ -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; +Index: src/nm-device.c +=================================================================== +--- src/nm-device.c (Revision 2558) ++++ src/nm-device.c (Revision 2652) +@@ -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)) + { +Index: src/NetworkManager.c +=================================================================== +--- src/NetworkManager.c (Revision 2558) ++++ src/NetworkManager.c (Revision 2652) +@@ -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,7 +275,184 @@ + } + + ++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,7 +521,31 @@ + 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) ++ if (!data->hal_ctx) ++ return; ++ ++ 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)) + { +- DBusError error; +- +- 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; ++ nm_warning ("libhal shutdown failed - %s", error.message); ++ dbus_error_free (&error); + } ++ libhal_ctx_free (data->hal_ctx); ++ data->hal_ctx = NULL; + } + + +Index: src/nm-device-802-11-wireless.c +=================================================================== +--- src/nm-device-802-11-wireless.c (Revision 2558) ++++ src/nm-device-802-11-wireless.c (Revision 2652) +@@ -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); +Index: src/NetworkManagerMain.h +=================================================================== +--- src/NetworkManagerMain.h (Revision 2558) ++++ src/NetworkManagerMain.h (Revision 2652) +@@ -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; +Index: src/NetworkManagerSystem.c +=================================================================== +--- src/NetworkManagerSystem.c (Revision 2558) ++++ src/NetworkManagerSystem.c (Revision 2652) +@@ -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; + |