diff options
Diffstat (limited to 'src/core')
| -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 |
9 files changed, 132 insertions, 22 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); |