mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-02 03:00:37 +01:00
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:
parent
b35afe4d0f
commit
fdd44b8e00
1 changed files with 62 additions and 13 deletions
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue