summary refs log tree commit diff
path: root/src/libnm-core-impl
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2025-08-01 19:15:13 +0200
committerMichael Biebl <biebl@debian.org>2025-08-01 19:15:13 +0200
commit7e9091a5960f67a84787c03153324915220e4816 (patch)
treedc743de962532932ebc3b4ed3a36ddd093d97d68 /src/libnm-core-impl
parent582eb4472a0f3375042afb9026cbeb50e058a27d (diff)
New upstream version 1.54.0 upstream/1.54.0
Diffstat (limited to 'src/libnm-core-impl')
-rw-r--r--src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in24
-rw-r--r--src/libnm-core-impl/meson.build1
-rw-r--r--src/libnm-core-impl/nm-connection.c2
-rw-r--r--src/libnm-core-impl/nm-keyfile.c2
-rw-r--r--src/libnm-core-impl/nm-meta-setting-base-impl.c9
-rw-r--r--src/libnm-core-impl/nm-setting-bond.c2
-rw-r--r--src/libnm-core-impl/nm-setting-connection.c2
-rw-r--r--src/libnm-core-impl/nm-setting-infiniband.c1
-rw-r--r--src/libnm-core-impl/nm-setting-ip-config.c53
-rw-r--r--src/libnm-core-impl/nm-setting-ipvlan.c13
-rw-r--r--src/libnm-core-impl/nm-setting-match.c9
-rw-r--r--src/libnm-core-impl/nm-setting-ovs-dpdk.c46
-rw-r--r--src/libnm-core-impl/nm-setting-ovs-external-ids.c2
-rw-r--r--src/libnm-core-impl/nm-setting-ovs-other-config.c4
-rw-r--r--src/libnm-core-impl/nm-setting-prefix-delegation.c118
-rw-r--r--src/libnm-core-impl/nm-setting-private.h3
-rw-r--r--src/libnm-core-impl/nm-setting-sriov.c47
-rw-r--r--src/libnm-core-impl/nm-setting-tun.c4
-rw-r--r--src/libnm-core-impl/nm-setting-user.c2
-rw-r--r--src/libnm-core-impl/nm-setting-wired.c2
-rw-r--r--src/libnm-core-impl/nm-setting-wireless.c2
-rw-r--r--src/libnm-core-impl/nm-utils.c18
-rw-r--r--src/libnm-core-impl/tests/test-general.c61
23 files changed, 369 insertions, 58 deletions
diff --git a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in
index e0ce4ac4..c764f535 100644
--- a/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in
+++ b/src/libnm-core-impl/gen-metadata-nm-settings-libnm-core.xml.in
@@ -1712,6 +1712,10 @@
                   dbus-type="as"
                   gprop-type="GStrv"
                   />
+        <property name="forwarding"
+                  dbus-type="i"
+                  gprop-type="gint"
+                  />
         <property name="gateway"
                   dbus-type="s"
                   gprop-type="gchararray"
@@ -1867,6 +1871,10 @@
                   dbus-type="as"
                   gprop-type="GStrv"
                   />
+        <property name="forwarding"
+                  dbus-type="i"
+                  gprop-type="gint"
+                  />
         <property name="gateway"
                   dbus-type="s"
                   gprop-type="gchararray"
@@ -2120,6 +2128,10 @@
                   dbus-type="s"
                   gprop-type="gchararray"
                   />
+        <property name="lsc-interrupt"
+                  dbus-type="i"
+                  gprop-type="gint"
+                  />
         <property name="n-rxq"
                   dbus-type="u"
                   gprop-type="guint"
@@ -2303,6 +2315,14 @@
                   gprop-type="gchararray"
                   />
     </setting>
+    <setting name="prefix-delegation"
+             gtype="NMSettingPrefixDelegation"
+             >
+        <property name="subnet-id"
+                  dbus-type="x"
+                  gprop-type="gint64"
+                  />
+    </setting>
     <setting name="proxy"
              gtype="NMSettingProxy"
              >
@@ -2366,6 +2386,10 @@
                   dbus-type="i"
                   gprop-type="gint"
                   />
+        <property name="preserve-on-down"
+                  dbus-type="i"
+                  gprop-type="gint"
+                  />
         <property name="total-vfs"
                   dbus-type="u"
                   gprop-type="guint"
diff --git a/src/libnm-core-impl/meson.build b/src/libnm-core-impl/meson.build
index e068d6bd..610e2279 100644
--- a/src/libnm-core-impl/meson.build
+++ b/src/libnm-core-impl/meson.build
@@ -41,6 +41,7 @@ libnm_core_settings_sources = files(
   'nm-setting-ovs-port.c',
   'nm-setting-ppp.c',
   'nm-setting-pppoe.c',
+  'nm-setting-prefix-delegation.c',
   'nm-setting-proxy.c',
   'nm-setting-serial.c',
   'nm-setting-sriov.c',
diff --git a/src/libnm-core-impl/nm-connection.c b/src/libnm-core-impl/nm-connection.c
index 61a20a13..0fbadfb8 100644
--- a/src/libnm-core-impl/nm-connection.c
+++ b/src/libnm-core-impl/nm-connection.c
@@ -3359,6 +3359,8 @@ nm_connection_get_virtual_device_description(NMConnection *connection)
         display_type = _("TUN/TAP");
     else if (nm_streq(type, NM_SETTING_VETH_SETTING_NAME))
         display_type = _("Veth");
+    else if (nm_streq(type, NM_SETTING_LOOPBACK_SETTING_NAME))
+        display_type = _("Loopback");
 
     if (!iface || !display_type)
         return NULL;
diff --git a/src/libnm-core-impl/nm-keyfile.c b/src/libnm-core-impl/nm-keyfile.c
index e4559e3c..f8f735e9 100644
--- a/src/libnm-core-impl/nm-keyfile.c
+++ b/src/libnm-core-impl/nm-keyfile.c
@@ -1684,7 +1684,7 @@ nm_keyfile_detect_unqualified_path_scheme(const char   *base_dir,
         const char *const _bin     = (bin);                             \
         const gsize       _bin_len = (bin_len);                         \
                                                                         \
-        nm_assert(_bin &&_bin_len > 0);                                 \
+        nm_assert(_bin && _bin_len > 0);                                \
                                                                         \
         (_bin_len > NM_STRLEN(scheme) + 1 && _bin[_bin_len - 1] == '\0' \
          && memcmp(_bin, scheme, NM_STRLEN(scheme)) == 0);              \
diff --git a/src/libnm-core-impl/nm-meta-setting-base-impl.c b/src/libnm-core-impl/nm-meta-setting-base-impl.c
index b9dcf34f..52af9ad2 100644
--- a/src/libnm-core-impl/nm-meta-setting-base-impl.c
+++ b/src/libnm-core-impl/nm-meta-setting-base-impl.c
@@ -51,6 +51,7 @@
 #include "nm-setting-ovs-port.h"
 #include "nm-setting-ppp.h"
 #include "nm-setting-pppoe.h"
+#include "nm-setting-prefix-delegation.h"
 #include "nm-setting-proxy.h"
 #include "nm-setting-serial.h"
 #include "nm-setting-tc-config.h"
@@ -484,6 +485,13 @@ const NMMetaSettingInfo nm_meta_setting_infos[] = {
             .setting_name      = NM_SETTING_PPP_SETTING_NAME,
             .get_setting_gtype = nm_setting_ppp_get_type,
         },
+    [NM_META_SETTING_TYPE_PREFIX_DELEGATION] =
+        {
+            .meta_type         = NM_META_SETTING_TYPE_PREFIX_DELEGATION,
+            .setting_priority  = NM_SETTING_PRIORITY_IP,
+            .setting_name      = NM_SETTING_PREFIX_DELEGATION_SETTING_NAME,
+            .get_setting_gtype = nm_setting_prefix_delegation_get_type,
+        },
     [NM_META_SETTING_TYPE_PROXY] =
         {
             .meta_type         = NM_META_SETTING_TYPE_PROXY,
@@ -698,6 +706,7 @@ const NMMetaSettingType nm_meta_setting_types_by_priority[] = {
     NM_META_SETTING_TYPE_HOSTNAME,
     NM_META_SETTING_TYPE_IP4_CONFIG,
     NM_META_SETTING_TYPE_IP6_CONFIG,
+    NM_META_SETTING_TYPE_PREFIX_DELEGATION,
     NM_META_SETTING_TYPE_PROXY,
     NM_META_SETTING_TYPE_TC_CONFIG,
 
diff --git a/src/libnm-core-impl/nm-setting-bond.c b/src/libnm-core-impl/nm-setting-bond.c
index 60ae0294..7204df48 100644
--- a/src/libnm-core-impl/nm-setting-bond.c
+++ b/src/libnm-core-impl/nm-setting-bond.c
@@ -1118,7 +1118,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
                     NM_CONNECTION_ERROR,
                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
                     _("'%s' option is only valid with mode '%s'"),
-                    NM_SETTING_BOND_OPTION_LACP_RATE,
+                    NM_SETTING_BOND_OPTION_LACP_ACTIVE,
                     "802.3ad");
         g_prefix_error(error, "%s.%s: ", NM_SETTING_BOND_SETTING_NAME, NM_SETTING_BOND_OPTIONS);
         return FALSE;
diff --git a/src/libnm-core-impl/nm-setting-connection.c b/src/libnm-core-impl/nm-setting-connection.c
index 4a910c7f..4829dcdc 100644
--- a/src/libnm-core-impl/nm-setting-connection.c
+++ b/src/libnm-core-impl/nm-setting-connection.c
@@ -2533,7 +2533,7 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass)
      * NMSettingConnection:stable-id:
      *
      * This represents the identity of the connection used for various purposes.
-     * It allows to configure multiple profiles to share the identity. Also,
+     * It allows configuring multiple profiles to share the identity. Also,
      * the stable-id can contain placeholders that are substituted dynamically and
      * deterministically depending on the context.
      *
diff --git a/src/libnm-core-impl/nm-setting-infiniband.c b/src/libnm-core-impl/nm-setting-infiniband.c
index 24e5807a..b70247c1 100644
--- a/src/libnm-core-impl/nm-setting-infiniband.c
+++ b/src/libnm-core-impl/nm-setting-infiniband.c
@@ -212,6 +212,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
                                 NM_CONNECTION_ERROR_INVALID_PROPERTY,
                                 _("Must specify a P_Key if specifying parent"));
             g_prefix_error(error, "%s: ", NM_SETTING_INFINIBAND_PARENT);
+            return FALSE;
         }
     }
 
diff --git a/src/libnm-core-impl/nm-setting-ip-config.c b/src/libnm-core-impl/nm-setting-ip-config.c
index 1ec97029..ad95eb1a 100644
--- a/src/libnm-core-impl/nm-setting-ip-config.c
+++ b/src/libnm-core-impl/nm-setting-ip-config.c
@@ -4009,7 +4009,8 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMSettingIPConfig,
                              PROP_DHCP_SEND_RELEASE,
                              PROP_ROUTED_DNS,
                              PROP_SHARED_DHCP_RANGE,
-                             PROP_SHARED_DHCP_LEASE_TIME, );
+                             PROP_SHARED_DHCP_LEASE_TIME,
+                             PROP_FORWARDING, );
 
 G_DEFINE_ABSTRACT_TYPE(NMSettingIPConfig, nm_setting_ip_config, NM_TYPE_SETTING)
 
@@ -5559,6 +5560,22 @@ nm_setting_ip_config_get_shared_dhcp_lease_time(NMSettingIPConfig *setting)
     return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->shared_dhcp_lease_time;
 }
 
+/**
+ * nm_setting_ip_config_get_forwarding:
+ * @setting: the #NMSettingIPConfig
+ *
+ * Returns: the #NMSettingIPConfig:forwarding property of the setting
+ *
+ * Since: 1.54
+ **/
+NMSettingIPConfigForwarding
+nm_setting_ip_config_get_forwarding(NMSettingIPConfig *setting)
+{
+    g_return_val_if_fail(NM_IS_SETTING_IP_CONFIG(setting), NM_SETTING_IP_CONFIG_FORWARDING_DEFAULT);
+
+    return NM_SETTING_IP_CONFIG_GET_PRIVATE(setting)->forwarding;
+}
+
 static gboolean
 verify_label(const char *label)
 {
@@ -6337,6 +6354,13 @@ _nm_sett_info_property_override_create_array_ip_config(int addr_family)
         .direct_offset =
             NM_STRUCT_OFFSET_ENSURE_TYPE(gint32, NMSettingIPConfigPrivate, shared_dhcp_lease_time));
 
+    _nm_properties_override_gobj(
+        properties_override,
+        obj_properties[PROP_FORWARDING],
+        &nm_sett_info_propert_type_direct_enum,
+        .direct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE(int, NMSettingIPConfigPrivate, forwarding),
+        .direct_data.enum_gtype = NM_TYPE_SETTING_IP_CONFIG_FORWARDING);
+
     return properties_override;
 }
 
@@ -7120,6 +7144,33 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass)
                          NM_SETTING_IP_CONFIG_ROUTED_DNS_DEFAULT,
                          G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
 
+    /**
+     * NMSettingIPConfig:forwarding:
+     *
+     * Whether to configure sysctl interface-specific forwarding. When enabled, the interface
+     * will act as a router to forward the packet from one interface to another. When set to
+     * %NM_SETTING_IP_CONFIG_FORWARDING_DEFAULT, the value from global configuration is used;
+     * if no global default is defined, %NM_SETTING_IP_CONFIG_FORWARDING_AUTO will be used.
+     * The #NMSettingIPConfig:forwarding property is ignored when #NMSettingIPConfig:method
+     * is set to "shared", because forwarding is always enabled in this case.
+     * The accepted values are:
+     *   %NM_SETTING_IP_CONFIG_FORWARDING_DEFAULT: use global default.
+     *   %NM_SETTING_IP_CONFIG_FORWARDING_NO: disabled.
+     *   %NM_SETTING_IP_CONFIG_FORWARDING_YES: enabled.
+     *   %NM_SETTING_IP_CONFIG_FORWARDING_AUTO: enable if any shared connection is active,
+     *        use kernel default otherwise.
+     *
+     * Since: 1.54
+     */
+    obj_properties[PROP_FORWARDING] =
+        g_param_spec_int(NM_SETTING_IP_CONFIG_FORWARDING,
+                         "",
+                         "",
+                         NM_SETTING_IP_CONFIG_FORWARDING_DEFAULT,
+                         NM_SETTING_IP_CONFIG_FORWARDING_AUTO,
+                         NM_SETTING_IP_CONFIG_FORWARDING_DEFAULT,
+                         G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
     /**                                                  
      * NMSettingIPConfig:dhcp-send-hostname-v2:
      *
diff --git a/src/libnm-core-impl/nm-setting-ipvlan.c b/src/libnm-core-impl/nm-setting-ipvlan.c
index fafa37b6..0468e31f 100644
--- a/src/libnm-core-impl/nm-setting-ipvlan.c
+++ b/src/libnm-core-impl/nm-setting-ipvlan.c
@@ -156,6 +156,19 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
         }
     }
 
+    if (!NM_IN_SET(priv->mode,
+                   NM_SETTING_IPVLAN_MODE_L2,
+                   NM_SETTING_IPVLAN_MODE_L3,
+                   NM_SETTING_IPVLAN_MODE_L3S)) {
+        g_set_error(error,
+                    NM_CONNECTION_ERROR,
+                    NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                    _("unsupported mode %u"),
+                    priv->mode);
+        g_prefix_error(error, "%s.%s: ", NM_SETTING_IPVLAN_SETTING_NAME, NM_SETTING_IPVLAN_MODE);
+        return FALSE;
+    }
+
     if (priv->private_flag && priv->vepa) {
         g_set_error(error,
                     NM_CONNECTION_ERROR,
diff --git a/src/libnm-core-impl/nm-setting-match.c b/src/libnm-core-impl/nm-setting-match.c
index 255283fc..dc743b15 100644
--- a/src/libnm-core-impl/nm-setting-match.c
+++ b/src/libnm-core-impl/nm-setting-match.c
@@ -309,9 +309,10 @@ nm_setting_match_clear_kernel_command_lines(NMSettingMatch *setting)
  * @setting: the #NMSettingMatch
  * @length: (out) (optional): the length of the returned interface names array.
  *
- * Returns all the interface names.
+ * Returns all the kernel command line arguments.
  *
- * Returns: (transfer none) (array length=length): the configured interface names.
+ * Returns: (transfer none) (array length=length): the configured kernel command
+ *    line arguments.
  *
  * Since: 1.26
  **/
@@ -344,7 +345,7 @@ nm_setting_match_get_num_drivers(NMSettingMatch *setting)
 /**
  * nm_setting_match_get_driver:
  * @setting: the #NMSettingMatch
- * @idx: index number of the DNS search domain to return
+ * @idx: index number of the driver to return
  *
  * Since 1.46, access at index "len" is allowed and returns NULL.
  *
@@ -443,7 +444,7 @@ nm_setting_match_clear_drivers(NMSettingMatch *setting)
 /**
  * nm_setting_match_get_drivers:
  * @setting: the #NMSettingMatch
- * @length: (out) (optional): the length of the returned interface names array.
+ * @length: (out) (optional): the length of the returned drivers array.
  *
  * Returns all the drivers.
  *
diff --git a/src/libnm-core-impl/nm-setting-ovs-dpdk.c b/src/libnm-core-impl/nm-setting-ovs-dpdk.c
index 53931f46..3f5cbe11 100644
--- a/src/libnm-core-impl/nm-setting-ovs-dpdk.c
+++ b/src/libnm-core-impl/nm-setting-ovs-dpdk.c
@@ -22,7 +22,11 @@
 
 /*****************************************************************************/
 
-NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_DEVARGS, PROP_N_RXQ, PROP_N_RXQ_DESC, PROP_N_TXQ_DESC, );
+NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_DEVARGS,
+                                  PROP_N_RXQ,
+                                  PROP_N_RXQ_DESC,
+                                  PROP_N_TXQ_DESC,
+                                  PROP_LSC_INTERRUPT, );
 
 /**
  * NMSettingOvsDpdk:
@@ -36,6 +40,7 @@ struct _NMSettingOvsDpdk {
     guint32 n_rxq;
     guint32 n_rxq_desc;
     guint32 n_txq_desc;
+    int     lsc_interrupt;
 };
 
 struct _NMSettingOvsDpdkClass {
@@ -110,6 +115,22 @@ nm_setting_ovs_dpdk_get_n_txq_desc(NMSettingOvsDpdk *self)
     return self->n_txq_desc;
 }
 
+/**
+ * nm_setting_ovs_dpdk_get_lsc_interrupt:
+ * @self: the #NMSettingOvsDpdk
+ *
+ * Returns: the #NMSettingOvsDpdk:lsc-interrupt property of the setting
+ *
+ * Since: 1.54
+ **/
+NMSettingOvsDpdkLscInterrupt
+nm_setting_ovs_dpdk_get_lsc_interrupt(NMSettingOvsDpdk *self)
+{
+    g_return_val_if_fail(NM_IS_SETTING_OVS_DPDK(self), NM_SETTING_OVS_DPDK_LSC_INTERRUPT_IGNORE);
+
+    return self->lsc_interrupt;
+}
+
 /*****************************************************************************/
 
 static gboolean
@@ -257,6 +278,29 @@ nm_setting_ovs_dpdk_class_init(NMSettingOvsDpdkClass *klass)
                                               NMSettingOvsDpdk,
                                               n_txq_desc);
 
+    /**
+     * NMSettingOvsDpdk:lsc-interrupt:
+     *
+     * Configures the Link State Change (LSC) detection mode for the OVS DPDK interface.
+     * When set to %NM_SETTING_OVS_DPDK_LSC_INTERRUPT_IGNORE, NetworkManager doesn't
+     * change the default value configured by Open vSwitch.
+     * %NM_SETTING_OVS_DPDK_LSC_INTERRUPT_ENABLED enables interrupts.
+     * %NM_SETTING_OVS_DPDK_LSC_INTERRUPT_DISABLED disables interrupts, thus setting the
+     * interface in poll mode.
+     *
+     * Since: 1.54
+     **/
+    _nm_setting_property_define_direct_enum(properties_override,
+                                            obj_properties,
+                                            NM_SETTING_OVS_DPDK_LSC_INTERRUPT,
+                                            PROP_LSC_INTERRUPT,
+                                            NM_TYPE_SETTING_OVS_DPDK_LSC_INTERRUPT,
+                                            NM_SETTING_OVS_DPDK_LSC_INTERRUPT_IGNORE,
+                                            NM_SETTING_PARAM_NONE,
+                                            NULL,
+                                            NMSettingOvsDpdk,
+                                            lsc_interrupt);
+
     g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
 
     _nm_setting_class_commit(setting_class,
diff --git a/src/libnm-core-impl/nm-setting-ovs-external-ids.c b/src/libnm-core-impl/nm-setting-ovs-external-ids.c
index 9acdae6c..22448e68 100644
--- a/src/libnm-core-impl/nm-setting-ovs-external-ids.c
+++ b/src/libnm-core-impl/nm-setting-ovs-external-ids.c
@@ -20,7 +20,7 @@
  * SECTION:nm-setting-ovs-external-ids
  * @short_description: External-IDs for OVS database
  *
- * The #NMSettingOvsExternalIDs object is a #NMSetting subclass that allow to
+ * The #NMSettingOvsExternalIDs object is a #NMSetting subclass that allows one to
  * configure external ids for OVS.
  **/
 
diff --git a/src/libnm-core-impl/nm-setting-ovs-other-config.c b/src/libnm-core-impl/nm-setting-ovs-other-config.c
index 46d991d4..392fc46b 100644
--- a/src/libnm-core-impl/nm-setting-ovs-other-config.c
+++ b/src/libnm-core-impl/nm-setting-ovs-other-config.c
@@ -19,8 +19,8 @@
  * SECTION:nm-setting-ovs-other-config
  * @short_description: Other-config settings for OVS
  *
- * The #NMSettingOvsOtherConfig object is a #NMSetting subclass that allows to
- * configure other_config settings for OVS. See also "other_config" in the
+ * The #NMSettingOvsOtherConfig object is a #NMSetting subclass that specifies
+ * "other_config" settings for OVS. See also "other_config" in the
  * "ovs-vswitchd.conf.db" manual for the keys that OVS supports.
  **/
 
diff --git a/src/libnm-core-impl/nm-setting-prefix-delegation.c b/src/libnm-core-impl/nm-setting-prefix-delegation.c
new file mode 100644
index 00000000..100d3153
--- /dev/null
+++ b/src/libnm-core-impl/nm-setting-prefix-delegation.c
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "libnm-core-impl/nm-default-libnm-core.h"
+
+#include "nm-setting-prefix-delegation.h"
+
+#include "nm-connection-private.h"
+#include "nm-setting-connection.h"
+#include "nm-setting-private.h"
+
+/**
+ * SECTION:nm-setting-prefix-delegation
+ * @short_description: Describes connection properties related to IPv6 prefix delegation
+ *
+ * The #NMSettingPrefixDelegation object is a #NMSetting subclass that describes the
+ * configuration of downstream interfaces using IPv6 prefix delegation.
+ **/
+
+/*****************************************************************************/
+
+NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_SUBNET_ID, );
+
+/**
+ * NMSettingPrefixDelegation:
+ *
+ * IPv6 prefix delegation settings
+ *
+ * Since: 1.54
+ */
+struct _NMSettingPrefixDelegation {
+    NMSetting parent;
+    gint64    subnet_id;
+};
+
+struct _NMSettingPrefixDelegationClass {
+    NMSettingClass parent;
+};
+
+G_DEFINE_TYPE(NMSettingPrefixDelegation, nm_setting_prefix_delegation, NM_TYPE_SETTING)
+
+/*****************************************************************************/
+
+/**
+ * nm_setting_prefix_delegation_get_subnet_id:
+ * @setting: the #NMSettingPrefixDelegation
+ *
+ * Returns: the subnet ID for prefix delegation
+ *
+ * Since: 1.54
+ **/
+gint64
+nm_setting_prefix_delegation_get_subnet_id(NMSettingPrefixDelegation *setting)
+{
+    g_return_val_if_fail(NM_IS_SETTING_PREFIX_DELEGATION(setting), 0);
+
+    return setting->subnet_id;
+}
+
+/*****************************************************************************/
+
+static void
+nm_setting_prefix_delegation_init(NMSettingPrefixDelegation *setting)
+{}
+
+/**
+ * nm_setting_prefix_delegation_new:
+ *
+ * Creates a new #NMSettingPrefixDelegation object with default values.
+ *
+ * Returns: (transfer full): the new empty #NMSettingPrefixDelegation object
+ *
+ * Since: 1.54
+ **/
+NMSetting *
+nm_setting_prefix_delegation_new(void)
+{
+    return g_object_new(NM_TYPE_SETTING_PREFIX_DELEGATION, NULL);
+}
+
+static void
+nm_setting_prefix_delegation_class_init(NMSettingPrefixDelegationClass *klass)
+{
+    GObjectClass   *object_class        = G_OBJECT_CLASS(klass);
+    NMSettingClass *setting_class       = NM_SETTING_CLASS(klass);
+    GArray         *properties_override = _nm_sett_info_property_override_create_array();
+
+    object_class->get_property = _nm_setting_property_get_property_direct;
+    object_class->set_property = _nm_setting_property_set_property_direct;
+
+    /**
+     * NMSettingPrefixDelegation:subnet-id:
+     *
+     * The subnet ID to use on the interface from the prefix delegation received via
+     * an upstream interface. Set to a value between 0 and 0xffffffff (2^32 - 1)
+     * to indicate a specific subnet ID; or set to -1 to automatically choose
+     * an available subnet ID.
+     *
+     * Since: 1.54
+     **/
+    _nm_setting_property_define_direct_int64(properties_override,
+                                             obj_properties,
+                                             NM_SETTING_PREFIX_DELEGATION_SUBNET_ID,
+                                             PROP_SUBNET_ID,
+                                             -1,
+                                             G_MAXUINT32,
+                                             -1,
+                                             NM_SETTING_PARAM_NONE,
+                                             NMSettingPrefixDelegation,
+                                             subnet_id);
+
+    g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+
+    _nm_setting_class_commit(setting_class,
+                             NM_META_SETTING_TYPE_PREFIX_DELEGATION,
+                             NULL,
+                             properties_override,
+                             0);
+}
diff --git a/src/libnm-core-impl/nm-setting-private.h b/src/libnm-core-impl/nm-setting-private.h
index ba838364..8ee770f4 100644
--- a/src/libnm-core-impl/nm-setting-private.h
+++ b/src/libnm-core-impl/nm-setting-private.h
@@ -193,6 +193,7 @@ typedef struct {
     int         replace_local_rule;
     int         dhcp_send_release;
     int         routed_dns;
+    int         forwarding;
     int         dhcp_send_hostname_v2;
     gint32      required_timeout;
     gint32      dad_timeout;
@@ -555,7 +556,7 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p
  *
  *    _nm_setting_get_private(setting, sett_info, property_info->direct_offset)
  *
- * which allows to generically handle the property operations (like get, set, compare).
+ * which allows one to generically handle the property operations (like get, set, compare).
  */
 
 #define _nm_setting_property_define_direct_boolean(properties_override,                        \
diff --git a/src/libnm-core-impl/nm-setting-sriov.c b/src/libnm-core-impl/nm-setting-sriov.c
index 4dc61d82..d6be0ec1 100644
--- a/src/libnm-core-impl/nm-setting-sriov.c
+++ b/src/libnm-core-impl/nm-setting-sriov.c
@@ -22,6 +22,7 @@
 NM_GOBJECT_PROPERTIES_DEFINE(NMSettingSriov,
                              PROP_TOTAL_VFS,
                              PROP_VFS,
+                             PROP_PRESERVE_ON_DOWN,
                              PROP_AUTOPROBE_DRIVERS,
                              PROP_ESWITCH_MODE,
                              PROP_ESWITCH_INLINE_MODE,
@@ -39,6 +40,7 @@ struct _NMSettingSriov {
     GPtrArray *vfs;
     int        autoprobe_drivers;
     guint32    total_vfs;
+    int        preserve_on_down;
     int        eswitch_mode;
     int        eswitch_inline_mode;
     int        eswitch_encap_mode;
@@ -827,6 +829,22 @@ nm_setting_sriov_clear_vfs(NMSettingSriov *setting)
 }
 
 /**
+ * nm_setting_sriov_get_preserve_on_down:
+ * @setting: the #NMSettingSriov
+ *
+ * Returns: the value contained in the #NMSettingSriov:preserve-on-down property.
+ *
+ * Since: 1.54
+ */
+NMSriovPreserveOnDown
+nm_setting_sriov_get_preserve_on_down(NMSettingSriov *setting)
+{
+    g_return_val_if_fail(NM_IS_SETTING_SRIOV(setting), NM_SRIOV_PRESERVE_ON_DOWN_DEFAULT);
+
+    return setting->preserve_on_down;
+}
+
+/**
  * nm_setting_sriov_get_autoprobe_drivers:
  * @setting: the #NMSettingSriov
  *
@@ -1462,6 +1480,35 @@ nm_setting_sriov_class_init(NMSettingSriovClass *klass)
                                             NMSettingSriov,
                                             eswitch_encap_mode);
 
+    /**
+     * NMSettingSriov:preserve-on-down
+     *
+     * This controls whether NetworkManager preserves the SR-IOV parameters set on
+     * the device when the connection is deactivated, or whether it resets them to
+     * their default value. The SR-IOV parameters are those specified in this setting
+     * (the "sriov" setting), like the number of VFs to create, the eswitch
+     * configuration, etc.
+     *
+     * If set to %NM_SRIOV_PRESERVE_ON_DOWN_NO, NetworkManager resets the SR-IOV
+     * parameters when the connection is deactivated. When set to
+     * %NM_SRIOV_PRESERVE_ON_DOWN_YES, NetworkManager preserves those parameters
+     * on the device. If the value is %NM_SRIOV_PRESERVE_ON_DOWN_DEFAULT, NetworkManager
+     * looks up a global default value in the configuration; in case no such value is
+     * defined, it uses %NM_SRIOV_PRESERVE_ON_DOWN_NO as fallback.
+     *
+     * Since: 1.54
+     */
+    _nm_setting_property_define_direct_enum(properties_override,
+                                            obj_properties,
+                                            NM_SETTING_SRIOV_PRESERVE_ON_DOWN,
+                                            PROP_PRESERVE_ON_DOWN,
+                                            NM_TYPE_SRIOV_PRESERVE_ON_DOWN,
+                                            NM_SRIOV_PRESERVE_ON_DOWN_DEFAULT,
+                                            NM_SETTING_PARAM_FUZZY_IGNORE,
+                                            NULL,
+                                            NMSettingSriov,
+                                            preserve_on_down);
+
     g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
 
     _nm_setting_class_commit(setting_class,
diff --git a/src/libnm-core-impl/nm-setting-tun.c b/src/libnm-core-impl/nm-setting-tun.c
index 05460104..cac0f10b 100644
--- a/src/libnm-core-impl/nm-setting-tun.c
+++ b/src/libnm-core-impl/nm-setting-tun.c
@@ -166,7 +166,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
     }
 
     if (priv->owner) {
-        if (_nm_utils_ascii_str_to_int64(priv->owner, 10, 0, G_MAXINT32, -1) == -1) {
+        if (_nm_utils_ascii_str_to_int64(priv->owner, 10, 0, G_MAXUINT32 - 1, -1) == -1) {
             g_set_error(error,
                         NM_CONNECTION_ERROR,
                         NM_CONNECTION_ERROR_INVALID_PROPERTY,
@@ -178,7 +178,7 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
     }
 
     if (priv->group) {
-        if (_nm_utils_ascii_str_to_int64(priv->group, 10, 0, G_MAXINT32, -1) == -1) {
+        if (_nm_utils_ascii_str_to_int64(priv->group, 10, 0, G_MAXUINT32 - 1, -1) == -1) {
             g_set_error(error,
                         NM_CONNECTION_ERROR,
                         NM_CONNECTION_ERROR_INVALID_PROPERTY,
diff --git a/src/libnm-core-impl/nm-setting-user.c b/src/libnm-core-impl/nm-setting-user.c
index 8c2a9942..69f73a8d 100644
--- a/src/libnm-core-impl/nm-setting-user.c
+++ b/src/libnm-core-impl/nm-setting-user.c
@@ -15,7 +15,7 @@
  * SECTION:nm-setting-user
  * @short_description: Describes user properties
  *
- * The #NMSettingUser object is a #NMSetting subclass that allow to attach
+ * The #NMSettingUser object is a #NMSetting subclass that allows one to attach
  * arbitrary user data to #NMConnection objects.
  **/
 
diff --git a/src/libnm-core-impl/nm-setting-wired.c b/src/libnm-core-impl/nm-setting-wired.c
index e02c0a06..b80d0142 100644
--- a/src/libnm-core-impl/nm-setting-wired.c
+++ b/src/libnm-core-impl/nm-setting-wired.c
@@ -1575,7 +1575,7 @@ nm_setting_wired_class_init(NMSettingWiredClass *klass)
      *
      * With #NMSettingWired:cloned-mac-address setting "random" or "stable",
      * by default all bits of the MAC address are scrambled and a locally-administered,
-     * unicast MAC address is created. This property allows to specify that certain bits
+     * unicast MAC address is created. This property allows one to specify that certain bits
      * are fixed. Note that the least significant bit of the first MAC address will
      * always be unset to create a unicast MAC address.
      *
diff --git a/src/libnm-core-impl/nm-setting-wireless.c b/src/libnm-core-impl/nm-setting-wireless.c
index be08fa8c..1c5486bf 100644
--- a/src/libnm-core-impl/nm-setting-wireless.c
+++ b/src/libnm-core-impl/nm-setting-wireless.c
@@ -1886,7 +1886,7 @@ nm_setting_wireless_class_init(NMSettingWirelessClass *klass)
      *
      * With #NMSettingWireless:cloned-mac-address setting "random" or "stable",
      * by default all bits of the MAC address are scrambled and a locally-administered,
-     * unicast MAC address is created. This property allows to specify that certain bits
+     * unicast MAC address is created. This property allows one to specify that certain bits
      * are fixed. Note that the least significant bit of the first MAC address will
      * always be unset to create a unicast MAC address.
      *
diff --git a/src/libnm-core-impl/nm-utils.c b/src/libnm-core-impl/nm-utils.c
index 6528b5fb..6d5df98c 100644
--- a/src/libnm-core-impl/nm-utils.c
+++ b/src/libnm-core-impl/nm-utils.c
@@ -1345,7 +1345,7 @@ nm_utils_ip4_dns_from_variant(GVariant *value)
  * @strict: whether to parse in strict mode or best-effort mode
  * @error: the error location
  *
- * Like #nm_utils_ip4_dns_from_variant, but allows to parse in strict mode. In
+ * Like #nm_utils_ip4_dns_from_variant, but allows one to parse in strict mode. In
  * strict mode, parsing is aborted on first error and %NULL is returned.
  *
  * Returns: (transfer full) (type utf8): a %NULL-terminated array of IP address
@@ -1467,9 +1467,9 @@ nm_utils_ip4_addresses_from_variant(GVariant *value, char **out_gateway)
  * @strict: whether to parse in strict mode or best-effort mode
  * @error: the error location
  *
- * Like #nm_utils_ip4_addresses_from_variant, but allows to parse in strict mode. In
+ * Like #nm_utils_ip4_addresses_from_variant, but allows one to parse in strict mode. In
  * strict mode, parsing is aborted on first error and %NULL is returned. It also
- * allows to parse the address-labels at the same time than the addresses.
+ * allows one to parse the address-labels at the same time than the addresses.
  *
  * The labels need to be processed at the same time than the addresses, inside
  * this function, because if there are invalid addresses they are filtered out,
@@ -1648,7 +1648,7 @@ nm_utils_ip4_routes_from_variant(GVariant *value)
  * @strict: whether to parse in strict mode or best-effort mode
  * @error: the error location
  *
- * Like #nm_utils_ip4_routes_from_variant, but allows to parse in strict mode. In
+ * Like #nm_utils_ip4_routes_from_variant, but allows one to parse in strict mode. In
  * strict mode, parsing is aborted on first error and %NULL is returned.
  *
  * Returns: (transfer full) (element-type NMIPRoute): a newly allocated
@@ -1799,7 +1799,7 @@ nm_utils_ip6_dns_from_variant(GVariant *value)
  * @strict: whether to parse in strict mode or best-effort mode
  * @error: the error location
  *
- * Like #nm_utils_ip6_dns_from_variant, but allows to parse in strict mode. In
+ * Like #nm_utils_ip6_dns_from_variant, but allows one to parse in strict mode. In
  * strict mode, parsing is aborted on first error and %NULL is returned.
  *
  * Returns: (transfer full) (type utf8): a %NULL-terminated array of IP address
@@ -1942,7 +1942,7 @@ nm_utils_ip6_addresses_from_variant(GVariant *value, char **out_gateway)
  * @strict: whether to parse in strict mode or best-effort mode
  * @error: the error location
  *
- * Like #nm_utils_ip6_addresses_from_variant, but allows to parse in strict mode. In
+ * Like #nm_utils_ip6_addresses_from_variant, but allows one to parse in strict mode. In
  * strict mode, parsing is aborted on first error and %NULL is returned.
  *
  * Returns: (transfer full) (element-type NMIPAddress): a newly allocated
@@ -2124,7 +2124,7 @@ nm_utils_ip6_routes_from_variant(GVariant *value)
  * @strict: whether to parse in strict mode or best-effort mode
  * @error: the error location
  *
- * Like #nm_utils_ip6_routes_from_variant, but allows to parse in strict mode. In
+ * Like #nm_utils_ip6_routes_from_variant, but allows one to parse in strict mode. In
  * strict mode, parsing is aborted on first error and %NULL is returned.
  *
  * Returns: (transfer full) (element-type NMIPRoute): a newly allocated
@@ -2315,7 +2315,7 @@ nm_utils_ip_addresses_from_variant(GVariant *value, int family)
  * @strict: whether to parse in strict mode or best-effort mode
  * @error: the error location
  *
- * Like #nm_utils_ip_addresses_from_variant, but allows to parse in strict mode. In
+ * Like #nm_utils_ip_addresses_from_variant, but allows one to parse in strict mode. In
  * strict mode, parsing is aborted on first error and %NULL is returned.
  *
  * Returns: (transfer full) (element-type NMIPAddress): a newly allocated
@@ -2493,7 +2493,7 @@ nm_utils_ip_routes_from_variant(GVariant *value, int family)
  * @strict: whether to parse in strict mode or best-effort mode
  * @error: the error location
  *
- * Like #nm_utils_ip_routes_from_variant, but allows to parse in strict mode. In
+ * Like #nm_utils_ip_routes_from_variant, but allows one to parse in strict mode. In
  * strict mode, parsing is aborted on first error and %NULL is returned.
  *
  * Returns: (transfer full) (element-type NMIPRoute): a newly allocated
diff --git a/src/libnm-core-impl/tests/test-general.c b/src/libnm-core-impl/tests/test-general.c
index d581fc79..43e73c3d 100644
--- a/src/libnm-core-impl/tests/test-general.c
+++ b/src/libnm-core-impl/tests/test-general.c
@@ -4099,6 +4099,7 @@ test_connection_diff_a_only(void)
              {NM_SETTING_IP_CONFIG_ROUTED_DNS, NM_SETTING_DIFF_RESULT_IN_A},
              {NM_SETTING_IP_CONFIG_SHARED_DHCP_RANGE, NM_SETTING_DIFF_RESULT_IN_A},
              {NM_SETTING_IP_CONFIG_SHARED_DHCP_LEASE_TIME, NM_SETTING_DIFF_RESULT_IN_A},
+             {NM_SETTING_IP_CONFIG_FORWARDING, NM_SETTING_DIFF_RESULT_IN_A},
              {NULL, NM_SETTING_DIFF_RESULT_UNKNOWN},
          }},
     };
@@ -8679,11 +8680,9 @@ test_nm_utils_ascii_str_to_int64(void)
 static void
 test_nm_utils_strstrdictkey(void)
 {
-#define _VALUES_STATIC(_v1, _v2)                              \
-    {                                                         \
-        .v1       = _v1,                                      \
-        .v2       = _v2,                                      \
-        .v_static = _nm_utils_strstrdictkey_static(_v1, _v2), \
+#define _VALUES_STATIC(_v1, _v2)                                                    \
+    {                                                                               \
+        .v1 = _v1, .v2 = _v2, .v_static = _nm_utils_strstrdictkey_static(_v1, _v2), \
     }
     const struct {
         const char           *v1;
@@ -11455,32 +11454,32 @@ static void
 test_dns_uri_parse(void)
 {
     /* clang-format off */
-    t_dns_1("dns+tls://8.8.8.8",                   INET,  TLS,  "8.8.8.8",            -1, NULL,      NULL);
-    t_dns_1("dns+tls://8.8.8.8",                   INET,  TLS,  "8.8.8.8",            -1, NULL,      NULL);
-    t_dns_1("dns+tls://1.2.3.4#name",              INET,  TLS,  "1.2.3.4",            -1, "name",    NULL);
-    t_dns_1("dns+tls://1.2.3.4#a.b.c",             INET,  TLS,  "1.2.3.4",            -1, "a.b.c",   NULL);
-    t_dns_1("dns+tls://1.2.3.4:53",                INET,  TLS,  "1.2.3.4",            53, NULL,      NULL);
-    t_dns_1("dns+tls://1.2.3.4:53#foobar",         INET,  TLS,  "1.2.3.4",            53, "foobar",  NULL);
-    t_dns_1("dns+tls://192.168.120.250:99",        INET,  TLS,  "192.168.120.250",    99, NULL,      NULL);
-    t_dns_1("dns+udp://8.8.8.8:65535",             INET,  UDP,  "8.8.8.8",         65535, NULL,      NULL);
-
-    t_dns_1("dns+udp://[fd01::1]",                 INET6, UDP,  "fd01::1",            -1, NULL,      NULL);
-    t_dns_1("dns+tls://[fd01::2]:5353",            INET6, UDP,  "fd01::2",          5353, NULL,      NULL);
-    t_dns_1("dns+tls://[::1]#name",                INET6, UDP,  "::1",                -1, "name",    NULL);
-    t_dns_1("dns+tls://[::2]:65535#name",          INET6, UDP,  "::2",             65535, "name",    NULL);
-    t_dns_1("dns+udp://[::ffff:1.2.3.4]",          INET6, UDP,  "::ffff:1.2.3.4",     -1, NULL,      NULL);
-    t_dns_1("dns+tls://[fe80::1%eth0]",            INET6, UDP,  "fe80::1",            -1, NULL,      "eth0");
-    t_dns_1("dns+tls://[fe80::2%en1]:53#a",        INET6, UDP,  "fe80::2",            53, "a",       "en1");
-    t_dns_1("dns+tls://[fe80::1%en3456789012345]", INET6, UDP,  "fe80::1",            -1, NULL, "en3456789012345");
-
-    t_dns_1("1.2.3.4",                             INET,  NONE, "1.2.3.4",            -1, NULL,      NULL);
-    t_dns_1("1.2.3.4#foo",                         INET,  NONE, "1.2.3.4",            -1, "foo",     NULL);
-    t_dns_1("1::#x",                               INET6, NONE, "1::",                -1, "x",       NULL);
-    t_dns_1("1::0#x",                              INET6, NONE, "1::",                -1, "x",       NULL);
-    t_dns_1("192.168.0.1",                         INET,  NONE, "192.168.0.1",        -1, NULL,      NULL);
-    t_dns_1("192.168.0.1#tst.com",                 INET,  NONE, "192.168.0.1",        -1, "tst.com", NULL);
-    t_dns_1("fe80::18",                            INET6, NONE, "fe80::18",           -1, NULL,      NULL);
-    t_dns_1("fe80::18#foo.com",                    INET6, NONE, "fe80::18",           -1, "foo.com", NULL);
+    t_dns_1("dns+tls://8.8.8.8",                   INET,  TLS,  "8.8.8.8",            0,     NULL,      NULL);
+    t_dns_1("dns+tls://8.8.8.8",                   INET,  TLS,  "8.8.8.8",            0,     NULL,      NULL);
+    t_dns_1("dns+tls://1.2.3.4#name",              INET,  TLS,  "1.2.3.4",            0,     "name",    NULL);
+    t_dns_1("dns+tls://1.2.3.4#a.b.c",             INET,  TLS,  "1.2.3.4",            0,     "a.b.c",   NULL);
+    t_dns_1("dns+tls://1.2.3.4:53",                INET,  TLS,  "1.2.3.4",            53,    NULL,      NULL);
+    t_dns_1("dns+tls://1.2.3.4:53#foobar",         INET,  TLS,  "1.2.3.4",            53,    "foobar",  NULL);
+    t_dns_1("dns+tls://192.168.120.250:99",        INET,  TLS,  "192.168.120.250",    99,    NULL,      NULL);
+    t_dns_1("dns+udp://8.8.8.8:65535",             INET,  UDP,  "8.8.8.8",         65535,    NULL,      NULL);
+
+    t_dns_1("dns+udp://[fd01::1]",                 INET6, UDP,  "fd01::1",            0,     NULL,      NULL);
+    t_dns_1("dns+tls://[fd01::2]:5353",            INET6, UDP,  "fd01::2",            5353,  NULL,      NULL);
+    t_dns_1("dns+tls://[::1]#name",                INET6, UDP,  "::1",                0,     "name",    NULL);
+    t_dns_1("dns+tls://[::2]:65535#name",          INET6, UDP,  "::2",                65535, "name",    NULL);
+    t_dns_1("dns+udp://[::ffff:1.2.3.4]",          INET6, UDP,  "::ffff:1.2.3.4",     0,     NULL,      NULL);
+    t_dns_1("dns+tls://[fe80::1%eth0]",            INET6, UDP,  "fe80::1",            0,     NULL,      "eth0");
+    t_dns_1("dns+tls://[fe80::2%en1]:53#a",        INET6, UDP,  "fe80::2",            53,    "a",       "en1");
+    t_dns_1("dns+tls://[fe80::1%en3456789012345]", INET6, UDP,  "fe80::1",            0,     NULL,      "en3456789012345");
+
+    t_dns_1("1.2.3.4",                             INET,  NONE, "1.2.3.4",            0,     NULL,      NULL);
+    t_dns_1("1.2.3.4#foo",                         INET,  NONE, "1.2.3.4",            0,     "foo",     NULL);
+    t_dns_1("1::#x",                               INET6, NONE, "1::",                0,     "x",       NULL);
+    t_dns_1("1::0#x",                              INET6, NONE, "1::",                0,     "x",       NULL);
+    t_dns_1("192.168.0.1",                         INET,  NONE, "192.168.0.1",        0,     NULL,      NULL);
+    t_dns_1("192.168.0.1#tst.com",                 INET,  NONE, "192.168.0.1",        0,     "tst.com", NULL);
+    t_dns_1("fe80::18",                            INET6, NONE, "fe80::18",           0,     NULL,      NULL);
+    t_dns_1("fe80::18#foo.com",                    INET6, NONE, "fe80::18",           0,     "foo.com", NULL);
     /* clang-format on */
 
     t_dns_0("http://8.8.8.8");              /* unsupported schema */