diff --git a/introspection/nm-manager.xml b/introspection/nm-manager.xml
index a93ee5897b..02e8bcf51a 100644
--- a/introspection/nm-manager.xml
+++ b/introspection/nm-manager.xml
@@ -39,12 +39,19 @@
- The device to be activated.
+ The object path of device to be activated for physical connections. This parameter is ignored for VPN connections, because the specific_object (if provided) specifies the device to use.
- The path of a device-type-specific object this activation should use, for example a WiFi access point.
+ The path of a connection-type-specific object this activation should use.
+ This parameter is currently ignored for wired and mobile broadband connections,
+ and the value of "/" should be used (ie, no specific object). For WiFi
+ connections, pass the object path of a specific AP from the card's scan
+ list, or "/" to pick and AP automatically. For VPN connections, pass
+ the object path of an ActiveConnection object that should serve as the
+ "base" connection (to which the VPN connections lifetime will be tied),
+ or pass "/" and NM will automatically use the current default device.
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 51a1e693ff..eb0fd2bfbd 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -1996,6 +1996,7 @@ nm_manager_activate_connection (NMManager *manager,
gboolean user_requested,
GError **error)
{
+ NMManagerPrivate *priv;
NMDevice *device = NULL;
NMSettingConnection *s_con;
NMVPNConnection *vpn_connection;
@@ -2006,26 +2007,47 @@ nm_manager_activate_connection (NMManager *manager,
g_return_val_if_fail (error != NULL, NULL);
g_return_val_if_fail (*error == NULL, NULL);
+ priv = NM_MANAGER_GET_PRIVATE (manager);
+
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
g_assert (s_con);
if (!strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_VPN_SETTING_NAME)) {
- NMActRequest *req;
+ NMActRequest *req = NULL;
NMVPNManager *vpn_manager;
/* VPN connection */
- req = nm_manager_get_act_request_by_path (manager, specific_object, &device);
- if (!req) {
- g_set_error (error,
- NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
- "%s", "Base connection for VPN connection not active.");
- return NULL;
+
+ if (specific_object) {
+ /* Find the specifc connection the client requested we use */
+ req = nm_manager_get_act_request_by_path (manager, specific_object, &device);
+ if (!req) {
+ g_set_error (error,
+ NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
+ "%s", "Base connection for VPN connection not active.");
+ return NULL;
+ }
+ } else {
+ GSList *iter;
+
+ /* Just find the current default connection */
+ for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
+ NMDevice *candidate = NM_DEVICE (iter->data);
+ NMActRequest *candidate_req;
+
+ candidate_req = nm_device_get_act_request (candidate);
+ if (candidate_req && nm_act_request_get_default (candidate_req)) {
+ device = candidate;
+ req = candidate_req;
+ break;
+ }
+ }
}
- if (!device) {
+ if (!device || !req) {
g_set_error (error,
NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
- "%s", "Source connection had no active device.");
+ "%s", "Could not find source connection, or the source connection had no active device.");
return NULL;
}