diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/devices/nm-device.c | 71 | ||||
| -rw-r--r-- | src/core/devices/nm-device.h | 2 | ||||
| -rw-r--r-- | src/core/devices/ovs/nm-device-ovs-port.c | 8 | ||||
| -rw-r--r-- | src/core/devices/wwan/nm-modem-broadband.c | 2 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-utils.c | 2 | ||||
| -rw-r--r-- | src/core/nm-checkpoint.c | 5 | ||||
| -rw-r--r-- | src/core/nm-manager.c | 35 | ||||
| -rw-r--r-- | src/core/ppp/nm-ppp-manager.c | 1 | ||||
| -rw-r--r-- | src/core/settings/nm-settings.c | 28 | ||||
| -rw-r--r-- | src/libnm-core-public/nm-dbus-interface.h | 16 | ||||
| -rw-r--r-- | src/libnm-core-public/nm-dbus-types.xml | 5 | ||||
| -rw-r--r-- | src/libnm-core-public/nm-version-macros.h | 2 |
12 files changed, 149 insertions, 28 deletions
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 35360cee..a11486d5 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -76,6 +76,7 @@ #include "nm-hostname-manager.h" #include "nm-device-generic.h" +#include "nm-device-bridge.h" #include "nm-device-vlan.h" #include "nm-device-vrf.h" #include "nm-device-wireguard.h" @@ -483,9 +484,12 @@ typedef struct _NMDevicePrivate { NMUtilsStableType current_stable_id_type : 3; + bool activation_state_preserve_external_ports : 1; + bool nm_owned : 1; /* whether the device is a device owned and created by NM */ - bool assume_state_guess_assume : 1; + bool assume_state_guess_assume : 1; + char *assume_state_connection_uuid; guint64 udi_id; @@ -7666,8 +7670,19 @@ nm_device_master_release_slaves(NMDevice *self) c_list_for_each_safe (iter, safe, &priv->slaves) { SlaveInfo *info = c_list_entry(iter, SlaveInfo, lst_slave); + if (priv->activation_state_preserve_external_ports + && nm_device_sys_iface_state_is_external(info->slave)) { + _LOGT(LOGD_DEVICE, + "master: preserve external port %s", + nm_device_get_iface(info->slave)); + continue; + } nm_device_master_release_one_slave(self, info->slave, TRUE, FALSE, reason); } + + /* We only need this flag for a short time. It served its purpose. Clear + * it again. */ + nm_device_activation_state_set_preserve_external_ports(self, FALSE); } /** @@ -15386,6 +15401,16 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, if (state > NM_DEVICE_STATE_DISCONNECTED) nm_device_assume_state_reset(self); + if (state < NM_DEVICE_STATE_UNAVAILABLE + || (state >= NM_DEVICE_STATE_IP_CONFIG && state < NM_DEVICE_STATE_ACTIVATED)) { + /* preserve-external-ports is used by NMCheckpoint to activate a master + * device, and preserve already attached ports. This means, this state is only + * relevant during the deactivation and the following activation of the + * right profile. Once we are sufficiently far in the activation of the + * intended profile, we clear the state again. */ + nm_device_activation_state_set_preserve_external_ports(self, FALSE); + } + if (state <= NM_DEVICE_STATE_UNAVAILABLE) { if (available_connections_del_all(self)) _notify(self, PROP_AVAILABLE_CONNECTIONS); @@ -15791,6 +15816,50 @@ nm_device_get_state(NMDevice *self) } /*****************************************************************************/ + +/** + * nm_device_activation_state_set_preserve_external_ports: + * @self: the NMDevice. + * @flag: whether to set or clear the the flag. + * + * This sets an internal flag to true, which does something specific. + * For non-master devices, it has no effect. For master devices, this + * will prevent to detach all external ports, until the next activation + * completes. + * + * This is used during checkpoint/rollback. We may want to preserve + * externally attached ports during the restore. NMCheckpoint will + * call this before doing a re-activation. By setting the flag, + * we basically preserve such ports. + * + * Once we reach again ACTIVATED state, the flag gets cleared. This + * only has effect for the next activation cycle. */ +void +nm_device_activation_state_set_preserve_external_ports(NMDevice *self, gboolean flag) +{ + NMDevicePrivate *priv; + + g_return_if_fail(NM_IS_DEVICE(self)); + + priv = NM_DEVICE_GET_PRIVATE(self); + + if (!NM_IS_DEVICE_BRIDGE(self)) { + /* This is actually only implemented for bridge devices. While it might + * make sense for bond/team or OVS, it's not clear that it is actually + * useful or desirable. */ + return; + } + + if (priv->activation_state_preserve_external_ports == flag) + return; + + priv->activation_state_preserve_external_ports = flag; + _LOGD(LOGD_DEVICE, + "activation-state: preserve-external-ports %s", + flag ? "enabled" : "disabled"); +} + +/*****************************************************************************/ /* NMConfigDevice interface related stuff */ const char * diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h index cfcd4ade..a7badb86 100644 --- a/src/core/devices/nm-device.h +++ b/src/core/devices/nm-device.h @@ -444,6 +444,8 @@ NMDeviceType nm_device_get_device_type(NMDevice *dev); NMLinkType nm_device_get_link_type(NMDevice *dev); NMMetered nm_device_get_metered(NMDevice *dev); +void nm_device_activation_state_set_preserve_external_ports(NMDevice *self, gboolean flag); + guint32 nm_device_get_route_table(NMDevice *self, int addr_family); guint32 nm_device_get_route_metric(NMDevice *dev, int addr_family); diff --git a/src/core/devices/ovs/nm-device-ovs-port.c b/src/core/devices/ovs/nm-device-ovs-port.c index 8406c364..116f58c4 100644 --- a/src/core/devices/ovs/nm-device-ovs-port.c +++ b/src/core/devices/ovs/nm-device-ovs-port.c @@ -188,8 +188,10 @@ del_iface_cb(GError *error, gpointer user_data) static void release_slave(NMDevice *device, NMDevice *slave, gboolean configure) { - NMDeviceOvsPort *self = NM_DEVICE_OVS_PORT(device); - bool slave_removed = nm_device_sys_iface_state_get(slave) == NM_DEVICE_SYS_IFACE_STATE_REMOVED; + NMDeviceOvsPort *self = NM_DEVICE_OVS_PORT(device); + bool slave_not_managed = !NM_IN_SET(nm_device_sys_iface_state_get(slave), + NM_DEVICE_SYS_IFACE_STATE_MANAGED, + NM_DEVICE_SYS_IFACE_STATE_ASSUME); _LOGI(LOGD_DEVICE, "releasing ovs interface %s", nm_device_get_ip_iface(slave)); @@ -197,7 +199,7 @@ release_slave(NMDevice *device, NMDevice *slave, gboolean configure) * removed and thus we're called with configure=FALSE), we still need * to make sure its OVSDB entry is gone. */ - if (configure || slave_removed) { + if (configure || slave_not_managed) { nm_ovsdb_del_interface(nm_ovsdb_get(), nm_device_get_iface(slave), del_iface_cb, diff --git a/src/core/devices/wwan/nm-modem-broadband.c b/src/core/devices/wwan/nm-modem-broadband.c index f5336d37..b585652e 100644 --- a/src/core/devices/wwan/nm-modem-broadband.c +++ b/src/core/devices/wwan/nm-modem-broadband.c @@ -1032,6 +1032,7 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho l3cd = nm_l3_config_data_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), ifindex, NM_IP_CONFIG_SOURCE_WWAN); + nm_l3_config_data_set_dns_priority(l3cd, AF_INET, 0); address = (NMPlatformIP4Address){ .address = address_network, @@ -1118,6 +1119,7 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho l3cd = nm_l3_config_data_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), ifindex, NM_IP_CONFIG_SOURCE_WWAN); + nm_l3_config_data_set_dns_priority(l3cd, AF_INET6, 0); do_auto = TRUE; diff --git a/src/core/dhcp/nm-dhcp-utils.c b/src/core/dhcp/nm-dhcp-utils.c index 4a138086..214e94cd 100644 --- a/src/core/dhcp/nm-dhcp-utils.c +++ b/src/core/dhcp/nm-dhcp-utils.c @@ -876,7 +876,7 @@ nm_dhcp_utils_merge_new_dhcp6_lease(const NML3ConfigData *l3cd_old, * addresses from the same transaction into a single configuration. **/ - l3cd_merged = nm_l3_config_data_new_clone(l3cd_old, -1); + l3cd_merged = nm_l3_config_data_new_clone(l3cd_old, 0); nm_l3_config_data_iter_ip6_address_for_each (&iter, l3cd_new, &addr) nm_l3_config_data_add_address_6(l3cd_merged, addr); diff --git a/src/core/nm-checkpoint.c b/src/core/nm-checkpoint.c index 0153af97..5b48f91a 100644 --- a/src/core/nm-checkpoint.c +++ b/src/core/nm-checkpoint.c @@ -282,6 +282,11 @@ restore_and_activate_connection(NMCheckpoint *self, DeviceCheckpoint *dev_checkp * an internal subject. */ if (nm_device_get_state(dev_checkpoint->device) > NM_DEVICE_STATE_DISCONNECTED && nm_device_get_state(dev_checkpoint->device) < NM_DEVICE_STATE_DEACTIVATING) { + if (!NM_FLAGS_HAS(priv->flags, NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS)) { + nm_device_activation_state_set_preserve_external_ports(dev_checkpoint->device, + TRUE); + } + nm_device_state_changed(dev_checkpoint->device, NM_DEVICE_STATE_DEACTIVATING, NM_DEVICE_STATE_REASON_NEW_ACTIVATION); diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c index b440b224..6c73d237 100644 --- a/src/core/nm-manager.c +++ b/src/core/nm-manager.c @@ -7453,15 +7453,31 @@ impl_manager_checkpoint_create(NMDBusObject *obj, GDBusMethodInvocation *invocation, GVariant *parameters) { - NMManager *self = NM_MANAGER(obj); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self); - NMAuthChain *chain; - char **devices; - guint32 rollback_timeout; - guint32 flags; + NMManager *self = NM_MANAGER(obj); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self); + NMAuthChain *chain; + gs_strfreev char **devices = NULL; + guint32 rollback_timeout; + guint32 flags; G_STATIC_ASSERT_EXPR(sizeof(flags) <= sizeof(NMCheckpointCreateFlags)); + g_variant_get(parameters, "(^aouu)", &devices, &rollback_timeout, &flags); + + if ((NMCheckpointCreateFlags) flags != flags + || NM_FLAGS_ANY(flags, + ~((guint32) (NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL + | NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS + | NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES + | NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING + | NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS)))) { + g_dbus_method_invocation_return_error_literal(invocation, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_INVALID_ARGUMENTS, + "Invalid flags"); + return; + } + chain = nm_auth_chain_new_context(invocation, checkpoint_auth_done_cb, self); if (!chain) { g_dbus_method_invocation_return_error_literal(invocation, @@ -7471,11 +7487,12 @@ impl_manager_checkpoint_create(NMDBusObject *obj, return; } - g_variant_get(parameters, "(^aouu)", &devices, &rollback_timeout, &flags); - c_list_link_tail(&priv->auth_lst_head, nm_auth_chain_parent_lst_list(chain)); nm_auth_chain_set_data(chain, "audit-op", NM_AUDIT_OP_CHECKPOINT_CREATE, NULL); - nm_auth_chain_set_data(chain, "devices", devices, (GDestroyNotify) g_strfreev); + nm_auth_chain_set_data(chain, + "devices", + g_steal_pointer(&devices), + (GDestroyNotify) g_strfreev); nm_auth_chain_set_data(chain, "flags", GUINT_TO_POINTER(flags), NULL); nm_auth_chain_set_data(chain, "timeout", GUINT_TO_POINTER(rollback_timeout), NULL); nm_auth_chain_add_call(chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, TRUE); diff --git a/src/core/ppp/nm-ppp-manager.c b/src/core/ppp/nm-ppp-manager.c index dd6b1bc7..5761d59d 100644 --- a/src/core/ppp/nm-ppp-manager.c +++ b/src/core/ppp/nm-ppp-manager.c @@ -545,6 +545,7 @@ impl_ppp_manager_set_ip4_config(NMDBusObject *obj, NM_IP_CONFIG_SOURCE_PPP); nm_l3_config_data_set_mtu(l3cd, mtu); + nm_l3_config_data_set_dns_priority(l3cd, AF_INET, 0); address = (NMPlatformIP4Address){ .plen = 32, diff --git a/src/core/settings/nm-settings.c b/src/core/settings/nm-settings.c index da09571b..6619d3e0 100644 --- a/src/core/settings/nm-settings.c +++ b/src/core/settings/nm-settings.c @@ -3266,7 +3266,7 @@ add_plugin(NMSettings *self, NMSettingsPlugin *plugin, const char *pname, const } static gboolean -add_plugin_load_file(NMSettings *self, const char *pname, GError **error) +add_plugin_load_file(NMSettings *self, const char *pname, gboolean ignore_not_found, GError **error) { gs_free char *full_name = NULL; gs_free char *path = NULL; @@ -3281,10 +3281,12 @@ add_plugin_load_file(NMSettings *self, const char *pname, GError **error) if (stat(path, &st) != 0) { errsv = errno; - _LOGW("could not load plugin '%s' from file '%s': %s", - pname, - path, - nm_strerror_native(errsv)); + if (!ignore_not_found) { + _LOGW("could not load plugin '%s' from file '%s': %s", + pname, + path, + nm_strerror_native(errsv)); + } return TRUE; } if (!S_ISREG(st.st_mode)) { @@ -3378,7 +3380,7 @@ load_plugins(NMSettings *self, const char *const *plugins, GError **error) continue; } - success = add_plugin_load_file(self, pname, error); + success = add_plugin_load_file(self, pname, FALSE, error); if (!success) break; } @@ -3872,8 +3874,18 @@ nm_settings_start(NMSettings *self, GError **error) /* Load the plugins; fail if a plugin is not found. */ plugins = nm_config_data_get_plugins(nm_config_get_data_orig(priv->config), TRUE); - if (!load_plugins(self, (const char *const *) plugins, error)) - return FALSE; + if (plugins && plugins[0]) { + if (!load_plugins(self, (const char *const *) plugins, error)) + return FALSE; + } else { + add_plugin_keyfile(self); +#if WITH_CONFIG_PLUGIN_IFCFG_RH + add_plugin_load_file(self, "ifcfg-rh", TRUE, NULL); +#endif +#if WITH_CONFIG_PLUGIN_IFUPDOWN + add_plugin_load_file(self, "ifupdown", TRUE, NULL); +#endif + } for (iter = priv->plugins; iter; iter = iter->next) { NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN(iter->data); diff --git a/src/libnm-core-public/nm-dbus-interface.h b/src/libnm-core-public/nm-dbus-interface.h index fe2a6c09..0d23c7d7 100644 --- a/src/libnm-core-public/nm-dbus-interface.h +++ b/src/libnm-core-public/nm-dbus-interface.h @@ -959,17 +959,23 @@ typedef enum { * overlapping younger checkpoints. This opts-in that the * checkpoint can be automatically destroyed by the rollback * of an older checkpoint. Since: 1.12. + * @NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS: during rollback, + * by default externally added ports attached to bridge devices are preserved. + * With this flag, the rollback detaches all external ports. + * This only has an effect for bridge ports. Before 1.38, 1.36.2, this was the default + * behavior. Since: 1.38, 1.36.2. * * The flags for CheckpointCreate call * * Since: 1.4 (gi flags generated since 1.12) */ typedef enum { /*< flags >*/ - NM_CHECKPOINT_CREATE_FLAG_NONE = 0, - NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL = 0x01, - NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS = 0x02, - NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES = 0x04, - NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING = 0x08, + NM_CHECKPOINT_CREATE_FLAG_NONE = 0, + NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL = 0x01, + NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS = 0x02, + NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES = 0x04, + NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING = 0x08, + NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS = 0x10, } NMCheckpointCreateFlags; /** diff --git a/src/libnm-core-public/nm-dbus-types.xml b/src/libnm-core-public/nm-dbus-types.xml index fa5b175b..653859e6 100644 --- a/src/libnm-core-public/nm-dbus-types.xml +++ b/src/libnm-core-public/nm-dbus-types.xml @@ -1647,6 +1647,11 @@ <entry role="enum_member_value"><para>= <literal>0x08</literal></para><para></para></entry> <entry role="enum_member_description"><para>by default, creating a checkpoint fails if there are already existing checkoints that reference the same devices. With this flag, creation of such checkpoints is allowed, however, if an older checkpoint that references overlapping devices gets rolled back, it will automatically destroy this checkpoint during rollback. This allows to create several overlapping checkpoints in parallel, and rollback to them at will. With the special case that rolling back to an older checkpoint will invalidate all overlapping younger checkpoints. This opts-in that the checkpoint can be automatically destroyed by the rollback of an older checkpoint. Since: 1.12.</para><para></para></entry> </row> + <row role="constant"> + <entry role="enum_member_name"><para>NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS</para><para></para></entry> + <entry role="enum_member_value"><para>= <literal>0x10</literal></para><para></para></entry> + <entry role="enum_member_description"><para>during rollback, by default externally added ports attached to bridge devices are preserved. With this flag, the rollback detaches all external ports. This only has an effect for bridge ports. Before 1.38, 1.36.2, this was the default behavior. Since: 1.38, 1.36.2.</para><para></para></entry> + </row> </tbody> </tgroup> </informaltable> diff --git a/src/libnm-core-public/nm-version-macros.h b/src/libnm-core-public/nm-version-macros.h index 7e9ff61b..8cb7ef49 100644 --- a/src/libnm-core-public/nm-version-macros.h +++ b/src/libnm-core-public/nm-version-macros.h @@ -30,7 +30,7 @@ * Evaluates to the micro version number of NetworkManager which this source * compiled against. */ -#define NM_MICRO_VERSION (0) +#define NM_MICRO_VERSION (2) /** * NM_CHECK_VERSION: |