summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Vaclav <jvaclav@redhat.com>2024-04-24 13:28:06 +0000
committerJan Vaclav <jvaclav@redhat.com>2024-04-24 13:28:06 +0000
commit905adf029806b182a1e60de6e4a2c76f129cd06e (patch)
tree67e1dfa9960adff8b1d47fed99121183e6190924
parentd5cd37a525b6bf8aebb6bd8eb604df711bb5e278 (diff)
parent5b9383aa68621f6ccb7e6490e0bdcf3428662751 (diff)
Merge branch 'jv/rhel10-meson-default' into jv/temp-mesonjv/temp-meson
-rwxr-xr-x.gitlab-ci/run-test.sh2
-rw-r--r--NEWS2
-rw-r--r--configure.ac2
-rw-r--r--contrib/fedora/rpm/NetworkManager.spec48
-rw-r--r--docs/api/network-manager-docs.xml4
-rw-r--r--docs/api/settings-spec.xsl4
-rw-r--r--docs/libnm/libnm-docs.xml4
-rw-r--r--man/NetworkManager-dispatcher.xml4
-rw-r--r--man/NetworkManager-wait-online.service.xml4
-rw-r--r--man/NetworkManager.conf.xml4
-rw-r--r--man/NetworkManager.xml4
-rw-r--r--man/nm-cloud-setup.xml4
-rw-r--r--man/nm-initrd-generator.xml4
-rw-r--r--man/nm-online.xml4
-rw-r--r--man/nm-openvswitch.xml4
-rw-r--r--man/nm-settings-dbus.xsl4
-rw-r--r--man/nm-settings-ifcfg-rh.xsl4
-rw-r--r--man/nm-settings-keyfile.xsl4
-rw-r--r--man/nm-settings-nmcli.xsl4
-rw-r--r--man/nmcli-examples.xml4
-rw-r--r--man/nmcli.xml4
-rw-r--r--man/nmtui.xml4
-rw-r--r--meson.build12
-rw-r--r--meson_options.txt1
-rw-r--r--src/core/devices/wwan/nm-modem-broadband.c64
-rw-r--r--src/libnm-core-impl/nm-setting-connection.c4
-rw-r--r--src/libnm-platform/nm-netlink.c9
-rw-r--r--src/libnm-systemd-core/src/libsystemd/sd-device/sd-device.c2
-rw-r--r--src/libnm-systemd-core/src/libsystemd/sd-event/sd-event.c6
-rw-r--r--src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.c4
-rw-r--r--src/libnm-systemd-core/src/systemd/sd-dhcp-duid.h1
-rw-r--r--src/libnm-systemd-core/src/systemd/sd-ndisc.h91
-rw-r--r--src/libnm-systemd-shared/src/basic/env-util.c33
-rw-r--r--src/libnm-systemd-shared/src/basic/env-util.h10
-rw-r--r--src/libnm-systemd-shared/src/basic/extract-word.c35
-rw-r--r--src/libnm-systemd-shared/src/basic/extract-word.h5
-rw-r--r--src/libnm-systemd-shared/src/basic/fd-util.c83
-rw-r--r--src/libnm-systemd-shared/src/basic/fd-util.h6
-rw-r--r--src/libnm-systemd-shared/src/basic/format-util.h8
-rw-r--r--src/libnm-systemd-shared/src/basic/fs-util.c16
-rw-r--r--src/libnm-systemd-shared/src/basic/fs-util.h10
-rw-r--r--src/libnm-systemd-shared/src/basic/glyph-util.c13
-rw-r--r--src/libnm-systemd-shared/src/basic/glyph-util.h6
-rw-r--r--src/libnm-systemd-shared/src/basic/hashmap.c53
-rw-r--r--src/libnm-systemd-shared/src/basic/hashmap.h10
-rw-r--r--src/libnm-systemd-shared/src/basic/in-addr-util.c16
-rw-r--r--src/libnm-systemd-shared/src/basic/in-addr-util.h2
-rw-r--r--src/libnm-systemd-shared/src/basic/locale-util.c7
-rw-r--r--src/libnm-systemd-shared/src/basic/log.h4
-rw-r--r--src/libnm-systemd-shared/src/basic/missing_fcntl.h21
-rw-r--r--src/libnm-systemd-shared/src/basic/missing_syscall.h19
-rw-r--r--src/libnm-systemd-shared/src/basic/namespace-util.h2
-rw-r--r--src/libnm-systemd-shared/src/basic/process-util.c23
-rw-r--r--src/libnm-systemd-shared/src/basic/process-util.h27
-rw-r--r--src/libnm-systemd-shared/src/basic/signal-util.c28
-rw-r--r--src/libnm-systemd-shared/src/basic/signal-util.h9
-rw-r--r--src/libnm-systemd-shared/src/basic/stat-util.c204
-rw-r--r--src/libnm-systemd-shared/src/basic/stat-util.h29
-rw-r--r--src/libnm-systemd-shared/src/basic/string-util.c3
-rw-r--r--src/libnm-systemd-shared/src/basic/strv.c2
-rw-r--r--src/libnm-systemd-shared/src/basic/time-util.c6
-rw-r--r--src/libnm-systemd-shared/src/fundamental/macro-fundamental.h26
-rw-r--r--src/libnmc-setting/settings-docs.h.in2
-rw-r--r--src/nmcli/gen-metadata-nm-settings-nmcli.xml.in2
-rwxr-xr-xtools/enums-to-docbook.pl2
65 files changed, 640 insertions, 402 deletions
diff --git a/.gitlab-ci/run-test.sh b/.gitlab-ci/run-test.sh
index e96f57e603..cd12220315 100755
--- a/.gitlab-ci/run-test.sh
+++ b/.gitlab-ci/run-test.sh
@@ -124,7 +124,7 @@ check_run_clean rpm+meson && test $IS_FEDORA = 1 && ./cont
if check_run_clean tarball && [ "$NM_BUILD_TARBALL" = 1 ]; then
SIGN_SOURCE=0 ./contrib/fedora/rpm/build_clean.sh -r
- mv ./NetworkManager-1*.tar.xz "$ARTIFACT_DIR/"
+ mv ./build/meson-dist/NetworkManager-1*.tar.xz "$ARTIFACT_DIR/"
mv ./contrib/fedora/rpm/latest/SRPMS/NetworkManager-1*.src.rpm "$ARTIFACT_DIR/"
do_clean
fi
diff --git a/NEWS b/NEWS
index 5dd05ed1bd..6420f894c3 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,8 @@ USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
* Deprecated 802-11-wireless and 802-11-wired property 'mac-address-blacklist'
and introduced the 'mac-address-denylist' property.
* Fix detection of 6 GHz band capability for WiFi devices
+* Allow IPv6 SLAAC and static IPv6 DNS server assignment for modem broadband
+ when IPv6 device address was not explicitly passed on by ModemManager
=============================================
NetworkManager-1.46
diff --git a/configure.ac b/configure.ac
index 358f9fc8d9..b2f5a45c64 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], [47])
-m4_define([nm_micro_version], [4])
+m4_define([nm_micro_version], [5])
m4_define([nm_version],
[nm_major_version.nm_minor_version.nm_micro_version])
diff --git a/contrib/fedora/rpm/NetworkManager.spec b/contrib/fedora/rpm/NetworkManager.spec
index b305aaac1c..9d78200cf1 100644
--- a/contrib/fedora/rpm/NetworkManager.spec
+++ b/contrib/fedora/rpm/NetworkManager.spec
@@ -48,7 +48,7 @@
%global systemd_units_cloud_setup nm-cloud-setup.service nm-cloud-setup.timer
###############################################################################
-%if 0%{?fedora} >= 39
+%if 0%{?fedora} > 40 || 0%{?rhel} >= 10
%bcond_without meson
%else
%bcond_with meson
@@ -56,7 +56,11 @@
%bcond_without adsl
%bcond_without bluetooth
%bcond_without wwan
+%if 0%{?rhel} >= 10
+%bcond_with team
+%else
%bcond_without team
+%endif
%bcond_without wifi
%bcond_without ovs
%bcond_without ppp
@@ -161,13 +165,18 @@
%global config_plugins_default_ifcfg_rh 1
%endif
-%if 0%{?fedora} >= 36 || 0%{?rhel} >= 10
+%if 0%{?rhel} >= 10
+%global with_ifcfg_rh 0
+%global split_ifcfg_rh 0
+%elif 0%{?fedora} >= 36
+%global with_ifcfg_rh 1
%global split_ifcfg_rh 1
%else
+%global with_ifcfg_rh 1
%global split_ifcfg_rh 0
%endif
-%if (0%{?fedora} >= 36 && 0%{?fedora} < 39) || 0%{?rhel} >= 9
+%if (0%{?fedora} >= 36 && 0%{?fedora} < 39) || 0%{?rhel} == 9
%global ifcfg_warning 1
%else
%global ifcfg_warning 0
@@ -543,6 +552,7 @@ This package is intended to be installed by default for server
deployments.
+%if %{?with_ifcfg_rh}
%package dispatcher-routing-rules
Summary: NetworkManager dispatcher file for advanced routing rules
Group: System Environment/Base
@@ -557,6 +567,7 @@ Obsoletes: %{name}-config-routing-rules < 1:1.31.0
This adds a NetworkManager dispatcher file to support networking
configurations using "/etc/sysconfig/network-scripts/rule-NAME" files
(eg, to do policy-based routing).
+%endif
%if %{with nmtui}
@@ -600,6 +611,7 @@ like Aliyun, Azure, EC2, GCP are supported.
%endif
+%if %{?with_ifcfg_rh}
%package initscripts-updown
Summary: Legacy ifup/ifdown scripts for NetworkManager that replace initscripts (network-scripts)
Group: System Environment/Base
@@ -612,7 +624,7 @@ Obsoletes: NetworkManager < %{obsoletes_initscripts_updown}
Installs alternative ifup/ifdown scripts that talk to NetworkManager.
This is only for backward compatibility with initscripts (network-scripts).
Preferably use nmcli instead.
-
+%endif
%prep
%autosetup -p1 -n NetworkManager-%{real_version}
@@ -726,7 +738,11 @@ Preferably use nmcli instead.
-Ddbus_conf_dir=%{dbus_sys_dir} \
-Dtests=yes \
-Dvalgrind=no \
+%if %{?with_ifcfg_rh}
-Difcfg_rh=true \
+%else
+ -Difcfg_rh=false \
+%endif
-Difupdown=false \
%if %{with ppp}
-Dppp=true \
@@ -874,7 +890,11 @@ autoreconf --install --force
--enable-more-warnings=yes \
%endif
--with-valgrind=no \
+%if %{?with_ifcfg_rh}
--enable-ifcfg-rh=yes \
+%else
+ --enable-ifcfg-rh=no \
+%endif
--enable-ifupdown=no \
%if %{with ppp}
--enable-ppp=yes \
@@ -936,9 +956,11 @@ cp %{SOURCE8} %{buildroot}%{_sysconfdir}/sysconfig/network-scripts
cp %{SOURCE9} %{buildroot}%{_sysconfdir}/sysconfig/network-scripts/readme-ifcfg-rh.txt
%endif
+%if %{?with_ifcfg_rh}
cp examples/dispatcher/10-ifcfg-rh-routes.sh %{buildroot}%{nmlibdir}/dispatcher.d/
ln -s ../no-wait.d/10-ifcfg-rh-routes.sh %{buildroot}%{nmlibdir}/dispatcher.d/pre-up.d/
ln -s ../10-ifcfg-rh-routes.sh %{buildroot}%{nmlibdir}/dispatcher.d/no-wait.d/
+%endif
%find_lang %{name}
@@ -954,9 +976,10 @@ mkdir -p %{buildroot}%{_prefix}/src/debug/NetworkManager-%{real_version}
cp valgrind.suppressions %{buildroot}%{_prefix}/src/debug/NetworkManager-%{real_version}
%endif
+%if %{?with_ifcfg_rh}
touch %{buildroot}%{_sbindir}/ifup
touch %{buildroot}%{_sbindir}/ifdown
-
+%endif
%check
%if %{with meson}
@@ -999,6 +1022,7 @@ fi
%systemd_post %{systemd_units}
+%if %{?with_ifcfg_rh}
%post initscripts-updown
if [ -f %{_sbindir}/ifup -a ! -L %{_sbindir}/ifup ]; then
# initscripts package too old, won't let us set an alternative
@@ -1007,6 +1031,7 @@ else
/usr/sbin/update-alternatives --install %{_sbindir}/ifup ifup %{_libexecdir}/nm-ifup 50 \
--slave %{_sbindir}/ifdown ifdown %{_libexecdir}/nm-ifdown
fi
+%endif
%if %{with nm_cloud_setup}
@@ -1026,10 +1051,12 @@ fi
%systemd_preun NetworkManager-wait-online.service NetworkManager-dispatcher.service nm-priv-helper.service
+%if %{?with_ifcfg_rh}
%preun initscripts-updown
if [ $1 -eq 0 ]; then
/usr/sbin/update-alternatives --remove ifup %{_libexecdir}/nm-ifup >/dev/null 2>&1 || :
fi
+%endif
%if %{with nm_cloud_setup}
@@ -1064,7 +1091,7 @@ fi
%{dbus_sys_dir}/org.freedesktop.NetworkManager.conf
%{dbus_sys_dir}/nm-dispatcher.conf
%{dbus_sys_dir}/nm-priv-helper.conf
-%if 0%{?split_ifcfg_rh} == 0
+%if %{?with_ifcfg_rh} && 0%{?split_ifcfg_rh} == 0
%{dbus_sys_dir}/nm-ifcfg-rh.conf
%endif
%{_sbindir}/%{name}
@@ -1092,7 +1119,7 @@ fi
%{_libexecdir}/nm-priv-helper
%dir %{_libdir}/%{name}
%dir %{nmplugindir}
-%if 0%{?split_ifcfg_rh} == 0
+%if %{?with_ifcfg_rh} && 0%{?split_ifcfg_rh} == 0
%{nmplugindir}/libnm-settings-plugin-ifcfg-rh.so
%endif
%if %{with nmtui}
@@ -1114,7 +1141,9 @@ fi
%{_mandir}/man8/NetworkManager-dispatcher.8*
%{_mandir}/man8/NetworkManager-wait-online.service.8*
%dir %{_localstatedir}/lib/NetworkManager
+%if %{?with_ifcfg_rh}
%dir %{_sysconfdir}/sysconfig/network-scripts
+%endif
%{_datadir}/dbus-1/system-services/org.freedesktop.nm_dispatcher.service
%{_datadir}/dbus-1/system-services/org.freedesktop.nm_priv_helper.service
%{_datadir}/polkit-1/actions/*.policy
@@ -1229,11 +1258,12 @@ fi
%{nmlibdir}/conf.d/00-server.conf
+%if %{?with_ifcfg_rh}
%files dispatcher-routing-rules
%{nmlibdir}/dispatcher.d/10-ifcfg-rh-routes.sh
%{nmlibdir}/dispatcher.d/no-wait.d/10-ifcfg-rh-routes.sh
%{nmlibdir}/dispatcher.d/pre-up.d/10-ifcfg-rh-routes.sh
-
+%endif
%if %{with nmtui}
%files tui
@@ -1264,11 +1294,13 @@ fi
%endif
+%if %{?with_ifcfg_rh}
%files initscripts-updown
%{_libexecdir}/nm-ifup
%ghost %attr(755, root, root) %{_sbindir}/ifup
%{_libexecdir}/nm-ifdown
%ghost %attr(755, root, root) %{_sbindir}/ifdown
+%endif
%changelog
diff --git a/docs/api/network-manager-docs.xml b/docs/api/network-manager-docs.xml
index faee87992e..a7cf24610a 100644
--- a/docs/api/network-manager-docs.xml
+++ b/docs/api/network-manager-docs.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY version SYSTEM "version.xml">
]>
<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
diff --git a/docs/api/settings-spec.xsl b/docs/api/settings-spec.xsl
index 7a4522370e..39d4e357f1 100644
--- a/docs/api/settings-spec.xsl
+++ b/docs/api/settings-spec.xsl
@@ -4,8 +4,8 @@
<xsl:output
method="xml"
- doctype-public="-//OASIS//DTD DocBook XML V4.3//EN"
- doctype-system="http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+ doctype-public="-//OASIS//DTD DocBook XML V4.5//EN"
+ doctype-system="http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
/>
<xsl:template match="nm-setting-docs">
diff --git a/docs/libnm/libnm-docs.xml b/docs/libnm/libnm-docs.xml
index f2b5658cdf..1b37fdd253 100644
--- a/docs/libnm/libnm-docs.xml
+++ b/docs/libnm/libnm-docs.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY version SYSTEM "version.xml">
]>
diff --git a/man/NetworkManager-dispatcher.xml b/man/NetworkManager-dispatcher.xml
index f85a495ac7..807e5c4cdd 100644
--- a/man/NetworkManager-dispatcher.xml
+++ b/man/NetworkManager-dispatcher.xml
@@ -1,7 +1,7 @@
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % entities SYSTEM "common.ent" >
%entities;
]>
diff --git a/man/NetworkManager-wait-online.service.xml b/man/NetworkManager-wait-online.service.xml
index 4776002c86..4a8b63bb35 100644
--- a/man/NetworkManager-wait-online.service.xml
+++ b/man/NetworkManager-wait-online.service.xml
@@ -1,7 +1,7 @@
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % entities SYSTEM "common.ent" >
%entities;
]>
diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml
index 3ea511d0b2..fc184ff774 100644
--- a/man/NetworkManager.conf.xml
+++ b/man/NetworkManager.conf.xml
@@ -1,7 +1,7 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % entities SYSTEM "common.ent" >
%entities;
]>
diff --git a/man/NetworkManager.xml b/man/NetworkManager.xml
index ff1635cd29..c2392ad36d 100644
--- a/man/NetworkManager.xml
+++ b/man/NetworkManager.xml
@@ -1,7 +1,7 @@
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % entities SYSTEM "common.ent" >
%entities;
]>
diff --git a/man/nm-cloud-setup.xml b/man/nm-cloud-setup.xml
index d0e14b4fae..7f9a7dbc52 100644
--- a/man/nm-cloud-setup.xml
+++ b/man/nm-cloud-setup.xml
@@ -1,7 +1,7 @@
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % entities SYSTEM "common.ent" >
%entities;
]>
diff --git a/man/nm-initrd-generator.xml b/man/nm-initrd-generator.xml
index 27219fda4c..51015ea8a3 100644
--- a/man/nm-initrd-generator.xml
+++ b/man/nm-initrd-generator.xml
@@ -1,7 +1,7 @@
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % entities SYSTEM "common.ent" >
%entities;
]>
diff --git a/man/nm-online.xml b/man/nm-online.xml
index e9deb83e94..2ed8f3b9b6 100644
--- a/man/nm-online.xml
+++ b/man/nm-online.xml
@@ -1,7 +1,7 @@
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % entities SYSTEM "common.ent" >
%entities;
]>
diff --git a/man/nm-openvswitch.xml b/man/nm-openvswitch.xml
index f0c2ca9462..67b5ea7ce6 100644
--- a/man/nm-openvswitch.xml
+++ b/man/nm-openvswitch.xml
@@ -1,7 +1,7 @@
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % entities SYSTEM "common.ent" >
%entities;
]>
diff --git a/man/nm-settings-dbus.xsl b/man/nm-settings-dbus.xsl
index 665105eea0..c4bd6d8351 100644
--- a/man/nm-settings-dbus.xsl
+++ b/man/nm-settings-dbus.xsl
@@ -8,8 +8,8 @@
<xsl:output
method="xml"
- doctype-public="-//OASIS//DTD DocBook XML V4.3//EN"
- doctype-system="http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+ doctype-public="-//OASIS//DTD DocBook XML V4.5//EN"
+ doctype-system="http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
/>
<xsl:template match="nm-setting-docs">
diff --git a/man/nm-settings-ifcfg-rh.xsl b/man/nm-settings-ifcfg-rh.xsl
index 7b270e9b18..8ad3b10825 100644
--- a/man/nm-settings-ifcfg-rh.xsl
+++ b/man/nm-settings-ifcfg-rh.xsl
@@ -12,8 +12,8 @@
<xsl:output
method="xml"
- doctype-public="-//OASIS//DTD DocBook XML V4.3//EN"
- doctype-system="http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+ doctype-public="-//OASIS//DTD DocBook XML V4.5//EN"
+ doctype-system="http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
/>
<xsl:template match="nm-setting-docs">
diff --git a/man/nm-settings-keyfile.xsl b/man/nm-settings-keyfile.xsl
index 450cc6fdee..d216ee15dd 100644
--- a/man/nm-settings-keyfile.xsl
+++ b/man/nm-settings-keyfile.xsl
@@ -8,8 +8,8 @@
<xsl:output
method="xml"
- doctype-public="-//OASIS//DTD DocBook XML V4.3//EN"
- doctype-system="http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+ doctype-public="-//OASIS//DTD DocBook XML V4.5//EN"
+ doctype-system="http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
/>
<xsl:template match="nm-setting-docs">
diff --git a/man/nm-settings-nmcli.xsl b/man/nm-settings-nmcli.xsl
index 794ee507b1..2f1d035cdf 100644
--- a/man/nm-settings-nmcli.xsl
+++ b/man/nm-settings-nmcli.xsl
@@ -8,8 +8,8 @@
<xsl:output
method="xml"
- doctype-public="-//OASIS//DTD DocBook XML V4.3//EN"
- doctype-system="http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+ doctype-public="-//OASIS//DTD DocBook XML V4.5//EN"
+ doctype-system="http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
/>
<xsl:template match="nm-setting-docs">
diff --git a/man/nmcli-examples.xml b/man/nmcli-examples.xml
index 2c7e16ab79..5249d6ba04 100644
--- a/man/nmcli-examples.xml
+++ b/man/nmcli-examples.xml
@@ -1,7 +1,7 @@
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % entities SYSTEM "common.ent" >
%entities;
]>
diff --git a/man/nmcli.xml b/man/nmcli.xml
index 6b3054c3d7..6299404703 100644
--- a/man/nmcli.xml
+++ b/man/nmcli.xml
@@ -1,7 +1,7 @@
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % entities SYSTEM "common.ent" >
%entities;
]>
diff --git a/man/nmtui.xml b/man/nmtui.xml
index f610be9d08..eac94ab039 100644
--- a/man/nmtui.xml
+++ b/man/nmtui.xml
@@ -1,7 +1,7 @@
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % entities SYSTEM "common.ent" >
%entities;
]>
diff --git a/meson.build b/meson.build
index a7d5ea9ea3..c353aca291 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.47.4',
+ version: '1.47.5',
license: 'GPL2+',
default_options: [
'buildtype=debugoptimized',
@@ -43,10 +43,18 @@ nm_libexecdir = join_paths(nm_prefix, get_option('libexecdir'))
nm_localedir = join_paths(nm_prefix, get_option('localedir'))
nm_localstatedir = join_paths(nm_prefix, get_option('localstatedir'))
nm_mandir = join_paths(nm_prefix, get_option('mandir'))
-nm_runstatedir = join_paths(nm_localstatedir, 'run')
nm_sbindir = join_paths(nm_prefix, get_option('sbindir'))
nm_sysconfdir = join_paths(nm_prefix, get_option('sysconfdir'))
+nm_runstatedir = get_option('runtime_dir')
+if nm_runstatedir == ''
+ if get_option('prefix') == '/usr'
+ nm_runstatedir = '/run'
+ else
+ nm_runstatedir = join_paths(nm_localstatedir, 'run')
+ endif
+endif
+
nm_pkgsbindir = join_paths(nm_sbindir, nm_name)
nm_pkgconfdir = join_paths(nm_sysconfdir, nm_name)
nm_pkgdatadir = join_paths(nm_datadir, nm_name)
diff --git a/meson_options.txt b/meson_options.txt
index 92439ac539..75cf183d71 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -4,6 +4,7 @@ option('system_ca_path', type: 'string', value: '/etc/ssl/certs', description: '
option('udev_dir', type: 'string', value: '', description: 'Absolute path of the udev base directory. Set to \'no\' not to install the udev rule')
option('dbus_conf_dir', type: 'string', value: '', description: 'where D-Bus system.d directory is')
option('kernel_firmware_dir', type: 'string', value: '/lib/firmware', description: 'where kernel firmware directory is (default is /lib/firmware)')
+option('runtime_dir', type: 'string', value: '', description: 'Directory for transient runtime state [default: LOCALSTATEDIR/run or /run]')
option('iptables', type: 'string', value: '', description: 'path to iptables')
option('nft', type: 'string', value: '', description: 'path to nft')
option('dnsmasq', type: 'string', value: '', description: 'path to dnsmasq')
diff --git a/src/core/devices/wwan/nm-modem-broadband.c b/src/core/devices/wwan/nm-modem-broadband.c
index a150040f3c..c03446b955 100644
--- a/src/core/devices/wwan/nm-modem-broadband.c
+++ b/src/core/devices/wwan/nm-modem-broadband.c
@@ -1155,6 +1155,8 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho
#endif
} else {
NMPlatformIP6Address address;
+ NMPlatformIP6Address gw;
+ const char *gw_string;
address_string = mm_bearer_ip_config_get_address(self->_priv.ipv6_config);
if (!address_string) {
@@ -1165,20 +1167,8 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho
NM_DEVICE_ERROR_INVALID_CONNECTION,
"(%s) retrieving IPv6 configuration failed: no address given",
nm_modem_get_uid(NM_MODEM(self)));
+ goto out;
}
- goto out;
- }
-
- address = (NMPlatformIP6Address){};
-
- if (!inet_pton(AF_INET6, address_string, &address.address)) {
- g_set_error(&error,
- NM_DEVICE_ERROR,
- NM_DEVICE_ERROR_INVALID_CONNECTION,
- "(%s) retrieving IPv6 configuration failed: invalid address given '%s'",
- nm_modem_get_uid(NM_MODEM(self)),
- address_string);
- goto out;
}
data_port = mm_bearer_get_interface(self->_priv.bearer);
@@ -1202,43 +1192,57 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho
NM_IP_CONFIG_SOURCE_WWAN);
do_auto = TRUE;
- address.plen = mm_bearer_ip_config_get_prefix(self->_priv.ipv6_config);
- if (address.plen <= 128) {
- if (IN6_IS_ADDR_LINKLOCAL(&address.address)) {
- nm_utils_ipv6_interface_identifier_get_from_addr(&iid_data, &address.address);
- iid = &iid_data;
- } else
- do_auto = FALSE;
- nm_l3_config_data_add_address_6(l3cd, &address);
+ if (address_string) {
+ address = (NMPlatformIP6Address){};
+
+ if (!inet_pton(AF_INET6, address_string, &address.address)) {
+ g_set_error(&error,
+ NM_DEVICE_ERROR,
+ NM_DEVICE_ERROR_INVALID_CONNECTION,
+ "(%s) retrieving IPv6 configuration failed: invalid address given '%s'",
+ nm_modem_get_uid(NM_MODEM(self)),
+ address_string);
+ goto out;
+ }
+
+ address.plen = mm_bearer_ip_config_get_prefix(self->_priv.ipv6_config);
+ if (address.plen <= 128) {
+ if (IN6_IS_ADDR_LINKLOCAL(&address.address)) {
+ nm_utils_ipv6_interface_identifier_get_from_addr(&iid_data, &address.address);
+ iid = &iid_data;
+ } else
+ do_auto = FALSE;
+ nm_l3_config_data_add_address_6(l3cd, &address);
+ }
+
+ _LOGI(" address %s", nm_platform_ip6_address_to_string(&address, sbuf, sizeof(sbuf)));
}
- _LOGI(" address %s (slaac %s)",
- nm_platform_ip6_address_to_string(&address, sbuf, sizeof(sbuf)),
- do_auto ? "enabled" : "disabled");
+ _LOGI(" slaac %s", do_auto ? "enabled" : "disabled");
- address_string = mm_bearer_ip_config_get_gateway(self->_priv.ipv6_config);
- if (address_string) {
- if (inet_pton(AF_INET6, address_string, &address.address) != 1) {
+ gw_string = mm_bearer_ip_config_get_gateway(self->_priv.ipv6_config);
+ if (gw_string) {
+ if (inet_pton(AF_INET6, gw_string, &gw.address) != 1) {
g_set_error(&error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_INVALID_CONNECTION,
"(%s) retrieving IPv6 configuration failed: invalid gateway given '%s'",
nm_modem_get_uid(NM_MODEM(self)),
- address_string);
+ gw_string);
goto out;
}
{
const NMPlatformIP6Route r = {
.rt_source = NM_IP_CONFIG_SOURCE_WWAN,
- .gateway = address.address,
+ .gateway = gw.address,
.table_any = TRUE,
.table_coerced = 0,
.metric_any = TRUE,
.metric = 0,
};
- _LOGI(" gateway %s", address_string);
+ _LOGI(" gateway %s", gw_string);
nm_l3_config_data_add_route_6(l3cd, &r);
}
} else if (ip_method == NM_MODEM_IP_METHOD_STATIC) {
diff --git a/src/libnm-core-impl/nm-setting-connection.c b/src/libnm-core-impl/nm-setting-connection.c
index 46045c46f1..30a9509b6d 100644
--- a/src/libnm-core-impl/nm-setting-connection.c
+++ b/src/libnm-core-impl/nm-setting-connection.c
@@ -2665,9 +2665,9 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass)
* If -1 (default) is set, global connection.autoconnect-slaves is read to
* determine the real value. If it is default as well, this fallbacks to 0.
*
- * Since: 1.2
- *
* Deprecated 1.46. Use #NMSettingConnection:autoconnect-ports instead, this is just an alias.
+ *
+ * Since: 1.2
**/
/* ---ifcfg-rh---
* property: autoconnect-slaves
diff --git a/src/libnm-platform/nm-netlink.c b/src/libnm-platform/nm-netlink.c
index 5684b8cda5..6d15312882 100644
--- a/src/libnm-platform/nm-netlink.c
+++ b/src/libnm-platform/nm-netlink.c
@@ -4,6 +4,7 @@
*/
#include "libnm-glib-aux/nm-default-glib-i18n-lib.h"
+#include "libnm-glib-aux/nm-random-utils.h"
#include "nm-netlink.h"
@@ -1105,7 +1106,7 @@ nl_socket_new(struct nl_sock **out_sk,
{
nm_auto_nlsock struct nl_sock *sk = NULL;
nm_auto_close int fd = -1;
- time_t t;
+ unsigned seq_init;
int err;
int nmerr;
socklen_t addrlen;
@@ -1121,7 +1122,7 @@ nl_socket_new(struct nl_sock **out_sk,
if (fd < 0)
return -nm_errno_from_native(errno);
- t = time(NULL);
+ nm_random_get_bytes(&seq_init, sizeof(seq_init));
sk = g_slice_new(struct nl_sock);
*sk = (struct nl_sock){
@@ -1138,8 +1139,8 @@ nl_socket_new(struct nl_sock **out_sk,
.nl_family = AF_NETLINK,
.nl_groups = 0,
},
- .s_seq_expect = t,
- .s_seq_next = t,
+ .s_seq_expect = seq_init,
+ .s_seq_next = seq_init,
.s_bufsize = 0,
.s_msg_peek = !NM_FLAGS_HAS(flags, NL_SOCKET_FLAGS_DISABLE_MSG_PEEK),
.s_auto_ack = TRUE,
diff --git a/src/libnm-systemd-core/src/libsystemd/sd-device/sd-device.c b/src/libnm-systemd-core/src/libsystemd/sd-device/sd-device.c
index 2e7cdcb3d5..0ca871464f 100644
--- a/src/libnm-systemd-core/src/libsystemd/sd-device/sd-device.c
+++ b/src/libnm-systemd-core/src/libsystemd/sd-device/sd-device.c
@@ -223,7 +223,7 @@ int device_set_syspath(sd_device *device, const char *_syspath, bool verify) {
/* Only operate on sysfs, i.e. refuse going down into /sys/fs/cgroup/ or similar places where
* things are not arranged as kobjects in kernel, and hence don't necessarily have
* kobject/attribute structure. */
- r = getenv_bool_secure("SYSTEMD_DEVICE_VERIFY_SYSFS");
+ r = secure_getenv_bool("SYSTEMD_DEVICE_VERIFY_SYSFS");
if (r < 0 && r != -ENXIO)
log_debug_errno(r, "Failed to parse $SYSTEMD_DEVICE_VERIFY_SYSFS value: %m");
if (r != 0) {
diff --git a/src/libnm-systemd-core/src/libsystemd/sd-event/sd-event.c b/src/libnm-systemd-core/src/libsystemd/sd-event/sd-event.c
index 33cf30800c..6449b85c50 100644
--- a/src/libnm-systemd-core/src/libsystemd/sd-event/sd-event.c
+++ b/src/libnm-systemd-core/src/libsystemd/sd-event/sd-event.c
@@ -1579,7 +1579,7 @@ static int child_exit_callback(sd_event_source *s, const siginfo_t *si, void *us
static bool shall_use_pidfd(void) {
/* Mostly relevant for debugging, i.e. this is used in test-event.c to test the event loop once with and once without pidfd */
- return getenv_bool_secure("SYSTEMD_PIDFD") != 0;
+ return secure_getenv_bool("SYSTEMD_PIDFD") != 0;
}
_public_ int sd_event_add_child(
@@ -4923,13 +4923,13 @@ _public_ int sd_event_get_state(sd_event *e) {
_public_ int sd_event_get_exit_code(sd_event *e, int *code) {
assert_return(e, -EINVAL);
assert_return(e = event_resolve(e), -ENOPKG);
- assert_return(code, -EINVAL);
assert_return(!event_origin_changed(e), -ECHILD);
if (!e->exit_requested)
return -ENODATA;
- *code = e->exit_code;
+ if (code)
+ *code = e->exit_code;
return 0;
}
diff --git a/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.c b/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.c
index 1fc011c7f3..5817305548 100644
--- a/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.c
+++ b/src/libnm-systemd-core/src/libsystemd/sd-id128/id128-util.c
@@ -143,7 +143,7 @@ int id128_read_at(int dir_fd, const char *path, Id128Flag f, sd_id128_t *ret) {
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
assert(path);
- fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NOCTTY, /* xopen_flags = */ 0, /* mode = */ 0);
+ fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (fd < 0)
return fd;
@@ -190,7 +190,7 @@ int id128_write_at(int dir_fd, const char *path, Id128Flag f, sd_id128_t id) {
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
assert(path);
- fd = xopenat(dir_fd, path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_TRUNC, /* xopen_flags = */ 0, 0444);
+ fd = xopenat_full(dir_fd, path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_TRUNC, /* xopen_flags = */ 0, 0444);
if (fd < 0)
return fd;
diff --git a/src/libnm-systemd-core/src/systemd/sd-dhcp-duid.h b/src/libnm-systemd-core/src/systemd/sd-dhcp-duid.h
index b1d2772a3e..555b40e9d8 100644
--- a/src/libnm-systemd-core/src/systemd/sd-dhcp-duid.h
+++ b/src/libnm-systemd-core/src/systemd/sd-dhcp-duid.h
@@ -3,7 +3,6 @@
#define foosddhcpduidhfoo
/***
- Copyright © 2013 Intel Corporation. All rights reserved.
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
diff --git a/src/libnm-systemd-core/src/systemd/sd-ndisc.h b/src/libnm-systemd-core/src/systemd/sd-ndisc.h
index a5ccd5f644..5f4f6caf8d 100644
--- a/src/libnm-systemd-core/src/systemd/sd-ndisc.h
+++ b/src/libnm-systemd-core/src/systemd/sd-ndisc.h
@@ -26,35 +26,14 @@
#include <sys/types.h>
#include "sd-event.h"
+#include "sd-ndisc-protocol.h"
+#include "sd-ndisc-router.h"
#include "_sd-common.h"
_SD_BEGIN_DECLARATIONS;
-/* Neighbor Discovery Options, RFC 4861, Section 4.6 and
- * https://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml#icmpv6-parameters-5 */
-enum {
- SD_NDISC_OPTION_SOURCE_LL_ADDRESS = 1,
- SD_NDISC_OPTION_TARGET_LL_ADDRESS = 2,
- SD_NDISC_OPTION_PREFIX_INFORMATION = 3,
- SD_NDISC_OPTION_MTU = 5,
- SD_NDISC_OPTION_ROUTE_INFORMATION = 24,
- SD_NDISC_OPTION_RDNSS = 25,
- SD_NDISC_OPTION_FLAGS_EXTENSION = 26,
- SD_NDISC_OPTION_DNSSL = 31,
- SD_NDISC_OPTION_CAPTIVE_PORTAL = 37,
- SD_NDISC_OPTION_PREF64 = 38
-};
-
-/* Route preference, RFC 4191, Section 2.1 */
-enum {
- SD_NDISC_PREFERENCE_LOW = 3U,
- SD_NDISC_PREFERENCE_MEDIUM = 0U,
- SD_NDISC_PREFERENCE_HIGH = 1U
-};
-
typedef struct sd_ndisc sd_ndisc;
-typedef struct sd_ndisc_router sd_ndisc_router;
__extension__ typedef enum sd_ndisc_event_t {
SD_NDISC_EVENT_TIMEOUT,
@@ -64,14 +43,16 @@ __extension__ typedef enum sd_ndisc_event_t {
_SD_ENUM_FORCE_S64(NDISC_EVENT)
} sd_ndisc_event_t;
-typedef void (*sd_ndisc_callback_t)(sd_ndisc *nd, sd_ndisc_event_t event, sd_ndisc_router *rt, void *userdata);
+typedef void (*sd_ndisc_callback_t)(sd_ndisc *nd, sd_ndisc_event_t event, void *message, void *userdata);
int sd_ndisc_new(sd_ndisc **ret);
sd_ndisc *sd_ndisc_ref(sd_ndisc *nd);
sd_ndisc *sd_ndisc_unref(sd_ndisc *nd);
+_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ndisc, sd_ndisc_unref);
int sd_ndisc_start(sd_ndisc *nd);
int sd_ndisc_stop(sd_ndisc *nd);
+int sd_ndisc_is_running(sd_ndisc *nd);
int sd_ndisc_attach_event(sd_ndisc *nd, sd_event *event, int64_t priority);
int sd_ndisc_detach_event(sd_ndisc *nd);
@@ -81,69 +62,9 @@ int sd_ndisc_set_callback(sd_ndisc *nd, sd_ndisc_callback_t cb, void *userdata);
int sd_ndisc_set_ifindex(sd_ndisc *nd, int interface_index);
int sd_ndisc_set_ifname(sd_ndisc *nd, const char *interface_name);
int sd_ndisc_get_ifname(sd_ndisc *nd, const char **ret);
+int sd_ndisc_set_link_local_address(sd_ndisc *nd, const struct in6_addr *addr);
int sd_ndisc_set_mac(sd_ndisc *nd, const struct ether_addr *mac_addr);
-sd_ndisc_router *sd_ndisc_router_ref(sd_ndisc_router *rt);
-sd_ndisc_router *sd_ndisc_router_unref(sd_ndisc_router *rt);
-
-int sd_ndisc_router_get_address(sd_ndisc_router *rt, struct in6_addr *ret);
-int sd_ndisc_router_get_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret);
-int sd_ndisc_router_get_raw(sd_ndisc_router *rt, const void **ret, size_t *ret_size);
-
-int sd_ndisc_router_get_hop_limit(sd_ndisc_router *rt, uint8_t *ret);
-int sd_ndisc_router_get_icmp6_ratelimit(sd_ndisc_router *rt, uint64_t *ret);
-int sd_ndisc_router_get_flags(sd_ndisc_router *rt, uint64_t *ret);
-int sd_ndisc_router_get_preference(sd_ndisc_router *rt, unsigned *ret);
-int sd_ndisc_router_get_lifetime(sd_ndisc_router *rt, uint64_t *ret);
-int sd_ndisc_router_get_lifetime_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret);
-int sd_ndisc_router_get_retransmission_time(sd_ndisc_router *rt, uint64_t *ret);
-int sd_ndisc_router_get_mtu(sd_ndisc_router *rt, uint32_t *ret);
-
-/* Generic option access */
-int sd_ndisc_router_option_rewind(sd_ndisc_router *rt);
-int sd_ndisc_router_option_next(sd_ndisc_router *rt);
-int sd_ndisc_router_option_get_type(sd_ndisc_router *rt, uint8_t *ret);
-int sd_ndisc_router_option_is_type(sd_ndisc_router *rt, uint8_t type);
-int sd_ndisc_router_option_get_raw(sd_ndisc_router *rt, const void **ret, size_t *ret_size);
-
-/* Specific option access: SD_NDISC_OPTION_PREFIX_INFORMATION */
-int sd_ndisc_router_prefix_get_valid_lifetime(sd_ndisc_router *rt, uint64_t *ret);
-int sd_ndisc_router_prefix_get_valid_lifetime_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret);
-int sd_ndisc_router_prefix_get_preferred_lifetime(sd_ndisc_router *rt, uint64_t *ret);
-int sd_ndisc_router_prefix_get_preferred_lifetime_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret);
-int sd_ndisc_router_prefix_get_flags(sd_ndisc_router *rt, uint8_t *ret);
-int sd_ndisc_router_prefix_get_address(sd_ndisc_router *rt, struct in6_addr *ret);
-int sd_ndisc_router_prefix_get_prefixlen(sd_ndisc_router *rt, unsigned *ret);
-
-/* Specific option access: SD_NDISC_OPTION_ROUTE_INFORMATION */
-int sd_ndisc_router_route_get_lifetime(sd_ndisc_router *rt, uint64_t *ret);
-int sd_ndisc_router_route_get_lifetime_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret);
-int sd_ndisc_router_route_get_address(sd_ndisc_router *rt, struct in6_addr *ret);
-int sd_ndisc_router_route_get_prefixlen(sd_ndisc_router *rt, unsigned *ret);
-int sd_ndisc_router_route_get_preference(sd_ndisc_router *rt, unsigned *ret);
-
-/* Specific option access: SD_NDISC_OPTION_RDNSS */
-int sd_ndisc_router_rdnss_get_addresses(sd_ndisc_router *rt, const struct in6_addr **ret);
-int sd_ndisc_router_rdnss_get_lifetime(sd_ndisc_router *rt, uint64_t *ret);
-int sd_ndisc_router_rdnss_get_lifetime_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret);
-
-/* Specific option access: SD_NDISC_OPTION_DNSSL */
-int sd_ndisc_router_dnssl_get_domains(sd_ndisc_router *rt, char ***ret);
-int sd_ndisc_router_dnssl_get_lifetime(sd_ndisc_router *rt, uint64_t *ret);
-int sd_ndisc_router_dnssl_get_lifetime_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret);
-
-/* Specific option access: SD_NDISC_OPTION_CAPTIVE_PORTAL */
-int sd_ndisc_router_captive_portal_get_uri(sd_ndisc_router *rt, const char **ret, size_t *ret_size);
-
-/* Specific option access: SD_NDISC_OPTION_PREF64 */
-int sd_ndisc_router_prefix64_get_prefix(sd_ndisc_router *rt, struct in6_addr *ret);
-int sd_ndisc_router_prefix64_get_prefixlen(sd_ndisc_router *rt, unsigned *ret);
-int sd_ndisc_router_prefix64_get_lifetime(sd_ndisc_router *rt, uint64_t *ret);
-int sd_ndisc_router_prefix64_get_lifetime_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret);
-
-_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ndisc, sd_ndisc_unref);
-_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ndisc_router, sd_ndisc_router_unref);
-
_SD_END_DECLARATIONS;
#endif
diff --git a/src/libnm-systemd-shared/src/basic/env-util.c b/src/libnm-systemd-shared/src/basic/env-util.c
index c12caa2e55..54509a559f 100644
--- a/src/libnm-systemd-shared/src/basic/env-util.c
+++ b/src/libnm-systemd-shared/src/basic/env-util.c
@@ -312,19 +312,17 @@ char **strv_env_delete(char **x, size_t n_lists, ...) {
return TAKE_PTR(t);
}
-char **strv_env_unset(char **l, const char *p) {
- char **f, **t;
+char** strv_env_unset(char **l, const char *p) {
+ assert(p);
if (!l)
return NULL;
- assert(p);
-
/* Drops every occurrence of the env var setting p in the
* string list. Edits in-place. */
+ char **f, **t;
for (f = t = l; *f; f++) {
-
if (env_match(*f, p)) {
free(*f);
continue;
@@ -337,14 +335,13 @@ char **strv_env_unset(char **l, const char *p) {
return l;
}
-char **strv_env_unset_many(char **l, ...) {
- char **f, **t;
-
+char** strv_env_unset_many_internal(char **l, ...) {
if (!l)
return NULL;
/* Like strv_env_unset() but applies many at once. Edits in-place. */
+ char **f, **t;
for (f = t = l; *f; f++) {
bool found = false;
const char *p;
@@ -352,12 +349,11 @@ char **strv_env_unset_many(char **l, ...) {
va_start(ap, l);
- while ((p = va_arg(ap, const char*))) {
+ while ((p = va_arg(ap, const char*)))
if (env_match(*f, p)) {
found = true;
break;
}
- }
va_end(ap);
@@ -972,7 +968,7 @@ int getenv_bool(const char *p) {
return parse_boolean(e);
}
-int getenv_bool_secure(const char *p) {
+int secure_getenv_bool(const char *p) {
const char *e;
e = secure_getenv(p);
@@ -982,8 +978,7 @@ int getenv_bool_secure(const char *p) {
return parse_boolean(e);
}
-#if 0 /* NM_IGNORED */
-int getenv_uint64_secure(const char *p, uint64_t *ret) {
+int secure_getenv_uint64(const char *p, uint64_t *ret) {
const char *e;
assert(p);
@@ -1017,6 +1012,7 @@ int putenv_dup(const char *assignment, bool override) {
return RET_NERRNO(setenv(n, e + 1, override));
}
+#if 0 /* NM_IGNORED */
int setenv_systemd_exec_pid(bool update_only) {
const char *e;
int r;
@@ -1037,6 +1033,17 @@ int setenv_systemd_exec_pid(bool update_only) {
return 1;
}
+int setenv_systemd_log_level(void) {
+ _cleanup_free_ char *val = NULL;
+ int r;
+
+ r = log_level_to_string_alloc(log_get_max_level(), &val);
+ if (r < 0)
+ return r;
+
+ return RET_NERRNO(setenv("SYSTEMD_LOG_LEVEL", val, /* overwrite= */ true));
+}
+
int getenv_path_list(const char *name, char ***ret_paths) {
_cleanup_strv_free_ char **l = NULL;
const char *e;
diff --git a/src/libnm-systemd-shared/src/basic/env-util.h b/src/libnm-systemd-shared/src/basic/env-util.h
index ad127de39f..6610ca8ca1 100644
--- a/src/libnm-systemd-shared/src/basic/env-util.h
+++ b/src/libnm-systemd-shared/src/basic/env-util.h
@@ -43,8 +43,9 @@ char** _strv_env_merge(char **first, ...);
#define strv_env_merge(first, ...) _strv_env_merge(first, __VA_ARGS__, POINTER_MAX)
char **strv_env_delete(char **x, size_t n_lists, ...); /* New copy */
-char **strv_env_unset(char **l, const char *p); /* In place ... */
-char **strv_env_unset_many(char **l, ...) _sentinel_;
+char** strv_env_unset(char **l, const char *p); /* In place ... */
+char** strv_env_unset_many_internal(char **l, ...) _sentinel_;
+#define strv_env_unset_many(l, ...) strv_env_unset_many_internal(l, __VA_ARGS__, NULL)
int strv_env_replace_consume(char ***l, char *p); /* In place ... */
int strv_env_replace_strdup(char ***l, const char *assignment);
int strv_env_replace_strdup_passthrough(char ***l, const char *assignment);
@@ -61,9 +62,9 @@ static inline char* strv_env_get(char * const *x, const char *n) {
char *strv_env_pairs_get(char **l, const char *name) _pure_;
int getenv_bool(const char *p);
-int getenv_bool_secure(const char *p);
+int secure_getenv_bool(const char *p);
-int getenv_uint64_secure(const char *p, uint64_t *ret);
+int secure_getenv_uint64(const char *p, uint64_t *ret);
/* Like setenv, but calls unsetenv if value == NULL. */
int set_unset_env(const char *name, const char *value, bool overwrite);
@@ -72,6 +73,7 @@ int set_unset_env(const char *name, const char *value, bool overwrite);
int putenv_dup(const char *assignment, bool override);
int setenv_systemd_exec_pid(bool update_only);
+int setenv_systemd_log_level(void);
/* Parses and does sanity checks on an environment variable containing
* PATH-like colon-separated absolute paths */
diff --git a/src/libnm-systemd-shared/src/basic/extract-word.c b/src/libnm-systemd-shared/src/basic/extract-word.c
index 2910a4cb60..bf7bc44fb6 100644
--- a/src/libnm-systemd-shared/src/basic/extract-word.c
+++ b/src/libnm-systemd-shared/src/basic/extract-word.c
@@ -247,52 +247,43 @@ int extract_first_word_and_warn(
* Let's make sure that ExtractFlags fits into an unsigned int. */
assert_cc(sizeof(enum ExtractFlags) <= sizeof(unsigned));
-int extract_many_words(const char **p, const char *separators, unsigned flags, ...) {
+int extract_many_words_internal(const char **p, const char *separators, unsigned flags, ...) {
va_list ap;
- char **l;
- int n = 0, i, c, r;
+ unsigned n = 0;
+ int r;
- /* Parses a number of words from a string, stripping any
- * quotes if necessary. */
+ /* Parses a number of words from a string, stripping any quotes if necessary. */
assert(p);
/* Count how many words are expected */
va_start(ap, flags);
- for (;;) {
- if (!va_arg(ap, char **))
- break;
+ while (va_arg(ap, char**))
n++;
- }
va_end(ap);
- if (n <= 0)
+ if (n == 0)
return 0;
/* Read all words into a temporary array */
- l = newa0(char*, n);
- for (c = 0; c < n; c++) {
+ char **l = newa0(char*, n);
+ unsigned c;
+ for (c = 0; c < n; c++) {
r = extract_first_word(p, &l[c], separators, flags);
if (r < 0) {
free_many_charp(l, c);
return r;
}
-
if (r == 0)
break;
}
- /* If we managed to parse all words, return them in the passed
- * in parameters */
+ /* If we managed to parse all words, return them in the passed in parameters */
va_start(ap, flags);
- for (i = 0; i < n; i++) {
- char **v;
-
- v = va_arg(ap, char **);
- assert(v);
-
- *v = l[i];
+ FOREACH_ARRAY(i, l, n) {
+ char **v = ASSERT_PTR(va_arg(ap, char**));
+ *v = *i;
}
va_end(ap);
diff --git a/src/libnm-systemd-shared/src/basic/extract-word.h b/src/libnm-systemd-shared/src/basic/extract-word.h
index c82ad761ef..da4f6ae674 100644
--- a/src/libnm-systemd-shared/src/basic/extract-word.h
+++ b/src/libnm-systemd-shared/src/basic/extract-word.h
@@ -19,4 +19,7 @@ typedef enum ExtractFlags {
int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags);
int extract_first_word_and_warn(const char **p, char **ret, const char *separators, ExtractFlags flags, const char *unit, const char *filename, unsigned line, const char *rvalue);
-int extract_many_words(const char **p, const char *separators, unsigned flags, ...) _sentinel_;
+
+int extract_many_words_internal(const char **p, const char *separators, unsigned flags, ...) _sentinel_;
+#define extract_many_words(p, separators, flags, ...) \
+ extract_many_words_internal(p, separators, flags, ##__VA_ARGS__, NULL)
diff --git a/src/libnm-systemd-shared/src/basic/fd-util.c b/src/libnm-systemd-shared/src/basic/fd-util.c
index afdc05f2ab..584d02f05b 100644
--- a/src/libnm-systemd-shared/src/basic/fd-util.c
+++ b/src/libnm-systemd-shared/src/basic/fd-util.c
@@ -311,7 +311,7 @@ static int close_all_fds_special_case(const int except[], size_t n_except) {
case 0:
/* Close everything. Yay! */
- if (close_range(3, -1, 0) >= 0)
+ if (close_range(3, INT_MAX, 0) >= 0)
return 1;
if (ERRNO_IS_NOT_SUPPORTED(errno) || ERRNO_IS_PRIVILEGE(errno)) {
@@ -422,7 +422,7 @@ int close_all_fds(const int except[], size_t n_except) {
if (sorted[n_sorted-1] >= INT_MAX) /* Dont let the addition below overflow */
return 0;
- if (close_range(sorted[n_sorted-1] + 1, -1, 0) >= 0)
+ if (close_range(sorted[n_sorted-1] + 1, INT_MAX, 0) >= 0)
return 0;
if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno))
@@ -467,6 +467,53 @@ int close_all_fds(const int except[], size_t n_except) {
return r;
}
+int pack_fds(int fds[], size_t n_fds) {
+ if (n_fds <= 0)
+ return 0;
+
+ /* Shifts around the fds in the provided array such that they
+ * all end up packed next to each-other, in order, starting
+ * from SD_LISTEN_FDS_START. This must be called after close_all_fds();
+ * it is likely to freeze up otherwise. You should probably use safe_fork_full
+ * with FORK_CLOSE_ALL_FDS|FORK_PACK_FDS set, to ensure that this is done correctly.
+ * The fds array is modified in place with the new FD numbers. */
+
+ assert(fds);
+
+ for (int start = 0;;) {
+ int restart_from = -1;
+
+ for (int i = start; i < (int) n_fds; i++) {
+ int nfd;
+
+ /* Already at right index? */
+ if (fds[i] == i + 3)
+ continue;
+
+ nfd = fcntl(fds[i], F_DUPFD, i + 3);
+ if (nfd < 0)
+ return -errno;
+
+ safe_close(fds[i]);
+ fds[i] = nfd;
+
+ /* Hmm, the fd we wanted isn't free? Then
+ * let's remember that and try again from here */
+ if (nfd != i + 3 && restart_from < 0)
+ restart_from = i;
+ }
+
+ if (restart_from < 0)
+ break;
+
+ start = restart_from;
+ }
+
+ assert(fds[0] == 3);
+
+ return 0;
+}
+
int same_fd(int a, int b) {
struct stat sta, stb;
pid_t pid;
@@ -875,6 +922,38 @@ int fd_is_opath(int fd) {
return FLAGS_SET(r, O_PATH);
}
+int fd_verify_safe_flags(int fd) {
+ int flags, unexpected_flags;
+
+ /* Check if an extrinsic fd is safe to work on (by a privileged service). This ensures that clients
+ * can't trick a privileged service into giving access to a file the client doesn't already have
+ * access to (especially via something like O_PATH).
+ *
+ * O_NOFOLLOW: For some reason the kernel will return this flag from fcntl; it doesn't go away
+ * immediately after open(). It should have no effect whatsoever to an already-opened FD,
+ * and since we refuse O_PATH it should be safe.
+ *
+ * RAW_O_LARGEFILE: glibc secretly sets this and neglects to hide it from us if we call fcntl.
+ * See comment in missing_fcntl.h for more details about this.
+ *
+ * O_DIRECTORY: this is set for directories, which are totally fine
+ */
+
+ assert(fd >= 0);
+
+ flags = fcntl(fd, F_GETFL);
+ if (flags < 0)
+ return -errno;
+
+ unexpected_flags = flags & ~(O_ACCMODE|O_NOFOLLOW|RAW_O_LARGEFILE|O_DIRECTORY);
+ if (unexpected_flags != 0)
+ return log_debug_errno(SYNTHETIC_ERRNO(EREMOTEIO),
+ "Unexpected flags set for extrinsic fd: 0%o",
+ (unsigned) unexpected_flags);
+
+ return 0;
+}
+
int read_nr_open(void) {
_cleanup_free_ char *nr_open = NULL;
int r;
diff --git a/src/libnm-systemd-shared/src/basic/fd-util.h b/src/libnm-systemd-shared/src/basic/fd-util.h
index 183266513a..f549831090 100644
--- a/src/libnm-systemd-shared/src/basic/fd-util.h
+++ b/src/libnm-systemd-shared/src/basic/fd-util.h
@@ -8,6 +8,7 @@
#include <sys/socket.h>
#include "macro.h"
+#include "missing_fcntl.h"
#include "stdio-util.h"
/* maximum length of fdname */
@@ -77,6 +78,8 @@ int get_max_fd(void);
int close_all_fds(const int except[], size_t n_except);
int close_all_fds_without_malloc(const int except[], size_t n_except);
+int pack_fds(int fds[], size_t n);
+
int same_fd(int a, int b);
void cmsg_close_all(struct msghdr *mh);
@@ -109,7 +112,10 @@ static inline int make_null_stdio(void) {
int fd_reopen(int fd, int flags);
int fd_reopen_condition(int fd, int flags, int mask, int *ret_new_fd);
+
int fd_is_opath(int fd);
+int fd_verify_safe_flags(int fd);
+
int read_nr_open(void);
int fd_get_diskseq(int fd, uint64_t *ret);
diff --git a/src/libnm-systemd-shared/src/basic/format-util.h b/src/libnm-systemd-shared/src/basic/format-util.h
index 7db8b61d89..8a80eb3339 100644
--- a/src/libnm-systemd-shared/src/basic/format-util.h
+++ b/src/libnm-systemd-shared/src/basic/format-util.h
@@ -18,6 +18,14 @@ assert_cc(sizeof(uid_t) == sizeof(uint32_t));
assert_cc(sizeof(gid_t) == sizeof(uint32_t));
#define GID_FMT "%" PRIu32
+/* Note: the lifetime of the compound literal is the immediately surrounding block,
+ * see C11 §6.5.2.5, and
+ * https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks */
+#define FORMAT_UID(uid) \
+ snprintf_ok((char[DECIMAL_STR_MAX(uid_t)]){}, DECIMAL_STR_MAX(uid_t), UID_FMT, uid)
+#define FORMAT_GID(gid) \
+ snprintf_ok((char[DECIMAL_STR_MAX(gid_t)]){}, DECIMAL_STR_MAX(gid_t), GID_FMT, gid)
+
#if SIZEOF_TIME_T == 8
# define PRI_TIME PRIi64
#elif SIZEOF_TIME_T == 4
diff --git a/src/libnm-systemd-shared/src/basic/fs-util.c b/src/libnm-systemd-shared/src/basic/fs-util.c
index 0210d3cdf9..3f414794ba 100644
--- a/src/libnm-systemd-shared/src/basic/fs-util.c
+++ b/src/libnm-systemd-shared/src/basic/fs-util.c
@@ -120,7 +120,11 @@ int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char
int readlinkat_malloc(int fd, const char *p, char **ret) {
size_t l = PATH_MAX;
- assert(p);
+ assert(fd >= 0 || fd == AT_FDCWD);
+
+ if (fd < 0 && isempty(p))
+ return -EISDIR; /* In this case, the fd points to the current working directory, and is
+ * definitely not a symlink. Let's return earlier. */
for (;;) {
_cleanup_free_ char *c = NULL;
@@ -130,7 +134,7 @@ int readlinkat_malloc(int fd, const char *p, char **ret) {
if (!c)
return -ENOMEM;
- n = readlinkat(fd, p, c, l);
+ n = readlinkat(fd, strempty(p), c, l);
if (n < 0)
return -errno;
@@ -1060,7 +1064,7 @@ int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode) {
path = fname;
}
- fd = xopenat(dirfd, path, flags|O_CREAT|O_DIRECTORY|O_NOFOLLOW, /* xopen_flags = */ 0, mode);
+ fd = xopenat_full(dirfd, path, flags|O_CREAT|O_DIRECTORY|O_NOFOLLOW, /* xopen_flags = */ 0, mode);
if (IN_SET(fd, -ELOOP, -ENOTDIR))
return -EEXIST;
if (fd < 0)
@@ -1116,7 +1120,7 @@ int openat_report_new(int dirfd, const char *pathname, int flags, mode_t mode, b
}
}
-int xopenat(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode) {
+int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode) {
_cleanup_close_ int fd = -EBADF;
bool made = false;
int r;
@@ -1198,7 +1202,7 @@ int xopenat(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags
}
#if 0 /* NM_IGNORED */
-int xopenat_lock(
+int xopenat_lock_full(
int dir_fd,
const char *path,
int open_flags,
@@ -1221,7 +1225,7 @@ int xopenat_lock(
for (;;) {
struct stat st;
- fd = xopenat(dir_fd, path, open_flags, xopen_flags, mode);
+ fd = xopenat_full(dir_fd, path, open_flags, xopen_flags, mode);
if (fd < 0)
return fd;
diff --git a/src/libnm-systemd-shared/src/basic/fs-util.h b/src/libnm-systemd-shared/src/basic/fs-util.h
index 1023ab73ca..6a1e2e76d1 100644
--- a/src/libnm-systemd-shared/src/basic/fs-util.h
+++ b/src/libnm-systemd-shared/src/basic/fs-util.h
@@ -137,6 +137,12 @@ typedef enum XOpenFlags {
XO_SUBVOLUME = 1 << 1,
} XOpenFlags;
-int xopenat(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode);
+int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode);
+static inline int xopenat(int dir_fd, const char *path, int open_flags) {
+ return xopenat_full(dir_fd, path, open_flags, 0, 0);
+}
-int xopenat_lock(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode, LockType locktype, int operation);
+int xopenat_lock_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_flags, mode_t mode, LockType locktype, int operation);
+static inline int xopenat_lock(int dir_fd, const char *path, int open_flags, LockType locktype, int operation) {
+ return xopenat_lock_full(dir_fd, path, open_flags, 0, 0, locktype, operation);
+}
diff --git a/src/libnm-systemd-shared/src/basic/glyph-util.c b/src/libnm-systemd-shared/src/basic/glyph-util.c
index 1de60e105b..58d64a0303 100644
--- a/src/libnm-systemd-shared/src/basic/glyph-util.c
+++ b/src/libnm-systemd-shared/src/basic/glyph-util.c
@@ -43,6 +43,8 @@ const char *special_glyph_full(SpecialGlyph code, bool force_utf) {
[SPECIAL_GLYPH_TREE_SPACE] = " ",
[SPECIAL_GLYPH_TREE_TOP] = ",-",
[SPECIAL_GLYPH_VERTICAL_DOTTED] = ":",
+ [SPECIAL_GLYPH_HORIZONTAL_DOTTED] = "-",
+ [SPECIAL_GLYPH_HORIZONTAL_FAT] = "=",
[SPECIAL_GLYPH_TRIANGULAR_BULLET] = ">",
[SPECIAL_GLYPH_BLACK_CIRCLE] = "*",
[SPECIAL_GLYPH_WHITE_CIRCLE] = "*",
@@ -76,6 +78,10 @@ const char *special_glyph_full(SpecialGlyph code, bool force_utf) {
[SPECIAL_GLYPH_SPARKLES] = "*",
[SPECIAL_GLYPH_LOW_BATTERY] = "!",
[SPECIAL_GLYPH_WARNING_SIGN] = "!",
+ [SPECIAL_GLYPH_RED_CIRCLE] = "o",
+ [SPECIAL_GLYPH_YELLOW_CIRCLE] = "o",
+ [SPECIAL_GLYPH_BLUE_CIRCLE] = "o",
+ [SPECIAL_GLYPH_GREEN_CIRCLE] = "o",
},
/* UTF-8 */
@@ -89,6 +95,8 @@ const char *special_glyph_full(SpecialGlyph code, bool force_utf) {
/* Single glyphs in both cases */
[SPECIAL_GLYPH_VERTICAL_DOTTED] = u8"┆",
+ [SPECIAL_GLYPH_HORIZONTAL_DOTTED] = u8"┄",
+ [SPECIAL_GLYPH_HORIZONTAL_FAT] = u8"━",
[SPECIAL_GLYPH_TRIANGULAR_BULLET] = u8"‣",
[SPECIAL_GLYPH_BLACK_CIRCLE] = u8"●",
[SPECIAL_GLYPH_WHITE_CIRCLE] = u8"○",
@@ -138,6 +146,11 @@ const char *special_glyph_full(SpecialGlyph code, bool force_utf) {
[SPECIAL_GLYPH_WARNING_SIGN] = u8"⚠️",
[SPECIAL_GLYPH_COMPUTER_DISK] = u8"💽",
[SPECIAL_GLYPH_WORLD] = u8"🌍",
+
+ [SPECIAL_GLYPH_RED_CIRCLE] = u8"🔴",
+ [SPECIAL_GLYPH_YELLOW_CIRCLE] = u8"🟡",
+ [SPECIAL_GLYPH_BLUE_CIRCLE] = u8"🔵",
+ [SPECIAL_GLYPH_GREEN_CIRCLE] = u8"🟢",
},
};
diff --git a/src/libnm-systemd-shared/src/basic/glyph-util.h b/src/libnm-systemd-shared/src/basic/glyph-util.h
index a7709976e1..db8dbbff26 100644
--- a/src/libnm-systemd-shared/src/basic/glyph-util.h
+++ b/src/libnm-systemd-shared/src/basic/glyph-util.h
@@ -13,6 +13,8 @@ typedef enum SpecialGlyph {
SPECIAL_GLYPH_TREE_SPACE,
SPECIAL_GLYPH_TREE_TOP,
SPECIAL_GLYPH_VERTICAL_DOTTED,
+ SPECIAL_GLYPH_HORIZONTAL_DOTTED,
+ SPECIAL_GLYPH_HORIZONTAL_FAT,
SPECIAL_GLYPH_TRIANGULAR_BULLET,
SPECIAL_GLYPH_BLACK_CIRCLE,
SPECIAL_GLYPH_WHITE_CIRCLE,
@@ -49,6 +51,10 @@ typedef enum SpecialGlyph {
SPECIAL_GLYPH_WARNING_SIGN,
SPECIAL_GLYPH_COMPUTER_DISK,
SPECIAL_GLYPH_WORLD,
+ SPECIAL_GLYPH_RED_CIRCLE,
+ SPECIAL_GLYPH_YELLOW_CIRCLE,
+ SPECIAL_GLYPH_BLUE_CIRCLE,
+ SPECIAL_GLYPH_GREEN_CIRCLE,
_SPECIAL_GLYPH_MAX,
_SPECIAL_GLYPH_INVALID = -EINVAL,
} SpecialGlyph;
diff --git a/src/libnm-systemd-shared/src/basic/hashmap.c b/src/libnm-systemd-shared/src/basic/hashmap.c
index 28d2efa0e2..9686af0d93 100644
--- a/src/libnm-systemd-shared/src/basic/hashmap.c
+++ b/src/libnm-systemd-shared/src/basic/hashmap.c
@@ -2126,24 +2126,27 @@ static int hashmap_entry_compare(
return compare((*a)->key, (*b)->key);
}
-int _hashmap_dump_sorted(HashmapBase *h, void ***ret, size_t *ret_n) {
- _cleanup_free_ struct hashmap_base_entry **entries = NULL;
+static int _hashmap_dump_entries_sorted(
+ HashmapBase *h,
+ void ***ret,
+ size_t *ret_n) {
+ _cleanup_free_ void **entries = NULL;
Iterator iter;
unsigned idx;
size_t n = 0;
assert(ret);
+ assert(ret_n);
if (_hashmap_size(h) == 0) {
*ret = NULL;
- if (ret_n)
- *ret_n = 0;
+ *ret_n = 0;
return 0;
}
/* We append one more element than needed so that the resulting array can be used as a strv. We
* don't count this entry in the returned size. */
- entries = new(struct hashmap_base_entry*, _hashmap_size(h) + 1);
+ entries = new(void*, _hashmap_size(h) + 1);
if (!entries)
return -ENOMEM;
@@ -2153,13 +2156,47 @@ int _hashmap_dump_sorted(HashmapBase *h, void ***ret, size_t *ret_n) {
assert(n == _hashmap_size(h));
entries[n] = NULL;
- typesafe_qsort_r(entries, n, hashmap_entry_compare, h->hash_ops->compare);
+ typesafe_qsort_r((struct hashmap_base_entry**) entries, n,
+ hashmap_entry_compare, h->hash_ops->compare);
+
+ *ret = TAKE_PTR(entries);
+ *ret_n = n;
+ return 0;
+}
+
+int _hashmap_dump_keys_sorted(HashmapBase *h, void ***ret, size_t *ret_n) {
+ _cleanup_free_ void **entries = NULL;
+ size_t n;
+ int r;
+
+ r = _hashmap_dump_entries_sorted(h, &entries, &n);
+ if (r < 0)
+ return r;
+
+ /* Reuse the array. */
+ FOREACH_ARRAY(e, entries, n)
+ *e = (void*) (*(struct hashmap_base_entry**) e)->key;
+
+ *ret = TAKE_PTR(entries);
+ if (ret_n)
+ *ret_n = n;
+ return 0;
+}
+
+int _hashmap_dump_sorted(HashmapBase *h, void ***ret, size_t *ret_n) {
+ _cleanup_free_ void **entries = NULL;
+ size_t n;
+ int r;
+
+ r = _hashmap_dump_entries_sorted(h, &entries, &n);
+ if (r < 0)
+ return r;
/* Reuse the array. */
FOREACH_ARRAY(e, entries, n)
- *e = entry_value(h, *e);
+ *e = entry_value(h, *(struct hashmap_base_entry**) e);
- *ret = (void**) TAKE_PTR(entries);
+ *ret = TAKE_PTR(entries);
if (ret_n)
*ret_n = n;
return 0;
diff --git a/src/libnm-systemd-shared/src/basic/hashmap.h b/src/libnm-systemd-shared/src/basic/hashmap.h
index 233f1d7a1e..49d9d118cc 100644
--- a/src/libnm-systemd-shared/src/basic/hashmap.h
+++ b/src/libnm-systemd-shared/src/basic/hashmap.h
@@ -39,8 +39,8 @@ typedef struct IteratedCache IteratedCache; /* Caches the iterated order of on
* by hashmap users, so the definition has to be here. Do not use its fields
* directly. */
typedef struct {
- unsigned idx; /* index of an entry to be iterated next */
const void *next_key; /* expected value of that entry's key pointer */
+ unsigned idx; /* index of an entry to be iterated next */
#if ENABLE_DEBUG_HASHMAP
unsigned put_count; /* hashmap's put_count recorded at start of iteration */
unsigned rem_count; /* hashmap's rem_count in previous iteration */
@@ -409,6 +409,14 @@ static inline int set_dump_sorted(Set *h, void ***ret, size_t *ret_n) {
return _hashmap_dump_sorted(HASHMAP_BASE(h), ret, ret_n);
}
+int _hashmap_dump_keys_sorted(HashmapBase *h, void ***ret, size_t *ret_n);
+static inline int hashmap_dump_keys_sorted(Hashmap *h, void ***ret, size_t *ret_n) {
+ return _hashmap_dump_keys_sorted(HASHMAP_BASE(h), ret, ret_n);
+}
+static inline int ordered_hashmap_dump_keys_sorted(OrderedHashmap *h, void ***ret, size_t *ret_n) {
+ return _hashmap_dump_keys_sorted(HASHMAP_BASE(h), ret, ret_n);
+}
+
/*
* Hashmaps are iterated in unpredictable order.
* OrderedHashmaps are an exception to this. They are iterated in the order
diff --git a/src/libnm-systemd-shared/src/basic/in-addr-util.c b/src/libnm-systemd-shared/src/basic/in-addr-util.c
index 0c3923b0ef..310e057a25 100644
--- a/src/libnm-systemd-shared/src/basic/in-addr-util.c
+++ b/src/libnm-systemd-shared/src/basic/in-addr-util.c
@@ -93,14 +93,26 @@ bool in6_addr_is_link_local_all_nodes(const struct in6_addr *a) {
be32toh(a->s6_addr32[3]) == UINT32_C(0x00000001);
}
+bool in4_addr_is_multicast(const struct in_addr *a) {
+ assert(a);
+
+ return IN_MULTICAST(be32toh(a->s_addr));
+}
+
+bool in6_addr_is_multicast(const struct in6_addr *a) {
+ assert(a);
+
+ return IN6_IS_ADDR_MULTICAST(a);
+}
+
int in_addr_is_multicast(int family, const union in_addr_union *u) {
assert(u);
if (family == AF_INET)
- return IN_MULTICAST(be32toh(u->in.s_addr));
+ return in4_addr_is_multicast(&u->in);
if (family == AF_INET6)
- return IN6_IS_ADDR_MULTICAST(&u->in6);
+ return in6_addr_is_multicast(&u->in6);
return -EAFNOSUPPORT;
}
diff --git a/src/libnm-systemd-shared/src/basic/in-addr-util.h b/src/libnm-systemd-shared/src/basic/in-addr-util.h
index 9fae3cae45..5c820c6ec6 100644
--- a/src/libnm-systemd-shared/src/basic/in-addr-util.h
+++ b/src/libnm-systemd-shared/src/basic/in-addr-util.h
@@ -40,6 +40,8 @@ static inline bool in_addr_data_is_set(const struct in_addr_data *a) {
return in_addr_data_is_null(a);
}
+bool in4_addr_is_multicast(const struct in_addr *a);
+bool in6_addr_is_multicast(const struct in6_addr *a);
int in_addr_is_multicast(int family, const union in_addr_union *u);
bool in4_addr_is_link_local(const struct in_addr *a);
diff --git a/src/libnm-systemd-shared/src/basic/locale-util.c b/src/libnm-systemd-shared/src/basic/locale-util.c
index 78564a74a0..95648775ec 100644
--- a/src/libnm-systemd-shared/src/basic/locale-util.c
+++ b/src/libnm-systemd-shared/src/basic/locale-util.c
@@ -263,7 +263,10 @@ bool locale_is_valid(const char *name) {
if (!filename_is_valid(name))
return false;
- if (!string_is_safe(name))
+ /* Locales look like: ll_CC.ENC@variant, where ll and CC are alphabetic, ENC is alphanumeric with
+ * dashes, and variant seems to be alphabetic.
+ * See: https://www.gnu.org/software/gettext/manual/html_node/Locale-Names.html */
+ if (!in_charset(name, ALPHANUMERICAL "_.-@"))
return false;
return true;
@@ -296,7 +299,7 @@ bool is_locale_utf8(void) {
if (cached_answer >= 0)
goto out;
- r = getenv_bool_secure("SYSTEMD_UTF8");
+ r = secure_getenv_bool("SYSTEMD_UTF8");
if (r >= 0) {
cached_answer = r;
goto out;
diff --git a/src/libnm-systemd-shared/src/basic/log.h b/src/libnm-systemd-shared/src/basic/log.h
index cc59b0775c..1b5bc655f8 100644
--- a/src/libnm-systemd-shared/src/basic/log.h
+++ b/src/libnm-systemd-shared/src/basic/log.h
@@ -524,7 +524,7 @@ typedef struct LogRateLimit {
RateLimit ratelimit;
} LogRateLimit;
-#define log_ratelimit_internal(_level, _error, _ratelimit, _format, _file, _line, _func, ...) \
+#define log_ratelimit_internal(_level, _error, _ratelimit, _file, _line, _func, _format, ...) \
({ \
int _log_ratelimit_error = (_error); \
int _log_ratelimit_level = (_level); \
@@ -548,7 +548,7 @@ typedef struct LogRateLimit {
({ \
int _level = (level), _e = (error); \
_e = (log_get_max_level() >= LOG_PRI(_level)) \
- ? log_ratelimit_internal(_level, _e, _ratelimit, format, PROJECT_FILE, __LINE__, __func__, ##__VA_ARGS__) \
+ ? log_ratelimit_internal(_level, _e, _ratelimit, PROJECT_FILE, __LINE__, __func__, format, ##__VA_ARGS__) \
: -ERRNO_VALUE(_e); \
_e < 0 ? _e : -ESTRPIPE; \
})
diff --git a/src/libnm-systemd-shared/src/basic/missing_fcntl.h b/src/libnm-systemd-shared/src/basic/missing_fcntl.h
index 24b2dc3119..3c85befda9 100644
--- a/src/libnm-systemd-shared/src/basic/missing_fcntl.h
+++ b/src/libnm-systemd-shared/src/basic/missing_fcntl.h
@@ -69,9 +69,26 @@
/* So O_LARGEFILE is generally implied by glibc, and defined to zero hence, because we only build in LFS
* mode. However, when invoking fcntl(F_GETFL) the flag is ORed into the result anyway — glibc does not mask
- * it away. Which sucks. Let's define the actual value here, so that we can mask it ourselves. */
+ * it away. Which sucks. Let's define the actual value here, so that we can mask it ourselves.
+ *
+ * The precise definition is arch specific, so we use the values defined in the kernel (note that some
+ * are hexa and others are octal; duplicated as-is from the kernel definitions):
+ * - alpha, arm, arm64, m68k, mips, parisc, powerpc, sparc: each has a specific value;
+ * - others: they use the "generic" value (defined in include/uapi/asm-generic/fcntl.h) */
#if O_LARGEFILE != 0
#define RAW_O_LARGEFILE O_LARGEFILE
#else
-#define RAW_O_LARGEFILE 0100000
+#if defined(__alpha__) || defined(__arm__) || defined(__aarch64__) || defined(__m68k__)
+#define RAW_O_LARGEFILE 0400000
+#elif defined(__mips__)
+#define RAW_O_LARGEFILE 0x2000
+#elif defined(__parisc__) || defined(__hppa__)
+#define RAW_O_LARGEFILE 000004000
+#elif defined(__powerpc__)
+#define RAW_O_LARGEFILE 0200000
+#elif defined(__sparc__)
+#define RAW_O_LARGEFILE 0x40000
+#else
+#define RAW_O_LARGEFILE 00100000
+#endif
#endif
diff --git a/src/libnm-systemd-shared/src/basic/missing_syscall.h b/src/libnm-systemd-shared/src/basic/missing_syscall.h
index a04633510d..149c5b4884 100644
--- a/src/libnm-systemd-shared/src/basic/missing_syscall.h
+++ b/src/libnm-systemd-shared/src/basic/missing_syscall.h
@@ -419,23 +419,14 @@ static inline int missing_execveat(int dirfd, const char *pathname,
/* ======================================================================= */
#if !HAVE_CLOSE_RANGE
-static inline int missing_close_range(int first_fd, int end_fd, unsigned flags) {
+static inline int missing_close_range(unsigned first_fd, unsigned end_fd, unsigned flags) {
# ifdef __NR_close_range
/* Kernel-side the syscall expects fds as unsigned integers (just like close() actually), while
- * userspace exclusively uses signed integers for fds. We don't know just yet how glibc is going to
- * wrap this syscall, but let's assume it's going to be similar to what they do for close(),
- * i.e. make the same unsigned → signed type change from the raw kernel syscall compared to the
- * userspace wrapper. There's only one caveat for this: unlike for close() there's the special
- * UINT_MAX fd value for the 'end_fd' argument. Let's safely map that to -1 here. And let's refuse
- * any other negative values. */
- if ((first_fd < 0) || (end_fd < 0 && end_fd != -1)) {
- errno = -EBADF;
- return -1;
- }
-
+ * userspace exclusively uses signed integers for fds. glibc chose to expose it 1:1 however, hence we
+ * do so here too, even if we end up passing signed fds to it most of the time. */
return syscall(__NR_close_range,
- (unsigned) first_fd,
- end_fd == -1 ? UINT_MAX : (unsigned) end_fd, /* Of course, the compiler should figure out that this is the identity mapping IRL */
+ first_fd,
+ end_fd,
flags);
# else
errno = ENOSYS;
diff --git a/src/libnm-systemd-shared/src/basic/namespace-util.h b/src/libnm-systemd-shared/src/basic/namespace-util.h
index d1d015612f..34cbec3f6e 100644
--- a/src/libnm-systemd-shared/src/basic/namespace-util.h
+++ b/src/libnm-systemd-shared/src/basic/namespace-util.h
@@ -53,3 +53,5 @@ static inline bool userns_shift_range_valid(uid_t shift, uid_t range) {
int userns_acquire(const char *uid_map, const char *gid_map);
int netns_acquire(void);
int in_same_namespace(pid_t pid1, pid_t pid2, NamespaceType type);
+
+int parse_userns_uid_range(const char *s, uid_t *ret_uid_shift, uid_t *ret_uid_range);
diff --git a/src/libnm-systemd-shared/src/basic/process-util.c b/src/libnm-systemd-shared/src/basic/process-util.c
index 0f1894b3af..5dd9003d5d 100644
--- a/src/libnm-systemd-shared/src/basic/process-util.c
+++ b/src/libnm-systemd-shared/src/basic/process-util.c
@@ -514,7 +514,7 @@ static int get_process_link_contents(pid_t pid, const char *proc_file, char **re
p = procfs_file_alloca(pid, proc_file);
r = readlink_malloc(p, ret);
- return r == -ENOENT ? -ESRCH : r;
+ return (r == -ENOENT && proc_mounted() > 0) ? -ESRCH : r;
}
int get_process_exe(pid_t pid, char **ret) {
@@ -1309,7 +1309,7 @@ int opinionated_personality(unsigned long *ret) {
if (current < 0)
return current;
- if (((unsigned long) current & 0xffff) == PER_LINUX32)
+ if (((unsigned long) current & OPINIONATED_PERSONALITY_MASK) == PER_LINUX32)
*ret = PER_LINUX32;
else
*ret = PER_LINUX;
@@ -1476,7 +1476,7 @@ static int fork_flags_to_signal(ForkFlags flags) {
int safe_fork_full(
const char *name,
const int stdio_fds[3],
- const int except_fds[],
+ int except_fds[],
size_t n_except_fds,
ForkFlags flags,
pid_t *ret_pid) {
@@ -1705,6 +1705,19 @@ int safe_fork_full(
}
}
+ if (flags & FORK_PACK_FDS) {
+ /* FORK_CLOSE_ALL_FDS ensures that except_fds are the only FDs >= 3 that are
+ * open, this is including the log. This is required by pack_fds, which will
+ * get stuck in an infinite loop of any FDs other than except_fds are open. */
+ assert(FLAGS_SET(flags, FORK_CLOSE_ALL_FDS));
+
+ r = pack_fds(except_fds, n_except_fds);
+ if (r < 0) {
+ log_full_errno(prio, r, "Failed to pack file descriptors: %m");
+ _exit(EXIT_FAILURE);
+ }
+ }
+
if (flags & FORK_CLOEXEC_OFF) {
r = fd_cloexec_many(except_fds, n_except_fds, false);
if (r < 0) {
@@ -1744,7 +1757,7 @@ int safe_fork_full(
int pidref_safe_fork_full(
const char *name,
const int stdio_fds[3],
- const int except_fds[],
+ int except_fds[],
size_t n_except_fds,
ForkFlags flags,
PidRef *ret_pid) {
@@ -1768,7 +1781,7 @@ int pidref_safe_fork_full(
int namespace_fork(
const char *outer_name,
const char *inner_name,
- const int except_fds[],
+ int except_fds[],
size_t n_except_fds,
ForkFlags flags,
int pidns_fd,
diff --git a/src/libnm-systemd-shared/src/basic/process-util.h b/src/libnm-systemd-shared/src/basic/process-util.h
index a75c44cfad..49350065fb 100644
--- a/src/libnm-systemd-shared/src/basic/process-util.h
+++ b/src/libnm-systemd-shared/src/basic/process-util.h
@@ -101,12 +101,17 @@ bool is_main_thread(void);
bool oom_score_adjust_is_valid(int oa);
#ifndef PERSONALITY_INVALID
-/* personality(7) documents that 0xffffffffUL is used for querying the
+/* personality(2) documents that 0xFFFFFFFFUL is used for querying the
* current personality, hence let's use that here as error
* indicator. */
-#define PERSONALITY_INVALID 0xffffffffLU
+#define PERSONALITY_INVALID 0xFFFFFFFFUL
#endif
+/* The personality() syscall returns a 32-bit value where the top three bytes are reserved for flags that
+ * emulate historical or architectural quirks, and only the least significant byte reflects the actual
+ * personality we're interested in. */
+#define OPINIONATED_PERSONALITY_MASK 0xFFUL
+
unsigned long personality_from_string(const char *p);
const char *personality_to_string(unsigned long);
@@ -182,12 +187,13 @@ typedef enum ForkFlags {
FORK_KEEP_NOTIFY_SOCKET = 1 << 17, /* Unless this specified, $NOTIFY_SOCKET will be unset. */
FORK_DETACH = 1 << 18, /* Double fork if needed to ensure PID1/subreaper is parent */
FORK_NEW_NETNS = 1 << 19, /* Run child in its own network namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */
+ FORK_PACK_FDS = 1 << 20, /* Rearrange the passed FDs to be FD 3,4,5,etc. Updates the array in place (combine with FORK_CLOSE_ALL_FDS!) */
} ForkFlags;
int safe_fork_full(
const char *name,
const int stdio_fds[3],
- const int except_fds[],
+ int except_fds[],
size_t n_except_fds,
ForkFlags flags,
pid_t *ret_pid);
@@ -199,7 +205,7 @@ static inline int safe_fork(const char *name, ForkFlags flags, pid_t *ret_pid) {
int pidref_safe_fork_full(
const char *name,
const int stdio_fds[3],
- const int except_fds[],
+ int except_fds[],
size_t n_except_fds,
ForkFlags flags,
PidRef *ret_pid);
@@ -208,7 +214,18 @@ static inline int pidref_safe_fork(const char *name, ForkFlags flags, PidRef *re
return pidref_safe_fork_full(name, NULL, NULL, 0, flags, ret_pid);
}
-int namespace_fork(const char *outer_name, const char *inner_name, const int except_fds[], size_t n_except_fds, ForkFlags flags, int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd, pid_t *ret_pid);
+int namespace_fork(
+ const char *outer_name,
+ const char *inner_name,
+ int except_fds[],
+ size_t n_except_fds,
+ ForkFlags flags,
+ int pidns_fd,
+ int mntns_fd,
+ int netns_fd,
+ int userns_fd,
+ int root_fd,
+ pid_t *ret_pid);
int set_oom_score_adjust(int value);
int get_oom_score_adjust(int *ret);
diff --git a/src/libnm-systemd-shared/src/basic/signal-util.c b/src/libnm-systemd-shared/src/basic/signal-util.c
index 4354edca7e..95c86584e9 100644
--- a/src/libnm-systemd-shared/src/basic/signal-util.c
+++ b/src/libnm-systemd-shared/src/basic/signal-util.c
@@ -21,7 +21,7 @@ int reset_all_signal_handlers(void) {
.sa_handler = SIG_DFL,
.sa_flags = SA_RESTART,
};
- int r = 0;
+ int ret = 0, r;
for (int sig = 1; sig < _NSIG; sig++) {
@@ -29,14 +29,14 @@ int reset_all_signal_handlers(void) {
if (IN_SET(sig, SIGKILL, SIGSTOP))
continue;
- /* On Linux the first two RT signals are reserved by
- * glibc, and sigaction() will return EINVAL for them. */
- if (sigaction(sig, &sa, NULL) < 0)
- if (errno != EINVAL && r >= 0)
- r = -errno;
+ /* On Linux the first two RT signals are reserved by glibc, and sigaction() will return
+ * EINVAL for them. */
+ r = RET_NERRNO(sigaction(sig, &sa, NULL));
+ if (r != -EINVAL)
+ RET_GATHER(ret, r);
}
- return r;
+ return ret;
}
int reset_signal_mask(void) {
@@ -60,10 +60,7 @@ int sigaction_many_internal(const struct sigaction *sa, ...) {
if (sig == 0)
continue;
- if (sigaction(sig, sa, NULL) < 0) {
- if (r >= 0)
- r = -errno;
- }
+ RET_GATHER(r, RET_NERRNO(sigaction(sig, sa, NULL)));
}
va_end(ap);
@@ -90,7 +87,7 @@ static int sigset_add_many_ap(sigset_t *ss, va_list ap) {
return r;
}
-int sigset_add_many(sigset_t *ss, ...) {
+int sigset_add_many_internal(sigset_t *ss, ...) {
va_list ap;
int r;
@@ -101,7 +98,7 @@ int sigset_add_many(sigset_t *ss, ...) {
return r;
}
-int sigprocmask_many(int how, sigset_t *old, ...) {
+int sigprocmask_many_internal(int how, sigset_t *old, ...) {
va_list ap;
sigset_t ss;
int r;
@@ -116,10 +113,7 @@ int sigprocmask_many(int how, sigset_t *old, ...) {
if (r < 0)
return r;
- if (sigprocmask(how, &ss, old) < 0)
- return -errno;
-
- return 0;
+ return RET_NERRNO(sigprocmask(how, &ss, old));
}
static const char *const static_signal_table[] = {
diff --git a/src/libnm-systemd-shared/src/basic/signal-util.h b/src/libnm-systemd-shared/src/basic/signal-util.h
index ad2ba841c6..8826fbeb7b 100644
--- a/src/libnm-systemd-shared/src/basic/signal-util.h
+++ b/src/libnm-systemd-shared/src/basic/signal-util.h
@@ -31,8 +31,11 @@ int sigaction_many_internal(const struct sigaction *sa, ...);
#define sigaction_many(sa, ...) \
sigaction_many_internal(sa, __VA_ARGS__, -1)
-int sigset_add_many(sigset_t *ss, ...);
-int sigprocmask_many(int how, sigset_t *old, ...);
+int sigset_add_many_internal(sigset_t *ss, ...);
+#define sigset_add_many(...) sigset_add_many_internal(__VA_ARGS__, -1)
+
+int sigprocmask_many_internal(int how, sigset_t *old, ...);
+#define sigprocmask_many(...) sigprocmask_many_internal(__VA_ARGS__, -1)
const char *signal_to_string(int i) _const_;
int signal_from_string(const char *s) _pure_;
@@ -46,7 +49,7 @@ static inline void block_signals_reset(sigset_t *ss) {
#define BLOCK_SIGNALS(...) \
_cleanup_(block_signals_reset) _unused_ sigset_t _saved_sigset = ({ \
sigset_t _t; \
- assert_se(sigprocmask_many(SIG_BLOCK, &_t, __VA_ARGS__, -1) >= 0); \
+ assert_se(sigprocmask_many(SIG_BLOCK, &_t, __VA_ARGS__) >= 0); \
_t; \
})
diff --git a/src/libnm-systemd-shared/src/basic/stat-util.c b/src/libnm-systemd-shared/src/basic/stat-util.c
index b50544c9f3..4da3845be8 100644
--- a/src/libnm-systemd-shared/src/basic/stat-util.c
+++ b/src/libnm-systemd-shared/src/basic/stat-util.c
@@ -27,46 +27,130 @@
#include "stat-util.h"
#include "string-util.h"
-#if 0 /* NM_IGNORED */
-int is_symlink(const char *path) {
- struct stat info;
+static int verify_stat_at(
+ int fd,
+ const char *path,
+ bool follow,
+ int (*verify_func)(const struct stat *st),
+ bool verify) {
+ struct stat st;
+ int r;
- assert(path);
+ assert(fd >= 0 || fd == AT_FDCWD);
+ assert(!isempty(path) || !follow);
+ assert(verify_func);
- if (lstat(path, &info) < 0)
+ if (fstatat(fd, strempty(path), &st,
+ (isempty(path) ? AT_EMPTY_PATH : 0) | (follow ? 0 : AT_SYMLINK_NOFOLLOW)) < 0)
return -errno;
- return !!S_ISLNK(info.st_mode);
+ r = verify_func(&st);
+ return verify ? r : r >= 0;
}
-#endif /* NM_IGNORED */
-int is_dir_full(int atfd, const char* path, bool follow) {
- struct stat st;
- int r;
+int stat_verify_regular(const struct stat *st) {
+ assert(st);
- assert(atfd >= 0 || atfd == AT_FDCWD);
- assert(atfd >= 0 || path);
+ /* Checks whether the specified stat() structure refers to a regular file. If not returns an
+ * appropriate error code. */
- if (path)
- r = fstatat(atfd, path, &st, follow ? 0 : AT_SYMLINK_NOFOLLOW);
- else
- r = fstat(atfd, &st);
- if (r < 0)
- return -errno;
+ if (S_ISDIR(st->st_mode))
+ return -EISDIR;
- return !!S_ISDIR(st.st_mode);
+ if (S_ISLNK(st->st_mode))
+ return -ELOOP;
+
+ if (!S_ISREG(st->st_mode))
+ return -EBADFD;
+
+ return 0;
}
-#if 0 /* NM_IGNORED */
-int is_device_node(const char *path) {
- struct stat info;
+int verify_regular_at(int fd, const char *path, bool follow) {
+ return verify_stat_at(fd, path, follow, stat_verify_regular, true);
+}
- assert(path);
+int fd_verify_regular(int fd) {
+ assert(fd >= 0);
+ return verify_regular_at(fd, NULL, false);
+}
- if (lstat(path, &info) < 0)
- return -errno;
+int stat_verify_directory(const struct stat *st) {
+ assert(st);
+
+ if (S_ISLNK(st->st_mode))
+ return -ELOOP;
+
+ if (!S_ISDIR(st->st_mode))
+ return -ENOTDIR;
+
+ return 0;
+}
+
+int fd_verify_directory(int fd) {
+ assert(fd >= 0);
+ return verify_stat_at(fd, NULL, false, stat_verify_directory, true);
+}
+
+int is_dir_at(int fd, const char *path, bool follow) {
+ return verify_stat_at(fd, path, follow, stat_verify_directory, false);
+}
+
+int is_dir(const char *path, bool follow) {
+ assert(!isempty(path));
+ return is_dir_at(AT_FDCWD, path, follow);
+}
+
+int stat_verify_symlink(const struct stat *st) {
+ assert(st);
+
+ if (S_ISDIR(st->st_mode))
+ return -EISDIR;
+
+ if (!S_ISLNK(st->st_mode))
+ return -ENOLINK;
+
+ return 0;
+}
+
+int is_symlink(const char *path) {
+ assert(!isempty(path));
+ return verify_stat_at(AT_FDCWD, path, false, stat_verify_symlink, false);
+}
+
+int stat_verify_linked(const struct stat *st) {
+ assert(st);
+
+ if (st->st_nlink <= 0)
+ return -EIDRM; /* recognizable error. */
+
+ return 0;
+}
+
+int fd_verify_linked(int fd) {
+ assert(fd >= 0);
+ return verify_stat_at(fd, NULL, false, stat_verify_linked, true);
+}
+
+int stat_verify_device_node(const struct stat *st) {
+ assert(st);
+
+ if (S_ISLNK(st->st_mode))
+ return -ELOOP;
+
+ if (S_ISDIR(st->st_mode))
+ return -EISDIR;
+
+ if (!S_ISBLK(st->st_mode) && !S_ISCHR(st->st_mode))
+ return -ENOTTY;
+
+ return 0;
+}
- return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
+#if 0 /* NM_IGNORED */
+int is_device_node(const char *path) {
+ assert(!isempty(path));
+ return verify_stat_at(AT_FDCWD, path, false, stat_verify_device_node, false);
}
int dir_is_empty_at(int dir_fd, const char *path, bool ignore_hidden_or_backup) {
@@ -268,72 +352,6 @@ int path_is_network_fs(const char *path) {
}
#endif /* NM_IGNORED */
-int stat_verify_regular(const struct stat *st) {
- assert(st);
-
- /* Checks whether the specified stat() structure refers to a regular file. If not returns an appropriate error
- * code. */
-
- if (S_ISDIR(st->st_mode))
- return -EISDIR;
-
- if (S_ISLNK(st->st_mode))
- return -ELOOP;
-
- if (!S_ISREG(st->st_mode))
- return -EBADFD;
-
- return 0;
-}
-
-int fd_verify_regular(int fd) {
- struct stat st;
-
- assert(fd >= 0);
-
- if (fstat(fd, &st) < 0)
- return -errno;
-
- return stat_verify_regular(&st);
-}
-
-#if 0 /* NM_IGNORED */
-int verify_regular_at(int dir_fd, const char *path, bool follow) {
- struct stat st;
-
- assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
- assert(path);
-
- if (fstatat(dir_fd, path, &st, (isempty(path) ? AT_EMPTY_PATH : 0) | (follow ? 0 : AT_SYMLINK_NOFOLLOW)) < 0)
- return -errno;
-
- return stat_verify_regular(&st);
-}
-
-int stat_verify_directory(const struct stat *st) {
- assert(st);
-
- if (S_ISLNK(st->st_mode))
- return -ELOOP;
-
- if (!S_ISDIR(st->st_mode))
- return -ENOTDIR;
-
- return 0;
-}
-
-int fd_verify_directory(int fd) {
- struct stat st;
-
- assert(fd >= 0);
-
- if (fstat(fd, &st) < 0)
- return -errno;
-
- return stat_verify_directory(&st);
-}
-#endif /* NM_IGNORED */
-
int proc_mounted(void) {
int r;
@@ -480,7 +498,7 @@ int xstatfsat(int dir_fd, const char *path, struct statfs *ret) {
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
assert(ret);
- fd = xopenat(dir_fd, path, O_PATH|O_CLOEXEC|O_NOCTTY, /* xopen_flags = */ 0, /* mode = */ 0);
+ fd = xopenat(dir_fd, path, O_PATH|O_CLOEXEC|O_NOCTTY);
if (fd < 0)
return fd;
diff --git a/src/libnm-systemd-shared/src/basic/stat-util.h b/src/libnm-systemd-shared/src/basic/stat-util.h
index 65a14a44cb..7eb951a7a4 100644
--- a/src/libnm-systemd-shared/src/basic/stat-util.h
+++ b/src/libnm-systemd-shared/src/basic/stat-util.h
@@ -14,14 +14,22 @@
#include "siphash24.h"
#include "time-util.h"
+int stat_verify_regular(const struct stat *st);
+int verify_regular_at(int fd, const char *path, bool follow);
+int fd_verify_regular(int fd);
+
+int stat_verify_directory(const struct stat *st);
+int fd_verify_directory(int fd);
+int is_dir_at(int fd, const char *path, bool follow);
+int is_dir(const char *path, bool follow);
+
+int stat_verify_symlink(const struct stat *st);
int is_symlink(const char *path);
-int is_dir_full(int atfd, const char *fname, bool follow);
-static inline int is_dir(const char *path, bool follow) {
- return is_dir_full(AT_FDCWD, path, follow);
-}
-static inline int is_dir_fd(int fd) {
- return is_dir_full(fd, NULL, false);
-}
+
+int stat_verify_linked(const struct stat *st);
+int fd_verify_linked(int fd);
+
+int stat_verify_device_node(const struct stat *st);
int is_device_node(const char *path);
int dir_is_empty_at(int dir_fd, const char *path, bool ignore_hidden_or_backup);
@@ -72,13 +80,6 @@ int path_is_network_fs(const char *path);
*/
#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
-int stat_verify_regular(const struct stat *st);
-int fd_verify_regular(int fd);
-int verify_regular_at(int dir_fd, const char *path, bool follow);
-
-int stat_verify_directory(const struct stat *st);
-int fd_verify_directory(int fd);
-
int proc_mounted(void);
bool stat_inode_same(const struct stat *a, const struct stat *b);
diff --git a/src/libnm-systemd-shared/src/basic/string-util.c b/src/libnm-systemd-shared/src/basic/string-util.c
index b48e25c7bf..59e659187c 100644
--- a/src/libnm-systemd-shared/src/basic/string-util.c
+++ b/src/libnm-systemd-shared/src/basic/string-util.c
@@ -625,6 +625,9 @@ char *cellescape(char *buf, size_t len, const char *s) {
char* strshorten(char *s, size_t l) {
assert(s);
+ if (l >= SIZE_MAX-1) /* Would not change anything */
+ return s;
+
if (strnlen(s, l+1) > l)
s[l] = 0;
diff --git a/src/libnm-systemd-shared/src/basic/strv.c b/src/libnm-systemd-shared/src/basic/strv.c
index 7c6de915b2..ed02b4818f 100644
--- a/src/libnm-systemd-shared/src/basic/strv.c
+++ b/src/libnm-systemd-shared/src/basic/strv.c
@@ -363,7 +363,7 @@ int strv_split_colon_pairs(char ***t, const char *s) {
const char *p = tuple;
r = extract_many_words(&p, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS,
- &first, &second, NULL);
+ &first, &second);
if (r < 0)
return r;
if (r == 0)
diff --git a/src/libnm-systemd-shared/src/basic/time-util.c b/src/libnm-systemd-shared/src/basic/time-util.c
index 2147156e55..47f5bb5a61 100644
--- a/src/libnm-systemd-shared/src/basic/time-util.c
+++ b/src/libnm-systemd-shared/src/basic/time-util.c
@@ -1434,7 +1434,7 @@ static int get_timezones_from_zone1970_tab(char ***ret) {
/* Line format is:
* 'country codes' 'coordinates' 'timezone' 'comments' */
- r = extract_many_words(&p, NULL, 0, &cc, &co, &tz, NULL);
+ r = extract_many_words(&p, NULL, 0, &cc, &co, &tz);
if (r < 0)
continue;
@@ -1479,7 +1479,7 @@ static int get_timezones_from_tzdata_zi(char ***ret) {
* Link line format is:
* 'Link' 'target' 'alias'
* See 'man zic' for more detail. */
- r = extract_many_words(&p, NULL, 0, &type, &f1, &f2, NULL);
+ r = extract_many_words(&p, NULL, 0, &type, &f1, &f2);
if (r < 0)
continue;
@@ -1579,7 +1579,7 @@ int verify_timezone(const char *name, int log_level) {
r = fd_verify_regular(fd);
if (r < 0)
- return log_full_errno(log_level, r, "Timezone file '%s' is not a regular file: %m", t);
+ return log_full_errno(log_level, r, "Timezone file '%s' is not a regular file: %m", t);
r = loop_read_exact(fd, buf, 4, false);
if (r < 0)
diff --git a/src/libnm-systemd-shared/src/fundamental/macro-fundamental.h b/src/libnm-systemd-shared/src/fundamental/macro-fundamental.h
index c810261308..00f2a2b9a1 100644
--- a/src/libnm-systemd-shared/src/fundamental/macro-fundamental.h
+++ b/src/libnm-systemd-shared/src/fundamental/macro-fundamental.h
@@ -264,6 +264,30 @@
})
#endif /* NM_IGNORED */
+#define ADD_SAFE(ret, a, b) (!__builtin_add_overflow(a, b, ret))
+#define INC_SAFE(a, b) __INC_SAFE(UNIQ, a, b)
+#define __INC_SAFE(q, a, b) \
+ ({ \
+ const typeof(a) UNIQ_T(A, q) = (a); \
+ ADD_SAFE(UNIQ_T(A, q), *UNIQ_T(A, q), b); \
+ })
+
+#define SUB_SAFE(ret, a, b) (!__builtin_sub_overflow(a, b, ret))
+#define DEC_SAFE(a, b) __DEC_SAFE(UNIQ, a, b)
+#define __DEC_SAFE(q, a, b) \
+ ({ \
+ const typeof(a) UNIQ_T(A, q) = (a); \
+ SUB_SAFE(UNIQ_T(A, q), *UNIQ_T(A, q), b); \
+ })
+
+#define MUL_SAFE(ret, a, b) (!__builtin_mul_overflow(a, b, ret))
+#define MUL_ASSIGN_SAFE(a, b) __MUL_ASSIGN_SAFE(UNIQ, a, b)
+#define __MUL_ASSIGN_SAFE(q, a, b) \
+ ({ \
+ const typeof(a) UNIQ_T(A, q) = (a); \
+ MUL_SAFE(UNIQ_T(A, q), *UNIQ_T(A, q), b); \
+ })
+
#define LESS_BY(a, b) __LESS_BY(UNIQ, (a), UNIQ, (b))
#define __LESS_BY(aq, a, bq, b) \
({ \
@@ -313,7 +337,7 @@
const typeof(y) UNIQ_T(A, q) = (y); \
const typeof(x) UNIQ_T(B, q) = DIV_ROUND_UP((x), UNIQ_T(A, q)); \
typeof(x) UNIQ_T(C, q); \
- __builtin_mul_overflow(UNIQ_T(B, q), UNIQ_T(A, q), &UNIQ_T(C, q)) ? (typeof(x)) -1 : UNIQ_T(C, q); \
+ MUL_SAFE(&UNIQ_T(C, q), UNIQ_T(B, q), UNIQ_T(A, q)) ? UNIQ_T(C, q) : (typeof(x)) -1; \
})
#define ROUND_UP(x, y) __ROUND_UP(UNIQ, (x), (y))
diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in
index 7ec99539aa..2a4e3991f2 100644
--- a/src/libnmc-setting/settings-docs.h.in
+++ b/src/libnmc-setting/settings-docs.h.in
@@ -5,7 +5,7 @@
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT_PORTS N_("Whether or not ports of this connection should be automatically brought up when NetworkManager activates this connection. This only has a real effect for controller connections. The properties \"autoconnect\", \"autoconnect-priority\" and \"autoconnect-retries\" are unrelated to this setting. The permitted values are: 0: leave port connections untouched, 1: activate all the port connections with this connection, -1: default. If -1 (default) is set, global connection.autoconnect-ports is read to determine the real value. If it is default as well, this fallbacks to 0.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY N_("The autoconnect priority in range -999 to 999. If the connection is set to autoconnect, connections with higher priority will be preferred. The higher number means higher priority. Defaults to 0. Note that this property only matters if there are more than one candidate profile to select for autoconnect. In case of equal priority, the profile used most recently is chosen.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES N_("The number of times a connection should be tried when autoactivating before giving up. Zero means forever, -1 means the global default (4 times if not overridden). Setting this to 1 means to try activation only once before blocking autoconnect. Note that after a timeout, NetworkManager will try to autoconnect again.")
-#define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES N_("Whether or not slaves of this connection should be automatically brought up when NetworkManager activates this connection. This only has a real effect for master connections. The properties \"autoconnect\", \"autoconnect-priority\" and \"autoconnect-retries\" are unrelated to this setting. The permitted values are: 0: leave slave connections untouched, 1: activate all the slave connections with this connection, -1: default. If -1 (default) is set, global connection.autoconnect-slaves is read to determine the real value. If it is default as well, this fallbacks to 0.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES N_("Whether or not slaves of this connection should be automatically brought up when NetworkManager activates this connection. This only has a real effect for master connections. The properties \"autoconnect\", \"autoconnect-priority\" and \"autoconnect-retries\" are unrelated to this setting. The permitted values are: 0: leave slave connections untouched, 1: activate all the slave connections with this connection, -1: default. If -1 (default) is set, global connection.autoconnect-slaves is read to determine the real value. If it is default as well, this fallbacks to 0. Deprecated 1.46. Use \"autoconnect-ports\" instead, this is just an alias.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_CONTROLLER N_("Interface name of the controller device or UUID of the controller connection.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_DNS_OVER_TLS N_("Whether DNSOverTls (dns-over-tls) is enabled for the connection. DNSOverTls is a technology which uses TLS to encrypt dns traffic. The permitted values are: \"yes\" (2) use DNSOverTls and disabled fallback, \"opportunistic\" (1) use DNSOverTls but allow fallback to unencrypted resolution, \"no\" (0) don't ever use DNSOverTls. If unspecified \"default\" depends on the plugin used. Systemd-resolved uses global setting. This feature requires a plugin which supports DNSOverTls. Otherwise, the setting has no effect. One such plugin is dns-systemd-resolved.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_DOWN_ON_POWEROFF N_("Whether the connection will be brought down before the system is powered off. The default value is \"default\" (-1). When the default value is specified, then the global value from NetworkManager configuration is looked up, if not set, it is considered as \"no\" (0).")
diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in
index 4eccae978a..24d1ddbf31 100644
--- a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in
+++ b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in
@@ -680,7 +680,7 @@
format="string"
values="bond, bridge, ovs-bridge, ovs-port, team, vrf" />
<property name="autoconnect-slaves"
- nmcli-description="Whether or not slaves of this connection should be automatically brought up when NetworkManager activates this connection. This only has a real effect for master connections. The properties &quot;autoconnect&quot;, &quot;autoconnect-priority&quot; and &quot;autoconnect-retries&quot; are unrelated to this setting. The permitted values are: 0: leave slave connections untouched, 1: activate all the slave connections with this connection, -1: default. If -1 (default) is set, global connection.autoconnect-slaves is read to determine the real value. If it is default as well, this fallbacks to 0."
+ nmcli-description="Whether or not slaves of this connection should be automatically brought up when NetworkManager activates this connection. This only has a real effect for master connections. The properties &quot;autoconnect&quot;, &quot;autoconnect-priority&quot; and &quot;autoconnect-retries&quot; are unrelated to this setting. The permitted values are: 0: leave slave connections untouched, 1: activate all the slave connections with this connection, -1: default. If -1 (default) is set, global connection.autoconnect-slaves is read to determine the real value. If it is default as well, this fallbacks to 0. Deprecated 1.46. Use &quot;autoconnect-ports&quot; instead, this is just an alias."
format="choice (NMSettingConnectionAutoconnectSlaves)"
values="default (-1), no (0), yes (1)" />
<property name="autoconnect-ports"
diff --git a/tools/enums-to-docbook.pl b/tools/enums-to-docbook.pl
index 8439eaee71..d21cafa2b1 100755
--- a/tools/enums-to-docbook.pl
+++ b/tools/enums-to-docbook.pl
@@ -27,7 +27,7 @@ my $nm = shift @ARGV or die "Missing title";
print <<END;
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<refentry id="$id">
<refmeta>