about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2022-02-19 17:19:17 +0100
committerMichael Biebl <biebl@debian.org>2022-02-19 17:19:17 +0100
commite3f2ee969d065d2971170563c8aef77d5a0d39b9 (patch)
tree94454d4e2fe0955c09516f18dc4e84a6cf7139fa
parent2f94dba7385fd0e0ef19a06eb4a2fcf6c43d7946 (diff)
New upstream version 1.35.92 upstream/1.35.92
-rw-r--r--TODO5
-rwxr-xr-xconfigure26
-rw-r--r--configure.ac2
-rw-r--r--docs/api/html/index.html2
-rw-r--r--docs/api/version.xml2
-rw-r--r--docs/libnm/html/index.html2
-rw-r--r--docs/libnm/html/usage.html2
-rw-r--r--docs/libnm/version.xml2
-rw-r--r--man/NetworkManager-dispatcher.84
-rw-r--r--man/NetworkManager.86
-rw-r--r--man/NetworkManager.conf.56
-rw-r--r--man/nm-cloud-setup.86
-rw-r--r--man/nm-initrd-generator.86
-rw-r--r--man/nm-online.16
-rw-r--r--man/nm-openvswitch.76
-rw-r--r--man/nm-settings-dbus.56
-rw-r--r--man/nm-settings-dbus.xml2
-rw-r--r--man/nm-settings-ifcfg-rh.56
-rw-r--r--man/nm-settings-ifcfg-rh.xml2
-rw-r--r--man/nm-settings-keyfile.56
-rw-r--r--man/nm-settings-keyfile.xml2
-rw-r--r--man/nm-settings-nmcli.56
-rw-r--r--man/nm-settings-nmcli.xml2
-rw-r--r--man/nmcli-examples.76
-rw-r--r--man/nmcli.16
-rw-r--r--man/nmtui.16
-rw-r--r--meson.build2
-rw-r--r--src/core/devices/nm-device.c29
-rw-r--r--src/core/nm-l3cfg.c17
-rw-r--r--src/core/nm-l3cfg.h2
-rw-r--r--src/core/nm-policy.c6
-rw-r--r--src/core/ppp/nm-ppp-manager.c2
-rw-r--r--src/libnm-core-impl/nm-keyfile-utils.c19
-rw-r--r--src/libnm-core-impl/nm-keyfile.c133
-rw-r--r--src/libnm-core-impl/tests/test-setting.c18
-rw-r--r--src/libnm-core-intern/nm-keyfile-utils.h2
-rw-r--r--src/libnm-core-public/nm-version-macros.h2
-rw-r--r--src/libnm-platform/nm-linux-platform.c177
-rwxr-xr-xtools/run-nm-test.sh4
39 files changed, 345 insertions, 201 deletions
diff --git a/TODO b/TODO
index 97b0df43..efb1e909 100644
--- a/TODO
+++ b/TODO
@@ -2,11 +2,6 @@ So you're interested in hacking on NetworkManager?  Here's some cool
 stuff you could do...
 
 
-* IPv6 Multihop Routes in Platform
-
-See src/libnm-platform/README.md
-
-
 * Use netlink API instead of ioctl based ethtool.
 
 NetworkManager uses ethtool API to set/obtain certain settings of network
diff --git a/configure b/configure
index 9c685f01..20a15bca 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for NetworkManager 1.35.91.
+# Generated by GNU Autoconf 2.69 for NetworkManager 1.35.92.
 #
 # Report bugs to <http://bugzilla.gnome.org/enter_bug.cgi?product=NetworkManager>.
 #
@@ -591,8 +591,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='NetworkManager'
 PACKAGE_TARNAME='NetworkManager'
-PACKAGE_VERSION='1.35.91'
-PACKAGE_STRING='NetworkManager 1.35.91'
+PACKAGE_VERSION='1.35.92'
+PACKAGE_STRING='NetworkManager 1.35.92'
 PACKAGE_BUGREPORT='http://bugzilla.gnome.org/enter_bug.cgi?product=NetworkManager'
 PACKAGE_URL=''
 
@@ -1747,7 +1747,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures NetworkManager 1.35.91 to adapt to many kinds of systems.
+\`configure' configures NetworkManager 1.35.92 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1819,7 +1819,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of NetworkManager 1.35.91:";;
+     short | recursive ) echo "Configuration of NetworkManager 1.35.92:";;
    esac
   cat <<\_ACEOF
 
@@ -2170,7 +2170,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-NetworkManager configure 1.35.91
+NetworkManager configure 1.35.92
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2943,7 +2943,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by NetworkManager $as_me 1.35.91, which was
+It was created by NetworkManager $as_me 1.35.92, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3813,7 +3813,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='NetworkManager'
- VERSION='1.35.91'
+ VERSION='1.35.92'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -17997,8 +17997,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 NM_MAJOR_VERSION=1
 NM_MINOR_VERSION=35
-NM_MICRO_VERSION=91
-NM_VERSION=1.35.91
+NM_MICRO_VERSION=92
+NM_VERSION=1.35.92
 
 
 
@@ -18006,7 +18006,7 @@ NM_VERSION=1.35.91
 
 
 
-NM_GIT_SHA=259999d55e0a1dba3c8d53ebb9fa8848404145c6
+NM_GIT_SHA=9024ff49a17a3c54c717067d9ddf99fed2f67932
 
 if test """" != "no-config-h" ; then
 
@@ -30502,7 +30502,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by NetworkManager $as_me 1.35.91, which was
+This file was extended by NetworkManager $as_me 1.35.92, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -30568,7 +30568,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-NetworkManager config.status 1.35.91
+NetworkManager config.status 1.35.92
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 66ca4a2e..18ce1f7f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -8,7 +8,7 @@ dnl    "shared/nm-version-macros.h.in"
 dnl  - update number in meson.build
 m4_define([nm_major_version], [1])
 m4_define([nm_minor_version], [35])
-m4_define([nm_micro_version], [91])
+m4_define([nm_micro_version], [92])
 m4_define([nm_version],
           [nm_major_version.nm_minor_version.nm_micro_version])
 
diff --git a/docs/api/html/index.html b/docs/api/html/index.html
index 5d829805..717bfd0e 100644
--- a/docs/api/html/index.html
+++ b/docs/api/html/index.html
@@ -16,7 +16,7 @@
 <div>
 <div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">NetworkManager Reference Manual</p></th></tr></table></div>
 <div><p class="releaseinfo">
-      for NetworkManager 1.35.91
+      for NetworkManager 1.35.92
 
       The latest version of this documentation can be found on-line at
       <a class="ulink" href="https://networkmanager.dev/docs/api/latest/" target="_top">https://networkmanager.dev/docs/api/latest/</a>.
diff --git a/docs/api/version.xml b/docs/api/version.xml
index 4401dc79..bfe5672f 100644
--- a/docs/api/version.xml
+++ b/docs/api/version.xml
@@ -1 +1 @@
-1.35.91
+1.35.92
diff --git a/docs/libnm/html/index.html b/docs/libnm/html/index.html
index c5758999..3438e60d 100644
--- a/docs/libnm/html/index.html
+++ b/docs/libnm/html/index.html
@@ -15,7 +15,7 @@
 <div>
 <div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">libnm Reference Manual</p></th></tr></table></div>
 <div><p class="releaseinfo">
-      for libnm 1.35.91
+      for libnm 1.35.92
 
       The latest version of this documentation can be found on-line at
       <a class="ulink" href="https://networkmanager.dev/docs/libnm/latest/" target="_top">https://networkmanager.dev/docs/libnm/latest/</a>.
diff --git a/docs/libnm/html/usage.html b/docs/libnm/html/usage.html
index 4503649b..229787c1 100644
--- a/docs/libnm/html/usage.html
+++ b/docs/libnm/html/usage.html
@@ -96,7 +96,7 @@
         </p>
 <pre class="screen"><code class="prompt">$ </code><strong class="userinput"><code>cc $(pkg-config --libs --cflags libnm) -o hello-nm hello-nm.c</code></strong>
   <code class="prompt">$ </code><strong class="userinput"><code>./hello-nm</code></strong>
-  NetworkManager version: 1.35.91
+  NetworkManager version: 1.35.92
 
   <code class="prompt">$ </code></pre>
 <p>
diff --git a/docs/libnm/version.xml b/docs/libnm/version.xml
index 4401dc79..bfe5672f 100644
--- a/docs/libnm/version.xml
+++ b/docs/libnm/version.xml
@@ -1 +1 @@
-1.35.91
+1.35.92
diff --git a/man/NetworkManager-dispatcher.8 b/man/NetworkManager-dispatcher.8
index 34433de3..e881f8e6 100644
--- a/man/NetworkManager-dispatcher.8
+++ b/man/NetworkManager-dispatcher.8
@@ -2,9 +2,9 @@
 .\"     Title: NetworkManager-dispatcher
 .\"    Author: 
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/10/2022
+.\"      Date: 02/19/2022
 .\"    Manual: Network management daemons
-.\"    Source: NetworkManager-dispatcher 1.35.91
+.\"    Source: NetworkManager-dispatcher 1.35.92
 .\"  Language: English
 .\"
 .TH "NETWORKMANAGER\-DISPATCHER" "8" "" "NetworkManager\-dispatcher 1\&" "Network management daemons"
diff --git a/man/NetworkManager.8 b/man/NetworkManager.8
index b7ca1378..c3eb0b83 100644
--- a/man/NetworkManager.8
+++ b/man/NetworkManager.8
@@ -2,12 +2,12 @@
 .\"     Title: NetworkManager
 .\"    Author: 
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/10/2022
+.\"      Date: 02/19/2022
 .\"    Manual: Network management daemons
-.\"    Source: NetworkManager 1.35.91
+.\"    Source: NetworkManager 1.35.92
 .\"  Language: English
 .\"
-.TH "NETWORKMANAGER" "8" "" "NetworkManager 1\&.35\&.91" "Network management daemons"
+.TH "NETWORKMANAGER" "8" "" "NetworkManager 1\&.35\&.92" "Network management daemons"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff --git a/man/NetworkManager.conf.5 b/man/NetworkManager.conf.5
index 4f62ed7c..017a6df6 100644
--- a/man/NetworkManager.conf.5
+++ b/man/NetworkManager.conf.5
@@ -2,12 +2,12 @@
 .\"     Title: NetworkManager.conf
 .\"    Author: 
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/10/2022
+.\"      Date: 02/19/2022
 .\"    Manual: Configuration
-.\"    Source: NetworkManager 1.35.91
+.\"    Source: NetworkManager 1.35.92
 .\"  Language: English
 .\"
-.TH "NETWORKMANAGER\&.CONF" "5" "" "NetworkManager 1\&.35\&.91" "Configuration"
+.TH "NETWORKMANAGER\&.CONF" "5" "" "NetworkManager 1\&.35\&.92" "Configuration"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff --git a/man/nm-cloud-setup.8 b/man/nm-cloud-setup.8
index cbf91efb..afdc530c 100644
--- a/man/nm-cloud-setup.8
+++ b/man/nm-cloud-setup.8
@@ -2,12 +2,12 @@
 .\"     Title: nm-cloud-setup
 .\"    Author: 
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/10/2022
+.\"      Date: 02/19/2022
 .\"    Manual: Automatic Network Configuration in Cloud with NetworkManager
-.\"    Source: NetworkManager 1.35.91
+.\"    Source: NetworkManager 1.35.92
 .\"  Language: English
 .\"
-.TH "NM\-CLOUD\-SETUP" "8" "" "NetworkManager 1\&.35\&.91" "Automatic Network Configuratio"
+.TH "NM\-CLOUD\-SETUP" "8" "" "NetworkManager 1\&.35\&.92" "Automatic Network Configuratio"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff --git a/man/nm-initrd-generator.8 b/man/nm-initrd-generator.8
index 3bf4619e..ce8ba7a0 100644
--- a/man/nm-initrd-generator.8
+++ b/man/nm-initrd-generator.8
@@ -2,12 +2,12 @@
 .\"     Title: nm-initrd-generator
 .\"    Author: 
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/10/2022
+.\"      Date: 02/19/2022
 .\"    Manual: System Administration
-.\"    Source: NetworkManager 1.35.91
+.\"    Source: NetworkManager 1.35.92
 .\"  Language: English
 .\"
-.TH "NM\-INITRD\-GENERATOR" "8" "" "NetworkManager 1\&.35\&.91" "System Administration"
+.TH "NM\-INITRD\-GENERATOR" "8" "" "NetworkManager 1\&.35\&.92" "System Administration"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff --git a/man/nm-online.1 b/man/nm-online.1
index c389fb22..a7b08a21 100644
--- a/man/nm-online.1
+++ b/man/nm-online.1
@@ -2,12 +2,12 @@
 .\"     Title: nm-online
 .\"    Author: 
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/10/2022
+.\"      Date: 02/19/2022
 .\"    Manual: General Commands Manual
-.\"    Source: NetworkManager 1.35.91
+.\"    Source: NetworkManager 1.35.92
 .\"  Language: English
 .\"
-.TH "NM\-ONLINE" "1" "" "NetworkManager 1\&.35\&.91" "General Commands Manual"
+.TH "NM\-ONLINE" "1" "" "NetworkManager 1\&.35\&.92" "General Commands Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff --git a/man/nm-openvswitch.7 b/man/nm-openvswitch.7
index 2d7d6418..6fd4641a 100644
--- a/man/nm-openvswitch.7
+++ b/man/nm-openvswitch.7
@@ -2,12 +2,12 @@
 .\"     Title: nm-openvswitch
 .\"    Author: 
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/10/2022
+.\"      Date: 02/19/2022
 .\"    Manual: Open vSwitch support overview
-.\"    Source: NetworkManager 1.35.91
+.\"    Source: NetworkManager 1.35.92
 .\"  Language: English
 .\"
-.TH "NM\-OPENVSWITCH" "7" "" "NetworkManager 1\&.35\&.91" "Open vSwitch support overview"
+.TH "NM\-OPENVSWITCH" "7" "" "NetworkManager 1\&.35\&.92" "Open vSwitch support overview"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff --git a/man/nm-settings-dbus.5 b/man/nm-settings-dbus.5
index d5e85d80..59ec036a 100644
--- a/man/nm-settings-dbus.5
+++ b/man/nm-settings-dbus.5
@@ -2,12 +2,12 @@
 .\"     Title: nm-settings-dbus
 .\"    Author: 
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/10/2022
+.\"      Date: 02/19/2022
 .\"    Manual: Configuration
-.\"    Source: NetworkManager 1.35.91
+.\"    Source: NetworkManager 1.35.92
 .\"  Language: English
 .\"
-.TH "NM\-SETTINGS\-DBUS" "5" "" "NetworkManager 1\&.35\&.91" "Configuration"
+.TH "NM\-SETTINGS\-DBUS" "5" "" "NetworkManager 1\&.35\&.92" "Configuration"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff --git a/man/nm-settings-dbus.xml b/man/nm-settings-dbus.xml
index b89c67da..ca26de73 100644
--- a/man/nm-settings-dbus.xml
+++ b/man/nm-settings-dbus.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
-<refentry id="nm-settings-dbus"><refentryinfo><title>nm-settings-dbus</title><author>NetworkManager developers</author></refentryinfo><refmeta><refentrytitle>nm-settings-dbus</refentrytitle><manvolnum>5</manvolnum><refmiscinfo class="source">NetworkManager</refmiscinfo><refmiscinfo class="manual">Configuration</refmiscinfo><refmiscinfo class="version">1.35.91</refmiscinfo></refmeta><refnamediv><refname>nm-settings-dbus</refname><refpurpose>Description of settings and properties of NetworkManager connection profiles on the D-Bus API</refpurpose></refnamediv><refsect1 id="description"><title>Description</title><para>
+<refentry id="nm-settings-dbus"><refentryinfo><title>nm-settings-dbus</title><author>NetworkManager developers</author></refentryinfo><refmeta><refentrytitle>nm-settings-dbus</refentrytitle><manvolnum>5</manvolnum><refmiscinfo class="source">NetworkManager</refmiscinfo><refmiscinfo class="manual">Configuration</refmiscinfo><refmiscinfo class="version">1.35.92</refmiscinfo></refmeta><refnamediv><refname>nm-settings-dbus</refname><refpurpose>Description of settings and properties of NetworkManager connection profiles on the D-Bus API</refpurpose></refnamediv><refsect1 id="description"><title>Description</title><para>
           NetworkManager is based on a concept of connection profiles, sometimes referred to as
           connections only. These connection profiles contain a network configuration. When
           NetworkManager activates a connection profile on a network device the configuration will
diff --git a/man/nm-settings-ifcfg-rh.5 b/man/nm-settings-ifcfg-rh.5
index ce3de878..59085de5 100644
--- a/man/nm-settings-ifcfg-rh.5
+++ b/man/nm-settings-ifcfg-rh.5
@@ -2,12 +2,12 @@
 .\"     Title: nm-settings-ifcfg-rh
 .\"    Author: 
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/10/2022
+.\"      Date: 02/19/2022
 .\"    Manual: Configuration
-.\"    Source: NetworkManager 1.35.91
+.\"    Source: NetworkManager 1.35.92
 .\"  Language: English
 .\"
-.TH "NM\-SETTINGS\-IFCFG\-RH" "5" "" "NetworkManager 1\&.35\&.91" "Configuration"
+.TH "NM\-SETTINGS\-IFCFG\-RH" "5" "" "NetworkManager 1\&.35\&.92" "Configuration"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff --git a/man/nm-settings-ifcfg-rh.xml b/man/nm-settings-ifcfg-rh.xml
index f598b017..c743dde6 100644
--- a/man/nm-settings-ifcfg-rh.xml
+++ b/man/nm-settings-ifcfg-rh.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
-<refentry id="nm-settings-ifcfg-rh"><refentryinfo><title>nm-settings-ifcfg-rh</title><author>NetworkManager developers</author></refentryinfo><refmeta><refentrytitle>nm-settings-ifcfg-rh</refentrytitle><manvolnum>5</manvolnum><refmiscinfo class="source">NetworkManager</refmiscinfo><refmiscinfo class="manual">Configuration</refmiscinfo><refmiscinfo class="version">1.35.91</refmiscinfo></refmeta><refnamediv><refname>nm-settings-ifcfg-rh</refname><refpurpose>Description of <emphasis>ifcfg-rh</emphasis> settings plugin</refpurpose></refnamediv><refsect1 id="description"><title>Description</title><para>
+<refentry id="nm-settings-ifcfg-rh"><refentryinfo><title>nm-settings-ifcfg-rh</title><author>NetworkManager developers</author></refentryinfo><refmeta><refentrytitle>nm-settings-ifcfg-rh</refentrytitle><manvolnum>5</manvolnum><refmiscinfo class="source">NetworkManager</refmiscinfo><refmiscinfo class="manual">Configuration</refmiscinfo><refmiscinfo class="version">1.35.92</refmiscinfo></refmeta><refnamediv><refname>nm-settings-ifcfg-rh</refname><refpurpose>Description of <emphasis>ifcfg-rh</emphasis> settings plugin</refpurpose></refnamediv><refsect1 id="description"><title>Description</title><para>
           NetworkManager is based on the concept of connection profiles that contain
           network configuration (see <citerefentry><refentrytitle>nm-settings</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details). The profiles can be
           stored in various formats. NetworkManager uses plugins for reading and writing
diff --git a/man/nm-settings-keyfile.5 b/man/nm-settings-keyfile.5
index 08e22fbb..c7ad87bf 100644
--- a/man/nm-settings-keyfile.5
+++ b/man/nm-settings-keyfile.5
@@ -2,12 +2,12 @@
 .\"     Title: nm-settings-keyfile
 .\"    Author: 
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/10/2022
+.\"      Date: 02/19/2022
 .\"    Manual: Configuration
-.\"    Source: NetworkManager 1.35.91
+.\"    Source: NetworkManager 1.35.92
 .\"  Language: English
 .\"
-.TH "NM\-SETTINGS\-KEYFILE" "5" "" "NetworkManager 1\&.35\&.91" "Configuration"
+.TH "NM\-SETTINGS\-KEYFILE" "5" "" "NetworkManager 1\&.35\&.92" "Configuration"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff --git a/man/nm-settings-keyfile.xml b/man/nm-settings-keyfile.xml
index 2383e53e..8347f63b 100644
--- a/man/nm-settings-keyfile.xml
+++ b/man/nm-settings-keyfile.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
-<refentry id="nm-settings-keyfile"><refentryinfo><title>nm-settings-keyfile</title><author>NetworkManager developers</author></refentryinfo><refmeta><refentrytitle>nm-settings-keyfile</refentrytitle><manvolnum>5</manvolnum><refmiscinfo class="source">NetworkManager</refmiscinfo><refmiscinfo class="manual">Configuration</refmiscinfo><refmiscinfo class="version">1.35.91</refmiscinfo></refmeta><refnamediv><refname>nm-settings-keyfile</refname><refpurpose>Description of <emphasis>keyfile</emphasis> settings plugin</refpurpose></refnamediv><refsect1 id="description"><title>Description</title><para>
+<refentry id="nm-settings-keyfile"><refentryinfo><title>nm-settings-keyfile</title><author>NetworkManager developers</author></refentryinfo><refmeta><refentrytitle>nm-settings-keyfile</refentrytitle><manvolnum>5</manvolnum><refmiscinfo class="source">NetworkManager</refmiscinfo><refmiscinfo class="manual">Configuration</refmiscinfo><refmiscinfo class="version">1.35.92</refmiscinfo></refmeta><refnamediv><refname>nm-settings-keyfile</refname><refpurpose>Description of <emphasis>keyfile</emphasis> settings plugin</refpurpose></refnamediv><refsect1 id="description"><title>Description</title><para>
           NetworkManager is based on the concept of connection profiles that contain
           network configuration (see <citerefentry><refentrytitle>nm-settings</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details). The profiles can be
           stored in various formats. NetworkManager uses plugins for reading and writing
diff --git a/man/nm-settings-nmcli.5 b/man/nm-settings-nmcli.5
index 83d2ec57..81f5cba9 100644
--- a/man/nm-settings-nmcli.5
+++ b/man/nm-settings-nmcli.5
@@ -2,12 +2,12 @@
 .\"     Title: nm-settings-nmcli
 .\"    Author: 
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/10/2022
+.\"      Date: 02/19/2022
 .\"    Manual: Configuration
-.\"    Source: NetworkManager 1.35.91
+.\"    Source: NetworkManager 1.35.92
 .\"  Language: English
 .\"
-.TH "NM\-SETTINGS\-NMCLI" "5" "" "NetworkManager 1\&.35\&.91" "Configuration"
+.TH "NM\-SETTINGS\-NMCLI" "5" "" "NetworkManager 1\&.35\&.92" "Configuration"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff --git a/man/nm-settings-nmcli.xml b/man/nm-settings-nmcli.xml
index 5d784423..e7dc08b8 100644
--- a/man/nm-settings-nmcli.xml
+++ b/man/nm-settings-nmcli.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
-<refentry id="nm-settings-nmcli"><refentryinfo><title>nm-settings-nmcli</title><author>NetworkManager developers</author></refentryinfo><refmeta><refentrytitle>nm-settings-nmcli</refentrytitle><manvolnum>5</manvolnum><refmiscinfo class="source">NetworkManager</refmiscinfo><refmiscinfo class="manual">Configuration</refmiscinfo><refmiscinfo class="version">1.35.91</refmiscinfo></refmeta><refnamediv><refname>nm-settings-nmcli</refname><refpurpose>Description of settings and properties of NetworkManager connection profiles for nmcli</refpurpose></refnamediv><refsect1 id="description"><title>Description</title><para>
+<refentry id="nm-settings-nmcli"><refentryinfo><title>nm-settings-nmcli</title><author>NetworkManager developers</author></refentryinfo><refmeta><refentrytitle>nm-settings-nmcli</refentrytitle><manvolnum>5</manvolnum><refmiscinfo class="source">NetworkManager</refmiscinfo><refmiscinfo class="manual">Configuration</refmiscinfo><refmiscinfo class="version">1.35.92</refmiscinfo></refmeta><refnamediv><refname>nm-settings-nmcli</refname><refpurpose>Description of settings and properties of NetworkManager connection profiles for nmcli</refpurpose></refnamediv><refsect1 id="description"><title>Description</title><para>
           NetworkManager is based on a concept of connection profiles, sometimes referred to as
           connections only. These connection profiles contain a network configuration. When
           NetworkManager activates a connection profile on a network device the configuration will
diff --git a/man/nmcli-examples.7 b/man/nmcli-examples.7
index adc605d4..04e864de 100644
--- a/man/nmcli-examples.7
+++ b/man/nmcli-examples.7
@@ -2,12 +2,12 @@
 .\"     Title: nmcli-examples
 .\"    Author: 
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/10/2022
+.\"      Date: 02/19/2022
 .\"    Manual: Examples
-.\"    Source: NetworkManager 1.35.91
+.\"    Source: NetworkManager 1.35.92
 .\"  Language: English
 .\"
-.TH "NMCLI\-EXAMPLES" "7" "" "NetworkManager 1\&.35\&.91" "Examples"
+.TH "NMCLI\-EXAMPLES" "7" "" "NetworkManager 1\&.35\&.92" "Examples"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff --git a/man/nmcli.1 b/man/nmcli.1
index 76ff9f21..7b70377d 100644
--- a/man/nmcli.1
+++ b/man/nmcli.1
@@ -2,12 +2,12 @@
 .\"     Title: nmcli
 .\"    Author: 
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/10/2022
+.\"      Date: 02/19/2022
 .\"    Manual: General Commands Manual
-.\"    Source: NetworkManager 1.35.91
+.\"    Source: NetworkManager 1.35.92
 .\"  Language: English
 .\"
-.TH "NMCLI" "1" "" "NetworkManager 1\&.35\&.91" "General Commands Manual"
+.TH "NMCLI" "1" "" "NetworkManager 1\&.35\&.92" "General Commands Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff --git a/man/nmtui.1 b/man/nmtui.1
index c2d27654..83c815ba 100644
--- a/man/nmtui.1
+++ b/man/nmtui.1
@@ -2,12 +2,12 @@
 .\"     Title: nmtui
 .\"    Author: 
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 02/10/2022
+.\"      Date: 02/19/2022
 .\"    Manual: General Commands Manual
-.\"    Source: NetworkManager 1.35.91
+.\"    Source: NetworkManager 1.35.92
 .\"  Language: English
 .\"
-.TH "NMTUI" "1" "" "NetworkManager 1\&.35\&.91" "General Commands Manual"
+.TH "NMTUI" "1" "" "NetworkManager 1\&.35\&.92" "General Commands Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
diff --git a/meson.build b/meson.build
index 05328b53..1c313ed8 100644
--- a/meson.build
+++ b/meson.build
@@ -6,7 +6,7 @@ project(
 #  - add corresponding NM_VERSION_x_y_z macros in
 #    "src/libnm-core-public/nm-version-macros.h.in"
 #  - update number in configure.ac
-  version: '1.35.91',
+  version: '1.35.92',
   license: 'GPL2+',
   default_options: [
     'buildtype=debugoptimized',
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index 696c0df8..aed580ab 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -3057,6 +3057,7 @@ _dev_ip_state_check(NMDevice *self, int addr_family)
     gboolean         s_is_started = FALSE;
     gboolean         s_is_failed  = FALSE;
     gboolean         s_is_pending = FALSE;
+    gboolean         has_tna      = FALSE;
     gboolean         v_bool;
     NMDeviceIPState  ip_state;
     NMDeviceIPState  ip_state_other;
@@ -3188,6 +3189,10 @@ _dev_ip_state_check(NMDevice *self, int addr_family)
                                 &s_is_pending,
                                 &s_is_failed);
 
+    has_tna = priv->l3cfg && nm_l3cfg_has_temp_not_available_obj(priv->l3cfg, addr_family);
+    if (has_tna)
+        s_is_pending = TRUE;
+
     if (s_is_failed)
         ip_state = NM_DEVICE_IP_STATE_FAILED;
     else if (s_is_pending)
@@ -3215,7 +3220,7 @@ got_ip_state:
     nm_assert(!priv->ip_data_4.is_ignore);
 
     _LOGT_ip(addr_family,
-             "check-state: state %s => %s, is_failed=%d, is_pending=%d, is_started=%d, "
+             "check-state: state %s => %s, is_failed=%d, is_pending=%d, is_started=%d temp_na=%d, "
              "may-fail-4=%d, may-fail-6=%d;"
              "%s;%s%s%s%s%s%s;%s%s%s%s%s%s%s%s",
              nm_device_ip_state_to_string(priv->ip_data_x[IS_IPv4].state),
@@ -3223,6 +3228,7 @@ got_ip_state:
              s_is_failed,
              s_is_pending,
              s_is_started,
+             has_tna,
              _prop_get_ipvx_may_fail_cached(self, AF_INET, IS_IPv4 ? &may_fail : &may_fail_other),
              _prop_get_ipvx_may_fail_cached(self, AF_INET6, !IS_IPv4 ? &may_fail : &may_fail_other),
              priv->ip_data_4.is_disabled ? " disabled4" : "",
@@ -3932,6 +3938,9 @@ _dev_l3_cfg_notify_cb(NML3Cfg *l3cfg, const NML3ConfigNotifyData *notify_data, N
                                     AF_INET6,
                                     NM_L3CFG_CHECK_READY_FLAGS_IP6_DAD_READY,
                                     NULL)) {
+            if (nm_l3cfg_has_temp_not_available_obj(priv->l3cfg, AF_INET6))
+                _dev_l3_cfg_commit(self, FALSE);
+
             nm_clear_l3cd(&priv->ipac6_data.l3cd);
             _dev_ipac6_set_state(self, NM_DEVICE_IP_STATE_READY);
             _dev_ip_state_check_async(self, AF_INET6);
@@ -9821,6 +9830,14 @@ _dev_ipmanual_check_ready(NMDevice *self)
             _dev_ipmanual_set_state(self, addr_family, NM_DEVICE_IP_STATE_FAILED);
             _dev_ip_state_check_async(self, AF_UNSPEC);
         } else if (ready) {
+            if (priv->ipmanual_data.state_x[IS_IPv4] != NM_DEVICE_IP_STATE_READY
+                && nm_l3cfg_has_temp_not_available_obj(priv->l3cfg, addr_family)) {
+                /* Addresses with pending ACD/DAD are a possible cause for the
+                 * presence of temporarily-not-available objects. Once all addresses
+                 * are ready, retry to commit those unavailable objects. */
+                _dev_l3_cfg_commit(self, FALSE);
+            }
+
             _dev_ipmanual_set_state(self, addr_family, NM_DEVICE_IP_STATE_READY);
             _dev_ip_state_check_async(self, AF_UNSPEC);
         }
@@ -10455,14 +10472,14 @@ nm_device_copy_ip6_dns_config(NMDevice *self, NMDevice *from_device)
         l3cd_src = priv_src->l3cds[L3_CONFIG_DATA_TYPE_AC_6].d;
     }
     if (l3cd_src) {
-        const char *const            *strvarr;
-        const struct in6_addr *const *addrs;
-        guint                         n;
-        guint                         i;
+        const char *const     *strvarr;
+        const struct in6_addr *addrs;
+        guint                  n;
+        guint                  i;
 
         addrs = nm_l3_config_data_get_nameservers(l3cd_src, AF_INET6, &n);
         for (i = 0; i < n; i++)
-            nm_l3_config_data_add_nameserver(l3cd, AF_INET6, addrs[i]);
+            nm_l3_config_data_add_nameserver(l3cd, AF_INET6, &addrs[i]);
 
         strvarr = nm_l3_config_data_get_searches(l3cd_src, AF_INET6, &n);
         for (i = 0; i < n; i++)
diff --git a/src/core/nm-l3cfg.c b/src/core/nm-l3cfg.c
index 9258decf..7d00264b 100644
--- a/src/core/nm-l3cfg.c
+++ b/src/core/nm-l3cfg.c
@@ -2948,6 +2948,23 @@ nm_l3cfg_get_acd_addr_info(NML3Cfg *self, in_addr_t addr)
 /*****************************************************************************/
 
 gboolean
+nm_l3cfg_has_temp_not_available_obj(NML3Cfg *self, int addr_family)
+{
+    ObjStateData *obj_state;
+
+    nm_assert(NM_IS_L3CFG(self));
+    nm_assert_addr_family(addr_family);
+
+    c_list_for_each_entry (obj_state,
+                           &self->priv.p->obj_state_temporary_not_available_lst_head,
+                           os_temporary_not_available_lst) {
+        if (NMP_OBJECT_GET_ADDR_FAMILY(obj_state->obj) == addr_family)
+            return TRUE;
+    }
+    return FALSE;
+}
+
+gboolean
 nm_l3cfg_check_ready(NML3Cfg               *self,
                      const NML3ConfigData  *l3cd,
                      int                    addr_family,
diff --git a/src/core/nm-l3cfg.h b/src/core/nm-l3cfg.h
index 7dc9facc..0ea68646 100644
--- a/src/core/nm-l3cfg.h
+++ b/src/core/nm-l3cfg.h
@@ -410,6 +410,8 @@ gboolean nm_l3cfg_check_ready(NML3Cfg               *self,
                               NML3CfgCheckReadyFlags flags,
                               gboolean              *acd_used);
 
+gboolean nm_l3cfg_has_temp_not_available_obj(NML3Cfg *self, int addr_family);
+
 /*****************************************************************************/
 
 NML3CfgCommitType nm_l3cfg_commit_type_get(NML3Cfg *self);
diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c
index cb5b543e..d77fc0a0 100644
--- a/src/core/nm-policy.c
+++ b/src/core/nm-policy.c
@@ -2005,7 +2005,8 @@ device_state_changed(NMDevice           *device,
                                          AF_UNSPEC,
                                          device,
                                          nm_device_get_l3cd(device, TRUE),
-                                         NM_DNS_IP_CONFIG_TYPE_DEFAULT,
+                                         nm_device_is_vpn(device) ? NM_DNS_IP_CONFIG_TYPE_VPN
+                                                                  : NM_DNS_IP_CONFIG_TYPE_DEFAULT,
                                          TRUE);
         }
         update_ip_dns(self, AF_INET, device);
@@ -2147,7 +2148,8 @@ device_l3cd_changed(NMDevice             *device,
                                      AF_UNSPEC,
                                      device,
                                      l3cd_new,
-                                     NM_DNS_IP_CONFIG_TYPE_DEFAULT,
+                                     nm_device_is_vpn(device) ? NM_DNS_IP_CONFIG_TYPE_VPN
+                                                              : NM_DNS_IP_CONFIG_TYPE_DEFAULT,
                                      TRUE);
         update_ip_dns(self, AF_INET, device);
         update_ip_dns(self, AF_INET6, device);
diff --git a/src/core/ppp/nm-ppp-manager.c b/src/core/ppp/nm-ppp-manager.c
index f1f10305..dd6b1bc7 100644
--- a/src/core/ppp/nm-ppp-manager.c
+++ b/src/core/ppp/nm-ppp-manager.c
@@ -1246,7 +1246,7 @@ _ppp_manager_stop(NMPPPManager            *self,
                               SIGTERM,
                               LOGD_PPP,
                               "pppd",
-                              NM_SHUTDOWN_TIMEOUT_MS,
+                              5000,
                               _stop_child_cb,
                               handle);
 
diff --git a/src/libnm-core-impl/nm-keyfile-utils.c b/src/libnm-core-impl/nm-keyfile-utils.c
index 0e2e2d45..c599aefa 100644
--- a/src/libnm-core-impl/nm-keyfile-utils.c
+++ b/src/libnm-core-impl/nm-keyfile-utils.c
@@ -682,3 +682,22 @@ nm_keyfile_key_decode(const char *key, char **out_to_free)
 #endif
     return name;
 }
+
+void
+nm_keyfile_add_group(GKeyFile *keyfile, const char *group)
+{
+    nm_assert(keyfile);
+    nm_assert(group);
+
+    /* You can only call this function if the group doesn't exist yet.
+     * Because, we are about to add a dummy key, so we would have to
+     * be sure that the key doesn't exist. */
+    nm_assert(!g_key_file_has_group(keyfile, group));
+
+    /* Ensure the group is present.
+     * There is no API for that, so add and remove a dummy key.
+     * For a profile it matters whether a setting is present or not,
+     * and we need to ensure that we persist the presence of the setting to keyfile*/
+    g_key_file_set_value(keyfile, group, ".X", "1");
+    g_key_file_remove_key(keyfile, group, ".X", NULL);
+}
diff --git a/src/libnm-core-impl/nm-keyfile.c b/src/libnm-core-impl/nm-keyfile.c
index 4ff9b582..dce53ae2 100644
--- a/src/libnm-core-impl/nm-keyfile.c
+++ b/src/libnm-core-impl/nm-keyfile.c
@@ -2305,8 +2305,21 @@ wired_s390_options_writer_full(KeyfileWriterInfo        *info,
 {
     NMSettingWired *s_wired = NM_SETTING_WIRED(setting);
     guint           i, n;
+    const char     *setting_alias;
 
     n = nm_setting_wired_get_num_s390_options(s_wired);
+    if (n == 0)
+        return;
+
+    setting_alias = nm_keyfile_plugin_get_alias_for_setting_name(NM_SETTING_WIRED_SETTING_NAME);
+    if (!g_key_file_has_group(info->keyfile, NM_SETTING_WIRED_SETTING_NAME)
+        && !g_key_file_has_group(info->keyfile, setting_alias)) {
+        /* groups in the keyfile are ordered. When we are about to add [ethernet-s390-options],
+         * we want to also have an [ethernet] group, first. */
+
+        nm_keyfile_add_group(info->keyfile, setting_alias ?: NM_SETTING_WIRED_SETTING_NAME);
+    }
+
     for (i = 0; i < n; i++) {
         gs_free char *key_to_free = NULL;
         const char   *opt_key;
@@ -2755,6 +2768,11 @@ struct _ParseInfoProperty {
      * default value. By setting this flag to TRUE, also
      * default values are written. */
     bool writer_persist_default : 1;
+
+    /*  This flag indicates that the property should always
+     * be written to keyfile, even if it's the default.
+     * This is currently only implemented for STRV properties. */
+    bool always_write : 1;
 };
 
 #define PARSE_INFO_PROPERTY(_property_name, ...) \
@@ -2856,53 +2874,57 @@ static const ParseInfoSetting *const parse_infos[_NM_META_SETTING_TYPE_NUM] = {
         NM_META_SETTING_TYPE_INFINIBAND,
         PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_INFINIBAND_MAC_ADDRESS,
                                                   .parser = mac_address_parser_INFINIBAND, ), ), ),
-    PARSE_INFO_SETTING(NM_META_SETTING_TYPE_IP4_CONFIG,
-                       PARSE_INFO_PROPERTIES(
-                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ADDRESSES,
-                                               .parser_no_check_key = TRUE,
-                                               .parser              = ip_address_or_route_parser,
-                                               .writer              = addr_writer, ),
-                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_DNS,
-                                               .parser_no_check_key = TRUE,
-                                               .parser              = ip_dns_parser,
-                                               .writer              = dns_writer, ),
-                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_GATEWAY, .writer_skip = TRUE, ),
-                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTES,
-                                               .parser_no_check_key = TRUE,
-                                               .parser              = ip_address_or_route_parser,
-                                               .writer              = route_writer, ),
-                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTING_RULES,
-                                               .parser_no_check_key = TRUE,
-                                               .parser_full         = ip_routing_rule_parser_full,
-                                               .writer_full         = ip_routing_rule_writer_full,
-                                               .has_parser_full     = TRUE,
-                                               .has_writer_full     = TRUE, ), ), ),
-    PARSE_INFO_SETTING(NM_META_SETTING_TYPE_IP6_CONFIG,
-                       PARSE_INFO_PROPERTIES(
-                           PARSE_INFO_PROPERTY(NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE,
-                                               .parser_no_check_key    = TRUE,
-                                               .parser                 = ip6_addr_gen_mode_parser,
-                                               .writer                 = ip6_addr_gen_mode_writer,
-                                               .writer_persist_default = TRUE, ),
-                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ADDRESSES,
-                                               .parser_no_check_key = TRUE,
-                                               .parser              = ip_address_or_route_parser,
-                                               .writer              = addr_writer, ),
-                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_DNS,
-                                               .parser_no_check_key = TRUE,
-                                               .parser              = ip_dns_parser,
-                                               .writer              = dns_writer, ),
-                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_GATEWAY, .writer_skip = TRUE, ),
-                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTES,
-                                               .parser_no_check_key = TRUE,
-                                               .parser              = ip_address_or_route_parser,
-                                               .writer              = route_writer, ),
-                           PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTING_RULES,
-                                               .parser_no_check_key = TRUE,
-                                               .parser_full         = ip_routing_rule_parser_full,
-                                               .writer_full         = ip_routing_rule_writer_full,
-                                               .has_parser_full     = TRUE,
-                                               .has_writer_full     = TRUE, ), ), ),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_IP4_CONFIG,
+        PARSE_INFO_PROPERTIES(
+            PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ADDRESSES,
+                                .parser_no_check_key = TRUE,
+                                .parser              = ip_address_or_route_parser,
+                                .writer              = addr_writer, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_DNS,
+                                .parser_no_check_key = TRUE,
+                                .parser              = ip_dns_parser,
+                                .writer              = dns_writer, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_DNS_OPTIONS, .always_write = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_GATEWAY, .writer_skip = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTES,
+                                .parser_no_check_key = TRUE,
+                                .parser              = ip_address_or_route_parser,
+                                .writer              = route_writer, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTING_RULES,
+                                .parser_no_check_key = TRUE,
+                                .parser_full         = ip_routing_rule_parser_full,
+                                .writer_full         = ip_routing_rule_writer_full,
+                                .has_parser_full     = TRUE,
+                                .has_writer_full     = TRUE, ), ), ),
+    PARSE_INFO_SETTING(
+        NM_META_SETTING_TYPE_IP6_CONFIG,
+        PARSE_INFO_PROPERTIES(
+            PARSE_INFO_PROPERTY(NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE,
+                                .parser_no_check_key    = TRUE,
+                                .parser                 = ip6_addr_gen_mode_parser,
+                                .writer                 = ip6_addr_gen_mode_writer,
+                                .writer_persist_default = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ADDRESSES,
+                                .parser_no_check_key = TRUE,
+                                .parser              = ip_address_or_route_parser,
+                                .writer              = addr_writer, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_DNS,
+                                .parser_no_check_key = TRUE,
+                                .parser              = ip_dns_parser,
+                                .writer              = dns_writer, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_DNS_OPTIONS, .always_write = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_GATEWAY, .writer_skip = TRUE, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTES,
+                                .parser_no_check_key = TRUE,
+                                .parser              = ip_address_or_route_parser,
+                                .writer              = route_writer, ),
+            PARSE_INFO_PROPERTY(NM_SETTING_IP_CONFIG_ROUTING_RULES,
+                                .parser_no_check_key = TRUE,
+                                .parser_full         = ip_routing_rule_parser_full,
+                                .writer_full         = ip_routing_rule_writer_full,
+                                .has_parser_full     = TRUE,
+                                .has_writer_full     = TRUE, ), ), ),
     PARSE_INFO_SETTING(
         NM_META_SETTING_TYPE_OVS_EXTERNAL_IDS,
         PARSE_INFO_PROPERTIES(PARSE_INFO_PROPERTY(NM_SETTING_OVS_EXTERNAL_IDS_DATA,
@@ -3936,11 +3958,13 @@ write_setting_value(KeyfileWriterInfo        *info,
         char **array;
 
         array = (char **) g_value_get_boxed(&value);
-        nm_keyfile_plugin_kf_set_string_list(info->keyfile,
-                                             setting_info->setting_name,
-                                             key,
-                                             (const char **const) array,
-                                             g_strv_length(array));
+        if ((g_strv_length(array) != 0) || (pip && pip->always_write)) {
+            nm_keyfile_plugin_kf_set_string_list(info->keyfile,
+                                                 setting_info->setting_name,
+                                                 key,
+                                                 (const char **const) array,
+                                                 g_strv_length(array));
+        }
     } else if (type == G_TYPE_HASH_TABLE) {
         write_hash_of_string(info->keyfile, setting, key, &value);
     } else if (type == G_TYPE_ARRAY) {
@@ -4190,10 +4214,7 @@ nm_keyfile_write(NMConnection         *connection,
             || g_key_file_has_group(info.keyfile, setting_name)) {
             /* we have a section for the setting. Nothing to do. */
         } else {
-            /* ensure the group is present. There is no API for that, so add and remove
-             * a dummy key. */
-            g_key_file_set_value(info.keyfile, setting_alias ?: setting_name, ".X", "1");
-            g_key_file_remove_key(info.keyfile, setting_alias ?: setting_name, ".X", NULL);
+            nm_keyfile_add_group(info.keyfile, setting_alias ?: setting_name);
         }
 
         if (NM_IS_SETTING_WIREGUARD(setting)) {
diff --git a/src/libnm-core-impl/tests/test-setting.c b/src/libnm-core-impl/tests/test-setting.c
index d6ac37b4..b260ac37 100644
--- a/src/libnm-core-impl/tests/test-setting.c
+++ b/src/libnm-core-impl/tests/test-setting.c
@@ -3587,20 +3587,16 @@ test_roundtrip_conversion(gconstpointer test_data)
                             "uuid=%s\n"
                             "type=ethernet\n"
                             "interface-name=%s\n"
-                            "permissions=\n"
                             "\n"
                             "[ethernet]\n"
-                            "mac-address-blacklist=\n"
                             "%s" /* mtu */
                             "\n"
                             "%s" /* [ethernet-s390-options] */
                             "[ipv4]\n"
-                            "dns-search=\n"
                             "method=auto\n"
                             "\n"
                             "[ipv6]\n"
                             "addr-gen-mode=stable-privacy\n"
-                            "dns-search=\n"
                             "method=auto\n"
                             "\n"
                             "[proxy]\n"
@@ -3618,20 +3614,16 @@ test_roundtrip_conversion(gconstpointer test_data)
                             "uuid=%s\n"
                             "type=ethernet\n"
                             "interface-name=%s\n"
-                            "permissions=\n"
                             "\n"
                             "[ethernet]\n"
-                            "mac-address-blacklist=\n"
                             "%s" /* mtu */
                             "\n"
                             "%s" /* [ethernet-s390-options] */
                             "[ipv4]\n"
-                            "dns-search=\n"
                             "method=auto\n"
                             "\n"
                             "[ipv6]\n"
                             "addr-gen-mode=stable-privacy\n"
-                            "dns-search=\n"
                             "method=auto\n"
                             "",
                             ID,
@@ -3661,17 +3653,14 @@ test_roundtrip_conversion(gconstpointer test_data)
                                         "uuid=%s\n"
                                         "type=wireguard\n"
                                         "interface-name=%s\n"
-                                        "permissions=\n"
                                         "\n"
                                         "[wireguard]\n"
                                         "\n"
                                         "[ipv4]\n"
-                                        "dns-search=\n"
                                         "method=disabled\n"
                                         "\n"
                                         "[ipv6]\n"
                                         "addr-gen-mode=stable-privacy\n"
-                                        "dns-search=\n"
                                         "method=disabled\n"
                                         "\n"
                                         "[proxy]\n"
@@ -3713,7 +3702,6 @@ test_roundtrip_conversion(gconstpointer test_data)
                 "uuid=%s\n"
                 "type=wireguard\n"
                 "interface-name=%s\n"
-                "permissions=\n"
                 "\n"
                 "[wireguard]\n"
                 "%s" /* fwmark */
@@ -3723,12 +3711,10 @@ test_roundtrip_conversion(gconstpointer test_data)
                 "%s" /* [wireguard-peers*] */
                 "\n"
                 "[ipv4]\n"
-                "dns-search=\n"
                 "method=disabled\n"
                 "\n"
                 "[ipv6]\n"
                 "addr-gen-mode=stable-privacy\n"
-                "dns-search=\n"
                 "method=disabled\n"
                 "\n"
                 "[proxy]\n"
@@ -3798,14 +3784,11 @@ test_roundtrip_conversion(gconstpointer test_data)
                             "uuid=%s\n"
                             "type=ethernet\n"
                             "interface-name=%s\n"
-                            "permissions=\n"
                             "\n"
                             "[ethernet]\n"
-                            "mac-address-blacklist=\n"
                             "%s" /* mtu */
                             "\n"
                             "[ipv4]\n"
-                            "dns-search=\n"
                             "method=auto\n"
                             "routing-rule1=priority 1 from 0.0.0.0/0 table 1000\n"
                             "routing-rule2=priority 2 from 192.168.1.0/25 table 1001\n"
@@ -3813,7 +3796,6 @@ test_roundtrip_conversion(gconstpointer test_data)
                             "\n"
                             "[ipv6]\n"
                             "addr-gen-mode=stable-privacy\n"
-                            "dns-search=\n"
                             "method=auto\n"
                             "routing-rule1=priority 1 from ::/0 table 1000\n"
                             "routing-rule2=priority 2 from 1:2:3:b::/65 table 1001\n"
diff --git a/src/libnm-core-intern/nm-keyfile-utils.h b/src/libnm-core-intern/nm-keyfile-utils.h
index 45741646..f79f020f 100644
--- a/src/libnm-core-intern/nm-keyfile-utils.h
+++ b/src/libnm-core-intern/nm-keyfile-utils.h
@@ -92,4 +92,6 @@ const char *nm_keyfile_key_encode(const char *name, char **out_to_free);
 
 const char *nm_keyfile_key_decode(const char *key, char **out_to_free);
 
+void nm_keyfile_add_group(GKeyFile *keyfile, const char *group);
+
 #endif /* __NM_KEYFILE_UTILS_H__ */
diff --git a/src/libnm-core-public/nm-version-macros.h b/src/libnm-core-public/nm-version-macros.h
index f0936734..25d432ad 100644
--- a/src/libnm-core-public/nm-version-macros.h
+++ b/src/libnm-core-public/nm-version-macros.h
@@ -30,7 +30,7 @@
  * Evaluates to the micro version number of NetworkManager which this source
  * compiled against.
  */
-#define NM_MICRO_VERSION (91)
+#define NM_MICRO_VERSION (92)
 
 /**
  * NM_CHECK_VERSION:
diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c
index 93935b98..ce21ebbb 100644
--- a/src/libnm-platform/nm-linux-platform.c
+++ b/src/libnm-platform/nm-linux-platform.c
@@ -1210,6 +1210,21 @@ _linktype_get_type(NMPlatform       *platform,
  * libnl unility functions and wrappers
  ******************************************************************/
 
+typedef struct {
+    /* The first time, we are called with "iter_more" false. If there is only
+     * one message to parse, the callee can leave this at false and be done
+     * (meaning, it can just ignore the potential parsing of multiple messages).
+     * If there are multiple message, then set this to TRUE. We will continue
+     * the parsing as long as this flag stays TRUE and an object gets returned. */
+    bool iter_more;
+
+    union {
+        struct {
+            guint next_multihop;
+        } ip6_route;
+    };
+} ParseNlmsgIter;
+
 #define NLMSG_TAIL(nmsg) ((struct rtattr *) (((char *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
 
 /* copied from iproute2's addattr_l(). */
@@ -3374,7 +3389,7 @@ _new_from_nl_addr(struct nlmsghdr *nlh, gboolean id_only)
 
 /* Copied and heavily modified from libnl3's rtnl_route_parse() and parse_multipath(). */
 static NMPObject *
-_new_from_nl_route(struct nlmsghdr *nlh, gboolean id_only)
+_new_from_nl_route(struct nlmsghdr *nlh, gboolean id_only, ParseNlmsgIter *parse_nlmsg_iter)
 {
     static const struct nla_policy policy[] = {
         [RTA_TABLE]     = {.type = NLA_U32},
@@ -3387,17 +3402,21 @@ _new_from_nl_route(struct nlmsghdr *nlh, gboolean id_only)
         [RTA_METRICS]   = {.type = NLA_NESTED},
         [RTA_MULTIPATH] = {.type = NLA_NESTED},
     };
+    guint                     multihop_idx;
     const struct rtmsg       *rtm;
     struct nlattr            *tb[G_N_ELEMENTS(policy)];
+    int                       addr_family;
     gboolean                  IS_IPv4;
     nm_auto_nmpobj NMPObject *obj = NULL;
     int                       addr_len;
     struct {
-        gboolean is_present;
+        gboolean found;
+        gboolean has_more;
         int      ifindex;
         NMIPAddr gateway;
     } nh = {
-        .is_present = FALSE,
+        .found    = FALSE,
+        .has_more = FALSE,
     };
     guint32 mss;
     guint32 window   = 0;
@@ -3407,6 +3426,10 @@ _new_from_nl_route(struct nlmsghdr *nlh, gboolean id_only)
     guint32 mtu      = 0;
     guint32 lock     = 0;
 
+    nm_assert((parse_nlmsg_iter->iter_more && parse_nlmsg_iter->ip6_route.next_multihop > 0)
+              || (!parse_nlmsg_iter->iter_more && parse_nlmsg_iter->ip6_route.next_multihop == 0));
+    multihop_idx = parse_nlmsg_iter->ip6_route.next_multihop;
+
     if (!nlmsg_valid_hdr(nlh, sizeof(*rtm)))
         return NULL;
 
@@ -3416,9 +3439,11 @@ _new_from_nl_route(struct nlmsghdr *nlh, gboolean id_only)
      * only handle ~supported~ routes.
      *****************************************************************/
 
-    if (rtm->rtm_family == AF_INET)
+    addr_family = rtm->rtm_family;
+
+    if (addr_family == AF_INET)
         IS_IPv4 = TRUE;
-    else if (rtm->rtm_family == AF_INET6)
+    else if (addr_family == AF_INET6)
         IS_IPv4 = FALSE;
     else
         return NULL;
@@ -3436,57 +3461,76 @@ _new_from_nl_route(struct nlmsghdr *nlh, gboolean id_only)
 
     /*****************************************************************/
 
-    addr_len = IS_IPv4 ? sizeof(in_addr_t) : sizeof(struct in6_addr);
+    addr_len = nm_utils_addr_family_to_size(addr_family);
 
     if (rtm->rtm_dst_len > (IS_IPv4 ? 32 : 128))
         return NULL;
 
-    /*****************************************************************
-     * parse nexthops. Only handle routes with one nh.
-     *****************************************************************/
-
     if (tb[RTA_MULTIPATH]) {
-        size_t            tlen = nla_len(tb[RTA_MULTIPATH]);
+        size_t            tlen;
         struct rtnexthop *rtnh;
+        guint             idx;
 
+        tlen = nla_len(tb[RTA_MULTIPATH]);
         if (tlen < sizeof(*rtnh))
             goto rta_multipath_done;
 
         rtnh = nla_data_as(struct rtnexthop, tb[RTA_MULTIPATH]);
-
         if (tlen < rtnh->rtnh_len)
             goto rta_multipath_done;
 
+        idx = 0;
         while (TRUE) {
-            if (nh.is_present) {
-                /* we don't support multipath routes. */
-                return NULL;
-            }
-
-            nh.is_present = TRUE;
-            nh.ifindex    = rtnh->rtnh_ifindex;
-
-            if (rtnh->rtnh_len > sizeof(*rtnh)) {
-                struct nlattr *ntb[G_N_ELEMENTS(policy)];
+            if (idx == multihop_idx) {
+                nh.found   = TRUE;
+                nh.ifindex = rtnh->rtnh_ifindex;
+                if (rtnh->rtnh_len > sizeof(*rtnh)) {
+                    struct nlattr *ntb[RTA_MAX + 1];
+
+                    if (nla_parse_arr(ntb,
+                                      (struct nlattr *) RTNH_DATA(rtnh),
+                                      rtnh->rtnh_len - sizeof(*rtnh),
+                                      NULL)
+                        < 0)
+                        return NULL;
 
-                if (nla_parse_arr(ntb,
-                                  (struct nlattr *) RTNH_DATA(rtnh),
-                                  rtnh->rtnh_len - sizeof(*rtnh),
-                                  policy)
-                    < 0)
+                    if (_check_addr_or_return_null(ntb, RTA_GATEWAY, addr_len))
+                        memcpy(&nh.gateway, nla_data(ntb[RTA_GATEWAY]), addr_len);
+                }
+            } else if (nh.found) {
+                /* we just parsed a nexthop, but there is yet another hop afterwards. */
+                nm_assert(idx == multihop_idx + 1);
+                if (IS_IPv4) {
+                    /* for IPv4, multihop routes are currently not supported.
+                     *
+                     * If we ever support them, then the next-hop list is part of the NMPlatformIPRoute,
+                     * that is, for IPv4 we truly have multihop routes. Unlike for IPv6.
+                     *
+                     * For now, just error out. */
                     return NULL;
+                }
 
-                if (_check_addr_or_return_null(ntb, RTA_GATEWAY, addr_len))
-                    memcpy(&nh.gateway, nla_data(ntb[RTA_GATEWAY]), addr_len);
+                /* For IPv6 multihop routes, we need to remember to iterate again.
+                 * For each next-hop, we will create a distinct single-hop NMPlatformIP6Route. */
+                nh.has_more = TRUE;
+                break;
             }
 
             if (tlen < RTNH_ALIGN(rtnh->rtnh_len) + sizeof(*rtnh))
-                goto rta_multipath_done;
+                break;
 
             tlen -= RTNH_ALIGN(rtnh->rtnh_len);
             rtnh = RTNH_NEXT(rtnh);
+            idx++;
         }
-rta_multipath_done:;
+    }
+
+rta_multipath_done:
+
+    if (!nh.found && multihop_idx > 0) {
+        /* something is wrong. We are called back to collect multi_idx, but the index
+         * is not there. We messed up the book keeping. */
+        return nm_assert_unreachable_val(NULL);
     }
 
     if (tb[RTA_OIF] || tb[RTA_GATEWAY] || tb[RTA_FLOW]) {
@@ -3498,18 +3542,21 @@ rta_multipath_done:;
         if (_check_addr_or_return_null(tb, RTA_GATEWAY, addr_len))
             memcpy(&gateway, nla_data(tb[RTA_GATEWAY]), addr_len);
 
-        if (!nh.is_present) {
+        if (!nh.found) {
             /* If no nexthops have been provided via RTA_MULTIPATH
              * we add it as regular nexthop to maintain backwards
              * compatibility */
-            nh.ifindex    = ifindex;
-            nh.gateway    = gateway;
-            nh.is_present = TRUE;
+            nh.ifindex = ifindex;
+            nh.gateway = gateway;
+            nh.found   = TRUE;
         } else {
             /* Kernel supports new style nexthop configuration,
              * verify that it is a duplicate and ignore old-style nexthop. */
-            if (nh.ifindex != ifindex || memcmp(&nh.gateway, &gateway, addr_len) != 0)
+            if (nh.ifindex != ifindex || memcmp(&nh.gateway, &gateway, addr_len) != 0) {
+                /* we have a RTA_MULTIPATH attribute that does not agree.
+                 * That seems not right. Error out. */
                 return NULL;
+            }
         }
     }
 
@@ -3518,7 +3565,7 @@ rta_multipath_done:;
          *
          * Well, actually, for IPv6 kernel will always say that the device is
          * 1 (lo). Of course it does!! */
-        if (nh.is_present) {
+        if (nh.found) {
             if (IS_IPv4) {
                 if (nh.ifindex != 0 || nh.gateway.addr4 != 0) {
                     /* we only accept kernel to notify about the ifindex/gateway, if it
@@ -3536,7 +3583,7 @@ rta_multipath_done:;
             }
         }
     } else {
-        if (!nh.is_present) {
+        if (!nh.found) {
             /* a "normal" route needs a device. This is not the route we are looking for. */
             return NULL;
         }
@@ -3639,6 +3686,12 @@ rta_multipath_done:;
     obj->ip_route.r_rtm_flags = rtm->rtm_flags;
     obj->ip_route.rt_source   = nmp_utils_ip_config_source_from_rtprot(rtm->rtm_protocol);
 
+    if (nh.has_more) {
+        parse_nlmsg_iter->iter_more               = TRUE;
+        parse_nlmsg_iter->ip6_route.next_multihop = multihop_idx + 1;
+    } else
+        parse_nlmsg_iter->iter_more = FALSE;
+
     return g_steal_pointer(&obj);
 }
 
@@ -4080,7 +4133,8 @@ static NMPObject *
 nmp_object_new_from_nl(NMPlatform     *platform,
                        const NMPCache *cache,
                        struct nl_msg  *msg,
-                       gboolean        id_only)
+                       gboolean        id_only,
+                       ParseNlmsgIter *parse_nlmsg_iter)
 {
     struct nlmsghdr *msghdr;
 
@@ -4102,7 +4156,7 @@ nmp_object_new_from_nl(NMPlatform     *platform,
     case RTM_NEWROUTE:
     case RTM_DELROUTE:
     case RTM_GETROUTE:
-        return _new_from_nl_route(msghdr, id_only);
+        return _new_from_nl_route(msghdr, id_only, parse_nlmsg_iter);
     case RTM_NEWRULE:
     case RTM_DELRULE:
     case RTM_GETRULE:
@@ -6977,12 +7031,13 @@ event_valid_msg(NMPlatform *platform, struct nl_msg *msg, gboolean handle_events
     gboolean                  is_del  = FALSE;
     gboolean                  is_dump = FALSE;
     NMPCache                 *cache   = nm_platform_get_cache(platform);
-
-    msghdr = nlmsg_hdr(msg);
+    ParseNlmsgIter            parse_nlmsg_iter;
 
     if (!handle_events)
         return;
 
+    msghdr = nlmsg_hdr(msg);
+
     if (NM_IN_SET(msghdr->nlmsg_type,
                   RTM_DELLINK,
                   RTM_DELADDR,
@@ -6995,7 +7050,11 @@ event_valid_msg(NMPlatform *platform, struct nl_msg *msg, gboolean handle_events
         is_del = TRUE;
     }
 
-    obj = nmp_object_new_from_nl(platform, cache, msg, is_del);
+    parse_nlmsg_iter = (ParseNlmsgIter){
+        .iter_more = FALSE,
+    };
+
+    obj = nmp_object_new_from_nl(platform, cache, msg, is_del, &parse_nlmsg_iter);
     if (!obj) {
         _LOGT("event-notification: %s: ignore",
               nl_nlmsghdr_to_str(msghdr, buf_nlmsghdr, sizeof(buf_nlmsghdr)));
@@ -7023,7 +7082,7 @@ event_valid_msg(NMPlatform *platform, struct nl_msg *msg, gboolean handle_events
                                NULL,
                                0));
 
-    {
+    while (TRUE) {
         nm_auto_nmpobj const NMPObject *obj_old = NULL;
         nm_auto_nmpobj const NMPObject *obj_new = NULL;
 
@@ -7085,7 +7144,10 @@ event_valid_msg(NMPlatform *platform, struct nl_msg *msg, gboolean handle_events
                  *
                  * This is to help with the performance overhead of a huge number of
                  * routes, for example with the bird BGP software, that adds routes
-                 * with RTPROT_BIRD protocol. */
+                 * with RTPROT_BIRD protocol.
+                 *
+                 * Even if this is a IPv6 multipath route, we abort (parse_nlmsg_iter). There
+                 * is nothing for us to do. */
                 return;
             }
 
@@ -7158,6 +7220,31 @@ event_valid_msg(NMPlatform *platform, struct nl_msg *msg, gboolean handle_events
         default:
             break;
         }
+
+        if (!parse_nlmsg_iter.iter_more) {
+            /* we are done. */
+            return;
+        }
+
+        /* There is a special case here. For IPv6 routes, kernel will merge/mangle routes
+         * that only differ by their next-hop, and pretend they are multi-hop routes. We
+         * untangle them, and pretend there are only single-hop routes. Hence, one RTM_{NEW,DEL}ROUTE
+         * message might be about multiple IPv6 routes (NMPObject). So, now let's parse the next... */
+
+        nm_assert(NM_IN_SET(msghdr->nlmsg_type, RTM_NEWROUTE, RTM_DELROUTE));
+
+        nm_clear_pointer(&obj, nmp_object_unref);
+
+        obj = nmp_object_new_from_nl(platform, cache, msg, is_del, &parse_nlmsg_iter);
+        if (!obj) {
+            /* we are done. Usually we don't expect this, because we were told that
+             * there would be another object to collect, but there isn't one. Something
+             * unusual happened.
+             *
+             * the only reason why this actually could happen is if the next-hop data
+             * is invalid -- we didn't verify that it would be valid when we set iter_more. */
+            return;
+        }
     }
 }
 
diff --git a/tools/run-nm-test.sh b/tools/run-nm-test.sh
index 59a48933..c88a1bd5 100755
--- a/tools/run-nm-test.sh
+++ b/tools/run-nm-test.sh
@@ -302,8 +302,8 @@ if ! _is_true "$NMTST_USE_VALGRIND" 0; then
     export NM_TEST_UNDER_VALGRIND=0
     "${NMTST_DBUS_RUN_SESSION[@]}" "$TEST" "${TEST_ARGV[@]}"
     r=$?
-    [ $r == 0 ] || die "exec \"$TEST\" failed with exit code $r"
-    exit 0
+    [ $r == 0 -o $r == 77 ] || die "exec \"$TEST\" failed with exit code $r"
+    exit $r
 fi
 
 if [[ -z "${NMTST_VALGRIND}" ]]; then