about summary refs log tree commit diff
path: root/src/core
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2024-09-01 22:38:35 +0200
committerMichael Biebl <biebl@debian.org>2024-09-01 22:38:35 +0200
commitf9bfd1158b8d08d6a5ed3bb7cc1ba7a6455e5201 (patch)
tree10267dcf5b842b7c638a79bd6851549cd849b81d /src/core
parent681dfc70ef98f6ed0c05bcb0fbff00e3fc0799ea (diff)
New upstream version 1.49.90 upstream/1.49.90
Diffstat (limited to 'src/core')
-rw-r--r--src/core/devices/nm-device-bond.c4
-rw-r--r--src/core/devices/nm-device-bridge.c2
-rw-r--r--src/core/devices/nm-device-ethernet.c4
-rw-r--r--src/core/devices/nm-device-utils.c13
-rw-r--r--src/core/devices/nm-device-utils.h12
-rw-r--r--src/core/devices/nm-device-vlan.c2
-rw-r--r--src/core/devices/nm-device-wireguard.c19
-rw-r--r--src/core/devices/nm-device.c231
-rw-r--r--src/core/devices/nm-device.h10
-rw-r--r--src/core/devices/ovs/nm-device-ovs-port.c6
-rw-r--r--src/core/devices/team/nm-device-team.c6
-rw-r--r--src/core/devices/wifi/nm-device-iwd.c4
-rw-r--r--src/core/devices/wifi/nm-device-wifi-p2p.c50
-rw-r--r--src/core/dhcp/nm-dhcp-listener.c12
-rw-r--r--src/core/dhcp/nm-dhcp-manager.c11
-rw-r--r--src/core/ndisc/nm-ndisc.c1
-rw-r--r--src/core/nm-active-connection.c8
-rw-r--r--src/core/nm-config-data.c33
-rw-r--r--src/core/nm-config-data.h2
-rw-r--r--src/core/nm-config.c1
-rw-r--r--src/core/nm-config.h1
-rw-r--r--src/core/nm-connectivity.c10
-rw-r--r--src/core/nm-core-utils.c4
-rw-r--r--src/core/nm-l3cfg.h2
-rw-r--r--src/core/nm-manager.c28
-rw-r--r--src/core/nm-policy.c14
-rw-r--r--src/core/settings/nm-settings.c2
-rw-r--r--src/core/supplicant/nm-supplicant-config.c84
-rw-r--r--src/core/supplicant/nm-supplicant-settings-verify.c3
-rw-r--r--src/core/tests/config/NetworkManager.conf1
-rw-r--r--src/core/tests/config/test-config.c3
31 files changed, 376 insertions, 207 deletions
diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c
index 06a02d1a..b60dd3f1 100644
--- a/src/core/devices/nm-device-bond.c
+++ b/src/core/devices/nm-device-bond.c
@@ -608,12 +608,12 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
     s_bond = nm_connection_get_setting_bond(connection);
     g_return_val_if_fail(s_bond, NM_ACT_STAGE_RETURN_FAILURE);
 
-    if (nm_device_sys_iface_state_is_external(device))
+    if (nm_device_managed_type_is_external(device))
         return NM_ACT_STAGE_RETURN_SUCCESS;
 
     _balance_slb_setup(self, connection);
 
-    if (nm_device_sys_iface_state_is_external_or_assume(device))
+    if (nm_device_managed_type_is_external_or_assume(device))
         return NM_ACT_STAGE_RETURN_SUCCESS;
 
     _platform_lnk_bond_init_from_setting(s_bond, &props);
diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c
index 7a496d96..a237c0b7 100644
--- a/src/core/devices/nm-device-bridge.c
+++ b/src/core/devices/nm-device-bridge.c
@@ -1049,7 +1049,7 @@ attach_port(NMDevice                  *device,
         nm_assert(s_bridge);
         s_port = nm_connection_get_setting_bridge_port(connection);
 
-        if (!nm_device_sys_iface_state_is_external(device))
+        if (!nm_device_managed_type_is_external(device))
             bridge_set_vlan_options(device, s_bridge, FALSE);
 
         if (nm_setting_bridge_get_vlan_filtering(s_bridge)) {
diff --git a/src/core/devices/nm-device-ethernet.c b/src/core/devices/nm-device-ethernet.c
index 8c2a9643..16992524 100644
--- a/src/core/devices/nm-device-ethernet.c
+++ b/src/core/devices/nm-device-ethernet.c
@@ -988,8 +988,8 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
     NMDeviceEthernet        *self = NM_DEVICE_ETHERNET(device);
     NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
 
-    if (nm_device_sys_iface_state_is_external_or_assume(device)) {
-        if (!priv->ethtool_prev_set && !nm_device_sys_iface_state_is_external(device)) {
+    if (nm_device_managed_type_is_external_or_assume(device)) {
+        if (!priv->ethtool_prev_set && !nm_device_managed_type_is_external(device)) {
             NMSettingWired *s_wired;
 
             /* During restart of NetworkManager service we forget the original auto
diff --git a/src/core/devices/nm-device-utils.c b/src/core/devices/nm-device-utils.c
index 4597ba85..ccb6292b 100644
--- a/src/core/devices/nm-device-utils.c
+++ b/src/core/devices/nm-device-utils.c
@@ -152,14 +152,13 @@ NM_UTILS_LOOKUP_STR_DEFINE(nm_device_mtu_source_to_string,
                            NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_CONNECTION,
                                                     "connection"), );
 
-NM_UTILS_LOOKUP_STR_DEFINE(nm_device_sys_iface_state_to_string,
-                           NMDeviceSysIfaceState,
+NM_UTILS_LOOKUP_STR_DEFINE(nm_device_managed_type_to_string,
+                           NMDeviceManagedType,
                            NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT("unknown"),
-                           NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, "external"),
-                           NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_ASSUME, "assume"),
-                           NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_MANAGED, "managed"),
-                           NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_REMOVED,
-                                                    "removed"), );
+                           NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MANAGED_TYPE_EXTERNAL, "external"),
+                           NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MANAGED_TYPE_ASSUME, "assume"),
+                           NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MANAGED_TYPE_FULL, "full"),
+                           NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MANAGED_TYPE_REMOVED, "removed"), );
 
 NM_UTILS_LOOKUP_STR_DEFINE(nm_device_ip_state_to_string,
                            NMDeviceIPState,
diff --git a/src/core/devices/nm-device-utils.h b/src/core/devices/nm-device-utils.h
index 7b879c90..e9e3b52f 100644
--- a/src/core/devices/nm-device-utils.h
+++ b/src/core/devices/nm-device-utils.h
@@ -57,19 +57,19 @@ const char *nm_device_mtu_source_to_string(NMDeviceMtuSource mtu_source);
 /*****************************************************************************/
 
 typedef enum _nm_packed {
-    NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
-    NM_DEVICE_SYS_IFACE_STATE_ASSUME,
-    NM_DEVICE_SYS_IFACE_STATE_MANAGED,
+    NM_DEVICE_MANAGED_TYPE_EXTERNAL,
+    NM_DEVICE_MANAGED_TYPE_ASSUME,
+    NM_DEVICE_MANAGED_TYPE_FULL,
 
     /* the REMOVED state applies when the device is manually set to unmanaged
      * or the link was externally removed. In both cases, we move the device
      * to UNMANAGED state, without touching the link -- be it, because the link
      * is already gone or because we want to release it (give it up).
      */
-    NM_DEVICE_SYS_IFACE_STATE_REMOVED,
-} NMDeviceSysIfaceState;
+    NM_DEVICE_MANAGED_TYPE_REMOVED,
+} NMDeviceManagedType;
 
-const char *nm_device_sys_iface_state_to_string(NMDeviceSysIfaceState sys_iface_state);
+const char *nm_device_managed_type_to_string(NMDeviceManagedType managed_type);
 
 /*****************************************************************************/
 
diff --git a/src/core/devices/nm-device-vlan.c b/src/core/devices/nm-device-vlan.c
index cc649ec9..d4630999 100644
--- a/src/core/devices/nm-device-vlan.c
+++ b/src/core/devices/nm-device-vlan.c
@@ -72,7 +72,7 @@ parent_hwaddr_maybe_changed(NMDevice *parent, GParamSpec *pspec, gpointer user_d
     const char   *new_mac;
 
     /* Never touch assumed devices */
-    if (nm_device_sys_iface_state_is_external_or_assume(device))
+    if (nm_device_managed_type_is_external_or_assume(device))
         return;
 
     connection = nm_device_get_applied_connection(device);
diff --git a/src/core/devices/nm-device-wireguard.c b/src/core/devices/nm-device-wireguard.c
index dd40d11e..00a8c718 100644
--- a/src/core/devices/nm-device-wireguard.c
+++ b/src/core/devices/nm-device-wireguard.c
@@ -1586,26 +1586,25 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
 {
     NMDeviceWireGuard        *self = NM_DEVICE_WIREGUARD(device);
     NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(self);
-    NMDeviceSysIfaceState     sys_iface_state;
+    NMDeviceManagedType       managed_type;
     NMDeviceStateReason       failure_reason;
     NMActStageReturn          ret;
 
-    sys_iface_state = nm_device_sys_iface_state_get(device);
+    managed_type = nm_device_managed_type_get(device);
 
-    if (sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_EXTERNAL) {
+    if (managed_type == NM_DEVICE_MANAGED_TYPE_EXTERNAL) {
         NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_NONE);
         return NM_ACT_STAGE_RETURN_SUCCESS;
     }
 
-    ret =
-        link_config(NM_DEVICE_WIREGUARD(device),
-                    "configure",
-                    (sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_ASSUME) ? LINK_CONFIG_MODE_ASSUME
-                                                                          : LINK_CONFIG_MODE_FULL,
-                    &failure_reason);
+    ret = link_config(NM_DEVICE_WIREGUARD(device),
+                      "configure",
+                      (managed_type == NM_DEVICE_MANAGED_TYPE_ASSUME) ? LINK_CONFIG_MODE_ASSUME
+                                                                      : LINK_CONFIG_MODE_FULL,
+                      &failure_reason);
 
     if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
-        if (sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_ASSUME) {
+        if (managed_type == NM_DEVICE_MANAGED_TYPE_ASSUME) {
             /* this never fails. */
             return NM_ACT_STAGE_RETURN_SUCCESS;
         }
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index 799aca04..66eba209 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -571,11 +571,11 @@ typedef struct _NMDevicePrivate {
     };
 
     union {
-        const NMDeviceSysIfaceState sys_iface_state;
-        NMDeviceSysIfaceState       sys_iface_state_;
+        const NMDeviceManagedType managed_type;
+        NMDeviceManagedType       managed_type_;
     };
 
-    NMDeviceSysIfaceState sys_iface_state_before_sleep;
+    NMDeviceManagedType managed_type_before_sleep;
 
     bool carrier : 1;
     bool ignore_carrier : 1;
@@ -3357,47 +3357,47 @@ nm_device_create_l3_config_data_from_connection(NMDevice *self, NMConnection *co
 
 /*****************************************************************************/
 
-NMDeviceSysIfaceState
-nm_device_sys_iface_state_get(NMDevice *self)
+NMDeviceManagedType
+nm_device_managed_type_get(NMDevice *self)
 {
-    g_return_val_if_fail(NM_IS_DEVICE(self), NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
+    g_return_val_if_fail(NM_IS_DEVICE(self), NM_DEVICE_MANAGED_TYPE_EXTERNAL);
 
-    return NM_DEVICE_GET_PRIVATE(self)->sys_iface_state;
+    return NM_DEVICE_GET_PRIVATE(self)->managed_type;
 }
 
 gboolean
-nm_device_sys_iface_state_is_external(NMDevice *self)
+nm_device_managed_type_is_external(NMDevice *self)
 {
-    return NM_IN_SET(nm_device_sys_iface_state_get(self), NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
+    return NM_IN_SET(nm_device_managed_type_get(self), NM_DEVICE_MANAGED_TYPE_EXTERNAL);
 }
 
 gboolean
-nm_device_sys_iface_state_is_external_or_assume(NMDevice *self)
+nm_device_managed_type_is_external_or_assume(NMDevice *self)
 {
-    return NM_IN_SET(nm_device_sys_iface_state_get(self),
-                     NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
-                     NM_DEVICE_SYS_IFACE_STATE_ASSUME);
+    return NM_IN_SET(nm_device_managed_type_get(self),
+                     NM_DEVICE_MANAGED_TYPE_EXTERNAL,
+                     NM_DEVICE_MANAGED_TYPE_ASSUME);
 }
 
 void
-nm_device_sys_iface_state_set(NMDevice *self, NMDeviceSysIfaceState sys_iface_state)
+nm_device_managed_type_set(NMDevice *self, NMDeviceManagedType managed_type)
 {
     NMDevicePrivate *priv;
 
     g_return_if_fail(NM_IS_DEVICE(self));
-    g_return_if_fail(NM_IN_SET(sys_iface_state,
-                               NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
-                               NM_DEVICE_SYS_IFACE_STATE_ASSUME,
-                               NM_DEVICE_SYS_IFACE_STATE_MANAGED,
-                               NM_DEVICE_SYS_IFACE_STATE_REMOVED));
+    g_return_if_fail(NM_IN_SET(managed_type,
+                               NM_DEVICE_MANAGED_TYPE_EXTERNAL,
+                               NM_DEVICE_MANAGED_TYPE_ASSUME,
+                               NM_DEVICE_MANAGED_TYPE_FULL,
+                               NM_DEVICE_MANAGED_TYPE_REMOVED));
 
     priv = NM_DEVICE_GET_PRIVATE(self);
-    if (priv->sys_iface_state != sys_iface_state) {
+    if (priv->managed_type != managed_type) {
         _LOGT(LOGD_DEVICE,
-              "sys-iface-state: %s -> %s",
-              nm_device_sys_iface_state_to_string(priv->sys_iface_state),
-              nm_device_sys_iface_state_to_string(sys_iface_state));
-        priv->sys_iface_state_ = sys_iface_state;
+              "managed-type: %s -> %s",
+              nm_device_managed_type_to_string(priv->managed_type),
+              nm_device_managed_type_to_string(managed_type));
+        priv->managed_type_ = managed_type;
         _dev_l3_cfg_commit_type_reset(self);
         nm_device_l3cfg_commit(self, NM_L3_CFG_COMMIT_TYPE_AUTO, FALSE);
     }
@@ -3406,7 +3406,7 @@ nm_device_sys_iface_state_set(NMDevice *self, NMDeviceSysIfaceState sys_iface_st
      *
      * If you change this, make sure that all callers are fine with such actions. */
 
-    nm_assert(priv->sys_iface_state == sys_iface_state);
+    nm_assert(priv->managed_type == managed_type);
 }
 
 void
@@ -3414,15 +3414,15 @@ nm_device_notify_sleeping(NMDevice *self)
 {
     NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
 
-    priv->sys_iface_state_before_sleep = priv->sys_iface_state;
+    priv->managed_type_before_sleep = priv->managed_type;
 }
 
-NMDeviceSysIfaceState
-nm_device_get_sys_iface_state_before_sleep(NMDevice *self)
+NMDeviceManagedType
+nm_device_get_managed_type_before_sleep(NMDevice *self)
 {
     NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
 
-    return priv->sys_iface_state_before_sleep;
+    return priv->managed_type_before_sleep;
 }
 
 static void
@@ -3820,7 +3820,7 @@ _dev_ip_state_check(NMDevice *self, int addr_family)
         goto got_ip_state;
     }
 
-    if (nm_device_sys_iface_state_is_external(self)) {
+    if (nm_device_managed_type_is_external(self)) {
         ip_state = NM_DEVICE_IP_STATE_READY;
         goto got_ip_state;
     }
@@ -4005,7 +4005,7 @@ got_ip_state:
         /* If both IP states failed, or one failed and the other is disabled
          * then it's a failure. may-fail does not mean that both families may
          * fail, instead it means that at least one family must succeed. */
-        if (nm_device_sys_iface_state_is_external_or_assume(self)) {
+        if (nm_device_managed_type_is_external_or_assume(self)) {
             _dev_ip_state_set_state(self, AF_INET, NM_DEVICE_IP_STATE_READY, "assumed");
             _dev_ip_state_set_state(self, AF_INET6, NM_DEVICE_IP_STATE_READY, "assumed");
             combinedip_state = NM_DEVICE_IP_STATE_READY;
@@ -4458,7 +4458,7 @@ _dev_l3_register_l3cds(NMDevice *self,
     if (!l3cfg)
         return FALSE;
 
-    is_external = nm_device_sys_iface_state_is_external(self);
+    is_external = nm_device_managed_type_is_external(self);
 
     changed = FALSE;
     for (i = 0; i < (int) G_N_ELEMENTS(priv->l3cds); i++) {
@@ -4530,7 +4530,7 @@ update_external_connection(NMDevice *self)
 
     /* Update external connections with configuration from platform */
 
-    if (!nm_device_sys_iface_state_is_external(self))
+    if (!nm_device_managed_type_is_external(self))
         return;
 
     settings_connection = nm_device_get_settings_connection(self);
@@ -4726,17 +4726,17 @@ _dev_l3_cfg_commit_type_reset(NMDevice *self)
     if (!priv->l3cfg)
         return;
 
-    switch (priv->sys_iface_state) {
-    case NM_DEVICE_SYS_IFACE_STATE_EXTERNAL:
-    case NM_DEVICE_SYS_IFACE_STATE_REMOVED:
+    switch (priv->managed_type) {
+    case NM_DEVICE_MANAGED_TYPE_EXTERNAL:
+    case NM_DEVICE_MANAGED_TYPE_REMOVED:
         commit_type = NM_L3_CFG_COMMIT_TYPE_NONE;
         goto do_set;
-    case NM_DEVICE_SYS_IFACE_STATE_ASSUME:
-        /* TODO: NM_DEVICE_SYS_IFACE_STATE_ASSUME, will be dropped from the code.
+    case NM_DEVICE_MANAGED_TYPE_ASSUME:
+        /* TODO: NM_DEVICE_MANAGED_TYPE_ASSUME, will be dropped from the code.
          * Meanwhile, the commit type must be updated. */
         commit_type = NM_L3_CFG_COMMIT_TYPE_UPDATE;
         goto do_set;
-    case NM_DEVICE_SYS_IFACE_STATE_MANAGED:
+    case NM_DEVICE_MANAGED_TYPE_FULL:
         commit_type = NM_L3_CFG_COMMIT_TYPE_UPDATE;
         goto do_set;
     }
@@ -6365,7 +6365,7 @@ concheck_update_state(NMDevice           *self,
 
     _notify(self, IS_IPv4 ? PROP_IP4_CONNECTIVITY : PROP_IP6_CONNECTIVITY);
 
-    if (priv->state == NM_DEVICE_STATE_ACTIVATED && !nm_device_sys_iface_state_is_external(self))
+    if (priv->state == NM_DEVICE_STATE_ACTIVATED && !nm_device_managed_type_is_external(self))
         _dev_l3_register_l3cds(self, priv->l3cfg, TRUE, NM_TERNARY_DEFAULT);
 }
 
@@ -6850,7 +6850,7 @@ nm_device_controller_release_port(NMDevice           *self,
     nm_clear_g_cancellable(&info->cancellable);
 
     /* first, let subclasses handle the release ... */
-    if (info->port_is_attached || nm_device_sys_iface_state_is_external(port)
+    if (info->port_is_attached || nm_device_managed_type_is_external(port)
         || release_type >= RELEASE_PORT_TYPE_CONFIG_FORCE) {
         NMTernary ret;
 
@@ -7286,7 +7286,7 @@ device_update_interface_flags(NMDevice *self, const NMPlatformLink *plink)
 /*
  * Returns the reason for managing a device. The suffix "external" indicates
  * that the reason mainly depends on whether we want to make the device
- * sys-iface-state=external or not.
+ * managed_type=external or not.
  */
 NMDeviceStateReason
 nm_device_get_manage_reason_external(NMDevice *self)
@@ -7294,14 +7294,14 @@ nm_device_get_manage_reason_external(NMDevice *self)
     NMDeviceStateReason reason;
 
     /* By default we return reason NOW_MANAGED, which makes the device fully
-     * managed by NM (sys-iface-state=managed). */
+     * managed by NM (managed_type=managed). */
     reason = NM_DEVICE_STATE_REASON_NOW_MANAGED;
 
     /* If the device is an external-down candidate but no longer has the flag
      * set, then the device is an externally created interface that previously
      * had no addresses or no controller and now has.
      * We need to set CONNECTION_ASSUMED as the reason, so that the device
-     * is managed but is not touched by NM (sys-iface-state=external). */
+     * is managed but is not touched by NM (managed_type=external). */
     if (nm_device_get_unmanaged_mask(self, NM_UNMANAGED_EXTERNAL_DOWN)
         && !nm_device_get_unmanaged_flags(self, NM_UNMANAGED_EXTERNAL_DOWN)) {
         /* user-udev overwrites external-down, so we only assume the device
@@ -7449,7 +7449,7 @@ device_link_changed(gpointer user_data)
          * NMVpnConnection should become like a regular device, akin to NMDevicePpp).
          */
         if (priv->state >= NM_DEVICE_STATE_IP_CONFIG && priv->state <= NM_DEVICE_STATE_ACTIVATED
-            && !nm_device_sys_iface_state_is_external(self))
+            && !nm_device_managed_type_is_external(self))
             nm_device_l3cfg_commit(self, NM_L3_CFG_COMMIT_TYPE_REAPPLY, FALSE);
 
         /* If the device is active without a carrier (probably because it is
@@ -8041,7 +8041,7 @@ realize_start_setup(NMDevice             *self,
 
     _assume_state_set(self, assume_state_guess_assume, assume_state_connection_uuid);
 
-    nm_device_sys_iface_state_set(self, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
+    nm_device_managed_type_set(self, NM_DEVICE_MANAGED_TYPE_EXTERNAL);
 
     if (plink)
         nm_device_update_from_platform_link(self, plink);
@@ -8469,9 +8469,9 @@ port_state_changed(NMDevice           *port,
     }
 
     if (release) {
-        configure = (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED
-                     && nm_device_sys_iface_state_get(port) != NM_DEVICE_SYS_IFACE_STATE_EXTERNAL)
-                    || nm_device_sys_iface_state_get(port) == NM_DEVICE_SYS_IFACE_STATE_MANAGED;
+        configure = (priv->managed_type == NM_DEVICE_MANAGED_TYPE_FULL
+                     && nm_device_managed_type_get(port) != NM_DEVICE_MANAGED_TYPE_EXTERNAL)
+                    || nm_device_managed_type_get(port) == NM_DEVICE_MANAGED_TYPE_FULL;
 
         nm_device_controller_release_port(self,
                                           port,
@@ -8610,7 +8610,7 @@ nm_device_controller_release_ports_all(NMDevice *self)
     PortInfo           *safe;
 
     /* Don't release the ports if this connection doesn't belong to NM. */
-    if (nm_device_sys_iface_state_is_external(self))
+    if (nm_device_managed_type_is_external(self))
         return;
 
     reason = priv->state_reason;
@@ -8619,7 +8619,7 @@ nm_device_controller_release_ports_all(NMDevice *self)
 
     c_list_for_each_entry_safe (info, safe, &priv->ports, lst_port) {
         if (priv->activation_state_preserve_external_ports
-            && nm_device_sys_iface_state_is_external(info->port)) {
+            && nm_device_managed_type_is_external(info->port)) {
             _LOGT(LOGD_DEVICE,
                   "controller: preserve external port %s",
                   nm_device_get_iface(info->port));
@@ -8821,9 +8821,9 @@ nm_device_removed(NMDevice *self, gboolean unconfigure_ip_config)
      * commit type NONE, that doesn't emit a l3cd-changed. Do it manually,
      * to ensure that entries are removed from the DNS manager. */
     if (priv->l3cfg
-        && NM_IN_SET(priv->sys_iface_state,
-                     NM_DEVICE_SYS_IFACE_STATE_REMOVED,
-                     NM_DEVICE_SYS_IFACE_STATE_EXTERNAL)) {
+        && NM_IN_SET(priv->managed_type,
+                     NM_DEVICE_MANAGED_TYPE_REMOVED,
+                     NM_DEVICE_MANAGED_TYPE_EXTERNAL)) {
         l3cd_old = nm_l3cfg_get_combined_l3cd(priv->l3cfg, TRUE);
         if (l3cd_old)
             g_signal_emit(self, signals[L3CD_CHANGED], 0, l3cd_old, NULL);
@@ -9937,7 +9937,7 @@ controller_ready(NMDevice *self, NMActiveConnection *active)
     /* If the controller didn't change, add-port only rechecks whether to assume a connection. */
     nm_device_controller_add_port(controller,
                                   self,
-                                  !nm_device_sys_iface_state_is_external_or_assume(self));
+                                  !nm_device_managed_type_is_external_or_assume(self));
 }
 
 static void
@@ -10093,7 +10093,7 @@ activate_stage1_device_prepare(NMDevice *self)
     if (priv->stage1_sriov_state != NM_DEVICE_STAGE_STATE_COMPLETED) {
         NMSettingSriov *s_sriov = NULL;
 
-        if (nm_device_sys_iface_state_is_external_or_assume(self)) {
+        if (nm_device_managed_type_is_external_or_assume(self)) {
             /* pass */
         } else if (priv->stage1_sriov_state == NM_DEVICE_STAGE_STATE_PENDING) {
             return;
@@ -10163,7 +10163,7 @@ activate_stage1_device_prepare(NMDevice *self)
     klass = NM_DEVICE_GET_CLASS(self);
 
     if (klass->act_stage1_prepare_set_hwaddr_ethernet
-        && !nm_device_sys_iface_state_is_external_or_assume(self)) {
+        && !nm_device_managed_type_is_external_or_assume(self)) {
         if (!nm_device_hw_addr_set_cloned(self, nm_device_get_applied_connection(self), FALSE)) {
             nm_device_state_changed(self,
                                     NM_DEVICE_STATE_FAILED,
@@ -10173,7 +10173,7 @@ activate_stage1_device_prepare(NMDevice *self)
     }
 
     if (klass->act_stage1_prepare_also_for_external_or_assume
-        || !nm_device_sys_iface_state_is_external_or_assume(self)) {
+        || !nm_device_managed_type_is_external_or_assume(self)) {
         nm_assert(!klass->act_stage1_prepare_also_for_external_or_assume
                   || klass->act_stage1_prepare);
         if (klass->act_stage1_prepare) {
@@ -10460,12 +10460,12 @@ activate_stage2_device_config(NMDevice *self)
 
     nm_device_state_changed(self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE);
 
-    if (!nm_device_sys_iface_state_is_external(self)) {
+    if (!nm_device_managed_type_is_external(self)) {
         _ethtool_state_set(self);
         nm_device_link_properties_set(self, FALSE);
     }
 
-    if (!nm_device_sys_iface_state_is_external(self)) {
+    if (!nm_device_managed_type_is_external(self)) {
         if (!priv->tc_committed && !tc_commit(self)) {
             _LOGW(LOGD_DEVICE, "failed applying traffic control rules");
             nm_device_state_changed(self,
@@ -10478,7 +10478,7 @@ activate_stage2_device_config(NMDevice *self)
 
     _routing_rules_sync(self, NM_TERNARY_TRUE);
 
-    if (!nm_device_sys_iface_state_is_external_or_assume(self)) {
+    if (!nm_device_managed_type_is_external_or_assume(self)) {
         if (!nm_device_bring_up_full(self, FALSE, TRUE, &no_firmware)) {
             nm_device_state_changed(self,
                                     NM_DEVICE_STATE_FAILED,
@@ -10490,7 +10490,7 @@ activate_stage2_device_config(NMDevice *self)
 
     klass = NM_DEVICE_GET_CLASS(self);
     if (klass->act_stage2_config_also_for_external_or_assume
-        || !nm_device_sys_iface_state_is_external_or_assume(self)) {
+        || !nm_device_managed_type_is_external_or_assume(self)) {
         NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE;
 
         ret = klass->act_stage2_config(self, &failure_reason);
@@ -10511,7 +10511,7 @@ activate_stage2_device_config(NMDevice *self)
             nm_device_controller_attach_port(self,
                                              info->port,
                                              nm_device_get_applied_connection(info->port));
-        else if (priv->act_request.obj && nm_device_sys_iface_state_is_external(self)
+        else if (priv->act_request.obj && nm_device_managed_type_is_external(self)
                  && port_state <= NM_DEVICE_STATE_DISCONNECTED)
             nm_device_queue_recheck_assume(info->port);
     }
@@ -11061,7 +11061,7 @@ _dev_ipdhcpx_notify(NMDhcpClient *client, const NMDhcpClientNotifyData *notify_d
                     priv->l3cfg,
                     _dev_l3_config_data_tag_get(priv, L3_CONFIG_DATA_TYPE_DHCP_X(IS_IPv4)),
                     dhcp_l3cd)) {
-                _dev_l3_cfg_commit(self, FALSE);
+                _dev_l3_cfg_commit(self, TRUE);
             }
             goto lease_update_out;
         }
@@ -11136,7 +11136,7 @@ _dev_ipdhcpx_start(NMDevice *self, int addr_family)
         return;
     }
 
-    if (nm_device_sys_iface_state_is_external(self)) {
+    if (nm_device_managed_type_is_external(self)) {
         fail_reason = nm_assert_unreachable_val("cannot run DHCP on external interface");
         goto out_fail;
     }
@@ -11745,7 +11745,7 @@ _dev_ipll6_start(NMDevice *self)
 
     connection = nm_device_get_applied_connection(self);
 
-    assume = nm_device_sys_iface_state_is_external_or_assume(self);
+    assume = nm_device_managed_type_is_external_or_assume(self);
 
     if (_prop_get_ipv6_addr_gen_mode(self) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) {
         NMUtilsStableType stable_type;
@@ -11977,7 +11977,7 @@ _commit_mtu(NMDevice *self)
     if (ifindex <= 0)
         return;
 
-    if (!nm_device_get_applied_connection(self) || nm_device_sys_iface_state_is_external(self)) {
+    if (!nm_device_get_applied_connection(self) || nm_device_managed_type_is_external(self)) {
         /* we don't tamper with the MTU of disconnected and external devices. */
         return;
     }
@@ -12703,7 +12703,7 @@ activate_stage3_ip_config_for_addr_family(NMDevice *self, int addr_family, const
     NMConnection    *connection;
     int              ip_ifindex;
 
-    if (nm_device_sys_iface_state_is_external(self))
+    if (nm_device_managed_type_is_external(self))
         goto out;
 
     connection = nm_device_get_applied_connection(self);
@@ -12940,7 +12940,7 @@ activate_stage3_ip_config(NMDevice *self)
     /* Add the interface to the specified firewall zone */
     switch (priv->fw_state) {
     case FIREWALL_STATE_UNMANAGED:
-        if (nm_device_sys_iface_state_is_external(self)) {
+        if (nm_device_managed_type_is_external(self)) {
             /* fake success */
             priv->fw_state = FIREWALL_STATE_INITIALIZED;
         } else if (ifindex > 0) {
@@ -12970,7 +12970,7 @@ activate_stage3_ip_config(NMDevice *self)
 
     ipv6_method = nm_device_get_effective_ip_config_method(self, AF_INET6);
     if (!g_file_test("/proc/sys/net/ipv6", G_FILE_TEST_IS_DIR)) {
-        _NMLOG_ip((nm_device_sys_iface_state_is_external(self)
+        _NMLOG_ip((nm_device_managed_type_is_external(self)
                    || NM_IN_STRSET(ipv6_method,
                                    NM_SETTING_IP6_CONFIG_METHOD_AUTO,
                                    NM_SETTING_IP6_CONFIG_METHOD_DISABLED,
@@ -13010,7 +13010,7 @@ activate_stage3_ip_config(NMDevice *self)
         nm_device_state_changed(self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE);
 
         /* Device should be up before we can do anything with it */
-        if (!nm_device_sys_iface_state_is_external(self) && ifindex > 0
+        if (!nm_device_managed_type_is_external(self) && ifindex > 0
             && !nm_platform_link_is_up(nm_device_get_platform(self), ifindex))
             _LOGW(LOGD_DEVICE,
                   "interface %s not up for IP configuration",
@@ -13026,7 +13026,7 @@ activate_stage3_ip_config(NMDevice *self)
      * let's do it! */
     _commit_mtu(self);
 
-    if (!nm_device_sys_iface_state_is_external(self)
+    if (!nm_device_managed_type_is_external(self)
         && (!klass->ready_for_ip_config || klass->ready_for_ip_config(self, TRUE))) {
         if (priv->ipmanual_data.state_6 == NM_DEVICE_IP_STATE_NONE
             && !NM_IN_STRSET(ipv6_method,
@@ -13042,7 +13042,7 @@ activate_stage3_ip_config(NMDevice *self)
              * IPv6LL if this is not an assumed connection, since assumed connections
              * will already have IPv6 set up.
              */
-            if (!nm_device_sys_iface_state_is_external_or_assume(self))
+            if (!nm_device_managed_type_is_external_or_assume(self))
                 _dev_addrgenmode6_set(self, NM_IN6_ADDR_GEN_MODE_NONE);
 
             /* Re-enable IPv6 on the interface */
@@ -13396,15 +13396,15 @@ act_request_set(NMDevice *self, NMActRequest *act_request)
         case NM_ACTIVATION_TYPE_EXTERNAL:
             break;
         case NM_ACTIVATION_TYPE_ASSUME:
-            if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_EXTERNAL)
-                nm_device_sys_iface_state_set(self, NM_DEVICE_SYS_IFACE_STATE_ASSUME);
+            if (priv->managed_type == NM_DEVICE_MANAGED_TYPE_EXTERNAL)
+                nm_device_managed_type_set(self, NM_DEVICE_MANAGED_TYPE_ASSUME);
             break;
         case NM_ACTIVATION_TYPE_MANAGED:
-            if (NM_IN_SET_TYPED(NMDeviceSysIfaceState,
-                                priv->sys_iface_state,
-                                NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
-                                NM_DEVICE_SYS_IFACE_STATE_ASSUME))
-                nm_device_sys_iface_state_set(self, NM_DEVICE_SYS_IFACE_STATE_MANAGED);
+            if (NM_IN_SET_TYPED(NMDeviceManagedType,
+                                priv->managed_type,
+                                NM_DEVICE_MANAGED_TYPE_EXTERNAL,
+                                NM_DEVICE_MANAGED_TYPE_ASSUME))
+                nm_device_managed_type_set(self, NM_DEVICE_MANAGED_TYPE_FULL);
             break;
         }
     }
@@ -13947,8 +13947,8 @@ reapply_cb(NMDevice              *self,
         return;
     }
 
-    if (nm_device_sys_iface_state_is_external(self))
-        nm_device_sys_iface_state_set(self, NM_DEVICE_SYS_IFACE_STATE_MANAGED);
+    if (nm_device_managed_type_is_external(self))
+        nm_device_managed_type_set(self, NM_DEVICE_MANAGED_TYPE_FULL);
 
     if (!check_and_reapply_connection(self,
                                       connection
@@ -14432,10 +14432,10 @@ nm_device_disconnect_active_connection(NMActiveConnection           *active,
     if (NM_ACTIVE_CONNECTION(priv->act_request.obj) == active) {
         if (priv->state < NM_DEVICE_STATE_DEACTIVATING) {
             /* When the user actively deactivates a profile, we set
-             * the sys-iface-state to managed so that we deconfigure/cleanup the interface.
+             * the managed-type to managed so that we deconfigure/cleanup the interface.
              * But for external connections that go down otherwise, we don't want to touch the interface. */
-            if (nm_device_sys_iface_state_is_external(self))
-                nm_device_sys_iface_state_set(self, NM_DEVICE_SYS_IFACE_STATE_MANAGED);
+            if (nm_device_managed_type_is_external(self))
+                nm_device_managed_type_set(self, NM_DEVICE_MANAGED_TYPE_FULL);
 
             nm_device_state_changed(self, NM_DEVICE_STATE_DEACTIVATING, device_reason);
         } else {
@@ -15702,8 +15702,7 @@ nm_device_update_firewall_zone(NMDevice *self)
 
     priv = NM_DEVICE_GET_PRIVATE(self);
 
-    if (priv->fw_state >= FIREWALL_STATE_INITIALIZED
-        && !nm_device_sys_iface_state_is_external(self))
+    if (priv->fw_state >= FIREWALL_STATE_INITIALIZED && !nm_device_managed_type_is_external(self))
         fw_change_zone(self);
 }
 
@@ -16350,7 +16349,7 @@ _cleanup_generic_pre(NMDevice *self, CleanupType cleanup_type)
     }
 
     if (cleanup_type == CLEANUP_TYPE_DECONFIGURE && priv->fw_state >= FIREWALL_STATE_INITIALIZED
-        && priv->fw_mgr && !nm_device_sys_iface_state_is_external(self)) {
+        && priv->fw_mgr && !nm_device_managed_type_is_external(self)) {
         nm_firewalld_manager_remove_from_zone(priv->fw_mgr,
                                               nm_device_get_ip_iface(self),
                                               NULL,
@@ -16715,7 +16714,7 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
 
     old_state = priv->state;
 
-    if (state == NM_DEVICE_STATE_FAILED && nm_device_sys_iface_state_is_external_or_assume(self)) {
+    if (state == NM_DEVICE_STATE_FAILED && nm_device_managed_type_is_external_or_assume(self)) {
         /* Avoid tearing down assumed connection, assume it's connected */
         state  = NM_DEVICE_STATE_ACTIVATED;
         reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED;
@@ -16728,21 +16727,21 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
     if ((priv->state == state)
         && (state != NM_DEVICE_STATE_UNAVAILABLE || !priv->firmware_missing)) {
         _LOGD(LOGD_DEVICE,
-              "state change: %s -> %s (reason '%s', sys-iface-state: '%s'%s)",
+              "state change: %s -> %s (reason '%s', managed-type: '%s'%s)",
               nm_device_state_to_string(old_state),
               nm_device_state_to_string(state),
               nm_device_state_reason_to_string_a(reason),
-              nm_device_sys_iface_state_to_string(priv->sys_iface_state),
+              nm_device_managed_type_to_string(priv->managed_type),
               priv->firmware_missing ? ", missing firmware" : "");
         return;
     }
 
     _LOGI(LOGD_DEVICE,
-          "state change: %s -> %s (reason '%s', sys-iface-state: '%s')",
+          "state change: %s -> %s (reason '%s', managed-type: '%s')",
           nm_device_state_to_string(old_state),
           nm_device_state_to_string(state),
           nm_device_state_reason_to_string_a(reason),
-          nm_device_sys_iface_state_to_string(priv->sys_iface_state));
+          nm_device_managed_type_to_string(priv->managed_type));
 
     /* in order to prevent triggering any callback caused
      * by the device not having any pending action anymore
@@ -16764,11 +16763,11 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
 
     if (state > NM_DEVICE_STATE_UNMANAGED && state <= NM_DEVICE_STATE_ACTIVATED
         && nm_device_state_reason_check(reason) == NM_DEVICE_STATE_REASON_NOW_MANAGED
-        && NM_IN_SET_TYPED(NMDeviceSysIfaceState,
-                           priv->sys_iface_state,
-                           NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
-                           NM_DEVICE_SYS_IFACE_STATE_ASSUME))
-        nm_device_sys_iface_state_set(self, NM_DEVICE_SYS_IFACE_STATE_MANAGED);
+        && NM_IN_SET_TYPED(NMDeviceManagedType,
+                           priv->managed_type,
+                           NM_DEVICE_MANAGED_TYPE_EXTERNAL,
+                           NM_DEVICE_MANAGED_TYPE_ASSUME))
+        nm_device_managed_type_set(self, NM_DEVICE_MANAGED_TYPE_FULL);
 
     if (state <= NM_DEVICE_STATE_DISCONNECTED || state >= NM_DEVICE_STATE_ACTIVATED)
         priv->auth_retries = NM_DEVICE_AUTH_RETRIES_UNSET;
@@ -16810,10 +16809,10 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
     case NM_DEVICE_STATE_UNMANAGED:
         nm_device_set_firmware_missing(self, FALSE);
         if (old_state > NM_DEVICE_STATE_UNMANAGED) {
-            if (priv->sys_iface_state != NM_DEVICE_SYS_IFACE_STATE_MANAGED) {
+            if (priv->managed_type != NM_DEVICE_MANAGED_TYPE_FULL) {
                 nm_device_cleanup(self,
                                   reason,
-                                  priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_REMOVED
+                                  priv->managed_type == NM_DEVICE_MANAGED_TYPE_REMOVED
                                       ? CLEANUP_TYPE_REMOVED
                                       : CLEANUP_TYPE_KEEP);
             } else {
@@ -16826,12 +16825,12 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
                 _dev_sysctl_restore_ip6_properties(self);
             }
         }
-        nm_device_sys_iface_state_set(self, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
+        nm_device_managed_type_set(self, NM_DEVICE_MANAGED_TYPE_EXTERNAL);
         break;
     case NM_DEVICE_STATE_UNAVAILABLE:
         if (old_state == NM_DEVICE_STATE_UNMANAGED) {
             _dev_sysctl_save_ip6_properties(self);
-            if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED)
+            if (priv->managed_type == NM_DEVICE_MANAGED_TYPE_FULL)
                 ip6_managed_setup(self);
             device_init_static_sriov_num_vfs(self);
 
@@ -16843,7 +16842,7 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
             carrier_detect_wait(self);
         }
 
-        if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED) {
+        if (priv->managed_type == NM_DEVICE_MANAGED_TYPE_FULL) {
             if (old_state == NM_DEVICE_STATE_UNMANAGED || priv->firmware_missing) {
                 if (!nm_device_bring_up_full(self, TRUE, FALSE, &no_firmware) && no_firmware)
                     _LOGW(LOGD_PLATFORM, "firmware may be missing.");
@@ -16867,13 +16866,13 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
              * userspace IPv6LL enabled.
              */
             _dev_addrgenmode6_set(self, NM_IN6_ADDR_GEN_MODE_NONE);
-            if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_REMOVED) {
+            if (priv->managed_type == NM_DEVICE_MANAGED_TYPE_REMOVED) {
                 nm_device_cleanup(self, reason, CLEANUP_TYPE_REMOVED);
             } else
                 nm_device_cleanup(self, reason, CLEANUP_TYPE_DECONFIGURE);
 
         } else if (old_state < NM_DEVICE_STATE_DISCONNECTED) {
-            if (priv->sys_iface_state == NM_DEVICE_SYS_IFACE_STATE_MANAGED) {
+            if (priv->managed_type == NM_DEVICE_MANAGED_TYPE_FULL) {
                 /* Ensure IPv6 is set up as it may not have been done when
                  * entering the UNAVAILABLE state depending on the reason.
                  */
@@ -16893,10 +16892,6 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
             _cleanup_ip_pre(self, AF_INET6, CLEANUP_TYPE_DECONFIGURE, FALSE);
         }
         break;
-    case NM_DEVICE_STATE_DEACTIVATING:
-        /* If we are now deactivating we should enforce IP cleanup. */
-        _cleanup_ip_pre(self, AF_INET, CLEANUP_TYPE_DECONFIGURE, FALSE);
-        _cleanup_ip_pre(self, AF_INET6, CLEANUP_TYPE_DECONFIGURE, FALSE);
     default:
         break;
     }
@@ -17040,7 +17035,7 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
     {
         gboolean change_zone = FALSE;
 
-        if (!nm_device_sys_iface_state_is_external(self)) {
+        if (!nm_device_managed_type_is_external(self)) {
             if (priv->ip_iface) {
                 /* The device now has a @ip_iface different from the
                  * @iface on which we previously set the zone. */
@@ -18632,14 +18627,14 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps
             managed = g_value_get_boolean(value);
             if (managed) {
                 reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED;
-                if (NM_IN_SET_TYPED(NMDeviceSysIfaceState,
-                                    priv->sys_iface_state,
-                                    NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
-                                    NM_DEVICE_SYS_IFACE_STATE_REMOVED))
-                    nm_device_sys_iface_state_set(self, NM_DEVICE_SYS_IFACE_STATE_ASSUME);
+                if (NM_IN_SET_TYPED(NMDeviceManagedType,
+                                    priv->managed_type,
+                                    NM_DEVICE_MANAGED_TYPE_EXTERNAL,
+                                    NM_DEVICE_MANAGED_TYPE_REMOVED))
+                    nm_device_managed_type_set(self, NM_DEVICE_MANAGED_TYPE_ASSUME);
             } else {
                 reason = NM_DEVICE_STATE_REASON_REMOVED;
-                nm_device_sys_iface_state_set(self, NM_DEVICE_SYS_IFACE_STATE_REMOVED);
+                nm_device_managed_type_set(self, NM_DEVICE_MANAGED_TYPE_REMOVED);
             }
             nm_device_set_unmanaged_by_flags(self, NM_UNMANAGED_USER_EXPLICIT, !managed, reason);
         }
@@ -18727,10 +18722,10 @@ nm_device_init(NMDevice *self)
     priv->available_connections = g_hash_table_new_full(nm_direct_hash, NULL, g_object_unref, NULL);
     priv->ip6_saved_properties  = g_hash_table_new_full(nm_str_hash, g_str_equal, NULL, g_free);
 
-    priv->sys_iface_state_ = NM_DEVICE_SYS_IFACE_STATE_EXTERNAL;
+    priv->managed_type_ = NM_DEVICE_MANAGED_TYPE_EXTERNAL;
     /* If networking is already disabled at boot, we want to manage all devices
      * after re-enabling networking; hence, the initial state is MANAGED. */
-    priv->sys_iface_state_before_sleep = NM_DEVICE_SYS_IFACE_STATE_MANAGED;
+    priv->managed_type_before_sleep = NM_DEVICE_MANAGED_TYPE_FULL;
 
     priv->promisc_reset = NM_OPTION_BOOL_DEFAULT;
 }
diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h
index 37eda5c0..b84bbb65 100644
--- a/src/core/devices/nm-device.h
+++ b/src/core/devices/nm-device.h
@@ -726,16 +726,16 @@ nm_device_autoconnect_blocked_unset(NMDevice *device, NMDeviceAutoconnectBlocked
 
 void nm_device_recheck_auto_activate_schedule(NMDevice *device);
 
-NMDeviceSysIfaceState nm_device_sys_iface_state_get(NMDevice *device);
+NMDeviceManagedType nm_device_managed_type_get(NMDevice *device);
 
-gboolean nm_device_sys_iface_state_is_external(NMDevice *self);
-gboolean nm_device_sys_iface_state_is_external_or_assume(NMDevice *self);
+gboolean nm_device_managed_type_is_external(NMDevice *self);
+gboolean nm_device_managed_type_is_external_or_assume(NMDevice *self);
 
-void nm_device_sys_iface_state_set(NMDevice *device, NMDeviceSysIfaceState sys_iface_state);
+void nm_device_managed_type_set(NMDevice *device, NMDeviceManagedType managed_type);
 
 void nm_device_notify_sleeping(NMDevice *self);
 
-NMDeviceSysIfaceState nm_device_get_sys_iface_state_before_sleep(NMDevice *self);
+NMDeviceManagedType nm_device_get_managed_type_before_sleep(NMDevice *self);
 
 void nm_device_state_changed(NMDevice *device, NMDeviceState state, NMDeviceStateReason reason);
 
diff --git a/src/core/devices/ovs/nm-device-ovs-port.c b/src/core/devices/ovs/nm-device-ovs-port.c
index 2acafba2..2e8ab717 100644
--- a/src/core/devices/ovs/nm-device-ovs-port.c
+++ b/src/core/devices/ovs/nm-device-ovs-port.c
@@ -218,9 +218,9 @@ detach_port(NMDevice                  *device,
             gpointer                   user_data)
 {
     NMDeviceOvsPort *self             = NM_DEVICE_OVS_PORT(device);
-    bool             port_not_managed = !NM_IN_SET(nm_device_sys_iface_state_get(port),
-                                       NM_DEVICE_SYS_IFACE_STATE_MANAGED,
-                                       NM_DEVICE_SYS_IFACE_STATE_ASSUME);
+    bool             port_not_managed = !NM_IN_SET(nm_device_managed_type_get(port),
+                                       NM_DEVICE_MANAGED_TYPE_FULL,
+                                       NM_DEVICE_MANAGED_TYPE_ASSUME);
     NMTernary        ret              = TRUE;
 
     _LOGI(LOGD_DEVICE, "detaching ovs interface %s", nm_device_get_ip_iface(port));
diff --git a/src/core/devices/team/nm-device-team.c b/src/core/devices/team/nm-device-team.c
index 0f420a7a..a4c77f7f 100644
--- a/src/core/devices/team/nm-device-team.c
+++ b/src/core/devices/team/nm-device-team.c
@@ -763,10 +763,10 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
     NMSettingTeam       *s_team;
     const char          *cfg;
 
-    if (nm_device_sys_iface_state_is_external(device))
+    if (nm_device_managed_type_is_external(device))
         return NM_ACT_STAGE_RETURN_SUCCESS;
 
-    if (nm_device_sys_iface_state_is_external_or_assume(device)) {
+    if (nm_device_managed_type_is_external_or_assume(device)) {
         if (ensure_teamd_connection(device, &error))
             return NM_ACT_STAGE_RETURN_SUCCESS;
         _LOGD(LOGD_TEAM, "could not connect to teamd: %s", error->message);
@@ -832,7 +832,7 @@ deactivate(NMDevice *device)
 
     priv->stage1_state = NM_DEVICE_STAGE_STATE_INIT;
 
-    if (nm_device_sys_iface_state_is_external(device))
+    if (nm_device_managed_type_is_external(device))
         return;
 
     if (priv->teamd_pid || priv->tdc)
diff --git a/src/core/devices/wifi/nm-device-iwd.c b/src/core/devices/wifi/nm-device-iwd.c
index 89444640..d6e3ed08 100644
--- a/src/core/devices/wifi/nm-device-iwd.c
+++ b/src/core/devices/wifi/nm-device-iwd.c
@@ -3483,7 +3483,7 @@ nm_device_iwd_parse_netconfig(NMDeviceIwd *self, int addr_family, GVariantIter *
                 /* Use SOURCE_DHCP as shorthand for the various autoconfiguration protocols */
                 source = NM_IP_CONFIG_SOURCE_DHCP;
             else
-                _LOGW(LOGD_WIFI, "iwd_parse_netconfig: Uknown Method value \"%s\"", str_value);
+                _LOGW(LOGD_WIFI, "iwd_parse_netconfig: Unknown Method value \"%s\"", str_value);
         }
 
         if (nm_streq(key, "Addresses")) {
@@ -3527,7 +3527,7 @@ nm_device_iwd_parse_netconfig(NMDeviceIwd *self, int addr_family, GVariantIter *
             else if (nm_streq(str_value, "resolve"))
                 mdns = NM_SETTING_CONNECTION_MDNS_RESOLVE;
             else
-                _LOGW(LOGD_WIFI, "iwd_parse_netconfig: Uknown MDNS value \"%s\"", str_value);
+                _LOGW(LOGD_WIFI, "iwd_parse_netconfig: Unknown MDNS value \"%s\"", str_value);
         }
     }
 
diff --git a/src/core/devices/wifi/nm-device-wifi-p2p.c b/src/core/devices/wifi/nm-device-wifi-p2p.c
index 981811a3..f06383b1 100644
--- a/src/core/devices/wifi/nm-device-wifi-p2p.c
+++ b/src/core/devices/wifi/nm-device-wifi-p2p.c
@@ -54,6 +54,7 @@ typedef struct {
     guint peer_missing_id;
 
     bool is_waiting_for_supplicant : 1;
+    bool enabled : 1;
 } NMDeviceWifiP2PPrivate;
 
 struct _NMDeviceWifiP2P {
@@ -774,7 +775,6 @@ supplicant_group_iface_is_ready(NMDeviceWifiP2P *self)
         return;
     }
 
-    _set_is_waiting_for_supplicant(self, FALSE);
     check_group_iface_ready(self);
 }
 
@@ -875,7 +875,6 @@ supplicant_iface_group_started_cb(NMSupplicantInterface *iface,
 
     state = nm_supplicant_interface_get_state(priv->group_iface);
     if (state == NM_SUPPLICANT_INTERFACE_STATE_STARTING) {
-        _set_is_waiting_for_supplicant(self, TRUE);
         return;
     }
 
@@ -917,7 +916,7 @@ supplicant_interfaces_release(NMDeviceWifiP2P *self, gboolean set_is_waiting)
 
     supplicant_group_interface_release(self);
 
-    if (set_is_waiting)
+    if (set_is_waiting && priv->enabled)
         _set_is_waiting_for_supplicant(self, TRUE);
 }
 
@@ -948,9 +947,10 @@ device_state_changed(NMDevice           *device,
     case NM_DEVICE_STATE_UNMANAGED:
         break;
     case NM_DEVICE_STATE_UNAVAILABLE:
-        if (!priv->mgmt_iface
-            || !nm_supplicant_interface_state_is_operational(
-                nm_supplicant_interface_get_state(priv->mgmt_iface)))
+        if (priv->enabled
+            && (!priv->mgmt_iface
+                || !nm_supplicant_interface_state_is_operational(
+                    nm_supplicant_interface_get_state(priv->mgmt_iface))))
             _set_is_waiting_for_supplicant(self, TRUE);
         break;
     case NM_DEVICE_STATE_NEED_AUTH:
@@ -1122,6 +1122,32 @@ impl_device_wifi_p2p_stop_find(NMDBusObject                      *obj,
                            NULL);
 }
 
+static gboolean
+get_enabled(NMDevice *device)
+{
+    return NM_DEVICE_WIFI_P2P_GET_PRIVATE(device)->enabled;
+}
+
+static void
+set_enabled(NMDevice *device, gboolean enabled)
+{
+    NMDeviceWifiP2P        *self = NM_DEVICE_WIFI_P2P(device);
+    NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self);
+
+    enabled = !!enabled;
+
+    if (priv->enabled == enabled)
+        return;
+
+    priv->enabled = enabled;
+
+    _LOGD(LOGD_DEVICE | LOGD_WIFI, "device now %s", enabled ? "enabled" : "disabled");
+
+    if (!enabled) {
+        _set_is_waiting_for_supplicant(self, FALSE);
+    }
+}
+
 /*****************************************************************************/
 
 NMSupplicantInterface *
@@ -1172,10 +1198,12 @@ done:
     nm_device_queue_recheck_available(NM_DEVICE(self),
                                       NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE,
                                       NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
-    _set_is_waiting_for_supplicant(self,
-                                   !priv->mgmt_iface
-                                       || !nm_supplicant_interface_state_is_operational(
-                                           nm_supplicant_interface_get_state(priv->mgmt_iface)));
+    _set_is_waiting_for_supplicant(
+        self,
+        priv->enabled
+            && (!priv->mgmt_iface
+                || !nm_supplicant_interface_state_is_operational(
+                    nm_supplicant_interface_get_state(priv->mgmt_iface))));
 }
 
 void
@@ -1338,6 +1366,8 @@ nm_device_wifi_p2p_class_init(NMDeviceWifiP2PClass *klass)
     device_class->get_configured_mtu        = get_configured_mtu;
     device_class->get_auto_ip_config_method = get_auto_ip_config_method;
     device_class->act_stage3_ip_config      = act_stage3_ip_config;
+    device_class->set_enabled               = set_enabled;
+    device_class->get_enabled               = get_enabled;
 
     device_class->deactivate        = deactivate;
     device_class->unmanaged_on_quit = unmanaged_on_quit;
diff --git a/src/core/dhcp/nm-dhcp-listener.c b/src/core/dhcp/nm-dhcp-listener.c
index 0854c1dc..05e428f8 100644
--- a/src/core/dhcp/nm-dhcp-listener.c
+++ b/src/core/dhcp/nm-dhcp-listener.c
@@ -27,21 +27,21 @@
 
 const NMDhcpClientFactory *const _nm_dhcp_manager_factories[6] = {
 
-/* the order here matters, as we will try the plugins in this order to find
- * the first available plugin. */
+    /* the order here matters, as we will try the plugins in this order to find
+     * the first available plugin. */
 
+    &_nm_dhcp_client_factory_internal,
 #if WITH_DHCPCANON
     &_nm_dhcp_client_factory_dhcpcanon,
 #endif
-#if WITH_DHCLIENT
-    &_nm_dhcp_client_factory_dhclient,
-#endif
 #if WITH_DHCPCD
     &_nm_dhcp_client_factory_dhcpcd,
 #endif
-    &_nm_dhcp_client_factory_internal,
     &_nm_dhcp_client_factory_systemd,
     &_nm_dhcp_client_factory_nettools,
+#if WITH_DHCLIENT
+    &_nm_dhcp_client_factory_dhclient,
+#endif
 };
 
 /*****************************************************************************/
diff --git a/src/core/dhcp/nm-dhcp-manager.c b/src/core/dhcp/nm-dhcp-manager.c
index cfff23f8..68bb327b 100644
--- a/src/core/dhcp/nm-dhcp-manager.c
+++ b/src/core/dhcp/nm-dhcp-manager.c
@@ -90,8 +90,15 @@ _client_factory_find_by_name(const char *name)
 static const NMDhcpClientFactory *
 _client_factory_available(const NMDhcpClientFactory *client_factory)
 {
-    if (client_factory && (!client_factory->get_path || client_factory->get_path()))
-        return client_factory;
+    if (client_factory) {
+        if (nm_streq(client_factory->name, "dhclient")) {
+            _LOGW(AF_UNSPEC,
+                  "attempting to used a deprecated DHCP client '%s' ",
+                  client_factory->name);
+        }
+        if (!client_factory->get_path || client_factory->get_path())
+            return client_factory;
+    }
     return NULL;
 }
 
diff --git a/src/core/ndisc/nm-ndisc.c b/src/core/ndisc/nm-ndisc.c
index 4800829f..86b7da6e 100644
--- a/src/core/ndisc/nm-ndisc.c
+++ b/src/core/ndisc/nm-ndisc.c
@@ -720,6 +720,7 @@ nm_ndisc_add_route(NMNDisc *ndisc, const NMNDiscRoute *new_item, gint64 now_msec
          * comparison is aborted, and both routes are added.
          */
         if (IN6_ARE_ADDR_EQUAL(&item->network, &new_item->network) && item->plen == new_item->plen
+            && IN6_ARE_ADDR_EQUAL(&item->gateway, &new_item->gateway)
             && item->on_link == new_item->on_link) {
             if (new_item->expiry_msec <= now_msec) {
                 g_array_remove_index(rdata->routes, i);
diff --git a/src/core/nm-active-connection.c b/src/core/nm-active-connection.c
index ca1993cf..ebfbc72b 100644
--- a/src/core/nm-active-connection.c
+++ b/src/core/nm-active-connection.c
@@ -989,10 +989,10 @@ _set_activation_type_managed(NMActiveConnection *self)
     _set_activation_type(self, NM_ACTIVATION_TYPE_MANAGED);
 
     if (priv->device && self == NM_ACTIVE_CONNECTION(nm_device_get_act_request(priv->device))
-        && NM_IN_SET(nm_device_sys_iface_state_get(priv->device),
-                     NM_DEVICE_SYS_IFACE_STATE_EXTERNAL,
-                     NM_DEVICE_SYS_IFACE_STATE_ASSUME))
-        nm_device_sys_iface_state_set(priv->device, NM_DEVICE_SYS_IFACE_STATE_MANAGED);
+        && NM_IN_SET(nm_device_managed_type_get(priv->device),
+                     NM_DEVICE_MANAGED_TYPE_EXTERNAL,
+                     NM_DEVICE_MANAGED_TYPE_ASSUME))
+        nm_device_managed_type_set(priv->device, NM_DEVICE_MANAGED_TYPE_FULL);
 }
 
 NMActivationReason
diff --git a/src/core/nm-config-data.c b/src/core/nm-config-data.c
index 9b3f958b..0a73695a 100644
--- a/src/core/nm-config-data.c
+++ b/src/core/nm-config-data.c
@@ -62,6 +62,7 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_CONFIG_MAIN_FILE,
                                   PROP_CONNECTIVITY_ENABLED,
                                   PROP_CONNECTIVITY_URI,
                                   PROP_CONNECTIVITY_INTERVAL,
+                                  PROP_CONNECTIVITY_TIMEOUT,
                                   PROP_CONNECTIVITY_RESPONSE,
                                   PROP_NO_AUTO_DEFAULT, );
 
@@ -86,6 +87,7 @@ typedef struct {
         char    *uri;
         char    *response;
         guint    interval;
+        guint    timeout;
     } connectivity;
 
     int autoconnect_retries_default;
@@ -304,6 +306,14 @@ nm_config_data_get_connectivity_interval(const NMConfigData *self)
     return NM_CONFIG_DATA_GET_PRIVATE(self)->connectivity.interval;
 }
 
+guint
+nm_config_data_get_connectivity_timeout(const NMConfigData *self)
+{
+    g_return_val_if_fail(self, 0);
+
+    return NM_CONFIG_DATA_GET_PRIVATE(self)->connectivity.timeout;
+}
+
 const char *
 nm_config_data_get_connectivity_response(const NMConfigData *self)
 {
@@ -2006,6 +2016,8 @@ nm_config_data_diff(NMConfigData *old_data, NMConfigData *new_data)
             != nm_config_data_get_connectivity_enabled(new_data)
         || nm_config_data_get_connectivity_interval(old_data)
                != nm_config_data_get_connectivity_interval(new_data)
+        || nm_config_data_get_connectivity_timeout(old_data)
+               != nm_config_data_get_connectivity_timeout(new_data)
         || !nm_streq0(nm_config_data_get_connectivity_uri(old_data),
                       nm_config_data_get_connectivity_uri(new_data))
         || !nm_streq0(nm_config_data_get_connectivity_response(old_data),
@@ -2079,6 +2091,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
     case PROP_CONNECTIVITY_INTERVAL:
         g_value_set_uint(value, nm_config_data_get_connectivity_interval(self));
         break;
+    case PROP_CONNECTIVITY_TIMEOUT:
+        g_value_set_uint(value, nm_config_data_get_connectivity_timeout(self));
+        break;
     case PROP_CONNECTIVITY_RESPONSE:
         g_value_set_string(value, nm_config_data_get_connectivity_response(self));
         break;
@@ -2221,6 +2236,15 @@ constructed(GObject *object)
                                      NM_CONFIG_DEFAULT_CONNECTIVITY_INTERVAL);
     g_free(str);
 
+    /* On missing or invalid config value, fallback to 20. */
+    str = g_key_file_get_string(priv->keyfile,
+                                NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY,
+                                NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_TIMEOUT,
+                                NULL);
+    priv->connectivity.timeout =
+        _nm_utils_ascii_str_to_int64(str, 10, 0, G_MAXUINT, NM_CONFIG_DEFAULT_CONNECTIVITY_TIMEOUT);
+    g_free(str);
+
     priv->dns_mode   = nm_strstrip(g_key_file_get_string(priv->keyfile,
                                                        NM_CONFIG_KEYFILE_GROUP_MAIN,
                                                        NM_CONFIG_KEYFILE_KEY_MAIN_DNS,
@@ -2420,6 +2444,15 @@ nm_config_data_class_init(NMConfigDataClass *config_class)
                           0,
                           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
 
+    obj_properties[PROP_CONNECTIVITY_TIMEOUT] =
+        g_param_spec_uint(NM_CONFIG_DATA_CONNECTIVITY_TIMEOUT,
+                          "",
+                          "",
+                          0,
+                          G_MAXUINT,
+                          0,
+                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
     obj_properties[PROP_CONNECTIVITY_RESPONSE] =
         g_param_spec_string(NM_CONFIG_DATA_CONNECTIVITY_RESPONSE,
                             "",
diff --git a/src/core/nm-config-data.h b/src/core/nm-config-data.h
index b9427969..1ea0ccf2 100644
--- a/src/core/nm-config-data.h
+++ b/src/core/nm-config-data.h
@@ -47,6 +47,7 @@ typedef enum {
 #define NM_CONFIG_DATA_CONNECTIVITY_ENABLED  "connectivity-enabled"
 #define NM_CONFIG_DATA_CONNECTIVITY_URI      "connectivity-uri"
 #define NM_CONFIG_DATA_CONNECTIVITY_INTERVAL "connectivity-interval"
+#define NM_CONFIG_DATA_CONNECTIVITY_TIMEOUT  "connectivity-timeout"
 #define NM_CONFIG_DATA_CONNECTIVITY_RESPONSE "connectivity-response"
 #define NM_CONFIG_DATA_NO_AUTO_DEFAULT       "no-auto-default"
 #define NM_CONFIG_DATA_DNS_MODE              "dns"
@@ -172,6 +173,7 @@ char      **nm_config_data_get_plugins(const NMConfigData *config_data, gboolean
 gboolean    nm_config_data_get_connectivity_enabled(const NMConfigData *config_data);
 const char *nm_config_data_get_connectivity_uri(const NMConfigData *config_data);
 guint       nm_config_data_get_connectivity_interval(const NMConfigData *config_data);
+guint       nm_config_data_get_connectivity_timeout(const NMConfigData *config_data);
 const char *nm_config_data_get_connectivity_response(const NMConfigData *config_data);
 
 int nm_config_data_get_autoconnect_retries_default(const NMConfigData *config_data);
diff --git a/src/core/nm-config.c b/src/core/nm-config.c
index 43eb3646..878f343a 100644
--- a/src/core/nm-config.c
+++ b/src/core/nm-config.c
@@ -871,6 +871,7 @@ static const ConfigGroup config_groups[] = {
         .group = NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY,
         .keys  = NM_MAKE_STRV(NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_ENABLED,
                              NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_INTERVAL,
+                             NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_TIMEOUT,
                              NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_RESPONSE,
                              NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_URI, ),
     },
diff --git a/src/core/nm-config.h b/src/core/nm-config.h
index e65582c3..5518184c 100644
--- a/src/core/nm-config.h
+++ b/src/core/nm-config.h
@@ -28,6 +28,7 @@
 #define NM_CONFIG_SIGNAL_CONFIG_CHANGED "config-changed"
 
 #define NM_CONFIG_DEFAULT_CONNECTIVITY_INTERVAL 300
+#define NM_CONFIG_DEFAULT_CONNECTIVITY_TIMEOUT  20
 #define NM_CONFIG_DEFAULT_CONNECTIVITY_RESPONSE "NetworkManager is online" /* NOT LOCALIZED */
 
 typedef struct NMConfigCmdLineOptions NMConfigCmdLineOptions;
diff --git a/src/core/nm-connectivity.c b/src/core/nm-connectivity.c
index 15dc31aa..65eec36d 100644
--- a/src/core/nm-connectivity.c
+++ b/src/core/nm-connectivity.c
@@ -56,6 +56,7 @@ typedef struct {
     char *host;
     char *port;
     char *response;
+    guint timeout;
 } ConConfig;
 
 struct _NMConnectivityCheckHandle {
@@ -738,7 +739,9 @@ do_curl_request(NMConnectivityCheckHandle *cb_data, const char *hosts)
     cb_data->concheck.curl_mhandle    = mhandle;
     cb_data->concheck.curl_ehandle    = ehandle;
     cb_data->concheck.request_headers = curl_slist_append(NULL, "Connection: close");
-    cb_data->timeout_source           = nm_g_timeout_add_seconds_source(20, _timeout_cb, cb_data);
+    cb_data->timeout_source = nm_g_timeout_add_seconds_source(cb_data->concheck.con_config->timeout,
+                                                              _timeout_cb,
+                                                              cb_data);
 
     curl_multi_setopt(mhandle, CURLMOPT_SOCKETFUNCTION, multi_socket_cb);
     curl_multi_setopt(mhandle, CURLMOPT_SOCKETDATA, cb_data);
@@ -1226,6 +1229,7 @@ update_config(NMConnectivity *self, NMConfigData *config_data)
 {
     NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE(self);
     guint                  interval;
+    guint                  new_timeout;
     gboolean               enabled;
     gboolean               changed      = FALSE;
     const char            *cur_uri      = priv->con_config ? priv->con_config->uri : NULL;
@@ -1237,6 +1241,8 @@ update_config(NMConnectivity *self, NMConfigData *config_data)
     gs_free char          *new_host      = NULL;
     gs_free char          *new_port      = NULL;
 
+    new_timeout = nm_config_data_get_connectivity_timeout(config_data);
+
     new_uri = nm_config_data_get_connectivity_uri(config_data);
     if (!nm_streq0(new_uri, cur_uri)) {
         new_uri_valid = (new_uri && *new_uri);
@@ -1277,6 +1283,7 @@ update_config(NMConnectivity *self, NMConfigData *config_data)
         changed = TRUE;
 
     if (!priv->con_config || !nm_streq0(new_uri, priv->con_config->uri)
+        || new_timeout != priv->con_config->timeout
         || !nm_streq0(new_response, priv->con_config->response)) {
         if (!new_host_port) {
             new_host = priv->con_config ? g_strdup(priv->con_config->host) : NULL;
@@ -1290,6 +1297,7 @@ update_config(NMConnectivity *self, NMConfigData *config_data)
             .response  = g_strdup(new_response),
             .host      = g_steal_pointer(&new_host),
             .port      = g_steal_pointer(&new_port),
+            .timeout   = new_timeout,
         };
     }
     priv->uri_valid = new_uri_valid;
diff --git a/src/core/nm-core-utils.c b/src/core/nm-core-utils.c
index dd1e9939..6aa38be2 100644
--- a/src/core/nm-core-utils.c
+++ b/src/core/nm-core-utils.c
@@ -5096,7 +5096,9 @@ helper_complete(HelperInfo *info, GError *error)
     }
 
     nm_clear_g_cancellable_disconnect(g_task_get_cancellable(info->task), &info->cancellable_id);
-    g_task_return_pointer(info->task, nm_str_buf_finalize(&info->in_buffer, NULL), g_free);
+    g_task_return_pointer(info->task,
+                          nm_str_buf_finalize(&info->in_buffer, NULL) ?: g_new0(char, 1),
+                          g_free);
     helper_info_free(info);
 }
 
diff --git a/src/core/nm-l3cfg.h b/src/core/nm-l3cfg.h
index 241fde02..f977b10f 100644
--- a/src/core/nm-l3cfg.h
+++ b/src/core/nm-l3cfg.h
@@ -354,7 +354,7 @@ gboolean nm_l3cfg_remove_config_all_dirty(NML3Cfg *self, gconstpointer tag);
  * nm_l3cfg_commit_type_register(). nm_l3cfg_commit_on_idle_schedule() also
  * accepts a one-time commit-type argument.
  *
- * This is related to NMDevice's sys_iface_state, which we use to control whether
+ * This is related to NMDevice's managed_type, which we use to control whether
  * to touch/assume/manage the interface.
  *
  * The numeric values of the enum matters: higher number mean more "important".
diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c
index 0a7e7b2e..0d6c1e2f 100644
--- a/src/core/nm-manager.c
+++ b/src/core/nm-manager.c
@@ -2309,7 +2309,7 @@ remove_device(NMManager *self, NMDevice *device, gboolean quitting)
             if (quitting)
                 nm_device_set_unmanaged_by_quitting(device);
             else {
-                nm_device_sys_iface_state_set(device, NM_DEVICE_SYS_IFACE_STATE_REMOVED);
+                nm_device_managed_type_set(device, NM_DEVICE_MANAGED_TYPE_REMOVED);
                 nm_device_set_unmanaged_by_flags(device,
                                                  NM_UNMANAGED_PLATFORM_INIT,
                                                  NM_UNMAN_FLAG_OP_SET_UNMANAGED,
@@ -3694,9 +3694,9 @@ recheck_assume_connection(NMManager *self, NMDevice *device)
         }
     }
 
-    nm_device_sys_iface_state_set(device,
-                                  activation_type_assume ? NM_DEVICE_SYS_IFACE_STATE_ASSUME
-                                                         : NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
+    nm_device_managed_type_set(device,
+                               activation_type_assume ? NM_DEVICE_MANAGED_TYPE_ASSUME
+                                                      : NM_DEVICE_MANAGED_TYPE_EXTERNAL);
 
     /* Move device to DISCONNECTED to activate the connection */
     if (state == NM_DEVICE_STATE_UNMANAGED) {
@@ -3765,8 +3765,8 @@ recheck_assume_connection(NMManager *self, NMDevice *device)
                        "assume: deleting generated connection after assuming failed");
                 nm_settings_connection_delete(sett_conn, FALSE);
             } else {
-                if (nm_device_sys_iface_state_get(device) == NM_DEVICE_SYS_IFACE_STATE_ASSUME)
-                    nm_device_sys_iface_state_set(device, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL);
+                if (nm_device_managed_type_get(device) == NM_DEVICE_MANAGED_TYPE_ASSUME)
+                    nm_device_managed_type_set(device, NM_DEVICE_MANAGED_TYPE_EXTERNAL);
             }
             return FALSE;
         }
@@ -4374,7 +4374,7 @@ _platform_link_cb_idle(PlatformLinkCbData *data)
         device = nm_manager_get_device_by_ifindex(self, ifindex);
         if (device) {
             if (nm_device_is_software(device)) {
-                nm_device_sys_iface_state_set(device, NM_DEVICE_SYS_IFACE_STATE_REMOVED);
+                nm_device_managed_type_set(device, NM_DEVICE_MANAGED_TYPE_REMOVED);
                 if (!nm_device_unrealize(device, FALSE, &error)) {
                     _LOG2W(LOGD_DEVICE, device, "failed to unrealize: %s", error->message);
                     g_clear_error(&error);
@@ -5768,7 +5768,7 @@ _internal_activate_device(NMManager *self, NMActiveConnection *active, GError **
     }
 
     if (nm_active_connection_get_activation_type(active) == NM_ACTIVATION_TYPE_MANAGED)
-        nm_device_sys_iface_state_set(device, NM_DEVICE_SYS_IFACE_STATE_MANAGED);
+        nm_device_managed_type_set(device, NM_DEVICE_MANAGED_TYPE_FULL);
 
     /* Try to find the controller connection/device if the connection has a dependency */
     if (!find_controller(self,
@@ -7404,13 +7404,13 @@ do_sleep_wake(NMManager *self, gboolean sleeping_changed)
                     nm_device_set_enabled(device, enabled);
             }
 
-            /* The reason determines whether the device will be sys-iface-state=managed
-             * or sys-iface-state=external. Pass the correct reason to restore the state
+            /* The reason determines whether the device will be managed_type=managed
+             * or managed_type=external. Pass the correct reason to restore the state
              * that was set before sleeping. */
-            reason = nm_device_get_sys_iface_state_before_sleep(device)
-                             == NM_DEVICE_SYS_IFACE_STATE_EXTERNAL
-                         ? NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED
-                         : NM_DEVICE_STATE_REASON_NOW_MANAGED;
+            reason =
+                nm_device_get_managed_type_before_sleep(device) == NM_DEVICE_MANAGED_TYPE_EXTERNAL
+                    ? NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED
+                    : NM_DEVICE_STATE_REASON_NOW_MANAGED;
             nm_device_set_unmanaged_by_flags(device,
                                              NM_UNMANAGED_SLEEPING,
                                              NM_UNMAN_FLAG_OP_SET_MANAGED,
diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c
index 93b52526..05d4d006 100644
--- a/src/core/nm-policy.c
+++ b/src/core/nm-policy.c
@@ -429,7 +429,7 @@ get_best_active_connection(NMPolicy *self, int addr_family, gboolean fully_activ
         if (state <= NM_DEVICE_STATE_DISCONNECTED || state >= NM_DEVICE_STATE_DEACTIVATING)
             continue;
 
-        if (nm_device_sys_iface_state_is_external(device))
+        if (nm_device_managed_type_is_external(device))
             continue;
 
         r = nm_device_get_best_default_route(device, addr_family);
@@ -482,7 +482,7 @@ any_devices_active(NMPolicy *self)
         state = nm_device_get_state(device);
         if (state <= NM_DEVICE_STATE_DISCONNECTED || state >= NM_DEVICE_STATE_DEACTIVATING)
             continue;
-        if (nm_device_sys_iface_state_is_external(device))
+        if (nm_device_managed_type_is_external(device))
             continue;
         return TRUE;
     }
@@ -809,7 +809,7 @@ build_device_hostname_infos(NMPolicy *self)
         if (!device)
             continue;
 
-        if (nm_device_sys_iface_state_is_external(device))
+        if (nm_device_managed_type_is_external(device))
             continue;
 
         only_from_default =
@@ -1307,7 +1307,7 @@ update_ip_dns(NMPolicy *self, int addr_family, NMDevice *changed_device)
         /* Tell the DNS manager this config is preferred by re-adding it with
          * a different IP config type.
          */
-        if (device && nm_device_sys_iface_state_is_external(device))
+        if (device && nm_device_managed_type_is_external(device))
             ip_config_type = NM_DNS_IP_CONFIG_TYPE_REMOVED;
         else if (vpn || (device && nm_device_is_vpn(device)))
             ip_config_type = NM_DNS_IP_CONFIG_TYPE_VPN;
@@ -1447,7 +1447,7 @@ _auto_activate_device(NMPolicy *self, NMDevice *device)
     // deactivate the device and activate the new connection instead of just
     // bailing if the device is already active
     if (nm_device_get_act_request(device)) {
-        if (nm_device_sys_iface_state_is_external(device)
+        if (nm_device_managed_type_is_external(device)
             && nm_device_get_allow_autoconnect_on_external(device)) {
             /* this is an external activation, and we allow autoconnecting on
              * top of that.
@@ -1781,7 +1781,7 @@ nm_policy_device_recheck_auto_activate_schedule(NMPolicy *self, NMDevice *device
 
     nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) {
         if (nm_active_connection_get_device(ac) == device) {
-            if (nm_device_sys_iface_state_is_external(device)
+            if (nm_device_managed_type_is_external(device)
                 && nm_device_get_allow_autoconnect_on_external(device)) {
                 /* pass */
             } else
@@ -2300,7 +2300,7 @@ device_state_changed(NMDevice           *device,
          * again when the device becomes ACTIVATED, we need also to update
          * routing and DNS here. */
         nm_dns_manager_begin_updates(priv->dns_manager, __func__);
-        if (!nm_device_sys_iface_state_is_external(device)) {
+        if (!nm_device_managed_type_is_external(device)) {
             nm_dns_manager_set_ip_config(priv->dns_manager,
                                          AF_UNSPEC,
                                          device,
diff --git a/src/core/settings/nm-settings.c b/src/core/settings/nm-settings.c
index 7fc20298..80b1f4b2 100644
--- a/src/core/settings/nm-settings.c
+++ b/src/core/settings/nm-settings.c
@@ -3520,7 +3520,7 @@ load_plugins(NMSettings *self, const char *const *plugins, GError **error)
         }
 
         if (NM_IN_STRSET(pname, "ifcfg-suse", "ifnet", "ibft", "no-ibft")) {
-            _LOGW("skipping deprecated plugin %s", pname);
+            _LOGW("skipping obsolete plugin %s", pname);
             continue;
         }
 
diff --git a/src/core/supplicant/nm-supplicant-config.c b/src/core/supplicant/nm-supplicant-config.c
index 7db614a2..4433e809 100644
--- a/src/core/supplicant/nm-supplicant-config.c
+++ b/src/core/supplicant/nm-supplicant-config.c
@@ -499,6 +499,52 @@ nm_supplicant_config_add_setting_macsec(NMSupplicantConfig    *self,
     return TRUE;
 }
 
+static void
+get_ap_params(guint                         freq,
+              NMSettingWirelessChannelWidth width,
+              guint                        *out_ht40,
+              int                          *out_max_oper_chwidth,
+              guint                        *out_center_freq)
+{
+    *out_ht40             = 0;
+    *out_max_oper_chwidth = -1;
+    *out_center_freq      = 0;
+
+    switch (width) {
+    case NM_SETTING_WIRELESS_CHANNEL_WIDTH_40MHZ:
+        *out_ht40             = 1;
+        *out_max_oper_chwidth = 0;
+        return;
+    case NM_SETTING_WIRELESS_CHANNEL_WIDTH_80MHZ:
+    {
+        guint channel;
+
+        if (freq < 5000) {
+            /* the setting is not valid */
+            nm_assert_not_reached();
+            return;
+        }
+
+        /* Determine the center channel according to the table at
+         * https://en.wikipedia.org/wiki/List_of_WLAN_channels */
+        channel = (freq - 5000) / 5;
+        channel = ((channel / 4 - 1) / 4) * 16 + 10;
+
+        *out_ht40             = 1;
+        *out_max_oper_chwidth = 1;
+        *out_center_freq      = 5000 + 5 * channel;
+
+        return;
+    }
+
+    case NM_SETTING_WIRELESS_CHANNEL_WIDTH_AUTO:
+    case NM_SETTING_WIRELESS_CHANNEL_WIDTH_20MHZ:
+    default:
+        /* in case of unknown enum value, fall back to the safest parameters */
+        return;
+    }
+}
+
 gboolean
 nm_supplicant_config_add_setting_wireless(NMSupplicantConfig *self,
                                           NMSettingWireless  *setting,
@@ -562,10 +608,48 @@ nm_supplicant_config_add_setting_wireless(NMSupplicantConfig *self,
 
     if ((is_adhoc || is_ap || is_mesh) && fixed_freq) {
         gs_free char *str_freq = NULL;
+        guint         ht40;
+        int           max_oper_chwidth;
+        guint         center_freq;
 
         str_freq = g_strdup_printf("%u", fixed_freq);
         if (!nm_supplicant_config_add_option(self, "frequency", str_freq, -1, NULL, error))
             return FALSE;
+
+        if (is_ap) {
+            get_ap_params(fixed_freq,
+                          nm_setting_wireless_get_channel_width(setting),
+                          &ht40,
+                          &max_oper_chwidth,
+                          &center_freq);
+
+            if (!nm_supplicant_config_add_option(self, "ht40", ht40 ? "1" : "0", -1, NULL, error))
+                return FALSE;
+
+            if (center_freq != 0) {
+                g_free(str_freq);
+                str_freq = g_strdup_printf("%u", center_freq);
+                if (!nm_supplicant_config_add_option(self,
+                                                     "vht_center_freq1",
+                                                     str_freq,
+                                                     -1,
+                                                     NULL,
+                                                     error))
+                    return FALSE;
+            }
+
+            if (max_oper_chwidth >= 0) {
+                g_free(str_freq);
+                str_freq = g_strdup_printf("%u", max_oper_chwidth);
+                if (!nm_supplicant_config_add_option(self,
+                                                     "max_oper_chwidth",
+                                                     str_freq,
+                                                     -1,
+                                                     NULL,
+                                                     error))
+                    return FALSE;
+            }
+        }
     }
 
     /* Except for Ad-Hoc, Hotspot and Mesh, request that the driver probe for the
diff --git a/src/core/supplicant/nm-supplicant-settings-verify.c b/src/core/supplicant/nm-supplicant-settings-verify.c
index 76328541..6e5e44d2 100644
--- a/src/core/supplicant/nm-supplicant-settings-verify.c
+++ b/src/core/supplicant/nm-supplicant-settings-verify.c
@@ -73,6 +73,7 @@ static const struct Opt opt_table[] = {
     OPT_KEYWORD("freq_list", NULL),
     OPT_INT("frequency", 2412, 5825),
     OPT_KEYWORD("group", NM_MAKE_STRV("CCMP", "TKIP", "WEP104", "WEP40", "GCMP-256", )),
+    OPT_INT("ht40", 0, 1),
     OPT_BYTES("identity", 0),
     OPT_INT("ieee80211w", 0, 2),
     OPT_INT("ignore_broadcast_ssid", 0, 2),
@@ -99,6 +100,7 @@ static const struct Opt opt_table[] = {
     OPT_INT("macsec_offload", 0, 2),
     OPT_INT("macsec_policy", 0, 1),
     OPT_INT("macsec_port", 1, 65534),
+    OPT_INT("max_oper_chwidth", 0, 9),
     OPT_BYTES("mka_cak", 65536),
     OPT_BYTES("mka_ckn", 65536),
     OPT_BYTES("nai", 0),
@@ -155,6 +157,7 @@ static const struct Opt opt_table[] = {
     OPT_BYTES("ssid", 32),
     OPT_BYTES("subject_match", 0),
     OPT_BYTES("subject_match2", 0),
+    OPT_INT("vht_center_freq1", 0, 100000),
     OPT_BYTES("wep_key0", 0),
     OPT_BYTES("wep_key1", 0),
     OPT_BYTES("wep_key2", 0),
diff --git a/src/core/tests/config/NetworkManager.conf b/src/core/tests/config/NetworkManager.conf
index a447b6d6..ae9f3e46 100644
--- a/src/core/tests/config/NetworkManager.conf
+++ b/src/core/tests/config/NetworkManager.conf
@@ -9,6 +9,7 @@ level=INFO
 [connectivity]
 uri=http://example.com
 interval=100
+timeout=42
 response=Hello
 
 [extra-section]
diff --git a/src/core/tests/config/test-config.c b/src/core/tests/config/test-config.c
index 2b27d535..8365fc82 100644
--- a/src/core/tests/config/test-config.c
+++ b/src/core/tests/config/test-config.c
@@ -167,6 +167,9 @@ test_config_simple(void)
     g_assert_cmpint(nm_config_data_get_connectivity_interval(nm_config_get_data_orig(config)),
                     ==,
                     100);
+    g_assert_cmpint(nm_config_data_get_connectivity_timeout(nm_config_get_data_orig(config)),
+                    ==,
+                    42);
 
     plugins = nm_config_data_get_plugins(nm_config_get_data_orig(config), FALSE);
     g_assert_cmpint(g_strv_length((char **) plugins), ==, 3);