core: add 'keep-configuration' device configuration option

Add a new 'keep-configuration' device option, set to 'yes' by
default. When set to 'no', on startup NetworkManager ignores that the
interface is pre-configured and doesn't try to keep its
configuration. Instead, it activates one of the persistent
connections.
This commit is contained in:
Beniamino Galvani 2021-05-07 13:57:04 +02:00
parent b1644fa826
commit df2fe15714
4 changed files with 74 additions and 21 deletions

View file

@ -1150,6 +1150,44 @@ managed=1
</para>
</listitem>
</varlistentry>
<varlistentry id="keep-configuration">
<term><varname>keep-configuration</varname></term>
<listitem>
<para>
On startup, NetworkManager tries to not interfere with
interfaces that are already configured. It does so by
generating a in-memory connection based on the interface
current configuration.
</para>
<para>
If this generated connection matches one of the existing
persistent connections, the persistent connection gets
activated. If there is no match, the generated
connection gets activated as "external", which means
that the connection is considered as active, but
NetworkManager doesn't actually touch the interface.
</para>
<para>
It is possible to disable this behavior by setting
<literal>keep-configuration</literal> to
<literal>no</literal>. In this way, on startup
NetworkManager always tries to activate the most
suitable persistent connection (the one with highest
autoconnect-priority or, in case of a tie, the one
activated most recently).
</para>
<para>
Note that when NetworkManager gets restarted, it stores
the previous state in
<filename>/run/NetworkManager</filename>; in particular
it saves the UUID of the connection that was previously
active so that it can be activated again after the
restart. Therefore,
<literal>keep-configuration</literal> does not have
any effect on service restart.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>wifi.scan-rand-mac-address</varname></term>
<listitem>

View file

@ -878,6 +878,7 @@ static const ConfigGroup config_groups[] = {
NM_CONFIG_KEYFILE_KEY_DEVICE_IGNORE_CARRIER,
NM_CONFIG_KEYFILE_KEY_DEVICE_MANAGED,
NM_CONFIG_KEYFILE_KEY_DEVICE_SRIOV_NUM_VFS,
NM_CONFIG_KEYFILE_KEY_DEVICE_KEEP_CONFIGURATION,
NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_BACKEND,
NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_SCAN_RAND_MAC_ADDRESS,
NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_SCAN_GENERATE_MAC_ADDRESS_MASK,

View file

@ -2632,28 +2632,41 @@ get_existing_connection(NMManager *self, NMDevice *device, gboolean *out_generat
}
}
/* The core of the API is nm_device_generate_connection() function, based on
* update_connection() virtual method and the @connection_type_supported
* class attribute. Devices that support assuming existing connections must
* have update_connection() implemented, otherwise
* nm_device_generate_connection() returns NULL. */
connection = nm_device_generate_connection(device, master, &maybe_later, &gen_error);
if (!connection) {
if (maybe_later) {
/* The device can potentially assume connections, but at this
* time there are no addresses configured and we can't generate
* a connection. Allow the device to assume a connection indicated
* in the state file by UUID. */
only_by_uuid = TRUE;
} else {
/* The device can't assume connections */
nm_device_assume_state_reset(device);
_LOG2D(LOGD_DEVICE,
device,
"assume: cannot generate connection: %s",
gen_error->message);
return NULL;
if (nm_config_data_get_device_config_boolean(NM_CONFIG_GET_DATA,
NM_CONFIG_KEYFILE_KEY_DEVICE_KEEP_CONFIGURATION,
device,
TRUE,
TRUE)) {
/* The core of the API is nm_device_generate_connection() function, based on
* update_connection() virtual method and the @connection_type_supported
* class attribute. Devices that support assuming existing connections must
* have update_connection() implemented, otherwise
* nm_device_generate_connection() returns NULL. */
connection = nm_device_generate_connection(device, master, &maybe_later, &gen_error);
if (!connection) {
if (maybe_later) {
/* The device can potentially assume connections, but at this
* time we can't generate a connection because no address is
* configured. Allow the device to assume a connection indicated
* in the state file by UUID. */
only_by_uuid = TRUE;
} else {
nm_device_assume_state_reset(device);
_LOG2D(LOGD_DEVICE,
device,
"assume: cannot generate connection: %s",
gen_error->message);
return NULL;
}
}
} else {
connection = NULL;
only_by_uuid = TRUE;
g_set_error(&gen_error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_FAILED,
"device %s has 'keep-configuration=no'",
nm_device_get_iface(device));
}
nm_device_assume_state_get(device, &assume_state_guess_assume, &assume_state_connection_uuid);

View file

@ -62,6 +62,7 @@
#define NM_CONFIG_KEYFILE_KEY_DEVICE_MANAGED "managed"
#define NM_CONFIG_KEYFILE_KEY_DEVICE_IGNORE_CARRIER "ignore-carrier"
#define NM_CONFIG_KEYFILE_KEY_DEVICE_SRIOV_NUM_VFS "sriov-num-vfs"
#define NM_CONFIG_KEYFILE_KEY_DEVICE_KEEP_CONFIGURATION "keep-configuration"
#define NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_BACKEND "wifi.backend"
#define NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_SCAN_RAND_MAC_ADDRESS "wifi.scan-rand-mac-address"
#define NM_CONFIG_KEYFILE_KEY_DEVICE_WIFI_SCAN_GENERATE_MAC_ADDRESS_MASK \