diff --git a/ChangeLog b/ChangeLog index d65c9cdb1c..209cef25cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2007-09-26 Tambet Ingo + + * src/nm-manager.c (manager_device_state_changed): Listen to device' NEED_AUTH + state and try to get the secrets. + + * src/NetworkManagerPolicy.c (nm_policy_auto_get_best_device): Get the list of + connections from NMManager and let the device to choose the best from the list. + Since the connection list is sorted by system ones first and user ones later, + the devices still prefer system connections like they did before. + (deactivate_old_device): Implement. When a device starts activation, we have a + policy (for now at least) to deactivate any other device that might be either + active or still activating. + + * src/vpn-manager/nm-vpn-manager.c: Add NMManager back to the private structure. + It's set on construction, there will be no other way to access it. + + * src/nm-device-802-11-wireless.c: Don't touch NMManager, NMManager can listen to + device events and drive the device, not the other way around. + + * src/nm-device-802-3-ethernet.c: Ditto. + + * src/nm-device.c (nm_device_get_best_connection): The connections list is now + sent along, pass it on to virtual functions. + + * src/nm-device-interface.c (nm_device_interface_get_iface): Implement. It's static + for now, but should really be public instead of nm_device_get_iface() since iface + is a property of the DeviceInterface, not Device. + (impl_device_activate): Don't touch NMManager! + 2007-09-26 Jürg Billeter * initscript/paldo/NetworkManager.in: diff --git a/src/NetworkManager.c b/src/NetworkManager.c index 3cfedc78c4..20567af5ed 100644 --- a/src/NetworkManager.c +++ b/src/NetworkManager.c @@ -345,7 +345,7 @@ main (int argc, char *argv[]) goto done; } - vpn_manager = nm_vpn_manager_new (); + vpn_manager = nm_vpn_manager_new (manager); if (!vpn_manager) { nm_warning ("Failed to start the VPN manager."); goto done; diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index 7017ede232..b9309d3d10 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c @@ -1,3 +1,4 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ /* NetworkManager -- Network link manager * * Dan Williams @@ -68,6 +69,7 @@ nm_policy_auto_get_best_device (NMPolicy *policy, NMConnection **connection, char **specific_object) { + GSList *connections; GSList * elt; NMDevice8023Ethernet * best_wired_dev = NULL; guint best_wired_prio = 0; @@ -87,6 +89,10 @@ nm_policy_auto_get_best_device (NMPolicy *policy, if (nm_manager_get_state (policy->manager) == NM_STATE_ASLEEP) return NULL; + /* System connections first, then user connections */ + connections = nm_manager_get_connections (policy->manager, NM_CONNECTION_TYPE_SYSTEM); + connections = g_slist_concat (connections, nm_manager_get_connections (policy->manager, NM_CONNECTION_TYPE_USER)); + for (elt = nm_manager_get_devices (policy->manager); elt; elt = elt->next) { NMConnection *tmp_con = NULL; char *tmp_obj = NULL; @@ -98,7 +104,7 @@ nm_policy_auto_get_best_device (NMPolicy *policy, link_active = nm_device_has_active_link (dev); caps = nm_device_get_capabilities (dev); - tmp_con = nm_device_get_best_connection (dev, &tmp_obj); + tmp_con = nm_device_get_best_connection (dev, connections, &tmp_obj); if (tmp_con == NULL) { NMActRequest *req = nm_device_get_act_request (dev); @@ -145,6 +151,8 @@ nm_policy_auto_get_best_device (NMPolicy *policy, } } + g_slist_free (connections); + if (best_wired_dev) { highest_priority_dev = NM_DEVICE (best_wired_dev); *connection = best_wired_connection; @@ -385,12 +393,41 @@ schedule_change_check (NMPolicy *policy) device_change_check_done); } +/* FIXME: remove when multiple active device support has landed */ +static void +deactivate_old_device (NMPolicy *policy, NMDevice *new_device) +{ + GSList *iter; + + for (iter = nm_manager_get_devices (policy->manager); iter; iter = iter->next) { + NMDevice *dev = NM_DEVICE (iter->data); + + if (dev == new_device) + continue; + + switch (nm_device_get_state (dev)) { + case NM_DEVICE_STATE_PREPARE: + case NM_DEVICE_STATE_CONFIG: + case NM_DEVICE_STATE_NEED_AUTH: + case NM_DEVICE_STATE_IP_CONFIG: + case NM_DEVICE_STATE_ACTIVATED: + nm_device_interface_deactivate (NM_DEVICE_INTERFACE (dev)); + break; + default: + break; + } + } +} + static void device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data) { NMPolicy *policy = (NMPolicy *) user_data; - if (state == NM_DEVICE_STATE_FAILED || state == NM_DEVICE_STATE_CANCELLED) + if (state == NM_DEVICE_STATE_PREPARE) + deactivate_old_device (policy, device); /* FIXME: remove when multiple active device support has landed */ + + else if (state == NM_DEVICE_STATE_FAILED || state == NM_DEVICE_STATE_CANCELLED) schedule_change_check (policy); } diff --git a/src/nm-device-802-11-wireless.c b/src/nm-device-802-11-wireless.c index 9caa1a05a6..686af1d893 100644 --- a/src/nm-device-802-11-wireless.c +++ b/src/nm-device-802-11-wireless.c @@ -694,32 +694,19 @@ find_best_connection (gpointer data, gpointer user_data) static NMConnection * real_get_best_connection (NMDevice *dev, + GSList *connections, char **specific_object) { NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev); - NMManager *manager = nm_manager_get (); - GSList *connections = NULL; BestConnectionInfo find_info; - /* System connections first */ - connections = nm_manager_get_connections (manager, NM_CONNECTION_TYPE_SYSTEM); memset (&find_info, 0, sizeof (BestConnectionInfo)); find_info.self = self; g_slist_foreach (connections, find_best_connection, &find_info); - g_slist_free (connections); - - /* Then user connections */ - if (!find_info.found) { - connections = nm_manager_get_connections (manager, NM_CONNECTION_TYPE_USER); - find_info.self = self; - g_slist_foreach (connections, find_best_connection, &find_info); - g_slist_free (connections); - } - - g_object_unref (manager); if (find_info.found) *specific_object = (char *) nm_ap_get_dbus_path (find_info.found_ap); + return find_info.found; } @@ -1919,7 +1906,6 @@ link_timeout_cb (gpointer user_data) NMActRequest * req = NULL; NMAccessPoint * ap = NULL; NMConnection * connection; - NMManager * manager; const char * setting_name; gboolean auth_enforced, encrypted = FALSE; @@ -1969,13 +1955,6 @@ link_timeout_cb (gpointer user_data) cleanup_association_attempt (self, TRUE); nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH); - manager = nm_manager_get (); - nm_manager_get_connection_secrets (manager, - NM_DEVICE_INTERFACE (self), - connection, - setting_name, - TRUE); - g_object_unref (manager); return FALSE; time_out: @@ -2361,20 +2340,12 @@ supplicant_connection_timeout_cb (gpointer user_data) nm_device_get_iface (dev)); nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED); } else { - NMManager *manager = nm_manager_get (); - /* Authentication failed, encryption key is probably bad */ nm_info ("Activation (%s/wireless): association took too long, " "asking for new key.", nm_device_get_iface (dev)); nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH); - nm_manager_get_connection_secrets (manager, - NM_DEVICE_INTERFACE (self), - connection, - NM_SETTING_WIRELESS_SECURITY, - TRUE); - g_object_unref (manager); } return FALSE; @@ -2556,20 +2527,11 @@ real_act_stage2_config (NMDevice *dev) /* If we need secrets, get them */ setting_name = nm_connection_need_secrets (connection); if (setting_name) { - NMManager * manager = nm_manager_get (); - nm_info ("Activation (%s/wireless): access point '%s' has security," " but secrets are required.", iface, s_connection->name); nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH); - nm_manager_get_connection_secrets (manager, - NM_DEVICE_INTERFACE (self), - connection, - setting_name, - FALSE); - g_object_unref (manager); - return NM_ACT_STAGE_RETURN_POSTPONE; } else { NMSettingWireless *s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_SETTING_WIRELESS); @@ -2714,7 +2676,6 @@ real_act_stage4_ip_config_timeout (NMDevice *dev, connection = nm_act_request_get_connection (req); auth_enforced = ap_auth_enforced (connection, ap, &encrypted); if (encrypted && !auth_enforced) { - NMManager *manager = nm_manager_get (); const GByteArray * ssid = nm_ap_get_ssid (ap); /* Activation failed, we must have bad encryption key */ @@ -2723,12 +2684,6 @@ real_act_stage4_ip_config_timeout (NMDevice *dev, nm_device_get_iface (dev), ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)"); nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH); - nm_manager_get_connection_secrets (manager, - NM_DEVICE_INTERFACE (self), - connection, - NM_SETTING_WIRELESS_SECURITY, - TRUE); - g_object_unref (manager); ret = NM_ACT_STAGE_RETURN_POSTPONE; } else if (nm_ap_get_mode (ap) == IW_MODE_ADHOC) { NMDevice80211WirelessClass * klass; diff --git a/src/nm-device-802-3-ethernet.c b/src/nm-device-802-3-ethernet.c index fba434cf4a..0f7dd6ca93 100644 --- a/src/nm-device-802-3-ethernet.c +++ b/src/nm-device-802-3-ethernet.c @@ -34,7 +34,6 @@ #include "nm-supplicant-manager.h" #include "nm-netlink-monitor.h" #include "nm-utils.h" -#include "nm-manager.h" #include "nm-device-802-3-ethernet-glue.h" @@ -366,11 +365,10 @@ find_best_connection (gpointer data, gpointer user_data) static NMConnection * real_get_best_connection (NMDevice *dev, + GSList *connections, char **specific_object) { NMDevice8023Ethernet * self = NM_DEVICE_802_3_ETHERNET (dev); - NMManager *manager; - GSList *connections = NULL; BestConnectionInfo find_info; guint32 caps; gboolean link_active; @@ -385,24 +383,9 @@ real_get_best_connection (NMDevice *dev, if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT)) return NULL; - manager = nm_manager_get (); - - /* System connections first */ - connections = nm_manager_get_connections (manager, NM_CONNECTION_TYPE_SYSTEM); memset (&find_info, 0, sizeof (BestConnectionInfo)); find_info.self = self; g_slist_foreach (connections, find_best_connection, &find_info); - g_slist_free (connections); - - /* Then user connections */ - if (!find_info.found) { - connections = nm_manager_get_connections (manager, NM_CONNECTION_TYPE_USER); - find_info.self = self; - g_slist_foreach (connections, find_best_connection, &find_info); - g_slist_free (connections); - } - - g_object_unref (manager); /* Wired devices autoconnect with DHCP by default if they have a link */ link_active = nm_device_has_active_link (dev); diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c index 1b0875e55d..c8f6b02a09 100644 --- a/src/nm-device-interface.c +++ b/src/nm-device-interface.c @@ -1,7 +1,7 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ #include "nm-device-interface.h" #include "nm-ip4-config.h" -#include "nm-manager.h" #include "nm-utils.h" static gboolean impl_device_activate (NMDeviceInterface *device, @@ -207,6 +207,19 @@ nm_device_interface_activate (NMDeviceInterface *device, user_requested); } +/* FIXME: This should be public and nm_device_get_iface() should be removed. */ +static const char * +nm_device_interface_get_iface (NMDeviceInterface *device) +{ + const char *iface = NULL; + + g_return_val_if_fail (NM_IS_DEVICE_INTERFACE (device), NULL); + + g_object_get (device, NM_DEVICE_INTERFACE_IFACE, &iface, NULL); + + return iface; +} + static gboolean impl_device_activate (NMDeviceInterface *device, const char *service_name, @@ -214,44 +227,7 @@ impl_device_activate (NMDeviceInterface *device, const char *specific_object, GError **err) { - NMManager *manager = nm_manager_get (); - NMDevice *old_dev = NULL; - GSList *iter; - - // FIXME: remove when multiple active device support has landed - switch (nm_manager_get_state (manager)) { - case NM_STATE_CONNECTED: - old_dev = nm_manager_get_active_device (manager); - break; - case NM_STATE_CONNECTING: - for (iter = nm_manager_get_devices (manager); iter; iter = iter->next) { - if (nm_device_is_activating (NM_DEVICE (iter->data))) { - old_dev = NM_DEVICE (iter->data); - break; - } - } - break; - case NM_STATE_DISCONNECTED: - /* Check for devices that have deferred activation requests */ - for (iter = nm_manager_get_devices (manager); iter; iter = iter->next) { - NMActRequest *req = nm_device_get_act_request (NM_DEVICE (iter->data)); - - if (req && nm_act_request_is_deferred (req)) { - old_dev = NM_DEVICE (iter->data); - break; - } - } - break; - default: - break; - } - g_object_unref (manager); - - nm_info ("User request for activation of %s.", nm_device_get_iface (NM_DEVICE (device))); - - if (old_dev) - nm_device_interface_deactivate (NM_DEVICE_INTERFACE (old_dev)); - + nm_info ("User request for activation of %s.", nm_device_interface_get_iface (device)); nm_device_interface_activate (device, service_name, connection_path, diff --git a/src/nm-device.c b/src/nm-device.c index f2160c9b47..5076bf51df 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -389,6 +389,7 @@ nm_device_set_active_link (NMDevice *self, NMConnection * nm_device_get_best_connection (NMDevice *dev, + GSList *connections, char **specific_object) { guint32 caps; @@ -405,7 +406,7 @@ nm_device_get_best_connection (NMDevice *dev, if (!NM_DEVICE_GET_CLASS (dev)->get_best_connection) return NULL; - return NM_DEVICE_GET_CLASS (dev)->get_best_connection (dev, specific_object); + return NM_DEVICE_GET_CLASS (dev)->get_best_connection (dev, connections, specific_object); } /* diff --git a/src/nm-device.h b/src/nm-device.h index 6a3dd257da..ea2b735b5c 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -91,6 +91,7 @@ struct _NMDeviceClass guint32 (* get_generic_capabilities) (NMDevice *self); NMConnection * (* get_best_connection) (NMDevice *self, + GSList *connections, char **specific_object); void (* connection_secrets_updated) (NMDevice *self, @@ -150,6 +151,7 @@ void * nm_device_get_system_config_data (NMDevice *dev); NMActRequest * nm_device_get_act_request (NMDevice *dev); NMConnection * nm_device_get_best_connection (NMDevice *dev, + GSList *connections, char **specific_object); void nm_device_activate_schedule_stage1_device_prepare (NMDevice *device); diff --git a/src/nm-manager.c b/src/nm-manager.c index 0e4db0ec9a..4d998ec3c6 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -658,11 +658,26 @@ manager_device_added (NMManager *manager, NMDevice *device) } static void -manager_device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data) +manager_device_state_changed (NMDeviceInterface *device, NMDeviceState state, gpointer user_data) { NMManager *manager = NM_MANAGER (user_data); nm_manager_update_state (manager); + + if (state == NM_DEVICE_STATE_NEED_AUTH) { + NMActRequest *req; + NMConnection *connection; + + req = nm_device_get_act_request (NM_DEVICE (device)); + /* When device needs an auth it must be activating and thus have an act request. */ + g_assert (req); + connection = nm_act_request_get_connection (req); + + nm_manager_get_connection_secrets (manager, device, + connection, + nm_connection_need_secrets (connection), + TRUE); + } } void diff --git a/src/vpn-manager/nm-vpn-manager.c b/src/vpn-manager/nm-vpn-manager.c index 703f12c0bc..e368c64c45 100644 --- a/src/vpn-manager/nm-vpn-manager.c +++ b/src/vpn-manager/nm-vpn-manager.c @@ -26,6 +26,7 @@ static gboolean impl_vpn_manager_get_connections (NMVPNManager *manager, G_DEFINE_TYPE (NMVPNManager, nm_vpn_manager, G_TYPE_OBJECT) typedef struct { + NMManager *nm_manager; NMDBusManager *dbus_mgr; GSList *services; } NMVPNManagerPrivate; @@ -99,13 +100,10 @@ nm_vpn_manager_connect (NMVPNManager *manager, static NMDevice * find_device (NMVPNManager *manager, const char *device_path) { - NMManager *nm_manager; GSList *devices; GSList *iter; - nm_manager = nm_manager_get (); - devices = nm_manager_get_devices (nm_manager); - g_object_unref (nm_manager); + devices = nm_manager_get_devices (NM_VPN_MANAGER_GET_PRIVATE (manager)->nm_manager); for (iter = devices; iter; iter = iter->next) { NMDevice *device = NM_DEVICE (iter->data); @@ -125,7 +123,6 @@ impl_vpn_manager_connect (NMVPNManager *manager, char **vpn_connection_path, GError **err) { - NMManager *nm_manager; NMDevice *device; NMConnection *connection = NULL; NMVPNConnection *vpn_connection = NULL; @@ -138,18 +135,14 @@ impl_vpn_manager_connect (NMVPNManager *manager, goto out; } - nm_manager = nm_manager_get (); - if (!strcmp (connection_type, NM_DBUS_SERVICE_USER_SETTINGS)) - connection = nm_manager_get_connection_by_object_path (nm_manager, + connection = nm_manager_get_connection_by_object_path (NM_VPN_MANAGER_GET_PRIVATE (manager)->nm_manager, NM_CONNECTION_TYPE_USER, connection_path); else if (!strcmp (connection_type, NM_DBUS_SERVICE_USER_SETTINGS)) - connection = nm_manager_get_connection_by_object_path (nm_manager, + connection = nm_manager_get_connection_by_object_path (NM_VPN_MANAGER_GET_PRIVATE (manager)->nm_manager, NM_CONNECTION_TYPE_SYSTEM, connection_path); - g_object_unref (nm_manager); - if (connection == NULL) { /* FIXME: set error */ goto out; @@ -207,11 +200,15 @@ impl_vpn_manager_get_connections (NMVPNManager *manager, GPtrArray **connections } NMVPNManager * -nm_vpn_manager_new (void) +nm_vpn_manager_new (NMManager *nm_manager) { NMVPNManager *manager; + g_return_val_if_fail (NM_IS_MANAGER (nm_manager), NULL); + manager = (NMVPNManager *) g_object_new (NM_TYPE_VPN_MANAGER, NULL); + if (manager) + NM_VPN_MANAGER_GET_PRIVATE (manager)->nm_manager = g_object_ref (nm_manager); return manager; } @@ -236,6 +233,7 @@ finalize (GObject *object) g_slist_foreach (priv->services, (GFunc) g_object_unref, NULL); g_object_unref (priv->dbus_mgr); + g_object_unref (priv->nm_manager); G_OBJECT_CLASS (nm_vpn_manager_parent_class)->finalize (object); } diff --git a/src/vpn-manager/nm-vpn-manager.h b/src/vpn-manager/nm-vpn-manager.h index f2c76d479a..a5e506c20a 100644 --- a/src/vpn-manager/nm-vpn-manager.h +++ b/src/vpn-manager/nm-vpn-manager.h @@ -5,6 +5,7 @@ #include #include +#include "nm-manager.h" #include "nm-vpn-connection.h" #define NM_TYPE_VPN_MANAGER (nm_vpn_manager_get_type ()) @@ -24,7 +25,7 @@ typedef struct { GType nm_vpn_manager_get_type (void); -NMVPNManager *nm_vpn_manager_new (void); +NMVPNManager *nm_vpn_manager_new (NMManager *nm_manager); NMVPNConnection *nm_vpn_manager_connect (NMVPNManager *manager, NMConnection *connection,