core: handle explicit device creation on connection activation

If the connection describing the virtual device isn't set to
autoconnect, the device may not yet have been created.  In that
case, create it.
This commit is contained in:
Dan Williams 2012-02-12 16:13:17 -06:00
parent b35afe4d0f
commit fdd44b8e00

View file

@ -2432,22 +2432,71 @@ nm_manager_activate_connection (NMManager *manager,
path = nm_active_connection_get_path (NM_ACTIVE_CONNECTION (vpn_connection));
} else {
NMDeviceState state;
char *iface;
int master_ifindex = -1;
/* Device-based connection */
device = nm_manager_get_device_by_path (manager, device_path);
if (!device) {
g_set_error (error,
NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
"%s", "Device not found");
return NULL;
}
if (device_path) {
device = nm_manager_get_device_by_path (manager, device_path);
if (!device) {
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
"Device not found");
return NULL;
}
state = nm_device_get_state (device);
if (state < NM_DEVICE_STATE_DISCONNECTED) {
g_set_error (error,
NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNMANAGED_DEVICE,
"%s", "Device not managed by NetworkManager or unavailable");
return NULL;
/* If it's a virtual interface make sure the device given by the
* path matches the connection's interface details.
*/
if (connection_needs_virtual_device (connection)) {
iface = get_virtual_iface_name (manager, connection, NULL);
if (!iface) {
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
"Failed to determine connection's virtual interface name");
return NULL;
} else if (g_strcmp0 (iface, nm_device_get_ip_iface (device)) != 0) {
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
"Device given by path did not match connection's virtual interface name");
g_free (iface);
return NULL;
}
g_free (iface);
}
state = nm_device_get_state (device);
if (state < NM_DEVICE_STATE_DISCONNECTED) {
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNMANAGED_DEVICE,
"Device not managed by NetworkManager or unavailable");
return NULL;
}
} else {
/* Virtual connections (VLAN, bond, etc) may not specify a device
* path because the device may not be created yet, or it be given
* by the connection's properties instead. Find the device the
* connection refers to, or create it if needed.
*/
if (!connection_needs_virtual_device (connection)) {
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
"This connection requires an existing device.");
return NULL;
}
iface = get_virtual_iface_name (manager, connection, &master_ifindex);
if (!iface) {
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
"Failed to determine connection's virtual interface name");
return NULL;
}
device = find_device_by_ip_iface (manager, iface);
if (!device) {
/* Create it */
device = system_create_virtual_device (manager, connection);
if (!device) {
g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
"Failed to create virtual interface");
return NULL;
}
}
}
path = internal_activate_device (manager,